mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-15 05:36:17 -08:00
* fix(ui): skeletons that match the M3U header and dashboard rails Loading skeletons now take their boxes from the code that draws the content, so the content lands where the skeleton was. - M3U channel list: the loading state's headers, divider, groups rail and first row share `styles/_channel-list-layout.scss` with the All channels, context and groups views. The All channels list moved down by 19px when a playlist loaded; the group header was 79px against the real 69px (the panel header's 52px minimum plus the padding that `.sidebar .sidebar-header` gives it, now one mixin both include). Group rows start at the list's top-left like the virtual-scroll rows. - Dashboard rails: `lib-dashboard-rail-skeleton` replaces six copies of the skeleton markup and takes the rail's layout and aspect ratio (channel cards for live favorites, 16:9 for sources, posters with a title and a meta line otherwise). Its header, track, cards and text line boxes come from `_dashboard-rail-geometry.scss`, which the rail itself now uses. The skeleton was 328px against the 337.8px poster rail and a 2:3 poster in front of the 83.5px channel cards. - One shimmer in `libs/ui/styles/_skeleton-shimmer.scss`, mixed from `--app-on-surface`: the rail sweep between the widget surfaces was 1.04:1 on the light theme. The dashboard hero and the detail skeletons (through a forward) use it too. - Electron E2E `skeleton-geometry.e2e.ts` holds the IPC channel behind each loading state, compares skeleton and content boxes to 0.5px at 1280x700 and caps the dashboard layout-shift score at 0.01. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * fix(dashboard): keep rail heights when a skeleton stands for a label-less or live rail Review follow-up (Greptile, local): - Rails that replace a skeleton (Continue Watching, sources, Xtream recently added, TMDB) keep an empty meta line under cards without labels (`reserveMetaLine`), as the skeleton always draws one; a Continue Watching rail of movies with no known duration came in shorter. - The recent-content skeleton follows the recent rail it waits for: posters while Continue Watching is still loading with no cards, channel cards otherwise. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
60 lines
1.7 KiB
SCSS
60 lines
1.7 KiB
SCSS
// The one shimmer recipe for loading placeholders: the dashboard hero and
|
|
// rails, and the detail-page hero, actions and episode rows.
|
|
//
|
|
// A block is a flat fill a step above whatever surface it sits on, with a
|
|
// moving highlight a step higher. Both are mixed from the theme's on-surface
|
|
// ink rather than from surface tokens: the light theme's widget and header
|
|
// surfaces are nearly the same white (1.04:1), so a sweep between them was
|
|
// invisible on the light page. On the page background the ink mix gives the
|
|
// base about 1.2:1 in both themes and the highlight 1.18:1 (light) and
|
|
// 1.26:1 (dark) over the base. Under `prefers-reduced-motion` the highlight
|
|
// stays put.
|
|
//
|
|
// Include `keyframes` once in a component stylesheet that uses `block`:
|
|
// Angular scopes keyframes to the component that declares them.
|
|
|
|
$duration: 1.4s;
|
|
$base-ink: 8%;
|
|
$highlight-ink: 16%;
|
|
|
|
@mixin keyframes {
|
|
@keyframes skeleton-shimmer {
|
|
from {
|
|
background-position: 100% 0;
|
|
}
|
|
|
|
to {
|
|
background-position: -100% 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
@mixin block($radius: 4px) {
|
|
--skeleton-base: color-mix(
|
|
in srgb,
|
|
var(--app-on-surface) #{$base-ink},
|
|
transparent
|
|
);
|
|
--skeleton-highlight: color-mix(
|
|
in srgb,
|
|
var(--app-on-surface) #{$highlight-ink},
|
|
transparent
|
|
);
|
|
|
|
display: block;
|
|
border-radius: $radius;
|
|
background: linear-gradient(
|
|
90deg,
|
|
var(--skeleton-base) 25%,
|
|
var(--skeleton-highlight) 50%,
|
|
var(--skeleton-base) 75%
|
|
);
|
|
background-size: 200% 100%;
|
|
animation: skeleton-shimmer $duration ease-in-out infinite;
|
|
|
|
@media (prefers-reduced-motion: reduce) {
|
|
animation: none;
|
|
background: var(--skeleton-base);
|
|
}
|
|
}
|