From 8773d67df7c19732ef9acaffdff60b30dc7ef19e Mon Sep 17 00:00:00 2001 From: Jorik Schellekens Date: Wed, 8 Jul 2020 17:28:15 +0100 Subject: [PATCH 01/10] Auto expand room list on search --- src/components/structures/RoomSearch.tsx | 9 ++++++++- src/components/views/rooms/RoomList2.tsx | 11 +++++++++++ src/dispatcher/actions.ts | 10 ++++++++++ src/stores/room-list/ListLayout.ts | 12 ++++++++++++ 4 files changed, 41 insertions(+), 1 deletion(-) diff --git a/src/components/structures/RoomSearch.tsx b/src/components/structures/RoomSearch.tsx index 15f3bd5b54..349025782d 100644 --- a/src/components/structures/RoomSearch.tsx +++ b/src/components/structures/RoomSearch.tsx @@ -76,6 +76,7 @@ export default class RoomSearch extends React.PureComponent { private clearInput = () => { if (!this.inputRef.current) return; this.inputRef.current.value = ""; + defaultDispatcher.dispatch({action: Action.StopRoomFilter}) this.onChange(); }; @@ -102,9 +103,15 @@ export default class RoomSearch extends React.PureComponent { private onFocus = (ev: React.FocusEvent) => { this.setState({focused: true}); ev.target.select(); + if (ev.target.value === "") { + defaultDispatcher.dispatch({action: Action.StartRoomFilter}) + } }; - private onBlur = () => { + private onBlur = (ev: React.FocusEvent) => { + if (ev.target.value === "") { + defaultDispatcher.dispatch({action: Action.StopRoomFilter}) + } this.setState({focused: false}); }; diff --git a/src/components/views/rooms/RoomList2.tsx b/src/components/views/rooms/RoomList2.tsx index fb0136fb29..c294b2e1b0 100644 --- a/src/components/views/rooms/RoomList2.tsx +++ b/src/components/views/rooms/RoomList2.tsx @@ -194,6 +194,17 @@ export default class RoomList2 extends React.Component { show_room_tile: true, // to make sure the room gets scrolled into view }); } + } else if (payload.action === Action.StartRoomFilter) { + this.state.layouts.forEach(x => { + x.saveCollapsedState(); + x.isCollapsed = false; + }); + this.forceUpdate(); + } else if (payload.action === Action.StopRoomFilter) { + this.state.layouts.forEach(x => { + x.restoreCollapsedState(); + }); + this.forceUpdate(); } }; diff --git a/src/dispatcher/actions.ts b/src/dispatcher/actions.ts index 9be674b59e..89b2216db1 100644 --- a/src/dispatcher/actions.ts +++ b/src/dispatcher/actions.ts @@ -84,4 +84,14 @@ export enum Action { * Changes room based on room list order and payload parameters. Should be used with ViewRoomDeltaPayload. */ ViewRoomDelta = "view_room_delta", + + /** + * Informs the room list when room filtering has begun. No additional payload information required. + */ + StartRoomFilter = "start_room_filter", + + /** + * Informs the room list when room filtering has ended. No additional payload information required. + */ + StopRoomFilter = "stop_room_filter", } diff --git a/src/stores/room-list/ListLayout.ts b/src/stores/room-list/ListLayout.ts index f31e92b8ae..7be284b0e5 100644 --- a/src/stores/room-list/ListLayout.ts +++ b/src/stores/room-list/ListLayout.ts @@ -26,12 +26,14 @@ interface ISerializedListLayout { numTiles: number; showPreviews: boolean; collapsed: boolean; + savedCollapsed: boolean; } export class ListLayout { private _n = 0; private _previews = false; private _collapsed = false; + private _savedCollapsed = false; constructor(public readonly tagId: TagID) { const serialized = localStorage.getItem(this.key); @@ -41,6 +43,7 @@ export class ListLayout { this._n = parsed.numTiles; this._previews = parsed.showPreviews; this._collapsed = parsed.collapsed; + this._savedCollapsed = parsed.savedCollapsed; } } @@ -136,11 +139,20 @@ export class ListLayout { localStorage.setItem(this.key, JSON.stringify(this.serialize())); } + public saveCollapsedState() { + this._savedCollapsed = this.isCollapsed; + } + + public restoreCollapsedState() { + this.isCollapsed = this._savedCollapsed; + } + private serialize(): ISerializedListLayout { return { numTiles: this.visibleTiles, showPreviews: this.showPreviews, collapsed: this.isCollapsed, + savedCollapsed: this._savedCollapsed, }; } } From bb18e677f9020348a1a4d4188f1a16bc90523177 Mon Sep 17 00:00:00 2001 From: Jorik Schellekens Date: Wed, 8 Jul 2020 18:05:07 +0100 Subject: [PATCH 02/10] Lint semis --- src/components/structures/RoomSearch.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/structures/RoomSearch.tsx b/src/components/structures/RoomSearch.tsx index 349025782d..dad05fb577 100644 --- a/src/components/structures/RoomSearch.tsx +++ b/src/components/structures/RoomSearch.tsx @@ -76,7 +76,7 @@ export default class RoomSearch extends React.PureComponent { private clearInput = () => { if (!this.inputRef.current) return; this.inputRef.current.value = ""; - defaultDispatcher.dispatch({action: Action.StopRoomFilter}) + defaultDispatcher.dispatch({action: Action.StopRoomFilter}); this.onChange(); }; @@ -104,13 +104,13 @@ export default class RoomSearch extends React.PureComponent { this.setState({focused: true}); ev.target.select(); if (ev.target.value === "") { - defaultDispatcher.dispatch({action: Action.StartRoomFilter}) + defaultDispatcher.dispatch({action: Action.StartRoomFilter}); } }; private onBlur = (ev: React.FocusEvent) => { if (ev.target.value === "") { - defaultDispatcher.dispatch({action: Action.StopRoomFilter}) + defaultDispatcher.dispatch({action: Action.StopRoomFilter}); } this.setState({focused: false}); }; From ae09bfb8fdfc93f9e74461fe91d7fca1a9734748 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 9 Jul 2020 10:22:04 -0600 Subject: [PATCH 03/10] Don't destroy room notification states when replacing them The "should never happen" now happens a lot by design. We shouldn't destroy the state as it'll stop badge counts for everything. Fixes https://github.com/vector-im/riot-web/issues/14391 --- src/stores/notifications/ListNotificationState.ts | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/stores/notifications/ListNotificationState.ts b/src/stores/notifications/ListNotificationState.ts index 6c5f6fc6dd..6c67dbdd08 100644 --- a/src/stores/notifications/ListNotificationState.ts +++ b/src/stores/notifications/ListNotificationState.ts @@ -55,11 +55,6 @@ export class ListNotificationState extends NotificationState { for (const newRoom of diff.added) { const state = this.getRoomFn(newRoom); state.on(NOTIFICATION_STATE_UPDATE, this.onRoomNotificationStateUpdate); - if (this.states[newRoom.roomId]) { - // "Should never happen" disclaimer. - console.warn("Overwriting notification state for room:", newRoom.roomId); - this.states[newRoom.roomId].destroy(); - } this.states[newRoom.roomId] = state; } From 74fa3b2c8148eb082c052c88741b78d19cc9d10f Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 9 Jul 2020 10:39:53 -0600 Subject: [PATCH 04/10] Fix rough badge alignment for community invite tiles again Fixes https://github.com/vector-im/riot-web/issues/14392 --- res/css/views/avatars/_DecoratedRoomAvatar.scss | 2 +- res/css/views/rooms/_RoomTile2.scss | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/res/css/views/avatars/_DecoratedRoomAvatar.scss b/res/css/views/avatars/_DecoratedRoomAvatar.scss index b500d44a43..900f351074 100644 --- a/res/css/views/avatars/_DecoratedRoomAvatar.scss +++ b/res/css/views/avatars/_DecoratedRoomAvatar.scss @@ -24,7 +24,7 @@ limitations under the License. right: 0; } - .mx_NotificationBadge { + .mx_NotificationBadge, .mx_RoomTile2_badgeContainer { position: absolute; top: 0; right: 0; diff --git a/res/css/views/rooms/_RoomTile2.scss b/res/css/views/rooms/_RoomTile2.scss index b9e0398e7d..d2d394e266 100644 --- a/res/css/views/rooms/_RoomTile2.scss +++ b/res/css/views/rooms/_RoomTile2.scss @@ -89,7 +89,6 @@ limitations under the License. height: 16px; // don't set width so that it takes no space when there is no badge to show margin: auto 0; // vertically align - position: relative; // fixes badge alignment in some scenarios // Create a flexbox to make aligning dot badges easier display: flex; From ade89ab4e90cf8882a68445f110e3e83f715a5e7 Mon Sep 17 00:00:00 2001 From: Jorik Schellekens Date: Thu, 9 Jul 2020 18:32:28 +0100 Subject: [PATCH 05/10] Move sublist auto expand to out from layouts Co-authored-by: Travis Ralston --- src/components/views/rooms/RoomList2.tsx | 14 ++-------- src/components/views/rooms/RoomSublist2.tsx | 31 +++++++++++++-------- src/stores/room-list/ListLayout.ts | 12 -------- 3 files changed, 22 insertions(+), 35 deletions(-) diff --git a/src/components/views/rooms/RoomList2.tsx b/src/components/views/rooms/RoomList2.tsx index 5cb60655ce..79f6ed0d10 100644 --- a/src/components/views/rooms/RoomList2.tsx +++ b/src/components/views/rooms/RoomList2.tsx @@ -191,18 +191,7 @@ export default class RoomList2 extends React.Component { show_room_tile: true, // to make sure the room gets scrolled into view }); } - } else if (payload.action === Action.StartRoomFilter) { - this.state.layouts.forEach(x => { - x.saveCollapsedState(); - x.isCollapsed = false; - }); - this.forceUpdate(); - } else if (payload.action === Action.StopRoomFilter) { - this.state.layouts.forEach(x => { - x.restoreCollapsedState(); - }); - this.forceUpdate(); - } + } }; private getRoomDelta = (roomId: string, delta: number, unread = false) => { @@ -304,6 +293,7 @@ export default class RoomList2 extends React.Component { isMinimized={this.props.isMinimized} onResize={this.props.onResize} extraBadTilesThatShouldntExist={extraTiles} + isFiltered={!!this.searchFilter.search} /> ); } diff --git a/src/components/views/rooms/RoomSublist2.tsx b/src/components/views/rooms/RoomSublist2.tsx index c3ac85e2de..e7deca2543 100644 --- a/src/components/views/rooms/RoomSublist2.tsx +++ b/src/components/views/rooms/RoomSublist2.tsx @@ -47,6 +47,7 @@ import { Direction } from "re-resizable/lib/resizer"; import { polyfillTouchEvent } from "../../../@types/polyfill"; import { RoomNotificationStateStore } from "../../../stores/notifications/RoomNotificationStateStore"; import RoomListLayoutStore from "../../../stores/room-list/RoomListLayoutStore"; +import { Action } from "../../../dispatcher/actions"; // TODO: Remove banner on launch: https://github.com/vector-im/riot-web/issues/14231 // TODO: Rename on launch: https://github.com/vector-im/riot-web/issues/14231 @@ -78,6 +79,7 @@ interface IProps { isMinimized: boolean; tagId: TagID; onResize: () => void; + isFiltered: boolean; // TODO: Don't use this. It's for community invites, and community invites shouldn't be here. // You should feel bad if you use this. @@ -92,6 +94,7 @@ interface IState { notificationState: ListNotificationState; contextMenuPosition: PartialDOMRect; isResizing: boolean; + isExpanded: boolean; // used for the for expand of the sublist when the room list is being filtered } export default class RoomSublist2 extends React.Component { @@ -109,6 +112,7 @@ export default class RoomSublist2 extends React.Component { notificationState: RoomNotificationStateStore.instance.getListState(this.props.tagId), contextMenuPosition: null, isResizing: false, + isExpanded: this.props.isFiltered ? this.props.isFiltered : !this.layout.isCollapsed }; this.state.notificationState.setRooms(this.props.rooms); this.dispatcherRef = defaultDispatcher.register(this.onAction); @@ -123,8 +127,15 @@ export default class RoomSublist2 extends React.Component { return Math.min(nVisible, this.numTiles); } - public componentDidUpdate() { + public componentDidUpdate(prevProps: Readonly) { this.state.notificationState.setRooms(this.props.rooms); + if (prevProps.isFiltered !== this.props.isFiltered) { + if (this.props.isFiltered) { + this.setState({isExpanded: true}); + } else { + this.setState({isExpanded: !this.layout.isCollapsed}); + } + } } public componentWillUnmount() { @@ -137,10 +148,9 @@ export default class RoomSublist2 extends React.Component { // XXX: we have to do this a tick later because we have incorrect intermediate props during a room change // where we lose the room we are changing from temporarily and then it comes back in an update right after. setImmediate(() => { - const isCollapsed = this.layout.isCollapsed; const roomIndex = this.props.rooms.findIndex((r) => r.roomId === payload.room_id); - if (isCollapsed && roomIndex > -1) { + if (!this.state.isExpanded && roomIndex > -1) { this.toggleCollapsed(); } // extend the visible section to include the room if it is entirely invisible @@ -295,24 +305,23 @@ export default class RoomSublist2 extends React.Component { }; private toggleCollapsed = () => { - this.layout.isCollapsed = !this.layout.isCollapsed; - this.forceUpdate(); // because the layout doesn't trigger an update + this.layout.isCollapsed = this.state.isExpanded; + this.setState({isExpanded: !this.layout.isCollapsed}); setImmediate(() => this.props.onResize()); // needs to happen when the DOM is updated }; private onHeaderKeyDown = (ev: React.KeyboardEvent) => { - const isCollapsed = this.layout && this.layout.isCollapsed; switch (ev.key) { case Key.ARROW_LEFT: ev.stopPropagation(); - if (!isCollapsed) { + if (this.state.isExpanded) { // On ARROW_LEFT collapse the room sublist if it isn't already this.toggleCollapsed(); } break; case Key.ARROW_RIGHT: { ev.stopPropagation(); - if (isCollapsed) { + if (!this.state.isExpanded) { // On ARROW_RIGHT expand the room sublist if it isn't already this.toggleCollapsed(); } else if (this.sublistRef.current) { @@ -341,7 +350,7 @@ export default class RoomSublist2 extends React.Component { }; private renderVisibleTiles(): React.ReactElement[] { - if (this.layout && this.layout.isCollapsed) { + if (!this.state.isExpanded) { // don't waste time on rendering return []; } @@ -498,7 +507,7 @@ export default class RoomSublist2 extends React.Component { const collapseClasses = classNames({ 'mx_RoomSublist2_collapseBtn': true, - 'mx_RoomSublist2_collapseBtn_collapsed': this.layout && this.layout.isCollapsed, + 'mx_RoomSublist2_collapseBtn_collapsed': !this.state.isExpanded, }); const classes = classNames({ @@ -526,7 +535,7 @@ export default class RoomSublist2 extends React.Component { tabIndex={tabIndex} className="mx_RoomSublist2_headerText" role="treeitem" - aria-expanded={!this.layout.isCollapsed} + aria-expanded={this.state.isExpanded} aria-level={1} onClick={this.onHeaderClick} onContextMenu={this.onContextMenu} diff --git a/src/stores/room-list/ListLayout.ts b/src/stores/room-list/ListLayout.ts index f87181ccd1..5169c5e4e5 100644 --- a/src/stores/room-list/ListLayout.ts +++ b/src/stores/room-list/ListLayout.ts @@ -26,14 +26,12 @@ interface ISerializedListLayout { numTiles: number; showPreviews: boolean; collapsed: boolean; - savedCollapsed: boolean; } export class ListLayout { private _n = 0; private _previews = false; private _collapsed = false; - private _savedCollapsed = false; constructor(public readonly tagId: TagID) { const serialized = localStorage.getItem(this.key); @@ -43,7 +41,6 @@ export class ListLayout { this._n = parsed.numTiles; this._previews = parsed.showPreviews; this._collapsed = parsed.collapsed; - this._savedCollapsed = parsed.savedCollapsed; } } @@ -136,20 +133,11 @@ export class ListLayout { localStorage.setItem(this.key, JSON.stringify(this.serialize())); } - public saveCollapsedState() { - this._savedCollapsed = this.isCollapsed; - } - - public restoreCollapsedState() { - this.isCollapsed = this._savedCollapsed; - } - private serialize(): ISerializedListLayout { return { numTiles: this.visibleTiles, showPreviews: this.showPreviews, collapsed: this.isCollapsed, - savedCollapsed: this._savedCollapsed, }; } } From 8a7bebc6bf446e58f47e4c163d62dcdcce47bd6f Mon Sep 17 00:00:00 2001 From: Jorik Schellekens Date: Thu, 9 Jul 2020 18:37:18 +0100 Subject: [PATCH 06/10] lint --- src/components/views/rooms/RoomList2.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/rooms/RoomList2.tsx b/src/components/views/rooms/RoomList2.tsx index 79f6ed0d10..ba0464a0a4 100644 --- a/src/components/views/rooms/RoomList2.tsx +++ b/src/components/views/rooms/RoomList2.tsx @@ -191,7 +191,7 @@ export default class RoomList2 extends React.Component { show_room_tile: true, // to make sure the room gets scrolled into view }); } - } + } }; private getRoomDelta = (roomId: string, delta: number, unread = false) => { From 00fc34924cffa7f83948f1c2151b050368c46c4e Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 9 Jul 2020 11:34:34 -0600 Subject: [PATCH 07/10] Fix rooms disappearing that were created by the user Fixes https://github.com/vector-im/riot-web/issues/14388 We were receiving a read receipt before a room object, leading to the algorithm to assume the room is archived (no membership), which was causing later index issues when the room tried to get moved from archived to untagged. To prevent this, we just ignore nonsensical updates. --- src/stores/room-list/algorithms/Algorithm.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/stores/room-list/algorithms/Algorithm.ts b/src/stores/room-list/algorithms/Algorithm.ts index eee8e60b86..f70eb69e91 100644 --- a/src/stores/room-list/algorithms/Algorithm.ts +++ b/src/stores/room-list/algorithms/Algorithm.ts @@ -41,6 +41,17 @@ import { getListAlgorithmInstance } from "./list-ordering"; */ export const LIST_UPDATED_EVENT = "list_updated_event"; +// These are the causes which require a room to be known in order for us to handle them. If +// a cause in this list is raised and we don't know about the room, we don't handle the update. +// +// Note: these typically happen when a new room is coming in, such as the user creating or +// joining the room. For these cases, we need to know about the room prior to handling it otherwise +// we'll make bad assumptions. +const CAUSES_REQUIRING_ROOM = [ + RoomUpdateCause.Timeline, + RoomUpdateCause.ReadReceipt, +]; + interface IStickyRoom { room: Room; position: number; @@ -755,6 +766,11 @@ export class Algorithm extends EventEmitter { } if (!this.roomIdsToTags[room.roomId]) { + if (CAUSES_REQUIRING_ROOM.includes(cause)) { + console.warn(`Skipping tag update for ${room.roomId} because we don't know about the room`); + return false; + } + // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14035 console.log(`[RoomListDebug] Updating tags for room ${room.roomId} (${room.name})`); From f8e1996e2fb8823efb3808d98a41ec19866a24f1 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 9 Jul 2020 12:08:40 -0600 Subject: [PATCH 08/10] Handle NewRoom and PossibleTagChange updates correctly For new rooms, we need to append to our list of known rooms. For tag changes, we need to be sure to update our cache when the tag can reasonably be assumed to have changed. Fixes https://github.com/vector-im/riot-web/issues/14389 --- src/stores/room-list/algorithms/Algorithm.ts | 21 ++++++++----------- .../list-ordering/ImportanceAlgorithm.ts | 14 ++++--------- .../list-ordering/NaturalAlgorithm.ts | 8 +++++-- .../list-ordering/OrderingAlgorithm.ts | 9 ++++++++ 4 files changed, 28 insertions(+), 24 deletions(-) diff --git a/src/stores/room-list/algorithms/Algorithm.ts b/src/stores/room-list/algorithms/Algorithm.ts index f70eb69e91..35511a461d 100644 --- a/src/stores/room-list/algorithms/Algorithm.ts +++ b/src/stores/room-list/algorithms/Algorithm.ts @@ -677,18 +677,6 @@ export class Algorithm extends EventEmitter { } } - if (hasTags && isForLastSticky && !knownRoomRef) { - // we have a fairly good chance at losing a room right now. Under some circumstances, - // we can end up with a room which transitions references and tag changes, then gets - // lost when the sticky room changes. To counter this, we try and add the room to the - // list manually as the condition below to update the reference will fail. - // - // Other conditions *should* result in the room being sorted into the right place. - console.warn(`${room.roomId} was about to be lost - inserting at end of room list`); - this.rooms.push(room); - knownRoomRef = true; - } - // If we have tags for a room and don't have the room referenced, something went horribly // wrong - the reference should have been updated above. if (hasTags && !knownRoomRef && !isSticky) { @@ -701,6 +689,13 @@ export class Algorithm extends EventEmitter { // to trigger a sticky room update ourselves. this._stickyRoom.room = room; } + + // If after all that we're still a NewRoom update, add the room if applicable. + // We don't do this for the sticky room (because it causes duplication issues) + // or if we know about the reference (as it should be replaced). + if (cause === RoomUpdateCause.NewRoom && !isSticky && !knownRoomRef) { + this.rooms.push(room); + } } if (cause === RoomUpdateCause.PossibleTagChange) { @@ -715,6 +710,7 @@ export class Algorithm extends EventEmitter { const algorithm: OrderingAlgorithm = this.algorithms[rmTag]; if (!algorithm) throw new Error(`No algorithm for ${rmTag}`); await algorithm.handleRoomUpdate(room, RoomUpdateCause.RoomRemoved); + this.cachedRooms[rmTag] = algorithm.orderedRooms; } for (const addTag of diff.added) { // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14035 @@ -722,6 +718,7 @@ export class Algorithm extends EventEmitter { const algorithm: OrderingAlgorithm = this.algorithms[addTag]; if (!algorithm) throw new Error(`No algorithm for ${addTag}`); await algorithm.handleRoomUpdate(room, RoomUpdateCause.NewRoom); + this.cachedRooms[addTag] = algorithm.orderedRooms; } // Update the tag map so we don't regen it in a moment diff --git a/src/stores/room-list/algorithms/list-ordering/ImportanceAlgorithm.ts b/src/stores/room-list/algorithms/list-ordering/ImportanceAlgorithm.ts index e95f92f985..3acd9f924e 100644 --- a/src/stores/room-list/algorithms/list-ordering/ImportanceAlgorithm.ts +++ b/src/stores/room-list/algorithms/list-ordering/ImportanceAlgorithm.ts @@ -160,7 +160,10 @@ export class ImportanceAlgorithm extends OrderingAlgorithm { this.cachedOrderedRooms.splice(this.indices[category], 0, room); // splice in the new room (pre-adjusted) } else if (cause === RoomUpdateCause.RoomRemoved) { const roomIdx = this.getRoomIndex(room); - if (roomIdx === -1) return false; // no change + if (roomIdx === -1) { + console.warn(`Tried to remove unknown room from ${this.tagId}: ${room.roomId}`); + return false; // no change + } const oldCategory = this.getCategoryFromIndices(roomIdx, this.indices); this.alterCategoryPositionBy(oldCategory, -1, this.indices); this.cachedOrderedRooms.splice(roomIdx, 1); // remove the room @@ -169,15 +172,6 @@ export class ImportanceAlgorithm extends OrderingAlgorithm { } } - private getRoomIndex(room: Room): number { - let roomIdx = this.cachedOrderedRooms.indexOf(room); - if (roomIdx === -1) { // can only happen if the js-sdk's store goes sideways. - console.warn(`Degrading performance to find missing room in "${this.tagId}": ${room.roomId}`); - roomIdx = this.cachedOrderedRooms.findIndex(r => r.roomId === room.roomId); - } - return roomIdx; - } - public async handleRoomUpdate(room: Room, cause: RoomUpdateCause): Promise { try { await this.updateLock.acquireAsync(); diff --git a/src/stores/room-list/algorithms/list-ordering/NaturalAlgorithm.ts b/src/stores/room-list/algorithms/list-ordering/NaturalAlgorithm.ts index f74329cb4d..849c8a2877 100644 --- a/src/stores/room-list/algorithms/list-ordering/NaturalAlgorithm.ts +++ b/src/stores/room-list/algorithms/list-ordering/NaturalAlgorithm.ts @@ -50,8 +50,12 @@ export class NaturalAlgorithm extends OrderingAlgorithm { if (cause === RoomUpdateCause.NewRoom) { this.cachedOrderedRooms.push(room); } else if (cause === RoomUpdateCause.RoomRemoved) { - const idx = this.cachedOrderedRooms.indexOf(room); - if (idx >= 0) this.cachedOrderedRooms.splice(idx, 1); + const idx = this.getRoomIndex(room); + if (idx >= 0) { + this.cachedOrderedRooms.splice(idx, 1); + } else { + console.warn(`Tried to remove unknown room from ${this.tagId}: ${room.roomId}`); + } } // TODO: Optimize this to avoid useless operations: https://github.com/vector-im/riot-web/issues/14035 diff --git a/src/stores/room-list/algorithms/list-ordering/OrderingAlgorithm.ts b/src/stores/room-list/algorithms/list-ordering/OrderingAlgorithm.ts index 4ab7650367..c47a35523c 100644 --- a/src/stores/room-list/algorithms/list-ordering/OrderingAlgorithm.ts +++ b/src/stores/room-list/algorithms/list-ordering/OrderingAlgorithm.ts @@ -70,4 +70,13 @@ export abstract class OrderingAlgorithm { * @returns True if the update requires the Algorithm to update the presentation layers. */ public abstract handleRoomUpdate(room: Room, cause: RoomUpdateCause): Promise; + + protected getRoomIndex(room: Room): number { + let roomIdx = this.cachedOrderedRooms.indexOf(room); + if (roomIdx === -1) { // can only happen if the js-sdk's store goes sideways. + console.warn(`Degrading performance to find missing room in "${this.tagId}": ${room.roomId}`); + roomIdx = this.cachedOrderedRooms.findIndex(r => r.roomId === room.roomId); + } + return roomIdx; + } } From 1983591cbf4e4b63c145570bd1be09525958314d Mon Sep 17 00:00:00 2001 From: Jorik Schellekens Date: Fri, 10 Jul 2020 02:22:34 +0100 Subject: [PATCH 09/10] Remove unused actions --- src/components/views/rooms/RoomSublist2.tsx | 1 - src/dispatcher/actions.ts | 10 ---------- 2 files changed, 11 deletions(-) diff --git a/src/components/views/rooms/RoomSublist2.tsx b/src/components/views/rooms/RoomSublist2.tsx index e7deca2543..67a84e9292 100644 --- a/src/components/views/rooms/RoomSublist2.tsx +++ b/src/components/views/rooms/RoomSublist2.tsx @@ -47,7 +47,6 @@ import { Direction } from "re-resizable/lib/resizer"; import { polyfillTouchEvent } from "../../../@types/polyfill"; import { RoomNotificationStateStore } from "../../../stores/notifications/RoomNotificationStateStore"; import RoomListLayoutStore from "../../../stores/room-list/RoomListLayoutStore"; -import { Action } from "../../../dispatcher/actions"; // TODO: Remove banner on launch: https://github.com/vector-im/riot-web/issues/14231 // TODO: Rename on launch: https://github.com/vector-im/riot-web/issues/14231 diff --git a/src/dispatcher/actions.ts b/src/dispatcher/actions.ts index 89b2216db1..9be674b59e 100644 --- a/src/dispatcher/actions.ts +++ b/src/dispatcher/actions.ts @@ -84,14 +84,4 @@ export enum Action { * Changes room based on room list order and payload parameters. Should be used with ViewRoomDeltaPayload. */ ViewRoomDelta = "view_room_delta", - - /** - * Informs the room list when room filtering has begun. No additional payload information required. - */ - StartRoomFilter = "start_room_filter", - - /** - * Informs the room list when room filtering has ended. No additional payload information required. - */ - StopRoomFilter = "stop_room_filter", } From ceff68476dcf92e49b18a730b7e2c3ecd7e9ddc1 Mon Sep 17 00:00:00 2001 From: Jorik Schellekens Date: Fri, 10 Jul 2020 02:25:15 +0100 Subject: [PATCH 10/10] Remove useless dispatches --- src/components/structures/RoomSearch.tsx | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/components/structures/RoomSearch.tsx b/src/components/structures/RoomSearch.tsx index 7c5799dcbb..8655db2e8c 100644 --- a/src/components/structures/RoomSearch.tsx +++ b/src/components/structures/RoomSearch.tsx @@ -76,7 +76,6 @@ export default class RoomSearch extends React.PureComponent { private clearInput = () => { if (!this.inputRef.current) return; this.inputRef.current.value = ""; - defaultDispatcher.dispatch({action: Action.StopRoomFilter}); this.onChange(); }; @@ -104,15 +103,9 @@ export default class RoomSearch extends React.PureComponent { private onFocus = (ev: React.FocusEvent) => { this.setState({focused: true}); ev.target.select(); - if (ev.target.value === "") { - defaultDispatcher.dispatch({action: Action.StartRoomFilter}); - } }; private onBlur = (ev: React.FocusEvent) => { - if (ev.target.value === "") { - defaultDispatcher.dispatch({action: Action.StopRoomFilter}); - } this.setState({focused: false}); };