42f8247c2e
* Module API experiments * Move ResizerNotifier into SDKContext so we don't have to pass it into RoomView * Add the MultiRoomViewStore * Make RoomViewStore able to take a roomId prop * Different interface to add space panel items A bit less flexible but probably simpler and will help keep things actually consistent rather than just allowing modules to stick any JSX into the space panel (which means they also have to worry about styling if they *do* want it to be consistent). * Allow space panel items to be updated and manage which one is selected, allowing module "spaces" to be considered spaces * Remove fetchRoomFn from SpaceNotificationStore which didn't really seem to have any point as it was only called from one place * Switch to using module api via .instance * Fairly awful workaround to actually break the dependency nightmare * Add test for multiroomviewstore * add test * Make room names deterministic So the tests don't fail if you add other tests or run them individually * Add test for builtinsapi * Update module api * RVS is not needed as prop anymore Since it's passed through context * Add roomId to prop * Remove RoomViewStore from state This is now accessed through class field * Fix test * No need to pass RVS from LoggedInView * Add RoomContextType * Implement new builtins api * Add tests * Fix import * Fix circular dependency issue * Fix import * Add more tests * Improve comment * room-id is optional * Update license * Add implementation for AccountDataApi * Add implementation for Room * Add implementation for ClientApi * Create ClientApi in Api.ts * Write tests * Use nullish coalescing assignment * Implement openRoom in NavigationApi * Write tests * Add implementation for StoresApi * Write tests * Fix circular dependency * Add comments in lieu of type and fix else block * Change to class field --------- Co-authored-by: R Midhun Suresh <hi@midhun.dev>
199 lines
7.6 KiB
TypeScript
199 lines
7.6 KiB
TypeScript
/*
|
|
Copyright 2024 New Vector Ltd.
|
|
Copyright 2022 The Matrix.org Foundation C.I.C.
|
|
|
|
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
|
|
Please see LICENSE files in the repository root for full details.
|
|
*/
|
|
|
|
import { type MatrixClient } from "matrix-js-sdk/src/matrix";
|
|
import { createContext } from "react";
|
|
|
|
import defaultDispatcher from "../dispatcher/dispatcher";
|
|
import LegacyCallHandler from "../LegacyCallHandler";
|
|
import { PosthogAnalytics } from "../PosthogAnalytics";
|
|
import { SlidingSyncManager } from "../SlidingSyncManager";
|
|
import { MemberListStore } from "../stores/MemberListStore";
|
|
import { RoomNotificationStateStore } from "../stores/notifications/RoomNotificationStateStore";
|
|
import RightPanelStore from "../stores/right-panel/RightPanelStore";
|
|
import { RoomViewStore } from "../stores/RoomViewStore";
|
|
import SpaceStore, { type SpaceStoreClass } from "../stores/spaces/SpaceStore";
|
|
import TypingStore from "../stores/TypingStore";
|
|
import { UserProfilesStore } from "../stores/UserProfilesStore";
|
|
import { WidgetLayoutStore } from "../stores/widgets/WidgetLayoutStore";
|
|
import { WidgetPermissionStore } from "../stores/widgets/WidgetPermissionStore";
|
|
import { OidcClientStore } from "../stores/oidc/OidcClientStore";
|
|
import WidgetStore from "../stores/WidgetStore";
|
|
import ResizeNotifier from "../utils/ResizeNotifier";
|
|
import { MultiRoomViewStore } from "../stores/MultiRoomViewStore";
|
|
|
|
// This context is available to components under MatrixChat,
|
|
// the context must not be used by components outside a SdkContextClass tree.
|
|
// This assertion allows us to make the type not nullable.
|
|
export const SDKContext = createContext<SdkContextClass>(null as any);
|
|
SDKContext.displayName = "SDKContext";
|
|
|
|
/**
|
|
* A class which lazily initialises stores as and when they are requested, ensuring they remain
|
|
* as singletons scoped to this object.
|
|
*/
|
|
export class SdkContextClass {
|
|
/**
|
|
* The global SdkContextClass instance. This is a temporary measure whilst so many stores remain global
|
|
* as well. Over time, these stores should accept a `SdkContextClass` instance in their constructor.
|
|
* When all stores do this, this static variable can be deleted.
|
|
*/
|
|
public static readonly instance = new SdkContextClass();
|
|
|
|
// Optional as we don't have a client on initial load if unregistered. This should be set
|
|
// when the MatrixClient is first acquired in the dispatcher event Action.OnLoggedIn.
|
|
// It is only safe to set this once, as updating this value will NOT notify components using
|
|
// this Context.
|
|
public client?: MatrixClient;
|
|
|
|
// All protected fields to make it easier to derive test stores
|
|
protected _WidgetPermissionStore?: WidgetPermissionStore;
|
|
protected _MemberListStore?: MemberListStore;
|
|
protected _RightPanelStore?: RightPanelStore;
|
|
protected _RoomNotificationStateStore?: RoomNotificationStateStore;
|
|
protected _RoomViewStore?: RoomViewStore;
|
|
protected _WidgetLayoutStore?: WidgetLayoutStore;
|
|
protected _WidgetStore?: WidgetStore;
|
|
protected _PosthogAnalytics?: PosthogAnalytics;
|
|
protected _SlidingSyncManager?: SlidingSyncManager;
|
|
protected _SpaceStore?: SpaceStoreClass;
|
|
protected _LegacyCallHandler?: LegacyCallHandler;
|
|
protected _TypingStore?: TypingStore;
|
|
protected _UserProfilesStore?: UserProfilesStore;
|
|
protected _OidcClientStore?: OidcClientStore;
|
|
protected _ResizeNotifier?: ResizeNotifier;
|
|
protected _MultiRoomViewStore?: MultiRoomViewStore;
|
|
|
|
/**
|
|
* Automatically construct stores which need to be created eagerly so they can register with
|
|
* the dispatcher.
|
|
*/
|
|
public constructEagerStores(): void {
|
|
this._RoomViewStore = this.roomViewStore;
|
|
}
|
|
|
|
public get legacyCallHandler(): LegacyCallHandler {
|
|
if (!this._LegacyCallHandler) {
|
|
this._LegacyCallHandler = LegacyCallHandler.instance;
|
|
}
|
|
return this._LegacyCallHandler;
|
|
}
|
|
public get rightPanelStore(): RightPanelStore {
|
|
if (!this._RightPanelStore) {
|
|
this._RightPanelStore = RightPanelStore.instance;
|
|
}
|
|
return this._RightPanelStore;
|
|
}
|
|
public get roomNotificationStateStore(): RoomNotificationStateStore {
|
|
if (!this._RoomNotificationStateStore) {
|
|
this._RoomNotificationStateStore = RoomNotificationStateStore.instance;
|
|
}
|
|
return this._RoomNotificationStateStore;
|
|
}
|
|
public get roomViewStore(): RoomViewStore {
|
|
if (!this._RoomViewStore) {
|
|
this._RoomViewStore = new RoomViewStore(defaultDispatcher, this);
|
|
}
|
|
return this._RoomViewStore;
|
|
}
|
|
public get widgetLayoutStore(): WidgetLayoutStore {
|
|
if (!this._WidgetLayoutStore) {
|
|
this._WidgetLayoutStore = WidgetLayoutStore.instance;
|
|
}
|
|
return this._WidgetLayoutStore;
|
|
}
|
|
public get widgetPermissionStore(): WidgetPermissionStore {
|
|
if (!this._WidgetPermissionStore) {
|
|
this._WidgetPermissionStore = new WidgetPermissionStore(this);
|
|
}
|
|
return this._WidgetPermissionStore;
|
|
}
|
|
public get widgetStore(): WidgetStore {
|
|
if (!this._WidgetStore) {
|
|
this._WidgetStore = WidgetStore.instance;
|
|
}
|
|
return this._WidgetStore;
|
|
}
|
|
public get posthogAnalytics(): PosthogAnalytics {
|
|
if (!this._PosthogAnalytics) {
|
|
this._PosthogAnalytics = PosthogAnalytics.instance;
|
|
}
|
|
return this._PosthogAnalytics;
|
|
}
|
|
public get memberListStore(): MemberListStore {
|
|
if (!this._MemberListStore) {
|
|
this._MemberListStore = new MemberListStore(this);
|
|
}
|
|
return this._MemberListStore;
|
|
}
|
|
public get slidingSyncManager(): SlidingSyncManager {
|
|
if (!this._SlidingSyncManager) {
|
|
this._SlidingSyncManager = SlidingSyncManager.instance;
|
|
}
|
|
return this._SlidingSyncManager;
|
|
}
|
|
public get spaceStore(): SpaceStoreClass {
|
|
if (!this._SpaceStore) {
|
|
this._SpaceStore = SpaceStore.instance;
|
|
}
|
|
return this._SpaceStore;
|
|
}
|
|
public get typingStore(): TypingStore {
|
|
if (!this._TypingStore) {
|
|
this._TypingStore = new TypingStore(this);
|
|
window.mxTypingStore = this._TypingStore;
|
|
}
|
|
return this._TypingStore;
|
|
}
|
|
|
|
public get userProfilesStore(): UserProfilesStore {
|
|
if (!this.client) {
|
|
throw new Error("Unable to create UserProfilesStore without a client");
|
|
}
|
|
|
|
if (!this._UserProfilesStore) {
|
|
this._UserProfilesStore = new UserProfilesStore(this.client);
|
|
}
|
|
|
|
return this._UserProfilesStore;
|
|
}
|
|
|
|
public get oidcClientStore(): OidcClientStore {
|
|
if (!this.client) {
|
|
throw new Error("Unable to create OidcClientStore without a client");
|
|
}
|
|
|
|
if (!this._OidcClientStore) {
|
|
this._OidcClientStore = new OidcClientStore(this.client);
|
|
}
|
|
|
|
return this._OidcClientStore;
|
|
}
|
|
|
|
// This is getting increasingly tenuous to have here but we still have class components so it's
|
|
// awkward to consume multiple contexts in them. This should be replaced with ResizeObservers
|
|
// anyway really.
|
|
public get resizeNotifier(): ResizeNotifier {
|
|
if (!this._ResizeNotifier) {
|
|
this._ResizeNotifier = new ResizeNotifier();
|
|
}
|
|
return this._ResizeNotifier;
|
|
}
|
|
|
|
public get multiRoomViewStore(): MultiRoomViewStore {
|
|
if (!this._MultiRoomViewStore) {
|
|
this._MultiRoomViewStore = new MultiRoomViewStore(defaultDispatcher, this);
|
|
}
|
|
return this._MultiRoomViewStore;
|
|
}
|
|
|
|
public onLoggedOut(): void {
|
|
this._UserProfilesStore = undefined;
|
|
}
|
|
}
|