From 7049a08bcdadb6475133e76501ba34f9a6f46bf0 Mon Sep 17 00:00:00 2001 From: Michael Weimann Date: Tue, 18 Oct 2022 22:34:53 +0200 Subject: [PATCH] Replace moment-countdown with countdown function --- includes/view/ShiftEntry_view.php | 6 +- includes/view/Shifts_view.php | 2 +- includes/view/User_view.php | 10 ++-- resources/assets/js/countdown.js | 80 +++++++++++++++++++++++++ resources/assets/js/moment-countdown.js | 21 ------- resources/assets/js/vendor.js | 11 +--- resources/views/pages/login.twig | 2 +- 7 files changed, 91 insertions(+), 41 deletions(-) create mode 100644 resources/assets/js/countdown.js delete mode 100644 resources/assets/js/moment-countdown.js diff --git a/includes/view/ShiftEntry_view.php b/includes/view/ShiftEntry_view.php index 45238e9f..73fff1b8 100644 --- a/includes/view/ShiftEntry_view.php +++ b/includes/view/ShiftEntry_view.php @@ -84,7 +84,7 @@ function ShiftEntry_create_view_admin($shift, Room $room, $angeltype, $angeltype { return page_with_title( ShiftEntry_create_title() . ': ' . $shift['name'] - . ' %c', + . ' %c', [ 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'] - . ' %c', + . ' %c', [ 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'] - . ' %c', + . ' %c', [ Shift_view_header($shift, $room), info(sprintf(__('Do you want to sign up for this shift as %s?'), AngelType_name_render($angeltype)), true), diff --git a/includes/view/Shifts_view.php b/includes/view/Shifts_view.php index 91e075ae..b1caa7e7 100644 --- a/includes/view/Shifts_view.php +++ b/includes/view/Shifts_view.php @@ -191,7 +191,7 @@ function Shift_view($shift, $shifttype, Room $room, $angeltypes_source, ShiftSig } return page_with_title( - $shift['name'] . ' %c', + $shift['name'] . ' %c', $content ); } diff --git a/includes/view/User_view.php b/includes/view/User_view.php index 7a33457f..2aef3b73 100644 --- a/includes/view/User_view.php +++ b/includes/view/User_view.php @@ -317,23 +317,23 @@ function User_shift_state_render($user) if ($nextShift['start'] > time()) { if ($nextShift['start'] - time() > 3600) { - return '' + return '' . __('Next shift %c') . ''; } - return '' + return '' . __('Next shift %c') . ''; } $halfway = ($nextShift['start'] + $nextShift['end']) / 2; if (time() < $halfway) { - return '' + return '' . __('Shift started %c') . ''; } - return '' + return '' . __('Shift ends %c') . ''; } @@ -350,7 +350,7 @@ function User_last_shift_render($user) } $lastShift = array_shift($last_shifts); - return '' + return '' . __('Shift ended %c') . ''; } diff --git a/resources/assets/js/countdown.js b/resources/assets/js/countdown.js new file mode 100644 index 00000000..debd8fb5 --- /dev/null +++ b/resources/assets/js/countdown.js @@ -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); + }); +}); diff --git a/resources/assets/js/moment-countdown.js b/resources/assets/js/moment-countdown.js deleted file mode 100644 index d12ee7ab..00000000 --- a/resources/assets/js/moment-countdown.js +++ /dev/null @@ -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); - }); - } -}); diff --git a/resources/assets/js/vendor.js b/resources/assets/js/vendor.js index 9df21462..9ea07a1b 100644 --- a/resources/assets/js/vendor.js +++ b/resources/assets/js/vendor.js @@ -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')} diff --git a/resources/views/pages/login.twig b/resources/views/pages/login.twig index cf012078..0bf31660 100644 --- a/resources/views/pages/login.twig +++ b/resources/views/pages/login.twig @@ -21,7 +21,7 @@ {% if date > date() %}

{{ name }}

-
%c
+
%c
{{ date.format(__('Y-m-d')) }}
{% endif %}