🌓 feat(ui): add auto theme mode, refactor ThemeToggle, optimize header theme handling
- Feature: Introduce 'auto' theme mode
- Detect system preference via matchMedia('(prefers-color-scheme: dark)')
- Add useActualTheme context to expose the effective theme ('light'|'dark')
- Persist selected mode in localStorage ('theme-mode') with 'auto' as default
- Apply/remove `dark` class on <html> and sync `theme-mode` on <body>
- Broadcast effective theme to iframes
- UI: Redesign ThemeToggle with Dropdown items and custom highlight
- Replace non-existent IconMonitor with IconRefresh
- Use Dropdown.Menu + Dropdown.Item with built-in icon prop
- Selected state uses custom background highlight; hover state preserved
- Remove checkmark; selection relies on background styling
- Current button icon reflects selected mode
- Performance: reduce re-renders and unnecessary effects
- Memoize theme options and current button icon (useMemo)
- Simplify handleThemeToggle to accept only explicit modes ('light'|'dark'|'auto')
- Minimize useEffect dependencies; remove unrelated deps
- Header: streamline useHeaderBar
- Use useActualTheme for iframe theme messaging
- Remove unused statusDispatch
- Remove isNewYear from theme effect dependencies
- Home: send effective theme (useActualTheme) to external content iframes
- i18n: add/enhance theme-related copy in locales (en/zh)
- Chore: minor code cleanup and consistency
- Improve readability and maintainability
- Lint clean; no functional regressions
This commit is contained in:
@@ -18,11 +18,12 @@ For commercial licensing, please contact support@quantumnous.com
|
||||
*/
|
||||
|
||||
import React, { useContext, useEffect, useState } from 'react';
|
||||
import { Button, Typography, Tag, Input, ScrollList, ScrollItem } from '@douyinfe/semi-ui';
|
||||
import { Button, Typography, Input, ScrollList, ScrollItem } from '@douyinfe/semi-ui';
|
||||
import { API, showError, copy, showSuccess } from '../../helpers';
|
||||
import { useIsMobile } from '../../hooks/common/useIsMobile';
|
||||
import { API_ENDPOINTS } from '../../constants/common.constant';
|
||||
import { StatusContext } from '../../context/Status';
|
||||
import { useActualTheme } from '../../context/Theme';
|
||||
import { marked } from 'marked';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { IconGithubLogo, IconPlay, IconFile, IconCopy } from '@douyinfe/semi-icons';
|
||||
@@ -35,6 +36,7 @@ const { Text } = Typography;
|
||||
const Home = () => {
|
||||
const { t, i18n } = useTranslation();
|
||||
const [statusState] = useContext(StatusContext);
|
||||
const actualTheme = useActualTheme();
|
||||
const [homePageContentLoaded, setHomePageContentLoaded] = useState(false);
|
||||
const [homePageContent, setHomePageContent] = useState('');
|
||||
const [noticeVisible, setNoticeVisible] = useState(false);
|
||||
@@ -62,9 +64,8 @@ const Home = () => {
|
||||
if (data.startsWith('https://')) {
|
||||
const iframe = document.querySelector('iframe');
|
||||
if (iframe) {
|
||||
const theme = localStorage.getItem('theme-mode') || 'light';
|
||||
iframe.onload = () => {
|
||||
iframe.contentWindow.postMessage({ themeMode: theme }, '*');
|
||||
iframe.contentWindow.postMessage({ themeMode: actualTheme }, '*');
|
||||
iframe.contentWindow.postMessage({ lang: i18n.language }, '*');
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user