From 41a94d07f00f53d4624205fa4b23553a11e305dc Mon Sep 17 00:00:00 2001 From: Rigel Kent Date: Sat, 11 Apr 2020 15:58:44 +0200 Subject: Refactor from-now pipe to display the two most significant intervals --- client/src/app/shared/angular/from-now.pipe.ts | 89 +++++++++++++++++++------- 1 file changed, 66 insertions(+), 23 deletions(-) (limited to 'client/src/app/shared') diff --git a/client/src/app/shared/angular/from-now.pipe.ts b/client/src/app/shared/angular/from-now.pipe.ts index 3a9a76411..c3c0efbfc 100644 --- a/client/src/app/shared/angular/from-now.pipe.ts +++ b/client/src/app/shared/angular/from-now.pipe.ts @@ -1,5 +1,6 @@ import { Pipe, PipeTransform } from '@angular/core' import { I18n } from '@ngx-translate/i18n-polyfill' +import { findIndex } from 'lodash-es' // Thanks: https://stackoverflow.com/questions/3177836/how-to-format-time-since-xxx-e-g-4-minutes-ago-similar-to-stack-exchange-site @Pipe({ name: 'myFromNow' }) @@ -10,31 +11,73 @@ export class FromNowPipe implements PipeTransform { transform (arg: number | Date | string) { const argDate = new Date(arg) const seconds = Math.floor((Date.now() - argDate.getTime()) / 1000) + let intervals = [ + { + unit: 31536000, // 1 year + singular: (i: number) => this.i18n('{{i}} year', { i }), + plural: (i: number) => this.i18n('{{i}} years', { i }) + }, + { + unit: 2592000, // 1 month + max: 11, + singular: (i: number) => this.i18n('{{i}} month', { i }), + plural: (i: number) => this.i18n('{{i}} months', { i }) + }, + { + unit: 604800, // 1 week + max: 3, + singular: (i: number) => this.i18n('{{i}} week', { i }), + plural: (i: number) => this.i18n('{{i}} weeks', { i }) + }, + { + unit: 86400, // 1 day + max: 6, + singular: (i: number) => this.i18n('{{i}} day', { i }), + plural: (i: number) => this.i18n('{{i}} days', { i }) + }, + { + unit: 3600, // 1 hour + max: 23, + singular: (i: number) => this.i18n('{{i}} hour', { i }), + plural: (i: number) => this.i18n('{{i}} hours', { i }) + }, + { + unit: 60, // 1 min + max: 59, + singular: (i: number) => this.i18n('{{i}} min', { i }), + plural: (i: number) => this.i18n('{{i}} min', { i }) + } + ] + .map(i => ({ ...i, interval: Math.floor(seconds / i.unit) })) // absolute interval + .map((i, index, array) => ({ // interval relative to remainder + ...i, + interval: index === 0 + ? i.interval + : Math.floor((seconds - array[index - 1].interval * array[index - 1].unit) / i.unit) + })) + .map(i => ({ // value, interval put in its translated text wrt max value + ...i, + value: (i.interval > 1 + ? i.plural + : i.singular + )(Math.min(i.max, i.interval)) // respect the max value + })) - let interval = Math.floor(seconds / 31536000) - if (interval > 1) { - return this.i18n('{{interval}} years ago', { interval }) - } - - interval = Math.floor(seconds / 2592000) - if (interval > 1) return this.i18n('{{interval}} months ago', { interval }) - if (interval === 1) return this.i18n('{{interval}} month ago', { interval }) - - interval = Math.floor(seconds / 604800) - if (interval > 1) return this.i18n('{{interval}} weeks ago', { interval }) - if (interval === 1) return this.i18n('{{interval}} week ago', { interval }) + // only keep the first two intervals with enough seconds to be considered + const big_interval_index = findIndex(intervals, i => i.interval >= 1) + intervals = intervals + .slice(big_interval_index, big_interval_index + 2) + .filter(i => i.interval >= 1) - interval = Math.floor(seconds / 86400) - if (interval > 1) return this.i18n('{{interval}} days ago', { interval }) - if (interval === 1) return this.i18n('{{interval}} day ago', { interval }) - - interval = Math.floor(seconds / 3600) - if (interval > 1) return this.i18n('{{interval}} hours ago', { interval }) - if (interval === 1) return this.i18n('{{interval}} hour ago', { interval }) - - interval = Math.floor(seconds / 60) - if (interval >= 1) return this.i18n('{{interval}} min ago', { interval }) + if (intervals.length === 0) { + return this.i18n('just now') + } - return this.i18n('{{interval}} sec ago', { interval: Math.max(0, seconds) }) + return intervals.length == 1 + ? this.i18n('{{interval}} ago', { interval: intervals[0].value }) + : this.i18n('{{big_interval}} {{small_interval}} ago', { + big_interval: intervals[0].value, + small_interval: intervals[1].value + }) } } -- cgit v1.2.3