Commit Graph
148 Commits
Author SHA1 Message Date
4gray 3d4d2ca9bf fix(angular): remove template diagnostics warnings (#1011)
* fix(angular): remove template diagnostics warnings

* fix(angular): preserve template fallback behavior
2026-05-26 18:33:44 +02:00
4gray ed8680116c fix(runtime): address consolidated review feedback 2026-05-22 14:02:56 +03:00
4gray 03586d934a refactor(channels): gate list epg by runtime capability 2026-05-22 13:33:31 +03:00
4gray 4ab8915483 chore(web): enable strict TypeScript mode 2026-05-22 02:58:12 +03:00
4grayandClaude 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 5e5a89a300 refactor(ui): remove dead portal code and share detail styles (#946) 2026-05-16 00:09:29 +02:00
4gray d24c77a143 chore(nx): enforce scoped workspace boundaries (#942) 2026-05-15 09:59:06 +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 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 f922dd2d00 style: adjust size and remove unnecessary styles for action buttons
Entire-Checkpoint: f957cd9849e0
2026-05-10 23:37:15 +02:00
Tedd Johnson 626948f2f5 Add double-click stream open setting 2026-05-07 20:03:33 -07:00
4gray ed6302c059 feat(m3u): add channel list sorting controls
Entire-Checkpoint: f957cd9849e0
2026-05-06 00:14:52 +02:00
4gray 6cbf2a1cfb feat(m3u): add context menus to recent channels
Entire-Checkpoint: f957cd9849e0
2026-05-05 00:27:15 +02:00
4gray 15b6ba985a feat(live-tv): collapsible sidebar in live tv views
Entire-Checkpoint: f957cd9849e0
2026-05-02 23:53:05 +02:00
4grayandClaude Opus 4.7 e888841b21 refactor(ui): unify live-tv channel skeleton across m3u, xtream, stalker
The loading placeholders for live channel rows were inconsistent and
visibly heavier than the real channel-list-item: each module rendered
its own skeleton with a colored card surface, larger padding/radius,
mismatched logo border-radius, and only a single tiny right-side dot
instead of the real 34×34 action buttons. Stalker had no initial-load
skeleton at all.

Extract a shared app-channel-list-item-skeleton that mirrors
channel-list-item 1:1 (transparent surface, 8/10/8/12 padding, 12px
radius, 44×44 logo with 10px radius, optional EPG progress placeholder,
0–3 button placeholders) plus a thin app-channel-list-skeleton wrapper
that renders N rows with deterministic width variance, and route every
live-tv loading state through it (m3u channel-list-loading-state,
xtream portal-channels-list, stalker live-stream-layout via a derived
isInitialChannelsLoading signal, and the unified favorites/recent
collection page). Drops the bespoke channel-skeleton-shimmer keyframes
in favor of the shared skeleton-shimmer animation.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Entire-Checkpoint: 58a2d50756dd
2026-05-02 00:52:38 +02:00
4grayandClaude Opus 4.7 6303986c72 perf(channel-list): replace per-tick channel cloning with side-car EPG map
The three channel-list views (all-channels, groups, favorites) each had
an enrichedXxx computed signal that, on every progressTick (~30 s),
spread-cloned every channel in scope to attach { epgProgram, logo,
progressPercentage }. On a 90 K-channel M3U playlist, all-channels-view
allocated ~90 K objects per tick — persistent young-gen pressure and
visible GC stutter on large lists.

Replace the pattern with a side-car ChannelEpgMetadata map keyed by EPG
lookup key, holding only entries for channels that actually have EPG
data (typically a small fraction of the playlist). Templates iterate
the raw channel array and look up { epgProgram, progressPercentage }
inline. Logo resolution moves to a per-row method call — under OnPush
+ virtual scroll only ~50 visible rows check at a time.

groups-view's selectedGroupChannels also lost its progressTick
dependency: sorting + filtering only reruns when the selected group or
sort mode changes, no longer every 30 s.

The EnrichedChannel interface is replaced with a smaller
ChannelEpgMetadata. Specs that asserted on the cloned `.logo` field now
call `getLogoForChannel(channel)`.

Inspired by matracey/iptvnator@8d78cc0, @b9e6e82, @296d61e — ported as
a single coherent change. Their version missed our second site
(selectedGroupChannels) and didn't address the per-tick logo cloning.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Entire-Checkpoint: e400bd558b10
2026-05-02 00:06:16 +02:00
4grayandClaude Opus 4.7 94a0756424 fix(ui): unify the three side-by-side empty states in m3u groups view
Three placeholders were rendering at once when a search filter cleared
both the groups rail and the channel list, and they each used a
different visual treatment:

1. Groups rail (.groups-nav-empty) was bare 0.82rem muted text with no
   icon and no hint, and routed through CHANNELS.NO_SEARCH_RESULTS
   ("No channels found") which is wrong copy for the *groups* column.
2. Channel list (.groups-content-empty-state) was the canonical L4
   icon + title + hint pattern (correct).
3. Player area (<app-portal-empty-state>) was a 72px icon at 0.2
   opacity, which read as ghosted on dark theme.

Bring the groups rail into the L4 family scaled down for the narrow
column: 28px search_off / folder_off icon at 0.5 opacity, 0.85rem
title, 0.78rem hint at 0.65 opacity, centered. Add a CHANNELS.NO_GROUPS_FOUND
i18n key so the copy reflects the column ("No groups found").

Bump portal-empty-state's icon opacity from 0.2 -> 0.35 and title
opacity from 0.5 -> 0.6 so the player-area placeholder feels present
rather than abandoned.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Entire-Checkpoint: 6719280e397b
2026-05-01 23:43:36 +02:00
4grayandClaude Opus 4.7 2f7406054d perf(ui): enable OnPush across hot list-rendering components
Audit found 10 list-rendering components (each >150 lines, all using
signal-based state) on default change detection. Default CD re-checks
every binding on every parent CD cycle (mouse moves, EPG progress
ticks, etc.); under OnPush these only re-check when their own signals
change or when explicitly markedForCheck.

All 10 use signals exclusively for state (no manual subscribe-and-mutate
patterns), so the conversion is straightforward and safe.

Components:
- recent-playlists (740L) — homepage playlist list with drag-drop
- vod-details-route (552L) — Xtream VOD detail page
- playlist-switcher (509L) — workspace shell playlist switcher
- season-container (444L) — Stalker/Xtream series episodes (DoCheck preserved)
- stalker-search (362L) — Stalker search results
- search-results (350L) — Xtream search results
- category-management-dialog (199L) — manage Xtream categories
- recently-added (162L) — Xtream recently-added rail
- category-content-view (Catalog) — category browse page
- grid-list (shared) — generic grid renderer used across portals

Tests: 124 passed across all touched lib projects.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Entire-Checkpoint: 2e1a36e2f0f6
2026-05-01 23:24:10 +02:00
4gray 1af287205f perf: optimize playlist favorite lookups
Use Map and Set lookups for M3U favorite aggregation, dashboard global favorite mapping, and channel-list favorite/group resolution.

Remove the duplicate NgxIndexedDB provider registration and add regression coverage for duplicate URL and earliest-match behavior.

Entire-Checkpoint: c2cea9c530e6
2026-05-01 20:44:30 +02:00
4gray a6e886116c style(dialog): increase dialog width from 300px to 400px for better visibility
Entire-Checkpoint: c2cea9c530e6
2026-04-30 13:19:38 +02:00
4grayandClaude Opus 4.7 6c0c04bcba fix(scrollbar): force overflow-y: scroll in .app-scrollbar utility
The favorites and recent views had local #id { overflow-y: auto }
which has higher CSS specificity than the global .app-scrollbar class.
On macOS, overflow-y: auto means overlay scrollbars that auto-fade,
so the gutter and themed thumb were never reserved.

Bake overflow-y: scroll into the utility itself (its whole purpose) and
drop the now-redundant overflow-y: auto from the two local rules.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Entire-Checkpoint: b2d2124cd992
2026-04-29 01:06:56 +02:00
4grayandClaude Opus 4.7 5ab6736613 refactor(channels): apply .app-scrollbar to favorites and recent views
Round out the channel-list-container views so the favorites and recent
panels get the same persistent scrollbar gutter and themed thumb as the
all-channels and groups views.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Entire-Checkpoint: 2301533420c9
2026-04-29 01:03:01 +02:00
4grayandClaude Opus 4.7 59beb324b4 refactor(styles): extract .app-scrollbar utility, apply to channel lists
Move the always-visible themed scrollbar from epg-list into a global
.app-scrollbar utility class in styles.scss. Apply it to the All
channels and Groups view virtual-scroll viewports so the channel list
gets the same persistent gutter and themed thumb as the EPG list.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Entire-Checkpoint: c470abf78379
2026-04-29 01:00:42 +02:00
4gray f0df67b5b4 test: add missing config
Entire-Checkpoint: c6e522b4276c
2026-04-26 00:31:23 +02:00
4gray 4bc733d9c2 refactor(external-playback): update styles
Entire-Checkpoint: c6e522b4276c
2026-04-25 23:48:21 +02:00
4gray ce7ae1a251 refactor(external-playback): add translation support for close player button and update UI styles
Entire-Checkpoint: c6e522b4276c
2026-04-25 23:43:22 +02:00
4gray c13dcc59dd feat: add channel metadata resolution and logo handling for enriched channel views
Entire-Checkpoint: c6e522b4276c
2026-04-20 00:23:32 +02:00
4gray ecb070d08e test: add unit tests for ContentHeroComponent and handle ResizeObserver unavailability
Entire-Checkpoint: c6e522b4276c
2026-04-19 23:39:16 +02:00
4gray 5e41e3d1ce refactor(favs-recent): adapt UI and routing behavior
- Introduced StalkerCollectionDetailComponent to handle detailed views for Stalker collections.
- Added XtreamCollectionDetailComponent for managing Xtream collection details.
- Updated routing components to integrate new detail components for both Stalker and Xtream.
- Enhanced global favorites and recently viewed functionalities to support new detail navigation for Stalker and Xtream items.
- Improved styling and structure for better responsiveness and user experience in detail views.

Entire-Checkpoint: c6e522b4276c
2026-04-18 10:16:09 +02:00
4gray 8be51fc246 feat(content-hero): add expandable description with toggle functionality and overflow detection
Entire-Checkpoint: c6e522b4276c
2026-04-17 23:18:29 +02:00
4gray 6e6bd04eca style(season-container): enhance empty state handling and add corresponding styles
Entire-Checkpoint: c6e522b4276c
2026-04-17 00:11:14 +02:00
4gray e2d1bb5400 feat(m3u): add inline search functionality for group filtering and enhance group management UI
Entire-Checkpoint: 21b9b9f90f23
2026-04-11 23:30:38 +02:00
4gray 0e98af2e1a feat(m3u): implement group management dialog and hidden group titles functionality for m3u module 2026-04-11 22:59:58 +02:00
4gray a8aa289735 feat(groups): implement channel sorting functionality with UI controls 2026-04-11 14:12:43 +02:00
4gray 0f72efb749 refactor(m3u): add loading state for channel list and improve playlist handling
- Implemented a loading state for channel lists in various components, enhancing user experience during data fetching.
- Added `ChannelListLoadingStateComponent` to display loading skeletons for channels and groups.
- Updated `M3uWorkspaceRouteSession` to manage loading states more effectively when fetching playlists.
- Modified `VideoPlayerComponent`, `SidebarComponent`, and `ChannelListContainerComponent` to utilize the new loading state.
- Enhanced tests to cover new loading behaviors and ensure proper dispatching of loading actions.
2026-04-11 13:20:22 +02:00
4gray bf427f7226 refactor: remove info overlay component and related files 2026-04-11 10:42:31 +02:00
4gray dd58e4a529 style: enhance channel details dialog with improved layout and additional stats
Entire-Checkpoint: db35a98d337f
2026-04-11 10:42:10 +02:00
4gray c97673b928 refactor: refactor date handling across components to use date-fns and Intl.DateTimeFormat
- Replaced moment.js usage with Intl.DateTimeFormat for date formatting in various components.
- Introduced utility functions `normalizeDateLocale` and `formatWithIntl` for locale normalization and date formatting.
- Updated PlaylistSwitcher, RecentPlaylists, ContentCard, EPG components, and MultiEpgContainer to utilize the new date formatting approach.
- Removed moment-date pipe and related tests, simplifying date handling logic.
- Ensured all date displays respect the current locale settings.

Entire-Checkpoint: 271bd0162027
2026-04-11 10:41:33 +02:00
4gray 77dbfd7eae style: unify search bar styling across components and improve display properties
Entire-Checkpoint: dd05e045e1b2
2026-04-11 08:13:39 +02:00
4gray c2f5c62e82 feat: add channel details dialog and context menu for channel items 2026-04-10 07:54:44 +02:00
4gray c2768ef687 feat: add isRadio input to channel components for improved radio handling 2026-04-06 23:14:48 +02:00
4gray 61a582b8b7 feat: add sidebar width management with resize events in channel list and groups view components 2026-04-06 12:57:27 +02:00
4gray 04e8709d7b feat: implement URL probing functionality and enhance time formatting in EPG component 2026-04-05 19:04:20 +02:00
4gray f87a261fb1 refactor(playlist): replace mat-list-item with div for improved layout and styling consistency
Entire-Checkpoint: 271bd0162027
2026-03-29 23:51:21 +02:00
4gray 94e9a5119c refactor(styles): implement panel header mixins for consistent layout across components
Entire-Checkpoint: 84693b066142
2026-03-29 18:16:54 +02:00
4gray 6c9a40d831 refactor: migrate from NgRx store to PlaylistContextFacade for playlist management
- Updated PlaylistErrorViewComponent to use PlaylistContextFacade for accessing the current playlist.
- Refactored StalkerSearchComponent to utilize PlaylistContextFacade for retrieving the active playlist.
- Modified StalkerWorkspaceRouteSession to sync route context using PlaylistContextFacade.
- Adjusted XtreamStore to remove NgRx store dependencies and use PlaylistContextFacade for current playlist access.
- Updated ChannelListContainerComponent to resolve playlist ID using PlaylistContextFacade.
- Refactored SidebarComponent and ToolbarComponent to eliminate NgRx store usage for playlist-related data.
- Enhanced unit tests in with-content.feature to ensure proper loading and cancellation of content imports.
2026-03-28 21:43:33 +01:00
4gray 4a7855895b feat(tests): update Jest configuration for ESM support and add new test setups for playlist-shared-ui 2026-03-28 15:44:17 +01:00
4gray b73053ea5a feat: update channel selection logic by removing EPG service call 2026-03-28 15:38:43 +01:00
4gray 1677d709ff feat(m3u): refactor GroupsViewComponent with improved state management and UI updates 2026-03-28 15:38:19 +01:00
4gray 7cf00510d1 feat: update DialogService tests and add new test runner for ESM libraries 2026-03-28 15:37:59 +01:00