Bläddra i källkod

Fixes focus/selection issues with EventBus

Adds strong typing to EventBus
main
Eric Amodio 1 år sedan
förälder
incheckning
e37cb70e44
6 ändrade filer med 105 tillägg och 41 borttagningar
  1. +57
    -24
      src/eventBus.ts
  2. +8
    -6
      src/plus/webviews/timeline/timelineWebviewView.ts
  3. +17
    -4
      src/views/commitsView.ts
  4. +17
    -1
      src/views/stashesView.ts
  5. +1
    -1
      src/views/viewBase.ts
  6. +5
    -5
      src/webviews/commitDetails/commitDetailsWebviewView.ts

+ 57
- 24
src/eventBus.ts Visa fil

@ -1,39 +1,59 @@
import type { Disposable } from 'vscode';
import type { Disposable, Uri } from 'vscode';
import { EventEmitter } from 'vscode';
import type { ViewsConfigKeys } from './config';
import type { GitCommit } from './git/models/commit';
import type { GitRevisionReference } from './git/models/reference';
import type { WebviewIds } from './webviews/webviewBase';
import type { WebviewViewIds } from './webviews/webviewViewBase';
export type EventBusPackage = {
name: string;
data?: unknown;
source?: string;
export type CommitSelectedEvent = EventBusEvent<'commit:selected'>;
export type FileSelectedEvent = EventBusEvent<'file:selected'>;
type EventBusEventMap = {
'commit:selected': CommitSelectedEventArgs;
'file:selected': FileSelectedEventArgs;
};
interface CommitSelectedEventArgs {
readonly commit: GitRevisionReference | GitCommit;
readonly pin?: boolean;
readonly preserveFocus?: boolean;
readonly preserveVisibility?: boolean;
}
interface FileSelectedEventArgs {
readonly uri: Uri;
readonly preserveFocus?: boolean;
readonly preserveVisibility?: boolean;
}
interface EventBusEvent<T extends keyof EventBusEventMap = keyof EventBusEventMap> {
name: T;
data?: EventBusEventMap[T] | undefined;
source?: EventBusSource | undefined;
}
export type EventBusSource =
| 'gitlens.rebase'
| `gitlens.${WebviewIds}`
| `gitlens.views.${WebviewViewIds}`
| `gitlens.views.${ViewsConfigKeys}`;
export type EventBusOptions = {
source?: string;
source?: EventBusSource;
};
export class EventBus implements Disposable {
private _emitter: EventEmitter<EventBusPackage>;
constructor() {
this._emitter = new EventEmitter();
}
private readonly _emitter = new EventEmitter<EventBusEvent>();
private get event() {
return this._emitter.event;
}
on(eventName: string, handler: (e: EventBusPackage) => void, thisArgs?: any, disposables?: Disposable[]) {
return this.event(
e => {
if (eventName !== e.name) return;
handler.call(thisArgs, e);
},
thisArgs,
disposables,
);
dispose() {
this._emitter.dispose();
}
fire(name: string, data?: unknown, options?: EventBusOptions) {
fire<T extends keyof EventBusEventMap>(name: T, data?: EventBusEventMap[T], options?: EventBusOptions) {
this._emitter.fire({
name: name,
data: data,
@ -41,7 +61,20 @@ export class EventBus implements Disposable {
});
}
dispose() {
this._emitter?.dispose();
on<T extends keyof EventBusEventMap>(
eventName: T,
handler: (e: EventBusEvent<T>) => void,
thisArgs?: any,
disposables?: Disposable[],
) {
return this.event(
// eslint-disable-next-line prefer-arrow-callback
function (e) {
if (eventName !== e.name) return;
handler.call(thisArgs, e as EventBusEvent<T>);
},
thisArgs,
disposables,
);
}
}

+ 8
- 6
src/plus/webviews/timeline/timelineWebviewView.ts Visa fil

@ -4,7 +4,7 @@ import { commands, Uri, window } from 'vscode';
import { configuration } from '../../../configuration';
import { Commands, ContextKeys } from '../../../constants';
import type { Container } from '../../../container';
import type { EventBusPackage } from '../../../eventBus';
import type { FileSelectedEvent } from '../../../eventBus';
import { PlusFeatures } from '../../../features';
import type { RepositoriesChangeEvent } from '../../../git/gitProviderService';
import { GitUri } from '../../../git/gitUri';
@ -83,7 +83,7 @@ export class TimelineWebviewView extends WebviewViewBase {
return [
this.container.subscription.onDidChange(this.onSubscriptionChanged, this),
window.onDidChangeActiveTextEditor(debounce(this.onActiveEditorChanged, 250), this),
this.container.events.on('file:selected', this.onFileSelected, this),
this.container.events.on('file:selected', debounce(this.onFileSelected, 250), this),
this.container.git.onDidChangeRepository(this.onRepositoryChanged, this),
this.container.git.onDidChangeRepositories(this.onRepositoriesChanged, this),
];
@ -138,6 +138,9 @@ export class TimelineWebviewView extends WebviewViewBase {
'commit:selected',
{
commit: commit,
pin: false,
preserveFocus: false,
preserveVisibility: false,
},
{ source: this.id },
);
@ -172,11 +175,10 @@ export class TimelineWebviewView extends WebviewViewBase {
}
@debug({ args: false })
private onFileSelected(event: EventBusPackage) {
if (event.data == null) return;
let uri: Uri | undefined = event.data as Uri;
private onFileSelected(e: FileSelectedEvent) {
if (e.data == null) return;
let uri: Uri | undefined = e.data.uri;
if (uri != null) {
if (!this.container.git.isTrackable(uri)) {
uri = undefined;

+ 17
- 4
src/views/commitsView.ts Visa fil

@ -311,15 +311,28 @@ export class CommitsView extends ViewBase {
private notifySelections() {
const node = this.selection?.[0];
if (node == null) return;
if (
node != null &&
(node instanceof CommitNode || node instanceof FileRevisionAsCommitNode || node instanceof CommitFileNode)
) {
if (node instanceof CommitNode || node instanceof FileRevisionAsCommitNode || node instanceof CommitFileNode) {
this.container.events.fire(
'commit:selected',
{
commit: node.commit,
pin: false,
preserveFocus: true,
preserveVisibility: true,
},
{ source: this.id },
);
}
if (node instanceof FileRevisionAsCommitNode || node instanceof CommitFileNode) {
this.container.events.fire(
'file:selected',
{
uri: node.uri,
preserveFocus: true,
preserveVisibility: true,
},
{ source: this.id },
);

+ 17
- 1
src/views/stashesView.ts Visa fil

@ -170,12 +170,28 @@ export class StashesView extends ViewBase {
private notifySelections() {
const node = this.selection?.[0];
if (node == null) return;
if (node != null && (node instanceof StashNode || node instanceof StashFileNode)) {
if (node instanceof StashNode || node instanceof StashFileNode) {
this.container.events.fire(
'commit:selected',
{
commit: node.commit,
pin: false,
preserveFocus: true,
preserveVisibility: true,
},
{ source: this.id },
);
}
if (node instanceof StashFileNode) {
this.container.events.fire(
'file:selected',
{
uri: node.uri,
preserveFocus: true,
preserveVisibility: true,
},
{ source: this.id },
);

+ 1
- 1
src/views/viewBase.ts Visa fil

@ -111,7 +111,7 @@ export abstract class ViewBase<
constructor(
public readonly container: Container,
public readonly id: `gitlens.views.${string}`,
public readonly id: `gitlens.views.${ViewsConfigKeys}`,
public readonly name: string,
private readonly trackingFeature: TrackedUsageFeatures,
) {

+ 5
- 5
src/webviews/commitDetails/commitDetailsWebviewView.ts Visa fil

@ -7,7 +7,7 @@ import { configuration } from '../../configuration';
import { Commands, ContextKeys, CoreCommands } from '../../constants';
import type { Container } from '../../container';
import { getContext } from '../../context';
import type { EventBusPackage } from '../../eventBus';
import type { CommitSelectedEvent } from '../../eventBus';
import { CommitFormatter } from '../../git/formatters/commitFormatter';
import type { GitCommit } from '../../git/models/commit';
import { isCommit } from '../../git/models/commit';
@ -112,10 +112,10 @@ export class CommitDetailsWebviewView extends WebviewViewBase
);
}
onCommitSelected(event: EventBusPackage) {
if (event.data == null) return;
onCommitSelected(e: CommitSelectedEvent) {
if (e.data == null) return;
void this.show(event.data);
void this.show(e.data);
}
@log<CommitDetailsWebviewView['show']>({
@ -824,7 +824,7 @@ export class CommitDetailsWebviewView extends WebviewViewBase
preview: true,
...this.getShowOptions(params),
});
this.container.events.fire('file:selected', file.uri, { source: this.id });
this.container.events.fire('file:selected', { uri: file.uri }, { source: this.id });
}
private async openFile(params: FileActionParams) {

Laddar…
Avbryt
Spara