Download desktop/src/components/layout/WindowControls.tsx from chenbhao/codev: direct link, hf CLI and curl.
- Browser
- Download file 3.37 kB
-
https://huggingface.co/chenbhao/codev/resolve/e40073cc959cd4729bf4009662bca374c5c4e266/desktop/src/components/layout/WindowControls.tsx
- Command line
-
hf download hf://chenbhao/codev@e40073cc959cd4729bf4009662bca374c5c4e266/desktop/src/components/layout/WindowControls.tsx
-
curl -L -o WindowControls.tsx https://huggingface.co/chenbhao/codev/resolve/e40073cc959cd4729bf4009662bca374c5c4e266/desktop/src/components/layout/WindowControls.tsx
3.37 kB
| import { useState, useEffect } from 'react' | |
| const isTauri = typeof window !== 'undefined' && ('__TAURI_INTERNALS__' in window || '__TAURI__' in window) | |
| const isWindows = typeof navigator !== 'undefined' && /Win/.test(navigator.platform) | |
| /** Whether to render custom window controls (Windows + Tauri only) */ | |
| export const showWindowControls = isTauri && isWindows | |
| export function WindowControls() { | |
| const [maximized, setMaximized] = useState(false) | |
| const [win, setWin] = useState<{ | |
| minimize: () => Promise<void> | |
| toggleMaximize: () => Promise<void> | |
| close: () => Promise<void> | |
| isMaximized: () => Promise<boolean> | |
| onResized: (handler: () => void) => Promise<() => void> | |
| } | null>(null) | |
| useEffect(() => { | |
| if (!showWindowControls) return | |
| let unlisten: (() => void) | undefined | |
| import('@tauri-apps/api/window') | |
| .then(async ({ getCurrentWindow }) => { | |
| const w = getCurrentWindow() | |
| setWin(w as any) | |
| setMaximized(await w.isMaximized()) | |
| unlisten = await w.onResized(async () => { | |
| setMaximized(await w.isMaximized()) | |
| }) | |
| }) | |
| .catch(() => {}) | |
| return () => { unlisten?.() } | |
| }, []) | |
| const runWindowAction = (action: () => Promise<void>) => { | |
| void action().catch((error) => { | |
| console.error('Window control action failed', error) | |
| }) | |
| } | |
| if (!showWindowControls || !win) return null | |
| return ( | |
| <div data-testid="window-controls" className="flex items-stretch flex-shrink-0 -my-px"> | |
| {/* Minimize */} | |
| <button | |
| onClick={() => runWindowAction(() => win.minimize())} | |
| aria-label="Minimize window" | |
| className="w-[46px] h-full flex items-center justify-center text-[var(--color-text-secondary)] hover:bg-[var(--color-surface-hover)] transition-colors" | |
| > | |
| <svg width="10" height="1" viewBox="0 0 10 1"> | |
| <rect width="10" height="1" fill="currentColor" /> | |
| </svg> | |
| </button> | |
| {/* Maximize / Restore */} | |
| <button | |
| onClick={() => runWindowAction(() => win.toggleMaximize())} | |
| aria-label={maximized ? 'Restore window' : 'Maximize window'} | |
| className="w-[46px] h-full flex items-center justify-center text-[var(--color-text-secondary)] hover:bg-[var(--color-surface-hover)] transition-colors" | |
| > | |
| {maximized ? ( | |
| <svg width="10" height="10" viewBox="0 0 10 10" fill="none" stroke="currentColor" strokeWidth="1"> | |
| <rect x="0" y="3" width="7" height="7" /> | |
| <polyline points="3,3 3,0 10,0 10,7 7,7" /> | |
| </svg> | |
| ) : ( | |
| <svg width="10" height="10" viewBox="0 0 10 10" fill="none" stroke="currentColor" strokeWidth="1"> | |
| <rect x="0.5" y="0.5" width="9" height="9" /> | |
| </svg> | |
| )} | |
| </button> | |
| {/* Close */} | |
| <button | |
| onClick={() => runWindowAction(() => win.close())} | |
| aria-label="Close window" | |
| className="w-[46px] h-full flex items-center justify-center text-[var(--color-text-secondary)] hover:bg-[var(--color-window-close-hover)] hover:text-white transition-colors" | |
| > | |
| <svg width="10" height="10" viewBox="0 0 10 10" fill="none" stroke="currentColor" strokeWidth="1.2"> | |
| <line x1="0" y1="0" x2="10" y2="10" /> | |
| <line x1="10" y1="0" x2="0" y2="10" /> | |
| </svg> | |
| </button> | |
| </div> | |
| ) | |
| } | |