mirror of
https://github.com/router-for-me/Cli-Proxy-API-Management-Center.git
synced 2026-02-19 19:20:49 +08:00
fix: address PR review feedback
- Use unique ID prefix for clipPath to avoid duplicate ID issues - Add cleanup function to initializeTheme to prevent memory leak - Change tooltip to show action description instead of current theme name
This commit is contained in:
@@ -31,10 +31,11 @@ function App() {
|
|||||||
const [authReady, setAuthReady] = useState(false);
|
const [authReady, setAuthReady] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
initializeTheme();
|
const cleanupTheme = initializeTheme();
|
||||||
void restoreSession().finally(() => {
|
void restoreSession().finally(() => {
|
||||||
setAuthReady(true);
|
setAuthReady(true);
|
||||||
});
|
});
|
||||||
|
return cleanupTheme;
|
||||||
}, [initializeTheme, restoreSession]);
|
}, [initializeTheme, restoreSession]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@@ -119,12 +119,12 @@ const headerIcons = {
|
|||||||
autoTheme: (
|
autoTheme: (
|
||||||
<svg {...headerIconProps}>
|
<svg {...headerIconProps}>
|
||||||
<defs>
|
<defs>
|
||||||
<clipPath id="sunLeftHalf">
|
<clipPath id="mainLayoutAutoThemeSunLeftHalf">
|
||||||
<rect x="0" y="0" width="12" height="24" />
|
<rect x="0" y="0" width="12" height="24" />
|
||||||
</clipPath>
|
</clipPath>
|
||||||
</defs>
|
</defs>
|
||||||
<circle cx="12" cy="12" r="4" />
|
<circle cx="12" cy="12" r="4" />
|
||||||
<circle cx="12" cy="12" r="4" clipPath="url(#sunLeftHalf)" fill="currentColor" />
|
<circle cx="12" cy="12" r="4" clipPath="url(#mainLayoutAutoThemeSunLeftHalf)" fill="currentColor" />
|
||||||
<path d="M12 2v2" />
|
<path d="M12 2v2" />
|
||||||
<path d="M12 20v2" />
|
<path d="M12 20v2" />
|
||||||
<path d="M4.93 4.93l1.41 1.41" />
|
<path d="M4.93 4.93l1.41 1.41" />
|
||||||
@@ -469,7 +469,7 @@ export function MainLayout() {
|
|||||||
<Button variant="ghost" size="sm" onClick={toggleLanguage} title={t('language.switch')}>
|
<Button variant="ghost" size="sm" onClick={toggleLanguage} title={t('language.switch')}>
|
||||||
{headerIcons.language}
|
{headerIcons.language}
|
||||||
</Button>
|
</Button>
|
||||||
<Button variant="ghost" size="sm" onClick={cycleTheme} title={t(`theme.${theme}`)}>
|
<Button variant="ghost" size="sm" onClick={cycleTheme} title={t('theme.switch')}>
|
||||||
{theme === 'auto'
|
{theme === 'auto'
|
||||||
? headerIcons.autoTheme
|
? headerIcons.autoTheme
|
||||||
: theme === 'dark'
|
: theme === 'dark'
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ interface ThemeState {
|
|||||||
resolvedTheme: ResolvedTheme;
|
resolvedTheme: ResolvedTheme;
|
||||||
setTheme: (theme: Theme) => void;
|
setTheme: (theme: Theme) => void;
|
||||||
cycleTheme: () => void;
|
cycleTheme: () => void;
|
||||||
initializeTheme: () => void;
|
initializeTheme: () => () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const getSystemTheme = (): ResolvedTheme => {
|
const getSystemTheme = (): ResolvedTheme => {
|
||||||
@@ -60,16 +60,23 @@ export const useThemeStore = create<ThemeState>()(
|
|||||||
setTheme(theme);
|
setTheme(theme);
|
||||||
|
|
||||||
// 监听系统主题变化(仅在 auto 模式下生效)
|
// 监听系统主题变化(仅在 auto 模式下生效)
|
||||||
if (window.matchMedia) {
|
if (!window.matchMedia) {
|
||||||
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {
|
return () => {};
|
||||||
const { theme: currentTheme } = get();
|
|
||||||
if (currentTheme === 'auto') {
|
|
||||||
const resolved = getSystemTheme();
|
|
||||||
applyTheme(resolved);
|
|
||||||
set({ resolvedTheme: resolved });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
|
||||||
|
const listener = () => {
|
||||||
|
const { theme: currentTheme } = get();
|
||||||
|
if (currentTheme === 'auto') {
|
||||||
|
const resolved = getSystemTheme();
|
||||||
|
applyTheme(resolved);
|
||||||
|
set({ resolvedTheme: resolved });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
mediaQuery.addEventListener('change', listener);
|
||||||
|
|
||||||
|
return () => mediaQuery.removeEventListener('change', listener);
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user