feat: refactor main and preload scripts, update window service logic, enhance TitleBar component, and adjust login page layout
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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(' ')}
|
||||
|
||||
Reference in New Issue
Block a user