From d2c7a55fa0d0cac3fcd7d68fb14588a24d0bfa30 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 13 Jul 2020 12:00:56 -0600 Subject: [PATCH 01/15] Ensure tag changes (leaving rooms) causes rooms to move between lists Fixes https://github.com/vector-im/riot-web/issues/14442 Turns out that we are so good at moving a room that when it flows through as a TIMELINE update the algorithm no-ops and does nothing, so don't do that. --- src/stores/room-list/algorithms/Algorithm.ts | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/stores/room-list/algorithms/Algorithm.ts b/src/stores/room-list/algorithms/Algorithm.ts index 17e8283c74..a8adaed4d7 100644 --- a/src/stores/room-list/algorithms/Algorithm.ts +++ b/src/stores/room-list/algorithms/Algorithm.ts @@ -698,8 +698,8 @@ export class Algorithm extends EventEmitter { } } + let didTagChange = false; if (cause === RoomUpdateCause.PossibleTagChange) { - let didTagChange = false; const oldTags = this.roomIdsToTags[room.roomId] || []; const newTags = this.getTagsForRoom(room); const diff = arrayDiff(oldTags, newTags); @@ -713,6 +713,11 @@ export class Algorithm extends EventEmitter { if (!algorithm) throw new Error(`No algorithm for ${rmTag}`); await algorithm.handleRoomUpdate(room, RoomUpdateCause.RoomRemoved); this.cachedRooms[rmTag] = algorithm.orderedRooms; + + // Later on we won't update the filtered rooms or sticky room for removed + // tags, so do so now. + this.recalculateFilteredRoomsForTag(rmTag); + this.recalculateStickyRoom(rmTag); } for (const addTag of diff.added) { if (!window.mx_QuietRoomListLogging) { @@ -812,7 +817,7 @@ export class Algorithm extends EventEmitter { return false; } - let changed = false; + let changed = didTagChange; for (const tag of tags) { const algorithm: OrderingAlgorithm = this.algorithms[tag]; if (!algorithm) throw new Error(`No algorithm for ${tag}`); From c9e231c3eb9d8662b4e2fa551408a5a22a527b57 Mon Sep 17 00:00:00 2001 From: Jorik Schellekens Date: Mon, 13 Jul 2020 19:03:31 +0100 Subject: [PATCH 02/15] Add fad --- res/css/views/rooms/_RoomSublist2.scss | 2 ++ 1 file changed, 2 insertions(+) diff --git a/res/css/views/rooms/_RoomSublist2.scss b/res/css/views/rooms/_RoomSublist2.scss index 633c33feea..20f836159b 100644 --- a/res/css/views/rooms/_RoomSublist2.scss +++ b/res/css/views/rooms/_RoomSublist2.scss @@ -196,6 +196,8 @@ limitations under the License. // as the box model should be top aligned. Happens in both FF and Chromium display: flex; flex-direction: column; + + mask-image: linear-gradient(0deg, transparent, black 3px); } .mx_RoomSublist2_resizerHandles_showNButton { From 8e982f52ff834e90464d944cf7a22131ee681936 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 13 Jul 2020 12:59:09 -0600 Subject: [PATCH 03/15] Fix extra room tiles being rendered on smaller sublists Fixes https://github.com/vector-im/riot-web/issues/14426 The issue only applies to lists which won't have a 'show less' button, as the lists with the button would have the button's height considered when determining visible tiles. For lists that were under that (1-4 rooms), the show more button wasn't being considered and thus leading to the padding being added rather than subtracted, causing an extra tile to render. By ensuring we include the padding for both show more and show less, we ensure that no extra tiles get rendered and that the cutoff semantics are still present. --- src/components/views/rooms/RoomSublist2.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/components/views/rooms/RoomSublist2.tsx b/src/components/views/rooms/RoomSublist2.tsx index c22e6cd807..2887b7fa55 100644 --- a/src/components/views/rooms/RoomSublist2.tsx +++ b/src/components/views/rooms/RoomSublist2.tsx @@ -137,9 +137,10 @@ export default class RoomSublist2 extends React.Component { let padding = RESIZE_HANDLE_HEIGHT; // this is used for calculating the max height of the whole container, // and takes into account whether there should be room reserved for the show less button - // when fully expanded. Note that the show more button might still be shown when not fully expanded, - // but in this case it will take the space of a tile and we don't need to reserve space for it. - if (this.numTiles > this.layout.defaultVisibleTiles) { + // when fully expanded. We cannot check against the layout's defaultVisible tile count + // because there are conditions in which we need to know that the 'show more' button + // is present while well under the default tile limit. + if (this.numTiles > this.numVisibleTiles) { padding += SHOW_N_BUTTON_HEIGHT; } return padding; From a8829f09d0ed23dc33148009322cb4019148e35d Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 13 Jul 2020 13:15:44 -0600 Subject: [PATCH 04/15] Ensure RoomListStore2 gets reset when the client becomes invalidated Fixes https://github.com/vector-im/riot-web/issues/14384 We also make use of the new AsyncStore type to handle this more safely. --- src/stores/room-list/RoomListStore2.ts | 48 +++++++------------- test/components/views/rooms/RoomList-test.js | 2 +- 2 files changed, 18 insertions(+), 32 deletions(-) diff --git a/src/stores/room-list/RoomListStore2.ts b/src/stores/room-list/RoomListStore2.ts index f3a77e765b..1be2bae6be 100644 --- a/src/stores/room-list/RoomListStore2.ts +++ b/src/stores/room-list/RoomListStore2.ts @@ -33,6 +33,7 @@ import { EffectiveMembership, getEffectiveMembership } from "./membership"; import { isNullOrUndefined } from "matrix-js-sdk/src/utils"; import RoomListLayoutStore from "./RoomListLayoutStore"; import { MarkedExecution } from "../../utils/MarkedExecution"; +import { AsyncStoreWithClient } from "../AsyncStoreWithClient"; interface IState { tagsEnabled?: boolean; @@ -44,14 +45,13 @@ interface IState { */ export const LISTS_UPDATE_EVENT = "lists_update"; -export class RoomListStore2 extends AsyncStore { +export class RoomListStore2 extends AsyncStoreWithClient { /** * Set to true if you're running tests on the store. Should not be touched in * any other environment. */ public static TEST_MODE = false; - private _matrixClient: MatrixClient; private initialListsGenerated = false; private enabled = false; private algorithm = new Algorithm(); @@ -78,33 +78,30 @@ export class RoomListStore2 extends AsyncStore { return this.algorithm.getOrderedRooms(); } - public get matrixClient(): MatrixClient { - return this._matrixClient; - } - // Intended for test usage public async resetStore() { await this.reset(); this.tagWatcher = new TagWatcher(this); this.filterConditions = []; this.initialListsGenerated = false; - this._matrixClient = null; this.algorithm.off(LIST_UPDATED_EVENT, this.onAlgorithmListUpdated); this.algorithm.off(FILTER_CHANGED, this.onAlgorithmListUpdated); this.algorithm = new Algorithm(); this.algorithm.on(LIST_UPDATED_EVENT, this.onAlgorithmListUpdated); this.algorithm.on(FILTER_CHANGED, this.onAlgorithmListUpdated); + + // Reset state without causing updates as the client will have been destroyed + // and downstream code will throw NPE errors. + await this.reset(null, true); } // Public for test usage. Do not call this. - public async makeReady(client: MatrixClient) { + public async makeReady() { // TODO: Remove with https://github.com/vector-im/riot-web/issues/14367 this.checkEnabled(); if (!this.enabled) return; - this._matrixClient = client; - // Update any settings here, as some may have happened before we were logically ready. // Update any settings here, as some may have happened before we were logically ready. console.log("Regenerating room lists: Startup"); @@ -161,7 +158,15 @@ export class RoomListStore2 extends AsyncStore { if (trigger) this.updateFn.trigger(); } - protected async onDispatch(payload: ActionPayload) { + protected async onReady(): Promise { + await this.makeReady(); + } + + protected async onNotReady(): Promise { + await this.resetStore(); + } + + protected async onAction(payload: ActionPayload) { // When we're running tests we can't reliably use setImmediate out of timing concerns. // As such, we use a more synchronous model. if (RoomListStore2.TEST_MODE) { @@ -175,29 +180,10 @@ export class RoomListStore2 extends AsyncStore { } protected async onDispatchAsync(payload: ActionPayload) { - if (payload.action === 'MatrixActions.sync') { - // Filter out anything that isn't the first PREPARED sync. - if (!(payload.prevState === 'PREPARED' && payload.state !== 'PREPARED')) { - return; - } - - await this.makeReady(payload.matrixClient); - - return; // no point in running the next conditions - they won't match - } - // TODO: Remove this once the RoomListStore becomes default if (!this.enabled) return; - if (payload.action === 'on_client_not_viable' || payload.action === 'on_logged_out') { - // Reset state without causing updates as the client will have been destroyed - // and downstream code will throw NPE errors. - await this.reset(null, true); - this._matrixClient = null; - this.initialListsGenerated = false; // we'll want to regenerate them - } - - // Everything below here requires a MatrixClient or some sort of logical readiness. + // Everything here requires a MatrixClient or some sort of logical readiness. const logicallyReady = this.matrixClient && this.initialListsGenerated; if (!logicallyReady) return; diff --git a/test/components/views/rooms/RoomList-test.js b/test/components/views/rooms/RoomList-test.js index e84f943708..313bd4b77e 100644 --- a/test/components/views/rooms/RoomList-test.js +++ b/test/components/views/rooms/RoomList-test.js @@ -109,7 +109,7 @@ describe('RoomList', () => { client.getRoom = (roomId) => roomMap[roomId]; // Now that everything has been set up, prepare and update the store - await RoomListStore.instance.makeReady(client); + await RoomListStore.instance.makeReady(); done(); }); From eb78b1b328a01fc7a6e2013c10a31e0feba80e6c Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 13 Jul 2020 13:18:01 -0600 Subject: [PATCH 05/15] Export the matrix client from the store --- src/stores/room-list/RoomListStore2.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/stores/room-list/RoomListStore2.ts b/src/stores/room-list/RoomListStore2.ts index 1be2bae6be..a3311ce90d 100644 --- a/src/stores/room-list/RoomListStore2.ts +++ b/src/stores/room-list/RoomListStore2.ts @@ -78,6 +78,10 @@ export class RoomListStore2 extends AsyncStoreWithClient { return this.algorithm.getOrderedRooms(); } + public get matrixClient(): MatrixClient { + return super.matrixClient; + } + // Intended for test usage public async resetStore() { await this.reset(); From 19500cf96abd23f761c5e6426da96af7329149ff Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 13 Jul 2020 13:24:02 -0600 Subject: [PATCH 06/15] Allow the tests to force a MatrixClient --- src/stores/room-list/RoomListStore2.ts | 6 +++++- test/components/views/rooms/RoomList-test.js | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/stores/room-list/RoomListStore2.ts b/src/stores/room-list/RoomListStore2.ts index a3311ce90d..d67c728bf0 100644 --- a/src/stores/room-list/RoomListStore2.ts +++ b/src/stores/room-list/RoomListStore2.ts @@ -101,7 +101,11 @@ export class RoomListStore2 extends AsyncStoreWithClient { } // Public for test usage. Do not call this. - public async makeReady() { + public async makeReady(forcedClient?: MatrixClient) { + if (forcedClient) { + super.matrixClient = forcedClient; + } + // TODO: Remove with https://github.com/vector-im/riot-web/issues/14367 this.checkEnabled(); if (!this.enabled) return; diff --git a/test/components/views/rooms/RoomList-test.js b/test/components/views/rooms/RoomList-test.js index 313bd4b77e..e84f943708 100644 --- a/test/components/views/rooms/RoomList-test.js +++ b/test/components/views/rooms/RoomList-test.js @@ -109,7 +109,7 @@ describe('RoomList', () => { client.getRoom = (roomId) => roomMap[roomId]; // Now that everything has been set up, prepare and update the store - await RoomListStore.instance.makeReady(); + await RoomListStore.instance.makeReady(client); done(); }); From 4b5faf814896445eec68de013c1fcb89a0b268a4 Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Mon, 13 Jul 2020 21:24:43 +0100 Subject: [PATCH 07/15] Update top vs. bottom sticky styles separately If a sublist changes from sticky top to sticky bottom in a single run of the logic (without passing through the default state), we were leaving the previous top position set. This handles them independently to resolve this. Fixes https://github.com/vector-im/riot-web/issues/14390 Maybe helps with https://github.com/vector-im/riot-web/issues/14443 For vector-im/riot-web#13635 --- src/components/structures/LeftPanel2.tsx | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/components/structures/LeftPanel2.tsx b/src/components/structures/LeftPanel2.tsx index 3c8994b1c0..58cf665430 100644 --- a/src/components/structures/LeftPanel2.tsx +++ b/src/components/structures/LeftPanel2.tsx @@ -187,10 +187,23 @@ export default class LeftPanel2 extends React.Component { if (header.style.top !== newTop) { header.style.top = newTop; } - } else if (style.stickyBottom) { + } else { + if (header.classList.contains("mx_RoomSublist2_headerContainer_stickyTop")) { + header.classList.remove("mx_RoomSublist2_headerContainer_stickyTop"); + } + if (header.style.top) { + header.style.removeProperty('top'); + } + } + + if (style.stickyBottom) { if (!header.classList.contains("mx_RoomSublist2_headerContainer_stickyBottom")) { header.classList.add("mx_RoomSublist2_headerContainer_stickyBottom"); } + } else { + if (header.classList.contains("mx_RoomSublist2_headerContainer_stickyBottom")) { + header.classList.remove("mx_RoomSublist2_headerContainer_stickyBottom"); + } } if (style.stickyTop || style.stickyBottom) { @@ -209,21 +222,12 @@ export default class LeftPanel2 extends React.Component { if (header.classList.contains("mx_RoomSublist2_headerContainer_sticky")) { header.classList.remove("mx_RoomSublist2_headerContainer_sticky"); } - if (header.classList.contains("mx_RoomSublist2_headerContainer_stickyTop")) { - header.classList.remove("mx_RoomSublist2_headerContainer_stickyTop"); - } - if (header.classList.contains("mx_RoomSublist2_headerContainer_stickyBottom")) { - header.classList.remove("mx_RoomSublist2_headerContainer_stickyBottom"); - } if (headerContainer.classList.contains("mx_RoomSublist2_headerContainer_hasSticky")) { headerContainer.classList.remove("mx_RoomSublist2_headerContainer_hasSticky"); } if (header.style.width) { header.style.removeProperty('width'); } - if (header.style.top) { - header.style.removeProperty('top'); - } } } From a3a1e2e01fa261698686fe8a1984b1dd5fc2197e Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 13 Jul 2020 16:38:13 -0600 Subject: [PATCH 08/15] Fix show less button occluding the last tile Fixes https://github.com/vector-im/riot-web/issues/14450 People may have to click various combinations of 'show more' and 'show less' until it fixes itself, as their layout could be a bit weird now. --- src/components/views/rooms/RoomSublist2.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/components/views/rooms/RoomSublist2.tsx b/src/components/views/rooms/RoomSublist2.tsx index 2887b7fa55..e06bbb6ff2 100644 --- a/src/components/views/rooms/RoomSublist2.tsx +++ b/src/components/views/rooms/RoomSublist2.tsx @@ -624,11 +624,15 @@ export default class RoomSublist2 extends React.Component { const showMoreAtMinHeight = minTiles < this.numTiles; const minHeightPadding = RESIZE_HANDLE_HEIGHT + (showMoreAtMinHeight ? SHOW_N_BUTTON_HEIGHT : 0); const minTilesPx = layout.tilesToPixelsWithPadding(minTiles, minHeightPadding); - const maxTilesPx = layout.tilesToPixelsWithPadding(this.numTiles, this.padding); + let maxTilesPx = layout.tilesToPixelsWithPadding(this.numTiles, this.padding); const showMoreBtnClasses = classNames({ 'mx_RoomSublist2_showNButton': true, }); + if (this.numTiles > this.layout.defaultVisibleTiles) { + maxTilesPx += SHOW_N_BUTTON_HEIGHT; + } + // If we're hiding rooms, show a 'show more' button to the user. This button // floats above the resize handle, if we have one present. If the user has all // tiles visible, it becomes 'show less'. From 80cf2839d9c90e5e41116d56c7149d8f08143430 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 13 Jul 2020 18:46:17 -0600 Subject: [PATCH 09/15] Ensure breadcrumbs don't keep turning themselves back on Fixes https://github.com/vector-im/riot-web/issues/14452 --- src/stores/BreadcrumbsStore.ts | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/stores/BreadcrumbsStore.ts b/src/stores/BreadcrumbsStore.ts index 48ef75cb59..5639a9104c 100644 --- a/src/stores/BreadcrumbsStore.ts +++ b/src/stores/BreadcrumbsStore.ts @@ -21,6 +21,7 @@ import { AsyncStoreWithClient } from "./AsyncStoreWithClient"; import defaultDispatcher from "../dispatcher/dispatcher"; import { arrayHasDiff } from "../utils/arrays"; import { RoomListStoreTempProxy } from "./room-list/RoomListStoreTempProxy"; +import { isNullOrUndefined } from "matrix-js-sdk/src/utils"; const MAX_ROOMS = 20; // arbitrary const AUTOJOIN_WAIT_THRESHOLD_MS = 90000; // 90s, the time we wait for an autojoined room to show up @@ -51,7 +52,11 @@ export class BreadcrumbsStore extends AsyncStoreWithClient { } public get visible(): boolean { - return this.state.enabled && this.matrixClient.getVisibleRooms().length >= 20; + return this.state.enabled && this.meetsRoomRequirement; + } + + private get meetsRoomRequirement(): boolean { + return this.matrixClient.getVisibleRooms().length >= 20; } protected async onAction(payload: ActionPayload) { @@ -99,8 +104,9 @@ export class BreadcrumbsStore extends AsyncStoreWithClient { } private onMyMembership = async (room: Room) => { - // We turn on breadcrumbs by default once the user has at least 1 room to show. - if (!this.state.enabled) { + // Only turn on breadcrumbs is the user hasn't explicitly turned it off again. + const settingValueRaw = SettingsStore.getValue("breadcrumbs", null, /*excludeDefault=*/true); + if (this.meetsRoomRequirement && isNullOrUndefined(settingValueRaw)) { await SettingsStore.setValue("breadcrumbs", null, SettingLevel.ACCOUNT, true); } }; From 917c41dfa03779b8207aa81f975b0395be645929 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 13 Jul 2020 20:08:12 -0600 Subject: [PATCH 10/15] Update sticky headers when breadcrumbs pop in or out Fixes https://github.com/vector-im/riot-web/issues/14455 --- src/components/structures/LeftPanel2.tsx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/components/structures/LeftPanel2.tsx b/src/components/structures/LeftPanel2.tsx index 58cf665430..9d836ddec3 100644 --- a/src/components/structures/LeftPanel2.tsx +++ b/src/components/structures/LeftPanel2.tsx @@ -111,6 +111,10 @@ export default class LeftPanel2 extends React.Component { const newVal = BreadcrumbsStore.instance.visible; if (newVal !== this.state.showBreadcrumbs) { this.setState({showBreadcrumbs: newVal}); + + // Update the sticky headers too as the breadcrumbs will be popping in or out. + if (!this.listContainerRef.current) return; // ignore: no headers to sticky + this.handleStickyHeaders(this.listContainerRef.current); } }; From bdb136e24ee6a5f2964b7b1b2780dd299e8c288e Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 13 Jul 2020 20:25:02 -0600 Subject: [PATCH 11/15] Clean up TODOs, comments, and imports in the new room list Fixes https://github.com/vector-im/riot-web/issues/14412 --- src/components/structures/LeftPanel2.tsx | 12 ------------ src/components/structures/RoomSearch.tsx | 10 ---------- src/components/structures/UserMenu.tsx | 1 + .../views/rooms/NotificationBadge.tsx | 2 -- src/components/views/rooms/RoomBreadcrumbs2.tsx | 9 --------- src/components/views/rooms/RoomList2.tsx | 10 +--------- src/components/views/rooms/RoomSublist2.tsx | 13 +------------ src/components/views/rooms/RoomTile2.tsx | 17 +---------------- src/components/views/rooms/TemporaryTile.tsx | 1 + src/stores/room-list/RoomListStore2.ts | 1 - src/stores/room-list/algorithms/Algorithm.ts | 2 -- .../list-ordering/NaturalAlgorithm.ts | 2 +- .../tag-sorting/AlphabeticAlgorithm.ts | 2 -- .../algorithms/tag-sorting/RecentAlgorithm.ts | 3 ++- 14 files changed, 8 insertions(+), 77 deletions(-) diff --git a/src/components/structures/LeftPanel2.tsx b/src/components/structures/LeftPanel2.tsx index 58cf665430..93270a5780 100644 --- a/src/components/structures/LeftPanel2.tsx +++ b/src/components/structures/LeftPanel2.tsx @@ -35,17 +35,8 @@ import RoomListStore, { LISTS_UPDATE_EVENT } from "../../stores/room-list/RoomLi import {Key} from "../../Keyboard"; import IndicatorScrollbar from "../structures/IndicatorScrollbar"; -// TODO: Remove banner on launch: https://github.com/vector-im/riot-web/issues/14367 // TODO: Rename on launch: https://github.com/vector-im/riot-web/issues/14367 -/******************************************************************* - * CAUTION * - ******************************************************************* - * This is a work in progress implementation and isn't complete or * - * even useful as a component. Please avoid using it until this * - * warning disappears. * - *******************************************************************/ - interface IProps { isMinimized: boolean; resizeNotifier: ResizeNotifier; @@ -246,7 +237,6 @@ export default class LeftPanel2 extends React.Component { } } - // TODO: Improve header reliability: https://github.com/vector-im/riot-web/issues/14232 private onScroll = (ev: React.MouseEvent) => { const list = ev.target as HTMLDivElement; this.handleStickyHeaders(list); @@ -387,8 +377,6 @@ export default class LeftPanel2 extends React.Component { onResize={this.onResize} />; - // TODO: Conference handling / calls: https://github.com/vector-im/riot-web/issues/14177 - const containerClasses = classNames({ "mx_LeftPanel2": true, "mx_LeftPanel2_hasTagPanel": !!tagPanel, diff --git a/src/components/structures/RoomSearch.tsx b/src/components/structures/RoomSearch.tsx index 231bd92ddf..517a5f2580 100644 --- a/src/components/structures/RoomSearch.tsx +++ b/src/components/structures/RoomSearch.tsx @@ -25,16 +25,6 @@ import { Key } from "../../Keyboard"; import AccessibleButton from "../views/elements/AccessibleButton"; import { Action } from "../../dispatcher/actions"; -// TODO: Remove banner on launch: https://github.com/vector-im/riot-web/issues/14367 - -/******************************************************************* - * CAUTION * - ******************************************************************* - * This is a work in progress implementation and isn't complete or * - * even useful as a component. Please avoid using it until this * - * warning disappears. * - *******************************************************************/ - interface IProps { onQueryUpdate: (newQuery: string) => void; isMinimized: boolean; diff --git a/src/components/structures/UserMenu.tsx b/src/components/structures/UserMenu.tsx index a6eabe25f7..842e11b516 100644 --- a/src/components/structures/UserMenu.tsx +++ b/src/components/structures/UserMenu.tsx @@ -170,6 +170,7 @@ export default class UserMenu extends React.Component { ev.stopPropagation(); // TODO: Archived room view: https://github.com/vector-im/riot-web/issues/14038 + // Note: You'll need to uncomment the button too. console.log("TODO: Show archived rooms"); }; diff --git a/src/components/views/rooms/NotificationBadge.tsx b/src/components/views/rooms/NotificationBadge.tsx index 941a057927..d215df9126 100644 --- a/src/components/views/rooms/NotificationBadge.tsx +++ b/src/components/views/rooms/NotificationBadge.tsx @@ -18,8 +18,6 @@ import React from "react"; import classNames from "classnames"; import { formatMinimalBadgeCount } from "../../../utils/FormattingUtils"; import SettingsStore from "../../../settings/SettingsStore"; -import { DefaultTagID, TagID } from "../../../stores/room-list/models"; -import { readReceiptChangeIsFor } from "../../../utils/read-receipts"; import AccessibleButton from "../elements/AccessibleButton"; import { XOR } from "../../../@types/common"; import { NOTIFICATION_STATE_UPDATE, NotificationState } from "../../../stores/notifications/NotificationState"; diff --git a/src/components/views/rooms/RoomBreadcrumbs2.tsx b/src/components/views/rooms/RoomBreadcrumbs2.tsx index 7d0584ef66..619ad6da4d 100644 --- a/src/components/views/rooms/RoomBreadcrumbs2.tsx +++ b/src/components/views/rooms/RoomBreadcrumbs2.tsx @@ -27,17 +27,8 @@ import RoomListStore from "../../../stores/room-list/RoomListStore2"; import { DefaultTagID } from "../../../stores/room-list/models"; import AccessibleTooltipButton from "../elements/AccessibleTooltipButton"; -// TODO: Remove banner on launch: https://github.com/vector-im/riot-web/issues/14367 // TODO: Rename on launch: https://github.com/vector-im/riot-web/issues/14367 -/******************************************************************* - * CAUTION * - ******************************************************************* - * This is a work in progress implementation and isn't complete or * - * even useful as a component. Please avoid using it until this * - * warning disappears. * - *******************************************************************/ - interface IProps { } diff --git a/src/components/views/rooms/RoomList2.tsx b/src/components/views/rooms/RoomList2.tsx index 67787963a3..61f0f5c0c8 100644 --- a/src/components/views/rooms/RoomList2.tsx +++ b/src/components/views/rooms/RoomList2.tsx @@ -41,17 +41,8 @@ import { Action } from "../../../dispatcher/actions"; import { ViewRoomDeltaPayload } from "../../../dispatcher/payloads/ViewRoomDeltaPayload"; import { RoomNotificationStateStore } from "../../../stores/notifications/RoomNotificationStateStore"; -// TODO: Remove banner on launch: https://github.com/vector-im/riot-web/issues/14367 // TODO: Rename on launch: https://github.com/vector-im/riot-web/issues/14367 -/******************************************************************* - * CAUTION * - ******************************************************************* - * This is a work in progress implementation and isn't complete or * - * even useful as a component. Please avoid using it until this * - * warning disappears. * - *******************************************************************/ - interface IProps { onKeyDown: (ev: React.KeyboardEvent) => void; onFocus: (ev: React.FocusEvent) => void; @@ -231,6 +222,7 @@ export default class RoomList2 extends React.Component { private renderCommunityInvites(): React.ReactElement[] { // TODO: Put community invites in a more sensible place (not in the room list) + // See https://github.com/vector-im/riot-web/issues/14456 return MatrixClientPeg.get().getGroups().filter(g => { if (g.myMembership !== 'invite') return false; return !this.searchFilter || this.searchFilter.matches(g.name || ""); diff --git a/src/components/views/rooms/RoomSublist2.tsx b/src/components/views/rooms/RoomSublist2.tsx index e06bbb6ff2..252de622a1 100644 --- a/src/components/views/rooms/RoomSublist2.tsx +++ b/src/components/views/rooms/RoomSublist2.tsx @@ -17,7 +17,7 @@ limitations under the License. */ import * as React from "react"; -import {createRef, UIEventHandler} from "react"; +import {createRef} from "react"; import { Room } from "matrix-js-sdk/src/models/room"; import classNames from 'classnames'; import { RovingAccessibleButton, RovingTabIndexWrapper } from "../../../accessibility/RovingTabIndex"; @@ -48,17 +48,8 @@ import { polyfillTouchEvent } from "../../../@types/polyfill"; import { RoomNotificationStateStore } from "../../../stores/notifications/RoomNotificationStateStore"; import RoomListLayoutStore from "../../../stores/room-list/RoomListLayoutStore"; -// TODO: Remove banner on launch: https://github.com/vector-im/riot-web/issues/14367 // TODO: Rename on launch: https://github.com/vector-im/riot-web/issues/14367 -/******************************************************************* - * CAUTION * - ******************************************************************* - * This is a work in progress implementation and isn't complete or * - * even useful as a component. Please avoid using it until this * - * warning disappears. * - *******************************************************************/ - const SHOW_N_BUTTON_HEIGHT = 28; // As defined by CSS const RESIZE_HANDLE_HEIGHT = 4; // As defined by CSS export const HEADER_HEIGHT = 32; // As defined by CSS @@ -607,8 +598,6 @@ export default class RoomSublist2 extends React.Component { } public render(): React.ReactElement { - // TODO: Error boundary: https://github.com/vector-im/riot-web/issues/14185 - const visibleTiles = this.renderVisibleTiles(); const classes = classNames({ 'mx_RoomSublist2': true, diff --git a/src/components/views/rooms/RoomTile2.tsx b/src/components/views/rooms/RoomTile2.tsx index ca2f8865f9..fe6a19f2ed 100644 --- a/src/components/views/rooms/RoomTile2.tsx +++ b/src/components/views/rooms/RoomTile2.tsx @@ -55,17 +55,8 @@ import {ActionPayload} from "../../../dispatcher/payloads"; import { RoomNotificationStateStore } from "../../../stores/notifications/RoomNotificationStateStore"; import { NotificationState } from "../../../stores/notifications/NotificationState"; -// TODO: Remove banner on launch: https://github.com/vector-im/riot-web/issues/14367 // TODO: Rename on launch: https://github.com/vector-im/riot-web/issues/14367 -/******************************************************************* - * CAUTION * - ******************************************************************* - * This is a work in progress implementation and isn't complete or * - * even useful as a component. Please avoid using it until this * - * warning disappears. * - *******************************************************************/ - interface IProps { room: Room; showMessagePreview: boolean; @@ -124,7 +115,6 @@ const NotifOption: React.FC = ({active, onClick, iconClassNam export default class RoomTile2 extends React.Component { private dispatcherRef: string; private roomTileRef = createRef(); - // TODO: a11y: https://github.com/vector-im/riot-web/issues/14180 constructor(props: IProps) { super(props); @@ -310,7 +300,7 @@ export default class RoomTile2 extends React.Component { await setRoomNotifsState(this.props.room.roomId, newState); } catch (error) { // TODO: some form of error notification to the user to inform them that their state change failed. - // https://github.com/vector-im/riot-web/issues/14281 + // See https://github.com/vector-im/riot-web/issues/14281 console.error(error); } @@ -398,8 +388,6 @@ export default class RoomTile2 extends React.Component { private renderGeneralMenu(): React.ReactElement { if (!this.showContextMenu) return null; // no menu to show - // TODO: We could do with a proper invite context menu, unlike what showContextMenu suggests - const roomTags = RoomListStore.instance.getTagsForRoom(this.props.room); const isFavorite = roomTags.includes(DefaultTagID.Favourite); @@ -465,8 +453,6 @@ export default class RoomTile2 extends React.Component { } public render(): React.ReactElement { - // TODO: Invites: https://github.com/vector-im/riot-web/issues/14198 - const classes = classNames({ 'mx_RoomTile2': true, 'mx_RoomTile2_selected': this.state.selected, @@ -495,7 +481,6 @@ export default class RoomTile2 extends React.Component { ); } - // TODO: the original RoomTile uses state for the room name. Do we need to? let name = this.props.room.name; if (typeof name !== 'string') name = ''; name = name.replace(":", ":\u200b"); // add a zero-width space to allow linewrapping after the colon diff --git a/src/components/views/rooms/TemporaryTile.tsx b/src/components/views/rooms/TemporaryTile.tsx index a3ee7eb5bd..9baaba817d 100644 --- a/src/components/views/rooms/TemporaryTile.tsx +++ b/src/components/views/rooms/TemporaryTile.tsx @@ -34,6 +34,7 @@ interface IState { hover: boolean; } +// TODO: Remove with community invites in the room list: https://github.com/vector-im/riot-web/issues/14456 export default class TemporaryTile extends React.Component { constructor(props: IProps) { super(props); diff --git a/src/stores/room-list/RoomListStore2.ts b/src/stores/room-list/RoomListStore2.ts index d67c728bf0..9b17069d90 100644 --- a/src/stores/room-list/RoomListStore2.ts +++ b/src/stores/room-list/RoomListStore2.ts @@ -19,7 +19,6 @@ import { MatrixClient } from "matrix-js-sdk/src/client"; import SettingsStore from "../../settings/SettingsStore"; import { DefaultTagID, OrderedDefaultTagIDs, RoomUpdateCause, TagID } from "./models"; import TagOrderStore from "../TagOrderStore"; -import { AsyncStore } from "../AsyncStore"; import { Room } from "matrix-js-sdk/src/models/room"; import { IListOrderingMap, ITagMap, ITagSortingMap, ListAlgorithm, SortAlgorithm } from "./algorithms/models"; import { ActionPayload } from "../../dispatcher/payloads"; diff --git a/src/stores/room-list/algorithms/Algorithm.ts b/src/stores/room-list/algorithms/Algorithm.ts index a8adaed4d7..e0692bbb30 100644 --- a/src/stores/room-list/algorithms/Algorithm.ts +++ b/src/stores/room-list/algorithms/Algorithm.ts @@ -34,8 +34,6 @@ import { EffectiveMembership, getEffectiveMembership, splitRoomsByMembership } f import { OrderingAlgorithm } from "./list-ordering/OrderingAlgorithm"; import { getListAlgorithmInstance } from "./list-ordering"; -// TODO: Add locking support to avoid concurrent writes? https://github.com/vector-im/riot-web/issues/14235 - /** * Fired when the Algorithm has determined a list has been updated. */ diff --git a/src/stores/room-list/algorithms/list-ordering/NaturalAlgorithm.ts b/src/stores/room-list/algorithms/list-ordering/NaturalAlgorithm.ts index ae1a2c98f6..a1c9e4eb85 100644 --- a/src/stores/room-list/algorithms/list-ordering/NaturalAlgorithm.ts +++ b/src/stores/room-list/algorithms/list-ordering/NaturalAlgorithm.ts @@ -55,7 +55,7 @@ export class NaturalAlgorithm extends OrderingAlgorithm { } } - // TODO: Optimize this to avoid useless operations: https://github.com/vector-im/riot-web/issues/14035 + // TODO: Optimize this to avoid useless operations: https://github.com/vector-im/riot-web/issues/14457 // For example, we can skip updates to alphabetic (sometimes) and manually ordered tags this.cachedOrderedRooms = await sortRoomsWithAlgorithm(this.cachedOrderedRooms, this.tagId, this.sortingAlgorithm); diff --git a/src/stores/room-list/algorithms/tag-sorting/AlphabeticAlgorithm.ts b/src/stores/room-list/algorithms/tag-sorting/AlphabeticAlgorithm.ts index 8d74ebd11e..d909fb6288 100644 --- a/src/stores/room-list/algorithms/tag-sorting/AlphabeticAlgorithm.ts +++ b/src/stores/room-list/algorithms/tag-sorting/AlphabeticAlgorithm.ts @@ -17,8 +17,6 @@ limitations under the License. import { Room } from "matrix-js-sdk/src/models/room"; import { TagID } from "../../models"; import { IAlgorithm } from "./IAlgorithm"; -import { MatrixClientPeg } from "../../../../MatrixClientPeg"; -import * as Unread from "../../../../Unread"; /** * Sorts rooms according to the browser's determination of alphabetic. diff --git a/src/stores/room-list/algorithms/tag-sorting/RecentAlgorithm.ts b/src/stores/room-list/algorithms/tag-sorting/RecentAlgorithm.ts index 154fd40b69..0a735762a9 100644 --- a/src/stores/room-list/algorithms/tag-sorting/RecentAlgorithm.ts +++ b/src/stores/room-list/algorithms/tag-sorting/RecentAlgorithm.ts @@ -33,12 +33,13 @@ export class RecentAlgorithm implements IAlgorithm { // of the rooms to each other. // TODO: We could probably improve the sorting algorithm here by finding changes. - // See https://github.com/vector-im/riot-web/issues/14035 + // See https://github.com/vector-im/riot-web/issues/14459 // For example, if we spent a little bit of time to determine which elements have // actually changed (probably needs to be done higher up?) then we could do an // insertion sort or similar on the limited set of changes. // TODO: Don't assume we're using the same client as the peg + // See https://github.com/vector-im/riot-web/issues/14458 let myUserId = ''; if (MatrixClientPeg.get()) { myUserId = MatrixClientPeg.get().getUserId(); From 4a8a59c578e442e3cd410a2a6db0859494ed516e Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 13 Jul 2020 20:29:46 -0600 Subject: [PATCH 12/15] Make EffectiveMembership utils generic Fixes https://github.com/vector-im/riot-web/issues/14460 Just have to move them to utils. --- src/stores/notifications/RoomNotificationState.ts | 2 +- src/stores/room-list/RoomListStore2.ts | 2 +- src/stores/room-list/algorithms/Algorithm.ts | 2 +- src/stores/room-list/algorithms/tag-sorting/RecentAlgorithm.ts | 2 +- src/{stores/room-list => utils}/membership.ts | 0 5 files changed, 4 insertions(+), 4 deletions(-) rename src/{stores/room-list => utils}/membership.ts (100%) diff --git a/src/stores/notifications/RoomNotificationState.ts b/src/stores/notifications/RoomNotificationState.ts index ab354c0e93..dc38f8bf0f 100644 --- a/src/stores/notifications/RoomNotificationState.ts +++ b/src/stores/notifications/RoomNotificationState.ts @@ -17,7 +17,7 @@ limitations under the License. import { NotificationColor } from "./NotificationColor"; import { IDestroyable } from "../../utils/IDestroyable"; import { MatrixClientPeg } from "../../MatrixClientPeg"; -import { EffectiveMembership, getEffectiveMembership } from "../room-list/membership"; +import { EffectiveMembership, getEffectiveMembership } from "../../utils/membership"; import { readReceiptChangeIsFor } from "../../utils/read-receipts"; import { MatrixEvent } from "matrix-js-sdk/src/models/event"; import { Room } from "matrix-js-sdk/src/models/room"; diff --git a/src/stores/room-list/RoomListStore2.ts b/src/stores/room-list/RoomListStore2.ts index d67c728bf0..80ad05cfbe 100644 --- a/src/stores/room-list/RoomListStore2.ts +++ b/src/stores/room-list/RoomListStore2.ts @@ -29,7 +29,7 @@ import { FILTER_CHANGED, IFilterCondition } from "./filters/IFilterCondition"; import { TagWatcher } from "./TagWatcher"; import RoomViewStore from "../RoomViewStore"; import { Algorithm, LIST_UPDATED_EVENT } from "./algorithms/Algorithm"; -import { EffectiveMembership, getEffectiveMembership } from "./membership"; +import { EffectiveMembership, getEffectiveMembership } from "../../utils/membership"; import { isNullOrUndefined } from "matrix-js-sdk/src/utils"; import RoomListLayoutStore from "./RoomListLayoutStore"; import { MarkedExecution } from "../../utils/MarkedExecution"; diff --git a/src/stores/room-list/algorithms/Algorithm.ts b/src/stores/room-list/algorithms/Algorithm.ts index a8adaed4d7..faa5b672d8 100644 --- a/src/stores/room-list/algorithms/Algorithm.ts +++ b/src/stores/room-list/algorithms/Algorithm.ts @@ -30,7 +30,7 @@ import { SortAlgorithm } from "./models"; import { FILTER_CHANGED, FilterPriority, IFilterCondition } from "../filters/IFilterCondition"; -import { EffectiveMembership, getEffectiveMembership, splitRoomsByMembership } from "../membership"; +import { EffectiveMembership, getEffectiveMembership, splitRoomsByMembership } from "../../../utils/membership"; import { OrderingAlgorithm } from "./list-ordering/OrderingAlgorithm"; import { getListAlgorithmInstance } from "./list-ordering"; diff --git a/src/stores/room-list/algorithms/tag-sorting/RecentAlgorithm.ts b/src/stores/room-list/algorithms/tag-sorting/RecentAlgorithm.ts index 154fd40b69..82a216c0aa 100644 --- a/src/stores/room-list/algorithms/tag-sorting/RecentAlgorithm.ts +++ b/src/stores/room-list/algorithms/tag-sorting/RecentAlgorithm.ts @@ -19,7 +19,7 @@ import { TagID } from "../../models"; import { IAlgorithm } from "./IAlgorithm"; import { MatrixClientPeg } from "../../../../MatrixClientPeg"; import * as Unread from "../../../../Unread"; -import { EffectiveMembership, getEffectiveMembership } from "../../membership"; +import { EffectiveMembership, getEffectiveMembership } from "../../../../utils/membership"; /** * Sorts rooms according to the last event's timestamp in each room that seems diff --git a/src/stores/room-list/membership.ts b/src/utils/membership.ts similarity index 100% rename from src/stores/room-list/membership.ts rename to src/utils/membership.ts From 6632db01cfae71fa5a61b842dcafc1201261a6a7 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 13 Jul 2020 20:34:05 -0600 Subject: [PATCH 13/15] Remove debug logging from new room list Fixes https://github.com/vector-im/riot-web/issues/14408 Yes, all the issue references are wrong :( --- src/@types/global.d.ts | 3 - src/components/views/rooms/RoomList2.tsx | 8 +-- src/stores/room-list/RoomListStore2.ts | 74 -------------------- src/stores/room-list/algorithms/Algorithm.ts | 73 ------------------- 4 files changed, 1 insertion(+), 157 deletions(-) diff --git a/src/@types/global.d.ts b/src/@types/global.d.ts index 3f970ea8c3..fc52296d8b 100644 --- a/src/@types/global.d.ts +++ b/src/@types/global.d.ts @@ -37,9 +37,6 @@ declare global { mx_RoomListStore2: RoomListStore2; mx_RoomListLayoutStore: RoomListLayoutStore; mxPlatformPeg: PlatformPeg; - - // TODO: Remove flag before launch: https://github.com/vector-im/riot-web/issues/14231 - mx_QuietRoomListLogging: boolean; } // workaround for https://github.com/microsoft/TypeScript/issues/30933 diff --git a/src/components/views/rooms/RoomList2.tsx b/src/components/views/rooms/RoomList2.tsx index 67787963a3..f0f3ae9f1d 100644 --- a/src/components/views/rooms/RoomList2.tsx +++ b/src/components/views/rooms/RoomList2.tsx @@ -218,13 +218,7 @@ export default class RoomList2 extends React.Component { }; private updateLists = () => { - const newLists = RoomListStore.instance.orderedLists; - if (!window.mx_QuietRoomListLogging) { - // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14035 - console.log("new lists", newLists); - } - - this.setState({sublists: newLists}, () => { + this.setState({sublists: RoomListStore.instance.orderedLists}, () => { this.props.onResize(); }); }; diff --git a/src/stores/room-list/RoomListStore2.ts b/src/stores/room-list/RoomListStore2.ts index d67c728bf0..da70135759 100644 --- a/src/stores/room-list/RoomListStore2.ts +++ b/src/stores/room-list/RoomListStore2.ts @@ -155,10 +155,6 @@ export class RoomListStore2 extends AsyncStoreWithClient { console.warn(`${activeRoomId} is current in RVS but missing from client - clearing sticky room`); await this.algorithm.setStickyRoom(null); } else if (activeRoom !== this.algorithm.stickyRoom) { - if (!window.mx_QuietRoomListLogging) { - // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14035 - console.log(`Changing sticky room to ${activeRoomId}`); - } await this.algorithm.setStickyRoom(activeRoom); } } @@ -219,20 +215,12 @@ export class RoomListStore2 extends AsyncStoreWithClient { console.warn(`Own read receipt was in unknown room ${room.roomId}`); return; } - if (!window.mx_QuietRoomListLogging) { - // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14035 - console.log(`[RoomListDebug] Got own read receipt in ${room.roomId}`); - } await this.handleRoomUpdate(room, RoomUpdateCause.ReadReceipt); this.updateFn.trigger(); return; } } else if (payload.action === 'MatrixActions.Room.tags') { const roomPayload = (payload); // TODO: Type out the dispatcher types - if (!window.mx_QuietRoomListLogging) { - // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14035 - console.log(`[RoomListDebug] Got tag change in ${roomPayload.room.roomId}`); - } await this.handleRoomUpdate(roomPayload.room, RoomUpdateCause.PossibleTagChange); this.updateFn.trigger(); } else if (payload.action === 'MatrixActions.Room.timeline') { @@ -244,16 +232,7 @@ export class RoomListStore2 extends AsyncStoreWithClient { const roomId = eventPayload.event.getRoomId(); const room = this.matrixClient.getRoom(roomId); const tryUpdate = async (updatedRoom: Room) => { - if (!window.mx_QuietRoomListLogging) { - // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14035 - console.log(`[RoomListDebug] Live timeline event ${eventPayload.event.getId()}` + - ` in ${updatedRoom.roomId}`); - } if (eventPayload.event.getType() === 'm.room.tombstone' && eventPayload.event.getStateKey() === '') { - if (!window.mx_QuietRoomListLogging) { - // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14035 - console.log(`[RoomListDebug] Got tombstone event - trying to remove now-dead room`); - } const newRoom = this.matrixClient.getRoom(eventPayload.event.getContent()['replacement_room']); if (newRoom) { // If we have the new room, then the new room check will have seen the predecessor @@ -283,18 +262,10 @@ export class RoomListStore2 extends AsyncStoreWithClient { console.warn(`Event ${eventPayload.event.getId()} was decrypted in an unknown room ${roomId}`); return; } - if (!window.mx_QuietRoomListLogging) { - // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14035 - console.log(`[RoomListDebug] Decrypted timeline event ${eventPayload.event.getId()} in ${roomId}`); - } await this.handleRoomUpdate(room, RoomUpdateCause.Timeline); this.updateFn.trigger(); } else if (payload.action === 'MatrixActions.accountData' && payload.event_type === 'm.direct') { const eventPayload = (payload); // TODO: Type out the dispatcher types - if (!window.mx_QuietRoomListLogging) { - // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14035 - console.log(`[RoomListDebug] Received updated DM map`); - } const dmMap = eventPayload.event.getContent(); for (const userId of Object.keys(dmMap)) { const roomIds = dmMap[userId]; @@ -318,54 +289,29 @@ export class RoomListStore2 extends AsyncStoreWithClient { const oldMembership = getEffectiveMembership(membershipPayload.oldMembership); const newMembership = getEffectiveMembership(membershipPayload.membership); if (oldMembership !== EffectiveMembership.Join && newMembership === EffectiveMembership.Join) { - if (!window.mx_QuietRoomListLogging) { - // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14035 - console.log(`[RoomListDebug] Handling new room ${membershipPayload.room.roomId}`); - } - // If we're joining an upgraded room, we'll want to make sure we don't proliferate // the dead room in the list. const createEvent = membershipPayload.room.currentState.getStateEvents("m.room.create", ""); if (createEvent && createEvent.getContent()['predecessor']) { - if (!window.mx_QuietRoomListLogging) { - // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14035 - console.log(`[RoomListDebug] Room has a predecessor`); - } const prevRoom = this.matrixClient.getRoom(createEvent.getContent()['predecessor']['room_id']); if (prevRoom) { const isSticky = this.algorithm.stickyRoom === prevRoom; if (isSticky) { - if (!window.mx_QuietRoomListLogging) { - // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14035 - console.log(`[RoomListDebug] Clearing sticky room due to room upgrade`); - } await this.algorithm.setStickyRoom(null); } // Note: we hit the algorithm instead of our handleRoomUpdate() function to // avoid redundant updates. - if (!window.mx_QuietRoomListLogging) { - // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14035 - console.log(`[RoomListDebug] Removing previous room from room list`); - } await this.algorithm.handleRoomUpdate(prevRoom, RoomUpdateCause.RoomRemoved); } } - if (!window.mx_QuietRoomListLogging) { - // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14035 - console.log(`[RoomListDebug] Adding new room to room list`); - } await this.handleRoomUpdate(membershipPayload.room, RoomUpdateCause.NewRoom); this.updateFn.trigger(); return; } if (oldMembership !== EffectiveMembership.Invite && newMembership === EffectiveMembership.Invite) { - if (!window.mx_QuietRoomListLogging) { - // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14035 - console.log(`[RoomListDebug] Handling invite to ${membershipPayload.room.roomId}`); - } await this.handleRoomUpdate(membershipPayload.room, RoomUpdateCause.NewRoom); this.updateFn.trigger(); return; @@ -373,10 +319,6 @@ export class RoomListStore2 extends AsyncStoreWithClient { // If it's not a join, it's transitioning into a different list (possibly historical) if (oldMembership !== newMembership) { - if (!window.mx_QuietRoomListLogging) { - // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14035 - console.log(`[RoomListDebug] Handling membership change in ${membershipPayload.room.roomId}`); - } await this.handleRoomUpdate(membershipPayload.room, RoomUpdateCause.PossibleTagChange); this.updateFn.trigger(); return; @@ -387,10 +329,6 @@ export class RoomListStore2 extends AsyncStoreWithClient { private async handleRoomUpdate(room: Room, cause: RoomUpdateCause): Promise { const shouldUpdate = await this.algorithm.handleRoomUpdate(room, cause); if (shouldUpdate) { - if (!window.mx_QuietRoomListLogging) { - // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14035 - console.log(`[DEBUG] Room "${room.name}" (${room.roomId}) triggered by ${cause} requires list update`); - } this.updateFn.mark(); } } @@ -510,10 +448,6 @@ export class RoomListStore2 extends AsyncStoreWithClient { } private onAlgorithmListUpdated = () => { - if (!window.mx_QuietRoomListLogging) { - // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14035 - console.log("Underlying algorithm has triggered a list update - marking"); - } this.updateFn.mark(); }; @@ -560,10 +494,6 @@ export class RoomListStore2 extends AsyncStoreWithClient { } public addFilter(filter: IFilterCondition): void { - if (!window.mx_QuietRoomListLogging) { - // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14035 - console.log("Adding filter condition:", filter); - } this.filterConditions.push(filter); if (this.algorithm) { this.algorithm.addFilterCondition(filter); @@ -572,10 +502,6 @@ export class RoomListStore2 extends AsyncStoreWithClient { } public removeFilter(filter: IFilterCondition): void { - if (!window.mx_QuietRoomListLogging) { - // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14035 - console.log("Removing filter condition:", filter); - } const idx = this.filterConditions.indexOf(filter); if (idx >= 0) { this.filterConditions.splice(idx, 1); diff --git a/src/stores/room-list/algorithms/Algorithm.ts b/src/stores/room-list/algorithms/Algorithm.ts index a8adaed4d7..d1ca0a8d46 100644 --- a/src/stores/room-list/algorithms/Algorithm.ts +++ b/src/stores/room-list/algorithms/Algorithm.ts @@ -321,11 +321,6 @@ export class Algorithm extends EventEmitter { } } newMap[tagId] = allowedRoomsInThisTag; - - if (!window.mx_QuietRoomListLogging) { - // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14035 - console.log(`[DEBUG] ${newMap[tagId].length}/${rooms.length} rooms filtered into ${tagId}`); - } } const allowedRooms = Object.values(newMap).reduce((rv, v) => { rv.push(...v); return rv; }, []); @@ -337,10 +332,6 @@ export class Algorithm extends EventEmitter { protected recalculateFilteredRoomsForTag(tagId: TagID): void { if (!this.hasFilters) return; // don't bother doing work if there's nothing to do - if (!window.mx_QuietRoomListLogging) { - // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14035 - console.log(`Recalculating filtered rooms for ${tagId}`); - } delete this.filteredRooms[tagId]; const rooms = this.cachedRooms[tagId].map(r => r); // cheap clone this.tryInsertStickyRoomToFilterSet(rooms, tagId); @@ -348,11 +339,6 @@ export class Algorithm extends EventEmitter { if (filteredRooms.length > 0) { this.filteredRooms[tagId] = filteredRooms; } - - if (!window.mx_QuietRoomListLogging) { - // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14035 - console.log(`[DEBUG] ${filteredRooms.length}/${rooms.length} rooms filtered into ${tagId}`); - } } protected tryInsertStickyRoomToFilterSet(rooms: Room[], tagId: TagID) { @@ -391,10 +377,6 @@ export class Algorithm extends EventEmitter { } if (!this._cachedStickyRooms || !updatedTag) { - if (!window.mx_QuietRoomListLogging) { - // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14035 - console.log(`Generating clone of cached rooms for sticky room handling`); - } const stickiedTagMap: ITagMap = {}; for (const tagId of Object.keys(this.cachedRooms)) { stickiedTagMap[tagId] = this.cachedRooms[tagId].map(r => r); // shallow clone @@ -405,10 +387,6 @@ export class Algorithm extends EventEmitter { if (updatedTag) { // Update the tag indicated by the caller, if possible. This is mostly to ensure // our cache is up to date. - if (!window.mx_QuietRoomListLogging) { - // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14035 - console.log(`Replacing cached sticky rooms for ${updatedTag}`); - } this._cachedStickyRooms[updatedTag] = this.cachedRooms[updatedTag].map(r => r); // shallow clone } @@ -417,10 +395,6 @@ export class Algorithm extends EventEmitter { // we might have updated from the cache is also our sticky room. const sticky = this._stickyRoom; if (!updatedTag || updatedTag === sticky.tag) { - if (!window.mx_QuietRoomListLogging) { - // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14035 - console.log(`Inserting sticky room ${sticky.room.roomId} at position ${sticky.position} in ${sticky.tag}`); - } this._cachedStickyRooms[sticky.tag].splice(sticky.position, 0, sticky.room); } @@ -645,10 +619,6 @@ export class Algorithm extends EventEmitter { * processing. */ public async handleRoomUpdate(room: Room, cause: RoomUpdateCause): Promise { - if (!window.mx_QuietRoomListLogging) { - // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14035 - console.log(`Handle room update for ${room.roomId} called with cause ${cause}`); - } if (!this.algorithms) throw new Error("Not ready: no algorithms to determine tags from"); // Note: check the isSticky against the room ID just in case the reference is wrong @@ -705,10 +675,6 @@ export class Algorithm extends EventEmitter { const diff = arrayDiff(oldTags, newTags); if (diff.removed.length > 0 || diff.added.length > 0) { for (const rmTag of diff.removed) { - if (!window.mx_QuietRoomListLogging) { - // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14035 - console.log(`Removing ${room.roomId} from ${rmTag}`); - } const algorithm: OrderingAlgorithm = this.algorithms[rmTag]; if (!algorithm) throw new Error(`No algorithm for ${rmTag}`); await algorithm.handleRoomUpdate(room, RoomUpdateCause.RoomRemoved); @@ -720,10 +686,6 @@ export class Algorithm extends EventEmitter { this.recalculateStickyRoom(rmTag); } for (const addTag of diff.added) { - if (!window.mx_QuietRoomListLogging) { - // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14035 - console.log(`Adding ${room.roomId} to ${addTag}`); - } const algorithm: OrderingAlgorithm = this.algorithms[addTag]; if (!algorithm) throw new Error(`No algorithm for ${addTag}`); await algorithm.handleRoomUpdate(room, RoomUpdateCause.NewRoom); @@ -733,17 +695,9 @@ export class Algorithm extends EventEmitter { // Update the tag map so we don't regen it in a moment this.roomIdsToTags[room.roomId] = newTags; - if (!window.mx_QuietRoomListLogging) { - // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14035 - console.log(`Changing update cause for ${room.roomId} to Timeline to sort rooms`); - } cause = RoomUpdateCause.Timeline; didTagChange = true; } else { - if (!window.mx_QuietRoomListLogging) { - // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14035 - console.log(`Received no-op update for ${room.roomId} - changing to Timeline update`); - } cause = RoomUpdateCause.Timeline; } @@ -769,28 +723,15 @@ export class Algorithm extends EventEmitter { // as the sticky room relies on this. if (cause !== RoomUpdateCause.NewRoom && cause !== RoomUpdateCause.RoomRemoved) { if (this.stickyRoom === room) { - if (!window.mx_QuietRoomListLogging) { - // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14035 - console.warn(`[RoomListDebug] Received ${cause} update for sticky room ${room.roomId} - ignoring`); - } return false; } } if (!this.roomIdsToTags[room.roomId]) { if (CAUSES_REQUIRING_ROOM.includes(cause)) { - if (!window.mx_QuietRoomListLogging) { - // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14035 - console.warn(`Skipping tag update for ${room.roomId} because we don't know about the room`); - } return false; } - if (!window.mx_QuietRoomListLogging) { - // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14035 - console.log(`[RoomListDebug] Updating tags for room ${room.roomId} (${room.name})`); - } - // Get the tags for the room and populate the cache const roomTags = this.getTagsForRoom(room).filter(t => !isNullOrUndefined(this.cachedRooms[t])); @@ -799,16 +740,6 @@ export class Algorithm extends EventEmitter { if (!roomTags.length) throw new Error(`Tags cannot be determined for ${room.roomId}`); this.roomIdsToTags[room.roomId] = roomTags; - - if (!window.mx_QuietRoomListLogging) { - // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14035 - console.log(`[RoomListDebug] Updated tags for ${room.roomId}:`, roomTags); - } - } - - if (!window.mx_QuietRoomListLogging) { - // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14035 - console.log(`[RoomListDebug] Reached algorithmic handling for ${room.roomId} and cause ${cause}`); } const tags = this.roomIdsToTags[room.roomId]; @@ -831,10 +762,6 @@ export class Algorithm extends EventEmitter { changed = true; } - if (!window.mx_QuietRoomListLogging) { - // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14035 - console.log(`[RoomListDebug] Finished handling ${room.roomId} with cause ${cause} (changed=${changed})`); - } return changed; } } From 03f94779f16d12801a951da8efd8647f61d9dcdc Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 14 Jul 2020 09:38:31 +0100 Subject: [PATCH 14/15] Fix show-all keyboard focus regression Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/rooms/RoomSublist2.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/components/views/rooms/RoomSublist2.tsx b/src/components/views/rooms/RoomSublist2.tsx index e06bbb6ff2..d24b28bb60 100644 --- a/src/components/views/rooms/RoomSublist2.tsx +++ b/src/components/views/rooms/RoomSublist2.tsx @@ -237,10 +237,13 @@ export default class RoomSublist2 extends React.Component { }; private onShowAllClick = () => { + // read number of visible tiles before we mutate it + const numVisibleTiles = this.numVisibleTiles; const newHeight = this.layout.tilesToPixelsWithPadding(this.numTiles, this.padding); this.applyHeightChange(newHeight); this.setState({height: newHeight}, () => { - this.focusRoomTile(this.numTiles - 1); + // focus the top-most new room + this.focusRoomTile(numVisibleTiles); }); }; From a09f773edd2864c408bedd80474dcab5e62b301a Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Tue, 14 Jul 2020 12:13:04 +0100 Subject: [PATCH 15/15] Tweak sticky header hiding to avoid pop When transitioning between sublists, there can be a visibly observable jump in the positioning of list items when the header container is restored to normal size outside of sticky mode. To avoid this problem, this leaves all headers at normal size. This creates a new issue of a permanent gap at the top of the list for the first header, but this can be solved by always hiding (since it can only ever appear stuck to top). Fixes https://github.com/vector-im/riot-web/issues/14429 --- res/css/views/rooms/_RoomSublist2.scss | 15 +++++++++------ src/components/structures/LeftPanel2.tsx | 7 ------- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/res/css/views/rooms/_RoomSublist2.scss b/res/css/views/rooms/_RoomSublist2.scss index 20f836159b..47de95dfc7 100644 --- a/res/css/views/rooms/_RoomSublist2.scss +++ b/res/css/views/rooms/_RoomSublist2.scss @@ -47,12 +47,6 @@ limitations under the License. padding-bottom: 8px; height: 24px; - // Hide the header container if the contained element is stickied. - // We don't use display:none as that causes the header to go away too. - &.mx_RoomSublist2_headerContainer_hasSticky { - height: 0; - } - .mx_RoomSublist2_stickable { flex: 1; max-width: 100%; @@ -180,6 +174,15 @@ limitations under the License. } } + // In the general case, we leave height of headers alone even if sticky, so + // that the sublists below them do not jump. However, that leaves a gap + // when scrolled to the top above the first sublist (whose header can only + // ever stick to top), so we force height to 0 for only that first header. + // See also https://github.com/vector-im/riot-web/issues/14429. + &:first-child .mx_RoomSublist2_headerContainer { + height: 0; + } + .mx_RoomSublist2_resizeBox { position: relative; diff --git a/src/components/structures/LeftPanel2.tsx b/src/components/structures/LeftPanel2.tsx index 870080c811..d41a7278d9 100644 --- a/src/components/structures/LeftPanel2.tsx +++ b/src/components/structures/LeftPanel2.tsx @@ -165,7 +165,6 @@ export default class LeftPanel2 extends React.Component { // layout updates. for (const header of targetStyles.keys()) { const style = targetStyles.get(header); - const headerContainer = header.parentElement; // .mx_RoomSublist2_headerContainer if (style.makeInvisible) { // we will have already removed the 'display: none', so add it back. @@ -205,9 +204,6 @@ export default class LeftPanel2 extends React.Component { if (!header.classList.contains("mx_RoomSublist2_headerContainer_sticky")) { header.classList.add("mx_RoomSublist2_headerContainer_sticky"); } - if (!headerContainer.classList.contains("mx_RoomSublist2_headerContainer_hasSticky")) { - headerContainer.classList.add("mx_RoomSublist2_headerContainer_hasSticky"); - } const newWidth = `${headerStickyWidth}px`; if (header.style.width !== newWidth) { @@ -217,9 +213,6 @@ export default class LeftPanel2 extends React.Component { if (header.classList.contains("mx_RoomSublist2_headerContainer_sticky")) { header.classList.remove("mx_RoomSublist2_headerContainer_sticky"); } - if (headerContainer.classList.contains("mx_RoomSublist2_headerContainer_hasSticky")) { - headerContainer.classList.remove("mx_RoomSublist2_headerContainer_hasSticky"); - } if (header.style.width) { header.style.removeProperty('width'); }