/* * vim: ts=4:sw=4:expandtab */ (function () { 'use strict'; window.Whisper = window.Whisper || {}; Whisper.TimestampView = Whisper.View.extend({ initialize: function() { extension.windows.onClosed(this.clearTimeout.bind(this)); }, update: function() { this.clearTimeout(); var millis_now = Date.now(); var millis = this.$el.data('timestamp'); if (millis >= millis_now) { millis = millis_now; } // defined in subclass! var result = this.getRelativeTimeSpanString(millis); this.$el.text(result); var millis_since = millis_now - millis; var delay = this.computeDelay(millis_since); if (delay) { if (delay < 0) { delay = 1000; } this.timeout = setTimeout(this.update.bind(this), delay); } }, clearTimeout: function() { clearTimeout(this.timeout); }, computeDelay: function(millis_since) { var delay; if (millis_since <= moment.relativeTimeThreshold('s') * 1000) { // a few seconds ago delay = 45 * 1000 - millis_since; } else if (millis_since <= moment.relativeTimeThreshold('m') * 1000 * 60) { // N minutes ago delay = 60 * 1000; } else if (millis_since <= moment.relativeTimeThreshold('h') * 1000 * 60 * 60) { // N hours ago delay = 60 * 60 * 1000; } else { // more than a week ago // Day of week + time delay = 7 * 24 * 60 * 60 * 1000 - millis_since; if (delay < -(60 * 1000)) { // more than one week and one minute ago // don't do any further updates as the displayed timestamp // won't change any more return; } } return delay; } }); Whisper.BriefTimestampView = Whisper.TimestampView.extend({ getRelativeTimeSpanString: function(timestamp_) { // Convert to moment timestamp if it isn't already var timestamp = moment(timestamp_), timediff = moment.duration(moment() - timestamp); // Do some wrapping to match conversation view, display >= 30 minutes (seconds) // as a full hour (minute) if the number of hours (minutes) isn't zero if (timediff.hours >= 1 && timediff.minutes() >= 30) { timediff.add(1, 'hours'); } else if (timediff.minutes() >= 1 && timediff.seconds() >= 30) { timediff.add(1, 'minutes'); } if (timediff.years() > 0) { return timestamp.format('MMM D, YYYY'); } else if (timediff.months() > 0 || timediff.days() > 6) { return timestamp.format('MMM D'); } else if (timediff.days() > 0) { return timestamp.format('ddd'); } else if (timediff.hours() > 1) { return timediff.hours() + ' hours'; } else if (timediff.hours() === 1 || timediff.minutes() >= 45) { // to match conversation view, display >= 45 minutes as 1 hour return '1 hour'; } else if (timediff.minutes() > 1) { return timediff.minutes() + ' min'; } else if (timediff.minutes() === 1 || timediff.seconds() >= 45) { // same as hours/minutes, 0:00:45 -> 1 min return '1 min'; } else { return 'now'; } }, }); Whisper.ExtendedTimestampView = Whisper.TimestampView.extend({ getRelativeTimeSpanString: function(timestamp_) { var timestamp = moment(timestamp_), now = moment(), lastWeek = moment().subtract(7, 'days'), lastYear = moment().subtract(1, 'years'); if (timestamp > now.startOf('day')) { // t units ago return timestamp.fromNow(); } else if (timestamp > lastWeek) { // Fri 1:30 PM or Fri 13:30 return timestamp.format('ddd ') + timestamp.format('LT'); } else if (timestamp > lastYear) { // Oct 31 1:30 PM or Oct 31 return timestamp.format('MMM D ') + timestamp.format('LT'); } else { // Oct 31, 2012 1:30 PM return timestamp.format('MMM D, YYYY ') + timestamp.format('LT'); } }, }); })();