Skip to content

Commit

Permalink
feat: video player configuration in app settings
Browse files Browse the repository at this point in the history
  • Loading branch information
4gray committed Sep 27, 2020
1 parent 1e852e3 commit 05c0c25
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 36 deletions.
55 changes: 36 additions & 19 deletions src/app/settings/settings.component.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
import { Component, OnInit } from '@angular/core';
import {
FormGroup,
FormControl,
FormBuilder,
Validators,
} from '@angular/forms';
import { Component, OnInit, OnDestroy } from '@angular/core';
import { FormGroup, FormBuilder } from '@angular/forms';
import { StorageMap } from '@ngx-pwa/local-storage';
import { Router } from '@angular/router';
import { MatSnackBar } from '@angular/material/snack-bar';
import { Subscription } from 'rxjs';
import { Settings } from './settings.interface';

@Component({
selector: 'app-settings',
templateUrl: './settings.component.html',
styleUrls: ['./settings.component.scss'],
})
export class SettingsComponent implements OnInit {
export class SettingsComponent implements OnInit, OnDestroy {
/** Subscription object */
private subscription: Subscription = new Subscription();

/** Player options */
players = [
{
Expand Down Expand Up @@ -52,23 +52,33 @@ export class SettingsComponent implements OnInit {
* Reads the config object from the browsers storage (indexed db)
*/
ngOnInit(): void {
this.storage.get('settings').subscribe((settings) => {
if (settings) {
this.settingsForm.setValue(settings);
}
});
this.subscription.add(
this.storage.get('settings').subscribe((settings: Settings) => {
if (settings) {
this.settingsForm.setValue(settings);
}
})
);
}

/**
* Triggers on form submit and saves the config object to the indexed db store
*/
onSubmit(): void {
this.storage.set('settings', this.settingsForm.value).subscribe(() => {
this.settingsForm.markAsPristine();
this.snackBar.open('Success! Configuration was saved.', null, {
duration: 2000,
});
});
this.subscription.add(
this.storage
.set('settings', this.settingsForm.value)
.subscribe(() => {
this.settingsForm.markAsPristine();
this.snackBar.open(
'Success! Configuration was saved.',
null,
{
duration: 2000,
}
);
})
);
}

/**
Expand All @@ -77,4 +87,11 @@ export class SettingsComponent implements OnInit {
backToHome(): void {
this.router.navigateByUrl('/', { skipLocationChange: true });
}

/**
* Unsubscribe on destroy
*/
ngOnDestroy(): void {
this.subscription.unsubscribe();
}
}
8 changes: 8 additions & 0 deletions src/app/settings/settings.interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export type VideoPlayerType = 'html5' | 'videojs';

/**
* Describes all available settings options of the application
*/
export interface Settings {
player: VideoPlayerType;
}
44 changes: 33 additions & 11 deletions src/app/video-player/video-player.component.html
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
<mat-drawer-container
class="main-container"
(backdropClick)="close()">

<mat-drawer-container class="main-container" (backdropClick)="close()">
<!-- sidebar content -->
<mat-drawer
#drawer
mode="side"
opened
(keydown.escape)="close()"
disableClose>
disableClose
>
<ng-container *ngIf="channels$ | async as channels">
<app-channel-list-container
[channelList]="channels"
(changeChannel)="playChannel($event)"></app-channel-list-container>
(changeChannel)="playChannel($event)"
>
</app-channel-list-container>
</ng-container>
</mat-drawer>

Expand All @@ -23,21 +23,43 @@
mat-icon-button
mat-toolbar="Add to favorites"
(click)="drawer.toggle()"
matTooltip="Open channels list">
matTooltip="Open channels list"
>
<mat-icon>menu</mat-icon>
</button>
{{ (activeChannel$ | async)?.name}}
{{ (activeChannel$ | async)?.name }}
<div class="spacer"></div>
<button mat-icon-button (click)="openAbout()"><mat-icon>info</mat-icon></button>
<button mat-icon-button (click)="openAbout()">
<mat-icon>info</mat-icon>
</button>
<!-- <mat-icon>star_outline</mat-icon> -->
</mat-toolbar>

<ng-container
*ngIf="
player === 'videojs' &&
(activeChannel$ | async) as activeChannel
"
>
<app-vjs-player
[options]="{
sources: [
{
src: activeChannel.url,
type: 'application/x-mpegURL'
}
]
}"
></app-vjs-player>
</ng-container>

<!-- player component -->
<video
*ngIf="player === 'html5'"
id="video-player"
autoplay="true"
controls="true"
muted="muted"></video>

muted="muted"
></video>
</mat-drawer-content>
</mat-drawer-container>
37 changes: 31 additions & 6 deletions src/app/video-player/video-player.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,12 @@ import * as Hls from 'hls.js';
import { ChannelQuery, Channel } from '../state';
import { Observable } from 'rxjs';
import { MatSidenav } from '@angular/material/sidenav';
import * as _ from 'lodash';
import { ElectronService } from 'app/services/electron.service';
import { StorageMap } from '@ngx-pwa/local-storage';
import { Settings, VideoPlayerType } from 'app/settings/settings.interface';

/** Settings key in storage */
export const SETTINGS_STORE_KEY = 'settings';

@Component({
selector: 'app-video-player',
Expand All @@ -30,29 +34,50 @@ export class VideoPlayerComponent implements OnInit {
/** Sidebar object */
@ViewChild('sidenav') sideNav: MatSidenav;

/** Selected video player component */
player: VideoPlayerType = 'html5';

/**
* Creates an instance of VideoPlayerComponent
* @param channelQuery akita's channel query
* @param electronService electron service
* @param storage browser storage service
*/
constructor(
private channelQuery: ChannelQuery,
private electronService: ElectronService
private electronService: ElectronService,
private storage: StorageMap
) {}

/**
* Sets video player and subscribes to channel list from the store
*/
ngOnInit(): void {
this.channels$ = this.channelQuery.selectAll();
this.videoPlayer = document.getElementById(
'video-player'
) as HTMLVideoElement;

this.activeChannel$ = this.channelQuery.select((state) => state.active);

this.applySettings();
}

/**
* Reads the app configuration from the browsers storage and applies the settings in the current component
*/
applySettings(): void {
this.storage.get(SETTINGS_STORE_KEY).subscribe((settings: Settings) => {
if (settings && Object.keys(settings).length > 0) {
this.player = settings.player;
if (this.player === 'html5') {
this.videoPlayer = document.getElementById(
'video-player'
) as HTMLVideoElement;
}
}
});
}

/**
* Closes sidebar
* Closes the channels sidebar
*/
close(): void {
this.sideNav.close();
Expand Down

0 comments on commit 05c0c25

Please sign in to comment.