Handle SDKContextClass client initialisation internally (#34146)
* Handle SDKContextClass `client` initialisation internally Rather than via MatrixChat - this is predominantly for Lifecycle tests as they don't use a MatrixChat and it doesn't make much sense for this component to own this state. * Fix tests
This commit is contained in:
@@ -81,6 +81,7 @@ import {
|
||||
import { TokenRefresher } from "./utils/oidc/TokenRefresher";
|
||||
import { checkBrowserSupport } from "./SupportedBrowser";
|
||||
import { type URLParams } from "./vector/url_utils.ts";
|
||||
import { type OnLoggedInPayload } from "./dispatcher/payloads/OnLoggedInPayload.ts";
|
||||
|
||||
const HOMESERVER_URL_KEY = "mx_hs_url";
|
||||
const ID_SERVER_URL_KEY = "mx_is_url";
|
||||
@@ -906,9 +907,9 @@ async function doSetLoggedIn(
|
||||
}
|
||||
checkSessionLock();
|
||||
|
||||
// We are now logged in, so fire this. We have yet to start the client but the
|
||||
// client_started dispatch is for that.
|
||||
dis.fire(Action.OnLoggedIn);
|
||||
// We are now logged in, so fire this. We have yet to start the client but the client_started dispatch is for that.
|
||||
// Dispatch this synchronously so SDKContextClass can set the client for other modules to consume.
|
||||
dis.dispatch<OnLoggedInPayload>({ action: Action.OnLoggedIn, client }, true);
|
||||
|
||||
const clientPegOpts: MatrixClientPegAssignOpts = {};
|
||||
if (credentials.pickleKey) {
|
||||
|
||||
@@ -1521,7 +1521,6 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
|
||||
* Handle an {@link Action.OnLoggedIn} action (i.e, we now have a client with working credentials).
|
||||
*/
|
||||
private onLoggedIn(): void {
|
||||
this.stores.client = MatrixClientPeg.safeGet();
|
||||
StorageManager.tryPersistStorage();
|
||||
|
||||
// If we're loading the app for the first time, we can now transition to a splash screen while we wait for the
|
||||
|
||||
@@ -26,6 +26,9 @@ import { OidcClientStore } from "../stores/oidc/OidcClientStore";
|
||||
import WidgetStore from "../stores/WidgetStore";
|
||||
import ResizeNotifier from "../utils/ResizeNotifier";
|
||||
import { MultiRoomViewStore } from "../stores/MultiRoomViewStore";
|
||||
import { type ActionPayload, isAction } from "../dispatcher/payloads.ts";
|
||||
import { Action } from "../dispatcher/actions.ts";
|
||||
import { type OnLoggedInPayload } from "../dispatcher/payloads/OnLoggedInPayload.ts";
|
||||
|
||||
/**
|
||||
* A class which (mostly) lazily initialises stores as and when they are requested, ensuring they remain
|
||||
@@ -43,11 +46,13 @@ export class SDKContextClass {
|
||||
*/
|
||||
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.
|
||||
// Optional as we don't have a client on initial load if unregistered.
|
||||
// It is only safe to set this once, as updating this value will NOT notify components using
|
||||
// this Context.
|
||||
public client?: MatrixClient;
|
||||
protected _client?: MatrixClient;
|
||||
public get client(): MatrixClient | undefined {
|
||||
return this._client;
|
||||
}
|
||||
|
||||
// All protected fields to make it easier to derive test stores
|
||||
protected _WidgetPermissionStore?: WidgetPermissionStore;
|
||||
@@ -67,6 +72,16 @@ export class SDKContextClass {
|
||||
protected _ResizeNotifier?: ResizeNotifier;
|
||||
protected _MultiRoomViewStore?: MultiRoomViewStore;
|
||||
|
||||
public constructor() {
|
||||
defaultDispatcher.register(this.onDispatch);
|
||||
}
|
||||
|
||||
private onDispatch = (payload: ActionPayload): void => {
|
||||
if (isAction<OnLoggedInPayload>(payload, Action.OnLoggedIn)) {
|
||||
this._client = payload.client;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Automatically construct stores which need to be created eagerly so they can register with
|
||||
* the dispatcher.
|
||||
@@ -193,5 +208,6 @@ export class SDKContextClass {
|
||||
public onLoggedOut(): void {
|
||||
this._UserProfilesStore = undefined;
|
||||
this._OidcClientStore = undefined;
|
||||
this._client = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -335,7 +335,7 @@ export enum Action {
|
||||
* access token from local storage). Note that this does not necessarily mean that a login action has happened,
|
||||
* just that authentication creds have been set up.
|
||||
*
|
||||
* No additional payload information required.
|
||||
* Use with a OnLoggedInPayload.
|
||||
*/
|
||||
OnLoggedIn = "on_logged_in",
|
||||
|
||||
|
||||
@@ -16,6 +16,15 @@ export interface ActionPayload {
|
||||
action: DispatcherAction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Type guard to check if a payload is of a specific action type.
|
||||
* @param payload - the incoming payload to check
|
||||
* @param action - the action to return true for
|
||||
*/
|
||||
export function isAction<P extends ActionPayload>(payload: ActionPayload, action: P["action"]): payload is P {
|
||||
return payload.action === action;
|
||||
}
|
||||
|
||||
/**
|
||||
* The function the dispatcher calls when ready for an AsyncActionPayload. The
|
||||
* single argument is used to start a dispatch. First the dispatcher calls the
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
Copyright 2026 Element Creations Ltd.
|
||||
|
||||
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 { type ActionPayload } from "../payloads";
|
||||
import { type Action } from "../actions";
|
||||
|
||||
export interface OnLoggedInPayload extends ActionPayload {
|
||||
action: Action.OnLoggedIn;
|
||||
|
||||
client: MatrixClient;
|
||||
}
|
||||
Reference in New Issue
Block a user