Skip to content

Commit b63bfe6

Browse files
committed
refactor: use the broadcast channel to update the currently active versions
1 parent 6e6c27e commit b63bfe6

File tree

3 files changed

+35
-48
lines changed

3 files changed

+35
-48
lines changed

src/interfaces.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,9 +236,14 @@ export type AppStateBroadcastMessage =
236236
| {
237237
type: AppStateBroadcastMessageType.syncVersions;
238238
payload: RunnableVersion[];
239+
}
240+
| {
241+
type: AppStateBroadcastMessageType.activeVersionsChanged;
242+
payload?: never;
239243
};
240244

241245
export enum AppStateBroadcastMessageType {
246+
activeVersionsChanged = 'activeVersionsChanged',
242247
isDownloadingAll = 'isDownloadingAll',
243248
syncVersions = 'syncVersions',
244249
}

src/renderer/components/settings-electron.tsx

Lines changed: 1 addition & 34 deletions
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

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -233,24 +233,25 @@ export class AppState {
233233

234234
private static versionLockNamePrefix = 'version:';
235235

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

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

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

256257
constructor(versions: RunnableVersion[]) {
@@ -261,6 +262,7 @@ export class AppState {
261262
addAcceleratorToBlock: action,
262263
addLocalVersion: action,
263264
addNewVersions: action,
265+
activeVersions: observable,
264266
channelsToShow: observable,
265267
clearConsole: action,
266268
currentElectronVersion: computed,
@@ -504,6 +506,12 @@ export class AppState {
504506
const { type, payload } = event.data;
505507

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

826-
const activeVersions = await this.getActiveVersions();
827-
828-
if (activeVersions.has(ver.version)) {
834+
if (this.activeVersions.has(ver.version)) {
829835
console.log(`State: Not removing active version ${version}`);
830836
return;
831837
}
@@ -1002,6 +1008,15 @@ export class AppState {
10021008
this.getVersionLockName(version),
10031009
{ mode: 'shared' },
10041010
(lock) => {
1011+
// let other windows know we're using this version
1012+
this.broadcastChannel.postMessage({
1013+
type: AppStateBroadcastMessageType.activeVersionsChanged,
1014+
});
1015+
1016+
// the current window's state also needs an update - that's how
1017+
// the current window knows it can't remove this version
1018+
this.updateActiveVersions();
1019+
10051020
this.hasActiveLock = Boolean(lock);
10061021

10071022
/**

0 commit comments

Comments
 (0)