Skip to content

Commit 1ceffaf

Browse files
author
Akos Kitta
committed
fix: can pull + sync from parent class
Signed-off-by: Akos Kitta <[email protected]>
1 parent 7b9471d commit 1ceffaf

File tree

4 files changed

+213
-67
lines changed

4 files changed

+213
-67
lines changed

arduino-ide-extension/src/browser/contributions/create-contribution.ts

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,29 @@
11
import { CompositeTreeNode } from '@theia/core/lib/browser';
2+
import { nls } from '@theia/core/lib/common/nls';
23
import URI from '@theia/core/lib/common/uri';
34
import { inject, injectable } from '@theia/core/shared/inversify';
45
import { Sketch } from '../../common/protocol';
56
import { CreateApi } from '../create/create-api';
67
import { CreateFeatures } from '../create/create-features';
8+
import { CreateUri } from '../create/create-uri';
9+
import { Create, isNotFound } from '../create/typings';
710
import { LocalCacheFsProvider } from '../local-cache/local-cache-fs-provider';
11+
import { CloudSketchbookTree } from '../widgets/cloud-sketchbook/cloud-sketchbook-tree';
812
import { CloudSketchbookTreeModel } from '../widgets/cloud-sketchbook/cloud-sketchbook-tree-model';
913
import { CloudSketchbookTreeWidget } from '../widgets/cloud-sketchbook/cloud-sketchbook-tree-widget';
14+
import { SketchbookCommands } from '../widgets/sketchbook/sketchbook-commands';
1015
import { SketchbookWidget } from '../widgets/sketchbook/sketchbook-widget';
1116
import { SketchbookWidgetContribution } from '../widgets/sketchbook/sketchbook-widget-contribution';
1217
import { SketchContribution } from './contribution';
1318

19+
export function sketchAlreadyExists(input: string): string {
20+
return nls.localize(
21+
'arduino/cloudSketch/sketchAlreadyExists',
22+
"Remote sketch '{0}' already exists.",
23+
input
24+
);
25+
}
26+
1427
@injectable()
1528
export abstract class CloudSketchContribution extends SketchContribution {
1629
@inject(LocalCacheFsProvider)
@@ -45,6 +58,57 @@ export abstract class CloudSketchContribution extends SketchContribution {
4558
return undefined;
4659
}
4760

61+
protected async openInNewWindow(sketch: Create.Sketch): Promise<unknown> {
62+
const node = await this.pull(sketch);
63+
if (node) {
64+
return this.open(node);
65+
}
66+
}
67+
68+
private async pull(
69+
sketch: Create.Sketch
70+
): Promise<CloudSketchbookTree.CloudSketchDirNode | undefined> {
71+
const treeModel = await this.treeModel();
72+
if (!treeModel) {
73+
return undefined;
74+
}
75+
const id = CreateUri.toUri(sketch).path.toString();
76+
const node = treeModel.getNode(id);
77+
if (!node) {
78+
throw new Error(
79+
`Could not find remote sketchbook tree node with Tree node ID: ${id}.`
80+
);
81+
}
82+
if (!CloudSketchbookTree.CloudSketchDirNode.is(node)) {
83+
throw new Error(
84+
`Remote sketchbook tree node expected to represent a directory but it did not. Tree node ID: ${id}.`
85+
);
86+
}
87+
try {
88+
await treeModel.sketchbookTree().pull({ node });
89+
} catch (err) {
90+
if (isNotFound(err)) {
91+
await treeModel.refresh();
92+
this.messageService.error(
93+
nls.localize(
94+
'arduino/cloudSketch/notFound',
95+
"Could not pull the remote sketch '{0}'. It does not exist.",
96+
sketch.name
97+
)
98+
);
99+
return undefined;
100+
}
101+
throw err;
102+
}
103+
}
104+
105+
private open(node: CloudSketchbookTree.CloudSketchDirNode): Promise<unknown> {
106+
return this.commandService.executeCommand(
107+
SketchbookCommands.OPEN_NEW_WINDOW.id,
108+
{ node }
109+
);
110+
}
111+
48112
private treeModelFrom(
49113
widget: SketchbookWidget
50114
): CloudSketchbookTreeModel | undefined {

arduino-ide-extension/src/browser/contributions/delete-sketch.ts

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,10 @@ export interface DeleteSketchParams {
2424
* Hence, the editors must be closed, the sketch will be scheduled
2525
* for deletion, and the browser window will close or navigate away.
2626
* If `false`, the sketch will be scheduled for deletion,
27-
* but the current window remains open.
27+
* but the current window remains open. If `force`, IDE2 won't open
28+
* confirmation dialogs.
2829
*/
29-
readonly willNavigateAway?: boolean;
30+
readonly willNavigateAway?: boolean | 'force';
3031
}
3132

3233
@injectable()
@@ -59,18 +60,20 @@ export class DeleteSketch extends CloudSketchContribution {
5960
return this.sketchesService.deleteSketch(sketch);
6061
}
6162
const cloudUri = this.cloudUri(sketch); // TODO: warn user that it's a remote sketch
62-
const { response } = await remote.dialog.showMessageBox({
63-
title: nls.localizeByDefault('Delete'),
64-
type: 'question',
65-
buttons: [Dialog.CANCEL, Dialog.OK],
66-
message: nls.localize(
67-
'theia/workspace/deleteCurrentSketch',
68-
'Do you want to delete the current sketch?'
69-
),
70-
});
71-
// cancel
72-
if (response === 0) {
73-
return;
63+
if (willNavigateAway !== 'force') {
64+
const { response } = await remote.dialog.showMessageBox({
65+
title: nls.localizeByDefault('Delete'),
66+
type: 'question',
67+
buttons: [Dialog.CANCEL, Dialog.OK],
68+
message: nls.localize(
69+
'theia/workspace/deleteCurrentSketch',
70+
'Do you want to delete the current sketch?'
71+
),
72+
});
73+
// cancel
74+
if (response === 0) {
75+
return;
76+
}
7477
}
7578
if (cloudUri) {
7679
const posixPath = cloudUri.path.toString();

arduino-ide-extension/src/browser/contributions/new-cloud-sketch.ts

Lines changed: 9 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,16 @@ import {
1111
Create,
1212
CreateError,
1313
isConflict,
14-
isNotFound,
1514
} from '../create/typings';
1615
import { ArduinoMenus } from '../menu/arduino-menus';
1716
import { WorkspaceInputDialogWithProgress } from '../theia/workspace/workspace-input-dialog';
1817
import { CloudSketchbookTree } from '../widgets/cloud-sketchbook/cloud-sketchbook-tree';
1918
import { CloudSketchbookTreeModel } from '../widgets/cloud-sketchbook/cloud-sketchbook-tree-model';
20-
import { SketchbookCommands } from '../widgets/sketchbook/sketchbook-commands';
21-
import { Command, CommandRegistry, Sketch, URI } from './contribution';
22-
import { CloudSketchContribution } from './create-contribution';
19+
import { Command, CommandRegistry, Sketch } from './contribution';
20+
import {
21+
CloudSketchContribution,
22+
sketchAlreadyExists,
23+
} from './create-contribution';
2324

2425
@injectable()
2526
export class NewCloudSketch extends CloudSketchContribution {
@@ -77,25 +78,21 @@ export class NewCloudSketch extends CloudSketchContribution {
7778
rootNode: CompositeTreeNode,
7879
treeModel: CloudSketchbookTreeModel,
7980
initialValue?: string | undefined
80-
): Promise<unknown> {
81+
): Promise<string | undefined> {
8182
const existingNames = rootNode.children
8283
.filter(CloudSketchbookTree.CloudSketchDirNode.is)
8384
.map(({ fileStat }) => fileStat.name);
8485
return new WorkspaceInputDialogWithProgress(
8586
{
8687
title: nls.localize(
8788
'arduino/newCloudSketch/newSketchTitle',
88-
'Name of a new Remote Sketch'
89+
'Name of the new Remote Sketch'
8990
),
9091
parentUri: CreateUri.root,
9192
initialValue,
9293
validate: (input) => {
9394
if (existingNames.includes(input)) {
94-
return nls.localize(
95-
'arduino/newCloudSketch/sketchAlreadyExists',
96-
"Remote sketch '{0}' already exists.",
97-
input
98-
);
95+
return sketchAlreadyExists(input);
9996
}
10097
return Sketch.validateCloudSketchFolderName(input) ?? '';
10198
},
@@ -142,49 +139,11 @@ export class NewCloudSketch extends CloudSketchContribution {
142139
return this.createNewSketch(value);
143140
}
144141
if (result) {
145-
return this.open(treeModel, result);
142+
return this.openInNewWindow(result);
146143
}
147144
return undefined;
148145
};
149146
}
150-
151-
private async open(
152-
treeModel: CloudSketchbookTreeModel,
153-
newSketch: Create.Sketch
154-
): Promise<URI | undefined> {
155-
const id = CreateUri.toUri(newSketch).path.toString();
156-
const node = treeModel.getNode(id);
157-
if (!node) {
158-
throw new Error(
159-
`Could not find remote sketchbook tree node with Tree node ID: ${id}.`
160-
);
161-
}
162-
if (!CloudSketchbookTree.CloudSketchDirNode.is(node)) {
163-
throw new Error(
164-
`Remote sketchbook tree node expected to represent a directory but it did not. Tree node ID: ${id}.`
165-
);
166-
}
167-
try {
168-
await treeModel.sketchbookTree().pull({ node });
169-
} catch (err) {
170-
if (isNotFound(err)) {
171-
await treeModel.refresh();
172-
this.messageService.error(
173-
nls.localize(
174-
'arduino/newCloudSketch/notFound',
175-
"Could not pull the remote sketch '{0}'. It does not exist.",
176-
newSketch.name
177-
)
178-
);
179-
return undefined;
180-
}
181-
throw err;
182-
}
183-
return this.commandService.executeCommand(
184-
SketchbookCommands.OPEN_NEW_WINDOW.id,
185-
{ node }
186-
);
187-
}
188147
}
189148
export namespace NewCloudSketch {
190149
export namespace Commands {

arduino-ide-extension/src/browser/contributions/rename-cloud-sketch.ts

Lines changed: 123 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,21 @@
1+
import { CompositeTreeNode } from '@theia/core/lib/browser/tree';
2+
import { Progress } from '@theia/core/lib/common/message-service-protocol';
3+
import { nls } from '@theia/core/lib/common/nls';
14
import { injectable } from '@theia/core/shared/inversify';
5+
import { CreateUri } from '../create/create-uri';
6+
import {
7+
ConflictError,
8+
Create,
9+
CreateError,
10+
isConflict,
11+
} from '../create/typings';
12+
import { WorkspaceInputDialogWithProgress } from '../theia/workspace/workspace-input-dialog';
13+
import { CloudSketchbookTree } from '../widgets/cloud-sketchbook/cloud-sketchbook-tree';
14+
import { CloudSketchbookTreeModel } from '../widgets/cloud-sketchbook/cloud-sketchbook-tree-model';
15+
import { SketchbookTree } from '../widgets/sketchbook/sketchbook-tree';
216
import { Command, CommandRegistry, Sketch, URI } from './contribution';
317
import { CloudSketchContribution } from './create-contribution';
18+
import { DeleteSketch, DeleteSketchParams } from './delete-sketch';
419

520
export interface RenameCloudSketchParams {
621
readonly cloudUri: URI;
@@ -11,15 +26,120 @@ export interface RenameCloudSketchParams {
1126
export class RenameCloudSketch extends CloudSketchContribution {
1227
override registerCommands(registry: CommandRegistry): void {
1328
registry.registerCommand(RenameCloudSketch.Commands.RENAME_CLOUD_SKETCH, {
14-
execute: (params: RenameCloudSketchParams) => this.rename(params),
29+
execute: (params: RenameCloudSketchParams) => this.renameSketch(params),
1530
});
1631
}
1732

18-
private async rename(
19-
params: RenameCloudSketchParams
33+
private async renameSketch(
34+
params: RenameCloudSketchParams,
35+
initValue: string = params.sketch.name
2036
): Promise<URI | undefined> {
37+
const treeModel = await this.treeModel();
38+
if (treeModel) {
39+
const posixPath = params.cloudUri.path.toString();
40+
const node = treeModel.getNode(posixPath);
41+
if (SketchbookTree.SketchDirNode.is(node)) {
42+
const result = await this.openWizard(
43+
params,
44+
node,
45+
treeModel.root,
46+
treeModel,
47+
initValue
48+
);
49+
if (result) {
50+
console.log(result);
51+
}
52+
}
53+
}
2154
return undefined;
2255
}
56+
57+
private async openWizard(
58+
params: RenameCloudSketchParams,
59+
node: SketchbookTree.SketchDirNode,
60+
rootNode: CompositeTreeNode,
61+
treeModel: CloudSketchbookTreeModel,
62+
initialValue?: string | undefined
63+
): Promise<string | undefined> {
64+
const existingNames = rootNode.children
65+
.filter(CloudSketchbookTree.CloudSketchDirNode.is)
66+
.map(({ fileStat }) => fileStat.name);
67+
return new WorkspaceInputDialogWithProgress(
68+
{
69+
title: nls.localize(
70+
'arduino/renameCloudSketch/renameSketchTitle',
71+
'New name of the Remote Sketch'
72+
),
73+
parentUri: CreateUri.root,
74+
initialValue,
75+
validate: (input) => {
76+
if (existingNames.includes(input)) {
77+
return nls.localize(
78+
'arduino/newCloudSketch/sketchAlreadyExists',
79+
"Remote sketch '{0}' already exists.",
80+
input
81+
);
82+
}
83+
return Sketch.validateCloudSketchFolderName(input) ?? '';
84+
},
85+
},
86+
this.labelProvider,
87+
(value) => this.renameSketchWithProgress(params, value, treeModel)
88+
).open();
89+
}
90+
91+
private renameSketchWithProgress(
92+
params: RenameCloudSketchParams,
93+
value: string,
94+
treeModel: CloudSketchbookTreeModel
95+
): (progress: Progress) => Promise<unknown> {
96+
return async (progress: Progress) => {
97+
let result: Create.Sketch | undefined | ConflictError;
98+
try {
99+
progress.report({
100+
message: nls.localize(
101+
'arduino/cloudSketch/renaming',
102+
"Renaming remote sketch '{0}'...",
103+
value
104+
),
105+
});
106+
result = await this.createApi.createSketch(value);
107+
} catch (err) {
108+
if (isConflict(err)) {
109+
result = err;
110+
} else {
111+
throw err;
112+
}
113+
} finally {
114+
if (result) {
115+
progress.report({
116+
message: nls.localize(
117+
'arduino/cloudSketch/synchronizing',
118+
"Synchronizing sketchbook, pulling '{0}'...",
119+
value
120+
),
121+
});
122+
await treeModel.refresh();
123+
}
124+
}
125+
if (result instanceof CreateError) {
126+
return this.renameSketch(params, value);
127+
}
128+
if (result) {
129+
setTimeout(() => {
130+
this.commandService.executeCommand(
131+
DeleteSketch.Commands.DELETE_SKETCH.id,
132+
<DeleteSketchParams>{
133+
toDelete: params.sketch,
134+
willNavigateAway: 'force',
135+
}
136+
);
137+
}, 0);
138+
return this.openInNewWindow(result);
139+
}
140+
return undefined;
141+
};
142+
}
23143
}
24144
export namespace RenameCloudSketch {
25145
export namespace Commands {

0 commit comments

Comments
 (0)