diff --git a/app/src/config/about.ts b/app/src/config/about.ts
index a654e07d9..ff198c36a 100644
--- a/app/src/config/about.ts
+++ b/app/src/config/about.ts
@@ -99,7 +99,7 @@ export const about = {
diff --git a/app/src/config/repos.ts b/app/src/config/repos.ts
index e02a881ad..a1d85a65b 100644
--- a/app/src/config/repos.ts
+++ b/app/src/config/repos.ts
@@ -1,42 +1,8 @@
-import {confirmDialog} from "../dialog/confirmDialog";
import {needSubscribe} from "../util/needSubscribe";
import {fetchPost} from "../util/fetch";
import {isMobile} from "../util/functions";
-import {Dialog} from "../dialog";
import {showMessage} from "../dialog/message";
-
-const getCloudList = (reload = false) => {
- const listElement = repos.element.querySelector("#reposCloudSyncList");
- if (!reload && listElement.firstElementChild.tagName !== "IMG") {
- return;
- }
- fetchPost("/api/sync/listCloudSyncDir", {}, (response) => {
- let syncListHTML = `
- ${window.siyuan.languages.emptyCloudSyncList}
`;
- if (response.code !== 1) {
- syncListHTML = '
-
-
-
-
-
`;
- }
- listElement.innerHTML = syncListHTML;
- });
-};
+import {bindSyncCloudListEvent, getSyncCloudList} from "../sync/syncGuide";
const renderCloudBackup = () => {
fetchPost("/api/cloud/getCloudSpace", {}, (response) => {
@@ -70,37 +36,6 @@ const renderCloudBackup = () => {
});
};
-const addCloudName = () => {
- const dialog = new Dialog({
- title: window.siyuan.languages.cloudSyncDir,
- content: `
-
-
${window.siyuan.languages.reposTip}
-
-
-
-
-
`,
- width: isMobile() ? "80vw" : "520px",
- });
- const inputElement = dialog.element.querySelector("input") as HTMLInputElement;
- const btnsElement = dialog.element.querySelectorAll(".b3-button");
- dialog.bindInput(inputElement, () => {
- (btnsElement[1] as HTMLButtonElement).click();
- });
- inputElement.focus();
- inputElement.select();
- btnsElement[0].addEventListener("click", () => {
- dialog.destroy();
- });
- btnsElement[1].addEventListener("click", () => {
- fetchPost("/api/sync/createCloudSyncDir", {name: inputElement.value}, () => {
- dialog.destroy();
- getCloudList(true);
- });
- });
-};
-
export const repos = {
element: undefined as Element,
genHTML: () => {
@@ -170,7 +105,7 @@ export const repos = {
${window.siyuan.languages.config}
-
${window.siyuan.languages.cloudBackup}
@@ -213,44 +148,14 @@ export const repos = {
const loadingElement = repos.element.querySelector("#reposLoading") as HTMLElement;
loadingElement.style.width = repos.element.clientWidth + "px";
loadingElement.style.height = repos.element.clientHeight + "px";
- repos.element.firstElementChild.addEventListener("click", (event) => {
- let target = event.target as HTMLElement;
- const syncConfigElement = repos.element.querySelector("#reposCloudSyncList");
- while (target && !target.isEqualNode(repos.element.firstElementChild)) {
- const type = target.getAttribute("data-type");
- if (type) {
- switch (type) {
- case "config":
- if (syncConfigElement.classList.contains("fn__none")) {
- getCloudList();
- syncConfigElement.classList.remove("fn__none");
- } else {
- syncConfigElement.classList.add("fn__none");
- }
- break;
- case "addCloud":
- addCloudName();
- break;
- case "removeCloud":
- confirmDialog(window.siyuan.languages.confirm, `${window.siyuan.languages.confirmDeleteCloudDir}
${target.parentElement.getAttribute("data-name")}`, () => {
- fetchPost("/api/sync/removeCloudSyncDir", {name: target.parentElement.getAttribute("data-name")}, (response) => {
- window.siyuan.config.sync.cloudName = response.data;
- getCloudList(true);
- });
- });
- break;
- case "selectCloud":
- fetchPost("/api/sync/setCloudSyncDir", {name: target.getAttribute("data-name")}, () => {
- window.siyuan.config.sync.cloudName = target.getAttribute("data-name");
- getCloudList(true);
- });
- break;
- }
- event.preventDefault();
- event.stopPropagation();
- break;
- }
- target = target.parentElement;
+ const syncConfigElement = repos.element.querySelector("#reposCloudSyncList");
+ bindSyncCloudListEvent(syncConfigElement);
+ repos.element.querySelector('[data-type="config"]').addEventListener("click", (event) => {
+ if (syncConfigElement.classList.contains("fn__none")) {
+ getSyncCloudList(syncConfigElement);
+ syncConfigElement.classList.remove("fn__none");
+ } else {
+ syncConfigElement.classList.add("fn__none");
}
});
},
diff --git a/app/src/mobile/util/menu.ts b/app/src/mobile/util/menu.ts
index 634513343..f730aa8e1 100644
--- a/app/src/mobile/util/menu.ts
+++ b/app/src/mobile/util/menu.ts
@@ -14,6 +14,7 @@ import {exitSiYuan} from "../../dialog/processSystem";
import {confirmDialog} from "../../dialog/confirmDialog";
import {openHistory} from "../../util/history";
import {Dialog} from "../../dialog";
+import {syncGuide} from "../../sync/syncGuide";
const showAccountInfo = (modelElement: HTMLElement, modelMainElement: Element) => {
closePanel();
@@ -435,14 +436,7 @@ ${accountHTML}
event.stopPropagation();
break;
} else if (target.id === "menuSyncNow") {
- if (needSubscribe()) {
- return;
- }
- if (!window.siyuan.config.sync.enabled) {
- showMessage(window.siyuan.languages._kernel[124]);
- return;
- }
- fetchPost("/api/sync/performSync", {});
+ syncGuide();
event.preventDefault();
event.stopPropagation();
break;
diff --git a/app/src/sync/syncGuide.ts b/app/src/sync/syncGuide.ts
new file mode 100644
index 000000000..c44199d1f
--- /dev/null
+++ b/app/src/sync/syncGuide.ts
@@ -0,0 +1,257 @@
+import {needSubscribe} from "../util/needSubscribe";
+import {showMessage} from "../dialog/message";
+import {fetchPost} from "../util/fetch";
+import {Dialog} from "../dialog";
+import {confirmDialog} from "../dialog/confirmDialog";
+import {isMobile} from "../util/functions";
+
+export const addCloudName = (cloudPanelElement: Element) => {
+ const dialog = new Dialog({
+ title: window.siyuan.languages.cloudSyncDir,
+ content: `
+
+
${window.siyuan.languages.reposTip}
+
+
+
+
+
`,
+ width: isMobile() ? "80vw" : "520px",
+ });
+ const inputElement = dialog.element.querySelector("input") as HTMLInputElement;
+ const btnsElement = dialog.element.querySelectorAll(".b3-button");
+ dialog.bindInput(inputElement, () => {
+ (btnsElement[1] as HTMLButtonElement).click();
+ });
+ inputElement.focus();
+ inputElement.select();
+ btnsElement[0].addEventListener("click", () => {
+ dialog.destroy();
+ });
+ btnsElement[1].addEventListener("click", () => {
+ cloudPanelElement.innerHTML = '

'
+ fetchPost("/api/sync/createCloudSyncDir", {name: inputElement.value}, () => {
+ dialog.destroy();
+ getSyncCloudList(cloudPanelElement, true);
+ });
+ });
+};
+
+export const bindSyncCloudListEvent = (cloudPanelElement: Element) => {
+ cloudPanelElement.addEventListener("click", (event) => {
+ let target = event.target as HTMLElement;
+ while (target && !target.isEqualNode(cloudPanelElement)) {
+ const type = target.getAttribute("data-type");
+ if (type) {
+ switch (type) {
+ case "addCloud":
+ addCloudName(cloudPanelElement);
+ break;
+ case "removeCloud":
+ confirmDialog(window.siyuan.languages.confirm, `${window.siyuan.languages.confirmDeleteCloudDir}
${target.parentElement.getAttribute("data-name")}`, () => {
+ cloudPanelElement.innerHTML = '

'
+ fetchPost("/api/sync/removeCloudSyncDir", {name: target.parentElement.getAttribute("data-name")}, (response) => {
+ window.siyuan.config.sync.cloudName = response.data;
+ getSyncCloudList(cloudPanelElement, true);
+ });
+ });
+ break;
+ case "selectCloud":
+ cloudPanelElement.innerHTML = '

'
+ fetchPost("/api/sync/setCloudSyncDir", {name: target.getAttribute("data-name")}, () => {
+ window.siyuan.config.sync.cloudName = target.getAttribute("data-name");
+ getSyncCloudList(cloudPanelElement, true);
+ });
+ break;
+ }
+ event.preventDefault();
+ event.stopPropagation();
+ break;
+ }
+ target = target.parentElement;
+ }
+ });
+};
+
+export const getSyncCloudList = (cloudPanelElement: Element, reload = false) => {
+ if (!reload && cloudPanelElement.firstElementChild.tagName !== "IMG") {
+ return;
+ }
+ fetchPost("/api/sync/listCloudSyncDir", {}, (response) => {
+ let syncListHTML = `
- ${window.siyuan.languages.emptyCloudSyncList}
`;
+ if (response.code !== 1) {
+ syncListHTML = '
+
+
+
+
+
`;
+ }
+ cloudPanelElement.innerHTML = syncListHTML;
+ });
+};
+
+export const syncGuide = (element?: Element) => {
+ if (needSubscribe() || (element && element.classList.contains("fn__rotate"))) {
+ return;
+ }
+ if (!window.siyuan.config.repo.key) {
+ setKey();
+ return;
+ }
+ if (!window.siyuan.config.sync.enabled) {
+ setSync();
+ return;
+ }
+ fetchPost("/api/sync/performSync", {});
+}
+
+const setSync = (key?: string, dialog?: Dialog) => {
+ if (dialog) {
+ dialog.destroy();
+ }
+ if (key) {
+ window.siyuan.config.repo.key = key;
+ }
+ if (!window.siyuan.config.sync.enabled) {
+ const listDialog = new Dialog({
+ title: window.siyuan.languages.cloudSyncDir,
+ content: `
+

+
+
+
+
`,
+ width: isMobile() ? "80vw" : "520px",
+ });
+ const contentElement = listDialog.element.querySelector(".b3-dialog__content")
+ bindSyncCloudListEvent(contentElement);
+ getSyncCloudList(contentElement);
+ listDialog.element.querySelector(".b3-button").addEventListener("click", () => {
+ listDialog.destroy()
+ fetchPost("/api/sync/setSyncEnable", {enabled: true}, (response) => {
+ if (response.code === 1) {
+ showMessage(response.msg);
+ } else {
+ window.siyuan.config.sync.enabled = true
+ confirmDialog(window.siyuan.languages.sync, window.siyuan.languages.syncNow, () => {
+ fetchPost("/api/sync/performSync", {});
+ });
+ }
+ });
+ });
+ } else {
+ confirmDialog(window.siyuan.languages.sync, window.siyuan.languages.syncNow, () => {
+ fetchPost("/api/sync/performSync", {});
+ });
+ }
+}
+
+const setKey = () => {
+ const dialog = new Dialog({
+ title: window.siyuan.languages.dataRepoKey,
+ content: `
+
${window.siyuan.languages.dataRepoKeyTip1}
+
+
+
+
+
+
+
+
${window.siyuan.languages.dataRepoKeyTip2}
+
+
+
+
`
+ });
+ dialog.element.querySelector(".b3-button--cancel").addEventListener("click", () => {
+ dialog.destroy();
+ });
+ dialog.element.querySelector("#importKey").addEventListener("click", () => {
+ const passwordDialog = new Dialog({
+ title: "🔑 " + window.siyuan.languages.key,
+ content: `
+
+
+
+
+
+
`,
+ width: isMobile() ? "80vw" : "520px",
+ });
+ const textAreaElement = passwordDialog.element.querySelector("textarea");
+ textAreaElement.focus();
+ const btnsElement = passwordDialog.element.querySelectorAll(".b3-button");
+ btnsElement[0].addEventListener("click", () => {
+ passwordDialog.destroy();
+ });
+ btnsElement[1].addEventListener("click", () => {
+ fetchPost("/api/repo/importRepoKey", {key: textAreaElement.value}, () => {
+ setSync(textAreaElement.value, dialog);
+ passwordDialog.destroy();
+ });
+ });
+ });
+ dialog.element.querySelector("#initKey").addEventListener("click", () => {
+ confirmDialog("🔑 " + window.siyuan.languages.genKey, window.siyuan.languages.initRepoKeyTip, () => {
+ fetchPost("/api/repo/initRepoKey", {}, (response) => {
+ setSync(response.data.key, dialog);
+ });
+ });
+ });
+ dialog.element.querySelector("#initKeyByPW").addEventListener("click", () => {
+ const initDialog = new Dialog({
+ title: "🔑 " + window.siyuan.languages.genKeyByPW,
+ content: `
+
+
+
+
+
+
`,
+ width: isMobile() ? "80vw" : "520px",
+ });
+ const inputElement = initDialog.element.querySelector(".b3-text-field") as HTMLInputElement;
+ inputElement.focus();
+ const btnsElement = initDialog.element.querySelectorAll(".b3-button");
+ initDialog.bindInput(inputElement, () => {
+ (btnsElement[1] as HTMLButtonElement).click();
+ });
+ btnsElement[0].addEventListener("click", () => {
+ initDialog.destroy();
+ });
+ btnsElement[1].addEventListener("click", () => {
+ if (!inputElement.value) {
+ showMessage(window.siyuan.languages._kernel[142]);
+ return;
+ }
+ confirmDialog("🔑 " + window.siyuan.languages.genKeyByPW, window.siyuan.languages.initRepoKeyTip, () => {
+ initDialog.destroy();
+ fetchPost("/api/repo/InitRepoKeyFromPassphrase", {pass: inputElement.value}, (response) => {
+ setSync(response.data.key, dialog);
+ });
+ });
+ });
+ });
+}
diff --git a/app/src/util/globalShortcut.ts b/app/src/util/globalShortcut.ts
index 084ecf00d..5631ba08b 100644
--- a/app/src/util/globalShortcut.ts
+++ b/app/src/util/globalShortcut.ts
@@ -38,6 +38,7 @@ import {Dialog} from "../dialog";
import {unicode2Emoji} from "../emoji";
import {deleteFile} from "../editor/deleteFile";
import {escapeHtml} from "./escape";
+import {syncGuide} from "../sync/syncGuide";
const getRightBlock = (element: HTMLElement, x: number, y: number) => {
let index = 1;
@@ -378,14 +379,7 @@ export const globalShortcut = () => {
if (matchHotKey(window.siyuan.config.keymap.general.syncNow.custom, event)) {
event.preventDefault();
event.stopPropagation();
- if (needSubscribe() || document.querySelector("#barSync svg").classList.contains("fn__rotate")) {
- return;
- }
- if (!window.siyuan.config.sync.enabled) {
- showMessage(window.siyuan.languages._kernel[124]);
- return;
- }
- fetchPost("/api/sync/performSync", {});
+ syncGuide(document.querySelector("#barSync svg"));
return;
}
if (matchHotKey(window.siyuan.config.keymap.general.lockScreen.custom, event)) {
diff --git a/app/src/util/onGetConfig.ts b/app/src/util/onGetConfig.ts
index e68cd775d..c751a55c5 100644
--- a/app/src/util/onGetConfig.ts
+++ b/app/src/util/onGetConfig.ts
@@ -23,6 +23,7 @@ import {openSetting} from "../config";
import {getSearch} from "./functions";
import {openHistory} from "./history";
import {initStatus} from "../layout/status";
+import {syncGuide} from "../sync/syncGuide";
const matchKeymap = (keymap: Record
, key1: "general" | "editor", key2?: "general" | "insert" | "heading" | "list" | "table") => {
if (key1 === "general") {
@@ -205,14 +206,7 @@ const initBar = () => {
event.stopPropagation();
break;
} else if (target.id === "barSync") {
- if (needSubscribe() || target.firstElementChild.classList.contains("fn__rotate")) {
- return;
- }
- if (!window.siyuan.config.sync.enabled) {
- showMessage(window.siyuan.languages._kernel[124]);
- return;
- }
- fetchPost("/api/sync/performSync", {});
+ syncGuide(target.firstElementChild);
event.stopPropagation();
break;
} else if (target.id === "barForward") {