Ver código fonte

Implement display of new notification status

Danilo Bargen 7 anos atrás
pai
commit
7d40b16a9e

+ 3 - 0
public/i18n/de.json

@@ -172,6 +172,9 @@
         "DELETE_THREAD": "Chat löschen",
         "DELETE_THREAD_MESSAGE": "{count, plural, one {Möchten Sie wirklich diesen Chat löschen? Die Nachrichten können nicht wiederhergestellt werden.} other {Möchten Sie wirklich # Chats löschen? Die Nachrichten können nicht wiederhergestellt werden.}}",
         "MUTED": "Keine Benachrichtigungen",
+        "MUTED_NONE": "Keine Benachrichtigungen",
+        "MUTED_MENTION_ONLY": "Nur bei Erwähnung benachrichtigen",
+        "MUTED_SILENT": "Stumme Benachrichtigungen",
         "ALL": "Alle"
     },
     "messageTypes": {

+ 3 - 1
public/i18n/en.json

@@ -171,7 +171,9 @@
         "THREEMA_BLOCKED_RECEIVER": "blocked",
         "DELETE_THREAD": "Delete chat",
         "DELETE_THREAD_MESSAGE": "{count, plural, one {Do you really want to delete this chat? You will not be able to recover the messages.} other {Do you really want to delete # chat(s)? You will not be able to recover the messages.}}",
-        "MUTED": "No notifications",
+        "MUTED_NONE": "No notifications",
+        "MUTED_MENTION_ONLY": "Only show notification when mentioned",
+        "MUTED_SILENT": "Silent notifications",
         "ALL": "All"
     },
     "messageTypes": {

+ 35 - 0
public/img/ic_dnd_mention.svg

@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   id="svg4550"
+   version="1.1"
+   viewBox="0 0 48 48"
+   height="48"
+   width="48">
+  <metadata
+     id="metadata4556">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs4554" />
+  <path
+     style="stroke-width:1.19999993;fill:#0000008a;"
+     id="path4548"
+     d="M 24,0 C 10.752,0 0,10.752 0,24 0,37.248 10.752,48 24,48 37.248,48 48,37.248 48,24 48,10.752 37.248,0 24,0 Z" />
+  <path
+     id="path2"
+     d="M 24,6.5 C 14.34,6.5 6.5,14.34 6.5,24 c 0,9.66 7.84,17.5 17.5,17.5 h 8.75 V 38 H 24 c -7.595,0 -14,-6.405 -14,-14 0,-7.595 6.405,-14 14,-14 7.595,0 14,6.405 14,14 v 2.5025 c 0,1.3825 -1.2425,2.7475 -2.625,2.7475 -1.3825,0 -2.625,-1.365 -2.625,-2.7475 V 24 c 0,-4.83 -3.92,-8.75 -8.75,-8.75 -4.83,0 -8.75,3.92 -8.75,8.75 0,4.83 3.92,8.75 8.75,8.75 2.415,0 4.62,-0.98 6.195,-2.5725 1.1375,1.5575 3.0975,2.5725 5.18,2.5725 3.4475,0 6.125,-2.8 6.125,-6.2475 V 24 C 41.5,14.34 33.66,6.5 24,6.5 Z m 0,22.75 c -2.905,0 -5.25,-2.345 -5.25,-5.25 0,-2.905 2.345,-5.25 5.25,-5.25 2.905,0 5.25,2.345 5.25,5.25 0,2.905 -2.345,5.25 -5.25,5.25 z"
+     style="fill:#ffffff;fill-opacity:1;stroke-width:1.75" />
+</svg>

+ 38 - 0
public/img/ic_dnd_total_silence.svg

@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   id="svg4550"
+   version="1.1"
+   viewBox="0 0 48 48"
+   height="48"
+   width="48">
+  <metadata
+     id="metadata4556">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs4554" />
+  <path
+     style="stroke-width:0.94999999;fill:#0000008a;"
+     id="path4548"
+     d="M 24,5 C 13.512,5 5,13.512 5,24 5,34.488 13.512,43 24,43 34.488,43 43,34.488 43,24 43,13.512 34.488,5 24,5 Z m 9.5,20.9 h -19 v -3.8 h 19 z" />
+  <ellipse
+     ry="23.040001"
+     rx="23.039999"
+     cy="24"
+     cx="24"
+     id="path5101"
+     style="fill:none;stroke:#0000008a;stroke-width:1.92;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:0.69999999;stroke-dasharray:none;stroke-dashoffset:38.53903961;stroke-opacity:1" />
+</svg>

+ 1 - 0
public/img/ic_notifications_off.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 48 48"><path fill="#0000008a" d="M40 37.39L15.68 12.3l-5.13-5.29L8 9.55l5.6 5.6.01.01C12.56 17.14 12 19.48 12 22v10l-4 4v2h27.46l4 4L42 39.45l-2-2.06zM24 44c2.21 0 4-1.79 4-4h-8c0 2.21 1.79 4 4 4zm12-14.64V22c0-6.15-3.27-11.28-9-12.64V8c0-1.66-1.34-3-3-3s-3 1.34-3 3v1.36c-.29.07-.57.15-.85.24-.21.07-.41.14-.61.22 0 0-.01 0-.01.01-.01 0-.02.01-.03.01-.46.18-.91.39-1.35.62-.01 0-.02.01-.03.01L36 29.36z"/></svg>

+ 1 - 1
src/directives/latest_message.html

@@ -47,7 +47,7 @@
                   class="message-date" eee-message="ctrl.message"></span>
 
             <span class="message-state" ng-show="ctrl.statusIcon">
-                 <i class="material-icons md-dark md-14 {{ctrl.message.state}}">
+                 <i class="material-icons md-medium-dark md-14 {{ctrl.message.state}}">
                      {{ ctrl.statusIcon }}
                  </i>
             </span>

+ 30 - 0
src/filters.ts

@@ -398,4 +398,34 @@ angular.module('3ema.filters', [])
     };
 }])
 
+/**
+ * Return a simplified DND mode.
+ *
+ * This will return either 'on', 'off' or 'mention'.
+ * The 'until' mode will be processed depending on the expiration timestamp.
+ */
+.filter('dndModeSimplified', [function() {
+    return (conversation: threema.Conversation) => {
+        if (!conversation.notifications) {
+            return 'off';
+        }
+        const dnd = conversation.notifications.dnd;
+        switch (dnd.mode) {
+            case threema.NotificationDndMode.On:
+                return 'on';
+            case threema.NotificationDndMode.Mention:
+                return 'mention';
+            case threema.NotificationDndMode.Off:
+                return 'off';
+            case threema.NotificationDndMode.Until:
+                if (!dnd.until || dnd.until <= 0) {
+                    return 'off';
+                }
+                const until: Date = new Date(dnd.until);
+                const now: Date = new Date();
+                return until > now ? 'on' : 'off';
+        }
+    };
+}])
+
 ;

+ 8 - 2
src/partials/messenger.navigation.html

@@ -85,8 +85,14 @@
                     <section class="receiver-box">
                         <span class="title" ng-class="{'disabled': conversation.receiver.disabled === true}" ng-bind-html="conversation.receiver.displayName | escapeHtml | emojify">
                         </span>
-                        <span class="muted" ng-show="conversation.isMuted">
-                            <i class="material-icons md-dark" translate translate-attr-title="messenger.MUTED">do_not_disturb_on</i>
+                        <span class="notification-settings" ng-show="(conversation | dndModeSimplified) === 'on'">
+                            <img height="16" width="16" src="img/ic_dnd_total_silence.svg" translate translate-attr-title="messenger.MUTED_NONE">
+                        </span>
+                        <span class="notification-settings" ng-show="(conversation | dndModeSimplified) === 'mention'">
+                            <img height="16" width="16" src="img/ic_dnd_mention.svg" translate translate-attr-title="messenger.MUTED_MENTION_ONLY">
+                        </span>
+                        <span class="notification-settings" ng-show="(conversation | dndModeSimplified) === 'off' && conversation.notifications && conversation.notifications.sound.mode === 'muted'">
+                            <img height="16" width="16" src="img/ic_notifications_off.svg" translate translate-attr-title="messenger.MUTED_SILENT">
                         </span>
                         <span class="badge unread-count" ng-show="conversation.unreadCount > 0">
                             {{ conversation.unreadCount }}

+ 3 - 0
src/sass/helpers/_colors.scss

@@ -26,3 +26,6 @@ $active-placeholder-color: lightgray;
 .color-status-error {
     color: $status-error;
 }
+
+.material-icons.md-medium-dark { color: rgba(0, 0, 0, 0.54); }
+.material-icons.md-medium-dark.md-inactive { color: rgba(0, 0, 0, 0.26); }

+ 2 - 8
src/sass/sections/_navigation.scss

@@ -193,16 +193,10 @@
                     .disabled {
                         text-decoration: line-through;
                     }
-                    .muted {
+                    .notification-settings {
                         margin: 1px 0 0 4px;
                         padding: 0;
                         height: 20px;
-                        i {
-                            color: $material-grey;
-                            font-size: 20px;
-                            margin: 0;
-                            padding: 0;
-                        }
                     }
                 }
 
@@ -214,7 +208,7 @@
                         flex-direction: row;
                         justify-content: space-between;
                         align-items: center;
-                        color: rgba(0, 0, 0, 0.54); // TODO: Extract color
+                        color: $material-grey;
 
                         .left {
                             white-space: nowrap;

+ 4 - 3
src/services/webclient.ts

@@ -2426,9 +2426,10 @@ export class WebClientService {
         }
 
         // Do not show any notifications on muted chats
-        if (conversation.isMuted === true) {
-            return;
-        }
+        // TODO
+        //if (conversation.isMuted === true) {
+        //    return;
+        //}
 
         // Determine sender and partner name (used for notification)
         let senderName = sender.id;

+ 27 - 1
src/threema.d.ts

@@ -316,7 +316,7 @@ declare namespace threema {
         latestMessage: Message | null;
         receiver?: Receiver;
         avatar?: ArrayBuffer;
-        isMuted?: boolean;
+        notifications?: NotificationSettings;
         isStarred?: boolean;
     }
 
@@ -327,6 +327,32 @@ declare namespace threema {
         position: number;
     }
 
+    interface NotificationSettings {
+        sound: NotificationSound;
+        dnd: NotificationDnd;
+    }
+
+    interface NotificationSound {
+        mode: NotificationSoundMode;
+    }
+
+    const enum NotificationSoundMode {
+        Default = 'default',
+        Muted = 'muted',
+    }
+
+    interface NotificationDnd {
+        mode: NotificationDndMode;
+        until?: number;
+    }
+
+    const enum NotificationDndMode {
+        Off = 'off',
+        On = 'on',
+        Mention = 'mention',
+        Until = 'until',
+    }
+
     /**
      * Connection state in the welcome dialog.
      *

+ 71 - 0
tests/filters.js

@@ -291,4 +291,75 @@ describe('Filters', function() {
         });
     });
 
+    describe('dndModeSimplified', function() {
+        let process = (dnd, sound) => {
+            return $filter('dndModeSimplified')({
+                notifications: {
+                    dnd: dnd,
+                    sound: sound,
+                },
+            })
+        };
+
+        it('dnd enabled', () => {
+            expect(process(
+                {mode: 'on'},
+                {mode: 'default'},
+            )).toEqual('on');
+        });
+
+        it('dnd enabled (no sound)', () => {
+            expect(process(
+                {mode: 'on'},
+                {mode: 'muted'},
+            )).toEqual('on');
+        });
+
+        it('dnd disabled', () => {
+            expect(process(
+                {mode: 'off'},
+                {mode: 'default'},
+            )).toEqual('off');
+        });
+
+        it('dnd disabled (no sound)', () => {
+            expect(process(
+                {mode: 'off'},
+                {mode: 'muted'},
+            )).toEqual('off');
+        });
+
+        it('mention only', () => {
+            expect(process(
+                {mode: 'mention'},
+                {mode: 'default'},
+            )).toEqual('mention');
+        });
+
+        it('mention only (no sound)', () => {
+            expect(process(
+                {mode: 'mention'},
+                {mode: 'muted'},
+            )).toEqual('mention');
+        });
+
+        it('until (not expired)', () => {
+            jasmine.clock().install();
+            jasmine.clock().mockDate(new Date(2018, 9, 9, 20, 42));
+            expect(process(
+                {mode: 'until', until: +(new Date(2018, 9, 9, 20, 50))},
+                {mode: 'default'},
+            )).toEqual('on');
+        });
+
+        it('until (expired)', () => {
+            jasmine.clock().install();
+            jasmine.clock().mockDate(new Date(2018, 9, 9, 20, 42));
+            expect(process(
+                {mode: 'until', until: +(new Date(2018, 9, 9, 19, 50))},
+                {mode: 'default'},
+            )).toEqual('off');
+        });
+    });
+
 });