Replace moment-countdown with countdown function

This commit is contained in:
Michael Weimann 2022-10-18 22:34:53 +02:00
parent a81992ca04
commit 7049a08bcd
No known key found for this signature in database
GPG Key ID: 34F0524D4DA694A1
7 changed files with 91 additions and 41 deletions

View File

@ -84,7 +84,7 @@ function ShiftEntry_create_view_admin($shift, Room $room, $angeltype, $angeltype
{
return page_with_title(
ShiftEntry_create_title() . ': ' . $shift['name']
. ' <small class="moment-countdown" data-timestamp="' . $shift['start'] . '">%c</small>',
. ' <small data-countdown-ts="' . $shift['start'] . '">%c</small>',
[
Shift_view_header($shift, $room),
info(__('Do you want to sign up the following user for this shift?'), true),
@ -111,7 +111,7 @@ function ShiftEntry_create_view_supporter($shift, Room $room, $angeltype, $signu
{
return page_with_title(
ShiftEntry_create_title() . ': ' . $shift['name']
. ' <small class="moment-countdown" data-timestamp="' . $shift['start'] . '">%c</small>',
. ' <small data-countdown-ts="' . $shift['start'] . '">%c</small>',
[
Shift_view_header($shift, $room),
info(sprintf(
@ -139,7 +139,7 @@ function ShiftEntry_create_view_user($shift, Room $room, $angeltype, $comment)
{
return page_with_title(
ShiftEntry_create_title() . ': ' . $shift['name']
. ' <small class="moment-countdown" data-timestamp="' . $shift['start'] . '">%c</small>',
. ' <small data-countdown-ts="' . $shift['start'] . '">%c</small>',
[
Shift_view_header($shift, $room),
info(sprintf(__('Do you want to sign up for this shift as %s?'), AngelType_name_render($angeltype)), true),

View File

@ -191,7 +191,7 @@ function Shift_view($shift, $shifttype, Room $room, $angeltypes_source, ShiftSig
}
return page_with_title(
$shift['name'] . ' <small class="moment-countdown" data-timestamp="' . $shift['start'] . '">%c</small>',
$shift['name'] . ' <small data-countdown-ts="' . $shift['start'] . '">%c</small>',
$content
);
}

View File

@ -317,23 +317,23 @@ function User_shift_state_render($user)
if ($nextShift['start'] > time()) {
if ($nextShift['start'] - time() > 3600) {
return '<span class="text-success moment-countdown" data-timestamp="' . $nextShift['start'] . '">'
return '<span class="text-success" data-countdown-ts="' . $nextShift['start'] . '">'
. __('Next shift %c')
. '</span>';
}
return '<span class="text-warning moment-countdown" data-timestamp="' . $nextShift['start'] . '">'
return '<span class="text-warning" data-countdown-ts="' . $nextShift['start'] . '">'
. __('Next shift %c')
. '</span>';
}
$halfway = ($nextShift['start'] + $nextShift['end']) / 2;
if (time() < $halfway) {
return '<span class="text-danger moment-countdown" data-timestamp="' . $nextShift['start'] . '">'
return '<span class="text-danger" data-countdown-ts="' . $nextShift['start'] . '">'
. __('Shift started %c')
. '</span>';
}
return '<span class="text-danger moment-countdown" data-timestamp="' . $nextShift['end'] . '">'
return '<span class="text-danger" data-countdown-ts="' . $nextShift['end'] . '">'
. __('Shift ends %c')
. '</span>';
}
@ -350,7 +350,7 @@ function User_last_shift_render($user)
}
$lastShift = array_shift($last_shifts);
return '<span class="moment-countdown" data-timestamp="' . $lastShift['end'] . '">'
return '<span data-countdown-ts="' . $lastShift['end'] . '">'
. __('Shift ended %c')
. '</span>';
}

View File

@ -0,0 +1,80 @@
const lang = document.documentElement.getAttribute('lang');
const templateFuture = 'in %value %unit';
const templatePast = lang === "en"
? '%value %unit ago'
: 'vor %value %unit';
const yearUnits = lang === "en"
? ["year", "years"]
: ["Jahr", "Jahren"];
const monthUnits = lang === "en"
? ["month", "months"]
: ["Monat", "Monaten"];
const dayUnits = lang === "en"
? ["day", "days"]
: ["Tag", "Tagen"];
const hourUnits = lang === "en"
? ["hour", "hours"]
: ["Stunde", "Stunden"];
const minuteUnits = lang === "en"
? ["minute", "minutes"]
: ["Minute", "Minuten"];
const secondUnits = lang === "en"
? ["second", "seconds"]
: ["Sekunde", "Sekunden"];
const nowString = lang === "en" ? "now" : "jetzt";
const secondsHour = 60 * 60;
const timeFrames = [
[365 * 24 * 60 * 60, yearUnits],
[30 * 24 * 60 * 60, monthUnits],
[24 * 60 * 60, dayUnits],
[secondsHour, hourUnits],
[60, minuteUnits],
[1, secondUnits],
];
function formatFromNow(timestamp) {
const now = Date.now() / 1000;
const diff = Math.abs(timestamp - now);
const ago = now > timestamp;
for (const [duration, [singular, plural]] of timeFrames) {
const value = diff < secondsHour
? Math.floor(diff / duration)
: Math.round(diff / duration);
if (value) {
const template = ago ? templatePast : templateFuture;
const unit = value === 1 ? singular : plural;
return template
.replace("%value", value)
.replace("%unit", unit);
}
}
return nowString;
}
/**
* Initialises all countdown fields on the page.
*/
$(document).ready(function () {
$.each($('[data-countdown-ts]'), function (i, e) {
var span = $(e);
const timestamp = span.data("countdown-ts");
var text = span.html();
span.html(text.replace('%c', formatFromNow(timestamp)));
setInterval(function () {
span.html(text.replace('%c', formatFromNow(timestamp)));
}, 1000);
});
});

View File

@ -1,21 +0,0 @@
/*
* Initialize all moment countdowns on the page. A moment countdown has the
* class 'moment-countdown' and the attribute 'data-timestamp' which defines the
* countdown's time goal.
*/
$(document).ready(function () {
if (typeof moment !== 'undefined') {
moment.locale($('html').attr('lang'));
$.each($('.moment-countdown'), function (i, e) {
var span = $(e);
var text = span.html();
/* global moment */
var timestamp = moment(parseInt(span.attr('data-timestamp') * 1000));
span.html(text.replace('%c', timestamp.fromNow()));
setInterval(function () {
span.html(text.replace('%c', timestamp.fromNow()));
}, 1000);
});
}
});

View File

@ -1,18 +1,9 @@
require('core-js/stable');
window.$ = window.jQuery = require('jquery');
window.bootstrap = require('bootstrap');
window.moment = require('moment');
require('moment/locale/de');
require('./forms');
require('./sticky-headers');
require('./moment-countdown');
moment.updateLocale('en', {
week : {
dow : 1, // Monday is the first day of the week.
doy : 4 // The week that contains Jan 4th is the first week of the year.
}
});
require('./countdown');
$.ajaxSetup({
headers: {'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')}

View File

@ -21,7 +21,7 @@
{% if date > date() %}
<div class="col-sm-3 text-center d-none d-sm-block">
<h4>{{ name }}</h4>
<div class="moment-countdown h2 text-body" data-timestamp="{{ date.getTimestamp }}">%c</div>
<div class="h2 text-body" data-countdown-ts="{{ date.getTimestamp }}">%c</div>
<small>{{ date.format(__('Y-m-d')) }}</small>
</div>
{% endif %}