fix(ui): keep dialogs clear of window controls

This commit is contained in:
NimBold
2026-07-11 21:52:01 +03:30
parent 33375df2ff
commit 7894c05bba
5 changed files with 50 additions and 10 deletions
+7 -1
View File
@@ -132,6 +132,10 @@ function App() {
const { addToast } = useToast(); const { addToast } = useToast();
const isMacUserAgent = navigator.userAgent.includes('Mac'); const isMacUserAgent = navigator.userAgent.includes('Mac');
const usesCustomWindowControls = !isMacUserAgent && platform.os !== 'macos'; const usesCustomWindowControls = !isMacUserAgent && platform.os !== 'macos';
// Keep dialogs out of the titlebar area while platform detection is still
// resolving. The conservative fallback prevents a startup handoff from
// briefly rendering underneath native or custom window controls.
const hasWindowChrome = isMacUserAgent || ['macos', 'windows', 'linux', 'unknown'].includes(platform.os);
const acknowledgePairingTokenChange = () => { const acknowledgePairingTokenChange = () => {
invoke('acknowledge_pairing_token_change').catch(error => { invoke('acknowledge_pairing_token_change').catch(error => {
@@ -669,7 +673,9 @@ function App() {
}, [coreReady]); }, [coreReady]);
return ( return (
<div className="app-shell flex h-screen w-screen overflow-hidden text-text-primary"> <div className={`app-shell flex h-screen w-screen overflow-hidden text-text-primary ${
hasWindowChrome ? 'app-shell--window-chrome' : ''
}`}>
{(platform.os === 'windows' || platform.os === 'linux') && <WindowControls />} {(platform.os === 'windows' || platform.os === 'linux') && <WindowControls />}
<div <div
className={`app-sidebar-shell relative z-20 shrink-0 transition-all duration-300 ease-[cubic-bezier(0.2,0.8,0.2,1)] ${ className={`app-sidebar-shell relative z-20 shrink-0 transition-all duration-300 ease-[cubic-bezier(0.2,0.8,0.2,1)] ${
+16 -4
View File
@@ -94,6 +94,7 @@ export const AddDownloadsModal = () => {
const [speedLimitEnabled, setSpeedLimitEnabled] = useState(false); const [speedLimitEnabled, setSpeedLimitEnabled] = useState(false);
const [speedLimit, setSpeedLimit] = useState('1024'); const [speedLimit, setSpeedLimit] = useState('1024');
const [freeSpace, setFreeSpace] = useState('Unknown'); const [freeSpace, setFreeSpace] = useState('Unknown');
const freeSpaceRequestRef = useRef(0);
const [useAuth, setUseAuth] = useState(false); const [useAuth, setUseAuth] = useState(false);
const [username, setUsername] = useState(''); const [username, setUsername] = useState('');
@@ -156,6 +157,7 @@ export const AddDownloadsModal = () => {
setPendingUseSharedDestination(false); setPendingUseSharedDestination(false);
setPendingDestinationOverrides({}); setPendingDestinationOverrides({});
setConnections(perServerConnections); setConnections(perServerConnections);
setFreeSpace('Unknown');
setSpeedLimitEnabled(false); setSpeedLimitEnabled(false);
setSpeedLimit('1024'); setSpeedLimit('1024');
setUseAuth(false); setUseAuth(false);
@@ -224,10 +226,20 @@ export const AddDownloadsModal = () => {
}, [isQueueMenuOpen, showingDuplicates]); }, [isQueueMenuOpen, showingDuplicates]);
useEffect(() => { useEffect(() => {
if (!saveLocation) return; const requestId = ++freeSpaceRequestRef.current;
if (!isAddModalOpen || !saveLocation) return;
invoke('get_free_space', { path: saveLocation }) invoke('get_free_space', { path: saveLocation })
.then(space => setFreeSpace(space)) .then(space => {
.catch(() => setFreeSpace('Unknown')); if (freeSpaceRequestRef.current === requestId) {
setFreeSpace(space);
}
})
.catch(() => {
if (freeSpaceRequestRef.current === requestId) {
setFreeSpace('Unknown');
}
});
}, [saveLocation, isAddModalOpen]); }, [saveLocation, isAddModalOpen]);
useEffect(() => { useEffect(() => {
@@ -826,7 +838,7 @@ export const AddDownloadsModal = () => {
/> />
)} )}
<div className="app-modal-backdrop fixed inset-0 z-50 flex items-center justify-center"> <div className="app-modal-backdrop fixed inset-0 z-50 flex items-center justify-center">
<div className="app-modal add-download-modal w-[900px] h-[650px] flex flex-col overflow-hidden text-sm"> <div className="app-modal add-download-modal flex flex-col overflow-hidden text-sm">
{/* Main Content Split */} {/* Main Content Split */}
<div className="flex flex-1 overflow-hidden"> <div className="flex flex-1 overflow-hidden">
+2 -2
View File
@@ -53,9 +53,9 @@ export const DeleteConfirmationModal: React.FC = () => {
const handleDeleteFile = () => removeMany(true); const handleDeleteFile = () => removeMany(true);
return ( return (
<div className="fixed inset-0 bg-black/40 flex items-center justify-center z-50 animate-fade-in"> <div className="app-modal-backdrop fixed inset-0 z-50 flex items-center justify-center bg-black/40">
<div <div
className="bg-bg-modal rounded-xl w-full max-w-md overflow-hidden flex flex-col shadow-2xl border border-border-modal scale-in" className="window-safe-modal bg-bg-modal rounded-xl w-full max-w-md overflow-hidden flex flex-col shadow-2xl border border-border-modal scale-in"
onClick={(e) => e.stopPropagation()} onClick={(e) => e.stopPropagation()}
> >
<div className="px-5 py-4 border-b border-border-modal flex items-center gap-3"> <div className="px-5 py-4 border-b border-border-modal flex items-center gap-3">
+3 -3
View File
@@ -56,9 +56,9 @@ export const KeychainPermissionModal: React.FC = () => {
}; };
return ( return (
<div className="fixed inset-0 bg-black/40 flex items-center justify-center z-50 animate-fade-in"> <div className="app-modal-backdrop fixed inset-0 z-50 flex items-center justify-center bg-black/40">
<div <div
className="bg-bg-modal rounded-xl w-full max-w-md overflow-hidden flex flex-col shadow-2xl border border-border-modal scale-in" className="window-safe-modal bg-bg-modal rounded-xl w-full max-w-md overflow-hidden flex flex-col shadow-2xl border border-border-modal scale-in"
onClick={(e) => e.stopPropagation()} onClick={(e) => e.stopPropagation()}
> >
<div className="px-5 py-4 border-b border-border-modal flex items-center gap-3"> <div className="px-5 py-4 border-b border-border-modal flex items-center gap-3">
@@ -68,7 +68,7 @@ export const KeychainPermissionModal: React.FC = () => {
<h2 className="text-lg font-semibold text-text-primary m-0">Credential Storage Access Needed</h2> <h2 className="text-lg font-semibold text-text-primary m-0">Credential Storage Access Needed</h2>
</div> </div>
<div className="px-5 py-6 flex-1 text-sm text-text-secondary leading-relaxed space-y-4"> <div className="px-5 py-6 flex-1 min-h-0 overflow-y-auto text-sm text-text-secondary leading-relaxed space-y-4">
<p> <p>
Firelink uses the browser extension to capture downloads. To keep the extension paired after restarts, Firelink uses the browser extension to capture downloads. To keep the extension paired after restarts,
Firelink stores its pairing token in {storeName}. Firelink stores its pairing token in {storeName}.
+22
View File
@@ -496,6 +496,20 @@ html[data-list-density="relaxed"] {
.app-modal-backdrop { .app-modal-backdrop {
background: hsl(0 0% 0% / 0.2); background: hsl(0 0% 0% / 0.2);
animation: fade-in 150ms ease-out; animation: fade-in 150ms ease-out;
overflow: auto;
padding: 16px;
}
.app-shell--window-chrome .app-modal-backdrop {
padding-top: 56px;
}
.app-modal-backdrop > .app-modal,
.app-modal-backdrop > .window-safe-modal {
max-width: 100%;
max-height: 100%;
min-width: 0;
min-height: 0;
} }
.app-modal { .app-modal {
@@ -510,6 +524,10 @@ html[data-list-density="relaxed"] {
/* Add Download window */ /* Add Download window */
.add-download-modal { .add-download-modal {
width: min(900px, 100%);
height: min(650px, 100%);
min-width: 0;
min-height: 0;
--add-surface: hsl(var(--surface-raised) / 0.72); --add-surface: hsl(var(--surface-raised) / 0.72);
--add-highlight: hsl(0 0% 100% / 0.08); --add-highlight: hsl(0 0% 100% / 0.08);
background: background:
@@ -525,12 +543,16 @@ html[data-list-density="relaxed"] {
} }
.add-download-left { .add-download-left {
min-width: 0;
min-height: 0;
background: background:
radial-gradient(circle at 18% 0%, hsl(var(--accent-color) / 0.055), transparent 34%), radial-gradient(circle at 18% 0%, hsl(var(--accent-color) / 0.055), transparent 34%),
hsl(var(--main-bg) / 0.56); hsl(var(--main-bg) / 0.56);
} }
.add-download-settings { .add-download-settings {
min-width: 0;
min-height: 0;
background: hsl(var(--bg-modal) / 0.7); background: hsl(var(--bg-modal) / 0.7);
} }