diff --git a/client/lib/chatMessages.coffee b/client/lib/chatMessages.coffee index 682b0e97d6919..781cd93b3053c 100644 --- a/client/lib/chatMessages.coffee +++ b/client/lib/chatMessages.coffee @@ -3,34 +3,18 @@ wrapper = {} input = {} editing = {} - selfTyping = new ReactiveVar false - typingTimeout = {} - + init = -> wrapper = $(".messages-container").find(".wrapper") input = $(".input-message").get(0) - # self.scrollable = false - # wrapper.bind "scroll", -> - # scrollable() bindEvents() return - # isScrollable = -> - # self.scrollable - resize = -> dif = 60 + $(".messages-container").find("footer").outerHeight() $(".messages-box").css height: "calc(100% - #{dif}px)" - # scrollable = -> - # wrapper = $(".messages-container").find(".wrapper") - # top = wrapper.scrollTop() + wrapper.outerHeight() - # if top == wrapper.get(0).scrollHeight - # self.scrollable = true - # else - # self.scrollable = false - toPrevMessage = -> msgs = wrapper.get(0).querySelectorAll(".own:not(.system)") if msgs.length @@ -83,9 +67,6 @@ else editing.saved = input.value - # toBottom = -> - # ScrollListener.toBottom() - send = (rid, input) -> if _.trim(input.value) isnt '' KonchatNotification.removeRoomNotification(rid) @@ -109,30 +90,18 @@ startTyping = (rid, input) -> if _.trim(input.value) isnt '' - unless typingTimeout?[rid] - if Meteor.userId()? - selfTyping.set true - Meteor.call 'typingStatus', rid, true - typingTimeout[rid] = Meteor.setTimeout -> - stopTyping(rid) - , 10000 + MsgTyping.start(rid) else - stopTyping(rid) + MsgTyping.stop(rid) stopTyping = (rid) -> - selfTyping.set false - if typingTimeout?[rid]? - clearTimeout(typingTimeout[rid]) - typingTimeout[rid] = null - - Meteor.call 'typingStatus', rid, false + MsgTyping.stop(rid) bindEvents = -> if wrapper?.length $(".input-message").autogrow postGrowCallback: -> resize() - # toBottom() if self.scrollable keyup = (rid, event) -> input = event.currentTarget @@ -194,13 +163,10 @@ RoomHistoryManager.clear rid - # isScrollable: isScrollable - # toBottom: toBottom keydown: keydown keyup: keyup deleteMsg: deleteMsg send: send init: init edit: edit - selfTyping: selfTyping -)() +)() \ No newline at end of file diff --git a/client/lib/collections.coffee b/client/lib/collections.coffee index 320a0ce5a0fd0..9e22025520645 100644 --- a/client/lib/collections.coffee +++ b/client/lib/collections.coffee @@ -4,7 +4,6 @@ @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/lib/msgTyping.coffee b/client/lib/msgTyping.coffee new file mode 100644 index 0000000000000..57291218b6415 --- /dev/null +++ b/client/lib/msgTyping.coffee @@ -0,0 +1,63 @@ +@MsgTyping = do -> + stream = new Meteor.Stream 'typing' + timeout = 15000 + timeouts = {} + renew = true + renewTimeout = 10000 + selfTyping = new ReactiveVar false + usersTyping = {} + + addStream = (room) -> + unless usersTyping[room]? + usersTyping[room] = { users: new ReactiveVar {} } + stream.on room, (typing) -> + unless typing.username is Meteor.user()?.username + if typing.start + console.log 'start', typing + users = usersTyping[room].users.get() + users[typing.username] = Meteor.setTimeout -> + delete users[typing.username] + , timeout + usersTyping[room].users.set users + else if typing.stop + console.log 'stop', typing + users = usersTyping[room].users.get() + delete users[typing.username] + usersTyping[room].users.set users + + Tracker.autorun -> + addStream Session.get 'openedRoom' + + start = (room) -> + return unless renew + + setTimeout -> + renew = true + , renewTimeout + + renew = false + selfTyping.set true + stream.emit 'typing', { room: room, username: Meteor.user().username, start: true } + clearTimeout timeouts[room] + timeouts[room] = Meteor.setTimeout -> + stop(room) + , timeout + + stop = (room) -> + renew = true + selfTyping.set false + if timeouts?[room]? + clearTimeout(timeouts[room]) + timeouts[room] = null + stream.emit 'typing', { room: room, username: Meteor.user().username, stop: true } + + get = (room) -> + users = usersTyping[room].users.get() + return _.keys(users) or [] + + return { + start: start + stop: stop + get: get + selfTyping: selfTyping + } \ No newline at end of file diff --git a/client/startup/startup.coffee b/client/startup/startup.coffee index 4cea1cd367f0d..c7e54589996aa 100644 --- a/client/startup/startup.coffee +++ b/client/startup/startup.coffee @@ -3,9 +3,6 @@ Meteor.startup -> UserPresence.start() Meteor.subscribe("activeUsers") - Tracker.autorun -> - Meteor.subscribe 'typing', Session.get 'openedRoom' - Session.setDefault('flexOpened', false) Session.setDefault('AvatarRandom', 0) diff --git a/client/views/app/room.coffee b/client/views/app/room.coffee index 5b6ad2e04cfa7..8de2d8cf6dbc8 100644 --- a/client/views/app/room.coffee +++ b/client/views/app/room.coffee @@ -48,36 +48,29 @@ Template.room.helpers console.log 'room.helpers roomContainerId' if window.rocketDebug return "room-container-#{this._id}" - showTyping: -> - console.log 'room.helpers showTyping' if window.rocketDebug - return this.t is 't' - - typing: -> - console.log 'room.helpers typing' if window.rocketDebug - return this.u._id isnt Meteor.userId() - usersTyping: -> console.log 'room.helpers usersTyping' if window.rocketDebug - messages = ChatTyping.find({ rid: this._id, 'u._id': { $ne: Meteor.userId() } }).fetch() - if messages.length is 0 + users = MsgTyping.get @_id + if users.length is 0 return - if messages.length is 1 + if users.length is 1 return { multi: false - selfTyping: ChatMessages.selfTyping.get() - users: messages[0].u.username + selfTyping: MsgTyping.selfTyping.get() + users: users[0] } - usernames = _.map messages, (message) -> return message.u.username + # usernames = _.map messages, (message) -> return message.u.username - last = usernames.pop() - if messages.length > 4 + last = users.pop() + if users.length > 4 last = t('others') - usernames = usernames.join(', ') + # else + usernames = users.join(', ') usernames = [usernames, last] return { multi: true - selfTyping: ChatMessages.selfTyping.get() + selfTyping: MsgTyping.selfTyping.get() users: usernames.join " #{t 'and'} " } @@ -189,15 +182,6 @@ Template.room.helpers console.log 'room.helpers flexOpened' if window.rocketDebug return 'opened' if Session.equals('flexOpened', true) - flexOpenedRTC1: -> - console.log 'room.helpers flexOpenedRTC1' if window.rocketDebug - return 'layout1' if Session.equals('flexOpenedRTC1', true) - - flexOpenedRTC2: -> - console.log 'room.helpers flexOpenedRTC2' if window.rocketDebug - return 'layout2' if Session.equals('flexOpenedRTC2', true) - - arrowPosition: -> console.log 'room.helpers arrowPosition' if window.rocketDebug return 'left' unless Session.equals('flexOpened', true) @@ -267,33 +251,14 @@ Template.room.helpers return Session.get('remoteVideoUrl') selfVideoUrl: -> - Meteor.defer -> - $('video.video-self')[0]?.muted = true; return Session.get('selfVideoUrl') - rtcLayout1: -> - return (Session.get('rtcLayoutmode') == 1 ? true: false); - - rtcLayout2: -> - return (Session.get('rtcLayoutmode') == 2 ? true: false); - - rtcLayout3: -> - return (Session.get('rtcLayoutmode') == 3 ? true: false); - - noRtcLayout: -> - return (!Session.get('rtcLayoutmode') || (Session.get('rtcLayoutmode') == 0) ? true: false); - Template.room.events "click .flex-tab .more": (event) -> console.log 'room click .flex-tab .more' if window.rocketDebug - if (Session.get('flexOpened')) - Session.set('rtcLayoutmode', 0) - Session.set('flexOpened',false) - else - Session.set('flexOpened', true) - + Session.set('flexOpened', !Session.get('flexOpened')) 'click .chat-new-messages': (event) -> console.log 'room click .chat-new-messages' if window.rocketDebug @@ -313,7 +278,7 @@ Template.room.events event.preventDefault() Meteor.call 'joinRoom', this._id - "click .burger": -> + "click .burger": -> console.log 'room click .burger' if window.rocketDebug chatContainer = $("#rocket-chat") if chatContainer.hasClass("menu-closed") @@ -383,36 +348,6 @@ Template.room.events Session.set('flexOpened', true) Session.set('showUserInfo', $(e.currentTarget).data('username')) - "click .flex-tab .video-remote" : (e) -> - console.log 'room click .flex-tab .video-remote' if window.rocketDebug - if (Session.get('flexOpened')) - if (!Session.get('rtcLayoutmode')) - Session.set('rtcLayoutmode', 1) - else - t = Session.get('rtcLayoutmode') - t = (t + 1) % 4 - console.log 'setting rtcLayoutmode to ' + t if window.rocketDebug - Session.set('rtcLayoutmode', t) - - "click .flex-tab .video-self" : (e) -> - console.log 'room click .flex-tab .video-self' if window.rocketDebug - if (Session.get('rtcLayoutmode') == 3) - console.log 'video-self clicked in layout3' if window.rocketDebug - i = document.getElementById("fullscreendiv") - if i.requestFullscreen - i.requestFullscreen() - else - if i.webkitRequestFullscreen - i.webkitRequestFullscreen() - else - if i.mozRequestFullScreen - i.mozRequestFullScreen() - else - if i.msRequestFullscreen - i.msRequestFullscreen() - - - 'click .user-card-message': (e) -> console.log 'room click .user-card-message' if window.rocketDebug roomData = Session.get('roomData' + this._arguments[1].rid) @@ -520,7 +455,6 @@ Template.room.events ChatMessages.deleteMsg(msg) 'click .start-video': (event) -> - webrtc.to = Router.current().params._id.replace(Meteor.userId(), '') webrtc.start(true) 'click .stop-video': (event) -> @@ -529,6 +463,7 @@ Template.room.events Template.room.onCreated -> console.log 'room.onCreated' if window.rocketDebug # this.scrollOnBottom = true + # this.typing = new msgTyping this.data._id this.showUsersOffline = new ReactiveVar false this.atBottom = true @@ -551,10 +486,6 @@ Template.room.onRendered -> newMessage.className = "new-message not" , 100 - wrapper.addEventListener 'touchmove', -> - template.atBottom = false - onscroll() - wrapper.addEventListener 'mousewheel', -> template.atBottom = false onscroll() @@ -567,6 +498,7 @@ Template.room.onRendered -> # salva a data da renderização para exibir alertas de novas mensagens $.data(this.firstNode, 'renderedAt', new Date) + webrtc.to = this.data._id.replace(Meteor.userId(), '') webrtc.onRemoteUrl = (url) -> Session.set('flexOpened', true) Session.set('remoteVideoUrl', url) diff --git a/packages/rocketchat-lib/server/sendMessage.coffee b/packages/rocketchat-lib/server/sendMessage.coffee index bd3b58278a1ef..2b720c25c5f61 100644 --- a/packages/rocketchat-lib/server/sendMessage.coffee +++ b/packages/rocketchat-lib/server/sendMessage.coffee @@ -30,15 +30,6 @@ RocketChat.sendMessage = (user, message, room) -> RocketChat.callbacks.run 'afterSaveMessage', message - ### - Remove the typing record - ### - Meteor.defer -> - - ChatTyping.remove - rid: message.rid - 'u._id': message.u._id - ### Update all the room activity tracker fields ### diff --git a/server/lib/collections.coffee b/server/lib/collections.coffee index fee6d591a6a20..5bc7b20bf634b 100644 --- a/server/lib/collections.coffee +++ b/server/lib/collections.coffee @@ -1,4 +1,3 @@ @ChatMessage = new Meteor.Collection 'data.ChatMessage' @ChatRoom = new Meteor.Collection 'data.ChatRoom' @ChatSubscription = new Meteor.Collection 'data.ChatSubscription' -@ChatTyping = new Meteor.Collection 'data.ChatTyping' diff --git a/server/methods/getAvatarSuggestion.coffee b/server/methods/getAvatarSuggestion.coffee index c2664a5cdab19..0224b5ae0f165 100644 --- a/server/methods/getAvatarSuggestion.coffee +++ b/server/methods/getAvatarSuggestion.coffee @@ -51,7 +51,7 @@ Meteor.methods getAvatarSuggestion: -> if not Meteor.userId() - throw new Meteor.Error 203, '[methods] typingStatus -> Usuário não logado' + throw new Meteor.Error 203, '[methods] getAvatarSuggestion -> Usuário não logado' user = Meteor.user() diff --git a/server/methods/getUsernameSuggestion.coffee b/server/methods/getUsernameSuggestion.coffee index 1b2e61eee53a7..152fc5ca966f2 100644 --- a/server/methods/getUsernameSuggestion.coffee +++ b/server/methods/getUsernameSuggestion.coffee @@ -59,7 +59,7 @@ usernameIsAvaliable = (username) -> Meteor.methods getUsernameSuggestion: -> if not Meteor.userId() - throw new Meteor.Error 203, '[methods] typingStatus -> Usuário não logado' + throw new Meteor.Error 203, '[methods] getUsernameSuggestion -> Usuário não logado' user = Meteor.user() return generateSuggestion(user) diff --git a/server/methods/typingStatus.coffee b/server/methods/typingStatus.coffee deleted file mode 100644 index 409ea8282d3c0..0000000000000 --- a/server/methods/typingStatus.coffee +++ /dev/null @@ -1,23 +0,0 @@ -Meteor.methods - typingStatus: (rid, start) -> - if not Meteor.userId() - throw new Meteor.Error('invalid-user', "[methods] typingStatus -> Invalid user") - - console.log '[methods] typingStatus -> '.green, 'userId:', Meteor.userId(), 'arguments:', arguments - - filter = - rid: rid - $and: [{'u._id': Meteor.userId()}] - - if start - msgData = - '$set': - expireAt: moment().add(30, 'seconds').toDate() - '$setOnInsert': - 'u._id': Meteor.userId() - 'u.username': Meteor.user().username - - ChatTyping.upsert(filter, msgData) - else - - ChatTyping.remove(filter) diff --git a/server/publications/typing.coffee b/server/publications/typing.coffee deleted file mode 100644 index 6e4c9736c7a87..0000000000000 --- a/server/publications/typing.coffee +++ /dev/null @@ -1,17 +0,0 @@ -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 diff --git a/server/startup/indexes.coffee b/server/startup/indexes.coffee index 2ab6ddf90248d..15230eddbbf70 100644 --- a/server/startup/indexes.coffee +++ b/server/startup/indexes.coffee @@ -15,7 +15,3 @@ Meteor.startup -> 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 ChatMessage._ensureIndex { '_deleted': 1 }, { sparse: 1 } 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 diff --git a/server/stream/streamBroadcast.coffee b/server/stream/streamBroadcast.coffee index 9d50da5c776c8..d1ad440cc901d 100644 --- a/server/stream/streamBroadcast.coffee +++ b/server/stream/streamBroadcast.coffee @@ -38,7 +38,6 @@ do (streamName, stream) -> emitters[streamName] = stream.emit stream.emit = (eventName, args...) -> - console.log 'stream.emit', eventName, args broadcast streamName, eventName, args emitters[streamName].apply {}, arguments @@ -52,3 +51,4 @@ Meteor.startup -> startStreamBroadcast 'webrtc.stream': webrtc.stream + 'typing': typingStream diff --git a/server/stream/typingStream.coffee b/server/stream/typingStream.coffee new file mode 100644 index 0000000000000..1746817ef33f9 --- /dev/null +++ b/server/stream/typingStream.coffee @@ -0,0 +1,10 @@ +@typingStream = new Meteor.Stream 'typing' + +typingStream.permissions.read -> + return true + +typingStream.permissions.write -> + return true + +typingStream.on 'typing', (typing) -> + typingStream.emit typing.room, _.pick(typing, 'username', 'start', 'stop')