mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2026-01-02 02:09:03 +08:00
refactor: update theme handling in TabContainer and Sidebar components (#8816)
* refactor: update theme handling in TabContainer and Sidebar components * refactor: replace setTheme with toggleTheme and update theme state management * feat: add Monitor icon for additional theme state in both components * feat(DisplaySettings): replace theme icons with lucide icons for improved visual representation * updated light and dark theme icons to use Sun and Moon from lucide * replaced SyncOutlined with Monitor icon for system theme option * format code * feat(TabContainer): add tooltip for theme toggle button with translation support * integrated Tooltip component to provide contextual information for the theme toggle button * utilized useTranslation hook for internationalization of tooltip text * imported getThemeModeLabel to enhance theme description
This commit is contained in:
parent
90c1fff54a
commit
e8b3d44400
@ -3,19 +3,21 @@ import { isLinux, isMac, isWin } from '@renderer/config/constant'
|
|||||||
import { useTheme } from '@renderer/context/ThemeProvider'
|
import { useTheme } from '@renderer/context/ThemeProvider'
|
||||||
import { useFullscreen } from '@renderer/hooks/useFullscreen'
|
import { useFullscreen } from '@renderer/hooks/useFullscreen'
|
||||||
import { useMinappPopup } from '@renderer/hooks/useMinappPopup'
|
import { useMinappPopup } from '@renderer/hooks/useMinappPopup'
|
||||||
import { getTitleLabel } from '@renderer/i18n/label'
|
import { getThemeModeLabel, getTitleLabel } from '@renderer/i18n/label'
|
||||||
import tabsService from '@renderer/services/TabsService'
|
import tabsService from '@renderer/services/TabsService'
|
||||||
import { useAppDispatch, useAppSelector } from '@renderer/store'
|
import { useAppDispatch, useAppSelector } from '@renderer/store'
|
||||||
import type { Tab } from '@renderer/store/tabs'
|
import type { Tab } from '@renderer/store/tabs'
|
||||||
import { addTab, removeTab, setActiveTab } from '@renderer/store/tabs'
|
import { addTab, removeTab, setActiveTab } from '@renderer/store/tabs'
|
||||||
import { ThemeMode } from '@renderer/types'
|
import { ThemeMode } from '@renderer/types'
|
||||||
import { classNames } from '@renderer/utils'
|
import { classNames } from '@renderer/utils'
|
||||||
|
import { Tooltip } from 'antd'
|
||||||
import {
|
import {
|
||||||
FileSearch,
|
FileSearch,
|
||||||
Folder,
|
Folder,
|
||||||
Home,
|
Home,
|
||||||
Languages,
|
Languages,
|
||||||
LayoutGrid,
|
LayoutGrid,
|
||||||
|
Monitor,
|
||||||
Moon,
|
Moon,
|
||||||
Palette,
|
Palette,
|
||||||
Settings,
|
Settings,
|
||||||
@ -25,6 +27,7 @@ import {
|
|||||||
X
|
X
|
||||||
} from 'lucide-react'
|
} from 'lucide-react'
|
||||||
import { useCallback, useEffect } from 'react'
|
import { useCallback, useEffect } from 'react'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
import { useLocation, useNavigate } from 'react-router-dom'
|
import { useLocation, useNavigate } from 'react-router-dom'
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
|
|
||||||
@ -69,8 +72,9 @@ const TabsContainer: React.FC<TabsContainerProps> = ({ children }) => {
|
|||||||
const tabs = useAppSelector((state) => state.tabs.tabs)
|
const tabs = useAppSelector((state) => state.tabs.tabs)
|
||||||
const activeTabId = useAppSelector((state) => state.tabs.activeTabId)
|
const activeTabId = useAppSelector((state) => state.tabs.activeTabId)
|
||||||
const isFullscreen = useFullscreen()
|
const isFullscreen = useFullscreen()
|
||||||
const { theme, setTheme } = useTheme()
|
const { settedTheme, toggleTheme } = useTheme()
|
||||||
const { hideMinappPopup } = useMinappPopup()
|
const { hideMinappPopup } = useMinappPopup()
|
||||||
|
const { t } = useTranslation()
|
||||||
|
|
||||||
const getTabId = (path: string): string => {
|
const getTabId = (path: string): string => {
|
||||||
if (path === '/') return 'home'
|
if (path === '/') return 'home'
|
||||||
@ -162,9 +166,20 @@ const TabsContainer: React.FC<TabsContainerProps> = ({ children }) => {
|
|||||||
</AddTabButton>
|
</AddTabButton>
|
||||||
<RightButtonsContainer>
|
<RightButtonsContainer>
|
||||||
<TopNavbarOpenedMinappTabs />
|
<TopNavbarOpenedMinappTabs />
|
||||||
<ThemeButton onClick={() => setTheme(theme === ThemeMode.dark ? ThemeMode.light : ThemeMode.dark)}>
|
<Tooltip
|
||||||
{theme === ThemeMode.dark ? <Moon size={16} /> : <Sun size={16} />}
|
title={t('settings.theme.title') + ': ' + getThemeModeLabel(settedTheme)}
|
||||||
</ThemeButton>
|
mouseEnterDelay={0.8}
|
||||||
|
placement="bottom">
|
||||||
|
<ThemeButton onClick={toggleTheme}>
|
||||||
|
{settedTheme === ThemeMode.dark ? (
|
||||||
|
<Moon size={16} />
|
||||||
|
) : settedTheme === ThemeMode.light ? (
|
||||||
|
<Sun size={16} />
|
||||||
|
) : (
|
||||||
|
<Monitor size={16} />
|
||||||
|
)}
|
||||||
|
</ThemeButton>
|
||||||
|
</Tooltip>
|
||||||
<SettingsButton onClick={handleSettingsClick} $active={activeTabId === 'settings'}>
|
<SettingsButton onClick={handleSettingsClick} $active={activeTabId === 'settings'}>
|
||||||
<Settings size={16} />
|
<Settings size={16} />
|
||||||
</SettingsButton>
|
</SettingsButton>
|
||||||
|
|||||||
@ -21,6 +21,7 @@ import {
|
|||||||
Languages,
|
Languages,
|
||||||
LayoutGrid,
|
LayoutGrid,
|
||||||
MessageSquare,
|
MessageSquare,
|
||||||
|
Monitor,
|
||||||
Moon,
|
Moon,
|
||||||
Palette,
|
Palette,
|
||||||
Settings,
|
Settings,
|
||||||
@ -44,7 +45,7 @@ const Sidebar: FC = () => {
|
|||||||
const { pathname } = useLocation()
|
const { pathname } = useLocation()
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
|
|
||||||
const { theme, setTheme } = useTheme()
|
const { theme, settedTheme, toggleTheme } = useTheme()
|
||||||
const avatar = useAvatar()
|
const avatar = useAvatar()
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
|
|
||||||
@ -105,11 +106,17 @@ const Sidebar: FC = () => {
|
|||||||
</Icon>
|
</Icon>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Tooltip
|
<Tooltip
|
||||||
title={t('settings.theme.title') + ': ' + getThemeModeLabel(theme)}
|
title={t('settings.theme.title') + ': ' + getThemeModeLabel(settedTheme)}
|
||||||
mouseEnterDelay={0.8}
|
mouseEnterDelay={0.8}
|
||||||
placement="right">
|
placement="right">
|
||||||
<Icon theme={theme} onClick={() => setTheme(theme === ThemeMode.dark ? ThemeMode.light : ThemeMode.dark)}>
|
<Icon theme={theme} onClick={toggleTheme}>
|
||||||
{theme === ThemeMode.dark ? <Moon size={20} className="icon" /> : <Sun size={20} className="icon" />}
|
{settedTheme === ThemeMode.dark ? (
|
||||||
|
<Moon size={20} className="icon" />
|
||||||
|
) : settedTheme === ThemeMode.light ? (
|
||||||
|
<Sun size={20} className="icon" />
|
||||||
|
) : (
|
||||||
|
<Monitor size={20} className="icon" />
|
||||||
|
)}
|
||||||
</Icon>
|
</Icon>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
<Tooltip title={t('settings.title')} mouseEnterDelay={0.8} placement="right">
|
<Tooltip title={t('settings.title')} mouseEnterDelay={0.8} placement="right">
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
import { SyncOutlined } from '@ant-design/icons'
|
|
||||||
import CodeEditor from '@renderer/components/CodeEditor'
|
import CodeEditor from '@renderer/components/CodeEditor'
|
||||||
import { HStack } from '@renderer/components/Layout'
|
import { HStack } from '@renderer/components/Layout'
|
||||||
import TextBadge from '@renderer/components/TextBadge'
|
import TextBadge from '@renderer/components/TextBadge'
|
||||||
@ -19,7 +18,7 @@ import {
|
|||||||
} from '@renderer/store/settings'
|
} from '@renderer/store/settings'
|
||||||
import { ThemeMode } from '@renderer/types'
|
import { ThemeMode } from '@renderer/types'
|
||||||
import { Button, ColorPicker, Segmented, Switch } from 'antd'
|
import { Button, ColorPicker, Segmented, Switch } from 'antd'
|
||||||
import { Minus, Plus, RotateCcw } from 'lucide-react'
|
import { Minus, Monitor, Moon, Plus, RotateCcw, Sun } from 'lucide-react'
|
||||||
import { FC, useCallback, useEffect, useMemo, useState } from 'react'
|
import { FC, useCallback, useEffect, useMemo, useState } from 'react'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
@ -108,7 +107,7 @@ const DisplaySettings: FC = () => {
|
|||||||
value: ThemeMode.light,
|
value: ThemeMode.light,
|
||||||
label: (
|
label: (
|
||||||
<div style={{ display: 'flex', alignItems: 'center', gap: '5px' }}>
|
<div style={{ display: 'flex', alignItems: 'center', gap: '5px' }}>
|
||||||
<i className="iconfont icon-theme icon-theme-light" />
|
<Sun size={16} />
|
||||||
<span>{t('settings.theme.light')}</span>
|
<span>{t('settings.theme.light')}</span>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
@ -117,7 +116,7 @@ const DisplaySettings: FC = () => {
|
|||||||
value: ThemeMode.dark,
|
value: ThemeMode.dark,
|
||||||
label: (
|
label: (
|
||||||
<div style={{ display: 'flex', alignItems: 'center', gap: '5px' }}>
|
<div style={{ display: 'flex', alignItems: 'center', gap: '5px' }}>
|
||||||
<i className="iconfont icon-theme icon-dark1" />
|
<Moon size={16} />
|
||||||
<span>{t('settings.theme.dark')}</span>
|
<span>{t('settings.theme.dark')}</span>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
@ -126,7 +125,7 @@ const DisplaySettings: FC = () => {
|
|||||||
value: ThemeMode.system,
|
value: ThemeMode.system,
|
||||||
label: (
|
label: (
|
||||||
<div style={{ display: 'flex', alignItems: 'center', gap: '5px' }}>
|
<div style={{ display: 'flex', alignItems: 'center', gap: '5px' }}>
|
||||||
<SyncOutlined />
|
<Monitor size={16} />
|
||||||
<span>{t('settings.theme.system')}</span>
|
<span>{t('settings.theme.system')}</span>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user