@@ -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. Trying
32+ // to call 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, so
45+ // clear it just in case.
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 /**
@@ -73,6 +86,37 @@ export class WorkspaceProvider implements vscode.TreeDataProvider<vscode.TreeIte
7386 } )
7487 }
7588
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+
76120 private _onDidChangeTreeData : vscode . EventEmitter < vscode . TreeItem | undefined | null | void > =
77121 new vscode . EventEmitter < vscode . TreeItem | undefined | null | void > ( )
78122 readonly onDidChangeTreeData : vscode . Event < vscode . TreeItem | undefined | null | void > =
0 commit comments