From 714a435e2d8027d517360df018d8db142d0f94f3 Mon Sep 17 00:00:00 2001 From: Steppenstreuner Date: Sat, 29 Aug 2026 04:55:08 +0200 Subject: [PATCH] fix(ui/ux): keep the import search dialog inside the viewport --- static/app.js | 22 +++++++++++++--------- static/index.html | 33 +++++++++++++++++++-------------- static/style.css | 22 +++++++++++++++++++++- 3 files changed, 53 insertions(+), 24 deletions(-) diff --git a/static/app.js b/static/app.js index b1adb40..44e2986 100644 --- a/static/app.js +++ b/static/app.js @@ -962,20 +962,24 @@ async function runQuickSearch() { box.innerHTML = `

${EMPTY_HINTS[item.media_type]}

`; return; } + // one compact row per hit: cover, title + a single meta line, action right box.innerHTML = results - .map( - (r, j) => `
+ .map((r, j) => { + const meta = [ + r.authors, + r.narrator ? "🎙 " + r.narrator : "", + r.series ? `📚 ${r.series}${r.volume != null ? " #" + r.volume : ""}` : "", + r.year ?? "", + ].filter(Boolean).map(esc).join(" · "); + return `
${r.cover_url ? `` : '
?
'}
${esc(r.title)} - ${esc(r.authors)} - ${r.narrator ? `🎙 ${esc(r.narrator)}` : ""} - ${r.series && r.media_type ? `📚 ${esc(r.series)}${r.volume != null ? " #" + r.volume : ""}` : ""} - ${r.year ?? ""} -
+ ${meta}
-
` - ) + +
`; + }) .join(""); box.querySelectorAll("[data-pick]").forEach((btn) => btn.addEventListener("click", () => pickQuickResult(results[btn.dataset.pick])) diff --git a/static/index.html b/static/index.html index 5a85463..4f5a843 100644 --- a/static/index.html +++ b/static/index.html @@ -202,21 +202,26 @@ -
-
-
- Nicht bei Audible? Manuell anlegen -
- - - +
+
+
+
+
+
+ Nicht bei Audible? Manuell anlegen +
+ + + +
+ +
+
+
- -
-
-
diff --git a/static/style.css b/static/style.css index e122b34..2f6735d 100644 --- a/static/style.css +++ b/static/style.css @@ -105,7 +105,27 @@ dialog label { display: flex; flex-direction: column; gap: 0.2rem; margin: 0.5re .series-list input[type=checkbox] { flex: none; } .series-list .num { flex: none; min-width: 3.2em; color: var(--muted); font-variant-numeric: tabular-nums; } .series-list .gap { padding: 0.35rem 0.6rem; color: var(--muted); font-size: 0.85rem; } -#quick-results { display: flex; flex-direction: column; max-height: 50vh; overflow-y: auto; margin-top: 0.6rem; } +/* the dialog keeps head and foot in place; only the results scroll, so the + "manuell anlegen" panel stays reachable no matter how many hits came back */ +#quick-dialog { display: flex; flex-direction: column; max-height: 85vh; width: min(680px, 92vw); } +#quick-scroll { flex: 1 1 auto; min-height: 4rem; overflow-y: auto; margin-top: 0.6rem; } +#quick-results { margin: 0; } +#quick-foot { flex: none; border-top: 1px solid var(--border); margin-top: 0.6rem; padding-top: 0.6rem; } +#quick-manual > summary { cursor: pointer; color: var(--accent); font-size: 0.9rem; padding: 0.2rem 0; } +#quick-manual[open] > summary { margin-bottom: 0.3rem; } +.quick-manual-fields { display: flex; gap: 0.6rem; flex-wrap: wrap; } +.quick-manual-fields label { flex: 1 1 10rem; margin: 0.2rem 0; } +.quick-manual-fields label.narrow { flex: 0 0 6.5rem; } +.quick-manual-fields input { min-width: 0; width: 100%; } +#quick-search-form { gap: 0.5rem; } +#quick-q { flex: 1 1 auto; min-width: 0; } +#quick-file { word-break: break-word; } +/* one row per hit: cover | title + meta line | action */ +#quick-results .card { align-items: center; gap: 0.7rem; padding: 0.45rem 0.6rem; } +#quick-results .card-body { flex: 1 1 auto; gap: 0.1rem; } +#quick-results .card-body strong { line-height: 1.25; } +#quick-results .card-body .muted { font-size: 0.78rem; } +#quick-results .card > button { flex: none; } .ok { color: var(--ok); } .error { color: #e08585; } #toast { position: fixed; bottom: 1.2rem; right: 1.2rem; background: var(--accent); color: #fff; padding: 0.7rem 1.1rem; border-radius: 6px; box-shadow: 0 4px 16px rgba(0,0,0,0.4); z-index: 10; }