Skip to content

Commit 70cf3be

Browse files
committed
Adds tracking of active repo
1 parent 23aa131 commit 70cf3be

File tree

6 files changed

+101
-15
lines changed

6 files changed

+101
-15
lines changed

src/webviews/apps/plus/home/components/active-work.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,7 @@ export class GlActiveWork extends SignalWatcher(LitElement) {
3737
override connectedCallback() {
3838
super.connectedCallback();
3939

40-
if (this._overviewState.state.value == null) {
41-
this._overviewState.run();
42-
}
40+
this._overviewState.run();
4341
}
4442

4543
override render() {

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

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,7 @@ export class GlOverview extends SignalWatcher(LitElement) {
3333
override connectedCallback() {
3434
super.connectedCallback();
3535

36-
if (this._overviewState.state.value == null) {
37-
this._overviewState.run();
38-
}
36+
this._overviewState.run();
3937
}
4038

4139
override render() {

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

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
import { createContext } from '@lit/context';
22
import type { GetOverviewResponse } from '../../../../home/protocol';
3-
import { GetOverview } from '../../../../home/protocol';
3+
import { DidChangeRepositoryWip, GetOverview } from '../../../../home/protocol';
44
import { AsyncComputedState } from '../../../shared/components/signal-utils';
5+
import type { Disposable } from '../../../shared/events';
56
import type { HostIpc } from '../../../shared/ipc';
67

78
export type Overview = GetOverviewResponse;
89

910
export class OverviewState extends AsyncComputedState<Overview> {
11+
private _disposable: Disposable | undefined;
12+
1013
constructor(
1114
private _ipc: HostIpc,
1215
options?: {
@@ -19,6 +22,18 @@ export class OverviewState extends AsyncComputedState<Overview> {
1922

2023
return rsp;
2124
}, options);
25+
26+
this._disposable = this._ipc.onReceiveMessage(msg => {
27+
switch (true) {
28+
case DidChangeRepositoryWip.is(msg):
29+
this.run(true);
30+
break;
31+
}
32+
});
33+
}
34+
35+
dispose() {
36+
this._disposable?.dispose();
2237
}
2338
}
2439

src/webviews/apps/shared/components/signal-utils.ts

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { signal } from '@lit-labs/signals';
12
import { AsyncComputed } from 'signal-utils/async-computed';
23

34
export const renderAsyncComputed = <T, R = unknown>(
@@ -27,10 +28,17 @@ export const renderAsyncComputed = <T, R = unknown>(
2728
};
2829

2930
export class AsyncComputedState<T, R = unknown> {
31+
private _invalidate = signal(0);
3032
private _initial?: T;
3133
private _state?: AsyncComputed<T>;
3234
get state() {
33-
this._state ??= new AsyncComputed(this._fetch, this._initial ? { initialValue: this._initial } : undefined);
35+
this._state ??= new AsyncComputed(
36+
(abortSignal: AbortSignal) => {
37+
this._invalidate.get();
38+
return this._fetch(abortSignal);
39+
},
40+
this._initial ? { initialValue: this._initial } : undefined,
41+
);
3442
return this._state;
3543
}
3644

@@ -48,10 +56,17 @@ export class AsyncComputedState<T, R = unknown> {
4856
}
4957
}
5058
}
51-
run() {
59+
run(force = false) {
60+
if (force) {
61+
this.invalidate();
62+
}
5263
this.state.run();
5364
}
5465

66+
invalidate() {
67+
this._invalidate.set(Date.now());
68+
}
69+
5570
render(config: {
5671
initial?: () => R;
5772
pending?: () => R;

src/webviews/home/homeWebview.ts

Lines changed: 64 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import type { Container } from '../../container';
77
import type { BranchContributorOverview } from '../../git/gitProvider';
88
import { sortBranches } from '../../git/models/branch';
99
import type { PullRequest } from '../../git/models/pullRequest';
10+
import type { Repository } from '../../git/models/repository';
11+
import { RepositoryChange, RepositoryChangeComparisonMode } from '../../git/models/repository';
1012
import type { GitStatus } from '../../git/models/status';
1113
import { getOpenedWorktreesByBranch, groupWorktreesByBranch } from '../../git/models/worktree';
1214
import type { Subscription } from '../../plus/gk/account/subscription';
@@ -34,6 +36,7 @@ import {
3436
DidChangeOrgSettings,
3537
DidChangePreviewEnabled,
3638
DidChangeRepositories,
39+
DidChangeRepositoryWip,
3740
DidChangeSubscription,
3841
DidChangeWalkthroughProgress,
3942
DidFocusAccount,
@@ -49,6 +52,8 @@ const emptyDisposable = Object.freeze({
4952
},
5053
});
5154

55+
type RepositorySubscription = { repo: Repository; subscription: Disposable };
56+
5257
export class HomeWebviewProvider implements WebviewProvider<State, State, HomeWebviewShowingArgs> {
5358
private readonly _disposable: Disposable;
5459
private _pendingFocusAccount = false;
@@ -138,7 +143,7 @@ export class HomeWebviewProvider implements WebviewProvider<State, State, HomeWe
138143
void this.host.respond(GetLaunchpadSummary, e, await getLaunchpadSummary(this.container));
139144
break;
140145
case GetOverview.is(e):
141-
void this.host.respond(GetOverview, e, await getBranchOverview(this.container));
146+
void this.host.respond(GetOverview, e, await this.getBranchOverview());
142147
break;
143148
}
144149
}
@@ -260,6 +265,63 @@ export class HomeWebviewProvider implements WebviewProvider<State, State, HomeWe
260265
};
261266
}
262267

268+
private async getBranchOverview(): Promise<GetOverviewResponse | undefined> {
269+
const repo = this.getSelectedRepository();
270+
if (repo == null) return undefined;
271+
272+
return getBranchOverview(repo, this.container);
273+
}
274+
275+
private _repositorySubscription: RepositorySubscription | undefined;
276+
private selectRepository(repoPath?: string) {
277+
let repo: Repository | undefined;
278+
if (repoPath != null) {
279+
repo = this.container.git.getRepository(repoPath)!;
280+
} else {
281+
repo = this.container.git.highlander;
282+
if (repo == null) {
283+
repo = this.container.git.getBestRepositoryOrFirst();
284+
}
285+
}
286+
287+
if (this._repositorySubscription != null) {
288+
this._repositorySubscription.subscription.dispose();
289+
this._repositorySubscription = undefined;
290+
}
291+
if (repo != null) {
292+
this._repositorySubscription = {
293+
repo: repo,
294+
subscription: this.subscribeToRepository(repo),
295+
};
296+
}
297+
298+
return repo;
299+
}
300+
301+
private subscribeToRepository(repo: Repository): Disposable {
302+
return Disposable.from(
303+
repo.watchFileSystem(1000),
304+
repo.onDidChangeFileSystem(() => this.onWipChanged(repo)),
305+
repo.onDidChange(e => {
306+
if (e.changed(RepositoryChange.Index, RepositoryChangeComparisonMode.Any)) {
307+
this.onWipChanged(repo);
308+
}
309+
}),
310+
);
311+
}
312+
313+
private onWipChanged(_repo: Repository) {
314+
void this.host.notify(DidChangeRepositoryWip, undefined);
315+
}
316+
317+
private getSelectedRepository() {
318+
if (this._repositorySubscription == null) {
319+
this.selectRepository();
320+
}
321+
322+
return this._repositorySubscription?.repo;
323+
}
324+
263325
private _hostedIntegrationConnected: boolean | undefined;
264326
private isAnyIntegrationConnected(force = false) {
265327
if (this._hostedIntegrationConnected == null || force === true) {
@@ -346,14 +408,10 @@ interface BranchOverviewOptions {
346408
}
347409

348410
async function getBranchOverview(
411+
repo: Repository,
349412
container: Container,
350413
options?: BranchOverviewOptions,
351414
): Promise<GetOverviewResponse | undefined> {
352-
const repo = container.git.highlander;
353-
if (repo == null) {
354-
return undefined;
355-
}
356-
357415
const [branchesResult, worktreesResult] = await Promise.allSettled([
358416
repo.git.getBranches({ filter: b => !b.remote }),
359417
repo.git.getWorktrees(),

src/webviews/home/protocol.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,8 @@ export const DismissWalkthroughSection = new IpcCommand<void>(scope, 'walkthroug
123123

124124
export const DidChangePreviewEnabled = new IpcNotification<boolean>(scope, 'previewEnabled/didChange');
125125

126+
export const DidChangeRepositoryWip = new IpcNotification<undefined>(scope, 'repository/wip/didChange');
127+
126128
export interface DidChangeRepositoriesParams {
127129
count: number;
128130
openCount: number;

0 commit comments

Comments
 (0)