Procházet zdrojové kódy

Mark blocked contacts / disable sending messages to blocked contacts (#325)

Fixes #135
Silly před 8 roky
rodič
revize
08d006c40e

+ 3 - 1
public/i18n/de.json

@@ -150,7 +150,8 @@
         "BALLOT_MESSAGES_NOT_SUPPORTED": "Umfragen werden in Threema Web derzeit nicht untersützt.",
         "UNKNOWN_MESSAGE_TYPE": "Unbekannter Nachrichtentyp",
         "NICKNAME": "Nickname",
-        "THREEMA_WORK_CONTACT": "Threema Work Nutzer"
+        "THREEMA_WORK_CONTACT": "Threema Work Nutzer",
+        "THREEMA_BLOCKED_RECEIVER": "blockiert"
     },
     "messageTypes": {
         "AUDIO_MESSAGE": "Sprachnachricht",
@@ -173,6 +174,7 @@
         "MESSAGE_NOT_SUPPORTED": "«{receiverName}» kann diese Nachricht noch nicht erhalten.",
         "AUDIO_MESSAGES_NOT_SUPPORTED": "«{receiverName}» kann noch keine Sprachnachrichten erhalten.",
         "FILE_MESSAGES_NOT_SUPPORTED": "«{receiverName}» kann noch keine Dateien erhalten.",
+        "CONTACT_BLOCKED":  "Sie können keine Nachrichten an blockierte Kontakte senden.",
         "ERROR_OCCURRED": "Es ist ein Fehler aufgetreten.",
         "FILE_TOO_LARGE": "Aktuell können keine Dateien grösser als 15 MiB über Threema Web versendet werden",
         "TEXT_TOO_LONG": "Diese Nachricht ist zu lang und kann nicht gesendet werden (Maximale Länge {max} Zeichen).",

+ 3 - 1
public/i18n/en.json

@@ -151,7 +151,8 @@
         "BALLOT_MESSAGES_NOT_SUPPORTED": "Ballot messages are not yet supported in Threema Web.",
         "UNKNOWN_MESSAGE_TYPE": "Unknown message type",
         "NICKNAME": "Nickname",
-        "THREEMA_WORK_CONTACT": "Threema Work user"
+        "THREEMA_WORK_CONTACT": "Threema Work user",
+        "THREEMA_BLOCKED_RECEIVER": "blocked"
     },
     "messageTypes": {
         "AUDIO_MESSAGE": "Audio Message",
@@ -175,6 +176,7 @@
         "MESSAGE_NOT_SUPPORTED": "«{receiverName}» cannot receive this message.",
         "AUDIO_MESSAGES_NOT_SUPPORTED": "«{receiverName}» cannot receive voice messages.",
         "FILE_MESSAGES_NOT_SUPPORTED": "«{receiverName}» cannot receive files.",
+        "CONTACT_BLOCKED":  "You cannot send messages to a blocked contact.",
         "ERROR_OCCURRED": "An error occurred.",
         "FILE_TOO_LARGE": "Currently files larger than 15 MiB cannot be sent through Threema Web",
         "TEXT_TOO_LONG": "This message is too long and cannot be sent (Max length {max} characters).",

+ 1 - 0
public/img/ic_blocked_24px.svg

@@ -0,0 +1 @@
+<svg x="0" y="0" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 24 24" width="24" height="24" style="fill: rgb(255, 255, 255);"><g transform=""><g fill="none" stroke="none" stroke-width="1" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="10" stroke-dasharray="" stroke-dashoffset="0" font-family="none" font-weight="none" font-size="none" text-anchor="start" mix-blend-mode="normal"><g><g><g><path d="M0,24l0,-24l24,0l0,24z" fill="none" font-family="sans-serif" font-weight="normal" font-size="12"/><path d="M12,24c-6.62742,0 -12,-5.37258 -12,-12l0,0c0,-6.62742 5.37258,-12 12,-12l0,0c6.62742,0 12,5.37258 12,12l0,0c0,6.62742 -5.37258,12 -12,12z" fill="#c0392b" font-family="sans-serif" font-weight="normal" font-size="12"/><g fill="#ffffff" font-family="serif" font-weight="400" font-size="16"><g id="surface1"><path d="M12,3c-4.95,0 -9,4.05 -9,9c0,4.95 4.05,9 9,9c4.95,0 9,-4.05 9,-9c0,-4.95 -4.05,-9 -9,-9z M12,4.8c3.95859,0 7.2,3.24141 7.2,7.2c0,1.65586 -0.56953,3.1957 -1.51875,4.41563l-10.09687,-10.09687c1.21992,-0.94922 2.75977,-1.51875 4.41563,-1.51875z M6.31875,7.58437l10.09687,10.09687c-1.21992,0.94922 -2.75977,1.51875 -4.41563,1.51875c-3.95859,0 -7.2,-3.24141 -7.2,-7.2c0,-1.65586 0.56953,-3.1957 1.51875,-4.41563z"/></g></g><g fill="none" font-family="sans-serif" font-weight="normal" font-size="12"/></g></g></g></g></g></svg>

+ 10 - 0
src/directives/avatar.ts

@@ -102,6 +102,11 @@ export default [
                         && !this.highResolution
                         && (this.receiver as threema.ContactReceiver).identityType === threema.IdentityType.Work;
                 };
+                this.showBlocked = () => {
+                    return this.type === 'contact'
+                        && !this.highResolution
+                        && (this.receiver as threema.ContactReceiver).isBlocked;
+                };
             }],
             template: `
                 <div class="avatar" ng-class="ctrl.avatarClass()">
@@ -113,6 +118,11 @@ export default [
                             'title': 'messenger.THREEMA_WORK_CONTACT'}">
                         <img src="img/ic_work_round.svg" alt="Threema Work user">
                     </div>
+                    <div class="blocked-indicator"  ng-if="ctrl.showBlocked()"
+                        translate-attr="{'aria-label': 'messenger.THREEMA_BLOCKED_RECEIVER',
+                            'title': 'messenger.THREEMA_BLOCKED_RECEIVER'}">
+                        <img src="img/ic_blocked_24px.svg" alt="blocked icon"/>
+                    </div>
                     <img
                          ng-class="ctrl.avatarClass()"
                          ng-style="{ 'background-color': ctrl.backgroundColor }"

+ 1 - 1
src/directives/message_icon.ts

@@ -50,7 +50,7 @@ export default [
                 this.icon = getIcon(this.message.type);
             }],
             template: `
-                <img ng-if="ctrl.icon !== null" ng-src="img/{{ ctrl.icon }}" alt="{{ ctrl.message.type }} icon">
+                <img ng-if="ctrl.icon !== null" ng-src="img/{{ ctrl.icon }}" alt="{{ ctrl.message.type }} icon" />
             `,
         };
     },

+ 4 - 0
src/partials/messenger.receiver/contact.html

@@ -12,6 +12,10 @@
 				<dd>
 					<span class="complex-values">
 						<span>{{ctrl.receiver.id}}</span>
+						<span class="indicator-icon" ng-if="ctrl.showBlocked()"
+							  translate-attr="{'aria-label': 'messenger.THREEMA_BLOCKED_RECEIVER'}">
+								(<span translate>messenger.THREEMA_BLOCKED_RECEIVER</span>)
+						</span>
 						<span class="indicator-icon" ng-if="ctrl.isWorkReceiver"
 							  translate-attr="{'aria-label': 'messenger.THREEMA_WORK_CONTACT',
 								'title': 'messenger.THREEMA_WORK_CONTACT'}">

+ 3 - 0
src/partials/messenger.ts

@@ -938,6 +938,7 @@ class ReceiverDetailController {
     private hasSystemEmails = false;
     private hasSystemPhones = false;
     private isWorkReceiver = false;
+    private showBlocked = () => false;
 
     private controllerModel: threema.ControllerModel;
 
@@ -989,6 +990,8 @@ class ReceiverDetailController {
                     }
                 },
             );
+
+            this.showBlocked = () => contactReceiver.isBlocked;
         }
 
         switch (this.receiver.type) {

+ 13 - 0
src/sass/components/_avatar.scss

@@ -55,4 +55,17 @@
         }
     }
 
+    // If a receiver is "blocked"
+    .blocked-indicator {
+        position: absolute;
+        $indicator-size: 18px;
+        position: absolute;
+        top: 48px - $indicator-size;
+        right: 0;
+        img {
+            width: $indicator-size;
+            height: $indicator-size;
+        }
+    }
+
 }

+ 10 - 1
src/services/webclient.ts

@@ -884,7 +884,13 @@ export class WebClientService {
                        message: threema.MessageData): Promise<Promise<any>> {
         return new Promise<any> (
             (resolve, reject) => {
-
+                // Try to load receiver object
+                let receiverObject = this.receivers.getData(receiver);
+                // Check blocked flag
+                if (receiverObject.type === 'contact'
+                    && (receiverObject as threema.ContactReceiver).isBlocked) {
+                    return reject(this.$translate.instant('error.CONTACT_BLOCKED'));
+                }
                 // Decide on subtype
                 let subType;
                 switch (type) {
@@ -1002,6 +1008,9 @@ export class WebClientService {
                         case 'file_too_large':
                             errorMessage = this.$translate.instant('error.FILE_TOO_LARGE');
                             break;
+                        case 'blocked':
+                            errorMessage = this.$translate.instant('error.CONTACT_BLOCKED');
+                            break;
                         default:
                             errorMessage = this.$translate.instant('error.ERROR_OCCURRED');
                     }

+ 3 - 0
src/threema.d.ts

@@ -223,6 +223,9 @@ declare namespace threema {
         // Only relevant for Threema Work users.
         isWork?: boolean;
 
+        // Whether this contact is blocked
+        isBlocked?: boolean;
+
         // The identity type.
         // 0 - Regular Threema user.
         // 1 - Threema Work user.