Преглед изворни кода

Fix typing indicator logic (#380)

Previously it was possible that the typing indicator was sent even when
the typing state did not change.
Danilo Bargen пре 8 година
родитељ
комит
db4266b295
2 измењених фајлова са 34 додато и 23 уклоњено
  1. 32 4
      src/directives/compose_area.ts
  2. 2 19
      src/partials/messenger.ts

+ 32 - 4
src/directives/compose_area.ts

@@ -116,6 +116,34 @@ export default [
                     };
                 })();
 
+                // Typing events
+                let stopTypingTimer: ng.IPromise<void> = null;
+                function stopTyping() {
+                    // We can only stop typing of the timer is set (meaning
+                    // that we started typing earlier)
+                    if (stopTypingTimer !== null) {
+                        // Cancel timer
+                        $timeout.cancel(stopTypingTimer);
+                        stopTypingTimer = null;
+
+                        // Send stop typing message
+                        scope.stopTyping();
+                    }
+                }
+                function startTyping() {
+                    if (stopTypingTimer === null) {
+                        // If the timer wasn't set previously, we just
+                        // started typing!
+                        scope.startTyping();
+                    } else {
+                        // Cancel timer, we'll re-create it
+                        $timeout.cancel(stopTypingTimer);
+                    }
+
+                    // Define a timeout to send the stopTyping event
+                    stopTypingTimer = $timeout(stopTyping, 10000);
+                }
+
                 // Process a DOM node recursively and extract text from compose area.
                 function getText() {
                     let text = '';
@@ -205,7 +233,7 @@ export default [
                             composeDiv[0].focus();
 
                             // Send stopTyping event
-                            scope.stopTyping();
+                            stopTyping();
 
                             // Clear draft
                             scope.onTyping('');
@@ -253,9 +281,9 @@ export default [
 
                         // Update typing information
                         if (composeAreaIsEmpty()) {
-                            scope.stopTyping();
+                            stopTyping();
                         } else {
-                            scope.startTyping();
+                            startTyping();
                         }
                         scope.onTyping(getText());
 
@@ -663,7 +691,7 @@ export default [
                 composeDiv.on('selectionchange', updateCaretPosition);
 
                 // When switching chat, send stopTyping message
-                scope.$on('$destroy', scope.stopTyping);
+                scope.$on('$destroy', stopTyping);
 
                 // Handle paste event
                 composeDiv.on('paste', onPaste);

+ 2 - 19
src/partials/messenger.ts

@@ -187,7 +187,6 @@ class ConversationController {
     // Scrolling
     public showScrollJump: boolean = false;
 
-    private stopTypingTimer: ng.IPromise<void> = null;
     public receiver: threema.Receiver;
     public type: threema.ReceiverType;
     public message: string = '';
@@ -550,30 +549,14 @@ class ConversationController {
      * We started typing.
      */
     public startTyping = () => {
-        if (this.stopTypingTimer === null) {
-            // Notify app
-            this.webClientService.sendMeIsTyping(this.$stateParams, true);
-        } else {
-            // Stop existing timer
-            this.$timeout.cancel(this.stopTypingTimer);
-        }
-
-        // Define a timeout to send the stopTyping event
-        this.stopTypingTimer = this.$timeout(() => {
-            this.stopTyping();
-        }, 10000);
+        // Notify app
+        this.webClientService.sendMeIsTyping(this.$stateParams, true);
     }
 
     /**
      * We stopped typing.
      */
     public stopTyping = () => {
-        // Cancel timer if present
-        if (this.stopTypingTimer !== null) {
-            this.$timeout.cancel(this.stopTypingTimer);
-            this.stopTypingTimer = null;
-        }
-
         // Notify app
         this.webClientService.sendMeIsTyping(this.$stateParams, false);
     }