From 1a068377696c09ffedf27a084561445cc5a20dbb Mon Sep 17 00:00:00 2001 From: vorotamoroz Date: Thu, 28 Aug 2025 10:26:17 +0100 Subject: [PATCH] ### Fixed - Automatic translation detection on the first launch now works correctly (#630). - No errors are shown during synchronisations in offline (if not explicitly requested) (#699). - Missing some checking during automatic-synchronisation now works correctly. --- src/lib | 2 +- src/modules/core/ModuleReplicator.ts | 13 ++++++++++++- src/modules/core/ModuleReplicatorCouchDB.ts | 4 ++-- src/modules/coreFeatures/ModuleCheckRemoteSize.ts | 4 ++++ .../coreObsidian/storageLib/SerializedFileAccess.ts | 12 ++++++++---- src/modules/essential/ModuleMigration.ts | 4 +++- src/modules/essentialObsidian/ModuleObsidianAPI.ts | 3 +++ src/modules/features/ModuleObsidianSetting.ts | 9 ++++----- 8 files changed, 37 insertions(+), 14 deletions(-) diff --git a/src/lib b/src/lib index e488bca..f21001f 160000 --- a/src/lib +++ b/src/lib @@ -1 +1 @@ -Subproject commit e488bca9fca5c85ab67f2c925d1cc137c70114c7 +Subproject commit f21001fcb2b933016a298d41566f1f64f16ae85d diff --git a/src/modules/core/ModuleReplicator.ts b/src/modules/core/ModuleReplicator.ts index 39ce7e0..dc20b91 100644 --- a/src/modules/core/ModuleReplicator.ts +++ b/src/modules/core/ModuleReplicator.ts @@ -17,6 +17,7 @@ import { type EntryLeaf, type LoadedEntry, type MetaEntry, + type RemoteType, } from "../../lib/src/common/types"; import { QueueProcessor } from "octagonal-wheels/concurrency/processor"; import { @@ -38,7 +39,8 @@ const KEY_REPLICATION_ON_EVENT = "replicationOnEvent"; const REPLICATION_ON_EVENT_FORECASTED_TIME = 5000; export class ModuleReplicator extends AbstractModule implements ICoreModule { - _replicatorType?: string; + _replicatorType?: RemoteType; + $everyOnloadAfterLoadSettings(): Promise { eventHub.onEvent(EVENT_FILE_SAVED, () => { if (this.settings.syncOnSave && !this.core.$$isSuspended()) { @@ -91,6 +93,10 @@ export class ModuleReplicator extends AbstractModule implements ICoreModule { async $everyBeforeReplicate(showMessage: boolean): Promise { // Checking salt + if (!this.core.managers.networkManager.isOnline) { + this._log("Network is offline", showMessage ? LOG_LEVEL_NOTICE : LOG_LEVEL_INFO); + return false; + } // Showing message is false: that because be shown here. (And it is a fatal error, no way to hide it). if (!(await this.ensureReplicatorPBKDF2Salt(false))) { Logger("Failed to initialise the encryption key, preventing replication.", LOG_LEVEL_NOTICE); @@ -182,6 +188,11 @@ Even if you choose to clean up, you will see this option again if you exit Obsid Logger($msg("Replicator.Message.Pending"), LOG_LEVEL_NOTICE); return false; } + + if (!this.core.managers.networkManager.isOnline) { + this._log("Network is offline", showMessage ? LOG_LEVEL_NOTICE : LOG_LEVEL_INFO); + return false; + } if (!(await this.core.$everyBeforeReplicate(showMessage))) { Logger($msg("Replicator.Message.SomeModuleFailed"), LOG_LEVEL_NOTICE); return false; diff --git a/src/modules/core/ModuleReplicatorCouchDB.ts b/src/modules/core/ModuleReplicatorCouchDB.ts index 5eedf1d..417f28e 100644 --- a/src/modules/core/ModuleReplicatorCouchDB.ts +++ b/src/modules/core/ModuleReplicatorCouchDB.ts @@ -18,12 +18,12 @@ export class ModuleReplicatorCouchDB extends AbstractModule implements ICoreModu if (this.settings.remoteType != REMOTE_MINIO && this.settings.remoteType != REMOTE_P2P) { // If LiveSync enabled, open replication if (this.settings.liveSync) { - fireAndForget(() => this.core.replicator.openReplication(this.settings, true, false, false)); + fireAndForget(() => this.core.$$replicate(false)); } // If sync on start enabled, open replication if (!this.settings.liveSync && this.settings.syncOnStart) { // Possibly ok as if only share the result - fireAndForget(() => this.core.replicator.openReplication(this.settings, false, false, false)); + fireAndForget(() => this.core.$$replicate(false)); } } diff --git a/src/modules/coreFeatures/ModuleCheckRemoteSize.ts b/src/modules/coreFeatures/ModuleCheckRemoteSize.ts index f01b481..798f3f5 100644 --- a/src/modules/coreFeatures/ModuleCheckRemoteSize.ts +++ b/src/modules/coreFeatures/ModuleCheckRemoteSize.ts @@ -6,6 +6,10 @@ import { $msg } from "src/lib/src/common/i18n.ts"; export class ModuleCheckRemoteSize extends AbstractModule implements ICoreModule { async $allScanStat(): Promise { + if (this.core.managers.networkManager.isOnline === false) { + this._log("Network is offline, skipping remote size check.", LOG_LEVEL_INFO); + return true; + } this._log($msg("moduleCheckRemoteSize.logCheckingStorageSizes"), LOG_LEVEL_VERBOSE); if (this.settings.notifyThresholdOfRemoteStorageSize < 0) { const message = $msg("moduleCheckRemoteSize.msgSetDBCapacity"); diff --git a/src/modules/coreObsidian/storageLib/SerializedFileAccess.ts b/src/modules/coreObsidian/storageLib/SerializedFileAccess.ts index 1a27533..6b7e446 100644 --- a/src/modules/coreObsidian/storageLib/SerializedFileAccess.ts +++ b/src/modules/coreObsidian/storageLib/SerializedFileAccess.ts @@ -11,7 +11,7 @@ import { type UXFileInfo } from "../../../lib/src/common/types.ts"; function getFileLockKey(file: TFile | TFolder | string | UXFileInfo) { return `fl:${typeof file == "string" ? file : file.path}`; } -function toArrayBuffer(arr: Uint8Array | ArrayBuffer | DataView): ArrayBufferLike { +function toArrayBuffer(arr: Uint8Array | ArrayBuffer | DataView): ArrayBuffer { if (arr instanceof Uint8Array) { return arr.buffer; } @@ -77,7 +77,11 @@ export class SerializedFileAccess { return await processReadFile(file, () => this.app.vault.adapter.readBinary(path)); } - async adapterWrite(file: TFile | string, data: string | ArrayBuffer | Uint8Array, options?: DataWriteOptions) { + async adapterWrite( + file: TFile | string, + data: string | ArrayBuffer | Uint8Array, + options?: DataWriteOptions + ) { const path = file instanceof TFile ? file.path : file; if (typeof data === "string") { return await processWriteFile(file, () => this.app.vault.adapter.write(path, data, options)); @@ -106,7 +110,7 @@ export class SerializedFileAccess { return await processReadFile(file, () => this.app.vault.readBinary(file)); } - async vaultModify(file: TFile, data: string | ArrayBuffer | Uint8Array, options?: DataWriteOptions) { + async vaultModify(file: TFile, data: string | ArrayBuffer | Uint8Array, options?: DataWriteOptions) { if (typeof data === "string") { return await processWriteFile(file, async () => { const oldData = await this.app.vault.read(file); @@ -131,7 +135,7 @@ export class SerializedFileAccess { } async vaultCreate( path: string, - data: string | ArrayBuffer | Uint8Array, + data: string | ArrayBuffer | Uint8Array, options?: DataWriteOptions ): Promise { if (typeof data === "string") { diff --git a/src/modules/essential/ModuleMigration.ts b/src/modules/essential/ModuleMigration.ts index e520221..5581e84 100644 --- a/src/modules/essential/ModuleMigration.ts +++ b/src/modules/essential/ModuleMigration.ts @@ -228,7 +228,9 @@ export class ModuleMigration extends AbstractModule implements ICoreModule { // Check local database for compromised chunks const localCompromised = await countCompromisedChunks(this.localDatabase.localDatabase); const remote = this.core.$$getReplicator(); - const remoteCompromised = await remote.countCompromisedChunks(); + const remoteCompromised = this.core.managers.networkManager.isOnline + ? await remote.countCompromisedChunks() + : 0; if (localCompromised === false) { Logger(`Failed to count compromised chunks in local database`, LOG_LEVEL_NOTICE); return false; diff --git a/src/modules/essentialObsidian/ModuleObsidianAPI.ts b/src/modules/essentialObsidian/ModuleObsidianAPI.ts index f436d34..816c2dc 100644 --- a/src/modules/essentialObsidian/ModuleObsidianAPI.ts +++ b/src/modules/essentialObsidian/ModuleObsidianAPI.ts @@ -106,6 +106,9 @@ export class ModuleObsidianAPI extends AbstractObsidianModule implements IObsidi if (!isValidRemoteCouchDBURI(uri)) return "Remote URI is not valid"; if (uri.toLowerCase() != uri) return "Remote URI and database name could not contain capital letters."; if (uri.indexOf(" ") !== -1) return "Remote URI and database name could not contain spaces."; + if (!this.core.managers.networkManager.isOnline) { + return "Network is offline"; + } // let authHeader = await this._authHeader.getAuthorizationHeader(auth); const conf: PouchDB.HttpAdapter.HttpAdapterConfiguration = { diff --git a/src/modules/features/ModuleObsidianSetting.ts b/src/modules/features/ModuleObsidianSetting.ts index bf229e6..d9da466 100644 --- a/src/modules/features/ModuleObsidianSetting.ts +++ b/src/modules/features/ModuleObsidianSetting.ts @@ -1,6 +1,6 @@ import { type IObsidianModule, AbstractObsidianModule } from "../AbstractObsidianModule.ts"; // import { PouchDB } from "../../lib/src/pouchdb/pouchdb-browser"; -import { EVENT_REQUEST_RELOAD_SETTING_TAB, EVENT_SETTING_SAVED, eventHub } from "../../common/events"; +import { EVENT_REQUEST_RELOAD_SETTING_TAB, EVENT_SETTING_SAVED, eventHub } from "../../common/events.ts"; import { type BucketSyncSetting, ChunkAlgorithmNames, @@ -11,8 +11,8 @@ import { SALT_OF_PASSPHRASE, } from "../../lib/src/common/types"; import { LOG_LEVEL_NOTICE, LOG_LEVEL_URGENT } from "octagonal-wheels/common/logger"; -import { $msg, setLang } from "../../lib/src/common/i18n"; -import { isCloudantURI } from "../../lib/src/pouchdb/utils_couchdb"; +import { $msg, setLang } from "../../lib/src/common/i18n.ts"; +import { isCloudantURI } from "../../lib/src/pouchdb/utils_couchdb.ts"; import { getLanguage } from "obsidian"; import { SUPPORTED_I18N_LANGS, type I18N_LANGS } from "../../lib/src/common/rosetta.ts"; import { decryptString, encryptString } from "@/lib/src/encryption/stringEncryption.ts"; @@ -23,8 +23,7 @@ export class ModuleObsidianSettings extends AbstractObsidianModule implements IO const obsidianLanguage = getLanguage(); if ( SUPPORTED_I18N_LANGS.indexOf(obsidianLanguage) !== -1 && // Check if the language is supported - obsidianLanguage != this.settings.displayLanguage && // Check if the language is different from the current setting - this.settings.displayLanguage != "" + obsidianLanguage != this.settings.displayLanguage // Check if the language is different from the current setting ) { // Check if the current setting is not empty (Means migrated or installed). this.settings.displayLanguage = obsidianLanguage as I18N_LANGS;