mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-27 04:31:27 +08:00
fix: flush redux persist data when app quit and update (#8741)
* feat(database): enable strict transaction durability for CherryStudio database - Updated the Dexie database initialization to include `chromeTransactionDurability: 'strict'`, enhancing data integrity during transactions. * feat(app): enhance application shutdown process and data flushing - Added functionality to flush storage data and cookies before quitting the application, ensuring data integrity. - Introduced a new `handleBeforeQuit` function to centralize cleanup logic for both manual and update-triggered quits. - Updated logging to provide better insights during the shutdown process. - Modified ProxyManager to use debug level for unchanged proxy configurations. - Added `persistor` to the global window object and implemented `handleSaveData` to flush Redux state before quitting. * format code * feat(ipc): add App_SaveData channel and implement data saving on window close - Introduced a new IPC channel `App_SaveData` for saving application data. - Updated `WindowService` to send a save data message when the main window is closed. - Enhanced `useAppInit` hook to handle the `App_SaveData` event and trigger data saving logic. * refactor(env): remove persistor from global window object - Removed the `persistor` property from the global `window` object in both `env.d.ts` and `index.ts` files, streamlining the application state management.
This commit is contained in:
parent
b7394c98a4
commit
488a01d7d7
@ -34,6 +34,7 @@ export enum IpcChannel {
|
||||
App_InstallUvBinary = 'app:install-uv-binary',
|
||||
App_InstallBunBinary = 'app:install-bun-binary',
|
||||
App_LogToMain = 'app:log-to-main',
|
||||
App_SaveData = 'app:save-data',
|
||||
|
||||
App_MacIsProcessTrusted = 'app:mac-is-process-trusted',
|
||||
App_MacRequestProcessTrust = 'app:mac-request-process-trust',
|
||||
|
||||
@ -66,7 +66,7 @@ export class ProxyManager {
|
||||
|
||||
try {
|
||||
if (config?.mode === this.config?.mode && config?.proxyRules === this.config?.proxyRules) {
|
||||
logger.info('proxy config is the same, skip configure')
|
||||
logger.debug('proxy config is the same, skip configure')
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@ -319,6 +319,13 @@ export class WindowService {
|
||||
|
||||
private setupWindowLifecycleEvents(mainWindow: BrowserWindow) {
|
||||
mainWindow.on('close', (event) => {
|
||||
// save data before when close window
|
||||
try {
|
||||
mainWindow.webContents.send(IpcChannel.App_SaveData)
|
||||
} catch (error) {
|
||||
logger.error('Failed to save data:', error as Error)
|
||||
}
|
||||
|
||||
// 如果已经触发退出,直接退出
|
||||
if (app.isQuitting) {
|
||||
return app.quit()
|
||||
|
||||
@ -8,10 +8,12 @@ import KnowledgeQueue from '@renderer/queue/KnowledgeQueue'
|
||||
import MemoryService from '@renderer/services/MemoryService'
|
||||
import { useAppDispatch } from '@renderer/store'
|
||||
import { useAppSelector } from '@renderer/store'
|
||||
import { handleSaveData } from '@renderer/store'
|
||||
import { selectMemoryConfig } from '@renderer/store/memory'
|
||||
import { setAvatar, setFilesPath, setResourcesPath, setUpdateState } from '@renderer/store/runtime'
|
||||
import { delay, runAsyncFunction } from '@renderer/utils'
|
||||
import { defaultLanguage } from '@shared/config/constant'
|
||||
import { IpcChannel } from '@shared/IpcChannel'
|
||||
import { useLiveQuery } from 'dexie-react-hooks'
|
||||
import { useEffect } from 'react'
|
||||
|
||||
@ -49,6 +51,12 @@ export function useAppInit() {
|
||||
})
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
window.electron.ipcRenderer.on(IpcChannel.App_SaveData, async () => {
|
||||
await handleSaveData()
|
||||
})
|
||||
}, [])
|
||||
|
||||
useUpdateHandler()
|
||||
useFullScreenNotice()
|
||||
|
||||
|
||||
@ -7,7 +7,7 @@ import { useMinappPopup } from '@renderer/hooks/useMinappPopup'
|
||||
import { useRuntime } from '@renderer/hooks/useRuntime'
|
||||
import { useSettings } from '@renderer/hooks/useSettings'
|
||||
import i18n from '@renderer/i18n'
|
||||
import { useAppDispatch } from '@renderer/store'
|
||||
import { handleSaveData, useAppDispatch } from '@renderer/store'
|
||||
import { setUpdateState } from '@renderer/store/runtime'
|
||||
import { ThemeMode } from '@renderer/types'
|
||||
import { runAsyncFunction } from '@renderer/utils'
|
||||
@ -41,6 +41,7 @@ const AboutSettings: FC = () => {
|
||||
}
|
||||
|
||||
if (update.downloaded) {
|
||||
await handleSaveData()
|
||||
window.api.showUpdateDialog()
|
||||
return
|
||||
}
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
import { combineReducers, configureStore } from '@reduxjs/toolkit'
|
||||
import { loggerService } from '@renderer/services/LoggerService'
|
||||
import { useDispatch, useSelector, useStore } from 'react-redux'
|
||||
import { FLUSH, PAUSE, PERSIST, persistReducer, persistStore, PURGE, REGISTER, REHYDRATE } from 'redux-persist'
|
||||
import storage from 'redux-persist/lib/storage'
|
||||
@ -28,6 +29,8 @@ import tabs from './tabs'
|
||||
import translate from './translate'
|
||||
import websearch from './websearch'
|
||||
|
||||
const logger = loggerService.withContext('Store')
|
||||
|
||||
const rootReducer = combineReducers({
|
||||
assistants,
|
||||
agents,
|
||||
@ -101,4 +104,10 @@ export const useAppSelector = useSelector.withTypes<RootState>()
|
||||
export const useAppStore = useStore.withTypes<typeof store>()
|
||||
window.store = store
|
||||
|
||||
export async function handleSaveData() {
|
||||
logger.info('Flushing redux persistor data')
|
||||
await persistor.flush()
|
||||
logger.info('Flushed redux persistor data')
|
||||
}
|
||||
|
||||
export default store
|
||||
|
||||
Loading…
Reference in New Issue
Block a user