import Box from "@mui/material/Box"; import Stack from "@mui/material/Stack"; import TextField from "@mui/material/TextField"; import { useI18n } from "../../hooks/I18n"; import { useSync } from "../../hooks/Sync"; 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 { 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(); const { sync, updateSync } = useSync(); const alert = useAlert(); const [loading, setLoading] = useState(false); const { reloadSetting } = useSetting(); const handleChange = async (e) => { e.preventDefault(); const { name, value } = e.target; await updateSync({ [name]: value, }); }; const handleSyncTest = async (e) => { e.preventDefault(); try { setLoading(true); await syncSettingAndRules(); await reloadSetting(); alert.success(i18n("sync_success")); } catch (err) { kissLog(err, "sync all"); alert.error(i18n("sync_failed")); } finally { setLoading(false); } }; 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; } const { syncType = OPT_SYNCTYPE_WORKER, syncUrl = "", syncUser = "", syncKey = "", } = sync; return ( {i18n("sync_warn")} {i18n("sync_warn_2")} {OPT_SYNCTYPE_ALL.map((item) => ( {item} ))} {i18n("about_sync_api")} ) } /> {syncType === OPT_SYNCTYPE_WEBDAV && ( )} } loading={loading} > {i18n("sync_now")} ); }