@@ -41,11 +41,116 @@ interface RowProps {
41
41
data : {
42
42
versions : RunnableVersion [ ] ;
43
43
appState : AppState ;
44
- renderHumanState : ( item : RunnableVersion ) => JSX . Element ;
45
- renderAction : ( ver : RunnableVersion ) => JSX . Element ;
46
44
} ;
47
45
}
48
46
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
+
49
154
/**
50
155
* Settings content to manage Electron-related preferences.
51
156
*/
@@ -351,8 +456,6 @@ export const ElectronSettings = observer(
351
456
const itemData = {
352
457
versions,
353
458
appState : this . props . appState ,
354
- renderHumanState : this . renderHumanState . bind ( this ) ,
355
- renderAction : this . renderAction . bind ( this ) ,
356
459
} ;
357
460
358
461
return (
@@ -373,131 +476,11 @@ export const ElectronSettings = observer(
373
476
itemData = { itemData }
374
477
className = "electron-versions-list"
375
478
>
376
- { this . Row }
479
+ { ElectronVersionRow }
377
480
</ List >
378
481
) }
379
482
</ div >
380
483
) ;
381
484
}
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
- }
502
485
} ,
503
486
) ;
0 commit comments