mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-11 11:06:16 -08:00
* feat(epg): manual EPG mapping for Stalker portals Extends the manual EPG-to-channel mapping (PR #1165) to Stalker: - shared key helper buildStalkerEpgMappingKey — playlist-scoped stalker:{playlistId}:{channelId} keys, mirroring the Xtream scheme - ITV sidebar: right-click context menu with "Map EPG channel"; after the dialog closes with a change, the bulk EPG cache is rebuilt so the panel and row previews reflect the new mapping immediately - withStalkerEpg().applyMappedItvEpg(): batch-resolves mappings for rendered channels (one getEpgMappingsBatch IPC per new id set) and overlays uploaded-XMLTV programs onto bulkItvEpgByChannel; overrides survive ensureBulkItvEpg reloads - stream-resolver: mapping check in loadStalkerEpgItems (detail) and batched prefetch in loadStalkerEpgBatch (previews); mappingCandidateKeys/prefetchEpgMappings generalized beyond Xtream - global favorites: stalker branch for the Map-EPG menu entry (item id extracted from the stalker::{playlistId}::{id} uid) - docs: manual-mapping section in docs/architecture/stalker-epg.md and a CLAUDE.md EPG bullet covering the whole mapping feature - tests: applyMappedItvEpg suite, stalker preview mapping in the stream-resolver spec, key-builder specs Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(epg): harden Stalker mapping edges found in adversarial review - stream-resolver: stalker items resolve only the playlist-scoped mapping key — bare tvgId/name candidates (tvgId mirrors the raw provider id) could only produce false matches against unrelated M3U mappings, and previews would disagree with the detail path - applyMappedItvEpg: staleness guard after every await so an in-flight call cannot write portal A's mapped EPG into portal B's state after a playlist switch (the store is a root singleton) - applyMappedItvEpg: ids are marked checked only after a successful lookup — a transient IPC failure no longer suppresses the mapping for the rest of the session - live layout: post-dialog refresh re-applies overrides for the unfiltered channel list, so an active search cannot drop the playing channel's mapping - global favorites: new epgMappingChanged output emitted when the dialog actually changed a mapping; unified live tab reloads its EPG previews in response Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
29 lines
996 B
TypeScript
29 lines
996 B
TypeScript
/**
|
|
* Key helpers for the manual EPG channel mapping table
|
|
* (`epg_channel_mappings`).
|
|
*
|
|
* M3U channels use their EPG lookup key (tvg-id, falling back to the
|
|
* channel name) directly — those identifiers are meaningful across
|
|
* playlists, so a mapping saved once applies everywhere.
|
|
*
|
|
* Xtream stream IDs and Stalker channel IDs, on the other hand, are
|
|
* provider-local: stream 12345 in portal A has nothing to do with
|
|
* stream 12345 in portal B. Mapping keys for portal channels therefore
|
|
* embed the playlist ID so mappings never leak across portals. Shared
|
|
* between the renderer and the Electron main process/worker, like
|
|
* `title-normalization.util.ts`.
|
|
*/
|
|
export function buildXtreamEpgMappingKey(
|
|
playlistId: string,
|
|
xtreamId: number | string
|
|
): string {
|
|
return `xtream:${playlistId}:${xtreamId}`;
|
|
}
|
|
|
|
export function buildStalkerEpgMappingKey(
|
|
playlistId: string,
|
|
stalkerId: number | string
|
|
): string {
|
|
return `stalker:${playlistId}:${stalkerId}`;
|
|
}
|