From eab3f9bac91ae79185c420b7dbd20d98d4a9acd3 Mon Sep 17 00:00:00 2001 From: Marcelo Schmidt <marcelo.schmidt@konecty.com> Date: Thu, 2 Jul 2015 01:03:26 -0300 Subject: [PATCH] Replace typing messages. Insert into data.Typing instead of data.Messages and use ReactiveVar to determine if current user is typing. --- client/lib/RoomManager.coffee | 1 + client/lib/chatMessages.coffee | 4 ++ client/lib/collections.coffee | 1 + client/methods/typingStatus.coffee | 7 +-- client/views/app/room.coffee | 63 ++++++++++++++----- i18n/en.i18n.json | 1 + .../rocketchat-lib/server/sendMessage.coffee | 3 +- server/lib/collections.coffee | 1 + server/methods/receiveMessage.coffee | 4 +- server/methods/typingStatus.coffee | 7 +-- server/publications/typing.coffee | 17 +++++ server/startup/indexes.coffee | 4 ++ 12 files changed, 81 insertions(+), 32 deletions(-) create mode 100644 server/publications/typing.coffee diff --git a/client/lib/RoomManager.coffee b/client/lib/RoomManager.coffee index 75f27efc820..51dd360cc73 100644 --- a/client/lib/RoomManager.coffee +++ b/client/lib/RoomManager.coffee @@ -26,6 +26,7 @@ record.sub = [ Meteor.subscribe 'room', rid Meteor.subscribe 'messages', rid + Meteor.subscribe 'typing', rid ] record.ready = record.sub[0].ready() and record.sub[1].ready() diff --git a/client/lib/chatMessages.coffee b/client/lib/chatMessages.coffee index e9e2d03be9a..d73a1f626e6 100644 --- a/client/lib/chatMessages.coffee +++ b/client/lib/chatMessages.coffee @@ -3,6 +3,7 @@ wrapper = {} input = {} editing = {} + selfTyping = new ReactiveVar false init = -> wrapper = $(".messages-container").find(".wrapper") @@ -108,12 +109,14 @@ if _.trim(input.value) isnt '' unless self.typingTimeout if Meteor.userId()? + selfTyping.set true Meteor.call 'typingStatus', rid, true self.typingTimeout = Meteor.setTimeout -> stopTyping() , 30000 stopTyping = -> + selfTyping.set false self.typingTimeout = null bindEvents = -> @@ -181,4 +184,5 @@ send: send init: init edit: edit + selfTyping: selfTyping )() diff --git a/client/lib/collections.coffee b/client/lib/collections.coffee index aa2e8ebf1cd..347843497b3 100644 --- a/client/lib/collections.coffee +++ b/client/lib/collections.coffee @@ -4,6 +4,7 @@ @ChatRoom = new Meteor.Collection 'data.ChatRoom' @ChatSubscription = new Meteor.Collection 'data.ChatSubscription' @ChatMessage = new Meteor.Collection 'data.ChatMessage' +@ChatTyping = new Meteor.Collection 'data.ChatTyping' Meteor.startup -> ChatMessage.find().observe diff --git a/client/methods/typingStatus.coffee b/client/methods/typingStatus.coffee index 2ff27da7c76..ae2b38c8512 100644 --- a/client/methods/typingStatus.coffee +++ b/client/methods/typingStatus.coffee @@ -4,7 +4,6 @@ Meteor.methods throw new Meteor.Error 203, t('User_logged_out') filter = - t: 't' rid: rid $and: [{'u._id': Meteor.userId()}] @@ -12,12 +11,10 @@ Meteor.methods msgData = '$setOnInsert': - msg: '...' 'u._id': Meteor.userId() 'u.username': Meteor.user().username - ts: moment().add(1, 'years').toDate() - ChatMessage.upsert(filter, msgData) + ChatTyping.upsert(filter, msgData) else - ChatMessage.remove(filter) + ChatTyping.remove(filter) diff --git a/client/views/app/room.coffee b/client/views/app/room.coffee index 2801fa64d00..51a8dad1dbe 100644 --- a/client/views/app/room.coffee +++ b/client/views/app/room.coffee @@ -58,36 +58,65 @@ Template.room.helpers usersTyping: -> console.log 'room.helpers usersTyping' if window.rocketDebug - messages = ChatMessage.find { rid: this._id, t: 't' }, { sort: { ts: 1 } } - usernames = [] - selfTyping = false - messages.forEach (message) -> - if message.u._id is Meteor.userId() - selfTyping = true - else - username = message.u.username - if username? - usernames.push username - - if usernames.length is 0 + messages = ChatTyping.find({ rid: this._id, 'u._id': { $ne: Meteor.userId() } }).fetch() + if messages.length is 0 return - - if usernames.length is 1 + if messages.length is 1 return { multi: false - selfTyping: selfTyping - users: usernames[0] + selfTyping: ChatMessages.selfTyping.get() + users: messages[0].u.username } + usernames = _.map messages, (message) -> return message.u.username + last = usernames.pop() + if messages.length > 4 + last = t('others') + else usernames = usernames.join(', ') usernames = [usernames, last] return { multi: true - selfTyping: selfTyping + selfTyping: ChatMessages.selfTyping.get() users: usernames.join " #{t 'and'} " } + + # usernames = [] + # selfTyping = false + # total = 0 + # messages.forEach (message) -> + # total++ + # if message.u._id is Meteor.userId() + # selfTyping = true + # else + # username = message.u.username + # if username? + # usernames.push username + + # if usernames.length is 0 + # return + + # if usernames.length is 1 + # return { + # multi: false + # selfTyping: selfTyping + # users: usernames[0] + # } + + # last = usernames.pop() + # if total > 4 + # last = t('others') + + # usernames = usernames.join(', ') + # usernames = [usernames, last] + # return { + # multi: true + # selfTyping: selfTyping + # users: usernames.join " #{t 'and'} " + # } + roomName: -> console.log 'room.helpers roomName' if window.rocketDebug roomData = Session.get('roomData' + this._id) diff --git a/i18n/en.i18n.json b/i18n/en.i18n.json index 25fe6e04099..e45154ae300 100755 --- a/i18n/en.i18n.json +++ b/i18n/en.i18n.json @@ -90,6 +90,7 @@ "Nothing_found" : "Nothing found", "Online" : "Online", "Oops!" : "Oops", + "others": "others", "Password" : "Password", "Please_wait" : "Please wait", "Powered_by" : "Powered by", diff --git a/packages/rocketchat-lib/server/sendMessage.coffee b/packages/rocketchat-lib/server/sendMessage.coffee index 5628bb91739..540c60df1d1 100644 --- a/packages/rocketchat-lib/server/sendMessage.coffee +++ b/packages/rocketchat-lib/server/sendMessage.coffee @@ -34,9 +34,8 @@ RocketChat.sendMessage = (user, message, room) -> ### Meteor.defer -> - ChatMessage.remove + ChatTyping.remove rid: message.rid - t: 't' 'u._id': message.u._id ### diff --git a/server/lib/collections.coffee b/server/lib/collections.coffee index 5bc7b20bf63..5989a5cea75 100644 --- a/server/lib/collections.coffee +++ b/server/lib/collections.coffee @@ -1,3 +1,4 @@ @ChatMessage = new Meteor.Collection 'data.ChatMessage' @ChatRoom = new Meteor.Collection 'data.ChatRoom' @ChatSubscription = new Meteor.Collection 'data.ChatSubscription' +@ChatTyping = new Meteor.Collection 'data.ChatTyping' \ No newline at end of file diff --git a/server/methods/receiveMessage.coffee b/server/methods/receiveMessage.coffee index 3be6b1d6745..e5cfb59007e 100644 --- a/server/methods/receiveMessage.coffee +++ b/server/methods/receiveMessage.coffee @@ -108,14 +108,12 @@ Meteor.methods ### Save the message. If there was already a typing record, update it. ### - ChatMessage.upsert + ChatTyping.upsert rid: message.rid - t: 't' $and: [{ 'u._id': message.u._id }] , $set: message $unset: - t: 1 expireAt: 1 Meteor.defer -> diff --git a/server/methods/typingStatus.coffee b/server/methods/typingStatus.coffee index f57b359f3ad..409ea8282d3 100644 --- a/server/methods/typingStatus.coffee +++ b/server/methods/typingStatus.coffee @@ -6,7 +6,6 @@ Meteor.methods console.log '[methods] typingStatus -> '.green, 'userId:', Meteor.userId(), 'arguments:', arguments filter = - t: 't' rid: rid $and: [{'u._id': Meteor.userId()}] @@ -15,12 +14,10 @@ Meteor.methods '$set': expireAt: moment().add(30, 'seconds').toDate() '$setOnInsert': - msg: '...' - ts: moment().add(1, 'years').toDate() 'u._id': Meteor.userId() 'u.username': Meteor.user().username - ChatMessage.upsert(filter, msgData) + ChatTyping.upsert(filter, msgData) else - ChatMessage.remove(filter) + ChatTyping.remove(filter) diff --git a/server/publications/typing.coffee b/server/publications/typing.coffee new file mode 100644 index 00000000000..d7493098bcc --- /dev/null +++ b/server/publications/typing.coffee @@ -0,0 +1,17 @@ +Meteor.publish 'typing', (rid, start) -> + unless this.userId + return this.ready() + + console.log '[publish] typing ->'.green, 'rid:', rid, 'start:', start + + if typeof rid isnt 'string' + return this.ready() + + if not Meteor.call 'canAccessRoom', rid, this.userId + return this.ready() + + ChatTyping.find + rid: rid + 'u._id': { $ne: this.userId } + , + limit: 5 \ No newline at end of file diff --git a/server/startup/indexes.coffee b/server/startup/indexes.coffee index e58c9b75b44..72985526016 100644 --- a/server/startup/indexes.coffee +++ b/server/startup/indexes.coffee @@ -13,3 +13,7 @@ Meteor.startup -> try ChatMessage._ensureIndex { 'rid': 1, 'ts': 1 } catch e then console.log e try ChatMessage._ensureIndex { 'rid': 1, 't': 1, 'u._id': 1 } catch e then console.log e try ChatMessage._ensureIndex { 'expireAt': 1 }, { expireAfterSeconds: 0 } catch e then console.log e + + try ChatTyping._ensureIndex { 'rid': 1 } catch e then console.log e + try ChatTyping._ensureIndex { 'rid': 1, 'u._id': 1 } catch e then console.log e + try ChatTyping._ensureIndex { 'expireAt': 1 }, { expireAfterSeconds: 0 } catch e then console.log e -- GitLab