1- import React from 'react' ;
1+ import React , { useCallback , useState } from 'react' ;
22import { ReactEditorComponent } from '@opensumi/ide-editor/lib/browser' ;
33import { Icon , getKaitianIcon , Button , Tabs } from '@opensumi/ide-components' ;
44import { localize , replaceLocalizePlaceholder } from '@opensumi/ide-core-common' ;
@@ -7,8 +7,8 @@ import { ProgressBar } from '@opensumi/ide-core-browser/lib/components/progressb
77import { useInjectable } from '@opensumi/ide-core-browser/lib/react-hooks/injectable-hooks' ;
88
99import { VSXExtensionRaw } from '../../common/vsx-registry-types' ;
10- import * as styles from './overview.module.less' ;
1110import { InstallState , IVSXExtensionService , VSXExtension , VSXExtensionServiceToken } from '../../common' ;
11+ import styles from './overview.module.less' ;
1212
1313enum TabActiveKey {
1414 details = 'Details' ,
@@ -30,18 +30,19 @@ export const ExtensionOverview: ReactEditorComponent<
3030 VSXExtensionRaw & VSXExtension & { state : string ; extensionId : string }
3131> = ( { resource } ) => {
3232 const vsxExtensionService = useInjectable < IVSXExtensionService > ( VSXExtensionServiceToken ) ;
33- const [ loading , setLoading ] = React . useState ( true ) ;
34- const [ activateKey , setActivateKey ] = React . useState ( TabActiveKey . details ) ;
35- const [ metadata , setMetadata ] = React . useState < IExtensionMetadata > ( { } ) ;
33+ const [ loading , setLoading ] = useState ( true ) ;
34+ const [ installing , setInstalling ] = useState < boolean > ( false ) ;
35+ const [ activateKey , setActivateKey ] = useState ( TabActiveKey . details ) ;
36+ const [ metadata , setMetadata ] = useState < IExtensionMetadata > ( { } ) ;
3637
37- const onDidTabChange = React . useCallback ( ( index : number ) => {
38+ const onDidTabChange = useCallback ( ( index : number ) => {
3839 const activeKey = tabMap [ index ] ;
3940 if ( activeKey ) {
4041 setActivateKey ( activeKey ) ;
4142 }
4243 } , [ ] ) ;
4344
44- const getExtensonMetadata = React . useCallback (
45+ const getExtensionMetadata = useCallback (
4546 ( { readme, changelog } : { [ prop : string ] : string | undefined } ) =>
4647 [
4748 readme && fetch ( readme ) . then ( ( res ) => res . text ( ) ) ,
@@ -50,16 +51,30 @@ export const ExtensionOverview: ReactEditorComponent<
5051 [ ] ,
5152 ) ;
5253
53- const initExtensionMetadata = React . useCallback ( async ( ) => {
54+ const initExtensionMetadata = useCallback ( async ( ) => {
5455 const extension = await vsxExtensionService . getRemoteRawExtension ( resource . metadata ! . extensionId ) ;
5556 if ( extension ) {
56- const tasks = getExtensonMetadata ( { readme : extension . files . readme , changelog : extension . files . changelog } ) ;
57+ const tasks = getExtensionMetadata ( { readme : extension . files . readme , changelog : extension . files . changelog } ) ;
5758 const [ readme , changelog ] = await Promise . all ( tasks ) ;
5859 setMetadata ( { readme, changelog, downloadCount : extension . downloadCount } ) ;
5960 }
6061 setLoading ( false ) ;
6162 } , [ resource ] ) ;
6263
64+ const onInstallCallback = useCallback (
65+ async ( e : React . MouseEvent ) => {
66+ e . stopPropagation ( ) ;
67+ const extension = await vsxExtensionService . getLocalExtension ( resource . metadata ! . extensionId ) ;
68+ if ( extension ) {
69+ setInstalling ( true ) ;
70+ vsxExtensionService . install ( extension ) . finally ( ( ) => {
71+ setInstalling ( false ) ;
72+ } ) ;
73+ }
74+ } ,
75+ [ resource ] ,
76+ ) ;
77+
6378 React . useEffect ( ( ) => {
6479 initExtensionMetadata ( ) ;
6580 } , [ resource ] ) ;
@@ -88,7 +103,7 @@ export const ExtensionOverview: ReactEditorComponent<
88103 { resource . metadata ?. namespace . toLowerCase ( ) + '.' + resource . metadata ?. name . toLowerCase ( ) }
89104 </ span >
90105 </ div >
91- < div className = { styles . mainfest } >
106+ < div className = { styles . manifest } >
92107 < span >
93108 < a href = { resource . metadata ?. namespaceUrl } target = '_blank' rel = 'noopener noreferrer' >
94109 { resource . metadata ?. namespace }
@@ -109,7 +124,7 @@ export const ExtensionOverview: ReactEditorComponent<
109124 { resource . metadata ?. license && (
110125 < span >
111126 < a href = { resource . metadata ?. files . license } target = 'blank' >
112- Lisense
127+ License
113128 </ a >
114129 </ span >
115130 ) }
@@ -118,13 +133,16 @@ export const ExtensionOverview: ReactEditorComponent<
118133 < div className = { styles . description } >
119134 { replaceLocalizePlaceholder ( resource . metadata ?. description , resource . metadata ?. extensionId ) }
120135 </ div >
121- { resource . metadata ?. state === InstallState . NOT_INSTALLED && (
122- < div >
123- < Button size = 'small' onClick = { ( ) => { } } >
124- { localize ( 'marketplace.extension.install' ) }
136+ < div >
137+ { resource . metadata ?. state === InstallState . NOT_INSTALLED && (
138+ < Button size = 'small' onClick = { onInstallCallback } disabled = { installing } >
139+ { localize ( installing ? 'marketplace.extension.installing' : 'marketplace.extension.install' ) }
125140 </ Button >
126- </ div >
127- ) }
141+ ) }
142+ { resource . metadata ?. state === InstallState . INSTALLED && (
143+ < span > { localize ( 'marketplace.extension.installed' ) } </ span >
144+ ) }
145+ </ div >
128146 </ div >
129147 </ div >
130148 < div className = { styles . extension_overview_body } >
0 commit comments