Skip to content

Commit 58f454b

Browse files
committed
fix: visual update bug on download or delete
1 parent cd4ae8f commit 58f454b

File tree

3 files changed

+113
-127
lines changed

3 files changed

+113
-127
lines changed

src/less/components/settings-electron.less

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,11 +83,13 @@
8383
justify-content: center;
8484

8585
.bp3-button {
86-
width: 90px;
86+
min-width: 80px;
87+
max-width: 130px;
8788
}
8889

8990
.disabled-version {
90-
width: 90px;
91+
min-width: 80px;
92+
max-width: 130px;
9193
}
9294
}
9395
}

src/renderer/components/settings-electron.tsx

Lines changed: 108 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,116 @@ interface RowProps {
4141
data: {
4242
versions: RunnableVersion[];
4343
appState: AppState;
44-
renderHumanState: (item: RunnableVersion) => JSX.Element;
45-
renderAction: (ver: RunnableVersion) => JSX.Element;
4644
};
4745
}
4846

47+
// Observer component for individual rows to ensure they re-render when version state changes
48+
const ElectronVersionRow = observer(({ index, style, data }: RowProps) => {
49+
const { versions, appState } = data;
50+
const item = versions[index];
51+
52+
const renderHumanState = (item: RunnableVersion): JSX.Element => {
53+
const { state, source } = item;
54+
const isLocal = source === VersionSource.local;
55+
let icon: IconName = 'box';
56+
let humanState = isLocal ? 'Available' : 'Downloaded';
57+
58+
if (state === InstallState.downloading) {
59+
icon = 'cloud-download';
60+
humanState = 'Downloading';
61+
} else if (state === InstallState.missing) {
62+
icon = isLocal ? 'issue' : 'cloud';
63+
humanState = isLocal ? 'Not Available' : 'Not Downloaded';
64+
}
65+
66+
return (
67+
<span>
68+
<Icon icon={icon} /> {humanState}
69+
</span>
70+
);
71+
};
72+
73+
const renderAction = (ver: RunnableVersion): JSX.Element => {
74+
const { state, source, version } = ver;
75+
const isLocal = source === VersionSource.local;
76+
const buttonProps: ButtonProps = {
77+
small: true,
78+
};
79+
80+
switch (state) {
81+
case InstallState.installed:
82+
case InstallState.downloaded:
83+
buttonProps.icon = 'trash';
84+
buttonProps.onClick = () => appState.removeVersion(ver);
85+
buttonProps.text = isLocal ? 'Remove' : 'Delete';
86+
break;
87+
88+
case InstallState.installing:
89+
case InstallState.downloading:
90+
buttonProps.disabled = true;
91+
buttonProps.icon = <Spinner size={16} value={ver.downloadProgress} />;
92+
buttonProps.text = 'Downloading';
93+
buttonProps.className = 'disabled-version';
94+
break;
95+
96+
case InstallState.missing:
97+
buttonProps.disabled = false;
98+
buttonProps.loading = false;
99+
buttonProps.icon = isLocal ? 'trash' : 'cloud-download';
100+
buttonProps.text = isLocal ? 'Remove' : 'Download';
101+
buttonProps.onClick = () => {
102+
isLocal ? appState.removeVersion(ver) : appState.downloadVersion(ver);
103+
};
104+
break;
105+
}
106+
107+
if (version === appState.currentElectronVersion.version) {
108+
return (
109+
<Tooltip2
110+
position="auto"
111+
intent="primary"
112+
content={`Can't remove currently active Electron version (${version})`}
113+
>
114+
<AnchorButton
115+
className={'disabled-version'}
116+
disabled={true}
117+
text={buttonProps.text}
118+
icon={buttonProps.icon}
119+
/>
120+
</Tooltip2>
121+
);
122+
} else if (disableDownload(version)) {
123+
return (
124+
<Tooltip2
125+
position="auto"
126+
intent="primary"
127+
content={`Version is not available on your current OS`}
128+
>
129+
<AnchorButton
130+
className={'disabled-version'}
131+
disabled={true}
132+
text={buttonProps.text}
133+
icon={buttonProps.icon}
134+
/>
135+
</Tooltip2>
136+
);
137+
}
138+
139+
return <Button {...buttonProps} type={undefined} />;
140+
};
141+
142+
return (
143+
<div
144+
className={`electron-version-row ${index % 2 === 0 ? 'even' : 'odd'}`}
145+
style={style}
146+
>
147+
<div className="version-col">{item.version}</div>
148+
<div className="status-col">{renderHumanState(item)}</div>
149+
<div className="action-col">{renderAction(item)}</div>
150+
</div>
151+
);
152+
});
153+
49154
/**
50155
* Settings content to manage Electron-related preferences.
51156
*/
@@ -351,8 +456,6 @@ export const ElectronSettings = observer(
351456
const itemData = {
352457
versions,
353458
appState: this.props.appState,
354-
renderHumanState: this.renderHumanState.bind(this),
355-
renderAction: this.renderAction.bind(this),
356459
};
357460

358461
return (
@@ -373,131 +476,11 @@ export const ElectronSettings = observer(
373476
itemData={itemData}
374477
className="electron-versions-list"
375478
>
376-
{this.Row}
479+
{ElectronVersionRow}
377480
</List>
378481
)}
379482
</div>
380483
);
381484
}
382-
383-
/**
384-
* Renders a single row in the list.
385-
*/
386-
private Row = ({ index, style, data }: RowProps) => {
387-
const { versions, renderHumanState, renderAction } = data;
388-
const item = versions[index];
389-
390-
return (
391-
<div
392-
className={`electron-version-row ${index % 2 === 0 ? 'even' : 'odd'}`}
393-
style={style}
394-
>
395-
<div className="version-col">{item.version}</div>
396-
<div className="status-col">{renderHumanState(item)}</div>
397-
<div className="action-col">{renderAction(item)}</div>
398-
</div>
399-
);
400-
};
401-
402-
/**
403-
* Returns a human-readable state indicator for an Electron version.
404-
*/
405-
private renderHumanState(item: RunnableVersion): JSX.Element {
406-
const { state, source } = item;
407-
const isLocal = source === VersionSource.local;
408-
let icon: IconName = 'box';
409-
let humanState = isLocal ? 'Available' : 'Downloaded';
410-
411-
if (state === InstallState.downloading) {
412-
icon = 'cloud-download';
413-
humanState = 'Downloading';
414-
} else if (state === InstallState.missing) {
415-
// The only way for a local version to be missing
416-
// is for it to have been deleted. Mark as unavailable.
417-
icon = isLocal ? 'issue' : 'cloud';
418-
humanState = isLocal ? 'Not Available' : 'Not Downloaded';
419-
}
420-
421-
return (
422-
<span>
423-
<Icon icon={icon} /> {humanState}
424-
</span>
425-
);
426-
}
427-
428-
/**
429-
* Renders the action for a single Electron version.
430-
*/
431-
private renderAction(ver: RunnableVersion): JSX.Element {
432-
const { state, source, version } = ver;
433-
const { appState } = this.props;
434-
const isLocal = source === VersionSource.local;
435-
const buttonProps: ButtonProps = {
436-
fill: true,
437-
small: true,
438-
};
439-
440-
switch (state) {
441-
case InstallState.installed:
442-
case InstallState.downloaded:
443-
buttonProps.icon = 'trash';
444-
buttonProps.onClick = () => appState.removeVersion(ver);
445-
buttonProps.text = isLocal ? 'Remove' : 'Delete';
446-
break;
447-
448-
case InstallState.installing:
449-
case InstallState.downloading:
450-
buttonProps.disabled = true;
451-
buttonProps.icon = <Spinner size={16} value={ver.downloadProgress} />;
452-
buttonProps.text = 'Downloading';
453-
break;
454-
455-
case InstallState.missing:
456-
buttonProps.disabled = false;
457-
buttonProps.loading = false;
458-
buttonProps.icon = isLocal ? 'trash' : 'cloud-download';
459-
buttonProps.text = isLocal ? 'Remove' : 'Download';
460-
buttonProps.onClick = () => {
461-
isLocal
462-
? appState.removeVersion(ver)
463-
: appState.downloadVersion(ver);
464-
};
465-
break;
466-
}
467-
468-
if (version === appState.currentElectronVersion.version) {
469-
return (
470-
<Tooltip2
471-
position="auto"
472-
intent="primary"
473-
content={`Can't remove currently active Electron version (${version})`}
474-
>
475-
<AnchorButton
476-
className={'disabled-version'}
477-
disabled={true}
478-
text={buttonProps.text}
479-
icon={buttonProps.icon}
480-
/>
481-
</Tooltip2>
482-
);
483-
} else if (disableDownload(version)) {
484-
return (
485-
<Tooltip2
486-
position="auto"
487-
intent="primary"
488-
content={`Version is not available on your current OS`}
489-
>
490-
<AnchorButton
491-
className={'disabled-version'}
492-
disabled={true}
493-
text={buttonProps.text}
494-
icon={buttonProps.icon}
495-
/>
496-
</Tooltip2>
497-
);
498-
}
499-
500-
return <Button {...buttonProps} type={undefined} />;
501-
}
502485
},
503486
);

tests/renderer/components/__snapshots__/settings-electron-spec.tsx.snap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,7 @@ exports[`ElectronSettings component renders 1`] = `
258258
}
259259
}
260260
itemSize={40}
261+
key="3.0.0-nightly.1:installed:0|3.0.0:installed:0|2.0.3:installed:0|2.0.2:downloading:0|2.0.1:missing:0|2.0.0:installing:0|1.8.7:installed:0"
261262
width="100%"
262263
>
263264
<Component />

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy