mirror of
https://github.com/element-hq/element-web
synced 2024-11-24 02:05:45 +03:00
Merge branch 'develop' into joriks/delabs-font-scaling
This commit is contained in:
commit
76fbb7c1b0
19 changed files with 93 additions and 299 deletions
|
@ -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;
|
||||
|
||||
|
@ -196,6 +199,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 {
|
||||
|
|
3
src/@types/global.d.ts
vendored
3
src/@types/global.d.ts
vendored
|
@ -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
|
||||
|
|
|
@ -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<IProps, IState> {
|
|||
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);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -170,7 +165,6 @@ export default class LeftPanel2 extends React.Component<IProps, IState> {
|
|||
// 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.
|
||||
|
@ -187,19 +181,29 @@ export default class LeftPanel2 extends React.Component<IProps, IState> {
|
|||
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) {
|
||||
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) {
|
||||
|
@ -209,21 +213,9 @@ export default class LeftPanel2 extends React.Component<IProps, IState> {
|
|||
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');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -242,7 +234,6 @@ export default class LeftPanel2 extends React.Component<IProps, IState> {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: Improve header reliability: https://github.com/vector-im/riot-web/issues/14232
|
||||
private onScroll = (ev: React.MouseEvent<HTMLDivElement>) => {
|
||||
const list = ev.target as HTMLDivElement;
|
||||
this.handleStickyHeaders(list);
|
||||
|
@ -383,8 +374,6 @@ export default class LeftPanel2 extends React.Component<IProps, IState> {
|
|||
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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -170,6 +170,7 @@ export default class UserMenu extends React.Component<IProps, IState> {
|
|||
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");
|
||||
};
|
||||
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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 {
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
@ -218,19 +209,14 @@ export default class RoomList2 extends React.Component<IProps, IState> {
|
|||
};
|
||||
|
||||
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();
|
||||
});
|
||||
};
|
||||
|
||||
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 || "");
|
||||
|
|
|
@ -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
|
||||
|
@ -137,9 +128,10 @@ export default class RoomSublist2 extends React.Component<IProps, IState> {
|
|||
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;
|
||||
|
@ -236,10 +228,13 @@ export default class RoomSublist2 extends React.Component<IProps, IState> {
|
|||
};
|
||||
|
||||
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);
|
||||
});
|
||||
};
|
||||
|
||||
|
@ -606,8 +601,6 @@ export default class RoomSublist2 extends React.Component<IProps, IState> {
|
|||
}
|
||||
|
||||
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,
|
||||
|
@ -623,11 +616,15 @@ export default class RoomSublist2 extends React.Component<IProps, IState> {
|
|||
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'.
|
||||
|
|
|
@ -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<INotifOptionProps> = ({active, onClick, iconClassNam
|
|||
export default class RoomTile2 extends React.Component<IProps, IState> {
|
||||
private dispatcherRef: string;
|
||||
private roomTileRef = createRef<HTMLDivElement>();
|
||||
// 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<IProps, IState> {
|
|||
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<IProps, IState> {
|
|||
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<IProps, IState> {
|
|||
}
|
||||
|
||||
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<IProps, IState> {
|
|||
);
|
||||
}
|
||||
|
||||
// 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
|
||||
|
|
|
@ -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<IProps, IState> {
|
||||
constructor(props: IProps) {
|
||||
super(props);
|
||||
|
|
|
@ -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<IState> {
|
|||
}
|
||||
|
||||
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<IState> {
|
|||
}
|
||||
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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,10 +28,11 @@ 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";
|
||||
import { AsyncStoreWithClient } from "../AsyncStoreWithClient";
|
||||
|
||||
interface IState {
|
||||
tagsEnabled?: boolean;
|
||||
|
@ -44,14 +44,13 @@ interface IState {
|
|||
*/
|
||||
export const LISTS_UPDATE_EVENT = "lists_update";
|
||||
|
||||
export class RoomListStore2 extends AsyncStore<ActionPayload> {
|
||||
export class RoomListStore2 extends AsyncStoreWithClient<ActionPayload> {
|
||||
/**
|
||||
* 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();
|
||||
|
@ -79,7 +78,7 @@ export class RoomListStore2 extends AsyncStore<ActionPayload> {
|
|||
}
|
||||
|
||||
public get matrixClient(): MatrixClient {
|
||||
return this._matrixClient;
|
||||
return super.matrixClient;
|
||||
}
|
||||
|
||||
// Intended for test usage
|
||||
|
@ -88,23 +87,28 @@ export class RoomListStore2 extends AsyncStore<ActionPayload> {
|
|||
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(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;
|
||||
|
||||
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");
|
||||
|
@ -150,10 +154,6 @@ export class RoomListStore2 extends AsyncStore<ActionPayload> {
|
|||
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);
|
||||
}
|
||||
}
|
||||
|
@ -161,7 +161,15 @@ export class RoomListStore2 extends AsyncStore<ActionPayload> {
|
|||
if (trigger) this.updateFn.trigger();
|
||||
}
|
||||
|
||||
protected async onDispatch(payload: ActionPayload) {
|
||||
protected async onReady(): Promise<any> {
|
||||
await this.makeReady();
|
||||
}
|
||||
|
||||
protected async onNotReady(): Promise<any> {
|
||||
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 +183,10 @@ export class RoomListStore2 extends AsyncStore<ActionPayload> {
|
|||
}
|
||||
|
||||
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;
|
||||
|
||||
|
@ -225,20 +214,12 @@ export class RoomListStore2 extends AsyncStore<ActionPayload> {
|
|||
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 = (<any>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') {
|
||||
|
@ -250,16 +231,7 @@ export class RoomListStore2 extends AsyncStore<ActionPayload> {
|
|||
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
|
||||
|
@ -289,18 +261,10 @@ export class RoomListStore2 extends AsyncStore<ActionPayload> {
|
|||
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 = (<any>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];
|
||||
|
@ -324,54 +288,29 @@ export class RoomListStore2 extends AsyncStore<ActionPayload> {
|
|||
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;
|
||||
|
@ -379,10 +318,6 @@ export class RoomListStore2 extends AsyncStore<ActionPayload> {
|
|||
|
||||
// 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;
|
||||
|
@ -393,10 +328,6 @@ export class RoomListStore2 extends AsyncStore<ActionPayload> {
|
|||
private async handleRoomUpdate(room: Room, cause: RoomUpdateCause): Promise<any> {
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
@ -516,10 +447,6 @@ export class RoomListStore2 extends AsyncStore<ActionPayload> {
|
|||
}
|
||||
|
||||
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();
|
||||
};
|
||||
|
||||
|
@ -566,10 +493,6 @@ export class RoomListStore2 extends AsyncStore<ActionPayload> {
|
|||
}
|
||||
|
||||
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);
|
||||
|
@ -578,10 +501,6 @@ export class RoomListStore2 extends AsyncStore<ActionPayload> {
|
|||
}
|
||||
|
||||
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);
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
@ -321,11 +319,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; }, <Room[]>[]);
|
||||
|
@ -337,10 +330,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 +337,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 +375,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 +385,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 +393,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 +617,6 @@ export class Algorithm extends EventEmitter {
|
|||
* processing.
|
||||
*/
|
||||
public async handleRoomUpdate(room: Room, cause: RoomUpdateCause): Promise<boolean> {
|
||||
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
|
||||
|
@ -698,27 +666,24 @@ 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);
|
||||
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);
|
||||
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) {
|
||||
// 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);
|
||||
|
@ -728,17 +693,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;
|
||||
}
|
||||
|
||||
|
@ -764,28 +721,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]));
|
||||
|
||||
|
@ -794,16 +738,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];
|
||||
|
@ -812,7 +746,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}`);
|
||||
|
@ -826,10 +760,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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in a new issue