Compare commits

...

1 Commits

Author SHA1 Message Date
Michael Telatynski
18c90e2a7d Small step in tidying the IPCs
Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
2025-06-11 13:21:08 +01:00
3 changed files with 21 additions and 25 deletions

View File

@@ -12,6 +12,7 @@ import "@types/modernizr";
import type { ModuleLoader } from "@element-hq/element-web-module-api"; import type { ModuleLoader } from "@element-hq/element-web-module-api";
import type { logger } from "matrix-js-sdk/src/logger"; import type { logger } from "matrix-js-sdk/src/logger";
import type { CallState } from "matrix-js-sdk/src/webrtc/call";
import type ContentMessages from "../ContentMessages"; import type ContentMessages from "../ContentMessages";
import { type IMatrixClientPeg } from "../MatrixClientPeg"; import { type IMatrixClientPeg } from "../MatrixClientPeg";
import type ToastStore from "../stores/ToastStore"; import type ToastStore from "../stores/ToastStore";
@@ -51,7 +52,6 @@ import type { RoomListStoreV3Class } from "../stores/room-list-v3/RoomListStoreV
/* eslint-disable @typescript-eslint/naming-convention */ /* eslint-disable @typescript-eslint/naming-convention */
type ElectronChannel = type ElectronChannel =
| "app_onAction"
| "before-quit" | "before-quit"
| "check_updates" | "check_updates"
| "install_update" | "install_update"
@@ -133,14 +133,18 @@ declare global {
send(channel: ElectronChannel, ...args: any[]): void; send(channel: ElectronChannel, ...args: any[]): void;
// Initialisation // Initialisation
initialise(): Promise<{ initialise(): Promise<{
version: string;
protocol: string; protocol: string;
sessionId: string; sessionId: string;
config: IConfigOptions; config: IConfigOptions;
supportedSettings: Record<string, boolean>; supportedSettings: Record<string, boolean>;
canSelfUpdate: boolean;
}>; }>;
// Settings // Settings
setSettingValue(settingName: string, value: any): Promise<void>; setSettingValue(settingName: string, value: any): Promise<void>;
getSettingValue(settingName: string): Promise<any>; getSettingValue(settingName: string): Promise<any>;
// Lifecycle
onCallState(callState: CallState): void;
} }
interface DesktopCapturerSource { interface DesktopCapturerSource {

View File

@@ -89,10 +89,7 @@ export default class ElectronPlatform extends BasePlatform {
private readonly eventIndexManager: BaseEventIndexManager = new SeshatIndexManager(); private readonly eventIndexManager: BaseEventIndexManager = new SeshatIndexManager();
private readonly initialised: Promise<void>; private readonly initialised: Promise<void>;
private readonly electron: Electron; private readonly electron: Electron;
private protocol!: string; private parameters?: Awaited<ReturnType<Electron["initialise"]>>;
private sessionId!: string;
private config!: IConfigOptions;
private supportedSettings?: Record<string, boolean>;
public constructor() { public constructor() {
super(); super();
@@ -189,21 +186,17 @@ export default class ElectronPlatform extends BasePlatform {
super.onAction(payload); super.onAction(payload);
// Whitelist payload actions, no point sending most across // Whitelist payload actions, no point sending most across
if (["call_state"].includes(payload.action)) { if (["call_state"].includes(payload.action)) {
this.electron.send("app_onAction", payload); this.electron.onCallState(payload.state);
} }
} }
private async initialise(): Promise<void> { private async initialise(): Promise<void> {
const { protocol, sessionId, config, supportedSettings } = await this.electron.initialise(); this.parameters = await this.electron.initialise();
this.protocol = protocol;
this.sessionId = sessionId;
this.config = config;
this.supportedSettings = supportedSettings;
} }
public async getConfig(): Promise<IConfigOptions | undefined> { public async getConfig(): Promise<IConfigOptions | undefined> {
await this.initialised; await this.initialised;
return this.config; return this.parameters?.config;
} }
private onBreadcrumbsUpdate = (): void => { private onBreadcrumbsUpdate = (): void => {
@@ -298,12 +291,13 @@ export default class ElectronPlatform extends BasePlatform {
} }
public async getAppVersion(): Promise<string> { public async getAppVersion(): Promise<string> {
return this.ipc.call("getAppVersion"); await this.initialised;
return this.parameters!.version;
} }
public supportsSetting(settingName?: string): boolean { public supportsSetting(settingName?: string): boolean {
if (settingName === undefined) return true; if (settingName === undefined) return true;
return this.supportedSettings?.[settingName] === true; return this.parameters?.supportedSettings[settingName] === true;
} }
public getSettingValue(settingName: string): Promise<any> { public getSettingValue(settingName: string): Promise<any> {
@@ -315,8 +309,8 @@ export default class ElectronPlatform extends BasePlatform {
} }
public async canSelfUpdate(): Promise<boolean> { public async canSelfUpdate(): Promise<boolean> {
const feedUrl = await this.ipc.call("getUpdateFeedUrl"); await this.initialised;
return Boolean(feedUrl); return this.parameters!.canSelfUpdate;
} }
public startUpdateCheck(): void { public startUpdateCheck(): void {
@@ -352,7 +346,7 @@ export default class ElectronPlatform extends BasePlatform {
} }
public async setLanguage(preferredLangs: string[]): Promise<any> { public async setLanguage(preferredLangs: string[]): Promise<any> {
return this.ipc.call("setLanguage", preferredLangs); return this.electron.setSettingValue("locale", preferredLangs);
} }
public setSpellCheckEnabled(enabled: boolean): void { public setSpellCheckEnabled(enabled: boolean): void {
@@ -397,7 +391,7 @@ export default class ElectronPlatform extends BasePlatform {
public getSSOCallbackUrl(fragmentAfterLogin?: string): URL { public getSSOCallbackUrl(fragmentAfterLogin?: string): URL {
const url = super.getSSOCallbackUrl(fragmentAfterLogin); const url = super.getSSOCallbackUrl(fragmentAfterLogin);
url.protocol = "element"; url.protocol = "element";
url.searchParams.set(SSO_ID_KEY, this.sessionId); url.searchParams.set(SSO_ID_KEY, this.parameters!.sessionId);
return url; return url;
} }
@@ -475,7 +469,7 @@ export default class ElectronPlatform extends BasePlatform {
} }
public getOidcClientState(): string { public getOidcClientState(): string {
return `:${SSO_ID_KEY}:${this.sessionId}`; return `:${SSO_ID_KEY}:${this.parameters!.sessionId}`;
} }
/** /**
@@ -483,7 +477,7 @@ export default class ElectronPlatform extends BasePlatform {
*/ */
public getOidcCallbackUrl(): URL { public getOidcCallbackUrl(): URL {
const url = super.getOidcCallbackUrl(); const url = super.getOidcCallbackUrl();
url.protocol = this.protocol; url.protocol = this.parameters!.protocol;
// Trim the double slash into a single slash to comply with https://datatracker.ietf.org/doc/html/rfc8252#section-7.1 // Trim the double slash into a single slash to comply with https://datatracker.ietf.org/doc/html/rfc8252#section-7.1
if (url.href.startsWith(`${url.protocol}//`)) { if (url.href.startsWith(`${url.protocol}//`)) {
url.href = url.href.replace("://", ":/"); url.href = url.href.replace("://", ":/");

View File

@@ -40,6 +40,7 @@ describe("ElectronPlatform", () => {
}), }),
setSettingValue: jest.fn().mockResolvedValue(undefined), setSettingValue: jest.fn().mockResolvedValue(undefined),
getSettingValue: jest.fn().mockResolvedValue(undefined), getSettingValue: jest.fn().mockResolvedValue(undefined),
onCallState: jest.fn(),
} as unknown as MockedObject<Electron>; } as unknown as MockedObject<Electron>;
const dispatchSpy = jest.spyOn(dispatcher, "dispatch"); const dispatchSpy = jest.spyOn(dispatcher, "dispatch");
@@ -399,10 +400,7 @@ describe("ElectronPlatform", () => {
true, true,
); );
const ipcMessage = mockElectron.send.mock.calls.find((call) => call[0] === "app_onAction"); const ipcMessage = mockElectron.onCallState.mock.calls[0];
expect(ipcMessage![1]).toEqual({ expect(ipcMessage![0]).toEqual("connected");
action: "call_state",
state: "connected",
});
}); });
}); });