@@ -14,34 +14,47 @@ export enum WorkspaceQuery {
14
14
export class WorkspaceProvider implements vscode . TreeDataProvider < vscode . TreeItem > {
15
15
private workspaces : WorkspaceTreeItem [ ] = [ ]
16
16
private agentWatchers : Record < WorkspaceAgent [ "id" ] , { dispose : ( ) => void ; metadata ?: AgentMetadataEvent [ ] } > = { }
17
+ private timeout : NodeJS . Timeout | undefined
18
+ private visible = false
17
19
private fetching = false
18
20
19
21
constructor (
20
22
private readonly getWorkspacesQuery : WorkspaceQuery ,
21
23
private readonly storage : Storage ,
24
+ private readonly timerSeconds ?: number ,
22
25
) {
23
26
this . fetchAndRefresh ( )
24
27
}
25
28
26
- // fetchAndRefresh fetches new workspaces then re-renders the entire tree.
27
- // Trying to call this while already refreshing is a no-op and will return
29
+ // fetchAndRefresh fetches new workspaces, re-renders the entire tree, then
30
+ // keeps refreshing (if a timer length was provided) as long as the user is
31
+ // still logged in and no errors were encountered fetching workspaces.
32
+ // Calling this while already refreshing is a no-op and will return
28
33
// immediately.
29
34
async fetchAndRefresh ( ) {
30
35
if ( this . fetching ) {
31
36
return
32
37
}
33
38
this . fetching = true
34
39
40
+ // TODO: It would be better to reuse these.
35
41
Object . values ( this . agentWatchers ) . forEach ( ( watcher ) => watcher . dispose ( ) )
36
42
43
+ // It is possible we called fetchAndRefresh() manually (through the button
44
+ // for example), in which case we might still have a pending refresh that
45
+ // needs to be cleared.
46
+ this . cancelPendingRefresh ( )
47
+
37
48
try {
38
49
this . workspaces = await this . fetch ( )
50
+ this . fetching = false
51
+ this . maybeScheduleRefresh ( )
39
52
} catch ( error ) {
40
53
this . workspaces = [ ]
54
+ this . fetching = false
41
55
}
42
56
43
57
this . refresh ( )
44
- this . fetching = false
45
58
}
46
59
47
60
/**
@@ -73,6 +86,37 @@ export class WorkspaceProvider implements vscode.TreeDataProvider<vscode.TreeIte
73
86
} )
74
87
}
75
88
89
+ /**
90
+ * Either start or stop the refresh timer based on visibility.
91
+ */
92
+ setVisibility ( visible : boolean ) {
93
+ this . visible = visible
94
+ if ( ! visible ) {
95
+ this . cancelPendingRefresh ( )
96
+ } else {
97
+ this . maybeScheduleRefresh ( )
98
+ }
99
+ }
100
+
101
+ private cancelPendingRefresh ( ) {
102
+ if ( this . timeout ) {
103
+ clearTimeout ( this . timeout )
104
+ this . timeout = undefined
105
+ }
106
+ }
107
+
108
+ /**
109
+ * Schedule a refresh if one is not already scheduled or underway and a
110
+ * timeout length was provided.
111
+ */
112
+ private maybeScheduleRefresh ( ) {
113
+ if ( this . timerSeconds && ! this . timeout && ! this . fetching ) {
114
+ this . timeout = setTimeout ( ( ) => {
115
+ this . fetchAndRefresh ( )
116
+ } , this . timerSeconds * 1000 )
117
+ }
118
+ }
119
+
76
120
private _onDidChangeTreeData : vscode . EventEmitter < vscode . TreeItem | undefined | null | void > =
77
121
new vscode . EventEmitter < vscode . TreeItem | undefined | null | void > ( )
78
122
readonly onDidChangeTreeData : vscode . Event < vscode . TreeItem | undefined | null | void > =
0 commit comments