Skip to content

Commit

Permalink
Adds new SubscriptionManager helper class
Browse files Browse the repository at this point in the history
Adopts it in the Home view to manage repo events
  • Loading branch information
eamodio committed Feb 27, 2025
1 parent 54f3988 commit 369c95c
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 40 deletions.
40 changes: 40 additions & 0 deletions src/system/subscriptionManager.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
type Status = 'started' | 'paused' | 'stopped';

export class SubscriptionManager<T> {
private _status: Status = 'stopped';
get status(): Status {
return this._status;
}

private _subscription: { dispose: () => void } | undefined;

constructor(
public readonly source: T,
private readonly subscribe: (source: T) => { dispose: () => void },
) {}

dispose(): void {
this.stop();
}

start(): void {
if (this._subscription != null && this._status === 'started') return;

this._subscription = this.subscribe(this.source);
this._status = 'started';
}

pause(): void {
this.stop('paused');
}

resume(): void {
this.start();
}

private stop(status?: Status): void {
this._subscription?.dispose();
this._subscription = undefined;
this._status = status ?? 'stopped';
}
}
58 changes: 18 additions & 40 deletions src/webviews/home/homeWebview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ import type { Deferrable } from '../../system/function/debounce';
import { debounce } from '../../system/function/debounce';
import { filterMap } from '../../system/iterable';
import { getSettledValue } from '../../system/promise';
import { SubscriptionManager } from '../../system/subscriptionManager';
import type { ShowInCommitGraphCommandArgs } from '../plus/graph/protocol';
import type { Change } from '../plus/patchDetails/protocol';
import type { IpcMessage } from '../protocol';
Expand Down Expand Up @@ -115,10 +116,6 @@ const emptyDisposable = Object.freeze({
},
});

interface RepositorySubscription {
repo: Repository;
subscription?: Disposable;
}
interface RepositoryBranchData {
repo: Repository;
branches: GitBranch[];
Expand Down Expand Up @@ -407,10 +404,10 @@ export class HomeWebviewProvider implements WebviewProvider<State, State, HomeWe
}

private hasRepositoryChanged(): boolean {
if (this._repositorySubscription?.repo != null) {
if (this._repositorySubscription?.source != null) {
if (
this._repositorySubscription.repo.etag !== this._etagRepository ||
this._repositorySubscription.repo.etagFileSystem !== this._etagFileSystem
this._repositorySubscription.source.etag !== this._etagRepository ||
this._repositorySubscription.source.etagFileSystem !== this._etagFileSystem
) {
return true;
}
Expand All @@ -423,12 +420,12 @@ export class HomeWebviewProvider implements WebviewProvider<State, State, HomeWe

onVisibilityChanged(visible: boolean): void {
if (!visible) {
this.stopRepositorySubscription();
this._repositorySubscription?.pause();

return;
}

this.resumeRepositorySubscription();
this._repositorySubscription?.resume();

if (
this._discovering == null &&
Expand Down Expand Up @@ -860,7 +857,7 @@ export class HomeWebviewProvider implements WebviewProvider<State, State, HomeWe
};
}

private _repositorySubscription: RepositorySubscription | undefined;
private _repositorySubscription: SubscriptionManager<Repository> | undefined;
private selectRepository(repoPath?: string) {
let repo: Repository | undefined;
if (repoPath != null) {
Expand All @@ -872,48 +869,29 @@ export class HomeWebviewProvider implements WebviewProvider<State, State, HomeWe
}
}

if (this._repositorySubscription != null) {
this._repositorySubscription.subscription?.dispose();
this._repositorySubscription = undefined;
}
this._repositorySubscription?.dispose();
this._repositorySubscription = undefined;

if (repo != null) {
this._repositorySubscription = {
repo: repo,
subscription: this.subscribeToRepository(repo),
};
this._repositorySubscription = new SubscriptionManager(repo, r => this.subscribeToRepository(r));
// Start the subscription immediately if webview is visible
if (this.host.visible) {
this._repositorySubscription.start();
}
}

return repo;
}

private stopRepositorySubscription() {
if (this._repositorySubscription != null) {
this._repositorySubscription.subscription?.dispose();
this._repositorySubscription.subscription = undefined;
}
}

private resumeRepositorySubscription(force = false) {
if (this._repositorySubscription == null) {
return;
}

if (force || this._repositorySubscription.subscription == null) {
this._repositorySubscription.subscription?.dispose();
this._repositorySubscription.subscription = undefined;
this._repositorySubscription.subscription = this.subscribeToRepository(this._repositorySubscription.repo);
}
}

private resetBranchOverview() {
this._repositoryBranches.clear();

if (!this.host.visible) {
this.stopRepositorySubscription();
this._repositorySubscription?.pause();
return;
}

this.resumeRepositorySubscription(true);
this._repositorySubscription?.resume();
}

private subscribeToRepository(repo: Repository): Disposable {
Expand Down Expand Up @@ -977,7 +955,7 @@ export class HomeWebviewProvider implements WebviewProvider<State, State, HomeWe
this.selectRepository();
}

return this._repositorySubscription?.repo;
return this._repositorySubscription?.source;
}

private _invalidateOverview: 'repo' | 'wip' | undefined;
Expand Down

0 comments on commit 369c95c

Please sign in to comment.