diff --git a/Guardfile b/Guardfile index 147f523cc2b..a3e3ef8b9c2 100644 --- a/Guardfile +++ b/Guardfile @@ -58,19 +58,21 @@ unless ENV["USING_AUTOSPEC"] end end -def message_bus - MessageBus::Instance.new.tap do |bus| - bus.site_id_lookup do - # this is going to be dev the majority of the time, if you have multisite configured in dev stuff may be different - "default" - end - end -end module ::Guard class AutoReload < ::Guard::Guard require File.dirname(__FILE__) + '/config/environment' + + def self.message_bus + MessageBus::Instance.new.tap do |bus| + bus.site_id_lookup do + # this is going to be dev the majority of the time, if you have multisite configured in dev stuff may be different + "default" + end + end + end + def run_on_change(paths) paths.map! do |p| hash = nil @@ -82,7 +84,7 @@ module ::Guard p = p.sub /^app\/assets\/stylesheets/, "assets" {name: p, hash: hash} end - message_bus.publish "/file-change", paths + self.class.message_bus.publish "/file-change", paths end def run_all @@ -93,7 +95,7 @@ end Thread.new do Listen.to('tmp/') do |modified,added,removed| modified.each do |m| - message_bus.publish "/file-change", ["refresh"] if m =~ /refresh_browser/ + Guard::AutoReload.message_bus.publish "/file-change", ["refresh"] if m =~ /refresh_browser/ end end end diff --git a/app/assets/javascripts/discourse.js b/app/assets/javascripts/discourse.js index 228db475c01..c619a7dcb18 100644 --- a/app/assets/javascripts/discourse.js +++ b/app/assets/javascripts/discourse.js @@ -141,6 +141,10 @@ Discourse = Ember.Application.createWithMixins({ xhr.setRequestHeader('X-CSRF-Token', csrfToken); } }); + + setInterval(function(){ + Discourse.Formatter.updateRelativeAge($('.relative-date')); + },60 * 1000); }, /** diff --git a/app/assets/javascripts/discourse/components/formatter.js b/app/assets/javascripts/discourse/components/formatter.js new file mode 100644 index 00000000000..a7152f51d77 --- /dev/null +++ b/app/assets/javascripts/discourse/components/formatter.js @@ -0,0 +1,68 @@ +Discourse.Formatter = (function(){ + var updateRelativeAge, autoUpdatingRelativeAge, relativeAge; + + updateRelativeAge = function(elems) { + elems.each(function(){ + var $this = $(this); + $this.html(relativeAge(new Date($this.data('time')), $this.data('format'))); + }); + }; + + autoUpdatingRelativeAge = function(date,options) { + options = options || {}; + var format = options.format || "tiny"; + + return "" + relativeAge(date, options) + ""; + }; + + // mostly lifted from rails with a few amendments + relativeAge = function(date, options) { + options = options || {}; + var format = options.format || "tiny"; + + var distance = Math.round((new Date() - date) / 1000); + var distance_in_minutes = Math.round(distance / 60.0); + + var formatted; + var t = function(key,opts){ + return Ember.String.i18n("dates." + format + "." + key, opts); + }; + + switch(true){ + + case(distance_in_minutes < 1): + formatted = t("less_than_x_minutes", {count: 1}); + break; + case(distance_in_minutes >= 1 && distance_in_minutes <= 44): + formatted = t("x_minutes", {count: distance_in_minutes}); + break; + case(distance_in_minutes >= 45 && distance_in_minutes <= 89): + formatted = t("about_x_hours", {count: 1}); + break; + case(distance_in_minutes >= 90 && distance_in_minutes <= 1439): + formatted = t("about_x_hours", {count: Math.round(distance_in_minutes / 60.0)}); + break; + case(distance_in_minutes >= 1440 && distance_in_minutes <= 2519): + formatted = t("x_days", {count: 1}); + break; + case(distance_in_minutes >= 2520 && distance_in_minutes <= 129599): + formatted = t("x_days", {count: Math.round(distance_in_minutes / 1440.0)}); + break; + case(distance_in_minutes >= 129600 && distance_in_minutes <= 525599): + formatted = t("x_months", {count: Math.round(distance_in_minutes / 43200.0)}); + break; + default: + var months = Math.round(distance_in_minutes / 43200.0); + if (months < 24) { + formatted = t("x_months", {count: months}); + } else { + formatted = t("over_x_years", {count: Math.round(months / 12.0)}); + } + break; + } + + return formatted; + }; + + return {relativeAge: relativeAge, autoUpdatingRelativeAge: autoUpdatingRelativeAge, updateRelativeAge: updateRelativeAge}; +})(); diff --git a/app/assets/javascripts/discourse/helpers/application_helpers.js b/app/assets/javascripts/discourse/helpers/application_helpers.js index 40a4fdf5391..6091aba78fb 100644 --- a/app/assets/javascripts/discourse/helpers/application_helpers.js +++ b/app/assets/javascripts/discourse/helpers/application_helpers.js @@ -173,11 +173,21 @@ Handlebars.registerHelper('avatar', function(user, options) { @for Handlebars **/ Handlebars.registerHelper('unboundDate', function(property, options) { - var dt; - dt = new Date(Ember.Handlebars.get(this, property, options)); + var dt = new Date(Ember.Handlebars.get(this, property, options)); return dt.format("long"); }); +/** + Live refreshing age helper + + @method unboundDate + @for Handlebars +**/ +Handlebars.registerHelper('unboundAge', function(property, options) { + var dt = new Date(Ember.Handlebars.get(this, property, options)); + return new Handlebars.SafeString(Discourse.Formatter.autoUpdatingRelativeAge(dt)); +}); + /** Display a date related to an edit of a post @@ -285,7 +295,7 @@ Handlebars.registerHelper('date', function(property, options) { } displayDate = humanized; if (!leaveAgo) { - displayDate = (dt.millisecondsAgo()).duration(); + displayDate = (dt.millisecondsAgo()).duration(); } } return new Handlebars.SafeString("" + displayDate + ""); diff --git a/app/assets/javascripts/discourse/templates/list/topic_list_item.js.handlebars b/app/assets/javascripts/discourse/templates/list/topic_list_item.js.handlebars index 5ab4f16640c..f03e659e238 100644 --- a/app/assets/javascripts/discourse/templates/list/topic_list_item.js.handlebars +++ b/app/assets/javascripts/discourse/templates/list/topic_list_item.js.handlebars @@ -63,14 +63,14 @@ {{#if bumped}}