mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2026-01-06 21:35:52 +08:00
refactor: move minapp settings to minapp page
This commit is contained in:
parent
3cb34d30a9
commit
5b379666f4
@ -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')};
|
||||||
|
`
|
||||||
|
|||||||
@ -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": "切换话题显示",
|
||||||
|
|||||||
@ -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": "切換話題顯示",
|
||||||
|
|||||||
@ -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>
|
||||||
)
|
)
|
||||||
|
|||||||
@ -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;
|
||||||
@ -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 />} />
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user