4gray and Claude Opus 4.7
bb6d1427fa
feat(dashboard): compact channel cards with lazy-loaded current EPG
...
The "Live now on your favorites" rail no longer reuses the 2:3 poster
card built for movies. TV station logos are typically 100–256px square,
so inflating them into portrait cards wastes most of the height and
hides the data users actually care about (what's airing right now).
Introduce a `layout: 'cover' | 'channel'` input on DashboardRailComponent.
The new channel layout is a wider, much shorter card: logo + channel
name + current program title + LIVE chip + progress bar + time range.
Current programs are lazy-loaded via EpgService.getCurrentProgramsForChannels
(already batched + 60s-cached at the service), keyed by the recent item's
display name — works out of the box for M3U sources whose XMLTV channels
resolve through the tvg-id → tvg-name → name fallback chain. A 30s tick
keeps the progress bar fresh between program boundaries.
The card renders gracefully without EPG enrichment (idle progress bar,
no program title) so Xtream/Stalker live items without an XMLTV side
channel still look fine.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-19 00:34:43 +02:00
4gray and Claude Opus 4.7
a048c18763
refactor(dashboard): split recently-watched into VOD and live rails
...
Per UX audit: a single "Recently Watched" rail mixed channels and VOD
into a grid where the two card formats fought for visual attention.
Split it into two rails — "Continue watching" (movies/series) and
"Live now on your favorites" (live channels) — so each surface uses
the card format that fits its content type.
Also relabel the rail header link from "Manage all" to "See all {N}"
when the total count exceeds what's rendered, so the user knows how
many items the link expands into; falls back to "See all" otherwise.
i18n: three new keys (LIVE_RECENT, SEE_ALL, SEE_ALL_COUNT) translated
across all 17 locales by per-locale agents reusing each file's existing
glossary; placeholder integrity verified.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-19 00:18:46 +02:00
4gray and Claude Opus 4.7
a27a29fcf2
refactor(ui): unify primary color to blue across all surfaces
...
Swap M3 primary palette from violet to azure so checkboxes, radio
buttons, raised CTAs, and active states read as the same blue used by
the rail selection token. Cascading template + SCSS updates align the
remaining hand-rolled surfaces (Add Playlist dialog, VOD play button,
radio player, multi-EPG, empty-state CTAs) with the unified system.
LIVE stays red (broadcast role), cyan stays on EPG "now" indicator,
green stays on completed-download — semantic colors keep their meaning;
only the indiscriminate accent uses get folded into the blue primary.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com >
2026-05-19 00:12:34 +02:00
4gray
20e7322353
refactor(portal): split collection data access ( #953 )
2026-05-19 00:01:34 +02:00
4gray
118d4fce32
fix(playback): improve inline stream diagnostics ( #952 )
...
* fix(playback): improve inline stream diagnostics
* fix(playback): preserve headers in diagnostics wrapper
* fix(portal): align unified live player imports
2026-05-18 23:59:20 +02:00
4gray
32cc0b74e8
feat: add self-hosted PWA backend runtime ( #944 )
...
* feat(web-backend): add self-hosted proxy app
* feat(web): enable runtime PWA configuration
* test(web-e2e): cover self-hosted backend proxy
* test(web-e2e): clean self-hosted lint warnings
* fix(web-backend): validate proxied provider URLs
* fix(web-backend): proxy through registered provider targets
* fix(web-backend): document CodeQL SSRF validation boundary
* test(web-e2e): mock provider target registration
* fix(web): address self-hosted review feedback
2026-05-16 00:10:03 +02:00
4gray
5e5a89a300
refactor(ui): remove dead portal code and share detail styles ( #946 )
2026-05-16 00:09:29 +02:00
4gray
0ec9b29993
fix(playlist): preserve auto-refresh on manual refresh ( #947 )
...
* fix(playlist): preserve auto-refresh on manual refresh
* test(playlist): cover disabled auto-refresh preservation
2026-05-15 23:10:35 +02:00
4gray
272e0e772e
fix(stalker): preserve explicit portal identity ( #941 )
2026-05-15 18:34:49 +02:00
4gray
2d5c4fa4f9
chore: tighten validation and runtime logging
...
* chore: tighten validation and runtime logging
* fix(i18n): localize new settings labels
2026-05-15 17:43:42 +02:00
4gray
d24c77a143
chore(nx): enforce scoped workspace boundaries ( #942 )
2026-05-15 09:59:06 +02:00
4gray
8f79b25f52
fix(playback): treat portal mpeg-ts vod as non-live
2026-05-15 01:07:23 +02:00
4gray
4a4334cb64
feat(playback): improve browser-player diagnostics ( #939 )
...
* feat(playback): diagnose browser stream access errors
Entire-Checkpoint: f957cd9849e0
* feat(playback): expose browser-player diagnostic details
Entire-Checkpoint: f957cd9849e0
* fix(playback): keep media path extensions authoritative
Entire-Checkpoint: f957cd9849e0
* fix(playback): tighten browser access diagnostics
Entire-Checkpoint: f957cd9849e0
* fix(playback): align diagnostic followups
Entire-Checkpoint: f957cd9849e0
* fix(playback): narrow declared stream metadata
Entire-Checkpoint: f957cd9849e0
* fix(playback): preserve explicit extension overrides
Entire-Checkpoint: f957cd9849e0
* fix(playback): keep mpeg-ts out of unsupported containers
Entire-Checkpoint: f957cd9849e0
* refactor(playback): split diagnostics utilities
Entire-Checkpoint: f957cd9849e0
* fix(playback): treat mpegts early eof as media fallback
Entire-Checkpoint: f957cd9849e0
2026-05-15 00:55:23 +02:00
4gray
8232a86a1e
feat(portal): add category sorting controls ( #940 )
...
* feat(portal): add category sort modes
* fix(portal): address category sort review feedback
2026-05-15 00:28:32 +02:00
4gray
2a5b1d1da7
fix(xtream): keep live playback on category switch ( #936 )
2026-05-14 20:52:02 +02:00
4gray
db08ec2958
fix(playback): keep diagnostics within player viewport
...
Entire-Checkpoint: f957cd9849e0
2026-05-14 20:49:40 +02:00
4gray
a40d5447e7
feat(settings): add external player arguments ( #932 )
...
* feat(settings): add external player arguments
* fix(settings): address external player argument review
* fix(settings): require external player argument settings
* feat(settings): add external player argument placeholders
Closes https://github.com/4gray/iptvnator/issues/835
2026-05-14 11:04:01 +02:00
Toni Oriol and 4gray
2f9aef1578
fix(playback): handle IPTV proxy URLs without file extensions ( #934 )
...
* fix(playback): handle IPTV proxy URLs without file extensions
IPTV proxy servers (Acexy, Xtream Codes, etc.) use query-string URLs
like `https://proxy.example.com/ace/getstream?infohash=abc ` that return
raw MPEG-TS streams without a file extension in the path.
`getExtensionFromUrl()` was returning garbage for these URLs (e.g.
`com/ace/getstream` from splitting on dots across path segments). All
four player backends then misrouted the stream — typically to HLS.js
which failed because the response is raw MPEG-TS, not an HLS manifest.
Root fix: rewrite `getExtensionFromUrl()` to extract the extension from
the last path segment only, returning `undefined` when there is no
dot-separated extension.
Player adjustments: treat `undefined` extension as MPEG-TS (the most
common format for live IPTV proxy streams) across all four backends
(HTML5, ArtPlayer, VideoJs, web-player-view).
* test(m3u-utils): cover URL extension parsing
* fix(playback): preserve query-declared stream extensions
---------
Co-authored-by: 4gray <serega05@gmail.com >
2026-05-14 00:13:08 +02:00
4gray
9ae984ad7f
feat(portal): add series quick start CTA ( #925 )
...
* feat(portal): add series quick start CTA
Entire-Checkpoint: f957cd9849e0
* fix(portal): address series quick start review
Entire-Checkpoint: f957cd9849e0
* docs: use repo-relative quick start path
Entire-Checkpoint: f957cd9849e0
2026-05-12 23:45:02 +02:00
4gray
e7db920543
fix(settings): clarify external player path hints ( #929 )
...
* fix(settings): clarify external player path hints
* fix(settings): gate external player hints to desktop
2026-05-12 19:49:14 +02:00
4gray
a33d506266
fix(stalker): play radio collections with audio layout ( #930 )
...
* fix(stalker): play radio collections with audio layout
* fix(stalker): address radio review feedback
2026-05-12 19:48:38 +02:00
4gray
6ae1251ad1
fix(playback): use inline player for collection VOD ( #928 )
...
* feat(portal): add series quick start CTA
Entire-Checkpoint: f957cd9849e0
* fix(playback): use inline player for collection vod
* fix(playback): address inline collection review feedback
* fix(playback): ignore stale vod position loads
2026-05-12 19:26:40 +02:00
4gray
ce0e61a92d
docs: publish embedded MPV macOS blog post
2026-05-11 20:44:01 +02:00
4gray
f922dd2d00
style: adjust size and remove unnecessary styles for action buttons
...
Entire-Checkpoint: f957cd9849e0
2026-05-10 23:37:15 +02:00
4gray
a2ecdc358f
fix(electron): resolve macOS external player app paths ( #924 )
...
* fix(electron): resolve macOS external player app paths
* fix(electron): make macos player executable mapping explicit
2026-05-10 23:36:35 +02:00
dependabot[bot]
67b0e8b0b6
chore(deps): bump axios from 1.15.0 to 1.15.2
...
Bumps [axios](https://github.com/axios/axios ) from 1.15.0 to 1.15.2.
- [Release notes](https://github.com/axios/axios/releases )
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md )
- [Commits](https://github.com/axios/axios/compare/v1.15.0...v1.15.2 )
---
updated-dependencies:
- dependency-name: axios
dependency-version: 1.15.2
dependency-type: direct:production
...
Signed-off-by: dependabot[bot] <support@github.com >
2026-05-10 20:03:21 +00:00
4gray
1ca291d35c
chore(nx): update Nx to 22.7.1 ( #923 )
...
* chore(nx): update Nx to 22.7.1
Entire-Checkpoint: f957cd9849e0
* fix(ci): patch nx-electron package metadata copy
Entire-Checkpoint: f957cd9849e0
* fix(packaging): preserve electron package metadata
Entire-Checkpoint: f957cd9849e0
* fix(packaging): address package verifier review
Entire-Checkpoint: f957cd9849e0
2026-05-10 22:01:25 +02:00
4gray
6305dcf00e
Add browser playback diagnostics and MPV/VLC fallback ( #921 )
...
* feat(playback): add codec diagnostics fallback
Entire-Checkpoint: f957cd9849e0
* fix(playback): address diagnostics review feedback
Entire-Checkpoint: f957cd9849e0
* fix(playback): ignore recoverable hls diagnostics
Entire-Checkpoint: f957cd9849e0
* fix(playback): polish diagnostic fallback banner
Entire-Checkpoint: f957cd9849e0
* fix(xtream): preserve live category search scope
Entire-Checkpoint: f957cd9849e0
2026-05-10 17:27:54 +02:00
4gray
5f4cf01467
fix(playback): avoid redundant VideoJS source resets ( #920 )
...
* fix(playback): avoid redundant VideoJS source resets
* fix(playback): clean up cleared VideoJS sources
* refactor(playback): use signal APIs in VideoJS player
closes #608
2026-05-10 15:32:00 +02:00
4gray
724e4b1ab3
feat(playback): add embedded mpv (macos) stream recording ( #916 )
...
* feat(playback): add embedded mpv stream recording
Entire-Checkpoint: f957cd9849e0
* fix(playback): address embedded mpv recording review
Entire-Checkpoint: f957cd9849e0
* fix(playback): track mpv recording auto-stop replies
Entire-Checkpoint: f957cd9849e0
2026-05-10 12:27:09 +02:00
4gray
935ed1b1a9
fix(lockfile): remove duplicate minimatch snapshot
2026-05-10 11:06:06 +02:00
dependabot[bot]
e94617fe83
chore(deps): bump ajv from 6.12.6 to 6.14.0 ( #783 )
...
Bumps [ajv](https://github.com/ajv-validator/ajv ) from 6.12.6 to 6.14.0.
- [Release notes](https://github.com/ajv-validator/ajv/releases )
- [Commits](https://github.com/ajv-validator/ajv/compare/v6.12.6...v6.14.0 )
---
updated-dependencies:
- dependency-name: ajv
dependency-version: 6.14.0
dependency-type: indirect
...
Signed-off-by: dependabot[bot] <support@github.com >
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-10 10:53:29 +02:00
dependabot[bot]
c84d65016a
chore(deps): bump rollup from 4.52.3 to 4.59.0 ( #796 )
...
Bumps [rollup](https://github.com/rollup/rollup ) from 4.52.3 to 4.59.0.
- [Release notes](https://github.com/rollup/rollup/releases )
- [Changelog](https://github.com/rollup/rollup/blob/master/CHANGELOG.md )
- [Commits](https://github.com/rollup/rollup/compare/v4.52.3...v4.59.0 )
---
updated-dependencies:
- dependency-name: rollup
dependency-version: 4.59.0
dependency-type: indirect
...
Signed-off-by: dependabot[bot] <support@github.com >
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-10 10:53:26 +02:00
dependabot[bot]
5d66a04d05
chore(deps): bump immutable from 5.1.4 to 5.1.5 ( #807 )
...
Bumps [immutable](https://github.com/immutable-js/immutable-js ) from 5.1.4 to 5.1.5.
- [Release notes](https://github.com/immutable-js/immutable-js/releases )
- [Changelog](https://github.com/immutable-js/immutable-js/blob/main/CHANGELOG.md )
- [Commits](https://github.com/immutable-js/immutable-js/compare/v5.1.4...v5.1.5 )
---
updated-dependencies:
- dependency-name: immutable
dependency-version: 5.1.5
dependency-type: indirect
...
Signed-off-by: dependabot[bot] <support@github.com >
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-10 10:53:23 +02:00
dependabot[bot]
a4fb202b62
chore(deps): bump svgo from 3.3.2 to 3.3.3 ( #808 )
...
Bumps [svgo](https://github.com/svg/svgo ) from 3.3.2 to 3.3.3.
- [Release notes](https://github.com/svg/svgo/releases )
- [Commits](https://github.com/svg/svgo/compare/v3.3.2...v3.3.3 )
---
updated-dependencies:
- dependency-name: svgo
dependency-version: 3.3.3
dependency-type: indirect
...
Signed-off-by: dependabot[bot] <support@github.com >
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-10 10:53:20 +02:00
dependabot[bot]
62f904ec86
chore(deps): bump express-rate-limit from 8.2.1 to 8.3.0 ( #810 )
...
Bumps [express-rate-limit](https://github.com/express-rate-limit/express-rate-limit ) from 8.2.1 to 8.3.0.
- [Release notes](https://github.com/express-rate-limit/express-rate-limit/releases )
- [Commits](https://github.com/express-rate-limit/express-rate-limit/compare/v8.2.1...v8.3.0 )
---
updated-dependencies:
- dependency-name: express-rate-limit
dependency-version: 8.3.0
dependency-type: indirect
...
Signed-off-by: dependabot[bot] <support@github.com >
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-10 10:53:17 +02:00
dependabot[bot]
23c74d6313
chore(deps): bump devalue from 5.6.2 to 5.6.4 ( #818 )
...
Bumps [devalue](https://github.com/sveltejs/devalue ) from 5.6.2 to 5.6.4.
- [Release notes](https://github.com/sveltejs/devalue/releases )
- [Changelog](https://github.com/sveltejs/devalue/blob/main/CHANGELOG.md )
- [Commits](https://github.com/sveltejs/devalue/compare/v5.6.2...v5.6.4 )
---
updated-dependencies:
- dependency-name: devalue
dependency-version: 5.6.4
dependency-type: indirect
...
Signed-off-by: dependabot[bot] <support@github.com >
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-10 10:53:14 +02:00
dependabot[bot]
d6417c699d
chore(deps): bump flatted from 3.3.3 to 3.4.2 ( #827 )
...
Bumps [flatted](https://github.com/WebReflection/flatted ) from 3.3.3 to 3.4.2.
- [Commits](https://github.com/WebReflection/flatted/compare/v3.3.3...v3.4.2 )
---
updated-dependencies:
- dependency-name: flatted
dependency-version: 3.4.2
dependency-type: indirect
...
Signed-off-by: dependabot[bot] <support@github.com >
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-10 10:53:10 +02:00
dependabot[bot]
1ea40216ce
build(deps): bump fast-uri from 3.1.0 to 3.1.2 ( #912 )
...
Bumps [fast-uri](https://github.com/fastify/fast-uri ) from 3.1.0 to 3.1.2.
- [Release notes](https://github.com/fastify/fast-uri/releases )
- [Commits](https://github.com/fastify/fast-uri/compare/v3.1.0...v3.1.2 )
---
updated-dependencies:
- dependency-name: fast-uri
dependency-version: 3.1.2
dependency-type: indirect
...
Signed-off-by: dependabot[bot] <support@github.com >
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-10 10:52:44 +02:00
dependabot[bot]
7da715c37f
build(deps): bump @babel/plugin-transform-modules-systemjs ( #915 )
...
Bumps [@babel/plugin-transform-modules-systemjs](https://github.com/babel/babel/tree/HEAD/packages/babel-plugin-transform-modules-systemjs ) from 7.28.5 to 7.29.4.
- [Release notes](https://github.com/babel/babel/releases )
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md )
- [Commits](https://github.com/babel/babel/commits/v7.29.4/packages/babel-plugin-transform-modules-systemjs )
---
updated-dependencies:
- dependency-name: "@babel/plugin-transform-modules-systemjs"
dependency-version: 7.29.4
dependency-type: indirect
...
Signed-off-by: dependabot[bot] <support@github.com >
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-05-10 10:52:23 +02:00
4gray
eb0da5951f
Merge pull request #914 from 4gray/codex/fix-linux-window-identity
...
fix(linux): align packaged app identity
2026-05-09 20:11:07 +02:00
4gray
48463953db
test(packaging): harden package identity regression
...
Entire-Checkpoint: f957cd9849e0
2026-05-09 19:28:35 +02:00
4gray
4a755b43ec
Merge pull request #885 from sapireli/fix/xtream-catchup-server-timezone
...
fix(xtream): use server timezone when constructing catchup/timeshift URLs
2026-05-09 19:28:16 +02:00
4gray
aead89e3e6
fix(xtream): keep category management available
...
Fixes #913
2026-05-09 18:34:57 +02:00
4gray
6cdd02f010
fix(linux): align packaged app identity
...
Entire-Checkpoint: f957cd9849e0
2026-05-09 16:22:37 +02:00
4gray
8b3b1c9bb7
chore: merge master into xtream timezone fix
2026-05-09 16:15:01 +02:00
4gray
134b5fb779
Merge pull request #911 from 4gray/codex/stalker-radio
...
feat(stalker): add radio support
2026-05-09 15:50:10 +02:00
4gray
0d93301520
fix(stalker): address radio review feedback
...
Entire-Checkpoint: f957cd9849e0
2026-05-09 13:08:41 +02:00
4gray
9261794b4a
Merge pull request #902 from weeco/feat/xtream-xmltv-epg-fallback
...
feat(xtream): fall back to uploaded XMLTV when provider has no EPG
2026-05-09 13:06:51 +02:00
4gray
4020822b90
fix(xtream): prevent stale epg queue fetches
2026-05-09 12:08:14 +02:00