From 44cc1c63804fb886168e04e65883339e49f99486 Mon Sep 17 00:00:00 2001 From: Silvano Cerza Date: Tue, 14 Jan 2025 18:31:19 +0100 Subject: [PATCH] Temporary conflict handling --- src/main.ts | 27 ++++++++++++++++++++++++++- src/sync-manager.ts | 32 ++++++++++++++++++++++++++++---- 2 files changed, 54 insertions(+), 5 deletions(-) diff --git a/src/main.ts b/src/main.ts index d72410f..6253177 100644 --- a/src/main.ts +++ b/src/main.ts @@ -2,6 +2,7 @@ import { EventRef, Plugin, FileView } from "obsidian"; import { GitHubSyncSettings, DEFAULT_SETTINGS } from "./settings/settings"; import GitHubSyncSettingsTab from "./settings/tab"; import SyncManager from "./sync-manager"; +import { FileMetadata } from "./metadata-store"; export default class GitHubSyncPlugin extends Plugin { settings: GitHubSyncSettings; @@ -24,7 +25,11 @@ export default class GitHubSyncPlugin extends Plugin { this.addSettingTab(new GitHubSyncSettingsTab(this.app, this)); - this.syncManager = new SyncManager(this.app.vault, this.settings); + this.syncManager = new SyncManager( + this.app.vault, + this.settings, + this.onConflicts.bind(this), + ); await this.syncManager.loadMetadata(); if (this.settings.uploadStrategy == "interval") { @@ -145,6 +150,26 @@ export default class GitHubSyncPlugin extends Plugin { this.uploadModifiedFilesRibbonIcon = null; } + async onConflicts( + conflicts: { remoteFile: FileMetadata; localFile: FileMetadata }[], + ): Promise { + return await Promise.all( + conflicts.map( + async ({ + remoteFile, + localFile, + }: { + remoteFile: FileMetadata; + localFile: FileMetadata; + }) => { + // TODO: Add a proper conflict resolution view + // This way remote files are always preferred + return true; + }, + ), + ); + } + async loadSettings() { this.settings = Object.assign({}, DEFAULT_SETTINGS, await this.loadData()); } diff --git a/src/sync-manager.ts b/src/sync-manager.ts index 12404d4..2d8e409 100644 --- a/src/sync-manager.ts +++ b/src/sync-manager.ts @@ -12,6 +12,10 @@ interface SyncAction { filePath: string; } +type OnConflictsCallback = ( + conflicts: { remoteFile: FileMetadata; localFile: FileMetadata }[], +) => Promise; + export default class SyncManager { private metadataStore: MetadataStore; private client: GithubClient; @@ -21,6 +25,7 @@ export default class SyncManager { constructor( private vault: Vault, private settings: GitHubSyncSettings, + private onConflicts: OnConflictsCallback, ) { this.metadataStore = new MetadataStore(this.vault); this.client = new GithubClient( @@ -131,6 +136,7 @@ export default class SyncManager { remoteMetadata.files, this.metadataStore.data.files, ); + let conflictResolutions: SyncAction[] = []; if (conflicts.length > 0) { // TODO: Show conflicts to the user with a callback // Wait for response @@ -138,12 +144,30 @@ export default class SyncManager { // Add the new action to the list later on console.log("Conflicts"); console.log(conflicts); + (await this.onConflicts(conflicts)).forEach( + (resolution: boolean, index: number) => { + if (resolution) { + conflictResolutions.push({ + type: "download", + filePath: conflicts[index].remoteFile.localPath, + }); + } else { + conflictResolutions.push({ + type: "upload", + filePath: conflicts[index].localFile.localPath, + }); + } + }, + ); } - const actions = this.determineSyncActions( - remoteMetadata.files, - this.metadataStore.data.files, - ); + const actions = [ + ...this.determineSyncActions( + remoteMetadata.files, + this.metadataStore.data.files, + ), + ...conflictResolutions, + ]; if (actions.length === 0) { console.log("Nothing to sync");