diff --git a/app/components/settings.tsx b/app/components/settings.tsx index 41fed620..1d45a0c6 100644 --- a/app/components/settings.tsx +++ b/app/components/settings.tsx @@ -46,6 +46,7 @@ import { InputRange } from "./input-range"; import { useNavigate } from "react-router-dom"; import { Avatar, AvatarPicker } from "./emoji"; import { getClientConfig } from "../config/client"; +import { useSyncStore } from "../store/sync"; function EditPromptModal(props: { id: number; onClose: () => void }) { const promptStore = usePromptStore(); @@ -198,6 +199,78 @@ function UserPromptModal(props: { onClose?: () => void }) { ); } +function SyncItems() { + const syncStore = useSyncStore(); + const webdav = syncStore.webDavConfig; + + // not ready: https://github.com/Yidadaa/ChatGPT-Next-Web/issues/920#issuecomment-1609866332 + return null; + + return ( + + + } + text="同步" + onClick={() => { + syncStore.check().then(console.log); + }} + /> + + + + + + { + syncStore.update( + (config) => (config.server = e.currentTarget.value), + ); + }} + /> + + + + { + syncStore.update( + (config) => (config.username = e.currentTarget.value), + ); + }} + /> + + + + { + syncStore.update( + (config) => (config.password = e.currentTarget.value), + ); + }} + /> + + + ); +} + function formatVersionDate(t: string) { const d = new Date(+t); const year = d.getUTCFullYear(); @@ -556,6 +629,7 @@ export function Settings() { accessStore.updateOpenAiUrl(e.currentTarget.value) } @@ -596,6 +670,8 @@ export function Settings() { + + ; + check: () => Promise; + + path: (path: string) => string; + headers: () => { Authorization: string }; +} + +const FILE = { + root: "/chatgpt-next-web/", +}; + +export const useSyncStore = create()( + persist( + (set, get) => ({ + webDavConfig: { + server: "", + username: "", + password: "", + }, + + lastSyncTime: 0, + + update(updater) { + const config = { ...get().webDavConfig }; + updater(config); + set({ webDavConfig: config }); + }, + + async check() { + try { + const res = await fetch(this.path(""), { + method: "PROFIND", + headers: this.headers(), + }); + console.log(res); + return res.status === 207; + } catch (e) { + console.error("[Sync] ", e); + return false; + } + }, + + path(path: string) { + let url = get().webDavConfig.server; + + if (!url.endsWith("/")) { + url += "/"; + } + + if (path.startsWith("/")) { + path = path.slice(1); + } + + return url + path; + }, + + headers() { + const auth = btoa( + [get().webDavConfig.username, get().webDavConfig.password].join(":"), + ); + + return { + Authorization: `Basic ${auth}`, + }; + }, + }), + { + name: StoreKey.Sync, + version: 1, + }, + ), +);