Use friendly dates for message timestamps
authorJames Burke <jrburke@mozillamessaging.com>
Mon, 21 Jun 2010 14:52:10 -0700
changeset 1783 1f8176fb4587ac77243c6262b035dd5fc2bd160c
parent 1782 f16982df0692fe1bf54f85244e0118e1c8a1d1b6
child 1784 395e1abc3bdfe60fc103791749fa97a8e4ae1389
push id986
push userjrburke@gmail.com
push dateMon, 21 Jun 2010 21:52:12 +0000
Use friendly dates for message timestamps
client/api/contacts.html
client/api/scripts/friendly.js
--- a/client/api/contacts.html
+++ b/client/api/contacts.html
@@ -13,18 +13,18 @@
         'use strict';
         /*global require: false, console: false */
 
         /*
          To detect orientation changes in Android:
          http://stackoverflow.com/questions/1649086/detect-rotation-of-android-phone-in-the-browser-with-javascript
         */
 
-        require(['jquery', 'rdapi', 'cards', 'blade/jig', 'json2', 'iscroll-min'],
-        function ($,        rdapi,   cards,   jig) {
+        require(['jquery', 'rdapi', 'cards', 'blade/jig', 'friendly', 'json2', 'iscroll-min'],
+        function ($,        rdapi,   cards,   jig,         friendly) {
 
             //Initialize the card setup
             cards('#display');
 
             //Set up extra template functions.
             rdapi.addJigFunctions({
                 getPhotoUrl: function (contact) {
                     var i, identity, url = 'i/face2.png';
@@ -32,16 +32,19 @@
                         for (i = 0; (identity = contact.identities[i]); i++) {
                             if (identity.image) {
                                 url = identity.image;
                                 break;
                             }
                         }
                     }
                     return url;
+                },
+                friendlyDate: function (timestamp) {
+                    return friendly.timestamp(timestamp).friendly;
                 }
             });
 
             $(function () {
                 //setup for the iscroll thing
                 if ('ontouchmove' in document) {
                     document.addEventListener('touchmove', function(e){ e.preventDefault(); }, false);
                     new iScroll('contactList');
@@ -231,17 +234,17 @@
     </li>
 
     <!-- Template for showing all messages in a conversation -->
     <div class="template message {id[0]}" data-id="fullConv">
         <div class="subject">{subject}</div>
         <ul class="maxWidthList">
             {messages [}
                 <li class="message">
-                    <div class="from name">{schemas['rd.msg.body'].from_display} <span class="date">on {schemas['rd.msg.body'].timestamp}</span></div>
+                    <div class="from name">{schemas['rd.msg.body'].from_display} <span class="date">{friendlyDate(schemas['rd.msg.body'].timestamp)}</span></div>
                     <div class="messageBody">
                         {schemas['rd.msg.body.quoted'].parts [}
                             {type [}
                                 <a class="quoteToggle" href="#quoteToggle">Show Quote</a>
                             {]}
                             <div class="quoteContent {type}">{^htmlBody(text)}</div>
                         {]}
                     </div>
new file mode 100644
--- /dev/null
+++ b/client/api/scripts/friendly.js
@@ -0,0 +1,129 @@
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Raindrop.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Messaging, Inc..
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * */
+
+/*jslint plusplus: false, nomen: false */
+/*global require: false */
+"use strict";
+
+require.def("friendly", function () {
+    var friendly = {
+        timestamp: function (timestamp) {
+            return friendly.date(new Date(timestamp * 1000));
+        },
+
+        date: function (date) {
+            var diff = (((new Date()).getTime() - date.getTime()) / 1000),
+                day_diff = Math.floor(diff / 86400),
+                dObj = { "friendly" : date.toLocaleDateString(), 
+                        "additional" : date.toLocaleTimeString(),
+                        "utc" : date.toUTCString(),
+                        "locale" : date.toLocaleString() };
+    
+            /* some kind of error */
+            if (day_diff < 0) {
+                dObj.friendly = "in the future";
+                return dObj;
+            } else if (isNaN(day_diff)) {
+                dObj.friendly = dObj.additional = "unknown";
+                return dObj;
+            }
+
+            if (day_diff === 0) {
+                if (diff < 60) {
+                    dObj.friendly = "just now";
+                    return dObj;
+                }
+                if (diff < 120 + 30) { /* 1 minute plus some fuzz */
+                    dObj.friendly = "a minute ago";
+                    return dObj;
+                }
+                if (diff < 3600) {
+                    dObj.friendly = Math.floor(diff / 60) + " minutes ago";
+                    return dObj;
+                }
+                if (diff < (60 * 60) * 2) {
+                    dObj.friendly = "1 hour ago";
+                    return dObj;
+                }
+                if (diff < 24 * 60 * 60) {
+                    dObj.friendly = Math.floor(diff / 3600) + " hours ago";
+                    return dObj;
+                }
+            }
+            if (day_diff === 1) {
+                dObj.friendly = "yesterday";
+                return dObj;
+            }
+            if (day_diff < 7) {
+                dObj.friendly = day_diff + " days ago";
+                return dObj;
+            }
+            if (day_diff < 8) {
+                dObj.friendly = "last week";
+                return dObj;
+            }
+            /* for this scope: we want day of week and the date 
+                 plus the month (if different) */
+            if (day_diff < 31) {
+                dObj.friendly = Math.ceil(day_diff / 7) + " weeks ago";
+                return dObj;
+            }
+
+            /* for this scope: we want month + date */
+            if (day_diff < 62) {
+                dObj.friendly = "a month ago";
+                return dObj;
+            }
+            if (day_diff < 365) {
+                dObj.friendly = Math.ceil(day_diff / 31) + " months ago";
+                return dObj;
+            }
+    
+            /* for this scope: we want month + year */
+            if (day_diff >= 365 && day_diff < 730) {
+                dObj.additional = date.toLocaleDateString();
+                dObj.friendly = "a year ago";
+                return dObj;
+            }
+            if (day_diff >= 365) {
+                dObj.additional = date.toLocaleDateString();
+                dObj.friendly = Math.ceil(day_diff / 365) + " years ago";
+                return dObj;
+            }
+            return dObj;
+        },
+    
+        name: function (name) {
+            var firstName = name.split(' ')[0];
+            if (firstName.indexOf('@') !== -1) {
+                firstName = firstName.split('@')[0];
+            }
+            firstName = firstName.replace(" ", "");
+            firstName = firstName.replace("'", "");
+            firstName = firstName.replace('"', "");
+            return firstName;
+        }    
+    };
+
+    return friendly;
+});