mirror of https://github.com/vector-im/riot-web
Update type and usage of window.matrixChat to be better React 18 friendly (#28415)
* Update type and usage of window.matrixChat to be better React 18 friendly Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Improve coverage Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Make modules import async to make the file testable Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --------- Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>pull/28457/head
parent
349c9b0c26
commit
ca239fee4d
|
@ -10,7 +10,6 @@ Please see LICENSE files in the repository root for full details.
|
||||||
import "matrix-js-sdk/src/@types/global"; // load matrix-js-sdk's type extensions first
|
import "matrix-js-sdk/src/@types/global"; // load matrix-js-sdk's type extensions first
|
||||||
import "@types/modernizr";
|
import "@types/modernizr";
|
||||||
|
|
||||||
import type { Renderer } from "react-dom";
|
|
||||||
import type { logger } from "matrix-js-sdk/src/logger";
|
import type { logger } from "matrix-js-sdk/src/logger";
|
||||||
import ContentMessages from "../ContentMessages";
|
import ContentMessages from "../ContentMessages";
|
||||||
import { IMatrixClientPeg } from "../MatrixClientPeg";
|
import { IMatrixClientPeg } from "../MatrixClientPeg";
|
||||||
|
@ -44,6 +43,7 @@ import AutoRageshakeStore from "../stores/AutoRageshakeStore";
|
||||||
import { IConfigOptions } from "../IConfigOptions";
|
import { IConfigOptions } from "../IConfigOptions";
|
||||||
import { MatrixDispatcher } from "../dispatcher/dispatcher";
|
import { MatrixDispatcher } from "../dispatcher/dispatcher";
|
||||||
import { DeepReadonly } from "./common";
|
import { DeepReadonly } from "./common";
|
||||||
|
import MatrixChat from "../components/structures/MatrixChat";
|
||||||
|
|
||||||
/* eslint-disable @typescript-eslint/naming-convention */
|
/* eslint-disable @typescript-eslint/naming-convention */
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ declare global {
|
||||||
interface Window {
|
interface Window {
|
||||||
mxSendRageshake: (text: string, withLogs?: boolean) => void;
|
mxSendRageshake: (text: string, withLogs?: boolean) => void;
|
||||||
matrixLogger: typeof logger;
|
matrixLogger: typeof logger;
|
||||||
matrixChat: ReturnType<Renderer>;
|
matrixChat?: MatrixChat;
|
||||||
mxSendSentryReport: (userText: string, issueUrl: string, error: Error) => Promise<void>;
|
mxSendSentryReport: (userText: string, issueUrl: string, error: Error) => Promise<void>;
|
||||||
mxLoginWithAccessToken: (hsUrl: string, accessToken: string) => Promise<void>;
|
mxLoginWithAccessToken: (hsUrl: string, accessToken: string) => Promise<void>;
|
||||||
mxAutoRageshakeStore?: AutoRageshakeStore;
|
mxAutoRageshakeStore?: AutoRageshakeStore;
|
||||||
|
|
|
@ -6,7 +6,6 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||||
Please see LICENSE files in the repository root for full details.
|
Please see LICENSE files in the repository root for full details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type MatrixChat from "../components/structures/MatrixChat";
|
|
||||||
import Views from "../Views";
|
import Views from "../Views";
|
||||||
|
|
||||||
export function isLoggedIn(): boolean {
|
export function isLoggedIn(): boolean {
|
||||||
|
@ -14,6 +13,5 @@ export function isLoggedIn(): boolean {
|
||||||
// `element-web` and into this file? Better yet, we should probably create a
|
// `element-web` and into this file? Better yet, we should probably create a
|
||||||
// store to hold this state.
|
// store to hold this state.
|
||||||
// See also https://github.com/vector-im/element-web/issues/15034.
|
// See also https://github.com/vector-im/element-web/issues/15034.
|
||||||
const app = window.matrixChat;
|
return window.matrixChat?.state.view === Views.LOGGED_IN;
|
||||||
return (app as MatrixChat)?.state.view === Views.LOGGED_IN;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,9 +23,6 @@ import ElectronPlatform from "./platform/ElectronPlatform";
|
||||||
import PWAPlatform from "./platform/PWAPlatform";
|
import PWAPlatform from "./platform/PWAPlatform";
|
||||||
import WebPlatform from "./platform/WebPlatform";
|
import WebPlatform from "./platform/WebPlatform";
|
||||||
import { initRageshake, initRageshakeStore } from "./rageshakesetup";
|
import { initRageshake, initRageshakeStore } from "./rageshakesetup";
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
||||||
// @ts-ignore - this path is created at runtime and therefore won't exist at typecheck time
|
|
||||||
import { INSTALLED_MODULES } from "../modules";
|
|
||||||
|
|
||||||
export const rageshakePromise = initRageshake();
|
export const rageshakePromise = initRageshake();
|
||||||
|
|
||||||
|
@ -104,7 +101,7 @@ export async function showError(title: string, messages?: string[]): Promise<voi
|
||||||
/* webpackChunkName: "error-view" */
|
/* webpackChunkName: "error-view" */
|
||||||
"../async-components/structures/ErrorView"
|
"../async-components/structures/ErrorView"
|
||||||
);
|
);
|
||||||
window.matrixChat = ReactDOM.render(
|
ReactDOM.render(
|
||||||
<StrictMode>
|
<StrictMode>
|
||||||
<ErrorView title={title} messages={messages} />
|
<ErrorView title={title} messages={messages} />
|
||||||
</StrictMode>,
|
</StrictMode>,
|
||||||
|
@ -117,7 +114,7 @@ export async function showIncompatibleBrowser(onAccept: () => void): Promise<voi
|
||||||
/* webpackChunkName: "error-view" */
|
/* webpackChunkName: "error-view" */
|
||||||
"../async-components/structures/ErrorView"
|
"../async-components/structures/ErrorView"
|
||||||
);
|
);
|
||||||
window.matrixChat = ReactDOM.render(
|
ReactDOM.render(
|
||||||
<StrictMode>
|
<StrictMode>
|
||||||
<UnsupportedBrowserView onAccept={onAccept} />
|
<UnsupportedBrowserView onAccept={onAccept} />
|
||||||
</StrictMode>,
|
</StrictMode>,
|
||||||
|
@ -126,6 +123,9 @@ export async function showIncompatibleBrowser(onAccept: () => void): Promise<voi
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function loadModules(): Promise<void> {
|
export async function loadModules(): Promise<void> {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-ignore - this path is created at runtime and therefore won't exist at typecheck time
|
||||||
|
const { INSTALLED_MODULES } = await import("../modules");
|
||||||
for (const InstalledModule of INSTALLED_MODULES) {
|
for (const InstalledModule of INSTALLED_MODULES) {
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
// @ts-ignore - we know the constructor exists even if TypeScript can't be convinced of that
|
// @ts-ignore - we know the constructor exists even if TypeScript can't be convinced of that
|
||||||
|
|
|
@ -11,7 +11,6 @@ Please see LICENSE files in the repository root for full details.
|
||||||
import { logger } from "matrix-js-sdk/src/logger";
|
import { logger } from "matrix-js-sdk/src/logger";
|
||||||
import { QueryDict } from "matrix-js-sdk/src/utils";
|
import { QueryDict } from "matrix-js-sdk/src/utils";
|
||||||
|
|
||||||
import MatrixChatType from "../components/structures/MatrixChat";
|
|
||||||
import { parseQsFromFragment } from "./url_utils";
|
import { parseQsFromFragment } from "./url_utils";
|
||||||
|
|
||||||
let lastLocationHashSet: string | null = null;
|
let lastLocationHashSet: string | null = null;
|
||||||
|
@ -31,7 +30,7 @@ function routeUrl(location: Location): void {
|
||||||
|
|
||||||
logger.log("Routing URL ", location.href);
|
logger.log("Routing URL ", location.href);
|
||||||
const s = getScreenFromLocation(location);
|
const s = getScreenFromLocation(location);
|
||||||
(window.matrixChat as MatrixChatType).showScreen(s.screen, s.params);
|
window.matrixChat.showScreen(s.screen, s.params);
|
||||||
}
|
}
|
||||||
|
|
||||||
function onHashChange(): void {
|
function onHashChange(): void {
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
/*
|
||||||
|
Copyright 2024 New Vector Ltd.
|
||||||
|
|
||||||
|
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||||
|
Please see LICENSE files in the repository root for full details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import MatrixChat from "../../../src/components/structures/MatrixChat.tsx";
|
||||||
|
import { isLoggedIn } from "../../../src/utils/login.ts";
|
||||||
|
import Views from "../../../src/Views.ts";
|
||||||
|
|
||||||
|
describe("isLoggedIn", () => {
|
||||||
|
it("should return true if MatrixChat state view is LOGGED_IN", () => {
|
||||||
|
window.matrixChat = {
|
||||||
|
state: {
|
||||||
|
view: Views.LOGGED_IN,
|
||||||
|
},
|
||||||
|
} as unknown as MatrixChat;
|
||||||
|
|
||||||
|
expect(isLoggedIn()).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,261 @@
|
||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`showError should match snapshot 1`] = `
|
||||||
|
<div
|
||||||
|
id="matrixchat"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="mx_ErrorView cpd-theme-light"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
alt="Element"
|
||||||
|
class="mx_ErrorView_logo"
|
||||||
|
height="160"
|
||||||
|
src="themes/element/img/logos/element-app-logo.png"
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
class="mx_ErrorView_container"
|
||||||
|
>
|
||||||
|
<h1
|
||||||
|
class="_typography_yh5dq_162 _font-heading-md-semibold_yh5dq_121"
|
||||||
|
>
|
||||||
|
Error title
|
||||||
|
</h1>
|
||||||
|
<p
|
||||||
|
class="_typography_yh5dq_162 _font-body-lg-regular_yh5dq_78"
|
||||||
|
>
|
||||||
|
msg1
|
||||||
|
</p>
|
||||||
|
<p
|
||||||
|
class="_typography_yh5dq_162 _font-body-lg-regular_yh5dq_78"
|
||||||
|
>
|
||||||
|
msg2
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
exports[`showIncompatibleBrowser should match snapshot 1`] = `
|
||||||
|
<div
|
||||||
|
id="matrixchat"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="mx_ErrorView cpd-theme-light"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
alt="Element"
|
||||||
|
class="mx_ErrorView_logo"
|
||||||
|
height="160"
|
||||||
|
src="themes/element/img/logos/element-app-logo.png"
|
||||||
|
/>
|
||||||
|
<div
|
||||||
|
class="mx_ErrorView_container"
|
||||||
|
>
|
||||||
|
<h1
|
||||||
|
class="_typography_yh5dq_162 _font-heading-md-semibold_yh5dq_121"
|
||||||
|
>
|
||||||
|
Element does not support this browser
|
||||||
|
</h1>
|
||||||
|
<p
|
||||||
|
class="_typography_yh5dq_162 _font-body-lg-regular_yh5dq_78"
|
||||||
|
>
|
||||||
|
Element uses some browser features which are not available in your current browser. If you continue, some features may stop working and there is a risk that you may lose data in the future.
|
||||||
|
</p>
|
||||||
|
<p
|
||||||
|
class="_typography_yh5dq_162 _font-body-lg-regular_yh5dq_78"
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
For the best experience, use
|
||||||
|
<a
|
||||||
|
href="https://google.com/chrome"
|
||||||
|
rel="noreferrer noopener"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
Chrome
|
||||||
|
</a>
|
||||||
|
,
|
||||||
|
<a
|
||||||
|
href="https://firefox.com"
|
||||||
|
rel="noreferrer noopener"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
Firefox
|
||||||
|
</a>
|
||||||
|
,
|
||||||
|
<a
|
||||||
|
href="https://microsoft.com/edge"
|
||||||
|
rel="noreferrer noopener"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
Edge
|
||||||
|
</a>
|
||||||
|
, or
|
||||||
|
<a
|
||||||
|
href="https://apple.com/safari"
|
||||||
|
rel="noreferrer noopener"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
Safari
|
||||||
|
</a>
|
||||||
|
.
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
<div
|
||||||
|
class="mx_Flex mx_ErrorView_buttons"
|
||||||
|
>
|
||||||
|
<button
|
||||||
|
class="_button_i91xf_17 _has-icon_i91xf_66"
|
||||||
|
data-kind="secondary"
|
||||||
|
data-size="sm"
|
||||||
|
role="button"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
aria-hidden="true"
|
||||||
|
fill="currentColor"
|
||||||
|
height="20"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
width="20"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M5 3h6a1 1 0 1 1 0 2H5v14h14v-6a1 1 0 1 1 2 0v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2Z"
|
||||||
|
/>
|
||||||
|
<path
|
||||||
|
d="M15 3h5a1 1 0 0 1 1 1v5a1 1 0 1 1-2 0V6.414l-6.293 6.293a1 1 0 0 1-1.414-1.414L17.586 5H15a1 1 0 1 1 0-2Z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
Learn more
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="_button_i91xf_17"
|
||||||
|
data-kind="primary"
|
||||||
|
data-size="sm"
|
||||||
|
role="button"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
Continue anyway
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="_separator_144s5_17"
|
||||||
|
data-kind="primary"
|
||||||
|
data-orientation="horizontal"
|
||||||
|
role="separator"
|
||||||
|
/>
|
||||||
|
<h2
|
||||||
|
class="_typography_yh5dq_162 _font-heading-sm-semibold_yh5dq_102"
|
||||||
|
>
|
||||||
|
Use Element Desktop instead
|
||||||
|
</h2>
|
||||||
|
<div
|
||||||
|
class="mx_Flex"
|
||||||
|
>
|
||||||
|
<a
|
||||||
|
class="_button_i91xf_17 _has-icon_i91xf_66"
|
||||||
|
data-kind="secondary"
|
||||||
|
data-size="lg"
|
||||||
|
href="https://packages.element.io/desktop/install/macos/Element.dmg"
|
||||||
|
role="link"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
aria-hidden="true"
|
||||||
|
height="20"
|
||||||
|
width="20"
|
||||||
|
/>
|
||||||
|
Mac
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
class="_button_i91xf_17 _has-icon_i91xf_66"
|
||||||
|
data-kind="secondary"
|
||||||
|
data-size="lg"
|
||||||
|
href="https://packages.element.io/desktop/install/win32/x64/Element%20Setup.exe"
|
||||||
|
role="link"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
aria-hidden="true"
|
||||||
|
height="20"
|
||||||
|
width="20"
|
||||||
|
/>
|
||||||
|
Windows (64-bit)
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
class="_button_i91xf_17 _has-icon_i91xf_66"
|
||||||
|
data-kind="secondary"
|
||||||
|
data-size="lg"
|
||||||
|
href="https://packages.element.io/desktop/install/win32/ia32/Element%20Setup.exe"
|
||||||
|
role="link"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
aria-hidden="true"
|
||||||
|
height="20"
|
||||||
|
width="20"
|
||||||
|
/>
|
||||||
|
Windows (32-bit)
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
class="_button_i91xf_17 _has-icon_i91xf_66"
|
||||||
|
data-kind="secondary"
|
||||||
|
data-size="lg"
|
||||||
|
href="https://element.io/download#linux"
|
||||||
|
role="link"
|
||||||
|
tabindex="0"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
aria-hidden="true"
|
||||||
|
height="20"
|
||||||
|
width="20"
|
||||||
|
/>
|
||||||
|
Linux
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<h2
|
||||||
|
class="_typography_yh5dq_162 _font-heading-sm-semibold_yh5dq_102"
|
||||||
|
>
|
||||||
|
Or use our mobile app
|
||||||
|
</h2>
|
||||||
|
<div
|
||||||
|
class="mx_Flex"
|
||||||
|
>
|
||||||
|
<a
|
||||||
|
href="https://apps.apple.com/app/vector/id1083446067"
|
||||||
|
rel="noreferrer noopener"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
alt="Apple App Store"
|
||||||
|
height="64"
|
||||||
|
src="themes/element/img/download/apple.svg"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
href="https://play.google.com/store/apps/details?id=im.vector.app"
|
||||||
|
rel="noreferrer noopener"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
alt="Google Play Store"
|
||||||
|
height="64"
|
||||||
|
src="themes/element/img/download/google.svg"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
href="https://f-droid.org/repository/browse/?fdid=im.vector.app"
|
||||||
|
rel="noreferrer noopener"
|
||||||
|
target="_blank"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
alt="F-Droid"
|
||||||
|
height="64"
|
||||||
|
src="themes/element/img/download/fdroid.svg"
|
||||||
|
/>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`;
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
Copyright 2024 New Vector Ltd.
|
||||||
|
|
||||||
|
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||||
|
Please see LICENSE files in the repository root for full details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { showError, showIncompatibleBrowser } from "../../../src/vector/init.tsx";
|
||||||
|
|
||||||
|
function setUpMatrixChatDiv() {
|
||||||
|
document.getElementById("matrixchat")?.remove();
|
||||||
|
const div = document.createElement("div");
|
||||||
|
div.id = "matrixchat";
|
||||||
|
document.body.appendChild(div);
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("showIncompatibleBrowser", () => {
|
||||||
|
beforeEach(setUpMatrixChatDiv);
|
||||||
|
|
||||||
|
it("should match snapshot", async () => {
|
||||||
|
await showIncompatibleBrowser(jest.fn());
|
||||||
|
expect(document.getElementById("matrixchat")).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("showError", () => {
|
||||||
|
beforeEach(setUpMatrixChatDiv);
|
||||||
|
|
||||||
|
it("should match snapshot", async () => {
|
||||||
|
await showError("Error title", ["msg1", "msg2"]);
|
||||||
|
expect(document.getElementById("matrixchat")).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
});
|
|
@ -6,7 +6,8 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only
|
||||||
Please see LICENSE files in the repository root for full details.
|
Please see LICENSE files in the repository root for full details.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { getInitialScreenAfterLogin, onNewScreen } from "../../../src/vector/routing";
|
import { getInitialScreenAfterLogin, init, onNewScreen } from "../../../src/vector/routing";
|
||||||
|
import MatrixChat from "../../../src/components/structures/MatrixChat.tsx";
|
||||||
|
|
||||||
describe("onNewScreen", () => {
|
describe("onNewScreen", () => {
|
||||||
it("should replace history if stripping via fields", () => {
|
it("should replace history if stripping via fields", () => {
|
||||||
|
@ -95,3 +96,27 @@ describe("getInitialScreenAfterLogin", () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("init", () => {
|
||||||
|
afterAll(() => {
|
||||||
|
// @ts-ignore
|
||||||
|
delete window.matrixChat;
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should call showScreen on MatrixChat on hashchange", () => {
|
||||||
|
Object.defineProperty(window, "location", {
|
||||||
|
value: {
|
||||||
|
hash: "#/room/!room:server?via=abc",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
window.matrixChat = {
|
||||||
|
showScreen: jest.fn(),
|
||||||
|
} as unknown as MatrixChat;
|
||||||
|
|
||||||
|
init();
|
||||||
|
window.dispatchEvent(new HashChangeEvent("hashchange"));
|
||||||
|
|
||||||
|
expect(window.matrixChat.showScreen).toHaveBeenCalledWith("room/!room:server", { via: "abc" });
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
Loading…
Reference in New Issue