Skip to content

Commit cc083c8

Browse files
committed
Fixes stale wip state in new home
1 parent d09b150 commit cc083c8

File tree

2 files changed

+116
-21
lines changed

2 files changed

+116
-21
lines changed

src/webviews/apps/plus/home/components/overviewState.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import type { GetOverviewResponse, OverviewFilters } from '../../../../home/prot
44
import {
55
ChangeOverviewRepository,
66
DidChangeOverviewFilter,
7+
DidChangeRepositories,
78
DidChangeRepositoryWip,
89
DidCompleteDiscoveringRepositories,
910
GetOverview,
@@ -38,6 +39,9 @@ export class OverviewState extends AsyncComputedState<Overview> {
3839
this.run(true);
3940
}
4041
break;
42+
case DidChangeRepositories.is(msg):
43+
this.run(true);
44+
break;
4145
case DidChangeRepositoryWip.is(msg):
4246
this.run(true);
4347
break;

src/webviews/home/homeWebview.ts

Lines changed: 112 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ import type { Subscription } from '../../plus/gk/account/subscription';
2525
import type { SubscriptionChangeEvent } from '../../plus/gk/account/subscriptionService';
2626
import { getLaunchpadSummary } from '../../plus/launchpad/utils';
2727
import { showRepositoryPicker } from '../../quickpicks/repositoryPicker';
28+
import type { Deferrable } from '../../system/function';
29+
import { debounce } from '../../system/function';
2830
import { map } from '../../system/iterable';
2931
import { getSettledValue } from '../../system/promise';
3032
import { executeActionCommand, executeCommand, registerCommand } from '../../system/vscode/command';
@@ -73,7 +75,7 @@ const emptyDisposable = Object.freeze({
7375
},
7476
});
7577

76-
type RepositorySubscription = { repo: Repository; subscription: Disposable };
78+
type RepositorySubscription = { repo: Repository; subscription?: Disposable };
7779
type RepositoryBranchData = {
7880
repo: Repository;
7981
branches: GitBranch[];
@@ -94,7 +96,7 @@ export class HomeWebviewProvider implements WebviewProvider<State, State, HomeWe
9496
this._disposable = Disposable.from(
9597
this.container.git.onDidChangeRepositories(this.onRepositoriesChanged, this),
9698
!workspace.isTrusted
97-
? workspace.onDidGrantWorkspaceTrust(this.notifyDidChangeRepositories, this)
99+
? workspace.onDidGrantWorkspaceTrust(() => this.notifyDidChangeRepositories(), this)
98100
: emptyDisposable,
99101
this.container.subscription.onDidChange(this.onSubscriptionChanged, this),
100102
onDidChangeContext(this.onContextChanged, this),
@@ -308,8 +310,13 @@ export class HomeWebviewProvider implements WebviewProvider<State, State, HomeWe
308310
return this.getState();
309311
}
310312

311-
onReloaded() {
313+
onRefresh() {
314+
this.resetBranchOverview();
312315
this.notifyDidChangeRepositories();
316+
}
317+
318+
onReloaded() {
319+
this.onRefresh();
313320
this.notifyDidChangeProgress();
314321
}
315322

@@ -321,6 +328,17 @@ export class HomeWebviewProvider implements WebviewProvider<State, State, HomeWe
321328
}
322329
}
323330

331+
onVisibilityChanged(visible: boolean) {
332+
if (!visible) {
333+
this.stopRepositorySubscription();
334+
335+
return;
336+
}
337+
338+
this.resumeRepositorySubscription();
339+
this.notifyDidChangeRepositories(true);
340+
}
341+
324342
private onTogglePreviewEnabled(isEnabled?: boolean) {
325343
if (isEnabled === undefined) {
326344
isEnabled = !this.getPreviewEnabled();
@@ -444,12 +462,16 @@ export class HomeWebviewProvider implements WebviewProvider<State, State, HomeWe
444462
const repo = this.getSelectedRepository();
445463
if (repo == null) return undefined;
446464

447-
const branchesAndWorktrees = await this.getBranchesData(repo);
465+
const forceRepo = this._invalidateOverview === 'repo';
466+
const forceWip = this._invalidateOverview !== undefined;
467+
const branchesAndWorktrees = await this.getBranchesData(repo, forceRepo);
448468
const overviewBranches = await getOverviewBranches(
449469
branchesAndWorktrees,
450470
this.container,
451471
this._overviewBranchFilter,
472+
forceWip ? { forceActive: true } : undefined,
452473
);
474+
this._invalidateOverview = undefined;
453475
if (overviewBranches == null) return undefined;
454476

455477
const result: GetOverviewResponse = {
@@ -476,7 +498,7 @@ export class HomeWebviewProvider implements WebviewProvider<State, State, HomeWe
476498
}
477499

478500
if (this._repositorySubscription != null) {
479-
this._repositorySubscription.subscription.dispose();
501+
this._repositorySubscription.subscription?.dispose();
480502
this._repositorySubscription = undefined;
481503
}
482504
if (repo != null) {
@@ -489,10 +511,41 @@ export class HomeWebviewProvider implements WebviewProvider<State, State, HomeWe
489511
return repo;
490512
}
491513

514+
private stopRepositorySubscription() {
515+
if (this._repositorySubscription != null) {
516+
this._repositorySubscription.subscription?.dispose();
517+
this._repositorySubscription.subscription = undefined;
518+
}
519+
}
520+
521+
private resumeRepositorySubscription(force = false) {
522+
if (this._repositorySubscription == null) {
523+
return;
524+
}
525+
526+
if (force || this._repositorySubscription.subscription == null) {
527+
this._repositorySubscription.subscription?.dispose();
528+
this._repositorySubscription.subscription = undefined;
529+
this._repositorySubscription.subscription = this.subscribeToRepository(this._repositorySubscription.repo);
530+
}
531+
}
532+
533+
private resetBranchOverview() {
534+
this._repositoryBranches.clear();
535+
536+
if (!this.host.visible) {
537+
this.stopRepositorySubscription();
538+
return;
539+
}
540+
541+
this.resumeRepositorySubscription(true);
542+
}
543+
492544
private subscribeToRepository(repo: Repository): Disposable {
493545
return Disposable.from(
546+
// TODO: advanced confiugration for the watchFileSystem timing
494547
repo.watchFileSystem(1000),
495-
repo.onDidChangeFileSystem(() => this.onWipChanged(repo)),
548+
repo.onDidChangeFileSystem(() => this.onOverviewRepoChanged('wip')),
496549
repo.onDidChange(e => {
497550
if (
498551
e.changed(
@@ -505,15 +558,23 @@ export class HomeWebviewProvider implements WebviewProvider<State, State, HomeWe
505558
RepositoryChangeComparisonMode.Any,
506559
)
507560
) {
508-
this.onWipChanged(repo);
561+
this.onOverviewRepoChanged('repo');
509562
}
510563
}),
511564
);
512565
}
513566

514-
private onWipChanged(_repo: Repository) {
515-
this._invalidateRepositoryBranches = true;
516-
void this.host.notify(DidChangeRepositoryWip, undefined);
567+
private onOverviewRepoChanged(scope: 'repo' | 'wip') {
568+
if (this._invalidateOverview !== 'repo') {
569+
this._invalidateOverview = scope;
570+
}
571+
if (!this.host.visible) return;
572+
573+
if (scope === 'wip') {
574+
void this.host.notify(DidChangeRepositoryWip, undefined);
575+
} else {
576+
this.notifyDidChangeRepositories();
577+
}
517578
}
518579

519580
private getSelectedRepository() {
@@ -524,9 +585,9 @@ export class HomeWebviewProvider implements WebviewProvider<State, State, HomeWe
524585
return this._repositorySubscription?.repo;
525586
}
526587

527-
private _invalidateRepositoryBranches = true;
588+
private _invalidateOverview: 'repo' | 'wip' | undefined;
528589
private readonly _repositoryBranches: Map<string, RepositoryBranchData> = new Map();
529-
private async getBranchesData(repo: Repository, force = this._invalidateRepositoryBranches) {
590+
private async getBranchesData(repo: Repository, force = false) {
530591
if (force || !this._repositoryBranches.has(repo.path)) {
531592
const worktrees = (await repo.git.getWorktrees()) ?? [];
532593
const worktreesByBranch = groupWorktreesByBranch(worktrees);
@@ -539,7 +600,6 @@ export class HomeWebviewProvider implements WebviewProvider<State, State, HomeWe
539600

540601
const branches = getSettledValue(branchesResult)?.values ?? [];
541602

542-
this._invalidateRepositoryBranches = false;
543603
this._repositoryBranches.set(repo.path, {
544604
repo: repo,
545605
branches: branches,
@@ -587,9 +647,22 @@ export class HomeWebviewProvider implements WebviewProvider<State, State, HomeWe
587647
});
588648
}
589649

590-
private notifyDidChangeRepositories() {
650+
private notifyDidChangeRepositoriesCore() {
591651
void this.host.notify(DidChangeRepositories, this.getRepositoriesState());
592652
}
653+
private _notifyDidChangeRepositoriesDebounced: Deferrable<() => void> | undefined = undefined;
654+
private notifyDidChangeRepositories(immediate = false) {
655+
if (immediate) {
656+
this.notifyDidChangeRepositoriesCore();
657+
return;
658+
}
659+
660+
if (this._notifyDidChangeRepositoriesDebounced == null) {
661+
this._notifyDidChangeRepositoriesDebounced = debounce(this.notifyDidChangeRepositoriesCore.bind(this), 500);
662+
}
663+
664+
this._notifyDidChangeRepositoriesDebounced();
665+
}
593666

594667
private notifyDidChangeProgress() {
595668
void this.host.notify(DidChangeWalkthroughProgress, {
@@ -745,7 +818,8 @@ const thresholdValues: Record<OverviewStaleThreshold | OverviewRecentThreshold,
745818
async function getOverviewBranches(
746819
branchesData: RepositoryBranchData,
747820
container: Container,
748-
options: OverviewFilters,
821+
filters: OverviewFilters,
822+
options?: { forceActive?: boolean },
749823
): Promise<GetOverviewBranches | undefined> {
750824
const { branches, worktreesByBranch } = branchesData;
751825
if (branches.length === 0) return undefined;
@@ -756,22 +830,29 @@ async function getOverviewBranches(
756830
stale: [],
757831
};
758832

833+
let repoStatusPromise: Promise<GitStatus | undefined> | undefined;
759834
const prPromises = new Map<string, Promise<PullRequest | undefined>>();
760835
const statusPromises = new Map<string, Promise<GitStatus | undefined>>();
761836
const contributorPromises = new Map<string, Promise<BranchContributorOverview | undefined>>();
762837

763838
const now = Date.now();
764-
const recentThreshold = now - thresholdValues[options.recent.threshold];
839+
const recentThreshold = now - thresholdValues[filters.recent.threshold];
765840

766841
for (const branch of branches) {
767842
const wt = worktreesByBranch.get(branch.id);
768843
const worktree: GetOverviewBranch['worktree'] = wt ? { name: wt.name, uri: wt.uri.toString() } : undefined;
769844

770845
const timestamp = branch.date?.getTime();
771846
if (branch.current || wt?.opened) {
847+
const forceOptions = options?.forceActive ? { force: true } : undefined;
772848
prPromises.set(branch.id, branch.getAssociatedPullRequest({ avatarSize: 16 }));
773849
if (wt != null) {
774-
statusPromises.set(branch.id, wt.getStatus());
850+
statusPromises.set(branch.id, wt.getStatus(forceOptions));
851+
} else {
852+
if (repoStatusPromise === undefined) {
853+
repoStatusPromise = container.git.getStatus(branch.repoPath);
854+
}
855+
statusPromises.set(branch.id, repoStatusPromise);
775856
}
776857
contributorPromises.set(branch.id, container.git.getBranchContributorOverview(branch.repoPath, branch.ref));
777858

@@ -811,8 +892,8 @@ async function getOverviewBranches(
811892
}
812893
}
813894

814-
if (options?.stale?.show === true) {
815-
const staleThreshold = now - thresholdValues[options.stale.threshold];
895+
if (filters?.stale?.show === true) {
896+
const staleThreshold = now - thresholdValues[filters.stale.threshold];
816897
sortBranches(branches, {
817898
missingUpstream: true,
818899
orderBy: 'date:asc',
@@ -861,6 +942,18 @@ async function getOverviewBranches(
861942
}
862943
}
863944

945+
await enrichOverviewBranches(overviewBranches, prPromises, statusPromises, contributorPromises);
946+
947+
return overviewBranches;
948+
}
949+
950+
// FIXME: support partial enrichment
951+
async function enrichOverviewBranches(
952+
overviewBranches: GetOverviewBranches,
953+
prPromises: Map<string, Promise<PullRequest | undefined>>,
954+
statusPromises: Map<string, Promise<GitStatus | undefined>>,
955+
contributorPromises: Map<string, Promise<BranchContributorOverview | undefined>>,
956+
) {
864957
const [prResults, statusResults, contributorResults] = await Promise.allSettled([
865958
Promise.allSettled(map(prPromises, ([id, pr]) => pr.then<[string, PullRequest | undefined]>(pr => [id, pr]))),
866959
Promise.allSettled(
@@ -941,6 +1034,4 @@ async function getOverviewBranches(
9411034
branch.contributors = contributors;
9421035
}
9431036
}
944-
945-
return overviewBranches;
9461037
}

0 commit comments

Comments
 (0)