浏览代码

Merge pull request #357 from threema-ch/346-muted-notifications

Add support for muted conversations. Fixes #346.
Danilo Bargen 7 年之前
父节点
当前提交
7b6dffc941

+ 2 - 1
public/i18n/de.json

@@ -157,7 +157,8 @@
         "THREEMA_WORK_CONTACT": "Threema Work Nutzer",
         "THREEMA_BLOCKED_RECEIVER": "blockiert",
         "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.}}"
+        "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"
     },
     "messageTypes": {
         "AUDIO_MESSAGE": "Sprachnachricht",

+ 2 - 1
public/i18n/en.json

@@ -157,7 +157,8 @@
         "THREEMA_WORK_CONTACT": "Threema Work user",
         "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.}}"
+        "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"
     },
     "messageTypes": {
         "AUDIO_MESSAGE": "Audio Message",

+ 4 - 1
src/partials/messenger.navigation.html

@@ -77,7 +77,10 @@
 
             <section class="conversation-box">
                 <section class="receiver-box">
-                    <span ng-class="{'disabled': conversation.receiver.disabled === true}" ng-bind-html="conversation.receiver.displayName | escapeHtml | emojify">
+                    <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>
                     <span class="badge unread-count" ng-show="conversation.unreadCount > 0">
                         {{ conversation.unreadCount }}

+ 13 - 1
src/sass/sections/_navigation.scss

@@ -119,7 +119,7 @@
                 justify-content: space-between;
                 font-weight: bold;
                 color: black;
-                :first-child {
+                .title {
                     flex: 1;
                     white-space: nowrap;
                     overflow: hidden;
@@ -129,6 +129,17 @@
                 .disabled {
                     text-decoration: line-through;
                 }
+                .muted {
+                    margin: 1px 0 0 4px;
+                    padding: 0;
+                    height: 20px;
+                    i {
+                        color: $material-grey;
+                        font-size: 20px;
+                        margin: 0;
+                        padding: 0;
+                    }
+                }
             }
 
             .message-box {
@@ -218,6 +229,7 @@
             color: white;
             font-size: 0.9em;
             padding: 0 5px;
+            margin-left: 4px;
         }
     }
 

+ 33 - 21
src/services/webclient.ts

@@ -1649,27 +1649,34 @@ export class WebClientService {
                 if (data.unreadCount > 0) {
 
                     // Find the correct conversation in the conversation list
-                    for (let conversation of this.conversations.get()) {
-                        if (this.receiverService.compare(conversation, data)) {
-
-                            if (data.unreadCount > conversation.unreadCount) {
-                                // This is our conversation! If the unreadcount
-                                // has increased, we received a new message.
-                                this.onNewMessage(data.latestMessage, conversation);
-                            } else if (data.unreadCount < conversation.unreadCount) {
-                                // Otherwise, if it has decreased, hide the notification.
-                                this.notificationService.hideNotification(data.type + '-' + data.id);
-                            }
-
-                            break;
+                    const conversation = this.conversations.find(data);
+                    if (data === null) {
+                        // Conversation not found, add it!
+                        this.conversations.add(data);
+                        this.onNewMessage(data.latestMessage, conversation);
+                    } else {
+                        // Check for unread count changes
+                        const unreadCountIncreased = data.unreadCount > conversation.unreadCount;
+                        const unreadCountDecreased = data.unreadCount < conversation.unreadCount;
+
+                        // Update the conversation
+                        this.conversations.updateOrAdd(data);
+
+                        // If the unreadcount has increased, we received a new message.
+                        // Otherwise, if it has decreased, hide the notification.
+                        if (unreadCountIncreased) {
+                            this.onNewMessage(data.latestMessage, conversation);
+                        } else if (unreadCountDecreased) {
+                            this.notificationService.hideNotification(data.type + '-' + data.id);
                         }
                     }
+
                 } else {
+                    // Update the conversation and hide any notifications
+                    this.conversations.updateOrAdd(data);
                     this.notificationService.hideNotification(data.type + '-' + data.id);
                 }
-                // we have to call update or add, we are not sure if this
-                // conversation is already fetched
-                this.conversations.updateOrAdd(data);
+
                 break;
             case WebClientService.ARGUMENT_MODE_REMOVED:
                 this.conversations.remove(data);
@@ -2088,18 +2095,23 @@ export class WebClientService {
      * Called when a new message arrives.
      */
     private onNewMessage(message: threema.Message, conversation: threema.Conversation): void {
-        // ignore message from active receivers (and if the browser tab is visible
+        // Ignore message from active receivers (and if the browser tab is visible)
         if (this.browserService.isVisible()
-            && this.receiverService.compare(conversation, this.receiverService.getActive())) {
-            this.$log.debug('do not show a notification of a active chat');
+                && this.receiverService.compare(conversation, this.receiverService.getActive())) {
             return;
         }
         const sender: threema.Receiver = conversation.receiver;
 
-        if (sender === undefined  || sender.locked) {
-            // do not show any notifications on private chats
+        // Do not show any notifications on private chats
+        if (sender === undefined || sender.locked) {
             return;
         }
+
+        // Do not show any notifications on muted chats
+        if (conversation.isMuted === true) {
+            return;
+        }
+
         // Determine sender and partner name (used for notification)
         let senderName = sender.id;
         if (sender.displayName) {

+ 2 - 0
src/threema.d.ts

@@ -286,6 +286,7 @@ declare namespace threema {
         latestMessage: Message;
         receiver?: Receiver;
         avatar?: ArrayBuffer;
+        isMuted?: boolean;
     }
 
     /**
@@ -523,6 +524,7 @@ declare namespace threema {
         interface Conversations {
             get(): Conversation[];
             set(data: Conversation[]): void;
+            find(pattern: Conversation | Receiver): Conversation | null;
             add(conversation: Conversation): void;
             updateOrAdd(conversation: Conversation): void;
             remove(conversation: Conversation): void;

+ 16 - 0
src/threema/container.ts

@@ -250,6 +250,22 @@ angular.module('3ema.container', [])
             });
         }
 
+        /**
+         * Find a stored conversation matching the given conversation or receiver.
+         *
+         * Comparison is done by type and id.
+         */
+        public find(pattern: threema.Conversation | threema.Receiver): threema.Conversation | null {
+            for (let conversation of this.get()) {
+                const a = pattern;
+                const b = conversation;
+                if (a !== undefined && b !== undefined && a.type === b.type && a.id === b.id) {
+                    return conversation;
+                }
+            }
+            return null;
+        }
+
         public add(conversation: threema.Conversation): void {
             this.conversations.splice(conversation.position, 0, conversation);
         }