feat: video player configuration in app settings

This commit is contained in:
4gray committed 2020-09-27 19:35:09 +02:00
1 parent 1e852e3899
commit 05c0c251cf
4 files changed
+108 -36

No files matched your search

+36 -19
View File
@@ -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 = [
{
@@ -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,
}
);
})
);
}
/**
@@ -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
View File
@@ -0,0 +1,8 @@
export type VideoPlayerType = 'html5' | 'videojs';
/**
* Describes all available settings options of the application
*/
export interface Settings {
player: VideoPlayerType;
}
@@ -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>
@@ -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>
+31 -6
View File
@@ -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',
@@ -30,14 +34,19 @@ 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
) {}
/**
@@ -45,14 +54,30 @@ export class VideoPlayerComponent implements OnInit {
*/
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();
}
/**
* Closes sidebar
* 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 the channels sidebar
*/
close(): void {
this.sideNav.close();