mirror of
https://github.com/vrtmrz/obsidian-livesync.git
synced 2026-10-21 16:52:32 +00:00
Merge current main into configuration encryption fixes
This commit is contained in:
@@ -3,6 +3,7 @@ import { EVENT_REQUEST_OPEN_PLUGIN_SYNC_DIALOG, eventHub } from "@/common/events
|
||||
import type { ObsidianLiveSyncSettingTab } from "./ObsidianLiveSyncSettingTab.ts";
|
||||
import type { PageFunctions } from "./SettingPane.ts";
|
||||
import { enableOnly, visibleOnly } from "./SettingPane.ts";
|
||||
import { $msg } from "@/common/translation";
|
||||
export function paneCustomisationSync(
|
||||
this: ObsidianLiveSyncSettingTab,
|
||||
paneEl: HTMLElement,
|
||||
@@ -10,7 +11,7 @@ export function paneCustomisationSync(
|
||||
): void {
|
||||
// With great respect, thank you TfTHacker!
|
||||
// Refer: https://github.com/TfTHacker/obsidian42-brat/blob/main/src/features/BetaPlugins.ts
|
||||
void addPanel(paneEl, "Customization Sync").then((paneEl) => {
|
||||
void addPanel(paneEl, $msg("Customization Sync")).then((paneEl) => {
|
||||
const enableOnlyOnPluginSyncIsNotEnabled = enableOnly(() => this.isConfiguredAs("usePluginSync", false));
|
||||
const visibleOnlyOnPluginSyncEnabled = visibleOnly(() => this.isConfiguredAs("usePluginSync", true));
|
||||
|
||||
@@ -18,7 +19,9 @@ export function paneCustomisationSync(
|
||||
paneEl,
|
||||
"div",
|
||||
{
|
||||
text: "Please set device name to identify this device. This name should be unique among your devices. While not configured, we cannot enable this feature.",
|
||||
text: $msg(
|
||||
"Please set device name to identify this device. This name should be unique among your devices. While not configured, we cannot enable this feature."
|
||||
),
|
||||
cls: "op-warn",
|
||||
},
|
||||
(c) => {},
|
||||
@@ -28,7 +31,9 @@ export function paneCustomisationSync(
|
||||
paneEl,
|
||||
"div",
|
||||
{
|
||||
text: "We cannot change the device name while this feature is enabled. Please disable this feature to change the device name.",
|
||||
text: $msg(
|
||||
"We cannot change the device name while this feature is enabled. Please disable this feature to change the device name."
|
||||
),
|
||||
cls: "op-warn-info",
|
||||
},
|
||||
(c) => {},
|
||||
@@ -60,11 +65,11 @@ export function paneCustomisationSync(
|
||||
});
|
||||
|
||||
new Setting(paneEl)
|
||||
.setName("Open")
|
||||
.setDesc("Open the dialog")
|
||||
.setName($msg("Open"))
|
||||
.setDesc($msg("Open the dialog"))
|
||||
.addButton((button) => {
|
||||
button
|
||||
.setButtonText("Open")
|
||||
.setButtonText($msg("Open"))
|
||||
.setDisabled(false)
|
||||
.onClick(() => {
|
||||
// this.plugin.getAddOn<ConfigSync>(ConfigSync.name)?.showPluginSyncModal();
|
||||
|
||||
@@ -83,7 +83,7 @@ export function paneHatch(this: ObsidianLiveSyncSettingTab, paneEl: HTMLElement,
|
||||
.setDesc($msg("Setting.TroubleShooting.ScanBrokenFiles.Desc"))
|
||||
.addButton((button) =>
|
||||
button
|
||||
.setButtonText("Scan for Broken files")
|
||||
.setButtonText($msg("Scan for Broken files"))
|
||||
.setCta()
|
||||
.setDisabled(false)
|
||||
.onClick(() => {
|
||||
@@ -136,7 +136,7 @@ export function paneHatch(this: ObsidianLiveSyncSettingTab, paneEl: HTMLElement,
|
||||
new Setting(paneEl).autoWireToggle("writeLogToTheFile");
|
||||
});
|
||||
|
||||
void addPanel(paneEl, "Scram Switches").then((paneEl) => {
|
||||
void addPanel(paneEl, $msg("Scram Switches")).then((paneEl) => {
|
||||
new Setting(paneEl).autoWireToggle("suspendFileWatching");
|
||||
this.addOnSaved("suspendFileWatching", () => this.services.appLifecycle.askRestart());
|
||||
|
||||
@@ -144,7 +144,7 @@ export function paneHatch(this: ObsidianLiveSyncSettingTab, paneEl: HTMLElement,
|
||||
this.addOnSaved("suspendParseReplicationResult", () => this.services.appLifecycle.askRestart());
|
||||
});
|
||||
|
||||
void addPanel(paneEl, "Recovery and Repair").then((paneEl) => {
|
||||
void addPanel(paneEl, $msg("Recovery and Repair")).then((paneEl) => {
|
||||
const resultArea = paneEl.createDiv({ text: "", cls: "sls-repair-results" });
|
||||
type RepairMenuAction = {
|
||||
title: string;
|
||||
@@ -1071,13 +1071,15 @@ export function paneHatch(this: ObsidianLiveSyncSettingTab, paneEl: HTMLElement,
|
||||
})
|
||||
);
|
||||
new Setting(paneEl)
|
||||
.setName("Resolve All conflicted files by the newer one")
|
||||
.setName($msg("Resolve All conflicted files by the newer one"))
|
||||
.setDesc(
|
||||
"Resolve all conflicted files by the newer one. Caution: This will overwrite the older one, and cannot resurrect the overwritten one."
|
||||
$msg(
|
||||
"Resolve all conflicted files by the newer one. Caution: This will overwrite the older one, and cannot resurrect the overwritten one."
|
||||
)
|
||||
)
|
||||
.addButton((button) =>
|
||||
button
|
||||
.setButtonText("Resolve All")
|
||||
.setButtonText($msg("Resolve All"))
|
||||
.setCta()
|
||||
.onClick(async () => {
|
||||
const confirmed =
|
||||
@@ -1097,11 +1099,11 @@ export function paneHatch(this: ObsidianLiveSyncSettingTab, paneEl: HTMLElement,
|
||||
})
|
||||
);
|
||||
new Setting(paneEl)
|
||||
.setName("Check and convert non-path-obfuscated files")
|
||||
.setName($msg("Check and convert non-path-obfuscated files"))
|
||||
.setDesc("")
|
||||
.addButton((button) =>
|
||||
setButtonDestructiveState(button)
|
||||
.setButtonText("Perform")
|
||||
.setButtonText($msg("Perform"))
|
||||
.setDisabled(false)
|
||||
.onClick(async () => {
|
||||
for await (const docName of this.core.localDatabase.findAllDocNames()) {
|
||||
@@ -1174,10 +1176,10 @@ export function paneHatch(this: ObsidianLiveSyncSettingTab, paneEl: HTMLElement,
|
||||
})
|
||||
);
|
||||
});
|
||||
void addPanel(paneEl, "Reset").then((paneEl) => {
|
||||
new Setting(paneEl).setName("Back to non-configured").addButton((button) =>
|
||||
void addPanel(paneEl, $msg("Reset")).then((paneEl) => {
|
||||
new Setting(paneEl).setName($msg("Back to non-configured")).addButton((button) =>
|
||||
button
|
||||
.setButtonText("Back")
|
||||
.setButtonText($msg("Back"))
|
||||
.setDisabled(false)
|
||||
.onClick(async () => {
|
||||
this.editingSettings.isConfigured = false;
|
||||
@@ -1186,9 +1188,9 @@ export function paneHatch(this: ObsidianLiveSyncSettingTab, paneEl: HTMLElement,
|
||||
})
|
||||
);
|
||||
|
||||
new Setting(paneEl).setName("Delete all customization sync data").addButton((button) =>
|
||||
new Setting(paneEl).setName($msg("Delete all customization sync data")).addButton((button) =>
|
||||
setButtonDestructiveState(button)
|
||||
.setButtonText("Delete")
|
||||
.setButtonText($msg("Delete"))
|
||||
.setDisabled(false)
|
||||
.onClick(async () => {
|
||||
Logger(`Deleting customization sync data`, LOG_LEVEL_NOTICE);
|
||||
|
||||
@@ -24,7 +24,9 @@ export function paneMaintenance(
|
||||
paneEl,
|
||||
"div",
|
||||
{
|
||||
text: "The remote database is locked for synchronization to prevent vault corruption because this device isn't marked as 'resolved'. Please backup your vault, reset the local database, and select 'Mark this device as resolved'. This warning will persist until the device is confirmed as resolved by replication.",
|
||||
text: $msg(
|
||||
"The remote database is locked for synchronisation to prevent vault corruption because this device is not marked as 'resolved'. Please back up your vault, reset the local database, and select 'Mark this device as resolved'. This warning will persist until replication confirms the device is resolved."
|
||||
),
|
||||
cls: "op-warn",
|
||||
},
|
||||
(c) => {
|
||||
@@ -32,7 +34,7 @@ export function paneMaintenance(
|
||||
c,
|
||||
"button",
|
||||
{
|
||||
text: "I've made a backup, mark this device 'resolved'",
|
||||
text: $msg("I have made a backup, mark this device as resolved"),
|
||||
cls: "mod-warning",
|
||||
},
|
||||
(e) => {
|
||||
@@ -51,7 +53,9 @@ export function paneMaintenance(
|
||||
paneEl,
|
||||
"div",
|
||||
{
|
||||
text: "To prevent unwanted vault corruption, the remote database has been locked for synchronization. (This device is marked 'resolved') When all your devices are marked 'resolved', unlock the database. This warning kept showing until confirming the device is resolved by the replication",
|
||||
text: $msg(
|
||||
"To prevent unwanted vault corruption, the remote database has been locked for synchronisation. (This device is marked as 'resolved'.) When all your devices are marked as 'resolved', unlock the database. This warning will continue to appear until replication confirms the device is resolved."
|
||||
),
|
||||
cls: "op-warn",
|
||||
},
|
||||
(c) =>
|
||||
@@ -59,7 +63,7 @@ export function paneMaintenance(
|
||||
c,
|
||||
"button",
|
||||
{
|
||||
text: "I'm ready, unlock the database",
|
||||
text: $msg("I am ready, unlock the database"),
|
||||
cls: "mod-warning",
|
||||
},
|
||||
(e) => {
|
||||
@@ -74,13 +78,13 @@ export function paneMaintenance(
|
||||
visibleOnly(isRemoteLocked)
|
||||
);
|
||||
|
||||
void addPanel(paneEl, "Scram!").then((paneEl) => {
|
||||
void addPanel(paneEl, $msg("Scram!")).then((paneEl) => {
|
||||
new Setting(paneEl)
|
||||
.setName("Lock Server")
|
||||
.setDesc("Lock the remote server to prevent synchronization with other devices.")
|
||||
.setName($msg("Lock Server"))
|
||||
.setDesc($msg("Lock the remote server to prevent synchronization with other devices."))
|
||||
.addButton((button) =>
|
||||
setButtonDestructiveState(button)
|
||||
.setButtonText("Lock")
|
||||
.setButtonText($msg("Lock"))
|
||||
.setDisabled(false)
|
||||
.onClick(async () => {
|
||||
await this.services.replication.markLocked();
|
||||
@@ -89,11 +93,11 @@ export function paneMaintenance(
|
||||
.addOnUpdate(this.onlyOnCouchDBOrMinIO);
|
||||
|
||||
new Setting(paneEl)
|
||||
.setName("Emergency restart")
|
||||
.setDesc("Disables all synchronization and restart.")
|
||||
.setName($msg("Emergency restart"))
|
||||
.setDesc($msg("Disables all synchronization and restart."))
|
||||
.addButton((button) =>
|
||||
setButtonDestructiveState(button)
|
||||
.setButtonText("Flag and restart")
|
||||
.setButtonText($msg("Flag and restart"))
|
||||
.setDisabled(false)
|
||||
.onClick(async () => {
|
||||
await this.core.storageAccess.writeFileAuto(FlagFilesOriginal.SUSPEND_ALL, "");
|
||||
@@ -102,13 +106,13 @@ export function paneMaintenance(
|
||||
);
|
||||
});
|
||||
|
||||
void addPanel(paneEl, "Reset Synchronisation information").then((paneEl) => {
|
||||
void addPanel(paneEl, $msg("Reset Synchronisation information")).then((paneEl) => {
|
||||
new Setting(paneEl)
|
||||
.setName("Reset Synchronisation on This Device")
|
||||
.setDesc("Restore or reconstruct local database from remote.")
|
||||
.setName($msg("Reset Synchronisation on This Device"))
|
||||
.setDesc($msg("Restore or reconstruct local database from remote."))
|
||||
.addButton((button) =>
|
||||
button
|
||||
.setButtonText("Schedule and Restart")
|
||||
.setButtonText($msg("Schedule and Restart"))
|
||||
.setCta()
|
||||
.setDisabled(false)
|
||||
.onClick(async () => {
|
||||
@@ -117,11 +121,11 @@ export function paneMaintenance(
|
||||
})
|
||||
);
|
||||
new Setting(paneEl)
|
||||
.setName("Overwrite Server Data with This Device's Files")
|
||||
.setDesc("Rebuild local and remote database with local files.")
|
||||
.setName($msg("Overwrite Server Data with This Device's Files"))
|
||||
.setDesc($msg("Rebuild local and remote database with local files."))
|
||||
.addButton((button) =>
|
||||
button
|
||||
.setButtonText("Schedule and Restart")
|
||||
.setButtonText($msg("Schedule and Restart"))
|
||||
.setCta()
|
||||
.setDisabled(false)
|
||||
.onClick(async () => {
|
||||
@@ -131,13 +135,13 @@ export function paneMaintenance(
|
||||
);
|
||||
});
|
||||
|
||||
void addPanel(paneEl, "Syncing", () => {}, this.onlyOnCouchDBOrMinIO).then((paneEl) => {
|
||||
void addPanel(paneEl, $msg("Syncing"), () => {}, this.onlyOnCouchDBOrMinIO).then((paneEl) => {
|
||||
new Setting(paneEl)
|
||||
.setName("Resend")
|
||||
.setDesc("Resend all chunks to the remote.")
|
||||
.setName($msg("Resend"))
|
||||
.setDesc($msg("Resend all chunks to the remote."))
|
||||
.addButton((button) =>
|
||||
setButtonDestructiveState(button)
|
||||
.setButtonText("Send chunks")
|
||||
.setButtonText($msg("Send chunks"))
|
||||
.setDisabled(false)
|
||||
.onClick(async () => {
|
||||
if (this.core.replicator instanceof LiveSyncCouchDBReplicator) {
|
||||
@@ -148,13 +152,15 @@ export function paneMaintenance(
|
||||
.addOnUpdate(this.onlyOnCouchDB);
|
||||
|
||||
new Setting(paneEl)
|
||||
.setName("Reset journal received history")
|
||||
.setName($msg("Reset journal received history"))
|
||||
.setDesc(
|
||||
"Initialise journal received history. On the next sync, every item except this device sent will be downloaded again."
|
||||
$msg(
|
||||
"Initialise journal received history. On the next sync, every item except this device sent will be downloaded again."
|
||||
)
|
||||
)
|
||||
.addButton((button) =>
|
||||
setButtonDestructiveState(button)
|
||||
.setButtonText("Reset received")
|
||||
.setButtonText($msg("Reset received"))
|
||||
.setDisabled(false)
|
||||
.onClick(async () => {
|
||||
await this.getMinioJournalSyncClient().updateCheckPointInfo((info) => ({
|
||||
@@ -168,13 +174,15 @@ export function paneMaintenance(
|
||||
.addOnUpdate(this.onlyOnMinIO);
|
||||
|
||||
new Setting(paneEl)
|
||||
.setName("Reset journal sent history")
|
||||
.setName($msg("Reset journal sent history"))
|
||||
.setDesc(
|
||||
"Initialise journal sent history. On the next sync, every item except this device received will be sent again."
|
||||
$msg(
|
||||
"Initialise journal sent history. On the next sync, every item except this device received will be sent again."
|
||||
)
|
||||
)
|
||||
.addButton((button) =>
|
||||
setButtonDestructiveState(button)
|
||||
.setButtonText("Reset sent history")
|
||||
.setButtonText($msg("Reset sent history"))
|
||||
.setDisabled(false)
|
||||
.onClick(async () => {
|
||||
await this.getMinioJournalSyncClient().updateCheckPointInfo((info) => ({
|
||||
@@ -188,13 +196,13 @@ export function paneMaintenance(
|
||||
)
|
||||
.addOnUpdate(this.onlyOnMinIO);
|
||||
});
|
||||
void addPanel(paneEl, "Garbage Collection V3 (Beta)", (e) => e, this.onlyOnCouchDB).then((paneEl) => {
|
||||
void addPanel(paneEl, $msg("Garbage Collection V3 (Beta)"), (e) => e, this.onlyOnCouchDB).then((paneEl) => {
|
||||
new Setting(paneEl)
|
||||
.setName("Perform Garbage Collection")
|
||||
.setDesc("Perform Garbage Collection to remove unused chunks and reduce database size.")
|
||||
.setName($msg("Perform Garbage Collection"))
|
||||
.setDesc($msg("Perform Garbage Collection to remove unused chunks and reduce database size."))
|
||||
.addButton((button) =>
|
||||
button
|
||||
.setButtonText("Perform Garbage Collection")
|
||||
.setButtonText($msg("Perform Garbage Collection"))
|
||||
.setDisabled(false)
|
||||
.onClick(() => {
|
||||
this.closeSetting();
|
||||
@@ -289,97 +297,103 @@ export function paneMaintenance(
|
||||
// }
|
||||
// );
|
||||
|
||||
void addPanel(paneEl, "Rebuilding Operations (Remote Only)", () => {}, this.onlyOnCouchDBOrMinIO).then((paneEl) => {
|
||||
new Setting(paneEl)
|
||||
.setName("Perform cleanup")
|
||||
.setDesc(
|
||||
"Reduces storage space by discarding all non-latest revisions. This requires the same amount of free space on the remote server and the local client."
|
||||
)
|
||||
.addButton((button) =>
|
||||
button
|
||||
.setButtonText("Perform")
|
||||
.setDisabled(false)
|
||||
.onClick(async () => {
|
||||
const replicator = this.core.replicator as LiveSyncCouchDBReplicator;
|
||||
Logger(`Cleanup has been began`, LOG_LEVEL_NOTICE, "compaction");
|
||||
if (await replicator.compactRemote(this.editingSettings)) {
|
||||
Logger(`Cleanup has been completed!`, LOG_LEVEL_NOTICE, "compaction");
|
||||
} else {
|
||||
Logger(`Cleanup has been failed!`, LOG_LEVEL_NOTICE, "compaction");
|
||||
}
|
||||
})
|
||||
)
|
||||
.addOnUpdate(this.onlyOnCouchDB);
|
||||
void addPanel(paneEl, $msg("Rebuilding Operations (Remote Only)"), () => {}, this.onlyOnCouchDBOrMinIO).then(
|
||||
(paneEl) => {
|
||||
new Setting(paneEl)
|
||||
.setName($msg("Perform cleanup"))
|
||||
.setDesc(
|
||||
$msg(
|
||||
"Reduces storage space by discarding all non-latest revisions. This requires the same amount of free space on the remote server and the local client."
|
||||
)
|
||||
)
|
||||
.addButton((button) =>
|
||||
button
|
||||
.setButtonText($msg("Perform"))
|
||||
.setDisabled(false)
|
||||
.onClick(async () => {
|
||||
const replicator = this.core.replicator as LiveSyncCouchDBReplicator;
|
||||
Logger(`Cleanup has been began`, LOG_LEVEL_NOTICE, "compaction");
|
||||
if (await replicator.compactRemote(this.editingSettings)) {
|
||||
Logger(`Cleanup has been completed!`, LOG_LEVEL_NOTICE, "compaction");
|
||||
} else {
|
||||
Logger(`Cleanup has been failed!`, LOG_LEVEL_NOTICE, "compaction");
|
||||
}
|
||||
})
|
||||
)
|
||||
.addOnUpdate(this.onlyOnCouchDB);
|
||||
|
||||
new Setting(paneEl)
|
||||
.setName("Overwrite remote")
|
||||
.setDesc("Overwrite remote with local DB and passphrase.")
|
||||
.addButton((button) =>
|
||||
setButtonDestructiveState(button)
|
||||
.setButtonText("Send")
|
||||
.setDisabled(false)
|
||||
.onClick(async () => {
|
||||
await this.rebuildDB("remoteOnly");
|
||||
})
|
||||
);
|
||||
new Setting(paneEl)
|
||||
.setName($msg("Overwrite remote"))
|
||||
.setDesc($msg("Overwrite remote with local DB and passphrase."))
|
||||
.addButton((button) =>
|
||||
setButtonDestructiveState(button)
|
||||
.setButtonText($msg("Send"))
|
||||
.setDisabled(false)
|
||||
.onClick(async () => {
|
||||
await this.rebuildDB("remoteOnly");
|
||||
})
|
||||
);
|
||||
|
||||
new Setting(paneEl)
|
||||
.setName("Reset all journal counter")
|
||||
.setDesc("Initialise all journal history, On the next sync, every item will be received and sent.")
|
||||
.addButton((button) =>
|
||||
setButtonDestructiveState(button)
|
||||
.setButtonText("Reset all")
|
||||
.setDisabled(false)
|
||||
.onClick(async () => {
|
||||
await this.getMinioJournalSyncClient().resetCheckpointInfo();
|
||||
Logger(`Journal exchange history has been cleared.`, LOG_LEVEL_NOTICE);
|
||||
})
|
||||
)
|
||||
.addOnUpdate(this.onlyOnMinIO);
|
||||
new Setting(paneEl)
|
||||
.setName($msg("Reset all journal counter"))
|
||||
.setDesc(
|
||||
$msg("Initialise all journal history, On the next sync, every item will be received and sent.")
|
||||
)
|
||||
.addButton((button) =>
|
||||
setButtonDestructiveState(button)
|
||||
.setButtonText($msg("Reset all"))
|
||||
.setDisabled(false)
|
||||
.onClick(async () => {
|
||||
await this.getMinioJournalSyncClient().resetCheckpointInfo();
|
||||
Logger(`Journal exchange history has been cleared.`, LOG_LEVEL_NOTICE);
|
||||
})
|
||||
)
|
||||
.addOnUpdate(this.onlyOnMinIO);
|
||||
|
||||
new Setting(paneEl)
|
||||
.setName("Purge all journal counter")
|
||||
.setDesc("Purge all download/upload cache.")
|
||||
.addButton((button) =>
|
||||
setButtonDestructiveState(button)
|
||||
.setButtonText("Reset all")
|
||||
.setDisabled(false)
|
||||
.onClick(() => {
|
||||
this.getMinioJournalSyncClient().resetAllCaches();
|
||||
Logger(`Journal download/upload cache has been cleared.`, LOG_LEVEL_NOTICE);
|
||||
})
|
||||
)
|
||||
.addOnUpdate(this.onlyOnMinIO);
|
||||
new Setting(paneEl)
|
||||
.setName($msg("Purge all journal counter"))
|
||||
.setDesc($msg("Purge all download/upload cache."))
|
||||
.addButton((button) =>
|
||||
setButtonDestructiveState(button)
|
||||
.setButtonText($msg("Reset all"))
|
||||
.setDisabled(false)
|
||||
.onClick(() => {
|
||||
this.getMinioJournalSyncClient().resetAllCaches();
|
||||
Logger(`Journal download/upload cache has been cleared.`, LOG_LEVEL_NOTICE);
|
||||
})
|
||||
)
|
||||
.addOnUpdate(this.onlyOnMinIO);
|
||||
|
||||
new Setting(paneEl)
|
||||
.setName("Fresh Start Wipe")
|
||||
.setDesc("Delete all data on the remote server.")
|
||||
.addButton((button) =>
|
||||
setButtonDestructiveState(button)
|
||||
.setButtonText("Delete")
|
||||
.setDisabled(false)
|
||||
.onClick(async () => {
|
||||
await this.getMinioJournalSyncClient().updateCheckPointInfo((info) => ({
|
||||
...info,
|
||||
receivedFiles: new Set(),
|
||||
knownIDs: new Set(),
|
||||
lastLocalSeq: 0,
|
||||
sentIDs: new Set(),
|
||||
sentFiles: new Set(),
|
||||
}));
|
||||
const reset = await this.resetRemoteBucket();
|
||||
Logger(
|
||||
reset
|
||||
? `Deleted all data on remote server`
|
||||
: `Fresh Start Wipe did not complete. Keep all synchronising devices stopped and run it again.`,
|
||||
LOG_LEVEL_NOTICE
|
||||
);
|
||||
})
|
||||
)
|
||||
.addOnUpdate(this.onlyOnMinIO);
|
||||
});
|
||||
new Setting(paneEl)
|
||||
.setName($msg("Fresh Start Wipe"))
|
||||
.setDesc($msg("Delete all data on the remote server."))
|
||||
.addButton((button) =>
|
||||
setButtonDestructiveState(button)
|
||||
.setButtonText($msg("Delete"))
|
||||
.setDisabled(false)
|
||||
.onClick(async () => {
|
||||
await this.getMinioJournalSyncClient().updateCheckPointInfo((info) => ({
|
||||
...info,
|
||||
receivedFiles: new Set(),
|
||||
knownIDs: new Set(),
|
||||
lastLocalSeq: 0,
|
||||
sentIDs: new Set(),
|
||||
sentFiles: new Set(),
|
||||
}));
|
||||
const reset = await this.resetRemoteBucket();
|
||||
Logger(
|
||||
reset
|
||||
? `Deleted all data on remote server`
|
||||
: `Fresh Start Wipe did not complete. Keep all synchronising devices stopped and run it again.`,
|
||||
LOG_LEVEL_NOTICE
|
||||
);
|
||||
})
|
||||
)
|
||||
.addOnUpdate(this.onlyOnMinIO);
|
||||
}
|
||||
);
|
||||
|
||||
void addPanel(paneEl, "Reset").then((paneEl) => {
|
||||
void addPanel(paneEl, $msg("Reset")).then((paneEl) => {
|
||||
new Setting(paneEl)
|
||||
.setName($msg("obsidianLiveSyncSettingTab.nameDiscardSettings"))
|
||||
.addButton((button) => {
|
||||
@@ -405,10 +419,10 @@ export function paneMaintenance(
|
||||
.addOnUpdate(visibleOnly(() => this.isConfiguredAs("isConfigured", true)));
|
||||
|
||||
new Setting(paneEl)
|
||||
.setName("Delete local database to reset or uninstall Self-hosted LiveSync")
|
||||
.setName($msg("Delete local database to reset or uninstall Self-hosted LiveSync"))
|
||||
.addButton((button) =>
|
||||
setButtonDestructiveState(button)
|
||||
.setButtonText("Delete")
|
||||
.setButtonText($msg("Delete"))
|
||||
.setDisabled(false)
|
||||
.onClick(async () => {
|
||||
await this.services.database.resetDatabase();
|
||||
|
||||
@@ -18,7 +18,7 @@ import { usesLegacyIndexedDBAdapter } from "@/common/compatibilitySettings.ts";
|
||||
import { $msg } from "@/common/translation";
|
||||
|
||||
export function panePatches(this: ObsidianLiveSyncSettingTab, paneEl: HTMLElement, { addPanel }: PageFunctions): void {
|
||||
void addPanel(paneEl, "Compatibility (Metadata)").then((paneEl) => {
|
||||
void addPanel(paneEl, $msg("Compatibility (Metadata)")).then((paneEl) => {
|
||||
new Setting(paneEl).autoWireToggle("deleteMetadataOfDeletedFiles");
|
||||
|
||||
new Setting(paneEl).autoWireNumeric("automaticallyDeleteMetadataOfDeletedFiles", {
|
||||
@@ -26,12 +26,12 @@ export function panePatches(this: ObsidianLiveSyncSettingTab, paneEl: HTMLElemen
|
||||
});
|
||||
});
|
||||
|
||||
void addPanel(paneEl, "Compatibility (Conflict Behaviour)").then((paneEl) => {
|
||||
void addPanel(paneEl, $msg("Compatibility (Conflict Behaviour)")).then((paneEl) => {
|
||||
new Setting(paneEl).autoWireToggle("disableMarkdownAutoMerge");
|
||||
new Setting(paneEl).autoWireToggle("writeDocumentsIfConflicted");
|
||||
});
|
||||
|
||||
void addPanel(paneEl, "Compatibility (Database structure)").then((paneEl) => {
|
||||
void addPanel(paneEl, $msg("Compatibility (Database structure)")).then((paneEl) => {
|
||||
const migrateAllToIndexedDB = async () => {
|
||||
const dbToName = this.core.localDatabase.dbname + SuffixDatabaseName + ExtraSuffixIndexedDB;
|
||||
const options = {
|
||||
@@ -80,16 +80,20 @@ export function panePatches(this: ObsidianLiveSyncSettingTab, paneEl: HTMLElemen
|
||||
const useIndexedDBAdapter = usesLegacyIndexedDBAdapter(this.editingSettings);
|
||||
const infoClass = useIndexedDBAdapter ? "op-warn" : "op-warn-info";
|
||||
paneEl.createDiv({
|
||||
text: "The IndexedDB adapter often offers superior performance in certain scenarios, but it has been found to cause memory leaks when used with LiveSync mode. When using LiveSync mode, please use IDB adapter instead.",
|
||||
text: $msg(
|
||||
"The IndexedDB adapter often offers superior performance in certain scenarios, but it has been found to cause memory leaks when used with LiveSync mode. When using LiveSync mode, please use IDB adapter instead."
|
||||
),
|
||||
cls: infoClass,
|
||||
});
|
||||
paneEl.createDiv({
|
||||
text: "Changing this setting requires migrating existing data (a bit time may be taken) and restarting Obsidian. Please make sure to back up your data before proceeding.",
|
||||
text: $msg(
|
||||
"Changing this setting requires migrating existing data (a bit time may be taken) and restarting Obsidian. Please make sure to back up your data before proceeding."
|
||||
),
|
||||
cls: "op-warn-info",
|
||||
});
|
||||
const setting = new Setting(paneEl)
|
||||
.setName("Database Adapter")
|
||||
.setDesc("Select the database adapter to use. ");
|
||||
.setName($msg("Database Adapter"))
|
||||
.setDesc($msg("Select the database adapter to use."));
|
||||
const el = setting.controlEl.createDiv({});
|
||||
el.setText(`Current adapter: ${useIndexedDBAdapter ? "IndexedDB" : "IDB"}`);
|
||||
if (!useIndexedDBAdapter) {
|
||||
@@ -119,10 +123,10 @@ export function panePatches(this: ObsidianLiveSyncSettingTab, paneEl: HTMLElemen
|
||||
new Setting(paneEl).autoWireToggle("handleFilenameCaseSensitive", { holdValue: true });
|
||||
});
|
||||
|
||||
void addPanel(paneEl, "Compatibility (Internal API Usage)").then((paneEl) => {
|
||||
void addPanel(paneEl, $msg("Compatibility (Internal API Usage)")).then((paneEl) => {
|
||||
new Setting(paneEl).autoWireToggle("watchInternalFileChanges", { invert: true });
|
||||
});
|
||||
void addPanel(paneEl, "Compatibility (Remote Database)").then((paneEl) => {
|
||||
void addPanel(paneEl, $msg("Compatibility (Remote Database)")).then((paneEl) => {
|
||||
new Setting(paneEl).autoWireDropDown("E2EEAlgorithm", {
|
||||
options: E2EEAlgorithmNames,
|
||||
});
|
||||
@@ -136,7 +140,7 @@ export function panePatches(this: ObsidianLiveSyncSettingTab, paneEl: HTMLElemen
|
||||
),
|
||||
});
|
||||
|
||||
void addPanel(paneEl, "Edge case addressing (Database)").then((paneEl) => {
|
||||
void addPanel(paneEl, $msg("Edge case addressing (Database)")).then((paneEl) => {
|
||||
new Setting(paneEl)
|
||||
.autoWireText("additionalSuffixOfDatabaseName", { holdValue: true })
|
||||
.addApplyButton(["additionalSuffixOfDatabaseName"]);
|
||||
@@ -161,13 +165,13 @@ export function panePatches(this: ObsidianLiveSyncSettingTab, paneEl: HTMLElemen
|
||||
await this.core.localDatabase._prepareHashFunctions();
|
||||
});
|
||||
});
|
||||
void addPanel(paneEl, "Edge case addressing (Behaviour)").then((paneEl) => {
|
||||
void addPanel(paneEl, $msg("Edge case addressing (Behaviour)")).then((paneEl) => {
|
||||
new Setting(paneEl).autoWireToggle("doNotSuspendOnFetching");
|
||||
new Setting(paneEl).autoWireToggle("doNotDeleteFolder");
|
||||
new Setting(paneEl).autoWireToggle("processSizeMismatchedFiles");
|
||||
});
|
||||
|
||||
void addPanel(paneEl, "Edge case addressing (Processing)").then((paneEl) => {
|
||||
void addPanel(paneEl, $msg("Edge case addressing (Processing)")).then((paneEl) => {
|
||||
new Setting(paneEl).autoWireToggle("disableWorkerForGeneratingChunks");
|
||||
|
||||
new Setting(paneEl).autoWireToggle("processSmallFilesInUIThread", {
|
||||
@@ -177,10 +181,10 @@ export function panePatches(this: ObsidianLiveSyncSettingTab, paneEl: HTMLElemen
|
||||
// void addPanel(paneEl, "Edge case addressing (Networking)").then((paneEl) => {
|
||||
// new Setting(paneEl).autoWireToggle("useRequestAPI");
|
||||
// });
|
||||
void addPanel(paneEl, "Compatibility (Trouble addressed)").then((paneEl) => {
|
||||
void addPanel(paneEl, $msg("Compatibility (Trouble addressed)")).then((paneEl) => {
|
||||
new Setting(paneEl).autoWireToggle("disableCheckingConfigMismatch");
|
||||
});
|
||||
void addPanel(paneEl, "Remediation").then((paneEl) => {
|
||||
void addPanel(paneEl, $msg("Remediation")).then((paneEl) => {
|
||||
const setting = setSettingAdditionalActionsState(new Setting(paneEl));
|
||||
const dateEl = setting.controlEl.createSpan();
|
||||
setting
|
||||
|
||||
@@ -2,18 +2,21 @@ import { type ConfigPassphraseStore } from "@vrtmrz/livesync-commonlib/compat/co
|
||||
import { LiveSyncSetting as Setting } from "./LiveSyncSetting.ts";
|
||||
import type { ObsidianLiveSyncSettingTab } from "./ObsidianLiveSyncSettingTab.ts";
|
||||
import type { PageFunctions } from "./SettingPane.ts";
|
||||
import { $msg } from "@/common/translation";
|
||||
|
||||
export function panePowerUsers(
|
||||
this: ObsidianLiveSyncSettingTab,
|
||||
paneEl: HTMLElement,
|
||||
{ addPanel }: PageFunctions
|
||||
): void {
|
||||
void addPanel(paneEl, "CouchDB Connection Tweak", undefined, this.onlyOnCouchDB).then((paneEl) => {
|
||||
void addPanel(paneEl, $msg("CouchDB Connection Tweak"), undefined, this.onlyOnCouchDB).then((paneEl) => {
|
||||
this.createEl(
|
||||
paneEl,
|
||||
"div",
|
||||
{
|
||||
text: `If you reached the payload size limit when using IBM Cloudant, please decrease batch size and batch limit to a lower value.`,
|
||||
text: $msg(
|
||||
"If you reached the payload size limit when using IBM Cloudant, please decrease batch size and batch limit to a lower value."
|
||||
),
|
||||
},
|
||||
undefined,
|
||||
this.onlyOnCouchDB
|
||||
@@ -26,15 +29,15 @@ export function panePowerUsers(
|
||||
});
|
||||
new Setting(paneEl).autoWireToggle("useTimeouts", { onUpdate: this.onlyOnCouchDB });
|
||||
});
|
||||
void addPanel(paneEl, "Configuration Encryption").then((paneEl) => {
|
||||
void addPanel(paneEl, $msg("Configuration Encryption")).then((paneEl) => {
|
||||
const passphrase_options: Record<ConfigPassphraseStore, string> = {
|
||||
"": "Default",
|
||||
LOCALSTORAGE: "Use a custom passphrase",
|
||||
ASK_AT_LAUNCH: "Ask an passphrase at every launch",
|
||||
"": $msg("Default"),
|
||||
LOCALSTORAGE: $msg("Use a custom passphrase"),
|
||||
ASK_AT_LAUNCH: $msg("Ask a passphrase at every launch"),
|
||||
};
|
||||
|
||||
new Setting(paneEl)
|
||||
.setName("Encrypting sensitive configuration items")
|
||||
.setName($msg("Encrypting sensitive configuration items"))
|
||||
.autoWireDropDown("configPassphraseStore", {
|
||||
options: passphrase_options,
|
||||
holdValue: true,
|
||||
@@ -45,7 +48,7 @@ export function panePowerUsers(
|
||||
}));
|
||||
new Setting(paneEl).addApplyButton(["configPassphrase", "configPassphraseStore"]);
|
||||
});
|
||||
void addPanel(paneEl, "Developer").then((paneEl) => {
|
||||
void addPanel(paneEl, $msg("Developer")).then((paneEl) => {
|
||||
new Setting(paneEl).autoWireToggle("enableDebugTools");
|
||||
});
|
||||
}
|
||||
|
||||
@@ -112,10 +112,10 @@ export function paneRemoteConfig(
|
||||
info: getE2EEConfigSummary(this.editingSettings),
|
||||
});
|
||||
};
|
||||
void addPanel(paneEl, "E2EE Configuration", () => {}).then((paneEl) => {
|
||||
void addPanel(paneEl, $msg("E2EE Configuration"), () => {}).then((paneEl) => {
|
||||
const infoPanel = new SveltePanel(InfoPanel, paneEl, E2EESummaryWritable);
|
||||
this.lifetimeComponent.register(() => infoPanel.destroy());
|
||||
const setupButton = setSettingAdditionalActionsState(new Setting(paneEl).setName("Configure E2EE"));
|
||||
const setupButton = setSettingAdditionalActionsState(new Setting(paneEl).setName($msg("Configure E2EE")));
|
||||
setupButton
|
||||
.addButton((button) =>
|
||||
setButtonDestructiveState(button)
|
||||
@@ -146,7 +146,7 @@ export function paneRemoteConfig(
|
||||
}
|
||||
updateE2EESummary();
|
||||
})
|
||||
.setButtonText("Configure")
|
||||
.setButtonText($msg("Configure"))
|
||||
)
|
||||
.addButton((button) =>
|
||||
setButtonDestructiveState(setButtonAdditionalActionState(button))
|
||||
@@ -156,7 +156,7 @@ export function paneRemoteConfig(
|
||||
await setupManager.onConfigureManually(originalSettings, UserMode.Update);
|
||||
updateE2EESummary();
|
||||
})
|
||||
.setButtonText("Configure And Change Remote")
|
||||
.setButtonText($msg("Configure And Change Remote"))
|
||||
);
|
||||
updateE2EESummary();
|
||||
});
|
||||
|
||||
@@ -6,12 +6,15 @@ import { mount, unmount } from "svelte";
|
||||
import type { ObsidianLiveSyncSettingTab } from "./ObsidianLiveSyncSettingTab.ts";
|
||||
import type { PageFunctions } from "./SettingPane.ts";
|
||||
import { visibleOnly } from "./SettingPane.ts";
|
||||
import { $msg } from "@/common/translation";
|
||||
export function paneSelector(this: ObsidianLiveSyncSettingTab, paneEl: HTMLElement, { addPanel }: PageFunctions): void {
|
||||
void addPanel(paneEl, "Normal Files").then((paneEl) => {
|
||||
void addPanel(paneEl, $msg("Normal Files")).then((paneEl) => {
|
||||
const syncFilesSetting = new Setting(paneEl)
|
||||
.setName("Synchronising files")
|
||||
.setName($msg("Synchronising files"))
|
||||
.setDesc(
|
||||
"(RegExp) Empty to sync all files. Set filter as a regular expression to limit synchronising files."
|
||||
$msg(
|
||||
"(RegExp) Empty to sync all files. Set filter as a regular expression to limit synchronising files."
|
||||
)
|
||||
);
|
||||
const syncFilesControl = mount(MultipleRegExpControl, {
|
||||
target: syncFilesSetting.controlEl,
|
||||
@@ -28,8 +31,10 @@ export function paneSelector(this: ObsidianLiveSyncSettingTab, paneEl: HTMLEleme
|
||||
this.lifetimeComponent.register(() => void unmount(syncFilesControl));
|
||||
|
||||
const nonSyncFilesSetting = new Setting(paneEl)
|
||||
.setName("Non-Synchronising files")
|
||||
.setDesc("(RegExp) If this is set, any changes to local and remote files that match this will be skipped.");
|
||||
.setName($msg("Non-Synchronising files"))
|
||||
.setDesc(
|
||||
$msg("(RegExp) If this is set, any changes to local and remote files that match this will be skipped.")
|
||||
);
|
||||
|
||||
const nonSyncFilesControl = mount(MultipleRegExpControl, {
|
||||
target: nonSyncFilesSetting.controlEl,
|
||||
@@ -51,10 +56,10 @@ export function paneSelector(this: ObsidianLiveSyncSettingTab, paneEl: HTMLEleme
|
||||
onUpdate: visibleOnly(() => this.isConfiguredAs("useIgnoreFiles", true)),
|
||||
});
|
||||
});
|
||||
void addPanel(paneEl, "Hidden Files", undefined, undefined, LEVEL_ADVANCED).then((paneEl) => {
|
||||
void addPanel(paneEl, $msg("Hidden Files"), undefined, undefined, LEVEL_ADVANCED).then((paneEl) => {
|
||||
const targetPatternSetting = new Setting(paneEl)
|
||||
.setName("Target patterns")
|
||||
.setDesc("Patterns to match files for syncing");
|
||||
.setName($msg("Target patterns"))
|
||||
.setDesc($msg("Patterns to match files for syncing"));
|
||||
const patTarget = splitCustomRegExpList(this.editingSettings.syncInternalFilesTargetPatterns, ",");
|
||||
const targetPatternControl = mount(MultipleRegExpControl, {
|
||||
target: targetPatternSetting.controlEl,
|
||||
@@ -75,7 +80,7 @@ export function paneSelector(this: ObsidianLiveSyncSettingTab, paneEl: HTMLEleme
|
||||
defaultSkipPattern + ",\\/workspace$ ,\\/workspace.json$,\\/workspace-mobile.json$";
|
||||
|
||||
const pat = splitCustomRegExpList(this.editingSettings.syncInternalFilesIgnorePatterns, ",");
|
||||
const patSetting = new Setting(paneEl).setName("Ignore patterns").setDesc("");
|
||||
const patSetting = new Setting(paneEl).setName($msg("Ignore patterns")).setDesc("");
|
||||
|
||||
const ignorePatternControl = mount(MultipleRegExpControl, {
|
||||
target: patSetting.controlEl,
|
||||
@@ -104,21 +109,21 @@ export function paneSelector(this: ObsidianLiveSyncSettingTab, paneEl: HTMLEleme
|
||||
};
|
||||
|
||||
new Setting(paneEl)
|
||||
.setName("Add default patterns")
|
||||
.setName($msg("Add default patterns"))
|
||||
.addButton((button) => {
|
||||
button.setButtonText("Default").onClick(async () => {
|
||||
button.setButtonText($msg("Default")).onClick(async () => {
|
||||
await addDefaultPatterns(defaultSkipPattern);
|
||||
});
|
||||
})
|
||||
.addButton((button) => {
|
||||
button.setButtonText("Cross-platform").onClick(async () => {
|
||||
button.setButtonText($msg("Cross-platform")).onClick(async () => {
|
||||
await addDefaultPatterns(defaultSkipPatternXPlat);
|
||||
});
|
||||
});
|
||||
|
||||
const overwritePatterns = new Setting(paneEl)
|
||||
.setName("Overwrite patterns")
|
||||
.setDesc("Patterns to match files for overwriting instead of merging");
|
||||
.setName($msg("Overwrite patterns"))
|
||||
.setDesc($msg("Patterns to match files for overwriting instead of merging"));
|
||||
const patTarget2 = splitCustomRegExpList(this.editingSettings.syncInternalFileOverwritePatterns, ",");
|
||||
const overwritePatternControl = mount(MultipleRegExpControl, {
|
||||
target: overwritePatterns.controlEl,
|
||||
|
||||
Reference in New Issue
Block a user