Kaynağa Gözat

Splits loading of the Graph webview from the rows

Loading the webview without the rows lets us provide feedback (spinners) while the rows are being loaded/processed and also parallelizes the webview initialization (react, component, etc) while git is working
main
Eric Amodio 2 yıl önce
ebeveyn
işleme
378d0880e9
3 değiştirilmiş dosya ile 38 ekleme ve 24 silme
  1. +31
    -17
      src/plus/webviews/graph/graphWebview.ts
  2. +2
    -2
      src/plus/webviews/graph/protocol.ts
  3. +5
    -5
      src/webviews/apps/plus/graph/GraphWrapper.tsx

+ 31
- 17
src/plus/webviews/graph/graphWebview.ts Dosyayı Görüntüle

@ -165,9 +165,7 @@ export class GraphWebview extends WebviewBase {
}
protected override async includeBootstrap(): Promise<State> {
return window.withProgress({ location: ProgressLocation.Window, title: 'Loading Commit Graph...' }, async () =>
this.getState(),
);
return this.getState(true);
}
protected override registerCommands(): Disposable[] {
@ -497,8 +495,8 @@ export class GraphWebview extends WebviewBase {
return config;
}
private async getState(): Promise<State> {
if (this.container.git.repositoryCount === 0) return { repositories: [] };
private async getState(deferRows?: boolean): Promise<State> {
if (this.container.git.repositoryCount === 0) return { allowed: true, repositories: [] };
if (this.previewBanner == null || this.trialBanner == null) {
const banners = this.container.storage.getWorkspace('graph:banners:dismissed');
@ -512,7 +510,7 @@ export class GraphWebview extends WebviewBase {
if (this.repository == null) {
this.repository = this.container.git.getBestRepositoryOrFirst();
if (this.repository == null) return { repositories: [] };
if (this.repository == null) return { allowed: true, repositories: [] };
}
this._etagRepository = this.repository?.etag;
@ -525,32 +523,48 @@ export class GraphWebview extends WebviewBase {
// Check for GitLens+ access
const access = await this.getGraphAccess();
const visibility = access.visibility ?? (await this.container.git.visibility(this.repository.path));
const data = await this.container.git.getCommitsForGraph(
const dataPromise = this.container.git.getCommitsForGraph(
this.repository.path,
this._panel!.webview.asWebviewUri.bind(this._panel!.webview),
{ limit: limit, ref: this._selectedSha ?? 'HEAD' },
);
this.setGraph(data);
this.setSelectedRows(data.sha);
let data;
if (deferRows) {
queueMicrotask(async () => {
const data = await dataPromise;
this.setGraph(data);
this.setSelectedRows(data.sha);
void this.notifyDidChangeCommits();
});
} else {
data = await dataPromise;
this.setGraph(data);
this.setSelectedRows(data.sha);
}
return {
previewBanner: this.previewBanner,
trialBanner: this.trialBanner,
repositories: formatRepositories(this.container.git.openRepositories),
selectedRepository: this.repository.path,
selectedRepositoryVisibility: visibility,
selectedRows: this._selectedRows,
selectedVisibility: visibility,
subscription: access.subscription.current,
allowed: access.allowed,
avatars: Object.fromEntries(data.avatars),
rows: data.rows,
paging: {
startingCursor: data.paging?.startingCursor,
more: data.paging?.more ?? false,
},
avatars: data != null ? Object.fromEntries(data.avatars) : undefined,
rows: data?.rows,
paging:
data != null
? {
startingCursor: data.paging?.startingCursor,
more: data.paging?.more ?? false,
}
: undefined,
config: config,
nonce: this.cspNonce,
};

+ 2
- 2
src/plus/webviews/graph/protocol.ts Dosyayı Görüntüle

@ -8,10 +8,10 @@ import { IpcCommandType, IpcNotificationType } from '../../../webviews/protocol'
export interface State {
repositories?: GraphRepository[];
selectedRepository?: string;
selectedVisibility?: RepositoryVisibility;
selectedRepositoryVisibility?: RepositoryVisibility;
selectedRows?: { [id: string]: true };
subscription?: Subscription;
allowed?: boolean;
allowed: boolean;
avatars?: { [email: string]: string };
rows?: GraphRow[];
paging?: GraphPaging;

+ 5
- 5
src/webviews/apps/plus/graph/GraphWrapper.tsx Dosyayı Görüntüle

@ -139,7 +139,7 @@ export function GraphWrapper({
selectedRepository,
selectedRows,
subscription,
selectedVisibility,
selectedRepositoryVisibility,
allowed,
avatars,
config,
@ -164,7 +164,7 @@ export function GraphWrapper({
const [graphSelectedRows, setSelectedRows] = useState(selectedRows);
const [graphColSettings, setGraphColSettings] = useState(getGraphColSettingsModel(config));
const [pagingState, setPagingState] = useState(paging);
const [isLoading, setIsLoading] = useState(false);
const [isLoading, setIsLoading] = useState(true);
const [styleProps, setStyleProps] = useState(getStyleProps(mixedColumnColors));
// TODO: application shouldn't know about the graph component's header
const graphHeaderOffset = 24;
@ -176,7 +176,7 @@ export function GraphWrapper({
// account
const [showAccount, setShowAccount] = useState(trialBanner);
const [isAllowed, setIsAllowed] = useState(allowed ?? false);
const [isPrivateRepo, setIsPrivateRepo] = useState(selectedVisibility === RepositoryVisibility.Private);
const [isPrivateRepo, setIsPrivateRepo] = useState(selectedRepositoryVisibility === RepositoryVisibility.Private);
const [subscriptionSnapshot, setSubscriptionSnapshot] = useState<Subscription | undefined>(subscription);
// repo selection UI
const [repoExpanded, setRepoExpanded] = useState(false);
@ -211,11 +211,11 @@ export function GraphWrapper({
setSelectedRows(state.selectedRows);
setGraphColSettings(getGraphColSettingsModel(state.config));
setPagingState(state.paging);
setIsLoading(false);
setIsLoading(state.rows == null);
setStyleProps(getStyleProps(state.mixedColumnColors));
setIsAllowed(state.allowed ?? false);
setSubscriptionSnapshot(state.subscription);
setIsPrivateRepo(state.selectedVisibility === RepositoryVisibility.Private);
setIsPrivateRepo(state.selectedRepositoryVisibility === RepositoryVisibility.Private);
}
useEffect(() => {

Yükleniyor…
İptal
Kaydet