mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-10 18:22:34 -05:00
Merge from vscode a234f13c45b40a0929777cb440ee011b7549eed2 (#8911)
* Merge from vscode a234f13c45b40a0929777cb440ee011b7549eed2 * update distro * fix layering * update distro * fix tests
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
|
||||
import { IUserDataSyncService, SyncStatus, SyncSource, CONTEXT_SYNC_STATE, IUserDataSyncStore, registerConfiguration, getUserDataSyncStore } from 'vs/platform/userDataSync/common/userDataSync';
|
||||
import { IUserDataSyncService, SyncStatus, SyncSource, CONTEXT_SYNC_STATE, IUserDataSyncStore, registerConfiguration, getUserDataSyncStore, ISyncConfiguration, IUserDataAuthTokenService, IUserDataAutoSyncService } from 'vs/platform/userDataSync/common/userDataSync';
|
||||
import { localize } from 'vs/nls';
|
||||
import { Disposable, MutableDisposable, toDisposable, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
|
||||
@@ -24,34 +24,46 @@ import { IHistoryService } from 'vs/workbench/services/history/common/history';
|
||||
import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService';
|
||||
import { isEqual } from 'vs/base/common/resources';
|
||||
import { IEditorInput } from 'vs/workbench/common/editor';
|
||||
import { IAuthTokenService, AuthTokenStatus } from 'vs/platform/auth/common/auth';
|
||||
import { IDialogService } from 'vs/platform/dialogs/common/dialogs';
|
||||
import { FalseContext } from 'vs/platform/contextkey/common/contextkeys';
|
||||
import { IQuickInputService } from 'vs/platform/quickinput/common/quickInput';
|
||||
import { isWeb } from 'vs/base/common/platform';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { UserDataAutoSync } from 'vs/workbench/contrib/userDataSync/browser/userDataAutoSync';
|
||||
import { UserDataSyncTrigger } from 'vs/workbench/contrib/userDataSync/browser/userDataSyncTrigger';
|
||||
import { timeout } from 'vs/base/common/async';
|
||||
import { IOutputService } from 'vs/workbench/contrib/output/common/output';
|
||||
import * as Constants from 'vs/workbench/contrib/logs/common/logConstants';
|
||||
import { IAuthenticationService } from 'vs/workbench/services/authentication/browser/authenticationService';
|
||||
import { Session } from 'vs/editor/common/modes';
|
||||
import { isPromiseCanceledError, canceled } from 'vs/base/common/errors';
|
||||
import { toErrorMessage } from 'vs/base/common/errorMessage';
|
||||
|
||||
const CONTEXT_AUTH_TOKEN_STATE = new RawContextKey<string>('authTokenStatus', AuthTokenStatus.Initializing);
|
||||
const enum AuthStatus {
|
||||
Initializing = 'Initializing',
|
||||
SignedIn = 'SignedIn',
|
||||
SignedOut = 'SignedOut'
|
||||
}
|
||||
const CONTEXT_AUTH_TOKEN_STATE = new RawContextKey<string>('authTokenStatus', AuthStatus.Initializing);
|
||||
const SYNC_PUSH_LIGHT_ICON_URI = URI.parse(registerAndGetAmdImageURL(`vs/workbench/contrib/userDataSync/browser/media/check-light.svg`));
|
||||
const SYNC_PUSH_DARK_ICON_URI = URI.parse(registerAndGetAmdImageURL(`vs/workbench/contrib/userDataSync/browser/media/check-dark.svg`));
|
||||
|
||||
type ConfigureSyncQuickPickItem = { id: string, label: string, description?: string };
|
||||
|
||||
export class UserDataSyncWorkbenchContribution extends Disposable implements IWorkbenchContribution {
|
||||
|
||||
private static readonly ENABLEMENT_SETTING = 'sync.enable';
|
||||
|
||||
private readonly userDataSyncStore: IUserDataSyncStore | undefined;
|
||||
private readonly syncStatusContext: IContextKey<string>;
|
||||
private readonly authTokenContext: IContextKey<string>;
|
||||
private readonly authenticationState: IContextKey<string>;
|
||||
private readonly badgeDisposable = this._register(new MutableDisposable());
|
||||
private readonly conflictsWarningDisposable = this._register(new MutableDisposable());
|
||||
private readonly signInNotificationDisposable = this._register(new MutableDisposable());
|
||||
private _activeAccount: Session | undefined;
|
||||
|
||||
constructor(
|
||||
@IUserDataSyncService private readonly userDataSyncService: IUserDataSyncService,
|
||||
@IAuthTokenService private readonly authTokenService: IAuthTokenService,
|
||||
@IAuthenticationService private readonly authenticationService: IAuthenticationService,
|
||||
@IContextKeyService contextKeyService: IContextKeyService,
|
||||
@IActivityService private readonly activityService: IActivityService,
|
||||
@INotificationService private readonly notificationService: INotificationService,
|
||||
@@ -63,43 +75,104 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
||||
@IDialogService private readonly dialogService: IDialogService,
|
||||
@IQuickInputService private readonly quickInputService: IQuickInputService,
|
||||
@IInstantiationService instantiationService: IInstantiationService,
|
||||
@IOutputService private readonly outputService: IOutputService,
|
||||
@IUserDataAuthTokenService private readonly userDataAuthTokenService: IUserDataAuthTokenService,
|
||||
@IUserDataAutoSyncService userDataAutoSyncService: IUserDataAutoSyncService,
|
||||
) {
|
||||
super();
|
||||
this.userDataSyncStore = getUserDataSyncStore(configurationService);
|
||||
this.syncStatusContext = CONTEXT_SYNC_STATE.bindTo(contextKeyService);
|
||||
this.authTokenContext = CONTEXT_AUTH_TOKEN_STATE.bindTo(contextKeyService);
|
||||
|
||||
this.authenticationState = CONTEXT_AUTH_TOKEN_STATE.bindTo(contextKeyService);
|
||||
if (this.userDataSyncStore) {
|
||||
registerConfiguration();
|
||||
this.onDidChangeAuthTokenStatus(this.authTokenService.status);
|
||||
this.onDidChangeSyncStatus(this.userDataSyncService.status);
|
||||
this._register(Event.debounce(authTokenService.onDidChangeStatus, () => undefined, 500)(() => this.onDidChangeAuthTokenStatus(this.authTokenService.status)));
|
||||
this._register(Event.debounce(userDataSyncService.onDidChangeStatus, () => undefined, 500)(() => this.onDidChangeSyncStatus(this.userDataSyncService.status)));
|
||||
this._register(Event.filter(this.configurationService.onDidChangeConfiguration, e => e.affectsConfiguration(UserDataSyncWorkbenchContribution.ENABLEMENT_SETTING))(() => this.onDidChangeEnablement()));
|
||||
this._register(this.authenticationService.onDidRegisterAuthenticationProvider(e => this.onDidRegisterAuthenticationProvider(e)));
|
||||
this._register(this.authenticationService.onDidUnregisterAuthenticationProvider(e => this.onDidUnregisterAuthenticationProvider(e)));
|
||||
this._register(this.authenticationService.onDidChangeSessions(e => this.onDidChangeSessions(e)));
|
||||
this.registerActions();
|
||||
this.initializeActiveAccount().then(_ => {
|
||||
if (isWeb) {
|
||||
this._register(instantiationService.createInstance(UserDataAutoSync));
|
||||
} else {
|
||||
this._register(instantiationService.createInstance(UserDataSyncTrigger).onDidTriggerSync(() => userDataAutoSyncService.triggerAutoSync()));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (isWeb) {
|
||||
this._register(instantiationService.createInstance(UserDataAutoSync));
|
||||
private async initializeActiveAccount(): Promise<void> {
|
||||
const accounts = await this.authenticationService.getSessions(this.userDataSyncStore!.authenticationProviderId);
|
||||
// Auth provider has not yet been registered
|
||||
if (!accounts) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (accounts.length === 0) {
|
||||
this.activeAccount = undefined;
|
||||
return;
|
||||
}
|
||||
|
||||
if (accounts.length === 1) {
|
||||
this.activeAccount = accounts[0];
|
||||
return;
|
||||
}
|
||||
|
||||
const selectedAccount = await this.quickInputService.pick(accounts.map(account => {
|
||||
return {
|
||||
id: account.id,
|
||||
label: account.displayName
|
||||
};
|
||||
}), { canPickMany: false });
|
||||
|
||||
if (selectedAccount) {
|
||||
this.activeAccount = accounts.filter(account => selectedAccount.id === account.id)[0];
|
||||
}
|
||||
}
|
||||
|
||||
get activeAccount(): Session | undefined {
|
||||
return this._activeAccount;
|
||||
}
|
||||
|
||||
set activeAccount(account: Session | undefined) {
|
||||
this._activeAccount = account;
|
||||
|
||||
if (account) {
|
||||
this.userDataAuthTokenService.setToken(account.accessToken);
|
||||
this.authenticationState.set(AuthStatus.SignedIn);
|
||||
} else {
|
||||
this.userDataAuthTokenService.setToken(undefined);
|
||||
this.authenticationState.set(AuthStatus.SignedOut);
|
||||
}
|
||||
|
||||
this.updateBadge();
|
||||
}
|
||||
|
||||
private async onDidChangeSessions(providerId: string): Promise<void> {
|
||||
if (providerId === this.userDataSyncStore!.authenticationProviderId) {
|
||||
if (this.activeAccount) {
|
||||
// Try to update existing account, case where access token has been refreshed
|
||||
const accounts = (await this.authenticationService.getSessions(this.userDataSyncStore!.authenticationProviderId) || []);
|
||||
const matchingAccount = accounts.filter(a => a.id === this.activeAccount?.id)[0];
|
||||
this.activeAccount = matchingAccount;
|
||||
} else {
|
||||
this._register(instantiationService.createInstance(UserDataSyncTrigger).onDidTriggerSync(() => this.triggerSync()));
|
||||
this.initializeActiveAccount();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private triggerSync(): void {
|
||||
if (this.configurationService.getValue<boolean>('sync.enable')
|
||||
&& this.userDataSyncService.status !== SyncStatus.Uninitialized
|
||||
&& this.authTokenService.status === AuthTokenStatus.SignedIn) {
|
||||
this.userDataSyncService.sync();
|
||||
private async onDidRegisterAuthenticationProvider(providerId: string) {
|
||||
if (providerId === this.userDataSyncStore!.authenticationProviderId) {
|
||||
await this.initializeActiveAccount();
|
||||
}
|
||||
}
|
||||
|
||||
private onDidChangeAuthTokenStatus(status: AuthTokenStatus) {
|
||||
this.authTokenContext.set(status);
|
||||
if (status === AuthTokenStatus.SignedIn) {
|
||||
this.signInNotificationDisposable.clear();
|
||||
private onDidUnregisterAuthenticationProvider(providerId: string) {
|
||||
if (providerId === this.userDataSyncStore!.authenticationProviderId) {
|
||||
this.activeAccount = undefined;
|
||||
this.authenticationState.reset();
|
||||
}
|
||||
this.updateBadge();
|
||||
}
|
||||
|
||||
private onDidChangeSyncStatus(status: SyncStatus) {
|
||||
@@ -120,7 +193,11 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
||||
label: localize('resolve', "Resolve Conflicts"),
|
||||
run: () => this.handleConflicts()
|
||||
}
|
||||
]);
|
||||
],
|
||||
{
|
||||
sticky: true
|
||||
}
|
||||
);
|
||||
this.conflictsWarningDisposable.value = toDisposable(() => handle.close());
|
||||
handle.onDidClose(() => this.conflictsWarningDisposable.clear());
|
||||
}
|
||||
@@ -137,8 +214,8 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
||||
this.updateBadge();
|
||||
const enabled = this.configurationService.getValue<boolean>(UserDataSyncWorkbenchContribution.ENABLEMENT_SETTING);
|
||||
if (enabled) {
|
||||
if (this.authTokenService.status === AuthTokenStatus.SignedOut) {
|
||||
const handle = this.notificationService.prompt(Severity.Info, localize('ask to sign in', "Please sign in with your {0} account to sync configuration across all your machines", this.userDataSyncStore!.account),
|
||||
if (this.authenticationState.get() === AuthStatus.SignedOut) {
|
||||
const handle = this.notificationService.prompt(Severity.Info, localize('sign in message', "Please sign in with your {0} account to continue sync", this.userDataSyncStore!.account),
|
||||
[
|
||||
{
|
||||
label: localize('Sign in', "Sign in"),
|
||||
@@ -153,19 +230,15 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
||||
}
|
||||
}
|
||||
|
||||
private updateBadge(): void {
|
||||
private async updateBadge(): Promise<void> {
|
||||
this.badgeDisposable.clear();
|
||||
|
||||
let badge: IBadge | undefined = undefined;
|
||||
let clazz: string | undefined;
|
||||
let priority: number | undefined = undefined;
|
||||
|
||||
if (this.userDataSyncService.status !== SyncStatus.Uninitialized && this.configurationService.getValue<boolean>(UserDataSyncWorkbenchContribution.ENABLEMENT_SETTING) && this.authTokenService.status === AuthTokenStatus.SignedOut) {
|
||||
if (this.userDataSyncService.status !== SyncStatus.Uninitialized && this.configurationService.getValue<boolean>(UserDataSyncWorkbenchContribution.ENABLEMENT_SETTING) && this.authenticationState.get() === AuthStatus.SignedOut) {
|
||||
badge = new NumberBadge(1, () => localize('sign in to sync', "Sign in to Sync"));
|
||||
} else if (this.authTokenService.status === AuthTokenStatus.SigningIn) {
|
||||
badge = new ProgressBadge(() => localize('signing in', "Signing in..."));
|
||||
clazz = 'progress-badge';
|
||||
priority = 1;
|
||||
} else if (this.userDataSyncService.status === SyncStatus.HasConflicts) {
|
||||
badge = new NumberBadge(1, () => localize('resolve conflicts', "Resolve Conflicts"));
|
||||
} else if (this.userDataSyncService.status === SyncStatus.Syncing) {
|
||||
@@ -180,53 +253,90 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
||||
}
|
||||
|
||||
private async turnOn(): Promise<void> {
|
||||
if (this.authTokenService.status === AuthTokenStatus.SignedOut) {
|
||||
const result = await this.dialogService.confirm({
|
||||
type: 'info',
|
||||
message: localize('sign in to account', "Sign in to {0}", this.userDataSyncStore!.name),
|
||||
detail: localize('ask to sign in', "Please sign in with your {0} account to sync configuration across all your machines", this.userDataSyncStore!.account),
|
||||
primaryButton: localize('Sign in', "Sign in")
|
||||
});
|
||||
if (!result.confirmed) {
|
||||
return;
|
||||
}
|
||||
await this.signIn();
|
||||
}
|
||||
await this.configureSyncOptions();
|
||||
await this.configurationService.updateValue(UserDataSyncWorkbenchContribution.ENABLEMENT_SETTING, true);
|
||||
this.notificationService.info(localize('Sync Started', "Sync Started."));
|
||||
}
|
||||
|
||||
private async configureSyncOptions(): Promise<void> {
|
||||
return new Promise((c, e) => {
|
||||
const disposables: DisposableStore = new DisposableStore();
|
||||
const quickPick = this.quickInputService.createQuickPick();
|
||||
const quickPick = this.quickInputService.createQuickPick<ConfigureSyncQuickPickItem>();
|
||||
disposables.add(quickPick);
|
||||
quickPick.title = localize('configure sync title', "Sync: Configure");
|
||||
quickPick.placeholder = localize('select configurations to sync', "Choose what to sync");
|
||||
quickPick.title = localize('turn on sync', "Turn on Sync");
|
||||
quickPick.ok = false;
|
||||
quickPick.customButton = true;
|
||||
if (this.authenticationState.get() === AuthStatus.SignedIn) {
|
||||
quickPick.description = localize('turn on sync detail', "Turn on to synchronize your following data across all your devices.");
|
||||
quickPick.customLabel = localize('turn on', "Turn on");
|
||||
} else {
|
||||
quickPick.description = localize('sign in and turn on sync detail', "Please sign in with your {0} account to synchronize your following data across all your devices.", this.userDataSyncStore!.account);
|
||||
quickPick.customLabel = localize('sign in and turn on sync', "Sign in & Turn on");
|
||||
}
|
||||
quickPick.placeholder = localize('configure sync placeholder', "Choose what to sync");
|
||||
quickPick.canSelectMany = true;
|
||||
quickPick.ignoreFocusOut = true;
|
||||
const items = [{
|
||||
id: 'sync.enableSettings',
|
||||
label: localize('user settings', "User Settings")
|
||||
}, {
|
||||
id: 'sync.enableKeybindings',
|
||||
label: localize('user keybindings', "User Keybindings")
|
||||
}, {
|
||||
id: 'sync.enableExtensions',
|
||||
label: localize('extensions', "Extensions")
|
||||
}];
|
||||
const items = this.getConfigureSyncQuickPickItems();
|
||||
quickPick.items = items;
|
||||
quickPick.selectedItems = items.filter(item => this.configurationService.getValue(item.id));
|
||||
disposables.add(quickPick.onDidAccept(() => {
|
||||
for (const item of items) {
|
||||
const wasEnabled = this.configurationService.getValue(item.id);
|
||||
const isEnabled = !!quickPick.selectedItems.filter(selected => selected.id === item.id)[0];
|
||||
if (wasEnabled !== isEnabled) {
|
||||
this.configurationService.updateValue(item.id!, isEnabled);
|
||||
}
|
||||
disposables.add(Event.any(quickPick.onDidAccept, quickPick.onDidCustom)(async () => {
|
||||
if (quickPick.selectedItems.length) {
|
||||
await this.updateConfiguration(items, quickPick.selectedItems);
|
||||
this.doTurnOn().then(c, e);
|
||||
quickPick.hide();
|
||||
}
|
||||
}));
|
||||
disposables.add(quickPick.onDidHide(() => disposables.dispose()));
|
||||
quickPick.show();
|
||||
});
|
||||
}
|
||||
|
||||
private async doTurnOn(): Promise<void> {
|
||||
if (this.authenticationState.get() === AuthStatus.SignedOut) {
|
||||
await this.signIn();
|
||||
}
|
||||
await this.handleFirstTimeSync();
|
||||
await this.enableSync();
|
||||
}
|
||||
|
||||
private getConfigureSyncQuickPickItems(): ConfigureSyncQuickPickItem[] {
|
||||
return [{
|
||||
id: 'sync.enableSettings',
|
||||
label: localize('settings', "Settings")
|
||||
}, {
|
||||
id: 'sync.enableKeybindings',
|
||||
label: localize('keybindings', "Keybindings")
|
||||
}, {
|
||||
id: 'sync.enableExtensions',
|
||||
label: localize('extensions', "Extensions")
|
||||
}, {
|
||||
id: 'sync.enableUIState',
|
||||
label: localize('ui state label', "UI State"),
|
||||
description: localize('ui state description', "Display Language (Only)")
|
||||
}];
|
||||
}
|
||||
|
||||
private async updateConfiguration(items: ConfigureSyncQuickPickItem[], selectedItems: ReadonlyArray<ConfigureSyncQuickPickItem>): Promise<void> {
|
||||
for (const item of items) {
|
||||
const wasEnabled = this.configurationService.getValue(item.id);
|
||||
const isEnabled = !!selectedItems.filter(selected => selected.id === item.id)[0];
|
||||
if (wasEnabled !== isEnabled) {
|
||||
await this.configurationService.updateValue(item.id!, isEnabled);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async configureSyncOptions(): Promise<ISyncConfiguration> {
|
||||
return new Promise((c, e) => {
|
||||
const disposables: DisposableStore = new DisposableStore();
|
||||
const quickPick = this.quickInputService.createQuickPick<ConfigureSyncQuickPickItem>();
|
||||
disposables.add(quickPick);
|
||||
quickPick.title = localize('turn on sync', "Turn on Sync");
|
||||
quickPick.placeholder = localize('configure sync placeholder', "Choose what to sync");
|
||||
quickPick.canSelectMany = true;
|
||||
quickPick.ignoreFocusOut = true;
|
||||
const items = this.getConfigureSyncQuickPickItems();
|
||||
quickPick.items = items;
|
||||
quickPick.selectedItems = items.filter(item => this.configurationService.getValue(item.id));
|
||||
disposables.add(quickPick.onDidAccept(async () => {
|
||||
if (quickPick.selectedItems.length) {
|
||||
await this.updateConfiguration(items, quickPick.selectedItems);
|
||||
quickPick.hide();
|
||||
}
|
||||
quickPick.hide();
|
||||
}));
|
||||
disposables.add(quickPick.onDidHide(() => {
|
||||
disposables.dispose();
|
||||
@@ -236,13 +346,60 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
||||
});
|
||||
}
|
||||
|
||||
private async handleFirstTimeSync(): Promise<void> {
|
||||
const hasRemote = await this.userDataSyncService.hasRemoteData();
|
||||
if (!hasRemote) {
|
||||
return;
|
||||
}
|
||||
const isFirstSyncAndHasUserData = await this.userDataSyncService.isFirstTimeSyncAndHasUserData();
|
||||
if (!isFirstSyncAndHasUserData) {
|
||||
return;
|
||||
}
|
||||
const result = await this.dialogService.show(
|
||||
Severity.Info,
|
||||
localize('firs time sync', "First time Sync"),
|
||||
[
|
||||
localize('merge', "Merge"),
|
||||
localize('cancel', "Cancel"),
|
||||
localize('replace', "Replace (Overwrite Local)"),
|
||||
],
|
||||
{
|
||||
cancelId: 1,
|
||||
detail: localize('first time sync detail', "Synchronizing from this device for the first time.\nWould you like to merge or replace with the data from cloud?"),
|
||||
}
|
||||
);
|
||||
switch (result.choice) {
|
||||
case 0: await this.userDataSyncService.sync(); break;
|
||||
case 1: throw canceled();
|
||||
case 2: await this.userDataSyncService.pull(); break;
|
||||
}
|
||||
}
|
||||
|
||||
private enableSync(): Promise<void> {
|
||||
return this.configurationService.updateValue(UserDataSyncWorkbenchContribution.ENABLEMENT_SETTING, true);
|
||||
}
|
||||
|
||||
private async turnOff(): Promise<void> {
|
||||
await this.configurationService.updateValue(UserDataSyncWorkbenchContribution.ENABLEMENT_SETTING, false);
|
||||
const result = await this.dialogService.confirm({
|
||||
type: 'info',
|
||||
message: localize('turn off sync confirmation', "Turn off Sync"),
|
||||
detail: localize('turn off sync detail', "Your settings, keybindings, extensions and more will no longer be synced."),
|
||||
primaryButton: localize('turn off', "Turn off"),
|
||||
checkbox: {
|
||||
label: localize('turn off sync everywhere', "Turn off sync in all your devices and clear the data in cloud.")
|
||||
}
|
||||
});
|
||||
if (result.confirmed) {
|
||||
await this.configurationService.updateValue(UserDataSyncWorkbenchContribution.ENABLEMENT_SETTING, false);
|
||||
if (result.checkboxChecked) {
|
||||
await this.userDataSyncService.reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async signIn(): Promise<void> {
|
||||
try {
|
||||
await this.authTokenService.login();
|
||||
this.activeAccount = await this.authenticationService.login(this.userDataSyncStore!.authenticationProviderId);
|
||||
} catch (e) {
|
||||
this.notificationService.error(e);
|
||||
throw e;
|
||||
@@ -250,7 +407,10 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
||||
}
|
||||
|
||||
private async signOut(): Promise<void> {
|
||||
await this.authTokenService.logout();
|
||||
if (this.activeAccount) {
|
||||
await this.authenticationService.logout(this.userDataSyncStore!.authenticationProviderId, this.activeAccount.id);
|
||||
this.activeAccount = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
private async continueSync(): Promise<void> {
|
||||
@@ -313,11 +473,23 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
||||
return null;
|
||||
}
|
||||
|
||||
private showSyncLog(): Promise<void> {
|
||||
return this.outputService.showChannel(Constants.userDataSyncLogChannelId);
|
||||
}
|
||||
|
||||
private registerActions(): void {
|
||||
|
||||
const turnOnSyncCommandId = 'workbench.userData.actions.syncStart';
|
||||
const turnOnSyncWhenContext = ContextKeyExpr.and(CONTEXT_SYNC_STATE.notEqualsTo(SyncStatus.Uninitialized), ContextKeyExpr.not(`config.${UserDataSyncWorkbenchContribution.ENABLEMENT_SETTING}`), CONTEXT_AUTH_TOKEN_STATE.notEqualsTo(AuthTokenStatus.SigningIn));
|
||||
CommandsRegistry.registerCommand(turnOnSyncCommandId, () => this.turnOn());
|
||||
const turnOnSyncWhenContext = ContextKeyExpr.and(CONTEXT_SYNC_STATE.notEqualsTo(SyncStatus.Uninitialized), ContextKeyExpr.not(`config.${UserDataSyncWorkbenchContribution.ENABLEMENT_SETTING}`), CONTEXT_AUTH_TOKEN_STATE.notEqualsTo(AuthStatus.Initializing));
|
||||
CommandsRegistry.registerCommand(turnOnSyncCommandId, async () => {
|
||||
try {
|
||||
await this.turnOn();
|
||||
} catch (e) {
|
||||
if (!isPromiseCanceledError(e)) {
|
||||
this.notificationService.error(localize('turn on failed', "Error while starting Sync: {0}", toErrorMessage(e)));
|
||||
}
|
||||
}
|
||||
});
|
||||
MenuRegistry.appendMenuItem(MenuId.GlobalActivity, {
|
||||
group: '5_sync',
|
||||
command: {
|
||||
@@ -329,13 +501,13 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
||||
MenuRegistry.appendMenuItem(MenuId.CommandPalette, {
|
||||
command: {
|
||||
id: turnOnSyncCommandId,
|
||||
title: localize('turn on sync', "Sync: Turn on sync...")
|
||||
title: localize('turn on sync...', "Sync: Turn on sync...")
|
||||
},
|
||||
when: turnOnSyncWhenContext,
|
||||
});
|
||||
|
||||
const signInCommandId = 'workbench.userData.actions.signin';
|
||||
const signInWhenContext = ContextKeyExpr.and(CONTEXT_SYNC_STATE.notEqualsTo(SyncStatus.Uninitialized), ContextKeyExpr.has(`config.${UserDataSyncWorkbenchContribution.ENABLEMENT_SETTING}`), CONTEXT_AUTH_TOKEN_STATE.isEqualTo(AuthTokenStatus.SignedOut));
|
||||
const signInWhenContext = ContextKeyExpr.and(CONTEXT_SYNC_STATE.notEqualsTo(SyncStatus.Uninitialized), ContextKeyExpr.has(`config.${UserDataSyncWorkbenchContribution.ENABLEMENT_SETTING}`), CONTEXT_AUTH_TOKEN_STATE.isEqualTo(AuthStatus.SignedOut));
|
||||
CommandsRegistry.registerCommand(signInCommandId, () => this.signIn());
|
||||
MenuRegistry.appendMenuItem(MenuId.GlobalActivity, {
|
||||
group: '5_sync',
|
||||
@@ -353,18 +525,6 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
||||
when: signInWhenContext,
|
||||
});
|
||||
|
||||
const signingInCommandId = 'workbench.userData.actions.signingin';
|
||||
CommandsRegistry.registerCommand(signingInCommandId, () => null);
|
||||
MenuRegistry.appendMenuItem(MenuId.GlobalActivity, {
|
||||
group: '5_sync',
|
||||
command: {
|
||||
id: signingInCommandId,
|
||||
title: localize('signinig in', "Signing in..."),
|
||||
precondition: FalseContext
|
||||
},
|
||||
when: CONTEXT_AUTH_TOKEN_STATE.isEqualTo(AuthTokenStatus.SigningIn)
|
||||
});
|
||||
|
||||
const stopSyncCommandId = 'workbench.userData.actions.stopSync';
|
||||
CommandsRegistry.registerCommand(stopSyncCommandId, () => this.turnOff());
|
||||
MenuRegistry.appendMenuItem(MenuId.GlobalActivity, {
|
||||
@@ -373,7 +533,7 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
||||
id: stopSyncCommandId,
|
||||
title: localize('global activity stop sync', "Turn off sync")
|
||||
},
|
||||
when: ContextKeyExpr.and(ContextKeyExpr.has(`config.${UserDataSyncWorkbenchContribution.ENABLEMENT_SETTING}`), CONTEXT_AUTH_TOKEN_STATE.isEqualTo(AuthTokenStatus.SignedIn), CONTEXT_SYNC_STATE.notEqualsTo(SyncStatus.Uninitialized), CONTEXT_SYNC_STATE.notEqualsTo(SyncStatus.HasConflicts))
|
||||
when: ContextKeyExpr.and(ContextKeyExpr.has(`config.${UserDataSyncWorkbenchContribution.ENABLEMENT_SETTING}`), CONTEXT_AUTH_TOKEN_STATE.isEqualTo(AuthStatus.SignedIn), CONTEXT_SYNC_STATE.notEqualsTo(SyncStatus.Uninitialized), CONTEXT_SYNC_STATE.notEqualsTo(SyncStatus.HasConflicts))
|
||||
});
|
||||
MenuRegistry.appendMenuItem(MenuId.CommandPalette, {
|
||||
command: {
|
||||
@@ -444,9 +604,39 @@ export class UserDataSyncWorkbenchContribution extends Disposable implements IWo
|
||||
id: 'workbench.userData.actions.signout',
|
||||
title: localize('sign out', "Sync: Sign out")
|
||||
},
|
||||
when: ContextKeyExpr.and(CONTEXT_AUTH_TOKEN_STATE.isEqualTo(AuthTokenStatus.SignedIn)),
|
||||
when: ContextKeyExpr.and(CONTEXT_AUTH_TOKEN_STATE.isEqualTo(AuthStatus.SignedIn)),
|
||||
};
|
||||
CommandsRegistry.registerCommand(signOutMenuItem.command.id, () => this.signOut());
|
||||
MenuRegistry.appendMenuItem(MenuId.CommandPalette, signOutMenuItem);
|
||||
|
||||
const configureSyncCommandId = 'workbench.userData.actions.configureSync';
|
||||
CommandsRegistry.registerCommand(configureSyncCommandId, () => this.configureSyncOptions());
|
||||
MenuRegistry.appendMenuItem(MenuId.CommandPalette, {
|
||||
command: {
|
||||
id: configureSyncCommandId,
|
||||
title: localize('configure sync', "Sync: Configure")
|
||||
},
|
||||
when: ContextKeyExpr.and(CONTEXT_SYNC_STATE.notEqualsTo(SyncStatus.Uninitialized), ContextKeyExpr.has(`config.${UserDataSyncWorkbenchContribution.ENABLEMENT_SETTING}`)),
|
||||
});
|
||||
|
||||
const showSyncLogCommandId = 'workbench.userData.actions.showSyncLog';
|
||||
CommandsRegistry.registerCommand(showSyncLogCommandId, () => this.showSyncLog());
|
||||
MenuRegistry.appendMenuItem(MenuId.CommandPalette, {
|
||||
command: {
|
||||
id: showSyncLogCommandId,
|
||||
title: localize('show sync log', "Sync: Show Sync Log")
|
||||
},
|
||||
when: ContextKeyExpr.and(CONTEXT_SYNC_STATE.notEqualsTo(SyncStatus.Uninitialized)),
|
||||
});
|
||||
|
||||
const resetLocalCommandId = 'workbench.userData.actions.resetLocal';
|
||||
CommandsRegistry.registerCommand(resetLocalCommandId, () => this.userDataSyncService.resetLocal());
|
||||
MenuRegistry.appendMenuItem(MenuId.CommandPalette, {
|
||||
command: {
|
||||
id: resetLocalCommandId,
|
||||
title: localize('reset local', "Developer: Reset Local (Sync)")
|
||||
},
|
||||
when: ContextKeyExpr.and(CONTEXT_SYNC_STATE.notEqualsTo(SyncStatus.Uninitialized)),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user