Skip to content

Commit 046a6a2

Browse files
committed
Fixes home view bugs
- handle push/pull actions - add link to pr - control force branches reloading
1 parent f6e0a17 commit 046a6a2

File tree

4 files changed

+101
-41
lines changed

4 files changed

+101
-41
lines changed

src/system/webview.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import type { WebviewIds, WebviewViewIds } from '../constants.views';
22

3-
export function createWebviewCommandLink(
3+
export function createWebviewCommandLink<T>(
44
command: `${WebviewIds | WebviewViewIds}.${string}`,
55
webviewId: WebviewIds | WebviewViewIds,
66
webviewInstanceId: string | undefined,
7+
args?: T,
78
): string {
89
return `command:${command}?${encodeURIComponent(
9-
JSON.stringify({ webview: webviewId, webviewInstance: webviewInstanceId } satisfies WebviewContext),
10+
JSON.stringify({ webview: webviewId, webviewInstance: webviewInstanceId, ...args } satisfies WebviewContext),
1011
)}`;
1112
}
1213

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

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { css, html, LitElement, nothing } from 'lit';
44
import { customElement, state } from 'lit/decorators.js';
55
import { when } from 'lit/directives/when.js';
66
import type { GitTrackingState } from '../../../../../git/models/branch';
7+
import { createWebviewCommandLink } from '../../../../../system/webview';
78
import type { GetOverviewBranch, State } from '../../../../home/protocol';
89
import { stateContext } from '../../../home/context';
910
import { branchCardStyles, sectionHeadingStyles } from './branch-section';
@@ -83,11 +84,11 @@ export class GlActiveWork extends SignalWatcher(LitElement) {
8384

8485
private renderComplete(overview: Overview) {
8586
const activeBranches = overview?.repository?.branches?.active;
86-
if (activeBranches == null) return html`<span>None</span>`;
87+
if (!activeBranches) return html`<span>None</span>`;
8788

8889
return html`
8990
<h3 class="section-heading section-heading--actions">
90-
<span><code-icon icon="repo" class="heading-icon"></code-icon> ${overview!.repository.name}</span>
91+
<span><code-icon icon="repo" class="heading-icon"></code-icon> ${overview.repository.name}</span>
9192
${when(
9293
this._homeState.repositories.openCount > 1,
9394
() =>
@@ -116,13 +117,13 @@ export class GlActiveWork extends SignalWatcher(LitElement) {
116117
<span class="branch-item__name">${name}</span>
117118
</p>
118119
${when(state, () => this.renderBranchStateActions(state, upstream))}
119-
${when(pr, () => {
120+
${when(pr, pr => {
120121
return html` <p class="branch-item__main is-end">
121122
<span class="branch-item__icon">
122-
<pr-icon state=${pr!.state}></pr-icon>
123+
<pr-icon state=${pr.state}></pr-icon>
123124
</span>
124-
<span class="branch-item__name">${pr!.title}</span>
125-
<span class="branch-item__identifier">#${pr!.id}</span>
125+
<span class="branch-item__name">${pr.title}</span>
126+
<a href=${pr.url} class="branch-item__identifier">#${pr.id}</a>
126127
</p>`;
127128
})}
128129
${when(workingTreeState, () => this.renderStatus(workingTreeState, state))}
@@ -134,7 +135,10 @@ export class GlActiveWork extends SignalWatcher(LitElement) {
134135
if (upstream?.missing !== false) {
135136
return html`<div>
136137
<button-container>
137-
<gl-button full appearance="secondary"
138+
<gl-button
139+
href=${createWebviewCommandLink('gitlens.views.home.publishBranch', 'gitlens.views.home', '')}
140+
full
141+
appearance="secondary"
138142
><code-icon icon="cloud-upload" slot="prefix"></code-icon> Publish Branch</gl-button
139143
></button-container
140144
>
@@ -148,15 +152,25 @@ export class GlActiveWork extends SignalWatcher(LitElement) {
148152
const forcePushTooltip = upstream?.name ? `Force Push to ${upstream.name}` : 'Force Push';
149153
return html`<div>
150154
<button-container>
151-
<gl-button full appearance="secondary" tooltip=${pullTooltip}
155+
<gl-button
156+
href=${createWebviewCommandLink('gitlens.views.home.pull', 'gitlens.views.home', '')}
157+
full
158+
appearance="secondary"
159+
tooltip=${pullTooltip}
152160
><code-icon icon="gl-repo-pull" slot="prefix"></code-icon> Pull
153161
<gl-tracking-pill
154162
.ahead=${state.ahead}
155163
.behind=${state.behind}
156164
slot="suffix"
157165
></gl-tracking-pill
158166
></gl-button>
159-
<gl-button appearance="secondary" density="compact" tooltip=${forcePushTooltip}
167+
<gl-button
168+
href=${createWebviewCommandLink('gitlens.views.home.push', 'gitlens.views.home', '', {
169+
force: true,
170+
})}
171+
appearance="secondary"
172+
density="compact"
173+
tooltip=${forcePushTooltip}
160174
><code-icon icon="repo-force-push"></code-icon
161175
></gl-button>
162176
</button-container>
@@ -166,7 +180,11 @@ export class GlActiveWork extends SignalWatcher(LitElement) {
166180
const tooltip = upstream?.name ? `Pull from ${upstream.name}` : 'Pull';
167181
return html`<div>
168182
<button-container>
169-
<gl-button full appearance="secondary" tooltip=${tooltip}
183+
<gl-button
184+
href=${createWebviewCommandLink('gitlens.views.home.pull', 'gitlens.views.home', '')}
185+
full
186+
appearance="secondary"
187+
tooltip=${tooltip}
170188
><code-icon icon="gl-repo-pull" slot="prefix"></code-icon> Pull
171189
<gl-tracking-pill
172190
.ahead=${state.ahead}
@@ -180,7 +198,11 @@ export class GlActiveWork extends SignalWatcher(LitElement) {
180198
const tooltip = upstream?.name ? `Push to ${upstream.name}` : 'Push';
181199
return html`<div>
182200
<button-container>
183-
<gl-button full appearance="secondary" tooltip=${tooltip}
201+
<gl-button
202+
href=${createWebviewCommandLink('gitlens.views.home.push', 'gitlens.views.home', '')}
203+
full
204+
appearance="secondary"
205+
tooltip=${tooltip}
184206
><code-icon icon="repo-push" slot="prefix"></code-icon> Push
185207
<gl-tracking-pill
186208
.ahead=${state.ahead}

src/webviews/apps/plus/home/components/branch-section.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,11 @@ export const branchCardStyles = css`
104104
105105
.branch-item__identifier {
106106
color: var(--vscode-descriptionForeground);
107+
text-decoration: none;
108+
}
109+
110+
.branch-item__identifier:hover {
111+
text-decoration: underline;
107112
}
108113
109114
.branch-item__details {
@@ -171,16 +176,15 @@ export class GlBranchCard extends LitElement {
171176

172177
override render() {
173178
const { name, pr, opened: active, timestamp: date, state, workingTreeState } = this.branch;
174-
175179
return html`
176180
<gl-card class="branch-item" .active=${active}>
177181
<p class="branch-item__main">
178182
<span class="branch-item__icon">${this.renderIcon(this.branch)}</span>
179183
${when(
180184
pr,
181-
() =>
182-
html`<span class="branch-item__name">${pr!.title}</span>
183-
<span class="branch-item__identifier">#${pr!.id}</span>`,
185+
pr =>
186+
html`<span class="branch-item__name">${pr.title} </span
187+
><a href=${pr.url} class="branch-item__identifier">#${pr.id}</a>`,
184188
() => html`<span class="branch-item__name">${name}</span>`,
185189
)}
186190
</p>

src/webviews/home/homeWebview.ts

Lines changed: 57 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { GlyphChars } from '../../constants';
55
import type { ContextKeys } from '../../constants.context';
66
import type { HomeTelemetryContext } from '../../constants.telemetry';
77
import type { Container } from '../../container';
8+
import { executeGitCommand } from '../../git/actions';
89
import type { BranchContributorOverview } from '../../git/gitProvider';
910
import type { GitBranch } from '../../git/models/branch';
1011
import { sortBranches } from '../../git/models/branch';
@@ -146,7 +147,7 @@ export class HomeWebviewProvider implements WebviewProvider<State, State, HomeWe
146147
this.notifyDidChangeOnboardingIntegration();
147148
}
148149

149-
private async shouldNotifyRespositoryChange(): Promise<boolean> {
150+
private async shouldNotifyRepositoryChange(): Promise<boolean> {
150151
if (this._etag === this.container.git.etag) {
151152
return false;
152153
}
@@ -181,7 +182,7 @@ export class HomeWebviewProvider implements WebviewProvider<State, State, HomeWe
181182
}
182183

183184
private async onRepositoriesChanged() {
184-
if (!(await this.shouldNotifyRespositoryChange())) {
185+
if (!(await this.shouldNotifyRepositoryChange())) {
185186
return;
186187
}
187188
this.notifyDidChangeRepositories();
@@ -197,8 +198,39 @@ export class HomeWebviewProvider implements WebviewProvider<State, State, HomeWe
197198
}
198199
}
199200

201+
private async push(force = false) {
202+
const repo = this.getSelectedRepository();
203+
if (repo) {
204+
return executeGitCommand({
205+
command: 'push',
206+
state: { repos: [repo], flags: force ? ['--force'] : undefined },
207+
});
208+
}
209+
return Promise.resolve();
210+
}
211+
212+
private async pull() {
213+
const repo = this.getSelectedRepository();
214+
if (repo) {
215+
return executeGitCommand({
216+
command: 'pull',
217+
state: { repos: [repo] },
218+
});
219+
}
220+
return Promise.resolve();
221+
}
222+
200223
registerCommands(): Disposable[] {
201224
return [
225+
registerCommand(`${this.host.id}.pull`, this.pull, this),
226+
registerCommand(
227+
`${this.host.id}.push`,
228+
args => {
229+
void this.push(args.force);
230+
},
231+
this,
232+
),
233+
registerCommand(`${this.host.id}.publishBranch`, this.push, this),
202234
registerCommand(`${this.host.id}.refresh`, () => this.host.refresh(true), this),
203235
registerCommand(
204236
`${this.host.id}.account.resync`,
@@ -426,6 +458,7 @@ export class HomeWebviewProvider implements WebviewProvider<State, State, HomeWe
426458
}
427459

428460
private onWipChanged(_repo: Repository) {
461+
this._invalidateRepositoryBranches = true;
429462
void this.host.notify(DidChangeRepositoryWip, undefined);
430463
}
431464

@@ -437,16 +470,21 @@ export class HomeWebviewProvider implements WebviewProvider<State, State, HomeWe
437470
return this._repositorySubscription?.repo;
438471
}
439472

440-
private _repositoryBranches: Map<string, { branches: GitBranch[]; worktrees: GitWorktree[] }> = new Map();
441-
private async getBranchesAndWorktrees(repo: Repository, force = false) {
473+
private _invalidateRepositoryBranches = true;
474+
private readonly _repositoryBranches: Map<string, { branches: GitBranch[]; worktrees: GitWorktree[] }> = new Map();
475+
private async getBranchesAndWorktrees(repo: Repository, force = this._invalidateRepositoryBranches) {
442476
if (force || !this._repositoryBranches.has(repo.path)) {
443-
const [branchesResult, worktreesResult] = await Promise.allSettled([
444-
repo.git.getBranches({ filter: b => !b.remote }),
445-
repo.git.getWorktrees(),
477+
const worktrees = (await repo.git.getWorktrees()) ?? [];
478+
const worktreesByBranch = groupWorktreesByBranch(worktrees);
479+
const [branchesResult] = await Promise.allSettled([
480+
repo.git.getBranches({
481+
filter: b => !b.remote,
482+
sort: { current: true, openedWorktreesByBranch: getOpenedWorktreesByBranch(worktreesByBranch) },
483+
}),
446484
]);
447485

448486
const branches = getSettledValue(branchesResult)?.values ?? [];
449-
const worktrees = getSettledValue(worktreesResult) ?? [];
487+
this._invalidateRepositoryBranches = false;
450488
this._repositoryBranches.set(repo.path, { branches: branches, worktrees: worktrees });
451489
}
452490

@@ -542,16 +580,11 @@ async function getOverviewBranches(
542580
container: Container,
543581
options: OverviewFilters,
544582
): Promise<GetOverviewBranches | undefined> {
583+
console.log('try to getOverviewBranches');
545584
if (branches.length === 0) return undefined;
546585

547586
const worktreesByBranch = groupWorktreesByBranch(worktrees);
548587

549-
sortBranches(branches, {
550-
current: true,
551-
orderBy: 'date:desc',
552-
openedWorktreesByBranch: getOpenedWorktreesByBranch(worktreesByBranch),
553-
});
554-
555588
const overviewBranches: GetOverviewBranches = {
556589
active: [],
557590
recent: [],
@@ -571,7 +604,7 @@ async function getOverviewBranches(
571604

572605
const timestamp = branch.date?.getTime();
573606
if (branch.current || wt?.opened) {
574-
prPromises.set(branch.id, branch.getAssociatedPullRequest());
607+
prPromises.set(branch.id, branch.getAssociatedPullRequest({ avatarSize: 16 }));
575608
if (wt != null) {
576609
statusPromises.set(branch.id, wt.getStatus());
577610
}
@@ -678,15 +711,15 @@ async function getOverviewBranches(
678711
const prs = new Map(
679712
getSettledValue(prResults)
680713
?.filter(r => r.status === 'fulfilled')
681-
.map(r => [
682-
r.value[0],
683-
r.value[1]
684-
? {
685-
id: r.value[1].id,
686-
title: r.value[1].title,
687-
state: r.value[1].state,
688-
url: r.value[1].url,
689-
}
714+
.map(({ value: [prId, pr] }) => [
715+
prId,
716+
pr
717+
? ({
718+
id: pr.id,
719+
title: pr.title,
720+
state: pr.state,
721+
url: pr.url,
722+
} satisfies GetOverviewBranch['pr'])
690723
: undefined,
691724
]),
692725
);

0 commit comments

Comments
 (0)