Skip to content

Commit

Permalink
Implement start and stop sync commands
Browse files Browse the repository at this point in the history
  • Loading branch information
Sandeep Somavarapu authored and Sandeep Somavarapu committed Sep 12, 2019
1 parent fcffaba commit 88bf57b
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 6 deletions.
38 changes: 34 additions & 4 deletions src/vs/workbench/contrib/userData/browser/userData.contribution.ts
Expand Up @@ -6,7 +6,7 @@
import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions, IWorkbenchContribution } from 'vs/workbench/common/contributions';
import { IUserDataSyncService, SyncStatus } from 'vs/workbench/services/userData/common/userData';
import { localize } from 'vs/nls';
import { Disposable, MutableDisposable } from 'vs/base/common/lifecycle';
import { Disposable, MutableDisposable, toDisposable } from 'vs/base/common/lifecycle';
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
import { Registry } from 'vs/platform/registry/common/platform';
import { LifecyclePhase } from 'vs/platform/lifecycle/common/lifecycle';
Expand All @@ -20,6 +20,7 @@ import { GLOBAL_ACTIVITY_ID } from 'vs/workbench/common/activity';
import { timeout } from 'vs/base/common/async';
import { registerEditorContribution } from 'vs/editor/browser/editorExtensions';
import { AcceptChangesController } from 'vs/workbench/contrib/userData/browser/userDataPreviewEditorContribution';
import { INotificationService, Severity } from 'vs/platform/notification/common/notification';

const CONTEXT_SYNC_STATE = new RawContextKey<string>('syncStatus', SyncStatus.Uninitialized);

Expand Down Expand Up @@ -74,11 +75,13 @@ class SyncContribution extends Disposable implements IWorkbenchContribution {

private readonly syncEnablementContext: IContextKey<string>;
private readonly badgeDisposable = this._register(new MutableDisposable());
private readonly conflictsWarningDisposable = this._register(new MutableDisposable());

constructor(
@IUserDataSyncService userDataSyncService: IUserDataSyncService,
@IUserDataSyncService private readonly userDataSyncService: IUserDataSyncService,
@IContextKeyService contextKeyService: IContextKeyService,
@IActivityService private readonly activityService: IActivityService
@IActivityService private readonly activityService: IActivityService,
@INotificationService private readonly notificationService: INotificationService
) {
super();
this.syncEnablementContext = CONTEXT_SYNC_STATE.bindTo(contextKeyService);
Expand All @@ -105,6 +108,24 @@ class SyncContribution extends Disposable implements IWorkbenchContribution {
if (badge) {
this.badgeDisposable.value = this.activityService.showActivity(GLOBAL_ACTIVITY_ID, badge, clazz);
}

if (status !== SyncStatus.HasConflicts) {
this.conflictsWarningDisposable.clear();
}
}

private async sync(): Promise<void> {
await this.userDataSyncService.sync();
if (this.userDataSyncService.status === SyncStatus.HasConflicts) {
const handle = this.notificationService.prompt(Severity.Warning, localize('conflicts detected', "Unable to sync due to conflicts. Please resolve them to continue."),
[
{
label: localize('resolve', "Resolve Conflicts"),
run: () => this.userDataSyncService.handleConflicts()
}
]);
this.conflictsWarningDisposable.value = toDisposable(() => handle.close());
}
}

private registerActions(): void {
Expand Down Expand Up @@ -154,7 +175,7 @@ class SyncContribution extends Disposable implements IWorkbenchContribution {

// Command Pallette Actions

CommandsRegistry.registerCommand('workbench.userData.actions.startSync', serviceAccessor => serviceAccessor.get(IUserDataSyncService).sync());
CommandsRegistry.registerCommand('workbench.userData.actions.startSync', () => this.sync());
MenuRegistry.appendMenuItem(MenuId.CommandPalette, {
command: {
id: 'workbench.userData.actions.startSync',
Expand All @@ -163,6 +184,15 @@ class SyncContribution extends Disposable implements IWorkbenchContribution {
when: ContextKeyExpr.and(CONTEXT_SYNC_STATE.isEqualTo(SyncStatus.Idle), ContextKeyExpr.not('config.userConfiguration.autoSync')),
});

CommandsRegistry.registerCommand('workbench.userData.actions.stopSync', serviceAccessor => serviceAccessor.get(IUserDataSyncService).stopSync());
MenuRegistry.appendMenuItem(MenuId.CommandPalette, {
command: {
id: 'workbench.userData.actions.stopSync',
title: localize('stop sync', "Sync: Stop")
},
when: ContextKeyExpr.and(CONTEXT_SYNC_STATE.isEqualTo(SyncStatus.HasConflicts), ContextKeyExpr.not('config.userConfiguration.autoSync')),
});

MenuRegistry.appendMenuItem(MenuId.CommandPalette, {
command: {
id: 'sync.resolveConflicts',
Expand Down
14 changes: 12 additions & 2 deletions src/vs/workbench/services/userData/common/settingsSync.ts
Expand Up @@ -26,6 +26,7 @@ import { ILogService } from 'vs/platform/log/common/log';
import { Position } from 'vs/editor/common/core/position';
import { IHistoryService } from 'vs/workbench/services/history/common/history';
import { isEqual } from 'vs/base/common/resources';
import { CancelablePromise, createCancelablePromise } from 'vs/base/common/async';

interface ISyncPreviewResult {
readonly fileContent: IFileContent | null;
Expand All @@ -40,7 +41,7 @@ export class SettingsSynchroniser extends Disposable implements ISynchroniser {
private static LAST_SYNC_SETTINGS_STORAGE_KEY: string = 'LAST_SYNC_SETTINGS_CONTENTS';
private static EXTERNAL_USER_DATA_SETTINGS_KEY: string = 'settings';

private syncPreviewResultPromise: Promise<ISyncPreviewResult> | null = null;
private syncPreviewResultPromise: CancelablePromise<ISyncPreviewResult> | null = null;

private _status: SyncStatus = SyncStatus.Idle;
get status(): SyncStatus { return this._status; }
Expand Down Expand Up @@ -101,6 +102,15 @@ export class SettingsSynchroniser extends Disposable implements ISynchroniser {
}
}

async stopSync(): Promise<void> {
await this.fileService.del(SETTINGS_PREVIEW_RESOURCE);
if (this.syncPreviewResultPromise) {
this.syncPreviewResultPromise.cancel();
this.syncPreviewResultPromise = null;
this.setStatus(SyncStatus.Idle);
}
}

handleConflicts(): boolean {
if (this.status !== SyncStatus.HasConflicts) {
return false;
Expand Down Expand Up @@ -152,7 +162,7 @@ export class SettingsSynchroniser extends Disposable implements ISynchroniser {

private getPreview(): Promise<ISyncPreviewResult> {
if (!this.syncPreviewResultPromise) {
this.syncPreviewResultPromise = this.generatePreview();
this.syncPreviewResultPromise = createCancelablePromise(token => this.generatePreview());
}
return this.syncPreviewResultPromise;
}
Expand Down
1 change: 1 addition & 0 deletions src/vs/workbench/services/userData/common/userData.ts
Expand Up @@ -101,6 +101,7 @@ export interface ISynchroniser {
readonly status: SyncStatus;
readonly onDidChangeStatus: Event<SyncStatus>;
sync(): Promise<boolean>;
stopSync(): Promise<void>;
handleConflicts(): boolean;
apply(previewResource: URI): Promise<boolean>;
}
Expand Down
Expand Up @@ -50,6 +50,15 @@ export class UserDataSyncService extends Disposable implements IUserDataSyncServ
return true;
}

async stopSync(): Promise<void> {
if (!this.remoteUserDataService.isEnabled()) {
throw new Error('Not enabled');
}
for (const synchroniser of this.synchronisers) {
await synchroniser.stopSync();
}
}

async apply(previewResource: URI): Promise<boolean> {
if (!this.remoteUserDataService.isEnabled()) {
throw new Error('Not enabled');
Expand Down

0 comments on commit 88bf57b

Please sign in to comment.