@@ -4,16 +4,16 @@ import { useAppSelector } from 'flashpoint-launcher-renderer-ext/hooks';
44import { getExtensionFileURL , runCommand , setExtensionEnabled } from 'flashpoint-launcher-renderer-ext/utils' ;
55import { useEffect , useState } from 'react' ;
66import { DownloadExtCommand , UninstallExtCommand } from '../commands' ;
7- import { loadExtIndexUrl , ManagerExtensionInfo } from '../extensionLoader' ;
7+ import { loadExtIndexUrl , ManagerExtensionInfo , ManagerExtensionRemoteInfo } from '../extensionLoader' ;
88
99export type ExtensionRowProps = {
10- item : ManagerExtensionInfo ;
10+ ext : ManagerExtensionInfo ;
1111 index : number ;
1212 disabled : boolean ;
1313}
1414
1515export function ExtensionSubsection ( ) {
16- const [ availableExtensions , setAvailableExtensions ] = useState < ManagerExtensionInfo [ ] > ( [ ] ) ;
16+ const [ remoteExtensions , setRemoteExtensions ] = useState < ManagerExtensionRemoteInfo [ ] > ( [ ] ) ;
1717 const installedExtensions = useAppSelector ( state => state . main . extensions ) ;
1818 console . log ( installedExtensions ) ;
1919 const disabledExtensions = useAppSelector ( state => state . preferences . disabledExtensions ) ;
@@ -22,40 +22,44 @@ export function ExtensionSubsection() {
2222 console . log ( 'loading ext' ) ;
2323 loadExtIndexUrl ( 'https://raw.githubusercontent.com/FlashpointProject/FlashpointExtensionIndex/refs/heads/main/extindex.json' )
2424 . then ( ( data ) => {
25- setAvailableExtensions ( data ) ;
25+ setRemoteExtensions ( data ) ;
2626 } ) ;
2727 } , [ ] ) ;
2828
2929 const extensionList : ManagerExtensionInfo [ ] = installedExtensions . map ( ext => {
3030 return {
3131 id : ext . id ,
32- title : ext . displayName || ext . name ,
33- description : ext . description || 'No Description' ,
34- newestVersion : ext . version ,
35- iconUrl : ext . icon ? getExtensionFileURL ( ext . id , ext . icon ) : undefined ,
36- installed : true ,
37- availableVersions : [ ] ,
32+ local : {
33+ title : ext . displayName || ext . name ,
34+ author : ext . author ,
35+ description : ext . description || 'No Description' ,
36+ installedVersion : ext . version ,
37+ iconUrl : ext . icon ? getExtensionFileURL ( ext . id , ext . icon ) : undefined ,
38+ }
3839 } satisfies ManagerExtensionInfo ;
3940 } ) ;
4041
41- for ( const ext of availableExtensions ) {
42- const existingIdx = installedExtensions . findIndex ( e => e . id === ext . id ) ;
42+ for ( const ext of remoteExtensions ) {
43+ const existingIdx = extensionList . findIndex ( e => e . id === ext . id ) ;
4344 if ( existingIdx === - 1 ) {
44- extensionList . push ( ext ) ;
45+ extensionList . push ( {
46+ id : ext . id ,
47+ remote : ext
48+ } ) ;
4549 } else {
46- extensionList [ existingIdx ] . availableVersions = ext . availableVersions ;
50+ extensionList [ existingIdx ] . remote = ext ;
4751 }
4852 }
4953
50- extensionList . sort ( ( a , b ) => a . title . localeCompare ( b . title ) ) ;
54+ extensionList . sort ( ( a , b ) => ( a . local ?. title || a . remote ?. title || '???' ) . localeCompare ( b . local ?. title || b . remote ?. title || '???' ) ) ;
5155
5256 return < div className = 'manager-page-subsection' >
5357 < div className = 'manager-page-subsection-header' > Extensions</ div >
5458 < div className = 'manager-page-subsection-list simple-scroll' >
5559 { extensionList . length > 0 ? extensionList . map ( ( ext , index ) => {
5660 return (
5761 < ExtensionRow
58- item = { ext }
62+ ext = { ext }
5963 index = { index }
6064 disabled = { ! disabledExtensions . includes ( ext . id ) } />
6165 ) ;
@@ -64,26 +68,18 @@ export function ExtensionSubsection() {
6468 </ div > ;
6569}
6670
67- export function ExtensionRow ( { item, disabled, index } : ExtensionRowProps ) {
68- const { id, title, description, installed, newestVersion, availableVersions, iconUrl, getDownloadUrl } = item ;
69- const [ selectedVersion , setSelectedVersion ] = useState ( newestVersion ) ;
71+ export function ExtensionRow ( { ext, disabled, index } : ExtensionRowProps ) {
72+ const [ userSelectedVersion , setUserSelectedVersion ] = useState < string > ( ) ;
7073 const [ busy , setBusy ] = useState ( false ) ;
71- const canInstall = getDownloadUrl !== undefined ;
7274 const enabled = ! disabled ;
7375 let rowClassName = 'manager-extension-row' ;
7476 if ( index % 2 === 0 ) { rowClassName += ' manager-extension-row--even' ; }
7577
76- const versionSelector = (
77- < Dropdown < DropdownStringRowProps >
78- text = { `Ver: ${ selectedVersion } ` }
79- rowCount = { availableVersions . length }
80- rowProps = { {
81- items : availableVersions ,
82- onSelect : ( index ) => setSelectedVersion ( availableVersions [ index ] )
83- } }
84- rowRenderer = { DropdownStringRow }
85- />
86- ) ;
78+ const selectedVersion = ( userSelectedVersion && ext . remote ?. availableVersions . includes ( userSelectedVersion ) ) ?
79+ userSelectedVersion :
80+ ( ext . local ?. installedVersion || ext . remote ?. newestVersion || '???' ) ;
81+
82+ const { title, description, iconUrl } = getExtDetails ( ext ) ;
8783
8884 return < div className = { rowClassName } >
8985 < div className = 'manager-extension-row-icon' >
@@ -93,12 +89,12 @@ export function ExtensionRow({ item, disabled, index }: ExtensionRowProps) {
9389 </ div >
9490 < div className = 'manager-extension-row-content' >
9591 < div className = 'manager-extension-row-top' >
96- < div className = 'manager-extension-row-title' > { title } - { `${ id } ` } </ div >
92+ < div className = 'manager-extension-row-title' > { title } - { `${ ext . id } ` } </ div >
9793 { ! busy && (
9894 < >
99- { installed && (
95+ { ext . local && (
10096 < CheckBox
101- onToggle = { ( ) => setExtensionEnabled ( id , ! enabled ) }
97+ onToggle = { ( ) => setExtensionEnabled ( ext . id , ! enabled ) }
10298 checked = { enabled } />
10399 ) }
104100 </ >
@@ -107,11 +103,22 @@ export function ExtensionRow({ item, disabled, index }: ExtensionRowProps) {
107103 < div className = 'manager-extension-row-inner' >
108104 < div > { description } </ div >
109105 { ! busy ? (
110- < >
111- { installed && (
106+ < div className = 'manager-extension-row-buttons' >
107+ { ext . remote && (
108+ < Dropdown < DropdownStringRowProps >
109+ text = { `Ver: ${ selectedVersion } ` }
110+ rowCount = { ext . remote . availableVersions . length }
111+ rowProps = { {
112+ items : ext . remote . availableVersions ,
113+ onSelect : ( index ) => setUserSelectedVersion ( ext . remote ! . availableVersions [ index ] )
114+ } }
115+ rowRenderer = { DropdownStringRow }
116+ />
117+ ) }
118+ { ext . local && (
112119 < SimpleButton value = { 'Remove' } onClick = { ( ) => {
113120 setBusy ( true ) ;
114- runCommand ( UninstallExtCommand , id )
121+ runCommand ( UninstallExtCommand , ext . id )
115122 . catch ( ( error ) => {
116123 const errorString = `Failed to uninstall extension: ${ error } ` ;
117124 alert ( errorString ) ;
@@ -120,24 +127,37 @@ export function ExtensionRow({ item, disabled, index }: ExtensionRowProps) {
120127 . finally ( ( ) => setBusy ( false ) ) ;
121128 } } />
122129 ) }
123- { canInstall && (
124- < >
125- < SimpleButton value = { 'Install' } onClick = { ( ) => {
126- setBusy ( true ) ;
127- runCommand ( DownloadExtCommand , getDownloadUrl ( newestVersion ) )
128- . catch ( ( error ) => {
129- const errorString = `Failed to download and install extension: ${ error } ` ;
130- alert ( errorString ) ;
131- log . error ( 'Manager' , errorString ) ;
132- } )
133- . finally ( ( ) => setBusy ( false ) ) ;
134- } } />
135- { versionSelector }
136- </ >
130+ { ext . remote !== undefined && (
131+ < SimpleButton value = { ext . local ? 'Update' : 'Install' } onClick = { ( ) => {
132+ setBusy ( true ) ;
133+ runCommand ( DownloadExtCommand , ext . id , ext . remote ! . getDownloadUrl ( selectedVersion ) )
134+ . catch ( ( error ) => {
135+ const errorString = `Failed to download and install extension: ${ error } ` ;
136+ alert ( errorString ) ;
137+ log . error ( 'Manager' , errorString ) ;
138+ } )
139+ . finally ( ( ) => setBusy ( false ) ) ;
140+ } } />
137141 ) }
138- </ >
142+ </ div >
139143 ) : < div > Busy...</ div > }
140144 </ div >
141145 </ div >
142146 </ div > ;
143147}
148+
149+ type ExtDetails = {
150+ author : string ,
151+ title : string ;
152+ description : string ;
153+ iconUrl ?: string ;
154+ }
155+
156+ function getExtDetails ( ext : ManagerExtensionInfo ) : ExtDetails {
157+ return {
158+ author : ext . remote ?. author || ext . local ?. author || '???' ,
159+ title : ext . remote ?. title || ext . local ?. title || '???' ,
160+ description : ext . remote ?. description || ext . local ?. description || '???' ,
161+ iconUrl : ext . local ?. iconUrl || ext . remote ?. iconUrl ,
162+ } ;
163+ }
0 commit comments