Enable oxlint restriction ruleset (#34307)
* Remove stale max-len disablements * Remove stale camelCase & naming-convention disablements * Remove stale ban-ts-comment disablements * Remove stale no-var disablements * Remove stale no-empty-property disablements * Remove stale react rule disablements * Remove stale no-constant-condition disablements * Remove stale no-unused-vars disablements * Remove stale disablements for disabled rules * fixup camelcase * Remove dead code * Tidy code * Tweak oxlint config * Use oxlint to apply jsx/tsx extension consistently * Fix import * Fix imports * Rename affected snapshots * Update more imports * Enable restriction ruleset * Make code comply with new rules * Make code comply with react/button-has-type * Make code comply with typescript/non-nullable-type-assertion-style * Comply with node/no-process-env * Comply with unicorn/prefer-node-protocol * Comply with unicorn/import-style * Comply with unicorn/no-process-exit * Comply with no-proto * Comply with node/handle-callback-err * Comply with import/no-commonjs * Comply with node/no-path-concat * Comply with unicorn/no-length-as-slice-end * Comply with unicorn/no-document-cookie * Comply with unicorn/prefer-module * Comply with typescript/prefer-literal-enum-member * Comply with jsx-a11y/anchor-ambiguous-text * Tweak oxlint config * Fix resolves * Iterate * Iterate * Iterate * Iterate * Iterate * Iterate * Iterate
This commit is contained in:
@@ -7,7 +7,7 @@ Please see LICENSE in the repository root for full details.
|
||||
|
||||
import * as os from "node:os";
|
||||
import * as fs from "node:fs";
|
||||
import * as path from "node:path";
|
||||
import path from "node:path";
|
||||
import { type Configuration as BaseConfiguration } from "electron-builder";
|
||||
|
||||
/**
|
||||
|
||||
@@ -5,19 +5,16 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import { resolve, dirname } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
import { test, expect } from "../../element-desktop-test.js";
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
test.describe("App config options", () => {
|
||||
test.describe("Should load custom config via env", () => {
|
||||
test.slow();
|
||||
test.use({
|
||||
extraEnv: {
|
||||
ELEMENT_DESKTOP_CONFIG_JSON: resolve(__dirname, "../..", "fixtures/custom-config.json"),
|
||||
ELEMENT_DESKTOP_CONFIG_JSON: fileURLToPath(import.meta.resolve("../../fixtures/custom-config.json")),
|
||||
},
|
||||
});
|
||||
test("should launch and use configured homeserver", async ({ page }) => {
|
||||
@@ -31,7 +28,7 @@ test.describe("App config options", () => {
|
||||
test.describe("Should load custom config via argument", () => {
|
||||
test.slow();
|
||||
test.use({
|
||||
extraArgs: ["--config", resolve(__dirname, "../..", "fixtures/custom-config.json")],
|
||||
extraArgs: ["--config", fileURLToPath(import.meta.resolve("../../fixtures/custom-config.json"))],
|
||||
});
|
||||
test("should launch and use configured homeserver", async ({ page }) => {
|
||||
await page.locator("#matrixchat").waitFor();
|
||||
|
||||
@@ -8,7 +8,7 @@ Please see LICENSE files in the repository root for full details.
|
||||
|
||||
import { _electron as electron, test as base, expect as baseExpect, type ElectronApplication } from "@playwright/test";
|
||||
import fs from "node:fs/promises";
|
||||
import path, { dirname } from "node:path";
|
||||
import path from "node:path";
|
||||
import os from "node:os";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { PassThrough } from "node:stream";
|
||||
@@ -44,7 +44,7 @@ interface Fixtures {
|
||||
stderr: CapturedPassThrough;
|
||||
}
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
export const test = base.extend<Fixtures>({
|
||||
extraEnv: {},
|
||||
|
||||
@@ -11,7 +11,7 @@ Please see LICENSE in the repository root for full details.
|
||||
|
||||
import parseArgs from "minimist";
|
||||
import * as chokidar from "chokidar";
|
||||
import * as path from "node:path";
|
||||
import path from "node:path";
|
||||
import * as fs from "node:fs";
|
||||
|
||||
const argv = parseArgs(process.argv.slice(2), {});
|
||||
|
||||
@@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
|
||||
Please see LICENSE in the repository root for full details.
|
||||
*/
|
||||
|
||||
import * as path from "node:path";
|
||||
import path from "node:path";
|
||||
import { createWriteStream, promises as fs } from "node:fs";
|
||||
import * as childProcess from "node:child_process";
|
||||
import * as tar from "tar";
|
||||
|
||||
@@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import path, { dirname } from "node:path";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
import HakEnv from "./hakEnv.ts";
|
||||
@@ -28,7 +28,7 @@ const METACOMMANDS: Record<string, string[]> = {
|
||||
// Scripts valid in a hak.json 'scripts' section
|
||||
const HAKSCRIPTS = ["check", "fetch", "build"];
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
async function main(): Promise<void> {
|
||||
const prefix = path.join(__dirname, "..", "..");
|
||||
|
||||
@@ -6,11 +6,11 @@ Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { dirname } from "node:path";
|
||||
import path from "node:path";
|
||||
|
||||
import { tryPaths } from "./utils.js";
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
let asarPathPromise: Promise<string> | undefined;
|
||||
// Get the webapp resource file path, memoizes result
|
||||
|
||||
@@ -7,12 +7,12 @@ Please see LICENSE files in the repository root for full details.
|
||||
|
||||
import { expect, describe, it, beforeEach, vi } from "vitest";
|
||||
import { fs as memfs, vol } from "memfs";
|
||||
import { dirname } from "node:path";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
import { getBuildConfig } from "./build-config.js";
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
vi.mock("node:fs", () => ({ default: memfs }));
|
||||
|
||||
|
||||
@@ -5,13 +5,13 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import path, { dirname } from "node:path";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { type JsonObject } from "shared-types";
|
||||
|
||||
import { loadJsonFile } from "./utils.js";
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
let buildConfig: BuildConfig;
|
||||
|
||||
|
||||
@@ -7,13 +7,13 @@ Please see LICENSE files in the repository root for full details.
|
||||
|
||||
import { expect, describe, it, beforeEach, vi } from "vitest";
|
||||
import { fs as memfs, vol } from "memfs";
|
||||
import { dirname, resolve } from "node:path";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { dialog } from "electron";
|
||||
|
||||
import { type ConfigOptions } from "./config.js";
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
vi.mock("node:fs", () => ({ default: memfs }));
|
||||
vi.mock("node:fs/promises", () => ({ default: memfs.promises }));
|
||||
@@ -52,7 +52,7 @@ describe("loadConfig", () => {
|
||||
});
|
||||
|
||||
it("should ignore localConfigPath if does not exist", async () => {
|
||||
const config = await loadConfig(resolve(__dirname, "../custom-config.json"));
|
||||
const config = await loadConfig("/invalid-path/custom-config.json");
|
||||
expect(config.brand).toBe("Element");
|
||||
expect(config.web_base_url).toBe("https://chat.org.com");
|
||||
expect(config.default_hs_url).toBe("https://matrix.org.com");
|
||||
|
||||
@@ -23,7 +23,7 @@ import {
|
||||
desktopCapturer,
|
||||
} from "electron";
|
||||
import * as Sentry from "@sentry/electron/main";
|
||||
import path, { dirname } from "node:path";
|
||||
import path from "node:path";
|
||||
import windowStateKeeper from "electron-window-state";
|
||||
import { URL, fileURLToPath } from "node:url";
|
||||
|
||||
@@ -48,7 +48,7 @@ import { getIconPath } from "./icon.js";
|
||||
import { getArgs } from "./args.js";
|
||||
import { type ConfigOptions, loadConfig } from "./config.js";
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
const buildConfig = getBuildConfig();
|
||||
const protocolHandler = new ProtocolHandler(buildConfig.protocol);
|
||||
|
||||
@@ -7,12 +7,9 @@ Please see LICENSE files in the repository root for full details.
|
||||
|
||||
import { expect, describe, it, beforeEach, vi } from "vitest";
|
||||
import { fs as memfs, vol } from "memfs";
|
||||
import { dirname, resolve } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
import { getIconPath } from "./icon.js";
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
vi.mock("node:fs/promises", () => ({ default: memfs.promises }));
|
||||
|
||||
@@ -28,20 +25,20 @@ describe("getIconPath", () => {
|
||||
"build/icon.png": "png",
|
||||
"build/icon.ico": "ico",
|
||||
},
|
||||
resolve(__dirname, "../webapp"),
|
||||
fileURLToPath(import.meta.resolve("../webapp")),
|
||||
);
|
||||
});
|
||||
|
||||
it("should use .ico on Windows", async () => {
|
||||
vi.spyOn(process, "platform", "get").mockReturnValue("win32");
|
||||
await expect(getIconPath()).resolves.toEqual(resolve(__dirname, "../build/icon.ico"));
|
||||
await expect(getIconPath()).resolves.toEqual(fileURLToPath(import.meta.resolve("../build/icon.ico")));
|
||||
});
|
||||
it("should use .png on macOS", async () => {
|
||||
vi.spyOn(process, "platform", "get").mockReturnValue("darwin");
|
||||
await expect(getIconPath()).resolves.toEqual(resolve(__dirname, "../build/icon.png"));
|
||||
await expect(getIconPath()).resolves.toEqual(fileURLToPath(import.meta.resolve("../build/icon.png")));
|
||||
});
|
||||
it("should use .png on Linux", async () => {
|
||||
vi.spyOn(process, "platform", "get").mockReturnValue("linux");
|
||||
await expect(getIconPath()).resolves.toEqual(resolve(__dirname, "../build/icon.png"));
|
||||
await expect(getIconPath()).resolves.toEqual(fileURLToPath(import.meta.resolve("../build/icon.png")));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -7,14 +7,14 @@ Please see LICENSE files in the repository root for full details.
|
||||
|
||||
import counterpart from "counterpart";
|
||||
import { type TranslationKey as TKey } from "matrix-web-i18n";
|
||||
import { dirname } from "node:path";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
import type EN from "./i18n/strings/en_EN.json";
|
||||
import { loadJsonFile } from "./utils.js";
|
||||
import type Store from "./store.js";
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
const FALLBACK_LOCALE = "en";
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ Please see LICENSE files in the repository root for full details.
|
||||
|
||||
import webpack from "webpack";
|
||||
import * as fs from "node:fs/promises";
|
||||
import * as path from "node:path";
|
||||
import path from "node:path";
|
||||
import _ from "lodash";
|
||||
import { type Translations } from "matrix-web-i18n";
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
const EventEmitter = require("events");
|
||||
const EventEmitter = require("node:events");
|
||||
const { LngLat, NavigationControl, LngLatBounds } = require("maplibre-gl");
|
||||
|
||||
class MockMap extends EventEmitter {
|
||||
|
||||
@@ -7,12 +7,12 @@ Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import { env } from "node:process";
|
||||
import path, { dirname } from "node:path";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
import type { Config } from "jest";
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
const config: Config = {
|
||||
testEnvironment: "jest-fixed-jsdom",
|
||||
|
||||
@@ -6,14 +6,13 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import path from "path";
|
||||
import path from "node:path";
|
||||
import { readFile } from "node:fs/promises";
|
||||
import { dirname } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
import { expect, test } from "../../element-web-test";
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
test.describe("migration", { tag: "@no-webkit" }, function () {
|
||||
test.use({
|
||||
|
||||
@@ -8,7 +8,7 @@ Please see LICENSE files in the repository root for full details.
|
||||
|
||||
import { type Locator, type Page, expect } from "@playwright/test";
|
||||
import { readFile } from "node:fs/promises";
|
||||
import { basename } from "node:path";
|
||||
import path from "node:path";
|
||||
import { rejectToast, rejectToastIfExists } from "@element-hq/element-web-playwright-common";
|
||||
|
||||
import { Settings } from "./settings";
|
||||
@@ -197,15 +197,19 @@ export class ElementAppPage {
|
||||
/**
|
||||
* Drags a "file" into the specified composer and automatically uploads it.
|
||||
* @param location Should the drop target the main room or the thread.
|
||||
* @param path The path to the sample file so it can be read.
|
||||
* @param samplePath The path to the sample file so it can be read.
|
||||
* @param type The mimetype of the file.
|
||||
*/
|
||||
public async composerDragAndUploadFiles(location: "room" | "thread", path: string, type: string): Promise<void> {
|
||||
public async composerDragAndUploadFiles(
|
||||
location: "room" | "thread",
|
||||
samplePath: string,
|
||||
type: string,
|
||||
): Promise<void> {
|
||||
// Based on https://github.com/microsoft/playwright/issues/10667#issuecomment-2742123424
|
||||
// This read a file, encodes it into base64 and then sends it along to the page to be treated
|
||||
// as a DataTransfer (the mechanism for drag and dropped files).
|
||||
const buffer = await readFile(path);
|
||||
const name = basename(path);
|
||||
const buffer = await readFile(samplePath);
|
||||
const name = path.basename(samplePath);
|
||||
|
||||
const dataTransfer = await this.page.evaluateHandle(
|
||||
async ([buffer, name, type]) => {
|
||||
@@ -227,15 +231,19 @@ export class ElementAppPage {
|
||||
/**
|
||||
* Paste a "file" into the specified locator and automatically uploads it.
|
||||
* @param location Should the drop target the main room or the thread.
|
||||
* @param path The path to the sample file so it can be read.
|
||||
* @param samplePath The path to the sample file so it can be read.
|
||||
* @param type The mimetype of the file.
|
||||
*/
|
||||
public async composerDragAndPasteFile(location: "room" | "thread", path: string, type: string): Promise<void> {
|
||||
public async composerDragAndPasteFile(
|
||||
location: "room" | "thread",
|
||||
samplePath: string,
|
||||
type: string,
|
||||
): Promise<void> {
|
||||
// Based on https://github.com/microsoft/playwright/issues/10667#issuecomment-2742123424
|
||||
// This read a file, encodes it into base64 and then sends it along to the page to be treated
|
||||
// as a DataTransfer (the mechanism for drag and dropped files).
|
||||
const buffer = await readFile(path);
|
||||
const name = basename(path);
|
||||
const buffer = await readFile(samplePath);
|
||||
const name = path.basename(samplePath);
|
||||
const composer = this.getComposerField(location === "thread");
|
||||
|
||||
await composer.evaluate(
|
||||
|
||||
@@ -7,18 +7,18 @@ Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import { type SynapseContainer } from "@element-hq/element-web-playwright-common/lib/testcontainers/index.js";
|
||||
import { dirname, join } from "node:path";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
import { type Fixtures } from "../../../element-web-test.ts";
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
export const consentHomeserver: Fixtures = {
|
||||
_homeserver: [
|
||||
async ({ _homeserver: container, mailpit }, use) => {
|
||||
(container as SynapseContainer)
|
||||
.withCopyDirectoriesToContainer([{ source: join(__dirname, "res"), target: "/data/res" }])
|
||||
.withCopyDirectoriesToContainer([{ source: path.join(__dirname, "res"), target: "/data/res" }])
|
||||
.withSmtpServer(mailpit)
|
||||
.withConfig({
|
||||
user_consent: {
|
||||
|
||||
@@ -6,15 +6,15 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import http from "http";
|
||||
import http from "node:http";
|
||||
import express from "express";
|
||||
import { type AddressInfo } from "net";
|
||||
import { type AddressInfo } from "node:net";
|
||||
import { type TestInfo } from "@playwright/test";
|
||||
import { randB64Bytes } from "@element-hq/element-web-playwright-common/lib/utils/rand.js";
|
||||
import { dirname } from "node:path";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
export class OAuthServer {
|
||||
private server?: http.Server;
|
||||
|
||||
@@ -19,6 +19,7 @@ export default class ExampleModule {
|
||||
}
|
||||
async load() {
|
||||
const brand = this.api.config.get("brand");
|
||||
// oxlint-disable-next-line no-alert
|
||||
alert(this.api.i18n.translate("key", { brand }));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,15 +5,15 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import { dirname, join } from "node:path";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { readFile } from "node:fs/promises";
|
||||
import { readFileSync } from "node:fs";
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
export function getSampleFilePath(file: string): string {
|
||||
return join(__dirname, file);
|
||||
return path.join(__dirname, file);
|
||||
}
|
||||
|
||||
export function readSampleFile(file: string, encoding: null): Promise<Buffer>;
|
||||
|
||||
@@ -11,6 +11,7 @@ export default class SettingsModule {
|
||||
this.api = api;
|
||||
}
|
||||
async load() {
|
||||
// oxlint-disable-next-line no-alert
|
||||
alert(this.api.settings.getValue("language"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ Please see LICENSE files in the repository root for full details.
|
||||
|
||||
// @vitest-environment happy-dom
|
||||
|
||||
import { EventEmitter } from "events";
|
||||
import { EventEmitter } from "node:events";
|
||||
import { vi, describe, it, expect, beforeEach, afterEach } from "vitest";
|
||||
import type { MatrixClient } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
// oxlint-disable-next-line no-restricted-imports
|
||||
import EventEmitter from "events";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
|
||||
|
||||
@@ -56,6 +56,7 @@ export async function startAnyRegistrationFlow(
|
||||
modal.close();
|
||||
dis.dispatch({ action: "start_registration", screenAfterLogin: options.screen_after });
|
||||
}}
|
||||
type="button"
|
||||
>
|
||||
{_t("auth|register_action")}
|
||||
</button>,
|
||||
|
||||
@@ -827,7 +827,7 @@ async function readEvents(
|
||||
const effectiveStateKey = stateKey === true ? undefined : stateKey;
|
||||
|
||||
let events: MatrixEvent[] = [];
|
||||
events = events.concat(room.currentState.getStateEvents(eventType, effectiveStateKey as string) || []);
|
||||
events = events.concat(room.currentState.getStateEvents(eventType, effectiveStateKey!) || []);
|
||||
events = events.slice(0, effectiveLimit);
|
||||
|
||||
sendResponse(event, {
|
||||
|
||||
@@ -12,7 +12,7 @@ import { vi, describe, it, expect, beforeEach } from "vitest";
|
||||
import { type SlidingSync, SlidingSyncEvent, SlidingSyncState } from "matrix-js-sdk/src/sliding-sync";
|
||||
import { ClientEvent, type MatrixClient, MatrixEvent, Room } from "matrix-js-sdk/src/matrix";
|
||||
import fetchMock from "@fetch-mock/vitest";
|
||||
import EventEmitter from "events";
|
||||
import EventEmitter from "node:events";
|
||||
import { waitFor } from "test-utils-rtl";
|
||||
import { mkStubRoom, stubClient } from "test-utils";
|
||||
|
||||
|
||||
@@ -101,7 +101,9 @@ export default class UserActivity {
|
||||
// as we fork the promise here,
|
||||
// avoid unhandled rejection warnings
|
||||
})
|
||||
.catch((err) => {});
|
||||
.catch(() => {
|
||||
// Do nothing
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -211,7 +211,7 @@ export default class ExportE2eKeysDialog extends React.Component<IProps, IState>
|
||||
value={_t("action|export")}
|
||||
disabled={disableForm}
|
||||
/>
|
||||
<button onClick={this.onCancelClick} disabled={disableForm}>
|
||||
<button onClick={this.onCancelClick} disabled={disableForm} type="button">
|
||||
{_t("action|cancel")}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -180,7 +180,7 @@ export default class ImportE2eKeysDialog extends React.Component<IProps, IState>
|
||||
value={_t("action|import")}
|
||||
disabled={!this.state.enableSubmit || disableForm}
|
||||
/>
|
||||
<button onClick={this.onCancelClick} disabled={disableForm}>
|
||||
<button onClick={this.onCancelClick} disabled={disableForm} type="button">
|
||||
{_t("action|cancel")}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -6,6 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
// oxlint-disable-next-line no-restricted-imports
|
||||
import EventEmitter from "events";
|
||||
import { SimpleObservable } from "matrix-widget-api";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
|
||||
@@ -9,6 +9,7 @@ Please see LICENSE files in the repository root for full details.
|
||||
import Recorder from "opus-recorder/dist/recorder.min.js";
|
||||
import encoderPath from "opus-recorder/dist/encoderWorker.min.js";
|
||||
import { SimpleObservable } from "matrix-widget-api";
|
||||
// oxlint-disable-next-line no-restricted-imports
|
||||
import EventEmitter from "events";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import { clamp } from "@element-hq/web-shared-components";
|
||||
|
||||
@@ -8,6 +8,7 @@ Please see LICENSE files in the repository root for full details.
|
||||
|
||||
import { EventType, type MatrixEvent } from "matrix-js-sdk/src/matrix";
|
||||
import { CallEvent, CallState, CallType, type MatrixCall } from "matrix-js-sdk/src/webrtc/call";
|
||||
// oxlint-disable-next-line no-restricted-imports
|
||||
import { EventEmitter } from "events";
|
||||
|
||||
import { LegacyCallHandlerEvent } from "../../LegacyCallHandler";
|
||||
|
||||
@@ -712,19 +712,19 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
|
||||
// Add watchers for each of the settings we just looked up
|
||||
this.settingWatchers = this.settingWatchers.concat([
|
||||
SettingsStore.watchSetting("showReadReceipts", roomId, (...[, , , value]) =>
|
||||
this.setState({ showReadReceipts: value as boolean }),
|
||||
this.setState({ showReadReceipts: value! }),
|
||||
),
|
||||
SettingsStore.watchSetting("showRedactions", roomId, (...[, , , value]) =>
|
||||
this.setState({ showRedactions: value as boolean }),
|
||||
this.setState({ showRedactions: value! }),
|
||||
),
|
||||
SettingsStore.watchSetting("showJoinLeaves", roomId, (...[, , , value]) =>
|
||||
this.setState({ showJoinLeaves: value as boolean }),
|
||||
this.setState({ showJoinLeaves: value! }),
|
||||
),
|
||||
SettingsStore.watchSetting("showAvatarChanges", roomId, (...[, , , value]) =>
|
||||
this.setState({ showAvatarChanges: value as boolean }),
|
||||
this.setState({ showAvatarChanges: value! }),
|
||||
),
|
||||
SettingsStore.watchSetting("showDisplaynameChanges", roomId, (...[, , , value]) =>
|
||||
this.setState({ showDisplaynameChanges: value as boolean }),
|
||||
this.setState({ showDisplaynameChanges: value! }),
|
||||
),
|
||||
]);
|
||||
|
||||
@@ -985,34 +985,32 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> {
|
||||
this.context.resizeNotifier.on("isResizing", this.onIsResizing);
|
||||
|
||||
this.settingWatchers = [
|
||||
SettingsStore.watchSetting("layout", null, (...[, , , value]) =>
|
||||
this.setState({ layout: value as Layout }),
|
||||
),
|
||||
SettingsStore.watchSetting("layout", null, (...[, , , value]) => this.setState({ layout: value! })),
|
||||
SettingsStore.watchSetting("lowBandwidth", null, (...[, , , value]) =>
|
||||
this.setState({ lowBandwidth: value as boolean }),
|
||||
this.setState({ lowBandwidth: value! }),
|
||||
),
|
||||
SettingsStore.watchSetting("alwaysShowTimestamps", null, (...[, , , value]) =>
|
||||
this.setState({ alwaysShowTimestamps: value as boolean }),
|
||||
this.setState({ alwaysShowTimestamps: value! }),
|
||||
),
|
||||
SettingsStore.watchSetting("showTwelveHourTimestamps", null, (...[, , , value]) =>
|
||||
this.setState({ showTwelveHourTimestamps: value as boolean }),
|
||||
this.setState({ showTwelveHourTimestamps: value! }),
|
||||
),
|
||||
SettingsStore.watchSetting(TimezoneHandler.USER_TIMEZONE_KEY, null, (...[, , , value]) =>
|
||||
this.setState({ userTimezone: value as string }),
|
||||
this.setState({ userTimezone: value! }),
|
||||
),
|
||||
SettingsStore.watchSetting("readMarkerInViewThresholdMs", null, (...[, , , value]) =>
|
||||
this.setState({ readMarkerInViewThresholdMs: value as number }),
|
||||
this.setState({ readMarkerInViewThresholdMs: value! }),
|
||||
),
|
||||
SettingsStore.watchSetting("readMarkerOutOfViewThresholdMs", null, (...[, , , value]) =>
|
||||
this.setState({ readMarkerOutOfViewThresholdMs: value as number }),
|
||||
this.setState({ readMarkerOutOfViewThresholdMs: value! }),
|
||||
),
|
||||
SettingsStore.watchSetting("showHiddenEventsInTimeline", null, (...[, , , value]) =>
|
||||
this.setState({ showHiddenEvents: value as boolean }),
|
||||
this.setState({ showHiddenEvents: value! }),
|
||||
),
|
||||
SettingsStore.watchSetting("urlPreviewsEnabled", null, this.onUrlPreviewsEnabledChange),
|
||||
SettingsStore.watchSetting("urlPreviewsEnabled_e2ee", null, this.onUrlPreviewsEnabledChange),
|
||||
SettingsStore.watchSetting("feature_dynamic_room_predecessors", null, (...[, , , value]) =>
|
||||
this.setState({ msc3946ProcessDynamicPredecessor: value as boolean }),
|
||||
this.setState({ msc3946ProcessDynamicPredecessor: value! }),
|
||||
),
|
||||
];
|
||||
|
||||
|
||||
@@ -158,7 +158,7 @@ export default class ScrollPanel extends React.Component<IProps> {
|
||||
return Promise.resolve(false);
|
||||
},
|
||||
onUnfillRequest: function (backwards: boolean, scrollToken: string) {},
|
||||
onScroll: function () {},
|
||||
onScroll: function (): void {},
|
||||
};
|
||||
|
||||
private readonly pendingFillRequests: Record<"b" | "f", boolean | null> = {
|
||||
|
||||
@@ -102,8 +102,6 @@ function TabLabel<T extends string>({ tab, isActive, showToolip, onClick }: ITab
|
||||
|
||||
const label = _t(tab.label);
|
||||
return (
|
||||
// The RovingAccessibleComponent correctly sets the tabIndex based on roving context
|
||||
// oxlint-disable-next-line jsx-a11y/interactive-supports-focus
|
||||
<RovingAccessibleButton
|
||||
className={classes}
|
||||
onClick={onClick}
|
||||
|
||||
@@ -106,7 +106,7 @@ export default class ThreadView extends React.Component<IProps, IState> {
|
||||
this.setupThreadListeners(this.state.thread);
|
||||
|
||||
this.layoutWatcherRef = SettingsStore.watchSetting("layout", null, (...[, , , value]) =>
|
||||
this.setState({ layout: value as Layout }),
|
||||
this.setState({ layout: value! }),
|
||||
);
|
||||
|
||||
if (this.state.thread) {
|
||||
|
||||
@@ -172,7 +172,9 @@ export default class ViewSource extends React.Component<IProps, IState> {
|
||||
{isEditing ? this.editSourceContent() : this.viewSourceContent()}
|
||||
{!isEditing && canEdit && (
|
||||
<div className="mx_Dialog_buttons">
|
||||
<button onClick={() => this.onEdit()}>{_t("action|edit")}</button>
|
||||
<button onClick={() => this.onEdit()} type="button">
|
||||
{_t("action|edit")}
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
</BaseDialog>
|
||||
|
||||
@@ -10,7 +10,7 @@ Please see LICENSE files in the repository root for full details.
|
||||
import { vi, describe, it, expect, beforeEach, afterEach } from "vitest";
|
||||
import React from "react";
|
||||
import { act, render, screen } from "test-utils-rtl";
|
||||
import EventEmitter from "events";
|
||||
import EventEmitter from "node:events";
|
||||
import { stubClient } from "test-utils";
|
||||
|
||||
import CompleteSecurity from "./CompleteSecurity";
|
||||
|
||||
@@ -11,7 +11,7 @@ Please see LICENSE files in the repository root for full details.
|
||||
import { vi, describe, it, expect, beforeEach } from "vitest";
|
||||
import { act, render, type RenderResult } from "test-utils-rtl";
|
||||
import React, { type ComponentProps } from "react";
|
||||
import EventEmitter from "events";
|
||||
import EventEmitter from "node:events";
|
||||
import { CryptoEvent } from "matrix-js-sdk/src/crypto-api";
|
||||
import { sleep } from "matrix-js-sdk/src/utils";
|
||||
|
||||
|
||||
@@ -64,10 +64,10 @@ export default class PasswordLogin extends React.PureComponent<IProps, IState> {
|
||||
private [LoginField.Password]: Field | null = null;
|
||||
|
||||
public static defaultProps = {
|
||||
onUsernameChanged: function () {},
|
||||
onUsernameBlur: function () {},
|
||||
onPhoneCountryChanged: function () {},
|
||||
onPhoneNumberChanged: function () {},
|
||||
onUsernameChanged: function (): void {},
|
||||
onUsernameBlur: function (): void {},
|
||||
onPhoneCountryChanged: function (): void {},
|
||||
onPhoneNumberChanged: function (): void {},
|
||||
loginIncorrect: false,
|
||||
disableSubmit: false,
|
||||
};
|
||||
|
||||
@@ -77,11 +77,13 @@ export default function AskInviteAnywayDialog({
|
||||
</div>
|
||||
|
||||
<div className="mx_Dialog_buttons">
|
||||
<button onClick={onGiveUpClicked}>{_t("action|close")}</button>
|
||||
<button onClick={onInviteNeverWarnClicked}>
|
||||
<button onClick={onGiveUpClicked} type="button">
|
||||
{_t("action|close")}
|
||||
</button>
|
||||
<button onClick={onInviteNeverWarnClicked} type="button">
|
||||
{inviteNeverWarnLabel ?? _t("invite|unable_find_profiles_invite_never_warn_label_default")}
|
||||
</button>
|
||||
<button onClick={onInviteClicked} autoFocus={true}>
|
||||
<button onClick={onInviteClicked} autoFocus={true} type="button">
|
||||
{inviteLabel ?? _t("invite|unable_find_profiles_invite_label_default")}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -97,7 +97,7 @@ const DevtoolsDialog: React.FC<IProps> = ({ roomId, threadRootId, onFinished })
|
||||
setTool([label, tool]);
|
||||
};
|
||||
return (
|
||||
<button className="mx_DevTools_button" key={label} onClick={onClick}>
|
||||
<button className="mx_DevTools_button" key={label} onClick={onClick} type="button">
|
||||
{_t(label)}
|
||||
</button>
|
||||
);
|
||||
|
||||
@@ -74,7 +74,12 @@ export default class ErrorDialog extends React.Component<IProps, IState> {
|
||||
{this.props.description || _t("error|dialog_description_default")}
|
||||
</div>
|
||||
<div className="mx_Dialog_buttons">
|
||||
<button className="mx_Dialog_primary" onClick={this.onClick} autoFocus={this.props.focus}>
|
||||
<button
|
||||
className="mx_Dialog_primary"
|
||||
onClick={this.onClick}
|
||||
autoFocus={this.props.focus}
|
||||
type="button"
|
||||
>
|
||||
{this.props.button || _t("action|ok")}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -50,7 +50,7 @@ export default class SessionRestoreErrorDialog extends React.Component<IProps> {
|
||||
const brand = SdkConfig.get().brand;
|
||||
|
||||
const clearStorageButton = (
|
||||
<button onClick={this.onClearStorageClick} className="danger">
|
||||
<button onClick={this.onClearStorageClick} className="danger" type="button">
|
||||
{_t("error|session_restore|clear_storage_button")}
|
||||
</button>
|
||||
);
|
||||
|
||||
@@ -104,7 +104,11 @@ export default class UploadConfirmDialog extends React.Component<IProps, IState>
|
||||
|
||||
let uploadAllButton: JSX.Element | undefined;
|
||||
if (this.props.currentIndex + 1 < this.props.totalFiles) {
|
||||
uploadAllButton = <button onClick={this.onUploadAllClick}>{_t("upload_file|upload_all_button")}</button>;
|
||||
uploadAllButton = (
|
||||
<button onClick={this.onUploadAllClick} type="button">
|
||||
{_t("upload_file|upload_all_button")}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@@ -78,7 +78,7 @@ const BaseAccountDataExplorer: React.FC<IProps> = ({ events, Editor, actionLabel
|
||||
};
|
||||
|
||||
return (
|
||||
<button className="mx_DevTools_button" key={eventType} onClick={onClick}>
|
||||
<button className="mx_DevTools_button" key={eventType} onClick={onClick} type="button">
|
||||
{eventType}
|
||||
</button>
|
||||
);
|
||||
|
||||
@@ -61,7 +61,11 @@ const BaseTool: React.FC<XOR<IMinProps, IProps>> = ({
|
||||
});
|
||||
};
|
||||
|
||||
actionButton = <button onClick={onActionClick}>{_t(actionLabel)}</button>;
|
||||
actionButton = (
|
||||
<button onClick={onActionClick} type="button">
|
||||
{_t(actionLabel)}
|
||||
</button>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -69,7 +73,9 @@ const BaseTool: React.FC<XOR<IMinProps, IProps>> = ({
|
||||
<div className={classNames("mx_DevTools_content", className)}>{children}</div>
|
||||
<div className="mx_Dialog_buttons">
|
||||
{extraButton}
|
||||
<button onClick={onBackClick}>{_t("action|back")}</button>
|
||||
<button onClick={onBackClick} type="button">
|
||||
{_t("action|back")}
|
||||
</button>
|
||||
{actionButton}
|
||||
</div>
|
||||
</>
|
||||
|
||||
@@ -50,7 +50,7 @@ const FilteredList: React.FC<IProps> = ({ children, query, onChange }) => {
|
||||
};
|
||||
|
||||
return (
|
||||
<button className="mx_DevTools_button" onClick={showMore}>
|
||||
<button className="mx_DevTools_button" onClick={showMore} type="button">
|
||||
{_t("common|and_n_others", { count: overflowCount })}
|
||||
</button>
|
||||
);
|
||||
|
||||
@@ -100,6 +100,7 @@ const StateEventButton: React.FC<StateEventButtonProps> = ({ label, onClick }) =
|
||||
mx_DevTools_RoomStateExplorer_button_emptyString: !trimmed,
|
||||
})}
|
||||
onClick={onClick}
|
||||
type="button"
|
||||
>
|
||||
{content}
|
||||
</button>
|
||||
@@ -148,7 +149,11 @@ const RoomStateExplorerEventType: React.FC<IEventTypeProps> = ({ eventType, onBa
|
||||
const onHistoryClick = (): void => {
|
||||
setHistory(true);
|
||||
};
|
||||
const extraButton = <button onClick={onHistoryClick}>{_t("devtools|see_history")}</button>;
|
||||
const extraButton = (
|
||||
<button onClick={onHistoryClick} type="button">
|
||||
{_t("devtools|see_history")}
|
||||
</button>
|
||||
);
|
||||
return <EventViewer mxEvent={event} onBack={_onBack} Editor={StateEventEditor} extraButton={extraButton} />;
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +56,11 @@ export const StickyStateExplorer: React.FC<IDevtoolsProps> = ({ onBack, setTool
|
||||
<Alert
|
||||
type="critical"
|
||||
title={_t("common|error")}
|
||||
actions={<button onClick={onBack}>{_t("action|back")}</button>}
|
||||
actions={
|
||||
<button onClick={onBack} type="button">
|
||||
{_t("action|back")}
|
||||
</button>
|
||||
}
|
||||
>
|
||||
{_t("devtools|sticky_events_not_supported")}
|
||||
</Alert>
|
||||
@@ -107,7 +111,12 @@ export const StickyStateExplorer: React.FC<IDevtoolsProps> = ({ onBack, setTool
|
||||
<BaseTool onBack={onBack} actionLabel={_td("devtools|send_custom_sticky_event")} onAction={onAction}>
|
||||
<p>
|
||||
{uniqueEventTypes.map((eventType) => (
|
||||
<button key={eventType} className="mx_DevTools_button" onClick={() => setEventType(eventType)}>
|
||||
<button
|
||||
key={eventType}
|
||||
className="mx_DevTools_button"
|
||||
onClick={() => setEventType(eventType)}
|
||||
type="button"
|
||||
>
|
||||
{eventType.length > 0 ? eventType : _t("devtools|empty_string")}
|
||||
</button>
|
||||
))}
|
||||
|
||||
@@ -88,7 +88,7 @@ interface UserButtonProps {
|
||||
*/
|
||||
const UserButton: React.FC<UserButtonProps> = ({ member, onClick }) => {
|
||||
return (
|
||||
<button className="mx_DevTools_button" onClick={onClick}>
|
||||
<button className="mx_DevTools_button" onClick={onClick} type="button">
|
||||
{member.userId}
|
||||
</button>
|
||||
);
|
||||
@@ -273,7 +273,7 @@ const DeviceButton: React.FC<DeviceButtonProps> = ({ crypto, device, onClick })
|
||||
null,
|
||||
);
|
||||
return (
|
||||
<button className="mx_DevTools_button" onClick={onClick}>
|
||||
<button className="mx_DevTools_button" onClick={onClick} type="button">
|
||||
{verificationIcon}
|
||||
{device.deviceId}
|
||||
</button>
|
||||
|
||||
@@ -53,7 +53,12 @@ const WidgetExplorer: React.FC<IDevtoolsProps> = ({ onBack }) => {
|
||||
<BaseTool onBack={onBack}>
|
||||
<FilteredList query={query} onChange={setQuery}>
|
||||
{widgets.map((w) => (
|
||||
<button className="mx_DevTools_button" key={w.url + w.eventId} onClick={() => setWidget(w)}>
|
||||
<button
|
||||
className="mx_DevTools_button"
|
||||
key={w.url + w.eventId}
|
||||
onClick={() => setWidget(w)}
|
||||
type="button"
|
||||
>
|
||||
{w.url}
|
||||
</button>
|
||||
))}
|
||||
|
||||
@@ -538,7 +538,7 @@ const SpotlightDialog: React.FC<IProps> = ({ initialText = "", initialFilter = n
|
||||
});
|
||||
// we intentionally ignore changes to the rovingContext for the purpose of this hook
|
||||
// we only want to reset the focus whenever the results or filters change
|
||||
// eslint-disable-next-line
|
||||
// oxlint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [results, filter]);
|
||||
|
||||
const viewRoom = (
|
||||
|
||||
@@ -238,9 +238,7 @@ export default class Dropdown extends React.Component<DropdownProps, IState> {
|
||||
highlightedOption: nextKey,
|
||||
});
|
||||
|
||||
(
|
||||
this.dropdownRootElement?.querySelector(`#${this.props.id}__${nextKey}`) as HTMLLIElement
|
||||
)?.focus();
|
||||
this.dropdownRootElement?.querySelector<HTMLLIElement>(`#${this.props.id}__${nextKey}`)?.focus();
|
||||
} else {
|
||||
this.setState({ expanded: true });
|
||||
}
|
||||
@@ -251,9 +249,7 @@ export default class Dropdown extends React.Component<DropdownProps, IState> {
|
||||
this.setState({
|
||||
highlightedOption: prevKey,
|
||||
});
|
||||
(
|
||||
this.dropdownRootElement?.querySelector(`#${this.props.id}__${prevKey}`) as HTMLLIElement
|
||||
)?.focus();
|
||||
this.dropdownRootElement?.querySelector<HTMLLIElement>(`#${this.props.id}__${prevKey}`)?.focus();
|
||||
} else {
|
||||
this.setState({ expanded: true });
|
||||
}
|
||||
@@ -319,7 +315,7 @@ export default class Dropdown extends React.Component<DropdownProps, IState> {
|
||||
<MenuOption
|
||||
id={`${this.props.id}__${child.key}`}
|
||||
key={child.key}
|
||||
dropdownKey={child.key as string}
|
||||
dropdownKey={child.key!}
|
||||
highlighted={highlighted}
|
||||
onMouseEnter={this.setHighlightedOption}
|
||||
onClick={this.onMenuOptionClick}
|
||||
|
||||
@@ -42,6 +42,7 @@ export default class Spoiler extends React.Component<IProps, IState> {
|
||||
<button
|
||||
className={"mx_EventTile_spoiler" + (this.state.visible ? " visible" : "")}
|
||||
onClick={this.toggleVisible}
|
||||
type="button"
|
||||
>
|
||||
{reason}
|
||||
|
||||
|
||||
@@ -100,6 +100,7 @@ class Header extends React.PureComponent<IProps> {
|
||||
tabIndex={category.firstVisible ? 0 : -1} // roving
|
||||
aria-selected={category.visible}
|
||||
aria-controls={`mx_EmojiPicker_category_${category.id}`}
|
||||
type="button"
|
||||
>
|
||||
{category.emoji}
|
||||
</button>
|
||||
|
||||
@@ -55,6 +55,7 @@ class Search extends React.PureComponent<IProps> {
|
||||
onClick={() => this.props.onChange("")}
|
||||
className="mx_EmojiPicker_search_clear"
|
||||
title={_t("emoji_picker|cancel_search_label")}
|
||||
type="button"
|
||||
>
|
||||
<CloseIcon />
|
||||
</button>
|
||||
|
||||
@@ -296,7 +296,7 @@ const MESSAGE_BODY_TYPES = new Map<string, MBodyComponent>([
|
||||
// Render a body using the picked factory.
|
||||
// Falls back to the provided factory when msgtype has no specific handler.
|
||||
export function renderMBody(props: IBodyProps, fallbackFactory?: MBodyComponent): JSX.Element | null {
|
||||
const BodyType = MESSAGE_BODY_TYPES.get(props.mxEvent.getContent().msgtype as string) ?? fallbackFactory;
|
||||
const BodyType = MESSAGE_BODY_TYPES.get(props.mxEvent.getContent().msgtype!) ?? fallbackFactory;
|
||||
if (!BodyType) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -92,10 +92,10 @@ export default class TimelineCard extends React.Component<IProps, IState> {
|
||||
this.context.roomViewStore.addListener(UPDATE_EVENT, this.onRoomViewStoreUpdate);
|
||||
this.dispatcherRef = dis.register(this.onAction);
|
||||
this.readReceiptsSettingWatcher = SettingsStore.watchSetting("showReadReceipts", null, (...[, , , value]) =>
|
||||
this.setState({ showReadReceipts: value as boolean }),
|
||||
this.setState({ showReadReceipts: value! }),
|
||||
);
|
||||
this.layoutWatcherRef = SettingsStore.watchSetting("layout", null, (...[, , , value]) =>
|
||||
this.setState({ layout: value as Layout }),
|
||||
this.setState({ layout: value! }),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -195,7 +195,7 @@ const UserInfo: React.FC<IProps> = ({ user, room, onClose, phase = RightPanelPha
|
||||
let content: JSX.Element | undefined;
|
||||
switch (phase) {
|
||||
case RightPanelPhases.MemberInfo:
|
||||
content = <UserInfoBasicView room={room as Room} member={member} />;
|
||||
content = <UserInfoBasicView room={room!} member={member} />;
|
||||
break;
|
||||
case RightPanelPhases.EncryptionPanel:
|
||||
classes.push("mx_UserInfo_smallAvatar");
|
||||
|
||||
@@ -485,6 +485,7 @@ export default function RoomHeader({
|
||||
: () => sdkContext.rightPanelStore.showOrHidePhase(RightPanelPhases.RoomSummary)
|
||||
}
|
||||
className="mx_RoomHeader_infoWrapper"
|
||||
type="button"
|
||||
>
|
||||
<Box flex="1" className="mx_RoomHeader_info">
|
||||
<Text
|
||||
|
||||
@@ -23,6 +23,7 @@ exports[`RoomHeader > dm > does not show the face pile for DMs 1`] = `
|
||||
aria-label="Room info"
|
||||
class="mx_RoomHeader_infoWrapper"
|
||||
tabindex="0"
|
||||
type="button"
|
||||
>
|
||||
<div
|
||||
class="mx_RoomHeader_info _box-flex_1odfs_9"
|
||||
|
||||
@@ -232,7 +232,7 @@ export default class Notifications extends React.PureComponent<EmptyObject, ISta
|
||||
public componentDidMount(): void {
|
||||
this.settingWatchers = [
|
||||
SettingsStore.watchSetting("deviceNotificationsEnabled", null, (...[, , , , value]) => {
|
||||
this.setState({ deviceNotificationsEnabled: value as boolean });
|
||||
this.setState({ deviceNotificationsEnabled: value! });
|
||||
}),
|
||||
];
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ export default class VoiceUserSettingsTab extends React.Component<EmptyObject, I
|
||||
this.legacyCallsEnabledWatcherRef = SettingsStore.watchSetting(
|
||||
"enableLegacyCallsVoip",
|
||||
null,
|
||||
(...[, , , , value]) => this.setState({ enableLegacyCallsVoip: value as boolean }),
|
||||
(...[, , , , value]) => this.setState({ enableLegacyCallsVoip: value! }),
|
||||
);
|
||||
|
||||
const canSeeDeviceLabels = await MediaDeviceHandler.hasAnyLabeledDevices();
|
||||
|
||||
@@ -501,38 +501,20 @@ export default class LegacyCallView extends React.Component<IProps, IState> {
|
||||
// We've already checked that we have feeds so we cast away the optional when passing the feed
|
||||
return (
|
||||
<div className="mx_LegacyCallView_content" onMouseMove={this.onMouseMove}>
|
||||
<VideoFeed
|
||||
feed={primaryFeed as CallFeed}
|
||||
call={call}
|
||||
pipMode={pipMode}
|
||||
onResize={onResize}
|
||||
primary={true}
|
||||
/>
|
||||
<VideoFeed feed={primaryFeed!} call={call} pipMode={pipMode} onResize={onResize} primary={true} />
|
||||
</div>
|
||||
);
|
||||
} else if (secondaryFeed) {
|
||||
return (
|
||||
<div className="mx_LegacyCallView_content" onMouseMove={this.onMouseMove}>
|
||||
<VideoFeed
|
||||
feed={primaryFeed as CallFeed}
|
||||
call={call}
|
||||
pipMode={pipMode}
|
||||
onResize={onResize}
|
||||
primary={true}
|
||||
/>
|
||||
<VideoFeed feed={primaryFeed!} call={call} pipMode={pipMode} onResize={onResize} primary={true} />
|
||||
{secondaryFeedElement}
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
return (
|
||||
<div className="mx_LegacyCallView_content" onMouseMove={this.onMouseMove}>
|
||||
<VideoFeed
|
||||
feed={primaryFeed as CallFeed}
|
||||
call={call}
|
||||
pipMode={pipMode}
|
||||
onResize={onResize}
|
||||
primary={true}
|
||||
/>
|
||||
<VideoFeed feed={primaryFeed!} call={call} pipMode={pipMode} onResize={onResize} primary={true} />
|
||||
{sidebarShown && (
|
||||
<LegacyCallViewSidebar feeds={sidebarFeeds} call={call} pipMode={Boolean(pipMode)} />
|
||||
)}
|
||||
|
||||
@@ -9,6 +9,7 @@ Please see LICENSE files in the repository root for full details.
|
||||
import { useRef, useEffect, useState, useCallback, type DependencyList } from "react";
|
||||
import { type ListenerMap, type TypedEventEmitter } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
// oxlint-disable-next-line no-restricted-imports
|
||||
import type { EventEmitter } from "events";
|
||||
|
||||
type Handler = (...args: any[]) => void;
|
||||
|
||||
@@ -42,6 +42,7 @@ export async function setLanguage(...preferredLangs: string[]): Promise<void> {
|
||||
|
||||
await SettingsStore.setValue("language", null, SettingLevel.DEVICE, chosenLanguage);
|
||||
// Adds a lot of noise to test runs, so disable logging there.
|
||||
// oxlint-disable-next-line node/no-process-env
|
||||
if (process.env.NODE_ENV !== "test") {
|
||||
logger.log("set language to " + chosenLanguage);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
// oxlint-disable-next-line no-restricted-imports
|
||||
import { EventEmitter } from "events";
|
||||
import {
|
||||
RoomMember,
|
||||
|
||||
@@ -26,6 +26,7 @@ import {
|
||||
MatrixRTCSessionManagerEvents,
|
||||
} from "matrix-js-sdk/src/matrixrtc";
|
||||
|
||||
// oxlint-disable-next-line no-restricted-imports
|
||||
import type EventEmitter from "events";
|
||||
import type { IApp } from "../stores/WidgetStore";
|
||||
import SettingsStore from "../settings/SettingsStore";
|
||||
|
||||
@@ -201,6 +201,7 @@ export async function initSentry(sentryConfig: IConfigOptions["sentry"]): Promis
|
||||
|
||||
Sentry.init({
|
||||
dsn: sentryConfig.dsn,
|
||||
// oxlint-disable-next-line node/no-process-env
|
||||
release: process.env.VERSION,
|
||||
environment: sentryConfig.environment,
|
||||
defaultIntegrations: false,
|
||||
|
||||
@@ -5,6 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
// oxlint-disable-next-line no-restricted-imports
|
||||
import EventEmitter from "events";
|
||||
import { type MatrixEvent, RoomStateEvent, type RoomState } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
// oxlint-disable-next-line no-restricted-imports
|
||||
import { EventEmitter } from "events";
|
||||
import AwaitLock from "await-lock";
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
// oxlint-disable-next-line no-restricted-imports
|
||||
import EventEmitter from "events";
|
||||
import { type MatrixClient } from "matrix-js-sdk/src/matrix";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
import { describe, it, expect, vi } from "vitest";
|
||||
import { type EventTimeline, EventType, RoomEvent } from "matrix-js-sdk/src/matrix";
|
||||
import { EventEmitter } from "stream";
|
||||
import { EventEmitter } from "node:events";
|
||||
|
||||
import { mkEvent, mkRoom, mkRoomMember, stubClient } from "../../test/test-utils";
|
||||
import { CallStoreEvent, type CallStore } from "./CallStore";
|
||||
|
||||
@@ -6,6 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
// oxlint-disable-next-line no-restricted-imports
|
||||
import EventEmitter from "events";
|
||||
|
||||
import { type ComponentClass } from "../@types/common";
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
*/
|
||||
|
||||
import { type MatrixClient, SyncState } from "matrix-js-sdk/src/matrix";
|
||||
// oxlint-disable-next-line no-restricted-imports
|
||||
import { EventEmitter } from "events";
|
||||
|
||||
import { MatrixClientPeg } from "../MatrixClientPeg";
|
||||
|
||||
@@ -15,6 +15,7 @@ import { KnownMembership } from "matrix-js-sdk/src/types";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import { type ViewRoom as ViewRoomEvent } from "@matrix-org/analytics-events/types/typescript/ViewRoom";
|
||||
import { type JoinedRoom as JoinedRoomEvent } from "@matrix-org/analytics-events/types/typescript/JoinedRoom";
|
||||
// oxlint-disable-next-line no-restricted-imports
|
||||
import EventEmitter from "events";
|
||||
import {
|
||||
RoomViewLifecycle,
|
||||
|
||||
@@ -6,6 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
// oxlint-disable-next-line no-restricted-imports
|
||||
import EventEmitter from "events";
|
||||
import {
|
||||
type KeyBackupInfo,
|
||||
|
||||
@@ -6,6 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
// oxlint-disable-next-line no-restricted-imports
|
||||
import EventEmitter from "events";
|
||||
import { base32 } from "rfc4648";
|
||||
import { type RoomType } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
@@ -6,6 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
// oxlint-disable-next-line no-restricted-imports
|
||||
import EventEmitter from "events";
|
||||
import { logger } from "matrix-js-sdk/src/logger";
|
||||
import { type JSX } from "react";
|
||||
|
||||
@@ -6,6 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
// oxlint-disable-next-line no-restricted-imports
|
||||
import EventEmitter from "events";
|
||||
|
||||
export enum UI_EVENTS {
|
||||
|
||||
@@ -6,6 +6,7 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com
|
||||
Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
// oxlint-disable-next-line no-restricted-imports
|
||||
import EventEmitter from "events";
|
||||
import { type IWidget } from "matrix-widget-api";
|
||||
import { type MatrixEvent } from "matrix-js-sdk/src/matrix";
|
||||
|
||||
@@ -7,6 +7,7 @@ Please see LICENSE files in the repository root for full details.
|
||||
*/
|
||||
|
||||
import { type MatrixClient } from "matrix-js-sdk/src/matrix";
|
||||
// oxlint-disable-next-line no-restricted-imports
|
||||
import { EventEmitter } from "events";
|
||||
|
||||
import { type EchoContext } from "./EchoContext";
|
||||
|
||||
@@ -9,7 +9,7 @@ Please see LICENSE files in the repository root for full details.
|
||||
// @vitest-environment happy-dom
|
||||
|
||||
import { vi, describe, it, expect, beforeAll, beforeEach, afterEach } from "vitest";
|
||||
import { type EventEmitter } from "events";
|
||||
import { type EventEmitter } from "node:events";
|
||||
import {
|
||||
EventType,
|
||||
RoomMember,
|
||||
|
||||
@@ -9,10 +9,11 @@ Please see LICENSE files in the repository root for full details.
|
||||
import { describe, it, expect } from "vitest";
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
import { blobIsAnimated, mayBeAnimated } from "./Image";
|
||||
|
||||
const imagesDir = path.resolve(__dirname, "../../test/unit-tests/images");
|
||||
const imagesDir = fileURLToPath(import.meta.resolve("../../test/unit-tests/images"));
|
||||
|
||||
describe("Image", () => {
|
||||
describe("mayBeAnimated", () => {
|
||||
|
||||
@@ -15,6 +15,7 @@ Please see LICENSE files in the repository root for full details.
|
||||
* @event module:utils~ResizeNotifier#"middlePanelResizedNoisy"
|
||||
*/
|
||||
|
||||
// oxlint-disable-next-line no-restricted-imports
|
||||
import { EventEmitter } from "events";
|
||||
import { throttle } from "lodash";
|
||||
|
||||
|
||||
@@ -212,17 +212,6 @@ export class UrlPreviewFetcher {
|
||||
* Convert an MSC4095 URL preview bundle item to a UrlPreview
|
||||
*/
|
||||
public previewFromBundle(single: UnstableBundledUrlPreviewSingle): UrlPreview {
|
||||
// missing fields from the bundle because backend does provide it:
|
||||
// - siteName (can be computed)
|
||||
// - favicon
|
||||
// - media is a video or audio?
|
||||
// TODO in next PR: URL previews in encrypted chat?
|
||||
const hasImage =
|
||||
typeof single["og:image"] === "string" &&
|
||||
typeof single["og:image:type"] === "string" &&
|
||||
typeof single["og:image:width"] === "number" &&
|
||||
typeof single["og:image:height"] === "number";
|
||||
|
||||
const preview: UrlPreview = {
|
||||
link: single.matched_url,
|
||||
title: single["og:title"] ?? single.matched_url,
|
||||
@@ -232,7 +221,17 @@ export class UrlPreviewFetcher {
|
||||
ogUrl: single["og:url"],
|
||||
};
|
||||
|
||||
if (hasImage) {
|
||||
// missing fields from the bundle because backend does provide it:
|
||||
// - siteName (can be computed)
|
||||
// - favicon
|
||||
// - media is a video or audio?
|
||||
// TODO in next PR: URL previews in encrypted chat?
|
||||
if (
|
||||
typeof single["og:image"] === "string" &&
|
||||
typeof single["og:image:type"] === "string" &&
|
||||
typeof single["og:image:width"] === "number" &&
|
||||
typeof single["og:image:height"] === "number"
|
||||
) {
|
||||
const media = mediaFromMxc(single["og:image"], this.client);
|
||||
const thumb = media.getThumbnailOfSourceHttp(PREVIEW_WIDTH_PX, PREVIEW_HEIGHT_PX, "scale");
|
||||
|
||||
@@ -245,10 +244,10 @@ export class UrlPreviewFetcher {
|
||||
preview.image = {
|
||||
imageThumb: thumb,
|
||||
imageFull: media.srcHttp,
|
||||
imageType: single["og:image:type"] as string,
|
||||
mxcImageFull: single["og:image"] as string,
|
||||
width: single["og:image:width"] as number,
|
||||
height: single["og:image:height"] as number,
|
||||
imageType: single["og:image:type"],
|
||||
mxcImageFull: single["og:image"],
|
||||
width: single["og:image:width"],
|
||||
height: single["og:image:height"],
|
||||
playable: false, // TODO: do we know?
|
||||
};
|
||||
}
|
||||
|
||||
@@ -135,7 +135,7 @@ export function arrayTrimFill<T>(a: T[], len: number, seed: T[]): T[] {
|
||||
* @returns A copy of the array.
|
||||
*/
|
||||
export function arrayFastClone<T>(a: T[]): T[] {
|
||||
return a.slice(0, a.length);
|
||||
return a.slice(0);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -63,7 +63,7 @@ export async function createThumbnail(
|
||||
let context: CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D;
|
||||
try {
|
||||
canvas = new window.OffscreenCanvas(targetWidth, targetHeight);
|
||||
context = canvas.getContext("2d") as OffscreenCanvasRenderingContext2D;
|
||||
context = canvas.getContext("2d")!;
|
||||
} catch {
|
||||
// Fallback support for other browsers (Safari and Firefox for now)
|
||||
canvas = document.createElement("canvas");
|
||||
|
||||
@@ -10,7 +10,7 @@ Please see LICENSE files in the repository root for full details.
|
||||
import { vi, describe, it, expect, afterAll, beforeEach } from "vitest";
|
||||
import { getMockClientWithEventEmitter } from "test-utils/client";
|
||||
|
||||
import { type EventEmitter } from "events";
|
||||
import { type EventEmitter } from "node:events";
|
||||
import { Room, RoomMember, EventType, MatrixEvent } from "matrix-js-sdk/src/matrix";
|
||||
import { KnownMembership } from "matrix-js-sdk/src/types";
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ import { ModuleNotificationDecoration } from "../modules/components/ModuleNotifi
|
||||
import Login from "../Login.ts";
|
||||
import { startOAuthLogin } from "../utils/oauth/authorize.ts";
|
||||
|
||||
// oxlint-disable-next-line node/no-process-env
|
||||
logger.log(`Application is running in ${process.env.NODE_ENV} mode`);
|
||||
|
||||
window.matrixLogger = logger;
|
||||
|
||||
@@ -22,10 +22,10 @@ import "../../res/css/_index.pcss";
|
||||
// Require common CSS here; this will make webpack process it into bundle.css.
|
||||
// Our own CSS (which is themed) is imported via separate webpack entry points
|
||||
// in webpack.config.js
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports,import/no-commonjs,unicorn/prefer-module
|
||||
require("katex/dist/katex.css");
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports,import/no-commonjs,unicorn/prefer-module
|
||||
require("./localstorage-fix");
|
||||
|
||||
// Patch a fake window.TouchEvent for re-resizable's unguarded `instanceof TouchEvent`.
|
||||
|
||||
@@ -59,7 +59,7 @@ export const mobileApps: Record<MobileAppVariant, MobileAppMetadata> = {
|
||||
};
|
||||
|
||||
export function updateMobilePage(metadata: MobileAppMetadata, deepLinkUrl: string, server: string | undefined): void {
|
||||
const appleMeta = document.querySelector('meta[name="apple-itunes-app"]') as Element;
|
||||
const appleMeta = document.querySelector('meta[name="apple-itunes-app"]')!;
|
||||
appleMeta.setAttribute("content", `app-id=${metadata.appleAppId}`);
|
||||
|
||||
if (server) {
|
||||
|
||||
@@ -136,6 +136,7 @@ describe("WebPlatform", () => {
|
||||
});
|
||||
|
||||
describe("app version", () => {
|
||||
// oxlint-disable-next-line node/no-process-env
|
||||
const envVersion = process.env.VERSION;
|
||||
const prodVersion = "1.10.13";
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@ function getNormalizedAppVersion(version: string): string {
|
||||
}
|
||||
|
||||
export default class WebPlatform extends BasePlatform {
|
||||
// oxlint-disable-next-line node/no-process-env
|
||||
private static readonly VERSION = process.env.VERSION!; // baked in by Webpack
|
||||
private readonly registerServiceWorkerPromise: Promise<void>;
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ describe("mxSendRageshake", () => {
|
||||
});
|
||||
|
||||
it.each(["", " ", undefined, null])("Does not send a rageshake if text is '%s'", async (text) => {
|
||||
await window.mxSendRageshake(text as string);
|
||||
await window.mxSendRageshake(text!);
|
||||
expect(fetchMock).not.toHaveFetched();
|
||||
});
|
||||
|
||||
|
||||
@@ -122,7 +122,7 @@ export class ImageBodyViewModel
|
||||
this.state = initialState;
|
||||
|
||||
const imageSizeWatcherRef = SettingsStore.watchSetting("Images.size", null, (_s, _r, _l, _nvl, value) => {
|
||||
this.setImageSize(value as ImageSize);
|
||||
this.setImageSize(value!);
|
||||
});
|
||||
this.disposables.track(() => SettingsStore.unwatchSetting(imageSizeWatcherRef));
|
||||
}
|
||||
|
||||
@@ -109,7 +109,7 @@ export class VideoBodyViewModel
|
||||
this.state = initialState;
|
||||
|
||||
const imageSizeWatcherRef = SettingsStore.watchSetting("Images.size", null, (_s, _r, _l, _nvl, value) => {
|
||||
this.setImageSize(value as ImageSize);
|
||||
this.setImageSize(value!);
|
||||
});
|
||||
this.disposables.track(() => SettingsStore.unwatchSetting(imageSizeWatcherRef));
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user