Skip to content

Commit

Permalink
SCM - 💄 adopt observables (microsoft#219162)
Browse files Browse the repository at this point in the history
  • Loading branch information
lszomoru committed Jun 29, 2024
1 parent 0225546 commit 0426dd4
Showing 1 changed file with 46 additions and 69 deletions.
115 changes: 46 additions & 69 deletions src/vs/workbench/contrib/scm/browser/activity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import { localize } from 'vs/nls';
import { basename } from 'vs/base/common/resources';
import { IDisposable, dispose, Disposable, DisposableStore, combinedDisposable } from 'vs/base/common/lifecycle';
import { Disposable, DisposableStore } from 'vs/base/common/lifecycle';
import { Emitter, Event } from 'vs/base/common/event';
import { VIEW_PANE_ID, ISCMService, ISCMRepository, ISCMViewService } from 'vs/workbench/contrib/scm/common/scm';
import { IActivityService, NumberBadge } from 'vs/workbench/services/activity/common/activity';
Expand All @@ -16,7 +16,6 @@ import { IEditorService } from 'vs/workbench/services/editor/common/editorServic
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { EditorResourceAccessor } from 'vs/workbench/common/editor';
import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity';
import { Schemas } from 'vs/base/common/network';
import { Iterable } from 'vs/base/common/iterator';
import { ITitleService } from 'vs/workbench/services/title/browser/titleService';
import { IEditorGroupContextKeyProvider, IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
Expand All @@ -28,6 +27,11 @@ import { derivedObservableWithCache, latestChangedValue, observableFromEventOpts
import { Command } from 'vs/editor/common/languages';
import { ISCMHistoryItemGroup } from 'vs/workbench/contrib/scm/common/history';

const ActiveRepositoryContextKeys = {
ActiveRepositoryName: new RawContextKey<string>('scmActiveRepositoryName', ''),
ActiveRepositoryBranchName: new RawContextKey<string>('scmActiveRepositoryBranchName', ''),
};

export class SCMActiveRepositoryController extends Disposable implements IWorkbenchContribution {
private readonly _countBadgeConfig = observableConfigValue<'all' | 'focused' | 'off'>('scm.countBadge', 'all', this.configurationService);

Expand Down Expand Up @@ -198,105 +202,78 @@ export class SCMActiveRepositoryController extends Disposable implements IWorkbe
}
}

const ActiveRepositoryContextKeys = {
ActiveRepositoryName: new RawContextKey<string>('scmActiveRepositoryName', ''),
ActiveRepositoryBranchName: new RawContextKey<string>('scmActiveRepositoryBranchName', ''),
};

export class SCMActiveResourceContextKeyController implements IWorkbenchContribution {
export class SCMActiveResourceContextKeyController extends Disposable implements IWorkbenchContribution {
private readonly _repositories = observableFromEvent(this,
Event.any(this.scmService.onDidAddRepository, this.scmService.onDidRemoveRepository),
() => this.scmService.repositories);

private readonly disposables = new DisposableStore();
private repositoryDisposables = new Set<IDisposable>();
private onDidRepositoryChange = new Emitter<void>();
private readonly _onDidRepositoryChange = new Emitter<void>();

constructor(
@IEditorGroupsService editorGroupsService: IEditorGroupsService,
@ISCMService private readonly scmService: ISCMService,
@IUriIdentityService private readonly uriIdentityService: IUriIdentityService
) {
super();

const activeResourceHasChangesContextKey = new RawContextKey<boolean>('scmActiveResourceHasChanges', false, localize('scmActiveResourceHasChanges', "Whether the active resource has changes"));
const activeResourceRepositoryContextKey = new RawContextKey<string | undefined>('scmActiveResourceRepository', undefined, localize('scmActiveResourceRepository', "The active resource's repository"));

this.scmService.onDidAddRepository(this.onDidAddRepository, this, this.disposables);

for (const repository of this.scmService.repositories) {
this.onDidAddRepository(repository);
}
this._store.add(autorunWithStore((reader, store) => {
for (const repository of this._repositories.read(reader)) {
store.add(Event.runAndSubscribe(repository.provider.onDidChangeResources, () => {
this._onDidRepositoryChange.fire();
}));
}
}));

// Create context key providers which will update the context keys based on each groups active editor
const hasChangesContextKeyProvider: IEditorGroupContextKeyProvider<boolean> = {
contextKey: activeResourceHasChangesContextKey,
getGroupContextKeyValue: (group) => this.getEditorHasChanges(group.activeEditor),
onDidChange: this.onDidRepositoryChange.event
getGroupContextKeyValue: (group) => this._getEditorHasChanges(group.activeEditor),
onDidChange: this._onDidRepositoryChange.event
};

const repositoryContextKeyProvider: IEditorGroupContextKeyProvider<string | undefined> = {
contextKey: activeResourceRepositoryContextKey,
getGroupContextKeyValue: (group) => this.getEditorRepositoryId(group.activeEditor),
onDidChange: this.onDidRepositoryChange.event
getGroupContextKeyValue: (group) => this._getEditorRepositoryId(group.activeEditor),
onDidChange: this._onDidRepositoryChange.event
};

this.disposables.add(editorGroupsService.registerContextKeyProvider(hasChangesContextKeyProvider));
this.disposables.add(editorGroupsService.registerContextKeyProvider(repositoryContextKeyProvider));
this._store.add(editorGroupsService.registerContextKeyProvider(hasChangesContextKeyProvider));
this._store.add(editorGroupsService.registerContextKeyProvider(repositoryContextKeyProvider));
}

private onDidAddRepository(repository: ISCMRepository): void {
const onDidChange = Event.any(repository.provider.onDidChange, repository.provider.onDidChangeResources);
const changeDisposable = onDidChange(() => {
this.onDidRepositoryChange.fire();
});

const onDidRemove = Event.filter(this.scmService.onDidRemoveRepository, e => e === repository);
const removeDisposable = onDidRemove(() => {
disposable.dispose();
this.repositoryDisposables.delete(disposable);
this.onDidRepositoryChange.fire();
});

const disposable = combinedDisposable(changeDisposable, removeDisposable);
this.repositoryDisposables.add(disposable);
}

private getEditorRepositoryId(activeEditor: EditorInput | null): string | undefined {
private _getEditorHasChanges(activeEditor: EditorInput | null): boolean {
const activeResource = EditorResourceAccessor.getOriginalUri(activeEditor);
if (!activeResource) {
return false;
}

if (activeResource?.scheme === Schemas.file || activeResource?.scheme === Schemas.vscodeRemote) {
const activeResourceRepository = Iterable.find(
this.scmService.repositories,
r => Boolean(r.provider.rootUri && this.uriIdentityService.extUri.isEqualOrParent(activeResource, r.provider.rootUri))
);

return activeResourceRepository?.id;
const activeResourceRepository = this.scmService.getRepository(activeResource);
for (const resourceGroup of activeResourceRepository?.provider.groups ?? []) {
if (resourceGroup.resources
.some(scmResource =>
this.uriIdentityService.extUri.isEqual(activeResource, scmResource.sourceUri))) {
return true;
}
}

return undefined;
return false;
}

private getEditorHasChanges(activeEditor: EditorInput | null): boolean {
private _getEditorRepositoryId(activeEditor: EditorInput | null): string | undefined {
const activeResource = EditorResourceAccessor.getOriginalUri(activeEditor);

if (activeResource?.scheme === Schemas.file || activeResource?.scheme === Schemas.vscodeRemote) {
const activeResourceRepository = Iterable.find(
this.scmService.repositories,
r => Boolean(r.provider.rootUri && this.uriIdentityService.extUri.isEqualOrParent(activeResource, r.provider.rootUri))
);

for (const resourceGroup of activeResourceRepository?.provider.groups ?? []) {
if (resourceGroup.resources
.some(scmResource =>
this.uriIdentityService.extUri.isEqual(activeResource, scmResource.sourceUri))) {
return true;
}
}
if (!activeResource) {
return undefined;
}

return false;
const activeResourceRepository = this.scmService.getRepository(activeResource);
return activeResourceRepository?.id;
}

dispose(): void {
this.disposables.dispose();
dispose(this.repositoryDisposables.values());
this.repositoryDisposables.clear();
this.onDidRepositoryChange.dispose();
override dispose(): void {
this._onDidRepositoryChange.dispose();
super.dispose();
}
}

0 comments on commit 0426dd4

Please sign in to comment.