mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
Merge from vscode 4d91d96e5e121b38d33508cdef17868bab255eae
This commit is contained in:
committed by
AzureDataStudio
parent
a971aee5bd
commit
5e7071e466
@@ -3,37 +3,39 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IUserDataSyncService, IUserDataSyncLogService, IUserDataSyncEnablementService } from 'vs/platform/userDataSync/common/userDataSync';
|
||||
import { IUserDataSyncService, IUserDataSyncLogService, IUserDataSyncResourceEnablementService, IUserDataSyncStoreService } from 'vs/platform/userDataSync/common/userDataSync';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { UserDataAutoSyncService as BaseUserDataAutoSyncService } from 'vs/platform/userDataSync/common/userDataAutoSyncService';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IHostService } from 'vs/workbench/services/host/browser/host';
|
||||
import { IAuthenticationTokenService } from 'vs/platform/authentication/common/authentication';
|
||||
import { IUserDataSyncAccountService } from 'vs/platform/userDataSync/common/userDataSyncAccount';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { UserDataSyncTrigger } from 'vs/workbench/contrib/userDataSync/browser/userDataSyncTrigger';
|
||||
import { IProductService } from 'vs/platform/product/common/productService';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IStorageService } from 'vs/platform/storage/common/storage';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
import { IUserDataSyncMachinesService } from 'vs/platform/userDataSync/common/userDataSyncMachines';
|
||||
|
||||
export class UserDataAutoSyncService extends BaseUserDataAutoSyncService {
|
||||
|
||||
constructor(
|
||||
@IUserDataSyncEnablementService userDataSyncEnablementService: IUserDataSyncEnablementService,
|
||||
@IUserDataSyncStoreService userDataSyncStoreService: IUserDataSyncStoreService,
|
||||
@IUserDataSyncResourceEnablementService userDataSyncResourceEnablementService: IUserDataSyncResourceEnablementService,
|
||||
@IUserDataSyncService userDataSyncService: IUserDataSyncService,
|
||||
@IUserDataSyncLogService logService: IUserDataSyncLogService,
|
||||
@IAuthenticationTokenService authTokenService: IAuthenticationTokenService,
|
||||
@IUserDataSyncAccountService authTokenService: IUserDataSyncAccountService,
|
||||
@IInstantiationService instantiationService: IInstantiationService,
|
||||
@IHostService hostService: IHostService,
|
||||
@ITelemetryService telemetryService: ITelemetryService,
|
||||
@IProductService productService: IProductService,
|
||||
@IConfigurationService configurationService: IConfigurationService,
|
||||
@IUserDataSyncMachinesService userDataSyncMachinesService: IUserDataSyncMachinesService,
|
||||
@IStorageService storageService: IStorageService,
|
||||
@IEnvironmentService environmentService: IEnvironmentService,
|
||||
) {
|
||||
super(userDataSyncEnablementService, userDataSyncService, logService, authTokenService, telemetryService, productService, configurationService);
|
||||
super(userDataSyncStoreService, userDataSyncResourceEnablementService, userDataSyncService, logService, authTokenService, telemetryService, userDataSyncMachinesService, storageService, environmentService);
|
||||
|
||||
this._register(Event.debounce<string, string[]>(Event.any<string>(
|
||||
Event.map(hostService.onDidChangeFocus, () => 'windowFocus'),
|
||||
instantiationService.createInstance(UserDataSyncTrigger).onDidTriggerSync,
|
||||
userDataSyncService.onDidChangeLocal,
|
||||
), (last, source) => last ? [...last, source] : [source], 1000)(sources => this.triggerAutoSync(sources)));
|
||||
), (last, source) => last ? [...last, source] : [source], 1000)(sources => this.triggerSync(sources, true)));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ class UserDataSyncReportIssueContribution extends Disposable implements IWorkben
|
||||
private onAutoSyncError(error: UserDataSyncError): void {
|
||||
switch (error.code) {
|
||||
case UserDataSyncErrorCode.LocalTooManyRequests:
|
||||
case UserDataSyncErrorCode.TooManyRequests:
|
||||
this.notificationService.notify({
|
||||
severity: Severity.Error,
|
||||
message: localize('too many requests', "Turned off syncing preferences on this device because it is making too many requests."),
|
||||
|
||||
@@ -29,7 +29,7 @@ import { IQuickInputService, IQuickPickItem, IQuickPickSeparator } from 'vs/plat
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import {
|
||||
IUserDataAutoSyncService, IUserDataSyncService, registerConfiguration,
|
||||
SyncResource, SyncStatus, UserDataSyncError, UserDataSyncErrorCode, USER_DATA_SYNC_SCHEME, IUserDataSyncEnablementService,
|
||||
SyncResource, SyncStatus, UserDataSyncError, UserDataSyncErrorCode, USER_DATA_SYNC_SCHEME, IUserDataSyncResourceEnablementService,
|
||||
SyncResourceConflicts, Conflict, getSyncResourceFromLocalPreview
|
||||
} from 'vs/platform/userDataSync/common/userDataSync';
|
||||
import { FloatingClickWidget } from 'vs/workbench/browser/parts/editor/editorWidgets';
|
||||
@@ -42,7 +42,7 @@ import { IActivityService, IBadge, NumberBadge, ProgressBadge } from 'vs/workben
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
|
||||
import { IPreferencesService } from 'vs/workbench/services/preferences/common/preferences';
|
||||
import { IAuthenticationTokenService } from 'vs/platform/authentication/common/authentication';
|
||||
import { IUserDataSyncAccountService } from 'vs/platform/userDataSync/common/userDataSyncAccount';
|
||||
import { fromNow } from 'vs/base/common/date';
|
||||
import { IProductService } from 'vs/platform/product/common/productService';
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
@@ -93,10 +93,11 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
||||
private readonly conflictsSources: IContextKey<string>;
|
||||
private readonly viewsEnablementContext: IContextKey<boolean>;
|
||||
|
||||
private readonly badgeDisposable = this._register(new MutableDisposable());
|
||||
private readonly globalActivityBadgeDisposable = this._register(new MutableDisposable());
|
||||
private readonly accountBadgeDisposable = this._register(new MutableDisposable());
|
||||
|
||||
constructor(
|
||||
@IUserDataSyncEnablementService private readonly userDataSyncEnablementService: IUserDataSyncEnablementService,
|
||||
@IUserDataSyncResourceEnablementService private readonly userDataSyncResourceEnablementService: IUserDataSyncResourceEnablementService,
|
||||
@IUserDataSyncService private readonly userDataSyncService: IUserDataSyncService,
|
||||
@IUserDataSyncWorkbenchService private readonly userDataSyncWorkbenchService: IUserDataSyncWorkbenchService,
|
||||
@IContextKeyService contextKeyService: IContextKeyService,
|
||||
@@ -108,8 +109,8 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
||||
@IQuickInputService private readonly quickInputService: IQuickInputService,
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
@IOutputService private readonly outputService: IOutputService,
|
||||
@IAuthenticationTokenService readonly authTokenService: IAuthenticationTokenService,
|
||||
@IUserDataAutoSyncService userDataAutoSyncService: IUserDataAutoSyncService,
|
||||
@IUserDataSyncAccountService readonly authTokenService: IUserDataSyncAccountService,
|
||||
@IUserDataAutoSyncService private readonly userDataAutoSyncService: IUserDataAutoSyncService,
|
||||
@ITextModelService private readonly textModelResolverService: ITextModelService,
|
||||
@IPreferencesService private readonly preferencesService: IPreferencesService,
|
||||
@ITelemetryService private readonly telemetryService: ITelemetryService,
|
||||
@@ -127,14 +128,18 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
||||
if (this.userDataSyncWorkbenchService.authenticationProviders.length) {
|
||||
registerConfiguration();
|
||||
|
||||
this.updateBadge();
|
||||
this.updateAccountBadge();
|
||||
this.updateGlobalActivityBadge();
|
||||
this.onDidChangeConflicts(this.userDataSyncService.conflicts);
|
||||
|
||||
this._register(Event.any(
|
||||
Event.debounce(userDataSyncService.onDidChangeStatus, () => undefined, 500),
|
||||
this.userDataSyncEnablementService.onDidChangeEnablement,
|
||||
this.userDataAutoSyncService.onDidChangeEnablement,
|
||||
this.userDataSyncWorkbenchService.onDidChangeAccountStatus
|
||||
)(() => this.updateBadge()));
|
||||
)(() => {
|
||||
this.updateAccountBadge();
|
||||
this.updateGlobalActivityBadge();
|
||||
}));
|
||||
this._register(userDataSyncService.onDidChangeConflicts(() => this.onDidChangeConflicts(this.userDataSyncService.conflicts)));
|
||||
this._register(userDataSyncService.onSyncErrors(errors => this.onSynchronizerErrors(errors)));
|
||||
this._register(userDataAutoSyncService.onError(error => this.onAutoSyncError(error)));
|
||||
@@ -149,7 +154,7 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
||||
|
||||
private readonly conflictsDisposables = new Map<SyncResource, IDisposable>();
|
||||
private onDidChangeConflicts(conflicts: SyncResourceConflicts[]) {
|
||||
this.updateBadge();
|
||||
this.updateGlobalActivityBadge();
|
||||
if (conflicts.length) {
|
||||
const conflictsSources: SyncResource[] = conflicts.map(conflict => conflict.syncResource);
|
||||
this.conflictsSources.set(conflictsSources.join(','));
|
||||
@@ -261,7 +266,7 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
||||
}
|
||||
}
|
||||
|
||||
private onAutoSyncError(error: UserDataSyncError): boolean {
|
||||
private onAutoSyncError(error: UserDataSyncError): void {
|
||||
switch (error.code) {
|
||||
case UserDataSyncErrorCode.TurnedOff:
|
||||
case UserDataSyncErrorCode.SessionExpired:
|
||||
@@ -272,31 +277,35 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
||||
primary: [new Action('turn on sync', localize('turn on sync', "Turn on Preferences Sync..."), undefined, true, () => this.turnOn())]
|
||||
}
|
||||
});
|
||||
return true;
|
||||
break;
|
||||
case UserDataSyncErrorCode.TooLarge:
|
||||
if (error.resource === SyncResource.Keybindings || error.resource === SyncResource.Settings) {
|
||||
this.disableSync(error.resource);
|
||||
const sourceArea = getSyncAreaLabel(error.resource);
|
||||
this.notificationService.notify({
|
||||
severity: Severity.Error,
|
||||
message: localize('too large', "Disabled syncing {0} because size of the {1} file to sync is larger than {2}. Please open the file and reduce the size and enable sync", sourceArea.toLowerCase(), sourceArea.toLowerCase(), '100kb'),
|
||||
actions: {
|
||||
primary: [new Action('open sync file', localize('open file', "Open {0} File", sourceArea), undefined, true,
|
||||
() => error.resource === SyncResource.Settings ? this.preferencesService.openGlobalSettings(true) : this.preferencesService.openGlobalKeybindingSettings(true))]
|
||||
}
|
||||
});
|
||||
this.handleTooLargeError(error.resource, localize('too large', "Disabled syncing {0} because size of the {1} file to sync is larger than {2}. Please open the file and reduce the size and enable sync", sourceArea.toLowerCase(), sourceArea.toLowerCase(), '100kb'));
|
||||
}
|
||||
return true;
|
||||
break;
|
||||
case UserDataSyncErrorCode.Incompatible:
|
||||
case UserDataSyncErrorCode.Gone:
|
||||
case UserDataSyncErrorCode.UpgradeRequired:
|
||||
this.disableSync();
|
||||
this.userDataSyncWorkbenchService.turnoff(false);
|
||||
this.notificationService.notify({
|
||||
severity: Severity.Error,
|
||||
message: localize('error upgrade required', "Turned off sync because the current version ({0}, {1}) of {2} is not compatible with the Preferences Sync Service. Please update and turn on sync to continue syncing.", this.productService.version, this.productService.commit, this.productService.nameLong),
|
||||
message: localize('error upgrade required', "Preferences sync is disabled because the current version ({0}, {1}) is not compatible with the sync service. Please update before turning on sync.", this.productService.version, this.productService.commit),
|
||||
});
|
||||
return true;
|
||||
break;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private handleTooLargeError(resource: SyncResource, message: string): void {
|
||||
this.notificationService.notify({
|
||||
severity: Severity.Error,
|
||||
message,
|
||||
actions: {
|
||||
primary: [new Action('open sync file', localize('open file', "Open {0} File", getSyncAreaLabel(resource)), undefined, true,
|
||||
() => resource === SyncResource.Settings ? this.preferencesService.openGlobalSettings(true) : this.preferencesService.openGlobalKeybindingSettings(true))]
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private readonly invalidContentErrorDisposables = new Map<SyncResource, IDisposable>();
|
||||
@@ -336,7 +345,7 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
||||
const errorArea = getSyncAreaLabel(source);
|
||||
const handle = this.notificationService.notify({
|
||||
severity: Severity.Error,
|
||||
message: localize('errorInvalidConfiguration', "Unable to sync {0} because there are some errors/warnings in the file. Please open the file to correct errors/warnings in it.", errorArea.toLowerCase()),
|
||||
message: localize('errorInvalidConfiguration', "Unable to sync {0} because the content in the file is not valid. Please open the file and correct it.", errorArea.toLowerCase()),
|
||||
actions: {
|
||||
primary: [new Action('open sync file', localize('open file', "Open {0} File", errorArea), undefined, true,
|
||||
() => source === SyncResource.Settings ? this.preferencesService.openGlobalSettings(true) : this.preferencesService.openGlobalKeybindingSettings(true))]
|
||||
@@ -349,16 +358,14 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
||||
}));
|
||||
}
|
||||
|
||||
private async updateBadge(): Promise<void> {
|
||||
this.badgeDisposable.clear();
|
||||
private async updateGlobalActivityBadge(): Promise<void> {
|
||||
this.globalActivityBadgeDisposable.clear();
|
||||
|
||||
let badge: IBadge | undefined = undefined;
|
||||
let clazz: string | undefined;
|
||||
let priority: number | undefined = undefined;
|
||||
|
||||
if (this.userDataSyncService.status !== SyncStatus.Uninitialized && this.userDataSyncEnablementService.isEnabled() && this.userDataSyncWorkbenchService.accountStatus === AccountStatus.Unavailable) {
|
||||
badge = new NumberBadge(1, () => localize('sign in to sync preferences', "Sign in to Sync Preferences"));
|
||||
} else if (this.userDataSyncService.conflicts.length) {
|
||||
if (this.userDataSyncService.conflicts.length) {
|
||||
badge = new NumberBadge(this.userDataSyncService.conflicts.reduce((result, syncResourceConflict) => { return result + syncResourceConflict.conflicts.length; }, 0), () => localize('has conflicts', "Preferences Sync: Conflicts Detected"));
|
||||
} else if (this.turningOnSync) {
|
||||
badge = new ProgressBadge(() => localize('turning on syncing', "Turning on Preferences Sync..."));
|
||||
@@ -367,7 +374,21 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
||||
}
|
||||
|
||||
if (badge) {
|
||||
this.badgeDisposable.value = this.activityService.showGlobalActivity({ badge, clazz, priority });
|
||||
this.globalActivityBadgeDisposable.value = this.activityService.showGlobalActivity({ badge, clazz, priority });
|
||||
}
|
||||
}
|
||||
|
||||
private async updateAccountBadge(): Promise<void> {
|
||||
this.accountBadgeDisposable.clear();
|
||||
|
||||
let badge: IBadge | undefined = undefined;
|
||||
|
||||
if (this.userDataSyncService.status !== SyncStatus.Uninitialized && this.userDataAutoSyncService.isEnabled() && this.userDataSyncWorkbenchService.accountStatus === AccountStatus.Unavailable) {
|
||||
badge = new NumberBadge(1, () => localize('sign in to sync preferences', "Sign in to Sync Preferences"));
|
||||
}
|
||||
|
||||
if (badge) {
|
||||
this.accountBadgeDisposable.value = this.activityService.showAccountsActivity({ badge, clazz: undefined, priority: undefined });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -377,7 +398,7 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
||||
|
||||
private set turningOnSync(turningOn: boolean) {
|
||||
this.turningOnSyncContext.set(turningOn);
|
||||
this.updateBadge();
|
||||
this.updateGlobalActivityBadge();
|
||||
}
|
||||
|
||||
private async turnOn(): Promise<void> {
|
||||
@@ -398,8 +419,23 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
||||
if (isPromiseCanceledError(e)) {
|
||||
return;
|
||||
}
|
||||
if (e instanceof UserDataSyncError && this.onAutoSyncError(e)) {
|
||||
return;
|
||||
if (e instanceof UserDataSyncError) {
|
||||
switch (e.code) {
|
||||
case UserDataSyncErrorCode.TooLarge:
|
||||
if (e.resource === SyncResource.Keybindings || e.resource === SyncResource.Settings) {
|
||||
this.handleTooLargeError(e.resource, localize('too large while starting sync', "Preferences sync cannot be turned on because size of the {0} file to sync is larger than {1}. Please open the file and reduce the size and turn on sync", getSyncAreaLabel(e.resource).toLowerCase(), '100kb'));
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case UserDataSyncErrorCode.Incompatible:
|
||||
case UserDataSyncErrorCode.Gone:
|
||||
case UserDataSyncErrorCode.UpgradeRequired:
|
||||
this.notificationService.notify({
|
||||
severity: Severity.Error,
|
||||
message: localize('error upgrade required while starting sync', "Preferences sync cannot be turned on because the current version ({0}, {1}) is not compatible with the sync service. Please update before turning on sync.", this.productService.version, this.productService.commit),
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
this.notificationService.error(localize('turn on failed', "Error while starting Sync: {0}", toErrorMessage(e)));
|
||||
} finally {
|
||||
@@ -450,7 +486,7 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
||||
quickPick.ignoreFocusOut = true;
|
||||
const items = this.getConfigureSyncQuickPickItems();
|
||||
quickPick.items = items;
|
||||
quickPick.selectedItems = items.filter(item => this.userDataSyncEnablementService.isResourceEnabled(item.id));
|
||||
quickPick.selectedItems = items.filter(item => this.userDataSyncResourceEnablementService.isResourceEnabled(item.id));
|
||||
let accepted: boolean = false;
|
||||
disposables.add(Event.any(quickPick.onDidAccept, quickPick.onDidCustom)(() => {
|
||||
accepted = true;
|
||||
@@ -493,10 +529,10 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
||||
|
||||
private updateConfiguration(items: ConfigureSyncQuickPickItem[], selectedItems: ReadonlyArray<ConfigureSyncQuickPickItem>): void {
|
||||
for (const item of items) {
|
||||
const wasEnabled = this.userDataSyncEnablementService.isResourceEnabled(item.id);
|
||||
const wasEnabled = this.userDataSyncResourceEnablementService.isResourceEnabled(item.id);
|
||||
const isEnabled = !!selectedItems.filter(selected => selected.id === item.id)[0];
|
||||
if (wasEnabled !== isEnabled) {
|
||||
this.userDataSyncEnablementService.setResourceEnablement(item.id!, isEnabled);
|
||||
this.userDataSyncResourceEnablementService.setResourceEnablement(item.id!, isEnabled);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -513,7 +549,7 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
||||
quickPick.ok = true;
|
||||
const items = this.getConfigureSyncQuickPickItems();
|
||||
quickPick.items = items;
|
||||
quickPick.selectedItems = items.filter(item => this.userDataSyncEnablementService.isResourceEnabled(item.id));
|
||||
quickPick.selectedItems = items.filter(item => this.userDataSyncResourceEnablementService.isResourceEnabled(item.id));
|
||||
disposables.add(quickPick.onDidAccept(async () => {
|
||||
if (quickPick.selectedItems.length) {
|
||||
this.updateConfiguration(items, quickPick.selectedItems);
|
||||
@@ -543,17 +579,13 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
||||
}
|
||||
}
|
||||
|
||||
private disableSync(source?: SyncResource): void {
|
||||
if (source === undefined) {
|
||||
this.userDataSyncEnablementService.setEnablement(false);
|
||||
} else {
|
||||
switch (source) {
|
||||
case SyncResource.Settings: return this.userDataSyncEnablementService.setResourceEnablement(SyncResource.Settings, false);
|
||||
case SyncResource.Keybindings: return this.userDataSyncEnablementService.setResourceEnablement(SyncResource.Keybindings, false);
|
||||
case SyncResource.Snippets: return this.userDataSyncEnablementService.setResourceEnablement(SyncResource.Snippets, false);
|
||||
case SyncResource.Extensions: return this.userDataSyncEnablementService.setResourceEnablement(SyncResource.Extensions, false);
|
||||
case SyncResource.GlobalState: return this.userDataSyncEnablementService.setResourceEnablement(SyncResource.GlobalState, false);
|
||||
}
|
||||
private disableSync(source: SyncResource): void {
|
||||
switch (source) {
|
||||
case SyncResource.Settings: return this.userDataSyncResourceEnablementService.setResourceEnablement(SyncResource.Settings, false);
|
||||
case SyncResource.Keybindings: return this.userDataSyncResourceEnablementService.setResourceEnablement(SyncResource.Keybindings, false);
|
||||
case SyncResource.Snippets: return this.userDataSyncResourceEnablementService.setResourceEnablement(SyncResource.Snippets, false);
|
||||
case SyncResource.Extensions: return this.userDataSyncResourceEnablementService.setResourceEnablement(SyncResource.Extensions, false);
|
||||
case SyncResource.GlobalState: return this.userDataSyncResourceEnablementService.setResourceEnablement(SyncResource.GlobalState, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -606,7 +638,7 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
||||
}
|
||||
|
||||
private registerActions(): void {
|
||||
if (this.userDataSyncEnablementService.canToggleEnablement()) {
|
||||
if (this.userDataAutoSyncService.canToggleEnablement()) {
|
||||
this.registerTurnOnSyncAction();
|
||||
this.registerTurnOffSyncAction();
|
||||
}
|
||||
@@ -690,7 +722,7 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
||||
constructor() {
|
||||
super({
|
||||
id: 'workbench.userData.actions.signin',
|
||||
title: localize('sign in global', "Sign in to Sync Preferences(1)"),
|
||||
title: localize('sign in global', "Sign in to Sync Preferences"),
|
||||
menu: {
|
||||
group: '5_sync',
|
||||
id: MenuId.GlobalActivity,
|
||||
@@ -701,7 +733,7 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
||||
}
|
||||
async run(): Promise<any> {
|
||||
try {
|
||||
await that.userDataSyncWorkbenchService.pickAccount();
|
||||
await that.userDataSyncWorkbenchService.signIn();
|
||||
} catch (e) {
|
||||
that.notificationService.error(e);
|
||||
}
|
||||
@@ -711,7 +743,7 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
||||
group: '1_sync',
|
||||
command: {
|
||||
id,
|
||||
title: localize('sign in accounts', "Sign in to Sync Preferences"),
|
||||
title: localize('sign in accounts', "Sign in to Sync Preferences (1)"),
|
||||
},
|
||||
when
|
||||
}));
|
||||
@@ -857,7 +889,7 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
||||
items.push({ id: configureSyncCommand.id, label: configureSyncCommand.title });
|
||||
items.push({ type: 'separator' });
|
||||
items.push({ id: syncNowCommand.id, label: syncNowCommand.title, description: syncNowCommand.description(that.userDataSyncService) });
|
||||
if (that.userDataSyncEnablementService.canToggleEnablement()) {
|
||||
if (that.userDataAutoSyncService.canToggleEnablement()) {
|
||||
const account = that.userDataSyncWorkbenchService.current;
|
||||
items.push({ id: turnOffSyncCommand.id, label: turnOffSyncCommand.title, description: account ? `${account.accountName} (${that.authenticationService.getDisplayName(account.authenticationProviderId)})` : undefined });
|
||||
}
|
||||
@@ -909,8 +941,7 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
||||
});
|
||||
}
|
||||
run(accessor: ServicesAccessor): Promise<any> {
|
||||
accessor.get(ITelemetryService).publicLog2(`sync/actions/${syncNowCommand.id}`);
|
||||
return that.userDataSyncService.sync();
|
||||
return that.userDataAutoSyncService.triggerSync([syncNowCommand.id], false);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import { localize } from 'vs/nls';
|
||||
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
|
||||
import { TreeViewPane, TreeView } from 'vs/workbench/browser/parts/views/treeView';
|
||||
import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { ALL_SYNC_RESOURCES, SyncResource, IUserDataSyncService, ISyncResourceHandle, SyncStatus, IUserDataSyncEnablementService } from 'vs/platform/userDataSync/common/userDataSync';
|
||||
import { ALL_SYNC_RESOURCES, SyncResource, IUserDataSyncService, ISyncResourceHandle, SyncStatus, IUserDataSyncResourceEnablementService, IUserDataAutoSyncService } from 'vs/platform/userDataSync/common/userDataSync';
|
||||
import { registerAction2, Action2, MenuId } from 'vs/platform/actions/common/actions';
|
||||
import { ContextKeyExpr, ContextKeyEqualsExpr, IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
@@ -19,7 +19,7 @@ import { fromNow } from 'vs/base/common/date';
|
||||
import { pad } from 'vs/base/common/strings';
|
||||
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { Disposable, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { ICommandService } from 'vs/platform/commands/common/commands';
|
||||
import { ViewPaneContainer } from 'vs/workbench/browser/parts/views/viewPaneContainer';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
@@ -31,9 +31,11 @@ import { IStorageService } from 'vs/platform/storage/common/storage';
|
||||
import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace';
|
||||
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
|
||||
import { IAction, Action } from 'vs/base/common/actions';
|
||||
import { IUserDataSyncWorkbenchService, CONTEXT_SYNC_STATE, getSyncAreaLabel, CONTEXT_ACCOUNT_STATE, AccountStatus, CONTEXT_ENABLE_VIEWS, SHOW_SYNC_LOG_COMMAND_ID, CONFIGURE_SYNC_COMMAND_ID, ENABLE_SYNC_VIEWS_COMMAND_ID } from 'vs/workbench/services/userDataSync/common/userDataSync';
|
||||
import { IUserDataSyncWorkbenchService, CONTEXT_SYNC_STATE, getSyncAreaLabel, CONTEXT_ACCOUNT_STATE, AccountStatus, CONTEXT_ENABLE_VIEWS, SHOW_SYNC_LOG_COMMAND_ID, CONFIGURE_SYNC_COMMAND_ID, ENABLE_SYNC_VIEWS_COMMAND_ID, SHOW_SYNCED_DATA_COMMAND_ID } from 'vs/workbench/services/userDataSync/common/userDataSync';
|
||||
import { IUserDataSyncMachinesService, IUserDataSyncMachine } from 'vs/platform/userDataSync/common/userDataSyncMachines';
|
||||
import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import { generateUuid } from 'vs/base/common/uuid';
|
||||
|
||||
export class UserDataSyncViewPaneContainer extends ViewPaneContainer {
|
||||
|
||||
@@ -68,10 +70,9 @@ export class UserDataSyncDataViews extends Disposable {
|
||||
constructor(
|
||||
container: ViewContainer,
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
@IUserDataSyncService private readonly userDataSyncService: IUserDataSyncService,
|
||||
@IUserDataSyncEnablementService private readonly userDataSyncEnablementService: IUserDataSyncEnablementService,
|
||||
@IUserDataAutoSyncService private readonly userDataAutoSyncService: IUserDataAutoSyncService,
|
||||
@IUserDataSyncResourceEnablementService private readonly userDataSyncResourceEnablementService: IUserDataSyncResourceEnablementService,
|
||||
@IContextKeyService private readonly contextKeyService: IContextKeyService,
|
||||
@IUserDataSyncMachinesService private readonly userDataSyncMachinesService: IUserDataSyncMachinesService,
|
||||
) {
|
||||
super();
|
||||
this.registerViews(container);
|
||||
@@ -96,11 +97,11 @@ export class UserDataSyncDataViews extends Disposable {
|
||||
const disposable = treeView.onDidChangeVisibility(visible => {
|
||||
if (visible && !treeView.dataProvider) {
|
||||
disposable.dispose();
|
||||
treeView.dataProvider = remote ? new RemoteUserDataSyncHistoryViewDataProvider(this.userDataSyncService, this.userDataSyncEnablementService, this.userDataSyncMachinesService)
|
||||
: new LocalUserDataSyncHistoryViewDataProvider(this.userDataSyncService, this.userDataSyncEnablementService);
|
||||
treeView.dataProvider = remote ? this.instantiationService.createInstance(RemoteUserDataSyncHistoryViewDataProvider)
|
||||
: this.instantiationService.createInstance(LocalUserDataSyncHistoryViewDataProvider);
|
||||
}
|
||||
});
|
||||
this._register(Event.any(this.userDataSyncEnablementService.onDidChangeResourceEnablement, this.userDataSyncEnablementService.onDidChangeEnablement)(() => treeView.refresh()));
|
||||
this._register(Event.any(this.userDataSyncResourceEnablementService.onDidChangeResourceEnablement, this.userDataAutoSyncService.onDidChangeEnablement)(() => treeView.refresh()));
|
||||
const viewsRegistry = Registry.as<IViewsRegistry>(Extensions.ViewsRegistry);
|
||||
viewsRegistry.registerViews([<ITreeViewDescriptor>{
|
||||
id,
|
||||
@@ -117,7 +118,7 @@ export class UserDataSyncDataViews extends Disposable {
|
||||
registerAction2(class extends Action2 {
|
||||
constructor() {
|
||||
super({
|
||||
id: `workbench.actions.showSync${remote ? 'Remote' : 'Local'}DataView`,
|
||||
id: remote ? SHOW_SYNCED_DATA_COMMAND_ID : 'workbench.userDataSync.actions.showLocalBackupData',
|
||||
title: remote ?
|
||||
{ value: localize('workbench.action.showSyncRemoteBackup', "Show Synced Data"), original: `Show Synced Data` }
|
||||
: { value: localize('workbench.action.showSyncLocalBackup', "Show Local Backup"), original: `Show Local Backup` },
|
||||
@@ -158,18 +159,18 @@ export class UserDataSyncDataViews extends Disposable {
|
||||
}
|
||||
|
||||
private registerMachinesView(container: ViewContainer): void {
|
||||
const that = this;
|
||||
const id = `workbench.views.sync.machines`;
|
||||
const name = localize('synced machines', "Synced Machines");
|
||||
const treeView = this.instantiationService.createInstance(TreeView, id, name);
|
||||
const dataProvider = this.instantiationService.createInstance(UserDataSyncMachinesViewDataProvider, treeView);
|
||||
treeView.showRefreshAction = true;
|
||||
const disposable = treeView.onDidChangeVisibility(visible => {
|
||||
if (visible && !treeView.dataProvider) {
|
||||
disposable.dispose();
|
||||
treeView.dataProvider = new UserDataSyncMachinesViewDataProvider(treeView, this.userDataSyncMachinesService);
|
||||
treeView.dataProvider = dataProvider;
|
||||
}
|
||||
});
|
||||
this._register(Event.any(this.userDataSyncEnablementService.onDidChangeResourceEnablement, this.userDataSyncEnablementService.onDidChangeEnablement)(() => treeView.refresh()));
|
||||
this._register(Event.any(this.userDataSyncResourceEnablementService.onDidChangeResourceEnablement, this.userDataAutoSyncService.onDidChangeEnablement)(() => treeView.refresh()));
|
||||
const viewsRegistry = Registry.as<IViewsRegistry>(Extensions.ViewsRegistry);
|
||||
viewsRegistry.registerViews([<ITreeViewDescriptor>{
|
||||
id,
|
||||
@@ -186,39 +187,42 @@ export class UserDataSyncDataViews extends Disposable {
|
||||
registerAction2(class extends Action2 {
|
||||
constructor() {
|
||||
super({
|
||||
id: `workbench.actions.sync.editCurrentMachineName`,
|
||||
title: localize('workbench.actions.sync.editCurrentMachineName', "Edit Name"),
|
||||
id: `workbench.actions.sync.editMachineName`,
|
||||
title: localize('workbench.actions.sync.editMachineName', "Edit Name"),
|
||||
icon: Codicon.edit,
|
||||
menu: {
|
||||
id: MenuId.ViewItemContext,
|
||||
when: ContextKeyExpr.and(ContextKeyEqualsExpr.create('view', id), ContextKeyEqualsExpr.create('viewItem', 'sync-machine')),
|
||||
when: ContextKeyExpr.and(ContextKeyEqualsExpr.create('view', id)),
|
||||
group: 'inline',
|
||||
},
|
||||
});
|
||||
}
|
||||
async run(accessor: ServicesAccessor, handle: TreeViewItemHandleArg): Promise<void> {
|
||||
const quickInputService = accessor.get(IQuickInputService);
|
||||
const inputBox = quickInputService.createInputBox();
|
||||
inputBox.placeholder = localize('placeholder', "Enter the name of the machine");
|
||||
inputBox.show();
|
||||
return new Promise((c, e) => {
|
||||
inputBox.onDidAccept(async () => {
|
||||
const name = inputBox.value;
|
||||
inputBox.dispose();
|
||||
if (name) {
|
||||
try {
|
||||
await that.userDataSyncMachinesService.renameMachine(handle.$treeItemHandle, name);
|
||||
await treeView.refresh();
|
||||
c();
|
||||
} catch (error) {
|
||||
e(error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
const changed = await dataProvider.rename(handle.$treeItemHandle);
|
||||
if (changed) {
|
||||
await treeView.refresh();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
registerAction2(class extends Action2 {
|
||||
constructor() {
|
||||
super({
|
||||
id: `workbench.actions.sync.turnOffSyncOnMachine`,
|
||||
title: localize('workbench.actions.sync.turnOffSyncOnMachine', "Turn off Preferences Sync"),
|
||||
menu: {
|
||||
id: MenuId.ViewItemContext,
|
||||
when: ContextKeyExpr.and(ContextKeyEqualsExpr.create('view', id), ContextKeyEqualsExpr.create('viewItem', 'sync-machine')),
|
||||
},
|
||||
});
|
||||
}
|
||||
async run(accessor: ServicesAccessor, handle: TreeViewItemHandleArg): Promise<void> {
|
||||
if (await dataProvider.disable(handle.$treeItemHandle)) {
|
||||
await treeView.refresh();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private registerDataViewActions(viewId: string) {
|
||||
@@ -244,7 +248,7 @@ export class UserDataSyncDataViews extends Disposable {
|
||||
constructor() {
|
||||
super({
|
||||
id: `workbench.actions.sync.replaceCurrent`,
|
||||
title: localize('workbench.actions.sync.replaceCurrent', "Download..."),
|
||||
title: localize('workbench.actions.sync.replaceCurrent', "Restore"),
|
||||
icon: { id: 'codicon/cloud-download' },
|
||||
menu: {
|
||||
id: MenuId.ViewItemContext,
|
||||
@@ -336,22 +340,29 @@ interface SyncResourceTreeItem extends ITreeItem {
|
||||
abstract class UserDataSyncHistoryViewDataProvider implements ITreeViewDataProvider {
|
||||
|
||||
constructor(
|
||||
protected readonly userDataSyncService: IUserDataSyncService,
|
||||
private readonly userDataSyncEnablementService: IUserDataSyncEnablementService,
|
||||
@IUserDataSyncService protected readonly userDataSyncService: IUserDataSyncService,
|
||||
@IUserDataAutoSyncService protected readonly userDataAutoSyncService: IUserDataAutoSyncService,
|
||||
@IUserDataSyncResourceEnablementService private readonly userDataSyncResourceEnablementService: IUserDataSyncResourceEnablementService,
|
||||
@INotificationService private readonly notificationService: INotificationService,
|
||||
) { }
|
||||
|
||||
async getChildren(element?: ITreeItem): Promise<ITreeItem[]> {
|
||||
if (!element) {
|
||||
return this.getRoots();
|
||||
try {
|
||||
if (!element) {
|
||||
return await this.getRoots();
|
||||
}
|
||||
const syncResource = ALL_SYNC_RESOURCES.filter(key => key === element.handle)[0] as SyncResource;
|
||||
if (syncResource) {
|
||||
return await this.getChildrenForSyncResource(syncResource);
|
||||
}
|
||||
if ((<SyncResourceTreeItem>element).resourceHandle) {
|
||||
return await this.getChildrenForSyncResourceTreeItem(<SyncResourceTreeItem>element);
|
||||
}
|
||||
return [];
|
||||
} catch (error) {
|
||||
this.notificationService.error(error);
|
||||
throw error;
|
||||
}
|
||||
const syncResource = ALL_SYNC_RESOURCES.filter(key => key === element.handle)[0] as SyncResource;
|
||||
if (syncResource) {
|
||||
return this.getChildrenForSyncResource(syncResource);
|
||||
}
|
||||
if ((<SyncResourceTreeItem>element).resourceHandle) {
|
||||
return this.getChildrenForSyncResourceTreeItem(<SyncResourceTreeItem>element);
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
protected async getRoots(): Promise<ITreeItem[]> {
|
||||
@@ -359,7 +370,7 @@ abstract class UserDataSyncHistoryViewDataProvider implements ITreeViewDataProvi
|
||||
handle: resourceKey,
|
||||
collapsibleState: TreeItemCollapsibleState.Collapsed,
|
||||
label: { label: getSyncAreaLabel(resourceKey) },
|
||||
description: !this.userDataSyncEnablementService.isEnabled() || this.userDataSyncEnablementService.isResourceEnabled(resourceKey) ? undefined : localize('not syncing', "Not syncing"),
|
||||
description: !this.userDataAutoSyncService.isEnabled() || this.userDataSyncResourceEnablementService.isResourceEnabled(resourceKey) ? undefined : localize('not syncing', "Not syncing"),
|
||||
themeIcon: FolderThemeIcon,
|
||||
contextValue: resourceKey
|
||||
}));
|
||||
@@ -367,19 +378,27 @@ abstract class UserDataSyncHistoryViewDataProvider implements ITreeViewDataProvi
|
||||
|
||||
protected async getChildrenForSyncResource(syncResource: SyncResource): Promise<ITreeItem[]> {
|
||||
const refHandles = await this.getSyncResourceHandles(syncResource);
|
||||
return refHandles.map(({ uri, created }) => {
|
||||
const handle = JSON.stringify({ resource: uri.toString(), syncResource });
|
||||
return <SyncResourceTreeItem>{
|
||||
handle,
|
||||
collapsibleState: TreeItemCollapsibleState.Collapsed,
|
||||
label: { label: label(new Date(created)) },
|
||||
description: fromNow(created, true),
|
||||
resourceUri: uri,
|
||||
resource: syncResource,
|
||||
resourceHandle: { uri, created },
|
||||
contextValue: `sync-resource-${syncResource}`
|
||||
};
|
||||
});
|
||||
if (refHandles.length) {
|
||||
return refHandles.map(({ uri, created }) => {
|
||||
const handle = JSON.stringify({ resource: uri.toString(), syncResource });
|
||||
return <SyncResourceTreeItem>{
|
||||
handle,
|
||||
collapsibleState: TreeItemCollapsibleState.Collapsed,
|
||||
label: { label: label(new Date(created)) },
|
||||
description: fromNow(created, true),
|
||||
resourceUri: uri,
|
||||
resource: syncResource,
|
||||
resourceHandle: { uri, created },
|
||||
contextValue: `sync-resource-${syncResource}`
|
||||
};
|
||||
});
|
||||
} else {
|
||||
return [{
|
||||
handle: generateUuid(),
|
||||
collapsibleState: TreeItemCollapsibleState.None,
|
||||
label: { label: localize('no data', "No Data") },
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
protected async getChildrenForSyncResourceTreeItem(element: SyncResourceTreeItem): Promise<ITreeItem[]> {
|
||||
@@ -411,11 +430,13 @@ class RemoteUserDataSyncHistoryViewDataProvider extends UserDataSyncHistoryViewD
|
||||
private machinesPromise: Promise<IUserDataSyncMachine[]> | undefined;
|
||||
|
||||
constructor(
|
||||
userDataSyncService: IUserDataSyncService,
|
||||
userDataSyncEnablementService: IUserDataSyncEnablementService,
|
||||
private readonly userDataSyncMachinesService: IUserDataSyncMachinesService,
|
||||
@IUserDataSyncService userDataSyncService: IUserDataSyncService,
|
||||
@IUserDataAutoSyncService userDataAutoSyncService: IUserDataAutoSyncService,
|
||||
@IUserDataSyncResourceEnablementService userDataSyncResourceEnablementService: IUserDataSyncResourceEnablementService,
|
||||
@IUserDataSyncMachinesService private readonly userDataSyncMachinesService: IUserDataSyncMachinesService,
|
||||
@INotificationService notificationService: INotificationService,
|
||||
) {
|
||||
super(userDataSyncService, userDataSyncEnablementService);
|
||||
super(userDataSyncService, userDataAutoSyncService, userDataSyncResourceEnablementService, notificationService);
|
||||
}
|
||||
|
||||
async getChildren(element?: ITreeItem): Promise<ITreeItem[]> {
|
||||
@@ -455,23 +476,110 @@ class RemoteUserDataSyncHistoryViewDataProvider extends UserDataSyncHistoryViewD
|
||||
|
||||
class UserDataSyncMachinesViewDataProvider implements ITreeViewDataProvider {
|
||||
|
||||
private machinesPromise: Promise<IUserDataSyncMachine[]> | undefined;
|
||||
|
||||
constructor(
|
||||
private readonly treeView: TreeView,
|
||||
private readonly userDataSyncMachinesService: IUserDataSyncMachinesService,
|
||||
) { }
|
||||
@IUserDataSyncMachinesService private readonly userDataSyncMachinesService: IUserDataSyncMachinesService,
|
||||
@IQuickInputService private readonly quickInputService: IQuickInputService,
|
||||
@INotificationService private readonly notificationService: INotificationService,
|
||||
@IDialogService private readonly dialogService: IDialogService,
|
||||
@IUserDataSyncWorkbenchService private readonly userDataSyncWorkbenchService: IUserDataSyncWorkbenchService,
|
||||
) {
|
||||
}
|
||||
|
||||
async getChildren(): Promise<ITreeItem[]> {
|
||||
let machines = await this.userDataSyncMachinesService.getMachines();
|
||||
machines = machines.filter(m => !m.disabled).sort((m1, m2) => m1.isCurrent ? -1 : 1);
|
||||
this.treeView.message = machines.length ? undefined : localize('no machines', "No Machines");
|
||||
return machines.map(({ id, name, isCurrent }) => ({
|
||||
handle: id,
|
||||
collapsibleState: TreeItemCollapsibleState.None,
|
||||
label: { label: name },
|
||||
description: isCurrent ? localize({ key: 'current', comment: ['Current machine'] }, "Current") : undefined,
|
||||
themeIcon: Codicon.vm,
|
||||
contextValue: 'sync-machine'
|
||||
}));
|
||||
async getChildren(element?: ITreeItem): Promise<ITreeItem[]> {
|
||||
if (!element) {
|
||||
this.machinesPromise = undefined;
|
||||
}
|
||||
try {
|
||||
let machines = await this.getMachines();
|
||||
machines = machines.filter(m => !m.disabled).sort((m1, m2) => m1.isCurrent ? -1 : 1);
|
||||
this.treeView.message = machines.length ? undefined : localize('no machines', "No Machines");
|
||||
return machines.map(({ id, name, isCurrent }) => ({
|
||||
handle: id,
|
||||
collapsibleState: TreeItemCollapsibleState.None,
|
||||
label: { label: name },
|
||||
description: isCurrent ? localize({ key: 'current', comment: ['Current machine'] }, "Current") : undefined,
|
||||
themeIcon: Codicon.vm,
|
||||
contextValue: 'sync-machine'
|
||||
}));
|
||||
} catch (error) {
|
||||
this.notificationService.error(error);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
private getMachines(): Promise<IUserDataSyncMachine[]> {
|
||||
if (this.machinesPromise === undefined) {
|
||||
this.machinesPromise = this.userDataSyncMachinesService.getMachines();
|
||||
}
|
||||
return this.machinesPromise;
|
||||
}
|
||||
|
||||
async disable(machineId: string): Promise<boolean> {
|
||||
const machines = await this.getMachines();
|
||||
const machine = machines.find(({ id }) => id === machineId);
|
||||
if (!machine) {
|
||||
throw new Error(localize('not found', "machine not found with id: {0}", machineId));
|
||||
}
|
||||
|
||||
const result = await this.dialogService.confirm({
|
||||
type: 'info',
|
||||
message: localize('turn off sync on machine', "Are you sure you want to turn off sync on {0}?", machine.name),
|
||||
primaryButton: localize('turn off', "Turn off"),
|
||||
});
|
||||
|
||||
if (!result.confirmed) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (machine.isCurrent) {
|
||||
await this.userDataSyncWorkbenchService.turnoff(false);
|
||||
} else {
|
||||
await this.userDataSyncMachinesService.setEnablement(machineId, false);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
async rename(machineId: string): Promise<boolean> {
|
||||
const disposableStore = new DisposableStore();
|
||||
const inputBox = disposableStore.add(this.quickInputService.createInputBox());
|
||||
inputBox.placeholder = localize('placeholder', "Enter the name of the machine");
|
||||
inputBox.busy = true;
|
||||
inputBox.show();
|
||||
const machines = await this.getMachines();
|
||||
const machine = machines.find(({ id }) => id === machineId);
|
||||
if (!machine) {
|
||||
inputBox.hide();
|
||||
disposableStore.dispose();
|
||||
throw new Error(localize('not found', "machine not found with id: {0}", machineId));
|
||||
}
|
||||
inputBox.busy = false;
|
||||
inputBox.value = machine.name;
|
||||
const validateMachineName = (machineName: string): string | null => {
|
||||
machineName = machineName.trim();
|
||||
return machineName && !machines.some(m => m.id !== machineId && m.name === machineName) ? machineName : null;
|
||||
};
|
||||
disposableStore.add(inputBox.onDidChangeValue(() =>
|
||||
inputBox.validationMessage = validateMachineName(inputBox.value) ? '' : localize('valid message', "Machine name should be unique and not empty")));
|
||||
return new Promise<boolean>((c, e) => {
|
||||
disposableStore.add(inputBox.onDidAccept(async () => {
|
||||
const machineName = validateMachineName(inputBox.value);
|
||||
disposableStore.dispose();
|
||||
if (machineName && machineName !== machine.name) {
|
||||
try {
|
||||
await this.userDataSyncMachinesService.renameMachine(machineId, machineName);
|
||||
c(true);
|
||||
} catch (error) {
|
||||
e(error);
|
||||
}
|
||||
} else {
|
||||
c(false);
|
||||
}
|
||||
}));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,31 +5,42 @@
|
||||
|
||||
import { IUserDataAutoSyncService, UserDataSyncError } from 'vs/platform/userDataSync/common/userDataSync';
|
||||
import { ISharedProcessService } from 'vs/platform/ipc/electron-browser/sharedProcessService';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { IChannel } from 'vs/base/parts/ipc/common/ipc';
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { UserDataSyncTrigger } from 'vs/workbench/contrib/userDataSync/browser/userDataSyncTrigger';
|
||||
import { UserDataAutoSyncEnablementService } from 'vs/platform/userDataSync/common/userDataAutoSyncService';
|
||||
import { IStorageService } from 'vs/platform/storage/common/storage';
|
||||
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
|
||||
|
||||
export class UserDataAutoSyncService extends Disposable implements IUserDataAutoSyncService {
|
||||
export class UserDataAutoSyncService extends UserDataAutoSyncEnablementService implements IUserDataAutoSyncService {
|
||||
|
||||
_serviceBrand: undefined;
|
||||
declare readonly _serviceBrand: undefined;
|
||||
|
||||
private readonly channel: IChannel;
|
||||
get onError(): Event<UserDataSyncError> { return Event.map(this.channel.listen<Error>('onError'), e => UserDataSyncError.toUserDataSyncError(e)); }
|
||||
|
||||
constructor(
|
||||
@IStorageService storageService: IStorageService,
|
||||
@IEnvironmentService environmentService: IEnvironmentService,
|
||||
@IInstantiationService instantiationService: IInstantiationService,
|
||||
@ISharedProcessService sharedProcessService: ISharedProcessService
|
||||
@ISharedProcessService sharedProcessService: ISharedProcessService,
|
||||
) {
|
||||
super();
|
||||
super(storageService, environmentService);
|
||||
this.channel = sharedProcessService.getChannel('userDataAutoSync');
|
||||
this._register(instantiationService.createInstance(UserDataSyncTrigger).onDidTriggerSync(source => this.triggerAutoSync([source])));
|
||||
this._register(instantiationService.createInstance(UserDataSyncTrigger).onDidTriggerSync(source => this.triggerSync([source], true)));
|
||||
}
|
||||
|
||||
triggerAutoSync(sources: string[]): Promise<void> {
|
||||
triggerSync(sources: string[], hasToLimitSync: boolean): Promise<void> {
|
||||
return this.channel.call('triggerSync', [sources, hasToLimitSync]);
|
||||
}
|
||||
|
||||
return this.channel.call('triggerAutoSync', [sources]);
|
||||
turnOn(pullFirst: boolean): Promise<void> {
|
||||
return this.channel.call('turnOn', [pullFirst]);
|
||||
}
|
||||
|
||||
turnOff(everywhere: boolean): Promise<void> {
|
||||
return this.channel.call('turnOff', [everywhere]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@ class UserDataSyncReportIssueContribution extends Disposable implements IWorkben
|
||||
private onAutoSyncError(error: UserDataSyncError): void {
|
||||
switch (error.code) {
|
||||
case UserDataSyncErrorCode.LocalTooManyRequests:
|
||||
case UserDataSyncErrorCode.TooManyRequests:
|
||||
this.notificationService.notify({
|
||||
severity: Severity.Error,
|
||||
message: localize('too many requests', "Turned off syncing preferences on this device because it is making too many requests. Please report an issue by providing the sync logs."),
|
||||
|
||||
Reference in New Issue
Block a user