change client-side to only deal with a duration converted server-side from an end-datetime or a duration like "+123seconds"

This commit is contained in:
Ralf Becker 2021-01-28 19:52:40 +02:00
parent 58dedd4f3b
commit 15c72f284f
3 changed files with 44 additions and 53 deletions

View File

@ -34,9 +34,9 @@ var et2_core_valueWidget_1 = require("./et2_core_valueWidget");
/** /**
* Class which implements the "countdown" XET-Tag * 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) { var et2_countdown = /** @class */ (function (_super) {
__extends(et2_countdown, _super); __extends(et2_countdown, _super);
@ -64,25 +64,14 @@ var et2_countdown = /** @class */ (function (_super) {
.addClass("et2_countdown_minutes").appendTo(_this.container); .addClass("et2_countdown_minutes").appendTo(_this.container);
_this.seconds = jQuery(document.createElement("span")) _this.seconds = jQuery(document.createElement("span"))
.addClass("et2_countdown_seconds").appendTo(_this.container); .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.setDOMNode(_this.container[0]);
_this.offset = (new Date).getTimezoneOffset();
return _this; return _this;
} }
et2_countdown.prototype.set_value = function (_time) { et2_countdown.prototype.set_value = function (_time) {
if (_time == "") if (isNaN(_time))
return; return;
if (!isNaN(_time)) { this.time = new Date();
var t = new Date(); this.time.setSeconds(this.time.getSeconds() + parseInt(_time));
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; var self = this;
this.timer = setInterval(function () { this.timer = setInterval(function () {
if (self._updateTimer() <= 0) { if (self._updateTimer() <= 0) {
@ -93,10 +82,8 @@ var et2_countdown = /** @class */ (function (_super) {
}, 1000); }, 1000);
}; };
et2_countdown.prototype._updateTimer = function () { et2_countdown.prototype._updateTimer = function () {
var tempDate = new Date(); var now = new Date();
var now = new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate(), tempDate.getHours(), tempDate.getMinutes() - this.offset, tempDate.getSeconds()); var distance = this.time.getTime() - now.getTime();
var time = new Date(this.time.getValue());
var distance = time.getTime() - now.getTime();
if (distance < 0) if (distance < 0)
return 0; return 0;
if (this.options.alarm > 0 && this.options.alarm == distance / 1000 && typeof this.onAlarm == 'function') { if (this.options.alarm > 0 && this.options.alarm == distance / 1000 && typeof this.onAlarm == 'function') {

View File

@ -23,9 +23,9 @@ import {et2_valueWidget} from "./et2_core_valueWidget";
/** /**
* Class which implements the "countdown" XET-Tag * 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 { export class et2_countdown extends et2_valueWidget {
static readonly _attributes: any = { 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 timer = null;
private container : JQuery = null; private container : JQuery = null;
@ -69,7 +69,6 @@ export class et2_countdown extends et2_valueWidget {
private hours : JQuery = null; private hours : JQuery = null;
private minutes : JQuery = null; private minutes : JQuery = null;
private seconds : JQuery = null; private seconds : JQuery = null;
private offset;
/** /**
* Constructor * Constructor
@ -89,27 +88,16 @@ export class et2_countdown extends et2_valueWidget {
.addClass("et2_countdown_minutes").appendTo(this.container); .addClass("et2_countdown_minutes").appendTo(this.container);
this.seconds = jQuery(document.createElement("span")) this.seconds = jQuery(document.createElement("span"))
.addClass("et2_countdown_seconds").appendTo(this.container); .addClass("et2_countdown_seconds").appendTo(this.container);
// create a date widget
this.time = <et2_date> et2_createWidget('date-time', {});
this.setDOMNode(this.container[0]); this.setDOMNode(this.container[0]);
this.offset = (new Date).getTimezoneOffset();
} }
public set_value(_time) public set_value(_time)
{ {
if (_time == "") return; if (isNaN(_time)) return;
if (!isNaN(_time))
{ this.time = new Date();
let t = new Date(); this.time.setSeconds(this.time.getSeconds() + parseInt(_time));
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; let self = this;
this.timer = setInterval(function(){ this.timer = setInterval(function(){
if (self._updateTimer() <= 0) if (self._updateTimer() <= 0)
@ -122,18 +110,8 @@ export class et2_countdown extends et2_valueWidget {
private _updateTimer() private _updateTimer()
{ {
let tempDate = new Date(); let now = new Date();
let now = new Date( let distance = this.time.getTime() - now.getTime();
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();
if (distance < 0) return 0; if (distance < 0) return 0;
if (this.options.alarm > 0 && this.options.alarm == distance/1000 && typeof this.onAlarm == 'function') if (this.options.alarm > 0 && this.options.alarm == distance/1000 && typeof this.onAlarm == 'function')

View File

@ -17,6 +17,11 @@ use EGroupware\Api;
/** /**
* eTemplate countdown widget * 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 class Countdown extends Api\Etemplate\Widget
{ {
@ -33,8 +38,29 @@ class Countdown extends Api\Etemplate\Widget
if ($value) 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'); \EGroupware\Api\Etemplate\Widget::registerWidget(Countdown::class, 'countdown');