From 67c7a06c2852d69cd01ff0a989cdf6090eb909dd Mon Sep 17 00:00:00 2001 From: lilia Date: Wed, 10 Aug 2016 11:33:56 -0700 Subject: [PATCH] Use momentjs for timestamp localization Let momentjs handle proper pluralization of relative times. This comes at the sacrifice of displaying 'minutes' in the conversation list timestamp rather than 'min'. Note that we don't use moment's fromNow instance method so as to preserve the rounding logic that matches the Android client. // FREEBIE --- _locales/en/messages.json | 36 ++++--------------------------- js/chromium.js | 9 +++++--- js/views/timestamp_view.js | 31 ++++++++++++-------------- test/views/timestamp_view_test.js | 2 +- 4 files changed, 25 insertions(+), 53 deletions(-) diff --git a/_locales/en/messages.json b/_locales/en/messages.json index 3255b252..ba3e56ee 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -310,43 +310,15 @@ "description": "Informational text displayed if a sync operation times out." }, "timestamp_s": { - "description": "Short or abbreviated timestamp for messages sent less than a minute ago. Displayed in the conversation list.", + "description": "Brief timestamp for messages sent less than a minute ago. Displayed in the conversation list and message bubble.", "message": "now" }, "timestamp_m": { - "description": "Short or abbreviated timestamp for messages sent a minute ago. Displayed in the conversation list.", - "message": "1 min" - }, - "timestamp_mm": { - "description": "Short or abbreviated timestamp for messages sent multiple minutes ago. Displayed in the conversation list.", - "message": "%d min" + "description": "Brief timestamp for messages sent about one minute ago. Displayed in the conversation list and message bubble.", + "message": "1 minute" }, "timestamp_h": { - "description": "Short or abbreviated timestamp for messages sent about an hour ago. Displayed in the conversation list.", + "description": "Brief timestamp for messages sent about one minute ago. Displayed in the conversation list and message bubble.", "message": "1 hour" - }, - "timestamp_hh": { - "description": "Short or abbreviated timestamp for messages sent multiple hours ago. Displayed in the conversation list.", - "message": "%d hours" - }, - "extendedTimestamp_s": { - "description": "Timestamp for messages sent less than a minute ago. Displayed in the message bubble.", - "message": "now" - }, - "extendedTimestamp_m": { - "description": "Timestamp for messages sent about a minute ago. Displayed in the message bubble.", - "message": "1 minute ago" - }, - "extendedTimestamp_mm": { - "description": "Timestamp for messages sent multiple minutes ago. Displayed in the message bubble.", - "message": "%d minutes ago" - }, - "extendedTimestamp_h": { - "description": "Timestamp for messages sent one hour ago. Displayed in the message bubble.", - "message": "1 hour ago" - }, - "extendedTimestamp_hh": { - "description": "Timestamp for messages sent multiple hours ago. Displayed in the message bubble.", - "message": "%d hours ago" } } diff --git a/js/chromium.js b/js/chromium.js index 87412124..39d7b5f3 100644 --- a/js/chromium.js +++ b/js/chromium.js @@ -169,9 +169,12 @@ return chrome.i18n.getMessage(message, substitutions); } }; - if (window.chrome && chrome.i18n) { - moment.locale(chrome.i18n.getUILanguage()); - } + i18n.getLocale = function() { + if (window.chrome && chrome.i18n) { + return chrome.i18n.getUILanguage(); + } + return 'en'; + }; window.textsecure = window.textsecure || {}; window.textsecure.registration = { diff --git a/js/views/timestamp_view.js b/js/views/timestamp_view.js index bb1999bd..3de8b515 100644 --- a/js/views/timestamp_view.js +++ b/js/views/timestamp_view.js @@ -5,6 +5,15 @@ 'use strict'; window.Whisper = window.Whisper || {}; + moment.updateLocale(i18n.getLocale(), { + relativeTime : { + s: i18n('timestamp_s') || 'now', + m: i18n('timestamp_m') || '1 minute', + h: i18n('timestamp_h') || '1 hour' + } + }); + moment.locale(i18n.getLocale()); + Whisper.TimestampView = Whisper.View.extend({ initialize: function(options) { extension.windows.onClosed(this.clearTimeout.bind(this)); @@ -50,13 +59,13 @@ return timestamp.format(this._format.d); } else if (timediff.hours() > 1) { this.delay = moment(timestamp).add(timediff.hours() + 1,'h').diff(moment()); - return this.relativeTime(timediff.hours(), 'hh'); + return this.relativeTime(timediff.hours(), 'h'); } else if (timediff.hours() === 1) { this.delay = moment(timestamp).add(timediff.hours() + 1,'h').diff(moment()); return this.relativeTime(timediff.hours(), 'h'); } else if (timediff.minutes() > 1) { this.delay = moment(timestamp).add(timediff.minutes() + 1,'m').diff(moment()); - return this.relativeTime(timediff.minutes(), 'mm'); + return this.relativeTime(timediff.minutes(), 'm'); } else if (timediff.minutes() === 1) { this.delay = moment(timestamp).add(timediff.minutes() + 1,'m').diff(moment()); return this.relativeTime(timediff.minutes(), 'm'); @@ -65,16 +74,10 @@ return this.relativeTime(timediff.seconds(), 's'); } }, - relativeTime : function (number, string, isFuture) { - var format = i18n("timestamp_"+string) || this._format[string]; - return format.replace(/%d/i, number); + relativeTime : function (number, string) { + return moment.duration(number, string).humanize(); }, _format: { - s: "now", - m: "1 min", - mm: "%d min", - h: "1 hour", - hh: "%d hours", y: "MMM D, YYYY", mo: "MMM D", d: "ddd" @@ -82,15 +85,9 @@ }); Whisper.ExtendedTimestampView = Whisper.TimestampView.extend({ relativeTime : function (number, string, isFuture) { - var format = i18n("extendedTimestamp_"+string) || this._format[string]; - return format.replace(/%d/i, number); + return moment.duration(-1 * number, string).humanize(string !== 's'); }, _format: { - s: "now", - m: "%d minute ago", - mm: "%d minutes ago", - h: "%d hour ago", - hh: "%d hours ago", y: "MMM D, YYYY LT", mo: "MMM D LT", d: "ddd LT" diff --git a/test/views/timestamp_view_test.js b/test/views/timestamp_view_test.js index 3615666e..bf426926 100644 --- a/test/views/timestamp_view_test.js +++ b/test/views/timestamp_view_test.js @@ -46,7 +46,7 @@ describe('TimestampView', function() { // check recent timestamps checkDiff(30, 'now', 'now'); // 30 seconds - checkDiff(40*60, '40 min', '40 minutes ago'); + checkDiff(40*60, '40 minutes', '40 minutes ago'); checkDiff(60*60, '1 hour', '1 hour ago'); checkDiff(125*60, '2 hours', '2 hours ago');