mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-22 08:40:08 +08:00
refactor: simplify custom CSS functionality by store sync (#5596)
* feat: implement store synchronization across windows - Added new IPC channels for store synchronization: StoreSync_Subscribe, StoreSync_Unsubscribe, StoreSync_OnUpdate, and StoreSync_BroadcastSync. - Integrated store sync service in various components, including the main IPC handler and renderer store. - Removed the MiniWindowReload IPC channel as it was no longer needed. - Updated the store configuration to support synchronization of specific state slices. * refactor: remove custom CSS functionality from IPC and related components - Removed the App_SetCustomCss channel and associated handlers from the IPC and ConfigManager. - Updated the renderer components to eliminate references to custom CSS settings. - Refactored the MiniWindow component to manage custom CSS directly without IPC communication.
This commit is contained in:
parent
9d35f1d6ab
commit
66abb416df
@ -12,7 +12,6 @@ export enum IpcChannel {
|
|||||||
App_SetTrayOnClose = 'app:set-tray-on-close',
|
App_SetTrayOnClose = 'app:set-tray-on-close',
|
||||||
App_RestartTray = 'app:restart-tray',
|
App_RestartTray = 'app:restart-tray',
|
||||||
App_SetTheme = 'app:set-theme',
|
App_SetTheme = 'app:set-theme',
|
||||||
App_SetCustomCss = 'app:set-custom-css',
|
|
||||||
App_SetAutoUpdate = 'app:set-auto-update',
|
App_SetAutoUpdate = 'app:set-auto-update',
|
||||||
|
|
||||||
App_IsBinaryExist = 'app:is-binary-exist',
|
App_IsBinaryExist = 'app:is-binary-exist',
|
||||||
|
|||||||
@ -141,22 +141,6 @@ export function registerIpc(mainWindow: BrowserWindow, app: Electron.App) {
|
|||||||
notifyThemeChange()
|
notifyThemeChange()
|
||||||
})
|
})
|
||||||
|
|
||||||
// custom css
|
|
||||||
ipcMain.handle(IpcChannel.App_SetCustomCss, (event, css: string) => {
|
|
||||||
if (css === configManager.getCustomCss()) return
|
|
||||||
configManager.setCustomCss(css)
|
|
||||||
|
|
||||||
// Broadcast to all windows including the mini window
|
|
||||||
const senderWindowId = event.sender.id
|
|
||||||
const windows = BrowserWindow.getAllWindows()
|
|
||||||
// 向其他窗口广播主题变化
|
|
||||||
windows.forEach((win) => {
|
|
||||||
if (win.webContents.id !== senderWindowId) {
|
|
||||||
win.webContents.send('custom-css:update', css)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
// clear cache
|
// clear cache
|
||||||
ipcMain.handle(IpcChannel.App_ClearCache, async () => {
|
ipcMain.handle(IpcChannel.App_ClearCache, async () => {
|
||||||
const sessions = [session.defaultSession, session.fromPartition('persist:webview')]
|
const sessions = [session.defaultSession, session.fromPartition('persist:webview')]
|
||||||
|
|||||||
@ -44,14 +44,6 @@ export class ConfigManager {
|
|||||||
this.set(ConfigKeys.Theme, theme)
|
this.set(ConfigKeys.Theme, theme)
|
||||||
}
|
}
|
||||||
|
|
||||||
getCustomCss(): string {
|
|
||||||
return this.store.get('customCss', '') as string
|
|
||||||
}
|
|
||||||
|
|
||||||
setCustomCss(css: string) {
|
|
||||||
this.store.set('customCss', css)
|
|
||||||
}
|
|
||||||
|
|
||||||
getLaunchToTray(): boolean {
|
getLaunchToTray(): boolean {
|
||||||
return !!this.get(ConfigKeys.LaunchToTray, false)
|
return !!this.get(ConfigKeys.LaunchToTray, false)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,7 +19,6 @@ const api = {
|
|||||||
setTrayOnClose: (isActive: boolean) => ipcRenderer.invoke(IpcChannel.App_SetTrayOnClose, isActive),
|
setTrayOnClose: (isActive: boolean) => ipcRenderer.invoke(IpcChannel.App_SetTrayOnClose, isActive),
|
||||||
restartTray: () => ipcRenderer.invoke(IpcChannel.App_RestartTray),
|
restartTray: () => ipcRenderer.invoke(IpcChannel.App_RestartTray),
|
||||||
setTheme: (theme: 'light' | 'dark' | 'auto') => ipcRenderer.invoke(IpcChannel.App_SetTheme, theme),
|
setTheme: (theme: 'light' | 'dark' | 'auto') => ipcRenderer.invoke(IpcChannel.App_SetTheme, theme),
|
||||||
setCustomCss: (css: string) => ipcRenderer.invoke(IpcChannel.App_SetCustomCss, css),
|
|
||||||
setAutoUpdate: (isActive: boolean) => ipcRenderer.invoke(IpcChannel.App_SetAutoUpdate, isActive),
|
setAutoUpdate: (isActive: boolean) => ipcRenderer.invoke(IpcChannel.App_SetAutoUpdate, isActive),
|
||||||
openWebsite: (url: string) => ipcRenderer.invoke(IpcChannel.Open_Website, url),
|
openWebsite: (url: string) => ipcRenderer.invoke(IpcChannel.Open_Website, url),
|
||||||
clearCache: () => ipcRenderer.invoke(IpcChannel.App_ClearCache),
|
clearCache: () => ipcRenderer.invoke(IpcChannel.App_ClearCache),
|
||||||
|
|||||||
@ -91,16 +91,16 @@ export function useAppInit() {
|
|||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const oldCustomCss = document.getElementById('user-defined-custom-css')
|
let customCssElement = document.getElementById('user-defined-custom-css') as HTMLStyleElement
|
||||||
if (oldCustomCss) {
|
if (customCssElement) {
|
||||||
oldCustomCss.remove()
|
customCssElement.remove()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (customCss) {
|
if (customCss) {
|
||||||
const style = document.createElement('style')
|
customCssElement = document.createElement('style')
|
||||||
style.id = 'user-defined-custom-css'
|
customCssElement.id = 'user-defined-custom-css'
|
||||||
style.textContent = customCss
|
customCssElement.textContent = customCss
|
||||||
document.head.appendChild(style)
|
document.head.appendChild(customCssElement)
|
||||||
}
|
}
|
||||||
}, [customCss])
|
}, [customCss])
|
||||||
|
|
||||||
|
|||||||
@ -190,7 +190,6 @@ const DisplaySettings: FC = () => {
|
|||||||
value={customCss}
|
value={customCss}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
dispatch(setCustomCss(e.target.value))
|
dispatch(setCustomCss(e.target.value))
|
||||||
window.api.setCustomCss(e.target.value)
|
|
||||||
}}
|
}}
|
||||||
placeholder={t('settings.display.custom.css.placeholder')}
|
placeholder={t('settings.display.custom.css.placeholder')}
|
||||||
style={{
|
style={{
|
||||||
|
|||||||
@ -97,8 +97,6 @@ export class StoreSyncService {
|
|||||||
IpcChannel.StoreSync_BroadcastSync,
|
IpcChannel.StoreSync_BroadcastSync,
|
||||||
(_, action: StoreSyncAction) => {
|
(_, action: StoreSyncAction) => {
|
||||||
try {
|
try {
|
||||||
console.log('StoreSync_BroadcastSync action', action)
|
|
||||||
|
|
||||||
// Dispatch to the store
|
// Dispatch to the store
|
||||||
if (window.store) {
|
if (window.store) {
|
||||||
window.store.dispatch(action)
|
window.store.dispatch(action)
|
||||||
|
|||||||
@ -1,10 +1,9 @@
|
|||||||
import '@renderer/databases'
|
import '@renderer/databases'
|
||||||
|
|
||||||
import { useSettings } from '@renderer/hooks/useSettings'
|
import { useSettings } from '@renderer/hooks/useSettings'
|
||||||
import store, { persistor, useAppDispatch } from '@renderer/store'
|
import store, { persistor } from '@renderer/store'
|
||||||
import { setCustomCss } from '@renderer/store/settings'
|
|
||||||
import { message } from 'antd'
|
import { message } from 'antd'
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect } from 'react'
|
||||||
import { Provider } from 'react-redux'
|
import { Provider } from 'react-redux'
|
||||||
import { PersistGate } from 'redux-persist/integration/react'
|
import { PersistGate } from 'redux-persist/integration/react'
|
||||||
|
|
||||||
@ -13,58 +12,23 @@ import { SyntaxHighlighterProvider } from '../../context/SyntaxHighlighterProvid
|
|||||||
import { ThemeProvider } from '../../context/ThemeProvider'
|
import { ThemeProvider } from '../../context/ThemeProvider'
|
||||||
import HomeWindow from './home/HomeWindow'
|
import HomeWindow from './home/HomeWindow'
|
||||||
|
|
||||||
function useMiniWindowCustomCss() {
|
// Inner component that uses the hook after Redux is initialized
|
||||||
|
function MiniWindowContent(): React.ReactElement {
|
||||||
const { customCss } = useSettings()
|
const { customCss } = useSettings()
|
||||||
const dispatch = useAppDispatch()
|
|
||||||
const [isInitialized, setIsInitialized] = useState(false)
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// 初始化时从主进程获取最新的CSS配置
|
let customCssElement = document.getElementById('user-defined-custom-css') as HTMLStyleElement
|
||||||
window.api.config.get('customCss').then((css) => {
|
if (customCssElement) {
|
||||||
if (css !== undefined) {
|
customCssElement.remove()
|
||||||
dispatch(setCustomCss(css))
|
|
||||||
}
|
|
||||||
setIsInitialized(true)
|
|
||||||
})
|
|
||||||
|
|
||||||
// Listen for custom CSS updates from main window
|
|
||||||
const removeListener = window.electron.ipcRenderer.on('custom-css:update', (_event, css) => {
|
|
||||||
dispatch(setCustomCss(css))
|
|
||||||
})
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
removeListener()
|
|
||||||
}
|
|
||||||
}, [dispatch])
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!isInitialized) return
|
|
||||||
|
|
||||||
// Apply custom CSS
|
|
||||||
const oldCustomCss = document.getElementById('user-defined-custom-css')
|
|
||||||
if (oldCustomCss) {
|
|
||||||
oldCustomCss.remove()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (customCss) {
|
if (customCss) {
|
||||||
const style = document.createElement('style')
|
customCssElement = document.createElement('style')
|
||||||
style.id = 'user-defined-custom-css'
|
customCssElement.id = 'user-defined-custom-css'
|
||||||
style.textContent = customCss
|
customCssElement.textContent = customCss
|
||||||
document.head.appendChild(style)
|
document.head.appendChild(customCssElement)
|
||||||
}
|
}
|
||||||
}, [customCss, isInitialized])
|
}, [customCss])
|
||||||
|
|
||||||
return isInitialized
|
|
||||||
}
|
|
||||||
|
|
||||||
// Inner component that uses the hook after Redux is initialized
|
|
||||||
function MiniWindowContent(): React.ReactElement {
|
|
||||||
const cssInitialized = useMiniWindowCustomCss()
|
|
||||||
|
|
||||||
// Show empty fragment until CSS is initialized
|
|
||||||
if (!cssInitialized) {
|
|
||||||
return <></>
|
|
||||||
}
|
|
||||||
|
|
||||||
return <HomeWindow />
|
return <HomeWindow />
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user