Skip to content

Commit

Permalink
feat(epg): epg program list with date navigation
Browse files Browse the repository at this point in the history
  • Loading branch information
4gray committed Feb 4, 2021
1 parent 4881ba8 commit fdbe02b
Show file tree
Hide file tree
Showing 4 changed files with 147 additions and 76 deletions.
112 changes: 75 additions & 37 deletions src/app/player/components/epg-list/epg-list.component.html
Original file line number Diff line number Diff line change
@@ -1,49 +1,87 @@
<ng-container *ngIf="channel; else noEpg">
<div fxFlex="80px" id="channel-info" fxLayoutAlign="row" fxLayoutGap="10px">
<div fxLayoutAlign="column" fxLayoutGap="10px">
<div fxFlex="48px" fxFlexAlign="center">
<!-- channel info panel -->
<div fxFlex="120px" id="channel-info" fxLayout="column">
<div fxFlex="79px" fxLayout="row" fxLayoutGap="10px">
<div
fxFlex="60px"
class="channel-icon"
fxLayoutAlign="center center"
>
<img *ngIf="channel?.icon" [src]="channel.icon" width="48" />
</div>
<div fxFlex="100">
<div class="channel-name">{{ channel?.name[0]?.value }}</div>
<ng-container>
<div class="playing-now">Playing now:</div>
<div class="epg-program-name">
{{
playingNow
? playingNow.title[0]?.value
: 'Live stream'
}}
</div>
</ng-container>
<div fxFlex="100" fxFlexAlign="center">
<div class="channel-name">
{{ channel?.name[0]?.value }}
</div>
<div class="program-name">
{{
playingNow ? playingNow.title[0]?.value : 'Live stream'
}}
</div>
</div>
</div>
<div fxFlex="40px" fxLayout="row" id="date-navigator">
<button
fxFlex="40px"
mat-icon-button
(click)="changeDate('prev')"
matTooltip="Previous day"
>
<mat-icon>chevron_left</mat-icon>
</button>
<span
class="selected-date"
fxFlex="100"
fxLayoutAlign="center center"
>
{{ dateToday | momentDate: 'YYYYMMDD':'MMMM Do dddd' }}</span
>
<button
fxFlex="40px"
mat-icon-button
(click)="changeDate('next')"
matTooltip="Next day"
>
<mat-icon>chevron_right</mat-icon>
</button>
</div>
</div>

<!-- program list -->
<mat-selection-list fxFlex [multiple]="false">
<mat-list-option
*ngFor="let item of items"
[value]="item"
[class.active]="timeNow >= item.start && timeNow <= item.stop"
(click)="
setEpgProgram(
item,
timeNow >= item.start && timeNow <= item.stop
)
"
>
<div matLine>
<span class="time">{{ item.start }} - {{ item.stop }}</span>
<span
*ngIf="timeNow >= item.start && timeNow <= item.stop"
class="live-badge"
>live</span
>
</div>
<p matLine>{{ item?.title[0]?.value }}</p>
<mat-divider></mat-divider>
</mat-list-option>
<ng-container *ngIf="items?.length > 0; else epgNotAvailable">
<mat-list-option
*ngFor="let item of items"
[value]="item"
[class.active]="timeNow >= item.start && timeNow <= item.stop"
(click)="
setEpgProgram(
item,
timeNow >= item.start && timeNow <= item.stop
)
"
>
<div matLine>
<span class="time">{{ item.start }} - {{ item.stop }}</span>
<span
*ngIf="timeNow >= item.start && timeNow <= item.stop"
class="live-badge"
>live</span
>
</div>
<p matLine>{{ item?.title[0]?.value }}</p>
<mat-divider></mat-divider>
</mat-list-option>
</ng-container>
<ng-template #epgNotAvailable>
<mat-list-option
>Ooops, EPG is not available for the selected
date</mat-list-option
>
</ng-template>
</mat-selection-list>
</ng-container>

<ng-template #noEpg>
<mat-list>
<mat-list-item>
Expand Down
44 changes: 25 additions & 19 deletions src/app/player/components/epg-list/epg-list.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -12,40 +12,37 @@
.active {
border-bottom: 1px dashed #666;
background: linear-gradient(to top, #d2d2d2 0%, #d6d6d6 20%, rgba(255, 255, 255, 0) 100%)

}

.time, .playing-now {
.time {
color: #666;
border-bottom: 1px solid #ccc;
font-size: 0.8em;
display: inline-block;
margin-bottom: 5px;
}

.epg-program-name {
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
font-size: 0.9em;
}

#channel-info {
padding:10px;
border-bottom: 1px solid #ccc;
box-shadow: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23);
background-color: #ccc;
}

.channel-name {
font-weight: 800;
}
.channel-icon {
overflow: hidden;
}

mat-list {
height: calc(100vh - 110px);
overflow: auto;
.channel-name {
font-weight: 800;
}

.program-name {
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
font-size: 0.9em;
}
}

mat-selection-list {
Expand All @@ -60,4 +57,13 @@ mat-selection-list {
text-transform: uppercase;
margin-left: 6px;
font-size: 0.8em;
}

#date-navigator {
border-top: 1px solid #999;

.selected-date {
font-size: 0.9em;
color: #333;
}
}
8 changes: 5 additions & 3 deletions src/app/player/components/epg-list/epg-list.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { EpgListComponent, EpgData } from './epg-list.component';
import { MatListModule } from '@angular/material/list';
import { MockModule } from 'ng-mocks';
import { MockModule, MockPipe } from 'ng-mocks';
import { ElectronService } from '../../../services/electron.service';
import { ElectronServiceStub } from '../../../home/home.component.spec';
import * as moment from 'moment';
import { EPG_GET_PROGRAM_DONE } from '../../../shared/ipc-commands';
import { ChannelStore } from '../../../state';
import { MomentDatePipe } from '../../../shared/pipes/moment-date.pipe';
import { MatIconModule } from '@angular/material/icon';

describe('EpgListComponent', () => {
let component: EpgListComponent;
Expand Down Expand Up @@ -77,8 +79,8 @@ describe('EpgListComponent', () => {

beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [EpgListComponent],
imports: [MockModule(MatListModule)],
declarations: [EpgListComponent, MockPipe(MomentDatePipe)],
imports: [MockModule(MatIconModule), MockModule(MatListModule)],
providers: [
{ provide: ElectronService, useClass: ElectronServiceStub },
],
Expand Down
59 changes: 42 additions & 17 deletions src/app/player/components/epg-list/epg-list.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ export class EpgListComponent {
/** Current time as formatted string */
timeNow: string;

selectedDate: string;

/**
* Creates an instance of EpgListComponent
* @param electronService
Expand All @@ -61,25 +63,11 @@ export class EpgListComponent {
*/
handleEpgData(programs: { payload: EpgData }): void {
if (programs.payload?.items?.length > 0) {
this.programs = programs;
this.timeNow = moment(Date.now()).format('HH:mm');
this.dateToday = moment(Date.now()).format('YYYYMMDD');
this.channel = programs.payload?.channel;
this.items = programs.payload?.items
.filter((item) =>
item.start.includes(this.dateToday.toString())
)
.map((program) => ({
...program,
start: moment(program.start, 'YYYYMMDDHHmm ZZ').format(
'HH:mm'
),
stop: moment(program.stop, 'YYYYMMDDHHmm ZZ').format(
'HH:mm'
),
}))
.sort((a, b) => {
return a.start.localeCompare(b.start);
});
this.items = this.selectPrograms(programs);

this.setPlayingNow();
} else {
Expand All @@ -88,6 +76,42 @@ export class EpgListComponent {
}
}

/**
* Selects the program based on the active date
* @param programs object with all available epg programs for the active channel
*/
selectPrograms(programs: { payload: EpgData }): EpgProgram[] {
return programs.payload?.items
.filter((item) => item.start.includes(this.dateToday.toString()))
.map((program) => ({
...program,
start: moment(program.start, 'YYYYMMDDHHmm ZZ').format('HH:mm'),
stop: moment(program.stop, 'YYYYMMDDHHmm ZZ').format('HH:mm'),
}))
.sort((a, b) => {
return a.start.localeCompare(b.start);
});
}

/**
* Changes the date to update the epg list with programs
* @param direction direction to switch
*/
changeDate(direction: 'next' | 'prev'): void {
let dateToSwitch;
if (direction === 'next') {
dateToSwitch = moment(this.dateToday, 'YYYYMMDD')
.add(1, 'days')
.format('YYYYMMDD');
} else if (direction === 'prev') {
dateToSwitch = moment(this.dateToday, 'YYYYMMDD')
.subtract(1, 'days')
.format('YYYYMMDD');
}
this.dateToday = dateToSwitch;
this.items = this.selectPrograms(this.programs);
}

/**
* Sets the playing now variable based on the current time
*/
Expand All @@ -99,7 +123,8 @@ export class EpgListComponent {

/**
* Sets the provided epg program as active and starts to play
* @param program
* @param program epg program to set
* @param isLive live stream flag
*/
setEpgProgram(program: EpgProgram, isLive?: boolean): void {
isLive
Expand Down

0 comments on commit fdbe02b

Please sign in to comment.