Преглед на файлове

Datetime formatting without moment.js

Danilo Bargen преди 7 години
родител
ревизия
6bdad0caf6
променени са 9 файла, в които са добавени 144 реда и са изтрити 50 реда
  1. 0 5
      index.html
  2. 0 13
      package-lock.json
  3. 0 2
      package.json
  4. 17 0
      public/i18n/de.json
  5. 17 0
      public/i18n/en.json
  6. 0 29
      src/app.ts
  7. 1 1
      src/directives/message_date.ts
  8. 68 0
      src/filters.ts
  9. 41 0
      tests/filters.js

+ 0 - 5
index.html

@@ -117,11 +117,6 @@
     <script src="node_modules/angular-translate/dist/angular-translate-loader-static-files/angular-translate-loader-static-files.min.js?v=[[VERSION]]"></script>
     <script src="node_modules/angular-translate/dist/angular-translate-interpolation-messageformat/angular-translate-interpolation-messageformat.min.js?v=[[VERSION]]"></script>
 
-    <!-- Date formatting -->
-    <script src="node_modules/moment/min/moment.min.js?v=[[VERSION]]"></script>
-    <script src="node_modules/moment/locale/de.js?v=[[VERSION]]"></script>
-    <script src="node_modules/angular-moment/angular-moment.min.js?v=[[VERSION]]"></script>
-
     <!-- Other -->
     <script src="node_modules/msgpack-lite/dist/msgpack.min.js?v=[[VERSION]]"></script>
     <script src="node_modules/tweetnacl/nacl-fast.min.js?v=[[VERSION]]"></script>

+ 0 - 13
package-lock.json

@@ -169,14 +169,6 @@
       "integrity": "sha1-oOHdDqVf137np1fXVTbF6WTIb4E=",
       "dev": true
     },
-    "angular-moment": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/angular-moment/-/angular-moment-1.2.0.tgz",
-      "integrity": "sha512-0jm7AfCTk/zbBuVuoz9MecMplGfTQ9Wk9JB8J4qYX9IddcETRukpbKXMy27YTL1wKwYJkRTbGMu/Pb3IXbMfyA==",
-      "requires": {
-        "moment": "2.22.1"
-      }
-    },
     "angular-qrcode": {
       "version": "6.2.1",
       "resolved": "https://registry.npmjs.org/angular-qrcode/-/angular-qrcode-6.2.1.tgz",
@@ -4853,11 +4845,6 @@
         }
       }
     },
-    "moment": {
-      "version": "2.22.1",
-      "resolved": "https://registry.npmjs.org/moment/-/moment-2.22.1.tgz",
-      "integrity": "sha512-shJkRTSebXvsVqk56I+lkb2latjBs8I+pc2TzWc545y2iFnSjm7Wg0QMh+ZWcdSLQyGEau5jI8ocnmkyTgr9YQ=="
-    },
     "ms": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",

+ 0 - 2
package.json

@@ -43,7 +43,6 @@
     "angular-aria": "~1.5.10",
     "angular-material": "=1.1.1",
     "angular-messages": "^1.6.10",
-    "angular-moment": "^1.2.0",
     "angular-qrcode": "~6.2.1",
     "angular-route": "~1.5.10",
     "angular-sanitize": "~1.5.10",
@@ -60,7 +59,6 @@
     "file-saver": "^1.3.8",
     "js-sha256": "~0.3.2",
     "messageformat": "~1.0.2",
-    "moment": "^2.22.1",
     "msgpack-lite": "~0.1.26",
     "node-sass": "^4.9.0",
     "sdp": "~1.3.0",

+ 17 - 0
public/i18n/de.json

@@ -269,5 +269,22 @@
         "ALERT": "Entladen: {percent}%",
         "LEVEL_LOW": "Der Akkustand Ihres Gerätes ist niedrig ({percent}%).",
         "LEVEL_CRITICAL": "Der Akkustand Ihres Gerätes ist kritisch ({percent}%)!"
+    },
+    "date": {
+        "YESTERDAY": "Gestern",
+        "month_short": {
+            "JAN": "Jan.",
+            "FEB": "Feb.",
+            "MAR": "Mär.",
+            "APR": "Apr.",
+            "MAY": "Mai",
+            "JUN": "Jun.",
+            "JUL": "Jul.",
+            "AUG": "Aug.",
+            "SEP": "Sep.",
+            "OCT": "Okt.",
+            "NOV": "Nov.",
+            "DEC": "Dez."
+        }
     }
 }

+ 17 - 0
public/i18n/en.json

@@ -269,5 +269,22 @@
         "ALERT": "Discharging: {percent}%",
         "LEVEL_LOW": "Your device battery level is low ({percent}%).",
         "LEVEL_CRITICAL": "Your device battery level is critical ({percent}%)!"
+    },
+    "date": {
+        "YESTERDAY": "Yesterday",
+        "month_short": {
+            "JAN": "Jan.",
+            "FEB": "Feb.",
+            "MAR": "Mar.",
+            "APR": "Apr.",
+            "MAY": "May",
+            "JUN": "Jun.",
+            "JUL": "Jul.",
+            "AUG": "Aug.",
+            "SEP": "Sep.",
+            "OCT": "Oct.",
+            "NOV": "Nov.",
+            "DEC": "Dec."
+        }
     }
 }

+ 0 - 29
src/app.ts

@@ -47,7 +47,6 @@ angular.module('3ema', [
     'luegg.directives',
     'pascalprecht.translate',
     'ngMaterial',
-    'angularMoment',
 
     // Own
     '3ema.filters',
@@ -136,32 +135,4 @@ angular.module('3ema', [
     }]);
 }])
 
-.run([
-    '$translate',
-    '$log',
-    'amMoment',
-    'moment',
-    ($translate: ng.translate.ITranslateService, $log: ng.ILogService, amMoment, moment) => {
-        const lang = $translate.proposedLanguage() || $translate.use();
-        $log.debug('Setting locale:', lang);
-        moment.updateLocale('en', {
-            longDateFormat : {
-                L: 'MMM Do YYYY',
-            },
-            calendar: {
-                sameElse: 'L, LT',
-            },
-        });
-        moment.updateLocale('de', {
-            longDateFormat : {
-                L: 'Do MMM YYYY',
-            },
-            calendar: {
-                sameElse: 'L, LT',
-            },
-        });
-        amMoment.changeLocale(lang);
-    },
-])
-
 ;

+ 1 - 1
src/directives/message_date.ts

@@ -23,7 +23,7 @@ export default [
                 message: '=eeeMessage',
             },
             template: `
-                <span>{{ message.date | amFromUnix | amCalendar }}</span>
+                <span>{{ message.date | unixToTimestring }}</span>
             `,
         };
     },

+ 68 - 0
src/filters.ts

@@ -330,4 +330,72 @@ angular.module('3ema.filters', [])
     };
 }])
 
+/**
+ * Format a unix timestamp as a date.
+ */
+.filter('unixToTimestring', ['$translate', function($translate) {
+    function formatTime(date) {
+        return ('00' + date.getHours()).slice(-2) + ':' +
+               ('00' + date.getMinutes()).slice(-2);
+    }
+
+    function formatMonth(num) {
+        switch (num) {
+            case 0x0:
+                return 'date.month_short.JAN';
+            case 0x1:
+                return 'date.month_short.FEB';
+            case 0x2:
+                return 'date.month_short.MAR';
+            case 0x3:
+                return 'date.month_short.APR';
+            case 0x4:
+                return 'date.month_short.MAY';
+            case 0x5:
+                return 'date.month_short.JUN';
+            case 0x6:
+                return 'date.month_short.JUL';
+            case 0x7:
+                return 'date.month_short.AUG';
+            case 0x8:
+                return 'date.month_short.SEP';
+            case 0x9:
+                return 'date.month_short.OCT';
+            case 0xa:
+                return 'date.month_short.NOV';
+            case 0xb:
+                return 'date.month_short.DEC';
+        }
+    }
+
+    function isSameDay(date1, date2) {
+        return date1.getFullYear() === date2.getFullYear()
+            && date1.getMonth() === date2.getMonth()
+            && date1.getDate() === date2.getDate();
+    }
+
+    return (timestamp: number) => {
+        const date = new Date(timestamp * 1000);
+
+        const now = new Date();
+        if (isSameDay(date, now)) {
+            return formatTime(date);
+        }
+
+        const yesterday = new Date(now.getTime() - 1000 * 60 * 60 * 24);
+        if (isSameDay(date, yesterday)) {
+            return $translate.instant('date.YESTERDAY') + ', ' + formatTime(date);
+        }
+
+        let year = '';
+        if (date.getFullYear() !== now.getFullYear()) {
+            year = ' ' + date.getFullYear();
+        }
+        return date.getDate() + '. '
+             + $translate.instant(formatMonth(date.getMonth()))
+             + year + ', '
+             + formatTime(date);
+    };
+}])
+
 ;

+ 41 - 0
tests/filters.js

@@ -1,3 +1,7 @@
+afterEach(function () {
+    jasmine.clock().uninstall();
+});
+
 describe('Filters', function() {
 
     let $filter;
@@ -243,4 +247,41 @@ describe('Filters', function() {
         });
     });
 
+    describe('unixToTimestring', function() {
+        this.testPatterns = (cases) => testPatterns('unixToTimestring', cases);
+
+        it('shows only time for today', () => {
+            const d1 = new Date(); d1.setHours(8); d1.setMinutes(7);
+            const d2 = new Date(); d2.setHours(12); d2.setMinutes(14);
+            const d3 = new Date(); d3.setHours(0); d3.setMinutes(0);
+            this.testPatterns([
+                [d1.getTime() / 1000, '08:07'],
+                [d2.getTime() / 1000, '12:14'],
+                [d3.getTime() / 1000, '00:00'],
+            ]);
+        });
+
+        it('shows "yesterday" for yesterday', () => {
+            const d1 = new Date();
+            const ts = d1.getTime();
+            const d2 = new Date(ts - 1000 * 60 * 60 * 24);
+            d2.setHours(8); d2.setMinutes(7);
+            this.testPatterns([
+                [d2.getTime() / 1000, 'date.YESTERDAY, 08:07'],
+            ]);
+        });
+
+        it('shows full datetime for other days', () => {
+            jasmine.clock().install();
+            jasmine.clock().mockDate(new Date(2018, 9, 9, 20, 42));
+            const now = new Date();
+            const d1 = new Date(2010, 1, 7, 18, 42);
+            const d2 = new Date(now.getFullYear(), 4, 2, 23, 59);
+            this.testPatterns([
+                [d1.getTime() / 1000, '7. date.month_short.FEB 2010, 18:42'],
+                [d2.getTime() / 1000, '2. date.month_short.MAY, 23:59'],
+            ]);
+        });
+    });
+
 });