|
|
|
|
@@ -30,11 +30,11 @@ import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
|
|
|
|
import {
|
|
|
|
|
IUserDataAutoSyncService, IUserDataSyncService, registerConfiguration,
|
|
|
|
|
SyncResource, SyncStatus, UserDataSyncError, UserDataSyncErrorCode, USER_DATA_SYNC_SCHEME, IUserDataSyncResourceEnablementService,
|
|
|
|
|
getSyncResourceFromLocalPreview, IResourcePreview, IUserDataSyncStoreManagementService, UserDataSyncStoreType
|
|
|
|
|
getSyncResourceFromLocalPreview, IResourcePreview, IUserDataSyncStoreManagementService, UserDataSyncStoreType, IUserDataSyncStore, IUserDataAutoSyncEnablementService
|
|
|
|
|
} from 'vs/platform/userDataSync/common/userDataSync';
|
|
|
|
|
import { FloatingClickWidget } from 'vs/workbench/browser/parts/editor/editorWidgets';
|
|
|
|
|
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
|
|
|
|
|
import { IEditorInput, toResource, SideBySideEditor } from 'vs/workbench/common/editor';
|
|
|
|
|
import { IEditorInput, EditorResourceAccessor, SideBySideEditor } from 'vs/workbench/common/editor';
|
|
|
|
|
import { DiffEditorInput } from 'vs/workbench/common/editor/diffEditorInput';
|
|
|
|
|
import * as Constants from 'vs/workbench/contrib/logs/common/logConstants';
|
|
|
|
|
import { IOutputService } from 'vs/workbench/contrib/output/common/output';
|
|
|
|
|
@@ -45,16 +45,14 @@ import { IPreferencesService } from 'vs/workbench/services/preferences/common/pr
|
|
|
|
|
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';
|
|
|
|
|
import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storage/common/storage';
|
|
|
|
|
import { IOpenerService } from 'vs/platform/opener/common/opener';
|
|
|
|
|
import { IAuthenticationService } from 'vs/workbench/services/authentication/browser/authenticationService';
|
|
|
|
|
import { Registry } from 'vs/platform/registry/common/platform';
|
|
|
|
|
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
|
|
|
|
|
import { Codicon } from 'vs/base/common/codicons';
|
|
|
|
|
import { ViewContainerLocation, IViewContainersRegistry, Extensions, ViewContainer } from 'vs/workbench/common/views';
|
|
|
|
|
import { UserDataSyncViewPaneContainer, UserDataSyncDataViews } from 'vs/workbench/contrib/userDataSync/browser/userDataSyncViews';
|
|
|
|
|
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 } from 'vs/workbench/services/userDataSync/common/userDataSync';
|
|
|
|
|
import { isNative } from 'vs/base/common/platform';
|
|
|
|
|
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_VIEW_ICON } from 'vs/workbench/services/userDataSync/common/userDataSync';
|
|
|
|
|
|
|
|
|
|
const CONTEXT_CONFLICTS_SOURCES = new RawContextKey<string>('conflictsSources', '');
|
|
|
|
|
|
|
|
|
|
@@ -105,12 +103,13 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
|
|
|
|
@IActivityService private readonly activityService: IActivityService,
|
|
|
|
|
@INotificationService private readonly notificationService: INotificationService,
|
|
|
|
|
@IEditorService private readonly editorService: IEditorService,
|
|
|
|
|
@IWorkbenchEnvironmentService private readonly workbenchEnvironmentService: IWorkbenchEnvironmentService,
|
|
|
|
|
@IWorkbenchEnvironmentService private readonly environmentService: IWorkbenchEnvironmentService,
|
|
|
|
|
@IDialogService private readonly dialogService: IDialogService,
|
|
|
|
|
@IQuickInputService private readonly quickInputService: IQuickInputService,
|
|
|
|
|
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
|
|
|
|
@IOutputService private readonly outputService: IOutputService,
|
|
|
|
|
@IUserDataSyncAccountService readonly authTokenService: IUserDataSyncAccountService,
|
|
|
|
|
@IUserDataAutoSyncEnablementService private readonly userDataAutoSyncEnablementService: IUserDataAutoSyncEnablementService,
|
|
|
|
|
@IUserDataAutoSyncService private readonly userDataAutoSyncService: IUserDataAutoSyncService,
|
|
|
|
|
@ITextModelService textModelResolverService: ITextModelService,
|
|
|
|
|
@IPreferencesService private readonly preferencesService: IPreferencesService,
|
|
|
|
|
@@ -136,14 +135,14 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
|
|
|
|
|
|
|
|
|
this._register(Event.any(
|
|
|
|
|
Event.debounce(userDataSyncService.onDidChangeStatus, () => undefined, 500),
|
|
|
|
|
this.userDataAutoSyncService.onDidChangeEnablement,
|
|
|
|
|
this.userDataAutoSyncEnablementService.onDidChangeEnablement,
|
|
|
|
|
this.userDataSyncWorkbenchService.onDidChangeAccountStatus
|
|
|
|
|
)(() => {
|
|
|
|
|
this.updateAccountBadge();
|
|
|
|
|
this.updateGlobalActivityBadge();
|
|
|
|
|
}));
|
|
|
|
|
this._register(userDataSyncService.onDidChangeConflicts(() => this.onDidChangeConflicts(this.userDataSyncService.conflicts)));
|
|
|
|
|
this._register(userDataAutoSyncService.onDidChangeEnablement(() => this.onDidChangeConflicts(this.userDataSyncService.conflicts)));
|
|
|
|
|
this._register(userDataAutoSyncEnablementService.onDidChangeEnablement(() => this.onDidChangeConflicts(this.userDataSyncService.conflicts)));
|
|
|
|
|
this._register(userDataSyncService.onSyncErrors(errors => this.onSynchronizerErrors(errors)));
|
|
|
|
|
this._register(userDataAutoSyncService.onError(error => this.onAutoSyncError(error)));
|
|
|
|
|
|
|
|
|
|
@@ -153,7 +152,7 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
|
|
|
|
textModelResolverService.registerTextModelContentProvider(USER_DATA_SYNC_SCHEME, instantiationService.createInstance(UserDataRemoteContentProvider));
|
|
|
|
|
registerEditorContribution(AcceptChangesContribution.ID, AcceptChangesContribution);
|
|
|
|
|
|
|
|
|
|
this._register(Event.any(userDataSyncService.onDidChangeStatus, userDataAutoSyncService.onDidChangeEnablement)(() => this.turningOnSync = !userDataAutoSyncService.isEnabled() && userDataSyncService.status !== SyncStatus.Idle));
|
|
|
|
|
this._register(Event.any(userDataSyncService.onDidChangeStatus, userDataAutoSyncEnablementService.onDidChangeEnablement)(() => this.turningOnSync = !userDataAutoSyncEnablementService.isEnabled() && userDataSyncService.status !== SyncStatus.Idle));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -168,7 +167,7 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
|
|
|
|
|
|
|
|
|
private readonly conflictsDisposables = new Map<SyncResource, IDisposable>();
|
|
|
|
|
private onDidChangeConflicts(conflicts: [SyncResource, IResourcePreview[]][]) {
|
|
|
|
|
if (!this.userDataAutoSyncService.isEnabled()) {
|
|
|
|
|
if (!this.userDataAutoSyncEnablementService.isEnabled()) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
this.updateGlobalActivityBadge();
|
|
|
|
|
@@ -256,7 +255,7 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
|
|
|
|
private async acceptRemote(syncResource: SyncResource, conflicts: IResourcePreview[]) {
|
|
|
|
|
try {
|
|
|
|
|
for (const conflict of conflicts) {
|
|
|
|
|
await this.userDataSyncService.accept(syncResource, conflict.remoteResource, undefined, this.userDataAutoSyncService.isEnabled());
|
|
|
|
|
await this.userDataSyncService.accept(syncResource, conflict.remoteResource, undefined, this.userDataAutoSyncEnablementService.isEnabled());
|
|
|
|
|
}
|
|
|
|
|
} catch (e) {
|
|
|
|
|
this.notificationService.error(e);
|
|
|
|
|
@@ -266,7 +265,7 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
|
|
|
|
private async acceptLocal(syncResource: SyncResource, conflicts: IResourcePreview[]): Promise<void> {
|
|
|
|
|
try {
|
|
|
|
|
for (const conflict of conflicts) {
|
|
|
|
|
await this.userDataSyncService.accept(syncResource, conflict.localResource, undefined, this.userDataAutoSyncService.isEnabled());
|
|
|
|
|
await this.userDataSyncService.accept(syncResource, conflict.localResource, undefined, this.userDataAutoSyncEnablementService.isEnabled());
|
|
|
|
|
}
|
|
|
|
|
} catch (e) {
|
|
|
|
|
this.notificationService.error(e);
|
|
|
|
|
@@ -374,8 +373,8 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
|
|
|
|
if (source !== SyncResource.Settings && source !== SyncResource.Keybindings) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
const resource = source === SyncResource.Settings ? this.workbenchEnvironmentService.settingsResource : this.workbenchEnvironmentService.keybindingsResource;
|
|
|
|
|
if (isEqual(resource, toResource(this.editorService.activeEditor, { supportSideBySide: SideBySideEditor.PRIMARY }))) {
|
|
|
|
|
const resource = source === SyncResource.Settings ? this.environmentService.settingsResource : this.environmentService.keybindingsResource;
|
|
|
|
|
if (isEqual(resource, EditorResourceAccessor.getCanonicalUri(this.editorService.activeEditor, { supportSideBySide: SideBySideEditor.PRIMARY }))) {
|
|
|
|
|
// Do not show notification if the file in error is active
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
@@ -402,7 +401,7 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
|
|
|
|
let clazz: string | undefined;
|
|
|
|
|
let priority: number | undefined = undefined;
|
|
|
|
|
|
|
|
|
|
if (this.userDataSyncService.conflicts.length && this.userDataAutoSyncService.isEnabled()) {
|
|
|
|
|
if (this.userDataSyncService.conflicts.length && this.userDataAutoSyncEnablementService.isEnabled()) {
|
|
|
|
|
badge = new NumberBadge(this.userDataSyncService.conflicts.reduce((result, [, conflicts]) => { return result + conflicts.length; }, 0), () => localize('has conflicts', "{0}: Conflicts Detected", SYNC_TITLE));
|
|
|
|
|
} else if (this.turningOnSync) {
|
|
|
|
|
badge = new ProgressBadge(() => localize('turning on syncing', "Turning on Settings Sync..."));
|
|
|
|
|
@@ -420,7 +419,7 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
|
|
|
|
|
|
|
|
|
let badge: IBadge | undefined = undefined;
|
|
|
|
|
|
|
|
|
|
if (this.userDataSyncService.status !== SyncStatus.Uninitialized && this.userDataAutoSyncService.isEnabled() && this.userDataSyncWorkbenchService.accountStatus === AccountStatus.Unavailable) {
|
|
|
|
|
if (this.userDataSyncService.status !== SyncStatus.Uninitialized && this.userDataAutoSyncEnablementService.isEnabled() && this.userDataSyncWorkbenchService.accountStatus === AccountStatus.Unavailable) {
|
|
|
|
|
badge = new NumberBadge(1, () => localize('sign in to sync', "Sign in to Sync Settings"));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -443,8 +442,11 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
|
|
|
|
if (!turnOn) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (this.userDataSyncStoreManagementService.userDataSyncStore?.canSwitch) {
|
|
|
|
|
await this.selectSettingsSyncService(this.userDataSyncStoreManagementService.userDataSyncStore);
|
|
|
|
|
}
|
|
|
|
|
await this.userDataSyncWorkbenchService.turnOn();
|
|
|
|
|
this.storageService.store('sync.donotAskPreviewConfirmation', true, StorageScope.GLOBAL);
|
|
|
|
|
this.storageService.store('sync.donotAskPreviewConfirmation', true, StorageScope.GLOBAL, StorageTarget.MACHINE);
|
|
|
|
|
} catch (e) {
|
|
|
|
|
if (isPromiseCanceledError(e)) {
|
|
|
|
|
return;
|
|
|
|
|
@@ -479,9 +481,12 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
return;
|
|
|
|
|
case UserDataSyncErrorCode.Unauthorized:
|
|
|
|
|
this.notificationService.error(localize('auth failed', "Error while turning on Settings Sync: Authentication failed."));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
this.notificationService.error(localize('turn on failed', "Error while starting Settings Sync: {0}", toErrorMessage(e)));
|
|
|
|
|
this.notificationService.error(localize('turn on failed', "Error while turning on Settings Sync. Please check [logs]({0}) for more details.", `command:${SHOW_SYNC_LOG_COMMAND_ID}`));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -513,19 +518,13 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
|
|
|
|
quickPick.title = SYNC_TITLE;
|
|
|
|
|
quickPick.ok = false;
|
|
|
|
|
quickPick.customButton = true;
|
|
|
|
|
if (this.userDataSyncWorkbenchService.all.length) {
|
|
|
|
|
quickPick.customLabel = localize('turn on', "Turn On");
|
|
|
|
|
} else {
|
|
|
|
|
const orTerm = localize({ key: 'or', comment: ['Here is the context where it is used - Sign in with your A or B or C account to synchronize your data across devices.'] }, "or");
|
|
|
|
|
const displayName = this.userDataSyncWorkbenchService.authenticationProviders.length === 1
|
|
|
|
|
? this.authenticationService.getLabel(this.userDataSyncWorkbenchService.authenticationProviders[0].id)
|
|
|
|
|
: this.userDataSyncWorkbenchService.authenticationProviders.map(({ id }) => this.authenticationService.getLabel(id)).join(` ${orTerm} `);
|
|
|
|
|
quickPick.description = localize('sign in and turn on sync detail', "Sign in with your {0} account to synchronize your data across devices.", displayName);
|
|
|
|
|
quickPick.customLabel = localize('sign in and turn on sync', "Sign in & Turn on");
|
|
|
|
|
}
|
|
|
|
|
quickPick.placeholder = localize('configure sync placeholder', "Choose what to sync");
|
|
|
|
|
quickPick.customLabel = localize('sign in and turn on', "Sign in & Turn on");
|
|
|
|
|
quickPick.description = localize('configure and turn on sync detail', "Please sign in to synchronize your data across devices.");
|
|
|
|
|
quickPick.canSelectMany = true;
|
|
|
|
|
quickPick.ignoreFocusOut = true;
|
|
|
|
|
quickPick.hideInput = true;
|
|
|
|
|
quickPick.hideCheckAll = true;
|
|
|
|
|
|
|
|
|
|
const items = this.getConfigureSyncQuickPickItems();
|
|
|
|
|
quickPick.items = items;
|
|
|
|
|
quickPick.selectedItems = items.filter(item => this.userDataSyncResourceEnablementService.isResourceEnabled(item.id));
|
|
|
|
|
@@ -612,7 +611,7 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
|
|
|
|
type: 'info',
|
|
|
|
|
message: localize('turn off sync confirmation', "Do you want to turn off sync?"),
|
|
|
|
|
detail: localize('turn off sync detail', "Your settings, keybindings, extensions, snippets and UI State will no longer be synced."),
|
|
|
|
|
primaryButton: localize('turn off', "Turn Off"),
|
|
|
|
|
primaryButton: localize({ key: 'turn off', comment: ['&& denotes a mnemonic'] }, "&&Turn off"),
|
|
|
|
|
checkbox: this.userDataSyncWorkbenchService.accountStatus === AccountStatus.Available ? {
|
|
|
|
|
label: localize('turn off sync everywhere', "Turn off sync on all your devices and clear the data from the cloud.")
|
|
|
|
|
} : undefined
|
|
|
|
|
@@ -635,14 +634,14 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
|
|
|
|
private getConflictsEditorInputs(syncResource: SyncResource): DiffEditorInput[] {
|
|
|
|
|
return this.editorService.editors.filter(input => {
|
|
|
|
|
const resource = input instanceof DiffEditorInput ? input.primary.resource : input.resource;
|
|
|
|
|
return resource && getSyncResourceFromLocalPreview(resource!, this.workbenchEnvironmentService) === syncResource;
|
|
|
|
|
return resource && getSyncResourceFromLocalPreview(resource!, this.environmentService) === syncResource;
|
|
|
|
|
}) as DiffEditorInput[];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private getAllConflictsEditorInputs(): IEditorInput[] {
|
|
|
|
|
return this.editorService.editors.filter(input => {
|
|
|
|
|
const resource = input instanceof DiffEditorInput ? input.primary.resource : input.resource;
|
|
|
|
|
return resource && getSyncResourceFromLocalPreview(resource!, this.workbenchEnvironmentService) !== undefined;
|
|
|
|
|
return resource && getSyncResourceFromLocalPreview(resource!, this.environmentService) !== undefined;
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -661,6 +660,7 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
|
|
|
|
leftResource: conflict.remoteResource,
|
|
|
|
|
rightResource: conflict.previewResource,
|
|
|
|
|
label: localize('sideBySideLabels', "{0} ↔ {1}", leftResourceName, rightResourceName),
|
|
|
|
|
description: localize('sideBySideDescription', "Settings Sync"),
|
|
|
|
|
options: {
|
|
|
|
|
preserveFocus: false,
|
|
|
|
|
pinned: true,
|
|
|
|
|
@@ -674,56 +674,50 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
|
|
|
|
return this.outputService.showChannel(Constants.userDataSyncLogChannelId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private async switchSyncService(): Promise<void> {
|
|
|
|
|
const userDataSyncStore = this.userDataSyncStoreManagementService.userDataSyncStore;
|
|
|
|
|
if (userDataSyncStore?.insidersUrl && userDataSyncStore?.stableUrl && ![userDataSyncStore.insidersUrl, userDataSyncStore.stableUrl].includes(userDataSyncStore.url)) {
|
|
|
|
|
return new Promise<void>((c, e) => {
|
|
|
|
|
const disposables: DisposableStore = new DisposableStore();
|
|
|
|
|
const quickPick = disposables.add(this.quickInputService.createQuickPick<{ id: UserDataSyncStoreType, label: string, description?: string }>());
|
|
|
|
|
quickPick.title = localize('switchSyncService.title', "Select Settings Sync Service...");
|
|
|
|
|
quickPick.placeholder = localize('choose sync service', "Choose settings sync Service to use");
|
|
|
|
|
quickPick.description = isNative ?
|
|
|
|
|
localize('choose sync service description', "Switching settings sync service requires restarting {0}", this.productService.nameLong) :
|
|
|
|
|
localize('choose sync service description web', "Switching settings sync service requires reloading {0}", this.productService.nameLong);
|
|
|
|
|
quickPick.hideInput = true;
|
|
|
|
|
const getDescription = (url: URI): string | undefined => {
|
|
|
|
|
const isCurrent = isEqual(url, userDataSyncStore.url);
|
|
|
|
|
const isDefault = isEqual(url, userDataSyncStore.defaultUrl);
|
|
|
|
|
if (isCurrent && isDefault) {
|
|
|
|
|
return localize('default and current', "Default & Current");
|
|
|
|
|
}
|
|
|
|
|
if (isDefault) {
|
|
|
|
|
return localize('default', "Default");
|
|
|
|
|
}
|
|
|
|
|
if (isCurrent) {
|
|
|
|
|
return localize('current', "Current");
|
|
|
|
|
}
|
|
|
|
|
return undefined;
|
|
|
|
|
};
|
|
|
|
|
quickPick.items = [
|
|
|
|
|
{
|
|
|
|
|
id: 'insiders',
|
|
|
|
|
label: localize('insiders', "Insiders"),
|
|
|
|
|
description: getDescription(userDataSyncStore.insidersUrl!)
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: 'stable',
|
|
|
|
|
label: localize('stable', "Stable"),
|
|
|
|
|
description: getDescription(userDataSyncStore.stableUrl!)
|
|
|
|
|
}
|
|
|
|
|
];
|
|
|
|
|
disposables.add(quickPick.onDidAccept(() => {
|
|
|
|
|
this.userDataSyncWorkbenchService.switchSyncService(quickPick.selectedItems[0].id);
|
|
|
|
|
private async selectSettingsSyncService(userDataSyncStore: IUserDataSyncStore): Promise<void> {
|
|
|
|
|
return new Promise<void>((c, e) => {
|
|
|
|
|
const disposables: DisposableStore = new DisposableStore();
|
|
|
|
|
const quickPick = disposables.add(this.quickInputService.createQuickPick<{ id: UserDataSyncStoreType, label: string, description?: string }>());
|
|
|
|
|
quickPick.title = localize('switchSyncService.title', "{0}: Select Service", SYNC_TITLE);
|
|
|
|
|
quickPick.description = localize('switchSyncService.description', "Ensure you are using the same settings sync service when syncing with multiple environments");
|
|
|
|
|
quickPick.hideInput = true;
|
|
|
|
|
quickPick.ignoreFocusOut = true;
|
|
|
|
|
const getDescription = (url: URI): string | undefined => {
|
|
|
|
|
const isDefault = isEqual(url, userDataSyncStore.defaultUrl);
|
|
|
|
|
if (isDefault) {
|
|
|
|
|
return localize('default', "Default");
|
|
|
|
|
}
|
|
|
|
|
return undefined;
|
|
|
|
|
};
|
|
|
|
|
quickPick.items = [
|
|
|
|
|
{
|
|
|
|
|
id: 'insiders',
|
|
|
|
|
label: localize('insiders', "Insiders"),
|
|
|
|
|
description: getDescription(userDataSyncStore.insidersUrl)
|
|
|
|
|
},
|
|
|
|
|
{
|
|
|
|
|
id: 'stable',
|
|
|
|
|
label: localize('stable', "Stable"),
|
|
|
|
|
description: getDescription(userDataSyncStore.stableUrl)
|
|
|
|
|
}
|
|
|
|
|
];
|
|
|
|
|
disposables.add(quickPick.onDidAccept(async () => {
|
|
|
|
|
try {
|
|
|
|
|
await this.userDataSyncStoreManagementService.switch(quickPick.selectedItems[0].id);
|
|
|
|
|
c();
|
|
|
|
|
} catch (error) {
|
|
|
|
|
e(error);
|
|
|
|
|
} finally {
|
|
|
|
|
quickPick.hide();
|
|
|
|
|
}));
|
|
|
|
|
disposables.add(quickPick.onDidHide(() => disposables.dispose()));
|
|
|
|
|
quickPick.show();
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}));
|
|
|
|
|
disposables.add(quickPick.onDidHide(() => disposables.dispose()));
|
|
|
|
|
quickPick.show();
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private registerActions(): void {
|
|
|
|
|
if (this.userDataAutoSyncService.canToggleEnablement()) {
|
|
|
|
|
if (this.userDataAutoSyncEnablementService.canToggleEnablement()) {
|
|
|
|
|
this.registerTurnOnSyncAction();
|
|
|
|
|
this.registerTurnOffSyncAction();
|
|
|
|
|
}
|
|
|
|
|
@@ -738,7 +732,6 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
|
|
|
|
this.registerSyncNowAction();
|
|
|
|
|
this.registerConfigureSyncAction();
|
|
|
|
|
this.registerShowSettingsAction();
|
|
|
|
|
this.registerSwitchSyncServiceAction();
|
|
|
|
|
this.registerShowLogAction();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -977,7 +970,7 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
|
|
|
|
items.push({ id: showSyncedDataCommand.id, label: showSyncedDataCommand.title });
|
|
|
|
|
items.push({ type: 'separator' });
|
|
|
|
|
items.push({ id: syncNowCommand.id, label: syncNowCommand.title, description: syncNowCommand.description(that.userDataSyncService) });
|
|
|
|
|
if (that.userDataAutoSyncService.canToggleEnablement()) {
|
|
|
|
|
if (that.userDataAutoSyncEnablementService.canToggleEnablement()) {
|
|
|
|
|
const account = that.userDataSyncWorkbenchService.current;
|
|
|
|
|
items.push({ id: turnOffSyncCommand.id, label: turnOffSyncCommand.title, description: account ? `${account.accountName} (${that.authenticationService.getLabel(account.authenticationProviderId)})` : undefined });
|
|
|
|
|
}
|
|
|
|
|
@@ -1117,28 +1110,6 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
|
|
|
|
}));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private registerSwitchSyncServiceAction(): void {
|
|
|
|
|
const that = this;
|
|
|
|
|
const userDataSyncStore = this.userDataSyncStoreManagementService.userDataSyncStore;
|
|
|
|
|
if (userDataSyncStore?.insidersUrl && userDataSyncStore?.stableUrl && ![userDataSyncStore.insidersUrl, userDataSyncStore.stableUrl].includes(userDataSyncStore.url)) {
|
|
|
|
|
this._register(registerAction2(class ShowSyncSettingsAction extends Action2 {
|
|
|
|
|
constructor() {
|
|
|
|
|
super({
|
|
|
|
|
id: 'workbench.userDataSync.actions.switchSyncService',
|
|
|
|
|
title: { value: localize('workbench.userDataSync.actions.switchSyncService', "{0}: Select Service...", SYNC_TITLE), original: 'Settings Sync: Select Service...' },
|
|
|
|
|
menu: {
|
|
|
|
|
id: MenuId.CommandPalette,
|
|
|
|
|
when: ContextKeyExpr.and(CONTEXT_SYNC_STATE.notEqualsTo(SyncStatus.Uninitialized)),
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
run(accessor: ServicesAccessor): any {
|
|
|
|
|
return that.switchSyncService();
|
|
|
|
|
}
|
|
|
|
|
}));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private registerViews(): void {
|
|
|
|
|
const container = this.registerViewContainer();
|
|
|
|
|
this.registerDataViews(container);
|
|
|
|
|
@@ -1153,7 +1124,7 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
|
|
|
|
UserDataSyncViewPaneContainer,
|
|
|
|
|
[SYNC_VIEW_CONTAINER_ID]
|
|
|
|
|
),
|
|
|
|
|
icon: Codicon.sync.classNames,
|
|
|
|
|
icon: SYNC_VIEW_ICON,
|
|
|
|
|
hideIfEmpty: true,
|
|
|
|
|
}, ViewContainerLocation.Sidebar);
|
|
|
|
|
}
|
|
|
|
|
@@ -1199,7 +1170,7 @@ class AcceptChangesContribution extends Disposable implements IEditorContributio
|
|
|
|
|
@IDialogService private readonly dialogService: IDialogService,
|
|
|
|
|
@IConfigurationService private readonly configurationService: IConfigurationService,
|
|
|
|
|
@ITelemetryService private readonly telemetryService: ITelemetryService,
|
|
|
|
|
@IUserDataAutoSyncService private readonly userDataAutoSyncService: IUserDataAutoSyncService,
|
|
|
|
|
@IUserDataAutoSyncEnablementService private readonly userDataAutoSyncEnablementService: IUserDataAutoSyncEnablementService,
|
|
|
|
|
) {
|
|
|
|
|
super();
|
|
|
|
|
|
|
|
|
|
@@ -1228,7 +1199,7 @@ class AcceptChangesContribution extends Disposable implements IEditorContributio
|
|
|
|
|
return false; // we need a model
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!this.userDataAutoSyncService.isEnabled()) {
|
|
|
|
|
if (!this.userDataAutoSyncEnablementService.isEnabled()) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -1255,6 +1226,8 @@ class AcceptChangesContribution extends Disposable implements IEditorContributio
|
|
|
|
|
const isRemote = conflicts.some(({ remoteResource }) => isEqual(remoteResource, resource));
|
|
|
|
|
const acceptRemoteLabel = localize('accept remote', "Accept Remote");
|
|
|
|
|
const acceptMergesLabel = localize('accept merges', "Accept Merges");
|
|
|
|
|
const acceptRemoteButtonLabel = localize('accept remote button', "Accept &&Remote");
|
|
|
|
|
const acceptMergesButtonLabel = localize('accept merges button', "Accept &&Merges");
|
|
|
|
|
this.acceptChangesButton = this.instantiationService.createInstance(FloatingClickWidget, this.editor, isRemote ? acceptRemoteLabel : acceptMergesLabel, null);
|
|
|
|
|
this._register(this.acceptChangesButton.onClick(async () => {
|
|
|
|
|
const model = this.editor.getModel();
|
|
|
|
|
@@ -1269,7 +1242,7 @@ class AcceptChangesContribution extends Disposable implements IEditorContributio
|
|
|
|
|
message: isRemote
|
|
|
|
|
? localize('confirm replace and overwrite local', "Would you like to accept remote {0} and replace local {1}?", syncAreaLabel.toLowerCase(), syncAreaLabel.toLowerCase())
|
|
|
|
|
: localize('confirm replace and overwrite remote', "Would you like to accept merges and replace remote {0}?", syncAreaLabel.toLowerCase()),
|
|
|
|
|
primaryButton: isRemote ? acceptRemoteLabel : acceptMergesLabel
|
|
|
|
|
primaryButton: isRemote ? acceptRemoteButtonLabel : acceptMergesButtonLabel
|
|
|
|
|
});
|
|
|
|
|
if (result.confirmed) {
|
|
|
|
|
try {
|
|
|
|
|
|