From 46042d995bc553a10513c527aba106e1b92d04d4 Mon Sep 17 00:00:00 2001
From: Florian Orben <florian.orben@gmail.com>
Date: Sun, 25 Oct 2015 02:00:55 +0100
Subject: PLT-703: Support multiple users being shown as typing underneath
 input boxes.

---
 web/react/components/msg_typing.jsx | 49 +++++++++++++++++++++++++------------
 1 file changed, 33 insertions(+), 16 deletions(-)

(limited to 'web/react/components/msg_typing.jsx')

diff --git a/web/react/components/msg_typing.jsx b/web/react/components/msg_typing.jsx
index 1bd23c55c..42ae4bcc4 100644
--- a/web/react/components/msg_typing.jsx
+++ b/web/react/components/msg_typing.jsx
@@ -11,11 +11,11 @@ export default class MsgTyping extends React.Component {
     constructor(props) {
         super(props);
 
-        this.timer = null;
-        this.lastTime = 0;
-
         this.onChange = this.onChange.bind(this);
+        this.getTypingText = this.getTypingText.bind(this);
+        this.componentWillReceiveProps = this.componentWillReceiveProps.bind(this);
 
+        this.typingUsers = {};
         this.state = {
             text: ''
         };
@@ -27,7 +27,7 @@ export default class MsgTyping extends React.Component {
 
     componentWillReceiveProps(newProps) {
         if (this.props.channelId !== newProps.channelId) {
-            this.setState({text: ''});
+            this.setState({text: this.getTypingText()});
         }
     }
 
@@ -36,27 +36,44 @@ export default class MsgTyping extends React.Component {
     }
 
     onChange(msg) {
+        let username = 'Someone';
         if (msg.action === SocketEvents.TYPING &&
                 this.props.channelId === msg.channel_id &&
                 this.props.parentId === msg.props.parent_id) {
-            this.lastTime = new Date().getTime();
-
-            var username = 'Someone';
             if (UserStore.hasProfile(msg.user_id)) {
                 username = UserStore.getProfile(msg.user_id).username;
             }
 
-            this.setState({text: username + ' is typing...'});
-
-            if (!this.timer) {
-                this.timer = setInterval(function myTimer() {
-                    if ((new Date().getTime() - this.lastTime) > 8000) {
-                        this.setState({text: ''});
-                    }
-                }.bind(this), 3000);
+            if (this.typingUsers[username]) {
+                clearTimeout(this.typingUsers[username]);
             }
+
+            this.typingUsers[username] = setTimeout(function myTimer(user) {
+                delete this.typingUsers[user];
+                this.setState({text: this.getTypingText()});
+            }.bind(this, username), Constants.UPDATE_TYPING_MS);
+
+            this.setState({text: this.getTypingText()});
         } else if (msg.action === SocketEvents.POSTED && msg.channel_id === this.props.channelId) {
-            this.setState({text: ''});
+            if (UserStore.hasProfile(msg.user_id)) {
+                username = UserStore.getProfile(msg.user_id).username;
+            }
+            clearTimeout(this.typingUsers[username]);
+            delete this.typingUsers[username];
+            this.setState({text: this.getTypingText()});
+        }
+    }
+
+    getTypingText() {
+        let users = Object.keys(this.typingUsers);
+        switch (users.length) {
+        case 0:
+            return '';
+        case 1:
+            return users[0] + ' is typing...';
+        default:
+            const last = users.pop();
+            return users.join(', ') + ' and ' + last + ' are typing...';
         }
     }
 
-- 
cgit v1.2.3-1-g7c22


From 9a4d648c9b9a6c78cd2a171b665bc5aa9ade3634 Mon Sep 17 00:00:00 2001
From: Florian Orben <florian.orben@gmail.com>
Date: Mon, 26 Oct 2015 17:44:29 +0100
Subject: rename getTypingText to updateTypingText and set component's state in
 it

---
 web/react/components/msg_typing.jsx | 26 ++++++++++++++++----------
 1 file changed, 16 insertions(+), 10 deletions(-)

(limited to 'web/react/components/msg_typing.jsx')

diff --git a/web/react/components/msg_typing.jsx b/web/react/components/msg_typing.jsx
index 42ae4bcc4..ccf8a2445 100644
--- a/web/react/components/msg_typing.jsx
+++ b/web/react/components/msg_typing.jsx
@@ -12,7 +12,7 @@ export default class MsgTyping extends React.Component {
         super(props);
 
         this.onChange = this.onChange.bind(this);
-        this.getTypingText = this.getTypingText.bind(this);
+        this.updateTypingText = this.updateTypingText.bind(this);
         this.componentWillReceiveProps = this.componentWillReceiveProps.bind(this);
 
         this.typingUsers = {};
@@ -27,7 +27,7 @@ export default class MsgTyping extends React.Component {
 
     componentWillReceiveProps(newProps) {
         if (this.props.channelId !== newProps.channelId) {
-            this.setState({text: this.getTypingText()});
+            this.updateTypingText();
         }
     }
 
@@ -50,31 +50,37 @@ export default class MsgTyping extends React.Component {
 
             this.typingUsers[username] = setTimeout(function myTimer(user) {
                 delete this.typingUsers[user];
-                this.setState({text: this.getTypingText()});
+                this.updateTypingText();
             }.bind(this, username), Constants.UPDATE_TYPING_MS);
 
-            this.setState({text: this.getTypingText()});
+            this.updateTypingText();
         } else if (msg.action === SocketEvents.POSTED && msg.channel_id === this.props.channelId) {
             if (UserStore.hasProfile(msg.user_id)) {
                 username = UserStore.getProfile(msg.user_id).username;
             }
             clearTimeout(this.typingUsers[username]);
             delete this.typingUsers[username];
-            this.setState({text: this.getTypingText()});
+            this.updateTypingText();
         }
     }
 
-    getTypingText() {
-        let users = Object.keys(this.typingUsers);
+    updateTypingText() {
+        const users = Object.keys(this.typingUsers);
+        let text = '';
         switch (users.length) {
         case 0:
-            return '';
+            text = '';
+            break;
         case 1:
-            return users[0] + ' is typing...';
+            text = users[0] + ' is typing...';
+            break;
         default:
             const last = users.pop();
-            return users.join(', ') + ' and ' + last + ' are typing...';
+            text = users.join(', ') + ' and ' + last + ' are typing...';
+            break;
         }
+
+        this.setState({text});
     }
 
     render() {
-- 
cgit v1.2.3-1-g7c22

