diff --git a/src/vs/platform/userDataSync/common/userDataSync.ts b/src/vs/platform/userDataSync/common/userDataSync.ts index e85515b3984..5e789abd52b 100644 --- a/src/vs/platform/userDataSync/common/userDataSync.ts +++ b/src/vs/platform/userDataSync/common/userDataSync.ts @@ -143,6 +143,11 @@ export interface IUserDataManifest { session: string; } +export interface IResourceRefHandle { + ref: string; + created: number; +} + export const IUserDataSyncStoreService = createDecorator('IUserDataSyncStoreService'); export interface IUserDataSyncStoreService { _serviceBrand: undefined; @@ -151,7 +156,7 @@ export interface IUserDataSyncStoreService { write(key: ResourceKey, content: string, ref: string | null, source?: SyncSource): Promise; manifest(): Promise; clear(): Promise; - getAllRefs(key: ResourceKey): Promise; + getAllRefs(key: ResourceKey): Promise; resolveContent(key: ResourceKey, ref: string): Promise; delete(key: ResourceKey): Promise; } diff --git a/src/vs/platform/userDataSync/common/userDataSyncStoreService.ts b/src/vs/platform/userDataSync/common/userDataSyncStoreService.ts index 3057e9052a5..091170c7abc 100644 --- a/src/vs/platform/userDataSync/common/userDataSyncStoreService.ts +++ b/src/vs/platform/userDataSync/common/userDataSyncStoreService.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import { Disposable, } from 'vs/base/common/lifecycle'; -import { IUserData, IUserDataSyncStoreService, UserDataSyncErrorCode, IUserDataSyncStore, getUserDataSyncStore, SyncSource, UserDataSyncStoreError, IUserDataSyncLogService, IUserDataManifest, ResourceKey } from 'vs/platform/userDataSync/common/userDataSync'; +import { IUserData, IUserDataSyncStoreService, UserDataSyncErrorCode, IUserDataSyncStore, getUserDataSyncStore, SyncSource, UserDataSyncStoreError, IUserDataSyncLogService, IUserDataManifest, ResourceKey, IResourceRefHandle } from 'vs/platform/userDataSync/common/userDataSync'; import { IRequestService, asText, isSuccess, asJson } from 'vs/platform/request/common/request'; import { joinPath, relativePath } from 'vs/base/common/resources'; import { CancellationToken } from 'vs/base/common/cancellation'; @@ -31,7 +31,7 @@ export class UserDataSyncStoreService extends Disposable implements IUserDataSyn this.userDataSyncStore = getUserDataSyncStore(productService, configurationService); } - async getAllRefs(key: ResourceKey): Promise { + async getAllRefs(key: ResourceKey): Promise { if (!this.userDataSyncStore) { throw new Error('No settings sync store url configured.'); } @@ -45,8 +45,8 @@ export class UserDataSyncStoreService extends Disposable implements IUserDataSyn throw new UserDataSyncStoreError('Server returned ' + context.res.statusCode, UserDataSyncErrorCode.Unknown, undefined); } - const resources: string[] = await asJson(context) || []; - return resources.map(resource => relativePath(uri, URI.parse(resource))!); + const result = await asJson<{ url: string, created: number }[]>(context) || []; + return result.map(({ url, created }) => ({ ref: relativePath(uri, URI.parse(url))!, created: created })); } async resolveContent(key: ResourceKey, ref: string): Promise { diff --git a/src/vs/workbench/contrib/userDataSync/browser/userDataSyncHistory.ts b/src/vs/workbench/contrib/userDataSync/browser/userDataSyncHistory.ts index f130aa5809c..c54ca8e290c 100644 --- a/src/vs/workbench/contrib/userDataSync/browser/userDataSyncHistory.ts +++ b/src/vs/workbench/contrib/userDataSync/browser/userDataSyncHistory.ts @@ -18,6 +18,8 @@ import { URI } from 'vs/base/common/uri'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { FolderThemeIcon, FileThemeIcon } from 'vs/platform/theme/common/themeService'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; +import { fromNow } from 'vs/base/common/date'; +import { pad } from 'vs/base/common/strings'; const CONTEXT_SHOW_USER_DATA_SYNC_HISTORY_VIEW = new RawContextKey('showUserDataSyncHistoryView', false); @@ -115,7 +117,7 @@ export class UserDataSyncHistoryViewContribution implements IWorkbenchContributi constructor() { super({ id: 'workbench.actions.commpareWithLocal', - title: localize('workbench.action.deleteRef', "Compare with Local"), + title: localize('workbench.action.deleteRef', "Open Changes"), menu: { id: MenuId.ViewItemContext, when: ContextKeyExpr.and(ContextKeyEqualsExpr.create('view', that.viewId), ContextKeyExpr.regex('viewItem', /syncref-(settings|keybindings).*/i)) @@ -169,13 +171,15 @@ class UserDataSyncHistoryViewDataProvider implements ITreeViewDataProvider { private async getResources(handle: string): Promise { const resourceKey = ALL_RESOURCE_KEYS.filter(key => key === handle)[0]; if (resourceKey) { - const refs = await this.userDataSyncStoreService.getAllRefs(resourceKey); - return refs.map(ref => { + const refHandles = await this.userDataSyncStoreService.getAllRefs(resourceKey); + return refHandles.map(({ ref, created }) => { const handle = toSyncResource(resourceKey, ref).toString(); return { handle, collapsibleState: TreeItemCollapsibleState.None, - label: { label: ref }, + label: { label: label(new Date(created)) }, + description: fromNow(created, true), + tooltip: ref, command: { id: 'workbench.actions.sync.resolveResourceRef', title: '', arguments: [{ $treeItemHandle: handle, $treeViewId: '' }] }, themeIcon: FileThemeIcon, contextValue: `syncref-${resourceKey}` @@ -187,3 +191,10 @@ class UserDataSyncHistoryViewDataProvider implements ITreeViewDataProvider { } +function label(date: Date): string { + return date.toLocaleDateString() + + ' ' + pad(date.getHours(), 2) + + ':' + pad(date.getMinutes(), 2) + + ':' + pad(date.getSeconds(), 2); +} + diff --git a/src/vs/workbench/services/userDataSync/electron-browser/userDataSyncStoreService.ts b/src/vs/workbench/services/userDataSync/electron-browser/userDataSyncStoreService.ts index a79674273a5..dd3273ab5f0 100644 --- a/src/vs/workbench/services/userDataSync/electron-browser/userDataSyncStoreService.ts +++ b/src/vs/workbench/services/userDataSync/electron-browser/userDataSyncStoreService.ts @@ -3,7 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { SyncSource, IUserDataSyncStoreService, IUserDataSyncStore, getUserDataSyncStore, ResourceKey, IUserData, IUserDataManifest } from 'vs/platform/userDataSync/common/userDataSync'; +import { SyncSource, IUserDataSyncStoreService, IUserDataSyncStore, getUserDataSyncStore, ResourceKey, IUserData, IUserDataManifest, IResourceRefHandle } from 'vs/platform/userDataSync/common/userDataSync'; import { ISharedProcessService } from 'vs/platform/ipc/electron-browser/sharedProcessService'; import { IChannel } from 'vs/base/parts/ipc/common/ipc'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; @@ -41,7 +41,7 @@ export class UserDataSyncStoreService implements IUserDataSyncStoreService { throw new Error('Not Supported'); } - getAllRefs(key: ResourceKey): Promise { + getAllRefs(key: ResourceKey): Promise { return this.channel.call('getAllRefs', [key]); }