diff --git a/src/vs/platform/userDataSync/common/userDataSync.ts b/src/vs/platform/userDataSync/common/userDataSync.ts index a79be906630..e4c71928b42 100644 --- a/src/vs/platform/userDataSync/common/userDataSync.ts +++ b/src/vs/platform/userDataSync/common/userDataSync.ts @@ -357,6 +357,7 @@ export interface IUserDataSyncService { readonly status: SyncStatus; readonly onDidChangeStatus: Event; + readonly onSynchronizeResource: Event; readonly conflicts: SyncResourceConflicts[]; readonly onDidChangeConflicts: Event; diff --git a/src/vs/platform/userDataSync/common/userDataSyncIpc.ts b/src/vs/platform/userDataSync/common/userDataSyncIpc.ts index 2df27100016..467f6902fe6 100644 --- a/src/vs/platform/userDataSync/common/userDataSyncIpc.ts +++ b/src/vs/platform/userDataSync/common/userDataSyncIpc.ts @@ -22,6 +22,7 @@ export class UserDataSyncChannel implements IServerChannel { listen(_: unknown, event: string): Event { switch (event) { case 'onDidChangeStatus': return this.service.onDidChangeStatus; + case 'onSynchronizeResource': return this.service.onSynchronizeResource; case 'onDidChangeConflicts': return this.service.onDidChangeConflicts; case 'onDidChangeLocal': return this.service.onDidChangeLocal; case 'onDidChangeLastSyncTime': return this.service.onDidChangeLastSyncTime; diff --git a/src/vs/platform/userDataSync/common/userDataSyncService.ts b/src/vs/platform/userDataSync/common/userDataSyncService.ts index a1e9c9592c9..2fadc715911 100644 --- a/src/vs/platform/userDataSync/common/userDataSyncService.ts +++ b/src/vs/platform/userDataSync/common/userDataSyncService.ts @@ -39,6 +39,9 @@ export class UserDataSyncService extends Disposable implements IUserDataSyncServ private _onDidChangeStatus: Emitter = this._register(new Emitter()); readonly onDidChangeStatus: Event = this._onDidChangeStatus.event; + private _onSynchronizeResource: Emitter = this._register(new Emitter()); + readonly onSynchronizeResource: Event = this._onSynchronizeResource.event; + readonly onDidChangeLocal: Event; private _conflicts: SyncResourceConflicts[] = []; @@ -91,6 +94,7 @@ export class UserDataSyncService extends Disposable implements IUserDataSyncServ try { for (const synchroniser of this.synchronisers) { try { + this._onSynchronizeResource.fire(synchroniser.resource); await synchroniser.pull(); } catch (e) { this.handleSynchronizerError(e, synchroniser.resource); @@ -175,6 +179,7 @@ export class UserDataSyncService extends Disposable implements IUserDataSyncServ return; } try { + this._onSynchronizeResource.fire(synchroniser.resource); await synchroniser.sync(manifest, syncHeaders); } catch (e) { this.handleSynchronizerError(e, synchroniser.resource); diff --git a/src/vs/workbench/services/userDataSync/browser/userDataSyncWorkbenchService.ts b/src/vs/workbench/services/userDataSync/browser/userDataSyncWorkbenchService.ts index a2b39520076..39cf3d651fa 100644 --- a/src/vs/workbench/services/userDataSync/browser/userDataSyncWorkbenchService.ts +++ b/src/vs/workbench/services/userDataSync/browser/userDataSyncWorkbenchService.ts @@ -6,7 +6,7 @@ import { IUserDataSyncService, IAuthenticationProvider, getUserDataSyncStore, isAuthenticationProvider, IUserDataAutoSyncService } from 'vs/platform/userDataSync/common/userDataSync'; import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry'; import { registerSingleton } from 'vs/platform/instantiation/common/extensions'; -import { IUserDataSyncWorkbenchService, IUserDataSyncAccount, AccountStatus, CONTEXT_SYNC_ENABLEMENT, CONTEXT_SYNC_STATE, CONTEXT_ACCOUNT_STATE, SHOW_SYNCED_DATA_COMMAND_ID } from 'vs/workbench/services/userDataSync/common/userDataSync'; +import { IUserDataSyncWorkbenchService, IUserDataSyncAccount, AccountStatus, CONTEXT_SYNC_ENABLEMENT, CONTEXT_SYNC_STATE, CONTEXT_ACCOUNT_STATE, SHOW_SYNCED_DATA_COMMAND_ID, SHOW_SYNC_LOG_COMMAND_ID, getSyncAreaLabel } from 'vs/workbench/services/userDataSync/common/userDataSync'; import { AuthenticationSession, AuthenticationSessionsChangeEvent } from 'vs/editor/common/modes'; import { Disposable, DisposableStore } from 'vs/base/common/lifecycle'; import { Emitter, Event } from 'vs/base/common/event'; @@ -28,6 +28,7 @@ import { IDialogService } from 'vs/platform/dialogs/common/dialogs'; import { IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey'; import { ICommandService } from 'vs/platform/commands/common/commands'; import { Action } from 'vs/base/common/actions'; +import { IProgressService, ProgressLocation } from 'vs/platform/progress/common/progress'; type UserAccountClassification = { id: { classification: 'EndUserPseudonymizedInformation', purpose: 'BusinessInsight' }; @@ -90,6 +91,7 @@ export class UserDataSyncWorkbenchService extends Disposable implements IUserDat @IExtensionService extensionService: IExtensionService, @IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService, @INotificationService private readonly notificationService: INotificationService, + @IProgressService private readonly progressService: IProgressService, @IDialogService private readonly dialogService: IDialogService, @ICommandService private readonly commandService: ICommandService, @IContextKeyService contextKeyService: IContextKeyService, @@ -219,18 +221,31 @@ export class UserDataSyncWorkbenchService extends Disposable implements IUserDat throw new Error(localize('no account', "No account available")); } - const pullFirst = await this.handleFirstTimeSync(); - await this.userDataAutoSyncService.turnOn(pullFirst); - this.notificationService.info(localize('sync turned on', "Preferences sync is turned on")); + const preferencesSyncTitle = localize('preferences sync', "Preferences Sync"); + const title = `${preferencesSyncTitle} [(${localize('details', "details")})](command:${SHOW_SYNC_LOG_COMMAND_ID})`; + await this.progressService.withProgress({ + location: ProgressLocation.Notification, + title, + delay: 500, + }, async (progress) => { + progress.report({ message: localize('turning on', "Turning on...") }); + const pullFirst = await this.isSyncingWithAnotherMachine(); + const disposable = this.userDataSyncService.onSynchronizeResource(resource => + progress.report({ message: localize('syncing resource', "Syncing {0}...", getSyncAreaLabel(resource)) })); + await this.userDataAutoSyncService.turnOn(pullFirst); + disposable.dispose(); + }); + + this.notificationService.info(localize('sync turned on', "{0} is turned on", title)); } turnoff(everywhere: boolean): Promise { return this.userDataAutoSyncService.turnOff(everywhere); } - private async handleFirstTimeSync(): Promise { - const isFirstTimeSyncingWithAnotherMachine = await this.userDataSyncService.isFirstTimeSyncingWithAnotherMachine(); - if (!isFirstTimeSyncingWithAnotherMachine) { + private async isSyncingWithAnotherMachine(): Promise { + const isSyncingWithAnotherMachine = await this.userDataSyncService.isFirstTimeSyncingWithAnotherMachine(); + if (!isSyncingWithAnotherMachine) { return false; } diff --git a/src/vs/workbench/services/userDataSync/electron-browser/userDataSyncService.ts b/src/vs/workbench/services/userDataSync/electron-browser/userDataSyncService.ts index a562eb0c66f..7f1084593fe 100644 --- a/src/vs/workbench/services/userDataSync/electron-browser/userDataSyncService.ts +++ b/src/vs/workbench/services/userDataSync/electron-browser/userDataSyncService.ts @@ -38,6 +38,8 @@ export class UserDataSyncService extends Disposable implements IUserDataSyncServ private _onSyncErrors: Emitter<[SyncResource, UserDataSyncError][]> = this._register(new Emitter<[SyncResource, UserDataSyncError][]>()); readonly onSyncErrors: Event<[SyncResource, UserDataSyncError][]> = this._onSyncErrors.event; + get onSynchronizeResource(): Event { return this.channel.listen('onSynchronizeResource'); } + constructor( @ISharedProcessService sharedProcessService: ISharedProcessService ) {