diff --git a/src/features/HiddenFileSync/CmdHiddenFileSync.ts b/src/features/HiddenFileSync/CmdHiddenFileSync.ts index 758a78c..9f66b87 100644 --- a/src/features/HiddenFileSync/CmdHiddenFileSync.ts +++ b/src/features/HiddenFileSync/CmdHiddenFileSync.ts @@ -722,6 +722,13 @@ Offline Changed files: ${processFiles.length}`; } else { this._log(`Object merge is not applicable.`, LOG_LEVEL_VERBOSE); } + // const pat = this.settings.syncInternalFileOverwritePatterns; + const regExp = getFileRegExp(this.settings, "syncInternalFileOverwritePatterns"); + if (regExp.some((r) => r.test(stripAllPrefixes(path)))) { + this._log(`Overwrite rule applied for conflicted hidden file: ${path}`, LOG_LEVEL_INFO); + await this.resolveByNewerEntry(id, path, doc, revA, revB); + return []; + } return [{ path, revA, revB, id, doc }]; } // When not JSON file, resolve conflicts by choosing a newer one. diff --git a/src/lib b/src/lib index f99e662..86b0a95 160000 --- a/src/lib +++ b/src/lib @@ -1 +1 @@ -Subproject commit f99e662309066a1f9ecb43e64a9c78cd76aa132b +Subproject commit 86b0a95d56e0410514264ab9d0b60d04c9165eb1 diff --git a/src/modules/features/ModuleLog.ts b/src/modules/features/ModuleLog.ts index e65eef7..b614c11 100644 --- a/src/modules/features/ModuleLog.ts +++ b/src/modules/features/ModuleLog.ts @@ -34,12 +34,17 @@ import { serialized } from "octagonal-wheels/concurrency/lock"; import { $msg } from "src/lib/src/common/i18n.ts"; import { P2PLogCollector } from "../../lib/src/replication/trystero/P2PReplicatorCore.ts"; import type { LiveSyncCore } from "../../main.ts"; +import { LiveSyncError } from "@/lib/src/common/LSError.ts"; // This module cannot be a core module because it depends on the Obsidian UI. // DI the log again. setGlobalLogFunction((message: any, level?: number, key?: string) => { - const entry = { message, level, key } as LogEntry; + const messageX = + message instanceof Error + ? new LiveSyncError("[Error Logged]: " + message.message, { cause: message }) + : message; + const entry = { message: messageX, level, key } as LogEntry; logStore.enqueue(entry); }); let recentLogs = [] as string[]; @@ -398,19 +403,29 @@ export class ModuleLog extends AbstractObsidianModule { const vaultName = this.services.vault.getVaultName(); const now = new Date(); const timestamp = now.toLocaleString(); + let errorInfo = ""; + if (message instanceof Error) { + if (message instanceof LiveSyncError) { + errorInfo = `${message.cause?.name}:${message.cause?.message}\n[StackTrace]: ${message.stack}\n[CausedBy]: ${message.cause?.stack}`; + } else { + const thisStack = new Error().stack; + errorInfo = `${message.name}:${message.message}\n[StackTrace]: ${message.stack}\n[LogCallStack]: ${thisStack}`; + } + } const messageContent = typeof message == "string" ? message : message instanceof Error - ? `${message.name}:${message.message}` + ? `${errorInfo}` : JSON.stringify(message, null, 2); - if (message instanceof Error) { - // debugger; - console.dir(message.stack); - } const newMessage = timestamp + "->" + messageContent; - - console.log(vaultName + ":" + newMessage); + if (message instanceof Error) { + console.error(vaultName + ":" + newMessage); + } else if (level >= LOG_LEVEL_INFO) { + console.log(vaultName + ":" + newMessage); + } else { + console.debug(vaultName + ":" + newMessage); + } if (!this.settings?.showOnlyIconsOnEditor) { this.statusLog.value = messageContent; } diff --git a/src/modules/features/SettingDialogue/PaneSelector.ts b/src/modules/features/SettingDialogue/PaneSelector.ts index 3e79cb3..ff0ac95 100644 --- a/src/modules/features/SettingDialogue/PaneSelector.ts +++ b/src/modules/features/SettingDialogue/PaneSelector.ts @@ -117,5 +117,26 @@ export function paneSelector(this: ObsidianLiveSyncSettingTab, paneEl: HTMLEleme await addDefaultPatterns(defaultSkipPatternXPlat); }); }); + + const overwritePatterns = new Setting(paneEl) + .setName("Overwrite patterns") + .setClass("wizardHidden") + .setDesc("Patterns to match files for overwriting instead of merging"); + const patTarget2 = splitCustomRegExpList(this.editingSettings.syncInternalFileOverwritePatterns, ","); + mount(MultipleRegExpControl, { + target: overwritePatterns.controlEl, + props: { + patterns: patTarget2, + originals: [...patTarget2], + apply: async (newPatterns: CustomRegExpSource[]) => { + this.editingSettings.syncInternalFileOverwritePatterns = constructCustomRegExpList( + newPatterns, + "," + ); + await this.saveAllDirtySettings(); + this.display(); + }, + }, + }); }); } diff --git a/src/modules/main/ModuleLiveSyncMain.ts b/src/modules/main/ModuleLiveSyncMain.ts index ba51989..22c5734 100644 --- a/src/modules/main/ModuleLiveSyncMain.ts +++ b/src/modules/main/ModuleLiveSyncMain.ts @@ -62,12 +62,19 @@ export class ModuleLiveSyncMain extends AbstractModule { _wireUpEvents() { eventHub.onEvent(EVENT_SETTING_SAVED, (settings: ObsidianLiveSyncSettings) => { - this.localDatabase.settings = settings; - setLang(settings.displayLanguage); - eventHub.emitEvent(EVENT_REQUEST_RELOAD_SETTING_TAB); - }); - eventHub.onEvent(EVENT_SETTING_SAVED, (settings: ObsidianLiveSyncSettings) => { - fireAndForget(() => this.core.services.setting.realiseSetting()); + fireAndForget(async () => { + try { + await this.core.services.setting.realiseSetting(); + const lang = this.core.services.setting.currentSettings()?.displayLanguage ?? undefined; + if (lang !== undefined) { + setLang(this.core.services.setting.currentSettings()?.displayLanguage); + } + eventHub.emitEvent(EVENT_REQUEST_RELOAD_SETTING_TAB); + } catch (e) { + this._log(`Error in Setting Save Event`, LOG_LEVEL_NOTICE); + this._log(e, LOG_LEVEL_VERBOSE); + } + }); }); return Promise.resolve(true); }