mirror of
https://github.com/vrtmrz/obsidian-livesync.git
synced 2026-10-28 03:53:20 +00:00
- 0.24.7
- Fixed (Security)
- Assigning IDs to chunks has been corrected for more safety.
- Fixed
- Conflict resolution dialogue has been fixed
- Resolving conflicts by timestamp has been fixed
- Improved
- Notifications can be suppressed for the hidden files update now.
- No longer uses the old-xxhash and sha1 for generating the chunk ID.
This commit is contained in:
1 parent
4b1fff852a
commit
7f853b0222
10 files changed
+99
-59
No files matched your search
Generated
+9
-24
@@ -18,9 +18,8 @@
|
|||||||
"fflate": "^0.8.2",
|
"fflate": "^0.8.2",
|
||||||
"idb": "^8.0.0",
|
"idb": "^8.0.0",
|
||||||
"minimatch": "^10.0.1",
|
"minimatch": "^10.0.1",
|
||||||
"octagonal-wheels": "^0.1.20",
|
"octagonal-wheels": "^0.1.21",
|
||||||
"svelte-check": "^4.0.4",
|
"svelte-check": "^4.0.4",
|
||||||
"xxhash-wasm": "0.4.2",
|
|
||||||
"xxhash-wasm-102": "npm:xxhash-wasm@^1.0.2"
|
"xxhash-wasm-102": "npm:xxhash-wasm@^1.0.2"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@@ -5105,13 +5104,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/octagonal-wheels": {
|
"node_modules/octagonal-wheels": {
|
||||||
"version": "0.1.20",
|
"version": "0.1.21",
|
||||||
"resolved": "https://registry.npmjs.org/octagonal-wheels/-/octagonal-wheels-0.1.20.tgz",
|
"resolved": "https://registry.npmjs.org/octagonal-wheels/-/octagonal-wheels-0.1.21.tgz",
|
||||||
"integrity": "sha512-cHM0UroCsZUZ/u0CA+DTOeasH2lPd8kkrfUiIFzg0d51ANY5KDJNk70rHoJbdph7+npNYgKSsdl1D3fEkzggFQ==",
|
"integrity": "sha512-yJYzli50IwXW1ARgVnHR8LpudhRay0pfkSYJyyxqDuk0WM8hbeWDWLtlB/77xga8WsqW1HnZZP/8LfyZYVg1ew==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"idb": "^8.0.0",
|
"idb": "^8.0.0"
|
||||||
"xxhash-wasm": "0.4.2",
|
|
||||||
"xxhash-wasm-102": "npm:xxhash-wasm@^1.0.2"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/once": {
|
"node_modules/once": {
|
||||||
@@ -6631,11 +6628,6 @@
|
|||||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
|
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/xxhash-wasm": {
|
|
||||||
"version": "0.4.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/xxhash-wasm/-/xxhash-wasm-0.4.2.tgz",
|
|
||||||
"integrity": "sha512-/eyHVRJQCirEkSZ1agRSCwriMhwlyUcFkXD5TPVSLP+IPzjsqMVzZwdoczLp1SoQU0R3dxz1RpIK+4YNQbCVOA=="
|
|
||||||
},
|
|
||||||
"node_modules/xxhash-wasm-102": {
|
"node_modules/xxhash-wasm-102": {
|
||||||
"name": "xxhash-wasm",
|
"name": "xxhash-wasm",
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
@@ -10316,13 +10308,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"octagonal-wheels": {
|
"octagonal-wheels": {
|
||||||
"version": "0.1.20",
|
"version": "0.1.21",
|
||||||
"resolved": "https://registry.npmjs.org/octagonal-wheels/-/octagonal-wheels-0.1.20.tgz",
|
"resolved": "https://registry.npmjs.org/octagonal-wheels/-/octagonal-wheels-0.1.21.tgz",
|
||||||
"integrity": "sha512-cHM0UroCsZUZ/u0CA+DTOeasH2lPd8kkrfUiIFzg0d51ANY5KDJNk70rHoJbdph7+npNYgKSsdl1D3fEkzggFQ==",
|
"integrity": "sha512-yJYzli50IwXW1ARgVnHR8LpudhRay0pfkSYJyyxqDuk0WM8hbeWDWLtlB/77xga8WsqW1HnZZP/8LfyZYVg1ew==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"idb": "^8.0.0",
|
"idb": "^8.0.0"
|
||||||
"xxhash-wasm": "0.4.2",
|
|
||||||
"xxhash-wasm-102": "npm:xxhash-wasm@^1.0.2"
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"once": {
|
"once": {
|
||||||
@@ -11427,11 +11417,6 @@
|
|||||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
|
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"xxhash-wasm": {
|
|
||||||
"version": "0.4.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/xxhash-wasm/-/xxhash-wasm-0.4.2.tgz",
|
|
||||||
"integrity": "sha512-/eyHVRJQCirEkSZ1agRSCwriMhwlyUcFkXD5TPVSLP+IPzjsqMVzZwdoczLp1SoQU0R3dxz1RpIK+4YNQbCVOA=="
|
|
||||||
},
|
|
||||||
"xxhash-wasm-102": {
|
"xxhash-wasm-102": {
|
||||||
"version": "npm:xxhash-wasm@1.0.2",
|
"version": "npm:xxhash-wasm@1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/xxhash-wasm/-/xxhash-wasm-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/xxhash-wasm/-/xxhash-wasm-1.0.2.tgz",
|
||||||
|
|||||||
+1
-2
@@ -72,9 +72,8 @@
|
|||||||
"fflate": "^0.8.2",
|
"fflate": "^0.8.2",
|
||||||
"idb": "^8.0.0",
|
"idb": "^8.0.0",
|
||||||
"minimatch": "^10.0.1",
|
"minimatch": "^10.0.1",
|
||||||
"octagonal-wheels": "^0.1.20",
|
"octagonal-wheels": "^0.1.21",
|
||||||
"svelte-check": "^4.0.4",
|
"svelte-check": "^4.0.4",
|
||||||
"xxhash-wasm": "0.4.2",
|
|
||||||
"xxhash-wasm-102": "npm:xxhash-wasm@^1.0.2"
|
"xxhash-wasm-102": "npm:xxhash-wasm@^1.0.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -85,6 +85,7 @@ export function getStoragePathFromUXFileInfo(file: UXFileInfoStub | string | Fil
|
|||||||
return stripAllPrefixes(file.path);
|
return stripAllPrefixes(file.path);
|
||||||
}
|
}
|
||||||
export function getDatabasePathFromUXFileInfo(file: UXFileInfoStub | string | FilePathWithPrefix) {
|
export function getDatabasePathFromUXFileInfo(file: UXFileInfoStub | string | FilePathWithPrefix) {
|
||||||
|
if (typeof file == "string" && file.startsWith(ICXHeader)) return file as FilePathWithPrefix;
|
||||||
const prefix = isInternalFile(file) ? ICHeader : "";
|
const prefix = isInternalFile(file) ? ICHeader : "";
|
||||||
if (typeof file == "string") return (prefix + stripAllPrefixes(file as FilePathWithPrefix)) as FilePathWithPrefix;
|
if (typeof file == "string") return (prefix + stripAllPrefixes(file as FilePathWithPrefix)) as FilePathWithPrefix;
|
||||||
return (prefix + stripAllPrefixes(file.path)) as FilePathWithPrefix;
|
return (prefix + stripAllPrefixes(file.path)) as FilePathWithPrefix;
|
||||||
|
|||||||
@@ -154,7 +154,7 @@ export class HiddenFileSync extends LiveSyncCommands implements IObsidianModule
|
|||||||
this.settings.syncInternalFilesBeforeReplication &&
|
this.settings.syncInternalFilesBeforeReplication &&
|
||||||
!this.settings.watchInternalFileChanges
|
!this.settings.watchInternalFileChanges
|
||||||
) {
|
) {
|
||||||
await this.scanAllStorageChanges();
|
await this.scanAllStorageChanges(showNotice);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1108,6 +1108,9 @@ Offline Changed files: ${files.length}`;
|
|||||||
}
|
}
|
||||||
|
|
||||||
queueNotification(key: FilePath) {
|
queueNotification(key: FilePath) {
|
||||||
|
if (this.settings.suppressNotifyHiddenFilesChange) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
const configDir = this.plugin.app.vault.configDir;
|
const configDir = this.plugin.app.vault.configDir;
|
||||||
if (!key.startsWith(configDir)) return;
|
if (!key.startsWith(configDir)) return;
|
||||||
const dirName = key.split("/").slice(0, -1).join("/");
|
const dirName = key.split("/").slice(0, -1).join("/");
|
||||||
|
|||||||
+1
-1
Submodule src/lib updated: b299a4255c...89e825ef3b.
@@ -22,6 +22,7 @@ import { getDocDataAsArray, isDocContentSame, readContent } from "../../lib/src/
|
|||||||
import { shouldBeIgnored } from "../../lib/src/string_and_binary/path";
|
import { shouldBeIgnored } from "../../lib/src/string_and_binary/path";
|
||||||
import type { ICoreModule } from "../ModuleTypes";
|
import type { ICoreModule } from "../ModuleTypes";
|
||||||
import { Semaphore } from "octagonal-wheels/concurrency/semaphore";
|
import { Semaphore } from "octagonal-wheels/concurrency/semaphore";
|
||||||
|
import { eventHub } from "../../common/events.ts";
|
||||||
|
|
||||||
export class ModuleFileHandler extends AbstractModule implements ICoreModule {
|
export class ModuleFileHandler extends AbstractModule implements ICoreModule {
|
||||||
get db() {
|
get db() {
|
||||||
@@ -356,6 +357,8 @@ export class ModuleFileHandler extends AbstractModule implements ICoreModule {
|
|||||||
`Processing ${path} (${entry._id.substring(0, 8)}: ${entry._rev?.substring(0, 5)}) :Started...`,
|
`Processing ${path} (${entry._id.substring(0, 8)}: ${entry._rev?.substring(0, 5)}) :Started...`,
|
||||||
LOG_LEVEL_VERBOSE
|
LOG_LEVEL_VERBOSE
|
||||||
);
|
);
|
||||||
|
// Before writing (or skipped ), merging dialogue should be cancelled.
|
||||||
|
eventHub.emitEvent("conflict-cancelled", path);
|
||||||
const ret = await this.dbToStorage(entry, targetFile);
|
const ret = await this.dbToStorage(entry, targetFile);
|
||||||
this._log(`Processing ${path} (${entry._id.substring(0, 8)} :${entry._rev?.substring(0, 5)}) : Done`);
|
this._log(`Processing ${path} (${entry._id.substring(0, 8)} :${entry._rev?.substring(0, 5)}) : Done`);
|
||||||
return ret;
|
return ret;
|
||||||
|
|||||||
@@ -11,10 +11,23 @@ import {
|
|||||||
type diff_check_result,
|
type diff_check_result,
|
||||||
type FilePathWithPrefix,
|
type FilePathWithPrefix,
|
||||||
} from "../../lib/src/common/types";
|
} from "../../lib/src/common/types";
|
||||||
import { compareMTime, displayRev, TARGET_IS_NEW } from "../../common/utils";
|
import {
|
||||||
|
compareMTime,
|
||||||
|
displayRev,
|
||||||
|
isCustomisationSyncMetadata,
|
||||||
|
isPluginMetadata,
|
||||||
|
TARGET_IS_NEW,
|
||||||
|
} from "../../common/utils";
|
||||||
import diff_match_patch from "diff-match-patch";
|
import diff_match_patch from "diff-match-patch";
|
||||||
import { stripAllPrefixes, isPlainText } from "../../lib/src/string_and_binary/path";
|
import { stripAllPrefixes, isPlainText } from "../../lib/src/string_and_binary/path";
|
||||||
import type { ICoreModule } from "../ModuleTypes.ts";
|
import type { ICoreModule } from "../ModuleTypes.ts";
|
||||||
|
import { eventHub } from "../../common/events.ts";
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface LSEvents {
|
||||||
|
"conflict-cancelled": FilePathWithPrefix;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class ModuleConflictResolver extends AbstractModule implements ICoreModule {
|
export class ModuleConflictResolver extends AbstractModule implements ICoreModule {
|
||||||
async $$resolveConflictByDeletingRev(
|
async $$resolveConflictByDeletingRev(
|
||||||
@@ -30,11 +43,16 @@ export class ModuleConflictResolver extends AbstractModule implements ICoreModul
|
|||||||
);
|
);
|
||||||
return MISSING_OR_ERROR;
|
return MISSING_OR_ERROR;
|
||||||
}
|
}
|
||||||
|
eventHub.emitEvent("conflict-cancelled", path);
|
||||||
this._log(`${title} Conflicted revision deleted ${displayRev(deleteRevision)} ${path}`, LOG_LEVEL_INFO);
|
this._log(`${title} Conflicted revision deleted ${displayRev(deleteRevision)} ${path}`, LOG_LEVEL_INFO);
|
||||||
if ((await this.core.databaseFileAccess.getConflictedRevs(path)).length != 0) {
|
if ((await this.core.databaseFileAccess.getConflictedRevs(path)).length != 0) {
|
||||||
this._log(`${title} some conflicts are left in ${path}`, LOG_LEVEL_INFO);
|
this._log(`${title} some conflicts are left in ${path}`, LOG_LEVEL_INFO);
|
||||||
return AUTO_MERGED;
|
return AUTO_MERGED;
|
||||||
}
|
}
|
||||||
|
this._log(`${title} ${path} is a plugin metadata file, no need to write to storage`, LOG_LEVEL_INFO);
|
||||||
|
if (isPluginMetadata(path) || isCustomisationSyncMetadata(path)) {
|
||||||
|
return AUTO_MERGED;
|
||||||
|
}
|
||||||
// If no conflicts were found, write the resolved content to the storage.
|
// If no conflicts were found, write the resolved content to the storage.
|
||||||
if (!(await this.core.fileHandler.dbToStorage(path, stripAllPrefixes(path), true))) {
|
if (!(await this.core.fileHandler.dbToStorage(path, stripAllPrefixes(path), true))) {
|
||||||
this._log(`Could not write the resolved content to the storage: ${path}`, LOG_LEVEL_NOTICE);
|
this._log(`Could not write the resolved content to the storage: ${path}`, LOG_LEVEL_NOTICE);
|
||||||
@@ -139,26 +157,42 @@ export class ModuleConflictResolver extends AbstractModule implements ICoreModul
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
this._log("[conflict] Manual merge required!");
|
this._log("[conflict] Manual merge required!");
|
||||||
|
eventHub.emitEvent("conflict-cancelled", filename);
|
||||||
await this.core.$anyResolveConflictByUI(filename, conflictCheckResult);
|
await this.core.$anyResolveConflictByUI(filename, conflictCheckResult);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async $anyResolveConflictByNewest(filename: FilePathWithPrefix): Promise<boolean> {
|
async $anyResolveConflictByNewest(filename: FilePathWithPrefix): Promise<boolean> {
|
||||||
|
const currentRev = await this.core.databaseFileAccess.fetchEntryMeta(filename, undefined, true);
|
||||||
|
if (currentRev == false) {
|
||||||
|
this._log(`Could not get current revision of ${filename}`);
|
||||||
|
return Promise.resolve(false);
|
||||||
|
}
|
||||||
const revs = await this.core.databaseFileAccess.getConflictedRevs(filename);
|
const revs = await this.core.databaseFileAccess.getConflictedRevs(filename);
|
||||||
if (revs.length == 0) {
|
if (revs.length == 0) {
|
||||||
return Promise.resolve(true);
|
return Promise.resolve(true);
|
||||||
}
|
}
|
||||||
const mTimeAndRev = (
|
const mTimeAndRev = (
|
||||||
await Promise.all(
|
[
|
||||||
revs.map(async (rev) => {
|
[currentRev.mtime, currentRev._rev],
|
||||||
const leaf = await this.core.databaseFileAccess.fetchEntryMeta(filename, rev);
|
...(await Promise.all(
|
||||||
if (leaf == false) {
|
revs.map(async (rev) => {
|
||||||
return [0, rev] as [number, string];
|
const leaf = await this.core.databaseFileAccess.fetchEntryMeta(filename, rev);
|
||||||
}
|
if (leaf == false) {
|
||||||
return [leaf.mtime, rev] as [number, string];
|
return [0, rev] as [number, string];
|
||||||
})
|
}
|
||||||
)
|
return [leaf.mtime, rev] as [number, string];
|
||||||
).sort((a, b) => b[0] - a[0]);
|
})
|
||||||
|
)),
|
||||||
|
] as [number, string][]
|
||||||
|
).sort((a, b) => {
|
||||||
|
const diff = b[0] - a[0];
|
||||||
|
if (diff == 0) {
|
||||||
|
return a[1].localeCompare(b[1], "en", { numeric: true });
|
||||||
|
}
|
||||||
|
return diff;
|
||||||
|
});
|
||||||
|
console.warn(mTimeAndRev);
|
||||||
this._log(
|
this._log(
|
||||||
`Resolving conflict by newest: ${filename} (Newest: ${new Date(mTimeAndRev[0][0]).toLocaleString()}) (${mTimeAndRev.length} revisions exists)`
|
`Resolving conflict by newest: ${filename} (Newest: ${new Date(mTimeAndRev[0][0]).toLocaleString()}) (${mTimeAndRev.length} revisions exists)`
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,10 +1,19 @@
|
|||||||
import { App, Modal } from "../../../deps.ts";
|
import { App, Modal } from "../../../deps.ts";
|
||||||
import { DIFF_DELETE, DIFF_EQUAL, DIFF_INSERT } from "diff-match-patch";
|
import { DIFF_DELETE, DIFF_EQUAL, DIFF_INSERT } from "diff-match-patch";
|
||||||
import { CANCELLED, LEAVE_TO_SUBSEQUENT, RESULT_TIMED_OUT, type diff_result } from "../../../lib/src/common/types.ts";
|
import { CANCELLED, LEAVE_TO_SUBSEQUENT, type diff_result } from "../../../lib/src/common/types.ts";
|
||||||
import { escapeStringToHTML } from "../../../lib/src/string_and_binary/convert.ts";
|
import { escapeStringToHTML } from "../../../lib/src/string_and_binary/convert.ts";
|
||||||
import { delay, fireAndForget, sendValue, waitForValue } from "../../../lib/src/common/utils.ts";
|
import { delay } from "../../../lib/src/common/utils.ts";
|
||||||
|
import { eventHub } from "../../../common/events.ts";
|
||||||
|
import { globalSlipBoard } from "../../../lib/src/bureau/bureau.ts";
|
||||||
|
|
||||||
|
export type MergeDialogResult = typeof CANCELLED | typeof LEAVE_TO_SUBSEQUENT | string;
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface Slips extends LSSlips {
|
||||||
|
"conflict-resolved": typeof CANCELLED | MergeDialogResult;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export type MergeDialogResult = typeof LEAVE_TO_SUBSEQUENT | typeof CANCELLED | string;
|
|
||||||
export class ConflictResolveModal extends Modal {
|
export class ConflictResolveModal extends Modal {
|
||||||
result: diff_result;
|
result: diff_result;
|
||||||
filename: string;
|
filename: string;
|
||||||
@@ -18,6 +27,7 @@ export class ConflictResolveModal extends Modal {
|
|||||||
pluginPickMode: boolean = false;
|
pluginPickMode: boolean = false;
|
||||||
localName: string = "Keep A";
|
localName: string = "Keep A";
|
||||||
remoteName: string = "Keep B";
|
remoteName: string = "Keep B";
|
||||||
|
offEvent?: ReturnType<typeof eventHub.onEvent>;
|
||||||
|
|
||||||
constructor(app: App, filename: string, diff: diff_result, pluginPickMode?: boolean, remoteName?: string) {
|
constructor(app: App, filename: string, diff: diff_result, pluginPickMode?: boolean, remoteName?: string) {
|
||||||
super(app);
|
super(app);
|
||||||
@@ -32,23 +42,21 @@ export class ConflictResolveModal extends Modal {
|
|||||||
// Send cancel signal for the previous merge dialogue
|
// Send cancel signal for the previous merge dialogue
|
||||||
// if not there, simply be ignored.
|
// if not there, simply be ignored.
|
||||||
// sendValue("close-resolve-conflict:" + this.filename, false);
|
// sendValue("close-resolve-conflict:" + this.filename, false);
|
||||||
sendValue("cancel-resolve-conflict:" + this.filename, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onOpen() {
|
onOpen() {
|
||||||
const { contentEl } = this;
|
const { contentEl } = this;
|
||||||
// Send cancel signal for the previous merge dialogue
|
// Send cancel signal for the previous merge dialogue
|
||||||
// if not there, simply be ignored.
|
// if not there, simply be ignored.
|
||||||
sendValue("cancel-resolve-conflict:" + this.filename, true);
|
globalSlipBoard.submit("conflict-resolved", this.filename, CANCELLED);
|
||||||
setTimeout(() => {
|
if (this.offEvent) {
|
||||||
fireAndForget(async () => {
|
this.offEvent();
|
||||||
const forceClose = await waitForValue("cancel-resolve-conflict:" + this.filename);
|
}
|
||||||
// debugger;
|
this.offEvent = eventHub.onEvent("conflict-cancelled", (path) => {
|
||||||
if (forceClose) {
|
if (path === this.filename) {
|
||||||
this.sendResponse(CANCELLED);
|
this.sendResponse(CANCELLED);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}, 10);
|
|
||||||
// sendValue("close-resolve-conflict:" + this.filename, false);
|
// sendValue("close-resolve-conflict:" + this.filename, false);
|
||||||
this.titleEl.setText(this.title);
|
this.titleEl.setText(this.title);
|
||||||
contentEl.empty();
|
contentEl.empty();
|
||||||
@@ -111,18 +119,19 @@ export class ConflictResolveModal extends Modal {
|
|||||||
onClose() {
|
onClose() {
|
||||||
const { contentEl } = this;
|
const { contentEl } = this;
|
||||||
contentEl.empty();
|
contentEl.empty();
|
||||||
|
if (this.offEvent) {
|
||||||
|
this.offEvent();
|
||||||
|
}
|
||||||
if (this.consumed) {
|
if (this.consumed) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.consumed = true;
|
this.consumed = true;
|
||||||
sendValue("close-resolve-conflict:" + this.filename, this.response);
|
globalSlipBoard.submit("conflict-resolved", this.filename, this.response);
|
||||||
sendValue("cancel-resolve-conflict:" + this.filename, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async waitForResult(): Promise<MergeDialogResult> {
|
async waitForResult(): Promise<MergeDialogResult> {
|
||||||
await delay(100);
|
await delay(100);
|
||||||
const r = await waitForValue<MergeDialogResult>("close-resolve-conflict:" + this.filename);
|
const r = await globalSlipBoard.awaitNext("conflict-resolved", this.filename);
|
||||||
if (r === RESULT_TIMED_OUT) return CANCELLED;
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1909,6 +1909,7 @@ I appreciate you for your great dedication.
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
new Setting(paneEl).setClass("wizardHidden").autoWireToggle("suppressNotifyHiddenFilesChange", {});
|
||||||
new Setting(paneEl).setClass("wizardHidden").autoWireToggle("syncInternalFilesBeforeReplication", {
|
new Setting(paneEl).setClass("wizardHidden").autoWireToggle("syncInternalFilesBeforeReplication", {
|
||||||
onUpdate: visibleOnly(() => this.isConfiguredAs("watchInternalFileChanges", true)),
|
onUpdate: visibleOnly(() => this.isConfiguredAs("watchInternalFileChanges", true)),
|
||||||
});
|
});
|
||||||
@@ -2748,9 +2749,10 @@ ${stringifyYaml(pluginConfig)}`;
|
|||||||
new Setting(paneEl).autoWireDropDown("hashAlg", {
|
new Setting(paneEl).autoWireDropDown("hashAlg", {
|
||||||
options: {
|
options: {
|
||||||
"": "Old Algorithm",
|
"": "Old Algorithm",
|
||||||
xxhash32: "xxhash32 (Fast)",
|
xxhash32: "xxhash32 (Fast but less collision resistance)",
|
||||||
xxhash64: "xxhash64 (Fastest)",
|
xxhash64: "xxhash64 (Fastest)",
|
||||||
sha1: "Fallback (Without WebAssembly)",
|
"mixed-purejs": "PureJS fallback (Fast, W/O WebAssembly)",
|
||||||
|
sha1: "Older fallback (Slow, W/O WebAssembly)",
|
||||||
} as Record<HashAlgorithm, string>,
|
} as Record<HashAlgorithm, string>,
|
||||||
});
|
});
|
||||||
this.addOnSaved("hashAlg", async () => {
|
this.addOnSaved("hashAlg", async () => {
|
||||||
|
|||||||
@@ -369,6 +369,10 @@ export const SettingInformation: Partial<Record<keyof AllSettings, Configuration
|
|||||||
name: "Enable Developers' Debug Tools.",
|
name: "Enable Developers' Debug Tools.",
|
||||||
desc: "Requires restart of Obsidian",
|
desc: "Requires restart of Obsidian",
|
||||||
},
|
},
|
||||||
|
suppressNotifyHiddenFilesChange: {
|
||||||
|
name: "Suppress notification of hidden files change",
|
||||||
|
desc: "If enabled, the notification of hidden files change will be suppressed.",
|
||||||
|
},
|
||||||
};
|
};
|
||||||
function translateInfo(infoSrc: ConfigurationItem | undefined | false) {
|
function translateInfo(infoSrc: ConfigurationItem | undefined | false) {
|
||||||
if (!infoSrc) return false;
|
if (!infoSrc) return false;
|
||||||
|
|||||||
Reference in new issue
Block a user