sync.ts 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  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. console.log(res);
  54. return res.status === 207;
  55. } catch (e) {
  56. console.error("[Sync] ", e);
  57. return false;
  58. }
  59. },
  60. path(path: string) {
  61. let url = get().webDavConfig.server;
  62. if (!url.endsWith("/")) {
  63. url += "/";
  64. }
  65. if (path.startsWith("/")) {
  66. path = path.slice(1);
  67. }
  68. return url + path;
  69. },
  70. headers() {
  71. const auth = btoa(
  72. [get().webDavConfig.username, get().webDavConfig.password].join(":"),
  73. );
  74. return {
  75. Authorization: `Basic ${auth}`,
  76. };
  77. },
  78. }),
  79. {
  80. name: StoreKey.Sync,
  81. version: 1,
  82. },
  83. );