mirror of
				https://github.com/Yidadaa/ChatGPT-Next-Web.git
				synced 2025-11-04 08:26:12 +08:00 
			
		
		
		
	new fix
This commit is contained in:
		@@ -99,24 +99,22 @@ export const useSyncStore = createPersistStore(
 | 
			
		||||
      try {
 | 
			
		||||
        const remoteState = await client.get(config.username);
 | 
			
		||||
        if (!remoteState || remoteState === "") {
 | 
			
		||||
          await client.set(config.username, JSON.stringify(localState));
 | 
			
		||||
          console.log("[Sync] Remote state is empty, using local state instead.");
 | 
			
		||||
          return
 | 
			
		||||
        } else {
 | 
			
		||||
          const parsedRemoteState = JSON.parse(
 | 
			
		||||
            await client.get(config.username),
 | 
			
		||||
          ) as AppState;
 | 
			
		||||
 | 
			
		||||
          mergeAppState(localState, parsedRemoteState);
 | 
			
		||||
          setLocalAppState(localState);
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
       } 
 | 
			
		||||
      } catch (e) {
 | 
			
		||||
        console.log("[Sync] failed to get remote state", e);
 | 
			
		||||
        throw e;
 | 
			
		||||
      }
 | 
			
		||||
    
 | 
			
		||||
      await client.set(config.username, JSON.stringify(localState));
 | 
			
		||||
      console.log("client set", localState);
 | 
			
		||||
      this.markSyncTime();
 | 
			
		||||
    },    
 | 
			
		||||
 | 
			
		||||
@@ -149,3 +147,161 @@ export const useSyncStore = createPersistStore(
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
**Output:**
 | 
			
		||||
<!-- prettier-ignore -->
 | 
			
		||||
```tsx
 | 
			
		||||
import { getClientConfig } from "../config/client";
 | 
			
		||||
import { Updater } from "../typing";
 | 
			
		||||
import { ApiPath, STORAGE_KEY, StoreKey } from "../constant";
 | 
			
		||||
import { createPersistStore } from "../utils/store";
 | 
			
		||||
import {
 | 
			
		||||
  AppState,
 | 
			
		||||
  getLocalAppState,
 | 
			
		||||
  GetStoreState,
 | 
			
		||||
  mergeAppState,
 | 
			
		||||
  setLocalAppState,
 | 
			
		||||
} from "../utils/sync";
 | 
			
		||||
import { downloadAs, readFromFile } from "../utils";
 | 
			
		||||
import { showToast } from "../components/ui-lib";
 | 
			
		||||
import Locale from "../locales";
 | 
			
		||||
import { createSyncClient, ProviderType } from "../utils/cloud";
 | 
			
		||||
import { corsPath } from "../utils/cors";
 | 
			
		||||
 | 
			
		||||
export interface WebDavConfig {
 | 
			
		||||
  server: string;
 | 
			
		||||
  username: string;
 | 
			
		||||
  password: string;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const isApp = !!getClientConfig()?.isApp;
 | 
			
		||||
export type SyncStore = GetStoreState<typeof useSyncStore>;
 | 
			
		||||
 | 
			
		||||
const DEFAULT_SYNC_STATE = {
 | 
			
		||||
  provider: ProviderType.WebDAV,
 | 
			
		||||
  useProxy: true,
 | 
			
		||||
  proxyUrl: corsPath(ApiPath.Cors),
 | 
			
		||||
 | 
			
		||||
  webdav: {
 | 
			
		||||
    endpoint: "",
 | 
			
		||||
    username: "",
 | 
			
		||||
    password: "",
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  upstash: {
 | 
			
		||||
    endpoint: "",
 | 
			
		||||
    username: STORAGE_KEY,
 | 
			
		||||
    apiKey: "",
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  lastSyncTime: 0,
 | 
			
		||||
  lastProvider: "",
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const useSyncStore = createPersistStore(
 | 
			
		||||
  DEFAULT_SYNC_STATE,
 | 
			
		||||
  (set, get) => ({
 | 
			
		||||
    cloudSync() {
 | 
			
		||||
      const config = get()[get().provider];
 | 
			
		||||
      return Object.values(config).every((c) => c.toString().length > 0);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    markSyncTime() {
 | 
			
		||||
      set({ lastSyncTime: Date.now(), lastProvider: get().provider });
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    export() {
 | 
			
		||||
      const state = getLocalAppState();
 | 
			
		||||
      const datePart = isApp
 | 
			
		||||
        ? `${new Date().toLocaleDateString().replace(/\//g, "_")} ${new Date()
 | 
			
		||||
            .toLocaleTimeString()
 | 
			
		||||
            .replace(/:/g, "_")}`
 | 
			
		||||
        : new Date().toLocaleString();
 | 
			
		||||
 | 
			
		||||
      const fileName = `Backup-${datePart}.json`;
 | 
			
		||||
      downloadAs(JSON.stringify(state), fileName);
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    async import() {
 | 
			
		||||
      const rawContent = await readFromFile();
 | 
			
		||||
 | 
			
		||||
      try {
 | 
			
		||||
        const remoteState = JSON.parse(rawContent) as AppState;
 | 
			
		||||
        const localState = getLocalAppState();
 | 
			
		||||
        mergeAppState(localState, remoteState);
 | 
			
		||||
        setLocalAppState(localState);
 | 
			
		||||
        location.reload();
 | 
			
		||||
      } catch (e) {
 | 
			
		||||
        console.error("[Import]", e);
 | 
			
		||||
        showToast(Locale.Settings.Sync.ImportFailed);
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    getClient() {
 | 
			
		||||
      const provider = get().provider;
 | 
			
		||||
      const client = createSyncClient(provider, get());
 | 
			
		||||
      return client;
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    async sync() {
 | 
			
		||||
      const localState = getLocalAppState();
 | 
			
		||||
      const provider = get().provider;
 | 
			
		||||
      const config = get()[provider];
 | 
			
		||||
      const client = this.getClient();
 | 
			
		||||
 | 
			
		||||
      try {
 | 
			
		||||
        const remoteState = await client.get(config.username);
 | 
			
		||||
        if (!remoteState || remoteState === "") {
 | 
			
		||||
          console.log(
 | 
			
		||||
            "[Sync] Remote state is empty, using local state instead.",
 | 
			
		||||
          );
 | 
			
		||||
          return;
 | 
			
		||||
        } else {
 | 
			
		||||
          const parsedRemoteState = JSON.parse(
 | 
			
		||||
            await client.get(config.username),
 | 
			
		||||
          ) as AppState;
 | 
			
		||||
 | 
			
		||||
          mergeAppState(localState, parsedRemoteState);
 | 
			
		||||
          setLocalAppState(localState);
 | 
			
		||||
        }
 | 
			
		||||
      } catch (e) {
 | 
			
		||||
        console.log("[Sync] failed to get remote state", e);
 | 
			
		||||
        throw e;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      await client.set(config.username, JSON.stringify(localState));
 | 
			
		||||
      console.log("client set", localState);
 | 
			
		||||
      this.markSyncTime();
 | 
			
		||||
    },
 | 
			
		||||
 | 
			
		||||
    async check() {
 | 
			
		||||
      const client = this.getClient();
 | 
			
		||||
      return await client.check();
 | 
			
		||||
    },
 | 
			
		||||
  }),
 | 
			
		||||
  {
 | 
			
		||||
    name: StoreKey.Sync,
 | 
			
		||||
    version: 1.2,
 | 
			
		||||
 | 
			
		||||
    migrate(persistedState, version) {
 | 
			
		||||
      const newState = persistedState as typeof DEFAULT_SYNC_STATE;
 | 
			
		||||
 | 
			
		||||
      if (version < 1.1) {
 | 
			
		||||
        newState.upstash.username = STORAGE_KEY;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (version < 1.2) {
 | 
			
		||||
        if (
 | 
			
		||||
          (persistedState as typeof DEFAULT_SYNC_STATE).proxyUrl ===
 | 
			
		||||
          "/api/cors/"
 | 
			
		||||
        ) {
 | 
			
		||||
          newState.proxyUrl = "";
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return newState as any;
 | 
			
		||||
    },
 | 
			
		||||
  },
 | 
			
		||||
);
 | 
			
		||||
		Reference in New Issue
	
	Block a user