diff --git a/api/js/etemplate/et2_widget_countdown.js b/api/js/etemplate/et2_widget_countdown.js index 5b9c1498f8..1b3a7452dd 100644 --- a/api/js/etemplate/et2_widget_countdown.js +++ b/api/js/etemplate/et2_widget_countdown.js @@ -34,7 +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. + * Value for countdown is the expiry date of the counter or a numeric timeout in seconds. + * + * The timeout 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); @@ -65,11 +67,21 @@ var et2_countdown = /** @class */ (function (_super) { // 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 == "") 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); var self = this; this.timer = setInterval(function () { @@ -82,7 +94,7 @@ var et2_countdown = /** @class */ (function (_super) { }; et2_countdown.prototype._updateTimer = function () { var tempDate = new Date(); - var now = new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate(), tempDate.getHours(), tempDate.getMinutes() - tempDate.getTimezoneOffset(), tempDate.getSeconds()); + 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(); if (distance < 0) diff --git a/api/js/etemplate/et2_widget_countdown.ts b/api/js/etemplate/et2_widget_countdown.ts index c04b9595b6..eca57c2c8e 100644 --- a/api/js/etemplate/et2_widget_countdown.ts +++ b/api/js/etemplate/et2_widget_countdown.ts @@ -23,7 +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. + * Value for countdown is the expiry date of the counter or a numeric timeout in seconds. + * + * The timeout 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 = { @@ -57,7 +59,6 @@ export class et2_countdown extends et2_valueWidget { default: "", description: "Defines a callback to gets called at alarm - timer. This only will work if there's an alarm set." } - }; private time : et2_date; @@ -68,6 +69,7 @@ export class et2_countdown extends et2_valueWidget { private hours : JQuery = null; private minutes : JQuery = null; private seconds : JQuery = null; + private offset; /** * Constructor @@ -90,11 +92,23 @@ export class et2_countdown extends et2_valueWidget { // 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); let self = this; this.timer = setInterval(function(){ @@ -114,7 +128,7 @@ export class et2_countdown extends et2_valueWidget { tempDate.getMonth(), tempDate.getDate(), tempDate.getHours(), - tempDate.getMinutes()-tempDate.getTimezoneOffset(), + tempDate.getMinutes()-this.offset, tempDate.getSeconds() ); diff --git a/api/src/Etemplate/Widget/Countdown.php b/api/src/Etemplate/Widget/Countdown.php new file mode 100644 index 0000000000..0c82fb937a --- /dev/null +++ b/api/src/Etemplate/Widget/Countdown.php @@ -0,0 +1,40 @@ + + * @copyright 2021 by rb@egroupware.org + */ + +namespace EGroupware\Api\Etemplate\Widget; + +use EGroupware\Api; + +/** + * eTemplate countdown widget + * + */ +class Countdown extends Api\Etemplate\Widget +{ + /** + * Convert end-datetime of countdown into a difference in seconds to avoid errors due to wrong time&timezone on client + * + * @param string $cname + * @param array $expand values for keys 'c', 'row', 'c_', 'row_', 'cont' + */ + public function beforeSendToClient($cname, array $expand=null) + { + $form_name = self::form_name($cname, $this->id, $expand); + $value =& self::get_array(self::$request->content, $form_name, false, true); + + if ($value) + { + $value = Api\DateTime::to($value, 'utc') - Api\DateTime::to('now', 'utc'); + } + } +} +\EGroupware\Api\Etemplate\Widget::registerWidget(Countdown::class, 'countdown'); \ No newline at end of file diff --git a/api/src/Etemplate/Widget/Date.php b/api/src/Etemplate/Widget/Date.php index 0bca6e1a28..f6895765f6 100644 --- a/api/src/Etemplate/Widget/Date.php +++ b/api/src/Etemplate/Widget/Date.php @@ -256,4 +256,4 @@ class Date extends Transformer } } } -\EGroupware\Api\Etemplate\Widget::registerWidget(__NAMESPACE__.'\\Date', array('time_or_date', 'countdown')); \ No newline at end of file +\EGroupware\Api\Etemplate\Widget::registerWidget(__NAMESPACE__.'\\Date', array('time_or_date')); \ No newline at end of file