@@ -14,34 +14,53 @@ 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
+
48
+ let hadError = false
37
49
try {
38
50
this . workspaces = await this . fetch ( )
39
51
} catch ( error ) {
52
+ hadError = true
40
53
this . workspaces = [ ]
41
54
}
42
55
43
- this . refresh ( )
44
56
this . fetching = false
57
+
58
+ this . refresh ( )
59
+
60
+ // As long as there was no error we can schedule the next refresh.
61
+ if ( hadError ) {
62
+ this . maybeScheduleRefresh ( )
63
+ }
45
64
}
46
65
47
66
/**
@@ -82,6 +101,37 @@ export class WorkspaceProvider implements vscode.TreeDataProvider<vscode.TreeIte
82
101
} )
83
102
}
84
103
104
+ /**
105
+ * Either start or stop the refresh timer based on visibility.
106
+ */
107
+ setVisibility ( visible : boolean ) {
108
+ this . visible = visible
109
+ if ( ! visible ) {
110
+ this . cancelPendingRefresh ( )
111
+ } else {
112
+ this . maybeScheduleRefresh ( )
113
+ }
114
+ }
115
+
116
+ private cancelPendingRefresh ( ) {
117
+ if ( this . timeout ) {
118
+ clearTimeout ( this . timeout )
119
+ this . timeout = undefined
120
+ }
121
+ }
122
+
123
+ /**
124
+ * Schedule a refresh if one is not already scheduled or underway and a
125
+ * timeout length was provided.
126
+ */
127
+ private maybeScheduleRefresh ( ) {
128
+ if ( this . timerSeconds && ! this . timeout && ! this . fetching ) {
129
+ this . timeout = setTimeout ( ( ) => {
130
+ this . fetchAndRefresh ( )
131
+ } , this . timerSeconds * 1000 )
132
+ }
133
+ }
134
+
85
135
private _onDidChangeTreeData : vscode . EventEmitter < vscode . TreeItem | undefined | null | void > =
86
136
new vscode . EventEmitter < vscode . TreeItem | undefined | null | void > ( )
87
137
readonly onDidChangeTreeData : vscode . Event < vscode . TreeItem | undefined | null | void > =
0 commit comments