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