feat: Add capabilities for user to load custom CSS #548
This commit is contained in:
parent
c409256ae9
commit
5337017648
@ -16,8 +16,16 @@ import useUpdateHandler from './useUpdateHandler'
|
|||||||
|
|
||||||
export function useAppInit() {
|
export function useAppInit() {
|
||||||
const dispatch = useAppDispatch()
|
const dispatch = useAppDispatch()
|
||||||
const { proxyUrl, language, windowStyle, manualUpdateCheck, proxyMode, webdavAutoSync, webdavSyncInterval } =
|
const {
|
||||||
useSettings()
|
proxyUrl,
|
||||||
|
language,
|
||||||
|
windowStyle,
|
||||||
|
manualUpdateCheck,
|
||||||
|
proxyMode,
|
||||||
|
webdavAutoSync,
|
||||||
|
webdavSyncInterval,
|
||||||
|
customCss
|
||||||
|
} = useSettings()
|
||||||
const { minappShow } = useRuntime()
|
const { minappShow } = useRuntime()
|
||||||
const { setDefaultModel, setTopicNamingModel, setTranslateModel } = useDefaultModel()
|
const { setDefaultModel, setTopicNamingModel, setTranslateModel } = useDefaultModel()
|
||||||
const avatar = useLiveQuery(() => db.settings.get('image://avatar'))
|
const avatar = useLiveQuery(() => db.settings.get('image://avatar'))
|
||||||
@ -83,4 +91,18 @@ export function useAppInit() {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
import('@renderer/queue/KnowledgeQueue')
|
import('@renderer/queue/KnowledgeQueue')
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const oldCustomCss = document.getElementById('user-defined-custom-css')
|
||||||
|
if (oldCustomCss) {
|
||||||
|
oldCustomCss.remove()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (customCss) {
|
||||||
|
const style = document.createElement('style')
|
||||||
|
style.id = 'user-defined-custom-css'
|
||||||
|
style.textContent = customCss
|
||||||
|
document.head.appendChild(style)
|
||||||
|
}
|
||||||
|
}, [customCss])
|
||||||
}
|
}
|
||||||
|
|||||||
@ -381,6 +381,8 @@
|
|||||||
"display.sidebar.files.icon": "Show Files icon",
|
"display.sidebar.files.icon": "Show Files icon",
|
||||||
"display.sidebar.title": "Sidebar Settings",
|
"display.sidebar.title": "Sidebar Settings",
|
||||||
"display.topic.title": "Topic Settings",
|
"display.topic.title": "Topic Settings",
|
||||||
|
"display.custom.css": "Custom CSS",
|
||||||
|
"display.custom.css.placeholder": "/* Put custom CSS here */",
|
||||||
"input.auto_translate_with_space": "Quickly translate with 3 spaces",
|
"input.auto_translate_with_space": "Quickly translate with 3 spaces",
|
||||||
"messages.divider": "Show divider between messages",
|
"messages.divider": "Show divider between messages",
|
||||||
"messages.input.paste_long_text_as_file": "Paste long text as file",
|
"messages.input.paste_long_text_as_file": "Paste long text as file",
|
||||||
|
|||||||
@ -379,6 +379,8 @@
|
|||||||
"display.sidebar.files.icon": "ファイルのアイコンを表示",
|
"display.sidebar.files.icon": "ファイルのアイコンを表示",
|
||||||
"display.sidebar.title": "サイドバー設定",
|
"display.sidebar.title": "サイドバー設定",
|
||||||
"display.topic.title": "トピック設定",
|
"display.topic.title": "トピック設定",
|
||||||
|
"display.custom.css": "カスタムCSS",
|
||||||
|
"display.custom.css.placeholder": "/* ここにカスタムCSSを入力 */",
|
||||||
"input.auto_translate_with_space": "スペースを3回押して翻訳",
|
"input.auto_translate_with_space": "スペースを3回押して翻訳",
|
||||||
"messages.divider": "メッセージ間に区切り線を表示",
|
"messages.divider": "メッセージ間に区切り線を表示",
|
||||||
"messages.input.paste_long_text_as_file": "長いテキストをファイルとして貼り付け",
|
"messages.input.paste_long_text_as_file": "長いテキストをファイルとして貼り付け",
|
||||||
|
|||||||
@ -381,6 +381,8 @@
|
|||||||
"display.sidebar.files.icon": "Показывать иконку файлов",
|
"display.sidebar.files.icon": "Показывать иконку файлов",
|
||||||
"display.sidebar.title": "Настройки боковой панели",
|
"display.sidebar.title": "Настройки боковой панели",
|
||||||
"display.topic.title": "Настройки топиков",
|
"display.topic.title": "Настройки топиков",
|
||||||
|
"display.custom.css": "Пользовательский CSS",
|
||||||
|
"display.custom.css.placeholder": "/* Здесь введите пользовательский CSS */",
|
||||||
"input.auto_translate_with_space": "Быстрый перевод с помощью 3-х пробелов",
|
"input.auto_translate_with_space": "Быстрый перевод с помощью 3-х пробелов",
|
||||||
"messages.divider": "Показывать разделитель между сообщениями",
|
"messages.divider": "Показывать разделитель между сообщениями",
|
||||||
"messages.input.paste_long_text_as_file": "Вставлять длинный текст как файл",
|
"messages.input.paste_long_text_as_file": "Вставлять длинный текст как файл",
|
||||||
|
|||||||
@ -382,6 +382,8 @@
|
|||||||
"display.sidebar.files.icon": "显示文件图标",
|
"display.sidebar.files.icon": "显示文件图标",
|
||||||
"display.sidebar.title": "侧边栏设置",
|
"display.sidebar.title": "侧边栏设置",
|
||||||
"display.topic.title": "话题设置",
|
"display.topic.title": "话题设置",
|
||||||
|
"display.custom.css": "自定义 CSS",
|
||||||
|
"display.custom.css.placeholder": "/* 这里写自定义CSS */",
|
||||||
"input.auto_translate_with_space": "快速敲击3次空格翻译",
|
"input.auto_translate_with_space": "快速敲击3次空格翻译",
|
||||||
"messages.divider": "消息分割线",
|
"messages.divider": "消息分割线",
|
||||||
"messages.input.paste_long_text_as_file": "长文本粘贴为文件",
|
"messages.input.paste_long_text_as_file": "长文本粘贴为文件",
|
||||||
|
|||||||
@ -381,6 +381,8 @@
|
|||||||
"display.sidebar.files.icon": "顯示文件圖示",
|
"display.sidebar.files.icon": "顯示文件圖示",
|
||||||
"display.sidebar.title": "側邊欄設定",
|
"display.sidebar.title": "側邊欄設定",
|
||||||
"display.topic.title": "話題設定",
|
"display.topic.title": "話題設定",
|
||||||
|
"display.custom.css": "自定義 CSS",
|
||||||
|
"display.custom.css.placeholder": "/* 這裡寫自定義 CSS */",
|
||||||
"input.auto_translate_with_space": "快速敲擊3次空格翻譯",
|
"input.auto_translate_with_space": "快速敲擊3次空格翻譯",
|
||||||
"messages.divider": "訊息間顯示分隔線",
|
"messages.divider": "訊息間顯示分隔線",
|
||||||
"messages.input.paste_long_text_as_file": "將長文本貼上為檔案",
|
"messages.input.paste_long_text_as_file": "將長文本貼上為檔案",
|
||||||
|
|||||||
@ -4,12 +4,13 @@ import { useSettings } from '@renderer/hooks/useSettings'
|
|||||||
import { useAppDispatch } from '@renderer/store'
|
import { useAppDispatch } from '@renderer/store'
|
||||||
import {
|
import {
|
||||||
setClickAssistantToShowTopic,
|
setClickAssistantToShowTopic,
|
||||||
|
setCustomCss,
|
||||||
setShowFilesIcon,
|
setShowFilesIcon,
|
||||||
setShowMinappIcon,
|
setShowMinappIcon,
|
||||||
setShowTopicTime
|
setShowTopicTime
|
||||||
} from '@renderer/store/settings'
|
} from '@renderer/store/settings'
|
||||||
import { ThemeMode } from '@renderer/types'
|
import { ThemeMode } from '@renderer/types'
|
||||||
import { Select, Switch } from 'antd'
|
import { Input, Select, Switch } from 'antd'
|
||||||
import { FC } from 'react'
|
import { FC } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
|
|
||||||
@ -26,7 +27,8 @@ const DisplaySettings: FC = () => {
|
|||||||
topicPosition,
|
topicPosition,
|
||||||
setTopicPosition,
|
setTopicPosition,
|
||||||
clickAssistantToShowTopic,
|
clickAssistantToShowTopic,
|
||||||
showTopicTime
|
showTopicTime,
|
||||||
|
customCss
|
||||||
} = useSettings()
|
} = useSettings()
|
||||||
const { theme: themeMode } = useTheme()
|
const { theme: themeMode } = useTheme()
|
||||||
|
|
||||||
@ -111,6 +113,19 @@ const DisplaySettings: FC = () => {
|
|||||||
<Switch checked={showFilesIcon} onChange={(value) => dispatch(setShowFilesIcon(value))} />
|
<Switch checked={showFilesIcon} onChange={(value) => dispatch(setShowFilesIcon(value))} />
|
||||||
</SettingRow>
|
</SettingRow>
|
||||||
</SettingGroup>
|
</SettingGroup>
|
||||||
|
<SettingGroup theme={theme}>
|
||||||
|
<SettingTitle>{t('settings.display.custom.css')}</SettingTitle>
|
||||||
|
<SettingDivider />
|
||||||
|
<Input.TextArea
|
||||||
|
value={customCss}
|
||||||
|
onChange={(e) => dispatch(setCustomCss(e.target.value))}
|
||||||
|
placeholder={t('settings.display.custom.css.placeholder')}
|
||||||
|
style={{
|
||||||
|
minHeight: 200,
|
||||||
|
fontFamily: 'monospace'
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</SettingGroup>
|
||||||
</SettingContainer>
|
</SettingContainer>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -44,6 +44,7 @@ export interface SettingsState {
|
|||||||
// Sidebar icons
|
// Sidebar icons
|
||||||
showMinappIcon: boolean
|
showMinappIcon: boolean
|
||||||
showFilesIcon: boolean
|
showFilesIcon: boolean
|
||||||
|
customCss: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const initialState: SettingsState = {
|
const initialState: SettingsState = {
|
||||||
@ -83,7 +84,8 @@ const initialState: SettingsState = {
|
|||||||
autoTranslateWithSpace: false,
|
autoTranslateWithSpace: false,
|
||||||
enableTopicNaming: true,
|
enableTopicNaming: true,
|
||||||
showMinappIcon: true,
|
showMinappIcon: true,
|
||||||
showFilesIcon: true
|
showFilesIcon: true,
|
||||||
|
customCss: ''
|
||||||
}
|
}
|
||||||
|
|
||||||
const settingsSlice = createSlice({
|
const settingsSlice = createSlice({
|
||||||
@ -207,6 +209,9 @@ const settingsSlice = createSlice({
|
|||||||
},
|
},
|
||||||
setPasteLongTextThreshold: (state, action: PayloadAction<number>) => {
|
setPasteLongTextThreshold: (state, action: PayloadAction<number>) => {
|
||||||
state.pasteLongTextThreshold = action.payload
|
state.pasteLongTextThreshold = action.payload
|
||||||
|
},
|
||||||
|
setCustomCss: (state, action: PayloadAction<string>) => {
|
||||||
|
state.customCss = action.payload
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -250,7 +255,8 @@ export const {
|
|||||||
setEnableTopicNaming,
|
setEnableTopicNaming,
|
||||||
setShowMinappIcon,
|
setShowMinappIcon,
|
||||||
setShowFilesIcon,
|
setShowFilesIcon,
|
||||||
setPasteLongTextThreshold
|
setPasteLongTextThreshold,
|
||||||
|
setCustomCss
|
||||||
} = settingsSlice.actions
|
} = settingsSlice.actions
|
||||||
|
|
||||||
export default settingsSlice.reducer
|
export default settingsSlice.reducer
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user