mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-08 17:06:15 -08:00
feat: added favorites for xtream live streams
This commit is contained in:
1 parent
4589adc52f
commit
b84d807882
6 files changed
+102
-11
No files matched your search
+2
-2
@@ -53,7 +53,7 @@ function createWindow(): BrowserWindow {
|
||||
require('@electron/remote/main').enable(win.webContents);
|
||||
|
||||
if (serve) {
|
||||
win.webContents.openDevTools();
|
||||
win.on('ready-to-show', () => win?.webContents.openDevTools());
|
||||
win.loadURL('http://localhost:4200');
|
||||
} else {
|
||||
win.loadURL(
|
||||
@@ -120,7 +120,7 @@ try {
|
||||
const menu = new AppMenu(win);
|
||||
Menu.setApplicationMenu(menu.getMenu());
|
||||
api.setMainWindow(win);
|
||||
|
||||
|
||||
// create hidden window for epg worker
|
||||
createEpgWorkerWindow();
|
||||
});
|
||||
|
||||
@@ -147,7 +147,16 @@ export class PlaylistsService {
|
||||
DbStores.Playlists,
|
||||
portalId
|
||||
)
|
||||
.pipe(map((item) => item.favorites ?? []));
|
||||
.pipe(map((item) => item.favorites.filter(itm => itm && itm.stream_type && itm.stream_type !== 'live') ?? []));
|
||||
}
|
||||
|
||||
getPortalLiveStreamFavorites(portalId: string) {
|
||||
return this.dbService
|
||||
.getByID<{ favorites: Partial<XtreamItem>[] }>(
|
||||
DbStores.Playlists,
|
||||
portalId
|
||||
)
|
||||
.pipe(map((item) => item.favorites.filter(itm => itm && itm.stream_type && itm.stream_type === 'live') ?? []));
|
||||
}
|
||||
|
||||
addPortalFavorite(portalId: string, item: any) {
|
||||
|
||||
@@ -51,6 +51,22 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="search-container">
|
||||
<div class="favorite">
|
||||
<button
|
||||
*ngIf="favoriteVisible && activeLiveStream"
|
||||
mat-icon-button
|
||||
(click)="clickFavorites()"
|
||||
[matTooltip]="'TOP_MENU.TOGGLE_FAVORITE_FLAG' | translate"
|
||||
>
|
||||
<mat-icon>
|
||||
{{
|
||||
isFavoriteStream
|
||||
? 'star'
|
||||
: 'star_outline'
|
||||
}}
|
||||
</mat-icon>
|
||||
</button>
|
||||
</div>
|
||||
<div class="sort" *ngIf="sortVisible">
|
||||
<button
|
||||
mat-icon-button
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { NgFor, NgIf } from '@angular/common';
|
||||
import { Component, EventEmitter, Input, Output, inject } from '@angular/core';
|
||||
import { NgFor, NgIf, AsyncPipe } from '@angular/common';
|
||||
import { Component, EventEmitter, Input, Output, inject, OnChanges, SimpleChanges } from '@angular/core';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatButtonToggleModule } from '@angular/material/button-toggle';
|
||||
@@ -10,7 +10,7 @@ import { MatInputModule } from '@angular/material/input';
|
||||
import { RouterLink } from '@angular/router';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { Subject, debounceTime, distinctUntilChanged } from 'rxjs';
|
||||
import { Observable, Subject, debounceTime, distinctUntilChanged, map } from 'rxjs';
|
||||
import { PlaylistInfoComponent } from '../../home/recent-playlists/playlist-info/playlist-info.component';
|
||||
import { selectCurrentPlaylist } from '../../state/selectors';
|
||||
import { Breadcrumb } from '../breadcrumb.interface';
|
||||
@@ -20,6 +20,7 @@ import { PortalStore } from '../portal.store';
|
||||
import { MatMenuModule } from '@angular/material/menu';
|
||||
import { MatCheckboxModule } from '@angular/material/checkbox';
|
||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
import { XtreamLiveStream } from '../../../../shared/xtream-live-stream.interface';
|
||||
|
||||
@Component({
|
||||
selector: 'app-navigation-bar',
|
||||
@@ -39,10 +40,11 @@ import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
TranslateModule,
|
||||
MatMenuModule,
|
||||
MatCheckboxModule,
|
||||
MatTooltipModule
|
||||
MatTooltipModule,
|
||||
AsyncPipe
|
||||
],
|
||||
})
|
||||
export class NavigationBarComponent {
|
||||
export class NavigationBarComponent implements OnChanges {
|
||||
@Input({ required: true }) breadcrumbs: Breadcrumb[];
|
||||
@Input({ required: true }) contentType: ContentType;
|
||||
@Input() searchVisible = true;
|
||||
@@ -50,12 +52,17 @@ export class NavigationBarComponent {
|
||||
@Input() contentTypeNavigationItems: ContentTypeNavigationItem[];
|
||||
@Input() clientSideSearch = true;
|
||||
@Input() showCategories = false;
|
||||
@Input() activeLiveStream!: XtreamLiveStream;
|
||||
@Input() favoritesLiveStream$: Observable<any>;
|
||||
@Input() favoriteVisible = false;
|
||||
|
||||
@Output() contentTypeChanged = new EventEmitter<ContentType>();
|
||||
@Output() breadcrumbClicked = new EventEmitter<Breadcrumb>();
|
||||
@Output() favoritesClicked = new EventEmitter<void>();
|
||||
@Output() searchTextChanged = new EventEmitter<string>();
|
||||
|
||||
@Output() addToFavoritesClicked = new EventEmitter<any>();
|
||||
@Output() removeFromFavoritesClicked = new EventEmitter<number>();
|
||||
|
||||
ContentTypeEnum = ContentType;
|
||||
dialog = inject(MatDialog);
|
||||
portalStore = inject(PortalStore);
|
||||
@@ -64,6 +71,7 @@ export class NavigationBarComponent {
|
||||
searchPhraseUpdate = new Subject<string>();
|
||||
currentPlaylist = this.store.selectSignal(selectCurrentPlaylist);
|
||||
sortType = this.portalStore.sortType;
|
||||
isFavoriteStream = false;
|
||||
|
||||
constructor() {
|
||||
this.searchPhraseUpdate
|
||||
@@ -101,4 +109,36 @@ export class NavigationBarComponent {
|
||||
trackByValue(_i: number, value: ContentTypeNavigationItem) {
|
||||
return value.contentType;
|
||||
}
|
||||
|
||||
clickFavorites(): void {
|
||||
const item = this.activeLiveStream;
|
||||
if (!this.isFavoriteStream) {
|
||||
this.addToFavoritesClicked.emit({
|
||||
name: item.name,
|
||||
stream_id: item.stream_id,
|
||||
cover: item.stream_icon,
|
||||
stream_type: 'live'
|
||||
});
|
||||
this.isFavoriteStream = true;
|
||||
} else {
|
||||
this.removeFromFavoritesClicked.emit(item.stream_id);
|
||||
this.isFavoriteStream = false;
|
||||
}
|
||||
}
|
||||
|
||||
ngOnChanges(changes: SimpleChanges) {
|
||||
if (changes.activeLiveStream && this.activeLiveStream) {
|
||||
this.checkFavorite();
|
||||
}
|
||||
}
|
||||
|
||||
checkFavorite() {
|
||||
// if activeLiveStream.stream_id include in favorites return the true
|
||||
const activeLiveStream = this.activeLiveStream;
|
||||
this.favoritesLiveStream$.pipe(
|
||||
map(favorites => favorites.some(fav => fav.stream_id === activeLiveStream.stream_id))
|
||||
).subscribe(isFavorite => {
|
||||
this.isFavoriteStream = isFavorite;
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,12 @@
|
||||
currentLayout === 'category' || currentLayout === 'category_content'
|
||||
"
|
||||
[sortVisible]="currentLayout === 'category_content'"
|
||||
[favoriteVisible]="currentLayout === 'category_content' || currentLayout === 'live-stream-favorites'"
|
||||
[contentTypeNavigationItems]="navigationContentTypes"
|
||||
[activeLiveStream]="activeLiveStream"
|
||||
[favoritesLiveStream$]="favoritesLiveStream$"
|
||||
(addToFavoritesClicked)="addToFavorites($event)"
|
||||
(removeFromFavoritesClicked)="removeFromFavorites($event)"
|
||||
/>
|
||||
|
||||
@if (isLoading) {
|
||||
@@ -68,5 +73,14 @@
|
||||
(itemClicked)="itemClicked($event)"
|
||||
/>
|
||||
}
|
||||
@case ('live-stream-favorites') {
|
||||
<app-live-stream-layout
|
||||
[channels]="favoritesLiveStream$"
|
||||
[player]="player"
|
||||
[streamUrl]="streamUrl"
|
||||
[epgItems]="epgItems"
|
||||
(itemClicked)="itemClicked($event)"
|
||||
/>
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -102,7 +102,8 @@ type LayoutView =
|
||||
| 'player'
|
||||
| 'serie-details'
|
||||
| 'favorites'
|
||||
| 'error-view';
|
||||
| 'error-view'
|
||||
| 'live-stream-favorites';
|
||||
|
||||
@Component({
|
||||
selector: 'app-xtream-main-container',
|
||||
@@ -167,6 +168,7 @@ export class XtreamMainContainerComponent implements OnInit {
|
||||
|
||||
player: VideoPlayer;
|
||||
favorites$: Observable<any>;
|
||||
favoritesLiveStream$: Observable<any>;
|
||||
breadcrumbs: Breadcrumb[] = [];
|
||||
items = [];
|
||||
listeners = [];
|
||||
@@ -183,6 +185,7 @@ export class XtreamMainContainerComponent implements OnInit {
|
||||
streamUrl: string;
|
||||
epgItems = [];
|
||||
hideExternalInfoDialog = this.portalStore.hideExternalInfoDialog;
|
||||
activeLiveStream: XtreamLiveStream;
|
||||
|
||||
commandsList = [
|
||||
new IpcCommand(XTREAM_RESPONSE, (response: XtreamResponse) =>
|
||||
@@ -200,6 +203,9 @@ export class XtreamMainContainerComponent implements OnInit {
|
||||
this.favorites$ = this.playlistService.getPortalFavorites(
|
||||
this.currentPlaylist()._id
|
||||
);
|
||||
this.favoritesLiveStream$ = this.playlistService.getPortalLiveStreamFavorites(
|
||||
this.currentPlaylist()._id
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -332,6 +338,7 @@ export class XtreamMainContainerComponent implements OnInit {
|
||||
stream_id: item.stream_id,
|
||||
limit: 10,
|
||||
});
|
||||
this.activeLiveStream = item;
|
||||
this.playLiveStream(item);
|
||||
} else if (item.series_id) {
|
||||
this.items = [];
|
||||
@@ -527,7 +534,12 @@ export class XtreamMainContainerComponent implements OnInit {
|
||||
}
|
||||
|
||||
favoritesClicked() {
|
||||
this.currentLayout = 'favorites';
|
||||
if (this.selectedContentType === ContentType.ITV) {
|
||||
this.currentLayout = 'live-stream-favorites';
|
||||
} else {
|
||||
this.currentLayout = 'favorites';
|
||||
}
|
||||
this.setInitialBreadcrumb();
|
||||
}
|
||||
|
||||
}
|
||||
Reference in new issue
Block a user