sync.ts 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. import { Updater } from "../typing";
  2. import { create } from "zustand";
  3. import { persist } from "zustand/middleware";
  4. import { StoreKey } from "../constant";
  5. export interface WebDavConfig {
  6. server: string;
  7. username: string;
  8. password: string;
  9. }
  10. export interface SyncStore {
  11. webDavConfig: WebDavConfig;
  12. lastSyncTime: number;
  13. update: Updater<WebDavConfig>;
  14. check: () => Promise<boolean>;
  15. path: (path: string) => string;
  16. headers: () => { Authorization: string };
  17. }
  18. const FILE = {
  19. root: "/chatgpt-next-web/",
  20. };
  21. export const useSyncStore = create<SyncStore>()(
  22. persist(
  23. (set, get) => ({
  24. webDavConfig: {
  25. server: "",
  26. username: "",
  27. password: "",
  28. },
  29. lastSyncTime: 0,
  30. update(updater) {
  31. const config = { ...get().webDavConfig };
  32. updater(config);
  33. set({ webDavConfig: config });
  34. },
  35. async check() {
  36. try {
  37. const res = await fetch(this.path(""), {
  38. method: "PROFIND",
  39. headers: this.headers(),
  40. });
  41. console.log(res);
  42. return res.status === 207;
  43. } catch (e) {
  44. console.error("[Sync] ", e);
  45. return false;
  46. }
  47. },
  48. path(path: string) {
  49. let url = get().webDavConfig.server;
  50. if (!url.endsWith("/")) {
  51. url += "/";
  52. }
  53. if (path.startsWith("/")) {
  54. path = path.slice(1);
  55. }
  56. return url + path;
  57. },
  58. headers() {
  59. const auth = btoa(
  60. [get().webDavConfig.username, get().webDavConfig.password].join(":"),
  61. );
  62. return {
  63. Authorization: `Basic ${auth}`,
  64. };
  65. },
  66. }),
  67. {
  68. name: StoreKey.Sync,
  69. version: 1,
  70. },
  71. ),
  72. );