/* global moment: false */ /* global Whisper: false */ /* global extension: false */ /* global i18n: false */ /* global _: false */ // eslint-disable-next-line func-names (function() { 'use strict'; window.Whisper = window.Whisper || {}; function extendedRelativeTime(number, string) { return moment.duration(-1 * number, string).humanize(string !== 's'); } const extendedFormats = { y: 'lll', M: `${i18n('timestampFormat_M') || 'MMM D'} LT`, d: 'ddd LT', }; function shortRelativeTime(number, string) { return moment.duration(number, string).humanize(); } const shortFormats = { y: 'll', M: i18n('timestampFormat_M') || 'MMM D', d: 'ddd', }; function getRelativeTimeSpanString(rawTimestamp, options = {}) { _.defaults(options, { extended: false }); const relativeTime = options.extended ? extendedRelativeTime : shortRelativeTime; const formats = options.extended ? extendedFormats : shortFormats; // Convert to moment timestamp if it isn't already const timestamp = moment(rawTimestamp); const now = moment(); const timediff = moment.duration(now - timestamp); if (timediff.years() > 0) { return timestamp.format(formats.y); } else if (timediff.months() > 0 || timediff.days() > 6) { return timestamp.format(formats.M); } else if (timediff.days() > 0) { return timestamp.format(formats.d); } else if (timediff.hours() >= 1) { return relativeTime(timediff.hours(), 'h'); } else if (timediff.minutes() >= 1) { // Note that humanize seems to jump to '1 hour' as soon as we cross 45 minutes return relativeTime(timediff.minutes(), 'm'); } return relativeTime(timediff.seconds(), 's'); } Whisper.TimestampView = Whisper.View.extend({ initialize() { extension.windows.onClosed(this.clearTimeout.bind(this)); }, update() { this.clearTimeout(); const millisNow = Date.now(); let millis = this.$el.data('timestamp'); if (millis === '') { return; } if (millis >= millisNow) { millis = millisNow; } const result = this.getRelativeTimeSpanString(millis); this.delay = this.getDelay(millis); this.$el.text(result); const timestamp = moment(millis); this.$el.attr('title', timestamp.format('llll')); if (this.delay) { if (this.delay < 0) { this.delay = 1000; } this.timeout = setTimeout(this.update.bind(this), this.delay); } }, clearTimeout() { clearTimeout(this.timeout); }, getRelativeTimeSpanString(timestamp) { return getRelativeTimeSpanString(timestamp); }, getDelay(rawTimestamp) { // Convert to moment timestamp if it isn't already const timestamp = moment(rawTimestamp); const now = moment(); const timediff = moment.duration(now - timestamp); if (timediff.years() > 0) { return null; } else if (timediff.months() > 0 || timediff.days() > 6) { return null; } else if (timediff.days() > 0) { return moment(timestamp) .add(timediff.days() + 1, 'd') .diff(now); } else if (timediff.hours() >= 1) { return moment(timestamp) .add(timediff.hours() + 1, 'h') .diff(now); } else if (timediff.minutes() >= 1) { return moment(timestamp) .add(timediff.minutes() + 1, 'm') .diff(now); } return moment(timestamp) .add(1, 'm') .diff(now); }, }); Whisper.ExtendedTimestampView = Whisper.TimestampView.extend({ getRelativeTimeSpanString(timestamp) { return getRelativeTimeSpanString(timestamp, { extended: true }); }, }); })();