1
1
import { injectable , inject } from 'inversify' ;
2
- import { toUnix } from 'upath' ;
3
- import URI from '@theia/core/lib/common/uri' ;
4
- import { isWindows } from '@theia/core/lib/common/os' ;
2
+ // import { toUnix } from 'upath';
3
+ // import URI from '@theia/core/lib/common/uri';
4
+ // import { isWindows } from '@theia/core/lib/common/os';
5
5
import { LabelProvider } from '@theia/core/lib/browser' ;
6
6
import { WorkspaceService } from '@theia/workspace/lib/browser/workspace-service' ;
7
7
import { ConfigService } from '../common/protocol/config-service' ;
8
8
import { SketchesService } from '../common/protocol/sketches-service' ;
9
+ // import { ArduinoAdvancedMode } from './arduino-frontend-contribution';
10
+ import { ArduinoWorkspaceRootResolver } from './arduino-workspace-resolver' ;
9
11
import { ArduinoAdvancedMode } from './arduino-frontend-contribution' ;
10
12
11
13
/**
12
14
* This is workaround to have custom frontend binding for the default workspace, although we
13
15
* already have a custom binding for the backend.
16
+ *
17
+ * The following logic is used for determining the default workspace location:
18
+ * - #hash exists in location?
19
+ * - Yes
20
+ * - `validateHash`. Is valid sketch location?
21
+ * - Yes
22
+ * - Done.
23
+ * - No
24
+ * - `checkHistoricalWorkspaceRoots`, `try open last modified sketch`,create new sketch`.
25
+ * - No
26
+ * - `checkHistoricalWorkspaceRoots`, `try open last modified sketch`, `create new sketch`.
14
27
*/
15
28
@injectable ( )
16
29
export class ArduinoWorkspaceService extends WorkspaceService {
@@ -25,105 +38,38 @@ export class ArduinoWorkspaceService extends WorkspaceService {
25
38
protected readonly labelProvider : LabelProvider ;
26
39
27
40
async getDefaultWorkspacePath ( ) : Promise < string | undefined > {
28
- const url = new URL ( window . location . href ) ;
29
- // If `sketch` is set and valid, we use it as is.
30
- // `sketch` is set as an encoded URI string.
31
- const sketch = url . searchParams . get ( 'sketch' ) ;
32
- if ( sketch ) {
33
- const sketchDirUri = new URI ( sketch ) . toString ( ) ;
34
- if ( await this . sketchService . isSketchFolder ( sketchDirUri ) ) {
35
- if ( await this . configService . isInSketchDir ( sketchDirUri ) ) {
36
- if ( ArduinoAdvancedMode . TOGGLED ) {
37
- return ( await this . configService . getConfiguration ( ) ) . sketchDirUri
38
- } else {
39
- return sketchDirUri ;
40
- }
41
- }
42
- return ( await this . configService . getConfiguration ( ) ) . sketchDirUri
43
- }
41
+ const [ hash , recentWorkspaces , recentSketches ] = await Promise . all ( [
42
+ window . location . hash ,
43
+ this . sketchService . getSketches ( ) . then ( sketches => sketches . map ( ( { uri } ) => uri ) ) ,
44
+ this . server . getRecentWorkspaces ( )
45
+ ] ) ;
46
+ const toOpen = await new ArduinoWorkspaceRootResolver ( {
47
+ isValid : this . isValid . bind ( this )
48
+ } ) . resolve ( {
49
+ hash ,
50
+ recentWorkspaces ,
51
+ recentSketches
52
+ } ) ;
53
+ if ( toOpen ) {
54
+ const { uri } = toOpen ;
55
+ await this . server . setMostRecentlyUsedWorkspace ( uri ) ;
56
+ return toOpen . uri ;
44
57
}
45
-
46
- const { hash } = window . location ;
47
- // Note: here, the `uriPath` was defined as new `URI(yourValidFsPath).path` so we have to map it to a valid FS path first.
48
- // This is important for Windows only and a NOOP on UNIX.
49
- if ( hash . length > 1 && hash . startsWith ( '#' ) ) {
50
- let uri = this . toUri ( hash . slice ( 1 ) ) ;
51
- if ( uri && await this . sketchService . isSketchFolder ( uri ) ) {
52
- return this . openSketchFilesInNewWindow ( uri ) ;
53
- }
54
- }
55
-
56
- // If we cannot acquire the FS path from the `location.hash` we try to get the most recently used workspace that was a valid sketch folder.
57
- // XXX: Check if `WorkspaceServer#getRecentWorkspaces()` returns with inverse-chrolonolgical order.
58
- const candidateUris = await this . server . getRecentWorkspaces ( ) ;
59
- for ( const uri of candidateUris ) {
60
- if ( await this . sketchService . isSketchFolder ( uri ) ) {
61
- return this . openSketchFilesInNewWindow ( uri ) ;
62
- }
63
- }
64
-
65
- const config = await this . configService . getConfiguration ( ) ;
66
- const { sketchDirUri } = config ;
67
- const stat = await this . fileSystem . getFileStat ( sketchDirUri ) ;
68
- if ( ! stat ) {
69
- // The folder for the workspace root does not exist yet, create it.
70
- await this . fileSystem . createFolder ( sketchDirUri ) ;
71
- await this . sketchService . createNewSketch ( sketchDirUri ) ;
72
- }
73
-
74
- const sketches = await this . sketchService . getSketches ( sketchDirUri ) ;
75
- if ( ! sketches . length ) {
76
- const sketch = await this . sketchService . createNewSketch ( sketchDirUri ) ;
77
- sketches . unshift ( sketch ) ;
78
- }
79
-
80
- const uri = sketches [ 0 ] . uri ;
81
- this . server . setMostRecentlyUsedWorkspace ( uri ) ;
82
- this . openSketchFilesInNewWindow ( uri ) ;
83
- if ( ArduinoAdvancedMode . TOGGLED && await this . configService . isInSketchDir ( uri ) ) {
84
- return ( await this . configService . getConfiguration ( ) ) . sketchDirUri ;
85
- }
86
- return uri ;
87
- }
88
-
89
- private toUri ( uriPath : string | undefined ) : string | undefined {
90
- if ( uriPath ) {
91
- return new URI ( toUnix ( uriPath . slice ( isWindows && uriPath . startsWith ( '/' ) ? 1 : 0 ) ) ) . withScheme ( 'file' ) . toString ( ) ;
92
- }
93
- return undefined ;
58
+ return ( await this . sketchService . createNewSketch ( ) ) . uri ;
94
59
}
95
60
96
- async openSketchFilesInNewWindow ( uri : string ) : Promise < string > {
97
- const url = new URL ( window . location . href ) ;
98
- const currentSketch = url . searchParams . get ( 'sketch' ) ;
99
- // Nothing to do if we want to open the same sketch which is already opened.
100
- const sketchUri = new URI ( uri ) ;
101
- if ( ! ! currentSketch && new URI ( currentSketch ) . toString ( ) === sketchUri . toString ( ) ) {
102
- return uri ;
103
- }
104
-
105
- url . searchParams . set ( 'sketch' , uri ) ;
106
- // If in advanced mode, we root folder of all sketch folders as the hash, so the default workspace will be opened on the root
107
- // Note: we set the `new URI(myValidUri).path.toString()` as the `hash`. See:
108
- // - https://github.com/eclipse-theia/theia/blob/8196e9dcf9c8de8ea0910efeb5334a974f426966/packages/workspace/src/browser/workspace-service.ts#L143 and
109
- // - https://github.com/eclipse-theia/theia/blob/8196e9dcf9c8de8ea0910efeb5334a974f426966/packages/workspace/src/browser/workspace-service.ts#L423
110
- if ( ArduinoAdvancedMode . TOGGLED && await this . configService . isInSketchDir ( uri ) ) {
111
- url . hash = new URI ( ( await this . configService . getConfiguration ( ) ) . sketchDirUri ) . path . toString ( ) ;
112
- } else {
113
- // Otherwise, we set the hash as is
114
- const hash = await this . fileSystem . getFsPath ( sketchUri . toString ( ) ) ;
115
- if ( hash ) {
116
- url . hash = sketchUri . path . toString ( )
117
- }
61
+ private async isValid ( uri : string ) : Promise < boolean > {
62
+ const exists = await this . fileSystem . exists ( uri ) ;
63
+ if ( ! exists ) {
64
+ return false ;
118
65
}
119
-
120
- // Preserve the current window if the `sketch` is not in the `searchParams`.
121
- if ( ! currentSketch ) {
122
- setTimeout ( ( ) => window . location . href = url . toString ( ) , 100 ) ;
123
- return uri ;
66
+ // The workspace root location must exist. However, when opening a workspace root in pro-mode,
67
+ // the workspace root must not be a sketch folder. It can be the default sketch directory, or any other directories, for instance.
68
+ if ( ! ArduinoAdvancedMode . TOGGLED ) {
69
+ return true ;
124
70
}
125
- this . windowService . openNewWindow ( url . toString ( ) ) ;
126
- return uri ;
71
+ const sketchFolder = await this . sketchService . isSketchFolder ( uri ) ;
72
+ return sketchFolder ;
127
73
}
128
74
129
75
}
0 commit comments