mirror of
https://github.com/vrtmrz/obsidian-livesync.git
synced 2025-12-13 09:45:56 +00:00
- Fixed:
- Fixed a bug on `fetch chunks on demand` that could not fetch the chunks on demand. - Improved: - `fetch chunks on demand` works more smoothly. - Initialisation `Fetch` is now more efficient. - Tidied: - Removed some meaningless codes.
This commit is contained in:
@@ -178,9 +178,7 @@ export class ConfigSync extends LiveSyncCommands {
|
|||||||
get kvDB() {
|
get kvDB() {
|
||||||
return this.plugin.kvDB;
|
return this.plugin.kvDB;
|
||||||
}
|
}
|
||||||
ensureDirectoryEx(fullPath: string) {
|
|
||||||
return this.plugin.ensureDirectoryEx(fullPath);
|
|
||||||
}
|
|
||||||
pluginDialog: PluginDialogModal = null;
|
pluginDialog: PluginDialogModal = null;
|
||||||
periodicPluginSweepProcessor = new PeriodicProcessor(this.plugin, async () => await this.scanAllConfigFiles(false));
|
periodicPluginSweepProcessor = new PeriodicProcessor(this.plugin, async () => await this.scanAllConfigFiles(false));
|
||||||
|
|
||||||
@@ -433,7 +431,7 @@ export class ConfigSync extends LiveSyncCommands {
|
|||||||
try {
|
try {
|
||||||
// console.dir(f);
|
// console.dir(f);
|
||||||
const path = `${baseDir}/${f.filename}`;
|
const path = `${baseDir}/${f.filename}`;
|
||||||
await this.ensureDirectoryEx(path);
|
await this.vaultAccess.ensureDirectory(path);
|
||||||
if (!content) {
|
if (!content) {
|
||||||
const dt = decodeBinary(f.data);
|
const dt = decodeBinary(f.data);
|
||||||
await this.vaultAccess.adapterWrite(path, dt);
|
await this.vaultAccess.adapterWrite(path, dt);
|
||||||
|
|||||||
@@ -20,9 +20,6 @@ export class HiddenFileSync extends LiveSyncCommands {
|
|||||||
get kvDB() {
|
get kvDB() {
|
||||||
return this.plugin.kvDB;
|
return this.plugin.kvDB;
|
||||||
}
|
}
|
||||||
ensureDirectoryEx(fullPath: string) {
|
|
||||||
return this.plugin.ensureDirectoryEx(fullPath);
|
|
||||||
}
|
|
||||||
getConflictedDoc(path: FilePathWithPrefix, rev: string) {
|
getConflictedDoc(path: FilePathWithPrefix, rev: string) {
|
||||||
return this.plugin.getConflictedDoc(path, rev);
|
return this.plugin.getConflictedDoc(path, rev);
|
||||||
}
|
}
|
||||||
@@ -202,7 +199,7 @@ export class HiddenFileSync extends LiveSyncCommands {
|
|||||||
const filename = stripAllPrefixes(path);
|
const filename = stripAllPrefixes(path);
|
||||||
const isExists = await this.plugin.vaultAccess.adapterExists(filename);
|
const isExists = await this.plugin.vaultAccess.adapterExists(filename);
|
||||||
if (!isExists) {
|
if (!isExists) {
|
||||||
await this.ensureDirectoryEx(filename);
|
await this.vaultAccess.ensureDirectory(filename);
|
||||||
}
|
}
|
||||||
await this.plugin.vaultAccess.adapterWrite(filename, result);
|
await this.plugin.vaultAccess.adapterWrite(filename, result);
|
||||||
const stat = await this.vaultAccess.adapterStat(filename);
|
const stat = await this.vaultAccess.adapterStat(filename);
|
||||||
@@ -498,7 +495,7 @@ export class HiddenFileSync extends LiveSyncCommands {
|
|||||||
type: "newnote",
|
type: "newnote",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
const ret = await this.localDatabase.putDBEntry(saveData, true);
|
const ret = await this.localDatabase.putDBEntry(saveData);
|
||||||
Logger(`STORAGE --> DB:${file.path}: (hidden) Done`);
|
Logger(`STORAGE --> DB:${file.path}: (hidden) Done`);
|
||||||
return ret;
|
return ret;
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
@@ -599,7 +596,7 @@ export class HiddenFileSync extends LiveSyncCommands {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (!isExists) {
|
if (!isExists) {
|
||||||
await this.ensureDirectoryEx(filename);
|
await this.vaultAccess.ensureDirectory(filename);
|
||||||
await this.plugin.vaultAccess.adapterWrite(filename, decodeBinary(fileOnDB.data), { mtime: fileOnDB.mtime, ctime: fileOnDB.ctime });
|
await this.plugin.vaultAccess.adapterWrite(filename, decodeBinary(fileOnDB.data), { mtime: fileOnDB.mtime, ctime: fileOnDB.ctime });
|
||||||
try {
|
try {
|
||||||
//@ts-ignore internalAPI
|
//@ts-ignore internalAPI
|
||||||
@@ -668,7 +665,7 @@ export class HiddenFileSync extends LiveSyncCommands {
|
|||||||
if (!keep && result) {
|
if (!keep && result) {
|
||||||
const isExists = await this.plugin.vaultAccess.adapterExists(filename);
|
const isExists = await this.plugin.vaultAccess.adapterExists(filename);
|
||||||
if (!isExists) {
|
if (!isExists) {
|
||||||
await this.ensureDirectoryEx(filename);
|
await this.vaultAccess.ensureDirectory(filename);
|
||||||
}
|
}
|
||||||
await this.plugin.vaultAccess.adapterWrite(filename, result);
|
await this.plugin.vaultAccess.adapterWrite(filename, result);
|
||||||
const stat = await this.plugin.vaultAccess.adapterStat(filename);
|
const stat = await this.plugin.vaultAccess.adapterStat(filename);
|
||||||
|
|||||||
@@ -359,7 +359,7 @@ Of course, we are able to disable these features.`
|
|||||||
Logger(`Fetching chunks done`, LOG_LEVEL_NOTICE);
|
Logger(`Fetching chunks done`, LOG_LEVEL_NOTICE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
async fetchLocal() {
|
async fetchLocal(makeLocalChunkBeforeSync?: boolean) {
|
||||||
this.suspendExtraSync();
|
this.suspendExtraSync();
|
||||||
await this.askUseNewAdapter();
|
await this.askUseNewAdapter();
|
||||||
this.plugin.settings.isConfigured = true;
|
this.plugin.settings.isConfigured = true;
|
||||||
@@ -368,8 +368,11 @@ Of course, we are able to disable these features.`
|
|||||||
await this.resetLocalDatabase();
|
await this.resetLocalDatabase();
|
||||||
await delay(1000);
|
await delay(1000);
|
||||||
await this.plugin.openDatabase();
|
await this.plugin.openDatabase();
|
||||||
await this.plugin.markRemoteResolved();
|
|
||||||
this.plugin.isReady = true;
|
this.plugin.isReady = true;
|
||||||
|
if (makeLocalChunkBeforeSync) {
|
||||||
|
await this.plugin.initializeDatabase(true);
|
||||||
|
}
|
||||||
|
await this.plugin.markRemoteResolved();
|
||||||
await delay(500);
|
await delay(500);
|
||||||
await this.plugin.replicateAllFromServer(true);
|
await this.plugin.replicateAllFromServer(true);
|
||||||
await delay(1000);
|
await delay(1000);
|
||||||
@@ -379,24 +382,7 @@ Of course, we are able to disable these features.`
|
|||||||
await this.askHiddenFileConfiguration({ enableFetch: true });
|
await this.askHiddenFileConfiguration({ enableFetch: true });
|
||||||
}
|
}
|
||||||
async fetchLocalWithKeepLocal() {
|
async fetchLocalWithKeepLocal() {
|
||||||
this.suspendExtraSync();
|
return await this.fetchLocal(true);
|
||||||
await this.askUseNewAdapter();
|
|
||||||
this.plugin.settings.isConfigured = true;
|
|
||||||
await this.suspendReflectingDatabase();
|
|
||||||
await this.plugin.realizeSettingSyncMode();
|
|
||||||
await this.resetLocalDatabase();
|
|
||||||
await delay(1000);
|
|
||||||
await this.plugin.initializeDatabase(true);
|
|
||||||
await this.plugin.openDatabase();
|
|
||||||
await this.plugin.markRemoteResolved();
|
|
||||||
this.plugin.isReady = true;
|
|
||||||
await delay(500);
|
|
||||||
await this.plugin.replicateAllFromServer(true);
|
|
||||||
await delay(1000);
|
|
||||||
await this.plugin.replicateAllFromServer(true);
|
|
||||||
await this.fetchRemoteChunks();
|
|
||||||
await this.resumeReflectingDatabase();
|
|
||||||
await this.askHiddenFileConfiguration({ enableFetch: true });
|
|
||||||
}
|
}
|
||||||
async rebuildRemote() {
|
async rebuildRemote() {
|
||||||
this.suspendExtraSync();
|
this.suspendExtraSync();
|
||||||
|
|||||||
@@ -663,7 +663,7 @@ export class ObsidianLiveSyncSettingTab extends PluginSettingTab {
|
|||||||
.setWarning()
|
.setWarning()
|
||||||
.setDisabled(false)
|
.setDisabled(false)
|
||||||
.onClick(async () => {
|
.onClick(async () => {
|
||||||
await rebuildDB("localOnly");
|
await rebuildDB("localOnlyWithChunks");
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
.addButton((button) =>
|
.addButton((button) =>
|
||||||
@@ -732,7 +732,7 @@ export class ObsidianLiveSyncSettingTab extends PluginSettingTab {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const rebuildDB = async (method: "localOnly" | "remoteOnly" | "rebuildBothByThisDevice") => {
|
const rebuildDB = async (method: "localOnly" | "remoteOnly" | "rebuildBothByThisDevice" | "localOnlyWithChunks") => {
|
||||||
if (encrypt && passphrase == "") {
|
if (encrypt && passphrase == "") {
|
||||||
Logger("If you enable encryption, you have to set the passphrase", LOG_LEVEL_NOTICE);
|
Logger("If you enable encryption, you have to set the passphrase", LOG_LEVEL_NOTICE);
|
||||||
return;
|
return;
|
||||||
@@ -1053,9 +1053,9 @@ export class ObsidianLiveSyncSettingTab extends PluginSettingTab {
|
|||||||
if (!this.plugin.settings.isConfigured) {
|
if (!this.plugin.settings.isConfigured) {
|
||||||
this.plugin.settings.isConfigured = true;
|
this.plugin.settings.isConfigured = true;
|
||||||
await this.plugin.saveSettings();
|
await this.plugin.saveSettings();
|
||||||
await rebuildDB("localOnly");
|
await rebuildDB("localOnlyWithChunks");
|
||||||
Logger("All done! Please set up subsequent devices with 'Copy current settings as a new setup URI' and 'Use the copied setup URI'.", LOG_LEVEL_NOTICE);
|
Logger("All done! Please set up subsequent devices with 'Copy current settings as a new setup URI' and 'Use the copied setup URI'.", LOG_LEVEL_NOTICE);
|
||||||
await this.plugin.addOnSetup.command_openSetupURI();
|
await this.plugin.addOnSetup.command_copySetupURI();
|
||||||
} else {
|
} else {
|
||||||
this.askReload();
|
this.askReload();
|
||||||
}
|
}
|
||||||
@@ -1922,7 +1922,7 @@ ${stringifyYaml(pluginConfig)}`;
|
|||||||
toggle.setValue(!this.plugin.settings.useIndexedDBAdapter).onChange(async (value) => {
|
toggle.setValue(!this.plugin.settings.useIndexedDBAdapter).onChange(async (value) => {
|
||||||
this.plugin.settings.useIndexedDBAdapter = !value;
|
this.plugin.settings.useIndexedDBAdapter = !value;
|
||||||
await this.plugin.saveSettings();
|
await this.plugin.saveSettings();
|
||||||
await rebuildDB("localOnly");
|
await rebuildDB("localOnlyWithChunks");
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -2119,6 +2119,19 @@ ${stringifyYaml(pluginConfig)}`;
|
|||||||
.setButtonText("Fetch")
|
.setButtonText("Fetch")
|
||||||
.setWarning()
|
.setWarning()
|
||||||
.setDisabled(false)
|
.setDisabled(false)
|
||||||
|
.onClick(async () => {
|
||||||
|
await rebuildDB("localOnlyWithChunks");
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
new Setting(containerMaintenanceEl)
|
||||||
|
.setName("Fetch rebuilt DB with all remote chunks")
|
||||||
|
.setDesc("Restore or reconstruct local database from remote database but use remote chunk .")
|
||||||
|
.addButton((button) =>
|
||||||
|
button
|
||||||
|
.setButtonText("Fetch all")
|
||||||
|
.setWarning()
|
||||||
|
.setDisabled(false)
|
||||||
.onClick(async () => {
|
.onClick(async () => {
|
||||||
await rebuildDB("localOnly");
|
await rebuildDB("localOnly");
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { type App, TFile, type DataWriteOptions, TFolder, TAbstractFile } from "./deps";
|
import { type App, TFile, type DataWriteOptions, TFolder, TAbstractFile } from "./deps";
|
||||||
import { serialized } from "./lib/src/lock";
|
import { serialized } from "./lib/src/lock";
|
||||||
|
import { Logger } from "./lib/src/logger";
|
||||||
import type { FilePath } from "./lib/src/types";
|
import type { FilePath } from "./lib/src/types";
|
||||||
import { createBinaryBlob, isDocContentSame } from "./lib/src/utils";
|
import { createBinaryBlob, isDocContentSame } from "./lib/src/utils";
|
||||||
import type { InternalFileInfo } from "./types";
|
import type { InternalFileInfo } from "./types";
|
||||||
@@ -107,6 +108,15 @@ export class SerializedFileAccess {
|
|||||||
return await processWriteFile(path, () => this.app.vault.createBinary(path, toArrayBuffer(data), options));
|
return await processWriteFile(path, () => this.app.vault.createBinary(path, toArrayBuffer(data), options));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trigger(name: string, ...data: any[]) {
|
||||||
|
return this.app.vault.trigger(name, ...data);
|
||||||
|
}
|
||||||
|
|
||||||
|
async adapterAppend(normalizedPath: string, data: string, options?: DataWriteOptions) {
|
||||||
|
return await this.app.vault.adapter.append(normalizedPath, data, options)
|
||||||
|
}
|
||||||
|
|
||||||
async delete(file: TFile | TFolder, force = false) {
|
async delete(file: TFile | TFolder, force = false) {
|
||||||
return await processWriteFile(file, () => this.app.vault.delete(file, force));
|
return await processWriteFile(file, () => this.app.vault.delete(file, force));
|
||||||
}
|
}
|
||||||
@@ -127,6 +137,31 @@ export class SerializedFileAccess {
|
|||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getFiles() {
|
||||||
|
return this.app.vault.getFiles();
|
||||||
|
}
|
||||||
|
|
||||||
|
async ensureDirectory(fullPath: string) {
|
||||||
|
const pathElements = fullPath.split("/");
|
||||||
|
pathElements.pop();
|
||||||
|
let c = "";
|
||||||
|
for (const v of pathElements) {
|
||||||
|
c += v;
|
||||||
|
try {
|
||||||
|
await this.app.vault.adapter.mkdir(c);
|
||||||
|
} catch (ex) {
|
||||||
|
// basically skip exceptions.
|
||||||
|
if (ex.message && ex.message == "Folder already exists.") {
|
||||||
|
// especially this message is.
|
||||||
|
} else {
|
||||||
|
Logger("Folder Create Error");
|
||||||
|
Logger(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c += "/";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
touchedFiles: string[] = [];
|
touchedFiles: string[] = [];
|
||||||
|
|
||||||
|
|||||||
2
src/lib
2
src/lib
Submodule src/lib updated: 1a3488339e...8a8177c1f0
168
src/main.ts
168
src/main.ts
@@ -84,7 +84,6 @@ export default class ObsidianLiveSyncPlugin extends Plugin
|
|||||||
this._suspended = value;
|
this._suspended = value;
|
||||||
}
|
}
|
||||||
deviceAndVaultName = "";
|
deviceAndVaultName = "";
|
||||||
isMobile = false;
|
|
||||||
isReady = false;
|
isReady = false;
|
||||||
packageVersion = "";
|
packageVersion = "";
|
||||||
manifestVersion = "";
|
manifestVersion = "";
|
||||||
@@ -248,6 +247,22 @@ export default class ObsidianLiveSyncPlugin extends Plugin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get isMobile() {
|
||||||
|
// @ts-ignore: internal API
|
||||||
|
return this.app.isMobile
|
||||||
|
}
|
||||||
|
|
||||||
|
get vaultName() {
|
||||||
|
return this.app.vault.getName()
|
||||||
|
}
|
||||||
|
getActiveFile() {
|
||||||
|
return this.app.workspace.getActiveFile();
|
||||||
|
}
|
||||||
|
|
||||||
|
get appId() {
|
||||||
|
return `${("appId" in this.app ? this.app.appId : "")}`;
|
||||||
|
}
|
||||||
|
|
||||||
id2path(id: DocumentID, entry?: EntryHasPath, stripPrefix?: boolean): FilePathWithPrefix {
|
id2path(id: DocumentID, entry?: EntryHasPath, stripPrefix?: boolean): FilePathWithPrefix {
|
||||||
const tempId = id2path(id, entry);
|
const tempId = id2path(id, entry);
|
||||||
if (stripPrefix && isInternalMetadata(tempId)) {
|
if (stripPrefix && isInternalMetadata(tempId)) {
|
||||||
@@ -309,13 +324,7 @@ export default class ObsidianLiveSyncPlugin extends Plugin
|
|||||||
// end interfaces
|
// end interfaces
|
||||||
|
|
||||||
getVaultName(): string {
|
getVaultName(): string {
|
||||||
return this.app.vault.getName() + (this.settings?.additionalSuffixOfDatabaseName ? ("-" + this.settings.additionalSuffixOfDatabaseName) : "");
|
return this.vaultName + (this.settings?.additionalSuffixOfDatabaseName ? ("-" + this.settings.additionalSuffixOfDatabaseName) : "");
|
||||||
}
|
|
||||||
|
|
||||||
setInterval(handler: () => any, timeout?: number): number {
|
|
||||||
const timer = window.setInterval(handler, timeout);
|
|
||||||
this.registerInterval(timer);
|
|
||||||
return timer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
isFlagFileExist(path: string) {
|
isFlagFileExist(path: string) {
|
||||||
@@ -361,7 +370,7 @@ export default class ObsidianLiveSyncPlugin extends Plugin
|
|||||||
}
|
}
|
||||||
notes.sort((a, b) => b.mtime - a.mtime);
|
notes.sort((a, b) => b.mtime - a.mtime);
|
||||||
const notesList = notes.map(e => e.dispPath);
|
const notesList = notes.map(e => e.dispPath);
|
||||||
const target = await askSelectString(this.app, "File to view History", notesList);
|
const target = await this.askSelectString("File to view History", notesList);
|
||||||
if (target) {
|
if (target) {
|
||||||
const targetId = notes.find(e => e.dispPath == target);
|
const targetId = notes.find(e => e.dispPath == target);
|
||||||
this.showHistory(targetId.path, targetId.id);
|
this.showHistory(targetId.path, targetId.id);
|
||||||
@@ -379,7 +388,7 @@ export default class ObsidianLiveSyncPlugin extends Plugin
|
|||||||
Logger("There are no conflicted documents", LOG_LEVEL_NOTICE);
|
Logger("There are no conflicted documents", LOG_LEVEL_NOTICE);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const target = await askSelectString(this.app, "File to resolve conflict", notesList);
|
const target = await this.askSelectString("File to resolve conflict", notesList);
|
||||||
if (target) {
|
if (target) {
|
||||||
const targetItem = notes.find(e => e.dispPath == target);
|
const targetItem = notes.find(e => e.dispPath == target);
|
||||||
this.resolveConflicted(targetItem.path);
|
this.resolveConflicted(targetItem.path);
|
||||||
@@ -458,10 +467,7 @@ Click anywhere to stop counting down.
|
|||||||
const ret = await confirmWithMessage(this, "Welcome to Self-hosted LiveSync", message, [USE_SETUP, OPEN_SETUP, DISMISS], DISMISS, 40);
|
const ret = await confirmWithMessage(this, "Welcome to Self-hosted LiveSync", message, [USE_SETUP, OPEN_SETUP, DISMISS], DISMISS, 40);
|
||||||
if (ret === OPEN_SETUP) {
|
if (ret === OPEN_SETUP) {
|
||||||
try {
|
try {
|
||||||
//@ts-ignore: undocumented api
|
this.openSetting();
|
||||||
this.app.setting.open();
|
|
||||||
//@ts-ignore: undocumented api
|
|
||||||
this.app.setting.openTabById("obsidian-livesync");
|
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
Logger("Something went wrong on opening setting dialog, please open it manually", LOG_LEVEL_NOTICE);
|
Logger("Something went wrong on opening setting dialog, please open it manually", LOG_LEVEL_NOTICE);
|
||||||
}
|
}
|
||||||
@@ -482,22 +488,20 @@ Click anywhere to stop counting down.
|
|||||||
Logger(`${FLAGMD_REDFLAG2} or ${FLAGMD_REDFLAG2_HR} has been detected! Self-hosted LiveSync suspends all sync and rebuild everything.`, LOG_LEVEL_NOTICE);
|
Logger(`${FLAGMD_REDFLAG2} or ${FLAGMD_REDFLAG2_HR} has been detected! Self-hosted LiveSync suspends all sync and rebuild everything.`, LOG_LEVEL_NOTICE);
|
||||||
await this.addOnSetup.rebuildEverything();
|
await this.addOnSetup.rebuildEverything();
|
||||||
await this.deleteRedFlag2();
|
await this.deleteRedFlag2();
|
||||||
if (await askYesNo(this.app, "Do you want to disable Suspend file watching and restart obsidian now?") == "yes") {
|
if (await this.askYesNo("Do you want to disable Suspend file watching and restart obsidian now?") == "yes") {
|
||||||
this.settings.suspendFileWatching = false;
|
this.settings.suspendFileWatching = false;
|
||||||
await this.saveSettings();
|
await this.saveSettings();
|
||||||
// @ts-ignore
|
this.performAppReload();
|
||||||
this.app.commands.executeCommandById("app:reload")
|
|
||||||
}
|
}
|
||||||
} else if (this.isRedFlag3Raised()) {
|
} else if (this.isRedFlag3Raised()) {
|
||||||
Logger(`${FLAGMD_REDFLAG3} or ${FLAGMD_REDFLAG3_HR} has been detected! Self-hosted LiveSync will discard the local database and fetch everything from the remote once again.`, LOG_LEVEL_NOTICE);
|
Logger(`${FLAGMD_REDFLAG3} or ${FLAGMD_REDFLAG3_HR} has been detected! Self-hosted LiveSync will discard the local database and fetch everything from the remote once again.`, LOG_LEVEL_NOTICE);
|
||||||
await this.addOnSetup.fetchLocal();
|
await this.addOnSetup.fetchLocal();
|
||||||
await this.deleteRedFlag3();
|
await this.deleteRedFlag3();
|
||||||
if (this.settings.suspendFileWatching) {
|
if (this.settings.suspendFileWatching) {
|
||||||
if (await askYesNo(this.app, "Do you want to disable Suspend file watching and restart obsidian now?") == "yes") {
|
if (await this.askYesNo("Do you want to disable Suspend file watching and restart obsidian now?") == "yes") {
|
||||||
this.settings.suspendFileWatching = false;
|
this.settings.suspendFileWatching = false;
|
||||||
await this.saveSettings();
|
await this.saveSettings();
|
||||||
// @ts-ignore
|
this.performAppReload();
|
||||||
this.app.commands.executeCommandById("app:reload")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -546,8 +550,7 @@ Click anywhere to stop counting down.
|
|||||||
this.askInPopup(`conflicting-detected-on-safety`, `Some files have been left conflicted! Press {HERE} to resolve them, or you can do it later by "Pick a file to resolve conflict`, (anchor) => {
|
this.askInPopup(`conflicting-detected-on-safety`, `Some files have been left conflicted! Press {HERE} to resolve them, or you can do it later by "Pick a file to resolve conflict`, (anchor) => {
|
||||||
anchor.text = "HERE";
|
anchor.text = "HERE";
|
||||||
anchor.addEventListener("click", () => {
|
anchor.addEventListener("click", () => {
|
||||||
// @ts-ignore
|
this.performCommand("obsidian-livesync:livesync-all-conflictcheck");
|
||||||
this.app.commands.executeCommandById("obsidian-livesync:livesync-all-conflictcheck");
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -629,7 +632,7 @@ Note: We can always able to read V1 format. It will be progressively converted.
|
|||||||
// this.localDatabase.getDBEntry(getPathFromTFile(file), {}, true, false);
|
// this.localDatabase.getDBEntry(getPathFromTFile(file), {}, true, false);
|
||||||
// },
|
// },
|
||||||
callback: () => {
|
callback: () => {
|
||||||
const file = this.app.workspace.getActiveFile();
|
const file = this.getActiveFile();
|
||||||
if (!file) return;
|
if (!file) return;
|
||||||
this.localDatabase.getDBEntry(getPathFromTFile(file), {}, true, false);
|
this.localDatabase.getDBEntry(getPathFromTFile(file), {}, true, false);
|
||||||
},
|
},
|
||||||
@@ -678,7 +681,7 @@ Note: We can always able to read V1 format. It will be progressively converted.
|
|||||||
id: "livesync-history",
|
id: "livesync-history",
|
||||||
name: "Show history",
|
name: "Show history",
|
||||||
callback: () => {
|
callback: () => {
|
||||||
const file = this.app.workspace.getActiveFile();
|
const file = this.getActiveFile();
|
||||||
if (file) this.showHistory(file, null);
|
if (file) this.showHistory(file, null);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -791,8 +794,7 @@ Note: We can always able to read V1 format. It will be progressively converted.
|
|||||||
}
|
}
|
||||||
|
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
if (this.app.isMobile) {
|
if (this.isMobile) {
|
||||||
this.isMobile = true;
|
|
||||||
this.settings.disableRequestURI = true;
|
this.settings.disableRequestURI = true;
|
||||||
}
|
}
|
||||||
if (last_version && Number(last_version) < VER) {
|
if (last_version && Number(last_version) < VER) {
|
||||||
@@ -869,8 +871,6 @@ Note: We can always able to read V1 format. It will be progressively converted.
|
|||||||
}
|
}
|
||||||
const vaultName = this.getVaultName();
|
const vaultName = this.getVaultName();
|
||||||
Logger("Waiting for ready...");
|
Logger("Waiting for ready...");
|
||||||
//@ts-ignore
|
|
||||||
this.isMobile = this.app.isMobile;
|
|
||||||
this.localDatabase = new LiveSyncLocalDB(vaultName, this);
|
this.localDatabase = new LiveSyncLocalDB(vaultName, this);
|
||||||
initializeStores(vaultName);
|
initializeStores(vaultName);
|
||||||
return await this.localDatabase.initializeDatabase();
|
return await this.localDatabase.initializeDatabase();
|
||||||
@@ -933,7 +933,7 @@ Note: We can always able to read V1 format. It will be progressively converted.
|
|||||||
if (JSON.stringify(settings) !== JSON.stringify(DEFAULT_SETTINGS)) {
|
if (JSON.stringify(settings) !== JSON.stringify(DEFAULT_SETTINGS)) {
|
||||||
settings.isConfigured = true;
|
settings.isConfigured = true;
|
||||||
} else {
|
} else {
|
||||||
settings.additionalSuffixOfDatabaseName = `${("appId" in this.app ? this.app.appId : "")}`
|
settings.additionalSuffixOfDatabaseName = this.appId;
|
||||||
settings.isConfigured = false;
|
settings.isConfigured = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1057,7 +1057,7 @@ Note: We can always able to read V1 format. It will be progressively converted.
|
|||||||
}
|
}
|
||||||
|
|
||||||
async parseSettingFromMarkdown(filename: string, data?: string) {
|
async parseSettingFromMarkdown(filename: string, data?: string) {
|
||||||
const file = this.app.vault.getAbstractFileByPath(filename);
|
const file = this.vaultAccess.getAbstractFileByPath(filename);
|
||||||
if (!(file instanceof TFile)) return {
|
if (!(file instanceof TFile)) return {
|
||||||
preamble: "",
|
preamble: "",
|
||||||
body: "",
|
body: "",
|
||||||
@@ -1066,7 +1066,7 @@ Note: We can always able to read V1 format. It will be progressively converted.
|
|||||||
if (data) {
|
if (data) {
|
||||||
return this.extractSettingFromWholeText(data);
|
return this.extractSettingFromWholeText(data);
|
||||||
}
|
}
|
||||||
const parseData = data ?? await this.app.vault.read(file);
|
const parseData = data ?? await this.vaultAccess.vaultRead(file);
|
||||||
return this.extractSettingFromWholeText(parseData);
|
return this.extractSettingFromWholeText(parseData);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1115,7 +1115,7 @@ Note: We can always able to read V1 format. It will be progressively converted.
|
|||||||
const APPLY_AND_REBUILD = "Apply settings and restart obsidian with red_flag_rebuild.md";
|
const APPLY_AND_REBUILD = "Apply settings and restart obsidian with red_flag_rebuild.md";
|
||||||
const APPLY_AND_FETCH = "Apply settings and restart obsidian with red_flag_fetch.md";
|
const APPLY_AND_FETCH = "Apply settings and restart obsidian with red_flag_fetch.md";
|
||||||
const CANCEL = "Cancel";
|
const CANCEL = "Cancel";
|
||||||
const result = await askSelectString(this.app, "Ready for apply the setting.", [APPLY_AND_RESTART, APPLY_ONLY, APPLY_AND_FETCH, APPLY_AND_REBUILD, CANCEL]);
|
const result = await this.askSelectString("Ready for apply the setting.", [APPLY_AND_RESTART, APPLY_ONLY, APPLY_AND_FETCH, APPLY_AND_REBUILD, CANCEL]);
|
||||||
if (result == APPLY_ONLY || result == APPLY_AND_RESTART || result == APPLY_AND_REBUILD || result == APPLY_AND_FETCH) {
|
if (result == APPLY_ONLY || result == APPLY_AND_RESTART || result == APPLY_AND_REBUILD || result == APPLY_AND_FETCH) {
|
||||||
this.settings = settingToApply;
|
this.settings = settingToApply;
|
||||||
await this.saveSettingData();
|
await this.saveSettingData();
|
||||||
@@ -1124,13 +1124,12 @@ Note: We can always able to read V1 format. It will be progressively converted.
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (result == APPLY_AND_REBUILD) {
|
if (result == APPLY_AND_REBUILD) {
|
||||||
await this.app.vault.create(FLAGMD_REDFLAG2_HR, "");
|
await this.vaultAccess.vaultCreate(FLAGMD_REDFLAG2_HR, "");
|
||||||
}
|
}
|
||||||
if (result == APPLY_AND_FETCH) {
|
if (result == APPLY_AND_FETCH) {
|
||||||
await this.app.vault.create(FLAGMD_REDFLAG3_HR, "");
|
await this.vaultAccess.vaultCreate(FLAGMD_REDFLAG3_HR, "");
|
||||||
}
|
}
|
||||||
// @ts-ignore
|
this.performAppReload();
|
||||||
this.app.commands.executeCommandById("app:reload");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@@ -1150,11 +1149,11 @@ Note: We can always able to read V1 format. It will be progressively converted.
|
|||||||
|
|
||||||
async saveSettingToMarkdown(filename: string) {
|
async saveSettingToMarkdown(filename: string) {
|
||||||
const saveData = this.generateSettingForMarkdown();
|
const saveData = this.generateSettingForMarkdown();
|
||||||
let file = this.app.vault.getAbstractFileByPath(filename);
|
let file = this.vaultAccess.getAbstractFileByPath(filename);
|
||||||
|
|
||||||
|
|
||||||
if (!file) {
|
if (!file) {
|
||||||
await this.ensureDirectoryEx(filename);
|
await this.vaultAccess.ensureDirectory(filename);
|
||||||
const initialContent = `This file contains Self-hosted LiveSync settings as YAML.
|
const initialContent = `This file contains Self-hosted LiveSync settings as YAML.
|
||||||
Except for the \`livesync-setting\` code block, we can add a note for free.
|
Except for the \`livesync-setting\` code block, we can add a note for free.
|
||||||
|
|
||||||
@@ -1167,21 +1166,21 @@ We can perform a command in this file.
|
|||||||
|
|
||||||
|
|
||||||
`
|
`
|
||||||
file = await this.app.vault.create(filename, initialContent + SETTING_HEADER + "\n" + SETTING_FOOTER);
|
file = await this.vaultAccess.vaultCreate(filename, initialContent + SETTING_HEADER + "\n" + SETTING_FOOTER);
|
||||||
}
|
}
|
||||||
if (!(file instanceof TFile)) {
|
if (!(file instanceof TFile)) {
|
||||||
Logger(`Markdown Setting: ${filename} already exists as a folder`, LOG_LEVEL_NOTICE);
|
Logger(`Markdown Setting: ${filename} already exists as a folder`, LOG_LEVEL_NOTICE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const data = await this.app.vault.read(file);
|
const data = await this.vaultAccess.vaultRead(file);
|
||||||
const { preamble, body, postscript } = this.extractSettingFromWholeText(data);
|
const { preamble, body, postscript } = this.extractSettingFromWholeText(data);
|
||||||
const newBody = stringifyYaml(saveData);
|
const newBody = stringifyYaml(saveData);
|
||||||
|
|
||||||
if (newBody == body) {
|
if (newBody == body) {
|
||||||
Logger("Markdown setting: Nothing had been changed", LOG_LEVEL_VERBOSE);
|
Logger("Markdown setting: Nothing had been changed", LOG_LEVEL_VERBOSE);
|
||||||
} else {
|
} else {
|
||||||
await this.app.vault.modify(file, preamble + SETTING_HEADER + newBody + SETTING_FOOTER + postscript);
|
await this.vaultAccess.vaultModify(file, preamble + SETTING_HEADER + newBody + SETTING_FOOTER + postscript);
|
||||||
Logger(`Markdown setting: ${filename} has been updated!`, LOG_LEVEL_VERBOSE);
|
Logger(`Markdown setting: ${filename} has been updated!`, LOG_LEVEL_VERBOSE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1224,8 +1223,7 @@ We can perform a command in this file.
|
|||||||
const _this = this;
|
const _this = this;
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
window.CodeMirrorAdapter.commands.save = () => {
|
window.CodeMirrorAdapter.commands.save = () => {
|
||||||
//@ts-ignore
|
_this.performCommand('editor:save-file');
|
||||||
_this.app.commands.executeCommandById('editor:save-file');
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
registerWatchEvents() {
|
registerWatchEvents() {
|
||||||
@@ -1235,7 +1233,6 @@ We can perform a command in this file.
|
|||||||
this.registerDomEvent(window, "offline", this.watchOnline);
|
this.registerDomEvent(window, "offline", this.watchOnline);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
watchOnline() {
|
watchOnline() {
|
||||||
scheduleTask("watch-online", 500, () => fireAndForget(() => this.watchOnlineAsync()));
|
scheduleTask("watch-online", 500, () => fireAndForget(() => this.watchOnlineAsync()));
|
||||||
}
|
}
|
||||||
@@ -1456,9 +1453,9 @@ We can perform a command in this file.
|
|||||||
const logDate = `${PREFIXMD_LOGFILE}${time}.md`;
|
const logDate = `${PREFIXMD_LOGFILE}${time}.md`;
|
||||||
const file = this.vaultAccess.getAbstractFileByPath(normalizePath(logDate));
|
const file = this.vaultAccess.getAbstractFileByPath(normalizePath(logDate));
|
||||||
if (!file) {
|
if (!file) {
|
||||||
this.app.vault.adapter.append(normalizePath(logDate), "```\n");
|
this.vaultAccess.adapterAppend(normalizePath(logDate), "```\n");
|
||||||
}
|
}
|
||||||
this.app.vault.adapter.append(normalizePath(logDate), vaultName + ":" + newMessage + "\n");
|
this.vaultAccess.adapterAppend(normalizePath(logDate), vaultName + ":" + newMessage + "\n");
|
||||||
}
|
}
|
||||||
recentLogProcessor.enqueue(newMessage);
|
recentLogProcessor.enqueue(newMessage);
|
||||||
|
|
||||||
@@ -1496,28 +1493,6 @@ We can perform a command in this file.
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async ensureDirectory(fullPath: string) {
|
|
||||||
const pathElements = fullPath.split("/");
|
|
||||||
pathElements.pop();
|
|
||||||
let c = "";
|
|
||||||
for (const v of pathElements) {
|
|
||||||
c += v;
|
|
||||||
try {
|
|
||||||
await this.app.vault.createFolder(c);
|
|
||||||
} catch (ex) {
|
|
||||||
// basically skip exceptions.
|
|
||||||
if (ex.message && ex.message == "Folder already exists.") {
|
|
||||||
// especially this message is.
|
|
||||||
} else {
|
|
||||||
Logger("Folder Create Error");
|
|
||||||
Logger(ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
c += "/";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async processEntryDoc(docEntry: EntryBody, file: TFile | undefined, force?: boolean) {
|
async processEntryDoc(docEntry: EntryBody, file: TFile | undefined, force?: boolean) {
|
||||||
const mode = file == undefined ? "create" : "modify";
|
const mode = file == undefined ? "create" : "modify";
|
||||||
|
|
||||||
@@ -1577,7 +1552,7 @@ We can perform a command in this file.
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const writeData = doc.datatype == "newnote" ? decodeBinary(doc.data) : getDocData(doc.data);
|
const writeData = doc.datatype == "newnote" ? decodeBinary(doc.data) : getDocData(doc.data);
|
||||||
await this.ensureDirectoryEx(path);
|
await this.vaultAccess.ensureDirectory(path);
|
||||||
try {
|
try {
|
||||||
let outFile;
|
let outFile;
|
||||||
let isChanged = true;
|
let isChanged = true;
|
||||||
@@ -1592,7 +1567,7 @@ We can perform a command in this file.
|
|||||||
if (isChanged) {
|
if (isChanged) {
|
||||||
Logger(msg + path);
|
Logger(msg + path);
|
||||||
this.vaultAccess.touch(outFile);
|
this.vaultAccess.touch(outFile);
|
||||||
this.app.vault.trigger(mode, outFile);
|
this.vaultAccess.trigger(mode, outFile);
|
||||||
} else {
|
} else {
|
||||||
Logger(msg + "Skipped, the file is the same: " + path, LOG_LEVEL_VERBOSE);
|
Logger(msg + "Skipped, the file is the same: " + path, LOG_LEVEL_VERBOSE);
|
||||||
}
|
}
|
||||||
@@ -1626,7 +1601,7 @@ We can perform a command in this file.
|
|||||||
queueConflictCheck(file: FilePathWithPrefix | TFile) {
|
queueConflictCheck(file: FilePathWithPrefix | TFile) {
|
||||||
const path = file instanceof TFile ? getPathFromTFile(file) : file;
|
const path = file instanceof TFile ? getPathFromTFile(file) : file;
|
||||||
if (this.settings.checkConflictOnlyOnOpen) {
|
if (this.settings.checkConflictOnlyOnOpen) {
|
||||||
const af = this.app.workspace.getActiveFile();
|
const af = this.getActiveFile();
|
||||||
if (af && af.path != path) {
|
if (af && af.path != path) {
|
||||||
Logger(`${file} is conflicted, merging process has been postponed.`, LOG_LEVEL_NOTICE);
|
Logger(`${file} is conflicted, merging process has been postponed.`, LOG_LEVEL_NOTICE);
|
||||||
return;
|
return;
|
||||||
@@ -1927,7 +1902,7 @@ Even if you choose to clean up, you will see this option again if you exit Obsid
|
|||||||
const CHOICE_DISMISS = "Dismiss";
|
const CHOICE_DISMISS = "Dismiss";
|
||||||
const ret = await confirmWithMessage(this, "Cleaned", message, [CHOICE_FETCH, CHOICE_CLEAN, CHOICE_DISMISS], CHOICE_DISMISS, 30);
|
const ret = await confirmWithMessage(this, "Cleaned", message, [CHOICE_FETCH, CHOICE_CLEAN, CHOICE_DISMISS], CHOICE_DISMISS, 30);
|
||||||
if (ret == CHOICE_FETCH) {
|
if (ret == CHOICE_FETCH) {
|
||||||
await performRebuildDB(this, "localOnly");
|
await performRebuildDB(this, "localOnlyWithChunks");
|
||||||
}
|
}
|
||||||
if (ret == CHOICE_CLEAN) {
|
if (ret == CHOICE_CLEAN) {
|
||||||
const remoteDB = await this.getReplicator().connectRemoteCouchDBWithSetting(this.settings, this.getIsMobile(), true);
|
const remoteDB = await this.getReplicator().connectRemoteCouchDBWithSetting(this.settings, this.getIsMobile(), true);
|
||||||
@@ -1961,7 +1936,7 @@ Or if you are sure know what had been happened, we can unlock the database from
|
|||||||
const CHOICE_DISMISS = "Dismiss";
|
const CHOICE_DISMISS = "Dismiss";
|
||||||
const ret = await confirmWithMessage(this, "Locked", message, [CHOICE_FETCH, CHOICE_DISMISS], CHOICE_DISMISS, 10);
|
const ret = await confirmWithMessage(this, "Locked", message, [CHOICE_FETCH, CHOICE_DISMISS], CHOICE_DISMISS, 10);
|
||||||
if (ret == CHOICE_FETCH) {
|
if (ret == CHOICE_FETCH) {
|
||||||
await performRebuildDB(this, "localOnly");
|
await performRebuildDB(this, "localOnlyWithChunks");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2036,7 +2011,7 @@ Or if you are sure know what had been happened, we can unlock the database from
|
|||||||
await this.collectDeletedFiles();
|
await this.collectDeletedFiles();
|
||||||
|
|
||||||
Logger("Collecting local files on the storage", LOG_LEVEL_VERBOSE);
|
Logger("Collecting local files on the storage", LOG_LEVEL_VERBOSE);
|
||||||
const filesStorageSrc = this.app.vault.getFiles();
|
const filesStorageSrc = this.vaultAccess.getFiles();
|
||||||
|
|
||||||
const filesStorage = [] as typeof filesStorageSrc;
|
const filesStorage = [] as typeof filesStorageSrc;
|
||||||
for (const f of filesStorageSrc) {
|
for (const f of filesStorageSrc) {
|
||||||
@@ -2534,7 +2509,7 @@ Or if you are sure know what had been happened, we can unlock the database from
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (this.settings.showMergeDialogOnlyOnActive) {
|
if (this.settings.showMergeDialogOnlyOnActive) {
|
||||||
const af = this.app.workspace.getActiveFile();
|
const af = this.getActiveFile();
|
||||||
if (af && af.path != filename) {
|
if (af && af.path != filename) {
|
||||||
Logger(`${filename} is conflicted. Merging process has been postponed to the file have got opened.`, LOG_LEVEL_NOTICE);
|
Logger(`${filename} is conflicted. Merging process has been postponed to the file have got opened.`, LOG_LEVEL_NOTICE);
|
||||||
return;
|
return;
|
||||||
@@ -2820,27 +2795,6 @@ Or if you are sure know what had been happened, we can unlock the database from
|
|||||||
await this.replicator.tryCreateRemoteDatabase(this.settings);
|
await this.replicator.tryCreateRemoteDatabase(this.settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
async ensureDirectoryEx(fullPath: string) {
|
|
||||||
const pathElements = fullPath.split("/");
|
|
||||||
pathElements.pop();
|
|
||||||
let c = "";
|
|
||||||
for (const v of pathElements) {
|
|
||||||
c += v;
|
|
||||||
try {
|
|
||||||
await this.app.vault.adapter.mkdir(c);
|
|
||||||
} catch (ex) {
|
|
||||||
// basically skip exceptions.
|
|
||||||
if (ex.message && ex.message == "Folder already exists.") {
|
|
||||||
// especially this message is.
|
|
||||||
} else {
|
|
||||||
Logger("Folder Create Error");
|
|
||||||
Logger(ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
c += "/";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
filterTargetFiles(files: InternalFileInfo[], targetFiles: string[] | false = false) {
|
filterTargetFiles(files: InternalFileInfo[], targetFiles: string[] | false = false) {
|
||||||
const ignorePatterns = this.settings.syncInternalFilesIgnorePatterns
|
const ignorePatterns = this.settings.syncInternalFilesIgnorePatterns
|
||||||
.replace(/\n| /g, "")
|
.replace(/\n| /g, "")
|
||||||
@@ -2949,6 +2903,12 @@ Or if you are sure know what had been happened, we can unlock the database from
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
askYesNo(message: string): Promise<"yes" | "no"> {
|
||||||
|
return askYesNo(this.app, message);
|
||||||
|
}
|
||||||
|
askSelectString(message: string, items: string[]): Promise<string> {
|
||||||
|
return askSelectString(this.app, message, items);
|
||||||
|
}
|
||||||
|
|
||||||
askInPopup(key: string, dialogText: string, anchorCallback: (anchor: HTMLAnchorElement) => void) {
|
askInPopup(key: string, dialogText: string, anchorCallback: (anchor: HTMLAnchorElement) => void) {
|
||||||
|
|
||||||
@@ -2967,7 +2927,6 @@ Or if you are sure know what had been happened, we can unlock the database from
|
|||||||
const popupKey = "popup-" + key;
|
const popupKey = "popup-" + key;
|
||||||
scheduleTask(popupKey, 1000, async () => {
|
scheduleTask(popupKey, 1000, async () => {
|
||||||
const popup = await memoIfNotExist(popupKey, () => new Notice(fragment, 0));
|
const popup = await memoIfNotExist(popupKey, () => new Notice(fragment, 0));
|
||||||
//@ts-ignore
|
|
||||||
const isShown = popup?.noticeEl?.isShown();
|
const isShown = popup?.noticeEl?.isShown();
|
||||||
if (!isShown) {
|
if (!isShown) {
|
||||||
memoObject(popupKey, new Notice(fragment, 0));
|
memoObject(popupKey, new Notice(fragment, 0));
|
||||||
@@ -2976,7 +2935,6 @@ Or if you are sure know what had been happened, we can unlock the database from
|
|||||||
const popup = retrieveMemoObject<Notice>(popupKey);
|
const popup = retrieveMemoObject<Notice>(popupKey);
|
||||||
if (!popup)
|
if (!popup)
|
||||||
return;
|
return;
|
||||||
//@ts-ignore
|
|
||||||
if (popup?.noticeEl?.isShown()) {
|
if (popup?.noticeEl?.isShown()) {
|
||||||
popup.hide();
|
popup.hide();
|
||||||
}
|
}
|
||||||
@@ -2984,5 +2942,19 @@ Or if you are sure know what had been happened, we can unlock the database from
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
openSetting() {
|
||||||
|
//@ts-ignore: undocumented api
|
||||||
|
this.app.setting.open();
|
||||||
|
//@ts-ignore: undocumented api
|
||||||
|
this.app.setting.openTabById("obsidian-livesync");
|
||||||
|
}
|
||||||
|
|
||||||
|
performAppReload() {
|
||||||
|
this.performCommand("app:reload");
|
||||||
|
}
|
||||||
|
performCommand(id: string) {
|
||||||
|
// @ts-ignore
|
||||||
|
this.app.commands.executeCommandById(id)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -405,10 +405,13 @@ export const requestToCouchDB = async (baseUri: string, username: string, passwo
|
|||||||
return await _requestToCouchDB(baseUri, username, password, origin, uri, body, method);
|
return await _requestToCouchDB(baseUri, username, password, origin, uri, body, method);
|
||||||
};
|
};
|
||||||
|
|
||||||
export async function performRebuildDB(plugin: ObsidianLiveSyncPlugin, method: "localOnly" | "remoteOnly" | "rebuildBothByThisDevice") {
|
export async function performRebuildDB(plugin: ObsidianLiveSyncPlugin, method: "localOnly" | "remoteOnly" | "rebuildBothByThisDevice" | "localOnlyWithChunks") {
|
||||||
if (method == "localOnly") {
|
if (method == "localOnly") {
|
||||||
await plugin.addOnSetup.fetchLocal();
|
await plugin.addOnSetup.fetchLocal();
|
||||||
}
|
}
|
||||||
|
if (method == "localOnlyWithChunks") {
|
||||||
|
await plugin.addOnSetup.fetchLocal(true);
|
||||||
|
}
|
||||||
if (method == "remoteOnly") {
|
if (method == "remoteOnly") {
|
||||||
await plugin.addOnSetup.rebuildRemote();
|
await plugin.addOnSetup.rebuildRemote();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user