Make existing controls real + add robustness pass

Wire up controls that were rendered but inert, expose unused server
actions, and harden the live update path.

Controls now functional:
- File priority dropdowns (Content tab) now persist via new
  setFilePriority server action
- Context menu: Set location, Limit download/upload rate, Set share
  limit (wire setSavePath/setDownLimit/setUpLimit/setRatioLimit)
- Trackers sidebar filter actually filters (snapshot now carries
  per-torrent trackerHosts)

Robustness:
- Grid updates cells in place when row order/columns are unchanged
  (preserves text selection/scroll, no per-second listener re-bind)
- Boot retries until the server responds; SSE drops show a
  "Reconnecting" banner; failed actions/add/delete surface a toast
- Prune selection/detail for torrents that disappear
- Drop Backspace-as-delete (kept Delete)

Cleanup:
- Remove pseudo DHT/PeX/LSD names from the real-tracker host pool in
  mock data (they leaked into announce URLs and the sidebar)
- Remove dead detailTab import/export

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
ookami125 2026-06-16 21:24:20 -04:00
parent bc1be49a37
commit 0b35571565
5 changed files with 172 additions and 21 deletions

View file

@ -346,3 +346,22 @@ code.inline { background: var(--bg-3); border: 1px solid var(--line); border-rad
.ctxmenu .sub { color: var(--txt-faint); padding: 4px 12px; font-size: 10.5px; text-transform: uppercase; letter-spacing: .5px; }
.empty { display: grid; place-items: center; height: 100%; color: var(--txt-faint); }
/* toasts */
.toast-host { position: fixed; right: 16px; bottom: 36px; z-index: 300; display: flex; flex-direction: column; gap: 8px; align-items: flex-end; }
.toast {
background: var(--bg-2); border: 1px solid var(--line); border-left: 3px solid var(--accent);
border-radius: 6px; padding: 9px 14px; color: var(--txt); box-shadow: 0 8px 24px rgba(0,0,0,.4);
max-width: 360px; animation: toast-in .18s ease-out;
}
.toast.err { border-left-color: var(--err); }
.toast.ok { border-left-color: var(--ok); }
.toast.out { opacity: 0; transform: translateY(6px); transition: opacity .25s, transform .25s; }
@keyframes toast-in { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
/* connection banner */
.conn-banner {
position: fixed; top: 52px; left: 50%; transform: translateX(-50%); z-index: 300;
background: var(--warn); color: #1a1300; font-weight: 600; font-size: 12px;
padding: 6px 16px; border-radius: 14px; box-shadow: 0 6px 20px rgba(0,0,0,.4);
}