From 13fbd096b0ef42f412bdb20c429c5c0e1c382423 Mon Sep 17 00:00:00 2001 From: kegsay Date: Wed, 19 Oct 2022 14:14:14 +0100 Subject: [PATCH] Stores refactor: convert TypingStore; rename TestStores to TestSdkContext (#9454) --- src/Lifecycle.ts | 6 +++--- src/components/views/rooms/BasicMessageComposer.tsx | 4 ++-- src/contexts/SDKContext.ts | 9 +++++++++ src/stores/TypingStore.ts | 13 +++---------- test/{TestStores.ts => TestSdkContext.ts} | 4 ++-- test/stores/RoomViewStore-test.ts | 4 ++-- test/stores/TypingStore-test.ts | 8 +++++--- 7 files changed, 26 insertions(+), 22 deletions(-) rename test/{TestStores.ts => TestSdkContext.ts} (91%) diff --git a/src/Lifecycle.ts b/src/Lifecycle.ts index 6c9c955818..9351e91ae4 100644 --- a/src/Lifecycle.ts +++ b/src/Lifecycle.ts @@ -39,7 +39,6 @@ import PlatformPeg from "./PlatformPeg"; import { sendLoginRequest } from "./Login"; import * as StorageManager from './utils/StorageManager'; import SettingsStore from "./settings/SettingsStore"; -import TypingStore from "./stores/TypingStore"; import ToastStore from "./stores/ToastStore"; import { IntegrationManagers } from "./integrations/IntegrationManagers"; import { Mjolnir } from "./mjolnir/Mjolnir"; @@ -62,6 +61,7 @@ import { DialogOpener } from "./utils/DialogOpener"; import { Action } from "./dispatcher/actions"; import AbstractLocalStorageSettingsHandler from "./settings/handlers/AbstractLocalStorageSettingsHandler"; import { OverwriteLoginPayload } from "./dispatcher/payloads/OverwriteLoginPayload"; +import { SdkContextClass } from './contexts/SDKContext'; const HOMESERVER_URL_KEY = "mx_hs_url"; const ID_SERVER_URL_KEY = "mx_is_url"; @@ -797,7 +797,7 @@ async function startMatrixClient(startSyncing = true): Promise { dis.dispatch({ action: 'will_start_client' }, true); // reset things first just in case - TypingStore.sharedInstance().reset(); + SdkContextClass.instance.typingStore.reset(); ToastStore.sharedInstance().reset(); DialogOpener.instance.prepare(); @@ -927,7 +927,7 @@ export function stopMatrixClient(unsetClient = true): void { Notifier.stop(); LegacyCallHandler.instance.stop(); UserActivity.sharedInstance().stop(); - TypingStore.sharedInstance().reset(); + SdkContextClass.instance.typingStore.reset(); Presence.stop(); ActiveWidgetStore.instance.stop(); IntegrationManagers.sharedInstance().stopWatching(); diff --git a/src/components/views/rooms/BasicMessageComposer.tsx b/src/components/views/rooms/BasicMessageComposer.tsx index d74c7b5148..4c2201a628 100644 --- a/src/components/views/rooms/BasicMessageComposer.tsx +++ b/src/components/views/rooms/BasicMessageComposer.tsx @@ -31,7 +31,6 @@ import Autocomplete, { generateCompletionDomId } from '../rooms/Autocomplete'; import { getAutoCompleteCreator, Part, Type } from '../../../editor/parts'; import { parseEvent, parsePlainTextMessage } from '../../../editor/deserialize'; import { renderModel } from '../../../editor/render'; -import TypingStore from "../../../stores/TypingStore"; import SettingsStore from "../../../settings/SettingsStore"; import { IS_MAC, Key } from "../../../Keyboard"; import { EMOTICON_TO_EMOJI } from "../../../emoji"; @@ -47,6 +46,7 @@ import { getKeyBindingsManager } from '../../../KeyBindingsManager'; import { ALTERNATE_KEY_NAME, KeyBindingAction } from '../../../accessibility/KeyboardShortcuts'; import { _t } from "../../../languageHandler"; import { linkify } from '../../../linkify-matrix'; +import { SdkContextClass } from '../../../contexts/SDKContext'; // matches emoticons which follow the start of a line or whitespace const REGEX_EMOTICON_WHITESPACE = new RegExp('(?:^|\\s)(' + EMOTICON_REGEX.source + ')\\s|:^$'); @@ -246,7 +246,7 @@ export default class BasicMessageEditor extends React.Component isTyping = false; } } - TypingStore.sharedInstance().setSelfTyping( + SdkContextClass.instance.typingStore.setSelfTyping( this.props.room.roomId, this.props.threadId, isTyping, diff --git a/src/contexts/SDKContext.ts b/src/contexts/SDKContext.ts index 61905dca92..8e6222512b 100644 --- a/src/contexts/SDKContext.ts +++ b/src/contexts/SDKContext.ts @@ -25,6 +25,7 @@ import { RoomNotificationStateStore } from "../stores/notifications/RoomNotifica import RightPanelStore from "../stores/right-panel/RightPanelStore"; import { RoomViewStore } from "../stores/RoomViewStore"; import SpaceStore, { SpaceStoreClass } from "../stores/spaces/SpaceStore"; +import TypingStore from "../stores/TypingStore"; import { WidgetLayoutStore } from "../stores/widgets/WidgetLayoutStore"; import WidgetStore from "../stores/WidgetStore"; @@ -59,6 +60,7 @@ export class SdkContextClass { protected _SlidingSyncManager?: SlidingSyncManager; protected _SpaceStore?: SpaceStoreClass; protected _LegacyCallHandler?: LegacyCallHandler; + protected _TypingStore?: TypingStore; /** * Automatically construct stores which need to be created eagerly so they can register with @@ -124,4 +126,11 @@ export class SdkContextClass { } return this._SpaceStore; } + public get typingStore(): TypingStore { + if (!this._TypingStore) { + this._TypingStore = new TypingStore(this); + window.mxTypingStore = this._TypingStore; + } + return this._TypingStore; + } } diff --git a/src/stores/TypingStore.ts b/src/stores/TypingStore.ts index d642f3fea7..be17da6e4e 100644 --- a/src/stores/TypingStore.ts +++ b/src/stores/TypingStore.ts @@ -14,7 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { MatrixClientPeg } from "../MatrixClientPeg"; +import { SdkContextClass } from "../contexts/SDKContext"; import SettingsStore from "../settings/SettingsStore"; import { isLocalRoom } from "../utils/localRoom/isLocalRoom"; import Timer from "../utils/Timer"; @@ -34,17 +34,10 @@ export default class TypingStore { }; }; - constructor() { + constructor(private readonly context: SdkContextClass) { this.reset(); } - public static sharedInstance(): TypingStore { - if (window.mxTypingStore === undefined) { - window.mxTypingStore = new TypingStore(); - } - return window.mxTypingStore; - } - /** * Clears all cached typing states. Intended to be called when the * MatrixClientPeg client changes. @@ -108,6 +101,6 @@ export default class TypingStore { } else currentTyping.userTimer.restart(); } - MatrixClientPeg.get().sendTyping(roomId, isTyping, TYPING_SERVER_TIMEOUT); + this.context.client?.sendTyping(roomId, isTyping, TYPING_SERVER_TIMEOUT); } } diff --git a/test/TestStores.ts b/test/TestSdkContext.ts similarity index 91% rename from test/TestStores.ts rename to test/TestSdkContext.ts index dbaa51f504..137b71f9a3 100644 --- a/test/TestStores.ts +++ b/test/TestSdkContext.ts @@ -25,10 +25,10 @@ import { WidgetLayoutStore } from "../src/stores/widgets/WidgetLayoutStore"; import WidgetStore from "../src/stores/WidgetStore"; /** - * A class which provides the same API as Stores but adds additional unsafe setters which can + * A class which provides the same API as SdkContextClass but adds additional unsafe setters which can * replace individual stores. This is useful for tests which need to mock out stores. */ -export class TestStores extends SdkContextClass { +export class TestSdkContext extends SdkContextClass { public _RightPanelStore?: RightPanelStore; public _RoomNotificationStateStore?: RoomNotificationStateStore; public _RoomViewStore?: RoomViewStore; diff --git a/test/stores/RoomViewStore-test.ts b/test/stores/RoomViewStore-test.ts index f6f6bf2cc7..5f1bb98d3d 100644 --- a/test/stores/RoomViewStore-test.ts +++ b/test/stores/RoomViewStore-test.ts @@ -27,7 +27,7 @@ import { MatrixDispatcher } from '../../src/dispatcher/dispatcher'; import { UPDATE_EVENT } from '../../src/stores/AsyncStore'; import { ActiveRoomChangedPayload } from '../../src/dispatcher/payloads/ActiveRoomChangedPayload'; import { SpaceStoreClass } from '../../src/stores/spaces/SpaceStore'; -import { TestStores } from '../TestStores'; +import { TestSdkContext } from '../TestSdkContext'; // mock out the injected classes jest.mock('../../src/PosthogAnalytics'); @@ -77,7 +77,7 @@ describe('RoomViewStore', function() { // Make the RVS to test dis = new MatrixDispatcher(); slidingSyncManager = new MockSlidingSyncManager(); - const stores = new TestStores(); + const stores = new TestSdkContext(); stores._SlidingSyncManager = slidingSyncManager; stores._PosthogAnalytics = new MockPosthogAnalytics(); stores._SpaceStore = new MockSpaceStore(); diff --git a/test/stores/TypingStore-test.ts b/test/stores/TypingStore-test.ts index 98ddfca3c4..a5b4437f14 100644 --- a/test/stores/TypingStore-test.ts +++ b/test/stores/TypingStore-test.ts @@ -17,13 +17,14 @@ limitations under the License. import { mocked } from "jest-mock"; import { MatrixClient } from "matrix-js-sdk/src/matrix"; -import { MatrixClientPeg } from "../../src/MatrixClientPeg"; import TypingStore from "../../src/stores/TypingStore"; import { LOCAL_ROOM_ID_PREFIX } from "../../src/models/LocalRoom"; import SettingsStore from "../../src/settings/SettingsStore"; +import { TestSdkContext } from "../TestSdkContext"; jest.mock("../../src/settings/SettingsStore", () => ({ getValue: jest.fn(), + monitorSetting: jest.fn(), })); describe("TypingStore", () => { @@ -37,11 +38,12 @@ describe("TypingStore", () => { const localRoomId = LOCAL_ROOM_ID_PREFIX + "test"; beforeEach(() => { - typingStore = new TypingStore(); mockClient = { sendTyping: jest.fn(), } as unknown as MatrixClient; - MatrixClientPeg.get = () => mockClient; + const context = new TestSdkContext(); + context.client = mockClient; + typingStore = new TypingStore(context); mocked(SettingsStore.getValue).mockImplementation((setting: string) => { return settings[setting]; });