|  |  |  | /* | 
					
						
							|  |  |  |  * 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 === "") { | 
					
						
							|  |  |  |                 return; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             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'); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         }, | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | })(); |