@@ -5,9 +5,13 @@ import { FileService } from '@theia/filesystem/lib/browser/file-service';
5
5
import { MessageService } from '@theia/core/lib/common/message-service' ;
6
6
import { WorkspaceService } from '@theia/workspace/lib/browser/workspace-service' ;
7
7
import { Sketch , SketchesService } from '../../common/protocol' ;
8
+ import { FrontendApplicationContribution } from '@theia/core/lib/browser' ;
9
+ import { ConfigService } from './config-service' ;
10
+ import { DisposableCollection , Emitter } from '@theia/core' ;
11
+ import { FileChangeType } from '@theia/filesystem/lib/browser' ;
8
12
9
13
@injectable ( )
10
- export class SketchesServiceClientImpl {
14
+ export class SketchesServiceClientImpl implements FrontendApplicationContribution {
11
15
12
16
@inject ( FileService )
13
17
protected readonly fileService : FileService ;
@@ -21,6 +25,58 @@ export class SketchesServiceClientImpl {
21
25
@inject ( WorkspaceService )
22
26
protected readonly workspaceService : WorkspaceService ;
23
27
28
+ @inject ( ConfigService )
29
+ protected readonly configService : ConfigService ;
30
+
31
+ protected toDispose = new DisposableCollection ( ) ;
32
+ protected sketches = new Map < string , Sketch > ( ) ;
33
+ protected sketchbookDidChangeEmitter = new Emitter < { created : Sketch [ ] , removed : Sketch [ ] } > ( ) ;
34
+ readonly onSketchbookDidChange = this . sketchbookDidChangeEmitter . event ;
35
+
36
+ onStart ( ) : void {
37
+ this . configService . getConfiguration ( ) . then ( ( { sketchDirUri } ) => {
38
+ this . sketchService . getSketches ( sketchDirUri ) . then ( sketches => {
39
+ const sketchbookUri = new URI ( sketchDirUri ) ;
40
+ for ( const sketch of sketches ) {
41
+ this . sketches . set ( sketch . uri , sketch ) ;
42
+ }
43
+ this . toDispose . push ( this . fileService . watch ( new URI ( sketchDirUri ) , { recursive : true , excludes : [ ] } ) ) ;
44
+ this . toDispose . push ( this . fileService . onDidFilesChange ( async event => {
45
+ for ( const { type, resource } of event . changes ) {
46
+ // We track main sketch files changes only.
47
+ if ( sketchbookUri . isEqualOrParent ( resource ) ) {
48
+ const { ext } = resource . path ; // TODO: add support for `.pde`.
49
+ if ( ext === '.ino' ) {
50
+ if ( type === FileChangeType . ADDED ) {
51
+ try {
52
+ const toAdd = await this . sketchService . loadSketch ( resource . parent . toString ( ) ) ;
53
+ if ( ! this . sketches . has ( toAdd . uri ) ) {
54
+ console . log ( `New sketch '${ toAdd . name } ' was crated in sketchbook '${ sketchDirUri } '.` ) ;
55
+ this . sketches . set ( toAdd . uri , toAdd ) ;
56
+ this . fireSoon ( toAdd , 'created' ) ;
57
+ }
58
+ } catch { }
59
+ } else if ( type === FileChangeType . DELETED ) {
60
+ const uri = resource . parent . toString ( ) ;
61
+ const toDelete = this . sketches . get ( uri ) ;
62
+ if ( toDelete ) {
63
+ console . log ( `Sketch '${ toDelete . name } ' was removed from sketchbook '${ sketchbookUri } '.` ) ;
64
+ this . sketches . delete ( uri ) ;
65
+ this . fireSoon ( toDelete , 'removed' ) ;
66
+ }
67
+ }
68
+ }
69
+ }
70
+ }
71
+ } ) ) ;
72
+ } ) ;
73
+ } ) ;
74
+ }
75
+
76
+ onStop ( ) : void {
77
+ this . toDispose . dispose ( ) ;
78
+ }
79
+
24
80
async currentSketch ( ) : Promise < Sketch | undefined > {
25
81
const sketches = ( await Promise . all ( this . workspaceService . tryGetRoots ( ) . map ( ( { resource } ) => this . sketchService . getSketchFolder ( resource . toString ( ) ) ) ) ) . filter ( notEmpty ) ;
26
82
if ( ! sketches . length ) {
@@ -46,4 +102,31 @@ export class SketchesServiceClientImpl {
46
102
return undefined ;
47
103
}
48
104
105
+ private fireSoonHandle ?: number ;
106
+ private bufferedSketchbookEvents : { type : 'created' | 'removed' , sketch : Sketch } [ ] = [ ] ;
107
+
108
+ private fireSoon ( sketch : Sketch , type : 'created' | 'removed' ) : void {
109
+ this . bufferedSketchbookEvents . push ( { type, sketch } ) ;
110
+
111
+ if ( typeof this . fireSoonHandle === 'number' ) {
112
+ window . clearTimeout ( this . fireSoonHandle ) ;
113
+ }
114
+
115
+ this . fireSoonHandle = window . setTimeout ( ( ) => {
116
+ const event : { created : Sketch [ ] , removed : Sketch [ ] } = {
117
+ created : [ ] ,
118
+ removed : [ ]
119
+ } ;
120
+ for ( const { type, sketch } of this . bufferedSketchbookEvents ) {
121
+ if ( type === 'created' ) {
122
+ event . created . push ( sketch ) ;
123
+ } else {
124
+ event . removed . push ( sketch ) ;
125
+ }
126
+ }
127
+ this . sketchbookDidChangeEmitter . fire ( event ) ;
128
+ this . bufferedSketchbookEvents . length = 0 ;
129
+ } , 100 ) ;
130
+ }
131
+
49
132
}
0 commit comments