mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-08 17:06:15 -08:00
feat: video player configuration in app settings
This commit is contained in:
1 parent
1e852e3899
commit
05c0c251cf
4 files changed
+108
-36
No files matched your search
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -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();
|
||||
|
||||
Reference in new issue
Block a user