Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/system/webview.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import type { WebviewIds, WebviewViewIds } from '../constants.views';

export function createWebviewCommandLink(
export function createWebviewCommandLink<T>(
command: `${WebviewIds | WebviewViewIds}.${string}`,
webviewId: WebviewIds | WebviewViewIds,
webviewInstanceId: string | undefined,
args?: T,
): string {
return `command:${command}?${encodeURIComponent(
JSON.stringify({ webview: webviewId, webviewInstance: webviewInstanceId } satisfies WebviewContext),
JSON.stringify({ webview: webviewId, webviewInstance: webviewInstanceId, ...args } satisfies WebviewContext),
)}`;
}

Expand Down
44 changes: 33 additions & 11 deletions src/webviews/apps/plus/home/components/active-work.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { css, html, LitElement, nothing } from 'lit';
import { customElement, state } from 'lit/decorators.js';
import { when } from 'lit/directives/when.js';
import type { GitTrackingState } from '../../../../../git/models/branch';
import { createWebviewCommandLink } from '../../../../../system/webview';
import type { GetOverviewBranch, State } from '../../../../home/protocol';
import { stateContext } from '../../../home/context';
import { branchCardStyles, sectionHeadingStyles } from './branch-section';
Expand Down Expand Up @@ -83,11 +84,11 @@ export class GlActiveWork extends SignalWatcher(LitElement) {

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

return html`
<h3 class="section-heading section-heading--actions">
<span><code-icon icon="repo" class="heading-icon"></code-icon> ${overview!.repository.name}</span>
<span><code-icon icon="repo" class="heading-icon"></code-icon> ${overview.repository.name}</span>
${when(
this._homeState.repositories.openCount > 1,
() =>
Expand Down Expand Up @@ -116,13 +117,13 @@ export class GlActiveWork extends SignalWatcher(LitElement) {
<span class="branch-item__name">${name}</span>
</p>
${when(state, () => this.renderBranchStateActions(state, upstream))}
${when(pr, () => {
${when(pr, pr => {
return html` <p class="branch-item__main is-end">
<span class="branch-item__icon">
<pr-icon state=${pr!.state}></pr-icon>
<pr-icon state=${pr.state}></pr-icon>
</span>
<span class="branch-item__name">${pr!.title}</span>
<span class="branch-item__identifier">#${pr!.id}</span>
<span class="branch-item__name">${pr.title}</span>
<a href=${pr.url} class="branch-item__identifier">#${pr.id}</a>
</p>`;
})}
${when(workingTreeState, () => this.renderStatus(workingTreeState, state))}
Expand All @@ -134,7 +135,10 @@ export class GlActiveWork extends SignalWatcher(LitElement) {
if (upstream?.missing !== false) {
return html`<div>
<button-container>
<gl-button full appearance="secondary"
<gl-button
href=${createWebviewCommandLink('gitlens.views.home.publishBranch', 'gitlens.views.home', '')}
full
appearance="secondary"
><code-icon icon="cloud-upload" slot="prefix"></code-icon> Publish Branch</gl-button
></button-container
>
Expand All @@ -148,15 +152,25 @@ export class GlActiveWork extends SignalWatcher(LitElement) {
const forcePushTooltip = upstream?.name ? `Force Push to ${upstream.name}` : 'Force Push';
return html`<div>
<button-container>
<gl-button full appearance="secondary" tooltip=${pullTooltip}
<gl-button
href=${createWebviewCommandLink('gitlens.views.home.pull', 'gitlens.views.home', '')}
full
appearance="secondary"
tooltip=${pullTooltip}
><code-icon icon="gl-repo-pull" slot="prefix"></code-icon> Pull
<gl-tracking-pill
.ahead=${state.ahead}
.behind=${state.behind}
slot="suffix"
></gl-tracking-pill
></gl-button>
<gl-button appearance="secondary" density="compact" tooltip=${forcePushTooltip}
<gl-button
href=${createWebviewCommandLink('gitlens.views.home.push', 'gitlens.views.home', '', {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a force push

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep

force: true,
})}
appearance="secondary"
density="compact"
tooltip=${forcePushTooltip}
><code-icon icon="repo-force-push"></code-icon
></gl-button>
</button-container>
Expand All @@ -166,7 +180,11 @@ export class GlActiveWork extends SignalWatcher(LitElement) {
const tooltip = upstream?.name ? `Pull from ${upstream.name}` : 'Pull';
return html`<div>
<button-container>
<gl-button full appearance="secondary" tooltip=${tooltip}
<gl-button
href=${createWebviewCommandLink('gitlens.views.home.pull', 'gitlens.views.home', '')}
full
appearance="secondary"
tooltip=${tooltip}
><code-icon icon="gl-repo-pull" slot="prefix"></code-icon> Pull
<gl-tracking-pill
.ahead=${state.ahead}
Expand All @@ -180,7 +198,11 @@ export class GlActiveWork extends SignalWatcher(LitElement) {
const tooltip = upstream?.name ? `Push to ${upstream.name}` : 'Push';
return html`<div>
<button-container>
<gl-button full appearance="secondary" tooltip=${tooltip}
<gl-button
href=${createWebviewCommandLink('gitlens.views.home.push', 'gitlens.views.home', '')}
full
appearance="secondary"
tooltip=${tooltip}
><code-icon icon="repo-push" slot="prefix"></code-icon> Push
<gl-tracking-pill
.ahead=${state.ahead}
Expand Down
12 changes: 8 additions & 4 deletions src/webviews/apps/plus/home/components/branch-section.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,11 @@ export const branchCardStyles = css`

.branch-item__identifier {
color: var(--vscode-descriptionForeground);
text-decoration: none;
}

.branch-item__identifier:hover {
text-decoration: underline;
}

.branch-item__details {
Expand Down Expand Up @@ -171,16 +176,15 @@ export class GlBranchCard extends LitElement {

override render() {
const { name, pr, opened: active, timestamp: date, state, workingTreeState } = this.branch;

return html`
<gl-card class="branch-item" .active=${active}>
<p class="branch-item__main">
<span class="branch-item__icon">${this.renderIcon(this.branch)}</span>
${when(
pr,
() =>
html`<span class="branch-item__name">${pr!.title}</span>
<span class="branch-item__identifier">#${pr!.id}</span>`,
pr =>
html`<span class="branch-item__name">${pr.title} </span
><a href=${pr.url} class="branch-item__identifier">#${pr.id}</a>`,
() => html`<span class="branch-item__name">${name}</span>`,
)}
</p>
Expand Down
81 changes: 57 additions & 24 deletions src/webviews/home/homeWebview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { GlyphChars } from '../../constants';
import type { ContextKeys } from '../../constants.context';
import type { HomeTelemetryContext } from '../../constants.telemetry';
import type { Container } from '../../container';
import { executeGitCommand } from '../../git/actions';
import type { BranchContributorOverview } from '../../git/gitProvider';
import type { GitBranch } from '../../git/models/branch';
import { sortBranches } from '../../git/models/branch';
Expand Down Expand Up @@ -146,7 +147,7 @@ export class HomeWebviewProvider implements WebviewProvider<State, State, HomeWe
this.notifyDidChangeOnboardingIntegration();
}

private async shouldNotifyRespositoryChange(): Promise<boolean> {
private async shouldNotifyRepositoryChange(): Promise<boolean> {
if (this._etag === this.container.git.etag) {
return false;
}
Expand Down Expand Up @@ -181,7 +182,7 @@ export class HomeWebviewProvider implements WebviewProvider<State, State, HomeWe
}

private async onRepositoriesChanged() {
if (!(await this.shouldNotifyRespositoryChange())) {
if (!(await this.shouldNotifyRepositoryChange())) {
return;
}
this.notifyDidChangeRepositories();
Expand All @@ -197,8 +198,39 @@ export class HomeWebviewProvider implements WebviewProvider<State, State, HomeWe
}
}

private async push(force = false) {
const repo = this.getSelectedRepository();
if (repo) {
return executeGitCommand({
command: 'push',
state: { repos: [repo], flags: force ? ['--force'] : undefined },
});
}
return Promise.resolve();
}

private async pull() {
const repo = this.getSelectedRepository();
if (repo) {
return executeGitCommand({
command: 'pull',
state: { repos: [repo] },
});
}
return Promise.resolve();
}

registerCommands(): Disposable[] {
return [
registerCommand(`${this.host.id}.pull`, this.pull, this),
registerCommand(
`${this.host.id}.push`,
args => {
void this.push(args.force);
},
this,
),
registerCommand(`${this.host.id}.publishBranch`, this.push, this),
registerCommand(`${this.host.id}.refresh`, () => this.host.refresh(true), this),
registerCommand(
`${this.host.id}.account.resync`,
Expand Down Expand Up @@ -426,6 +458,7 @@ export class HomeWebviewProvider implements WebviewProvider<State, State, HomeWe
}

private onWipChanged(_repo: Repository) {
this._invalidateRepositoryBranches = true;
void this.host.notify(DidChangeRepositoryWip, undefined);
}

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

private _repositoryBranches: Map<string, { branches: GitBranch[]; worktrees: GitWorktree[] }> = new Map();
private async getBranchesAndWorktrees(repo: Repository, force = false) {
private _invalidateRepositoryBranches = true;
private readonly _repositoryBranches: Map<string, { branches: GitBranch[]; worktrees: GitWorktree[] }> = new Map();
private async getBranchesAndWorktrees(repo: Repository, force = this._invalidateRepositoryBranches) {
if (force || !this._repositoryBranches.has(repo.path)) {
const [branchesResult, worktreesResult] = await Promise.allSettled([
repo.git.getBranches({ filter: b => !b.remote }),
repo.git.getWorktrees(),
const worktrees = (await repo.git.getWorktrees()) ?? [];
const worktreesByBranch = groupWorktreesByBranch(worktrees);
const [branchesResult] = await Promise.allSettled([
repo.git.getBranches({
filter: b => !b.remote,
sort: { current: true, openedWorktreesByBranch: getOpenedWorktreesByBranch(worktreesByBranch) },
}),
]);

const branches = getSettledValue(branchesResult)?.values ?? [];
const worktrees = getSettledValue(worktreesResult) ?? [];
this._invalidateRepositoryBranches = false;
this._repositoryBranches.set(repo.path, { branches: branches, worktrees: worktrees });
}

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

const worktreesByBranch = groupWorktreesByBranch(worktrees);

sortBranches(branches, {
current: true,
orderBy: 'date:desc',
openedWorktreesByBranch: getOpenedWorktreesByBranch(worktreesByBranch),
});

const overviewBranches: GetOverviewBranches = {
active: [],
recent: [],
Expand All @@ -571,7 +604,7 @@ async function getOverviewBranches(

const timestamp = branch.date?.getTime();
if (branch.current || wt?.opened) {
prPromises.set(branch.id, branch.getAssociatedPullRequest());
prPromises.set(branch.id, branch.getAssociatedPullRequest({ avatarSize: 16 }));
if (wt != null) {
statusPromises.set(branch.id, wt.getStatus());
}
Expand Down Expand Up @@ -678,15 +711,15 @@ async function getOverviewBranches(
const prs = new Map(
getSettledValue(prResults)
?.filter(r => r.status === 'fulfilled')
.map(r => [
r.value[0],
r.value[1]
? {
id: r.value[1].id,
title: r.value[1].title,
state: r.value[1].state,
url: r.value[1].url,
}
.map(({ value: [prId, pr] }) => [
prId,
pr
? ({
id: pr.id,
title: pr.title,
state: pr.state,
url: pr.url,
} satisfies GetOverviewBranch['pr'])
: undefined,
]),
);
Expand Down
Loading