Skip to content

Commit 0d736fe

Browse files
author
Akos Kitta
committed
feat: refresh remote tree on sketch create
Signed-off-by: Akos Kitta <[email protected]>
1 parent ca049a9 commit 0d736fe

File tree

4 files changed

+100
-32
lines changed

4 files changed

+100
-32
lines changed

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

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,6 @@ export class NewCloudSketch extends Contribution {
110110
}
111111
} finally {
112112
if (result) {
113-
await treeModel.updateRoot();
114113
await treeModel.refresh();
115114
}
116115
}
@@ -145,7 +144,6 @@ export class NewCloudSketch extends Contribution {
145144
await treeModel.sketchbookTree().pull({ node });
146145
} catch (err) {
147146
if (isNotFound(err)) {
148-
await treeModel.updateRoot();
149147
await treeModel.refresh();
150148
this.messageService.error(
151149
nls.localize(

arduino-ide-extension/src/browser/local-cache/local-cache-fs-provider.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,6 @@ export class LocalCacheFsProvider
3434
@inject(AuthenticationClientService)
3535
protected readonly authenticationService: AuthenticationClientService;
3636

37-
// TODO: do we need this? Cannot we `await` on the `init` call from `registerFileSystemProviders`?
3837
readonly ready = new Deferred<void>();
3938

4039
private _localCacheRoot: URI;
@@ -153,7 +152,7 @@ export class LocalCacheFsProvider
153152
return uri;
154153
}
155154

156-
private toUri(session: AuthenticationSession): URI {
155+
toUri(session: AuthenticationSession): URI {
157156
// Hack: instead of getting the UUID only, we get `auth0|UUID` after the authentication. `|` cannot be part of filesystem path or filename.
158157
return this._localCacheRoot.resolve(session.id.split('|')[1]);
159158
}

arduino-ide-extension/src/browser/widgets/cloud-sketchbook/cloud-sketchbook-tree-model.ts

Lines changed: 98 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,31 @@
1-
import { inject, injectable, postConstruct } from '@theia/core/shared/inversify';
2-
import { TreeNode } from '@theia/core/lib/browser/tree';
1+
import {
2+
inject,
3+
injectable,
4+
postConstruct,
5+
} from '@theia/core/shared/inversify';
6+
import { CompositeTreeNode, TreeNode } from '@theia/core/lib/browser/tree';
37
import { posixSegments, splitSketchPath } from '../../create/create-paths';
48
import { CreateApi } from '../../create/create-api';
59
import { CloudSketchbookTree } from './cloud-sketchbook-tree';
610
import { AuthenticationClientService } from '../../auth/authentication-client-service';
711
import { SketchbookTreeModel } from '../sketchbook/sketchbook-tree-model';
8-
import { ArduinoPreferences } from '../../arduino-preferences';
912
import { WorkspaceNode } from '@theia/navigator/lib/browser/navigator-tree';
1013
import { CreateUri } from '../../create/create-uri';
11-
import { FileStat } from '@theia/filesystem/lib/common/files';
12-
import { LocalCacheFsProvider } from '../../local-cache/local-cache-fs-provider';
13-
import { FileService } from '@theia/filesystem/lib/browser/file-service';
14+
import {
15+
FileChangesEvent,
16+
FileChangeType,
17+
FileStat,
18+
} from '@theia/filesystem/lib/common/files';
19+
import {
20+
LocalCacheFsProvider,
21+
LocalCacheUri,
22+
} from '../../local-cache/local-cache-fs-provider';
1423
import URI from '@theia/core/lib/common/uri';
1524
import { SketchCache } from './cloud-sketch-cache';
1625
import { Create } from '../../create/typings';
17-
import { nls } from '@theia/core/lib/common';
26+
import { nls } from '@theia/core/lib/common/nls';
27+
import { DisposableCollection } from '@theia/core/lib/common/disposable';
28+
import { Deferred } from '@theia/core/lib/common/promise-util';
1829

1930
export function sketchBaseDir(sketch: Create.Sketch): FileStat {
2031
// extract the sketch path
@@ -52,35 +63,79 @@ export function sketchesToFileStats(sketches: Create.Sketch[]): FileStat[] {
5263

5364
@injectable()
5465
export class CloudSketchbookTreeModel extends SketchbookTreeModel {
55-
@inject(FileService)
56-
protected override readonly fileService: FileService;
57-
58-
@inject(AuthenticationClientService)
59-
protected readonly authenticationService: AuthenticationClientService;
60-
6166
@inject(CreateApi)
62-
protected readonly createApi: CreateApi;
63-
64-
@inject(CloudSketchbookTree)
65-
protected readonly cloudSketchbookTree: CloudSketchbookTree;
66-
67-
@inject(ArduinoPreferences)
68-
protected override readonly arduinoPreferences: ArduinoPreferences;
69-
67+
private readonly createApi: CreateApi;
68+
@inject(AuthenticationClientService)
69+
private readonly authenticationService: AuthenticationClientService;
7070
@inject(LocalCacheFsProvider)
71-
protected readonly localCacheFsProvider: LocalCacheFsProvider;
72-
71+
private readonly localCacheFsProvider: LocalCacheFsProvider;
7372
@inject(SketchCache)
74-
protected readonly sketchCache: SketchCache;
73+
private readonly sketchCache: SketchCache;
74+
75+
private readonly toDisposeOnSessionDidChange = new DisposableCollection();
76+
private _localCacheFsProviderReady: Deferred<void> | undefined;
7577

7678
@postConstruct()
7779
protected override init(): void {
7880
super.init();
7981
this.toDispose.push(
80-
this.authenticationService.onSessionDidChange(() => this.updateRoot())
82+
this.authenticationService.onSessionDidChange((session) => {
83+
this.updateRoot();
84+
this.toDisposeOnSessionDidChange.dispose();
85+
if (session) {
86+
this.toDisposeOnSessionDidChange.push(
87+
this.fileService.watch(CreateUri.root)
88+
);
89+
}
90+
})
91+
);
92+
this.ensureLocalFsProviderReady();
93+
}
94+
95+
override *getNodesByUri(uri: URI): IterableIterator<TreeNode> {
96+
if (uri.scheme === LocalCacheUri.scheme) {
97+
const workspace = this.root;
98+
const { session } = this.authenticationService;
99+
if (session && WorkspaceNode.is(workspace)) {
100+
const currentUri = this.localCacheFsProvider.to(uri);
101+
if (currentUri) {
102+
const rootPath = this.localCacheFsProvider
103+
.toUri(session)
104+
.path.toString();
105+
const currentPath = currentUri.path.toString();
106+
if (rootPath === currentPath) {
107+
return workspace;
108+
}
109+
if (currentPath.startsWith(rootPath)) {
110+
const id = currentPath.substring(rootPath.length);
111+
const node = this.getNode(id);
112+
if (node) {
113+
yield node;
114+
}
115+
}
116+
}
117+
}
118+
}
119+
}
120+
121+
protected override isRootAffected(changes: FileChangesEvent): boolean {
122+
return changes.changes.some(
123+
(change) =>
124+
change.type === FileChangeType.ADDED &&
125+
change.resource.parent.toString() === LocalCacheUri.root.toString()
81126
);
82127
}
83128

129+
override async refresh(
130+
parent?: Readonly<CompositeTreeNode>
131+
): Promise<CompositeTreeNode | undefined> {
132+
if (parent) {
133+
return super.refresh(parent);
134+
}
135+
await this.updateRoot();
136+
return super.refresh();
137+
}
138+
84139
override async createRoot(): Promise<TreeNode | undefined> {
85140
const { session } = this.authenticationService;
86141
if (!session) {
@@ -89,7 +144,10 @@ export class CloudSketchbookTreeModel extends SketchbookTreeModel {
89144
}
90145
this.createApi.init(this.authenticationService, this.arduinoPreferences);
91146
this.sketchCache.init();
92-
const sketches = await this.createApi.sketches();
147+
const [sketches] = await Promise.all([
148+
this.createApi.sketches(),
149+
this.ensureLocalFsProviderReady(),
150+
]);
93151
const rootFileStats = sketchesToFileStats(sketches);
94152
if (this.workspaceService.opened) {
95153
const workspaceNode = WorkspaceNode.createRoot(
@@ -108,7 +166,9 @@ export class CloudSketchbookTreeModel extends SketchbookTreeModel {
108166
return this.tree as CloudSketchbookTree;
109167
}
110168

111-
protected override recursivelyFindSketchRoot(node: TreeNode): any {
169+
protected override recursivelyFindSketchRoot(
170+
node: TreeNode
171+
): TreeNode | false {
112172
if (node && CloudSketchbookTree.CloudSketchDirNode.is(node)) {
113173
return node;
114174
}
@@ -132,4 +192,15 @@ export class CloudSketchbookTreeModel extends SketchbookTreeModel {
132192
return super.revealFile(uri);
133193
}
134194
}
195+
196+
private async ensureLocalFsProviderReady(): Promise<void> {
197+
if (this._localCacheFsProviderReady) {
198+
return this._localCacheFsProviderReady.promise;
199+
}
200+
this._localCacheFsProviderReady = new Deferred();
201+
this.fileService
202+
.access(LocalCacheUri.root)
203+
.then(() => this._localCacheFsProviderReady?.resolve());
204+
return this._localCacheFsProviderReady.promise;
205+
}
135206
}

arduino-ide-extension/src/browser/widgets/cloud-sketchbook/cloud-sketchbook-tree.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ export class CloudSketchbookTree extends SketchbookTree {
269269
return prev;
270270
}
271271

272-
// do not map "do_not_sync" files/directoris and their descendants
272+
// do not map "do_not_sync" files/directories and their descendants
273273
const segments = path[1].split(posix.sep) || [];
274274
if (
275275
segments.some((segment) => Create.do_not_sync_files.includes(segment))

0 commit comments

Comments
 (0)