rework style TobBar in themes.ts

This commit is contained in:
2025-12-14 23:49:32 +05:00
parent e93379ff12
commit ff87c9d4a5
2 changed files with 103 additions and 178 deletions

View File

@ -20,6 +20,7 @@ import CalendarMonthIcon from '@mui/icons-material/CalendarMonth';
import EmojiEventsIcon from '@mui/icons-material/EmojiEvents'; import EmojiEventsIcon from '@mui/icons-material/EmojiEvents';
import PersonIcon from '@mui/icons-material/Person'; import PersonIcon from '@mui/icons-material/Person';
import SettingsIcon from '@mui/icons-material/Settings'; import SettingsIcon from '@mui/icons-material/Settings';
import { useTheme } from '@mui/material/styles';
declare global { declare global {
interface Window { interface Window {
electron: { electron: {
@ -48,6 +49,7 @@ export default function TopBar({ onRegister, username }: TopBarProps) {
const navigate = useNavigate(); const navigate = useNavigate();
const tabsWrapperRef = useRef<HTMLDivElement | null>(null); const tabsWrapperRef = useRef<HTMLDivElement | null>(null);
const tabsRootRef = useRef<HTMLDivElement | null>(null); const tabsRootRef = useRef<HTMLDivElement | null>(null);
const theme = useTheme();
const updateGradientVars = useCallback(() => { const updateGradientVars = useCallback(() => {
const root = tabsRootRef.current; const root = tabsRootRef.current;
@ -71,7 +73,8 @@ export default function TopBar({ onRegister, username }: TopBarProps) {
); );
const path = location.pathname || ''; const path = location.pathname || '';
const isAuthPage = path.startsWith('/login') || path.startsWith('/registration'); const isAuthPage =
path.startsWith('/login') || path.startsWith('/registration');
const TAB_ROUTES: Array<{ const TAB_ROUTES: Array<{
value: number; value: number;
@ -198,26 +201,7 @@ export default function TopBar({ onRegister, username }: TopBarProps) {
// Функция для получения количества монет // Функция для получения количества монет
const tabBaseSx = { const tabBaseSx = [{ fontSize: '0.7em' }, theme.launcher.topbar.tabBase];
color: 'white',
fontFamily: 'Benzin-Bold',
fontSize: '0.7em',
transition: 'all 0.3s ease',
'&:hover': {
color: 'rgb(170, 170, 170)',
},
};
const activeTabSx = {
color: 'transparent',
WebkitTextFillColor: 'transparent',
backgroundImage: 'var(--tabs-grad)',
backgroundRepeat: 'no-repeat',
backgroundSize: 'var(--tabs-w) 100%',
backgroundPosition: 'calc(-1 * var(--active-x)) 0',
WebkitBackgroundClip: 'text',
backgroundClip: 'text',
};
const logout = () => { const logout = () => {
localStorage.removeItem('launcher_config'); localStorage.removeItem('launcher_config');
@ -230,7 +214,7 @@ export default function TopBar({ onRegister, username }: TopBarProps) {
return; return;
} }
const savedConfig = localStorage.getItem('launcher_config'); const savedConfig = localStorage.getItem('launcher_config');
if (!savedConfig) return; if (!savedConfig) return;
let cfg: any = null; let cfg: any = null;
@ -263,33 +247,29 @@ export default function TopBar({ onRegister, username }: TopBarProps) {
}; };
window.addEventListener('skin-updated', handler as EventListener); window.addEventListener('skin-updated', handler as EventListener);
return () => window.removeEventListener('skin-updated', handler as EventListener); return () =>
window.removeEventListener('skin-updated', handler as EventListener);
}, [loadSkin]); }, [loadSkin]);
return ( return (
<Box <Box
sx={{ sx={[
display: 'flex', {
position: 'fixed', display: 'flex',
top: 0, position: 'fixed',
left: 0, top: 0,
right: 0, left: 0,
height: '8vh', right: 0,
zIndex: 1000, height: '8vh',
width: '100%', zIndex: 1000,
WebkitAppRegion: 'drag', width: '100%',
overflow: 'hidden', WebkitAppRegion: 'drag',
justifyContent: 'space-between', overflow: 'hidden',
alignItems: 'center', justifyContent: 'space-between',
alignItems: 'center',
// убрать если не оч },
theme.launcher.topbar.firstBox,
// стиль как в Registration ]}
background: isAuthPage ?
'none' : 'linear-gradient(71deg, rgba(242,113,33,0.18) 0%, rgba(233,64,205,0.14) 70%, rgba(138,35,135,0.16) 100%)',
backdropFilter: isAuthPage ? 'none' : 'blur(10px)',
boxShadow: isAuthPage ? 'none' : '0 8px 30px rgba(0,0,0,0.35)',
}}
> >
{/* Левая часть */} {/* Левая часть */}
<Box <Box
@ -305,19 +285,16 @@ export default function TopBar({ onRegister, username }: TopBarProps) {
<Button <Button
variant="outlined" variant="outlined"
onClick={() => handleLaunchPage()} onClick={() => handleLaunchPage()}
sx={{ sx={[
width: '3em', {
height: '3em', width: '3em',
borderRadius: '50%', height: '3em',
border: 'unset', borderRadius: '50%',
color: 'white', minWidth: 'unset',
minWidth: 'unset', minHeight: 'unset',
minHeight: 'unset',
transition: 'transform 0.3s ease',
'&:hover': {
transform: 'scale(1.2)',
}, },
}} theme.launcher.topbar.backButton,
]}
> >
<ArrowBackRoundedIcon /> <ArrowBackRoundedIcon />
</Button> </Button>
@ -329,7 +306,7 @@ export default function TopBar({ onRegister, username }: TopBarProps) {
// старый вариант // старый вариант
sx={{ sx={{
borderBottom: 1, borderBottom: 1,
borderColor: 'transparent', ...theme.launcher.topbar.tabsBox,
// '& .MuiTabs-indicator': { // '& .MuiTabs-indicator': {
// backgroundColor: 'rgba(255, 77, 77, 1)', // backgroundColor: 'rgba(255, 77, 77, 1)',
// }, // },
@ -371,61 +348,40 @@ export default function TopBar({ onRegister, username }: TopBarProps) {
scrollButtons={false} scrollButtons={false}
disableRipple={true} disableRipple={true}
sx={{ sx={{
// один градиент на весь Tabs ...theme.launcher.topbar.tabs,
'--tabs-grad': 'linear-gradient(90deg, #F27121 0%, #E940CD 50%, #8A2387 100%)',
// активный текст показывает “срез” общего градиента
'& .MuiTab-root.Mui-selected': {
color: 'transparent',
backgroundImage: 'var(--tabs-grad)',
backgroundRepeat: 'no-repeat',
backgroundSize: 'var(--tabs-w) 100%',
backgroundPosition: 'calc(-1 * var(--active-x)) 0',
WebkitBackgroundClip: 'text',
backgroundClip: 'text',
},
// подчёркивание тоже из того же “единого” градиента
'& .MuiTabs-indicator': {
height: '2px',
backgroundImage: 'var(--tabs-grad)',
backgroundRepeat: 'no-repeat',
backgroundSize: 'var(--tabs-w) 100%',
backgroundPosition: 'calc(-1 * var(--active-x)) 0',
},
}} }}
> >
<Tab <Tab
label="Новости" label="Новости"
disableRipple={true} disableRipple={true}
sx={{ sx={[
...tabBaseSx, ...tabBaseSx,
...(selectedTab === 0 ? activeTabSx : null), selectedTab === 0 ? theme.launcher.topbar.tabActive : null,
}} ]}
/> />
<Tab <Tab
label="Версии" label="Версии"
disableRipple={true} disableRipple={true}
sx={{ sx={[
...tabBaseSx, ...tabBaseSx,
...(selectedTab === 1 ? activeTabSx : null), selectedTab === 1 ? theme.launcher.topbar.tabActive : null,
}} ]}
/> />
<Tab <Tab
label="Магазин" label="Магазин"
disableRipple={true} disableRipple={true}
sx={{ sx={[
...tabBaseSx, ...tabBaseSx,
...(selectedTab === 2 ? activeTabSx : null), selectedTab === 2 ? theme.launcher.topbar.tabActive : null,
}} ]}
/> />
<Tab <Tab
label="Рынок" label="Рынок"
disableRipple={true} disableRipple={true}
sx={{ sx={[
...tabBaseSx, ...tabBaseSx,
...(selectedTab === 3 ? activeTabSx : null), selectedTab === 3 ? theme.launcher.topbar.tabActive : null,
}} ]}
/> />
</Tabs> </Tabs>
</CustomTooltip> </CustomTooltip>
@ -497,6 +453,7 @@ export default function TopBar({ onRegister, username }: TopBarProps) {
width: '3em', width: '3em',
height: '3em', height: '3em',
borderRadius: '50%', borderRadius: '50%',
...theme.launcher.topbar.windowControlButton,
}} }}
> >
<svg <svg
@ -507,7 +464,7 @@ export default function TopBar({ onRegister, username }: TopBarProps) {
> >
<path <path
d="M 7 19 h 10 c 0.55 0 1 0.45 1 1 s -0.45 1 -1 1 H 7 c -0.55 0 -1 -0.45 -1 -1 s 0.45 -1 1 -1" d="M 7 19 h 10 c 0.55 0 1 0.45 1 1 s -0.45 1 -1 1 H 7 c -0.55 0 -1 -0.45 -1 -1 s 0.45 -1 1 -1"
fill="white" fill={theme.launcher.topbar.windowControlIcon.color}
></path> ></path>
</svg> </svg>
</Button> </Button>
@ -521,9 +478,12 @@ export default function TopBar({ onRegister, username }: TopBarProps) {
width: '3em', width: '3em',
height: '3em', height: '3em',
borderRadius: '50%', borderRadius: '50%',
...theme.launcher.topbar.windowControlButton,
}} }}
> >
<CloseRoundedIcon sx={{ color: 'white' }} /> <CloseRoundedIcon
sx={{ color: theme.launcher.topbar.windowControlIcon.color }}
/>
</Button> </Button>
</Box> </Box>
<Menu <Menu
@ -543,11 +503,7 @@ export default function TopBar({ onRegister, username }: TopBarProps) {
mt: '0.5vw', mt: '0.5vw',
borderRadius: '1vw', borderRadius: '1vw',
minWidth: '16vw', minWidth: '16vw',
color: 'white', ...theme.launcher.topbar.menuPaper,
bgcolor: 'rgba(0,0,0,0.82)',
backdropFilter: 'blur(10px)',
border: '1px solid rgba(233,64,205,0.25)',
boxShadow: '0 18px 40px rgba(0,0,0,0.55)',
}, },
}} }}
> >
@ -571,10 +527,7 @@ export default function TopBar({ onRegister, username }: TopBarProps) {
<Box sx={{ display: 'flex', flexDirection: 'column' }}> <Box sx={{ display: 'flex', flexDirection: 'column' }}>
<Typography <Typography
sx={{ sx={[{ fontSize: '2vw' }, theme.launcher.topbar.menuUsername]}
fontFamily: 'Benzin-Bold',
fontSize: '2vw',
}}
> >
{username || 'Игрок'} {username || 'Игрок'}
</Typography> </Typography>
@ -593,22 +546,17 @@ export default function TopBar({ onRegister, username }: TopBarProps) {
</Box> </Box>
</Box> </Box>
<Divider sx={{ my: '0.4vw', borderColor: 'rgba(255,255,255,0.08)' }} /> <Divider sx={{ my: '0.4vw', ...theme.launcher.topbar.menuDivider }} />
<MenuItem <MenuItem
onClick={() => { onClick={() => {
handleAvatarMenuClose(); handleAvatarMenuClose();
navigate('/profile'); navigate('/profile');
}} }}
sx={{ sx={[
fontFamily: 'Benzin-Bold', { fontSize: '1.5vw', gap: '0.5vw', py: '0.7vw' },
fontSize: '1.5vw', theme.launcher.topbar.menuItem,
gap: '0.5vw', ]}
py: '0.7vw',
'&:hover': {
bgcolor: 'rgba(255,77,77,0.15)',
},
}}
> >
<PersonIcon sx={{ fontSize: '2vw' }} /> Профиль <PersonIcon sx={{ fontSize: '2vw' }} /> Профиль
</MenuItem> </MenuItem>
@ -619,15 +567,10 @@ export default function TopBar({ onRegister, username }: TopBarProps) {
handleAvatarMenuClose(); handleAvatarMenuClose();
navigate('/dailyquests'); navigate('/dailyquests');
}} }}
sx={{ sx={[
fontFamily: 'Benzin-Bold', { fontSize: '1.5vw', gap: '0.5vw', py: '0.7vw' },
fontSize: '1.5vw', theme.launcher.topbar.menuItem,
gap: '0.5vw', ]}
py: '0.7vw',
'&:hover': {
bgcolor: 'rgba(255,77,77,0.15)',
},
}}
> >
<CalendarMonthIcon sx={{ fontSize: '2vw' }} /> Ежедневные задания <CalendarMonthIcon sx={{ fontSize: '2vw' }} /> Ежедневные задания
</MenuItem> </MenuItem>
@ -638,15 +581,10 @@ export default function TopBar({ onRegister, username }: TopBarProps) {
handleAvatarMenuClose(); handleAvatarMenuClose();
navigate('/daily'); navigate('/daily');
}} }}
sx={{ sx={[
fontFamily: 'Benzin-Bold', { fontSize: '1.5vw', gap: '0.5vw', py: '0.7vw' },
fontSize: '1.5vw', theme.launcher.topbar.menuItem,
gap: '0.5vw', ]}
py: '0.7vw',
'&:hover': {
bgcolor: 'rgba(255,77,77,0.15)',
},
}}
> >
<EmojiEventsIcon sx={{ fontSize: '2vw' }} /> Ежедневная награда <EmojiEventsIcon sx={{ fontSize: '2vw' }} /> Ежедневная награда
</MenuItem> </MenuItem>
@ -656,20 +594,15 @@ export default function TopBar({ onRegister, username }: TopBarProps) {
handleAvatarMenuClose(); handleAvatarMenuClose();
navigate('/settings'); navigate('/settings');
}} }}
sx={{ sx={[
fontFamily: 'Benzin-Bold', { fontSize: '1.5vw', gap: '0.5vw', py: '0.7vw' },
fontSize: '1.5vw', theme.launcher.topbar.menuItem,
gap: '0.5vw', ]}
py: '0.7vw',
'&:hover': {
bgcolor: 'rgba(255,77,77,0.15)',
},
}}
> >
<SettingsIcon sx={{ fontSize: '2vw' }} /> Настройки <SettingsIcon sx={{ fontSize: '2vw' }} /> Настройки
</MenuItem> </MenuItem>
<Divider sx={{ my: '0.4vw', borderColor: 'rgba(255,255,255,0.08)' }} /> <Divider sx={{ my: '0.4vw', ...theme.launcher.topbar.menuDivider }} />
{!isLoginPage && !isRegistrationPage && username && ( {!isLoginPage && !isRegistrationPage && username && (
<Button <Button
variant="outlined" variant="outlined"
@ -678,26 +611,15 @@ export default function TopBar({ onRegister, username }: TopBarProps) {
handleAvatarMenuClose(); handleAvatarMenuClose();
logout(); logout();
}} }}
sx={{ sx={[
width: '8vw', {
height: '3vw', width: '8vw',
borderRadius: '2.5vw', height: '3vw',
fontFamily: 'Benzin-Bold', fontSize: '1.2vw',
fontSize: '1.2vw', m: '0 0 0 18vw',
background:
'linear-gradient(71deg, #F27121 0%, #E940CD 70%, #8A2387 100%)',
color: 'white',
border: 'none',
transition: 'transform 0.3s ease',
'&:hover': {
background:
'linear-gradient(71deg, #F27121 0%, #E940CD 70%, #8A2387 100%)',
transform: 'scale(1.01)',
boxShadow: '0 4px 15px rgba(242, 113, 33, 0.4)',
}, },
boxShadow: '0 2px 8px rgba(0, 0, 0, 0.3)', theme.launcher.topbar.logoutButton,
m: '0 0 0 18vw', ]}
}}
> >
Выйти Выйти
</Button> </Button>

View File

@ -7,18 +7,14 @@ declare module '@mui/material/styles' {
default: string; default: string;
}; };
gradients: {
accent: string;
tabs: string;
};
topbar: { topbar: {
firstBox: { firstBox: SxProps<Theme>;
background: string; backButton: SxProps<Theme>;
backdropFilter: string;
boxShadow: string;
};
backButton: {
transition: string;
'&:hover': {
transform: string;
};
};
tabsBox: { tabsBox: {
borderColor: string; borderColor: string;
}; };
@ -59,19 +55,25 @@ export const defaultTheme = createTheme({
default: 'Benzin-Bold', default: 'Benzin-Bold',
}, },
gradients: {
accent: '#F27121 0%, #E940CD 50%, #8A2387 100%',
tabs: 'linear-gradient(71deg, rgba(242,113,33,0.18) 0%, rgba(233,64,205,0.14) 70%, rgba(138,35,135,0.16) 100%)',
},
topbar: { topbar: {
firstBox: { firstBox: (theme: Theme) => ({
background: background: theme.launcher.gradients.tabs,
'linear-gradient(71deg, rgba(242,113,33,0.18) 0%, rgba(233,64,205,0.14) 70%, rgba(138,35,135,0.16) 100%)',
backdropFilter: 'blur(10px)', backdropFilter: 'blur(10px)',
boxShadow: '0 8px 30px rgba(0,0,0,0.35)', boxShadow: '0 8px 30px rgba(0,0,0,0.35)',
}, }),
backButton: { backButton: (theme: Theme) => ({
color: theme.palette.text.primary,
transition: 'transform 0.3s ease', transition: 'transform 0.3s ease',
'&:hover': { '&:hover': {
transform: 'scale(1.2)', transform: 'scale(1.2)',
}, },
}, border: 'unset',
}),
tabsBox: { tabsBox: {
borderColor: 'transparent', borderColor: 'transparent',
}, },
@ -144,9 +146,10 @@ export const defaultTheme = createTheme({
logoutButton: (theme: Theme) => ({ logoutButton: (theme: Theme) => ({
fontFamily: theme.launcher.fonts.default, fontFamily: theme.launcher.fonts.default,
borderRadius: '2.5vw',
background: background:
'linear-gradient(71deg, #F27121 0%, #E940CD 70%, #8A2387 100%)', 'linear-gradient(71deg, #F27121 0%, #E940CD 70%, #8A2387 100%)',
color: theme.palette.text.primary, color: 'white',
border: 'none', border: 'none',
transition: 'transform 0.3s ease', transition: 'transform 0.3s ease',
'&:hover': { '&:hover': {