diff --git a/src/components/structures/LeftPanel2.tsx b/src/components/structures/LeftPanel2.tsx index 74aa07e8b5..b5725c597e 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; @@ -111,6 +102,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); } }; @@ -246,7 +241,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 +381,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 916d4c0d83..798bfaa7fe 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 2887b7fa55..68b7a585b5 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 @@ -237,10 +228,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); }); }; @@ -607,8 +601,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, @@ -624,11 +616,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'. 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/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); } }; 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..ca3fcf5729 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"; @@ -29,7 +28,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..3cf71f1ca8 100644 --- a/src/stores/room-list/algorithms/Algorithm.ts +++ b/src/stores/room-list/algorithms/Algorithm.ts @@ -30,12 +30,10 @@ 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"; -// 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..09182f3bfb 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 @@ -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(); 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