From afacd2bdfe7060f09df9b9139521718915949757 Mon Sep 17 00:00:00 2001 From: Eric Amodio Date: Sun, 1 Mar 2020 11:29:26 -0500 Subject: [PATCH] Fixes #89509, #91464, #91628, #91619 --- .../api/browser/mainThreadTimeline.ts | 4 +- .../workbench/api/common/extHost.protocol.ts | 4 +- .../workbench/api/common/extHostTimeline.ts | 89 +++++------ .../timeline/browser/media/timelinePane.css | 18 ++- .../contrib/timeline/browser/timelinePane.ts | 144 ++++++++++++------ .../contrib/timeline/common/timeline.ts | 9 +- .../timeline/common/timelineService.ts | 98 +++++++----- 7 files changed, 218 insertions(+), 148 deletions(-) diff --git a/src/vs/workbench/api/browser/mainThreadTimeline.ts b/src/vs/workbench/api/browser/mainThreadTimeline.ts index cfeb1c6c38c..c8d6d0a9a96 100644 --- a/src/vs/workbench/api/browser/mainThreadTimeline.ts +++ b/src/vs/workbench/api/browser/mainThreadTimeline.ts @@ -9,7 +9,7 @@ import { URI } from 'vs/base/common/uri'; import { ILogService } from 'vs/platform/log/common/log'; import { MainContext, MainThreadTimelineShape, IExtHostContext, ExtHostTimelineShape, ExtHostContext } from 'vs/workbench/api/common/extHost.protocol'; import { extHostNamedCustomer } from 'vs/workbench/api/common/extHostCustomers'; -import { TimelineChangeEvent, TimelineOptions, TimelineProviderDescriptor, ITimelineService } from 'vs/workbench/contrib/timeline/common/timeline'; +import { TimelineChangeEvent, TimelineOptions, TimelineProviderDescriptor, ITimelineService, InternalTimelineOptions } from 'vs/workbench/contrib/timeline/common/timeline'; @extHostNamedCustomer(MainContext.MainThreadTimeline) export class MainThreadTimeline implements MainThreadTimelineShape { @@ -39,7 +39,7 @@ export class MainThreadTimeline implements MainThreadTimelineShape { this._timelineService.registerTimelineProvider({ ...provider, onDidChange: onDidChange.event, - provideTimeline(uri: URI, options: TimelineOptions, token: CancellationToken, internalOptions?: { cacheResults?: boolean }) { + provideTimeline(uri: URI, options: TimelineOptions, token: CancellationToken, internalOptions?: InternalTimelineOptions) { return proxy.$getTimeline(provider.id, uri, options, token, internalOptions); }, dispose() { diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 10f51d23548..d9b76522d9a 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -49,7 +49,7 @@ import { SaveReason } from 'vs/workbench/common/editor'; import { ExtensionActivationReason } from 'vs/workbench/api/common/extHostExtensionActivator'; import { TunnelDto } from 'vs/workbench/api/common/extHostTunnelService'; import { TunnelOptions } from 'vs/platform/remote/common/tunnel'; -import { Timeline, TimelineChangeEvent, TimelineOptions, TimelineProviderDescriptor } from 'vs/workbench/contrib/timeline/common/timeline'; +import { Timeline, TimelineChangeEvent, TimelineOptions, TimelineProviderDescriptor, InternalTimelineOptions } from 'vs/workbench/contrib/timeline/common/timeline'; import { revive } from 'vs/base/common/marshalling'; import { CallHierarchyItem } from 'vs/workbench/contrib/callHierarchy/common/callHierarchy'; import { Dto } from 'vs/base/common/types'; @@ -1468,7 +1468,7 @@ export interface ExtHostTunnelServiceShape { } export interface ExtHostTimelineShape { - $getTimeline(source: string, uri: UriComponents, options: TimelineOptions, token: CancellationToken, internalOptions?: { cacheResults?: boolean }): Promise; + $getTimeline(source: string, uri: UriComponents, options: TimelineOptions, token: CancellationToken, internalOptions?: InternalTimelineOptions): Promise; } // --- proxy identifiers diff --git a/src/vs/workbench/api/common/extHostTimeline.ts b/src/vs/workbench/api/common/extHostTimeline.ts index 9db000d04f7..4df94da98d5 100644 --- a/src/vs/workbench/api/common/extHostTimeline.ts +++ b/src/vs/workbench/api/common/extHostTimeline.ts @@ -7,7 +7,7 @@ import * as vscode from 'vscode'; import { UriComponents, URI } from 'vs/base/common/uri'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; import { ExtHostTimelineShape, MainThreadTimelineShape, IMainContext, MainContext } from 'vs/workbench/api/common/extHost.protocol'; -import { Timeline, TimelineItem, TimelineOptions, TimelineProvider } from 'vs/workbench/contrib/timeline/common/timeline'; +import { Timeline, TimelineItem, TimelineOptions, TimelineProvider, InternalTimelineOptions } from 'vs/workbench/contrib/timeline/common/timeline'; import { IDisposable, toDisposable, DisposableStore } from 'vs/base/common/lifecycle'; import { CancellationToken } from 'vs/base/common/cancellation'; import { CommandsConverter, ExtHostCommands } from 'vs/workbench/api/common/extHostCommands'; @@ -16,21 +16,19 @@ import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions'; export interface IExtHostTimeline extends ExtHostTimelineShape { readonly _serviceBrand: undefined; - $getTimeline(id: string, uri: UriComponents, options: vscode.TimelineOptions, token: vscode.CancellationToken, internalOptions?: { cacheResults?: boolean }): Promise; + $getTimeline(id: string, uri: UriComponents, options: vscode.TimelineOptions, token: vscode.CancellationToken, internalOptions?: InternalTimelineOptions): Promise; } export const IExtHostTimeline = createDecorator('IExtHostTimeline'); export class ExtHostTimeline implements IExtHostTimeline { - private static handlePool = 0; - _serviceBrand: undefined; private _proxy: MainThreadTimelineShape; private _providers = new Map(); - private _itemsBySourceByUriMap = new Map>>(); + private _itemsBySourceAndUriMap = new Map>>(); constructor( mainContext: IMainContext, @@ -42,7 +40,7 @@ export class ExtHostTimeline implements IExtHostTimeline { processArgument: arg => { if (arg && arg.$mid === 11) { const uri = arg.uri === undefined ? undefined : URI.revive(arg.uri); - return this._itemsBySourceByUriMap.get(getUriKey(uri))?.get(arg.source)?.get(arg.handle); + return this._itemsBySourceAndUriMap.get(arg.source)?.get(getUriKey(uri))?.get(arg.handle); } return arg; @@ -50,7 +48,7 @@ export class ExtHostTimeline implements IExtHostTimeline { }); } - async $getTimeline(id: string, uri: UriComponents, options: vscode.TimelineOptions, token: vscode.CancellationToken, internalOptions?: { cacheResults?: boolean }): Promise { + async $getTimeline(id: string, uri: UriComponents, options: vscode.TimelineOptions, token: vscode.CancellationToken, internalOptions?: InternalTimelineOptions): Promise { const provider = this._providers.get(id); return provider?.provideTimeline(URI.revive(uri), options, token, internalOptions); } @@ -62,26 +60,21 @@ export class ExtHostTimeline implements IExtHostTimeline { let disposable: IDisposable | undefined; if (provider.onDidChange) { - disposable = provider.onDidChange(this.emitTimelineChangeEvent(provider.id), this); + disposable = provider.onDidChange(e => this._proxy.$emitTimelineChangeEvent({ ...e, id: provider.id }), this); } - const itemsBySourceByUriMap = this._itemsBySourceByUriMap; + const itemsBySourceAndUriMap = this._itemsBySourceAndUriMap; return this.registerTimelineProviderCore({ ...provider, scheme: scheme, onDidChange: undefined, - async provideTimeline(uri: URI, options: TimelineOptions, token: CancellationToken, internalOptions?: { cacheResults?: boolean }) { - // For now, only allow the caching of a single Uri - if (internalOptions?.cacheResults) { - if (options.cursor === undefined) { - timelineDisposables.clear(); - } - - if (!itemsBySourceByUriMap.has(getUriKey(uri))) { - itemsBySourceByUriMap.clear(); - } - } else { + async provideTimeline(uri: URI, options: TimelineOptions, token: CancellationToken, internalOptions?: InternalTimelineOptions) { + if (internalOptions?.resetCache) { timelineDisposables.clear(); + + // For now, only allow the caching of a single Uri + // itemsBySourceAndUriMap.get(provider.id)?.get(getUriKey(uri))?.clear(); + itemsBySourceAndUriMap.get(provider.id)?.clear(); } const result = await provider.provideTimeline(uri, options, token); @@ -91,8 +84,9 @@ export class ExtHostTimeline implements IExtHostTimeline { return undefined; } - // TODO: Determine if we should cache dependent on who calls us (internal vs external) - const convertItem = convertTimelineItem(uri, internalOptions?.cacheResults ?? false); + // TODO: Should we bother converting all the data if we aren't caching? Meaning it is being requested by an extension? + + const convertItem = convertTimelineItem(uri, internalOptions); return { ...result, source: provider.id, @@ -100,6 +94,10 @@ export class ExtHostTimeline implements IExtHostTimeline { }; }, dispose() { + for (const sourceMap of itemsBySourceAndUriMap.values()) { + sourceMap.get(provider.id)?.clear(); + } + disposable?.dispose(); timelineDisposables.dispose(); } @@ -107,29 +105,28 @@ export class ExtHostTimeline implements IExtHostTimeline { } private convertTimelineItem(source: string, commandConverter: CommandsConverter, disposables: DisposableStore) { - return (uri: URI, cacheResults: boolean) => { - let itemsMap: Map | undefined; - if (cacheResults) { - const uriKey = getUriKey(uri); - - let sourceMap = this._itemsBySourceByUriMap.get(uriKey); - if (sourceMap === undefined) { - sourceMap = new Map(); - this._itemsBySourceByUriMap.set(uriKey, sourceMap); + return (uri: URI, options?: InternalTimelineOptions) => { + let items: Map | undefined; + if (options?.cacheResults) { + let itemsByUri = this._itemsBySourceAndUriMap.get(source); + if (itemsByUri === undefined) { + itemsByUri = new Map(); + this._itemsBySourceAndUriMap.set(source, itemsByUri); } - itemsMap = sourceMap.get(source); - if (itemsMap === undefined) { - itemsMap = new Map(); - sourceMap.set(source, itemsMap); + const uriKey = getUriKey(uri); + items = itemsByUri.get(uriKey); + if (items === undefined) { + items = new Map(); + itemsByUri.set(uriKey, items); } } return (item: vscode.TimelineItem): TimelineItem => { const { iconPath, ...props } = item; - const handle = `${source}|${item.id ?? `${item.timestamp}-${ExtHostTimeline.handlePool++}`}`; - itemsMap?.set(handle, item); + const handle = `${source}|${item.id ?? item.timestamp}`; + items?.set(handle, item); let icon; let iconDark; @@ -161,22 +158,6 @@ export class ExtHostTimeline implements IExtHostTimeline { }; } - private emitTimelineChangeEvent(id: string) { - return (e: vscode.TimelineChangeEvent) => { - // Clear caches - if (e?.uri === undefined) { - for (const sourceMap of this._itemsBySourceByUriMap.values()) { - sourceMap.get(id)?.clear(); - } - } - else { - this._itemsBySourceByUriMap.get(getUriKey(e.uri))?.clear(); - } - - this._proxy.$emitTimelineChangeEvent({ ...e, id: id }); - }; - } - private registerTimelineProviderCore(provider: TimelineProvider): IDisposable { // console.log(`ExtHostTimeline#registerTimelineProvider: id=${provider.id}`); @@ -193,7 +174,7 @@ export class ExtHostTimeline implements IExtHostTimeline { this._providers.set(provider.id, provider); return toDisposable(() => { - for (const sourceMap of this._itemsBySourceByUriMap.values()) { + for (const sourceMap of this._itemsBySourceAndUriMap.values()) { sourceMap.get(provider.id)?.clear(); } diff --git a/src/vs/workbench/contrib/timeline/browser/media/timelinePane.css b/src/vs/workbench/contrib/timeline/browser/media/timelinePane.css index 3b036147cfc..4e6b3c4972a 100644 --- a/src/vs/workbench/contrib/timeline/browser/media/timelinePane.css +++ b/src/vs/workbench/contrib/timeline/browser/media/timelinePane.css @@ -7,9 +7,25 @@ position: relative; } +.monaco-workbench .timeline-view.pane-header .description { + margin-left: 10px; + opacity: 0.6; + text-transform: none; + font-weight: normal; +} + +.monaco-workbench .timeline-view.pane-header:not(.expanded) .description { + display: none; +} + +.monaco-workbench .timeline-view.pane-header .description span.codicon { + font-size: 9px; + margin-left: 2px; +} + .monaco-workbench .timeline-tree-view .message.timeline-subtle { - padding: 10px 22px 0 22px; opacity: 0.5; + padding: 10px 22px 0 22px; position: absolute; pointer-events: none; z-index: 1; diff --git a/src/vs/workbench/contrib/timeline/browser/timelinePane.ts b/src/vs/workbench/contrib/timeline/browser/timelinePane.ts index 29dceaaca3d..031b6f27d11 100644 --- a/src/vs/workbench/contrib/timeline/browser/timelinePane.ts +++ b/src/vs/workbench/contrib/timeline/browser/timelinePane.ts @@ -89,9 +89,10 @@ export class TimelinePane extends ViewPane { static readonly ID = 'timeline'; static readonly TITLE = localize('timeline', 'Timeline'); - private _container!: HTMLElement; - private _messageElement!: HTMLDivElement; - private _treeElement!: HTMLDivElement; + private _$container!: HTMLElement; + private _$message!: HTMLDivElement; + private _$titleDescription!: HTMLSpanElement; + private _$tree!: HTMLDivElement; private _tree!: WorkbenchObjectTree; private _treeRenderer: TimelineTreeRenderer | undefined; private _menus: TimelineMenus; @@ -100,7 +101,6 @@ export class TimelinePane extends ViewPane { private _excludedSources: Set; private _cursorsByProvider: Map = new Map(); private _items: { element: TreeElement }[] = []; - private _loadingMessageTimer: any | undefined; private _pendingRequests = new Map(); private _uri: URI | undefined; @@ -181,6 +181,17 @@ export class TimelinePane extends ViewPane { this.loadTimeline(true); } + + private _titleDescription: string | undefined; + get titleDescription(): string | undefined { + return this._titleDescription; + } + + set titleDescription(description: string | undefined) { + this._titleDescription = description; + this._$titleDescription.textContent = description ?? ''; + } + private _message: string | undefined; get message(): string | undefined { return this._message; @@ -192,7 +203,7 @@ export class TimelinePane extends ViewPane { } private updateMessage(): void { - if (this._message) { + if (this._message !== undefined) { this.showMessage(this._message); } else { this.hideMessage(); @@ -200,35 +211,32 @@ export class TimelinePane extends ViewPane { } private showMessage(message: string): void { - DOM.removeClass(this._messageElement, 'hide'); + DOM.removeClass(this._$message, 'hide'); this.resetMessageElement(); - this._messageElement.textContent = message; + this._$message.textContent = message; } private hideMessage(): void { this.resetMessageElement(); - DOM.addClass(this._messageElement, 'hide'); + DOM.addClass(this._$message, 'hide'); } private resetMessageElement(): void { - DOM.clearNode(this._messageElement); + DOM.clearNode(this._$message); } + private _pendingAnyResults: boolean = false; private async loadTimeline(reset: boolean, sources?: string[], options: TimelineOptions = {}) { const defaultPageSize = reset ? InitialPageSize : SubsequentPageSize; // If we have no source, we are reseting all sources, so cancel everything in flight and reset caches if (sources === undefined) { if (reset) { + this._pendingAnyResults = this._pendingAnyResults || this._items.length !== 0; this._items.length = 0; this._cursorsByProvider.clear(); - if (this._loadingMessageTimer) { - clearTimeout(this._loadingMessageTimer); - this._loadingMessageTimer = undefined; - } - for (const { tokenSource } of this._pendingRequests.values()) { tokenSource.dispose(true); } @@ -237,26 +245,23 @@ export class TimelinePane extends ViewPane { } // TODO[ECA]: Are these the right the list of schemes to exclude? Is there a better way? - if (this._uri && (this._uri.scheme === 'vscode-settings' || this._uri.scheme === 'webview-panel' || this._uri.scheme === 'walkThrough')) { - this.message = localize('timeline.editorCannotProvideTimeline', 'The active editor cannot provide timeline information.'); - this._tree.setChildren(null, undefined); + if (this._uri?.scheme === 'vscode-settings' || this._uri?.scheme === 'webview-panel' || this._uri?.scheme === 'walkThrough') { + this._uri = undefined; + this._items.length = 0; + this.refresh(); return; } - if (reset && this._uri !== undefined) { - this._loadingMessageTimer = setTimeout((uri: URI) => { - if (uri !== this._uri) { - return; - } - - this._tree.setChildren(null, undefined); - this.message = localize('timeline.loading', 'Loading timeline for {0}...', basename(uri.fsPath)); - }, 500, this._uri); + if (!this._pendingAnyResults && this._uri !== undefined) { + this.setLoadingUriMessage(); } } if (this._uri === undefined) { + this._items.length = 0; + this.refresh(); + return; } @@ -284,6 +289,8 @@ export class TimelinePane extends ViewPane { } } + let noRequests = true; + for (const source of filteredSources) { let request = this._pendingRequests.get(source); @@ -303,13 +310,14 @@ export class TimelinePane extends ViewPane { ...options, limit: options.limit === 0 ? undefined : options.limit ?? defaultPageSize }, - request?.tokenSource ?? new CancellationTokenSource(), { cacheResults: true } + request?.tokenSource ?? new CancellationTokenSource(), { cacheResults: true, resetCache: false } )!; if (request === undefined) { continue; } + noRequests = false; this._pendingRequests.set(source, request); if (!reusingToken) { request.tokenSource.token.onCancellationRequested(() => this._pendingRequests.delete(source)); @@ -323,19 +331,24 @@ export class TimelinePane extends ViewPane { ...options, limit: options.limit === 0 ? undefined : (reset ? cursors?.endCursors?.after : undefined) ?? options.limit ?? defaultPageSize }, - new CancellationTokenSource(), { cacheResults: true } + new CancellationTokenSource(), { cacheResults: true, resetCache: true } )!; if (request === undefined) { continue; } + noRequests = false; this._pendingRequests.set(source, request); request.tokenSource.token.onCancellationRequested(() => this._pendingRequests.delete(source)); } this.handleRequest(request); } + + if (noRequests) { + this.refresh(); + } } private async handleRequest(request: TimelineRequest) { @@ -348,13 +361,20 @@ export class TimelinePane extends ViewPane { } if ( - timeline === undefined || request.tokenSource.token.isCancellationRequested || request.uri !== this._uri ) { return; } + if (timeline === undefined) { + if (this._pendingRequests.size === 0) { + this.refresh(); + } + + return; + } + let items: TreeElement[]; const source = request.source; @@ -512,15 +532,19 @@ export class TimelinePane extends ViewPane { } private refresh() { - if (this._loadingMessageTimer) { - clearTimeout(this._loadingMessageTimer); - this._loadingMessageTimer = undefined; - } + this._pendingAnyResults = false; - if (this._items.length === 0) { - this.message = localize('timeline.noTimelineInfo', 'No timeline information was provided.'); - } else { - this.message = undefined; + if (this._uri === undefined) { + this.titleDescription = undefined; + this.message = localize('timeline.editorCannotProvideTimeline', 'The active editor cannot provide timeline information.'); + } + else { + this.titleDescription = basename(this._uri.fsPath); + if (this._items.length === 0) { + this.message = localize('timeline.noTimelineInfo', 'No timeline information was provided.'); + } else { + this.message = undefined; + } } this._tree.setChildren(null, this._items); @@ -555,23 +579,30 @@ export class TimelinePane extends ViewPane { this._tree.layout(height, width); } + protected renderHeaderTitle(container: HTMLElement): void { + super.renderHeaderTitle(container, this.title); + + DOM.addClass(container, 'timeline-view'); + this._$titleDescription = DOM.append(container, DOM.$('span.description', undefined, this.titleDescription ?? '')); + } + protected renderBody(container: HTMLElement): void { - this._container = container; + this._$container = container; DOM.addClasses(container, 'tree-explorer-viewlet-tree-view', 'timeline-tree-view'); - this._messageElement = DOM.append(this._container, DOM.$('.message')); - DOM.addClass(this._messageElement, 'timeline-subtle'); + this._$message = DOM.append(this._$container, DOM.$('.message')); + DOM.addClass(this._$message, 'timeline-subtle'); this.message = localize('timeline.editorCannotProvideTimeline', 'The active editor cannot provide timeline information.'); - this._treeElement = document.createElement('div'); - DOM.addClasses(this._treeElement, 'customview-tree', 'file-icon-themable-tree', 'hide-arrows'); + this._$tree = document.createElement('div'); + DOM.addClasses(this._$tree, 'customview-tree', 'file-icon-themable-tree', 'hide-arrows'); // DOM.addClass(this._treeElement, 'show-file-icons'); - container.appendChild(this._treeElement); + container.appendChild(this._$tree); this._treeRenderer = this.instantiationService.createInstance(TimelineTreeRenderer, this._menus); this._tree = >this.instantiationService.createInstance(WorkbenchObjectTree, 'TimelinePane', - this._treeElement, new TimelineListVirtualDelegate(), [this._treeRenderer], { + this._$tree, new TimelineListVirtualDelegate(), [this._treeRenderer], { identityProvider: new TimelineIdentityProvider(), keyboardNavigationLabelProvider: new TimelineKeyboardNavigationLabelProvider(), overrideStyles: { @@ -583,9 +614,10 @@ export class TimelinePane extends ViewPane { const customTreeNavigator = new TreeResourceNavigator(this._tree, { openOnFocus: false, openOnSelection: false }); this._register(customTreeNavigator); this._register(this._tree.onContextMenu(e => this.onContextMenu(this._menus, e))); + this._register(this._tree.onDidChangeSelection(e => this.ensureValidItems())); this._register( customTreeNavigator.onDidOpenResource(e => { - if (!e.browserEvent) { + if (!e.browserEvent || !this.ensureValidItems()) { return; } @@ -612,6 +644,24 @@ export class TimelinePane extends ViewPane { }) ); } + ensureValidItems() { + if (this._pendingAnyResults) { + this._tree.setChildren(null, undefined); + + this.setLoadingUriMessage(); + + this._pendingAnyResults = false; + return false; + } + + return true; + } + + setLoadingUriMessage() { + const file = this._uri && basename(this._uri.fsPath); + this.titleDescription = file ?? ''; + this.message = file ? localize('timeline.loading', 'Loading timeline for {0}...', file) : ''; + } private onContextMenu(menus: TimelineMenus, treeEvent: ITreeContextMenuEvent): void { const item = treeEvent.element; @@ -623,6 +673,10 @@ export class TimelinePane extends ViewPane { event.preventDefault(); event.stopPropagation(); + if (!this.ensureValidItems()) { + return; + } + this._tree.setFocus([item]); const actions = menus.getResourceContextActions(item); if (!actions.length) { diff --git a/src/vs/workbench/contrib/timeline/common/timeline.ts b/src/vs/workbench/contrib/timeline/common/timeline.ts index 3c5597d21fc..72ca602fa56 100644 --- a/src/vs/workbench/contrib/timeline/common/timeline.ts +++ b/src/vs/workbench/contrib/timeline/common/timeline.ts @@ -43,6 +43,11 @@ export interface TimelineOptions { limit?: number | string; } +export interface InternalTimelineOptions { + cacheResults: boolean; + resetCache: boolean; +} + export interface Timeline { source: string; items: TimelineItem[]; @@ -59,7 +64,7 @@ export interface Timeline { export interface TimelineProvider extends TimelineProviderDescriptor, IDisposable { onDidChange?: Event; - provideTimeline(uri: URI, options: TimelineOptions, token: CancellationToken, internalOptions?: { cacheResults?: boolean }): Promise; + provideTimeline(uri: URI, options: TimelineOptions, token: CancellationToken, internalOptions?: InternalTimelineOptions): Promise; } export interface TimelineProviderDescriptor { @@ -93,7 +98,7 @@ export interface ITimelineService { getSources(): string[]; - getTimeline(id: string, uri: URI, options: TimelineOptions, tokenSource: CancellationTokenSource, internalOptions?: { cacheResults?: boolean }): TimelineRequest | undefined; + getTimeline(id: string, uri: URI, options: TimelineOptions, tokenSource: CancellationTokenSource, internalOptions?: InternalTimelineOptions): TimelineRequest | undefined; // refresh(fetch?: 'all' | 'more'): void; reset(): void; diff --git a/src/vs/workbench/contrib/timeline/common/timelineService.ts b/src/vs/workbench/contrib/timeline/common/timelineService.ts index d017b15245d..4f61ad5ef20 100644 --- a/src/vs/workbench/contrib/timeline/common/timelineService.ts +++ b/src/vs/workbench/contrib/timeline/common/timelineService.ts @@ -9,7 +9,7 @@ import { IDisposable } from 'vs/base/common/lifecycle'; // import { basename } from 'vs/base/common/path'; import { URI } from 'vs/base/common/uri'; import { ILogService } from 'vs/platform/log/common/log'; -import { ITimelineService, TimelineChangeEvent, TimelineOptions, TimelineProvidersChangeEvent, TimelineProvider } from './timeline'; +import { ITimelineService, TimelineChangeEvent, TimelineOptions, TimelineProvidersChangeEvent, TimelineProvider, InternalTimelineOptions } from './timeline'; export class TimelineService implements ITimelineService { _serviceBrand: undefined; @@ -27,54 +27,68 @@ export class TimelineService implements ITimelineService { private readonly _providerSubscriptions = new Map(); constructor(@ILogService private readonly logService: ILogService) { + // let source = 'slow-source'; // this.registerTimelineProvider({ - // id: 'local-history', - // label: 'Local History', - // provideTimeline(uri: URI, token: CancellationToken) { + // scheme: '*', + // id: source, + // label: 'Slow Source', + // provideTimeline(uri: URI, options: TimelineOptions, token: CancellationToken, internalOptions?: { cacheResults?: boolean | undefined; }) { // return new Promise(resolve => setTimeout(() => { - // resolve([ - // { - // id: '1', - // label: 'Slow Timeline1', - // description: basename(uri.fsPath), - // timestamp: Date.now(), - // source: 'local-history' - // }, - // { - // id: '2', - // label: 'Slow Timeline2', - // description: basename(uri.fsPath), - // timestamp: new Date(0).getTime(), - // source: 'local-history' - // } - // ]); - // }, 3000)); + // resolve({ + // source: source, + // items: [ + // { + // handle: `${source}|1`, + // id: '1', + // label: 'Slow Timeline1', + // description: basename(uri.fsPath), + // timestamp: Date.now(), + // source: source + // }, + // { + // handle: `${source}|2`, + // id: '2', + // label: 'Slow Timeline2', + // description: basename(uri.fsPath), + // timestamp: new Date(0).getTime(), + // source: source + // } + // ] + // }); + // }, 5000)); // }, // dispose() { } // }); + // source = 'very-slow-source'; // this.registerTimelineProvider({ - // id: 'slow-history', - // label: 'Slow History', - // provideTimeline(uri: URI, token: CancellationToken) { + // scheme: '*', + // id: source, + // label: 'Very Slow Source', + // provideTimeline(uri: URI, options: TimelineOptions, token: CancellationToken, internalOptions?: { cacheResults?: boolean | undefined; }) { // return new Promise(resolve => setTimeout(() => { - // resolve([ - // { - // id: '1', - // label: 'VERY Slow Timeline1', - // description: basename(uri.fsPath), - // timestamp: Date.now(), - // source: 'slow-history' - // }, - // { - // id: '2', - // label: 'VERY Slow Timeline2', - // description: basename(uri.fsPath), - // timestamp: new Date(0).getTime(), - // source: 'slow-history' - // } - // ]); - // }, 6000)); + // resolve({ + // source: source, + // items: [ + // { + // handle: `${source}|1`, + // id: '1', + // label: 'VERY Slow Timeline1', + // description: basename(uri.fsPath), + // timestamp: Date.now(), + // source: source + // }, + // { + // handle: `${source}|2`, + // id: '2', + // label: 'VERY Slow Timeline2', + // description: basename(uri.fsPath), + // timestamp: new Date(0).getTime(), + // source: source + // } + // ] + // }); + // }, 10000)); // }, // dispose() { } // }); @@ -84,7 +98,7 @@ export class TimelineService implements ITimelineService { return [...this._providers.keys()]; } - getTimeline(id: string, uri: URI, options: TimelineOptions, tokenSource: CancellationTokenSource, internalOptions?: { cacheResults?: boolean }) { + getTimeline(id: string, uri: URI, options: TimelineOptions, tokenSource: CancellationTokenSource, internalOptions?: InternalTimelineOptions) { this.logService.trace(`TimelineService#getTimeline(${id}): uri=${uri.toString(true)}`); const provider = this._providers.get(id); -- GitLab