ソースを参照

Fix updating of latest message text

Prior to this fix, the latest message text was not updated in the
conversation list.
Danilo Bargen 6 年 前
コミット
f309cb68c5

+ 11 - 11
src/directives/latest_message.html

@@ -10,26 +10,26 @@
     </div>
 
     <!-- Left aligned message content -->
-    <div class="left no-draft no-typing no-hidden" ng-if="ctrl.message">
+    <div class="left no-draft no-typing no-hidden" ng-if="ctrl.conversation.latestMessage">
 
         <!-- If this receiver is a group, show contact name that sent last message. -->
         <span eee-message-contact
-              ng-if="ctrl.isGroup" eee-contact="ctrl.contact"></span>
+              ng-if="ctrl.isGroup" eee-contact="ctrl.getContact()"></span>
 
         <!-- For non-text-messages, show an icon. -->
         <span eee-message-icon
-              ng-show="ctrl.showIcon" class="message-icon"
-              eee-message="ctrl.message"></span>
+              ng-show="ctrl.showIcon()" class="message-icon"
+              eee-message="ctrl.conversation.latestMessage"></span>
 
         <!-- For voip status messages -->
         <eee-message-voip-status
-                ng-if="ctrl.showVoipInfo"
+                ng-if="ctrl.showVoipInfo()"
                 class="message-voip-status"
-                eee-message="ctrl.message">
+                eee-message="ctrl.conversation.latestMessage">
         </eee-message-voip-status>
 
         <!-- For text-messages, show message text excerpt. -->
-        <span eee-message-text class="message-text" eee-message="ctrl.message" multi-line="false" linkify="false"></span>
+        <span eee-message-text class="message-text" message="ctrl.conversation.latestMessage" multi-line="false" linkify="false"></span>
 
     </div>
     <div class="left hidden no-typing">
@@ -43,11 +43,11 @@
     <div class="right">
         <span class="no-draft no-hidden">
             <span eee-message-date
-                  class="message-date" eee-message="ctrl.message"></span>
+                  class="message-date" eee-message="ctrl.conversation.latestMessage"></span>
 
-            <span class="message-state" ng-show="ctrl.statusIcon">
-                 <i class="material-icons md-medium-dark md-14 {{ctrl.message.state}}">
-                     {{ ctrl.statusIcon }}
+            <span class="message-state" ng-show="ctrl.getStatusIcon()">
+                 <i class="material-icons md-medium-dark md-14 {{ctrl.conversation.latestMessage.state}}">
+                     {{ ctrl.getStatusIcon() }}
                  </i>
             </span>
         </span>

+ 38 - 45
src/directives/latest_message.ts

@@ -28,71 +28,64 @@ export default [
             restrict: 'EA',
             scope: {},
             bindToController: {
-                type: '=eeeType',
-                message: '=eeeMessage',
-                receiver: '=eeeReceiver',
+                conversation: '<conversation',
             },
             controllerAs: 'ctrl',
             controller: [function() {
                 this.$onInit = function() {
-
                     // Conversation properties
-                    this.isGroup = this.type as threema.ReceiverType === 'group';
-                    this.isDistributionList = !this.isGroup
-                        && this.type as threema.ReceiverType === 'distributionList';
+                    this.isGroup = this.conversation.type === 'group';
+                    this.isDistributionList = !this.isGroup && this.conversation.type === 'distributionList';
 
-                    this.showVoipInfo = this.message
-                        && (this.message as threema.Message).type === 'voipStatus';
+                    // Voip status
+                    this.showVoipInfo = () => this.conversation.latestMessage.type === 'voipStatus';
 
-                    if (this.showVoipInfo) {
-                        this.statusIcon = 'phone_locked';
-                    } else if (this.isGroup) {
-                        this.statusIcon = 'group';
-                    } else if (this.isDistributionList) {
-                        this.statusIcon = 'forum';
-                    } else if (!this.message.isOutbox) {
-                        this.statusIcon = 'reply';
-                    } else if (messageService.showStatusIcon(this.message, this.receiver)) {
-                        // Show status icon of incoming messages every time
-                        this.statusIcon = $filter('messageStateIcon')(this.message);
-                    } else {
-                        // Do not show a status icon
-                        this.statusIcon = null;
-                    }
+                    this.getStatusIcon = () => {
+                        if (this.showVoipInfo()) {
+                            return 'phone_locked';
+                        } else if (this.isGroup) {
+                            return 'group';
+                        } else if (this.isDistributionList) {
+                            return 'forum';
+                        } else if (!this.conversation.latestMessage.isOutbox) {
+                            return 'reply';
+                        } else if (messageService.showStatusIcon(
+                            this.conversation.latestMessage, this.conversation.receiver)
+                        ) {
+                            return $filter('messageStateIcon')(this.conversation.latestMessage);
+                        }
+                        return null;
+                    };
 
                     // Find sender of latest message
-                    this.contact = null;
-                    if (this.message) {
-                        this.contact = webClientService.contacts.get(
-                            getSenderIdentity(this.message, webClientService.me.id),
+                    this.getContact = () => {
+                        return webClientService.contacts.get(
+                            getSenderIdentity(
+                                (this.conversation as threema.Conversation).latestMessage,
+                                webClientService.me.id,
+                            ),
                         );
-                    }
+                    };
+                    const contact = this.getContact();
 
                     // Typing indicator
                     this.isTyping = () => false;
-                    if (this.isGroup === false
-                        && this.isDistributionList === false
-                        && this.contact !== null) {
-                        this.isTyping = () => {
-                            return webClientService.isTyping(this.contact);
-                        };
+                    if (this.isGroup === false && this.isDistributionList === false && contact !== null) {
+                        this.isTyping = () => webClientService.isTyping(contact);
                     }
 
-                    this.isHidden = () => {
-                        return this.receiver.locked;
-                    };
+                    this.isHidden = () => this.conversation.receiver.locked;
 
                     // Show...
-                    this.showIcon = this.message
-                        && this.message.type !== 'text'
-                        && this.message.type !== 'status';
-
-                    this.getDraft = () => {
-                        return webClientService.getDraft(this.receiver);
+                    this.showIcon = () => {
+                        const message = (this.conversation as threema.Conversation).latestMessage;
+                        return message.type !== 'text' && message.type !== 'status';
                     };
 
+                    // Drafts
+                    this.getDraft = () => webClientService.getDraft(this.conversation.receiver);
                     this.showDraft = () => {
-                        if (receiverService.isConversationActive(this.receiver)) {
+                        if (receiverService.isConversationActive(this.conversation.receiver)) {
                             // Don't show draft if conversation is active
                             return false;
                         }

+ 2 - 2
src/directives/message.html

@@ -41,7 +41,7 @@
         <eee-message-text
             ng-if="ctrl.showText"
             class="message-text"
-            eee-message="ctrl.message">
+            message="ctrl.message">
         </eee-message-text>
 
         <div class="message-info">
@@ -60,7 +60,7 @@
 <!-- Status messages -->
 <article ng-if="ctrl.isStatusMessage" class="message message-status">
     <div ng-if="ctrl.message.statusType == 'text'" class="message-body">
-        <eee-message-text class="message-text" eee-message="ctrl.message"></eee-message-text>
+        <eee-message-text class="message-text" message="ctrl.message"></eee-message-text>
     </div>
     <div ng-if="ctrl.message.statusType == 'firstUnreadMessage'" class="unread-separator">
         <div class="line"></div>

+ 48 - 22
src/directives/message_text.ts

@@ -17,37 +17,50 @@
 
 // tslint:disable:max-line-length
 
+import {hasValue} from '../helpers';
 import {WebClientService} from '../services/webclient';
 
+// Get text depending on type
+function getText(message: threema.Message): string {
+    switch (message.type) {
+        case 'text':
+            return message.body;
+        case 'location':
+            return message.location.description;
+        case 'file':
+            // Prefer caption for file messages, if available
+            if (message.caption && message.caption.length > 0) {
+                return message.caption;
+            }
+            return message.file.name;
+    }
+    return message.caption;
+}
+
 export default [
     function() {
         return {
             restrict: 'EA',
             scope: {},
             bindToController: {
-                message: '=eeeMessage',
+                message: '=',
                 multiLine: '@?multiLine',
                 linkify: '@?linkify',
             },
+            link: function(scope, elem, attrs) {
+                scope.$watch(
+                    () => scope.ctrl.message.id,
+                    (newId, oldId) => {
+                        // Register for message changes. When the ID changes, update the text.
+                        // This prevents processing the text more than once.
+                        if (hasValue(newId) && newId !== oldId) {
+                            scope.ctrl.updateText();
+                        }
+                    },
+                );
+            },
             controllerAs: 'ctrl',
             controller: ['WebClientService', '$filter', function(webClientService: WebClientService, $filter: ng.IFilterService) {
-                // Get text depending on type
-                function getText(message: threema.Message): string {
-                    switch (message.type) {
-                        case 'text':
-                            return message.body;
-                        case 'location':
-                            return message.location.description;
-                        case 'file':
-                            // Prefer caption for file messages, if available
-                            if (message.caption && message.caption.length > 0) {
-                                return message.caption;
-                            }
-                            return message.file.name;
-                    }
-                    return message.caption;
-                }
-
                 // TODO: Extract filters into helper functions
                 const escapeHtml = $filter('escapeHtml') as any;
                 const markify = $filter('markify') as any;
@@ -66,16 +79,29 @@ export default [
                     return nlToBr(maybeLinkified, multiLine);
                 }
 
-                this.enlargeSingleEmoji = webClientService.appConfig.largeSingleEmoji;
-
-                this.$onInit = function() {
+                /**
+                 * Text update function.
+                 */
+                this.updateText = () => {
                     // Because this.multiLine and this.linkify are bound using an `@` binding,
                     // they are either undefined or a string. Convert to boolean.
                     const multiLine = (this.multiLine === undefined || this.multiLine !== 'false');
                     const linkifyText = (this.linkify === undefined || this.linkify !== 'false');
 
                     // Process text once, apply all filter functions
-                    this.text = processText(getText(this.message), this.largeSingleEmoji, multiLine, linkifyText);
+                    this.text = processText(
+                        getText(this.message),
+                        this.largeSingleEmoji,
+                        multiLine,
+                        linkifyText,
+                    );
+                };
+
+                this.enlargeSingleEmoji = webClientService.appConfig.largeSingleEmoji;
+
+                this.$onInit = function() {
+                    // Process initial text
+                    this.updateText();
                 };
             }],
             template: `

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

@@ -105,9 +105,7 @@
                         <eee-latest-message
                             ng-if="!conversation.receiver.isTyping() && conversation.latestMessage"
                             ng-class="latest-message-text"
-                            eee-type="conversation.type"
-                            eee-receiver="conversation.receiver"
-                            eee-message="conversation.latestMessage"></eee-latest-message>
+                            conversation="conversation"></eee-latest-message>
                     </section>
                 </section>