feat: refactor main and preload scripts, update window service logic, enhance TitleBar component, and adjust login page layout

This commit is contained in:
DEV_DSW
2026-04-27 09:10:57 +08:00
parent 4c61e93c3e
commit dd211056dd
7 changed files with 99 additions and 171 deletions

View File

@@ -1,17 +1,24 @@
import { useEffect, useState } from 'react';
import { Copy, Minus, Square, X } from 'lucide-react';
import { useI18n } from '../../i18n';
type TitleBarProps = {
variant?: 'default' | 'light';
controlsTheme?: 'default' | 'white';
};
export default function TitleBar({ variant = 'default' }: TitleBarProps) {
type WindowsTitleBarProps = {
variant: TitleBarProps['variant'];
controlsTheme: NonNullable<TitleBarProps['controlsTheme']>;
closeLabel: string;
maximizeLabel: string;
minimizeLabel: string;
restoreLabel: string;
};
export default function TitleBar({ variant = 'default', controlsTheme }: TitleBarProps) {
const { t } = useI18n();
const platform = (window as any).api?.platform ?? '';
if (platform === 'linux') return null;
const iconColorClass =
variant === 'light' ? 'text-white' : 'text-[#525866] dark:text-gray-300';
const platform = window.api?.platform ?? '';
const borderColorClass =
variant === 'light' ? 'border-b-white/30' : 'border-b-gray-300 dark:border-gray-700';
@@ -24,6 +31,64 @@ export default function TitleBar({ variant = 'default' }: TitleBarProps) {
);
}
if (platform !== 'win32') {
return null;
}
return (
<WindowsTitleBar
variant={variant}
controlsTheme={controlsTheme ?? (variant === 'light' ? 'white' : 'default')}
closeLabel={t('window.close')}
maximizeLabel={t('window.maximize')}
minimizeLabel={t('window.minimize')}
restoreLabel={t('window.restore')}
/>
);
}
function WindowsTitleBar({
variant = 'default',
controlsTheme,
closeLabel,
maximizeLabel,
minimizeLabel,
restoreLabel,
}: WindowsTitleBarProps) {
const [maximized, setMaximized] = useState(false);
useEffect(() => {
void syncMaximizedState();
}, []);
const syncMaximizedState = async () => {
const nextState = await window.api.windowIsMaximized();
setMaximized(Boolean(nextState));
};
const handleMinimize = () => {
void window.api.windowMinimize();
};
const handleMaximize = async () => {
await window.api.windowMaximize();
await syncMaximizedState();
};
const handleClose = () => {
void window.api.windowClose();
};
const useWhiteControls = controlsTheme === 'white';
const iconColorClass = useWhiteControls ? 'text-white/95' : 'text-[#525866] dark:text-gray-300';
const borderColorClass =
variant === 'light' ? 'border-b-white/30' : 'border-b-gray-300 dark:border-gray-700';
const buttonClass = [
'flex h-full w-11 items-center justify-center transition-colors',
useWhiteControls ? 'hover:bg-white/15 hover:text-white' : 'hover:bg-[#999] hover:text-white',
iconColorClass,
].join(' ');
return (
<div
className={['drag-region flex h-10 shrink-0 items-center justify-end border-b', borderColorClass].join(
@@ -34,39 +99,32 @@ export default function TitleBar({ variant = 'default' }: TitleBarProps) {
<div className="no-drag flex h-full">
<button
type="button"
className={['flex h-full w-11 items-center justify-center hover:bg-[#999] hover:text-white transition-colors', iconColorClass].join(
' ',
)}
title={t('window.minimize')}
onClick={() => {
(window as any).api?.windowMinimize?.();
}}
className={buttonClass}
title={minimizeLabel}
onClick={handleMinimize}
>
<span className="text-base leading-none"></span>
<Minus className="h-4 w-4" />
</button>
<button
type="button"
className={['flex h-full w-11 items-center justify-center hover:bg-[#999] hover:text-white transition-colors', iconColorClass].join(
' ',
)}
title={t('window.maximize')}
className={buttonClass}
title={maximized ? restoreLabel : maximizeLabel}
onClick={() => {
(window as any).api?.windowMaximize?.();
void handleMaximize();
}}
>
<span className="text-[14px] leading-none"></span>
{maximized ? <Copy className="h-3.5 w-3.5" /> : <Square className="h-3.5 w-3.5" />}
</button>
<button
type="button"
className={['flex h-full w-11 items-center justify-center hover:bg-[#ff0000] hover:text-white transition-colors', iconColorClass].join(
' ',
)}
title={t('window.close')}
onClick={() => {
(window as any).api?.windowClose?.();
}}
className={[
'flex h-full w-11 items-center justify-center transition-colors hover:bg-[#ff0000] hover:text-white',
iconColorClass,
].join(' ')}
title={closeLabel}
onClick={handleClose}
>
<span className="text-base leading-none">×</span>
<X className="h-4 w-4" />
</button>
</div>
</div>

View File

@@ -144,7 +144,9 @@ export default function LoginPage() {
/>
) : null}
<TitleBar variant="light" />
<div className="relative z-20">
<TitleBar variant="light" controlsTheme="white" />
</div>
<main
className={['relative z-10 box-border flex flex-auto pl-2 pr-2 pb-2', platform !== 'linux' ? 'pt-2' : 'pt-11'].join(' ')}