@opensumi/ide-addons 2.21.13 → 2.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/browser/chrome-devtools.contribution.js.map +1 -1
- package/lib/browser/connection-rtt-contribution.js.map +1 -1
- package/lib/browser/connection-rtt-service.js.map +1 -1
- package/lib/browser/file-content-update-time.contribution.js +4 -4
- package/lib/browser/file-content-update-time.contribution.js.map +1 -1
- package/lib/browser/file-drop.contribution.js.map +1 -1
- package/lib/browser/file-drop.service.js.map +1 -1
- package/lib/browser/file-search.contribution.d.ts.map +1 -1
- package/lib/browser/file-search.contribution.js +15 -6
- package/lib/browser/file-search.contribution.js.map +1 -1
- package/lib/browser/index.js.map +1 -1
- package/lib/browser/language-change.contribution.js +1 -1
- package/lib/browser/language-change.contribution.js.map +1 -1
- package/lib/browser/status-bar-contribution.js.map +1 -1
- package/lib/browser/toolbar-customize/toolbar-customize.contribution.js.map +1 -1
- package/lib/browser/toolbar-customize/toolbar-customize.js +1 -1
- package/lib/browser/toolbar-customize/toolbar-customize.js.map +1 -1
- package/lib/node/connection-rtt-service.js.map +1 -1
- package/lib/node/file-drop.service.js.map +1 -1
- package/lib/node/index.js.map +1 -1
- package/package.json +17 -16
- package/src/browser/chrome-devtools.contribution.ts +66 -0
- package/src/browser/connection-rtt-contribution.ts +82 -0
- package/src/browser/connection-rtt-service.ts +15 -0
- package/src/browser/file-content-update-time.contribution.ts +256 -0
- package/src/browser/file-drop.contribution.ts +17 -0
- package/src/browser/file-drop.service.ts +165 -0
- package/src/browser/file-search.contribution.ts +612 -0
- package/src/browser/index.ts +44 -0
- package/src/browser/language-change.contribution.ts +45 -0
- package/src/browser/status-bar-contribution.ts +28 -0
- package/src/browser/toolbar-customize/style.module.less +52 -0
- package/src/browser/toolbar-customize/toolbar-customize.contribution.ts +59 -0
- package/src/browser/toolbar-customize/toolbar-customize.tsx +147 -0
- package/src/common/index.ts +46 -0
- package/src/index.ts +1 -0
- package/src/node/connection-rtt-service.ts +10 -0
- package/src/node/file-drop.service.ts +34 -0
- package/src/node/index.ts +37 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Autowired } from '@opensumi/di';
|
|
2
|
+
import { ClientAppContribution } from '@opensumi/ide-core-browser';
|
|
3
|
+
import {
|
|
4
|
+
BrowserConnectionCloseEvent,
|
|
5
|
+
BrowserConnectionOpenEvent,
|
|
6
|
+
OnEvent,
|
|
7
|
+
WithEventBus,
|
|
8
|
+
CommandService,
|
|
9
|
+
Domain,
|
|
10
|
+
} from '@opensumi/ide-core-common';
|
|
11
|
+
|
|
12
|
+
@Domain(ClientAppContribution)
|
|
13
|
+
export class StatusBarContribution extends WithEventBus implements ClientAppContribution {
|
|
14
|
+
@Autowired(CommandService)
|
|
15
|
+
private readonly commandService: CommandService;
|
|
16
|
+
|
|
17
|
+
onStart() {}
|
|
18
|
+
|
|
19
|
+
@OnEvent(BrowserConnectionOpenEvent)
|
|
20
|
+
handleBrowserConnectionOpen() {
|
|
21
|
+
this.commandService.executeCommand('statusbar.changeBackgroundColor', 'var(--statusBar-background)');
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
@OnEvent(BrowserConnectionCloseEvent)
|
|
25
|
+
handleBrowserConnectionClose() {
|
|
26
|
+
this.commandService.executeCommand('statusbar.changeBackgroundColor', 'var(--kt-statusbar-offline-background)');
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
@import '~@opensumi/ide-components/lib/style/mixins.less';
|
|
2
|
+
|
|
3
|
+
.toolbar-customize-overlay {
|
|
4
|
+
position: fixed;
|
|
5
|
+
width: 100%;
|
|
6
|
+
height: 100%;
|
|
7
|
+
left: 0;
|
|
8
|
+
top: 0;
|
|
9
|
+
z-index: 1000;
|
|
10
|
+
.toolbar-customize {
|
|
11
|
+
position: fixed;
|
|
12
|
+
width: 720px;
|
|
13
|
+
margin-left: -360px;
|
|
14
|
+
left: 50%;
|
|
15
|
+
top: 30px;
|
|
16
|
+
z-index: 1001;
|
|
17
|
+
.overlay-shadow();
|
|
18
|
+
background-color: var(--kt-modal-background);
|
|
19
|
+
color: var(--kt-modal-foreground);
|
|
20
|
+
min-height: 200px;
|
|
21
|
+
.toolbar-customize-location {
|
|
22
|
+
display: flex;
|
|
23
|
+
flex-wrap: wrap;
|
|
24
|
+
border-bottom: 1px solid var(--kt-modal-separatorBackground);
|
|
25
|
+
.action-item {
|
|
26
|
+
margin-right: 10px;
|
|
27
|
+
margin-bottom: 5px;
|
|
28
|
+
margin-top: 5px;
|
|
29
|
+
}
|
|
30
|
+
padding: 15px 20px;
|
|
31
|
+
}
|
|
32
|
+
.button-display {
|
|
33
|
+
padding: 20px;
|
|
34
|
+
display: flex;
|
|
35
|
+
justify-content: left;
|
|
36
|
+
align-items: center;
|
|
37
|
+
> div:first-child {
|
|
38
|
+
margin-right: 10px;
|
|
39
|
+
font-size: 12px;
|
|
40
|
+
}
|
|
41
|
+
.button-display-select {
|
|
42
|
+
width: 200px;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
.customize-complete {
|
|
46
|
+
display: flex;
|
|
47
|
+
justify-content: center;
|
|
48
|
+
align-items: center;
|
|
49
|
+
padding: 20px;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { Autowired } from '@opensumi/di';
|
|
2
|
+
import {
|
|
3
|
+
Domain,
|
|
4
|
+
CommandContribution,
|
|
5
|
+
CommandRegistry,
|
|
6
|
+
ComponentContribution,
|
|
7
|
+
ComponentRegistry,
|
|
8
|
+
AppConfig,
|
|
9
|
+
SlotLocation,
|
|
10
|
+
localize,
|
|
11
|
+
} from '@opensumi/ide-core-browser';
|
|
12
|
+
import { MenuContribution, IMenuRegistry, MenuId } from '@opensumi/ide-core-browser/lib/menu/next';
|
|
13
|
+
|
|
14
|
+
import { ToolbarCustomizeComponent, ToolbarCustomizeViewService } from './toolbar-customize';
|
|
15
|
+
|
|
16
|
+
@Domain(CommandContribution, ComponentContribution, MenuContribution)
|
|
17
|
+
export class ToolbarCustomizeContribution implements CommandContribution, ComponentContribution, MenuContribution {
|
|
18
|
+
@Autowired(AppConfig)
|
|
19
|
+
config: AppConfig;
|
|
20
|
+
|
|
21
|
+
@Autowired(ToolbarCustomizeViewService)
|
|
22
|
+
viewService: ToolbarCustomizeViewService;
|
|
23
|
+
|
|
24
|
+
registerCommands(registry: CommandRegistry) {
|
|
25
|
+
registry.registerCommand(
|
|
26
|
+
{
|
|
27
|
+
id: 'toolbar.showCustomizePanel',
|
|
28
|
+
label: 'Show Toolbar Customization',
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
execute: () => {
|
|
32
|
+
this.viewService.setVisible(true);
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
registerComponent(registry: ComponentRegistry) {
|
|
39
|
+
registry.register('addon/toolbar-customize', {
|
|
40
|
+
id: 'addon/toolbar-customize',
|
|
41
|
+
component: ToolbarCustomizeComponent,
|
|
42
|
+
});
|
|
43
|
+
if (!this.config.layoutConfig[SlotLocation.extra]) {
|
|
44
|
+
this.config.layoutConfig[SlotLocation.extra] = {
|
|
45
|
+
modules: [],
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
this.config.layoutConfig[SlotLocation.extra].modules.push('addon/toolbar-customize');
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
registerMenus(registry: IMenuRegistry) {
|
|
52
|
+
registry.registerMenuItem(MenuId.KTToolbarLocationContext, {
|
|
53
|
+
command: {
|
|
54
|
+
id: 'toolbar.showCustomizePanel',
|
|
55
|
+
label: localize('toolbar.customize.menu'),
|
|
56
|
+
},
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import { Injectable, Autowired } from '@opensumi/di';
|
|
4
|
+
import { CheckBox, Select, Button } from '@opensumi/ide-components';
|
|
5
|
+
import {
|
|
6
|
+
useInjectable,
|
|
7
|
+
PreferenceService,
|
|
8
|
+
PreferenceScope,
|
|
9
|
+
IToolbarRegistry,
|
|
10
|
+
localize,
|
|
11
|
+
} from '@opensumi/ide-core-browser';
|
|
12
|
+
|
|
13
|
+
import styles from './style.module.less';
|
|
14
|
+
|
|
15
|
+
@Injectable()
|
|
16
|
+
export class ToolbarCustomizeViewService {
|
|
17
|
+
private _setVisible: (visible: boolean) => void;
|
|
18
|
+
|
|
19
|
+
@Autowired(PreferenceService)
|
|
20
|
+
preferenceService: PreferenceService;
|
|
21
|
+
|
|
22
|
+
public bindSetVisibleHandle(setVisible: (visible: boolean) => void) {
|
|
23
|
+
this._setVisible = setVisible;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
setVisible(visible: boolean) {
|
|
27
|
+
this._setVisible(visible);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async toggleActionVisibility(location: string, actionId: string, visible: boolean) {
|
|
31
|
+
const prev: { [key: string]: string[] } = this.preferenceService.getValid('toolbar.ignoreActions', {});
|
|
32
|
+
if (!prev[location]) {
|
|
33
|
+
prev[location] = [];
|
|
34
|
+
}
|
|
35
|
+
if (!visible) {
|
|
36
|
+
if (prev[location].indexOf(actionId) === -1) {
|
|
37
|
+
prev[location].push(actionId);
|
|
38
|
+
}
|
|
39
|
+
} else {
|
|
40
|
+
const index = prev[location].indexOf(actionId);
|
|
41
|
+
if (index !== -1) {
|
|
42
|
+
prev[location].splice(index, 1);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
const effectingScope = this.preferenceService.inspect('toolbar.ignoreActions')!.workspaceValue
|
|
46
|
+
? PreferenceScope.Workspace
|
|
47
|
+
: PreferenceScope.User;
|
|
48
|
+
await this.preferenceService.set('toolbar.ignoreActions', prev, effectingScope);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export const ToolbarCustomizeComponent = () => {
|
|
53
|
+
const [visible, setVisible] = React.useState<boolean>(false);
|
|
54
|
+
const service: ToolbarCustomizeViewService = useInjectable(ToolbarCustomizeViewService);
|
|
55
|
+
const registry: IToolbarRegistry = useInjectable(IToolbarRegistry);
|
|
56
|
+
const preferenceService: PreferenceService = useInjectable(PreferenceService);
|
|
57
|
+
|
|
58
|
+
service.bindSetVisibleHandle(setVisible);
|
|
59
|
+
|
|
60
|
+
if (!visible) {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const locations = registry.getAllLocations();
|
|
65
|
+
|
|
66
|
+
const currentPref: { [key: string]: string[] } = preferenceService.get('toolbar.ignoreActions') || {};
|
|
67
|
+
|
|
68
|
+
let currentDisplayPref: string = preferenceService.get<string>('toolbar.buttonDisplay', 'iconAndText')!;
|
|
69
|
+
|
|
70
|
+
function renderLocationPref(location: string) {
|
|
71
|
+
const groups = [{ id: '_head' }, ...(registry.getActionGroups(location) || []), { id: '_tail' }];
|
|
72
|
+
const result: React.ReactNode[] = [];
|
|
73
|
+
const pref = currentPref[location] || [];
|
|
74
|
+
|
|
75
|
+
groups.forEach((group, gi) => {
|
|
76
|
+
const actions = registry.getToolbarActions({ location, group: group.id });
|
|
77
|
+
if (actions && actions.actions.length > 0) {
|
|
78
|
+
if (result.length > 0) {
|
|
79
|
+
result.push(<div className={styles['group-split']} key={'split-' + gi}></div>);
|
|
80
|
+
}
|
|
81
|
+
actions.actions.forEach((action, i) => {
|
|
82
|
+
let visible = pref.indexOf(action.id) === -1;
|
|
83
|
+
const id = 'action-toggle-' + action.id;
|
|
84
|
+
result.push(
|
|
85
|
+
<div className={styles['action-item']} key={i + '_' + action.id}>
|
|
86
|
+
<CheckBox
|
|
87
|
+
onChange={() => {
|
|
88
|
+
service.toggleActionVisibility(location, action.id, !visible);
|
|
89
|
+
visible = !visible;
|
|
90
|
+
}}
|
|
91
|
+
defaultChecked={visible}
|
|
92
|
+
id={id}
|
|
93
|
+
label={action.description ?? action.id}
|
|
94
|
+
/>
|
|
95
|
+
</div>,
|
|
96
|
+
);
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
if (result.length === 0) {
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return (
|
|
105
|
+
<div key={location} className={styles['toolbar-customize-location']}>
|
|
106
|
+
{result}
|
|
107
|
+
</div>
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return (
|
|
112
|
+
<div className={styles['toolbar-customize-overlay']}>
|
|
113
|
+
<div className={styles['toolbar-customize']}>
|
|
114
|
+
{locations.map((location) => renderLocationPref(location))}
|
|
115
|
+
<div className={styles['button-display']}>
|
|
116
|
+
<div>{localize('toolbar-customize.buttonDisplay.description')}</div>
|
|
117
|
+
<Select
|
|
118
|
+
options={[
|
|
119
|
+
{
|
|
120
|
+
label: localize('toolbar-customize.buttonDisplay.icon'),
|
|
121
|
+
value: 'icon',
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
label: localize('toolbar-customize.buttonDisplay.iconAndText'),
|
|
125
|
+
value: 'iconAndText',
|
|
126
|
+
},
|
|
127
|
+
]}
|
|
128
|
+
value={currentDisplayPref}
|
|
129
|
+
onChange={(v) => {
|
|
130
|
+
const effectingScope = preferenceService.inspect('toolbar.buttonDisplay')!.workspaceValue
|
|
131
|
+
? PreferenceScope.Workspace
|
|
132
|
+
: PreferenceScope.User;
|
|
133
|
+
preferenceService.set('toolbar.buttonDisplay', v, effectingScope);
|
|
134
|
+
currentDisplayPref = v;
|
|
135
|
+
}}
|
|
136
|
+
className={styles['button-display-select']}
|
|
137
|
+
></Select>
|
|
138
|
+
</div>
|
|
139
|
+
<div className={styles['customize-complete']}>
|
|
140
|
+
<Button type='primary' onClick={() => setVisible(false)}>
|
|
141
|
+
{localize('toolbar-customize.complete')}
|
|
142
|
+
</Button>
|
|
143
|
+
</div>
|
|
144
|
+
</div>
|
|
145
|
+
</div>
|
|
146
|
+
);
|
|
147
|
+
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { FileTreeDropEvent } from '@opensumi/ide-core-common';
|
|
2
|
+
|
|
3
|
+
export const FileDropServicePath = 'FileDropServicePath';
|
|
4
|
+
|
|
5
|
+
export const IFileDropServiceToken = Symbol('IFileDropService');
|
|
6
|
+
|
|
7
|
+
export interface IFileDropBackendService {
|
|
8
|
+
$ensureFileExist(fileName: string, targetDir: string): Promise<boolean>;
|
|
9
|
+
$writeStream(chunk: string | ArrayBuffer, fileName: string, targetDir: string, done: boolean): Promise<void>;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const IFileDropFrontendServiceToken = Symbol('IFileDropFrontendService');
|
|
13
|
+
export interface IFileDropFrontendService {
|
|
14
|
+
onDidDropFile(e: FileTreeDropEvent): void;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface IWebkitDataTransfer {
|
|
18
|
+
items: IWebkitDataTransferItem[];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface IWebkitDataTransferItem {
|
|
22
|
+
webkitGetAsEntry(): IWebkitDataTransferItemEntry;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export interface IWebkitDataTransferItemEntry {
|
|
26
|
+
name: string | undefined;
|
|
27
|
+
fullPath: string;
|
|
28
|
+
isFile: boolean;
|
|
29
|
+
isDirectory: boolean;
|
|
30
|
+
type: string;
|
|
31
|
+
|
|
32
|
+
file(resolve: (file: File) => void, reject: () => void): void;
|
|
33
|
+
createReader(): IWebkitDataTransferItemEntryReader;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface IWebkitDataTransferItemEntryReader {
|
|
37
|
+
readEntries(resolve: (file: IWebkitDataTransferItemEntry[]) => void, reject: () => void): void;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export const ConnectionBackServicePath = 'ConnectionBackServicePath';
|
|
41
|
+
|
|
42
|
+
export const IConnectionBackService = Symbol('IConnectionBackService');
|
|
43
|
+
|
|
44
|
+
export interface IConnectionBackService {
|
|
45
|
+
$measure(): Promise<void>;
|
|
46
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './common';
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
|
|
4
|
+
import { Injectable } from '@opensumi/di';
|
|
5
|
+
import { Uri } from '@opensumi/ide-core-common';
|
|
6
|
+
|
|
7
|
+
import { IFileDropBackendService } from '../common';
|
|
8
|
+
@Injectable()
|
|
9
|
+
export class FileDropService implements IFileDropBackendService {
|
|
10
|
+
private writeableStreams: Map<string, fs.WriteStream> = new Map();
|
|
11
|
+
|
|
12
|
+
async $ensureFileExist(fileName: string, targetDir: string): Promise<boolean> {
|
|
13
|
+
const targetPath = Uri.file(path.join(targetDir, fileName)).path;
|
|
14
|
+
this.writeableStreams.set(targetPath, fs.createWriteStream(targetPath));
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
$writeStream(chunk: string | ArrayBuffer, fileName: string, targetDir: string, done: boolean): Promise<void> {
|
|
19
|
+
const targetPath = Uri.file(path.join(targetDir, fileName)).path;
|
|
20
|
+
const stream = this.writeableStreams.get(targetPath);
|
|
21
|
+
return new Promise((resolve, reject) => {
|
|
22
|
+
stream?.write(chunk, 'binary', (err) => {
|
|
23
|
+
if (err) {
|
|
24
|
+
reject(err);
|
|
25
|
+
}
|
|
26
|
+
resolve();
|
|
27
|
+
if (done) {
|
|
28
|
+
stream.close();
|
|
29
|
+
this.writeableStreams.delete(targetPath);
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Provider, Injectable } from '@opensumi/di';
|
|
2
|
+
import { NodeModule } from '@opensumi/ide-core-node';
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
IFileDropServiceToken,
|
|
6
|
+
FileDropServicePath,
|
|
7
|
+
IConnectionBackService,
|
|
8
|
+
ConnectionBackServicePath,
|
|
9
|
+
} from '../common';
|
|
10
|
+
|
|
11
|
+
import { ConnectionRTTBackService } from './connection-rtt-service';
|
|
12
|
+
import { FileDropService } from './file-drop.service';
|
|
13
|
+
|
|
14
|
+
@Injectable()
|
|
15
|
+
export class AddonsModule extends NodeModule {
|
|
16
|
+
providers: Provider[] = [
|
|
17
|
+
{
|
|
18
|
+
token: IFileDropServiceToken,
|
|
19
|
+
useClass: FileDropService,
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
token: IConnectionBackService,
|
|
23
|
+
useClass: ConnectionRTTBackService,
|
|
24
|
+
},
|
|
25
|
+
];
|
|
26
|
+
|
|
27
|
+
backServices = [
|
|
28
|
+
{
|
|
29
|
+
servicePath: FileDropServicePath,
|
|
30
|
+
token: IFileDropServiceToken,
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
servicePath: ConnectionBackServicePath,
|
|
34
|
+
token: IConnectionBackService,
|
|
35
|
+
},
|
|
36
|
+
];
|
|
37
|
+
}
|