Skip to content

Commit a78c9a2

Browse files
authored
fix: add extension overview page download button (#308)
* fix: add extension overview page download button * fix: change extension onInstall return type
1 parent 38ae2a6 commit a78c9a2

File tree

5 files changed

+42
-26
lines changed

5 files changed

+42
-26
lines changed

packages/extension-manager/src/browser/extension-overview/index.tsx

Lines changed: 35 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from 'react';
1+
import React, { useCallback, useState } from 'react';
22
import { ReactEditorComponent } from '@opensumi/ide-editor/lib/browser';
33
import { Icon, getKaitianIcon, Button, Tabs } from '@opensumi/ide-components';
44
import { localize, replaceLocalizePlaceholder } from '@opensumi/ide-core-common';
@@ -7,8 +7,8 @@ import { ProgressBar } from '@opensumi/ide-core-browser/lib/components/progressb
77
import { useInjectable } from '@opensumi/ide-core-browser/lib/react-hooks/injectable-hooks';
88

99
import { VSXExtensionRaw } from '../../common/vsx-registry-types';
10-
import * as styles from './overview.module.less';
1110
import { InstallState, IVSXExtensionService, VSXExtension, VSXExtensionServiceToken } from '../../common';
11+
import styles from './overview.module.less';
1212

1313
enum 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}>

packages/extension-manager/src/browser/extension-overview/overview.module.less

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@
5050
}
5151
}
5252

53-
.mainfest {
53+
.manifest {
5454
margin-top: 6px;
5555
display: flex;
5656
align-items: center;

packages/extension-manager/src/browser/extension/index.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
1-
import * as React from 'react';
2-
import { useCallback, useState } from 'react';
1+
import React, { useCallback, useState } from 'react';
32
import { localize, replaceLocalizePlaceholder } from '@opensumi/ide-core-common';
43
import { Button, Icon, getKaitianIcon } from '@opensumi/ide-components';
54

65
import { InstallState, VSXExtension } from '../../common';
76

8-
import * as styles from './extension.module.less';
7+
import styles from './extension.module.less';
98

109
interface IExtensionViewProps {
1110
extension: VSXExtension;
12-
onInstall(extension: VSXExtension): Promise<string | undefined>;
11+
onInstall(extension: VSXExtension): Promise<void>;
1312
onClick(extension: VSXExtension, state: InstallState): void;
1413
installed: boolean;
1514
}

packages/extension-manager/src/browser/vsx-extension.service.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ export class VSXExtensionService implements IVSXExtensionService {
6767
}
6868
}
6969

70-
async install(extension: VSXExtension): Promise<string | undefined> {
70+
async install(extension: VSXExtension): Promise<void> {
7171
const id = extension?.namespace?.toLowerCase() + '.' + extension?.name?.toLowerCase();
7272
if (this.tasks.has(id) || !extension.downloadUrl) {
7373
return;
@@ -81,12 +81,11 @@ export class VSXExtensionService implements IVSXExtensionService {
8181
});
8282
this.tasks.set(id, task);
8383
this.updateStatusBar();
84-
task.then((res) => {
84+
return task.then((res) => {
8585
this.tasks.delete(id);
8686
this.updateStatusBar();
8787
this.extensionManagementService.postChangedExtension(false, res);
8888
});
89-
return task;
9089
}
9190

9291
private asExtensionId(extension: VSXExtension) {

packages/extension-manager/src/common/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ export const VSXExtensionServiceToken = Symbol('VSXExtensionSerivceToken');
7070

7171
export interface IVSXExtensionService {
7272
search(keyword: string): Promise<void>;
73-
install(extension: VSXExtension): Promise<string | undefined>;
73+
install(extension: VSXExtension): Promise<void>;
7474
getLocalExtension(extensionId: string): Promise<VSXExtension | undefined>;
7575
getRemoteRawExtension(extensionId: string): Promise<VSXExtensionRaw | undefined>;
7676
openExtensionEditor(extensionId: string, state: InstallState): Promise<void>;

0 commit comments

Comments
 (0)