From b14ba1725612ee5ddaa40626c4fcd32212f0cc7f Mon Sep 17 00:00:00 2001 From: tusooa Date: Sat, 14 Sep 2024 00:00:18 -0400 Subject: Support displaying time in absolute format This adds two config items: useAbsoluteTimeFormat (boolean) and absoluteTimeFormatMinAge (string, number + unit ('d'|'h'|'m'|'s')). When `useAbsoluteTimeFormat` is true, the Timeago component will display absolute time if the time is at least `absoluteTimeFormatMinAge` from now. If `longFormat` prop is true, the fully formatted time is displayed. Otherwise, the format is determined by the `time` prop: (1) if `time` is on the same day of now, display hour and minute; (2) if `time` is in the same month of now, display day and hour; (3) if `time` is in the same year of now, display month and day; (4) otherwise, display year and month. If it should display relative time, the format is the same as before. --- src/components/settings_modal/tabs/general_tab.vue | 23 +++++++++ src/components/timeago/timeago.vue | 57 ++++++++++++++++++++-- 2 files changed, 75 insertions(+), 5 deletions(-) (limited to 'src/components') diff --git a/src/components/settings_modal/tabs/general_tab.vue b/src/components/settings_modal/tabs/general_tab.vue index 4ece6cf4..82d5da89 100644 --- a/src/components/settings_modal/tabs/general_tab.vue +++ b/src/components/settings_modal/tabs/general_tab.vue @@ -217,6 +217,29 @@ {{ $t('settings.no_rich_text_description') }} +
  • + + {{ $t('settings.absolute_time_format') }} + +
  • +

    {{ $t('settings.attachments') }}

  • - {{ relativeTimeString }} + {{ relativeOrAbsoluteTimeString }} @@ -16,16 +16,28 @@ export default { props: ['time', 'autoUpdate', 'longFormat', 'nowThreshold', 'templateKey'], data () { return { + relativeTimeMs: 0, relativeTime: { key: 'time.now', num: 0 }, interval: null } }, computed: { - localeDateString () { - const browserLocale = localeService.internalToBrowserLocale(this.$i18n.locale) + shouldUseAbsoluteTimeFormat () { + if (!this.$store.getters.mergedConfig.useAbsoluteTimeFormat) { + return false + } + return DateUtils.durationStrToMs(this.$store.getters.mergedConfig.absoluteTimeFormatMinAge) <= this.relativeTimeMs + }, + browserLocale () { + return localeService.internalToBrowserLocale(this.$i18n.locale) + }, + timeAsDate () { return typeof this.time === 'string' - ? new Date(Date.parse(this.time)).toLocaleString(browserLocale) - : this.time.toLocaleString(browserLocale) + ? new Date(Date.parse(this.time)) + : this.time + }, + localeDateString () { + return this.timeAsDate.toLocaleString(this.browserLocale) }, relativeTimeString () { const timeString = this.$i18n.tc(this.relativeTime.key, this.relativeTime.num, [this.relativeTime.num]) @@ -35,6 +47,40 @@ export default { } return timeString + }, + absoluteTimeString () { + if (this.longFormat) { + return this.localeDateString + } + const now = new Date() + const formatter = (() => { + if (DateUtils.isSameDay(this.timeAsDate, now)) { + return new Intl.DateTimeFormat(this.browserLocale, { + minute: 'numeric', + hour: 'numeric' + }) + } else if (DateUtils.isSameMonth(this.timeAsDate, now)) { + return new Intl.DateTimeFormat(this.browserLocale, { + hour: 'numeric', + day: 'numeric' + }) + } else if (DateUtils.isSameYear(this.timeAsDate, now)) { + return new Intl.DateTimeFormat(this.browserLocale, { + month: 'short', + day: 'numeric' + }) + } else { + return new Intl.DateTimeFormat(this.browserLocale, { + year: 'numeric', + month: 'short' + }) + } + })() + + return formatter.format(this.timeAsDate) + }, + relativeOrAbsoluteTimeString () { + return this.shouldUseAbsoluteTimeFormat ? this.absoluteTimeString : this.relativeTimeString } }, watch: { @@ -54,6 +100,7 @@ export default { methods: { refreshRelativeTimeObject () { const nowThreshold = typeof this.nowThreshold === 'number' ? this.nowThreshold : 1 + this.relativeTimeMs = DateUtils.relativeTimeMs(this.time) this.relativeTime = this.longFormat ? DateUtils.relativeTime(this.time, nowThreshold) : DateUtils.relativeTimeShort(this.time, nowThreshold) -- cgit v1.2.3-70-g09d2