1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 | import * as React from 'react';
|
18 | import { inject, injectable, postConstruct } from 'inversify';
|
19 | import { Dialog, DialogProps } from './dialogs';
|
20 | import { ReactDialog } from './dialogs/react-dialog';
|
21 | import { ApplicationServer, ApplicationInfo, ExtensionInfo } from '../common/application-protocol';
|
22 | import { Message } from './widgets/widget';
|
23 | import { FrontendApplicationConfigProvider } from './frontend-application-config-provider';
|
24 | import { DEFAULT_SUPPORTED_API_VERSION } from '@theia/application-package/lib/api';
|
25 | import { WindowService } from './window/window-service';
|
26 | import { Key, KeyCode } from './keys';
|
27 | import { nls } from '../common/nls';
|
28 |
|
29 | export const ABOUT_CONTENT_CLASS = 'theia-aboutDialog';
|
30 | export const ABOUT_EXTENSIONS_CLASS = 'theia-aboutExtensions';
|
31 |
|
32 | @injectable()
|
33 | export class AboutDialogProps extends DialogProps {
|
34 | }
|
35 |
|
36 | @injectable()
|
37 | export class AboutDialog extends ReactDialog<void> {
|
38 | protected applicationInfo: ApplicationInfo | undefined;
|
39 | protected extensionsInfos: ExtensionInfo[] = [];
|
40 | protected readonly okButton: HTMLButtonElement;
|
41 |
|
42 | @inject(ApplicationServer)
|
43 | protected readonly appServer: ApplicationServer;
|
44 |
|
45 | @inject(WindowService)
|
46 | protected readonly windowService: WindowService;
|
47 |
|
48 | constructor(
|
49 | @inject(AboutDialogProps) protected override readonly props: AboutDialogProps
|
50 | ) {
|
51 | super({
|
52 | title: FrontendApplicationConfigProvider.get().applicationName,
|
53 | });
|
54 | this.appendAcceptButton(Dialog.OK);
|
55 | }
|
56 |
|
57 | @postConstruct()
|
58 | protected async init(): Promise<void> {
|
59 | this.applicationInfo = await this.appServer.getApplicationInfo();
|
60 | this.extensionsInfos = await this.appServer.getExtensionsInfos();
|
61 | this.update();
|
62 | }
|
63 |
|
64 | protected renderHeader(): React.ReactNode {
|
65 | const applicationInfo = this.applicationInfo;
|
66 | const compatibilityUrl = 'https://eclipse-theia.github.io/vscode-theia-comparator/status.html';
|
67 |
|
68 | const detailsLabel = nls.localizeByDefault('Details');
|
69 | const versionLabel = nls.localize('theia/core/about/version', 'Version');
|
70 | const defaultApiLabel = nls.localize('theia/core/about/defaultApi', 'Default {0} API', 'VS Code');
|
71 | const compatibilityLabel = nls.localize('theia/core/about/compatibility', '{0} Compatibility', 'VS Code');
|
72 |
|
73 | return <>
|
74 | <h3>{detailsLabel}</h3>
|
75 | <div className='about-details'>
|
76 | {applicationInfo && <p>{`${versionLabel}: ${applicationInfo.version}`}</p>}
|
77 | <p>{`${defaultApiLabel}: ${DEFAULT_SUPPORTED_API_VERSION}`}</p>
|
78 | <p>
|
79 | <a
|
80 | role={'button'}
|
81 | tabIndex={0}
|
82 | onClick={() => this.doOpenExternalLink(compatibilityUrl)}
|
83 | onKeyDown={(e: React.KeyboardEvent) => this.doOpenExternalLinkEnter(e, compatibilityUrl)}>
|
84 | {compatibilityLabel}
|
85 | </a>
|
86 | </p>
|
87 | </div>
|
88 | </>;
|
89 | }
|
90 |
|
91 | protected renderExtensions(): React.ReactNode {
|
92 | const extensionsInfos = this.extensionsInfos;
|
93 | return <>
|
94 | <h3>List of extensions</h3>
|
95 | <ul className={ABOUT_EXTENSIONS_CLASS}>
|
96 | {
|
97 | extensionsInfos
|
98 | .sort((a: ExtensionInfo, b: ExtensionInfo) => a.name.toLowerCase().localeCompare(b.name.toLowerCase()))
|
99 | .map((extension: ExtensionInfo) => <li key={extension.name}>{extension.name} {extension.version}</li>)
|
100 | }
|
101 | </ul>
|
102 | </>;
|
103 | }
|
104 |
|
105 | protected render(): React.ReactNode {
|
106 | return <div className={ABOUT_CONTENT_CLASS}>
|
107 | {this.renderHeader()}
|
108 | {this.renderExtensions()}
|
109 | </div>;
|
110 | }
|
111 |
|
112 | protected override onAfterAttach(msg: Message): void {
|
113 | super.onAfterAttach(msg);
|
114 | this.update();
|
115 | }
|
116 |
|
117 | |
118 |
|
119 |
|
120 |
|
121 | protected doOpenExternalLink = (url: string) => this.windowService.openNewWindow(url, { external: true });
|
122 | protected doOpenExternalLinkEnter = (e: React.KeyboardEvent, url: string) => {
|
123 | if (this.isEnterKey(e)) {
|
124 | this.doOpenExternalLink(url);
|
125 | }
|
126 | };
|
127 |
|
128 | protected isEnterKey(e: React.KeyboardEvent): boolean {
|
129 | return Key.ENTER.keyCode === KeyCode.createKeyCode(e.nativeEvent).key?.keyCode;
|
130 | }
|
131 |
|
132 | get value(): undefined { return undefined; }
|
133 | }
|