fix: unbroken divider between sidebar and feed
The title bar was one band across the top of the window, so the sidebar's right border only began below it and the pane read as detached from the top of the window. Each pane now reserves its own strip for the traffic lights instead. The border runs from the very top, and because both insets are the same height the sidebar header and the top bar share a baseline, so their bottom borders form one continuous line across the window. Both strips stay draggable, and the inset collapses in window fullscreen where there are no traffic lights to clear.
This commit is contained in:
+9
-11
@@ -214,19 +214,14 @@ export default function App() {
|
|||||||
return "Nothing matches this filter.";
|
return "Nothing matches this filter.";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Each pane reserves its own strip for the traffic lights instead of one
|
||||||
|
// band across the top, so the sidebar's right border runs unbroken from the
|
||||||
|
// very top of the window. In macOS window fullscreen there are no traffic
|
||||||
|
// lights, so the inset collapses.
|
||||||
|
const titleBarInset = !windowFullscreen;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex h-screen flex-col">
|
<div className="flex h-screen flex-col">
|
||||||
{/* The webview paints the title bar itself. It sits directly above the
|
|
||||||
sidebar and top bar, so it takes the panel colour, not the page's.
|
|
||||||
In macOS window fullscreen the traffic lights are gone, so the strip
|
|
||||||
would just be a blank bar — it collapses instead. */}
|
|
||||||
{!windowFullscreen && (
|
|
||||||
<div
|
|
||||||
data-tauri-drag-region
|
|
||||||
className="h-9 shrink-0 bg-white dark:bg-slate-900"
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<div className="relative flex min-h-0 flex-1 flex-col lg:flex-row">
|
<div className="relative flex min-h-0 flex-1 flex-col lg:flex-row">
|
||||||
{/* With the sidebar hidden, a thin strip along the left edge brings it
|
{/* With the sidebar hidden, a thin strip along the left edge brings it
|
||||||
back on hover. */}
|
back on hover. */}
|
||||||
@@ -251,6 +246,7 @@ export default function App() {
|
|||||||
totalVideos={totals.videos}
|
totalVideos={totals.videos}
|
||||||
totalDownloaded={totals.downloaded}
|
totalDownloaded={totals.downloaded}
|
||||||
onHide={() => { setSidebarHidden(true); setSidebarPeek(false); }}
|
onHide={() => { setSidebarHidden(true); setSidebarPeek(false); }}
|
||||||
|
titleBarInset={titleBarInset}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
@@ -264,6 +260,7 @@ export default function App() {
|
|||||||
totalVideos={totals.videos}
|
totalVideos={totals.videos}
|
||||||
totalDownloaded={totals.downloaded}
|
totalDownloaded={totals.downloaded}
|
||||||
onHide={() => setSidebarHidden(true)}
|
onHide={() => setSidebarHidden(true)}
|
||||||
|
titleBarInset={titleBarInset}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
@@ -279,6 +276,7 @@ export default function App() {
|
|||||||
view={view} onView={setView}
|
view={view} onView={setView}
|
||||||
sidebarHidden={sidebarHidden}
|
sidebarHidden={sidebarHidden}
|
||||||
onShowSidebar={() => { setSidebarHidden(false); setSidebarPeek(false); }}
|
onShowSidebar={() => { setSidebarHidden(false); setSidebarPeek(false); }}
|
||||||
|
titleBarInset={titleBarInset}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{!online && (
|
{!online && (
|
||||||
|
|||||||
@@ -11,11 +11,13 @@ interface Props {
|
|||||||
onHide: () => void;
|
onHide: () => void;
|
||||||
/** True when revealed by hover over the left edge rather than pinned open. */
|
/** True when revealed by hover over the left edge rather than pinned open. */
|
||||||
floating?: boolean;
|
floating?: boolean;
|
||||||
|
/** Reserve room for the macOS traffic lights above the header. */
|
||||||
|
titleBarInset: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Sidebar({
|
export default function Sidebar({
|
||||||
channels, activeChannel, onSelect, onOpenSettings, totalVideos, totalDownloaded,
|
channels, activeChannel, onSelect, onOpenSettings, totalVideos, totalDownloaded,
|
||||||
onHide, floating,
|
onHide, floating, titleBarInset,
|
||||||
}: Props) {
|
}: Props) {
|
||||||
const row =
|
const row =
|
||||||
"flex w-full cursor-pointer items-center justify-between gap-2 rounded-lg px-2 py-1.5 " +
|
"flex w-full cursor-pointer items-center justify-between gap-2 rounded-lg px-2 py-1.5 " +
|
||||||
@@ -35,6 +37,10 @@ export default function Sidebar({
|
|||||||
"lg:border-b-0 lg:border-r")
|
"lg:border-b-0 lg:border-r")
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
{/* The pane starts at the very top of the window so its right border is
|
||||||
|
one unbroken line; this reserves the strip the traffic lights sit in. */}
|
||||||
|
{titleBarInset && <div data-tauri-drag-region className="h-9 shrink-0" />}
|
||||||
|
|
||||||
<header
|
<header
|
||||||
className="sticky top-0 z-20 flex items-center justify-between gap-2 border-b
|
className="sticky top-0 z-20 flex items-center justify-between gap-2 border-b
|
||||||
border-slate-200 bg-white/95 px-4 py-3 backdrop-blur
|
border-slate-200 bg-white/95 px-4 py-3 backdrop-blur
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ interface Props {
|
|||||||
onView: (v: ViewMode) => void;
|
onView: (v: ViewMode) => void;
|
||||||
sidebarHidden: boolean;
|
sidebarHidden: boolean;
|
||||||
onShowSidebar: () => void;
|
onShowSidebar: () => void;
|
||||||
|
/** Matches the sidebar's inset so the two headers share a baseline. */
|
||||||
|
titleBarInset: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Neutral outline until active; active is the one filled state. */
|
/** Neutral outline until active; active is the one filled state. */
|
||||||
@@ -56,7 +58,7 @@ export default function TopBar({
|
|||||||
search, onSearch, downloadedOnly, onDownloadedOnly, hideShorts, onHideShorts,
|
search, onSearch, downloadedOnly, onDownloadedOnly, hideShorts, onHideShorts,
|
||||||
online, reachable, forcedOffline, onToggleForcedOffline,
|
online, reachable, forcedOffline, onToggleForcedOffline,
|
||||||
onRefresh, refreshing, refreshProgress, resultCount, view, onView,
|
onRefresh, refreshing, refreshProgress, resultCount, view, onView,
|
||||||
sidebarHidden, onShowSidebar,
|
sidebarHidden, onShowSidebar, titleBarInset,
|
||||||
}: Props) {
|
}: Props) {
|
||||||
const pct = refreshProgress && refreshProgress.total > 0
|
const pct = refreshProgress && refreshProgress.total > 0
|
||||||
? (refreshProgress.done / refreshProgress.total) * 100
|
? (refreshProgress.done / refreshProgress.total) * 100
|
||||||
@@ -67,6 +69,8 @@ export default function TopBar({
|
|||||||
className="sticky top-0 z-20 border-b border-slate-200 bg-white/95 backdrop-blur
|
className="sticky top-0 z-20 border-b border-slate-200 bg-white/95 backdrop-blur
|
||||||
dark:border-slate-800 dark:bg-slate-900/95"
|
dark:border-slate-800 dark:bg-slate-900/95"
|
||||||
>
|
>
|
||||||
|
{titleBarInset && <div data-tauri-drag-region className="h-9" />}
|
||||||
|
|
||||||
<div className="flex flex-wrap items-center gap-2 px-4 py-3">
|
<div className="flex flex-wrap items-center gap-2 px-4 py-3">
|
||||||
{sidebarHidden && (
|
{sidebarHidden && (
|
||||||
<button
|
<button
|
||||||
|
|||||||
Reference in New Issue
Block a user