Skip to content

Commit d532fad

Browse files
authored
1 parent 62755fc commit d532fad

File tree

4 files changed

+94
-71
lines changed

4 files changed

+94
-71
lines changed

src/vs/workbench/contrib/userDataSync/browser/userDataSync.ts

Lines changed: 11 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import { localize } from 'vs/nls';
1818
import { MenuId, MenuRegistry, registerAction2, Action2 } from 'vs/platform/actions/common/actions';
1919
import { ICommandService } from 'vs/platform/commands/common/commands';
2020
import { ContextKeyExpr, ContextKeyTrueExpr, IContextKey, IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey';
21-
import { IDialogService, IFileDialogService } from 'vs/platform/dialogs/common/dialogs';
21+
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
2222
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
2323
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
2424
import { QuickPickItem, IQuickInputService } from 'vs/platform/quickinput/common/quickInput';
@@ -42,7 +42,7 @@ import { Registry } from 'vs/platform/registry/common/platform';
4242
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
4343
import { ViewContainerLocation, IViewContainersRegistry, Extensions, ViewContainer } from 'vs/workbench/common/views';
4444
import { UserDataSyncDataViews } from 'vs/workbench/contrib/userDataSync/browser/userDataSyncViews';
45-
import { IUserDataSyncWorkbenchService, getSyncAreaLabel, AccountStatus, CONTEXT_SYNC_STATE, CONTEXT_SYNC_ENABLEMENT, CONTEXT_ACCOUNT_STATE, CONFIGURE_SYNC_COMMAND_ID, SHOW_SYNC_LOG_COMMAND_ID, SYNC_VIEW_CONTAINER_ID, SYNC_TITLE, SYNC_ORIGINAL_TITLE, SYNC_VIEW_ICON, CONTEXT_HAS_CONFLICTS } from 'vs/workbench/services/userDataSync/common/userDataSync';
45+
import { IUserDataSyncWorkbenchService, getSyncAreaLabel, AccountStatus, CONTEXT_SYNC_STATE, CONTEXT_SYNC_ENABLEMENT, CONTEXT_ACCOUNT_STATE, CONFIGURE_SYNC_COMMAND_ID, SHOW_SYNC_LOG_COMMAND_ID, SYNC_VIEW_CONTAINER_ID, SYNC_TITLE, SYNC_ORIGINAL_TITLE, SYNC_VIEW_ICON, CONTEXT_HAS_CONFLICTS, DOWNLOAD_ACTIVITY_ACTION_DESCRIPTOR } from 'vs/workbench/services/userDataSync/common/userDataSync';
4646
import { Codicon } from 'vs/base/common/codicons';
4747
import { ViewPaneContainer } from 'vs/workbench/browser/parts/views/viewPaneContainer';
4848
import { Categories } from 'vs/platform/action/common/actionCommonCategories';
@@ -53,11 +53,7 @@ import { ctxIsMergeResultEditor, ctxMergeBaseUri } from 'vs/workbench/contrib/me
5353
import { IWorkbenchIssueService } from 'vs/workbench/services/issue/common/issue';
5454
import { IUserDataProfileService } from 'vs/workbench/services/userDataProfile/common/userDataProfile';
5555
import { ILocalizedString } from 'vs/platform/action/common/action';
56-
import { IProgressService, ProgressLocation } from 'vs/platform/progress/common/progress';
57-
import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity';
58-
import { IFileService } from 'vs/platform/files/common/files';
59-
import { escapeRegExpCharacters } from 'vs/base/common/strings';
60-
import { IUserDataSyncMachinesService } from 'vs/platform/userDataSync/common/userDataSyncMachines';
56+
import { isWeb } from 'vs/base/common/platform';
6157

6258
type ConfigureSyncQuickPickItem = { id: SyncResource; label: string; description?: string };
6359

@@ -714,7 +710,10 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
714710
this.registerShowLogAction();
715711
this.registerResetSyncDataAction();
716712
this.registerAcceptMergesAction();
717-
this.registerDownloadSyncActivityAction();
713+
714+
if (isWeb) {
715+
this.registerDownloadSyncActivityAction();
716+
}
718717
}
719718

720719
private registerTurnOnSyncAction(): void {
@@ -1131,60 +1130,15 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
11311130
private registerDownloadSyncActivityAction(): void {
11321131
this._register(registerAction2(class DownloadSyncActivityAction extends Action2 {
11331132
constructor() {
1134-
super({
1135-
id: 'workbench.userDataSync.actions.downloadSyncActivity',
1136-
title: { original: 'Download Settings Sync Activity', value: localize('download sync activity title', "Download Settings Sync Activity") },
1137-
category: Categories.Developer,
1138-
f1: true,
1139-
precondition: ContextKeyExpr.and(CONTEXT_ACCOUNT_STATE.isEqualTo(AccountStatus.Available), CONTEXT_SYNC_STATE.notEqualsTo(SyncStatus.Uninitialized))
1140-
});
1133+
super(DOWNLOAD_ACTIVITY_ACTION_DESCRIPTOR);
11411134
}
1142-
11431135
async run(accessor: ServicesAccessor): Promise<void> {
11441136
const userDataSyncWorkbenchService = accessor.get(IUserDataSyncWorkbenchService);
1145-
const fileDialogService = accessor.get(IFileDialogService);
1146-
const progressService = accessor.get(IProgressService);
1147-
const uriIdentityService = accessor.get(IUriIdentityService);
1148-
const fileService = accessor.get(IFileService);
1149-
const userDataSyncMachinesService = accessor.get(IUserDataSyncMachinesService);
11501137
const notificationService = accessor.get(INotificationService);
1151-
1152-
const result = await fileDialogService.showOpenDialog({
1153-
title: localize('download sync activity dialog title', "Select folder to download Settings Sync activity"),
1154-
canSelectFiles: false,
1155-
canSelectFolders: true,
1156-
canSelectMany: false,
1157-
openLabel: localize('download sync activity dialog open label', "Save"),
1158-
});
1159-
1160-
if (!result?.[0]) {
1161-
return;
1138+
const folder = await userDataSyncWorkbenchService.downloadSyncActivity();
1139+
if (folder) {
1140+
notificationService.info(localize('download sync activity complete', "Successfully downloaded Settings Sync activity."));
11621141
}
1163-
1164-
await progressService.withProgress({ location: ProgressLocation.Window }, async () => {
1165-
const machines = await userDataSyncMachinesService.getMachines();
1166-
const currentMachine = machines.find(m => m.isCurrent);
1167-
const name = (currentMachine ? currentMachine.name + ' - ' : '') + 'Settings Sync Activity';
1168-
const stat = await fileService.resolve(result[0]);
1169-
1170-
const nameRegEx = new RegExp(`${escapeRegExpCharacters(name)}\\s(\\d+)`);
1171-
const indexes: number[] = [];
1172-
for (const child of stat.children ?? []) {
1173-
if (child.name === name) {
1174-
indexes.push(0);
1175-
} else {
1176-
const matches = nameRegEx.exec(child.name);
1177-
if (matches) {
1178-
indexes.push(parseInt(matches[1]));
1179-
}
1180-
}
1181-
}
1182-
indexes.sort((a, b) => a - b);
1183-
1184-
return userDataSyncWorkbenchService.downloadSyncActivity(uriIdentityService.extUri.joinPath(result[0], indexes[0] !== 0 ? name : `${name} ${indexes[indexes.length - 1] + 1}`));
1185-
});
1186-
1187-
notificationService.info(localize('download sync activity complete', "Successfully downloaded Settings Sync activity."));
11881142
}
11891143

11901144
}));

src/vs/workbench/contrib/userDataSync/electron-sandbox/userDataSync.contribution.ts

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation
1515
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
1616
import { IFileService } from 'vs/platform/files/common/files';
1717
import { INativeHostService } from 'vs/platform/native/common/native';
18-
import { INotificationService } from 'vs/platform/notification/common/notification';
19-
import { CONTEXT_SYNC_STATE, SYNC_TITLE } from 'vs/workbench/services/userDataSync/common/userDataSync';
18+
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
19+
import { CONTEXT_SYNC_STATE, DOWNLOAD_ACTIVITY_ACTION_DESCRIPTOR, IUserDataSyncWorkbenchService, SYNC_TITLE } from 'vs/workbench/services/userDataSync/common/userDataSync';
2020
import { Schemas } from 'vs/base/common/network';
2121

2222
class UserDataSyncServicesContribution implements IWorkbenchContribution {
@@ -58,3 +58,23 @@ registerAction2(class OpenSyncBackupsFolder extends Action2 {
5858
}
5959
}
6060
});
61+
62+
registerAction2(class DownloadSyncActivityAction extends Action2 {
63+
constructor() {
64+
super(DOWNLOAD_ACTIVITY_ACTION_DESCRIPTOR);
65+
}
66+
67+
async run(accessor: ServicesAccessor): Promise<void> {
68+
const userDataSyncWorkbenchService = accessor.get(IUserDataSyncWorkbenchService);
69+
const notificationService = accessor.get(INotificationService);
70+
const hostService = accessor.get(INativeHostService);
71+
const folder = await userDataSyncWorkbenchService.downloadSyncActivity();
72+
if (folder) {
73+
notificationService.prompt(Severity.Info, localize('download sync activity complete', "Successfully downloaded Settings Sync activity."),
74+
[{
75+
label: localize('open', "Open Folder"),
76+
run: () => hostService.showItemInFolder(folder.fsPath)
77+
}]);
78+
}
79+
}
80+
});

src/vs/workbench/services/userDataSync/browser/userDataSyncWorkbenchService.ts

Lines changed: 49 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import { IProductService } from 'vs/platform/product/common/productService';
1919
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
2020
import { localize } from 'vs/nls';
2121
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';
22-
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
22+
import { IDialogService, IFileDialogService } from 'vs/platform/dialogs/common/dialogs';
2323
import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
2424
import { IProgressService, ProgressLocation } from 'vs/platform/progress/common/progress';
2525
import { URI } from 'vs/base/common/uri';
@@ -39,6 +39,8 @@ import { IBrowserWorkbenchEnvironmentService } from 'vs/workbench/services/envir
3939
import { IUserDataInitializationService } from 'vs/workbench/services/userData/browser/userDataInit';
4040
import { ISecretStorageService } from 'vs/platform/secrets/common/secrets';
4141
import { IFileService } from 'vs/platform/files/common/files';
42+
import { escapeRegExpCharacters } from 'vs/base/common/strings';
43+
import { IUserDataSyncMachinesService } from 'vs/platform/userDataSync/common/userDataSyncMachines';
4244

4345
type AccountQuickPickItem = { label: string; authenticationProvider: IAuthenticationProvider; account?: UserDataSyncAccount; description?: string };
4446

@@ -115,6 +117,8 @@ export class UserDataSyncWorkbenchService extends Disposable implements IUserDat
115117
@IEditorService private readonly editorService: IEditorService,
116118
@IUserDataInitializationService private readonly userDataInitializationService: IUserDataInitializationService,
117119
@IFileService private readonly fileService: IFileService,
120+
@IFileDialogService private readonly fileDialogService: IFileDialogService,
121+
@IUserDataSyncMachinesService private readonly userDataSyncMachinesService: IUserDataSyncMachinesService,
118122
) {
119123
super();
120124
this.syncEnablementContext = CONTEXT_SYNC_ENABLEMENT.bindTo(contextKeyService);
@@ -477,15 +481,50 @@ export class UserDataSyncWorkbenchService extends Disposable implements IUserDat
477481
await this.viewsService.openViewContainer(SYNC_VIEW_CONTAINER_ID);
478482
}
479483

480-
async downloadSyncActivity(location: URI): Promise<void> {
481-
await Promise.all([
482-
this.userDataSyncService.saveRemoteActivityData(this.uriIdentityService.extUri.joinPath(location, 'remoteActivity.json')),
483-
(async () => {
484-
const logResources = await this.getAllLogResources();
485-
await Promise.all(logResources.map(async logResource => this.fileService.copy(logResource, this.uriIdentityService.extUri.joinPath(location, 'logs', `${this.uriIdentityService.extUri.basename(this.uriIdentityService.extUri.dirname(logResource))}.log`))));
486-
})(),
487-
this.fileService.copy(this.environmentService.userDataSyncHome, this.uriIdentityService.extUri.joinPath(location, 'localActivity')),
488-
]);
484+
async downloadSyncActivity(): Promise<URI | undefined> {
485+
const result = await this.fileDialogService.showOpenDialog({
486+
title: localize('download sync activity dialog title', "Select folder to download Settings Sync activity"),
487+
canSelectFiles: false,
488+
canSelectFolders: true,
489+
canSelectMany: false,
490+
openLabel: localize('download sync activity dialog open label', "Save"),
491+
});
492+
493+
if (!result?.[0]) {
494+
return;
495+
}
496+
497+
return this.progressService.withProgress({ location: ProgressLocation.Window }, async () => {
498+
const machines = await this.userDataSyncMachinesService.getMachines();
499+
const currentMachine = machines.find(m => m.isCurrent);
500+
const name = (currentMachine ? currentMachine.name + ' - ' : '') + 'Settings Sync Activity';
501+
const stat = await this.fileService.resolve(result[0]);
502+
503+
const nameRegEx = new RegExp(`${escapeRegExpCharacters(name)}\\s(\\d+)`);
504+
const indexes: number[] = [];
505+
for (const child of stat.children ?? []) {
506+
if (child.name === name) {
507+
indexes.push(0);
508+
} else {
509+
const matches = nameRegEx.exec(child.name);
510+
if (matches) {
511+
indexes.push(parseInt(matches[1]));
512+
}
513+
}
514+
}
515+
indexes.sort((a, b) => a - b);
516+
517+
const folder = this.uriIdentityService.extUri.joinPath(result[0], indexes[0] !== 0 ? name : `${name} ${indexes[indexes.length - 1] + 1}`);
518+
await Promise.all([
519+
this.userDataSyncService.saveRemoteActivityData(this.uriIdentityService.extUri.joinPath(folder, 'remoteActivity.json')),
520+
(async () => {
521+
const logResources = await this.getAllLogResources();
522+
await Promise.all(logResources.map(async logResource => this.fileService.copy(logResource, this.uriIdentityService.extUri.joinPath(folder, 'logs', `${this.uriIdentityService.extUri.basename(this.uriIdentityService.extUri.dirname(logResource))}.log`))));
523+
})(),
524+
this.fileService.copy(this.environmentService.userDataSyncHome, this.uriIdentityService.extUri.joinPath(folder, 'localActivity')),
525+
]);
526+
return folder;
527+
});
489528
}
490529

491530
private async waitForActiveSyncViews(): Promise<void> {

src/vs/workbench/services/userDataSync/common/userDataSync.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@
66
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
77
import { IAuthenticationProvider, SyncStatus, SyncResource, IUserDataSyncResource, IResourcePreview } from 'vs/platform/userDataSync/common/userDataSync';
88
import { Event } from 'vs/base/common/event';
9-
import { RawContextKey } from 'vs/platform/contextkey/common/contextkey';
9+
import { ContextKeyExpr, RawContextKey } from 'vs/platform/contextkey/common/contextkey';
1010
import { localize } from 'vs/nls';
1111
import { URI } from 'vs/base/common/uri';
1212
import { Codicon } from 'vs/base/common/codicons';
1313
import { registerIcon } from 'vs/platform/theme/common/iconRegistry';
1414
import { IView } from 'vs/workbench/common/views';
15+
import { Categories } from 'vs/platform/action/common/actionCommonCategories';
16+
import { IAction2Options } from 'vs/platform/actions/common/actions';
1517

1618
export interface IUserDataSyncAccount {
1719
readonly authenticationProviderId: string;
@@ -45,7 +47,7 @@ export interface IUserDataSyncWorkbenchService {
4547
accept(resource: IUserDataSyncResource, conflictResource: URI, content: string | null | undefined, apply: boolean): Promise<void>;
4648

4749
getAllLogResources(): Promise<URI[]>;
48-
downloadSyncActivity(location: URI): Promise<void>;
50+
downloadSyncActivity(): Promise<URI | undefined>;
4951
}
5052

5153
export function getSyncAreaLabel(source: SyncResource): string {
@@ -90,3 +92,11 @@ export const SHOW_SYNC_LOG_COMMAND_ID = 'workbench.userDataSync.actions.showLog'
9092
// VIEWS
9193
export const SYNC_VIEW_CONTAINER_ID = 'workbench.view.sync';
9294
export const SYNC_CONFLICTS_VIEW_ID = 'workbench.views.sync.conflicts';
95+
96+
export const DOWNLOAD_ACTIVITY_ACTION_DESCRIPTOR: Readonly<IAction2Options> = {
97+
id: 'workbench.userDataSync.actions.downloadSyncActivity',
98+
title: { original: 'Download Settings Sync Activity', value: localize('download sync activity title', "Download Settings Sync Activity") },
99+
category: Categories.Developer,
100+
f1: true,
101+
precondition: ContextKeyExpr.and(CONTEXT_ACCOUNT_STATE.isEqualTo(AccountStatus.Available), CONTEXT_SYNC_STATE.notEqualsTo(SyncStatus.Uninitialized))
102+
};

0 commit comments

Comments
 (0)