@@ -14,34 +14,47 @@ export enum WorkspaceQuery {
1414export class WorkspaceProvider implements vscode . TreeDataProvider < vscode . TreeItem > {
1515 private workspaces : WorkspaceTreeItem [ ] = [ ]
1616 private agentWatchers : Record < WorkspaceAgent [ "id" ] , { dispose : ( ) => void ; metadata ?: AgentMetadataEvent [ ] } > = { }
17+ private timeout : NodeJS . Timeout | undefined
18+ private visible = false
1719 private fetching = false
1820
1921 constructor (
2022 private readonly getWorkspacesQuery : WorkspaceQuery ,
2123 private readonly storage : Storage ,
24+ private readonly timerSeconds ?: number ,
2225 ) {
2326 this . fetchAndRefresh ( )
2427 }
2528
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
2833 // immediately.
2934 async fetchAndRefresh ( ) {
3035 if ( this . fetching ) {
3136 return
3237 }
3338 this . fetching = true
3439
40+ // TODO: It would be better to reuse these.
3541 Object . values ( this . agentWatchers ) . forEach ( ( watcher ) => watcher . dispose ( ) )
3642
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+
3748 try {
3849 this . workspaces = await this . fetch ( )
50+ this . fetching = false
51+ this . maybeScheduleRefresh ( )
3952 } catch ( error ) {
4053 this . workspaces = [ ]
54+ this . fetching = false
4155 }
4256
4357 this . refresh ( )
44- this . fetching = false
4558 }
4659
4760 /**
@@ -82,6 +95,37 @@ export class WorkspaceProvider implements vscode.TreeDataProvider<vscode.TreeIte
8295 } )
8396 }
8497
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+
85129 private _onDidChangeTreeData : vscode . EventEmitter < vscode . TreeItem | undefined | null | void > =
86130 new vscode . EventEmitter < vscode . TreeItem | undefined | null | void > ( )
87131 readonly onDidChangeTreeData : vscode . Event < vscode . TreeItem | undefined | null | void > =
0 commit comments