Commit Graph
17 Commits
Author SHA1 Message Date
4grayandClaude Fable 5 ce24e16e32 feat(portals): two-state VOD detail pages (browse ↔ watch) with season tabs (#1127)
* feat(ui): slim ContentHero to non-scrolling hero block

The page scroll container moves out of the hero into the upcoming
PortalDetailShellComponent; the hero no longer hosts a default content
slot for player/seasons/extras.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(ui): add PortalDetailShellComponent with browse/watch states

Two-state detail layout shell: owns page scroll, hero collapse animation
(~300ms, reduced-motion aware), Escape-to-close-player handling, and an
About block that re-stamps host-provided *detailTags/*detailMeta
templates in watch state. The [detail-player] slot is never wrapped in a
shell conditional so the host-owned player subtree survives state
changes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(playback): restyle inline player header as now-playing bar

Adds a back button (emits the existing closed output — in watch state
back returns to browse, not route navigation) and replaces the
hardcoded header strings with i18n keys (PORTALS.NOW_PLAYING,
CLOSE_PLAYER, BACK_TO_BROWSE).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor(xtream): migrate VOD and serial detail templates to detail shell

Hero chips/meta/actions become *detailTags/*detailMeta/*detailActions
templates; the inline player moves to the full-width [detail-player]
slot; trailer and similar rail move to [detail-extras]. Escape and the
now-playing back button close the inline player back to browse.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* refactor(stalker): migrate shared VodDetails and series view to detail shell

The shared VodDetailsComponent (Stalker VOD, collections, search) and
StalkerSeriesViewComponent move their hero content into
*detailTags/*detailMeta/*detailActions templates and host the inline
player in the full-width [detail-player] slot.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(ui): season tabs replace two-level seasons navigation

SeasonTabsComponent renders a pill row (dropdown beyond 6 seasons), an
optional season description and a back-to-playing chip. The season
container auto-selects a season (inline-playing episode's season →
most recent in-progress → first), emits seasonSelected for
auto-selections so lazy-load/enrichment hooks keep firing, highlights
the inline-playing episode, and loses the seasons grid + 'Back to
seasons' button. Download/progress helpers move to pure utils; season
strings are now translatable.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(portals): season descriptions under the season tabs

Xtream reads season overviews from get_series_info; Stalker exposes the
TMDB season overview through TmdbEnrichmentService.getSeason (same
cache rows as the episode enrichment) and keys it per tmdbId so views
reused across detail navigations cannot leak descriptions.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* docs: document two-state detail layout and season tabs

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(ui): app-prefix detail template directive selectors, build fixes

detailTags/detailMeta/detailActions → appDetailTags/appDetailMeta/
appDetailActions per @angular-eslint/directive-selector; type the
Escape host listener as Event; drop a redundant ?? in season tabs.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore(i18n): translate new detail-page keys across all 17 locales

13 PORTALS.* keys (now-playing bar, About block, season tabs, episode
empty states) translated via the i18n-fill workflow.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(playback): keep now-playing bar actions inside the viewport

The nowrap title made the header grid track grow to min-content and
pushed Copy/Close out of the page; min-width: 0 on the header/title row
lets the title truncate instead.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(ui): expandable season description and episode info dialog

Season descriptions get the same show more/less toggle as the hero
(new shared ExpandableTextComponent); episode cards and list rows get
an info button that opens a dialog with the full plot, duration, air
date and a Play action — card heights stay fixed and click-to-play
semantics stay intact. Also: drop the per-frame backdrop blur on the
player card and make the watch-enter scroll instant so the hero morph
stops competing for frame budget.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(portals): re-run TMDB season enrichment when the show match arrives

With season tabs the first seasonSelected fires as soon as seasons
load — usually before the async show-level TMDB enrichment has written
tmdb_id — so the season fetch silently no-oped and was never retried,
leaving episode stills/plots and the season description empty. Both
detail hosts now key the fetch on (tmdb_id, selected season) in an
effect, so it runs whichever arrives last. Also adds breathing room
above the About divider in watch state.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(ui): move episode info button into the card body, compact overlay actions

Three overlay buttons crowded the thumbnail on hover and the new info
button had no styling at all. Info belongs with the content text: it
now sits as a quiet ghost button at the end of the title row (revealed
on card hover, MDC touch target clamped so it cannot swallow the
play-on-click card area). Download + watched-toggle stay on the
artwork, shrunk to 28px with a subtle edge border. List view already
used the shared action style and is unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(ui): single watched indicator-toggle on episode cards

Watched state was signalled three times on one card: the green badge,
the hover toggle in the top-right cluster, and a checkmark appended to
the title. Now one control does both jobs — a toggle at the top-left
of the artwork that looks like the old green badge when watched
(always visible) and appears as a ghost circle on hover when not.
The right cluster keeps only the download action; the title checkmark
is gone.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(playback): back arrow in watch mode navigates straight to the list

Leaving the theater took two clicks: back to browse, then back to the
list. Watch state already shows everything browse offers (episodes,
About, extras), so the bar's back arrow is now route-level back
(new backClicked output wired to each host's goBack), while Close
player and Escape keep exiting to browse without navigating. Replaces
PORTALS.BACK_TO_BROWSE with a generic top-level BACK key (all locales).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(ui): compact episode stills in the list view

When a season has genuinely distinct per-episode art (TMDB stills or
provider images), list rows show a 96x54 thumbnail with the episode
number riding on it instead of the number square. When every episode
repeats the same image (providers often send the series poster), the
plain number square stays — a column of identical posters is worse
than none.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test(ui): compact list-thumbnail spec under the max-lines limit

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(ui): address Greptile review — real fallback asset, untracked overflow measure

default-episode.png never existed (pre-existing in the grid card, copied
into the list thumbs) — both onerror handlers now fall back to the real
default-poster.png. The expandable-text and content-hero measuring
effects read the expanded signal via untracked so toggling show
more/less no longer rebuilds their ResizeObservers.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 21:28:00 +02:00
4gray 4094a36fef Harden Linux embedded MPV packaging (#1043) 2026-06-13 17:24:13 +02:00
4gray 8d672f8b81 feat(playback): add web player series navigation (#1049) 2026-06-13 10:19:57 +02:00
4gray 06700b318a feat(electron): add embedded mpv support for windows and linux (#1031)
Adds experimental embedded MPV support for Windows and Linux, expands packaging/runtime validation, and updates CI coverage for the cross-platform native addon.
2026-06-09 08:58:38 +02:00
4gray edaa981061 refactor(electron): split external player sessions
Split the Electron external-player IPC monolith into focused launch-context, playback-request, runtime, MPV session, and VLC session modules. Includes Greptile follow-up fixes for Homebrew Cask VLC path resolution and VLC spawn-error promise handling, with regression coverage.
2026-05-26 23:15:28 +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 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 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
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 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 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
4grayandClaude Opus 4.7 e192cba776 feat(player): add VLC reuse-instance setting (#893)
VLC was unconditionally spawned per click — VLC's own single-instance
preference fails because the per-launch RC args defeat its D-Bus
forwarder. Mirror the existing MPV reuse pattern so users can opt in to
driving one tracked VLC via its RC interface (clear + add) instead of
opening a new window every stream.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Entire-Checkpoint: f957cd9849e0
2026-05-05 00:55:04 +02:00
4gray 9f873e6bed feat(player): add embedded-mpv player for macOS as experimental feature
- Introduced tooling for building and staging the macOS `libmpv` runtime for IPTVnator's embedded MPV player.
- Added `build-macos-runtime.mjs` for building an LGPL-compatible runtime from source.
- Created `stage-macos-runtime.mjs` for staging the built runtime artifacts.
- Implemented validation for the packaged embedded MPV runtime in `electron-after-pack.cjs` and `embedded-mpv-macos.cjs`.
- Updated packaging scripts to ensure the embedded MPV runtime is correctly integrated and validated during the build process.
- Added README files to document the expected layout and usage for the embedded MPV runtime artifacts.

Entire-Checkpoint: c6e522b4276c
2026-04-27 00:32:14 +02:00
4gray 35141bec31 build: configure Flatpak finish arguments for external player launching
Entire-Checkpoint: 21b9b9f90f23
2026-04-12 18:38:07 +02:00
4gray d366672506 docs: refactor and document architecture for Stalker and Workspace components
- Moved Stalker-related components and services from apps/web to libs/portal for better modularity.
- Introduced SQLite DB Worker to handle non-EPG database operations, improving UI responsiveness.
- Updated documentation for the Workspace Dashboard and Shell, detailing current implementation and routing structure.
- Added new EPG fixture scenarios to the Xtream mock server for testing purposes.
- Enhanced the overall architecture documentation to reflect recent changes and improvements.
2026-04-05 19:05:07 +02:00