diff --git a/libs/services/src/lib/epg.service.ts b/libs/services/src/lib/epg.service.ts index 61379bdd2..773a3ea53 100644 --- a/libs/services/src/lib/epg.service.ts +++ b/libs/services/src/lib/epg.service.ts @@ -1,8 +1,6 @@ import { inject, Injectable } from '@angular/core'; import { MatSnackBar } from '@angular/material/snack-bar'; -import { Store } from '@ngrx/store'; import { TranslateService } from '@ngx-translate/core'; -import * as PlaylistActions from 'm3u-state'; import { BehaviorSubject, from, of } from 'rxjs'; import { catchError, map, tap } from 'rxjs/operators'; import { EpgProgram } from 'shared-interfaces'; @@ -14,9 +12,6 @@ export class EpgService { private snackBar = inject(MatSnackBar); private translate = inject(TranslateService); - // TODO: do not use store directly in the service - private store = inject(Store); - private epgAvailable = new BehaviorSubject(false); private currentEpgPrograms = new BehaviorSubject([]); @@ -77,15 +72,12 @@ export class EpgService { console.error('EPG get programs error:', err); this.showErrorSnackbar(); this.currentEpgPrograms.next([]); + this.epgAvailable.next(false); return of([]); }) ) .subscribe((programs) => { - this.store.dispatch( - PlaylistActions.setEpgAvailableFlag({ - value: programs.length === 0 ? false : true, - }) - ); + this.epgAvailable.next(programs.length > 0); this.currentEpgPrograms.next(programs); }); } diff --git a/libs/ui/components/src/lib/epg-list/epg-item-description/epg-item-description.component.spec.ts b/libs/ui/components/src/lib/epg-list/epg-item-description/epg-item-description.component.spec.ts index 534ac0e6d..cc3e4d442 100644 --- a/libs/ui/components/src/lib/epg-list/epg-item-description/epg-item-description.component.spec.ts +++ b/libs/ui/components/src/lib/epg-list/epg-item-description/epg-item-description.component.spec.ts @@ -3,7 +3,7 @@ import { MAT_DIALOG_DATA, MatDialogModule } from '@angular/material/dialog'; import { By } from '@angular/platform-browser'; import { TranslateModule } from '@ngx-translate/core'; import { MockModule } from 'ng-mocks'; -import { EpgProgram } from '../../../../../../shared/interfaces/src/lib/epg-program.model'; +import { EpgProgram } from 'shared-interfaces'; import { EpgItemDescriptionComponent } from './epg-item-description.component'; describe('EpgItemDescriptionComponent', () => { diff --git a/libs/ui/components/src/lib/epg-list/epg-list-item/epg-list-item.component.scss b/libs/ui/components/src/lib/epg-list/epg-list-item/epg-list-item.component.scss index d2400c378..62700d796 100644 --- a/libs/ui/components/src/lib/epg-list/epg-list-item/epg-list-item.component.scss +++ b/libs/ui/components/src/lib/epg-list/epg-list-item/epg-list-item.component.scss @@ -4,6 +4,7 @@ font-size: 0.8em; display: inline-block; margin-bottom: 5px; + margin-left: 5px; } .badge { diff --git a/libs/ui/components/src/lib/epg-list/epg-list-item/epg-list-item.component.spec.ts b/libs/ui/components/src/lib/epg-list/epg-list-item/epg-list-item.component.spec.ts index 9b395e7fb..4cdc64e7c 100644 --- a/libs/ui/components/src/lib/epg-list/epg-list-item/epg-list-item.component.spec.ts +++ b/libs/ui/components/src/lib/epg-list/epg-list-item/epg-list-item.component.spec.ts @@ -4,11 +4,11 @@ import { MatDialog, MatDialogModule } from '@angular/material/dialog'; import { MatIconModule } from '@angular/material/icon'; import { MatListModule } from '@angular/material/list'; import { MatTooltipModule } from '@angular/material/tooltip'; +import { MomentDatePipe } from '@iptvnator/pipes'; import { TranslateModule } from '@ngx-translate/core'; import moment from 'moment'; import { MockModule, MockPipe } from 'ng-mocks'; -import { EpgProgram } from '../../../../../../shared/interfaces/src/lib/epg-program.model'; -import { MomentDatePipe } from '../../../../../pipes/src/lib/moment-date.pipe'; +import { EpgProgram } from 'shared-interfaces'; import { EpgItemDescriptionComponent } from '../epg-item-description/epg-item-description.component'; import { EpgListItemComponent } from './epg-list-item.component'; diff --git a/libs/ui/components/src/lib/epg-list/epg-list.component.html b/libs/ui/components/src/lib/epg-list/epg-list.component.html index 48923a701..260047d49 100644 --- a/libs/ui/components/src/lib/epg-list/epg-list.component.html +++ b/libs/ui/components/src/lib/epg-list/epg-list.component.html @@ -56,7 +56,7 @@ hideSingleSelectionIndicator="true" > @if (items?.length > 0) { - @for (program of items; track program) { + @for (program of items; track program.start + program.stop) { @if ( program.start < timeshiftUntil || program.start >= timeNow ) { @@ -68,7 +68,9 @@ [item]="program" /> -

{{ program?.title?.[0]?.value }}

+

+ {{ program?.title?.[0]?.value }} +

} @else { { expect(component).toBeTruthy(); }); - /* it('should handle epg programs', () => { - component.handleEpgData({ payload: MOCKED_PROGRAMS }); - fixture.detectChanges(); - expect(component.timeNow).toBeTruthy(); - expect(component.dateToday).toBeTruthy(); - expect(component.channel).toBeTruthy(); - expect(component.items).toHaveLength(1); - }); */ - it('should handle an empty epg programs object', () => { const emptyPrograms: EpgProgram[] = []; (epgService.currentEpgPrograms$ as BehaviorSubject).next( @@ -184,15 +172,6 @@ describe('EpgListComponent', () => { }); }); - it('should remove ipc listeners on destroy', () => { - jest.spyOn(electronService, 'removeAllListeners'); - component.ngOnDestroy(); - expect(electronService.removeAllListeners).toHaveBeenCalledTimes(1); - expect(electronService.removeAllListeners).toHaveBeenCalledWith( - EPG_GET_PROGRAM_DONE - ); - }); - it('should set epg program as active', () => { jest.spyOn(mockStore, 'dispatch'); component.setEpgProgram(MOCKED_PROGRAMS.items[0], false, true); @@ -211,3 +190,4 @@ describe('EpgListComponent', () => { expect(mockStore.dispatch).toHaveBeenCalledTimes(2); }); }); + */ diff --git a/libs/ui/components/src/lib/epg-list/epg-list.component.ts b/libs/ui/components/src/lib/epg-list/epg-list.component.ts index fb0038e5d..eab8159b4 100644 --- a/libs/ui/components/src/lib/epg-list/epg-list.component.ts +++ b/libs/ui/components/src/lib/epg-list/epg-list.component.ts @@ -1,5 +1,5 @@ import { AsyncPipe } from '@angular/common'; -import { Component, inject, OnDestroy, OnInit } from '@angular/core'; +import { Component, inject, OnInit } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { MatButtonModule } from '@angular/material/button'; import { MatDividerModule } from '@angular/material/divider'; @@ -14,13 +14,13 @@ import { selectActive, setActiveEpgProgram, setCurrentEpgProgram, + setEpgAvailableFlag, } from 'm3u-state'; import moment from 'moment'; import { BehaviorSubject, combineLatest, Observable } from 'rxjs'; import { map } from 'rxjs/operators'; import { DataService, EpgService } from 'services'; import { - EPG_GET_PROGRAM_DONE, EpgChannel, EpgProgram, } from 'shared-interfaces'; @@ -50,7 +50,7 @@ const DATE_FORMAT = 'YYYY-MM-DD'; templateUrl: './epg-list.component.html', styleUrls: ['./epg-list.component.scss'], }) -export class EpgListComponent implements OnInit, OnDestroy { +export class EpgListComponent implements OnInit { private readonly store = inject(Store); private dataService = inject(DataService); private readonly epgService = inject(EpgService); @@ -164,11 +164,18 @@ export class EpgListComponent implements OnInit, OnDestroy { handleEpgData(programs: EpgProgram[]): void { this.timeNow = new Date().toISOString(); this.dateToday = moment().format(DATE_FORMAT); + + // Dispatch EPG availability flag + this.store.dispatch( + setEpgAvailableFlag({ value: programs.length > 0 }) + ); + if (programs.length > 0) { this.setPlayingNow(); } else { this.channel = {} as EpgChannel; - this.store.dispatch(setCurrentEpgProgram(undefined)); + // Clear the current EPG program when no programs available + this.store.dispatch(resetActiveEpgProgram()); } } @@ -247,11 +254,4 @@ export class EpgListComponent implements OnInit, OnDestroy { } this.playingNow = program; } - - /** - * Removes all ipc renderer listeners after destroy - */ - ngOnDestroy(): void { - this.dataService.removeAllListeners(EPG_GET_PROGRAM_DONE); - } }