Skip to content

Commit 71db241

Browse files
committed
Splits home overview state by active and inactive branches (wip)
1 parent 9b8e414 commit 71db241

File tree

6 files changed

+488
-43
lines changed

6 files changed

+488
-43
lines changed

src/webviews/apps/home/home.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,14 @@ import { customElement, query } from 'lit/decorators.js';
66
import { when } from 'lit/directives/when.js';
77
import type { State } from '../../home/protocol';
88
import { DidFocusAccount } from '../../home/protocol';
9-
import { OverviewState, overviewStateContext } from '../plus/home/components/overviewState';
9+
import {
10+
ActiveOverviewState,
11+
activeOverviewStateContext,
12+
InactiveOverviewState,
13+
inactiveOverviewStateContext,
14+
OverviewState,
15+
overviewStateContext,
16+
} from '../plus/home/components/overviewState';
1017
import type { GLHomeHeader } from '../plus/shared/components/home-header';
1118
import { GlApp } from '../shared/app';
1219
import { scrollableBase } from '../shared/components/styles/lit/base.css';
@@ -30,13 +37,21 @@ export class GlHomeApp extends GlApp<State> {
3037
@provide({ context: overviewStateContext })
3138
private _overviewState!: OverviewState;
3239

40+
@provide({ context: activeOverviewStateContext })
41+
private _activeOverviewState!: ActiveOverviewState;
42+
43+
@provide({ context: inactiveOverviewStateContext })
44+
private _inactiveOverviewState!: InactiveOverviewState;
45+
3346
@query('gl-home-header')
3447
private _header!: GLHomeHeader;
3548

3649
private badgeSource = { source: 'home', detail: 'badge' };
3750

3851
protected override createStateProvider(state: State, ipc: HostIpc) {
3952
this.disposables.push((this._overviewState = new OverviewState(ipc)));
53+
this.disposables.push((this._activeOverviewState = new ActiveOverviewState(ipc)));
54+
this.disposables.push((this._inactiveOverviewState = new InactiveOverviewState(ipc)));
4055

4156
return new HomeStateProvider(this, state, ipc);
4257
}

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

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@ import { ifDefined } from 'lit/directives/if-defined.js';
77
import { when } from 'lit/directives/when.js';
88
import { createCommandLink } from '../../../../../system/commands';
99
import { createWebviewCommandLink } from '../../../../../system/webview';
10-
import type { GetOverviewBranch, OpenInGraphParams, State } from '../../../../home/protocol';
10+
import type { GetActiveOverviewResponse, GetOverviewBranch, OpenInGraphParams, State } from '../../../../home/protocol';
1111
import { stateContext } from '../../../home/context';
1212
import { linkStyles } from '../../shared/components/vscode.css';
1313
import { branchCardStyles, GlBranchCardBase } from './branch-card';
14-
import type { Overview, OverviewState } from './overviewState';
15-
import { overviewStateContext } from './overviewState';
14+
import type { ActiveOverviewState } from './overviewState';
15+
import { activeOverviewStateContext } from './overviewState';
1616
import '../../../shared/components/button';
1717
import '../../../shared/components/code-icon';
1818
import '../../../shared/components/skeleton-loader';
@@ -62,14 +62,14 @@ export class GlActiveWork extends SignalWatcher(LitElement) {
6262
@state()
6363
private _homeState!: State;
6464

65-
@consume({ context: overviewStateContext })
66-
private _overviewState!: OverviewState;
65+
@consume({ context: activeOverviewStateContext })
66+
private _activeOverviewState!: ActiveOverviewState;
6767

6868
override connectedCallback() {
6969
super.connectedCallback();
7070

7171
if (this._homeState.repositories.openCount > 0) {
72-
this._overviewState.run();
72+
this._activeOverviewState.run();
7373
}
7474
}
7575

@@ -82,7 +82,7 @@ export class GlActiveWork extends SignalWatcher(LitElement) {
8282
return nothing;
8383
}
8484

85-
return this._overviewState.render({
85+
return this._activeOverviewState.render({
8686
pending: () => this.renderPending(),
8787
complete: overview => this.renderComplete(overview),
8888
error: () => html`<span>Error</span>`,
@@ -99,13 +99,13 @@ export class GlActiveWork extends SignalWatcher(LitElement) {
9999
}
100100

101101
private renderPending() {
102-
if (this._overviewState.state == null) {
102+
if (this._activeOverviewState.state == null) {
103103
return this.renderLoader();
104104
}
105-
return this.renderComplete(this._overviewState.state, true);
105+
return this.renderComplete(this._activeOverviewState.state, true);
106106
}
107107

108-
private renderComplete(overview: Overview, isFetching = false) {
108+
private renderComplete(overview: GetActiveOverviewResponse, isFetching = false) {
109109
const repo = overview?.repository;
110110
const activeBranches = repo?.branches?.active;
111111
if (!activeBranches) return html`<span>None</span>`;
@@ -138,7 +138,7 @@ export class GlActiveWork extends SignalWatcher(LitElement) {
138138
tooltip="Open in Commit Graph"
139139
href=${createCommandLink('gitlens.home.openInGraph', {
140140
type: 'repo',
141-
repoPath: this._overviewState.state!.repository.path,
141+
repoPath: this._activeOverviewState.state!.repository.path,
142142
} satisfies OpenInGraphParams)}
143143
><code-icon icon="gl-graph"></code-icon
144144
></gl-button>
@@ -191,7 +191,7 @@ export class GlActiveWork extends SignalWatcher(LitElement) {
191191
}
192192

193193
private onChange(_e: MouseEvent) {
194-
void this._overviewState.changeRepository();
194+
void this._activeOverviewState.changeRepository();
195195
}
196196
}
197197

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

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,17 @@ import { SignalWatcher } from '@lit-labs/signals';
33
import { css, html, LitElement, nothing } from 'lit';
44
import { customElement, state } from 'lit/decorators.js';
55
import { when } from 'lit/directives/when.js';
6-
import type { GetOverviewResponse, OverviewRecentThreshold, State } from '../../../../home/protocol';
6+
import type { GetInactiveOverviewResponse, OverviewRecentThreshold, State } from '../../../../home/protocol';
77
import { SetOverviewFilter } from '../../../../home/protocol';
88
import { stateContext } from '../../../home/context';
99
import { ipcContext } from '../../../shared/context';
1010
import type { HostIpc } from '../../../shared/ipc';
1111
import { linkStyles } from '../../shared/components/vscode.css';
12-
import type { OverviewState } from './overviewState';
13-
import { overviewStateContext } from './overviewState';
12+
import type { InactiveOverviewState } from './overviewState';
13+
import { inactiveOverviewStateContext } from './overviewState';
1414
import '../../../shared/components/skeleton-loader';
1515
import './branch-threshold-filter';
1616

17-
type Overview = GetOverviewResponse;
18-
1917
export const overviewTagName = 'gl-overview';
2018

2119
@customElement(overviewTagName)
@@ -35,14 +33,14 @@ export class GlOverview extends SignalWatcher(LitElement) {
3533
@state()
3634
private _homeState!: State;
3735

38-
@consume({ context: overviewStateContext })
39-
private _overviewState!: OverviewState;
36+
@consume({ context: inactiveOverviewStateContext })
37+
private _inactiveOverviewState!: InactiveOverviewState;
4038

4139
override connectedCallback() {
4240
super.connectedCallback();
4341

4442
if (this._homeState.repositories.openCount > 0) {
45-
this._overviewState.run();
43+
this._inactiveOverviewState.run();
4644
}
4745
}
4846

@@ -55,7 +53,7 @@ export class GlOverview extends SignalWatcher(LitElement) {
5553
return nothing;
5654
}
5755

58-
return this._overviewState.render({
56+
return this._inactiveOverviewState.render({
5957
pending: () => this.renderPending(),
6058
complete: summary => this.renderComplete(summary),
6159
error: () => html`<span>Error</span>`,
@@ -72,26 +70,26 @@ export class GlOverview extends SignalWatcher(LitElement) {
7270
}
7371

7472
private renderPending() {
75-
if (this._overviewState.state == null) {
73+
if (this._inactiveOverviewState.state == null) {
7674
return this.renderLoader();
7775
}
78-
return this.renderComplete(this._overviewState.state, true);
76+
return this.renderComplete(this._inactiveOverviewState.state, true);
7977
}
8078

8179
@consume({ context: ipcContext })
8280
private readonly _ipc!: HostIpc;
8381

8482
private onChangeRecentThresholdFilter(e: CustomEvent<{ threshold: OverviewRecentThreshold }>) {
85-
if (!this._overviewState.filter.stale || !this._overviewState.filter.recent) {
83+
if (!this._inactiveOverviewState.filter.stale || !this._inactiveOverviewState.filter.recent) {
8684
return;
8785
}
8886
this._ipc.sendCommand(SetOverviewFilter, {
89-
stale: this._overviewState.filter.stale,
90-
recent: { ...this._overviewState.filter.recent, threshold: e.detail.threshold },
87+
stale: this._inactiveOverviewState.filter.stale,
88+
recent: { ...this._inactiveOverviewState.filter.recent, threshold: e.detail.threshold },
9189
});
9290
}
9391

94-
private renderComplete(overview: Overview, isFetching = false) {
92+
private renderComplete(overview: GetInactiveOverviewResponse, isFetching = false) {
9593
if (overview == null) return nothing;
9694
const { repository } = overview;
9795
return html`
@@ -113,11 +111,11 @@ export class GlOverview extends SignalWatcher(LitElement) {
113111
label: string;
114112
}[]}
115113
.disabled=${isFetching}
116-
.value=${this._overviewState.filter.recent?.threshold}
114+
.value=${this._inactiveOverviewState.filter.recent?.threshold}
117115
></gl-branch-threshold-filter>
118116
</gl-branch-section>
119117
${when(
120-
this._overviewState.filter.stale?.show === true,
118+
this._inactiveOverviewState.filter.stale?.show === true,
121119
() => html`
122120
<gl-branch-section
123121
label="stale"

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

Lines changed: 88 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,18 @@
11
import { createContext } from '@lit/context';
22
import { signalObject } from 'signal-utils/object';
3-
import type { GetOverviewResponse, OverviewFilters } from '../../../../home/protocol';
3+
import type {
4+
GetActiveOverviewResponse,
5+
GetInactiveOverviewResponse,
6+
GetOverviewResponse,
7+
OverviewFilters,
8+
} from '../../../../home/protocol';
49
import {
510
ChangeOverviewRepository,
611
DidChangeOverviewFilter,
712
DidChangeRepositories,
813
DidChangeRepositoryWip,
14+
GetActiveOverview,
15+
GetInactiveOverview,
916
GetOverview,
1017
GetOverviewFilterState,
1118
} from '../../../../home/protocol';
@@ -14,6 +21,8 @@ import type { Disposable } from '../../../shared/events';
1421
import type { HostIpc } from '../../../shared/ipc';
1522

1623
export type Overview = GetOverviewResponse;
24+
export type ActiveOverview = GetActiveOverviewResponse;
25+
export type InactiveOverview = GetInactiveOverviewResponse;
1726

1827
export class OverviewState extends AsyncComputedState<Overview> {
1928
private readonly _disposable: Disposable | undefined;
@@ -64,4 +73,82 @@ export class OverviewState extends AsyncComputedState<Overview> {
6473
}
6574
}
6675

76+
export class ActiveOverviewState extends AsyncComputedState<ActiveOverview> {
77+
private readonly _disposable: Disposable | undefined;
78+
79+
constructor(
80+
private readonly _ipc: HostIpc,
81+
options?: {
82+
runImmediately?: boolean;
83+
initial?: ActiveOverview;
84+
},
85+
) {
86+
super(async _abortSignal => {
87+
const rsp: ActiveOverview = await this._ipc.sendRequest(GetActiveOverview, {});
88+
return rsp;
89+
}, options);
90+
91+
this._disposable = this._ipc.onReceiveMessage(msg => {
92+
switch (true) {
93+
case DidChangeRepositories.is(msg):
94+
this.run(true);
95+
break;
96+
case DidChangeRepositoryWip.is(msg):
97+
this.run(true);
98+
break;
99+
}
100+
});
101+
}
102+
103+
dispose() {
104+
this._disposable?.dispose();
105+
}
106+
107+
async changeRepository() {
108+
await this._ipc.sendRequest(ChangeOverviewRepository, undefined);
109+
this.run(true);
110+
}
111+
}
112+
113+
export class InactiveOverviewState extends AsyncComputedState<InactiveOverview> {
114+
private readonly _disposable: Disposable | undefined;
115+
filter = signalObject<Partial<OverviewFilters>>({});
116+
117+
constructor(
118+
private readonly _ipc: HostIpc,
119+
options?: {
120+
runImmediately?: boolean;
121+
initial?: InactiveOverview;
122+
},
123+
) {
124+
super(async _abortSignal => {
125+
const rsp: InactiveOverview = await this._ipc.sendRequest(GetInactiveOverview, {});
126+
return rsp;
127+
}, options);
128+
129+
this._disposable = this._ipc.onReceiveMessage(msg => {
130+
switch (true) {
131+
case DidChangeRepositories.is(msg):
132+
this.run(true);
133+
break;
134+
case DidChangeOverviewFilter.is(msg):
135+
this.filter.recent = msg.params.filter.recent;
136+
this.filter.stale = msg.params.filter.stale;
137+
this.run(true);
138+
break;
139+
}
140+
});
141+
void this._ipc.sendRequest(GetOverviewFilterState, undefined).then(rsp => {
142+
this.filter.recent = rsp.recent;
143+
this.filter.stale = rsp.stale;
144+
});
145+
}
146+
147+
dispose() {
148+
this._disposable?.dispose();
149+
}
150+
}
151+
67152
export const overviewStateContext = createContext<Overview>('overviewState');
153+
export const activeOverviewStateContext = createContext<ActiveOverview>('activeOverviewState');
154+
export const inactiveOverviewStateContext = createContext<InactiveOverview>('inactiveOverviewState');

0 commit comments

Comments
 (0)