106 lines
2.9 KiB
TypeScript
106 lines
2.9 KiB
TypeScript
import React, { useState, useEffect } from 'react';
|
|
import { Box, IconButton, Icon } from 'folds';
|
|
import { invoke } from '@tauri-apps/api/core';
|
|
import * as css from './WindowControls.css';
|
|
|
|
export function WindowControls() {
|
|
const [isMaximized, setIsMaximized] = useState(false);
|
|
|
|
// Check initial maximized state
|
|
useEffect(() => {
|
|
const checkMaximized = async () => {
|
|
try {
|
|
const maximized = await invoke<boolean>('window_is_maximized');
|
|
setIsMaximized(maximized);
|
|
} catch (error) {
|
|
console.error('Failed to check window state:', error);
|
|
}
|
|
};
|
|
checkMaximized();
|
|
}, []);
|
|
|
|
const handleMinimize = async () => {
|
|
try {
|
|
await invoke('window_minimize');
|
|
} catch (error) {
|
|
console.error('Failed to minimize window:', error);
|
|
}
|
|
};
|
|
|
|
const handleMaximize = async () => {
|
|
try {
|
|
if (isMaximized) {
|
|
await invoke('window_unmaximize');
|
|
} else {
|
|
await invoke('window_maximize');
|
|
}
|
|
setIsMaximized(!isMaximized);
|
|
} catch (error) {
|
|
console.error('Failed to toggle maximize:', error);
|
|
}
|
|
};
|
|
|
|
const handleClose = async () => {
|
|
try {
|
|
await invoke('window_close');
|
|
} catch (error) {
|
|
console.error('Failed to close window:', error);
|
|
}
|
|
};
|
|
|
|
// Only render on desktop (when Tauri is available)
|
|
if (typeof (window as any).__TAURI__ === 'undefined') {
|
|
return null;
|
|
}
|
|
|
|
return (
|
|
<Box className={css.WindowControls} alignItems="Center" gap="100">
|
|
<button
|
|
className={css.WindowButton}
|
|
onClick={handleMinimize}
|
|
aria-label="Minimize"
|
|
type="button"
|
|
>
|
|
<svg width="12" height="12" viewBox="0 0 12 12">
|
|
<rect y="5" width="12" height="2" fill="currentColor" />
|
|
</svg>
|
|
</button>
|
|
|
|
<button
|
|
className={css.WindowButton}
|
|
onClick={handleMaximize}
|
|
aria-label={isMaximized ? 'Restore' : 'Maximize'}
|
|
type="button"
|
|
>
|
|
{isMaximized ? (
|
|
<svg width="12" height="12" viewBox="0 0 12 12">
|
|
<rect x="2" y="0" width="10" height="10" fill="none" stroke="currentColor" strokeWidth="1.5" />
|
|
<rect x="0" y="2" width="10" height="10" fill="currentColor" />
|
|
<rect x="1.5" y="3.5" width="7" height="7" fill="var(--bg-surface)" />
|
|
</svg>
|
|
) : (
|
|
<svg width="12" height="12" viewBox="0 0 12 12">
|
|
<rect x="0" y="0" width="12" height="12" fill="none" stroke="currentColor" strokeWidth="1.5" />
|
|
</svg>
|
|
)}
|
|
</button>
|
|
|
|
<button
|
|
className={css.WindowButtonClose}
|
|
onClick={handleClose}
|
|
aria-label="Close"
|
|
type="button"
|
|
>
|
|
<svg width="12" height="12" viewBox="0 0 12 12">
|
|
<path
|
|
d="M 1 1 L 11 11 M 11 1 L 1 11"
|
|
stroke="currentColor"
|
|
strokeWidth="1.5"
|
|
strokeLinecap="round"
|
|
/>
|
|
</svg>
|
|
</button>
|
|
</Box>
|
|
);
|
|
}
|