Skip to content

Commit 96a196b

Browse files
committed
refactor: use the broadcast channel to update the currently active versions
1 parent 4d2f516 commit 96a196b

File tree

3 files changed

+35
-48
lines changed

3 files changed

+35
-48
lines changed

src/interfaces.ts

+5
Original file line numberDiff line numberDiff line change
@@ -229,9 +229,14 @@ export type AppStateBroadcastMessage =
229229
| {
230230
type: AppStateBroadcastMessageType.syncVersions;
231231
payload: RunnableVersion[];
232+
}
233+
| {
234+
type: AppStateBroadcastMessageType.activeVersionsChanged;
235+
payload?: never;
232236
};
233237

234238
export enum AppStateBroadcastMessageType {
239+
activeVersionsChanged = 'activeVersionsChanged',
235240
isDownloadingAll = 'isDownloadingAll',
236241
syncVersions = 'syncVersions',
237242
}

src/renderer/components/settings-electron.tsx

+1-34
Original file line numberDiff line numberDiff line change
@@ -52,39 +52,6 @@ export const ElectronSettings = observer(
5252
this.handleStateChange = this.handleStateChange.bind(this);
5353
}
5454

55-
/**
56-
* Queries the currently active versions and update the local state.
57-
*
58-
* This currently gives a warning/error in development mode when the ElectronSettings component is unmounted
59-
* ("Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak
60-
* in your application"). This is a false positive, the warning has been removed in React 18+ (see
61-
* https://github.com/facebook/react/pull/22114).
62-
*
63-
* @TODO upgrade to React 18
64-
*/
65-
updateActiveVersions = () => {
66-
this.props.appState
67-
.getActiveVersions()
68-
.then((activeVersions) =>
69-
this.setState({ ...this.state, activeVersions }),
70-
)
71-
.catch((err) => {
72-
console.error(
73-
'Error updating the currently active Electron versions:',
74-
);
75-
console.error(err);
76-
});
77-
};
78-
79-
public componentDidMount() {
80-
this.updateActiveVersions();
81-
}
82-
83-
// Fired when other windows change their active Electron version
84-
public componentDidUpdate() {
85-
this.updateActiveVersions();
86-
}
87-
8855
public handleUpdateElectronVersions() {
8956
this.props.appState.updateElectronVersions();
9057
}
@@ -435,7 +402,7 @@ export const ElectronSettings = observer(
435402
break;
436403
}
437404

438-
if (this.state.activeVersions.has(version)) {
405+
if (appState.activeVersions.has(version)) {
439406
return (
440407
<Tooltip
441408
position="auto"

src/renderer/state.ts

+29-14
Original file line numberDiff line numberDiff line change
@@ -234,24 +234,25 @@ export class AppState {
234234

235235
private static versionLockNamePrefix = 'version:';
236236

237+
public activeVersions: Set<string> = new Set();
238+
237239
private getVersionLockName(ver: string) {
238240
return `${AppState.versionLockNamePrefix}${ver}`;
239241
}
240242

241243
/**
242-
* Retrieves all Electron versions that are currently active in some window.
244+
* Updates the Electron versions that are currently active in some window.
243245
*/
244-
public async getActiveVersions(): Promise<Set<string>> {
245-
return ((await navigator.locks.query()).held || []).reduce<Set<string>>(
246-
(acc, item) => {
247-
if (item.name?.startsWith(AppState.versionLockNamePrefix)) {
248-
acc.add(item.name.split(AppState.versionLockNamePrefix)[1]);
249-
}
246+
private async updateActiveVersions(): Promise<void> {
247+
this.activeVersions = ((await navigator.locks.query()).held || []).reduce<
248+
Set<string>
249+
>((acc, item) => {
250+
if (item.name?.startsWith(AppState.versionLockNamePrefix)) {
251+
acc.add(item.name.split(AppState.versionLockNamePrefix)[1]);
252+
}
250253

251-
return acc;
252-
},
253-
new Set(),
254-
);
254+
return acc;
255+
}, new Set());
255256
}
256257

257258
constructor(versions: RunnableVersion[]) {
@@ -262,6 +263,7 @@ export class AppState {
262263
addAcceleratorToBlock: action,
263264
addLocalVersion: action,
264265
addNewVersions: action,
266+
activeVersions: observable,
265267
channelsToShow: observable,
266268
clearConsole: action,
267269
currentElectronVersion: computed,
@@ -505,6 +507,12 @@ export class AppState {
505507
const { type, payload } = event.data;
506508

507509
switch (type) {
510+
case AppStateBroadcastMessageType.activeVersionsChanged: {
511+
this.updateActiveVersions();
512+
513+
break;
514+
}
515+
508516
case AppStateBroadcastMessageType.isDownloadingAll: {
509517
this.isDownloadingAll = payload;
510518
break;
@@ -824,9 +832,7 @@ export class AppState {
824832
public async removeVersion(ver: RunnableVersion): Promise<void> {
825833
const { version, state, source } = ver;
826834

827-
const activeVersions = await this.getActiveVersions();
828-
829-
if (activeVersions.has(ver.version)) {
835+
if (this.activeVersions.has(ver.version)) {
830836
console.log(`State: Not removing active version ${version}`);
831837
return;
832838
}
@@ -1007,6 +1013,15 @@ export class AppState {
10071013
this.getVersionLockName(version),
10081014
{ mode: 'shared' },
10091015
(lock) => {
1016+
// let other windows know we're using this version
1017+
this.broadcastChannel.postMessage({
1018+
type: AppStateBroadcastMessageType.activeVersionsChanged,
1019+
});
1020+
1021+
// the current window's state also needs an update - that's how
1022+
// the current window knows it can't remove this version
1023+
this.updateActiveVersions();
1024+
10101025
this.hasActiveLock = Boolean(lock);
10111026

10121027
/**

0 commit comments

Comments
 (0)