From 13fae7d4ec8baa50af653ec25340cdd4ca1c5c40 Mon Sep 17 00:00:00 2001 From: Reid Wakida Date: Fri, 21 Aug 2015 15:53:54 -1000 Subject: [PATCH] Fixes #547 where editing channel/group name crashed RoomManager's openRoom tracker Bug is a side effect of User friendly URLs #18. The commit changed Room subscription based on room id to room name.. It created a new room subscription, but didn't remove the old name from the RoomManager's openedRooms cache. Whenever the tracker ran, an 'undefined' room was returned because the old room name was invalid. Adds code that observes room name changes, closes the old room, and opens the new room via the RoomManager. There is still a small bug where the room name changed message is not displayed to the user who changed the name probably due to the message stream subscribing after the message was sent. --- client/lib/RoomHistoryManager.coffee | 6 +++- client/lib/RoomManager.coffee | 44 +++++++++++++++++++++++----- client/routes/roomRoute.coffee | 7 ++++- client/startup/roomObserve.coffee | 30 +++++++++++++++++-- 4 files changed, 76 insertions(+), 11 deletions(-) diff --git a/client/lib/RoomHistoryManager.coffee b/client/lib/RoomHistoryManager.coffee index 2b3beb9069558..9ad68e566dcb8 100644 --- a/client/lib/RoomHistoryManager.coffee +++ b/client/lib/RoomHistoryManager.coffee @@ -30,10 +30,14 @@ ts = new Date Meteor.call 'loadHistory', rid, ts, limit, 0, (err, result) -> + if err + console.log err + return + ChatMessage.insert item for item in result room.isLoading.set false room.loaded += result.length - if result.length < limit + if result?.length < limit room.hasMore.set false hasMore = (rid) -> diff --git a/client/lib/RoomManager.coffee b/client/lib/RoomManager.coffee index 359d910ab0ce9..fd4c087f4c402 100644 --- a/client/lib/RoomManager.coffee +++ b/client/lib/RoomManager.coffee @@ -43,6 +43,12 @@ Meteor.startup -> RoomHistoryManager.clear openedRooms[typeName].rid ChatMessage.remove rid: openedRooms[typeName].rid + remove = (typeName) -> + # this is called when the room name is changed and the cached room is no longer valid + if openedRooms[typeName] + close typeName + delete openedRooms[typeName] + computation = Tracker.autorun -> for typeName, record of openedRooms when record.active is true do (typeName, record) -> @@ -68,15 +74,15 @@ Meteor.startup -> room = ChatRoom.findOne query, { reactive: false } - openedRooms[typeName].rid = room._id + if room + openedRooms[typeName].rid = room._id + msgStream.on openedRooms[typeName].rid, (msg) -> + ChatMessage.upsert { _id: msg._id }, msg - msgStream.on openedRooms[typeName].rid, (msg) -> - ChatMessage.upsert { _id: msg._id }, msg + deleteMsgStream.on openedRooms[typeName].rid, (msg) -> + ChatMessage.remove _id: msg._id - deleteMsgStream.on openedRooms[typeName].rid, (msg) -> - ChatMessage.remove _id: msg._id - - Dep.changed() + Dep.changed() setRoomExpireExcept = (except) -> @@ -126,6 +132,27 @@ Meteor.startup -> room = openedRooms[typeName] return room?.dom? + refreshDomOfRoom = (typeName, rid) -> + mainNode = document.querySelector('.main-content') + if mainNode? + for child in mainNode.children + mainNode.removeChild child if child? + roomDom = getDomOfRoom(typeName, rid) + mainNode.appendChild roomDom + if roomDom.classList.contains('room-container') + roomDom.querySelector('.messages-box > .wrapper').scrollTop = roomDom.oldScrollTop + + + + removeDomOfRoom = () -> + mainNode = document.querySelector('.main-content') + if mainNode? + for child in mainNode.children + if child? + if child.classList.contains('room-container') + child.oldScrollTop = child.querySelector('.messages-box > .wrapper').scrollTop + mainNode.removeChild child + updateUserStatus = (user, status, utcOffset) -> onlineUsersValue = onlineUsers.curValue @@ -143,7 +170,10 @@ Meteor.startup -> init: init getDomOfRoom: getDomOfRoom existsDomOfRoom: existsDomOfRoom + refreshDomOfRoom: refreshDomOfRoom + removeDomOfRoom: removeDomOfRoom msgStream: msgStream openedRooms: openedRooms updateUserStatus: updateUserStatus onlineUsers: onlineUsers + remove:remove diff --git a/client/routes/roomRoute.coffee b/client/routes/roomRoute.coffee index 89745c5aa2053..6cc5f8ad9cdb8 100644 --- a/client/routes/roomRoute.coffee +++ b/client/routes/roomRoute.coffee @@ -24,6 +24,8 @@ openRoom = (type, name) -> FlowRouter.go 'home' return + RoomManager.refreshDomOfRoom(type + name, room._id) + ### mainNode = document.querySelector('.main-content') if mainNode? for child in mainNode.children @@ -33,6 +35,7 @@ openRoom = (type, name) -> if roomDom.classList.contains('room-container') roomDom.querySelector('.messages-box > .wrapper').scrollTop = roomDom.oldScrollTop + ### Session.set 'openedRoom', room._id Session.set 'editRoomTitle', false @@ -44,8 +47,9 @@ openRoom = (type, name) -> $('.message-form .input-message').focus() , 100 - roomExit = -> + RoomManager.removeDomOfRoom() + ### mainNode = document.querySelector('.main-content') if mainNode? for child in mainNode.children @@ -53,6 +57,7 @@ roomExit = -> if child.classList.contains('room-container') child.oldScrollTop = child.querySelector('.messages-box > .wrapper').scrollTop mainNode.removeChild child + ### FlowRouter.route '/channel/:name', diff --git a/client/startup/roomObserve.coffee b/client/startup/roomObserve.coffee index 2cbee3b767af5..3ccf5480bba07 100644 --- a/client/startup/roomObserve.coffee +++ b/client/startup/roomObserve.coffee @@ -2,7 +2,33 @@ Meteor.startup -> ChatRoom.find().observe added: (data) -> Session.set('roomData' + data._id, data) - changed: (data) -> - Session.set('roomData' + data._id, data) + changed: (newData, oldData) -> + handleRoomNameChanged( newData, oldData) + Session.set('roomData' + newData._id, null) + Session.set('roomData' + newData._id, newData) removed: (data) -> Session.set('roomData' + data._id, undefined) + +handleRoomNameChanged = (newData, oldData) -> + if newData.t in ['p','c'] and newData.name isnt oldData.name + oldTypeName = oldData.t + oldData.name + RoomManager.remove oldTypeName + openedRoom = Session.get('openedRoom') + if openedRoom is newData._id + newTypeName = newData.t + newData.name + Tracker.autorun (c) -> + if RoomManager.open(newTypeName).ready() isnt true + return + c.stop() + RoomManager.removeDomOfRoom() + RoomManager.refreshDomOfRoom( newTypeName, newData._id ) + Session.set 'openedRoom', newData._id + Session.set 'editRoomTitle', false + Meteor.call 'readMessages', newData._id if Meteor.userId()? + # KonchatNotification.removeRoomNotification(params._id) + + if Meteor.Device.isDesktop() + setTimeout -> + $('.message-form .input-message').focus() + , 100 +