Skip to content

Commit

Permalink
Adds context menu support to upstream status
Browse files Browse the repository at this point in the history
Adds dblclick action to upstream & pr metadata
  • Loading branch information
eamodio committed Feb 9, 2023
1 parent 58a0db7 commit b232476
Show file tree
Hide file tree
Showing 5 changed files with 102 additions and 20 deletions.
15 changes: 15 additions & 0 deletions package.json
Expand Up @@ -11612,6 +11612,21 @@
"when": "webviewItem =~ /gitlens:pullrequest\\b/",
"group": "1_gitlens_actions@1"
},
{
"command": "gitlens.graph.push",
"when": "webviewItem =~ /gitlens:upstreamStatus\\b/",
"group": "1_gitlens_actions@1"
},
{
"command": "gitlens.graph.pull",
"when": "webviewItem =~ /gitlens:upstreamStatus\\b/",
"group": "1_gitlens_actions@2"
},
{
"command": "gitlens.graph.fetch",
"when": "webviewItem =~ /gitlens:upstreamStatus\\b/",
"group": "1_gitlens_actions@3"
},
{
"command": "gitlens.graph.compareWithUpstream",
"when": "!gitlens:hasVirtualFolders && webviewItem =~ /gitlens:branch\\b(?=.*?\\b\\+tracking\\b)/",
Expand Down
90 changes: 75 additions & 15 deletions src/plus/webviews/graph/graphWebview.ts
Expand Up @@ -702,11 +702,25 @@ export class GraphWebview extends WebviewBase<State> {

private onDoubleClick(e: DoubleClickedParams) {
if (e.type === 'ref' && e.ref.context) {
const item = typeof e.ref.context === 'string' ? JSON.parse(e.ref.context) : e.ref.context;
if (!('webview' in item)) {
item.webview = this.id;
}
let item = this.getGraphItemContext(e.ref.context);
if (isGraphItemRefContext(item)) {
if (e.metadata != null) {
item = this.getGraphItemContext(e.metadata.data.context);
if (e.metadata.type === 'upstream' && isGraphItemTypedContext(item, 'upstreamStatus')) {
const { ahead, behind, ref } = item.webviewItemValue;
if (behind > 0) {
return void RepoActions.pull(ref.repoPath, ref);
}
if (ahead > 0) {
return void RepoActions.push(ref.repoPath, false, ref);
}
} else if (e.metadata.type === 'pullRequest' && isGraphItemTypedContext(item, 'pullrequest')) {
return void this.openPullRequestOnRemote(item);
}

return;
}

const { ref } = item.webviewItemValue;
if (e.ref.refType === 'head' && e.ref.isCurrentHead) {
return RepoActions.switchTo(ref.repoPath);
Expand Down Expand Up @@ -817,8 +831,8 @@ export class GraphWebview extends WebviewBase<State> {
const pr = await branch?.getAssociatedPullRequest();

if (pr == null) {
if (metadata.pullRequests === undefined || metadata.pullRequests?.length === 0) {
metadata.pullRequests = null;
if (metadata.pullRequest === undefined || metadata.pullRequest?.length === 0) {
metadata.pullRequest = null;
}

this._refsMetadata.set(id, metadata);
Expand All @@ -844,7 +858,7 @@ export class GraphWebview extends WebviewBase<State> {
}),
};

metadata.pullRequests = [prMetadata];
metadata.pullRequest = [prMetadata];

this._refsMetadata.set(id, metadata);
continue;
Expand All @@ -864,6 +878,15 @@ export class GraphWebview extends WebviewBase<State> {
owner: getRemoteNameFromBranchName(upstream.name),
ahead: branch.state.ahead,
behind: branch.state.behind,
context: serializeWebviewItemContext<GraphItemContext>({
webviewItem: 'gitlens:upstreamStatus',
webviewItemValue: {
type: 'upstreamStatus',
ref: GitReference.fromBranch(branch),
ahead: branch.state.ahead,
behind: branch.state.behind,
},
}),
};

metadata.upstream = upstreamMetadata;
Expand Down Expand Up @@ -1667,6 +1690,15 @@ export class GraphWebview extends WebviewBase<State> {
return [access, visibility] as const;
}

private getGraphItemContext(context: unknown): unknown | undefined {
const item = typeof context === 'string' ? JSON.parse(context) : context;
// Add the `webview` prop to the context if its missing (e.g. when this context doesn't come through via the context menus)
if (item != null && !('webview' in item)) {
item.webview = this.id;
}
return item;
}

private async getWorkingTreeStats(): Promise<GraphWorkingTreeStats | undefined> {
if (this.repository == null || this.container.git.repositoryCount === 0) return undefined;

Expand Down Expand Up @@ -1937,18 +1969,21 @@ export class GraphWebview extends WebviewBase<State> {
}

@debug()
private fetch() {
void RepoActions.fetch(this.repository);
private fetch(item?: GraphItemContext) {
const ref = this.getGraphItemRef(item, 'branch');
void RepoActions.fetch(this.repository, ref);
}

@debug()
private pull() {
void RepoActions.pull(this.repository);
private pull(item?: GraphItemContext) {
const ref = this.getGraphItemRef(item, 'branch');
void RepoActions.pull(this.repository, ref);
}

@debug()
private push() {
void RepoActions.push(this.repository);
private push(item?: GraphItemContext) {
const ref = this.getGraphItemRef(item);
void RepoActions.push(this.repository, undefined, ref);
}

@debug()
Expand Down Expand Up @@ -2444,6 +2479,10 @@ export class GraphWebview extends WebviewBase<State> {
}

private getGraphItemRef(item?: GraphItemContext | unknown | undefined): GitReference | undefined;
private getGraphItemRef(
item: GraphItemContext | unknown | undefined,
refType: 'branch',
): GitBranchReference | undefined;
private getGraphItemRef(
item: GraphItemContext | unknown | undefined,
refType: 'revision',
Expand All @@ -2452,20 +2491,27 @@ export class GraphWebview extends WebviewBase<State> {
item: GraphItemContext | unknown | undefined,
refType: 'stash',
): GitStashReference | undefined;
private getGraphItemRef(item: GraphItemContext | unknown | undefined, refType: 'tag'): GitTagReference | undefined;
private getGraphItemRef(
item?: GraphItemContext | unknown,
refType?: 'revision' | 'stash',
refType?: 'branch' | 'revision' | 'stash' | 'tag',
): GitReference | undefined {
if (item == null) {
const ref = this.activeSelection;
return ref != null && (refType == null || refType === ref.refType) ? ref : undefined;
}

switch (refType) {
case 'branch':
return isGraphItemRefContext(item, 'branch') || isGraphItemTypedContext(item, 'upstreamStatus')
? item.webviewItemValue.ref
: undefined;
case 'revision':
return isGraphItemRefContext(item, 'revision') ? item.webviewItemValue.ref : undefined;
case 'stash':
return isGraphItemRefContext(item, 'stash') ? item.webviewItemValue.ref : undefined;
case 'tag':
return isGraphItemRefContext(item, 'tag') ? item.webviewItemValue.ref : undefined;
default:
return isGraphItemRefContext(item) ? item.webviewItemValue.ref : undefined;
}
Expand Down Expand Up @@ -2504,7 +2550,10 @@ export interface GraphItemRefGroupContextValue {
}

export type GraphItemTypedContext<T = GraphItemTypedContextValue> = WebviewItemContext<T>;
export type GraphItemTypedContextValue = GraphContributorContextValue | GraphPullRequestContextValue;
export type GraphItemTypedContextValue =
| GraphContributorContextValue
| GraphPullRequestContextValue
| GraphUpstreamStatusContextValue;

export type GraphColumnsContextValue = string;

Expand Down Expand Up @@ -2542,6 +2591,13 @@ export interface GraphTagContextValue {
ref: GitTagReference;
}

export interface GraphUpstreamStatusContextValue {
type: 'upstreamStatus';
ref: GitBranchReference;
ahead: number;
behind: number;
}

function isGraphItemContext(item: unknown): item is GraphItemContext {
if (item == null) return false;

Expand All @@ -2562,6 +2618,10 @@ function isGraphItemTypedContext(
item: unknown,
type: 'pullrequest',
): item is GraphItemTypedContext<GraphPullRequestContextValue>;
function isGraphItemTypedContext(
item: unknown,
type: 'upstreamStatus',
): item is GraphItemTypedContext<GraphUpstreamStatusContextValue>;
function isGraphItemTypedContext(
item: unknown,
type: GraphItemTypedContextValue['type'],
Expand Down
5 changes: 4 additions & 1 deletion src/plus/webviews/graph/protocol.ts
Expand Up @@ -14,6 +14,7 @@ import type {
IncludeOnlyRefsById,
PullRequestMetadata,
RefMetadata,
RefMetadataItem,
RefMetadataType,
Remote,
Tag,
Expand All @@ -38,14 +39,15 @@ export type GraphRefMetadata = RefMetadata | null;
export type GraphUpstreamMetadata = UpstreamMetadata | null;
export type GraphRefsMetadata = Record</* id */ string, GraphRefMetadata>;
export type GraphHostingServiceType = HostingServiceType;
export type GraphRefMetadataItem = RefMetadataItem;
export type GraphRefMetadataType = RefMetadataType;
export type GraphMissingRefsMetadataType = RefMetadataType;
export type GraphMissingRefsMetadata = Record</*id*/ string, /*missingType*/ GraphMissingRefsMetadataType[]>;
export type GraphPullRequestMetadata = PullRequestMetadata;

export enum GraphRefMetadataTypes {
Upstream = 'upstream',
PullRequest = 'pullRequests',
PullRequest = 'pullRequest',
}

export const supportedRefMetadataTypes: GraphRefMetadataType[] = Object.values(GraphRefMetadataTypes);
Expand Down Expand Up @@ -182,6 +184,7 @@ export type DoubleClickedParams =
| {
type: 'ref';
ref: GraphRef;
metadata?: GraphRefMetadataItem;
}
| {
type: 'row';
Expand Down
6 changes: 4 additions & 2 deletions src/webviews/apps/plus/graph/GraphWrapper.tsx
Expand Up @@ -31,6 +31,7 @@ import type {
GraphExcludedRef,
GraphExcludeTypes,
GraphMissingRefsMetadata,
GraphRefMetadataItem,
GraphRepository,
GraphSearchResults,
GraphSearchResultsError,
Expand Down Expand Up @@ -81,7 +82,7 @@ export interface GraphWrapperProps {
onChooseRepository?: () => void;
onColumnsChange?: (colsSettings: GraphColumnsConfig) => void;
onDimMergeCommits?: (dim: boolean) => void;
onDoubleClickRef?: (ref: GraphRef) => void;
onDoubleClickRef?: (ref: GraphRef, metadata?: GraphRefMetadataItem) => void;
onDoubleClickRow?: (row: GraphRow, preserveFocus?: boolean) => void;
onMissingAvatars?: (emails: { [email: string]: string }) => void;
onMissingRefsMetadata?: (metadata: GraphMissingRefsMetadata) => void;
Expand Down Expand Up @@ -835,9 +836,10 @@ export function GraphWrapper({
_event: React.MouseEvent<HTMLButtonElement, globalThis.MouseEvent>,
refGroup: GraphRefGroup,
_row: GraphRow,
metadata?: GraphRefMetadataItem,
) => {
if (refGroup.length > 0) {
onDoubleClickRef?.(refGroup[0]);
onDoubleClickRef?.(refGroup[0], metadata);
}
};

Expand Down
6 changes: 4 additions & 2 deletions src/webviews/apps/plus/graph/graph.tsx
Expand Up @@ -11,6 +11,7 @@ import type {
GraphExcludedRef,
GraphExcludeTypes,
GraphMissingRefsMetadata,
GraphRefMetadataItem,
InternalNotificationType,
State,
UpdateGraphConfigurationParams,
Expand Down Expand Up @@ -101,7 +102,7 @@ export class GraphApp extends App<State> {
this.onRefsVisibilityChanged(refs, visible)
}
onChooseRepository={debounce<GraphApp['onChooseRepository']>(() => this.onChooseRepository(), 250)}
onDoubleClickRef={ref => this.onDoubleClickRef(ref)}
onDoubleClickRef={(ref, metadata) => this.onDoubleClickRef(ref, metadata)}
onDoubleClickRow={(row, preserveFocus) => this.onDoubleClickRow(row, preserveFocus)}
onMissingAvatars={(...params) => this.onGetMissingAvatars(...params)}
onMissingRefsMetadata={(...params) => this.onGetMissingRefsMetadata(...params)}
Expand Down Expand Up @@ -583,10 +584,11 @@ export class GraphApp extends App<State> {
});
}

private onDoubleClickRef(ref: GraphRef) {
private onDoubleClickRef(ref: GraphRef, metadata?: GraphRefMetadataItem) {
this.sendCommand(DoubleClickedCommandType, {
type: 'ref',
ref: ref,
metadata: metadata,
});
}

Expand Down

0 comments on commit b232476

Please sign in to comment.