From 2aa79f4fbe64b8fe88dae5414cc7f81a851fbb23 Mon Sep 17 00:00:00 2001 From: Kegan Dougal Date: Fri, 31 Oct 2014 14:26:51 +0000 Subject: [PATCH 01/53] Added model-service.js to store model data. --- webclient/app.js | 1 + .../matrix/event-handler-service.js | 4 +- webclient/components/matrix/model-service.js | 98 +++++++++++++++++++ webclient/index.html | 1 + 4 files changed, 102 insertions(+), 2 deletions(-) create mode 100644 webclient/components/matrix/model-service.js diff --git a/webclient/app.js b/webclient/app.js index c091f8c6c..17b2bb6e8 100644 --- a/webclient/app.js +++ b/webclient/app.js @@ -31,6 +31,7 @@ var matrixWebClient = angular.module('matrixWebClient', [ 'eventStreamService', 'eventHandlerService', 'notificationService', + 'modelService', 'infinite-scroll', 'ui.bootstrap', 'monospaced.elastic' diff --git a/webclient/components/matrix/event-handler-service.js b/webclient/components/matrix/event-handler-service.js index e63584510..84b2a220e 100644 --- a/webclient/components/matrix/event-handler-service.js +++ b/webclient/components/matrix/event-handler-service.js @@ -27,8 +27,8 @@ Typically, this service will store events or broadcast them to any listeners if typically all the $on method would do is update its own $scope. */ angular.module('eventHandlerService', []) -.factory('eventHandlerService', ['matrixService', '$rootScope', '$q', '$timeout', 'mPresence', 'notificationService', -function(matrixService, $rootScope, $q, $timeout, mPresence, notificationService) { +.factory('eventHandlerService', ['matrixService', '$rootScope', '$q', '$timeout', 'mPresence', 'notificationService', 'modelService', +function(matrixService, $rootScope, $q, $timeout, mPresence, notificationService, modelService) { var ROOM_CREATE_EVENT = "ROOM_CREATE_EVENT"; var MSG_EVENT = "MSG_EVENT"; var MEMBER_EVENT = "MEMBER_EVENT"; diff --git a/webclient/components/matrix/model-service.js b/webclient/components/matrix/model-service.js new file mode 100644 index 000000000..c10e5185a --- /dev/null +++ b/webclient/components/matrix/model-service.js @@ -0,0 +1,98 @@ +/* +Copyright 2014 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +'use strict'; + +/* +This service serves as the entry point for all models in the app. If access to +underlying data in a room is required, then this service should be used as the +dependency. +*/ +// NB: This is more explicit than linking top-level models to $rootScope +// in that by adding this service as a dep you are clearly saying "this X +// needs access to the underlying data store", rather than polluting the +// $rootScope. +angular.module('modelService', []) +.factory('modelService', ['matrixService', function(matrixService) { + + /***** Room Object *****/ + var Room = function Room(room_id) { + this.room_id = room_id; + this.old_room_state = RoomState(); + this.current_room_state = RoomState(); + }; + Room.prototype = { + leave: function leave() { + return matrixService.leave(this.room_id); + } + }; + + /***** Room State Object *****/ + var RoomState = function RoomState() { + // list of RoomMember + this.members = []; + // state events, the key is a compound of event type + state_key + this.state_events = {}; + // earliest token + this.pagination_token = ""; + }; + RoomState.prototype = { + // get a state event for this room from this.state_events. State events + // are unique per type+state_key tuple, with a lot of events using 0-len + // state keys. To make it not Really Annoying to access, this method is + // provided which can just be given the type and it will return the + // 0-len event by default. + state: function state(type, state_key) { + if (!state_key) { + return this.state_events[type]; + } + return this.state_events[type + state_key]; + }, + + storeState: function storeState(event) { + this.state_events[event.type + event.state_key] = event; + } + }; + + /***** Room Member Object *****/ + var RoomMember = function RoomMember() { + this.event = {}; // the m.room.member event representing the RoomMember. + this.user = undefined; // the User + }; + + /***** User Object *****/ + var User = function User() { + this.event = {}; // the m.presence event representing the User. + }; + + // rooms are stored here when they come in. + var rooms = { + // roomid: + }; + + console.log("Models inited."); + + return { + + getRoom: function(roomId) { + if(!rooms[roomId]) { + rooms[roomId] = new Room(roomId); + } + return rooms[roomId]; + } + + }; +}]); diff --git a/webclient/index.html b/webclient/index.html index bc011a6c7..965981f7d 100644 --- a/webclient/index.html +++ b/webclient/index.html @@ -42,6 +42,7 @@ + From 394f77c3ff2d849b4ec69595f40ebfcc84ed1d31 Mon Sep 17 00:00:00 2001 From: Kegan Dougal Date: Fri, 31 Oct 2014 14:50:31 +0000 Subject: [PATCH 02/53] Parse /initialSync data and populate the new data structures. --- .../matrix/event-handler-service.js | 12 +++++++++ webclient/components/matrix/model-service.js | 25 ++++++++++++++++--- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/webclient/components/matrix/event-handler-service.js b/webclient/components/matrix/event-handler-service.js index 84b2a220e..a8d89834a 100644 --- a/webclient/components/matrix/event-handler-service.js +++ b/webclient/components/matrix/event-handler-service.js @@ -86,6 +86,18 @@ function(matrixService, $rootScope, $q, $timeout, mPresence, notificationService } $rootScope.events.rooms[room_id].membership = room.membership; } + + // ========================================= + var __room = modelService.getRoom(room_id); + if (room) { // /initialSync data + __room.current_room_state.storeStateEvents(room.state); + __room.current_room_state.pagination_token = room.messages.end; + + __room.old_room_state.storeStateEvents(room.state); + __room.old_room_state.pagination_token = room.messages.start; + + __room.addMessages(room.messages.chunk); + } }; var resetRoomMessages = function(room_id) { diff --git a/webclient/components/matrix/model-service.js b/webclient/components/matrix/model-service.js index c10e5185a..0ba23cb76 100644 --- a/webclient/components/matrix/model-service.js +++ b/webclient/components/matrix/model-service.js @@ -31,10 +31,22 @@ angular.module('modelService', []) /***** Room Object *****/ var Room = function Room(room_id) { this.room_id = room_id; - this.old_room_state = RoomState(); - this.current_room_state = RoomState(); + this.old_room_state = new RoomState(); + this.current_room_state = new RoomState(); + this.messages = []; // events which can be displayed on the UI. TODO move? }; Room.prototype = { + addMessages: function addMessages(events, toFront) { + for (var i=0; i Date: Fri, 31 Oct 2014 15:16:43 +0000 Subject: [PATCH 03/53] Hook into more of event-handler-service and mimic its functions for now. --- .../matrix/event-handler-service.js | 164 +++++++++++------- webclient/components/matrix/model-service.js | 34 +++- 2 files changed, 130 insertions(+), 68 deletions(-) diff --git a/webclient/components/matrix/event-handler-service.js b/webclient/components/matrix/event-handler-service.js index a8d89834a..589554ec0 100644 --- a/webclient/components/matrix/event-handler-service.js +++ b/webclient/components/matrix/event-handler-service.js @@ -96,7 +96,7 @@ function(matrixService, $rootScope, $q, $timeout, mPresence, notificationService __room.old_room_state.storeStateEvents(room.state); __room.old_room_state.pagination_token = room.messages.start; - __room.addMessages(room.messages.chunk); + __room.addMessageEvents(room.messages.chunk); } }; @@ -108,6 +108,26 @@ function(matrixService, $rootScope, $q, $timeout, mPresence, notificationService // Generic method to handle events data var handleRoomDateEvent = function(event, isLiveEvent, addToRoomMessages) { + var __room = modelService.getRoom(event.room_id); + if (addToRoomMessages) { + __room.addMessageEvent(event, !isLiveEvent); + } + if (isLiveEvent) { + __room.current_room_state.storeStateEvent(event); + } + else { + var eventTs = event.origin_server_ts; + var storedEvent = __room.current_room_state.getStateEvent(event.type, event.state_key); + if (storedEvent) { + if (storedEvent.origin_server_ts < eventTs) { + // the incoming event is newer, use it. + __room.current_room_state.storeStateEvent(event); + } + } + } + + // ===================================== + // Add topic changes as if they were a room message if (addToRoomMessages) { if (isLiveEvent) { @@ -144,6 +164,70 @@ function(matrixService, $rootScope, $q, $timeout, mPresence, notificationService var handleRoomAliases = function(event, isLiveEvent) { matrixService.createRoomIdToAliasMapping(event.room_id, event.content.aliases[0]); }; + + var displayNotification = function(event) { + if (window.Notification && event.user_id != matrixService.config().user_id) { + var shouldBing = notificationService.containsBingWord( + matrixService.config().user_id, + matrixService.config().display_name, + matrixService.config().bingWords, + event.content.body + ); + + // Ideally we would notify only when the window is hidden (i.e. document.hidden = true). + // + // However, Chrome on Linux and OSX currently returns document.hidden = false unless the window is + // explicitly showing a different tab. So we need another metric to determine hiddenness - we + // simply use idle time. If the user has been idle enough that their presence goes to idle, then + // we also display notifs when things happen. + // + // This is far far better than notifying whenever anything happens anyway, otherwise you get spammed + // to death with notifications when the window is in the foreground, which is horrible UX (especially + // if you have not defined any bingers and so get notified for everything). + var isIdle = (document.hidden || matrixService.presence.unavailable === mPresence.getState()); + + // We need a way to let people get notifications for everything, if they so desire. The way to do this + // is to specify zero bingwords. + var bingWords = matrixService.config().bingWords; + if (bingWords === undefined || bingWords.length === 0) { + shouldBing = true; + } + + if (shouldBing && isIdle) { + console.log("Displaying notification for "+JSON.stringify(event)); + var member = getMember(event.room_id, event.user_id); + var displayname = getUserDisplayName(event.room_id, event.user_id); + + var message = event.content.body; + if (event.content.msgtype === "m.emote") { + message = "* " + displayname + " " + message; + } + else if (event.content.msgtype === "m.image") { + message = displayname + " sent an image."; + } + + var roomTitle = matrixService.getRoomIdToAliasMapping(event.room_id); + var theRoom = $rootScope.events.rooms[event.room_id]; + if (!roomTitle && theRoom && theRoom["m.room.name"] && theRoom["m.room.name"].content) { + roomTitle = theRoom["m.room.name"].content.name; + } + + if (!roomTitle) { + roomTitle = event.room_id; + } + + notificationService.showNotification( + displayname + " (" + roomTitle + ")", + message, + member ? member.avatar_url : undefined, + function() { + console.log("notification.onclick() room=" + event.room_id); + $rootScope.goToPage('room/' + event.room_id); + } + ); + } + } + }; var handleMessage = function(event, isLiveEvent) { // Check for empty event content @@ -156,6 +240,21 @@ function(matrixService, $rootScope, $q, $timeout, mPresence, notificationService // empty json object is a redacted event, so ignore. return; } + + // ======================= + + var __room = modelService.getRoom(event.room_id); + + if (event.user_id !== matrixService.config().user_id) { + __room.addMessageEvent(event, !isLiveEvent); + } + else { + // we may have locally echoed this, so we should replace the event + // instead of just adding. + __room.addOrReplaceMessageEvent(event, !isLiveEvent); + } + + // ======================= if (isLiveEvent) { if (event.user_id === matrixService.config().user_id && @@ -172,69 +271,10 @@ function(matrixService, $rootScope, $q, $timeout, mPresence, notificationService } else { $rootScope.events.rooms[event.room_id].messages.push(event); + displayNotification(event); } - if (window.Notification && event.user_id != matrixService.config().user_id) { - var shouldBing = notificationService.containsBingWord( - matrixService.config().user_id, - matrixService.config().display_name, - matrixService.config().bingWords, - event.content.body - ); - - // Ideally we would notify only when the window is hidden (i.e. document.hidden = true). - // - // However, Chrome on Linux and OSX currently returns document.hidden = false unless the window is - // explicitly showing a different tab. So we need another metric to determine hiddenness - we - // simply use idle time. If the user has been idle enough that their presence goes to idle, then - // we also display notifs when things happen. - // - // This is far far better than notifying whenever anything happens anyway, otherwise you get spammed - // to death with notifications when the window is in the foreground, which is horrible UX (especially - // if you have not defined any bingers and so get notified for everything). - var isIdle = (document.hidden || matrixService.presence.unavailable === mPresence.getState()); - - // We need a way to let people get notifications for everything, if they so desire. The way to do this - // is to specify zero bingwords. - var bingWords = matrixService.config().bingWords; - if (bingWords === undefined || bingWords.length === 0) { - shouldBing = true; - } - - if (shouldBing && isIdle) { - console.log("Displaying notification for "+JSON.stringify(event)); - var member = getMember(event.room_id, event.user_id); - var displayname = getUserDisplayName(event.room_id, event.user_id); - - var message = event.content.body; - if (event.content.msgtype === "m.emote") { - message = "* " + displayname + " " + message; - } - else if (event.content.msgtype === "m.image") { - message = displayname + " sent an image."; - } - - var roomTitle = matrixService.getRoomIdToAliasMapping(event.room_id); - var theRoom = $rootScope.events.rooms[event.room_id]; - if (!roomTitle && theRoom && theRoom["m.room.name"] && theRoom["m.room.name"].content) { - roomTitle = theRoom["m.room.name"].content.name; - } - - if (!roomTitle) { - roomTitle = event.room_id; - } - - notificationService.showNotification( - displayname + " (" + roomTitle + ")", - message, - member ? member.avatar_url : undefined, - function() { - console.log("notification.onclick() room=" + event.room_id); - $rootScope.goToPage('room/' + event.room_id); - } - ); - } - } + } else { $rootScope.events.rooms[event.room_id].messages.unshift(event); diff --git a/webclient/components/matrix/model-service.js b/webclient/components/matrix/model-service.js index 0ba23cb76..6e1576cd6 100644 --- a/webclient/components/matrix/model-service.js +++ b/webclient/components/matrix/model-service.js @@ -36,15 +36,33 @@ angular.module('modelService', []) this.messages = []; // events which can be displayed on the UI. TODO move? }; Room.prototype = { - addMessages: function addMessages(events, toFront) { + addMessageEvents: function addMessageEvents(events, toFront) { for (var i=0; i= 0; i--) { + var storedEvent = this.messages[i]; + if (storedEvent.event_id === event.event_id) { + // It's clobbering time! + this.messages[i] = event; + return; } } + this.addMessageEvent(event, toFront); }, leave: function leave() { @@ -81,6 +99,10 @@ angular.module('modelService', []) for (var i=0; i Date: Fri, 31 Oct 2014 16:22:15 +0000 Subject: [PATCH 04/53] room.html now displays messages from model-service. Add debugging fields. Hook up the room member *at the time* to the message so it can display the right historical member info. --- .../components/matrix/event-handler-service.js | 9 ++++++++- webclient/components/matrix/model-service.js | 16 ++++++++++------ webclient/index.html | 2 +- webclient/room/room-controller.js | 11 +++++++---- webclient/room/room.html | 10 +++++----- 5 files changed, 31 insertions(+), 17 deletions(-) diff --git a/webclient/components/matrix/event-handler-service.js b/webclient/components/matrix/event-handler-service.js index 589554ec0..a511b394b 100644 --- a/webclient/components/matrix/event-handler-service.js +++ b/webclient/components/matrix/event-handler-service.js @@ -96,7 +96,7 @@ function(matrixService, $rootScope, $q, $timeout, mPresence, notificationService __room.old_room_state.storeStateEvents(room.state); __room.old_room_state.pagination_token = room.messages.start; - __room.addMessageEvents(room.messages.chunk); + $rootScope["debug_"+room_id] = __room; } }; @@ -589,6 +589,10 @@ function(matrixService, $rootScope, $q, $timeout, mPresence, notificationService // Store how far back we've paginated $rootScope.events.rooms[room_id].pagination.earliest_token = messages.end; + + var __room = modelService.getRoom(room_id); + __room.old_room_state.pagination_token = messages.end; + } else { // InitialSync returns messages in chronological order @@ -597,6 +601,9 @@ function(matrixService, $rootScope, $q, $timeout, mPresence, notificationService } // Store where to start pagination $rootScope.events.rooms[room_id].pagination.earliest_token = messages.start; + + var __room = modelService.getRoom(room_id); + __room.old_room_state.pagination_token = messages.start; } }, diff --git a/webclient/components/matrix/model-service.js b/webclient/components/matrix/model-service.js index 6e1576cd6..d47ac6b2a 100644 --- a/webclient/components/matrix/model-service.js +++ b/webclient/components/matrix/model-service.js @@ -33,7 +33,7 @@ angular.module('modelService', []) this.room_id = room_id; this.old_room_state = new RoomState(); this.current_room_state = new RoomState(); - this.messages = []; // events which can be displayed on the UI. TODO move? + this.events = []; // events which can be displayed on the UI. TODO move? }; Room.prototype = { addMessageEvents: function addMessageEvents(events, toFront) { @@ -43,22 +43,26 @@ angular.module('modelService', []) }, addMessageEvent: function addMessageEvent(event, toFront) { + // every message must reference the RoomMember which made it *at + // that time* so things like display names display correctly. if (toFront) { - this.messages.unshift(event); + event.room_member = this.old_room_state.getStateEvent("m.room.member", event.user_id); + this.events.unshift(event); } else { - this.messages.push(event); + event.room_member = this.current_room_state.getStateEvent("m.room.member", event.user_id); + this.events.push(event); } }, addOrReplaceMessageEvent: function addOrReplaceMessageEvent(event, toFront) { // Start looking from the tail since the first goal of this function // is to find a message among the latest ones - for (var i = this.messages.length - 1; i >= 0; i--) { - var storedEvent = this.messages[i]; + for (var i = this.events.length - 1; i >= 0; i--) { + var storedEvent = this.events[i]; if (storedEvent.event_id === event.event_id) { // It's clobbering time! - this.messages[i] = event; + this.events[i] = event; return; } } diff --git a/webclient/index.html b/webclient/index.html index 965981f7d..3ed968a5e 100644 --- a/webclient/index.html +++ b/webclient/index.html @@ -13,7 +13,7 @@ - + diff --git a/webclient/room/room-controller.js b/webclient/room/room-controller.js index 486ead0da..7125c98e0 100644 --- a/webclient/room/room-controller.js +++ b/webclient/room/room-controller.js @@ -15,8 +15,8 @@ limitations under the License. */ angular.module('RoomController', ['ngSanitize', 'matrixFilter', 'mFileInput']) -.controller('RoomController', ['$modal', '$filter', '$scope', '$timeout', '$routeParams', '$location', '$rootScope', 'matrixService', 'mPresence', 'eventHandlerService', 'mFileUpload', 'matrixPhoneService', 'MatrixCall', 'notificationService', - function($modal, $filter, $scope, $timeout, $routeParams, $location, $rootScope, matrixService, mPresence, eventHandlerService, mFileUpload, matrixPhoneService, MatrixCall, notificationService) { +.controller('RoomController', ['$modal', '$filter', '$scope', '$timeout', '$routeParams', '$location', '$rootScope', 'matrixService', 'mPresence', 'eventHandlerService', 'mFileUpload', 'matrixPhoneService', 'MatrixCall', 'notificationService', 'modelService', + function($modal, $filter, $scope, $timeout, $routeParams, $location, $rootScope, matrixService, mPresence, eventHandlerService, mFileUpload, matrixPhoneService, MatrixCall, notificationService, modelService) { 'use strict'; var MESSAGES_PER_PAGINATION = 30; var THUMBNAIL_SIZE = 320; @@ -254,11 +254,11 @@ angular.module('RoomController', ['ngSanitize', 'matrixFilter', 'mFileInput']) $scope.state.paginating = true; } - console.log("paginateBackMessages from " + $rootScope.events.rooms[$scope.room_id].pagination.earliest_token + " for " + numItems); + console.log("paginateBackMessages from " + $scope.room.old_room_state.pagination_token + " for " + numItems); var originalTopRow = $("#messageTable>tbody>tr:first")[0]; // Paginate events from the point in cache - matrixService.paginateBackMessages($scope.room_id, $rootScope.events.rooms[$scope.room_id].pagination.earliest_token, numItems).then( + matrixService.paginateBackMessages($scope.room_id, $scope.room.old_room_state.pagination_token, numItems).then( function(response) { eventHandlerService.handleRoomMessages($scope.room_id, response.data, false, 'b'); @@ -717,6 +717,9 @@ angular.module('RoomController', ['ngSanitize', 'matrixFilter', 'mFileInput']) var onInit2 = function() { console.log("onInit2"); + // ============================= + $scope.room = modelService.getRoom($scope.room_id); + // ============================= // Scroll down as soon as possible so that we point to the last message // if it already exists in memory diff --git a/webclient/room/room.html b/webclient/room/room.html index 5265f42dd..8c1e45dfd 100644 --- a/webclient/room/room.html +++ b/webclient/room/room.html @@ -123,10 +123,10 @@ ng-style="{ 'visibility': state.messages_visibility }" keep-scroll> - +
-
{{ msg.user_id | mUserDisplayName: room_id }}
+
{{ msg.user_id | mUserDisplayName: room_id }}
{{ (msg.origin_server_ts) | date:'MMM d HH:mm' }} @@ -134,7 +134,7 @@
+ ng-hide="room.events[$index - 1].user_id === msg.user_id || msg.user_id === state.user_id"/>
@@ -204,7 +204,7 @@
+ ng-hide="room.events[$index - 1].user_id === msg.user_id || msg.user_id !== state.user_id"/>
From f21960ec9d346d53a21369b8179cc30365654517 Mon Sep 17 00:00:00 2001 From: Kegan Dougal Date: Fri, 31 Oct 2014 17:13:27 +0000 Subject: [PATCH 05/53] Replace lots of .events.rooms[room_id] with .room --- .../matrix/event-handler-service.js | 6 ++++++ webclient/components/matrix/model-service.js | 2 +- webclient/room/room-controller.js | 19 +++++++++---------- webclient/room/room.html | 11 ++++++----- 4 files changed, 22 insertions(+), 16 deletions(-) diff --git a/webclient/components/matrix/event-handler-service.js b/webclient/components/matrix/event-handler-service.js index a511b394b..f8a91ee0a 100644 --- a/webclient/components/matrix/event-handler-service.js +++ b/webclient/components/matrix/event-handler-service.js @@ -289,6 +289,8 @@ function(matrixService, $rootScope, $q, $timeout, mPresence, notificationService }; var handleRoomMember = function(event, isLiveEvent, isStateEvent) { + var __room = modelService.getRoom(event.room_id); + // add membership changes as if they were a room message if something interesting changed // Exception: Do not do this if the event is a room state event because such events already come @@ -317,6 +319,9 @@ function(matrixService, $rootScope, $q, $timeout, mPresence, notificationService else { $rootScope.events.rooms[event.room_id].messages.unshift(event); } + // ============ + + __room.addMessageEvent(event, !isLiveEvent); } } @@ -324,6 +329,7 @@ function(matrixService, $rootScope, $q, $timeout, mPresence, notificationService // Do not care of events that come when paginating back if (isStateEvent || isLiveEvent) { $rootScope.events.rooms[event.room_id].members[event.state_key] = event; + __room.current_room_state.members[event.state_key] = event; } $rootScope.$broadcast(MEMBER_EVENT, event, isLiveEvent, isStateEvent); diff --git a/webclient/components/matrix/model-service.js b/webclient/components/matrix/model-service.js index d47ac6b2a..6167a84c6 100644 --- a/webclient/components/matrix/model-service.js +++ b/webclient/components/matrix/model-service.js @@ -77,7 +77,7 @@ angular.module('modelService', []) /***** Room State Object *****/ var RoomState = function RoomState() { // list of RoomMember - this.members = []; + this.members = {}; // state events, the key is a compound of event type + state_key this.state_events = {}; this.pagination_token = ""; diff --git a/webclient/room/room-controller.js b/webclient/room/room-controller.js index 7125c98e0..b5f2b6041 100644 --- a/webclient/room/room-controller.js +++ b/webclient/room/room-controller.js @@ -64,7 +64,7 @@ angular.module('RoomController', ['ngSanitize', 'matrixFilter', 'mFileInput']) return; }; - var nameEvent = $rootScope.events.rooms[$scope.room_id]['m.room.name']; + var nameEvent = $scope.room.current_room_state.state_events['m.room.name']; if (nameEvent) { $scope.name.newNameText = nameEvent.content.name; } @@ -105,7 +105,7 @@ angular.module('RoomController', ['ngSanitize', 'matrixFilter', 'mFileInput']) console.log("Warning: Already editing topic."); return; } - var topicEvent = $rootScope.events.rooms[$scope.room_id]['m.room.topic']; + var topicEvent = $scope.room.current_room_state.state_events['m.room.topic']; if (topicEvent) { $scope.topic.newTopicText = topicEvent.content.topic; } @@ -492,7 +492,7 @@ angular.module('RoomController', ['ngSanitize', 'matrixFilter', 'mFileInput']) var room_id = matrixService.getAliasToRoomIdMapping(room_alias); console.log("joining " + room_alias + " id=" + room_id); - if ($rootScope.events.rooms[room_id]) { + if ($scope.room) { // TODO actually check that you = join // don't send a join event for a room you're already in. $location.url("room/" + room_alias); } @@ -629,7 +629,7 @@ angular.module('RoomController', ['ngSanitize', 'matrixFilter', 'mFileInput']) }; $('#mainInput').val(''); - $rootScope.events.rooms[$scope.room_id].messages.push(echoMessage); + $scope.room.addMessageEvent(echoMessage); scrollToBottom(); } @@ -732,9 +732,9 @@ angular.module('RoomController', ['ngSanitize', 'matrixFilter', 'mFileInput']) var needsToJoin = true; // The room members is available in the data fetched by initialSync - if ($rootScope.events.rooms[$scope.room_id]) { + if ($scope.room) { - var messages = $rootScope.events.rooms[$scope.room_id].messages; + var messages = $scope.room.events; if (0 === messages.length || (1 === messages.length && "m.room.member" === messages[0].type && "invite" === messages[0].content.membership && $scope.state.user_id === messages[0].state_key)) { @@ -746,7 +746,7 @@ angular.module('RoomController', ['ngSanitize', 'matrixFilter', 'mFileInput']) $scope.state.first_pagination = false; } - var members = $rootScope.events.rooms[$scope.room_id].members; + var members = $scope.room.current_room_state.members; // Update the member list for (var i in members) { @@ -1042,8 +1042,7 @@ angular.module('RoomController', ['ngSanitize', 'matrixFilter', 'mFileInput']) state_key: "" }; - var stateFilter = $filter("stateEventsFilter"); - var stateEvents = stateFilter($scope.events.rooms[$scope.room_id]); + var stateEvents = $scope.room.current_room_state.state_events; // The modal dialog will 2-way bind this field, so we MUST make a deep // copy of the state events else we will be *actually adjusing our view // of the world* when fiddling with the JSON!! Apparently parse/stringify @@ -1062,7 +1061,7 @@ angular.module('RoomController', ['ngSanitize', 'matrixFilter', 'mFileInput']) console.log("Displaying modal dialog for >>>> " + JSON.stringify($scope.event_selected)); $scope.redact = function() { console.log("User level = "+$scope.pow($scope.room_id, $scope.state.user_id)+ - " Redact level = "+$scope.events.rooms[$scope.room_id]["m.room.ops_levels"].content.redact_level); + " Redact level = "+$scope.room.current_room_state.state_events["m.room.ops_levels"].content.redact_level); console.log("Redact event >> " + JSON.stringify($scope.event_selected)); $modalInstance.close("redact"); }; diff --git a/webclient/room/room.html b/webclient/room/room.html index 8c1e45dfd..1cec8ac70 100644 --- a/webclient/room/room.html +++ b/webclient/room/room.html @@ -6,7 +6,7 @@