simplify time_ago_date processing

there was a one-off unfudge calculation. meticulous manipulation of the
code gives almost the exact same implementation as
unfudgeDateForProfileTimezone, and whose only deviations appear to be
bugs.

however, doing that unfudge (whether adhoc or using
unfudgeDateForProfileTimezone) was only necessary and appropriate when
the date to parse didn't have TZ info embedded (which it sometimes, but
only sometimes, did).

to simplify, just embed a known ISO formatted timestamp in all
time_ago_date elements. then we can parse that and use if for
calculations without any unfudging.

but don't forget to fudge that date before formatting for display (title
attribute and displayed string when > 1 day old).

test-plan:
 - have a student in a course that's posted on a discussion in that
   course
 - as a teacher in that course whose profile timezone does not match the
   system timezone, view the student's course roster page
   (/course/x/users/y)
 - under "Recent Messages", confirm that the friendly timestamps on the
   right for the discussion entry is displayed according to the correct
   (profile) timezone
 - confirm the title attribute (hover) of the friendly timestamp is
   formatted in the profile timezone

Change-Id: Id3385d58a9da02e9ed991ebd59152ca3f5fbd280
Reviewed-on: https://gerrit.instructure.com/31591
Tested-by: Jenkins <jenkins@instructure.com>
Reviewed-by: Braden Anderson <banderson@instructure.com>
Product-Review: Jacob Fugal <jacob@instructure.com>
QA-Review: Jacob Fugal <jacob@instructure.com>
This commit is contained in:
Jacob Fugal 2013-09-25 15:16:44 -06:00
parent 95c1e68eac
commit e53d01da15
7 changed files with 19 additions and 42 deletions

View File

@ -19,11 +19,11 @@
<p>
<% if export.export_type == 'common_cartridge' %>
<%= t 'links.download', "Course Export from %{date}: *Click here to download*",
:date => "<span class=\"created_at time_ago_date\">#{datetime_string export.created_at}</span>".html_safe,
:date => "<span class=\"created_at time_ago_date\" data-timestamp=\"#{export.created_at.iso8601}\">#{datetime_string export.created_at}</span>".html_safe,
:wrapper => link_to('\1', export.attachment ? verified_file_download_url(export.attachment) : nil) %>
<% else %>
<%= t 'links.download_qti', "QTI Export from %{date}: *Click here to download*",
:date => "<span class=\"created_at time_ago_date\">#{datetime_string export.created_at}</span>".html_safe,
:date => "<span class=\"created_at time_ago_date\" data-timestamp=\"#{export.created_at.iso8601}\">#{datetime_string export.created_at}</span>".html_safe,
:wrapper => link_to('\1', export.attachment ? verified_file_download_url(export.attachment) : nil) %>
<% end %>
</p>

View File

@ -3,7 +3,7 @@
<div class="clearfix <%= 'read' if message_read %> <%= inbox_item.try_rescue(:item_asset_string) %> communication_message inbox_item <%= inbox_item.try_rescue(:asset_type).try_rescue(:underscore) %>" style="<%= hidden unless inbox_item %>" id="inbox_item_<%= inbox_item ? inbox_item.id : "blank" %>">
<div class="header">
<div class="post_date">
<span class="time_ago_date created_at" style="padding-right: 45px;"><%= datetime_string(inbox_item.try_rescue(:created_at)) || nbsp %></span>
<span class="time_ago_date created_at" data-timestamp="<%= inbox_item.try_rescue(:created_at).try_rescue(:iso8601) %>" style="padding-right: 45px;"><%= datetime_string(inbox_item.try_rescue(:created_at)) || nbsp %></span>
<a href="<%= inbox_item_path(inbox_item ? inbox_item.id : "{{ id }}") %>" class="delete_inbox_item_link no-hover" title="<%= t('links.title.remove_message', %{Remove this Message}) %>"><%= image_tag "delete_circle.png" %></a>
</div>
<div>

View File

@ -75,7 +75,7 @@
</td>
<td class="view_score"><%= access.corrected_view_score %></td>
<td class="participate_score"><%= access.participate_score %></td>
<td class="last_viewed time_ago_date"><%= datetime_string(access.last_access) %></td>
<td class="last_viewed time_ago_date" data-timestamp="<%= access.last_access.try_rescue(:iso8601) %>"><%= datetime_string(access.last_access) %></td>
</tr>
<% end %>
<tr class="access blank" style="display: none;">

View File

@ -51,7 +51,7 @@
</span>
</div>
<% end %>
<div class="post_date time_ago_date"><%= entry.try_rescue(:created_at).tap{|time| time && datetime_string(time)} %></div>
<div class="post_date time_ago_date" data-timestamp="<%= entry.try_rescue(:created_at).try_rescue(:iso8601) %>"><%= datetime_string(entry.try_rescue(:created_at)) || nbsp %></div>
<div class="clear"></div>
<% end %>
</div>

View File

@ -9,7 +9,7 @@
<div class="link_box">
<a href="<%= context_url(entry_context, :context_discussion_entry_url, entry ? entry.id : "{{ id }}") %>" class="delete_entry_link disabled_link"><%= image_tag "delete.png" %></a>
</div>
<div class="post_date time_ago_date"><%= datetime_string(entry.try_rescue(:created_at)) || nbsp %></div>
<div class="post_date time_ago_date" data-timestamp="<%= entry.try_rescue(:created_at).try_rescue(:iso8601) %>"><%= datetime_string(entry.try_rescue(:created_at)) || nbsp %></div>
<div class="clear"></div>
</div>
<div class="content">

View File

@ -2,7 +2,6 @@
id = user_note.new_record? ? 'user_note_blank' : "user_note_#{user_note.id}"
style = user_note.new_record? ? 'display: none;' : ''
creator = user_note.creator.try_rescue(:name) || nil
created_at = datetime_string(user_note.try_rescue(:created_at)) || nil
%>
<div id="<%= id %>" class="user_note communication_message" style="<%= style %>">
<div class="header clearfix">
@ -22,17 +21,15 @@
<div class="title subject">
<%= user_note.try_rescue(:title) || t(:no_title, "No Title") %>
</div>
<% if creator || created_at %>
<% if creator || user_note.created_at %>
<div class="sub_title creator_name">
<span class="created_at time_ago_date">
<% if creator && created_at %>
<%= t 'subheader', "%{creator} on %{created_at}", :creator => creator, :created_at => created_at %>
<% if creator && user_note.created_at %>
<%= t 'subheader', "%{creator} on %{created_at}", :creator => creator, :created_at => datetime_string(user_note.created_at) %>
<% elsif creator %>
<%= creator %>
<% elsif created_at %>
<% created_at %>
<% elsif user_note.created_at %>
<span class="created_at time_ago_date" data-timestamp="<%= user_note.created_at.iso8601 %>"><%= datetime_string user_note.created_at %></span>
<% end %>
</span>
</div>
<% end %>
</div>

View File

@ -22,7 +22,6 @@ define([
'i18n!instructure',
'jquery' /* $ */,
'underscore',
'timezone',
'compiled/userSettings',
'str/htmlEscape',
'wikiSidebar',
@ -32,7 +31,7 @@ define([
'jquery.doc_previews' /* filePreviewsEnabled, loadDocPreview */,
'jquery.dropdownList' /* dropdownList */,
'jquery.google-analytics' /* trackEvent */,
'jquery.instructure_date_and_time' /* parseFromISO, dateString */,
'jquery.instructure_date_and_time' /* parseFromISO, dateString, fudgeDateForProfileTimezone */,
'jquery.instructure_forms' /* formSubmit, fillFormData, formErrors */,
'jqueryui/dialog',
'jquery.instructure_misc_helpers' /* replaceTags, youTubeID */,
@ -54,7 +53,7 @@ define([
'compiled/badge_counts',
'vendor/scribd.view' /* scribd */,
'vendor/jquery.placeholder'
], function(KeyboardNavDialog, INST, I18n, $, _, tz, userSettings, htmlEscape, wikiSidebar) {
], function(KeyboardNavDialog, INST, I18n, $, _, userSettings, htmlEscape, wikiSidebar) {
$.trackEvent('Route', location.pathname.replace(/\/$/, '').replace(/\d+/g, '--') || '/');
@ -759,8 +758,7 @@ define([
// vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
// vvvvvvvvvvvvvvvvv BEGIN stuf form making pretty dates vvvvvvvvvvvvvvvvvv
// vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
var timeZoneOffset = tz.currentOffset() / -60,
timeAgoEvents = [];
var timeAgoEvents = [];
function timeAgoRefresh() {
timeAgoEvents = $(".time_ago_date:visible").toArray();
processNextTimeAgoEvent();
@ -769,31 +767,13 @@ define([
var eventElement = timeAgoEvents.shift();
if (eventElement) {
var $event = $(eventElement),
originalDate = $event.data('original_date') || "",
date = $event.data('parsed_date') || ( originalDate ?
Date.parse(originalDate.replace(/ (at|by)/, "")) :
Date.parse(($event.text() || "").replace(/ (at|by)/, "")) );
date = $event.data('parsed_date') || Date.parse($event.data('timestamp') || "");
if (date) {
var now = new Date();
now.setDate(now.getDate() + 1);
if (!originalDate && date > now && date - now > 3600000) {
var year = date.getUTCFullYear().toString();
if(date > now && date.getUTCFullYear() == now.getUTCFullYear() && !$event.text().match(year)) {
date.setUTCFullYear(date.getUTCFullYear() - 1);
}
}
var timeZoneDiff = now.getTimezoneOffset() - timeZoneOffset;
if(isNaN(timeZoneDiff)) { timeZoneDiff = 0; }
var diff = now - date + (timeZoneDiff * 60 * 1000);
$event.data('original_date', date.toString("MMM d, yyyy h:mmtt"));
var diff = new Date() - date;
$event.data('timestamp', date.toISOString());
$event.data('parsed_date', date);
// This line would compensate for a user who set their time zone to something
// different than the time zone setting on the current computer. It would adjust
// the times displayed to match the time zone of the current computer. This could
// be confusing for a student since due dates and things will NOT be adjusted,
// so dates and times will not match up.
// date = date.addMinutes(-1 * timeZoneDiff);
var defaultDateString = date.toString("MMM d, yyyy") + date.toString(" h:mmtt").toLowerCase();
var fudgedDate = $.fudgeDateForProfileTimezone(date);
var defaultDateString = fudgedDate.toString("MMM d, yyyy") + fudgedDate.toString(" h:mmtt").toLowerCase();
var dateString = defaultDateString;
if(diff < (24 * 3600 * 1000)) {
if(diff < (3600 * 1000)) {