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,
+ },
+ ),
+);