From 39654e7366c7aff7631db9e5646790d4a06ab0ea Mon Sep 17 00:00:00 2001 From: 4gray Date: Sun, 4 May 2025 23:02:13 +0200 Subject: [PATCH] refactor(xtream): add stream URL construction methods and initialize streamUrl in state --- src/app/xtream-tauri/xtream-state.ts | 1 + src/app/xtream-tauri/xtream.store.ts | 54 ++++++++++++++++++++++++++-- 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/src/app/xtream-tauri/xtream-state.ts b/src/app/xtream-tauri/xtream-state.ts index 9fa0291a1..54d450c04 100644 --- a/src/app/xtream-tauri/xtream-state.ts +++ b/src/app/xtream-tauri/xtream-state.ts @@ -41,4 +41,5 @@ export interface XtreamState { hideExternalInfoDialog: boolean; portalStatus: PortalStatusType; globalSearchResults: GlobalSearchResult[]; + streamUrl: string; } diff --git a/src/app/xtream-tauri/xtream.store.ts b/src/app/xtream-tauri/xtream.store.ts index c9935e161..b2b505c71 100644 --- a/src/app/xtream-tauri/xtream.store.ts +++ b/src/app/xtream-tauri/xtream.store.ts @@ -20,10 +20,15 @@ import { tap, } from 'rxjs'; import { XtreamCodeActions } from '../../../shared/xtream-code-actions'; -import { XtreamSerieDetails } from '../../../shared/xtream-serie-details.interface'; +import { + XtreamSerieDetails, + XtreamSerieEpisode, +} from '../../../shared/xtream-serie-details.interface'; import { XtreamVodDetails } from '../../../shared/xtream-vod-details.interface'; import { DataService } from '../services/data.service'; import { DatabaseService } from '../services/database.service'; +import { PlayerService } from '../services/player.service'; +import { SettingsStore } from '../services/settings-store.service'; import { selectActivePlaylist } from '../state/selectors'; import { XtreamAccountInfo } from './account-info/account-info.interface'; import { withFavorites } from './with-favorites.feature'; @@ -54,6 +59,7 @@ const initialState: XtreamState = { localStorage.getItem('hideExternalInfoDialog') === 'true', portalStatus: 'unavailable', globalSearchResults: [], + streamUrl: null, }; /** to decode epg */ @@ -173,7 +179,9 @@ export const XtreamStore = signalStore( route = inject(ActivatedRoute), dataService = inject(DataService), dbService = inject(DatabaseService), - oldStore = inject(Store) + oldStore = inject(Store), + settingsStore = inject(SettingsStore), + playerService = inject(PlayerService) ) => { const fetchCategories = ( action: XtreamCodeActions, @@ -790,6 +798,48 @@ export const XtreamStore = signalStore( globalSearchResults: results, }); }, + constructStreamUrl(item: any) { + const { serverUrl, username, password } = + store.currentPlaylist(); + const streamFormat = settingsStore.streamFormat() ?? 'ts'; + const streamUrl = `${serverUrl}/live/${username}/${password}/${item.xtream_id}.${streamFormat}`; + + // Set the selected item and load EPG data in the store + setSelectedItem(item); + this.loadEpg(); + + patchState(store, { streamUrl }); + return streamUrl; + }, + constructVodStreamUrl(vodItem: XtreamVodDetails) { + const { serverUrl, username, password } = + store.currentPlaylist(); + const streamUrl = `${serverUrl}/movie/${username}/${password}/${vodItem.movie_data.stream_id}.${vodItem.movie_data.container_extension}`; + + patchState(store, { streamUrl }); + return streamUrl; + }, + constructEpisodeStreamUrl(episode: XtreamSerieEpisode) { + const { serverUrl, username, password } = + store.currentPlaylist(); + const streamUrl = `${serverUrl}/series/${username}/${password}/${episode.id}.${episode.container_extension}`; + patchState(store, { streamUrl }); + return streamUrl; + }, + openPlayer( + streamUrl: string, + title: string, + thumbnail: string = null + ) { + playerService.openPlayer( + streamUrl, + title, + thumbnail, + localStorage.getItem('hideExternalInfoDialog') === + 'true', + store.selectedContentType() === 'live' + ); + }, }; } )