mirror of
https://github.com/vrtmrz/obsidian-livesync.git
synced 2025-12-13 17:55:56 +00:00
Improvements:
- Show sync status information inside the editor. Fixed: - Reduce the same messages on popup notifications - show warning message when synchronization
This commit is contained in:
@@ -143,6 +143,11 @@ You can dump saved note structure to `Dump informations of this doc`. Replace ev
|
|||||||
|
|
||||||
Default values are 20 letters and 250 letters.
|
Default values are 20 letters and 250 letters.
|
||||||
|
|
||||||
|
## Miscellaneous
|
||||||
|
### Show status inside editor
|
||||||
|
Show information inside the editor pane.
|
||||||
|
It would be useful for mobile.
|
||||||
|
|
||||||
## Hatch
|
## Hatch
|
||||||
From here, everything is under the hood. Please handle it with care.
|
From here, everything is under the hood. Please handle it with care.
|
||||||
|
|
||||||
|
|||||||
@@ -142,6 +142,12 @@ Self-hosted LiveSyncは一つのチャンクのサイズを最低minimum chunk s
|
|||||||
改行文字と#を除き、すべて●に置換しても、アルゴリズムは有効に働きます。
|
改行文字と#を除き、すべて●に置換しても、アルゴリズムは有効に働きます。
|
||||||
デフォルトは20文字と、250文字です。
|
デフォルトは20文字と、250文字です。
|
||||||
|
|
||||||
|
## Miscellaneous
|
||||||
|
その他の設定です
|
||||||
|
### Show status inside editor
|
||||||
|
同期の情報をエディター内に表示します。
|
||||||
|
モバイルで便利です。
|
||||||
|
|
||||||
## Hatch
|
## Hatch
|
||||||
ここから先は、困ったときに開ける蓋の中身です。注意して使用してください。
|
ここから先は、困ったときに開ける蓋の中身です。注意して使用してください。
|
||||||
|
|
||||||
|
|||||||
76
main.ts
76
main.ts
@@ -54,6 +54,7 @@ interface ObsidianLiveSyncSettings {
|
|||||||
deviceAndVaultName: string;
|
deviceAndVaultName: string;
|
||||||
usePluginSettings: boolean;
|
usePluginSettings: boolean;
|
||||||
showOwnPlugins: boolean;
|
showOwnPlugins: boolean;
|
||||||
|
showStatusOnEditor: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const DEFAULT_SETTINGS: ObsidianLiveSyncSettings = {
|
const DEFAULT_SETTINGS: ObsidianLiveSyncSettings = {
|
||||||
@@ -86,6 +87,7 @@ const DEFAULT_SETTINGS: ObsidianLiveSyncSettings = {
|
|||||||
deviceAndVaultName: "",
|
deviceAndVaultName: "",
|
||||||
usePluginSettings: false,
|
usePluginSettings: false,
|
||||||
showOwnPlugins: false,
|
showOwnPlugins: false,
|
||||||
|
showStatusOnEditor: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
interface Entry {
|
interface Entry {
|
||||||
@@ -2004,6 +2006,7 @@ export default class ObsidianLiveSyncPlugin extends Plugin {
|
|||||||
}
|
}
|
||||||
addLogHook: () => void = null;
|
addLogHook: () => void = null;
|
||||||
//--> Basic document Functions
|
//--> Basic document Functions
|
||||||
|
notifies: { [key: string]: { notice: Notice; timer: NodeJS.Timeout; count: number } } = {};
|
||||||
async addLog(message: any, level: LOG_LEVEL = LOG_LEVEL.INFO) {
|
async addLog(message: any, level: LOG_LEVEL = LOG_LEVEL.INFO) {
|
||||||
if (level < LOG_LEVEL.INFO && this.settings && this.settings.lessInformationInLog) {
|
if (level < LOG_LEVEL.INFO && this.settings && this.settings.lessInformationInLog) {
|
||||||
return;
|
return;
|
||||||
@@ -2021,8 +2024,23 @@ export default class ObsidianLiveSyncPlugin extends Plugin {
|
|||||||
// if (this.statusBar2 != null) {
|
// if (this.statusBar2 != null) {
|
||||||
// this.statusBar2.setText(newmessage.substring(0, 60));
|
// this.statusBar2.setText(newmessage.substring(0, 60));
|
||||||
// }
|
// }
|
||||||
|
|
||||||
if (level >= LOG_LEVEL.NOTICE) {
|
if (level >= LOG_LEVEL.NOTICE) {
|
||||||
new Notice(messagecontent);
|
if (messagecontent in this.notifies) {
|
||||||
|
clearTimeout(this.notifies[messagecontent].timer);
|
||||||
|
this.notifies[messagecontent].count++;
|
||||||
|
this.notifies[messagecontent].notice.setMessage(`(${this.notifies[messagecontent].count}):${messagecontent}`);
|
||||||
|
} else {
|
||||||
|
let notify = new Notice(messagecontent, 0);
|
||||||
|
this.notifies[messagecontent] = {
|
||||||
|
count: 0,
|
||||||
|
notice: notify,
|
||||||
|
timer: setTimeout(() => {
|
||||||
|
notify.hide();
|
||||||
|
delete this.notifies[messagecontent];
|
||||||
|
}, 5000),
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (this.addLogHook != null) this.addLogHook();
|
if (this.addLogHook != null) this.addLogHook();
|
||||||
}
|
}
|
||||||
@@ -2241,6 +2259,7 @@ export default class ObsidianLiveSyncPlugin extends Plugin {
|
|||||||
}
|
}
|
||||||
this.setPeriodicSync();
|
this.setPeriodicSync();
|
||||||
}
|
}
|
||||||
|
lastMessage = "";
|
||||||
refreshStatusText() {
|
refreshStatusText() {
|
||||||
let sent = this.localDatabase.docSent;
|
let sent = this.localDatabase.docSent;
|
||||||
let arrived = this.localDatabase.docArrived;
|
let arrived = this.localDatabase.docArrived;
|
||||||
@@ -2268,9 +2287,23 @@ export default class ObsidianLiveSyncPlugin extends Plugin {
|
|||||||
let waiting = "";
|
let waiting = "";
|
||||||
if (this.settings.batchSave) {
|
if (this.settings.batchSave) {
|
||||||
waiting = " " + this.batchFileChange.map((e) => "🛫").join("");
|
waiting = " " + this.batchFileChange.map((e) => "🛫").join("");
|
||||||
waiting = waiting.replace(/🛫{10}/g,"🚀");
|
waiting = waiting.replace(/🛫{10}/g, "🚀");
|
||||||
|
}
|
||||||
|
const message = `Sync:${w} ↑${sent} ↓${arrived}${waiting}`;
|
||||||
|
this.setStatusBarText(message);
|
||||||
|
}
|
||||||
|
setStatusBarText(message: string) {
|
||||||
|
if (this.lastMessage != message) {
|
||||||
|
this.statusBar.setText(message);
|
||||||
|
if (this.settings.showStatusOnEditor) {
|
||||||
|
const root = document.documentElement;
|
||||||
|
root.style.setProperty("--slsmessage", '"' + message + '"');
|
||||||
|
} else {
|
||||||
|
const root = document.documentElement;
|
||||||
|
root.style.setProperty("--slsmessage", '""');
|
||||||
|
}
|
||||||
|
this.lastMessage = message;
|
||||||
}
|
}
|
||||||
this.statusBar.setText(`Sync:${w} ↑${sent} ↓${arrived}${waiting}`);
|
|
||||||
}
|
}
|
||||||
async replicate(showMessage?: boolean) {
|
async replicate(showMessage?: boolean) {
|
||||||
if (this.settings.versionUpFlash != "") {
|
if (this.settings.versionUpFlash != "") {
|
||||||
@@ -2316,7 +2349,8 @@ export default class ObsidianLiveSyncPlugin extends Plugin {
|
|||||||
const syncFiles = filesStorage.filter((e) => onlyInStorageNames.indexOf(e.path) == -1);
|
const syncFiles = filesStorage.filter((e) => onlyInStorageNames.indexOf(e.path) == -1);
|
||||||
Logger("Initialize and checking database files");
|
Logger("Initialize and checking database files");
|
||||||
Logger("Updating database by new files");
|
Logger("Updating database by new files");
|
||||||
this.statusBar.setText(`UPDATE DATABASE`);
|
this.setStatusBarText(`UPDATE DATABASE`);
|
||||||
|
let _this = this;
|
||||||
async function runAll<T>(procedurename: string, objects: T[], callback: (arg: T) => Promise<void>) {
|
async function runAll<T>(procedurename: string, objects: T[], callback: (arg: T) => Promise<void>) {
|
||||||
const count = objects.length;
|
const count = objects.length;
|
||||||
Logger(procedurename);
|
Logger(procedurename);
|
||||||
@@ -2333,7 +2367,7 @@ export default class ObsidianLiveSyncPlugin extends Plugin {
|
|||||||
if (notice != null) notice.setMessage(notify);
|
if (notice != null) notice.setMessage(notify);
|
||||||
Logger(notify);
|
Logger(notify);
|
||||||
// lastTicks = performance.now() + 2000;
|
// lastTicks = performance.now() + 2000;
|
||||||
// this.statusBar.setText(notify);
|
_this.setStatusBarText(notify);
|
||||||
}
|
}
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
Logger(`Error while ${procedurename}`, LOG_LEVEL.NOTICE);
|
Logger(`Error while ${procedurename}`, LOG_LEVEL.NOTICE);
|
||||||
@@ -2369,7 +2403,7 @@ export default class ObsidianLiveSyncPlugin extends Plugin {
|
|||||||
await runAll("CHECK FILE STATUS", syncFiles, async (e) => {
|
await runAll("CHECK FILE STATUS", syncFiles, async (e) => {
|
||||||
await this.syncFileBetweenDBandStorage(e, filesStorage);
|
await this.syncFileBetweenDBandStorage(e, filesStorage);
|
||||||
});
|
});
|
||||||
this.statusBar.setText(`NOW TRACKING!`);
|
this.setStatusBarText(`NOW TRACKING!`);
|
||||||
Logger("Initialized,NOW TRACKING!");
|
Logger("Initialized,NOW TRACKING!");
|
||||||
if (showingNotice) {
|
if (showingNotice) {
|
||||||
notice.hide();
|
notice.hide();
|
||||||
@@ -2807,6 +2841,9 @@ class ObsidianLiveSyncSettingTab extends PluginSettingTab {
|
|||||||
containerEl.createEl("h2", { text: "Settings for Self-hosted LiveSync." });
|
containerEl.createEl("h2", { text: "Settings for Self-hosted LiveSync." });
|
||||||
|
|
||||||
containerEl.createEl("h3", { text: "Remote Database configuration" });
|
containerEl.createEl("h3", { text: "Remote Database configuration" });
|
||||||
|
let syncWarn = containerEl.createEl("div", { text: "The remote configuration is locked while any synchronization is enabled." });
|
||||||
|
syncWarn.addClass("op-warn");
|
||||||
|
syncWarn.addClass("sls-hidden");
|
||||||
|
|
||||||
const isAnySyncEnabled = (): boolean => {
|
const isAnySyncEnabled = (): boolean => {
|
||||||
if (this.plugin.settings.liveSync) return true;
|
if (this.plugin.settings.liveSync) return true;
|
||||||
@@ -2820,10 +2857,12 @@ class ObsidianLiveSyncSettingTab extends PluginSettingTab {
|
|||||||
dbsettings.forEach((e) => {
|
dbsettings.forEach((e) => {
|
||||||
e.setDisabled(true).setTooltip("When any sync is enabled, It cound't be changed.");
|
e.setDisabled(true).setTooltip("When any sync is enabled, It cound't be changed.");
|
||||||
});
|
});
|
||||||
|
syncWarn.removeClass("sls-hidden");
|
||||||
} else {
|
} else {
|
||||||
dbsettings.forEach((e) => {
|
dbsettings.forEach((e) => {
|
||||||
e.setDisabled(false).setTooltip("");
|
e.setDisabled(false).setTooltip("");
|
||||||
});
|
});
|
||||||
|
syncWarn.addClass("sls-hidden");
|
||||||
}
|
}
|
||||||
if (this.plugin.settings.liveSync) {
|
if (this.plugin.settings.liveSync) {
|
||||||
syncNonLive.forEach((e) => {
|
syncNonLive.forEach((e) => {
|
||||||
@@ -3215,6 +3254,17 @@ class ObsidianLiveSyncSettingTab extends PluginSettingTab {
|
|||||||
text.inputEl.setAttribute("type", "number");
|
text.inputEl.setAttribute("type", "number");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
containerEl.createEl("h3", { text: "Miscellaneous" });
|
||||||
|
new Setting(containerEl)
|
||||||
|
.setName("Show status inside editor")
|
||||||
|
.setDesc("")
|
||||||
|
.addToggle((toggle) =>
|
||||||
|
toggle.setValue(this.plugin.settings.showStatusOnEditor).onChange(async (value) => {
|
||||||
|
this.plugin.settings.showStatusOnEditor = value;
|
||||||
|
await this.plugin.saveSettings();
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
containerEl.createEl("h3", { text: "Hatch" });
|
containerEl.createEl("h3", { text: "Hatch" });
|
||||||
|
|
||||||
if (this.plugin.localDatabase.remoteLockedAndDeviceNotAccepted) {
|
if (this.plugin.localDatabase.remoteLockedAndDeviceNotAccepted) {
|
||||||
@@ -3469,7 +3519,7 @@ class ObsidianLiveSyncSettingTab extends PluginSettingTab {
|
|||||||
html += `
|
html += `
|
||||||
<tr>
|
<tr>
|
||||||
<th colspan=2>${escapeStringToHTML(vaults)}</th>
|
<th colspan=2>${escapeStringToHTML(vaults)}</th>
|
||||||
</tr>`
|
</tr>`;
|
||||||
for (let v of plugins[vaults]) {
|
for (let v of plugins[vaults]) {
|
||||||
let mtime = v.mtime == 0 ? "-" : new Date(v.mtime).toLocaleString();
|
let mtime = v.mtime == 0 ? "-" : new Date(v.mtime).toLocaleString();
|
||||||
let settingApplyable: boolean | string = "-";
|
let settingApplyable: boolean | string = "-";
|
||||||
@@ -3480,9 +3530,7 @@ class ObsidianLiveSyncSettingTab extends PluginSettingTab {
|
|||||||
if (thisDevicePlugins[v.manifest.id].manifest.version == v.manifest.version) {
|
if (thisDevicePlugins[v.manifest.id].manifest.version == v.manifest.version) {
|
||||||
isSameVersion = true;
|
isSameVersion = true;
|
||||||
}
|
}
|
||||||
if (thisDevicePlugins[v.manifest.id].styleCss == v.styleCss &&
|
if (thisDevicePlugins[v.manifest.id].styleCss == v.styleCss && thisDevicePlugins[v.manifest.id].mainJs == v.mainJs && thisDevicePlugins[v.manifest.id].manifestJson == v.manifestJson) {
|
||||||
thisDevicePlugins[v.manifest.id].mainJs == v.mainJs &&
|
|
||||||
thisDevicePlugins[v.manifest.id].manifestJson == v.manifestJson) {
|
|
||||||
isSameContents = true;
|
isSameContents = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3515,7 +3563,7 @@ class ObsidianLiveSyncSettingTab extends PluginSettingTab {
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<th class='sls-table-head'>${escapeStringToHTML(v.manifest.name)}</th>
|
<th class='sls-table-head'>${escapeStringToHTML(v.manifest.name)}</th>
|
||||||
<td class="sls-table-tail tcenter">${isSameContents?"even":`<button data-key='${v._id}' class='apply-plugin-version mod-cta'>Use (${isSameVersion ? "=" : ""}${v.manifest.version}) </button>`}</td>
|
<td class="sls-table-tail tcenter">${isSameContents ? "even" : `<button data-key='${v._id}' class='apply-plugin-version mod-cta'>Use (${isSameVersion ? "=" : ""}${v.manifest.version}) </button>`}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td class="sls-table-head tcenter">${escapeStringToHTML(mtime)}</td>
|
<td class="sls-table-head tcenter">${escapeStringToHTML(mtime)}</td>
|
||||||
@@ -3528,7 +3576,7 @@ class ObsidianLiveSyncSettingTab extends PluginSettingTab {
|
|||||||
<tr class='divider'>
|
<tr class='divider'>
|
||||||
<th colspan=2></th>
|
<th colspan=2></th>
|
||||||
</tr>
|
</tr>
|
||||||
`
|
`;
|
||||||
}
|
}
|
||||||
html += "</table></div>";
|
html += "</table></div>";
|
||||||
pluginConfig.innerHTML = html;
|
pluginConfig.innerHTML = html;
|
||||||
@@ -3635,7 +3683,7 @@ class ObsidianLiveSyncSettingTab extends PluginSettingTab {
|
|||||||
xx.remove();
|
xx.remove();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
ba.addClass("mod-warning")
|
ba.addClass("mod-warning");
|
||||||
xx.createEl("button", { text: `Restore from file` }, (e) => {
|
xx.createEl("button", { text: `Restore from file` }, (e) => {
|
||||||
e.addEventListener("click", async () => {
|
e.addEventListener("click", async () => {
|
||||||
let f = await this.app.vault.getFiles().filter((e) => path2id(e.path) == k);
|
let f = await this.app.vault.getFiles().filter((e) => path2id(e.path) == k);
|
||||||
@@ -3647,7 +3695,7 @@ class ObsidianLiveSyncSettingTab extends PluginSettingTab {
|
|||||||
xx.remove();
|
xx.remove();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
xx.addClass("mod-warning")
|
xx.addClass("mod-warning");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let cx = containerEl.createEl("div", { text: "There's no collupted data." });
|
let cx = containerEl.createEl("div", { text: "There's no collupted data." });
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"id": "obsidian-livesync",
|
"id": "obsidian-livesync",
|
||||||
"name": "Self-hosted LiveSync",
|
"name": "Self-hosted LiveSync",
|
||||||
"version": "0.1.22",
|
"version": "0.1.23",
|
||||||
"minAppVersion": "0.9.12",
|
"minAppVersion": "0.9.12",
|
||||||
"description": "Community implementation of self-hosted livesync. Reflect your vault changes to some other devices immediately. Please make sure to disable other synchronize solutions to avoid content corruption or duplication.",
|
"description": "Community implementation of self-hosted livesync. Reflect your vault changes to some other devices immediately. Please make sure to disable other synchronize solutions to avoid content corruption or duplication.",
|
||||||
"author": "vorotamoroz",
|
"author": "vorotamoroz",
|
||||||
|
|||||||
4
package-lock.json
generated
4
package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "obsidian-livesync",
|
"name": "obsidian-livesync",
|
||||||
"version": "0.1.22",
|
"version": "0.1.23",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "obsidian-livesync",
|
"name": "obsidian-livesync",
|
||||||
"version": "0.1.22",
|
"version": "0.1.23",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"diff-match-patch": "^1.0.5",
|
"diff-match-patch": "^1.0.5",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "obsidian-livesync",
|
"name": "obsidian-livesync",
|
||||||
"version": "0.1.22",
|
"version": "0.1.23",
|
||||||
"description": "Reflect your vault changes to some other devices immediately. Please make sure to disable other synchronize solutions to avoid content corruption or duplication.",
|
"description": "Reflect your vault changes to some other devices immediately. Please make sure to disable other synchronize solutions to avoid content corruption or duplication.",
|
||||||
"main": "main.js",
|
"main": "main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
38
styles.css
38
styles.css
@@ -37,11 +37,11 @@
|
|||||||
/* overflow: scroll; */
|
/* overflow: scroll; */
|
||||||
}
|
}
|
||||||
.sls-plugins-tbl {
|
.sls-plugins-tbl {
|
||||||
border:1px solid var(--background-modifier-border);
|
border: 1px solid var(--background-modifier-border);
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
.divider th{
|
.divider th {
|
||||||
border-top:1px solid var(--background-modifier-border);
|
border-top: 1px solid var(--background-modifier-border);
|
||||||
}
|
}
|
||||||
/* .sls-table-head{
|
/* .sls-table-head{
|
||||||
width:50%;
|
width:50%;
|
||||||
@@ -52,8 +52,34 @@
|
|||||||
} */
|
} */
|
||||||
|
|
||||||
.sls-btn-left {
|
.sls-btn-left {
|
||||||
padding-right:4px;
|
padding-right: 4px;
|
||||||
}
|
}
|
||||||
.sls-btn-right {
|
.sls-btn-right {
|
||||||
padding-left:4px;
|
padding-left: 4px;
|
||||||
}
|
}
|
||||||
|
.sls-hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--slsmessage: "";
|
||||||
|
}
|
||||||
|
.CodeMirror-wrap::before , .cm-s-obsidian > .cm-editor::before {
|
||||||
|
content: var(--slsmessage);
|
||||||
|
position: absolute;
|
||||||
|
border-radius: 4px;
|
||||||
|
/* border:1px solid --background-modifier-border; */
|
||||||
|
display: inline-block;
|
||||||
|
top: 8px;
|
||||||
|
color: --text-normal;
|
||||||
|
opacity: 0.5;
|
||||||
|
font-size:80%;
|
||||||
|
-webkit-filter: grayscale(100%);
|
||||||
|
filter: grayscale(100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.CodeMirror-wrap::before {
|
||||||
|
right: 0px;
|
||||||
|
} .cm-s-obsidian > .cm-editor::before {
|
||||||
|
right: 16px;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user