From 12b6dc4dd3e009f2e844d87181800aa12d07a3a6 Mon Sep 17 00:00:00 2001 From: Christophe Besson Date: Wed, 2 Sep 2026 03:13:53 +0200 Subject: fix(hub): steady the show detail modal, and give a series its director MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Opening a different season of the same show moved everything under the synopsis, which is where the season control and the episode list are, so the thing just clicked was no longer under the pointer. - The synopsis is exactly three lines for a multi-season show, with a "read more" link floated into the third line box (-webkit-line-clamp only ever puts its ellipsis at the end of the last line and leaves no room after it). Clamped from above and pinned from below to the same number: a constant, not a range — a season summary runs two lines and the next one twelve, and a band still reads as a jump. Whether three lines is all of it depends on the modal's width, so it is measured in the browser and re-measured on a resize. - The cast is clamped to two lines. - SeasonMenu replaces SeasonTabs: the tab row scrolled sideways once a show had more seasons than fit, which is close to unusable on a phone. One trigger reading "Season 5 · 1997" and a menu of every season with its episode count, one row high whatever the season count. - media_meta_resp.director was filled from the credits crew's job == "Director", a movie shape. TMDB's aggregate tv_credits crew is routinely empty and never carries that job, so every show answered null and the modal dropped the line. It now comes from created_by on the show details. Cached show metadata keeps its null until TMDB_META_TTL_SECS expires or an operator re-matches. The facts line is joined rather than concatenated (a title with no rating used to open with " · ") and carries the show's own year next to the director; the selected season's air year moved onto the picker. test_video_detail_measured.py asserts rectangles through layout_probe.py, not declarations: the picker's offset inside its own modal body is the same pixel either way, the synopsis and cast heights, where the read-more link lands, and the open menu at 320 px. Each measured block sits in a whole-pixel-height container, or two identical layouts an eighth of a pixel apart round to tops one pixel apart. test_tmdb_show_director.py covers the credit. docs/mediacenter.md §10.4. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_014UtzVrzM7e2tG9fSpkR9ML --- .../meshbay-node/src/meshbay_node/transport/webrtc_server.py | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'packages/meshbay-node/src/meshbay_node') diff --git a/packages/meshbay-node/src/meshbay_node/transport/webrtc_server.py b/packages/meshbay-node/src/meshbay_node/transport/webrtc_server.py index 64ba75c..1f069e7 100644 --- a/packages/meshbay-node/src/meshbay_node/transport/webrtc_server.py +++ b/packages/meshbay-node/src/meshbay_node/transport/webrtc_server.py @@ -3404,6 +3404,16 @@ class WebRTCPeerSession: director = next( (c.get("name") for c in (credits or {}).get("crew", []) if c.get("job") == "Director"), None) + else: + # A series has no single director, and `tv_credits`' crew is the + # aggregate one — routinely empty, and never a "Director" job. + # TMDB models the equivalent credit as `created_by` on the show + # itself, which is what its own page shows; several creators are + # ordinary, and they read as one line in the detail modal. + director = ", ".join( + name for name in + (c.get("name") for c in details.get("created_by") or []) + if name) or None runtime = details.get("runtime") if runtime is None and media_type == "tv": episode_run_times = details.get("episode_run_time") or [] -- cgit v1.2.3