Browse Source

Send remote ids and handle ref metadata requests when remote connected

main
Ramin Tadayon 2 years ago
committed by Eric Amodio
parent
commit
0a17784b42
7 changed files with 157 additions and 7 deletions
  1. +10
    -4
      src/env/node/git/localGitProvider.ts
  2. +5
    -1
      src/git/models/graph.ts
  3. +12
    -1
      src/plus/github/githubGitProvider.ts
  4. +83
    -1
      src/plus/webviews/graph/graphWebview.ts
  5. +17
    -0
      src/plus/webviews/graph/protocol.ts
  6. +15
    -0
      src/webviews/apps/plus/graph/GraphWrapper.tsx
  7. +15
    -0
      src/webviews/apps/plus/graph/graph.tsx

+ 10
- 4
src/env/node/git/localGitProvider.ts View File

@ -14,8 +14,9 @@ import type {
} from '../../../@types/vscode.git'; } from '../../../@types/vscode.git';
import { getCachedAvatarUri } from '../../../avatars'; import { getCachedAvatarUri } from '../../../avatars';
import { configuration } from '../../../configuration'; import { configuration } from '../../../configuration';
import { CoreGitConfiguration, GlyphChars, Schemes } from '../../../constants';
import { ContextKeys, CoreGitConfiguration, GlyphChars, Schemes } from '../../../constants';
import type { Container } from '../../../container'; import type { Container } from '../../../container';
import { getContext } from '../../../context';
import { emojify } from '../../../emojis'; import { emojify } from '../../../emojis';
import { Features } from '../../../features'; import { Features } from '../../../features';
import { GitErrorHandling } from '../../../git/commandOptions'; import { GitErrorHandling } from '../../../git/commandOptions';
@ -61,6 +62,7 @@ import type { GitFile, GitFileStatus } from '../../../git/models/file';
import { GitFileChange } from '../../../git/models/file'; import { GitFileChange } from '../../../git/models/file';
import type { import type {
GitGraph, GitGraph,
GitGraphRefMetadata,
GitGraphRow, GitGraphRow,
GitGraphRowContexts, GitGraphRowContexts,
GitGraphRowHead, GitGraphRowHead,
@ -1660,7 +1662,9 @@ export class LocalGitProvider implements GitProvider, Disposable {
); );
} }
const hasConnectedRemotes = getContext(ContextKeys.HasConnectedRemotes);
const avatars = new Map<string, string>(); const avatars = new Map<string, string>();
const refMetadata = hasConnectedRemotes ? new Map<string, GitGraphRefMetadata>() : undefined;
const ids = new Set<string>(); const ids = new Set<string>();
const reachableFromHEAD = new Set<string>(); const reachableFromHEAD = new Set<string>();
const skippedIds = new Set<string>(); const skippedIds = new Set<string>();
@ -1706,7 +1710,7 @@ export class LocalGitProvider implements GitProvider, Disposable {
if (cursorIndex === -1) { if (cursorIndex === -1) {
// If we didn't find any new commits, we must have them all so return that we have everything // If we didn't find any new commits, we must have them all so return that we have everything
if (size === data.length) { if (size === data.length) {
return { repoPath: repoPath, avatars: avatars, ids: ids, rows: [] };
return { repoPath: repoPath, avatars: avatars, ids: ids, refMetadata: refMetadata, rows: [] };
} }
size = data.length; size = data.length;
@ -1732,7 +1736,7 @@ export class LocalGitProvider implements GitProvider, Disposable {
} }
} }
if (!data) return { repoPath: repoPath, avatars: avatars, ids: ids, rows: [] };
if (!data) return { repoPath: repoPath, avatars: avatars, ids: ids, refMetadata: refMetadata, rows: [] };
log = data; log = data;
if (limit !== 0) { if (limit !== 0) {
@ -1812,6 +1816,7 @@ export class LocalGitProvider implements GitProvider, Disposable {
} }
} }
branch = branchMap.get(tip);
remoteName = getRemoteNameFromBranchName(tip); remoteName = getRemoteNameFromBranchName(tip);
if (remoteName) { if (remoteName) {
remote = remoteMap.get(remoteName); remote = remoteMap.get(remoteName);
@ -1820,6 +1825,7 @@ export class LocalGitProvider implements GitProvider, Disposable {
if (branchName === 'HEAD') continue; if (branchName === 'HEAD') continue;
refRemoteHeads.push({ refRemoteHeads.push({
id: branch?.id ?? remote.id,
name: branchName, name: branchName,
owner: remote.name, owner: remote.name,
url: remote.url, url: remote.url,
@ -1845,7 +1851,6 @@ export class LocalGitProvider implements GitProvider, Disposable {
} }
} }
branch = branchMap.get(tip);
refHeads.push({ refHeads.push({
name: tip, name: tip,
isCurrentHead: current, isCurrentHead: current,
@ -1963,6 +1968,7 @@ export class LocalGitProvider implements GitProvider, Disposable {
avatars: avatars, avatars: avatars,
ids: ids, ids: ids,
skippedIds: skippedIds, skippedIds: skippedIds,
refMetadata: refMetadata,
rows: rows, rows: rows,
id: sha, id: sha,

+ 5
- 1
src/git/models/graph.ts View File

@ -1,9 +1,11 @@
import type { GraphRow, Head, Remote, RowContexts, Tag } from '@gitkraken/gitkraken-components';
import type { GraphRow, Head, HostingServiceType, RefMetadata, Remote, RowContexts, Tag } from '@gitkraken/gitkraken-components';
export type GitGraphRowHead = Head; export type GitGraphRowHead = Head;
export type GitGraphRowRemoteHead = Remote; export type GitGraphRowRemoteHead = Remote;
export type GitGraphRowTag = Tag; export type GitGraphRowTag = Tag;
export type GitGraphRowContexts = RowContexts; export type GitGraphRowContexts = RowContexts;
export type GitGraphRefMetadata = RefMetadata;
export type GitGraphHostingServiceType = HostingServiceType;
export const enum GitGraphRowType { export const enum GitGraphRowType {
Commit = 'commit-node', Commit = 'commit-node',
MergeCommit = 'merge-node', MergeCommit = 'merge-node',
@ -25,6 +27,8 @@ export interface GitGraph {
readonly repoPath: string; readonly repoPath: string;
/** A map of all avatar urls */ /** A map of all avatar urls */
readonly avatars: Map<string, string>; readonly avatars: Map<string, string>;
/** A map of all ref metadata */
readonly refMetadata: Map<string, RefMetadata> | undefined;
/** A set of all "seen" commit ids */ /** A set of all "seen" commit ids */
readonly ids: Set<string>; readonly ids: Set<string>;
/** A set of all skipped commit ids -- typically for stash index/untracked commits */ /** A set of all skipped commit ids -- typically for stash index/untracked commits */

+ 12
- 1
src/plus/github/githubGitProvider.ts View File

@ -14,7 +14,7 @@ import { encodeUtf8Hex } from '@env/hex';
import { configuration } from '../../configuration'; import { configuration } from '../../configuration';
import { CharCode, ContextKeys, Schemes } from '../../constants'; import { CharCode, ContextKeys, Schemes } from '../../constants';
import type { Container } from '../../container'; import type { Container } from '../../container';
import { setContext } from '../../context';
import { getContext, setContext } from '../../context';
import { emojify } from '../../emojis'; import { emojify } from '../../emojis';
import { import {
AuthenticationError, AuthenticationError,
@ -48,6 +48,7 @@ import type { GitFile } from '../../git/models/file';
import { GitFileChange, GitFileIndexStatus } from '../../git/models/file'; import { GitFileChange, GitFileIndexStatus } from '../../git/models/file';
import type { import type {
GitGraph, GitGraph,
GitGraphRefMetadata,
GitGraphRow, GitGraphRow,
GitGraphRowHead, GitGraphRowHead,
GitGraphRowRemoteHead, GitGraphRowRemoteHead,
@ -56,6 +57,7 @@ import type {
import { GitGraphRowType } from '../../git/models/graph'; import { GitGraphRowType } from '../../git/models/graph';
import type { GitLog } from '../../git/models/log'; import type { GitLog } from '../../git/models/log';
import type { GitMergeStatus } from '../../git/models/merge'; import type { GitMergeStatus } from '../../git/models/merge';
import type { PullRequest } from '../../git/models/pullRequest';
import type { GitRebaseStatus } from '../../git/models/rebase'; import type { GitRebaseStatus } from '../../git/models/rebase';
import type { GitBranchReference, GitReference } from '../../git/models/reference'; import type { GitBranchReference, GitReference } from '../../git/models/reference';
import { GitRevision } from '../../git/models/reference'; import { GitRevision } from '../../git/models/reference';
@ -1083,7 +1085,9 @@ export class GitHubGitProvider implements GitProvider, Disposable {
this.getTags(repoPath), this.getTags(repoPath),
]); ]);
const hasConnectedRemotes = getContext(ContextKeys.HasConnectedRemotes);
const avatars = new Map<string, string>(); const avatars = new Map<string, string>();
const refMetadata = hasConnectedRemotes ? new Map<string, GitGraphRefMetadata>() : undefined;
const ids = new Set<string>(); const ids = new Set<string>();
return this.getCommitsForGraphCore( return this.getCommitsForGraphCore(
@ -1094,6 +1098,7 @@ export class GitHubGitProvider implements GitProvider, Disposable {
getSettledValue(remotesResult)?.[0], getSettledValue(remotesResult)?.[0],
getSettledValue(tagsResult)?.values, getSettledValue(tagsResult)?.values,
avatars, avatars,
refMetadata,
ids, ids,
options, options,
); );
@ -1107,6 +1112,7 @@ export class GitHubGitProvider implements GitProvider, Disposable {
remote: GitRemote | undefined, remote: GitRemote | undefined,
tags: GitTag[] | undefined, tags: GitTag[] | undefined,
avatars: Map<string, string>, avatars: Map<string, string>,
refMetadata: Map<string, GitGraphRefMetadata> | undefined,
ids: Set<string>, ids: Set<string>,
options?: { options?: {
branch?: string; branch?: string;
@ -1119,6 +1125,7 @@ export class GitHubGitProvider implements GitProvider, Disposable {
return { return {
repoPath: repoPath, repoPath: repoPath,
avatars: avatars, avatars: avatars,
refMetadata: refMetadata,
ids: ids, ids: ids,
rows: [], rows: [],
}; };
@ -1129,6 +1136,7 @@ export class GitHubGitProvider implements GitProvider, Disposable {
return { return {
repoPath: repoPath, repoPath: repoPath,
avatars: avatars, avatars: avatars,
refMetadata: refMetadata,
ids: ids, ids: ids,
rows: [], rows: [],
}; };
@ -1154,6 +1162,7 @@ export class GitHubGitProvider implements GitProvider, Disposable {
]; ];
refRemoteHeads = [ refRemoteHeads = [
{ {
id: remote.id,
name: branch.name, name: branch.name,
owner: remote.name, owner: remote.name,
url: remote.url, url: remote.url,
@ -1213,6 +1222,7 @@ export class GitHubGitProvider implements GitProvider, Disposable {
return { return {
repoPath: repoPath, repoPath: repoPath,
avatars: avatars, avatars: avatars,
refMetadata: refMetadata,
ids: ids, ids: ids,
rows: rows, rows: rows,
id: options?.ref, id: options?.ref,
@ -1232,6 +1242,7 @@ export class GitHubGitProvider implements GitProvider, Disposable {
remote, remote,
tags, tags,
avatars, avatars,
refMetadata,
ids, ids,
options, options,
); );

+ 83
- 1
src/plus/webviews/graph/graphWebview.ts View File

@ -32,9 +32,10 @@ import type { Container } from '../../../container';
import { getContext, onDidChangeContext, setContext } from '../../../context'; import { getContext, onDidChangeContext, setContext } from '../../../context';
import { PlusFeatures } from '../../../features'; import { PlusFeatures } from '../../../features';
import { GitSearchError } from '../../../git/errors'; import { GitSearchError } from '../../../git/errors';
import type { GitBranch } from '../../../git/models/branch';
import type { GitCommit } from '../../../git/models/commit'; import type { GitCommit } from '../../../git/models/commit';
import { GitGraphRowType } from '../../../git/models/graph'; import { GitGraphRowType } from '../../../git/models/graph';
import type { GitGraph } from '../../../git/models/graph';
import type { GitGraph, GitGraphHostingServiceType } from '../../../git/models/graph';
import type { import type {
GitBranchReference, GitBranchReference,
GitRevisionReference, GitRevisionReference,
@ -76,6 +77,7 @@ import type {
DismissBannerParams, DismissBannerParams,
EnsureRowParams, EnsureRowParams,
GetMissingAvatarsParams, GetMissingAvatarsParams,
GetMissingRefMetadataParams,
GetMoreRowsParams, GetMoreRowsParams,
GraphColumnConfig, GraphColumnConfig,
GraphColumnName, GraphColumnName,
@ -96,6 +98,7 @@ import {
DidChangeColumnsNotificationType, DidChangeColumnsNotificationType,
DidChangeGraphConfigurationNotificationType, DidChangeGraphConfigurationNotificationType,
DidChangeNotificationType, DidChangeNotificationType,
DidChangeRefMetadataNotificationType,
DidChangeRowsNotificationType, DidChangeRowsNotificationType,
DidChangeSelectionNotificationType, DidChangeSelectionNotificationType,
DidChangeSubscriptionNotificationType, DidChangeSubscriptionNotificationType,
@ -105,6 +108,7 @@ import {
DismissBannerCommandType, DismissBannerCommandType,
EnsureRowCommandType, EnsureRowCommandType,
GetMissingAvatarsCommandType, GetMissingAvatarsCommandType,
GetMissingRefMetadataCommandType,
GetMoreRowsCommandType, GetMoreRowsCommandType,
SearchCommandType, SearchCommandType,
SearchOpenInViewCommandType, SearchOpenInViewCommandType,
@ -351,6 +355,9 @@ export class GraphWebview extends WebviewBase {
case GetMissingAvatarsCommandType.method: case GetMissingAvatarsCommandType.method:
onIpc(GetMissingAvatarsCommandType, e, params => this.onGetMissingAvatars(params)); onIpc(GetMissingAvatarsCommandType, e, params => this.onGetMissingAvatars(params));
break; break;
case GetMissingRefMetadataCommandType.method:
onIpc(GetMissingRefMetadataCommandType, e, params => this.onGetMissingRefMetadata(params));
break;
case GetMoreRowsCommandType.method: case GetMoreRowsCommandType.method:
onIpc(GetMoreRowsCommandType, e, params => this.onGetMoreRows(params)); onIpc(GetMoreRowsCommandType, e, params => this.onGetMoreRows(params));
break; break;
@ -535,6 +542,52 @@ export class GraphWebview extends WebviewBase {
} }
} }
private async onGetMissingRefMetadata(e: GetMissingRefMetadataParams) {
if (this._graph == null) return;
const repoPath = this._graph.repoPath;
const hasConnectedRemotes = getContext(ContextKeys.HasConnectedRemotes);
if (!hasConnectedRemotes) return;
async function getRefMetadata(this: GraphWebview, id: string, type: string) {
const newRefMetadata = { ...(this._graph!.refMetadata ? this._graph!.refMetadata.get(id) : undefined) };
const foundBranchesResult = await this.container.git.getBranches(repoPath, { filter: b => b.id === id });
const foundBranches = foundBranchesResult?.values;
const refBranch: GitBranch | undefined = foundBranches?.length ? foundBranches[0] : undefined;
switch (type) {
case 'pullRequests':
newRefMetadata.pullRequests = null;
if (refBranch != null) {
const pullRequest = await refBranch.getAssociatedPullRequest();
if (pullRequest != null) {
const pullRequestMetadata = {
hostingServiceType: pullRequest.provider.name as GitGraphHostingServiceType,
id: Number.parseInt(pullRequest.id) || 0,
title: pullRequest.title
};
newRefMetadata.pullRequests = [ pullRequestMetadata ];
}
}
break;
default:
break;
}
this._graph!.refMetadata?.set(id, newRefMetadata);
}
const promises: Promise<void>[] = [];
for (const [id, missingTypes] of Object.entries(e.missing)) {
for (const missingType of missingTypes) {
promises.push(getRefMetadata.call(this, id, missingType));
}
}
if (promises.length) {
await Promise.allSettled(promises);
this.updateRefMetadata();
}
}
@gate() @gate()
@debug() @debug()
private async onGetMoreRows(e: GetMoreRowsParams, sendSelectedRows: boolean = false) { private async onGetMoreRows(e: GetMoreRowsParams, sendSelectedRows: boolean = false) {
@ -761,6 +814,33 @@ export class GraphWebview extends WebviewBase {
}); });
} }
private _notifyDidChangeRefMetadataDebounced: Deferrable<GraphWebview['notifyDidChangeRefMetadata']> | undefined =
undefined;
@debug()
private updateRefMetadata(immediate: boolean = false) {
if (immediate) {
void this.notifyDidChangeRefMetadata();
return;
}
if (this._notifyDidChangeRefMetadataDebounced == null) {
this._notifyDidChangeRefMetadataDebounced = debounce(this.notifyDidChangeRefMetadata.bind(this), 100);
}
void this._notifyDidChangeRefMetadataDebounced();
}
@debug()
private async notifyDidChangeRefMetadata() {
if (this._graph == null) return;
const data = this._graph;
return this.notify(DidChangeRefMetadataNotificationType, {
refMetadata: data.refMetadata ? Object.fromEntries(data.refMetadata) : undefined,
});
}
@debug() @debug()
private async notifyDidChangeColumns() { private async notifyDidChangeColumns() {
if (!this.isReady || !this.visible) { if (!this.isReady || !this.visible) {
@ -797,6 +877,7 @@ export class GraphWebview extends WebviewBase {
{ {
rows: data.rows, rows: data.rows,
avatars: Object.fromEntries(data.avatars), avatars: Object.fromEntries(data.avatars),
refMetadata: data.refMetadata != undefined ? Object.fromEntries(data.refMetadata) : undefined,
selectedRows: sendSelectedRows ? this._selectedRows : undefined, selectedRows: sendSelectedRows ? this._selectedRows : undefined,
paging: { paging: {
startingCursor: data.paging?.startingCursor, startingCursor: data.paging?.startingCursor,
@ -1088,6 +1169,7 @@ export class GraphWebview extends WebviewBase {
subscription: access?.subscription.current, subscription: access?.subscription.current,
allowed: (access?.allowed ?? false) !== false, allowed: (access?.allowed ?? false) !== false,
avatars: data != null ? Object.fromEntries(data.avatars) : undefined, avatars: data != null ? Object.fromEntries(data.avatars) : undefined,
refMetadata: data?.refMetadata != undefined ? Object.fromEntries(data.refMetadata) : undefined,
loading: deferRows, loading: deferRows,
rows: data?.rows, rows: data?.rows,
paging: paging:

+ 17
- 0
src/plus/webviews/graph/protocol.ts View File

@ -4,6 +4,7 @@ import type {
GraphContexts, GraphContexts,
GraphRow, GraphRow,
GraphZoneType, GraphZoneType,
RefMetadata,
Remote, Remote,
WorkDirStats, WorkDirStats,
} from '@gitkraken/gitkraken-components'; } from '@gitkraken/gitkraken-components';
@ -18,6 +19,8 @@ import { IpcCommandType, IpcNotificationType } from '../../../webviews/protocol'
export type GraphColumnsSettings = Record<GraphColumnName, GraphColumnSetting>; export type GraphColumnsSettings = Record<GraphColumnName, GraphColumnSetting>;
export type GraphSelectedRows = Record</*id*/ string, true>; export type GraphSelectedRows = Record</*id*/ string, true>;
export type GraphAvatars = Record</*email*/ string, /*url*/ string>; export type GraphAvatars = Record</*email*/ string, /*url*/ string>;
export type GraphRefMetadata = Record</* id */ string, RefMetadata>;
export type GraphMissingRefMetadata = Record</*id*/ string, /*missingType*/ string[]>;
export interface State { export interface State {
repositories?: GraphRepository[]; repositories?: GraphRepository[];
@ -28,6 +31,7 @@ export interface State {
allowed: boolean; allowed: boolean;
avatars?: GraphAvatars; avatars?: GraphAvatars;
loading?: boolean; loading?: boolean;
refMetadata?: GraphRefMetadata;
rows?: GraphRow[]; rows?: GraphRow[];
paging?: GraphPaging; paging?: GraphPaging;
columns?: GraphColumnsSettings; columns?: GraphColumnsSettings;
@ -117,6 +121,11 @@ export interface GetMissingAvatarsParams {
} }
export const GetMissingAvatarsCommandType = new IpcCommandType<GetMissingAvatarsParams>('graph/avatars/get'); export const GetMissingAvatarsCommandType = new IpcCommandType<GetMissingAvatarsParams>('graph/avatars/get');
export interface GetMissingRefMetadataParams {
missing: GraphMissingRefMetadata;
}
export const GetMissingRefMetadataCommandType = new IpcCommandType<GetMissingRefMetadataParams>('graph/refMetadata/get');
export interface GetMoreRowsParams { export interface GetMoreRowsParams {
id?: string; id?: string;
} }
@ -182,6 +191,13 @@ export const DidChangeAvatarsNotificationType = new IpcNotificationType
'graph/avatars/didChange', 'graph/avatars/didChange',
); );
export interface DidChangeRefMetadataParams {
refMetadata: GraphRefMetadata | undefined;
}
export const DidChangeRefMetadataNotificationType = new IpcNotificationType<DidChangeRefMetadataParams>(
'graph/refMetadata/didChange',
);
export interface DidChangeColumnsParams { export interface DidChangeColumnsParams {
columns: GraphColumnsSettings | undefined; columns: GraphColumnsSettings | undefined;
context?: string; context?: string;
@ -195,6 +211,7 @@ export interface DidChangeRowsParams {
rows: GraphRow[]; rows: GraphRow[];
avatars: { [email: string]: string }; avatars: { [email: string]: string };
paging?: GraphPaging; paging?: GraphPaging;
refMetadata: GraphRefMetadata | undefined;
selectedRows?: GraphSelectedRows; selectedRows?: GraphSelectedRows;
} }
export const DidChangeRowsNotificationType = new IpcNotificationType<DidChangeRowsParams>('graph/rows/didChange'); export const DidChangeRowsNotificationType = new IpcNotificationType<DidChangeRowsParams>('graph/rows/didChange');

+ 15
- 0
src/webviews/apps/plus/graph/GraphWrapper.tsx View File

@ -30,6 +30,7 @@ import {
DidChangeAvatarsNotificationType, DidChangeAvatarsNotificationType,
DidChangeColumnsNotificationType, DidChangeColumnsNotificationType,
DidChangeGraphConfigurationNotificationType, DidChangeGraphConfigurationNotificationType,
DidChangeRefMetadataNotificationType,
DidChangeRowsNotificationType, DidChangeRowsNotificationType,
DidChangeSelectionNotificationType, DidChangeSelectionNotificationType,
DidChangeSubscriptionNotificationType, DidChangeSubscriptionNotificationType,
@ -52,6 +53,7 @@ export interface GraphWrapperProps {
onSelectRepository?: (repository: GraphRepository) => void; onSelectRepository?: (repository: GraphRepository) => void;
onColumnChange?: (name: GraphColumnName, settings: GraphColumnConfig) => void; onColumnChange?: (name: GraphColumnName, settings: GraphColumnConfig) => void;
onMissingAvatars?: (emails: { [email: string]: string }) => void; onMissingAvatars?: (emails: { [email: string]: string }) => void;
onMissingRefMetadata?: (missing: { [id: string]: string[] }) => void;
onMoreRows?: (id?: string) => void; onMoreRows?: (id?: string) => void;
onSearch?: (search: SearchQuery | undefined, options?: { limit?: number }) => void; onSearch?: (search: SearchQuery | undefined, options?: { limit?: number }) => void;
onSearchPromise?: ( onSearchPromise?: (
@ -132,6 +134,7 @@ export function GraphWrapper({
onColumnChange, onColumnChange,
onEnsureRowPromise, onEnsureRowPromise,
onMissingAvatars, onMissingAvatars,
onMissingRefMetadata,
onMoreRows, onMoreRows,
onSearch, onSearch,
onSearchPromise, onSearchPromise,
@ -148,6 +151,7 @@ export function GraphWrapper({
const [rows, setRows] = useState(state.rows ?? []); const [rows, setRows] = useState(state.rows ?? []);
const [avatars, setAvatars] = useState(state.avatars); const [avatars, setAvatars] = useState(state.avatars);
const [refMetadata, setRefMetadata] = useState(state.refMetadata);
const [repos, setRepos] = useState(state.repositories ?? []); const [repos, setRepos] = useState(state.repositories ?? []);
const [repo, setRepo] = useState<GraphRepository | undefined>( const [repo, setRepo] = useState<GraphRepository | undefined>(
repos.find(item => item.path === state.selectedRepository), repos.find(item => item.path === state.selectedRepository),
@ -205,6 +209,9 @@ export function GraphWrapper({
case DidChangeAvatarsNotificationType: case DidChangeAvatarsNotificationType:
setAvatars(state.avatars); setAvatars(state.avatars);
break; break;
case DidChangeRefMetadataNotificationType:
setRefMetadata(state.refMetadata);
break;
case DidChangeColumnsNotificationType: case DidChangeColumnsNotificationType:
setColumns(state.columns); setColumns(state.columns);
setContext(state.context); setContext(state.context);
@ -213,6 +220,7 @@ export function GraphWrapper({
setRows(state.rows ?? []); setRows(state.rows ?? []);
setSelectedRows(state.selectedRows); setSelectedRows(state.selectedRows);
setAvatars(state.avatars); setAvatars(state.avatars);
setRefMetadata(state.refMetadata);
setPagingHasMore(state.paging?.hasMore ?? false); setPagingHasMore(state.paging?.hasMore ?? false);
setIsLoading(state.loading); setIsLoading(state.loading);
break; break;
@ -248,6 +256,7 @@ export function GraphWrapper({
setSelectedRows(state.selectedRows); setSelectedRows(state.selectedRows);
setContext(state.context); setContext(state.context);
setAvatars(state.avatars ?? {}); setAvatars(state.avatars ?? {});
setRefMetadata(state.refMetadata ?? {});
setPagingHasMore(state.paging?.hasMore ?? false); setPagingHasMore(state.paging?.hasMore ?? false);
setRepos(state.repositories ?? []); setRepos(state.repositories ?? []);
setRepo(repos.find(item => item.path === state.selectedRepository)); setRepo(repos.find(item => item.path === state.selectedRepository));
@ -437,6 +446,10 @@ export function GraphWrapper({
onMissingAvatars?.(emails); onMissingAvatars?.(emails);
}; };
const handleMissingRefMetadata = (missing: { [id: string]: string[] }) => {
onMissingRefMetadata?.(missing);
};
const handleToggleColumnSettings = (event: React.MouseEvent<HTMLButtonElement, globalThis.MouseEvent>) => { const handleToggleColumnSettings = (event: React.MouseEvent<HTMLButtonElement, globalThis.MouseEvent>) => {
const e = event.nativeEvent; const e = event.nativeEvent;
const evt = new MouseEvent('contextmenu', { const evt = new MouseEvent('contextmenu', {
@ -688,8 +701,10 @@ export function GraphWrapper({
onColumnResized={handleOnColumnResized} onColumnResized={handleOnColumnResized}
onSelectGraphRows={handleSelectGraphRows} onSelectGraphRows={handleSelectGraphRows}
onEmailsMissingAvatarUrls={handleMissingAvatars} onEmailsMissingAvatarUrls={handleMissingAvatars}
onRefsMissingMetadata={handleMissingRefMetadata}
onShowMoreCommits={handleMoreCommits} onShowMoreCommits={handleMoreCommits}
platform={clientPlatform} platform={clientPlatform}
refMetadataById={refMetadata}
shaLength={graphConfig?.idLength} shaLength={graphConfig?.idLength}
themeOpacityFactor={styleProps?.themeOpacityFactor} themeOpacityFactor={styleProps?.themeOpacityFactor}
useAuthorInitialsForAvatars={!graphConfig?.avatars} useAuthorInitialsForAvatars={!graphConfig?.avatars}

+ 15
- 0
src/webviews/apps/plus/graph/graph.tsx View File

@ -18,6 +18,7 @@ import {
DidChangeColumnsNotificationType, DidChangeColumnsNotificationType,
DidChangeGraphConfigurationNotificationType, DidChangeGraphConfigurationNotificationType,
DidChangeNotificationType, DidChangeNotificationType,
DidChangeRefMetadataNotificationType,
DidChangeRowsNotificationType, DidChangeRowsNotificationType,
DidChangeSelectionNotificationType, DidChangeSelectionNotificationType,
DidChangeSubscriptionNotificationType, DidChangeSubscriptionNotificationType,
@ -27,6 +28,7 @@ import {
DismissBannerCommandType, DismissBannerCommandType,
EnsureRowCommandType, EnsureRowCommandType,
GetMissingAvatarsCommandType, GetMissingAvatarsCommandType,
GetMissingRefMetadataCommandType,
GetMoreRowsCommandType, GetMoreRowsCommandType,
SearchCommandType, SearchCommandType,
SearchOpenInViewCommandType, SearchOpenInViewCommandType,
@ -85,6 +87,7 @@ export class GraphApp extends App {
250, 250,
)} )}
onMissingAvatars={(...params) => this.onGetMissingAvatars(...params)} onMissingAvatars={(...params) => this.onGetMissingAvatars(...params)}
onMissingRefMetadata={(...params) => this.onGetMissingRefMetadata(...params)}
onMoreRows={(...params) => this.onGetMoreRows(...params)} onMoreRows={(...params) => this.onGetMoreRows(...params)}
onSearch={debounce<GraphApp['onSearch']>((search, options) => this.onSearch(search, options), 250)} onSearch={debounce<GraphApp['onSearch']>((search, options) => this.onSearch(search, options), 250)}
onSearchPromise={(...params) => this.onSearchPromise(...params)} onSearchPromise={(...params) => this.onSearchPromise(...params)}
@ -141,6 +144,13 @@ export class GraphApp extends App {
}); });
break; break;
case DidChangeRefMetadataNotificationType.method:
onIpc(DidChangeRefMetadataNotificationType, msg, (params, type) => {
this.state.refMetadata = params.refMetadata;
this.setState(this.state, type);
});
break;
case DidChangeRowsNotificationType.method: case DidChangeRowsNotificationType.method:
onIpc(DidChangeRowsNotificationType, msg, (params, type) => { onIpc(DidChangeRowsNotificationType, msg, (params, type) => {
let rows; let rows;
@ -205,6 +215,7 @@ export class GraphApp extends App {
} }
this.state.avatars = params.avatars; this.state.avatars = params.avatars;
this.state.refMetadata = params.refMetadata;
this.state.rows = rows; this.state.rows = rows;
this.state.paging = params.paging; this.state.paging = params.paging;
if (params.selectedRows != null) { if (params.selectedRows != null) {
@ -365,6 +376,10 @@ export class GraphApp extends App {
this.sendCommand(GetMissingAvatarsCommandType, { emails: emails }); this.sendCommand(GetMissingAvatarsCommandType, { emails: emails });
} }
private onGetMissingRefMetadata(missing: { [id: string]: string[] }) {
this.sendCommand(GetMissingRefMetadataCommandType, { missing: missing });
}
private onGetMoreRows(sha?: string) { private onGetMoreRows(sha?: string) {
return this.sendCommand(GetMoreRowsCommandType, { id: sha }); return this.sendCommand(GetMoreRowsCommandType, { id: sha });
} }

Loading…
Cancel
Save