From 15c72f284f6aec28b2a2690050b5942b818606f0 Mon Sep 17 00:00:00 2001 From: Ralf Becker Date: Thu, 28 Jan 2021 19:52:40 +0200 Subject: [PATCH] change client-side to only deal with a duration converted server-side from an end-datetime or a duration like "+123seconds" --- api/js/etemplate/et2_widget_countdown.js | 27 ++++----------- api/js/etemplate/et2_widget_countdown.ts | 42 ++++++------------------ api/src/Etemplate/Widget/Countdown.php | 28 +++++++++++++++- 3 files changed, 44 insertions(+), 53 deletions(-) diff --git a/api/js/etemplate/et2_widget_countdown.js b/api/js/etemplate/et2_widget_countdown.js index 1b3a7452dd..509bce8e48 100644 --- a/api/js/etemplate/et2_widget_countdown.js +++ b/api/js/etemplate/et2_widget_countdown.js @@ -34,9 +34,9 @@ var et2_core_valueWidget_1 = require("./et2_core_valueWidget"); /** * Class which implements the "countdown" XET-Tag * - * Value for countdown is the expiry date of the counter or a numeric timeout in seconds. + * Value for countdown is an integer duration in seconds or a server-side to a duration converted expiry datetime. * - * The timeout has the benefit, that it does not depend on the correct set time and timezone of the browser / computer of the user. + * The duration has the benefit, that it does not depend on the correct set time and timezone of the browser / computer of the user. */ var et2_countdown = /** @class */ (function (_super) { __extends(et2_countdown, _super); @@ -64,25 +64,14 @@ var et2_countdown = /** @class */ (function (_super) { .addClass("et2_countdown_minutes").appendTo(_this.container); _this.seconds = jQuery(document.createElement("span")) .addClass("et2_countdown_seconds").appendTo(_this.container); - // create a date widget - _this.time = et2_core_widget_1.et2_createWidget('date-time', {}); _this.setDOMNode(_this.container[0]); - _this.offset = (new Date).getTimezoneOffset(); return _this; } et2_countdown.prototype.set_value = function (_time) { - if (_time == "") + if (isNaN(_time)) return; - if (!isNaN(_time)) { - var t = new Date(); - t.setSeconds(t.getSeconds() + parseInt(_time)); - _time = t; - this.offset = 0; - } - else { - this.offset = (new Date).getTimezoneOffset(); - } - this.time.set_value(_time); + this.time = new Date(); + this.time.setSeconds(this.time.getSeconds() + parseInt(_time)); var self = this; this.timer = setInterval(function () { if (self._updateTimer() <= 0) { @@ -93,10 +82,8 @@ var et2_countdown = /** @class */ (function (_super) { }, 1000); }; et2_countdown.prototype._updateTimer = function () { - var tempDate = new Date(); - var now = new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate(), tempDate.getHours(), tempDate.getMinutes() - this.offset, tempDate.getSeconds()); - var time = new Date(this.time.getValue()); - var distance = time.getTime() - now.getTime(); + var now = new Date(); + var distance = this.time.getTime() - now.getTime(); if (distance < 0) return 0; if (this.options.alarm > 0 && this.options.alarm == distance / 1000 && typeof this.onAlarm == 'function') { diff --git a/api/js/etemplate/et2_widget_countdown.ts b/api/js/etemplate/et2_widget_countdown.ts index eca57c2c8e..d0c313d36c 100644 --- a/api/js/etemplate/et2_widget_countdown.ts +++ b/api/js/etemplate/et2_widget_countdown.ts @@ -23,9 +23,9 @@ import {et2_valueWidget} from "./et2_core_valueWidget"; /** * Class which implements the "countdown" XET-Tag * - * Value for countdown is the expiry date of the counter or a numeric timeout in seconds. + * Value for countdown is an integer duration in seconds or a server-side to a duration converted expiry datetime. * - * The timeout has the benefit, that it does not depend on the correct set time and timezone of the browser / computer of the user. + * The duration has the benefit, that it does not depend on the correct set time and timezone of the browser / computer of the user. */ export class et2_countdown extends et2_valueWidget { static readonly _attributes: any = { @@ -61,7 +61,7 @@ export class et2_countdown extends et2_valueWidget { } }; - private time : et2_date; + private time : Date; private timer = null; private container : JQuery = null; @@ -69,7 +69,6 @@ export class et2_countdown extends et2_valueWidget { private hours : JQuery = null; private minutes : JQuery = null; private seconds : JQuery = null; - private offset; /** * Constructor @@ -89,27 +88,16 @@ export class et2_countdown extends et2_valueWidget { .addClass("et2_countdown_minutes").appendTo(this.container); this.seconds = jQuery(document.createElement("span")) .addClass("et2_countdown_seconds").appendTo(this.container); - // create a date widget - this.time = et2_createWidget('date-time', {}); this.setDOMNode(this.container[0]); - this.offset = (new Date).getTimezoneOffset(); } public set_value(_time) { - if (_time == "") return; - if (!isNaN(_time)) - { - let t = new Date(); - t.setSeconds(t.getSeconds()+parseInt(_time)); - _time = t; - this.offset = 0; - } - else - { - this.offset = (new Date).getTimezoneOffset(); - } - this.time.set_value(_time); + if (isNaN(_time)) return; + + this.time = new Date(); + this.time.setSeconds(this.time.getSeconds() + parseInt(_time)); + let self = this; this.timer = setInterval(function(){ if (self._updateTimer() <= 0) @@ -122,18 +110,8 @@ export class et2_countdown extends et2_valueWidget { private _updateTimer() { - let tempDate = new Date(); - let now = new Date( - tempDate.getFullYear(), - tempDate.getMonth(), - tempDate.getDate(), - tempDate.getHours(), - tempDate.getMinutes()-this.offset, - tempDate.getSeconds() - ); - - let time = new Date (this.time.getValue()); - let distance = time.getTime() - now.getTime(); + let now = new Date(); + let distance = this.time.getTime() - now.getTime(); if (distance < 0) return 0; if (this.options.alarm > 0 && this.options.alarm == distance/1000 && typeof this.onAlarm == 'function') diff --git a/api/src/Etemplate/Widget/Countdown.php b/api/src/Etemplate/Widget/Countdown.php index 0c82fb937a..0481ef34dd 100644 --- a/api/src/Etemplate/Widget/Countdown.php +++ b/api/src/Etemplate/Widget/Countdown.php @@ -17,6 +17,11 @@ use EGroupware\Api; /** * eTemplate countdown widget * + * Value for countdown is an expiry datetime or a duration like '+123seconds'. + * Both are converted by beforeSendToClient to integer duration in seconds. + * Integer are treated as timestamps not duration! + * + * The duration has the benefit, that it does not depend on the correct set time and timezone of the browser / computer of the user. */ class Countdown extends Api\Etemplate\Widget { @@ -33,8 +38,29 @@ class Countdown extends Api\Etemplate\Widget if ($value) { - $value = Api\DateTime::to($value, 'utc') - Api\DateTime::to('now', 'utc'); + $value = Api\DateTime::to($value, 'utc') - time(); // =Api\DateTime::to('now', 'utc'); } } + + /** + * Perform any needed data manipulation on each row + * before sending it to client. + * + * This is used by Nextmatch on each row to do any needed + * adjustments. If not needed, don't implement it. + * + * @param type $cname + * @param array $expand + * @param array $data Row data + * @return type + */ + public function set_row_value($cname, Array $expand, Array &$data) + { + $form_name = self::form_name($cname, $this->id, $expand); + $value =& $this->get_array($data, $form_name, true); + + if ($value) $value = Api\DateTime::to($value, 'utc') - time(); // =Api\DateTime::to('now', 'utc'); + } + } \EGroupware\Api\Etemplate\Widget::registerWidget(Countdown::class, 'countdown'); \ No newline at end of file