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' ;
3
7
import { posixSegments , splitSketchPath } from '../../create/create-paths' ;
4
8
import { CreateApi } from '../../create/create-api' ;
5
9
import { CloudSketchbookTree } from './cloud-sketchbook-tree' ;
6
10
import { AuthenticationClientService } from '../../auth/authentication-client-service' ;
7
11
import { SketchbookTreeModel } from '../sketchbook/sketchbook-tree-model' ;
8
- import { ArduinoPreferences } from '../../arduino-preferences' ;
9
12
import { WorkspaceNode } from '@theia/navigator/lib/browser/navigator-tree' ;
10
13
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' ;
14
23
import URI from '@theia/core/lib/common/uri' ;
15
24
import { SketchCache } from './cloud-sketch-cache' ;
16
25
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' ;
18
29
19
30
export function sketchBaseDir ( sketch : Create . Sketch ) : FileStat {
20
31
// extract the sketch path
@@ -52,35 +63,79 @@ export function sketchesToFileStats(sketches: Create.Sketch[]): FileStat[] {
52
63
53
64
@injectable ( )
54
65
export class CloudSketchbookTreeModel extends SketchbookTreeModel {
55
- @inject ( FileService )
56
- protected override readonly fileService : FileService ;
57
-
58
- @inject ( AuthenticationClientService )
59
- protected readonly authenticationService : AuthenticationClientService ;
60
-
61
66
@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 ;
70
70
@inject ( LocalCacheFsProvider )
71
- protected readonly localCacheFsProvider : LocalCacheFsProvider ;
72
-
71
+ private readonly localCacheFsProvider : LocalCacheFsProvider ;
73
72
@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 ;
75
77
76
78
@postConstruct ( )
77
79
protected override init ( ) : void {
78
80
super . init ( ) ;
79
81
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 ( )
81
126
) ;
82
127
}
83
128
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
+
84
139
override async createRoot ( ) : Promise < TreeNode | undefined > {
85
140
const { session } = this . authenticationService ;
86
141
if ( ! session ) {
@@ -89,7 +144,10 @@ export class CloudSketchbookTreeModel extends SketchbookTreeModel {
89
144
}
90
145
this . createApi . init ( this . authenticationService , this . arduinoPreferences ) ;
91
146
this . sketchCache . init ( ) ;
92
- const sketches = await this . createApi . sketches ( ) ;
147
+ const [ sketches ] = await Promise . all ( [
148
+ this . createApi . sketches ( ) ,
149
+ this . ensureLocalFsProviderReady ( ) ,
150
+ ] ) ;
93
151
const rootFileStats = sketchesToFileStats ( sketches ) ;
94
152
if ( this . workspaceService . opened ) {
95
153
const workspaceNode = WorkspaceNode . createRoot (
@@ -108,7 +166,9 @@ export class CloudSketchbookTreeModel extends SketchbookTreeModel {
108
166
return this . tree as CloudSketchbookTree ;
109
167
}
110
168
111
- protected override recursivelyFindSketchRoot ( node : TreeNode ) : any {
169
+ protected override recursivelyFindSketchRoot (
170
+ node : TreeNode
171
+ ) : TreeNode | false {
112
172
if ( node && CloudSketchbookTree . CloudSketchDirNode . is ( node ) ) {
113
173
return node ;
114
174
}
@@ -132,4 +192,15 @@ export class CloudSketchbookTreeModel extends SketchbookTreeModel {
132
192
return super . revealFile ( uri ) ;
133
193
}
134
194
}
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
+ }
135
206
}
0 commit comments