diff --git a/src/config/setting.js b/src/config/setting.js
index e214e32..da7bdda 100644
--- a/src/config/setting.js
+++ b/src/config/setting.js
@@ -33,6 +33,7 @@ export const DEFAULT_CSPLIST = ["https://github.com"]; // 禁用CSP名单
// 同步设置
export const OPT_SYNCTYPE_WORKER = "KISS-Worker";
export const OPT_SYNCTYPE_WEBDAV = "WebDAV";
+export const OPT_SYNCTOKEN_PERFIX = "kt_";
export const OPT_SYNCTYPE_ALL = [OPT_SYNCTYPE_WORKER, OPT_SYNCTYPE_WEBDAV];
export const DEFAULT_SYNC = {
syncType: OPT_SYNCTYPE_WORKER, // 同步方式
diff --git a/src/views/Options/SyncSetting.js b/src/views/Options/SyncSetting.js
index b896639..d260596 100644
--- a/src/views/Options/SyncSetting.js
+++ b/src/views/Options/SyncSetting.js
@@ -7,18 +7,22 @@ import Alert from "@mui/material/Alert";
import Link from "@mui/material/Link";
import MenuItem from "@mui/material/MenuItem";
import LoadingButton from "@mui/lab/LoadingButton";
+import Button from "@mui/material/Button";
import {
URL_KISS_WORKER,
OPT_SYNCTYPE_ALL,
OPT_SYNCTYPE_WORKER,
OPT_SYNCTYPE_WEBDAV,
+ OPT_SYNCTOKEN_PERFIX,
} from "../../config";
import { useState } from "react";
import { syncSettingAndRules } from "../../libs/sync";
import { useAlert } from "../../hooks/Alert";
-import SyncIcon from "@mui/icons-material/Sync";
import { useSetting } from "../../hooks/Setting";
import { kissLog } from "../../libs/log";
+import SyncIcon from "@mui/icons-material/Sync";
+import ContentCopyIcon from '@mui/icons-material/ContentCopy';
+import ContentPasteIcon from '@mui/icons-material/ContentPaste';
export default function SyncSetting() {
const i18n = useI18n();
@@ -50,6 +54,57 @@ export default function SyncSetting() {
}
};
+ const handleGenerateShareString = async () => {
+ try {
+ const base64Config = btoa(JSON.stringify({
+ syncType: syncType,
+ syncUrl: syncUrl,
+ syncUser: syncUser,
+ syncKey: syncKey,
+ }));
+ const shareString = `${OPT_SYNCTOKEN_PERFIX}${base64Config}`;
+ await navigator.clipboard.writeText(shareString);
+ console.debug("Share string copied to clipboard", shareString);
+ } catch (error) {
+ console.error("Failed to copy share string to clipboard", error);
+ }
+ };
+
+ const handleImportFromClipboard = async () => {
+ try {
+ const text = await navigator.clipboard.readText();
+ console.debug('read_clipboard', text)
+ if (text.startsWith(OPT_SYNCTOKEN_PERFIX)) {
+ const base64Config = text.slice(OPT_SYNCTOKEN_PERFIX.length);
+ const jsonString = atob(base64Config);
+ const updatedConfig = JSON.parse(jsonString);
+
+ if (!OPT_SYNCTYPE_ALL.includes(updatedConfig.syncType)) {
+ console.error('error syncType', updatedConfig.syncType)
+ return;
+ }
+
+ if (
+ updatedConfig.syncUrl
+ ) {
+ updateSync({
+ syncType: updatedConfig.syncType,
+ syncUrl: updatedConfig.syncUrl,
+ syncUser: updatedConfig.syncUser,
+ syncKey: updatedConfig.syncKey,
+ });
+ } else {
+ console.error("Invalid config structure");
+ }
+ } else {
+ console.error("Invalid share string", text);
+ }
+ } catch (error) {
+ console.error("Failed to read from clipboard or parse JSON", error);
+ }
+ };
+
+
if (!sync) {
return;
}
@@ -133,6 +188,22 @@ export default function SyncSetting() {
>
{i18n("sync_now")}
+ }
+ >
+ {i18n("copy", "copy")}
+
+ }
+ >
+ {i18n("import", "import")}
+