bugfix: measure bar heights with ResizeObserver instead of magic numbers (0.21.2)

This commit is contained in:
MechaCat02
2026-05-17 20:47:32 +02:00
parent 215325ad2f
commit 64ccc0ba84
5 changed files with 57 additions and 5 deletions

2
backend/Cargo.lock generated
View File

@@ -1033,7 +1033,7 @@ checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
[[package]]
name = "mangalord"
version = "0.21.1"
version = "0.21.2"
dependencies = [
"anyhow",
"argon2",

View File

@@ -1,6 +1,6 @@
[package]
name = "mangalord"
version = "0.21.1"
version = "0.21.2"
edition = "2021"
[lib]

View File

@@ -1,6 +1,6 @@
{
"name": "mangalord-frontend",
"version": "0.21.1",
"version": "0.21.2",
"private": true,
"type": "module",
"scripts": {

View File

@@ -14,11 +14,32 @@
let { children } = $props();
let loggingOut = $state(false);
let headerEl: HTMLElement | undefined = $state();
onMount(() => {
theme.init();
preferences.init();
if (!session.loaded) session.refresh();
// Publish the header's measured height as a CSS custom
// property so sticky descendants (e.g. the reader nav) can
// pin themselves directly below it without guessing. A
// ResizeObserver keeps it in sync as the viewport reflows
// (the nav `flex-wrap: wrap`s on narrow widths), the user
// zooms, or fonts swap. Hard-coded pixel offsets in tokens
// are wrong in principle — actual height varies with all
// of the above.
if (!headerEl) return;
const publish = () => {
document.documentElement.style.setProperty(
'--app-header-h',
`${headerEl!.offsetHeight}px`
);
};
publish();
const ro = new ResizeObserver(publish);
ro.observe(headerEl);
return () => ro.disconnect();
});
// Pull fresh server preferences whenever the user changes (login,
@@ -46,7 +67,7 @@
}
</script>
<header>
<header bind:this={headerEl}>
<nav aria-label="primary">
<a class="brand" href="/">Mangalord</a>
<a class="nav-link" href="/upload">

View File

@@ -68,6 +68,33 @@
})();
let index = $state(initialIndex);
let continuousPageEls: HTMLImageElement[] = $state([]);
let chapterBarEl: HTMLElement | undefined = $state();
// Publish the bottom chapter-bar's actual measured height so the
// continuous container's `padding-bottom` exactly matches it. Same
// rationale as the layout header's measurement: the bar's height
// changes with font size, padding, browser zoom, and content
// wrap on narrow viewports — a single hard-coded number is wrong.
// Only present in continuous mode, so the effect only runs there
// and cleans up when the bar unmounts on mode toggle.
$effect(() => {
if (mode !== 'continuous' || !chapterBarEl) return;
const publish = () => {
document.documentElement.style.setProperty(
'--reader-bar-h',
`${chapterBarEl!.offsetHeight}px`
);
};
publish();
const ro = new ResizeObserver(publish);
ro.observe(chapterBarEl);
return () => {
ro.disconnect();
// Clear so other pages (single mode, /upload, etc.) don't
// inherit a stale reservation.
document.documentElement.style.removeProperty('--reader-bar-h');
};
});
// ---- Navigation ----
//
@@ -538,7 +565,11 @@
<!-- Sticky bottom bar — always visible at the foot of the viewport
in continuous mode. Slides off when full-screen is toggled. -->
<div class="chapter-bar" data-testid="chevrons-inline-bottom">
<div
class="chapter-bar"
bind:this={chapterBarEl}
data-testid="chevrons-inline-bottom"
>
<button
type="button"
class="inline-btn"