From 982e81f9a38573c303b7989a29ea180d18b12acb Mon Sep 17 00:00:00 2001 From: Travis Ralston <travpc@gmail.com> Date: Mon, 25 May 2020 15:43:21 -0600 Subject: [PATCH 1/5] Rename MatrixClientPeg to ts --- src/{MatrixClientPeg.js => MatrixClientPeg.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename src/{MatrixClientPeg.js => MatrixClientPeg.ts} (100%) diff --git a/src/MatrixClientPeg.js b/src/MatrixClientPeg.ts similarity index 100% rename from src/MatrixClientPeg.js rename to src/MatrixClientPeg.ts From bd2d13edd23aa341f14081e5b536f614b82eb2bf Mon Sep 17 00:00:00 2001 From: Travis Ralston <travpc@gmail.com> Date: Mon, 25 May 2020 15:52:05 -0600 Subject: [PATCH 2/5] Convert the MatrixClientPeg to TypeScript --- src/MatrixClientPeg.ts | 90 +++++++++++++++++++++++++----------------- 1 file changed, 53 insertions(+), 37 deletions(-) diff --git a/src/MatrixClientPeg.ts b/src/MatrixClientPeg.ts index 21f05b9759..2c35129734 100644 --- a/src/MatrixClientPeg.ts +++ b/src/MatrixClientPeg.ts @@ -17,8 +17,8 @@ See the License for the specific language governing permissions and limitations under the License. */ -import {MatrixClient, MemoryStore} from 'matrix-js-sdk'; - +import {MatrixClient} from 'matrix-js-sdk/src/client'; +import {MemoryStore} from 'matrix-js-sdk/src/store/memory'; import * as utils from 'matrix-js-sdk/src/utils'; import {EventTimeline} from 'matrix-js-sdk/src/models/event-timeline'; import {EventTimelineSet} from 'matrix-js-sdk/src/models/event-timeline-set'; @@ -34,7 +34,7 @@ import IdentityAuthClient from './IdentityAuthClient'; import { crossSigningCallbacks } from './CrossSigningManager'; import {SHOW_QR_CODE_METHOD} from "matrix-js-sdk/src/crypto/verification/QRCode"; -interface MatrixClientCreds { +interface ICredentials { homeserverUrl: string, identityServerUrl: string, userId: string, @@ -43,6 +43,13 @@ interface MatrixClientCreds { guest: boolean, } +// TODO: Move this to the js-sdk +interface IOpts { + initialSyncLimit?: number; + pendingEventOrdering?: "detached" | "chronological"; + lazyLoadMembers?: boolean; +} + /** * Wrapper object for handling the js-sdk Matrix Client object in the react-sdk * Handles the creation/initialisation of client objects. @@ -50,20 +57,22 @@ interface MatrixClientCreds { * Matrix Client object is available easily. */ class _MatrixClientPeg { - constructor() { - this.matrixClient = null; - this._justRegisteredUserId = null; + private matrixClient: MatrixClient; + private justRegisteredUserId: string; - // These are the default options used when when the - // client is started in 'start'. These can be altered - // at any time up to after the 'will_start_client' - // event is finished processing. - this.opts = { - initialSyncLimit: 20, - }; - // the credentials used to init the current client object. - // used if we tear it down & recreate it with a different store - this._currentClientCreds = null; + // These are the default options used when when the + // client is started in 'start'. These can be altered + // at any time up to after the 'will_start_client' + // event is finished processing. + private opts: IOpts = { + initialSyncLimit: 20, + }; + + // the credentials used to init the current client object. + // used if we tear it down & recreate it with a different store + private currentClientCreds: ICredentials; + + constructor() { } /** @@ -73,15 +82,15 @@ class _MatrixClientPeg { * * @param {string} script href to the script to be passed to the web worker */ - setIndexedDbWorkerScript(script) { + public setIndexedDbWorkerScript(script: string): void { createMatrixClient.indexedDbWorkerScript = script; } - get(): MatrixClient { + public get(): MatrixClient { return this.matrixClient; } - unset() { + public unset(): void { this.matrixClient = null; MatrixActionCreators.stop(); @@ -95,8 +104,8 @@ class _MatrixClientPeg { * * @param {string} uid The user ID of the user we've just registered */ - setJustRegisteredUserId(uid) { - this._justRegisteredUserId = uid; + public setJustRegisteredUserId(uid: string): void { + this.justRegisteredUserId = uid; } /** @@ -105,23 +114,25 @@ class _MatrixClientPeg { * * @returns {bool} True if user has just been registered */ - currentUserIsJustRegistered() { + public currentUserIsJustRegistered(): boolean { return ( this.matrixClient && - this.matrixClient.credentials.userId === this._justRegisteredUserId + this.matrixClient.credentials.userId === this.justRegisteredUserId ); } - /* + /** * Replace this MatrixClientPeg's client with a client instance that has * homeserver / identity server URLs and active credentials + * + * @param {ICredentials} creds The new credentials to use. */ - replaceUsingCreds(creds: MatrixClientCreds) { - this._currentClientCreds = creds; + public replaceUsingCreds(creds: ICredentials): void { + this.currentClientCreds = creds; this._createClient(creds); } - async assign() { + public async assign(): Promise<any> { for (const dbType of ['indexeddb', 'memory']) { try { const promise = this.matrixClient.store.startup(); @@ -132,7 +143,7 @@ class _MatrixClientPeg { if (dbType === 'indexeddb') { console.error('Error starting matrixclient store - falling back to memory store', err); this.matrixClient.store = new MemoryStore({ - localStorage: global.localStorage, + localStorage: localStorage, }); } else { console.error('Failed to start memory store!', err); @@ -179,7 +190,7 @@ class _MatrixClientPeg { return opts; } - async start() { + public async start(): Promise<any> { const opts = await this.assign(); console.log(`MatrixClientPeg: really starting MatrixClient`); @@ -187,7 +198,7 @@ class _MatrixClientPeg { console.log(`MatrixClientPeg: MatrixClient started`); } - getCredentials(): MatrixClientCreds { + public getCredentials(): ICredentials { return { homeserverUrl: this.matrixClient.baseUrl, identityServerUrl: this.matrixClient.idBaseUrl, @@ -198,12 +209,14 @@ class _MatrixClientPeg { }; } - /* + /** * Return the server name of the user's homeserver * Throws an error if unable to deduce the homeserver name * (eg. if the user is not logged in) + * + * @returns {string} The homeserver name, if present. */ - getHomeserverName() { + public getHomeserverName(): string { const matches = /^@.+:(.+)$/.exec(this.matrixClient.credentials.userId); if (matches === null || matches.length < 1) { throw new Error("Failed to derive homeserver name from user ID!"); @@ -211,7 +224,8 @@ class _MatrixClientPeg { return matches[1]; } - _createClient(creds: MatrixClientCreds) { + private _createClient(creds: ICredentials): void { + // TODO: Make these opts typesafe with the js-sdk const opts = { baseUrl: creds.homeserverUrl, idBaseUrl: creds.identityServerUrl, @@ -228,9 +242,9 @@ class _MatrixClientPeg { ], unstableClientRelationAggregation: true, identityServer: new IdentityAuthClient(), + cryptoCallbacks: {}, }; - opts.cryptoCallbacks = {}; // These are always installed regardless of the labs flag so that // cross-signing features can toggle on without reloading and also be // accessed immediately after login. @@ -253,8 +267,10 @@ class _MatrixClientPeg { } } -if (!global.mxMatrixClientPeg) { - global.mxMatrixClientPeg = new _MatrixClientPeg(); +const anyGlobal = <any>global; + +if (!anyGlobal.mxMatrixClientPeg) { + anyGlobal.mxMatrixClientPeg = new _MatrixClientPeg(); } -export const MatrixClientPeg = global.mxMatrixClientPeg; +export const MatrixClientPeg = <_MatrixClientPeg>anyGlobal.mxMatrixClientPeg; From 0cec74cc2b436ec3b1f7e7fd6e0d05b650263fcc Mon Sep 17 00:00:00 2001 From: Travis Ralston <travpc@gmail.com> Date: Mon, 25 May 2020 15:59:15 -0600 Subject: [PATCH 3/5] Appease the linter (and the project) Also export the interface that the project expects to be able to import :| --- src/MatrixClientPeg.ts | 20 ++++++++++---------- src/components/structures/LoggedInView.tsx | 4 ++-- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/MatrixClientPeg.ts b/src/MatrixClientPeg.ts index 2c35129734..2a89b05a39 100644 --- a/src/MatrixClientPeg.ts +++ b/src/MatrixClientPeg.ts @@ -34,7 +34,7 @@ import IdentityAuthClient from './IdentityAuthClient'; import { crossSigningCallbacks } from './CrossSigningManager'; import {SHOW_QR_CODE_METHOD} from "matrix-js-sdk/src/crypto/verification/QRCode"; -interface ICredentials { +export interface IMatrixClientCreds { homeserverUrl: string, identityServerUrl: string, userId: string, @@ -57,20 +57,20 @@ interface IOpts { * Matrix Client object is available easily. */ class _MatrixClientPeg { - private matrixClient: MatrixClient; - private justRegisteredUserId: string; - // These are the default options used when when the // client is started in 'start'. These can be altered // at any time up to after the 'will_start_client' // event is finished processing. - private opts: IOpts = { + public opts: IOpts = { initialSyncLimit: 20, }; + private matrixClient: MatrixClient; + private justRegisteredUserId: string; + // the credentials used to init the current client object. // used if we tear it down & recreate it with a different store - private currentClientCreds: ICredentials; + private currentClientCreds: IMatrixClientCreds; constructor() { } @@ -125,9 +125,9 @@ class _MatrixClientPeg { * Replace this MatrixClientPeg's client with a client instance that has * homeserver / identity server URLs and active credentials * - * @param {ICredentials} creds The new credentials to use. + * @param {IMatrixClientCreds} creds The new credentials to use. */ - public replaceUsingCreds(creds: ICredentials): void { + public replaceUsingCreds(creds: IMatrixClientCreds): void { this.currentClientCreds = creds; this._createClient(creds); } @@ -198,7 +198,7 @@ class _MatrixClientPeg { console.log(`MatrixClientPeg: MatrixClient started`); } - public getCredentials(): ICredentials { + public getCredentials(): IMatrixClientCreds { return { homeserverUrl: this.matrixClient.baseUrl, identityServerUrl: this.matrixClient.idBaseUrl, @@ -224,7 +224,7 @@ class _MatrixClientPeg { return matches[1]; } - private _createClient(creds: ICredentials): void { + private _createClient(creds: IMatrixClientCreds): void { // TODO: Make these opts typesafe with the js-sdk const opts = { baseUrl: creds.homeserverUrl, diff --git a/src/components/structures/LoggedInView.tsx b/src/components/structures/LoggedInView.tsx index 148d10fe8d..f502b4da4b 100644 --- a/src/components/structures/LoggedInView.tsx +++ b/src/components/structures/LoggedInView.tsx @@ -29,7 +29,7 @@ import { fixupColorFonts } from '../../utils/FontManager'; import * as sdk from '../../index'; import dis from '../../dispatcher/dispatcher'; import sessionStore from '../../stores/SessionStore'; -import {MatrixClientPeg, MatrixClientCreds} from '../../MatrixClientPeg'; +import {MatrixClientPeg, IMatrixClientCreds} from '../../MatrixClientPeg'; import SettingsStore from "../../settings/SettingsStore"; import TagOrderActions from '../../actions/TagOrderActions'; @@ -57,7 +57,7 @@ function canElementReceiveInput(el) { interface IProps { matrixClient: MatrixClient; - onRegistered: (credentials: MatrixClientCreds) => Promise<MatrixClient>; + onRegistered: (credentials: IMatrixClientCreds) => Promise<MatrixClient>; viaServers?: string[]; hideToSRUsers: boolean; resizeNotifier: ResizeNotifier; From e5c2d17015700ffae6ff676ea68360d6f02baf2f Mon Sep 17 00:00:00 2001 From: Travis Ralston <travpc@gmail.com> Date: Mon, 25 May 2020 16:06:05 -0600 Subject: [PATCH 4/5] Move the instance definition to the Window --- src/@types/global.d.ts | 2 + src/MatrixClientPeg.ts | 101 ++++++++++++++++++++++++----------------- 2 files changed, 62 insertions(+), 41 deletions(-) diff --git a/src/@types/global.d.ts b/src/@types/global.d.ts index e6e339d067..87e1e44341 100644 --- a/src/@types/global.d.ts +++ b/src/@types/global.d.ts @@ -15,10 +15,12 @@ limitations under the License. */ import * as ModernizrStatic from "modernizr"; +import { IMatrixClientPeg } from "../MatrixClientPeg"; declare global { interface Window { Modernizr: ModernizrStatic; + mxMatrixClientPeg: IMatrixClientPeg; Olm: { init: () => Promise<void>; }; diff --git a/src/MatrixClientPeg.ts b/src/MatrixClientPeg.ts index 2a89b05a39..ab19295263 100644 --- a/src/MatrixClientPeg.ts +++ b/src/MatrixClientPeg.ts @@ -44,19 +44,74 @@ export interface IMatrixClientCreds { } // TODO: Move this to the js-sdk -interface IOpts { +export interface IOpts { initialSyncLimit?: number; pendingEventOrdering?: "detached" | "chronological"; lazyLoadMembers?: boolean; } +export interface IMatrixClientPeg { + opts: IOpts; + + /** + * Sets the script href passed to the IndexedDB web worker + * If set, a separate web worker will be started to run the IndexedDB + * queries on. + * + * @param {string} script href to the script to be passed to the web worker + */ + setIndexedDbWorkerScript(script: string): void; + + /** + * Return the server name of the user's homeserver + * Throws an error if unable to deduce the homeserver name + * (eg. if the user is not logged in) + * + * @returns {string} The homeserver name, if present. + */ + getHomeserverName(): string; + + get(): MatrixClient; + unset(): void; + assign(): Promise<any>; + start(): Promise<any>; + + getCredentials(): IMatrixClientCreds; + + /** + * If we've registered a user ID we set this to the ID of the + * user we've just registered. If they then go & log in, we + * can send them to the welcome user (obviously this doesn't + * guarentee they'll get a chat with the welcome user). + * + * @param {string} uid The user ID of the user we've just registered + */ + setJustRegisteredUserId(uid: string): void; + + /** + * Returns true if the current user has just been registered by this + * client as determined by setJustRegisteredUserId() + * + * @returns {bool} True if user has just been registered + */ + currentUserIsJustRegistered(): boolean; + + /** + * Replace this MatrixClientPeg's client with a client instance that has + * homeserver / identity server URLs and active credentials + * + * @param {IMatrixClientCreds} creds The new credentials to use. + */ + replaceUsingCreds(creds: IMatrixClientCreds): void; +} + /** * Wrapper object for handling the js-sdk Matrix Client object in the react-sdk * Handles the creation/initialisation of client objects. * This module provides a singleton instance of this class so the 'current' * Matrix Client object is available easily. */ -class _MatrixClientPeg { +class _MatrixClientPeg implements IMatrixClientPeg { // These are the default options used when when the // client is started in 'start'. These can be altered // at any time up to after the 'will_start_client' @@ -75,13 +130,6 @@ class _MatrixClientPeg { constructor() { } - /** - * Sets the script href passed to the IndexedDB web worker - * If set, a separate web worker will be started to run the IndexedDB - * queries on. - * - * @param {string} script href to the script to be passed to the web worker - */ public setIndexedDbWorkerScript(script: string): void { createMatrixClient.indexedDbWorkerScript = script; } @@ -96,24 +144,10 @@ class _MatrixClientPeg { MatrixActionCreators.stop(); } - /** - * If we've registered a user ID we set this to the ID of the - * user we've just registered. If they then go & log in, we - * can send them to the welcome user (obviously this doesn't - * guarentee they'll get a chat with the welcome user). - * - * @param {string} uid The user ID of the user we've just registered - */ public setJustRegisteredUserId(uid: string): void { this.justRegisteredUserId = uid; } - /** - * Returns true if the current user has just been registered by this - * client as determined by setJustRegisteredUserId() - * - * @returns {bool} True if user has just been registered - */ public currentUserIsJustRegistered(): boolean { return ( this.matrixClient && @@ -121,12 +155,6 @@ class _MatrixClientPeg { ); } - /** - * Replace this MatrixClientPeg's client with a client instance that has - * homeserver / identity server URLs and active credentials - * - * @param {IMatrixClientCreds} creds The new credentials to use. - */ public replaceUsingCreds(creds: IMatrixClientCreds): void { this.currentClientCreds = creds; this._createClient(creds); @@ -209,13 +237,6 @@ class _MatrixClientPeg { }; } - /** - * Return the server name of the user's homeserver - * Throws an error if unable to deduce the homeserver name - * (eg. if the user is not logged in) - * - * @returns {string} The homeserver name, if present. - */ public getHomeserverName(): string { const matches = /^@.+:(.+)$/.exec(this.matrixClient.credentials.userId); if (matches === null || matches.length < 1) { @@ -267,10 +288,8 @@ class _MatrixClientPeg { } } -const anyGlobal = <any>global; - -if (!anyGlobal.mxMatrixClientPeg) { - anyGlobal.mxMatrixClientPeg = new _MatrixClientPeg(); +if (!window.mxMatrixClientPeg) { + window.mxMatrixClientPeg = new _MatrixClientPeg(); } -export const MatrixClientPeg = <_MatrixClientPeg>anyGlobal.mxMatrixClientPeg; +export const MatrixClientPeg = window.mxMatrixClientPeg; From 1c9b5eb42d99ddcc8ac04c9f8fed0ca1a5dd2a67 Mon Sep 17 00:00:00 2001 From: Travis Ralston <travpc@gmail.com> Date: Mon, 25 May 2020 16:14:51 -0600 Subject: [PATCH 5/5] Appease the tests --- src/MatrixClientPeg.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/MatrixClientPeg.ts b/src/MatrixClientPeg.ts index ab19295263..ff0750c501 100644 --- a/src/MatrixClientPeg.ts +++ b/src/MatrixClientPeg.ts @@ -120,7 +120,7 @@ class _MatrixClientPeg implements IMatrixClientPeg { initialSyncLimit: 20, }; - private matrixClient: MatrixClient; + private matrixClient: MatrixClient = null; private justRegisteredUserId: string; // the credentials used to init the current client object. @@ -157,7 +157,7 @@ class _MatrixClientPeg implements IMatrixClientPeg { public replaceUsingCreds(creds: IMatrixClientCreds): void { this.currentClientCreds = creds; - this._createClient(creds); + this.createClient(creds); } public async assign(): Promise<any> { @@ -245,7 +245,7 @@ class _MatrixClientPeg implements IMatrixClientPeg { return matches[1]; } - private _createClient(creds: IMatrixClientCreds): void { + private createClient(creds: IMatrixClientCreds): void { // TODO: Make these opts typesafe with the js-sdk const opts = { baseUrl: creds.homeserverUrl,