mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-09 01:16:15 -08:00
perf/devtools-dev-only
1
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
eb96b4c9f2 |
feat(website): turn the screenshot showcase into a channel switcher (#1540)
* feat(website): turn the screenshot showcase into a channel switcher Second landing redesign PR. "See it in action" was a tab strip in a dashed frame showing one screenshot inside a drawn window chrome that duplicated the chrome already in the shot. It is now a channel list: number, screen name and one line about what the screen is for on the left, a single frame on the right, and a caption linking to the matching feature page. - Channels advance on their own with a progress hairline under the active row; hovering, focusing or scrolling the block out of view pauses it and `prefers-reduced-motion` disables autoplay entirely. - A brief on-screen "CH 03" badge confirms every switch. - Arrow keys, Home and End move between channels; the list is a proper vertical tablist with roving tabindex, panels carry `aria-hidden`. - Six screens: Dashboard, Live TV, Program guide, Movies & series, Downloads, Settings. Same files from `public/screenshots`; the add-playlist shot is replaced by the movie detail and the download manager. - On phones the screen comes first and the list follows. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * test(website): cover the channel switcher, keep focus pausing after mouseleave Hover and focus now pause autoplay independently: clicking a channel focused it, but moving the pointer away resumed the timer and seven seconds later the selection moved under a still-focused tab. New `website-screenshot-showcase.test.mjs` (in the website test target): a structural half over the built HTML (vertical tablist, roving tabindex, one aria-hidden panel per channel) and a browser half that serves the build and drives it in Chromium — autoplay advances, hover pauses, click + mouseleave keeps the pause while focused, arrow/Home/End keys move selection, focus, panel, caption and badge together, blur resumes, and `prefers-reduced-motion` disables autoplay. The browser half falls back to the system Chrome channel and skips when no Chromium exists, so the structural checks run everywhere. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * perf(website): lazy-load every showcase screenshot The block sits below the hero and the feature grid, so an eager first frame only competed with above-the-fold assets for visitors who never scroll to it. Native look-ahead loading brings it in well before the switcher is on screen. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * test(website): share the browser harness, fail in CI without Chromium `website-browser-support.mjs` owns the loopback static server and the Chromium launcher for the website browser tests. The server resolves every request against the build root and answers 404 for anything that escapes it (CodeQL js/path-injection on the previous inline copy). The launcher tries the Playwright download, then the system Chrome and Chromium channels; when none launches it returns null locally so the structural half still runs, and throws under `CI` so the interaction assertions can never turn into a silent skip on the runner. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * perf(website): defer inactive showcase frames, document the browser tests The six frames are stacked with opacity, so native lazy loading treated all of them as near-viewport and fetched every screenshot at once. Only the first frame now ships with a `src`; the switcher assigns it from `data-src` when a channel is shown and preloads the one after it, so at most two frames are ever in flight. The showcase test asserts the markup and the runtime behaviour. The website README now describes the browser-dependent suites, the shared harness, and the skip-locally / fail-in-CI rule. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * docs(website): describe only the suite this PR adds Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix(website): resume the switcher from where it paused, keep DOM order on phones The dwell clock now stops while the switcher is hovered or focused and the pause time is added back on resume, so the progress hairline continues from its frozen position instead of snapping to zero and granting a fresh seven seconds. The test asserts the resume. On phones the list stays before the screen in the DOM and on screen (tabs before their panels, focus order equals reading order); it hides the per-channel descriptions and the keyboard hint there so the screen stays close instead of being reordered with `order-first`. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix(website): never crop a showcase frame The screen box stretches to the channel list's row height, and with `object-cover` a wide screenshot lost its right side just above the `lg` breakpoint. Frames are now contained on a dark stage (a letterbox, as on a TV), and the per-channel descriptions are hidden between `lg` and `xl` so the row stays close to the frame's own height. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix(website): pause the switcher dwell while offscreen instead of resetting it Leaving the viewport is now a pause like hover and focus: the frame loop stops, the progress hairline keeps its width, and the clock resumes from the same mark when the block scrolls back in. Only a channel change resets the dwell. The interaction test scrolls away and back to assert it. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * perf(website): no next-frame prefetch when reduced motion disables autoplay Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * feat(website): persistent pause control for the channel switcher Hover and focus only pause while they last, which is no use to touch or screen-reader visitors, so the list footer now carries a Pause/Resume toggle (`aria-pressed`, full `aria-label`) that keeps autoplay stopped until pressed again (WCAG 2.2.2). It is removed under reduced motion, where nothing advances. The interaction test now waits for the seven-second rollover and checks that tab, panel, caption, badge and the preloaded frame all move to channel 02, and that the toggle holds through mouseleave and blur. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix(website): keep the tablist to its tabs, no successor prefetch when autoplay is off The channel list's header and the Pause/Resume control sat inside the `role="tablist"` container; the tablist now wraps only the six tabs so assistive technology reads the toggle as an ordinary button beside the list. `show()` preloads the next frame only while autoplay can reach it (neither reduced motion nor the toggle has stopped it). Tests assert both. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix(website): preload the successor when auto-advance resumes A channel picked while the switcher is paused deliberately skips its successor; resuming now fetches that frame so the next automatic switch does not land on a blank screen. The interaction test covers pause → manual selection → resume. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix(website): Resume restarts autoplay at once; same-channel progress in the test The transient hover/focus pauses now watch only the channel list and the screen. The footer with the Pause/Resume control is not one of those regions, so after pressing Resume — with the pointer and the focus still on the button — autoplay visibly restarts instead of waiting for the visitor to leave the whole block. The interaction test compares progress within one channel (a paused Movies before and after Resume) rather than across channels, which could fail on a slow runner, and asserts that autoplay runs while the toggle keeps focus and hover. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * perf(website): one scheduler for the switcher, no frames while paused Every pause reason (hover, focus, the toggle, leaving the viewport) now goes through a single `sync()`: the animation-frame loop runs only while the block is visible and nothing pauses it, and is cancelled otherwise, so a switcher left paused schedules no frames at all. The dwell clock still resumes from where it froze, and the successor frame is fetched only when the loop actually starts — so scrolling away and back under a persistent pause loads nothing. Tests count scheduled frames while paused and cover pause → manual selection → offscreen → return. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix(website): a channel picked while paused gets its full dwell after Resume `show()` reset the pause mark, so the time a visitor spent paused after picking a channel counted toward that channel's dwell and Resume could advance immediately. When the loop is not running the new channel now starts out paused at that moment. The interaction test asserts the progress is still near zero right after Resume. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix(website): follow reduced-motion changes and hidden tabs in the switcher The reduced-motion preference is read from a live MediaQueryList: when it changes while the page is open the scheduler stops or restarts and the Pause/Resume control is hidden or shown (it is hidden, not removed, for that reason). A hidden document counts as a pause too — background tabs throttle animation frames while the clock keeps running, so without it the first frame back would skip a channel. The interaction test flips both at runtime. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix(website): plain action button for the switcher pause, no manual animations under reduced motion `aria-pressed` on a button whose name changes between "Pause auto-advance" and "Resume auto-advance" announced the wrong thing; the control is now an ordinary action button whose name says what pressing it does next. The OSD slide and the panel fade get `motion-reduce:transition-none`, so a manual selection under reduced motion moves nothing. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com> |