sync.ts 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. import { Updater } from "../typing";
  2. import { StoreKey } from "../constant";
  3. import { createPersistStore } from "../utils/store";
  4. import {
  5. AppState,
  6. getLocalAppState,
  7. mergeAppState,
  8. setLocalAppState,
  9. } from "../utils/sync";
  10. import { downloadAs, readFromFile } from "../utils";
  11. import { showToast } from "../components/ui-lib";
  12. import Locale from "../locales";
  13. export interface WebDavConfig {
  14. server: string;
  15. username: string;
  16. password: string;
  17. }
  18. export const useSyncStore = createPersistStore(
  19. {
  20. webDavConfig: {
  21. server: "",
  22. username: "",
  23. password: "",
  24. },
  25. lastSyncTime: 0,
  26. },
  27. (set, get) => ({
  28. export() {
  29. const state = getLocalAppState();
  30. const fileName = `Backup-${new Date().toLocaleString()}.json`;
  31. downloadAs(JSON.stringify(state), fileName);
  32. set({ lastSyncTime: Date.now() });
  33. },
  34. async import() {
  35. const rawContent = await readFromFile();
  36. try {
  37. const remoteState = JSON.parse(rawContent) as AppState;
  38. const localState = getLocalAppState();
  39. mergeAppState(localState, remoteState);
  40. setLocalAppState(localState);
  41. location.reload();
  42. } catch (e) {
  43. console.error("[Import]", e);
  44. showToast(Locale.Settings.Sync.ImportFailed);
  45. }
  46. },
  47. async check() {
  48. try {
  49. const res = await fetch(this.path(""), {
  50. method: "PROFIND",
  51. headers: this.headers(),
  52. });
  53. const sanitizedRes = {
  54. status: res.status,
  55. statusText: res.statusText,
  56. headers: res.headers,
  57. };
  58. console.log(sanitizedRes);
  59. return res.status === 207;
  60. } catch (e) {
  61. console.error("[Sync] ", e);
  62. return false;
  63. }
  64. },
  65. path(path: string) {
  66. let url = get().webDavConfig.server;
  67. if (!url.endsWith("/")) {
  68. url += "/";
  69. }
  70. if (path.startsWith("/")) {
  71. path = path.slice(1);
  72. }
  73. return url + path;
  74. },
  75. headers() {
  76. const auth = btoa(
  77. [get().webDavConfig.username, get().webDavConfig.password].join(":"),
  78. );
  79. return {
  80. Authorization: `Basic ${auth}`,
  81. };
  82. },
  83. }),
  84. {
  85. name: StoreKey.Sync,
  86. version: 1,
  87. },
  88. );