refactor: move minapp settings to minapp page

This commit is contained in:
kangfenmao 2025-06-06 16:41:10 +08:00
parent 3cb34d30a9
commit 5b379666f4
7 changed files with 141 additions and 106 deletions

View File

@ -34,6 +34,15 @@ export const NavbarRight: FC<Props> = ({ children, ...props }) => {
) )
} }
export const NavbarMain: FC<Props> = ({ children, ...props }) => {
const isFullscreen = useFullscreen()
return (
<NavbarMainContainer {...props} $isFullscreen={isFullscreen}>
{children}
</NavbarMainContainer>
)
}
const NavbarContainer = styled.div` const NavbarContainer = styled.div`
min-width: 100%; min-width: 100%;
display: flex; display: flex;
@ -72,3 +81,15 @@ const NavbarRightContainer = styled.div<{ $isFullscreen: boolean }>`
padding-right: ${({ $isFullscreen }) => ($isFullscreen ? '12px' : isWindows ? '140px' : isLinux ? '120px' : '12px')}; padding-right: ${({ $isFullscreen }) => ($isFullscreen ? '12px' : isWindows ? '140px' : isLinux ? '120px' : '12px')};
justify-content: flex-end; justify-content: flex-end;
` `
const NavbarMainContainer = styled.div<{ $isFullscreen: boolean }>`
flex: 1;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
padding: 0 ${isMac ? '20px' : 0};
font-weight: bold;
color: var(--color-text-1);
padding-right: ${({ $isFullscreen }) => ($isFullscreen ? '12px' : isWindows ? '140px' : isLinux ? '120px' : '12px')};
`

View File

@ -1698,7 +1698,7 @@
"search_message_in_chat": "在当前对话中搜索消息", "search_message_in_chat": "在当前对话中搜索消息",
"show_app": "显示/隐藏应用", "show_app": "显示/隐藏应用",
"show_settings": "打开设置", "show_settings": "打开设置",
"title": "快捷方式", "title": "快捷",
"toggle_new_context": "清除上下文", "toggle_new_context": "清除上下文",
"toggle_show_assistants": "切换助手显示", "toggle_show_assistants": "切换助手显示",
"toggle_show_topics": "切换话题显示", "toggle_show_topics": "切换话题显示",

View File

@ -1688,7 +1688,7 @@
"search_message_in_chat": "在當前對話中搜尋訊息", "search_message_in_chat": "在當前對話中搜尋訊息",
"show_app": "顯示/隱藏應用程式", "show_app": "顯示/隱藏應用程式",
"show_settings": "開啟設定", "show_settings": "開啟設定",
"title": "快速方式", "title": "快捷鍵",
"toggle_new_context": "清除上下文", "toggle_new_context": "清除上下文",
"toggle_show_assistants": "切換助手顯示", "toggle_show_assistants": "切換助手顯示",
"toggle_show_topics": "切換話題顯示", "toggle_show_topics": "切換話題顯示",

View File

@ -1,18 +1,22 @@
import { Navbar, NavbarCenter } from '@renderer/components/app/Navbar' import { Navbar, NavbarMain } from '@renderer/components/app/Navbar'
import { useMinapps } from '@renderer/hooks/useMinapps' import { useMinapps } from '@renderer/hooks/useMinapps'
import { Input } from 'antd' import { Button, Input } from 'antd'
import { Search } from 'lucide-react' import { Search, SettingsIcon, X } from 'lucide-react'
import React, { FC, useState } from 'react' import React, { FC, useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { useLocation } from 'react-router'
import styled from 'styled-components' import styled from 'styled-components'
import App from './App' import App from './App'
import MiniAppSettings from './MiniappSettings/MiniAppSettings'
import NewAppButton from './NewAppButton' import NewAppButton from './NewAppButton'
const AppsPage: FC = () => { const AppsPage: FC = () => {
const { t } = useTranslation() const { t } = useTranslation()
const [search, setSearch] = useState('') const [search, setSearch] = useState('')
const { minapps } = useMinapps() const { minapps } = useMinapps()
const [isSettingsOpen, setIsSettingsOpen] = useState(false)
const location = useLocation()
const filteredApps = search const filteredApps = search
? minapps.filter( ? minapps.filter(
@ -31,31 +35,51 @@ const AppsPage: FC = () => {
e.preventDefault() e.preventDefault()
} }
useEffect(() => {
setIsSettingsOpen(false)
}, [location.key])
return ( return (
<Container onContextMenu={handleContextMenu}> <Container onContextMenu={handleContextMenu}>
<Navbar> <Navbar>
<NavbarCenter style={{ borderRight: 'none', justifyContent: 'space-between' }}> <NavbarMain>
{t('minapp.title')} {t('minapp.title')}
<Input <Input
placeholder={t('common.search')} placeholder={t('common.search')}
className="nodrag" className="nodrag"
style={{ width: '30%', height: 28, borderRadius: 15 }} style={{
width: '30%',
height: 28,
borderRadius: 15,
position: 'absolute',
left: '50vw',
transform: 'translateX(-50%)'
}}
size="small" size="small"
variant="filled" variant="filled"
suffix={<Search size={18} />} suffix={<Search size={18} />}
value={search} value={search}
onChange={(e) => setSearch(e.target.value)} onChange={(e) => setSearch(e.target.value)}
disabled={isSettingsOpen}
/> />
<div style={{ width: 80 }} /> <Button
</NavbarCenter> type="text"
className="nodrag"
icon={isSettingsOpen ? <X size={18} /> : <SettingsIcon size={18} color="var(--color-text-2)" />}
onClick={() => setIsSettingsOpen(!isSettingsOpen)}
/>
</NavbarMain>
</Navbar> </Navbar>
<ContentContainer id="content-container"> <ContentContainer id="content-container">
<AppsContainer style={{ height: containerHeight }}> {isSettingsOpen && <MiniAppSettings />}
{filteredApps.map((app) => ( {!isSettingsOpen && (
<App key={app.id} app={app} /> <AppsContainer style={{ height: containerHeight }}>
))} {filteredApps.map((app) => (
<NewAppButton /> <App key={app.id} app={app} />
</AppsContainer> ))}
<NewAppButton />
</AppsContainer>
)}
</ContentContainer> </ContentContainer>
</Container> </Container>
) )

View File

@ -1,8 +1,8 @@
import { UndoOutlined } from '@ant-design/icons' // 导入重置图标 import { UndoOutlined } from '@ant-design/icons' // 导入重置图标
import { DEFAULT_MIN_APPS } from '@renderer/config/minapps' import { DEFAULT_MIN_APPS } from '@renderer/config/minapps'
import { useTheme } from '@renderer/context/ThemeProvider'
import { useMinapps } from '@renderer/hooks/useMinapps' import { useMinapps } from '@renderer/hooks/useMinapps'
import { useSettings } from '@renderer/hooks/useSettings' import { useSettings } from '@renderer/hooks/useSettings'
import { SettingDescription, SettingDivider, SettingRowTitle, SettingTitle } from '@renderer/pages/settings'
import { useAppDispatch } from '@renderer/store' import { useAppDispatch } from '@renderer/store'
import { import {
setMaxKeepAliveMinapps, setMaxKeepAliveMinapps,
@ -12,9 +12,9 @@ import {
import { Button, message, Slider, Switch, Tooltip } from 'antd' import { Button, message, Slider, Switch, Tooltip } from 'antd'
import { FC, useCallback, useEffect, useRef, useState } from 'react' import { FC, useCallback, useEffect, useRef, useState } from 'react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { useNavigate } from 'react-router'
import styled from 'styled-components' import styled from 'styled-components'
import { SettingContainer, SettingDescription, SettingDivider, SettingGroup, SettingRowTitle, SettingTitle } from '..'
import MiniAppIconsManager from './MiniAppIconsManager' import MiniAppIconsManager from './MiniAppIconsManager'
// 默认小程序缓存数量 // 默认小程序缓存数量
@ -22,10 +22,10 @@ const DEFAULT_MAX_KEEPALIVE = 3
const MiniAppSettings: FC = () => { const MiniAppSettings: FC = () => {
const { t } = useTranslation() const { t } = useTranslation()
const { theme } = useTheme()
const dispatch = useAppDispatch() const dispatch = useAppDispatch()
const { maxKeepAliveMinapps, showOpenedMinappsInSidebar, minappsOpenLinkExternal } = useSettings() const { maxKeepAliveMinapps, showOpenedMinappsInSidebar, minappsOpenLinkExternal } = useSettings()
const { minapps, disabled, updateMinapps, updateDisabledMinapps } = useMinapps() const { minapps, disabled, updateMinapps, updateDisabledMinapps } = useMinapps()
const navigate = useNavigate()
const [visibleMiniApps, setVisibleMiniApps] = useState(minapps) const [visibleMiniApps, setVisibleMiniApps] = useState(minapps)
const [disabledMiniApps, setDisabledMiniApps] = useState(disabled || []) const [disabledMiniApps, setDisabledMiniApps] = useState(disabled || [])
@ -72,83 +72,87 @@ const MiniAppSettings: FC = () => {
}, []) }, [])
return ( return (
<SettingContainer theme={theme}> <Container>
{contextHolder} {/* 添加消息上下文 */} {contextHolder} {/* 添加消息上下文 */}
<SettingGroup theme={theme}> <SettingTitle
<SettingTitle>{t('settings.miniapps.title')}</SettingTitle> style={{ display: 'flex', flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center' }}>
<SettingDivider /> <span>{t('settings.miniapps.display_title')}</span>
<ResetButtonWrapper>
<SettingTitle <Button onClick={handleResetMinApps}>{t('common.reset')}</Button>
style={{ display: 'flex', flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center' }}> </ResetButtonWrapper>
<span>{t('settings.miniapps.display_title')}</span> </SettingTitle>
<ResetButtonWrapper> <BorderedContainer>
<Button onClick={handleResetMinApps}>{t('common.reset')}</Button> <MiniAppIconsManager
</ResetButtonWrapper> visibleMiniApps={visibleMiniApps}
</SettingTitle> disabledMiniApps={disabledMiniApps}
<BorderedContainer> setVisibleMiniApps={setVisibleMiniApps}
<MiniAppIconsManager setDisabledMiniApps={setDisabledMiniApps}
visibleMiniApps={visibleMiniApps} />
disabledMiniApps={disabledMiniApps} </BorderedContainer>
setVisibleMiniApps={setVisibleMiniApps} <SettingDivider />
setDisabledMiniApps={setDisabledMiniApps} <SettingRow style={{ height: 40, alignItems: 'center' }}>
/> <SettingLabelGroup>
</BorderedContainer> <SettingRowTitle>{t('settings.miniapps.open_link_external.title')}</SettingRowTitle>
<SettingDivider /> </SettingLabelGroup>
<SettingRow style={{ height: 40, alignItems: 'center' }}> <Switch
<SettingLabelGroup> checked={minappsOpenLinkExternal}
<SettingRowTitle>{t('settings.miniapps.open_link_external.title')}</SettingRowTitle> onChange={(checked) => dispatch(setMinappsOpenLinkExternal(checked))}
</SettingLabelGroup> />
<Switch </SettingRow>
checked={minappsOpenLinkExternal} <SettingDivider />
onChange={(checked) => dispatch(setMinappsOpenLinkExternal(checked))} {/* 缓存小程序数量设置 */}
/> <SettingRow>
</SettingRow> <SettingLabelGroup>
<SettingDivider /> <SettingRowTitle>{t('settings.miniapps.cache_title')}</SettingRowTitle>
<SettingDescription>{t('settings.miniapps.cache_description')}</SettingDescription>
{/* 缓存小程序数量设置 */} </SettingLabelGroup>
<SettingRow> <CacheSettingControls>
<SettingLabelGroup> <SliderWithResetContainer>
<SettingRowTitle>{t('settings.miniapps.cache_title')}</SettingRowTitle> <Tooltip title={t('settings.miniapps.reset_tooltip')} placement="top">
<SettingDescription>{t('settings.miniapps.cache_description')}</SettingDescription> <ResetButton onClick={handleResetCacheLimit}>
</SettingLabelGroup> <UndoOutlined />
<CacheSettingControls> </ResetButton>
<SliderWithResetContainer> </Tooltip>
<Tooltip title={t('settings.miniapps.reset_tooltip')} placement="top"> <Slider
<ResetButton onClick={handleResetCacheLimit}> min={1}
<UndoOutlined /> max={10}
</ResetButton> value={maxKeepAliveMinapps}
</Tooltip> onChange={handleCacheChange}
<Slider marks={{
min={1} 1: '1',
max={10} 5: '5',
value={maxKeepAliveMinapps} 10: 'Max'
onChange={handleCacheChange} }}
marks={{ tooltip={{ formatter: (value) => `${value}` }}
1: '1', />
5: '5', </SliderWithResetContainer>
10: 'Max' </CacheSettingControls>
}} </SettingRow>
tooltip={{ formatter: (value) => `${value}` }} <SettingDivider />
/> <SettingRow>
</SliderWithResetContainer> <SettingLabelGroup>
</CacheSettingControls> <SettingRowTitle>{t('settings.miniapps.sidebar_title')}</SettingRowTitle>
</SettingRow> <SettingDescription>{t('settings.miniapps.sidebar_description')}</SettingDescription>
<SettingDivider /> </SettingLabelGroup>
<SettingRow> <Switch
<SettingLabelGroup> checked={showOpenedMinappsInSidebar}
<SettingRowTitle>{t('settings.miniapps.sidebar_title')}</SettingRowTitle> onChange={(checked) => dispatch(setShowOpenedMinappsInSidebar(checked))}
<SettingDescription>{t('settings.miniapps.sidebar_description')}</SettingDescription> />
</SettingLabelGroup> </SettingRow>
<Switch <SettingDivider />
checked={showOpenedMinappsInSidebar} <SettingRow style={{ justifyContent: 'flex-end' }}>
onChange={(checked) => dispatch(setShowOpenedMinappsInSidebar(checked))} <Button onClick={() => navigate('/apps')}>{t('common.close')}</Button>
/> </SettingRow>
</SettingRow> </Container>
</SettingGroup>
</SettingContainer>
) )
} }
const Container = styled.div`
display: flex;
flex-direction: column;
flex: 1;
`
// 修改和新增样式 // 修改和新增样式
const SettingRow = styled.div` const SettingRow = styled.div`
display: flex; display: flex;

View File

@ -1,5 +1,4 @@
import { Navbar, NavbarCenter } from '@renderer/components/app/Navbar' import { Navbar, NavbarCenter } from '@renderer/components/app/Navbar'
import { useSidebarIconShow } from '@renderer/hooks/useSidebarIcon'
import ModelSettings from '@renderer/pages/settings/ModelSettings/ModelSettings' import ModelSettings from '@renderer/pages/settings/ModelSettings/ModelSettings'
import { import {
Cloud, Cloud,
@ -7,7 +6,6 @@ import {
Globe, Globe,
HardDrive, HardDrive,
Info, Info,
LayoutGrid,
MonitorCog, MonitorCog,
Package, Package,
Rocket, Rocket,
@ -28,7 +26,6 @@ import DisplaySettings from './DisplaySettings/DisplaySettings'
import GeneralSettings from './GeneralSettings' import GeneralSettings from './GeneralSettings'
import MCPSettings from './MCPSettings' import MCPSettings from './MCPSettings'
import { McpSettingsNavbar } from './MCPSettings/McpSettingsNavbar' import { McpSettingsNavbar } from './MCPSettings/McpSettingsNavbar'
import MiniAppSettings from './MiniappSettings/MiniAppSettings'
import ProvidersList from './ProviderSettings' import ProvidersList from './ProviderSettings'
import QuickAssistantSettings from './QuickAssistantSettings' import QuickAssistantSettings from './QuickAssistantSettings'
import QuickPhraseSettings from './QuickPhraseSettings' import QuickPhraseSettings from './QuickPhraseSettings'
@ -40,8 +37,6 @@ const SettingsPage: FC = () => {
const { pathname } = useLocation() const { pathname } = useLocation()
const { t } = useTranslation() const { t } = useTranslation()
const showMiniAppSettings = useSidebarIconShow('minapp')
const isRoute = (path: string): string => (pathname.startsWith(path) ? 'active' : '') const isRoute = (path: string): string => (pathname.startsWith(path) ? 'active' : '')
return ( return (
@ -88,14 +83,6 @@ const SettingsPage: FC = () => {
{t('settings.display.title')} {t('settings.display.title')}
</MenuItem> </MenuItem>
</MenuItemLink> </MenuItemLink>
{showMiniAppSettings && (
<MenuItemLink to="/settings/miniapps">
<MenuItem className={isRoute('/settings/miniapps')}>
<LayoutGrid size={18} />
{t('settings.miniapps.title')}
</MenuItem>
</MenuItemLink>
)}
<MenuItemLink to="/settings/shortcut"> <MenuItemLink to="/settings/shortcut">
<MenuItem className={isRoute('/settings/shortcut')}> <MenuItem className={isRoute('/settings/shortcut')}>
<Command size={18} /> <Command size={18} />
@ -141,7 +128,6 @@ const SettingsPage: FC = () => {
<Route path="mcp/*" element={<MCPSettings />} /> <Route path="mcp/*" element={<MCPSettings />} />
<Route path="general" element={<GeneralSettings />} /> <Route path="general" element={<GeneralSettings />} />
<Route path="display" element={<DisplaySettings />} /> <Route path="display" element={<DisplaySettings />} />
{showMiniAppSettings && <Route path="miniapps" element={<MiniAppSettings />} />}
<Route path="shortcut" element={<ShortcutSettings />} /> <Route path="shortcut" element={<ShortcutSettings />} />
<Route path="quickAssistant" element={<QuickAssistantSettings />} /> <Route path="quickAssistant" element={<QuickAssistantSettings />} />
<Route path="selectionAssistant" element={<SelectionAssistantSettings />} /> <Route path="selectionAssistant" element={<SelectionAssistantSettings />} />