From eae593d660fb04acb99ecae40719e9e4b47404c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E8=B6=85?= Date: Thu, 15 Aug 2024 22:39:30 +0800 Subject: [PATCH] feat: Add automatic data synchronization settings and implementation, enabling auto-sync after completing replies or deleting conversations --- app/components/settings.tsx | 15 +++++++++++++++ app/locales/cn.ts | 4 ++++ app/locales/en.ts | 5 +++++ app/store/chat.ts | 14 ++++++++++++++ app/store/sync.ts | 22 +++++++++++++++++++--- app/utils/sync.ts | 8 ++++---- 6 files changed, 61 insertions(+), 7 deletions(-) diff --git a/app/components/settings.tsx b/app/components/settings.tsx index ca0a5a18796..b265d78ded2 100644 --- a/app/components/settings.tsx +++ b/app/components/settings.tsx @@ -357,6 +357,21 @@ function SyncConfigModal(props: { onClose?: () => void }) { + + { + syncStore.update( + (config) => (config.enableAutoSync = e.currentTarget.checked), + ); + }} + > + + { + syncStore.autoSync(); + }, 500); +} + const DEFAULT_CHAT_STATE = { sessions: [createEmptySession()], currentSessionIndex: 0, @@ -297,12 +307,15 @@ export const useChatStore = createPersistStore( deletedSessionIds, })); + noticeCloudSync(); + showToast( Locale.Home.DeleteToast, { text: Locale.Home.Revert, onClick() { set(() => restoreState); + noticeCloudSync(); }, }, 5000, @@ -330,6 +343,7 @@ export const useChatStore = createPersistStore( }); get().updateStat(message); get().summarizeSession(); + noticeCloudSync(); }, async onUserInput(content: string, attachImages?: string[]) { diff --git a/app/store/sync.ts b/app/store/sync.ts index d3582e3c935..e20f42bf596 100644 --- a/app/store/sync.ts +++ b/app/store/sync.ts @@ -26,6 +26,7 @@ export type SyncStore = GetStoreState; const DEFAULT_SYNC_STATE = { provider: ProviderType.WebDAV, + enableAutoSync: true, useProxy: true, proxyUrl: corsPath(ApiPath.Cors), @@ -91,6 +92,11 @@ export const useSyncStore = createPersistStore( }, async sync() { + const enableAutoSync = get().enableAutoSync; + if (!enableAutoSync) { + return; + } + const localState = getLocalAppState(); const provider = get().provider; const config = get()[provider]; @@ -100,15 +106,17 @@ export const useSyncStore = createPersistStore( 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 + 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; @@ -123,6 +131,14 @@ export const useSyncStore = createPersistStore( const client = this.getClient(); return await client.check(); }, + + async autoSync() { + const { lastSyncTime, provider } = get(); + const syncStore = useSyncStore.getState(); + if (lastSyncTime && syncStore.cloudSync()) { + syncStore.sync(); + } + }, }), { name: StoreKey.Sync, diff --git a/app/utils/sync.ts b/app/utils/sync.ts index 1c8f0a11bf9..0943260abc2 100644 --- a/app/utils/sync.ts +++ b/app/utils/sync.ts @@ -130,10 +130,10 @@ const MergeStates: StateMerger = { }); // sort local sessions with date field in desc order - localState.sessions.sort( - (a, b) => - new Date(b.lastUpdate).getTime() - new Date(a.lastUpdate).getTime(), - ); + // localState.sessions.sort( + // (a, b) => + // new Date(b.lastUpdate).getTime() - new Date(a.lastUpdate).getTime(), + // ); const deletedSessionIds = { ...remoteDeletedSessionIds,