Step 8.3: Convert RoomViewStore to a more modern singleton for imports

This commit is contained in:
Travis Ralston 2022-03-22 23:26:30 -06:00
parent 8d2dba4102
commit d5ed1eb66e
24 changed files with 99 additions and 102 deletions

View file

@ -16,7 +16,7 @@ limitations under the License.
import { logger } from "matrix-js-sdk/src/logger";
import RoomViewStore from './stores/RoomViewStore';
import { RoomViewStore } from './stores/RoomViewStore';
type Listener = (isActive: boolean) => void;
@ -31,11 +31,12 @@ type Listener = (isActive: boolean) => void;
*/
export class ActiveRoomObserver {
private listeners: {[key: string]: Listener[]} = {};
private _activeRoomId = RoomViewStore.getRoomId();
private _activeRoomId = RoomViewStore.instance.getRoomId();
private readonly roomStoreToken: EventSubscription;
constructor() {
// TODO: We could self-destruct when the last listener goes away, or at least stop listening.
RoomViewStore.addListener(this.onRoomViewStoreUpdate);
this.roomStoreToken = RoomViewStore.instance.addListener(this.onRoomViewStoreUpdate);
}
public get activeRoomId(): string {
@ -71,7 +72,7 @@ export class ActiveRoomObserver {
if (this._activeRoomId) this.emit(this._activeRoomId, false);
// update our cache
this._activeRoomId = RoomViewStore.getRoomId();
this._activeRoomId = RoomViewStore.instance.getRoomId();
// and emit for the new one
if (this._activeRoomId) this.emit(this._activeRoomId, true);

View file

@ -44,7 +44,7 @@ import { BlurhashEncoder } from "./BlurhashEncoder";
import SettingsStore from "./settings/SettingsStore";
import { decorateStartSendingTime, sendRoundTripMetric } from "./sendTimePerformanceMetrics";
import { TimelineRenderingType } from "./contexts/RoomContext";
import RoomViewStore from "./stores/RoomViewStore";
import { RoomViewStore } from "./stores/RoomViewStore";
import { addReplyToMessageContent } from "./utils/Reply";
import ErrorDialog from "./components/views/dialogs/ErrorDialog";
import UploadFailureDialog from "./components/views/dialogs/UploadFailureDialog";
@ -468,7 +468,7 @@ export default class ContentMessages {
return;
}
const replyToEvent = RoomViewStore.getQuotingEvent();
const replyToEvent = RoomViewStore.instance.getQuotingEvent();
if (!this.mediaConfig) { // hot-path optimization to not flash a spinner if we don't need to
const modal = Modal.createDialog(Spinner, null, 'mx_Dialog_spinner');
await this.ensureMediaConfigFetched(matrixClient);

View file

@ -37,7 +37,7 @@ import SettingsStore from "./settings/SettingsStore";
import { hideToast as hideNotificationsToast } from "./toasts/DesktopNotificationsToast";
import { SettingLevel } from "./settings/SettingLevel";
import { isPushNotifyDisabled } from "./settings/controllers/NotificationControllers";
import RoomViewStore from "./stores/RoomViewStore";
import { RoomViewStore } from "./stores/RoomViewStore";
import UserActivity from "./UserActivity";
import { mediaFromMxc } from "./customisations/Media";
import ErrorDialog from "./components/views/dialogs/ErrorDialog";
@ -401,7 +401,7 @@ export const Notifier = {
const actions = MatrixClientPeg.get().getPushActionsForEvent(ev);
if (actions?.notify) {
if (RoomViewStore.getRoomId() === room.roomId &&
if (RoomViewStore.instance.getRoomId() === room.roomId &&
UserActivity.sharedInstance().userActiveRecently() &&
!Modal.hasDialogs()
) {

View file

@ -241,7 +241,7 @@ import { logger } from "matrix-js-sdk/src/logger";
import { MatrixClientPeg } from './MatrixClientPeg';
import dis from './dispatcher/dispatcher';
import WidgetUtils from './utils/WidgetUtils';
import RoomViewStore from './stores/RoomViewStore';
import { RoomViewStore } from './stores/RoomViewStore';
import { _t } from './languageHandler';
import { IntegrationManagers } from "./integrations/IntegrationManagers";
import { WidgetType } from "./widgets/WidgetType";
@ -638,7 +638,7 @@ const onMessage = function(event: MessageEvent<any>): void {
}
}
if (roomId !== RoomViewStore.getRoomId()) {
if (roomId !== RoomViewStore.instance.getRoomId()) {
sendError(event, _t('Room %(roomId)s not visible', { roomId: roomId }));
return;
}

View file

@ -61,7 +61,7 @@ import InfoDialog from "./components/views/dialogs/InfoDialog";
import SlashCommandHelpDialog from "./components/views/dialogs/SlashCommandHelpDialog";
import { shouldShowComponent } from "./customisations/helpers/UIComponents";
import { TimelineRenderingType } from './contexts/RoomContext';
import RoomViewStore from "./stores/RoomViewStore";
import { RoomViewStore } from "./stores/RoomViewStore";
import { XOR } from "./@types/common";
import { PosthogAnalytics } from "./PosthogAnalytics";
import { ViewRoomPayload } from "./dispatcher/payloads/ViewRoomPayload";
@ -851,7 +851,7 @@ export const Commands = [
description: _td('Define the power level of a user'),
isEnabled(): boolean {
const cli = MatrixClientPeg.get();
const room = cli.getRoom(RoomViewStore.getRoomId());
const room = cli.getRoom(RoomViewStore.instance.getRoomId());
return room?.currentState.maySendStateEvent(EventType.RoomPowerLevels, cli.getUserId());
},
runFn: function(roomId, args) {
@ -891,7 +891,7 @@ export const Commands = [
description: _td('Deops user with given id'),
isEnabled(): boolean {
const cli = MatrixClientPeg.get();
const room = cli.getRoom(RoomViewStore.getRoomId());
const room = cli.getRoom(RoomViewStore.instance.getRoomId());
return room?.currentState.maySendStateEvent(EventType.RoomPowerLevels, cli.getUserId());
},
runFn: function(roomId, args) {

View file

@ -25,7 +25,7 @@ import { MatrixClientPeg } from "../MatrixClientPeg";
import { arrayFastClone } from "../utils/arrays";
import { PlaybackManager } from "./PlaybackManager";
import { isVoiceMessage } from "../utils/EventUtils";
import RoomViewStore from "../stores/RoomViewStore";
import { RoomViewStore } from "../stores/RoomViewStore";
/**
* Audio playback queue management for a given room. This keeps track of where the user
@ -51,8 +51,8 @@ export class PlaybackQueue {
constructor(private room: Room) {
this.loadClocks();
RoomViewStore.addListener(() => {
if (RoomViewStore.getRoomId() === this.room.roomId) {
RoomViewStore.instance.addListener(() => {
if (RoomViewStore.instance.getRoomId() === this.room.roomId) {
// Reset the state of the playbacks before they start mounting and enqueuing updates.
// We reset the entirety of the queue, including order, to ensure the user isn't left
// confused with what order the messages are playing in.

View file

@ -48,7 +48,7 @@ import * as Rooms from '../../Rooms';
import eventSearch, { searchPagination } from '../../Searching';
import MainSplit from './MainSplit';
import RightPanel from './RightPanel';
import RoomViewStore from '../../stores/RoomViewStore';
import { RoomViewStore } from '../../stores/RoomViewStore';
import RoomScrollStateStore, { ScrollState } from '../../stores/RoomScrollStateStore';
import WidgetEchoStore from '../../stores/WidgetEchoStore';
import SettingsStore from "../../settings/SettingsStore";
@ -296,7 +296,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
context.on(CryptoEvent.KeysChanged, this.onCrossSigningKeysChanged);
context.on(MatrixEventEvent.Decrypted, this.onEventDecrypted);
// Start listening for RoomViewStore updates
this.roomStoreToken = RoomViewStore.addListener(this.onRoomViewStoreUpdate);
this.roomStoreToken = RoomViewStore.instance.addListener(this.onRoomViewStoreUpdate);
RightPanelStore.instance.on(UPDATE_EVENT, this.onRightPanelStoreUpdate);
@ -387,7 +387,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
return;
}
if (!initial && this.state.roomId !== RoomViewStore.getRoomId()) {
if (!initial && this.state.roomId !== RoomViewStore.instance.getRoomId()) {
// RoomView explicitly does not support changing what room
// is being viewed: instead it should just be re-mounted when
// switching rooms. Therefore, if the room ID changes, we
@ -402,28 +402,28 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
return;
}
const roomId = RoomViewStore.getRoomId();
const roomId = RoomViewStore.instance.getRoomId();
const newState: Pick<IRoomState, any> = {
roomId,
roomAlias: RoomViewStore.getRoomAlias(),
roomLoading: RoomViewStore.isRoomLoading(),
roomLoadError: RoomViewStore.getRoomLoadError(),
joining: RoomViewStore.isJoining(),
replyToEvent: RoomViewStore.getQuotingEvent(),
roomAlias: RoomViewStore.instance.getRoomAlias(),
roomLoading: RoomViewStore.instance.isRoomLoading(),
roomLoadError: RoomViewStore.instance.getRoomLoadError(),
joining: RoomViewStore.instance.isJoining(),
replyToEvent: RoomViewStore.instance.getQuotingEvent(),
// we should only peek once we have a ready client
shouldPeek: this.state.matrixClientIsReady && RoomViewStore.shouldPeek(),
shouldPeek: this.state.matrixClientIsReady && RoomViewStore.instance.shouldPeek(),
showReadReceipts: SettingsStore.getValue("showReadReceipts", roomId),
showRedactions: SettingsStore.getValue("showRedactions", roomId),
showJoinLeaves: SettingsStore.getValue("showJoinLeaves", roomId),
showAvatarChanges: SettingsStore.getValue("showAvatarChanges", roomId),
showDisplaynameChanges: SettingsStore.getValue("showDisplaynameChanges", roomId),
wasContextSwitch: RoomViewStore.getWasContextSwitch(),
wasContextSwitch: RoomViewStore.instance.getWasContextSwitch(),
initialEventId: null, // default to clearing this, will get set later in the method if needed
showRightPanel: RightPanelStore.instance.isOpenForRoom(roomId),
};
const initialEventId = RoomViewStore.getInitialEventId();
const initialEventId = RoomViewStore.instance.getInitialEventId();
if (initialEventId) {
const room = this.context.getRoom(roomId);
let initialEvent = room?.findEventById(initialEventId);
@ -448,17 +448,17 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
showThread({
rootEvent: thread.rootEvent,
initialEvent,
highlighted: RoomViewStore.isInitialEventHighlighted(),
highlighted: RoomViewStore.instance.isInitialEventHighlighted(),
});
} else {
newState.initialEventId = initialEventId;
newState.isInitialEventHighlighted = RoomViewStore.isInitialEventHighlighted();
newState.isInitialEventHighlighted = RoomViewStore.instance.isInitialEventHighlighted();
if (thread && initialEvent?.isThreadRoot) {
showThread({
rootEvent: thread.rootEvent,
initialEvent,
highlighted: RoomViewStore.isInitialEventHighlighted(),
highlighted: RoomViewStore.instance.isInitialEventHighlighted(),
});
}
}

View file

@ -60,7 +60,7 @@ import MatrixClientContext from "../../contexts/MatrixClientContext";
import { useTypedEventEmitterState } from "../../hooks/useEventEmitter";
import { IOOBData } from "../../stores/ThreepidInviteStore";
import { awaitRoomDownSync } from "../../utils/RoomUpgrade";
import RoomViewStore from "../../stores/RoomViewStore";
import { RoomViewStore } from "../../stores/RoomViewStore";
import { ViewRoomPayload } from "../../dispatcher/payloads/ViewRoomPayload";
import { JoinRoomReadyPayload } from "../../dispatcher/payloads/JoinRoomReadyPayload";
import { KeyBindingAction } from "../../accessibility/KeyboardShortcuts";
@ -371,7 +371,7 @@ export const joinRoom = (cli: MatrixClient, hierarchy: RoomHierarchy, roomId: st
metricsTrigger: "SpaceHierarchy",
});
}, err => {
RoomViewStore.showJoinRoomError(err, roomId);
RoomViewStore.instance.showJoinRoomError(err, roomId);
});
return prom;

View file

@ -37,7 +37,7 @@ import Modal from "../../../Modal";
import ExportDialog from "../dialogs/ExportDialog";
import { useSettingValue } from "../../../hooks/useSettings";
import { usePinnedEvents } from "../right_panel/PinnedMessagesCard";
import RoomViewStore from "../../../stores/RoomViewStore";
import { RoomViewStore } from "../../../stores/RoomViewStore";
import { RightPanelPhases } from '../../../stores/right-panel/RightPanelStorePhases';
import { ROOM_NOTIFICATIONS_TAB } from "../dialogs/RoomSettingsDialog";
import { useEventEmitterState } from "../../../hooks/useEventEmitter";
@ -280,7 +280,7 @@ const RoomContextMenu = ({ room, onFinished, ...props }: IProps) => {
};
const ensureViewingRoom = (ev: ButtonEvent) => {
if (RoomViewStore.getRoomId() === room.roomId) return;
if (RoomViewStore.instance.getRoomId() === room.roomId) return;
dis.dispatch<ViewRoomPayload>({
action: Action.ViewRoom,
room_id: room.roomId,
@ -361,7 +361,7 @@ const RoomContextMenu = ({ room, onFinished, ...props }: IProps) => {
ev.stopPropagation();
Modal.createDialog(DevtoolsDialog, {
roomId: RoomViewStore.getRoomId(),
roomId: RoomViewStore.instance.getRoomId(),
}, "mx_DevtoolsDialog_wrapper");
onFinished();
}}

View file

@ -58,7 +58,7 @@ import DecoratedRoomAvatar from "../avatars/DecoratedRoomAvatar";
import { Action } from "../../../dispatcher/actions";
import Modal from "../../../Modal";
import AccessibleTooltipButton from "../elements/AccessibleTooltipButton";
import RoomViewStore from "../../../stores/RoomViewStore";
import { RoomViewStore } from "../../../stores/RoomViewStore";
import { showStartChatInviteDialog } from "../../../RoomInvite";
import SettingsStore from "../../../settings/SettingsStore";
import { SettingLevel } from "../../../settings/SettingLevel";
@ -559,7 +559,7 @@ const SpotlightDialog: React.FC<IProps> = ({ initialText = "", onFinished }) =>
<h4>{ _t("Recently viewed") }</h4>
<div>
{ BreadcrumbsStore.instance.rooms
.filter(r => r.roomId !== RoomViewStore.getRoomId())
.filter(r => r.roomId !== RoomViewStore.instance.getRoomId())
.map(room => (
<TooltipOption
id={`mx_SpotlightDialog_button_recentlyViewed_${room.roomId}`}

View file

@ -44,7 +44,7 @@ import { IApp } from "../../../stores/WidgetStore";
import { Container, WidgetLayoutStore } from "../../../stores/widgets/WidgetLayoutStore";
import { OwnProfileStore } from '../../../stores/OwnProfileStore';
import { UPDATE_EVENT } from '../../../stores/AsyncStore';
import RoomViewStore from '../../../stores/RoomViewStore';
import { RoomViewStore } from '../../../stores/RoomViewStore';
import WidgetUtils from '../../../utils/WidgetUtils';
import MatrixClientContext from "../../../contexts/MatrixClientContext";
import { ActionPayload } from "../../../dispatcher/payloads";
@ -195,7 +195,7 @@ export default class AppTile extends React.Component<IProps, IState> {
);
if (isActiveWidget) {
// We just left the room that the active widget was from.
if (this.props.room && RoomViewStore.getRoomId() !== this.props.room.roomId) {
if (this.props.room && RoomViewStore.instance.getRoomId() !== this.props.room.roomId) {
// If we are not actively looking at the room then destroy this widget entirely.
this.endWidgetActions();
} else if (WidgetType.JITSI.matches(this.props.app.type)) {

View file

@ -35,7 +35,7 @@ import dis from '../../../dispatcher/dispatcher';
import { _t } from '../../../languageHandler';
import { ActionPayload } from '../../../dispatcher/payloads';
import { Action } from '../../../dispatcher/actions';
import RoomViewStore from '../../../stores/RoomViewStore';
import { RoomViewStore } from '../../../stores/RoomViewStore';
import ContentMessages from '../../../ContentMessages';
import UploadBar from '../../structures/UploadBar';
import SettingsStore from '../../../settings/SettingsStore';
@ -92,7 +92,7 @@ export default class TimelineCard extends React.Component<IProps, IState> {
}
public componentDidMount(): void {
this.roomStoreToken = RoomViewStore.addListener(this.onRoomViewStoreUpdate);
this.roomStoreToken = RoomViewStore.instance.addListener(this.onRoomViewStoreUpdate);
this.dispatcherRef = dis.register(this.onAction);
this.readReceiptsSettingWatcher = SettingsStore.watchSetting("showReadReceipts", null, (...[,,, value]) =>
this.setState({ showReadReceipts: value as boolean }),
@ -119,12 +119,12 @@ export default class TimelineCard extends React.Component<IProps, IState> {
private onRoomViewStoreUpdate = async (initial?: boolean): Promise<void> => {
const newState: Pick<IState, any> = {
// roomLoading: RoomViewStore.isRoomLoading(),
// roomLoadError: RoomViewStore.getRoomLoadError(),
// roomLoading: RoomViewStore.instance.isRoomLoading(),
// roomLoadError: RoomViewStore.instance.getRoomLoadError(),
initialEventId: RoomViewStore.getInitialEventId(),
isInitialEventHighlighted: RoomViewStore.isInitialEventHighlighted(),
replyToEvent: RoomViewStore.getQuotingEvent(),
initialEventId: RoomViewStore.instance.getInitialEventId(),
isInitialEventHighlighted: RoomViewStore.instance.isInitialEventHighlighted(),
replyToEvent: RoomViewStore.instance.getQuotingEvent(),
};
this.setState(newState);

View file

@ -37,7 +37,7 @@ import createRoom, { findDMForUser, privateShouldBeEncrypted } from '../../../cr
import DMRoomMap from '../../../utils/DMRoomMap';
import AccessibleButton, { ButtonEvent } from '../elements/AccessibleButton';
import SdkConfig from '../../../SdkConfig';
import RoomViewStore from "../../../stores/RoomViewStore";
import { RoomViewStore } from "../../../stores/RoomViewStore";
import MultiInviter from "../../../utils/MultiInviter";
import { MatrixClientPeg } from "../../../MatrixClientPeg";
import E2EIcon from "../rooms/E2EIcon";
@ -425,7 +425,7 @@ const UserOptionsSection: React.FC<{
}
if (canInvite && (member?.membership ?? 'leave') === 'leave' && shouldShowComponent(UIComponent.InviteUsers)) {
const roomId = member && member.roomId ? member.roomId : RoomViewStore.getRoomId();
const roomId = member && member.roomId ? member.roomId : RoomViewStore.instance.getRoomId();
const onInviteUserButton = async (ev: ButtonEvent) => {
try {
// We use a MultiInviter to re-use the invite logic, even though

View file

@ -23,7 +23,7 @@ import { _t, _td } from "../../../languageHandler";
import { IState as IRovingTabIndexState, RovingTabIndexProvider } from "../../../accessibility/RovingTabIndex";
import ResizeNotifier from "../../../utils/ResizeNotifier";
import RoomListStore, { LISTS_UPDATE_EVENT } from "../../../stores/room-list/RoomListStore";
import RoomViewStore from "../../../stores/RoomViewStore";
import { RoomViewStore } from "../../../stores/RoomViewStore";
import { ITagMap } from "../../../stores/room-list/algorithms/models";
import { DefaultTagID, TagID } from "../../../stores/room-list/models";
import defaultDispatcher from "../../../dispatcher/dispatcher";
@ -368,7 +368,7 @@ export default class RoomList extends React.PureComponent<IProps, IState> {
public componentDidMount(): void {
this.dispatcherRef = defaultDispatcher.register(this.onAction);
this.roomStoreToken = RoomViewStore.addListener(this.onRoomViewStoreUpdate);
this.roomStoreToken = RoomViewStore.instance.addListener(this.onRoomViewStoreUpdate);
SpaceStore.instance.on(UPDATE_SUGGESTED_ROOMS, this.updateSuggestedRooms);
RoomListStore.instance.on(LISTS_UPDATE_EVENT, this.updateLists);
this.updateLists(); // trigger the first update
@ -383,14 +383,14 @@ export default class RoomList extends React.PureComponent<IProps, IState> {
private onRoomViewStoreUpdate = () => {
this.setState({
currentRoomId: RoomViewStore.getRoomId(),
currentRoomId: RoomViewStore.instance.getRoomId(),
});
};
private onAction = (payload: ActionPayload) => {
if (payload.action === Action.ViewRoomDelta) {
const viewRoomDeltaPayload = payload as ViewRoomDeltaPayload;
const currentRoomId = RoomViewStore.getRoomId();
const currentRoomId = RoomViewStore.instance.getRoomId();
const room = this.getRoomDelta(currentRoomId, viewRoomDeltaPayload.delta, viewRoomDeltaPayload.unread);
if (room) {
defaultDispatcher.dispatch<ViewRoomPayload>({

View file

@ -36,7 +36,7 @@ import { Icon as FavoriteIcon } from '../../../../res/img/element-icons/roomlist
import SettingsStore from "../../../settings/SettingsStore";
import Modal from "../../../Modal";
import DevtoolsDialog from "../dialogs/DevtoolsDialog";
import RoomViewStore from "../../../stores/RoomViewStore";
import { RoomViewStore } from "../../../stores/RoomViewStore";
const QuickSettingsButton = ({ isPanelCollapsed = false }) => {
const [menuDisplayed, handle, openMenu, closeMenu] = useContextMenu<HTMLDivElement>();
@ -72,7 +72,7 @@ const QuickSettingsButton = ({ isPanelCollapsed = false }) => {
onClick={() => {
closeMenu();
Modal.createDialog(DevtoolsDialog, {
roomId: RoomViewStore.getRoomId(),
roomId: RoomViewStore.instance.getRoomId(),
}, "mx_DevtoolsDialog_wrapper");
}}
kind="danger_outline"

View file

@ -21,7 +21,7 @@ import { logger } from "matrix-js-sdk/src/logger";
import classNames from 'classnames';
import CallView from "./CallView";
import RoomViewStore from '../../../stores/RoomViewStore';
import { RoomViewStore } from '../../../stores/RoomViewStore';
import CallHandler, { CallHandlerEvent } from '../../../CallHandler';
import PersistentApp from "../elements/PersistentApp";
import SettingsStore from "../../../settings/SettingsStore";
@ -111,7 +111,7 @@ export default class PipView extends React.Component<IProps, IState> {
constructor(props: IProps) {
super(props);
const roomId = RoomViewStore.getRoomId();
const roomId = RoomViewStore.instance.getRoomId();
const [primaryCall, secondaryCalls] = getPrimarySecondaryCallsForPip(roomId);
@ -129,7 +129,7 @@ export default class PipView extends React.Component<IProps, IState> {
public componentDidMount() {
CallHandler.instance.addListener(CallHandlerEvent.CallChangeRoom, this.updateCalls);
CallHandler.instance.addListener(CallHandlerEvent.CallState, this.updateCalls);
this.roomStoreToken = RoomViewStore.addListener(this.onRoomViewStoreUpdate);
this.roomStoreToken = RoomViewStore.instance.addListener(this.onRoomViewStoreUpdate);
MatrixClientPeg.get().on(CallEvent.RemoteHoldUnhold, this.onCallRemoteHold);
const room = MatrixClientPeg.get()?.getRoom(this.state.viewedRoomId);
if (room) {
@ -162,7 +162,7 @@ export default class PipView extends React.Component<IProps, IState> {
}
private onRoomViewStoreUpdate = () => {
const newRoomId = RoomViewStore.getRoomId();
const newRoomId = RoomViewStore.instance.getRoomId();
const oldRoomId = this.state.viewedRoomId;
if (newRoomId === oldRoomId) return;
// The WidgetLayoutStore observer always tracks the currently viewed Room,

View file

@ -1,7 +1,7 @@
/*
Copyright 2017 Vector Creations Ltd
Copyright 2017, 2018 New Vector Ltd
Copyright 2019 The Matrix.org Foundation C.I.C.
Copyright 2019 - 2022 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -84,14 +84,16 @@ const INITIAL_STATE = {
* with a subset of the js-sdk.
* ```
*/
class RoomViewStore extends Store<ActionPayload> {
export class RoomViewStore extends Store<ActionPayload> {
public static readonly instance = new RoomViewStore();
private state = INITIAL_STATE; // initialize state
constructor() {
public constructor() {
super(dis);
}
setState(newState: Partial<typeof INITIAL_STATE>) {
private setState(newState: Partial<typeof INITIAL_STATE>) {
// If values haven't changed, there's nothing to do.
// This only tries a shallow comparison, so unchanged objects will slip
// through, but that's probably okay for now.
@ -110,7 +112,7 @@ class RoomViewStore extends Store<ActionPayload> {
this.__emitChange();
}
__onDispatch(payload) { // eslint-disable-line @typescript-eslint/naming-convention
protected __onDispatch(payload) { // eslint-disable-line @typescript-eslint/naming-convention
switch (payload.action) {
// view_room:
// - room_alias: '#somealias:matrix.org'
@ -367,7 +369,7 @@ class RoomViewStore extends Store<ActionPayload> {
}
}
private static getInvitingUserId(roomId: string): string {
private getInvitingUserId(roomId: string): string {
const cli = MatrixClientPeg.get();
const room = cli.getRoom(roomId);
if (room && room.getMyMembership() === "invite") {
@ -389,7 +391,7 @@ class RoomViewStore extends Store<ActionPayload> {
{ _t("Please contact your homeserver administrator.") }
</div>;
} else if (err.httpStatus === 404) {
const invitingUserId = RoomViewStore.getInvitingUserId(roomId);
const invitingUserId = this.getInvitingUserId(roomId);
// only provide a better error message for invites
if (invitingUserId) {
// if the inviting user is on the same HS, there can only be one cause: they left.
@ -466,7 +468,7 @@ class RoomViewStore extends Store<ActionPayload> {
// // Not joined
// }
// } else {
// if (RoomViewStore.isJoining()) {
// if (RoomViewStore.instance.isJoining()) {
// // show spinner
// } else {
// // show join prompt
@ -494,9 +496,3 @@ class RoomViewStore extends Store<ActionPayload> {
return this.state.wasContextSwitch;
}
}
let singletonRoomViewStore: RoomViewStore = null;
if (!singletonRoomViewStore) {
singletonRoomViewStore = new RoomViewStore();
}
export default singletonRoomViewStore;

View file

@ -31,7 +31,7 @@ import {
IRightPanelCard,
IRightPanelForRoom,
} from './RightPanelStoreIPanelState';
import RoomViewStore from '../RoomViewStore';
import { RoomViewStore } from '../RoomViewStore';
/**
* A class for tracking the state of the right panel between layouts and
@ -55,9 +55,9 @@ export default class RightPanelStore extends ReadyWatchingStore {
}
protected async onReady(): Promise<any> {
this.roomStoreToken = RoomViewStore.addListener(this.onRoomViewStoreUpdate);
this.roomStoreToken = RoomViewStore.instance.addListener(this.onRoomViewStoreUpdate);
this.matrixClient.on(CryptoEvent.VerificationRequest, this.onVerificationRequestUpdate);
this.viewedRoomId = RoomViewStore.getRoomId();
this.viewedRoomId = RoomViewStore.instance.getRoomId();
this.loadCacheFromSettings();
this.emitAndUpdateSettings();
}
@ -338,7 +338,7 @@ export default class RightPanelStore extends ReadyWatchingStore {
private onRoomViewStoreUpdate = () => {
const oldRoomId = this.viewedRoomId;
this.viewedRoomId = RoomViewStore.getRoomId();
this.viewedRoomId = RoomViewStore.instance.getRoomId();
// load values from byRoomCache with the viewedRoomId.
this.loadCacheFromSettings();

View file

@ -27,7 +27,7 @@ import { ActionPayload } from "../../dispatcher/payloads";
import defaultDispatcher from "../../dispatcher/dispatcher";
import { readReceiptChangeIsFor } from "../../utils/read-receipts";
import { FILTER_CHANGED, FilterKind, IFilterCondition } from "./filters/IFilterCondition";
import RoomViewStore from "../RoomViewStore";
import { RoomViewStore } from "../RoomViewStore";
import { Algorithm, LIST_UPDATED_EVENT } from "./algorithms/Algorithm";
import { EffectiveMembership, getEffectiveMembership } from "../../utils/membership";
import RoomListLayoutStore from "./RoomListLayoutStore";
@ -111,7 +111,7 @@ export class RoomListStoreClass extends AsyncStoreWithClient<IState> {
this.readyStore.useUnitTestClient(forcedClient);
}
RoomViewStore.addListener(() => this.handleRVSUpdate({}));
RoomViewStore.instance.addListener(() => this.handleRVSUpdate({}));
this.algorithm.on(LIST_UPDATED_EVENT, this.onAlgorithmListUpdated);
this.algorithm.on(FILTER_CHANGED, this.onAlgorithmFilterUpdated);
this.setupWatchers();
@ -134,7 +134,7 @@ export class RoomListStoreClass extends AsyncStoreWithClient<IState> {
private handleRVSUpdate({ trigger = true }) {
if (!this.matrixClient) return; // We assume there won't be RVS updates without a client
const activeRoomId = RoomViewStore.getRoomId();
const activeRoomId = RoomViewStore.instance.getRoomId();
if (!activeRoomId && this.algorithm.stickyRoom) {
this.algorithm.setStickyRoom(null);
} else if (activeRoomId) {

View file

@ -34,7 +34,7 @@ import { RoomNotificationStateStore } from "../notifications/RoomNotificationSta
import { DefaultTagID } from "../room-list/models";
import { EnhancedMap, mapDiff } from "../../utils/maps";
import { setDiff, setHasDiff } from "../../utils/sets";
import RoomViewStore from "../RoomViewStore";
import { RoomViewStore } from "../RoomViewStore";
import { Action } from "../../dispatcher/actions";
import { arrayHasDiff, arrayHasOrderChange } from "../../utils/arrays";
import { reorderLexicographically } from "../../utils/stringOrderField";
@ -804,7 +804,7 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
};
private switchSpaceIfNeeded = () => {
const roomId = RoomViewStore.getRoomId();
const roomId = RoomViewStore.instance.getRoomId();
if (!this.isRoomInSpace(this.activeSpace, roomId) && !this.matrixClient.getRoom(roomId)?.isSpaceRoom()) {
this.switchToRelatedSpace(roomId);
}
@ -855,7 +855,7 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
}
// if the room currently being viewed was just joined then switch to its related space
if (newMembership === "join" && room.roomId === RoomViewStore.getRoomId()) {
if (newMembership === "join" && room.roomId === RoomViewStore.instance.getRoomId()) {
this.switchToRelatedSpace(room.roomId);
}
}
@ -882,7 +882,7 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
this.emit(room.roomId);
}
if (membership === "join" && room.roomId === RoomViewStore.getRoomId()) {
if (membership === "join" && room.roomId === RoomViewStore.instance.getRoomId()) {
// if the user was looking at the space and then joined: select that space
this.setActiveSpace(room.roomId, false);
} else if (membership === "leave" && room.roomId === this.activeSpace) {

View file

@ -39,7 +39,7 @@ import { ClientEvent } from "matrix-js-sdk/src/client";
import { StopGapWidgetDriver } from "./StopGapWidgetDriver";
import { WidgetMessagingStore } from "./WidgetMessagingStore";
import RoomViewStore from "../RoomViewStore";
import { RoomViewStore } from "../RoomViewStore";
import { MatrixClientPeg } from "../../MatrixClientPeg";
import { OwnProfileStore } from "../OwnProfileStore";
import WidgetUtils from '../../utils/WidgetUtils';
@ -175,7 +175,7 @@ export class StopGapWidget extends EventEmitter {
if (this.roomId) return this.roomId;
return RoomViewStore.getRoomId();
return RoomViewStore.instance.getRoomId();
}
public get widgetApi(): ClientWidgetApi {
@ -361,13 +361,13 @@ export class StopGapWidget extends EventEmitter {
// TODO: Open the right integration manager for the widget
if (SettingsStore.getValue("feature_many_integration_managers")) {
IntegrationManagers.sharedInstance().openAll(
MatrixClientPeg.get().getRoom(RoomViewStore.getRoomId()),
MatrixClientPeg.get().getRoom(RoomViewStore.instance.getRoomId()),
`type_${integType}`,
integId,
);
} else {
IntegrationManagers.sharedInstance().getPrimaryManager().open(
MatrixClientPeg.get().getRoom(RoomViewStore.getRoomId()),
MatrixClientPeg.get().getRoom(RoomViewStore.instance.getRoomId()),
`type_${integType}`,
integId,
);

View file

@ -24,7 +24,7 @@ import { _t } from "../languageHandler";
import Modal, { IHandle } from "../Modal";
import ErrorDialog from "../components/views/dialogs/ErrorDialog";
import dis from "../dispatcher/dispatcher";
import RoomViewStore from "../stores/RoomViewStore";
import { RoomViewStore } from "../stores/RoomViewStore";
import Spinner from "../components/views/elements/Spinner";
import { isMetaSpace } from "../stores/spaces";
import SpaceStore from "../stores/spaces/SpaceStore";
@ -186,7 +186,7 @@ export async function leaveRoomBehaviour(roomId: string, retry = true, spinner =
if (!isMetaSpace(SpaceStore.instance.activeSpace) &&
SpaceStore.instance.activeSpace !== roomId &&
RoomViewStore.getRoomId() === roomId
RoomViewStore.instance.getRoomId() === roomId
) {
dis.dispatch<ViewRoomPayload>({
action: Action.ViewRoom,

View file

@ -33,7 +33,7 @@ import CreateSubspaceDialog from "../components/views/dialogs/CreateSubspaceDial
import AddExistingSubspaceDialog from "../components/views/dialogs/AddExistingSubspaceDialog";
import defaultDispatcher from "../dispatcher/dispatcher";
import dis from "../dispatcher/dispatcher";
import RoomViewStore from "../stores/RoomViewStore";
import { RoomViewStore } from "../stores/RoomViewStore";
import { Action } from "../dispatcher/actions";
import { leaveRoomBehaviour } from "./membership";
import Spinner from "../components/views/elements/Spinner";
@ -83,7 +83,7 @@ export const showAddExistingRooms = (space: Room): void => {
onAddSubspaceClick: () => showAddExistingSubspace(space),
space,
onFinished: (added: boolean) => {
if (added && RoomViewStore.getRoomId() === space.roomId) {
if (added && RoomViewStore.instance.getRoomId() === space.roomId) {
defaultDispatcher.fire(Action.UpdateSpaceHierarchy);
}
},
@ -142,7 +142,7 @@ export const showAddExistingSubspace = (space: Room): void => {
space,
onCreateSubspaceClick: () => showCreateNewSubspace(space),
onFinished: (added: boolean) => {
if (added && RoomViewStore.getRoomId() === space.roomId) {
if (added && RoomViewStore.instance.getRoomId() === space.roomId) {
defaultDispatcher.fire(Action.UpdateSpaceHierarchy);
}
},
@ -160,7 +160,7 @@ export const showCreateNewSubspace = (space: Room): void => {
space,
onAddExistingSpaceClick: () => showAddExistingSubspace(space),
onFinished: (added: boolean) => {
if (added && RoomViewStore.getRoomId() === space.roomId) {
if (added && RoomViewStore.instance.getRoomId() === space.roomId) {
defaultDispatcher.fire(Action.UpdateSpaceHierarchy);
}
},

View file

@ -14,12 +14,12 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import RoomViewStore from '../../src/stores/RoomViewStore';
import { RoomViewStore } from '../../src/stores/RoomViewStore';
import { Action } from '../../src/dispatcher/actions';
import { MatrixClientPeg as peg } from '../../src/MatrixClientPeg';
import * as testUtils from '../test-utils';
const dispatch = testUtils.getDispatchForStore(RoomViewStore);
const dispatch = testUtils.getDispatchForStore(RoomViewStore.instance);
jest.mock('../../src/utils/DMRoomMap', () => {
const mock = {
@ -41,7 +41,7 @@ describe('RoomViewStore', function() {
peg.get().off = jest.fn();
// Reset the state of the store
RoomViewStore.reset();
RoomViewStore.instance.reset();
});
it('can be used to view a room by ID and join', function(done) {
@ -52,16 +52,16 @@ describe('RoomViewStore', function() {
dispatch({ action: Action.ViewRoom, room_id: '!randomcharacters:aser.ver' });
dispatch({ action: 'join_room' });
expect(RoomViewStore.isJoining()).toBe(true);
expect(RoomViewStore.instance.isJoining()).toBe(true);
});
it('can be used to view a room by alias and join', function(done) {
const token = RoomViewStore.addListener(() => {
const token = RoomViewStore.instance.addListener(() => {
// Wait until the room alias has resolved and the room ID is
if (!RoomViewStore.isRoomLoading()) {
expect(RoomViewStore.getRoomId()).toBe("!randomcharacters:aser.ver");
if (!RoomViewStore.instance.isRoomLoading()) {
expect(RoomViewStore.instance.getRoomId()).toBe("!randomcharacters:aser.ver");
dispatch({ action: 'join_room' });
expect(RoomViewStore.isJoining()).toBe(true);
expect(RoomViewStore.instance.isJoining()).toBe(true);
}
});