diff options
author | Alec Kojaev <alec@kojaev.name> | 2021-07-16 15:40:04 +0300 |
---|---|---|
committer | Sean Molenaar <SMillerDev@users.noreply.github.com> | 2021-07-24 14:52:34 +0200 |
commit | 65c15dac38358d5c3a619379b57bd498c070ea6f (patch) | |
tree | 8052e83899b96b7e761f779a43d15feb7921e353 /js/filter | |
parent | 691c42bdbce50eaa7857f8386c706a4e8c763d60 (diff) |
Reimplement relative time formatting as a filter, dropping dependency on deprecated moment.js
Signed-off-by: Alec Kojaev <alec@kojaev.name>
Diffstat (limited to 'js/filter')
-rw-r--r-- | js/filter/RelativeTimestamp.js | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/js/filter/RelativeTimestamp.js b/js/filter/RelativeTimestamp.js new file mode 100644 index 000000000..1a70db4a7 --- /dev/null +++ b/js/filter/RelativeTimestamp.js @@ -0,0 +1,58 @@ +/** + * Nextcloud - News + * + * This file is licensed under the Affero General Public License version 3 or + * later. See the COPYING file. + * + * @author Alec Kojaev <alec@kojaev.name> + * @copyright Alec Kojaev 2021 + */ +app.filter('relativeTimestamp', ['SettingsResource', function (SettingsResource) { + 'use strict'; + + const languageCode = SettingsResource.get('language'); + const relFormat = Intl.RelativeTimeFormat ? + new Intl.RelativeTimeFormat(languageCode, { numeric: 'auto' }) : null; + const maxRelDistance = 90*86400*1000; + const relLimits = [ + [ 7*86400*1000, 'week' ], + [ 86400*1000, 'day' ], + [ 3600*1000, 'hour' ], + [ 60*1000, 'minute' ], + [ 1*1000, 'second' ] + ]; + const absLimits = [ + [ 7*86400*1000, { hour: '2-digit', minute: '2-digit', dayPeriod: 'narrow', + year: 'numeric', month: 'short', day: 'numeric' } ], + [ 43200*1000, { hour: '2-digit', minute: '2-digit', dayPeriod: 'narrow', + weekday: 'long' } ], + [ 0, { hour: '2-digit', minute: '2-digit', dayPeriod: 'narrow' } ] + ]; + + return function (timestamp) { + if (!Number.isFinite(timestamp)) { + return timestamp; + } + const ts = new Date(timestamp); + const dist = ts.getTime() - Date.now(); + const absDist = Math.abs(dist); + if (relFormat && absDist < maxRelDistance) { + for (const [ scale, unit ] of relLimits) { + const value = Math.trunc(dist / scale); + if (value !== 0) { + return relFormat.format(value, unit); + } + } + // We arrive here only if distance from now is less than 1 second + return relFormat.format(0, 'second'); + } else { + for (const [ limit, options ] of absLimits) { + if (absDist >= limit) { + return ts.toLocaleString(languageCode, options); + } + } + // We shouldn't be here + return ts.toLocaleString(languageCode, absLimits[absLimits.length - 1][1]); + } + }; +}]); |