Skip to content

Commit

Permalink
Splits home overview state by active and inactive branches
Browse files Browse the repository at this point in the history
  • Loading branch information
d13 committed Jan 27, 2025
1 parent d1f6477 commit 5f4aaa8
Show file tree
Hide file tree
Showing 6 changed files with 331 additions and 261 deletions.
17 changes: 13 additions & 4 deletions src/webviews/apps/home/home.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@ import { customElement, query } from 'lit/decorators.js';
import { when } from 'lit/directives/when.js';
import type { State } from '../../home/protocol';
import { DidFocusAccount } from '../../home/protocol';
import { OverviewState, overviewStateContext } from '../plus/home/components/overviewState';
import {
ActiveOverviewState,
activeOverviewStateContext,
InactiveOverviewState,
inactiveOverviewStateContext,
} from '../plus/home/components/overviewState';
import type { GLHomeHeader } from '../plus/shared/components/home-header';
import { GlApp } from '../shared/app';
import { scrollableBase } from '../shared/components/styles/lit/base.css';
Expand All @@ -27,16 +32,20 @@ import './components/repo-alerts';
export class GlHomeApp extends GlApp<State> {
static override styles = [homeBaseStyles, scrollableBase, homeStyles];

@provide({ context: overviewStateContext })
private _overviewState!: OverviewState;
@provide({ context: activeOverviewStateContext })
private _activeOverviewState!: ActiveOverviewState;

@provide({ context: inactiveOverviewStateContext })
private _inactiveOverviewState!: InactiveOverviewState;

@query('gl-home-header')
private _header!: GLHomeHeader;

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

protected override createStateProvider(state: State, ipc: HostIpc): HomeStateProvider {
this.disposables.push((this._overviewState = new OverviewState(ipc)));
this.disposables.push((this._activeOverviewState = new ActiveOverviewState(ipc)));
this.disposables.push((this._inactiveOverviewState = new InactiveOverviewState(ipc)));

return new HomeStateProvider(this, state, ipc);
}
Expand Down
32 changes: 15 additions & 17 deletions src/webviews/apps/plus/home/components/active-work.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ import { ifDefined } from 'lit/directives/if-defined.js';
import { when } from 'lit/directives/when.js';
import { createCommandLink } from '../../../../../system/commands';
import { createWebviewCommandLink } from '../../../../../system/webview';
import type { GetOverviewBranch, OpenInGraphParams, State } from '../../../../home/protocol';
import type { GetActiveOverviewResponse, GetOverviewBranch, OpenInGraphParams, State } from '../../../../home/protocol';
import { stateContext } from '../../../home/context';
import { linkStyles } from '../../shared/components/vscode.css';
import { branchCardStyles, GlBranchCardBase } from './branch-card';
import type { Overview, OverviewState } from './overviewState';
import { overviewStateContext } from './overviewState';
import type { ActiveOverviewState } from './overviewState';
import { activeOverviewStateContext } from './overviewState';
import '../../../shared/components/button';
import '../../../shared/components/code-icon';
import '../../../shared/components/skeleton-loader';
Expand Down Expand Up @@ -62,14 +62,14 @@ export class GlActiveWork extends SignalWatcher(LitElement) {
@state()
private _homeState!: State;

@consume({ context: overviewStateContext })
private _overviewState!: OverviewState;
@consume({ context: activeOverviewStateContext })
private _activeOverviewState!: ActiveOverviewState;

override connectedCallback(): void {
super.connectedCallback();

if (this._homeState.repositories.openCount > 0) {
this._overviewState.run();
this._activeOverviewState.run();
}
}

Expand All @@ -82,7 +82,7 @@ export class GlActiveWork extends SignalWatcher(LitElement) {
return nothing;
}

return this._overviewState.render({
return this._activeOverviewState.render({
pending: () => this.renderPending(),
complete: overview => this.renderComplete(overview),
error: () => html`<span>Error</span>`,
Expand All @@ -99,16 +99,16 @@ export class GlActiveWork extends SignalWatcher(LitElement) {
}

private renderPending() {
if (this._overviewState.state == null) {
if (this._activeOverviewState.state == null) {
return this.renderLoader();
}
return this.renderComplete(this._overviewState.state, true);
return this.renderComplete(this._activeOverviewState.state, true);
}

private renderComplete(overview: Overview, isFetching = false) {
private renderComplete(overview: GetActiveOverviewResponse, isFetching = false) {
const repo = overview?.repository;
const activeBranches = repo?.branches?.active;
if (!activeBranches) return html`<span>None</span>`;
const activeBranch = overview?.active;
if (!repo || !activeBranch) return html`<span>None</span>`;

return html`
<gl-section ?loading=${isFetching}>
Expand Down Expand Up @@ -138,7 +138,7 @@ export class GlActiveWork extends SignalWatcher(LitElement) {
tooltip="Open in Commit Graph"
href=${createCommandLink('gitlens.home.openInGraph', {
type: 'repo',
repoPath: this._overviewState.state!.repository.path,
repoPath: this._activeOverviewState.state!.repository.path,
} satisfies OpenInGraphParams)}
><code-icon icon="gl-graph"></code-icon
></gl-button>
Expand All @@ -152,9 +152,7 @@ export class GlActiveWork extends SignalWatcher(LitElement) {
><code-icon icon="repo-fetch"></code-icon
></gl-button>
</span>
${activeBranches.map(branch => {
return this.renderRepoBranchCard(branch, repo.path, isFetching);
})}
${this.renderRepoBranchCard(activeBranch, repo.path, isFetching)}
</gl-section>
`;
}
Expand Down Expand Up @@ -191,7 +189,7 @@ export class GlActiveWork extends SignalWatcher(LitElement) {
}

private onChange(_e: MouseEvent) {
void this._overviewState.changeRepository();
void this._activeOverviewState.changeRepository();
}
}

Expand Down
36 changes: 17 additions & 19 deletions src/webviews/apps/plus/home/components/overview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,17 @@ import { SignalWatcher } from '@lit-labs/signals';
import { css, html, LitElement, nothing } from 'lit';
import { customElement, state } from 'lit/decorators.js';
import { when } from 'lit/directives/when.js';
import type { GetOverviewResponse, OverviewRecentThreshold, State } from '../../../../home/protocol';
import type { GetInactiveOverviewResponse, OverviewRecentThreshold, State } from '../../../../home/protocol';
import { SetOverviewFilter } from '../../../../home/protocol';
import { stateContext } from '../../../home/context';
import { ipcContext } from '../../../shared/context';
import type { HostIpc } from '../../../shared/ipc';
import { linkStyles } from '../../shared/components/vscode.css';
import type { OverviewState } from './overviewState';
import { overviewStateContext } from './overviewState';
import type { InactiveOverviewState } from './overviewState';
import { inactiveOverviewStateContext } from './overviewState';
import '../../../shared/components/skeleton-loader';
import './branch-threshold-filter';

type Overview = GetOverviewResponse;

export const overviewTagName = 'gl-overview';

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

@consume({ context: overviewStateContext })
private _overviewState!: OverviewState;
@consume({ context: inactiveOverviewStateContext })
private _inactiveOverviewState!: InactiveOverviewState;

override connectedCallback(): void {
super.connectedCallback();

if (this._homeState.repositories.openCount > 0) {
this._overviewState.run();
this._inactiveOverviewState.run();
}
}

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

return this._overviewState.render({
return this._inactiveOverviewState.render({
pending: () => this.renderPending(),
complete: summary => this.renderComplete(summary),
error: () => html`<span>Error</span>`,
Expand All @@ -72,34 +70,34 @@ export class GlOverview extends SignalWatcher(LitElement) {
}

private renderPending() {
if (this._overviewState.state == null) {
if (this._inactiveOverviewState.state == null) {
return this.renderLoader();
}
return this.renderComplete(this._overviewState.state, true);
return this.renderComplete(this._inactiveOverviewState.state, true);
}

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

private onChangeRecentThresholdFilter(e: CustomEvent<{ threshold: OverviewRecentThreshold }>) {
if (!this._overviewState.filter.stale || !this._overviewState.filter.recent) {
if (!this._inactiveOverviewState.filter.stale || !this._inactiveOverviewState.filter.recent) {
return;
}
this._ipc.sendCommand(SetOverviewFilter, {
stale: this._overviewState.filter.stale,
recent: { ...this._overviewState.filter.recent, threshold: e.detail.threshold },
stale: this._inactiveOverviewState.filter.stale,
recent: { ...this._inactiveOverviewState.filter.recent, threshold: e.detail.threshold },
});
}

private renderComplete(overview: Overview, isFetching = false) {
private renderComplete(overview: GetInactiveOverviewResponse, isFetching = false) {
if (overview == null) return nothing;
const { repository } = overview;
return html`
<gl-branch-section
label="recent"
.isFetching=${isFetching}
.repo=${repository.path}
.branches=${repository.branches.recent}
.branches=${overview.recent}
>
<gl-branch-threshold-filter
slot="heading-actions"
Expand All @@ -113,16 +111,16 @@ export class GlOverview extends SignalWatcher(LitElement) {
label: string;
}[]}
.disabled=${isFetching}
.value=${this._overviewState.filter.recent?.threshold}
.value=${this._inactiveOverviewState.filter.recent?.threshold}
></gl-branch-threshold-filter>
</gl-branch-section>
${when(
this._overviewState.filter.stale?.show === true,
this._inactiveOverviewState.filter.stale?.show === true && overview.stale,
() => html`
<gl-branch-section
label="stale"
.repo=${repository.path}
.branches=${repository.branches.stale}
.branches=${overview.stale!}
></gl-branch-section>
`,
)}
Expand Down
64 changes: 49 additions & 15 deletions src/webviews/apps/plus/home/components/overviewState.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,38 @@
import { createContext } from '@lit/context';
import { signalObject } from 'signal-utils/object';
import type { GetOverviewResponse, OverviewFilters } from '../../../../home/protocol';
import type {
GetActiveOverviewResponse,
GetInactiveOverviewResponse,
OverviewFilters,
} from '../../../../home/protocol';
import {
ChangeOverviewRepository,
DidChangeOverviewFilter,
DidChangeRepositories,
DidChangeRepositoryWip,
GetOverview,
GetActiveOverview,
GetInactiveOverview,
GetOverviewFilterState,
} from '../../../../home/protocol';
import { AsyncComputedState } from '../../../shared/components/signal-utils';
import type { Disposable } from '../../../shared/events';
import type { HostIpc } from '../../../shared/ipc';

export type Overview = GetOverviewResponse;
export type ActiveOverview = GetActiveOverviewResponse;
export type InactiveOverview = GetInactiveOverviewResponse;

export class OverviewState extends AsyncComputedState<Overview> {
export class ActiveOverviewState extends AsyncComputedState<ActiveOverview> {
private readonly _disposable: Disposable | undefined;

constructor(
private readonly _ipc: HostIpc,
options?: {
runImmediately?: boolean;
initial?: Overview;
initial?: ActiveOverview;
},
) {
super(async _abortSignal => {
const rsp: Overview = await this._ipc.sendRequest(GetOverview, {});

const rsp: ActiveOverview = await this._ipc.sendRequest(GetActiveOverview, {});
return rsp;
}, options);

Expand All @@ -39,6 +44,41 @@ export class OverviewState extends AsyncComputedState<Overview> {
case DidChangeRepositoryWip.is(msg):
this.run(true);
break;
}
});
}

dispose() {
this._disposable?.dispose();
}

async changeRepository(): Promise<void> {
await this._ipc.sendRequest(ChangeOverviewRepository, undefined);
this.run(true);
}
}

export class InactiveOverviewState extends AsyncComputedState<InactiveOverview> {
private readonly _disposable: Disposable | undefined;
filter = signalObject<Partial<OverviewFilters>>({});

constructor(
private readonly _ipc: HostIpc,
options?: {
runImmediately?: boolean;
initial?: InactiveOverview;
},
) {
super(async _abortSignal => {
const rsp: InactiveOverview = await this._ipc.sendRequest(GetInactiveOverview, {});
return rsp;
}, options);

this._disposable = this._ipc.onReceiveMessage(msg => {
switch (true) {
case DidChangeRepositories.is(msg):
this.run(true);
break;
case DidChangeOverviewFilter.is(msg):
this.filter.recent = msg.params.filter.recent;
this.filter.stale = msg.params.filter.stale;
Expand All @@ -55,13 +95,7 @@ export class OverviewState extends AsyncComputedState<Overview> {
dispose(): void {
this._disposable?.dispose();
}

filter = signalObject<Partial<OverviewFilters>>({});

async changeRepository(): Promise<void> {
await this._ipc.sendRequest(ChangeOverviewRepository, undefined);
this.run(true);
}
}

export const overviewStateContext = createContext<Overview>('overviewState');
export const activeOverviewStateContext = createContext<ActiveOverview>('activeOverviewState');
export const inactiveOverviewStateContext = createContext<InactiveOverview>('inactiveOverviewState');
Loading

0 comments on commit 5f4aaa8

Please sign in to comment.