Skip to content

Commit 216d85b

Browse files
authored
Merge branch 'develop' into t3chguy/downstream-test-modules
2 parents ab009a0 + 501c819 commit 216d85b

File tree

108 files changed

+891
-958
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

108 files changed

+891
-958
lines changed

.github/workflows/triage-labelled.yml

+4-4
Original file line numberDiff line numberDiff line change
@@ -150,15 +150,15 @@ jobs:
150150
project-url: https://github.com/orgs/element-hq/projects/41
151151
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
152152

153-
verticals_feature:
154-
name: Add labelled issues to Verticals Feature project
153+
crypto:
154+
name: Add labelled issues to Crypto project
155155
runs-on: ubuntu-24.04
156156
if: >
157-
contains(github.event.issue.labels.*.name, 'Team: Verticals Feature')
157+
contains(github.event.issue.labels.*.name, 'Team: Crypto')
158158
steps:
159159
- uses: actions/add-to-project@main
160160
with:
161-
project-url: https://github.com/orgs/element-hq/projects/57
161+
project-url: https://github.com/orgs/element-hq/projects/76
162162
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
163163

164164
tech_debt:

package.json

+4-4
Original file line numberDiff line numberDiff line change
@@ -123,9 +123,9 @@
123123
"jsrsasign": "^11.0.0",
124124
"jszip": "^3.7.0",
125125
"katex": "^0.16.0",
126-
"linkify-react": "4.2.0",
127-
"linkify-string": "4.2.0",
128-
"linkifyjs": "4.2.0",
126+
"linkify-react": "4.3.1",
127+
"linkify-string": "4.3.1",
128+
"linkifyjs": "4.3.1",
129129
"lodash": "^4.17.21",
130130
"maplibre-gl": "^5.0.0",
131131
"matrix-encrypt-attachment": "^1.0.3",
@@ -262,7 +262,7 @@
262262
"jest-raw-loader": "^1.0.1",
263263
"jsqr": "^1.4.0",
264264
"knip": "^5.36.2",
265-
"lint-staged": "^15.0.2",
265+
"lint-staged": "^16.0.0",
266266
"matrix-web-i18n": "^3.2.1",
267267
"mini-css-extract-plugin": "2.9.2",
268268
"minimist": "^1.2.6",

playwright/e2e/oidc/oidc-native.spec.ts

-1
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,6 @@ test.describe("OIDC Native", { tag: ["@no-firefox", "@no-webkit"] }, () => {
8888
await expect(page.getByText("Welcome")).toBeVisible();
8989
await page.goto("about:blank");
9090

91-
// @ts-expect-error
9291
const result = await mas.manage("kill-sessions", userId);
9392
expect(result.output).toContain("Ended 1 active OAuth 2.0 session");
9493

playwright/e2e/release-announcement/releaseAnnouncement.spec.ts

+27-13
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,34 @@ test.describe("Release announcement", () => {
1515
feature_release_announcement: true,
1616
},
1717
},
18-
labsFlags: ["threadsActivityCentre"],
18+
room: async ({ app, user }, use) => {
19+
const roomId = await app.client.createRoom({
20+
name: "Test room",
21+
});
22+
await app.viewRoomById(roomId);
23+
await use({ roomId });
24+
},
1925
});
2026

21-
test("should display the release announcement process", { tag: "@screenshot" }, async ({ page, app, util }) => {
22-
// The TAC release announcement should be displayed
23-
await util.assertReleaseAnnouncementIsVisible("Threads Activity Centre");
24-
// Hide the release announcement
25-
await util.markReleaseAnnouncementAsRead("Threads Activity Centre");
26-
await util.assertReleaseAnnouncementIsNotVisible("Threads Activity Centre");
27+
test(
28+
"should display the pinned messages release announcement",
29+
{ tag: "@screenshot" },
30+
async ({ page, app, room, util }) => {
31+
await app.toggleRoomInfoPanel();
2732

28-
await page.reload();
29-
// Wait for EW to load
30-
await expect(page.getByRole("navigation", { name: "Spaces" })).toBeVisible();
31-
// Check that once the release announcement has been marked as viewed, it does not appear again
32-
await util.assertReleaseAnnouncementIsNotVisible("Threads Activity Centre");
33-
});
33+
const name = "All new pinned messages";
34+
35+
// The release announcement should be displayed
36+
await util.assertReleaseAnnouncementIsVisible(name);
37+
// Hide the release announcement
38+
await util.markReleaseAnnouncementAsRead(name);
39+
await util.assertReleaseAnnouncementIsNotVisible(name);
40+
41+
await page.reload();
42+
await app.toggleRoomInfoPanel();
43+
await expect(page.getByRole("menuitem", { name: "Pinned messages" })).toBeVisible();
44+
// Check that once the release announcement has been marked as viewed, it does not appear again
45+
await util.assertReleaseAnnouncementIsNotVisible(name);
46+
},
47+
);
3448
});

playwright/e2e/spaces/threads-activity-centre/threadsActivityCentre.spec.ts

-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ test.describe("Threads Activity Centre", { tag: "@no-firefox" }, () => {
1919
test.use({
2020
displayName: "Alice",
2121
botCreateOpts: { displayName: "Other User" },
22-
labsFlags: ["threadsActivityCentre"],
2322
});
2423

2524
test(

src/@types/global.d.ts

-37
Original file line numberDiff line numberDiff line change
@@ -82,19 +82,10 @@ declare global {
8282
mxMatrixClientPeg: IMatrixClientPeg;
8383
mxReactSdkConfig: DeepReadonly<IConfigOptions>;
8484

85-
// Needed for Safari, unknown to TypeScript
86-
webkitAudioContext: typeof AudioContext;
87-
8885
// https://docs.microsoft.com/en-us/previous-versions/hh772328(v=vs.85)
8986
// we only ever check for its existence, so we can ignore its actual type
9087
MSStream?: unknown;
9188

92-
// https://github.com/microsoft/TypeScript-DOM-lib-generator/issues/1029#issuecomment-869224737
93-
// https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas
94-
OffscreenCanvas?: {
95-
new (width: number, height: number): OffscreenCanvas;
96-
};
97-
9889
mxContentMessages: ContentMessages;
9990
mxToastStore: ToastStore;
10091
mxDeviceListener: DeviceListener;
@@ -156,31 +147,10 @@ declare global {
156147
fetchWindowIcons?: boolean;
157148
}
158149

159-
interface Document {
160-
// Safari & IE11 only have this prefixed: we used prefixed versions
161-
// previously so let's continue to support them for now
162-
webkitExitFullscreen(): Promise<void>;
163-
msExitFullscreen(): Promise<void>;
164-
readonly webkitFullscreenElement: Element | null;
165-
readonly msFullscreenElement: Element | null;
166-
}
167-
168-
interface Navigator {
169-
userLanguage?: string;
170-
}
171-
172150
interface StorageEstimate {
173151
usageDetails?: { [key: string]: number };
174152
}
175153

176-
interface Element {
177-
// Safari & IE11 only have this prefixed: we used prefixed versions
178-
// previously so let's continue to support them for now
179-
webkitRequestFullScreen(options?: FullscreenOptions): Promise<void>;
180-
msRequestFullscreen(options?: FullscreenOptions): Promise<void>;
181-
// scrollIntoView(arg?: boolean | _ScrollIntoViewOptions): void;
182-
}
183-
184154
// https://github.com/microsoft/TypeScript/issues/28308#issuecomment-650802278
185155
interface AudioWorkletProcessor {
186156
readonly port: MessagePort;
@@ -239,11 +209,4 @@ declare global {
239209
var mx_rage_store: IndexedDBLogStore;
240210
}
241211

242-
// add method which is missing from the node typing
243-
declare module "url" {
244-
interface Url {
245-
format(): string;
246-
}
247-
}
248-
249212
/* eslint-enable @typescript-eslint/naming-convention */

src/BasePlatform.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ export default abstract class BasePlatform {
7272
protected _favicon?: Favicon;
7373

7474
protected constructor() {
75-
dis.register(this.onAction);
75+
dis.register(this.onAction.bind(this));
7676
this.startUpdateCheck = this.startUpdateCheck.bind(this);
7777
}
7878

@@ -85,14 +85,14 @@ export default abstract class BasePlatform {
8585
*/
8686
public abstract getDefaultDeviceDisplayName(): string;
8787

88-
protected onAction = (payload: ActionPayload): void => {
88+
protected onAction(payload: ActionPayload): void {
8989
switch (payload.action) {
9090
case "on_client_not_viable":
9191
case Action.OnLoggedOut:
9292
this.setNotificationCount(0);
9393
break;
9494
}
95-
};
95+
}
9696

9797
// Used primarily for Analytics
9898
public abstract getHumanReadableName(): string;

src/DeviceListener.ts

+27-9
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ export default class DeviceListener {
132132
this.dismissedThisDeviceToast = false;
133133
this.keyBackupInfo = null;
134134
this.keyBackupFetchedAt = null;
135-
this.keyBackupStatusChecked = false;
135+
this.cachedKeyBackupStatus = undefined;
136136
this.ourDeviceIdsAtStart = null;
137137
this.displayingToastsForDeviceIds = new Set();
138138
this.client = undefined;
@@ -512,18 +512,36 @@ export default class DeviceListener {
512512
* trigger an auto-rageshake).
513513
*/
514514
private checkKeyBackupStatus = async (): Promise<void> => {
515-
if (this.keyBackupStatusChecked || !this.client) {
516-
return;
515+
if (!(await this.getKeyBackupStatus())) {
516+
dis.dispatch({ action: Action.ReportKeyBackupNotEnabled });
517517
}
518-
const activeKeyBackupVersion = await this.client.getCrypto()?.getActiveSessionBackupVersion();
519-
// if key backup is enabled, no need to check this ever again (XXX: why only when it is enabled?)
520-
this.keyBackupStatusChecked = !!activeKeyBackupVersion;
518+
};
521519

522-
if (!activeKeyBackupVersion) {
523-
dis.dispatch({ action: Action.ReportKeyBackupNotEnabled });
520+
/**
521+
* Is key backup enabled? Use a cached answer if we have one.
522+
*/
523+
private getKeyBackupStatus = async (): Promise<boolean> => {
524+
if (!this.client) {
525+
// To preserve existing behaviour, if there is no client, we
526+
// pretend key storage is on.
527+
//
528+
// Someone looking to improve this code could try throwing an error
529+
// here since we don't expect client to be undefined.
530+
return true;
531+
}
532+
533+
// If we've already cached the answer, return it.
534+
if (this.cachedKeyBackupStatus !== undefined) {
535+
return this.cachedKeyBackupStatus;
524536
}
537+
538+
// Fetch the answer and cache it
539+
const activeKeyBackupVersion = await this.client.getCrypto()?.getActiveSessionBackupVersion();
540+
this.cachedKeyBackupStatus = !!activeKeyBackupVersion;
541+
542+
return this.cachedKeyBackupStatus;
525543
};
526-
private keyBackupStatusChecked = false;
544+
private cachedKeyBackupStatus: boolean | undefined = undefined;
527545

528546
private onRecordClientInformationSettingChange: CallbackFn = (
529547
_originalSettingName,

src/Lifecycle.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -1115,7 +1115,9 @@ export async function onLoggedOut(): Promise<void> {
11151115
* @param {object} opts Options for how to clear storage.
11161116
* @returns {Promise} promise which resolves once the stores have been cleared
11171117
*/
1118-
async function clearStorage(opts?: { deleteEverything?: boolean }): Promise<void> {
1118+
export async function clearStorage(opts?: { deleteEverything?: boolean }): Promise<void> {
1119+
logger.info(`Clearing storage, deleteEverything=${opts?.deleteEverything}`);
1120+
11191121
if (window.localStorage) {
11201122
// get the currently defined device language, if set, so we can restore it later
11211123
const language = SettingsStore.getValueAt(SettingLevel.DEVICE, "language", null, true, true);

src/Modal.tsx

+2-3
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ Please see LICENSE files in the repository root for full details.
1010
import React, { StrictMode } from "react";
1111
import { createRoot, type Root } from "react-dom/client";
1212
import classNames from "classnames";
13-
import { type IDeferred, defer } from "matrix-js-sdk/src/utils";
1413
import { TypedEventEmitter } from "matrix-js-sdk/src/matrix";
1514
import { Glass, TooltipProvider } from "@vector-im/compound-web";
1615

@@ -70,7 +69,7 @@ export interface IModal<C extends ComponentType> {
7069
/** A deferred to resolve when the dialog closes, with the results as provided by
7170
* the call to {@link close} (normally from the `onFinished` callback).
7271
*/
73-
deferred?: IDeferred<OnFinishedParams<C> | []>;
72+
deferred?: PromiseWithResolvers<OnFinishedParams<C> | []>;
7473
}
7574

7675
/** The result of {@link Modal.createDialog}.
@@ -254,7 +253,7 @@ export class ModalManager extends TypedEventEmitter<ModalManagerEvent, HandlerMa
254253
}
255254

256255
private getCloseFn<C extends ComponentType>(modal: IModal<C>): [IHandle<C>["close"], IHandle<C>["finished"]] {
257-
modal.deferred = defer<OnFinishedParams<C> | []>();
256+
modal.deferred = Promise.withResolvers<OnFinishedParams<C> | []>();
258257
return [
259258
async (...args: OnFinishedParams<C>): Promise<void> => {
260259
if (modal.beforeClosePromise) {

src/SlidingSyncManager.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ import {
4949
SlidingSyncState,
5050
} from "matrix-js-sdk/src/sliding-sync";
5151
import { logger } from "matrix-js-sdk/src/logger";
52-
import { defer, sleep } from "matrix-js-sdk/src/utils";
52+
import { sleep } from "matrix-js-sdk/src/utils";
5353

5454
// how long to long poll for
5555
const SLIDING_SYNC_TIMEOUT_MS = 20 * 1000;
@@ -184,7 +184,7 @@ export class SlidingSyncManager {
184184
public slidingSync?: SlidingSync;
185185
private client?: MatrixClient;
186186

187-
private configureDefer = defer<void>();
187+
private configureDefer = Promise.withResolvers<void>();
188188

189189
public static get instance(): SlidingSyncManager {
190190
return SlidingSyncManager.internalInstance;

src/WorkerManager.ts

+2-4
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,12 @@ SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Com
66
Please see LICENSE files in the repository root for full details.
77
*/
88

9-
import { defer, type IDeferred } from "matrix-js-sdk/src/utils";
10-
119
import { type WorkerPayload } from "./workers/worker";
1210

1311
export class WorkerManager<Request extends object, Response> {
1412
private readonly worker: Worker;
1513
private seq = 0;
16-
private pendingDeferredMap = new Map<number, IDeferred<Response>>();
14+
private pendingDeferredMap = new Map<number, PromiseWithResolvers<Response>>();
1715

1816
public constructor(worker: Worker) {
1917
this.worker = worker;
@@ -30,7 +28,7 @@ export class WorkerManager<Request extends object, Response> {
3028

3129
public call(request: Request): Promise<Response> {
3230
const seq = this.seq++;
33-
const deferred = defer<Response>();
31+
const deferred = Promise.withResolvers<Response>();
3432
this.pendingDeferredMap.set(seq, deferred);
3533
this.worker.postMessage({ seq, ...request });
3634
return deferred.promise;

src/accessibility/KeyboardShortcuts.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -521,7 +521,8 @@ export const KEYBOARD_SHORTCUTS: IKeyboardShortcuts = {
521521
[KeyBindingAction.GoToHome]: {
522522
default: {
523523
ctrlKey: true,
524-
altKey: true,
524+
altKey: !IS_MAC,
525+
shiftKey: IS_MAC,
525526
key: Key.H,
526527
},
527528
displayName: _td("keyboard|go_home_view"),
@@ -586,7 +587,7 @@ export const KEYBOARD_SHORTCUTS: IKeyboardShortcuts = {
586587
default: {
587588
ctrlKey: true,
588589
shiftKey: true,
589-
key: Key.H,
590+
key: Key.J,
590591
},
591592
displayName: _td("keyboard|toggle_hidden_events"),
592593
},

0 commit comments

Comments
 (0)