mirror of
https://github.com/codeninjasllc/discourse.git
synced 2024-11-27 17:46:05 -05:00
automatically updating times for posts on topic
moved moment.js into localization file (we need to localize it) added helpers for date formatting use, moment().shortDate() moment().longDate() moment().shortDateNoYear()
This commit is contained in:
parent
6d85dc1724
commit
c2cfbce9ce
8 changed files with 65 additions and 22 deletions
|
@ -4,15 +4,10 @@ Discourse.Formatter = (function(){
|
||||||
relativeAgeMedium, relativeAgeMediumSpan, longDate, toTitleCase,
|
relativeAgeMedium, relativeAgeMediumSpan, longDate, toTitleCase,
|
||||||
shortDate;
|
shortDate;
|
||||||
|
|
||||||
var shortDateNoYearFormat = Ember.String.i18n("dates.short_date_no_year");
|
|
||||||
var longDateFormat = Ember.String.i18n("dates.long_date");
|
|
||||||
var shortDateFormat = Ember.String.i18n("dates.short_date");
|
|
||||||
|
|
||||||
shortDate = function(date){
|
shortDate = function(date){
|
||||||
return moment(date).format(shortDateFormat);
|
return moment(date).shortDate();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// http://stackoverflow.com/questions/196972/convert-string-to-title-case-with-javascript
|
// http://stackoverflow.com/questions/196972/convert-string-to-title-case-with-javascript
|
||||||
// TODO: locale support ?
|
// TODO: locale support ?
|
||||||
toTitleCase = function toTitleCase(str)
|
toTitleCase = function toTitleCase(str)
|
||||||
|
@ -23,14 +18,14 @@ Discourse.Formatter = (function(){
|
||||||
}
|
}
|
||||||
|
|
||||||
longDate = function(dt) {
|
longDate = function(dt) {
|
||||||
return moment(dt).format(longDateFormat);
|
return moment(dt).longDate();
|
||||||
};
|
};
|
||||||
|
|
||||||
updateRelativeAge = function(elems) {
|
updateRelativeAge = function(elems) {
|
||||||
// jQuery .each
|
// jQuery .each
|
||||||
elems.each(function(){
|
elems.each(function(){
|
||||||
var $this = $(this);
|
var $this = $(this);
|
||||||
$this.html(relativeAge(new Date($this.data('time')), $this.data('format')));
|
$this.html(relativeAge(new Date($this.data('time')), {format: $this.data('format'), wrapInSpan: false}));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -38,7 +33,17 @@ Discourse.Formatter = (function(){
|
||||||
options = options || {};
|
options = options || {};
|
||||||
var format = options.format || "tiny";
|
var format = options.format || "tiny";
|
||||||
|
|
||||||
return "<span class='relative-date' data-time='" + date.getTime() + "' data-format='" + format + "'>" + relativeAge(date, options) + "</span>";
|
var append = "";
|
||||||
|
|
||||||
|
if(format === 'medium') {
|
||||||
|
append = " date' title='" + longDate(date);
|
||||||
|
if(options.leaveAgo) {
|
||||||
|
format = 'medium-with-ago';
|
||||||
|
}
|
||||||
|
options.wrapInSpan = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return "<span class='relative-date" + append + "' data-time='" + date.getTime() + "' data-format='" + format + "'>" + relativeAge(date, options) + "</span>";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -139,7 +144,7 @@ Discourse.Formatter = (function(){
|
||||||
if ((new Date()).getFullYear() !== date.getFullYear()) {
|
if ((new Date()).getFullYear() !== date.getFullYear()) {
|
||||||
displayDate = shortDate(date);
|
displayDate = shortDate(date);
|
||||||
} else {
|
} else {
|
||||||
displayDate = moment(date).format(shortDateNoYearFormat);
|
displayDate = moment(date).shortDateNoYear();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
displayDate = relativeAgeMediumSpan(distance, leaveAgo);
|
displayDate = relativeAgeMediumSpan(distance, leaveAgo);
|
||||||
|
@ -160,6 +165,8 @@ Discourse.Formatter = (function(){
|
||||||
return relativeAgeTiny(date, options);
|
return relativeAgeTiny(date, options);
|
||||||
} else if (format === "medium") {
|
} else if (format === "medium") {
|
||||||
return relativeAgeMedium(date, options);
|
return relativeAgeMedium(date, options);
|
||||||
|
} else if (format === 'medium-with-ago') {
|
||||||
|
return relativeAgeMedium(date, _.extend(options, {format: 'medium', leaveAgo: true}));
|
||||||
}
|
}
|
||||||
|
|
||||||
return "UNKNOWN FORMAT";
|
return "UNKNOWN FORMAT";
|
||||||
|
|
|
@ -212,7 +212,7 @@ Handlebars.registerHelper('unboundAge', function(property, options) {
|
||||||
Handlebars.registerHelper('editDate', function(property, options) {
|
Handlebars.registerHelper('editDate', function(property, options) {
|
||||||
// autoupdating this is going to be painful
|
// autoupdating this is going to be painful
|
||||||
var date = new Date(Ember.Handlebars.get(this, property, options));
|
var date = new Date(Ember.Handlebars.get(this, property, options));
|
||||||
return new Handlebars.SafeString(Discourse.Formatter.relativeAge(date, {format: 'medium', leaveAgo: true, wrapInSpan: false}));
|
return new Handlebars.SafeString(Discourse.Formatter.autoUpdatingRelativeAge(date, {format: 'medium', leaveAgo: true, wrapInSpan: false}));
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -286,6 +286,6 @@ Handlebars.registerHelper('date', function(property, options) {
|
||||||
if (val) {
|
if (val) {
|
||||||
date = new Date(val);
|
date = new Date(val);
|
||||||
}
|
}
|
||||||
return new Handlebars.SafeString(Discourse.Formatter.relativeAge(date, {format: 'medium', leaveAgo: leaveAgo}));
|
return new Handlebars.SafeString(Discourse.Formatter.autoUpdatingRelativeAge(date, {format: 'medium', leaveAgo: leaveAgo}));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -8,9 +8,6 @@
|
||||||
en:
|
en:
|
||||||
js:
|
js:
|
||||||
dates:
|
dates:
|
||||||
short_date_no_year: "D MMM"
|
|
||||||
short_date: "D MMM, YYYY"
|
|
||||||
long_date: "MMMM D, YYYY h:mma"
|
|
||||||
tiny:
|
tiny:
|
||||||
half_a_minute: "< 1m"
|
half_a_minute: "< 1m"
|
||||||
less_than_x_seconds:
|
less_than_x_seconds:
|
||||||
|
|
|
@ -5,6 +5,10 @@
|
||||||
# http://yamllint.com/
|
# http://yamllint.com/
|
||||||
|
|
||||||
en:
|
en:
|
||||||
|
dates:
|
||||||
|
short_date_no_year: "D MMM"
|
||||||
|
short_date: "D MMM, YYYY"
|
||||||
|
long_date: "MMMM D, YYYY h:mma"
|
||||||
time:
|
time:
|
||||||
formats:
|
formats:
|
||||||
short: "%m-%d-%Y"
|
short: "%m-%d-%Y"
|
||||||
|
|
|
@ -18,11 +18,26 @@ module JsLocaleHelper
|
||||||
result = generate_message_format(message_formats, locale_str)
|
result = generate_message_format(message_formats, locale_str)
|
||||||
|
|
||||||
result << "I18n.translations = #{translations.to_json};\n"
|
result << "I18n.translations = #{translations.to_json};\n"
|
||||||
result << "I18n.locale = '#{locale_str}'\n"
|
result << "I18n.locale = '#{locale_str}';\n"
|
||||||
|
# loading moment here cause we must customize it
|
||||||
|
result << File.read("#{Rails.root}/lib/javascripts/moment.js")
|
||||||
result << moment_locale(locale_str)
|
result << moment_locale(locale_str)
|
||||||
|
result << moment_formats
|
||||||
result
|
result
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.moment_formats
|
||||||
|
result = ""
|
||||||
|
result << moment_format_function('short_date_no_year')
|
||||||
|
result << moment_format_function('short_date')
|
||||||
|
result << moment_format_function('long_date')
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.moment_format_function(name)
|
||||||
|
format = I18n.t("dates." << name)
|
||||||
|
result = "moment.fn.#{name.camelize(:lower)} = function(){ return this.format('#{format}'); };\n"
|
||||||
|
end
|
||||||
|
|
||||||
def self.moment_locale(locale_str)
|
def self.moment_locale(locale_str)
|
||||||
filename = Rails.root + "lib/javascript/moment_locale/#{locale_str}.js"
|
filename = Rails.root + "lib/javascript/moment_locale/#{locale_str}.js"
|
||||||
if File.exists?(filename)
|
if File.exists?(filename)
|
||||||
|
|
|
@ -85,12 +85,22 @@ describe("Discourse.Formatter", function() {
|
||||||
|
|
||||||
describe("autoUpdatingRelativeAge", function(){
|
describe("autoUpdatingRelativeAge", function(){
|
||||||
it("can format dates", function(){
|
it("can format dates", function(){
|
||||||
var d = new Date();
|
var d = moment().subtract('days',1).toDate();
|
||||||
|
|
||||||
var $elem = $(Discourse.Formatter.autoUpdatingRelativeAge(d));
|
var $elem = $(Discourse.Formatter.autoUpdatingRelativeAge(d));
|
||||||
|
|
||||||
expect($elem.data('format')).toBe("tiny");
|
expect($elem.data('format')).toBe("tiny");
|
||||||
expect($elem.data('time')).toBe(d.getTime());
|
expect($elem.data('time')).toBe(d.getTime());
|
||||||
|
|
||||||
|
$elem = $(Discourse.Formatter.autoUpdatingRelativeAge(d,{format: 'medium', leaveAgo: true}));
|
||||||
|
expect($elem.data('format')).toBe("medium-with-ago");
|
||||||
|
expect($elem.data('time')).toBe(d.getTime());
|
||||||
|
expect($elem.attr('title')).toBe(moment(d).longDate());
|
||||||
|
expect($elem.html()).toBe('1 day ago');
|
||||||
|
|
||||||
|
$elem = $(Discourse.Formatter.autoUpdatingRelativeAge(d,{format: 'medium'}));
|
||||||
|
expect($elem.data('format')).toBe("medium");
|
||||||
|
expect($elem.data('time')).toBe(d.getTime());
|
||||||
|
expect($elem.html()).toBe('1 day');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -105,6 +115,14 @@ describe("Discourse.Formatter", function() {
|
||||||
|
|
||||||
expect($elem.html()).toBe("2m");
|
expect($elem.html()).toBe("2m");
|
||||||
|
|
||||||
|
|
||||||
|
d = new Date();
|
||||||
|
$elem = $(Discourse.Formatter.autoUpdatingRelativeAge(d, {format: 'medium', leaveAgo: true}));
|
||||||
|
$elem.data('time', d.getTime() - 2 * 60 * 1000);
|
||||||
|
|
||||||
|
Discourse.Formatter.updateRelativeAge($elem);
|
||||||
|
|
||||||
|
expect($elem.html()).toBe("2 minutes ago");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
|
||||||
//= require env
|
//= require env
|
||||||
|
|
||||||
//= require ../../app/assets/javascripts/preload_store.js
|
//= require ../../app/assets/javascripts/preload_store.js
|
||||||
|
@ -13,16 +14,17 @@
|
||||||
//= require ../../app/assets/javascripts/external_production/ember.js
|
//= require ../../app/assets/javascripts/external_production/ember.js
|
||||||
//= require ../../app/assets/javascripts/external_production/group-helper.js
|
//= require ../../app/assets/javascripts/external_production/group-helper.js
|
||||||
|
|
||||||
|
//= require ../../app/assets/javascripts/locales/i18n
|
||||||
|
//= require ../../app/assets/javascripts/locales/date_locales.js
|
||||||
|
//= require ../../app/assets/javascripts/discourse/helpers/i18n_helpers
|
||||||
|
//= require ../../app/assets/javascripts/locales/en
|
||||||
|
//
|
||||||
// Pagedown customizations
|
// Pagedown customizations
|
||||||
//= require ../../app/assets/javascripts/pagedown_custom.js
|
//= require ../../app/assets/javascripts/pagedown_custom.js
|
||||||
|
|
||||||
// The rest of the externals
|
// The rest of the externals
|
||||||
//= require_tree ../../app/assets/javascripts/external
|
//= require_tree ../../app/assets/javascripts/external
|
||||||
|
|
||||||
//= require ../../app/assets/javascripts/locales/i18n
|
|
||||||
//= require ../../app/assets/javascripts/locales/date_locales.js
|
|
||||||
//= require ../../app/assets/javascripts/discourse/helpers/i18n_helpers
|
|
||||||
//= require ../../app/assets/javascripts/locales/en
|
|
||||||
//= require ../../app/assets/javascripts/discourse
|
//= require ../../app/assets/javascripts/discourse
|
||||||
|
|
||||||
// Stuff we need to load first
|
// Stuff we need to load first
|
||||||
|
|
Loading…
Reference in a new issue