Skip to content

Commit 6d90c12

Browse files
authored
Clean up getting started async (microsoft#182947)
* move remote entry to gettingstarted.contribution * Clean up gettingStarted service
1 parent 679bb96 commit 6d90c12

File tree

5 files changed

+94
-141
lines changed

5 files changed

+94
-141
lines changed

src/vs/workbench/contrib/remote/browser/remote.contribution.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import { TunnelFactoryContribution } from 'vs/workbench/contrib/remote/browser/t
1111
import { RemoteAgentConnectionStatusListener, RemoteMarkers } from 'vs/workbench/contrib/remote/browser/remote';
1212
import { RemoteStatusIndicator } from 'vs/workbench/contrib/remote/browser/remoteIndicator';
1313
import { AutomaticPortForwarding, ForwardedPortsView, PortRestore } from 'vs/workbench/contrib/remote/browser/remoteExplorer';
14-
import { RemoteStartEntry } from 'vs/workbench/contrib/remote/browser/remoteStartEntry';
1514

1615
const workbenchContributionsRegistry = Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench);
1716
workbenchContributionsRegistry.registerWorkbenchContribution(ShowCandidateContribution, LifecyclePhase.Ready);
@@ -22,4 +21,3 @@ workbenchContributionsRegistry.registerWorkbenchContribution(ForwardedPortsView,
2221
workbenchContributionsRegistry.registerWorkbenchContribution(PortRestore, LifecyclePhase.Eventually);
2322
workbenchContributionsRegistry.registerWorkbenchContribution(AutomaticPortForwarding, LifecyclePhase.Eventually);
2423
workbenchContributionsRegistry.registerWorkbenchContribution(RemoteMarkers, LifecyclePhase.Eventually);
25-
workbenchContributionsRegistry.registerWorkbenchContribution(RemoteStartEntry, LifecyclePhase.Restored);

src/vs/workbench/contrib/remote/browser/remote.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ class HelpItemValue {
316316
} else if (this.urlOrCommandOrId?.id) {
317317
try {
318318
const walkthroughId = `${this.extensionDescription.id}#${this.urlOrCommandOrId.id}`;
319-
const walkthrough = this.walkthroughService.getWalkthrough(walkthroughId);
319+
const walkthrough = await this.walkthroughService.getWalkthrough(walkthroughId);
320320
this._description = walkthrough.title;
321321
this._url = walkthroughId;
322322
} catch { }

src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted.contribution.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import { IExtensionService } from 'vs/workbench/services/extensions/common/exten
3131
import { StartupPageContribution, } from 'vs/workbench/contrib/welcomeGettingStarted/browser/startupPage';
3232
import { ExtensionsInput } from 'vs/workbench/contrib/extensions/common/extensionsInput';
3333
import { Categories } from 'vs/platform/action/common/actionCommonCategories';
34+
import { RemoteStartEntry } from 'vs/workbench/contrib/remote/browser/remoteStartEntry';
3435

3536
export * as icons from 'vs/workbench/contrib/welcomeGettingStarted/browser/gettingStartedIcons';
3637

@@ -205,11 +206,11 @@ registerAction2(class extends Action2 {
205206
});
206207
}
207208

208-
private getQuickPickItems(
209+
private async getQuickPickItems(
209210
contextService: IContextKeyService,
210211
gettingStartedService: IWalkthroughsService
211-
): IQuickPickItem[] {
212-
const categories = gettingStartedService.getWalkthroughs();
212+
): Promise<IQuickPickItem[]> {
213+
const categories = await gettingStartedService.getWalkthroughs();
213214
return categories
214215
.filter(c => contextService.contextMatchesRules(c.when))
215216
.map(x => ({
@@ -232,7 +233,7 @@ registerAction2(class extends Action2 {
232233
quickPick.matchOnDescription = true;
233234
quickPick.matchOnDetail = true;
234235
quickPick.placeholder = localize('pickWalkthroughs', 'Select a walkthrough to open');
235-
quickPick.items = this.getQuickPickItems(contextService, gettingStartedService);
236+
quickPick.items = await this.getQuickPickItems(contextService, gettingStartedService);
236237
quickPick.busy = true;
237238
quickPick.onDidAccept(() => {
238239
const selection = quickPick.selectedItems[0];
@@ -245,8 +246,7 @@ registerAction2(class extends Action2 {
245246
quickPick.show();
246247
await extensionService.whenInstalledExtensionsRegistered();
247248
quickPick.busy = false;
248-
await gettingStartedService.installedExtensionsRegistered;
249-
quickPick.items = this.getQuickPickItems(contextService, gettingStartedService);
249+
quickPick.items = await this.getQuickPickItems(contextService, gettingStartedService);
250250
}
251251
});
252252

@@ -325,3 +325,6 @@ configurationRegistry.registerConfiguration({
325325

326326
Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench)
327327
.registerWorkbenchContribution(StartupPageContribution, LifecyclePhase.Restored);
328+
329+
Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench)
330+
.registerWorkbenchContribution(RemoteStartEntry, LifecyclePhase.Restored);

src/vs/workbench/contrib/welcomeGettingStarted/browser/gettingStarted.ts

Lines changed: 59 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ import { ConfigurationTarget, IConfigurationService } from 'vs/platform/configur
2929
import { ContextKeyExpr, ContextKeyExpression, IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey';
3030
import { IRecentFolder, IRecentlyOpened, IRecentWorkspace, isRecentFolder, isRecentWorkspace, IWorkspacesService } from 'vs/platform/workspaces/common/workspaces';
3131
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
32-
import { onUnexpectedError } from 'vs/base/common/errors';
3332
import { ILabelService, Verbosity } from 'vs/platform/label/common/label';
3433
import { IWindowOpenable } from 'vs/platform/window/common/window';
3534
import { splitName } from 'vs/base/common/labels';
@@ -74,6 +73,7 @@ import { IFeaturedExtensionsService } from 'vs/workbench/contrib/welcomeGettingS
7473
import { IFeaturedExtension } from 'vs/base/common/product';
7574
import { IExtensionManagementService } from 'vs/platform/extensionManagement/common/extensionManagement';
7675
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
76+
import { ILifecycleService, LifecyclePhase } from 'vs/workbench/services/lifecycle/common/lifecycle';
7777

7878
const SLIDE_TRANSITION_TIME_MS = 250;
7979
const configurationKey = 'workbench.startupEditor';
@@ -129,8 +129,11 @@ export class GettingStartedPage extends EditorPane {
129129
private stepDisposables: DisposableStore = new DisposableStore();
130130
private detailsPageDisposables: DisposableStore = new DisposableStore();
131131

132-
private gettingStartedCategories: IResolvedWalkthrough[];
133-
private featuredExtensions?: Promise<IFeaturedExtension[]>;
132+
// Ensure that the these are initialized before use.
133+
// Currently initialized before use in buildCategoriesSlide and scrollToCategory
134+
private recentlyOpened!: IRecentlyOpened;
135+
private gettingStartedCategories!: IResolvedWalkthrough[];
136+
private featuredExtensions!: IFeaturedExtension[];
134137

135138
private currentWalkthrough: IResolvedWalkthrough | undefined;
136139

@@ -145,7 +148,6 @@ export class GettingStartedPage extends EditorPane {
145148

146149
private contextService: IContextKeyService;
147150

148-
private recentlyOpened: Promise<IRecentlyOpened>;
149151
private hasScrolledToFirstCategory = false;
150152
private recentlyOpenedList?: GettingStartedIndexList<RecentEntry>;
151153
private startList?: GettingStartedIndexList<IWelcomePageStartEntry>;
@@ -182,13 +184,14 @@ export class GettingStartedPage extends EditorPane {
182184
@IEditorGroupsService private readonly groupsService: IEditorGroupsService,
183185
@IContextKeyService contextService: IContextKeyService,
184186
@IQuickInputService private quickInputService: IQuickInputService,
185-
@IWorkspacesService workspacesService: IWorkspacesService,
187+
@IWorkspacesService private readonly workspacesService: IWorkspacesService,
186188
@ILabelService private readonly labelService: ILabelService,
187189
@IHostService private readonly hostService: IHostService,
188190
@IWebviewService private readonly webviewService: IWebviewService,
189191
@IWorkspaceContextService private readonly workspaceContextService: IWorkspaceContextService,
190192
@IAccessibilityService private readonly accessibilityService: IAccessibilityService,
191-
@IExtensionManagementService private readonly extensionManagementService: IExtensionManagementService
193+
@IExtensionManagementService private readonly extensionManagementService: IExtensionManagementService,
194+
@ILifecycleService private readonly lifecycleService: ILifecycleService,
192195
) {
193196

194197
super(GettingStartedPage.ID, telemetryService, themeService, storageService);
@@ -209,28 +212,11 @@ export class GettingStartedPage extends EditorPane {
209212
this.contextService = this._register(contextService.createScoped(this.container));
210213
inWelcomeContext.bindTo(this.contextService).set(true);
211214

212-
this.gettingStartedCategories = this.gettingStartedService.getWalkthroughs();
213-
this.featuredExtensions = this.featuredExtensionService.getExtensions();
214-
215215
this._register(this.dispatchListeners);
216216
this.buildSlideThrottle = new Throttler();
217217

218218
const rerender = () => {
219-
this.gettingStartedCategories = this.gettingStartedService.getWalkthroughs();
220-
this.featuredExtensions = this.featuredExtensionService.getExtensions();
221-
222-
if (this.currentWalkthrough) {
223-
const existingSteps = this.currentWalkthrough.steps.map(step => step.id);
224-
const newCategory = this.gettingStartedCategories.find(category => this.currentWalkthrough?.id === category.id);
225-
if (newCategory) {
226-
const newSteps = newCategory.steps.map(step => step.id);
227-
if (!equals(newSteps, existingSteps)) {
228-
this.buildSlideThrottle.queue(() => this.buildCategoriesSlide());
229-
}
230-
}
231-
} else {
232-
this.buildSlideThrottle.queue(() => this.buildCategoriesSlide());
233-
}
219+
this.buildSlideThrottle.queue(async () => await this.buildCategoriesSlide());
234220
};
235221

236222
this._register(this.extensionManagementService.onDidInstallExtensions(async (result) => {
@@ -242,30 +228,9 @@ export class GettingStartedPage extends EditorPane {
242228
}
243229
}));
244230

245-
this._register(this.gettingStartedService.onDidAddBuiltInWalkthrough(() => {
246-
rerender();
247-
const someStepsComplete = this.gettingStartedCategories.some(category => category.steps.find(s => s.done));
248-
if (!this.productService.openToWelcomeMainPage && !someStepsComplete && !this.hasScrolledToFirstCategory) {
249-
const firstSessionDateString = this.storageService.get(firstSessionDateStorageKey, StorageScope.APPLICATION) || new Date().toUTCString();
250-
const daysSinceFirstSession = ((+new Date()) - (+new Date(firstSessionDateString))) / 1000 / 60 / 60 / 24;
251-
const fistContentBehaviour = daysSinceFirstSession < 1 ? 'openToFirstCategory' : 'index';
252-
253-
if (fistContentBehaviour === 'openToFirstCategory') {
254-
const first = this.gettingStartedCategories.filter(c => !c.when || this.contextService.contextMatchesRules(c.when))[0];
255-
this.hasScrolledToFirstCategory = true;
256-
if (first) {
257-
this.currentWalkthrough = first;
258-
this.editorInput.selectedCategory = this.currentWalkthrough?.id;
259-
this.buildCategorySlide(this.editorInput.selectedCategory, undefined);
260-
this.setSlide('details');
261-
return;
262-
}
263-
}
264-
}
265-
}));
266-
267231
this._register(this.gettingStartedService.onDidAddWalkthrough(rerender));
268232
this._register(this.gettingStartedService.onDidRemoveWalkthrough(rerender));
233+
this._register(workspacesService.onDidChangeRecentlyOpened(rerender));
269234

270235
this._register(this.gettingStartedService.onDidChangeWalkthrough(category => {
271236
const ourCategory = this.gettingStartedCategories.find(c => c.id === category.id);
@@ -315,12 +280,6 @@ export class GettingStartedPage extends EditorPane {
315280
}
316281
this.updateCategoryProgress();
317282
}));
318-
319-
this.recentlyOpened = workspacesService.getRecentlyOpened();
320-
this._register(workspacesService.onDidChangeRecentlyOpened(() => {
321-
this.recentlyOpened = workspacesService.getRecentlyOpened();
322-
rerender();
323-
}));
324283
}
325284

326285
// remove when 'workbench.welcomePage.preferReducedMotion' deprecated
@@ -345,6 +304,7 @@ export class GettingStartedPage extends EditorPane {
345304
override async setInput(newInput: GettingStartedInput, options: IEditorOptions | undefined, context: IEditorOpenContext, token: CancellationToken) {
346305
this.container.classList.remove('animatable');
347306
this.editorInput = newInput;
307+
await this.lifecycleService.when(LifecyclePhase.Restored);
348308
await super.setInput(newInput, options, context, token);
349309
await this.buildCategoriesSlide();
350310
if (this.shouldAnimate()) {
@@ -353,16 +313,6 @@ export class GettingStartedPage extends EditorPane {
353313
}
354314

355315
async makeCategoryVisibleWhenAvailable(categoryID: string, stepId?: string) {
356-
if (!this.gettingStartedCategories.some(c => c.id === categoryID)) {
357-
await this.gettingStartedService.installedExtensionsRegistered;
358-
this.gettingStartedCategories = this.gettingStartedService.getWalkthroughs();
359-
}
360-
361-
const ourCategory = this.gettingStartedCategories.find(c => c.id === categoryID);
362-
if (!ourCategory) {
363-
throw Error('Could not find category with ID: ' + categoryID);
364-
}
365-
366316
this.scrollToCategory(categoryID, stepId);
367317
}
368318

@@ -419,12 +369,8 @@ export class GettingStartedPage extends EditorPane {
419369
break;
420370
}
421371
case 'selectCategory': {
422-
const selectedCategory = this.gettingStartedCategories.find(category => category.id === argument);
423-
if (!selectedCategory) { throw Error('Could not find category with ID ' + argument); }
424-
425-
this.gettingStartedService.markWalkthroughOpened(argument);
426-
this.gettingStartedList?.setEntries(this.gettingStartedService.getWalkthroughs());
427372
this.scrollToCategory(argument);
373+
this.gettingStartedService.markWalkthroughOpened(argument);
428374
break;
429375
}
430376
case 'selectStartEntry': {
@@ -717,8 +663,6 @@ export class GettingStartedPage extends EditorPane {
717663
}
718664

719665
private async selectStep(id: string | undefined, delayFocus = true) {
720-
if (id && this.editorInput.selectedStep === id) { return; }
721-
722666
if (id) {
723667
let stepElement = this.container.querySelector<HTMLDivElement>(`[data-step-id="${id}"]`);
724668
if (!stepElement) {
@@ -784,6 +728,11 @@ export class GettingStartedPage extends EditorPane {
784728
}
785729

786730
private async buildCategoriesSlide() {
731+
732+
this.recentlyOpened = await this.workspacesService.getRecentlyOpened();
733+
this.gettingStartedCategories = await this.gettingStartedService.getWalkthroughs();
734+
this.featuredExtensions = await this.featuredExtensionService.getExtensions();
735+
787736
this.categoriesSlideDisposables.clear();
788737
const showOnStartupCheckbox = new Toggle({
789738
icon: Codicon.check,
@@ -883,10 +832,6 @@ export class GettingStartedPage extends EditorPane {
883832
this.currentWalkthrough = this.gettingStartedCategories.find(category => category.id === this.editorInput.selectedCategory);
884833

885834
if (!this.currentWalkthrough) {
886-
this.container.classList.add('loading');
887-
await this.gettingStartedService.installedExtensionsRegistered;
888-
this.container.classList.remove('loading');
889-
this.gettingStartedCategories = this.gettingStartedService.getWalkthroughs();
890835
this.currentWalkthrough = this.gettingStartedCategories.find(category => category.id === this.editorInput.selectedCategory);
891836
}
892837

@@ -895,17 +840,35 @@ export class GettingStartedPage extends EditorPane {
895840
this.editorInput.selectedCategory = undefined;
896841
this.editorInput.selectedStep = undefined;
897842
} else {
898-
this.buildCategorySlide(this.editorInput.selectedCategory, this.editorInput.selectedStep);
843+
await this.buildCategorySlide(this.editorInput.selectedCategory, this.editorInput.selectedStep);
899844
this.setSlide('details');
900845
return;
901846
}
902847
}
903848

849+
const someStepsComplete = this.gettingStartedCategories.some(category => category.steps.find(s => s.done));
904850
if (this.editorInput.showTelemetryNotice && this.productService.openToWelcomeMainPage) {
905851
const telemetryNotice = $('p.telemetry-notice');
906852
this.buildTelemetryFooter(telemetryNotice);
907853
footer.appendChild(telemetryNotice);
854+
} else if (!this.productService.openToWelcomeMainPage && !someStepsComplete && !this.hasScrolledToFirstCategory) {
855+
const firstSessionDateString = this.storageService.get(firstSessionDateStorageKey, StorageScope.APPLICATION) || new Date().toUTCString();
856+
const daysSinceFirstSession = ((+new Date()) - (+new Date(firstSessionDateString))) / 1000 / 60 / 60 / 24;
857+
const fistContentBehaviour = daysSinceFirstSession < 1 ? 'openToFirstCategory' : 'index';
858+
859+
if (fistContentBehaviour === 'openToFirstCategory') {
860+
const first = this.gettingStartedCategories.filter(c => !c.when || this.contextService.contextMatchesRules(c.when))[0];
861+
this.hasScrolledToFirstCategory = true;
862+
if (first) {
863+
this.currentWalkthrough = first;
864+
this.editorInput.selectedCategory = this.currentWalkthrough?.id;
865+
await this.buildCategorySlide(this.editorInput.selectedCategory, undefined);
866+
this.setSlide('details');
867+
return;
868+
}
869+
}
908870
}
871+
909872
this.setSlide('categories');
910873
}
911874

@@ -974,20 +937,10 @@ export class GettingStartedPage extends EditorPane {
974937

975938
recentlyOpenedList.onDidChange(() => this.registerDispatchListeners());
976939

977-
this.recentlyOpened.then(({ workspaces }) => {
978-
// Filter out the current workspace
979-
const workspacesWithID = workspaces
980-
.filter(recent => !this.workspaceContextService.isCurrentWorkspace(isRecentWorkspace(recent) ? recent.workspace : recent.folderUri))
981-
.map(recent => ({ ...recent, id: isRecentWorkspace(recent) ? recent.workspace.id : recent.folderUri.toString() }));
982-
983-
const updateEntries = () => {
984-
recentlyOpenedList.setEntries(workspacesWithID);
985-
};
986-
987-
updateEntries();
940+
const entries = this.recentlyOpened.workspaces.filter(recent => !this.workspaceContextService.isCurrentWorkspace(isRecentWorkspace(recent) ? recent.workspace : recent.folderUri))
941+
.map(recent => ({ ...recent, id: isRecentWorkspace(recent) ? recent.workspace.id : recent.folderUri.toString() }));
988942

989-
recentlyOpenedList.register(this.labelService.onDidChangeFormatters(() => updateEntries()));
990-
}).catch(onUnexpectedError);
943+
recentlyOpenedList.setEntries(entries);
991944

992945
return recentlyOpenedList;
993946
}
@@ -1151,14 +1104,12 @@ export class GettingStartedPage extends EditorPane {
11511104
contextService: this.contextService,
11521105
});
11531106

1154-
this.featuredExtensions?.then(extensions => {
1155-
featuredExtensionsList.setEntries(extensions);
1156-
});
1107+
featuredExtensionsList.setEntries(this.featuredExtensions);
11571108

11581109
this.featuredExtensionsList?.onDidChange(() => {
1159-
11601110
this.registerDispatchListeners();
11611111
});
1112+
11621113
return featuredExtensionsList;
11631114
}
11641115

@@ -1207,12 +1158,22 @@ export class GettingStartedPage extends EditorPane {
12071158
}
12081159

12091160
private async scrollToCategory(categoryID: string, stepId?: string) {
1161+
1162+
if (!this.gettingStartedCategories.some(c => c.id === categoryID)) {
1163+
this.gettingStartedCategories = await this.gettingStartedService.getWalkthroughs();
1164+
}
1165+
1166+
const ourCategory = this.gettingStartedCategories.find(c => c.id === categoryID);
1167+
if (!ourCategory) {
1168+
throw Error('Could not find category with ID: ' + categoryID);
1169+
}
1170+
12101171
this.inProgressScroll = this.inProgressScroll.then(async () => {
12111172
reset(this.stepsContent);
12121173
this.editorInput.selectedCategory = categoryID;
12131174
this.editorInput.selectedStep = stepId;
1214-
this.currentWalkthrough = this.gettingStartedCategories.find(category => category.id === categoryID);
1215-
this.buildCategorySlide(categoryID);
1175+
this.currentWalkthrough = ourCategory;
1176+
await this.buildCategorySlide(categoryID);
12161177
this.setSlide('details');
12171178
});
12181179
}
@@ -1345,13 +1306,13 @@ export class GettingStartedPage extends EditorPane {
13451306
super.clearInput();
13461307
}
13471308

1348-
private buildCategorySlide(categoryID: string, selectedStep?: string) {
1309+
private async buildCategorySlide(categoryID: string, selectedStep?: string) {
13491310
if (this.detailsScrollbar) { this.detailsScrollbar.dispose(); }
13501311

1351-
this.extensionService.whenInstalledExtensionsRegistered().then(() => {
1352-
// Remove internal extension id specifier from exposed id's
1353-
this.extensionService.activateByEvent(`onWalkthrough:${categoryID.replace(/[^#]+#/, '')}`);
1354-
});
1312+
await this.extensionService.whenInstalledExtensionsRegistered();
1313+
1314+
// Remove internal extension id specifier from exposed id's
1315+
await this.extensionService.activateByEvent(`onWalkthrough:${categoryID.replace(/[^#]+#/, '')}`);
13551316

13561317
this.detailsPageDisposables.clear();
13571318

0 commit comments

Comments
 (0)