Merge pull request #4281 from Ruxton/feature/use_rails_timeago_gem_instead_of_vendored_js
Switched to using rails-timeago to make keeping on top of new versions o...
This commit is contained in:
commit
0e291fd9c4
16 changed files with 38 additions and 173 deletions
|
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
## Bug fixes
|
## Bug fixes
|
||||||
|
|
||||||
|
Improve time agos by updating the plugin [#4280](https://github.com/diaspora/diaspora/issues/4280)
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
# 0.3.0.0
|
# 0.3.0.0
|
||||||
|
|
|
||||||
3
Gemfile
3
Gemfile
|
|
@ -129,6 +129,8 @@ group :assets do
|
||||||
gem 'handlebars_assets', '0.12.0'
|
gem 'handlebars_assets', '0.12.0'
|
||||||
gem 'jquery-rails', '2.1.4'
|
gem 'jquery-rails', '2.1.4'
|
||||||
|
|
||||||
|
gem 'rails-timeago'
|
||||||
|
|
||||||
# Windows and OSX have an execjs compatible runtime built-in, Linux users should
|
# Windows and OSX have an execjs compatible runtime built-in, Linux users should
|
||||||
# install Node.js or use 'therubyracer'.
|
# install Node.js or use 'therubyracer'.
|
||||||
#
|
#
|
||||||
|
|
@ -172,7 +174,6 @@ group :development do
|
||||||
gem 'rmagick', '2.13.2', :require => false
|
gem 'rmagick', '2.13.2', :require => false
|
||||||
|
|
||||||
# Automatic test runs
|
# Automatic test runs
|
||||||
|
|
||||||
gem 'guard-cucumber', '1.4.1'
|
gem 'guard-cucumber', '1.4.1'
|
||||||
gem 'guard-rspec', '4.2.4'
|
gem 'guard-rspec', '4.2.4'
|
||||||
gem 'rb-fsevent', '0.9.4', :require => false
|
gem 'rb-fsevent', '0.9.4', :require => false
|
||||||
|
|
|
||||||
|
|
@ -42,12 +42,12 @@ GEM
|
||||||
activemodel
|
activemodel
|
||||||
fog (>= 1.8.0)
|
fog (>= 1.8.0)
|
||||||
atomic (1.1.14)
|
atomic (1.1.14)
|
||||||
bcrypt-ruby (3.1.2)
|
|
||||||
backbone-on-rails (1.1.0.0)
|
backbone-on-rails (1.1.0.0)
|
||||||
eco
|
eco
|
||||||
ejs
|
ejs
|
||||||
jquery-rails
|
jquery-rails
|
||||||
rails (>= 3.1)
|
rails (>= 3.1)
|
||||||
|
bcrypt-ruby (3.1.2)
|
||||||
bootstrap-sass (2.2.2.0)
|
bootstrap-sass (2.2.2.0)
|
||||||
sass (~> 3.2)
|
sass (~> 3.2)
|
||||||
builder (3.0.4)
|
builder (3.0.4)
|
||||||
|
|
@ -306,6 +306,9 @@ GEM
|
||||||
railties (= 3.2.16)
|
railties (= 3.2.16)
|
||||||
rails-i18n (0.7.4)
|
rails-i18n (0.7.4)
|
||||||
i18n (~> 0.5)
|
i18n (~> 0.5)
|
||||||
|
rails-timeago (2.4.0)
|
||||||
|
actionpack (>= 3.1)
|
||||||
|
activesupport (>= 3.1)
|
||||||
rails_admin (0.4.9)
|
rails_admin (0.4.9)
|
||||||
bootstrap-sass (~> 2.2)
|
bootstrap-sass (~> 2.2)
|
||||||
builder (~> 3.0)
|
builder (~> 3.0)
|
||||||
|
|
@ -498,6 +501,7 @@ DEPENDENCIES
|
||||||
rack-ssl (= 1.3.3)
|
rack-ssl (= 1.3.3)
|
||||||
rails (= 3.2.16)
|
rails (= 3.2.16)
|
||||||
rails-i18n (= 0.7.4)
|
rails-i18n (= 0.7.4)
|
||||||
|
rails-timeago
|
||||||
rails_admin (= 0.4.9)
|
rails_admin (= 0.4.9)
|
||||||
rails_autolink (= 1.1.5)
|
rails_autolink (= 1.1.5)
|
||||||
rb-fsevent (= 0.9.4)
|
rb-fsevent (= 0.9.4)
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
//= require jquery-ui-1.8.9.custom.min
|
//= require jquery-ui-1.8.9.custom.min
|
||||||
//= require jquery.charcount
|
//= require jquery.charcount
|
||||||
//= require jquery.placeholder
|
//= require jquery.placeholder
|
||||||
//= require timeago
|
//= require rails-timeago
|
||||||
//= require facebox
|
//= require facebox
|
||||||
//= require jquery.events.input
|
//= require jquery.events.input
|
||||||
//= require jquery.elastic
|
//= require jquery.elastic
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,15 @@
|
||||||
|
|
||||||
this.subscribe("widget/ready", function() {
|
this.subscribe("widget/ready", function() {
|
||||||
if(Diaspora.I18n.language !== "en") {
|
if(Diaspora.I18n.language !== "en") {
|
||||||
$.each($.timeago.settings.strings, function(index) {
|
$.timeago.settings.lang = Diaspora.I18n.language;
|
||||||
$.timeago.settings.strings[index] = Diaspora.I18n.t("timeago." + index);
|
$.timeago.settings.strings[Diaspora.I18n.language] = {}
|
||||||
|
$.each($.timeago.settings.strings["en"], function(index) {
|
||||||
|
if(index == "numbers") {
|
||||||
|
$.timeago.settings.strings[Diaspora.I18n.language][index] = [];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$.timeago.settings.strings[Diaspora.I18n.language][index] = Diaspora.I18n.t("timeago." + index);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -17,13 +17,8 @@ module ApplicationHelper
|
||||||
url
|
url
|
||||||
end
|
end
|
||||||
|
|
||||||
def how_long_ago(obj)
|
|
||||||
timeago(obj.created_at)
|
|
||||||
end
|
|
||||||
|
|
||||||
def timeago(time, options={})
|
def timeago(time, options={})
|
||||||
options[:class] ||= "timeago"
|
timeago_tag(time, options.merge(:title => time.iso8601)) if time
|
||||||
content_tag(:abbr, time.to_s, options.merge(:title => time.iso8601)) if time
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def bookmarklet
|
def bookmarklet
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,8 @@
|
||||||
= person_image_link(comment.author)
|
= person_image_link(comment.author)
|
||||||
= person_link(comment.author)
|
= person_link(comment.author)
|
||||||
.info
|
.info
|
||||||
%span.time.timeago{:datetime => comment.created_at}
|
%span
|
||||||
= comment.created_at ? time_ago_in_words(comment.created_at) : time_ago_in_words(Time.now)
|
= timeago(comment.created_at ? comment.created_at : Time.now)
|
||||||
|
|
||||||
%div{:class => direction_for(comment.text)}
|
%div{:class => direction_for(comment.text)}
|
||||||
= markdownify(comment)
|
= markdownify(comment)
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,8 @@
|
||||||
.subject
|
.subject
|
||||||
%div{ :class => direction_for(conversation.subject) }
|
%div{ :class => direction_for(conversation.subject) }
|
||||||
= conversation.subject
|
= conversation.subject
|
||||||
%time.timeago.timestamp{:datetime => conversation.updated_at.iso8601}
|
.timestamp
|
||||||
= t('ago', :time => time_ago_in_words(conversation.updated_at))
|
= timeago(conversation.updated_at)
|
||||||
.last_author
|
.last_author
|
||||||
- if authors[conversation.id].present?
|
- if authors[conversation.id].present?
|
||||||
= authors[conversation.id].name
|
= authors[conversation.id].name
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
.last_author
|
.last_author
|
||||||
.timestamp
|
.timestamp
|
||||||
= t('ago', :time => time_ago_in_words(conversation.updated_at))
|
= timeago(conversation.updated_at)
|
||||||
|
|
||||||
- if authors[conversation.id].present?
|
- if authors[conversation.id].present?
|
||||||
= authors[conversation.id].name
|
= authors[conversation.id].name
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,7 @@
|
||||||
= person_image_link(message.author, :size => :thumb_small)
|
= person_image_link(message.author, :size => :thumb_small)
|
||||||
.bd
|
.bd
|
||||||
= person_link(message.author, :class => 'author from')
|
= person_link(message.author, :class => 'author from')
|
||||||
%time.timeago{:datetime => message.created_at.iso8601}
|
= timeago(message.created_at)
|
||||||
= t('ago', :time => time_ago_in_words(message.created_at))
|
|
||||||
|
|
||||||
%div{ :class => direction_for(message.text) }
|
%div{ :class => direction_for(message.text) }
|
||||||
= markdownify(message, :oembed => true)
|
= markdownify(message, :oembed => true)
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,5 @@
|
||||||
= person_image_tag n.actors.first, :thumb_small
|
= person_image_tag n.actors.first, :thumb_small
|
||||||
= notification_message_for(n)
|
= notification_message_for(n)
|
||||||
%div
|
%div
|
||||||
%time
|
|
||||||
= timeago(n.created_at)
|
= timeago(n.created_at)
|
||||||
= link_to t('notifications.index.mark_unread'), "#", :class => "unread-setter"
|
= link_to t('notifications.index.mark_unread'), "#", :class => "unread-setter"
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,6 @@
|
||||||
= person_image_tag note.actors.first, :thumb_medium
|
= person_image_tag note.actors.first, :thumb_medium
|
||||||
= notification_message_for(note)
|
= notification_message_for(note)
|
||||||
%div
|
%div
|
||||||
%time
|
|
||||||
= timeago(note.created_at)
|
= timeago(note.created_at)
|
||||||
= link_to t('.mark_unread'), "#", :class => "unread-setter"
|
= link_to t('.mark_unread'), "#", :class => "unread-setter"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,6 @@
|
||||||
.from
|
.from
|
||||||
= notification_message_for(note)
|
= notification_message_for(note)
|
||||||
.time_notif
|
.time_notif
|
||||||
= time_ago_in_words(note.created_at)
|
= timeago(note.created_at)
|
||||||
|
|
||||||
= will_paginate @notifications, :renderer => WillPaginate::ActionView::BootstrapLinkRenderer
|
= will_paginate @notifications, :renderer => WillPaginate::ActionView::BootstrapLinkRenderer
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,9 @@
|
||||||
= person_image_link(photo.author, :size => :thumb_small)
|
= person_image_link(photo.author, :size => :thumb_small)
|
||||||
= person_link(photo.author)
|
= person_link(photo.author)
|
||||||
.info
|
.info
|
||||||
%span.time{:integer => photo.created_at.to_i}
|
%span
|
||||||
= link_to(t('ago', :time => time_ago_in_words(photo.created_at)), post_path(photo))
|
= link_to(post_path(photo)) do
|
||||||
|
= timeago(photo.created_at)
|
||||||
|
|
||||||
-if additional_photos && additional_photos.length > 1
|
-if additional_photos && additional_photos.length > 1
|
||||||
#photo_controls
|
#photo_controls
|
||||||
|
|
|
||||||
|
|
@ -11,8 +11,9 @@
|
||||||
= link_to(image_tag('deletelabel.png'), post_path(post), :method => :delete, :data => { :confirm => "#{t('are_you_sure')}" }, :class => "remove")
|
= link_to(image_tag('deletelabel.png'), post_path(post), :method => :delete, :data => { :confirm => "#{t('are_you_sure')}" }, :class => "remove")
|
||||||
|
|
||||||
.info
|
.info
|
||||||
%span.time{:integer => post.created_at.to_i}
|
%span
|
||||||
= link_to(t('ago', :time => time_ago_in_words(post.created_at)), post_path(post))
|
= link_to(post_path(post)) do
|
||||||
|
= timeago(post.created_at)
|
||||||
%span.via
|
%span.via
|
||||||
- if post.activity_streams?
|
- if post.activity_streams?
|
||||||
= t('shared.stream_element.via', :link => link_to("#{post.provider_display_name}", post.actor_url)).html_safe
|
= t('shared.stream_element.via', :link => link_to("#{post.provider_display_name}", post.actor_url)).html_safe
|
||||||
|
|
|
||||||
143
vendor/assets/javascripts/timeago.js
vendored
143
vendor/assets/javascripts/timeago.js
vendored
|
|
@ -1,143 +0,0 @@
|
||||||
|
|
||||||
/*
|
|
||||||
* timeago: a jQuery plugin, version: 0.9.2 (2010-09-14)
|
|
||||||
* @requires jQuery v1.2.3 or later
|
|
||||||
*
|
|
||||||
* Timeago is a jQuery plugin that makes it easy to support automatically
|
|
||||||
* updating fuzzy timestamps (e.g. "4 minutes ago" or "about 1 day ago").
|
|
||||||
*
|
|
||||||
* For usage and examples, visit:
|
|
||||||
* http://timeago.yarp.com/
|
|
||||||
*
|
|
||||||
* Licensed under the MIT:
|
|
||||||
* http://www.opensource.org/licenses/mit-license.php
|
|
||||||
*
|
|
||||||
* Copyright (c) 2008-2010, Ryan McGeary (ryanonjavascript -[at]- mcgeary [*dot*] org)
|
|
||||||
*/
|
|
||||||
(function($) {
|
|
||||||
$.timeago = function(timestamp) {
|
|
||||||
if (timestamp instanceof Date) return inWords(timestamp);
|
|
||||||
else if (typeof timestamp == "string") return inWords($.timeago.parse(timestamp));
|
|
||||||
else return inWords($.timeago.datetime(timestamp));
|
|
||||||
};
|
|
||||||
var $t = $.timeago;
|
|
||||||
|
|
||||||
$.extend($.timeago, {
|
|
||||||
settings: {
|
|
||||||
refreshMillis: 60000,
|
|
||||||
allowFuture: false,
|
|
||||||
strings: {
|
|
||||||
prefixAgo: null,
|
|
||||||
prefixFromNow: null,
|
|
||||||
suffixAgo: "ago",
|
|
||||||
suffixFromNow: "from now",
|
|
||||||
seconds: "less than a minute",
|
|
||||||
minute: "about a minute",
|
|
||||||
minutes: "%d minutes",
|
|
||||||
hour: "about an hour",
|
|
||||||
hours: "about %d hours",
|
|
||||||
day: "a day",
|
|
||||||
days: "%d days",
|
|
||||||
month: "about a month",
|
|
||||||
months: "%d months",
|
|
||||||
year: "about a year",
|
|
||||||
years: "%d years",
|
|
||||||
numbers: []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
inWords: function(distanceMillis) {
|
|
||||||
var $l = this.settings.strings;
|
|
||||||
var prefix = $l.prefixAgo;
|
|
||||||
var suffix = $l.suffixAgo;
|
|
||||||
if (this.settings.allowFuture) {
|
|
||||||
if (distanceMillis < 0) {
|
|
||||||
prefix = $l.prefixFromNow;
|
|
||||||
suffix = $l.suffixFromNow;
|
|
||||||
}
|
|
||||||
distanceMillis = Math.abs(distanceMillis);
|
|
||||||
}
|
|
||||||
|
|
||||||
var seconds = distanceMillis / 1000;
|
|
||||||
var minutes = seconds / 60;
|
|
||||||
var hours = minutes / 60;
|
|
||||||
var days = hours / 24;
|
|
||||||
var years = days / 365;
|
|
||||||
|
|
||||||
function substitute(stringOrFunction, number) {
|
|
||||||
var string = $.isFunction(stringOrFunction) ? stringOrFunction(number, distanceMillis) : stringOrFunction;
|
|
||||||
var value = ($l.numbers && $l.numbers[number]) || number;
|
|
||||||
return string.replace(/%d/i, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
var words = seconds < 45 && substitute($l.seconds, Math.round(seconds)) ||
|
|
||||||
seconds < 90 && substitute($l.minute, 1) ||
|
|
||||||
minutes < 45 && substitute($l.minutes, Math.round(minutes)) ||
|
|
||||||
minutes < 90 && substitute($l.hour, 1) ||
|
|
||||||
hours < 24 && substitute($l.hours, Math.round(hours)) ||
|
|
||||||
hours < 48 && substitute($l.day, 1) ||
|
|
||||||
days < 30 && substitute($l.days, Math.floor(days)) ||
|
|
||||||
days < 60 && substitute($l.month, 1) ||
|
|
||||||
days < 365 && substitute($l.months, Math.floor(days / 30)) ||
|
|
||||||
years < 2 && substitute($l.year, 1) ||
|
|
||||||
substitute($l.years, Math.floor(years));
|
|
||||||
|
|
||||||
return $.trim([prefix, words, suffix].join(" "));
|
|
||||||
},
|
|
||||||
parse: function(iso8601) {
|
|
||||||
var s = $.trim(iso8601);
|
|
||||||
s = s.replace(/\.\d\d\d+/,""); // remove milliseconds
|
|
||||||
s = s.replace(/-/,"/").replace(/-/,"/");
|
|
||||||
s = s.replace(/T/," ").replace(/Z/," UTC");
|
|
||||||
s = s.replace(/([\+-]\d\d)\:?(\d\d)/," $1$2"); // -04:00 -> -0400
|
|
||||||
return new Date(s);
|
|
||||||
},
|
|
||||||
datetime: function(elem) {
|
|
||||||
// jQuery's `is()` doesn't play well with HTML5 in IE
|
|
||||||
var isTime = $(elem).get(0).tagName.toLowerCase() == "time"; // $(elem).is("time");
|
|
||||||
var iso8601 = isTime ? $(elem).attr("datetime") : $(elem).attr("title");
|
|
||||||
return $t.parse(iso8601);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$.fn.timeago = function() {
|
|
||||||
var self = this;
|
|
||||||
self.each(refresh);
|
|
||||||
|
|
||||||
var $s = $t.settings;
|
|
||||||
if ($s.refreshMillis > 0) {
|
|
||||||
setInterval(function() { self.each(refresh); }, $s.refreshMillis);
|
|
||||||
}
|
|
||||||
return self;
|
|
||||||
};
|
|
||||||
|
|
||||||
function refresh() {
|
|
||||||
var data = prepareData(this);
|
|
||||||
if (!isNaN(data.datetime)) {
|
|
||||||
$(this).text(inWords(data.datetime));
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
function prepareData(element) {
|
|
||||||
element = $(element);
|
|
||||||
if (!element.data("timeago")) {
|
|
||||||
element.data("timeago", { datetime: $t.datetime(element) });
|
|
||||||
var text = $.trim(element.text());
|
|
||||||
if (text.length > 0) element.attr("title", text);
|
|
||||||
}
|
|
||||||
return element.data("timeago");
|
|
||||||
}
|
|
||||||
|
|
||||||
function inWords(date) {
|
|
||||||
return $t.inWords(distance(date));
|
|
||||||
}
|
|
||||||
|
|
||||||
function distance(date) {
|
|
||||||
return (new Date().getTime() - date.getTime());
|
|
||||||
}
|
|
||||||
|
|
||||||
// fix for IE6 suckage
|
|
||||||
document.createElement("abbr");
|
|
||||||
document.createElement("time");
|
|
||||||
})(jQuery);
|
|
||||||
|
|
||||||
Loading…
Reference in a new issue