Skip to content

Commit

Permalink
refactor: update settings store
Browse files Browse the repository at this point in the history
  • Loading branch information
4gray committed Dec 20, 2024
1 parent ee490ee commit 13b4cf3
Show file tree
Hide file tree
Showing 9 changed files with 87 additions and 69 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
OnDestroy,
OnInit,
effect,
inject,
} from '@angular/core';
import { MatSidenavModule } from '@angular/material/sidenav';
import { MatSnackBar } from '@angular/material/snack-bar';
Expand Down Expand Up @@ -133,6 +134,8 @@ export class VideoPlayerComponent implements OnInit, OnDestroy {

volume = 1;

private settingsStore = inject(SettingsStore);

constructor(
private activatedRoute: ActivatedRoute,
private dataService: DataService,
Expand All @@ -142,8 +145,7 @@ export class VideoPlayerComponent implements OnInit, OnDestroy {
private router: Router,
private snackBar: MatSnackBar,
private storage: StorageMap,
private store: Store,
private settingsStore: SettingsStore
private store: Store
) {
// Initialize volume from localStorage in constructor
const savedVolume = localStorage.getItem('volume');
Expand Down
7 changes: 3 additions & 4 deletions src/app/services/player.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ export class PlayerService {
private dialog = inject(MatDialog);
private dataService = inject(DataService);
private settingsStore = inject(SettingsStore);
private settings = this.settingsStore.getSettings();

openPlayer(
streamUrl: string,
Expand All @@ -26,15 +25,15 @@ export class PlayerService {
hideExternalInfoDialog = false,
isLiveContent = false
) {
const player = this.settings()?.player ?? VideoPlayer.VideoJs;
const player = this.settingsStore.player() ?? VideoPlayer.VideoJs;

if (player === VideoPlayer.MPV) {
if (!hideExternalInfoDialog) {
this.dialog.open(ExternalPlayerInfoDialogComponent);
}
this.dataService.sendIpcEvent(OPEN_MPV_PLAYER, {
url: streamUrl,
mpvPlayerPath: this.settings()?.mpvPlayerPath,
mpvPlayerPath: this.settingsStore.mpvPlayerPath(),
title,
thumbnail,
});
Expand All @@ -44,7 +43,7 @@ export class PlayerService {
}
this.dataService.sendIpcEvent(OPEN_VLC_PLAYER, {
url: streamUrl,
vlcPlayerPath: this.settings()?.vlcPlayerPath,
vlcPlayerPath: this.settingsStore.vlcPlayerPath(),
});
} else if (!isLiveContent) {
this.dialog.open<PlayerDialogComponent, PlayerDialogData>(
Expand Down
79 changes: 48 additions & 31 deletions src/app/services/settings-store.service.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
import { Injectable, computed, signal } from '@angular/core';
import { computed, inject } from '@angular/core';
import {
patchState,
signalStore,
withComputed,
withMethods,
withState,
} from '@ngrx/signals';
import { StorageMap } from '@ngx-pwa/local-storage';
import { firstValueFrom } from 'rxjs';
import { Language } from '../settings/language.enum';
import { Settings, VideoPlayer } from '../settings/settings.interface';
import { Theme } from '../settings/theme.enum';
Expand All @@ -17,35 +25,44 @@ const DEFAULT_SETTINGS: Settings = {
epgUrl: [],
};

@Injectable({
providedIn: 'root',
})
export class SettingsStore {
private settings = signal<Settings>(DEFAULT_SETTINGS);
export const SettingsStore = signalStore(
{ providedIn: 'root' },
withState<Settings>(DEFAULT_SETTINGS),
withComputed((store) => ({
player: computed(() => store.player()),
showCaptions: computed(() => store.showCaptions()),
theme: computed(() => store.theme()),
})),
withMethods((store, storage = inject(StorageMap)) => ({
async loadSettings() {
const stored = await firstValueFrom(
storage.get(STORE_KEY.Settings)
);
if (stored) {
patchState(store, {
...DEFAULT_SETTINGS,
...(stored as Settings),
});
}
},

// Computed values for commonly used settings
readonly player = computed(() => this.settings().player);
readonly showCaptions = computed(() => this.settings().showCaptions);
readonly theme = computed(() => this.settings().theme);
async updateSettings(settings: Partial<Settings>) {
patchState(store, settings);
await firstValueFrom(storage.set(STORE_KEY.Settings, settings));
},

constructor(private storage: StorageMap) {
this.loadSettings();
}

async loadSettings() {
const stored = await this.storage.get(STORE_KEY.Settings).toPromise();
if (stored) {
this.settings.set({ ...DEFAULT_SETTINGS, ...(stored as Settings) });
}
}

async updateSettings(settings: Partial<Settings>) {
const newSettings = { ...this.settings(), ...settings };
this.settings.set(newSettings);
await this.storage.set(STORE_KEY.Settings, newSettings).toPromise();
}

getSettings() {
return this.settings;
}
}
getSettings() {
return {
player: store.player(),
language: store.language(),
showCaptions: store.showCaptions(),
theme: store.theme(),
mpvPlayerPath: store.mpvPlayerPath(),
vlcPlayerPath: store.vlcPlayerPath(),
remoteControl: store.remoteControl(),
remoteControlPort: store.remoteControlPort(),
epgUrl: store.epgUrl(),
};
},
}))
);
2 changes: 2 additions & 0 deletions src/app/settings/settings.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ <h2 mat-dialog-title>{{ 'SETTINGS.TITLE' | translate }}</h2>
></mat-checkbox>
</div>
</div>
<!-- not ported to tauri yet
@if (isPwa || isTauri) {
<mat-divider />
<div class="row">
Expand All @@ -226,6 +227,7 @@ <h2 mat-dialog-title>{{ 'SETTINGS.TITLE' | translate }}</h2>
</div>
</div>
}
-->
@if (settingsForm.value.remoteControl === true) {
<mat-divider />
<div class="row">
Expand Down
14 changes: 11 additions & 3 deletions src/app/settings/settings.component.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
/* eslint-disable @typescript-eslint/no-base-to-string */
import { CommonModule } from '@angular/common';
import { Component, Inject, Input, OnInit, Optional } from '@angular/core';
import {
Component,
inject,
Inject,
Input,
OnInit,
Optional,
} from '@angular/core';
import {
FormArray,
FormBuilder,
Expand Down Expand Up @@ -136,6 +143,8 @@ export class SettingsComponent implements OnInit {
/** Form array with epg sources */
epgUrl = this.settingsForm.get('epgUrl') as FormArray;

private settingsStore = inject(SettingsStore);

/**
* Creates an instance of SettingsComponent and injects
* required dependencies into the component
Expand All @@ -152,7 +161,6 @@ export class SettingsComponent implements OnInit {
private store: Store,
private translate: TranslateService,
private matDialog: MatDialog,
private settingsStore: SettingsStore,
@Optional() @Inject(MAT_DIALOG_DATA) data?: { isDialog: boolean }
) {
this.isDialog = data?.isDialog ?? false;
Expand All @@ -172,7 +180,7 @@ export class SettingsComponent implements OnInit {
*/
async setSettings() {
await this.settingsStore.loadSettings();
const currentSettings = this.settingsStore.getSettings()();
const currentSettings = this.settingsStore.getSettings();
this.settingsForm.patchValue(currentSettings);

if (this.isTauri && currentSettings.epgUrl) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,13 +106,13 @@ export class LiveStreamLayoutComponent implements OnInit {

openPlayer(streamUrl: string, title: string, thumbnail: string) {
this.streamUrl = streamUrl;
this.player = this.settings()?.player ?? VideoPlayer.VideoJs;
this.player = this.settingsStore.player() ?? VideoPlayer.VideoJs;
if (this.player === VideoPlayer.MPV) {
if (!this.hideExternalInfoDialog())
this.dialog.open(ExternalPlayerInfoDialogComponent);
this.dataService.sendIpcEvent(OPEN_MPV_PLAYER, {
url: streamUrl,
mpvPlayerPath: this.settings()?.mpvPlayerPath,
mpvPlayerPath: this.settingsStore.mpvPlayerPath(),
title,
thumbnail,
});
Expand All @@ -121,7 +121,7 @@ export class LiveStreamLayoutComponent implements OnInit {
this.dialog.open(ExternalPlayerInfoDialogComponent);
this.dataService.sendIpcEvent(OPEN_VLC_PLAYER, {
url: streamUrl,
vlcPlayerPath: this.settings()?.vlcPlayerPath,
vlcPlayerPath: this.settingsStore.vlcPlayerPath(),
});
} else {
if (this.selectedContentType() !== 'live') {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
class="container"
[style.background]="
item?.info?.backdrop_path && item?.info?.backdrop_path.length > 0
? settings().theme === 'DARK_THEME'
? theme() === 'DARK_THEME'
? 'linear-gradient(to top, rgba(29,29,29,1) 0%, rgba(0,0,0,0.5) 100%), url(' +
item?.info?.backdrop_path[0] +
') repeat-x'
Expand Down
6 changes: 1 addition & 5 deletions src/app/xtream-tauri/vod-details/vod-details.component.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import { Component, OnDestroy, OnInit, inject } from '@angular/core';
import { MatButton } from '@angular/material/button';
import { MatDialog } from '@angular/material/dialog';
import { MatIcon } from '@angular/material/icon';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { ActivatedRoute } from '@angular/router';
import { Store } from '@ngrx/store';
import { TranslateModule } from '@ngx-translate/core';
import { XtreamVodDetails } from '../../../../shared/xtream-vod-details.interface';
import { DataService } from '../../services/data.service';
import { PlayerService } from '../../services/player.service';
import { SettingsStore } from '../../services/settings-store.service';
import { selectActivePlaylist } from '../../state/selectors';
Expand All @@ -27,15 +25,13 @@ import { SafePipe } from './safe.pipe';
],
})
export class VodDetailsComponent implements OnInit, OnDestroy {
private dataService = inject(DataService);
private dialog = inject(MatDialog);
private settingsStore = inject(SettingsStore);
private route = inject(ActivatedRoute);
private store = inject(Store);
private readonly xtreamStore = inject(XtreamStore);
private playerService = inject(PlayerService);

readonly settings = this.settingsStore.getSettings();
readonly theme = this.settingsStore.theme;
private readonly selectedContentType = this.xtreamStore.selectedContentType;
private readonly hideExternalInfoDialog =
this.xtreamStore.hideExternalInfoDialog;
Expand Down
34 changes: 14 additions & 20 deletions src/app/xtream/xtream-main-container.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,13 @@ import { VodDetailsComponent } from './vod-details/vod-details.component';

import { MatDialog } from '@angular/material/dialog';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { Router } from '@angular/router';
import { StorageMap } from '@ngx-pwa/local-storage';
import { TranslateModule, TranslateService } from '@ngx-translate/core';
import { Observable } from 'rxjs';
import {
XtreamSerieDetails,
XtreamSerieEpisode,
} from '../../../shared/xtream-serie-details.interface';
import { LiveStreamLayoutComponent } from '../portals/live-stream-layout/live-stream-layout.component';
import { DialogService } from '../services/dialog.service';
import { PlaylistsService } from '../services/playlists.service';
import { SettingsStore } from '../services/settings-store.service';
import { VideoPlayer } from '../settings/settings.interface';
Expand Down Expand Up @@ -115,18 +112,15 @@ type LayoutView =
],
})
export class XtreamMainContainerComponent implements OnInit {
dataService = inject(DataService);
dialog = inject(MatDialog);
dialogService = inject(DialogService);
ngZone = inject(NgZone);
playlistService = inject(PlaylistsService);
portalStore = inject(PortalStore);
router = inject(Router);
settingsStore = inject(SettingsStore);
snackBar = inject(MatSnackBar);
storage = inject(StorageMap);
store = inject(Store);
translate = inject(TranslateService);
private readonly dataService = inject(DataService);
private readonly dialog = inject(MatDialog);
private readonly ngZone = inject(NgZone);
private readonly playlistService = inject(PlaylistsService);
private readonly portalStore = inject(PortalStore);
private readonly settingsStore = inject(SettingsStore);
private readonly snackBar = inject(MatSnackBar);
private readonly store = inject(Store);
private readonly translate = inject(TranslateService);

currentPlaylist = this.store.selectSignal(selectCurrentPlaylist);
navigationContentTypes: ContentTypeNavigationItem[] = [
Expand Down Expand Up @@ -156,7 +150,7 @@ export class XtreamMainContainerComponent implements OnInit {
selectedContentType = ContentType.VODS;
currentLayout: LayoutView = 'category';
vodDetails!: XtreamVodDetails | XtreamSerieDetails;
settings = this.settingsStore.getSettings();
settings = this.settingsStore;
isLoading = true;
searchPhrase = this.portalStore.searchPhrase();
contentId: number;
Expand Down Expand Up @@ -344,20 +338,20 @@ export class XtreamMainContainerComponent implements OnInit {

openPlayer(streamUrl: string, title: string) {
this.streamUrl = streamUrl;
this.player = this.settings()?.player ?? VideoPlayer.VideoJs;
this.player = this.settingsStore.player() ?? VideoPlayer.VideoJs;
if (this.player === VideoPlayer.MPV) {
if (!this.hideExternalInfoDialog())
this.dialog.open(ExternalPlayerInfoDialogComponent);
this.dataService.sendIpcEvent(OPEN_MPV_PLAYER, {
url: streamUrl,
mpvPlayerPath: this.settings()?.mpvPlayerPath,
mpvPlayerPath: this.settingsStore.mpvPlayerPath(),
});
} else if (this.player === VideoPlayer.VLC) {
if (!this.hideExternalInfoDialog())
this.dialog.open(ExternalPlayerInfoDialogComponent);
this.dataService.sendIpcEvent(OPEN_VLC_PLAYER, {
url: streamUrl,
vlcPlayerPath: this.settings()?.vlcPlayerPath,
vlcPlayerPath: this.settingsStore.vlcPlayerPath(),
});
} else {
if (this.selectedContentType !== ContentType.ITV) {
Expand All @@ -382,7 +376,7 @@ export class XtreamMainContainerComponent implements OnInit {

playEpisode(episode: XtreamSerieEpisode) {
const { serverUrl, username, password } = this.currentPlaylist();
const player = this.settings().player;
const player = this.settingsStore.player();
const streamUrl = `${serverUrl}/series/${username}/${password}/${episode.id}.${episode.container_extension}`;
if (player === VideoPlayer.MPV) {
this.dataService.sendIpcEvent(OPEN_MPV_PLAYER, { url: streamUrl });
Expand Down

0 comments on commit 13b4cf3

Please sign in to comment.