11import axios from 'axios' ;
22import { XMLParser } from 'fast-xml-parser' ;
33import { useAppSelector } from 'flashpoint-launcher-renderer-ext/hooks' ;
4- import fs from 'fs' ;
5- import path from 'path' ;
4+ import { runCommand } from 'flashpoint-launcher-renderer-ext/utils' ;
65import { useEffect , useState } from 'react' ;
6+ import { ReadInstalledComponents } from '../commands' ;
77import { selectComponentRootUrls } from '../select' ;
88
99export function ComponentSubsection ( ) {
1010 const [ remoteInfo , setRemoteInfo ] = useState < ManagerComponentRemoteInfo [ ] > ( [ ] ) ;
11- const [ installedInfo , setInstalledInfo ] = useState < Record < string , ManagerInstalledComponentInfo > > ( { } ) ;
11+ const [ installedInfo , setInstalledInfo ] = useState < ManagerInstalledComponentInfo [ ] > ( [ ] ) ;
1212 const [ ready , setReady ] = useState ( false ) ;
13- const componentsPath = useAppSelector ( state => path . join ( state . main . config . flashpointPath , 'Components' ) ) ;
1413 const remoteComponentUrlsRaw = useAppSelector ( selectComponentRootUrls ) ;
1514
1615 useEffect ( ( ) => {
17- readInstalledComponents ( componentsPath )
16+ readInstalledComponents ( )
1817 . then ( ( data ) => {
1918 setInstalledInfo ( data ) ;
2019 setReady ( true ) ;
2120 } )
22- } , [ componentsPath ] ) ;
21+ } , [ ] ) ;
2322
2423 useEffect ( ( ) => {
2524 const repoUrls = remoteComponentUrlsRaw
@@ -33,60 +32,61 @@ export function ComponentSubsection() {
3332 } )
3433 } , [ remoteComponentUrlsRaw ] ) ;
3534
36- const componentList : Record < string , ManagerComponent > = { } ;
37- if ( ready ) {
38- for ( const key in installedInfo ) {
39- componentList [ key ] = {
40- installed : installedInfo [ key ] ,
41- canUpdate : false ,
42- updateDiff : 0 ,
43- } ;
35+ const componentList : ManagerComponent [ ] = installedInfo . map ( comp => {
36+ return {
37+ id : comp . id ,
38+ installed : comp ,
39+ canUpdate : false ,
40+ updateDiff : 0
4441 }
42+ } ) ;
43+ if ( ready ) {
4544 for ( const remote of remoteInfo ) {
46- const comp = componentList [ remote . id ] ;
47- if ( comp ) {
45+ const existingIdx = componentList . findIndex ( c => c . id === c . id ) ;
46+ if ( existingIdx === - 1 ) {
47+ componentList . push ( {
48+ id : remote . id ,
49+ remote,
50+ canUpdate : true ,
51+ updateDiff : remote . installSize
52+ } ) ;
53+ } else {
54+ const comp = componentList [ existingIdx ] ;
4855 comp . remote = remote ;
4956 const installedSize = comp . installed ? comp . installed . size : 0 ;
5057 const installedHash = comp . installed ? comp . installed . hash : '' ;
5158 if ( installedHash . toLowerCase ( ) !== remote . hash . toLowerCase ( ) ) {
5259 comp . canUpdate = true ;
5360 comp . updateDiff = installedSize - remote . installSize ;
5461 }
55- } else {
56- componentList [ remote . id ] = {
57- remote,
58- canUpdate : true ,
59- updateDiff : remote . installSize
60- }
6162 }
6263 }
6364 }
6465
66+ return < div className = 'manager-page-subsection' >
67+ < div className = 'manager-page-subsection-header' > Components</ div >
68+ < div className = 'manager-page-subsection-list simple-scroll' >
69+ { componentList . length > 0 ? componentList . map ( ( comp , index ) => {
70+ return (
71+ < ComponentRow
72+ comp = { comp }
73+ index = { index } />
74+ ) ;
75+ } ) : < div > Loading...</ div > }
76+ </ div >
77+ </ div > ;
6578}
6679
67- async function readInstalledComponents ( componentsPath : string ) : Promise < Record < string , ManagerInstalledComponentInfo > > {
68- await fs . promises . mkdir ( componentsPath , { recursive : true } ) ;
69- const files = await fs . promises . readdir ( componentsPath ) ;
70- const components : Record < string , ManagerInstalledComponentInfo > = { } ;
71- for ( const file of files ) {
72- try {
73- const filePath = path . join ( componentsPath , file ) ;
74- const content = await fs . promises . readFile ( filePath , { encoding : 'utf-8' } ) ;
75- const lines = content . split ( '\n' ) ;
76- const [ hash , size ] = lines [ 0 ] . split ( ' ' ) ;
77- if ( hash . length !== 8 ) {
78- throw 'Hash length invalid' ;
79- }
80- components [ file ] = {
81- size : parseInt ( size ) ,
82- hash,
83- fileCount : lines . length - 1
84- } ;
85- } catch ( err ) {
86- log . error ( 'Manager' , 'Failed to read component: ' + file ) ;
87- }
88- }
89- return components ;
80+ function ComponentRow ( { comp, index } : ComponentRowProps ) {
81+ return (
82+ < div className = 'manager-component-row' >
83+ { comp . id }
84+ </ div >
85+ ) ;
86+ }
87+
88+ async function readInstalledComponents ( ) : Promise < ManagerInstalledComponentInfo [ ] > {
89+ return runCommand ( ReadInstalledComponents ) ;
9090}
9191
9292async function getRemoteFromIndex ( indexUrl : string ) : Promise < ManagerComponentRemoteInfo [ ] > {
@@ -141,27 +141,7 @@ async function getRemoteFromIndex(indexUrl: string): Promise<ManagerComponentRem
141141 return components ;
142142}
143143
144- type ManagerComponent = {
145- installed ?: ManagerInstalledComponentInfo ;
146- remote ?: ManagerComponentRemoteInfo ;
147- canUpdate : boolean ;
148- updateDiff : number ;
149- }
150-
151- type ManagerInstalledComponentInfo = {
152- size : number ;
153- hash : string ;
154- fileCount : number ;
155- }
156-
157- type ManagerComponentRemoteInfo = {
158- id : string ;
159- title : string ;
160- description : string ;
161- dateModified : string ;
162- downloadSize : number ;
163- installSize : number ;
164- path : string ;
165- hash : string ;
166- downloadUrl : string ;
144+ export type ComponentRowProps = {
145+ comp : ManagerComponent ;
146+ index : number ;
167147}
0 commit comments