mirror of https://github.com/zulip/zulip.git
Render recent dates as weekdays, part 2.
This commit does the actual work of formatting recent dates as weekday names and updating the format when the date is sufficiently far in the past. Also, silence a bogus jslint warning. (imported from commit 503286fbd9c1e33a81cc7d78cf8d08d5e7f78c1a)
This commit is contained in:
parent
59dab21fcd
commit
61350d65d1
|
@ -114,6 +114,10 @@ var exceptions = {
|
|||
|
||||
"Unexpected 'else' after 'return'." : function () {
|
||||
return true;
|
||||
},
|
||||
|
||||
"Don't make functions within a loop." : function () {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -2,16 +2,123 @@ var timerender = (function () {
|
|||
|
||||
var exports = {};
|
||||
|
||||
// If this is 5, then times from up to 5 days before the current
|
||||
// day will be formatted as weekday names:
|
||||
//
|
||||
// 1/10 1/11 1/12
|
||||
// Sun Mon Tue Wed Thu 1/18 1/19
|
||||
// ^ today
|
||||
var MAX_AGE_FOR_WEEKDAY = 5;
|
||||
|
||||
var next_timerender_id = 0;
|
||||
|
||||
var set_to_start_of_day = function (time) {
|
||||
return time.setMilliseconds(0).setSeconds(0).setMinutes(0).setHours(0);
|
||||
};
|
||||
|
||||
function now() { return (new XDate()); }
|
||||
|
||||
// Given an XDate object 'time', return a two-element list containing
|
||||
// - a string for the current human-formatted version
|
||||
// - a string like "2013-01-20" representing the day the format
|
||||
// needs to change, or null if it will never need to change.
|
||||
function render_now(time) {
|
||||
var start_of_today = set_to_start_of_day(now());
|
||||
var start_of_other_day = set_to_start_of_day(time.clone());
|
||||
|
||||
// How many days old is 'time'? 0 = today, 1 = yesterday, 7 = a
|
||||
// week ago, -1 = tomorrow, etc.
|
||||
|
||||
// Presumably the result of diffDays will be an integer in this
|
||||
// case, but round it to be sure before comparing to an integer
|
||||
// constant.
|
||||
var days_old = Math.round(start_of_other_day.diffDays(start_of_today));
|
||||
|
||||
if (days_old >= 0 && days_old <= MAX_AGE_FOR_WEEKDAY)
|
||||
// "\xa0" is U+00A0 NO-BREAK SPACE.
|
||||
// Can't use as that represents the literal string " ".
|
||||
return [time.toString("ddd") + "\xa0" + time.toString("HH:mm"),
|
||||
start_of_other_day.addDays(MAX_AGE_FOR_WEEKDAY+1)
|
||||
.toString("yyyy-MM-dd")];
|
||||
else {
|
||||
// For now, if we get a message from tomorrow, we don't bother
|
||||
// rewriting the timestamp when it gets to be tomorrow.
|
||||
return [time.toString("MMM dd") + "\xa0\xa0" + time.toString("HH:mm"),
|
||||
undefined];
|
||||
}
|
||||
}
|
||||
|
||||
// This table associates to each day (represented as a yyyy-MM-dd
|
||||
// string) a list of timestamps that need to be updated on that day.
|
||||
// Each timestamp is represented as a list of length 2:
|
||||
// [id of the span element, XDate representing the time]
|
||||
|
||||
// This is an efficient data structure because we only need to update
|
||||
// timestamps at the start of each day. If timestamp update times were
|
||||
// arbitrary, a priority queue would be more sensible.
|
||||
var update_table = {};
|
||||
|
||||
// The day that elements are currently up-to-date with respect to.
|
||||
// Represented as an XDate with hour, minute, second, millisecond 0.
|
||||
var last_updated = set_to_start_of_day(now());
|
||||
|
||||
function maybe_add_update_table_entry(update_date, id, time) {
|
||||
if (update_date === undefined)
|
||||
return;
|
||||
if (update_table[update_date] === undefined)
|
||||
update_table[update_date] = [];
|
||||
update_table[update_date].push([id, time]);
|
||||
}
|
||||
|
||||
// Given an XDate object 'time', return a DOM node that initially
|
||||
// displays the human-formatted time, and is updated automatically as
|
||||
// necessary (e.g. changing "Mon 11:21" to "Jan 14 11:21" after a week
|
||||
// or so).
|
||||
|
||||
// (But for now it just returns a static node.)
|
||||
exports.render_time = function(time) {
|
||||
// Wrap the text in a span because (oddly) a text node has no outerHTML attribute.
|
||||
return $("<span />").text(time.toString("MMM dd") + "\xa0\xa0" + time.toString("HH:mm"));
|
||||
// (What's actually spliced into the message template is the contents
|
||||
// of this DOM node as HTML, so effectively a copy of the node. That's
|
||||
// okay since to update the time later we look up the node by its id.)
|
||||
exports.render_time = function (time) {
|
||||
var id = "timerender" + next_timerender_id;
|
||||
next_timerender_id++;
|
||||
var rendered_now = render_now(time);
|
||||
var node = $("<span />").attr('id', id).text(rendered_now[0]);
|
||||
maybe_add_update_table_entry(rendered_now[1], id, time);
|
||||
return node;
|
||||
};
|
||||
|
||||
setInterval(function () {
|
||||
var start_of_today = set_to_start_of_day(now());
|
||||
var new_date;
|
||||
// This loop won't do anything unless the day changed since the
|
||||
// last time it ran.
|
||||
for (new_date = last_updated.clone().addDays(1);
|
||||
new_date <= start_of_today;
|
||||
new_date.addDays(1)) {
|
||||
var update_date = new_date.toString("yyyy-MM-dd");
|
||||
if (update_table[update_date] !== undefined)
|
||||
{
|
||||
var to_process = update_table[update_date];
|
||||
var i;
|
||||
update_table[update_date] = [];
|
||||
$.each(to_process, function (idx, elem) {
|
||||
var id = elem[0];
|
||||
var element = document.getElementById(id);
|
||||
// The element might not exist any more (because it
|
||||
// was in the zfilt table, or because we added
|
||||
// messages above it and re-collapsed).
|
||||
if (element !== null) {
|
||||
var time = elem[1];
|
||||
var new_rendered = render_now(time);
|
||||
$(document.getElementById(id)).text(new_rendered[0]);
|
||||
|
||||
maybe_add_update_table_entry(new_rendered[1], id, time);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
last_updated = start_of_today;
|
||||
}, 60 * 1000);
|
||||
|
||||
return exports;
|
||||
}());
|
||||
|
|
Loading…
Reference in New Issue