changeset 330:58467ce8f44a

leave timestamps as JS date objects instead of translating them into ms-since-epoch integers (and then translating them back before we use them for anything); in the process, handle null timestamp values in SnowlUtils:_formatDate instead of throwing an exception when we encounter one
author Myk Melez <myk@mozilla.org>
date Fri, 17 Oct 2008 17:30:25 -0700
parents e217720a7da8
children 00bcb31061f4
files content/list.js content/message/message.js content/river.js content/stream.js modules/collection.js modules/feed.js modules/message.js modules/twitter.js modules/utils.js
diffstat 9 files changed, 36 insertions(+), 72 deletions(-) [+]
line wrap: on
line diff
--- a/content/list.js	Thu Oct 16 19:11:46 2008 -0700
+++ b/content/list.js	Fri Oct 17 17:30:25 2008 -0700
@@ -133,7 +133,7 @@
       case "snowlSubjectCol":
         return this._collection.messages[aRow].subject;
       case "snowlTimestampCol":
-        return SnowlUtils._formatDate(new Date(this._collection.messages[aRow].timestamp));
+        return SnowlUtils._formatDate(this._collection.messages[aRow].timestamp);
       default:
         return null;
     }
--- a/content/message/message.js	Thu Oct 16 19:11:46 2008 -0700
+++ b/content/message/message.js	Fri Oct 17 17:30:25 2008 -0700
@@ -39,7 +39,9 @@
 const Cr = Components.results;
 const Cu = Components.utils;
 
+// modules that are Snowl-specific
 Cu.import("resource://snowl/modules/message.js");
+Cu.import("resource://snowl/modules/utils.js");
 
 const XML_NS = "http://www.w3.org/XML/1998/namespace"
 const XUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
@@ -76,65 +78,6 @@
 document.getElementById("author").value = message.author;
 document.getElementById("subject").value = message.subject;
 document.documentElement.setAttribute("title", message.subject);
-document.getElementById("timestamp").value = formatTimestamp(new Date(message.timestamp));
+document.getElementById("timestamp").value = SnowlUtils._formatDate(message.timestamp);
 document.getElementById("link").href = message.link;
 document.getElementById("link").value = message.link;
-
-// FIXME: put this into a SnowlUtils module.
-
-/**
- * Formats a timestamp for human consumption using the date formatting service
- * for locale-specific formatting along with some additional smarts for more
- * human-readable representations of recent timestamps.
- * @param   {Date} the timestamp to format
- * @returns a human-readable string
- */
-function formatTimestamp(aTimestamp) {
-  let formattedString;
-
-  let dfSvc = Cc["@mozilla.org/intl/scriptabledateformat;1"].
-              getService(Ci.nsIScriptableDateFormat);
-
-  let now = new Date();
-
-  let yesterday = new Date(now - 24 * 60 * 60 * 1000);
-  yesterday = new Date(yesterday.getFullYear(), yesterday.getMonth(), yesterday.getDate());
-
-  let sixDaysAgo = new Date(now - 6 * 24 * 60 * 60 * 1000);
-  sixDaysAgo = new Date(sixDaysAgo.getFullYear(), sixDaysAgo.getMonth(), sixDaysAgo.getDate());
-
-  if (aTimestamp.toLocaleDateString() == now.toLocaleDateString())
-    formattedString = dfSvc.FormatTime("",
-                                             dfSvc.timeFormatNoSeconds,
-                                             aTimestamp.getHours(),
-                                             aTimestamp.getMinutes(),
-                                             null);
-  else if (aTimestamp > yesterday)
-    formattedString = "Yesterday " + dfSvc.FormatTime("",
-                                                            dfSvc.timeFormatNoSeconds,
-                                                            aTimestamp.getHours(),
-                                                            aTimestamp.getMinutes(),
-                                                            null);
-  else if (aTimestamp > sixDaysAgo)
-    formattedString = dfSvc.FormatDateTime("",
-                                                 dfSvc.dateFormatWeekday, 
-                                                 dfSvc.timeFormatNoSeconds,
-                                                 aTimestamp.getFullYear(),
-                                                 aTimestamp.getMonth() + 1,
-                                                 aTimestamp.getDate(),
-                                                 aTimestamp.getHours(),
-                                                 aTimestamp.getMinutes(),
-                                                 aTimestamp.getSeconds());
-  else
-    formattedString = dfSvc.FormatDateTime("",
-                                                 dfSvc.dateFormatShort, 
-                                                 dfSvc.timeFormatNoSeconds,
-                                                 aTimestamp.getFullYear(),
-                                                 aTimestamp.getMonth() + 1,
-                                                 aTimestamp.getDate(),
-                                                 aTimestamp.getHours(),
-                                                 aTimestamp.getMinutes(),
-                                                 aTimestamp.getSeconds());
-
-  return formattedString;
-}
--- a/content/river.js	Thu Oct 16 19:11:46 2008 -0700
+++ b/content/river.js	Fri Oct 17 17:30:25 2008 -0700
@@ -41,11 +41,14 @@
 const Cr = Components.results;
 const Cu = Components.utils;
 
+// modules that come with Firefox
 Cu.import("resource://gre/modules/XPCOMUtils.jsm");
 
+// modules that should come with Firefox
 Cu.import("resource://snowl/modules/log4moz.js");
 Cu.import("resource://snowl/modules/URI.js");
 
+// modules that are Snowl-specific
 Cu.import("resource://snowl/modules/datastore.js");
 Cu.import("resource://snowl/modules/collection.js");
 Cu.import("resource://snowl/modules/utils.js");
@@ -221,6 +224,13 @@
   // Initialization
 
   init: function() {
+    // FIXME: use the Observers module to observe message change notifications
+    // and rebuild the view when they happen.  Or does the collections view
+    // already do that for us?
+
+    // FIXME: simplify the way the view gets built after the collections view
+    // gets loaded to make this code less buggy and easier to hack.
+
     // Finish initializing after a brief timeout to give the collections view
     // time to initialize itself.
     let t = this;
@@ -726,7 +736,7 @@
         bylineBox.appendChild(this._document.createTextNode(message.source.name));
 
       // Timestamp
-      let lastUpdated = SnowlUtils._formatDate(new Date(message.timestamp));
+      let lastUpdated = SnowlUtils._formatDate(message.timestamp);
       if (lastUpdated) {
         let timestamp = this._document.createElementNS(HTML_NS, "span");
         timestamp.className = "timestamp";
--- a/content/stream.js	Thu Oct 16 19:11:46 2008 -0700
+++ b/content/stream.js	Fri Oct 17 17:30:25 2008 -0700
@@ -439,7 +439,7 @@
     // by time received.  Instead, we're going to group by time period
     // received (this morning, yesterday, last week, etc.) to give users
     // useful chronographic info.
-    //let lastUpdated = SnowlUtils._formatDate(new Date(message.timestamp));
+    //let lastUpdated = SnowlUtils._formatDate(message.timestamp);
     //if (lastUpdated) {
     //  let timestamp = this._document.createElementNS(XUL_NS, "description");
     //  timestamp.className = "timestamp";
--- a/modules/collection.js	Thu Oct 16 19:11:46 2008 -0700
+++ b/modules/collection.js	Fri Oct 17 17:30:25 2008 -0700
@@ -254,10 +254,10 @@
                                        statement.row.subject,
                                        statement.row.author,
                                        statement.row.link,
-                                       // FIXME: leave this as a JS Date object.
-                                       SnowlUtils.julianToJSDate(statement.row.timestamp).getTime(),
+                                       SnowlUtils.julianToJSDate(statement.row.timestamp),
                                        (statement.row.read ? true : false),
                                        statement.row.authorIcon,
+                                       // FIXME: leave this as a JS Date object.
                                        SnowlUtils.julianToJSDate(statement.row.received).getTime());
         this._messages.push(message);
         this._messageIndex[message.id] = message;
--- a/modules/feed.js	Thu Oct 16 19:11:46 2008 -0700
+++ b/modules/feed.js	Fri Oct 17 17:30:25 2008 -0700
@@ -331,9 +331,6 @@
     // 1. when the entry was last updated;
     // 2. when the entry was published;
     // 3. the Dublin Core timestamp associated with the entry;
-    // XXX Should we separately record when we added the entry so that the user
-    // can sort in the "order received" and view "when received" separately from
-    // "when published/updated"?
     let timestamp =   aEntry.updated        ? new Date(aEntry.updated)
                     : aEntry.published      ? new Date(aEntry.published)
                     : aEntry.get("dc:date") ? ISO8601DateUtils.parse(aEntry.get("dc:date"))
@@ -471,7 +468,7 @@
                                    aExternalID,
                                    aSubject,
                                    aAuthorID,
-                                   aTimestamp ? SnowlUtils.jsToJulianDate(aTimestamp) : null,
+                                   SnowlUtils.jsToJulianDate(aTimestamp),
                                    SnowlUtils.jsToJulianDate(aReceived),
                                    aLink ? aLink.spec : null);
 
--- a/modules/message.js	Thu Oct 16 19:11:46 2008 -0700
+++ b/modules/message.js	Fri Oct 17 17:30:25 2008 -0700
@@ -86,10 +86,10 @@
                                  statement.row.subject,
                                  statement.row.author,
                                  statement.row.link,
-                                 // FIXME: leave this as a JS Date object.
-                                 SnowlUtils.julianToJSDate(statement.row.timestamp).getTime(),
+                                 SnowlUtils.julianToJSDate(statement.row.timestamp),
                                  (statement.row.read ? true : false),
                                  statement.row.authorIcon,
+                                 // FIXME: leave this as a JS Date object.
                                  SnowlUtils.julianToJSDate(statement.row.received).getTime());
     }
   }
--- a/modules/twitter.js	Thu Oct 16 19:11:46 2008 -0700
+++ b/modules/twitter.js	Fri Oct 17 17:30:25 2008 -0700
@@ -474,7 +474,7 @@
                                    aExternalID,
                                    aSubject,
                                    aAuthorID,
-                                   aTimestamp ? SnowlUtils.jsToJulianDate(aTimestamp) : null,
+                                   SnowlUtils.jsToJulianDate(aTimestamp),
                                    SnowlUtils.jsToJulianDate(aReceived),
                                    aLink ? aLink.spec : null);
 
--- a/modules/utils.js	Thu Oct 16 19:11:46 2008 -0700
+++ b/modules/utils.js	Fri Oct 17 17:30:25 2008 -0700
@@ -45,6 +45,11 @@
 
 let SnowlUtils = {
   jsToJulianDate: function(date) {
+    // Sometimes we don't have a date.  We represent that the same way
+    // for both JS and Julian dates.
+    if (date == null)
+      return null;
+
     // Divide by 1000 to get seconds since Unix epoch, divide by 86400
     // to get days since Unix epoch, add the difference between the Unix epoch
     // and the Julian epoch.
@@ -52,6 +57,11 @@
   },
 
   julianToJSDate: function(date) {
+    // Sometimes we don't have a date.  We represent that the same way
+    // for both JS and Julian dates.
+    if (date == null)
+      return null;
+
     // Invert the function in jsToJulianDate, but round its result before
     // constructing a Date object, as the Date object would truncate (floor)
     // the non-integer result of the calculation, potentially resulting in
@@ -142,6 +152,10 @@
    * @returns a human-readable string representing the date
    */
   _formatDate: function(date) {
+    // FIXME: make this localizable.
+    if (!date)
+      return "unknown date";
+
     let day = new Date(date.getFullYear(), date.getMonth(), date.getDate());
     let now = new Date();
     let today = new Date(now.getFullYear(), now.getMonth(), now.getDate());