Files
2026-05-03 23:36:48 +02:00

234 lines
9.6 KiB
Markdown

# Stalker Portal Architecture
This document describes the Stalker portal implementation in IPTVnator and where each feature is integrated.
## Related Docs
- [Stalker Portal EPG Architecture](./stalker-epg.md)
- [Playlist Backup/Restore Architecture](./playlist-backup-restore.md)
- [Portal Detail Navigation](./portal-detail-navigation.md)
- [Embedded Inline Playback](./embedded-inline-playback.md)
- [Remote Control Architecture](./remote-control.md)
- [Download Manager](./download-manager.md)
- [Category Management](./category-management.md)
- [Stalker Store API Baseline](./stalker-store-api-baseline.md)
## Scope
Stalker support covers:
- Live TV (`itv`)
- VOD (`vod`)
- Series (`series`)
- VOD-as-series flows (`is_series=1` and embedded `series[]`)
- Favorites and recently viewed collections
- Search
- External player playback (shared Xtream player infrastructure)
- Remote control for live ITV navigation
## Routing Structure
Primary route tree lives in `/Users/4gray/Code/iptvnator/libs/portal/stalker/feature/src/lib/stalker-feature.routes.ts`.
- `/stalker/:id/vod`
- `/stalker/:id/series`
- `/stalker/:id/itv`
- `/stalker/:id/favorites`
- `/stalker/:id/recent`
- `/stalker/:id/search`
- `/stalker/:id/downloads` (shared downloads module from Xtream UI)
## Runtime Architecture
1. Angular Stalker screens call methods/resources in `StalkerStore`.
2. `StalkerStore` builds request params based on selected content type and current view state.
3. Requests go through `DataService.sendIpcEvent(STALKER_REQUEST, ...)` or `StalkerSessionService` (full portal auth).
4. Electron main process handles `STALKER_REQUEST` in `/Users/4gray/Code/iptvnator/apps/electron-backend/src/app/events/stalker.events.ts`.
5. Axios calls Stalker `load.php` API with required headers/cookies and returns normalized payloads to renderer.
## Main UI Components
- `/Users/4gray/Code/iptvnator/libs/portal/stalker/feature/src/lib/stalker-main-container.component.ts`
- Category + content layout for `vod` and `series`
- `/Users/4gray/Code/iptvnator/libs/portal/stalker/feature/src/lib/stalker-live-stream-layout/stalker-live-stream-layout.component.ts`
- ITV live playback, channel navigation, EPG panel integration
- `/Users/4gray/Code/iptvnator/libs/ui/components/src/lib/stalker-series-view/stalker-series-view.component.ts`
- Season/episode UI for all Stalker series modes
- `/Users/4gray/Code/iptvnator/libs/portal/stalker/feature/src/lib/stalker-favorites/stalker-favorites.component.ts`
- `/Users/4gray/Code/iptvnator/libs/portal/stalker/feature/src/lib/recently-viewed/recently-viewed.component.ts`
- `/Users/4gray/Code/iptvnator/libs/portal/stalker/feature/src/lib/stalker-search/stalker-search.component.ts`
## Store and Data Flow
Stalker store is now feature-composed:
- Facade: `/Users/4gray/Code/iptvnator/libs/portal/stalker/data-access/src/lib/stalker.store.ts`
- Feature slices: `/Users/4gray/Code/iptvnator/libs/portal/stalker/data-access/src/lib/stores/features/*`
- Shared helpers: `/Users/4gray/Code/iptvnator/libs/portal/stalker/data-access/src/lib/*`
Important store responsibilities:
- Selected content/category/item state
- Category and paginated content resources
- ITV channel list + pagination
- Regular series seasons resource
- VOD-series (`is_series=1`) seasons + episodes resources
- Playback link creation (`create_link` flow)
- Favorites and recently viewed persistence helpers
Internal structure to preserve:
- `stalker.store.ts` stays as the thin facade that composes feature slices.
- Cross-slice contracts live in `stores/stalker-store.contracts.ts` so
feature dependencies are declared instead of repeated `unknown` casts.
- Request execution is centralized in `stores/utils/stalker-request.utils.ts`
for both authenticated full-portal calls and simple IPC-backed requests.
- Playback link resolution and Stalker collection persistence live in
dedicated `stores/utils/` helpers so player/favorites/recent slices stay
focused on orchestration.
- Category/content resources stay internal to the store slices. Feature
consumers should read `getCategoryResource()` and `getPaginatedContent()`,
which now always return arrays, and pair them with
`isCategoryResourceFailed()` / `isPaginatedContentFailed()` for explicit
error handling.
Failure-handling rule:
- Failed category or content requests must degrade into empty/error UI state,
not `undefined` collections or renderer exceptions. The workspace Stalker
context panel and live layout rely on this guarantee.
## VOD/Series Modes
Stalker has multiple real-world data shapes. The current implementation supports all three:
1. Regular Series (`/series`):
- Seasons come from API resource (`serialSeasonsResource`).
- Episodes are derived from season payload.
2. VOD with Embedded `series[]`:
- Item is opened under VOD, but already contains episodes.
- `StalkerSeriesViewComponent` creates a pseudo-season and renders episodes directly.
3. VOD with `is_series=1` (Ministra plugin behavior):
- Treated as series flow from VOD context.
- Seasons are fetched lazily.
- Episodes are fetched on season select.
- Uses unique generated tracking IDs for episode playback position compatibility.
Core decision logic and normalization are centralized in:
- `/Users/4gray/Code/iptvnator/libs/portal/stalker/data-access/src/lib/stalker-vod.utils.ts`
- `/Users/4gray/Code/iptvnator/libs/portal/stalker/data-access/src/lib/models/*.ts`
## Favorites and Recently Viewed
Current implementation is shared via Stalker-specific helpers:
- `createPortalCollectionResource(...)` generic collection loader
- `createPortalFavoritesResource(...)` favorites wrapper
- `createStalkerDetailViewState(...)` unified "open detail" decision
- `toggleStalkerVodFavorite(...)` shared add/remove behavior
- `normalizeStalkerEntityId(...)` and `normalizeStalkerEntityIdAsNumber(...)` for stable ID matching
- `matchesFavoriteById(...)` for cross-shape favorite matching
Where this is used:
- `/Users/4gray/Code/iptvnator/libs/portal/stalker/feature/src/lib/stalker-favorites/stalker-favorites.component.ts`
- `/Users/4gray/Code/iptvnator/libs/portal/stalker/feature/src/lib/recently-viewed/recently-viewed.component.ts`
- `/Users/4gray/Code/iptvnator/libs/portal/stalker/feature/src/lib/stalker-search/stalker-search.component.ts`
- `/Users/4gray/Code/iptvnator/libs/ui/components/src/lib/stalker-favorites-button/stalker-favorites-button.component.ts`
Navigation rule to preserve:
- Stalker favorites, recently viewed, and search stay in their current screen and open inline detail state.
- They should not redirect into a canonical content/category/item route because Stalker detail rendering is currently store-state/inline driven, not route driven.
- VOD-backed series favorites can be displayed in series collections, but detail
opening must preserve their VOD origin: `is_series=1` favorites set the
selected content type to `vod` so the lazy Ministra season/episode resources
run, and embedded `series[]` favorites render through the embedded VOD-series
branch.
- See [Portal Detail Navigation](./portal-detail-navigation.md).
## Backup and Restore
Versioned playlist backups include Stalker connection metadata plus playlist-
scoped favorites/recent snapshots.
Exported fields:
- `portalUrl`
- `macAddress`
- `isFullStalkerPortal`
- optional `username` / `password`
- optional request headers (`userAgent`, `referrer`, `origin`)
- full-portal serial/device/signature fields when present
- favorites and recently viewed collections
Excluded fields:
- `stalkerToken`
- `stalkerAccountInfo`
- playback positions in backup v1
Import rule:
- backups restore the saved portal definition and replace the stored
favorites/recent state for the matched playlist
- a fresh handshake must happen after import for full-portal sessions; imported
backups never trust a serialized token
## Remote Control Integration
Stalker live remote control is implemented in:
- `/Users/4gray/Code/iptvnator/libs/portal/stalker/feature/src/lib/stalker-live-stream-layout/stalker-live-stream-layout.component.ts`
Supported today:
- Channel up/down
- Numeric channel selection (list-position based)
- Status publish for remote UI (portal/channel/current program)
See full backend and web-remote flow in [Remote Control Architecture](./remote-control.md).
## EPG Integration
Stalker ITV now splits EPG usage:
- active channel panel: bulk `get_epg_info` cached once per playlist and rendered
through shared `app-epg-list`
- channel row preview: no pre-playback network requests; previews are derived
from cached bulk EPG only after the first active-channel fetch succeeds
- active panel fallback: `get_short_epg` when bulk EPG is missing or unsupported
Full details are documented in [Stalker Portal EPG Architecture](./stalker-epg.md).
## Shared/Reusable Infrastructure
Stalker reuses some Xtream UI infrastructure deliberately:
- Category content rendering route uses Xtream category content component
- Season container for episodes uses shared Xtream season UI component
- Playback position handling for series episodes reuses Xtream store position mechanisms
- Downloads route reuses shared downloads feature
This reduces duplicate UI logic across portal types and keeps compatibility behavior aligned.
## Regression Coverage
Focused regression tests for Stalker VOD mode branching live in:
- `/Users/4gray/Code/iptvnator/libs/portal/stalker/data-access/src/lib/stalker-vod.utils.spec.ts`
Covered scenarios include:
- Embedded `series[]` opens series view state
- `is_series=1` opens lazy series state
- VOD-backed series favorites keep VOD-series loading semantics when opened from
favorites/global favorites
- Favorite toggle helper path invokes the expected add/remove flow