Skip to content
This repository was archived by the owner on Sep 11, 2024. It is now read-only.

Commit e946674

Browse files
kegsayt3chguy
andauthored
Store refactor: use non-global stores in components (#9293)
* Add Stores and StoresContext and use it in MatrixChat and RoomView Added a new kind of class: - Add God object `Stores` which will hold refs to all known stores and the `MatrixClient`. This object is NOT a singleton. - Add `StoresContext` to hold onto a ref of `Stores` for use inside components. `StoresContext` is created via: - Create `Stores` in `MatrixChat`, assigning the `MatrixClient` when we have one set. Currently sets the RVS to `RoomViewStore.instance`. - Wrap `MatrixChat`s `render()` function in a `StoresContext.Provider` so it can be used anywhere. `StoresContext` is currently only used in `RoomView` via the following changes: - Remove the HOC, which redundantly set `mxClient` as a prop. We don't need this as `RoomView` was using the client from `this.context`. - Change the type of context accepted from `MatrixClientContext` to `StoresContext`. - Modify alllll the places where `this.context` is used to interact with the client and suffix `.client`. - Modify places where we use `RoomViewStore.instance` and replace them with `this.context.roomViewStore`. This makes `RoomView` use a non-global instance of RVS. * Linting * SDKContext and make client an optional constructor arg * Move SDKContext to /src/contexts * Inject all RVS deps * Linting * Remove reset calls; deep copy the INITIAL_STATE to avoid test pollution * DI singletons used in RoomView; DI them in RoomView-test too * Initial RoomViewStore.instance after all files are imported to avoid cyclical deps * Lazily init stores to allow for circular dependencies Rather than stores accepting a list of other stores in their constructors, which doesn't work when A needs B and B needs A, make new-style stores simply accept Stores. When a store needs another store, they access it via `Stores` which then lazily constructs that store if it needs it. This breaks the circular dependency at constructor time, without needing to introduce wiring diagrams or any complex DI framework. * Delete RoomViewStore.instance Replaced with Stores.instance.roomViewStore * Linting * Move OverridableStores to test/TestStores * Rejig how eager stores get made; don't automatically do it else tests break * Linting * Linting and review comments * Fix new code to use Stores.instance * s/Stores/SdkContextClass/g * Update docs * Remove unused imports * Update src/stores/RoomViewStore.tsx Co-authored-by: Michael Telatynski <[email protected]> * Remove empty c'tor to make sonar happy Co-authored-by: Michael Telatynski <[email protected]>
1 parent 84f2974 commit e946674

36 files changed

+467
-275
lines changed

src/ContentMessages.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,14 +43,14 @@ import { RoomUpload } from "./models/RoomUpload";
4343
import SettingsStore from "./settings/SettingsStore";
4444
import { decorateStartSendingTime, sendRoundTripMetric } from "./sendTimePerformanceMetrics";
4545
import { TimelineRenderingType } from "./contexts/RoomContext";
46-
import { RoomViewStore } from "./stores/RoomViewStore";
4746
import { addReplyToMessageContent } from "./utils/Reply";
4847
import ErrorDialog from "./components/views/dialogs/ErrorDialog";
4948
import UploadFailureDialog from "./components/views/dialogs/UploadFailureDialog";
5049
import UploadConfirmDialog from "./components/views/dialogs/UploadConfirmDialog";
5150
import { createThumbnail } from "./utils/image-media";
5251
import { attachRelation } from "./components/views/rooms/SendMessageComposer";
5352
import { doMaybeLocalRoomAction } from "./utils/local-room";
53+
import { SdkContextClass } from "./contexts/SDKContext";
5454

5555
// scraped out of a macOS hidpi (5660ppm) screenshot png
5656
// 5669 px (x-axis) , 5669 px (y-axis) , per metre
@@ -361,7 +361,7 @@ export default class ContentMessages {
361361
return;
362362
}
363363

364-
const replyToEvent = RoomViewStore.instance.getQuotingEvent();
364+
const replyToEvent = SdkContextClass.instance.roomViewStore.getQuotingEvent();
365365
if (!this.mediaConfig) { // hot-path optimization to not flash a spinner if we don't need to
366366
const modal = Modal.createDialog(Spinner, null, 'mx_Dialog_spinner');
367367
await this.ensureMediaConfigFetched(matrixClient);

src/Notifier.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,12 @@ import SettingsStore from "./settings/SettingsStore";
4141
import { hideToast as hideNotificationsToast } from "./toasts/DesktopNotificationsToast";
4242
import { SettingLevel } from "./settings/SettingLevel";
4343
import { isPushNotifyDisabled } from "./settings/controllers/NotificationControllers";
44-
import { RoomViewStore } from "./stores/RoomViewStore";
4544
import UserActivity from "./UserActivity";
4645
import { mediaFromMxc } from "./customisations/Media";
4746
import ErrorDialog from "./components/views/dialogs/ErrorDialog";
4847
import LegacyCallHandler from "./LegacyCallHandler";
4948
import VoipUserMapper from "./VoipUserMapper";
49+
import { SdkContextClass } from "./contexts/SDKContext";
5050
import { localNotificationsAreSilenced } from "./utils/notifications";
5151
import { getIncomingCallToastKey, IncomingCallToast } from "./toasts/IncomingCallToast";
5252
import ToastStore from "./stores/ToastStore";
@@ -435,7 +435,7 @@ export const Notifier = {
435435
if (actions?.notify) {
436436
this._performCustomEventHandling(ev);
437437

438-
if (RoomViewStore.instance.getRoomId() === room.roomId &&
438+
if (SdkContextClass.instance.roomViewStore.getRoomId() === room.roomId &&
439439
UserActivity.sharedInstance().userActiveRecently() &&
440440
!Modal.hasDialogs()
441441
) {

src/ScalarMessaging.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -272,12 +272,12 @@ import { logger } from "matrix-js-sdk/src/logger";
272272
import { MatrixClientPeg } from './MatrixClientPeg';
273273
import dis from './dispatcher/dispatcher';
274274
import WidgetUtils from './utils/WidgetUtils';
275-
import { RoomViewStore } from './stores/RoomViewStore';
276275
import { _t } from './languageHandler';
277276
import { IntegrationManagers } from "./integrations/IntegrationManagers";
278277
import { WidgetType } from "./widgets/WidgetType";
279278
import { objectClone } from "./utils/objects";
280279
import { EffectiveMembership, getEffectiveMembership } from './utils/membership';
280+
import { SdkContextClass } from './contexts/SDKContext';
281281

282282
enum Action {
283283
CloseScalar = "close_scalar",
@@ -721,7 +721,7 @@ const onMessage = function(event: MessageEvent<any>): void {
721721
}
722722
}
723723

724-
if (roomId !== RoomViewStore.instance.getRoomId()) {
724+
if (roomId !== SdkContextClass.instance.roomViewStore.getRoomId()) {
725725
sendError(event, _t('Room %(roomId)s not visible', { roomId: roomId }));
726726
return;
727727
}

src/SlashCommands.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,14 +62,14 @@ import InfoDialog from "./components/views/dialogs/InfoDialog";
6262
import SlashCommandHelpDialog from "./components/views/dialogs/SlashCommandHelpDialog";
6363
import { shouldShowComponent } from "./customisations/helpers/UIComponents";
6464
import { TimelineRenderingType } from './contexts/RoomContext';
65-
import { RoomViewStore } from "./stores/RoomViewStore";
6665
import { XOR } from "./@types/common";
6766
import { PosthogAnalytics } from "./PosthogAnalytics";
6867
import { ViewRoomPayload } from "./dispatcher/payloads/ViewRoomPayload";
6968
import VoipUserMapper from './VoipUserMapper';
7069
import { htmlSerializeFromMdIfNeeded } from './editor/serialize';
7170
import { leaveRoomBehaviour } from "./utils/leave-behaviour";
7271
import { isLocalRoom } from './utils/localRoom/isLocalRoom';
72+
import { SdkContextClass } from './contexts/SDKContext';
7373

7474
// XXX: workaround for https://github.com/microsoft/TypeScript/issues/31816
7575
interface HTMLInputEvent extends Event {
@@ -209,7 +209,7 @@ function successSync(value: any) {
209209

210210
const isCurrentLocalRoom = (): boolean => {
211211
const cli = MatrixClientPeg.get();
212-
const room = cli.getRoom(RoomViewStore.instance.getRoomId());
212+
const room = cli.getRoom(SdkContextClass.instance.roomViewStore.getRoomId());
213213
return isLocalRoom(room);
214214
};
215215

@@ -868,7 +868,7 @@ export const Commands = [
868868
description: _td('Define the power level of a user'),
869869
isEnabled(): boolean {
870870
const cli = MatrixClientPeg.get();
871-
const room = cli.getRoom(RoomViewStore.instance.getRoomId());
871+
const room = cli.getRoom(SdkContextClass.instance.roomViewStore.getRoomId());
872872
return room?.currentState.maySendStateEvent(EventType.RoomPowerLevels, cli.getUserId())
873873
&& !isLocalRoom(room);
874874
},
@@ -909,7 +909,7 @@ export const Commands = [
909909
description: _td('Deops user with given id'),
910910
isEnabled(): boolean {
911911
const cli = MatrixClientPeg.get();
912-
const room = cli.getRoom(RoomViewStore.instance.getRoomId());
912+
const room = cli.getRoom(SdkContextClass.instance.roomViewStore.getRoomId());
913913
return room?.currentState.maySendStateEvent(EventType.RoomPowerLevels, cli.getUserId())
914914
&& !isLocalRoom(room);
915915
},

src/audio/PlaybackQueue.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ import { MatrixClientPeg } from "../MatrixClientPeg";
2525
import { arrayFastClone } from "../utils/arrays";
2626
import { PlaybackManager } from "./PlaybackManager";
2727
import { isVoiceMessage } from "../utils/EventUtils";
28-
import { RoomViewStore } from "../stores/RoomViewStore";
28+
import { SdkContextClass } from "../contexts/SDKContext";
2929

3030
/**
3131
* Audio playback queue management for a given room. This keeps track of where the user
@@ -51,7 +51,7 @@ export class PlaybackQueue {
5151
constructor(private room: Room) {
5252
this.loadClocks();
5353

54-
RoomViewStore.instance.addRoomListener(this.room.roomId, (isActive) => {
54+
SdkContextClass.instance.roomViewStore.addRoomListener(this.room.roomId, (isActive) => {
5555
if (!isActive) return;
5656

5757
// Reset the state of the playbacks before they start mounting and enqueuing updates.

src/components/structures/MatrixChat.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ import { TimelineRenderingType } from "../../contexts/RoomContext";
137137
import { UseCaseSelection } from '../views/elements/UseCaseSelection';
138138
import { ValidatedServerConfig } from '../../utils/ValidatedServerConfig';
139139
import { isLocalRoom } from '../../utils/localRoom/isLocalRoom';
140+
import { SdkContextClass, SDKContext } from '../../contexts/SDKContext';
140141
import { viewUserDeviceSettings } from '../../actions/handlers/viewUserDeviceSettings';
141142

142143
// legacy export
@@ -238,9 +239,12 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
238239
private readonly dispatcherRef: string;
239240
private readonly themeWatcher: ThemeWatcher;
240241
private readonly fontWatcher: FontWatcher;
242+
private readonly stores: SdkContextClass;
241243

242244
constructor(props: IProps) {
243245
super(props);
246+
this.stores = SdkContextClass.instance;
247+
this.stores.constructEagerStores();
244248

245249
this.state = {
246250
view: Views.LOADING,
@@ -762,6 +766,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
762766
Modal.createDialog(DialPadModal, {}, "mx_Dialog_dialPadWrapper");
763767
break;
764768
case Action.OnLoggedIn:
769+
this.stores.client = MatrixClientPeg.get();
765770
if (
766771
// Skip this handling for token login as that always calls onLoggedIn itself
767772
!this.tokenLogin &&
@@ -2087,7 +2092,9 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
20872092
}
20882093

20892094
return <ErrorBoundary>
2090-
{ view }
2095+
<SDKContext.Provider value={this.stores}>
2096+
{ view }
2097+
</SDKContext.Provider>
20912098
</ErrorBoundary>;
20922099
}
20932100
}

0 commit comments

Comments
 (0)