diff --git a/electron/main.ts b/electron/main.ts index d91b7d552..ea8ac697a 100644 --- a/electron/main.ts +++ b/electron/main.ts @@ -99,7 +99,7 @@ function registerGlobalShortcuts() { */ function createEpgWorkerWindow() { const window = new BrowserWindow({ - show: true, + show: false, webPreferences: { nodeIntegration: true, contextIsolation: false, diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index aea5ac266..2892cbdf9 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -7,6 +7,11 @@ const routes: Routes = [ loadChildren: () => import('./home/home.module').then((m) => m.HomeModule), }, + { + path: 'playlists', + loadChildren: () => + import('./player/player.module').then((m) => m.PlayerModule), + }, { path: 'playlists/:id', loadChildren: () => diff --git a/src/app/home/home.component.spec.ts b/src/app/home/home.component.spec.ts index b3c46fbbe..99a4fbbab 100644 --- a/src/app/home/home.component.spec.ts +++ b/src/app/home/home.component.spec.ts @@ -18,10 +18,7 @@ import { UrlUploadComponent } from '../home/url-upload/url-upload.component'; import { DataService } from '../services/data.service'; import { ElectronServiceStub } from '../services/electron.service.stub'; import { HeaderComponent } from '../shared/components/header/header.component'; -import { - PLAYLIST_PARSE, - PLAYLIST_PARSE_BY_URL, -} from './../../../shared/ipc-commands'; +import { PLAYLIST_PARSE_BY_URL } from './../../../shared/ipc-commands'; import { HomeComponent } from './home.component'; class MatSnackBarStub { @@ -106,7 +103,7 @@ describe('HomeComponent', () => { }); it('should send an event to the main process to parse a playlist', () => { - jest.spyOn(electronService, 'sendIpcEvent'); + jest.spyOn(mockStore, 'dispatch'); const title = 'my-list.m3u'; const path = '/home/user/iptv/' + title; const playlistContent = 'test'; @@ -118,10 +115,7 @@ describe('HomeComponent', () => { target: { result: playlistContent }, } as unknown as Event; component.handlePlaylist({ file, uploadEvent }); - expect(electronService.sendIpcEvent).toHaveBeenCalledWith( - PLAYLIST_PARSE, - { title, playlist: [playlistContent], path } - ); + expect(mockStore.dispatch).toHaveBeenCalledTimes(1); }); it('should set IPC event listeners', () => { @@ -140,11 +134,11 @@ describe('HomeComponent', () => { it('should navigate to the player view', () => { jest.spyOn(router, 'navigateByUrl'); - component.navigateToPlayer(); + const playlistId = 'some-id'; + component.navigateToPlayer(playlistId); expect(router.navigateByUrl).toHaveBeenCalledTimes(1); expect(router.navigateByUrl).toHaveBeenCalledWith( - '/iptv', - expect.anything() + `/playlists/${playlistId}` ); }); diff --git a/src/app/home/recent-playlists/playlist-info/playlist-info.component.html b/src/app/home/recent-playlists/playlist-info/playlist-info.component.html index cfe746ab2..778ac7892 100644 --- a/src/app/home/recent-playlists/playlist-info/playlist-info.component.html +++ b/src/app/home/recent-playlists/playlist-info/playlist-info.component.html @@ -54,7 +54,7 @@ {{ 'HOME.PLAYLISTS.INFO_DIALOG.UPDATE_FAILED' | translate }} - + {{ 'HOME.PLAYLISTS.INFO_DIALOG.AUTO_UPDATE' | translate }} diff --git a/src/app/home/recent-playlists/playlist-info/playlist-info.component.spec.ts b/src/app/home/recent-playlists/playlist-info/playlist-info.component.spec.ts index cb6f9c372..c5985e0e6 100644 --- a/src/app/home/recent-playlists/playlist-info/playlist-info.component.spec.ts +++ b/src/app/home/recent-playlists/playlist-info/playlist-info.component.spec.ts @@ -1,5 +1,4 @@ import { MatCheckboxModule } from '@angular/material/checkbox'; -import { PLAYLIST_SAVE_DETAILS } from './../../../../../shared/ipc-commands'; /* eslint-disable @typescript-eslint/unbound-method */ import { DatePipe } from '@angular/common'; import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing'; @@ -10,8 +9,12 @@ import { } from '@angular/forms'; import { MatDialogModule, MAT_DIALOG_DATA } from '@angular/material/dialog'; import { MatFormFieldModule } from '@angular/material/form-field'; +import { Actions } from '@ngrx/effects'; +import { provideMockActions } from '@ngrx/effects/testing'; +import { MockStore, provideMockStore } from '@ngrx/store/testing'; import { TranslateModule } from '@ngx-translate/core'; import { MockModule, MockPipe } from 'ng-mocks'; +import { Observable } from 'rxjs'; import { DataService } from '../../../services/data.service'; import { ElectronServiceStub } from '../../../services/electron.service.stub'; import { Playlist } from './../../../../../shared/playlist.interface'; @@ -21,6 +24,8 @@ describe('PlaylistInfoComponent', () => { let component: PlaylistInfoComponent; let fixture: ComponentFixture; let electronService: DataService; + let mockStore: MockStore; + const actions$ = new Observable(); beforeEach( waitForAsync(() => { @@ -38,6 +43,8 @@ describe('PlaylistInfoComponent', () => { { provide: MAT_DIALOG_DATA, useValue: {} }, { provide: DataService, useClass: ElectronServiceStub }, UntypedFormBuilder, + provideMockStore(), + provideMockActions(actions$), ], }).compileComponents(); }) @@ -47,6 +54,7 @@ describe('PlaylistInfoComponent', () => { fixture = TestBed.createComponent(PlaylistInfoComponent); component = fixture.componentInstance; electronService = TestBed.inject(DataService); + mockStore = TestBed.inject(MockStore); fixture.detectChanges(); }); @@ -54,14 +62,10 @@ describe('PlaylistInfoComponent', () => { expect(component).toBeTruthy(); }); - it('should send an event to the main process after save', () => { + it('should dispatch an event to save changes in the store', () => { const playlistToSave = { _id: 'a12345', title: 'Playlist' } as Playlist; - jest.spyOn(electronService, 'sendIpcEvent'); + jest.spyOn(mockStore, 'dispatch'); component.saveChanges(playlistToSave); - expect(electronService.sendIpcEvent).toHaveBeenCalledTimes(1); - expect(electronService.sendIpcEvent).toHaveBeenCalledWith( - PLAYLIST_SAVE_DETAILS, - playlistToSave - ); + expect(mockStore.dispatch).toHaveBeenCalledTimes(1); }); }); diff --git a/src/app/home/recent-playlists/playlist-info/playlist-info.component.ts b/src/app/home/recent-playlists/playlist-info/playlist-info.component.ts index ea830c359..98d7e12d1 100644 --- a/src/app/home/recent-playlists/playlist-info/playlist-info.component.ts +++ b/src/app/home/recent-playlists/playlist-info/playlist-info.component.ts @@ -36,7 +36,7 @@ import * as PlaylistActions from '../../../state/actions'; }) export class PlaylistInfoComponent { /** Flag that returns true if application runs in electron-based environment */ - isElectron = this.electronService.isElectron; + isElectron = this.dataService.isElectron; /** Playlist object */ playlist: Playlist; @@ -44,17 +44,10 @@ export class PlaylistInfoComponent { /** Form group with playlist details */ playlistDetails: UntypedFormGroup; - /** - * Creates an instance of the component and injects the selected playlist from the parent component - * @param datePipe - * @param formBuilder - * @param electronService - * @param playlist playlist object to show - */ constructor( private datePipe: DatePipe, private formBuilder: UntypedFormBuilder, - private electronService: DataService, + private dataService: DataService, @Inject(MAT_DIALOG_DATA) playlist: Playlist, private store: Store ) { @@ -93,10 +86,6 @@ export class PlaylistInfoComponent { }); } - /** - * Saves updated playlist information - * @param data updated form data - */ saveChanges(playlist: PlaylistMeta): void { this.store.dispatch(PlaylistActions.updatePlaylistMeta({ playlist })); } diff --git a/src/app/home/recent-playlists/recent-playlists.component.spec.ts b/src/app/home/recent-playlists/recent-playlists.component.spec.ts index 7b156b423..97b0b5ec4 100644 --- a/src/app/home/recent-playlists/recent-playlists.component.spec.ts +++ b/src/app/home/recent-playlists/recent-playlists.component.spec.ts @@ -4,17 +4,19 @@ import { MatIconModule } from '@angular/material/icon'; import { MatListModule } from '@angular/material/list'; import { MatSnackBar } from '@angular/material/snack-bar'; import { MatTooltipModule } from '@angular/material/tooltip'; +import { Actions } from '@ngrx/effects'; +import { provideMockActions } from '@ngrx/effects/testing'; +import { MockStore, provideMockStore } from '@ngrx/store/testing'; import { TranslatePipe, TranslateService } from '@ngx-translate/core'; import { MockModule, MockPipe, MockProvider } from 'ng-mocks'; -import { - PLAYLIST_GET_BY_ID, - PLAYLIST_REMOVE_BY_ID, - PLAYLIST_UPDATE, -} from '../../../../shared/ipc-commands'; +import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader'; +import { Observable } from 'rxjs'; +import { PLAYLIST_UPDATE } from '../../../../shared/ipc-commands'; import { DataService } from '../../services/data.service'; import { DialogService } from '../../services/dialog.service'; import { ElectronServiceStub } from '../../services/electron.service.stub'; import { PlaylistMeta } from '../../shared/playlist-meta.type'; +import { initialPlaylistMetaState } from '../../state/playlists.state'; import { RecentPlaylistsComponent } from './recent-playlists.component'; describe('RecentPlaylistsComponent', () => { @@ -23,6 +25,8 @@ describe('RecentPlaylistsComponent', () => { let electronService: DataService; let dialog: MatDialog; let dialogService: DialogService; + let mockStore: MockStore; + const actions$ = new Observable(); beforeEach( waitForAsync(() => { @@ -36,12 +40,15 @@ describe('RecentPlaylistsComponent', () => { MockModule(MatListModule), MockModule(MatIconModule), MockModule(MatTooltipModule), + MockModule(NgxSkeletonLoaderModule), ], providers: [ { provide: DataService, useClass: ElectronServiceStub }, MockProvider(TranslateService), MockProvider(DialogService), MatSnackBar, + provideMockStore(), + provideMockActions(actions$), ], }).compileComponents(); }) @@ -50,10 +57,13 @@ describe('RecentPlaylistsComponent', () => { beforeEach(() => { fixture = TestBed.createComponent(RecentPlaylistsComponent); component = fixture.componentInstance; - component.playlists = []; dialog = TestBed.inject(MatDialog); electronService = TestBed.inject(DataService); dialogService = TestBed.inject(DialogService); + mockStore = TestBed.inject(MockStore); + mockStore.setState({ + playlistState: { playlists: initialPlaylistMetaState }, + }); fixture.detectChanges(); }); @@ -78,9 +88,9 @@ describe('RecentPlaylistsComponent', () => { distance: { x: 0, y: 0 }, dropPoint: { x: 0, y: 0 }, } as any; - jest.spyOn(electronService, 'sendIpcEvent'); - component.drop(event); - expect(electronService.sendIpcEvent).toHaveBeenCalledTimes(1); + jest.spyOn(mockStore, 'dispatch'); + component.drop(event, []); + expect(mockStore.dispatch).toHaveBeenCalledTimes(1); }); it('should open the confirmation dialog on remove icon click', () => { @@ -92,36 +102,33 @@ describe('RecentPlaylistsComponent', () => { it('should send an event to the main process to remove a playlist', () => { const playlistId = '12345'; - jest.spyOn(electronService, 'sendIpcEvent'); + jest.spyOn(mockStore, 'dispatch'); component.removePlaylist(playlistId); - expect(electronService.sendIpcEvent).toHaveBeenCalledWith( - PLAYLIST_REMOVE_BY_ID, - { id: playlistId } - ); + expect(mockStore.dispatch).toHaveBeenCalledTimes(1); }); it('should send an event to the main process to refresh a playlist', () => { const playlistMeta: PlaylistMeta = { id: 'iptv1', + title: 'iptv', filePath: '/home/user/lists/iptv.m3u', - } as PlaylistMeta; + } as unknown as PlaylistMeta; jest.spyOn(electronService, 'sendIpcEvent'); component.refreshPlaylist(playlistMeta); expect(electronService.sendIpcEvent).toHaveBeenCalledWith( PLAYLIST_UPDATE, - { id: playlistMeta._id, filePath: playlistMeta.filePath } + { + id: playlistMeta._id, + filePath: playlistMeta.filePath, + title: playlistMeta.title, + } ); }); it('should send an event to the main process to get a playlist', () => { const playlistId = '6789'; - jest.spyOn(electronService, 'sendIpcEvent'); + jest.spyOn(component.playlistClicked, 'emit'); component.getPlaylist(playlistId); - expect(electronService.sendIpcEvent).toHaveBeenCalledWith( - PLAYLIST_GET_BY_ID, - { - id: playlistId, - } - ); + expect(component.playlistClicked.emit).toHaveBeenCalledTimes(1); }); }); diff --git a/src/app/home/recent-playlists/recent-playlists.component.ts b/src/app/home/recent-playlists/recent-playlists.component.ts index 2a64bd592..7cf5ada99 100644 --- a/src/app/home/recent-playlists/recent-playlists.component.ts +++ b/src/app/home/recent-playlists/recent-playlists.component.ts @@ -46,11 +46,11 @@ export class RecentPlaylistsComponent implements OnDestroy { new IpcCommand( PLAYLIST_UPDATE_RESPONSE, (response: { message: string; playlist: Playlist }) => { - console.log(response.playlist); this.snackBar.open(response.message, null, { duration: 2000 }); this.store.dispatch( PlaylistActions.updatePlaylist({ - playlistId: '', + // TODO: check if this is correct + playlistId: response.playlist._id, playlist: response.playlist, }) ); @@ -142,10 +142,6 @@ export class RecentPlaylistsComponent implements OnDestroy { ); } - /** - * Requests playlist by id - * @param playlistId playlist id - */ getPlaylist(playlistId: string): void { this.router.navigate(['playlists', playlistId]); this.playlistClicked.emit(playlistId); diff --git a/src/app/player/components/channel-list-container/channel-list-container.component.spec.ts b/src/app/player/components/channel-list-container/channel-list-container.component.spec.ts index 6905daf4d..e246e6a24 100644 --- a/src/app/player/components/channel-list-container/channel-list-container.component.spec.ts +++ b/src/app/player/components/channel-list-container/channel-list-container.component.spec.ts @@ -13,8 +13,9 @@ import { RouterTestingModule } from '@angular/router/testing'; import { Actions } from '@ngrx/effects'; import { provideMockActions } from '@ngrx/effects/testing'; import { MockStore, provideMockStore } from '@ngrx/store/testing'; -import { TranslatePipe } from '@ngx-translate/core'; -import { MockModule, MockPipes } from 'ng-mocks'; +import { TranslatePipe, TranslateService } from '@ngx-translate/core'; +import { MockModule, MockPipes, MockProviders } from 'ng-mocks'; +import { NgxIndexedDBService } from 'ngx-indexed-db'; import { Observable } from 'rxjs'; import * as MOCKED_PLAYLIST from '../../../../mocks/playlist.json'; import { DataService } from '../../../services/data.service'; @@ -44,6 +45,7 @@ describe('ChannelListContainerComponent', () => { { provide: DataService, useClass: ElectronServiceStub }, provideMockStore(), provideMockActions(actions$), + MockProviders(NgxIndexedDBService, TranslateService), ], imports: [ MockModule(MatSnackBarModule), @@ -73,8 +75,6 @@ describe('ChannelListContainerComponent', () => { mockStore.setState({ playlistState: { channels, - favorites: [MOCKED_PLAYLIST.playlist.items[0].url], - playlistId: '', active: undefined, }, }); @@ -158,9 +158,10 @@ describe('ChannelListContainerComponent', () => { new MouseEvent('click') ); fixture.detectChanges(); - expect(mockStore.dispatch).toHaveBeenCalledWith( - {channel: component._channelList[0], type: expect.stringContaining('favorites')}, - ); + expect(mockStore.dispatch).toHaveBeenCalledWith({ + channel: component._channelList[0], + type: expect.stringContaining('favorites'), + }); expect(mockStore.dispatch).toHaveBeenCalledTimes(1); }); }); diff --git a/src/app/player/components/video-player/video-player.component.spec.ts b/src/app/player/components/video-player/video-player.component.spec.ts index c03594a08..7ad5a079b 100644 --- a/src/app/player/components/video-player/video-player.component.spec.ts +++ b/src/app/player/components/video-player/video-player.component.spec.ts @@ -9,12 +9,10 @@ import { ActivatedRoute } from '@angular/router'; import { RouterTestingModule } from '@angular/router/testing'; import { MockStore, provideMockStore } from '@ngrx/store/testing'; import { TranslatePipe } from '@ngx-translate/core'; -import { MockComponent, MockModule, MockPipe } from 'ng-mocks'; -import * as MOCKED_PLAYLIST from '../../../../mocks/playlist.json'; +import { MockComponent, MockModule, MockPipe, MockProviders } from 'ng-mocks'; import { DataService } from '../../../services/data.service'; import { ElectronServiceStub } from '../../../services/electron.service.stub'; import { VideoPlayer } from '../../../settings/settings.interface'; -import { createChannel } from '../../../shared/channel.model'; import { ChannelListContainerComponent } from '../channel-list-container/channel-list-container.component'; import { EpgListComponent } from '../epg-list/epg-list.component'; import { HtmlVideoPlayerComponent } from '../html-video-player/html-video-player.component'; @@ -24,7 +22,10 @@ import { VideoPlayerComponent } from './video-player.component'; import { Actions } from '@ngrx/effects'; import { provideMockActions } from '@ngrx/effects/testing'; -import { Observable } from 'rxjs'; +import { NgxIndexedDBService } from 'ngx-indexed-db'; +import { Observable, of } from 'rxjs'; +import { PlaylistsService } from '../../../services/playlists.service'; +import { initialState } from '../../../state/state'; class MatSnackBarStub { open(): void {} @@ -56,6 +57,7 @@ describe('VideoPlayerComponent', () => { { provide: ActivatedRoute, useValue: { + params: of({ id: '1' }), snapshot: { queryParams: { url: 'https://iptvnator/list.m3u', @@ -65,6 +67,7 @@ describe('VideoPlayerComponent', () => { }, provideMockStore(), provideMockActions(actions$), + MockProviders(NgxIndexedDBService, PlaylistsService), ], imports: [ MockModule(MatSidenavModule), @@ -83,34 +86,16 @@ describe('VideoPlayerComponent', () => { component = fixture.componentInstance; mockStore = TestBed.inject(MockStore); - // set channels - channels = MOCKED_PLAYLIST.playlist.items.map((element) => - createChannel(element) - ); - - mockStore.setState({ playlistState: {channels} }); - }); - - it('should create and init component', () => { - expect(component).toBeTruthy(); - jest.spyOn(component, 'applySettings'); + mockStore.setState({ + playlistState: initialState, + }); fixture.detectChanges(); - expect(component.applySettings).toHaveBeenCalledTimes(1); }); it('should check default component settings', () => { - fixture.detectChanges(); expect(component.playerSettings).toEqual({ player: VideoPlayer.VideoJs, showCaptions: false, }); }); - - it('should update store after channel was faved', () => { - jest.spyOn(mockStore, 'dispatch'); - const [firstChannel] = channels; - component.addToFavorites(firstChannel); - expect(mockStore.dispatch).toHaveBeenCalledTimes(1); - expect(mockStore.dispatch).toHaveBeenCalledWith({channel: firstChannel, type: expect.stringContaining('favorite')}); - }); }); diff --git a/src/app/player/components/video-player/video-player.component.ts b/src/app/player/components/video-player/video-player.component.ts index 88038dc66..3a9b35c63 100644 --- a/src/app/player/components/video-player/video-player.component.ts +++ b/src/app/player/components/video-player/video-player.component.ts @@ -11,7 +11,13 @@ import { import { ActivatedRoute } from '@angular/router'; import { Store } from '@ngrx/store'; import { StorageMap } from '@ngx-pwa/local-storage'; -import { filter, Observable, skipWhile, switchMap } from 'rxjs'; +import { + combineLatestWith, + filter, + Observable, + skipWhile, + switchMap, +} from 'rxjs'; import { Channel } from '../../../../../shared/channel.interface'; import { PLAYLIST_PARSE_BY_URL, @@ -25,6 +31,7 @@ import { STORE_KEY } from '../../../shared/enums/store-keys.enum'; import * as PlaylistActions from '../../../state/actions'; import { selectActive, + selectChannels, selectCurrentEpgProgram, selectPlaylistTitle, } from '../../../state/selectors'; @@ -69,11 +76,19 @@ export class VideoPlayerComponent implements OnInit, OnDestroy { { id: PLAYLIST_PARSE_RESPONSE, execute: (response: { payload: Playlist }): void => { - this.store.dispatch( - PlaylistActions.addPlaylist({ - playlist: response.payload, - }) - ); + if (response.payload.isTemporary) { + this.store.dispatch( + PlaylistActions.setChannels({ + channels: response.payload.playlist.items, + }) + ); + } else { + this.store.dispatch( + PlaylistActions.addPlaylist({ + playlist: response.payload, + }) + ); + } this.sidebarView = 'CHANNELS'; }, }, @@ -107,11 +122,18 @@ export class VideoPlayerComponent implements OnInit, OnDestroy { this.getPlaylistUrlAsParam(); this.channels$ = this.activatedRoute.params.pipe( - switchMap((params) => { - this.store.dispatch( - PlaylistActions.setActivePlaylist({ playlistId: params.id }) - ); - return this.playlistsService.getPlaylistChannels(params.id); + combineLatestWith(this.activatedRoute.queryParams), + switchMap(([params, queryParams]) => { + if (params.id) { + this.store.dispatch( + PlaylistActions.setActivePlaylist({ + playlistId: params.id, + }) + ); + return this.playlistsService.getPlaylistChannels(params.id); + } else if (queryParams.url) { + return this.store.select(selectChannels); + } }) ); } diff --git a/src/app/services/pwa.service.ts b/src/app/services/pwa.service.ts index 62883c81c..4014c8471 100644 --- a/src/app/services/pwa.service.ts +++ b/src/app/services/pwa.service.ts @@ -6,7 +6,7 @@ import { SwUpdate } from '@angular/service-worker'; import { Store } from '@ngrx/store'; import { TranslateService } from '@ngx-translate/core'; import { NgxIndexedDBService } from 'ngx-indexed-db'; -import { catchError, of, switchMap, throwError } from 'rxjs'; +import { catchError, throwError } from 'rxjs'; import { ERROR, PLAYLIST_PARSE_BY_URL, @@ -15,7 +15,6 @@ import { } from '../../../shared/ipc-commands'; import { Playlist } from '../../../shared/playlist.interface'; import { AppConfig } from '../../environments/environment'; -import { DbStores } from '../indexed-db.config'; import * as PlaylistActions from '../state/actions'; import { DataService } from './data.service'; import { PlaylistsService } from './playlists.service'; @@ -96,13 +95,12 @@ export class PwaService extends DataService { playlistId: payload.id, }) ); - console.log('playlist was updated...'); - // TODO: show notification - /* window.postMessage({ - type: PLAYLIST_UPDATE_RESPONSE, - message: `Success! The playlist was successfully updated.`, - }); */ + this.snackBar.open( + `Success! The playlist was successfully updated.`, + null, + { duration: 2000 } + ); }); } } @@ -114,11 +112,6 @@ export class PwaService extends DataService { fetchFromUrl(payload: Partial): void { this.getPlaylistFromUrl(payload.url) .pipe( - switchMap((response) => - payload.isTemporary - ? of(response) - : this.dbService.add(DbStores.Playlists, response) - ), catchError((error) => { window.postMessage({ type: ERROR, @@ -131,7 +124,7 @@ export class PwaService extends DataService { .subscribe((response: any) => { window.postMessage({ type: PLAYLIST_PARSE_RESPONSE, - payload: response, + payload: { ...response, isTemporary: payload.isTemporary }, }); }); } diff --git a/src/app/state/actions.ts b/src/app/state/actions.ts index 17974ec53..d7bffa0a3 100644 --- a/src/app/state/actions.ts +++ b/src/app/state/actions.ts @@ -90,9 +90,9 @@ export const setEpgAvailableFlag = createAction( props<{ value: boolean }>() ); -export const setPlaylist = createAction( - `${STORE_KEY} Set playlist as active`, - props<{ playlist: Playlist }>() +export const setChannels = createAction( + `${STORE_KEY} Set channels`, + props<{ channels: Channel[] }>() ); export const updatePlaylistPositions = createAction( diff --git a/src/app/state/reducers.ts b/src/app/state/reducers.ts index aceb06ce1..935111fa4 100644 --- a/src/app/state/reducers.ts +++ b/src/app/state/reducers.ts @@ -47,17 +47,6 @@ export const playlistReducer = createReducer( epgAvailable: action.value, }) ), - - /* on(PlaylistActions.setPlaylist, (state, action): PlaylistState => { - const { playlist } = action; - return { - ...state, - channels: playlist?.playlist.items.map((element) => - createChannel(element) - ), - active: undefined, - }; - }), */ on(PlaylistActions.updateFavorites, (state, action): PlaylistState => { let favorites; const { channel } = action; @@ -167,6 +156,12 @@ export const playlistReducer = createReducer( state.playlists ), }; + }), + on(PlaylistActions.setChannels, (state, action): PlaylistState => { + return { + ...state, + channels: action.channels, + }; }) );