mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-16 06:06:18 -08:00
* style(ui): every remaining dialog onto the shared dialog shell Sixteen dialogs move onto app-dialog-shell, so every dialog shares one frame: the header with its icon tile, heading, subtitle and close button, the body, and a footer with the dismiss first and the main action last. Settings unsaved changes and delete all, the server migration prompt, the external player notice, source cleanup, the group, category, lock and EPG mapping pickers, playlist details, both account info dialogs, channel details, downloaded episodes, episode info, the trailer, release notes and the parental lock PIN. A hero dialog keeps its stats band as the body's first block, edge to edge, with its title in the shell's header and its status pills in the header's end slot; a media dialog does the same with its frame or still. Widths come from dialogSize() at every opener; the account dialogs and the trailer keep their wider explicit widths. The command palette, the programme dialog and the EPG import panel stay as they are, by design. Specs that pinned the old literal widths at the openers now expect the preset values; the delete-all spec counts the footer's buttons, since the shell adds its header close. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix(ui): let a picker's list own the scrolling; keep cleanup's lock on close A child of the dialog shell's body cannot size itself from the body's height: a flex item's height is indefinite for percentages, so the list wrappers' height: 100% never resolved. With eighty groups the wrapper grew to its content, the whole body scrolled and the search box and bulk actions scrolled away. The shell gains bodyLayout="column", which lays the body out as a flex column; the three list pickers set it, their wrapper flexes to the height left under the cap and only the list scrolls. An Electron E2E imports eighty groups and checks that the body holds still, the list scrolls and the search box stays in view; it fails without the fix. The source cleanup dialog hides the shell's header close while it deletes: mat-dialog-close ignores disableClose, so the header close would have ended the batch and hidden its results. Stop stays the one way out. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix(ui): close the shell with no result; hide its close while a save runs A bare mat-dialog-close attribute closes with an empty string, not with undefined as Escape and the backdrop do. The parental lock services take any string for an entered PIN, so the shell's header close would have opened the lock on a bare dismissal, and the groups view would have taken the empty string for a saved result. The header close now binds undefined. The shell's spec asserts it, and the PIN dialog's spec that its header close cancels. The Xtream category and Stalker lock pickers hide the header close while they save: mat-dialog-close ignores disableClose, and a dismissal mid-save would have skipped the caller's reload while the writes still finished. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix(ui): wrap an unbreakable heading in the dialog shell A shell heading often carries provider text: an episode's file name, a channel name with no spaces. Such a string has no break opportunity, and the episode title lost the overflow-wrap it had before the shell, so it ran under the header's close button. The shell's heading and subtitle now wrap anywhere. An Electron E2E opens channel details for an underscore-only channel name in a narrow window and checks the title wraps and stays clear of the close button; it fails without the rule. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * refactor(ui): one opener for the channel details dialog Five channel lists opened the channel details dialog with the same size preset repeated at each site. The dialog now owns its settings in a static open(dialog, channel), as the EPG mapping and PIN dialogs do, so a later size change cannot miss a caller. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix(ui): keep the hero bands' grid stretched in a narrow window Removing the padding rules the shell made redundant left the hero selector grouped with the status pills' left-alignment rule in both hero stylesheets. On a grid, justify-content: flex-start stops the implicit column from stretching, so under 720px the account stats shrank to their content, 157px in a 355px band. Only the status pills re-align now. An Electron E2E opens the account dialog in a narrow window and checks the stats fill the band; it fails without the fix. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * refactor(settings): one opener for the release notes dialog The notification card and the settings facade opened the release notes dialog with the same size, autofocus and restore settings repeated at each site. The dialog now owns them in a static open(dialog, data); a caller picks only which release to show. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * test(ui): measure the hero band against the body's client width The narrow-window hero test compared the band to the body's bounding width, which on Linux includes the 15px scrollbar that macOS overlays, so it failed on the ubuntu runners while passing on a Mac. The client width leaves the scrollbar out on both. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * test(ui): keep the fraction when measuring the hero band's body clientWidth is an integer; against the band's fractional bounding width it left a 1.4px difference on a Mac. The body's bounding width minus its integer scrollbar width keeps the fraction and still leaves out the classic scrollbar the CI runners draw. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix(ui): keep the dialog shell's header close reachable when the dialog scrolls Under 600px of height the shell let Material's surface scroll every dialog whole, so the header close scrolled away; a dialog without a footer (account info, downloaded episodes, keyboard shortcuts) then had no in-dialog dismissal left in view. Such a dialog now keeps its body as the scroll owner, with the header in place; the cap still comes off for a dialog with a footer, whose stacked actions would squeeze the body. An opener's `maxHeight` tighter than the shell's own cap (the account dialogs' 90vh) also left the surface scrolling: the dialog component between the surface and the shell is a block that never shrinks below its content. Those ancestors are now shrinkable flex columns, so the shell sizes from the surface and only the body scrolls. The dialog-shell E2E opens the account dialog in a 520px-tall window, scrolls both candidate owners and checks that the body took the scroll and the close button stayed inside the surface; it fails without either rule. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix(ui): hide the PIN dialog's header close while a verification is pending The dialog disables its field, Cancel and Submit while the caller's `verify` runs, but the shell's header close stayed enabled: a dismissal then handed the caller a cancel, and an accepted PIN could no longer be delivered. The close now follows Cancel, as the category and lock pickers' does while they save. The spec holds a verification open and checks that the close is gone and the accepted PIN still arrives. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>