fix(ui/ux): keep the import search dialog inside the viewport
This commit is contained in:
+13
-9
@@ -962,20 +962,24 @@ async function runQuickSearch() {
|
||||
box.innerHTML = `<p class='muted'>${EMPTY_HINTS[item.media_type]}</p>`;
|
||||
return;
|
||||
}
|
||||
// one compact row per hit: cover, title + a single meta line, action right
|
||||
box.innerHTML = results
|
||||
.map(
|
||||
(r, j) => `<div class="card">
|
||||
.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 `<div class="card">
|
||||
${r.cover_url ? `<img src="${esc(r.cover_url)}" alt="" loading="lazy">` : '<div class="nocover">?</div>'}
|
||||
<div class="card-body">
|
||||
<strong>${esc(r.title)}</strong>
|
||||
<span>${esc(r.authors)}</span>
|
||||
${r.narrator ? `<span class="muted">🎙 ${esc(r.narrator)}</span>` : ""}
|
||||
${r.series && r.media_type ? `<span class="muted">📚 ${esc(r.series)}${r.volume != null ? " #" + r.volume : ""}</span>` : ""}
|
||||
<span class="muted">${r.year ?? ""}</span>
|
||||
<div class="row"><button data-pick="${j}">Anfragen & verbinden</button></div>
|
||||
<span class="muted">${meta}</span>
|
||||
</div>
|
||||
</div>`
|
||||
)
|
||||
<button data-pick="${j}" title="Anfrage anlegen und mit diesem Eintrag verbinden">Verbinden</button>
|
||||
</div>`;
|
||||
})
|
||||
.join("");
|
||||
box.querySelectorAll("[data-pick]").forEach((btn) =>
|
||||
btn.addEventListener("click", () => pickQuickResult(results[btn.dataset.pick]))
|
||||
|
||||
+19
-14
@@ -202,21 +202,26 @@
|
||||
<label class="muted"
|
||||
>Ziel-Library <select id="quick-library"></select
|
||||
></label>
|
||||
<div id="quick-open-requests"></div>
|
||||
<div id="quick-results" class="cards"></div>
|
||||
<details id="quick-manual">
|
||||
<summary>Nicht bei Audible? Manuell anlegen</summary>
|
||||
<div class="bar wrap">
|
||||
<label>Titel <input id="quick-m-title" /></label>
|
||||
<label>Serie <input id="quick-m-series" placeholder="optional" /></label>
|
||||
<label>Folge/Band <input id="quick-m-volume" type="number" min="0" /></label>
|
||||
<div id="quick-scroll">
|
||||
<div id="quick-open-requests"></div>
|
||||
<div id="quick-results" class="cards view-list"></div>
|
||||
</div>
|
||||
<div id="quick-foot">
|
||||
<details id="quick-manual">
|
||||
<summary>Nicht bei Audible? Manuell anlegen</summary>
|
||||
<div class="quick-manual-fields">
|
||||
<label>Titel <input id="quick-m-title" /></label>
|
||||
<label>Serie <input id="quick-m-series" placeholder="optional" /></label>
|
||||
<label class="narrow"
|
||||
>Folge/Band <input id="quick-m-volume" type="number" min="0" /></label>
|
||||
</div>
|
||||
<button type="button" id="quick-m-submit">Anlegen & verbinden</button>
|
||||
</details>
|
||||
<div class="row">
|
||||
<button type="button" id="quick-close" class="secondary">
|
||||
Schließen
|
||||
</button>
|
||||
</div>
|
||||
<button type="button" id="quick-m-submit">Anlegen & verbinden</button>
|
||||
</details>
|
||||
<div class="row">
|
||||
<button type="button" id="quick-close" class="secondary">
|
||||
Schließen
|
||||
</button>
|
||||
</div>
|
||||
</dialog>
|
||||
</section>
|
||||
|
||||
+21
-1
@@ -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; }
|
||||
|
||||
Reference in New Issue
Block a user