@@ -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
/**
@@ -82,6 +95,37 @@ export class WorkspaceProvider implements vscode.TreeDataProvider<vscode.TreeIte
82
95
} )
83
96
}
84
97
98
+ /**
99
+ * Either start or stop the refresh timer based on visibility.
100
+ */
101
+ setVisibility ( visible : boolean ) {
102
+ this . visible = visible
103
+ if ( ! visible ) {
104
+ this . cancelPendingRefresh ( )
105
+ } else {
106
+ this . maybeScheduleRefresh ( )
107
+ }
108
+ }
109
+
110
+ private cancelPendingRefresh ( ) {
111
+ if ( this . timeout ) {
112
+ clearTimeout ( this . timeout )
113
+ this . timeout = undefined
114
+ }
115
+ }
116
+
117
+ /**
118
+ * Schedule a refresh if one is not already scheduled or underway and a
119
+ * timeout length was provided.
120
+ */
121
+ private maybeScheduleRefresh ( ) {
122
+ if ( this . timerSeconds && ! this . timeout && ! this . fetching ) {
123
+ this . timeout = setTimeout ( ( ) => {
124
+ this . fetchAndRefresh ( )
125
+ } , this . timerSeconds * 1000 )
126
+ }
127
+ }
128
+
85
129
private _onDidChangeTreeData : vscode . EventEmitter < vscode . TreeItem | undefined | null | void > =
86
130
new vscode . EventEmitter < vscode . TreeItem | undefined | null | void > ( )
87
131
readonly onDidChangeTreeData : vscode . Event < vscode . TreeItem | undefined | null | void > =
0 commit comments