mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-08 17:06:15 -08:00
fix(ui): season list rows and both theme contexts follow the progress token
Review round 1: - Codex: season list mode drew its episode bar with --mat-sys-primary; `.episode-list-item__progress-fill` now reads --app-progress-color, with a spec (the grid mode already goes through the capsule). - Greptile: nothing pinned the token's `.dark-theme` re-declaration, so dropping it would have left every spec green while dark mode inherited the light colour. `m3-theme.spec.ts` (web) asserts the declaration in both theme contexts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
f12dfabcce
commit
ef40da23e4
4 files changed
+91
-7
No files matched your search
@@ -0,0 +1,53 @@
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { resolve } from 'node:path';
|
||||
|
||||
// A custom property that reads another one is resolved where it is declared,
|
||||
// so a token derived from a per-theme colour has to be declared again inside
|
||||
// `.dark-theme`; inherited from `html`, it would keep the light value there.
|
||||
const THEME = readFileSync(
|
||||
resolve(process.cwd(), 'apps/web/src/m3-theme.scss'),
|
||||
'utf8'
|
||||
)
|
||||
.replace(/\/\*[\s\S]*?\*\//g, '')
|
||||
.replace(/(^|\s)\/\/[^\n]*/g, '$1');
|
||||
|
||||
/** The body of the brace block that opens at `start` (an index of `{`). */
|
||||
function block(source: string, start: number): string {
|
||||
let depth = 0;
|
||||
for (let index = start; index < source.length; index++) {
|
||||
if (source[index] === '{') depth++;
|
||||
if (source[index] === '}' && --depth === 0) {
|
||||
return source.slice(start + 1, index);
|
||||
}
|
||||
}
|
||||
throw new Error('Unbalanced braces in m3-theme.scss');
|
||||
}
|
||||
|
||||
/** Light declarations (the `html` block minus `.dark-theme`) and dark ones. */
|
||||
function themeContexts(): { light: string; dark: string } {
|
||||
const darkStart = THEME.indexOf('.dark-theme {');
|
||||
const htmlStart = THEME.lastIndexOf('html {', darkStart);
|
||||
expect(darkStart).toBeGreaterThan(-1);
|
||||
expect(htmlStart).toBeGreaterThan(-1);
|
||||
|
||||
const html = block(THEME, THEME.indexOf('{', htmlStart));
|
||||
const dark = block(THEME, THEME.indexOf('{', darkStart));
|
||||
return { light: html.replace(dark, ''), dark };
|
||||
}
|
||||
|
||||
describe('m3-theme watch-progress token', () => {
|
||||
it('declares --app-progress-color from the selection colour in both themes', () => {
|
||||
const { light, dark } = themeContexts();
|
||||
const progress =
|
||||
/--app-progress-color:\s*var\(--app-selection-color\);/;
|
||||
const selection = /--app-selection-color:\s*#[0-9a-f]{6};/i;
|
||||
|
||||
for (const context of [light, dark]) {
|
||||
expect(context).toMatch(selection);
|
||||
expect(context).toMatch(progress);
|
||||
}
|
||||
expect(light.match(selection)?.[0]).not.toBe(
|
||||
dark.match(selection)?.[0]
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -531,10 +531,12 @@ A title's watch progress (its resume share, `progressPercent`) has exactly one
|
||||
colour per context, and never a literal of its own:
|
||||
|
||||
- **App chrome** — dashboard rail cards and the hero, catalog grids and season
|
||||
episodes (`app-progress-capsule`): `--app-progress-color`, declared per theme
|
||||
in `apps/web/src/m3-theme.scss` as that theme's `--app-selection-color`. The
|
||||
capsule's green from 90 % marks a finished title; it is a status, not
|
||||
progress.
|
||||
episodes (`app-progress-capsule`, and the season list rows' own fill):
|
||||
`--app-progress-color`, declared per theme in `apps/web/src/m3-theme.scss`
|
||||
as that theme's `--app-selection-color`, and declared again inside
|
||||
`.dark-theme` because a derived custom property resolves where it is
|
||||
declared. The capsule's green from 90 % marks a finished title; it is a
|
||||
status, not progress.
|
||||
- **Over video** — the dock timeline, the Up next card, the Up Next rail and
|
||||
the fullscreen episode panel: the player's fixed `--pc-progress` (accent
|
||||
blue `#4f8eff`), never an app token, because the player palette is
|
||||
@@ -550,8 +552,10 @@ colour per context, and never a literal of its own:
|
||||
live hero slides) keeps `--app-live-color`; EPG programme progress keeps the
|
||||
fill described below.
|
||||
|
||||
Specs hold the rule in each owning project: `player-progress.palette.spec.ts`
|
||||
(ui-playback), `progress-capsule.component.spec.ts` (components) and
|
||||
Specs hold the rule in each owning project: `m3-theme.spec.ts` (web: the token
|
||||
in both theme contexts), `player-progress.palette.spec.ts` (ui-playback),
|
||||
`progress-capsule.component.spec.ts` and
|
||||
`season-container.progress-colour.spec.ts` (components) and
|
||||
`dashboard-progress-colour.spec.ts` (workspace-dashboard-feature).
|
||||
|
||||
### Track
|
||||
|
||||
@@ -671,7 +671,7 @@ app-season-tabs {
|
||||
|
||||
&__progress-fill {
|
||||
height: 100%;
|
||||
background: var(--mat-sys-primary);
|
||||
background: var(--app-progress-color);
|
||||
border-radius: 2px;
|
||||
transition: width 0.3s ease;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { resolve } from 'node:path';
|
||||
|
||||
// Watch progress in app chrome reads one theme token in both season view
|
||||
// modes; the list rows draw their own fill rather than the grid's capsule
|
||||
// (see the UI guidelines' Progress Bars section).
|
||||
const DIR = resolve(
|
||||
process.cwd(),
|
||||
'libs/ui/components/src/lib/season-container'
|
||||
);
|
||||
|
||||
function read(file: string): string {
|
||||
return readFileSync(resolve(DIR, file), 'utf8');
|
||||
}
|
||||
|
||||
describe('season container watch-progress colour', () => {
|
||||
it('fills list rows with the app watch-progress token', () => {
|
||||
const styles = read('season-container.component.scss');
|
||||
const listItem = styles.slice(styles.indexOf('.episode-list-item {'));
|
||||
const fill = listItem.match(/&__progress-fill\s*\{([^}]*)\}/)?.[1];
|
||||
|
||||
expect(read('season-container.component.html')).toContain(
|
||||
'class="episode-list-item__progress-fill"'
|
||||
);
|
||||
expect(fill).toMatch(/background:\s*var\(--app-progress-color\);/);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user