Skip to content

Commit 27d93d2

Browse files
committed
Adds open worktree in new window to branch cards
1 parent ec615ec commit 27d93d2

File tree

4 files changed

+87
-8
lines changed

4 files changed

+87
-8
lines changed

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import type {
2323
GetOverviewBranch,
2424
OpenInGraphParams,
2525
OpenInTimelineParams,
26+
OpenWorktreeCommandArgs,
2627
State,
2728
} from '../../../../home/protocol';
2829
import { stateContext } from '../../../home/context';
@@ -976,8 +977,13 @@ export class GlBranchCard extends GlBranchCardBase {
976977
actions.push(
977978
html`<action-item
978979
label="Open Worktree"
980+
alt-label="Open Worktree in New Window"
979981
icon="browser"
982+
alt-icon="empty-window"
980983
href=${this.createCommandLink('gitlens.home.openWorktree')}
984+
alt-href=${this.createCommandLink<OpenWorktreeCommandArgs>('gitlens.home.openWorktree', {
985+
location: 'newWindow',
986+
})}
981987
></action-item>`,
982988
);
983989
} else {
@@ -1002,8 +1008,13 @@ export class GlBranchCard extends GlBranchCardBase {
10021008
actions.push(
10031009
html`<action-item
10041010
label="Open Worktree"
1011+
alt-label="Open Worktree in New Window"
10051012
icon="browser"
1013+
alt-icon="empty-window"
10061014
href=${this.createCommandLink('gitlens.home.openWorktree')}
1015+
alt-href=${this.createCommandLink<OpenWorktreeCommandArgs>('gitlens.home.openWorktree', {
1016+
location: 'newWindow',
1017+
})}
10071018
></action-item>`,
10081019
);
10091020

src/webviews/apps/shared/components/actions/action-item.ts

Lines changed: 67 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { css, html, LitElement, nothing } from 'lit';
2-
import { customElement, property, query } from 'lit/decorators.js';
2+
import { customElement, property, query, state } from 'lit/decorators.js';
3+
import { getAltKeySymbol } from '@env/platform';
34
import { focusOutline } from '../styles/lit/a11y.css';
45
import '../overlays/tooltip';
56
import '../code-icon';
@@ -55,29 +56,89 @@ export class ActionItem extends LitElement {
5556
@property()
5657
href?: string;
5758

59+
@property({ attribute: 'alt-href' })
60+
altHref?: string;
61+
5862
@property()
5963
label?: string;
6064

65+
@property({ attribute: 'alt-label' })
66+
altLabel?: string;
67+
6168
@property()
6269
icon = '';
6370

71+
@property({ attribute: 'alt-icon' })
72+
altIcon?: string;
73+
6474
@property({ type: Boolean })
6575
disabled = false;
6676

6777
@query('a')
6878
private defaultFocusEl!: HTMLAnchorElement;
6979

80+
@state()
81+
private isAltKeyPressed = false;
82+
83+
get effectiveIcon(): string {
84+
if (this.isAltKeyPressed && this.altIcon) {
85+
return this.altIcon;
86+
}
87+
return this.icon;
88+
}
89+
90+
get effectiveLabel(): string | undefined {
91+
if (!this.label && !this.altLabel) {
92+
return undefined;
93+
}
94+
if (this.altLabel) {
95+
if (this.isAltKeyPressed) {
96+
return this.altLabel;
97+
}
98+
return `${this.label}\n[${getAltKeySymbol()}] ${this.altLabel}`;
99+
}
100+
return this.label;
101+
}
102+
103+
get effectiveHref(): string | undefined {
104+
if (this.isAltKeyPressed && this.altHref) {
105+
return this.altHref;
106+
}
107+
return this.href;
108+
}
109+
110+
override connectedCallback(): void {
111+
super.connectedCallback();
112+
window.addEventListener('keydown', this);
113+
window.addEventListener('keyup', this);
114+
}
115+
116+
override disconnectedCallback(): void {
117+
super.disconnectedCallback();
118+
window.removeEventListener('keydown', this);
119+
window.removeEventListener('keyup', this);
120+
}
121+
122+
handleEvent(e: KeyboardEvent) {
123+
const isAltKey = e.key === 'Alt' || e.altKey;
124+
if (e.type === 'keydown') {
125+
this.isAltKeyPressed = isAltKey;
126+
} else if (e.type === 'keyup' && isAltKey) {
127+
this.isAltKeyPressed = false;
128+
}
129+
}
130+
70131
override render(): unknown {
71132
return html`
72-
<gl-tooltip hoist content="${this.label ?? nothing}">
133+
<gl-tooltip hoist content="${this.effectiveLabel ?? nothing}">
73134
<a
74-
role="${!this.href ? 'button' : nothing}"
75-
type="${!this.href ? 'button' : nothing}"
135+
role="${!this.effectiveHref ? 'button' : nothing}"
136+
type="${!this.effectiveHref ? 'button' : nothing}"
76137
aria-label="${this.label ?? nothing}"
77138
?disabled=${this.disabled}
78-
href=${this.href ?? nothing}
139+
href=${this.effectiveHref ?? nothing}
79140
>
80-
<code-icon icon="${this.icon}"></code-icon>
141+
<code-icon icon="${this.effectiveIcon}"></code-icon>
81142
</a>
82143
</gl-tooltip>
83144
`;

src/webviews/home/homeWebview.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ import type {
9191
IntegrationState,
9292
OpenInGraphParams,
9393
OpenInTimelineParams,
94+
OpenWorktreeCommandArgs,
9495
OverviewFilters,
9596
OverviewRecentThreshold,
9697
OverviewRepository,
@@ -1482,12 +1483,13 @@ export class HomeWebviewProvider implements WebviewProvider<State, State, HomeWe
14821483
@log<HomeWebviewProvider['worktreeOpen']>({
14831484
args: { 0: r => `${r.branchId}, worktree: ${r.worktree?.name}` },
14841485
})
1485-
private async worktreeOpen(ref: BranchRef) {
1486+
private async worktreeOpen(args: OpenWorktreeCommandArgs) {
1487+
const { location, ...ref } = args;
14861488
const { branch } = await this.getRepoInfoFromRef(ref);
14871489
const worktree = await branch?.getWorktree();
14881490
if (worktree == null) return;
14891491

1490-
openWorkspace(worktree.uri);
1492+
openWorkspace(worktree.uri, location ? { location: location } : undefined);
14911493
}
14921494

14931495
@log<HomeWebviewProvider['switchToBranch']>({ args: { 0: r => r.branchId } })

src/webviews/home/protocol.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import type { Subscription } from '../../plus/gk/models/subscription';
1313
import type { LaunchpadSummaryResult } from '../../plus/launchpad/launchpadIndicator';
1414
import type { LaunchpadItem } from '../../plus/launchpad/launchpadProvider';
1515
import type { LaunchpadGroup } from '../../plus/launchpad/models/launchpad';
16+
import type { OpenWorkspaceLocation } from '../../system/-webview/vscode/workspaces';
1617
import type { IpcScope, WebviewState } from '../protocol';
1718
import { IpcCommand, IpcNotification, IpcRequest } from '../protocol';
1819

@@ -353,6 +354,10 @@ export interface BranchRef {
353354
};
354355
}
355356

357+
export interface OpenWorktreeCommandArgs extends BranchRef {
358+
location?: OpenWorkspaceLocation;
359+
}
360+
356361
export interface BranchAndTargetRefs extends BranchRef {
357362
mergeTargetId: string;
358363
mergeTargetName: string;

0 commit comments

Comments
 (0)