From d559bfd0cf34b0cf2f51442cb909ee1b66303cf5 Mon Sep 17 00:00:00 2001 From: Toby Zerner Date: Mon, 2 Feb 2015 16:58:23 +1030 Subject: [PATCH] Make human-time live update --- .../core/ember/app/helpers/human-time.js | 29 +--- .../app/initializers/human-time-updater.js | 143 ++++++++++++++++++ framework/core/ember/app/utils/human-time.js | 42 +++++ 3 files changed, 191 insertions(+), 23 deletions(-) create mode 100644 framework/core/ember/app/initializers/human-time-updater.js create mode 100644 framework/core/ember/app/utils/human-time.js diff --git a/framework/core/ember/app/helpers/human-time.js b/framework/core/ember/app/helpers/human-time.js index c05e8d065..c45902c7f 100644 --- a/framework/core/ember/app/helpers/human-time.js +++ b/framework/core/ember/app/helpers/human-time.js @@ -1,31 +1,14 @@ import Ember from 'ember'; +import humanTime from '../utils/human-time'; + export default Ember.Handlebars.makeBoundHelper(function(time) { var m = moment(time); - var datetime = m.format(), - full = m.format('LLLL'); + var datetime = m.format(); + var full = m.format('LLLL'); - // var second = 1e3; - var minute = 6e4; - var hour = 36e5; - var day = 864e5; - // var week = 6048e5; - var ago = null; + var ago = humanTime(m); - var diff = Math.abs(m.diff(moment())); - - if (diff < 60 * minute) { - ago = moment.duration(diff).minutes()+'m ago'; - } else if (diff < 24 * hour) { - ago = moment.duration(diff).hours()+'h ago'; - } else if (diff < 30 * day) { - ago = moment.duration(diff).days()+'d ago'; - } else if (m.year() === moment().year()) { - ago = m.format('D MMM'); - } else { - ago = m.format('MMM \'YY'); - } - - return new Ember.Handlebars.SafeString(''); + return new Ember.Handlebars.SafeString(''); }); diff --git a/framework/core/ember/app/initializers/human-time-updater.js b/framework/core/ember/app/initializers/human-time-updater.js new file mode 100644 index 000000000..1b60c108c --- /dev/null +++ b/framework/core/ember/app/initializers/human-time-updater.js @@ -0,0 +1,143 @@ +import Ember from 'ember'; + +import humanTime from '../utils/human-time'; + +var $ = Ember.$; + +export default { + name: 'human-time-updater', + initialize: function(container) { + + // Livestamp.js / v1.1.2 / (c) 2012 Matt Bradley / MIT License + (function($, moment) { + var updateInterval = 1e3, + paused = false, + $livestamps = $([]), + + init = function() { + livestampGlobal.resume(); + }, + + prep = function($el, timestamp) { + var oldData = $el.data('livestampdata'); + if (typeof timestamp == 'number') + timestamp *= 1e3; + + $el.removeAttr('data-livestamp') + .removeData('livestamp'); + + timestamp = moment(timestamp); + if (moment.isMoment(timestamp) && !isNaN(+timestamp)) { + var newData = $.extend({ }, { 'original': $el.contents() }, oldData); + newData.moment = moment(timestamp); + + $el.data('livestampdata', newData).empty(); + $livestamps.push($el[0]); + } + }, + + run = function() { + if (paused) return; + livestampGlobal.update(); + setTimeout(run, updateInterval); + }, + + livestampGlobal = { + update: function() { + $('[data-humantime]').each(function() { + var $this = $(this); + prep($this, $this.attr('datetime')); + }); + + var toRemove = []; + $livestamps.each(function() { + var $this = $(this), + data = $this.data('livestampdata'); + + if (data === undefined) + toRemove.push(this); + else if (moment.isMoment(data.moment)) { + var from = $this.html(), + to = humanTime(data.moment); + // to = data.moment.fromNow(); + + if (from != to) { + var e = $.Event('change.livestamp'); + $this.trigger(e, [from, to]); + if (!e.isDefaultPrevented()) + $this.html(to); + } + } + }); + + $livestamps = $livestamps.not(toRemove); + }, + + pause: function() { + paused = true; + }, + + resume: function() { + paused = false; + run(); + }, + + interval: function(interval) { + if (interval === undefined) + return updateInterval; + updateInterval = interval; + } + }, + + livestampLocal = { + add: function($el, timestamp) { + if (typeof timestamp == 'number') + timestamp *= 1e3; + timestamp = moment(timestamp); + + if (moment.isMoment(timestamp) && !isNaN(+timestamp)) { + $el.each(function() { + prep($(this), timestamp); + }); + livestampGlobal.update(); + } + + return $el; + }, + + destroy: function($el) { + $livestamps = $livestamps.not($el); + $el.each(function() { + var $this = $(this), + data = $this.data('livestampdata'); + + if (data === undefined) + return $el; + + $this + .html(data.original ? data.original : '') + .removeData('livestampdata'); + }); + + return $el; + }, + + isLivestamp: function($el) { + return $el.data('livestampdata') !== undefined; + } + }; + + $.livestamp = livestampGlobal; + $(init); + $.fn.livestamp = function(method, options) { + if (!livestampLocal[method]) { + options = method; + method = 'add'; + } + + return livestampLocal[method](this, options); + }; + })(jQuery, moment); + + } +}; \ No newline at end of file diff --git a/framework/core/ember/app/utils/human-time.js b/framework/core/ember/app/utils/human-time.js new file mode 100644 index 000000000..e089d6d50 --- /dev/null +++ b/framework/core/ember/app/utils/human-time.js @@ -0,0 +1,42 @@ +import Ember from 'ember'; + +moment.locale('en', { + relativeTime : { + future: "in %s", + past: "%s ago", + s: "seconds", + m: "1m", + mm: "%dm", + h: "1h", + hh: "%dh", + d: "1d", + dd: "%dd", + M: "a month", + MM: "%d months", + y: "a year", + yy: "%d years" + } +}); + +export default function(time) { + var m = moment(time); + + var minute = 6e4; + var hour = 36e5; + var day = 864e5; + var ago = null; + + var diff = m.diff(moment()); + + if (diff < -30 * day) { + if (m.year() === moment().year()) { + ago = m.format('D MMM'); + } else { + ago = m.format('MMM \'YY'); + } + } else { + ago = m.fromNow(); + } + + return ago; +}; \ No newline at end of file