Skip to content

Commit ac1633c

Browse files
committed
Fixes welcome view blocking required access
1 parent 70b62af commit ac1633c

File tree

3 files changed

+86
-24
lines changed

3 files changed

+86
-24
lines changed

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19444,12 +19444,12 @@
1944419444
},
1944519445
{
1944619446
"view": "gitlens.views.scm.grouped",
19447-
"contents": "GitLens views—Commits, Branches, Stashes, etc—are grouped together for easier view management.\nUse the tabs above to navigate, or detach the views you want to keep separated. Once detached, you can regroup them anytime using the 'x' in the view's header.\n\n[Continue](command:gitlens.views.scm.grouped.welcome.dismiss)",
19447+
"contents": "GitLens groups many related views—Commits, Branches, Stashes, etc—here for easier view management.\nUse the tabs above to navigate, or detach the views you want to keep separated. You can regroup them anytime using the 'x' in the view header.\n\n[Continue](command:gitlens.views.scm.grouped.welcome.dismiss)",
1944819448
"when": "!gitlens:views:scm:grouped:welcome:dismissed && gitlens:newInstall"
1944919449
},
1945019450
{
1945119451
"view": "gitlens.views.scm.grouped",
19452-
"contents": "In GitLens 16, we've grouped many views—Commits, Branches, Stashes, etc—together here for easier view management.\nUse the tabs above to navigate, or detach the views you want to keep separated. Once detached, you can regroup them anytime using the 'x' in the view's header.\n\n[Continue](command:gitlens.views.scm.grouped.welcome.dismiss)\n\nPrefer them separate? [Restore views to previous locations](command:gitlens.views.scm.grouped.welcome.restore)",
19452+
"contents": "In GitLens 16, we've grouped many related views—Commits, Branches, Stashes, etc—here for easier view management.\nUse the tabs above to navigate, or detach the views you want to keep separated. You can regroup them anytime using the 'x' in the view header.\n\n[Continue](command:gitlens.views.scm.grouped.welcome.dismiss)\n\nPrefer them separate? [Restore views to previous locations](command:gitlens.views.scm.grouped.welcome.restore)",
1945319453
"when": "!gitlens:views:scm:grouped:welcome:dismissed && !gitlens:newInstall"
1945419454
}
1945519455
],

src/views/viewBase.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,11 @@ export abstract class ViewBase<
167167
return types.includes(this.type as unknown as T[number]);
168168
}
169169

170+
private _disposed: boolean = false;
171+
get disposed(): boolean {
172+
return this._disposed;
173+
}
174+
170175
get id(): TreeViewIds<Type> {
171176
return `gitlens.views.${this.type}`;
172177
}
@@ -266,6 +271,7 @@ export abstract class ViewBase<
266271
}
267272

268273
dispose() {
274+
this._disposed = true;
269275
this._nodeState?.dispose();
270276
this._nodeState = undefined;
271277
this.root?.dispose();

src/views/views.ts

Lines changed: 78 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
import type { ConfigurationChangeEvent } from 'vscode';
2-
import { Disposable } from 'vscode';
1+
import type { ConfigurationChangeEvent, MessageItem } from 'vscode';
2+
import { Disposable, window } from 'vscode';
3+
import type { Commands } from '../constants.commands';
34
import type { GroupableTreeViewTypes } from '../constants.views';
45
import type { Container } from '../container';
56
import type { GitContributor } from '../git/models/contributor';
@@ -18,9 +19,9 @@ import { registerPatchDetailsWebviewView } from '../plus/webviews/patchDetails/r
1819
import type { TimelineWebviewShowingArgs } from '../plus/webviews/timeline/registration';
1920
import { registerTimelineWebviewView } from '../plus/webviews/timeline/registration';
2021
import { first } from '../system/iterable';
21-
import { executeCoreCommand, registerCommand } from '../system/vscode/command';
22+
import { executeCommand, executeCoreCommand, registerCommand } from '../system/vscode/command';
2223
import { configuration } from '../system/vscode/configuration';
23-
import { setContext } from '../system/vscode/context';
24+
import { getContext, setContext } from '../system/vscode/context';
2425
import type { CommitDetailsWebviewShowingArgs } from '../webviews/commitDetails/registration';
2526
import {
2627
registerCommitDetailsWebviewView,
@@ -43,7 +44,7 @@ import { ScmGroupedView } from './scmGroupedView';
4344
import { SearchAndCompareView } from './searchAndCompareView';
4445
import { StashesView } from './stashesView';
4546
import { TagsView } from './tagsView';
46-
import type { ViewsWithRepositoryFolders } from './viewBase';
47+
import type { TreeViewByType, ViewsWithRepositoryFolders } from './viewBase';
4748
import { ViewCommands } from './viewCommands';
4849
import { WorkspacesView } from './workspacesView';
4950
import { WorktreesView } from './worktreesView';
@@ -67,7 +68,7 @@ export class Views implements Disposable {
6768
void this.container.storage.storeWorkspace('views:scm:grouped:selected', type);
6869
}
6970

70-
private _scmGroupedView!: ScmGroupedView;
71+
private _scmGroupedView: ScmGroupedView | undefined;
7172
private _scmGroupedViews!: Set<GroupableTreeViewTypes>;
7273
get scmGroupedViews() {
7374
return this._scmGroupedViews;
@@ -285,9 +286,38 @@ export class Views implements Disposable {
285286
setTimeout(() => executeCoreCommand(`gitlens.views.${grouped ? 'scm.grouped' : type}.focus`), 1);
286287
}
287288

288-
private updateScmGroupedViewsRegistration() {
289+
private async showWelcomeNotification() {
290+
this._welcomeDismissed = true;
291+
292+
const newInstall = getContext('gitlens:newInstall', false);
293+
294+
const confirm: MessageItem = { title: 'OK', isCloseAffordance: true };
295+
const Restore: MessageItem = { title: 'Restore Previous Locations' };
296+
297+
const buttons = newInstall ? [confirm] : [confirm, Restore];
298+
299+
const result = await window.showInformationMessage(
300+
newInstall
301+
? 'GitLens groups many related views—Commits, Branches, Stashes, etc—together for easier view management. Use the tabs in the view header to navigate, detach, or regroup views.'
302+
: "In GitLens 16, we've grouped many related views—Commits, Branches, Stashes, etc—together for easier view management. Use the tabs in the view header to navigate, detach, or regroup views.",
303+
...buttons,
304+
);
305+
306+
if (result === Restore) {
307+
executeCommand('gitlens.views.scm.grouped.welcome.restore' as Commands);
308+
} else {
309+
executeCommand('gitlens.views.scm.grouped.welcome.dismiss' as Commands);
310+
}
311+
}
312+
313+
private updateScmGroupedViewsRegistration(bypassWelcomeView?: boolean) {
289314
void setContext('gitlens:views:scm:grouped:welcome:dismissed', this._welcomeDismissed);
290-
if (!this._welcomeDismissed) return;
315+
if (!this._welcomeDismissed) {
316+
if (!bypassWelcomeView) return;
317+
318+
// If we are bypassing the welcome view, show it as a notification -- since we can't block the view from loading
319+
void this.showWelcomeNotification();
320+
}
291321

292322
const groupedViews = getScmGroupedViewsFromConfig();
293323

@@ -306,7 +336,7 @@ export class Views implements Disposable {
306336
}
307337

308338
this._scmGroupedView?.dispose();
309-
this._scmGroupedView = undefined!;
339+
this._scmGroupedView = undefined;
310340

311341
if (!this._scmGroupedViews.has('branches')) {
312342
this._branchesView ??= new BranchesView(this.container);
@@ -380,20 +410,20 @@ export class Views implements Disposable {
380410

381411
if (this._scmGroupedViews.size) {
382412
this._scmGroupedView ??= new ScmGroupedView(this.container, this);
383-
} else {
384-
this._scmGroupedView?.dispose();
385-
this._scmGroupedView = undefined!;
413+
// } else {
414+
// this._scmGroupedView?.dispose();
415+
// this._scmGroupedView = undefined;
386416
}
387417
}
388418

389419
private _branchesView: BranchesView | undefined;
390420
get branches(): BranchesView {
391-
return this._branchesView ?? this._scmGroupedView.setView('branches');
421+
return this._branchesView ?? this.getScmGroupedView('branches');
392422
}
393423

394424
private _commitsView: CommitsView | undefined;
395425
get commits(): CommitsView {
396-
return this._commitsView ?? this._scmGroupedView.setView('commits');
426+
return this._commitsView ?? this.getScmGroupedView('commits');
397427
}
398428

399429
private _commitDetailsView!: WebviewViewProxy<CommitDetailsWebviewShowingArgs>;
@@ -403,7 +433,7 @@ export class Views implements Disposable {
403433

404434
private _contributorsView: ContributorsView | undefined;
405435
get contributors(): ContributorsView {
406-
return this._contributorsView ?? this._scmGroupedView.setView('contributors');
436+
return this._contributorsView ?? this.getScmGroupedView('contributors');
407437
}
408438

409439
private _draftsView!: DraftsView;
@@ -433,7 +463,7 @@ export class Views implements Disposable {
433463

434464
private _launchpadView!: LaunchpadView | undefined;
435465
get launchpad(): LaunchpadView {
436-
return this._launchpadView ?? this._scmGroupedView.setView('launchpad');
466+
return this._launchpadView ?? this.getScmGroupedView('launchpad');
437467
}
438468

439469
private _lineHistoryView!: LineHistoryView;
@@ -453,27 +483,27 @@ export class Views implements Disposable {
453483

454484
private _remotesView: RemotesView | undefined;
455485
get remotes(): RemotesView {
456-
return this._remotesView ?? this._scmGroupedView.setView('remotes');
486+
return this._remotesView ?? this.getScmGroupedView('remotes');
457487
}
458488

459489
private _repositoriesView!: RepositoriesView | undefined;
460490
get repositories(): RepositoriesView {
461-
return this._repositoriesView ?? this._scmGroupedView.setView('repositories');
491+
return this._repositoriesView ?? this.getScmGroupedView('repositories');
462492
}
463493

464494
private _searchAndCompareView: SearchAndCompareView | undefined;
465495
get searchAndCompare(): SearchAndCompareView {
466-
return this._searchAndCompareView ?? this._scmGroupedView.setView('searchAndCompare');
496+
return this._searchAndCompareView ?? this.getScmGroupedView('searchAndCompare');
467497
}
468498

469499
private _stashesView: StashesView | undefined;
470500
get stashes(): StashesView {
471-
return this._stashesView ?? this._scmGroupedView.setView('stashes');
501+
return this._stashesView ?? this.getScmGroupedView('stashes');
472502
}
473503

474504
private _tagsView: TagsView | undefined;
475505
get tags(): TagsView {
476-
return this._tagsView ?? this._scmGroupedView.setView('tags');
506+
return this._tagsView ?? this.getScmGroupedView('tags');
477507
}
478508

479509
private _timelineView!: WebviewViewProxy<TimelineWebviewShowingArgs>;
@@ -483,14 +513,40 @@ export class Views implements Disposable {
483513

484514
private _worktreesView: WorktreesView | undefined;
485515
get worktrees(): WorktreesView {
486-
return this._worktreesView ?? this._scmGroupedView.setView('worktrees');
516+
return this._worktreesView ?? this.getScmGroupedView('worktrees');
487517
}
488518

489519
private _workspacesView!: WorkspacesView;
490520
get workspaces(): WorkspacesView {
491521
return this._workspacesView;
492522
}
493523

524+
private getScmGroupedView<T extends GroupableTreeViewTypes>(type: T): TreeViewByType[T] {
525+
// eslint-disable-next-line @typescript-eslint/no-this-alias
526+
const self = this;
527+
528+
// Use a proxy to guard against the view not existing or having been disposed
529+
530+
let view: TreeViewByType[T] | undefined;
531+
const proxy = new Proxy<TreeViewByType[T]>(Object.create(null) as TreeViewByType[T], {
532+
get: function (_target, prop) {
533+
if (view == null || view.disposed) {
534+
if (self._scmGroupedView == null) {
535+
// Don't bother creating the view if we are just checking visibility
536+
if (prop === 'visible') return false;
537+
538+
self.updateScmGroupedViewsRegistration(true);
539+
}
540+
view = self._scmGroupedView!.setView(type);
541+
}
542+
543+
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
544+
return (view as any)[prop];
545+
},
546+
});
547+
return proxy;
548+
}
549+
494550
async revealBranch(
495551
branch: GitBranchReference,
496552
options?: {

0 commit comments

Comments
 (0)