Просмотр исходного кода

Fix updating of message caption (#638)

The caption may change for example when receiving an image message on
Android. Because the internet connection may be slow, a create/message
will be sent initially (before downloading the image from the blob
server) without thumbnail and without caption (because the caption is
contained in the image EXIF data). Once the image is downloaded and
processed, an update will be sent with the caption.
Danilo Bargen 6 лет назад
Родитель
Сommit
cf5ae16287

+ 4 - 3
src/directives/latest_message.html

@@ -17,9 +17,10 @@
               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.conversation.latestMessage"></span>
+        <eee-message-icon
+                ng-show="ctrl.showIcon()"
+                class="message-icon"
+                eee-message="ctrl.conversation.latestMessage"></eee-message-icon>
 
         <!-- For voip status messages -->
         <eee-message-voip-status

+ 7 - 6
src/directives/latest_message.ts

@@ -28,7 +28,7 @@ export default [
             restrict: 'EA',
             scope: {},
             bindToController: {
-                conversation: '<conversation',
+                conversation: '<',
             },
             controllerAs: 'ctrl',
             controller: [function() {
@@ -49,12 +49,13 @@ export default [
                             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);
+                        } else {
+                            const showStatusIcon = messageService.showStatusIcon(
+                                this.conversation.latestMessage,
+                                this.conversation.receiver,
+                            );
+                            return showStatusIcon ? $filter('messageStateIcon')(this.conversation.latestMessage) : null;
                         }
-                        return null;
                     };
 
                     // Find sender of latest message

+ 19 - 1
src/directives/message_icon.ts

@@ -15,6 +15,8 @@
  * along with Threema Web. If not, see <http://www.gnu.org/licenses/>.
  */
 
+import {hasValue} from '../helpers';
+
 export default [
     function() {
         return {
@@ -23,6 +25,18 @@ export default [
             bindToController: {
                 message: '=eeeMessage',
             },
+            link: function(scope, elem, attrs) {
+                scope.$watch(
+                    () => scope.ctrl.message.id,
+                    (newId, oldId) => {
+                        // Register for message changes. When the ID changes, update the icon.
+                        // This prevents processing the message more than once.
+                        if (hasValue(newId) && newId !== oldId) {
+                            scope.ctrl.update();
+                        }
+                    },
+                );
+            },
             controllerAs: 'ctrl',
             controller: [function() {
                 // Return icon depending on message type.
@@ -48,10 +62,14 @@ export default [
                     }
                 };
 
-                this.$onInit = function() {
+                this.update = () => {
                     this.icon = getIcon(this.message.type);
                     this.altText = this.message.type + ' icon';
                 };
+
+                this.$onInit = function() {
+                    this.update();
+                };
             }],
             template: `
                 <img ng-if="ctrl.icon !== null" ng-src="img/{{ ctrl.icon }}" alt="{{ ctrl.altText }}">

+ 3 - 1
src/directives/message_media.ts

@@ -156,7 +156,9 @@ export default [
                         this.wasInView = inView;
 
                         if (!inView) {
-                            timeoutService.cancel(loadingThumbnailTimeout);
+                            if (loadingThumbnailTimeout !== null) {
+                                timeoutService.cancel(loadingThumbnailTimeout);
+                            }
                             this.thumbnailDownloading = false;
                             this.thumbnail = null;
                         } else {

+ 17 - 2
src/directives/message_text.ts

@@ -51,13 +51,27 @@ export default [
                 scope.$watch(
                     () => scope.ctrl.message.id,
                     (newId, oldId) => {
-                        // Register for message changes. When the ID changes, update the text.
+                        // Register for message ID changes. When it changes, update the text.
                         // This prevents processing the text more than once.
                         if (hasValue(newId) && newId !== oldId) {
                             scope.ctrl.updateText();
                         }
                     },
                 );
+                scope.$watch(
+                    () => scope.ctrl.message.caption,
+                    (newCaption, oldCaption) => {
+                        // Register for message caption changes. When it changes, update the text.
+                        //
+                        // Background: The caption may change because image messages may be sent from the
+                        // app before the image has been downloaded and parsed. That information
+                        // (thumbnail + caption) is sent later on as an update.
+                        if (hasValue(newCaption) && newCaption !== oldCaption) {
+                            scope.ctrl.updateText();
+                        }
+                    },
+                );
+
             },
             controllerAs: 'ctrl',
             controller: ['WebClientService', '$filter', function(webClientService: WebClientService, $filter: ng.IFilterService) {
@@ -89,8 +103,9 @@ export default [
                     const linkifyText = (this.linkify === undefined || this.linkify !== 'false');
 
                     // Process text once, apply all filter functions
+                    const text = getText(this.message);
                     this.text = processText(
-                        getText(this.message),
+                        text,
                         this.largeSingleEmoji,
                         multiLine,
                         linkifyText,