mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-08 17:06:15 -08:00
feat(ui): use playlist-switcher in all modules
This commit is contained in:
1 parent
b9b7fc8a63
commit
6b94fcbdd6
18 files changed
+86
-125
No files matched your search
@@ -1,9 +1,10 @@
|
||||
<div class="sidebar">
|
||||
<div class="sidebar-header">
|
||||
<button mat-icon-button disabled>
|
||||
<mat-icon>list</mat-icon>
|
||||
</button>
|
||||
<h2>{{ 'PORTALS.ALL_CATEGORIES' | translate }}</h2>
|
||||
<app-playlist-switcher
|
||||
class="switcher"
|
||||
[currentTitle]="playlistTitle()"
|
||||
[subtitle]="playlistSubtitle()"
|
||||
/>
|
||||
</div>
|
||||
<app-category-view
|
||||
[items]="categories()"
|
||||
|
||||
@@ -5,6 +5,7 @@ import { MatCardModule } from '@angular/material/card';
|
||||
import { MatIcon } from '@angular/material/icon';
|
||||
import { MatTooltip } from '@angular/material/tooltip';
|
||||
import { TranslatePipe } from '@ngx-translate/core';
|
||||
import { PlaylistSwitcherComponent } from 'components';
|
||||
import { CategoryViewComponent } from '../../../xtream-tauri/category-view/category-view.component';
|
||||
|
||||
@Component({
|
||||
@@ -20,14 +21,16 @@ import { CategoryViewComponent } from '../../../xtream-tauri/category-view/categ
|
||||
MatCardModule,
|
||||
MatIcon,
|
||||
MatIconButton,
|
||||
/* MpvPlayerBarComponent, */
|
||||
MatTooltip,
|
||||
PlaylistSwitcherComponent,
|
||||
TranslatePipe,
|
||||
],
|
||||
})
|
||||
export class FavoritesLayoutComponent {
|
||||
readonly categories = input<any[]>([]);
|
||||
readonly favorites = input<any[]>([]);
|
||||
readonly playlistSubtitle = input<string>('');
|
||||
readonly playlistTitle = input<string>('Playlist');
|
||||
readonly selectedCategoryId = input<string>('movie');
|
||||
readonly titleTranslationString = input<string>('CHANNELS.FAVORITES');
|
||||
|
||||
|
||||
@@ -31,10 +31,12 @@
|
||||
<app-favorites-layout
|
||||
[categories]="categories() ?? []"
|
||||
[favorites]="itemsToShow() ?? []"
|
||||
[playlistSubtitle]="'Stalker Portal'"
|
||||
[playlistTitle]="currentPlaylist()?.title || 'Portal'"
|
||||
[selectedCategoryId]="selectedCategoryId()"
|
||||
[titleTranslationString]="'PORTALS.SIDEBAR.RECENT'"
|
||||
(categoryClicked)="setCategoryId($event.category_id)"
|
||||
(removeFavorite)="removeFromRecentlyViewed($event)"
|
||||
[titleTranslationString]="'PORTALS.SIDEBAR.RECENT'"
|
||||
(openItem)="openItem($event)"
|
||||
/>
|
||||
}
|
||||
@@ -43,6 +43,8 @@ export class RecentlyViewedComponent {
|
||||
|
||||
itemDetails: any = null;
|
||||
|
||||
readonly currentPlaylist = this.stalkerStore.currentPlaylist;
|
||||
|
||||
readonly allFavorites = rxResource({
|
||||
params: () => ({
|
||||
refreshTimestamp: this.refreshTimestamp(),
|
||||
|
||||
@@ -29,6 +29,8 @@
|
||||
<app-favorites-layout
|
||||
[categories]="categories() ?? []"
|
||||
[favorites]="favoritesToShow() ?? []"
|
||||
[playlistSubtitle]="'Stalker Portal'"
|
||||
[playlistTitle]="currentPlaylist()?.title || 'Portal'"
|
||||
[selectedCategoryId]="selectedCategoryId()"
|
||||
(categoryClicked)="setCategoryId($event.category_id)"
|
||||
(removeFavorite)="removeFromFavorites($event)"
|
||||
|
||||
@@ -43,6 +43,8 @@ export class StalkerFavoritesComponent {
|
||||
|
||||
itemDetails: any = null;
|
||||
|
||||
readonly currentPlaylist = this.stalkerStore.currentPlaylist;
|
||||
|
||||
readonly allFavorites = rxResource({
|
||||
params: () => ({
|
||||
refreshTimestamp: this.refreshTimestamp(),
|
||||
|
||||
@@ -9,10 +9,11 @@
|
||||
</button>
|
||||
<h2>{{ selectedCategoryTitle() }}</h2>
|
||||
} @else {
|
||||
<button mat-icon-button disabled>
|
||||
<mat-icon>list</mat-icon>
|
||||
</button>
|
||||
<h2>{{ 'PORTALS.ALL_CATEGORIES' | translate }}</h2>
|
||||
<app-playlist-switcher
|
||||
class="switcher"
|
||||
[currentTitle]="currentPlaylist()?.title || 'Portal'"
|
||||
[subtitle]="'Stalker Portal'"
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
@if (isItvCategorySelected) {
|
||||
|
||||
@@ -8,6 +8,7 @@ import { ActivatedRoute, Router, RouterOutlet } from '@angular/router';
|
||||
import { TranslatePipe } from '@ngx-translate/core';
|
||||
import { NgxSkeletonLoaderModule } from 'ngx-skeleton-loader';
|
||||
import { PlaylistsService } from 'services';
|
||||
import { PlaylistSwitcherComponent } from 'components';
|
||||
import { CategoryViewComponent } from '../xtream-tauri/category-view/category-view.component';
|
||||
import { PlaylistErrorViewComponent } from '../xtream/playlist-error-view/playlist-error-view.component';
|
||||
import { StalkerStore } from './stalker.store';
|
||||
@@ -27,11 +28,11 @@ import { StalkerStore } from './stalker.store';
|
||||
MatIconButton,
|
||||
MatListModule,
|
||||
MatPaginatorModule,
|
||||
/* MpvPlayerBarComponent, */
|
||||
NgxSkeletonLoaderModule,
|
||||
PlaylistErrorViewComponent,
|
||||
TranslatePipe,
|
||||
PlaylistSwitcherComponent,
|
||||
RouterOutlet,
|
||||
TranslatePipe,
|
||||
],
|
||||
})
|
||||
export class StalkerMainContainerComponent {
|
||||
@@ -54,6 +55,7 @@ export class StalkerMainContainerComponent {
|
||||
readonly itvChannels = this.stalkerStore.itvChannels;
|
||||
|
||||
readonly selectedCategoryTitle = this.stalkerStore.getSelectedCategoryName;
|
||||
readonly currentPlaylist = this.stalkerStore.currentPlaylist;
|
||||
|
||||
/** categories */
|
||||
readonly categories = this.stalkerStore.getCategoryResource;
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
<app-favorites-layout
|
||||
[categories]="categories()"
|
||||
[favorites]="favoritesToShow()"
|
||||
[playlistSubtitle]="'Xtream Code'"
|
||||
[playlistTitle]="currentPlaylist()?.name || currentPlaylist()?.title || 'Playlist'"
|
||||
[selectedCategoryId]="selectedCategoryId()"
|
||||
(categoryClicked)="setCategoryId($event.category_id)"
|
||||
(removeFavorite)="removeFromFavorites($event)"
|
||||
|
||||
@@ -24,6 +24,7 @@ export class FavoritesComponent implements OnInit {
|
||||
private xtreamStore = inject(XtreamStore);
|
||||
|
||||
readonly categories = signal<XtreamCategory[]>([]);
|
||||
readonly currentPlaylist = this.xtreamStore.currentPlaylist;
|
||||
|
||||
readonly series = signal<FavoriteItem[]>([]);
|
||||
readonly movies = signal<FavoriteItem[]>([]);
|
||||
|
||||
@@ -9,10 +9,11 @@
|
||||
</button>
|
||||
<h2>{{ 'HOME.PLAYLISTS.CHANNELS' | translate }}</h2>
|
||||
} @else {
|
||||
<button mat-icon-button disabled>
|
||||
<mat-icon>list</mat-icon>
|
||||
</button>
|
||||
<h2>{{ 'PORTALS.ALL_CATEGORIES' | translate }}</h2>
|
||||
<app-playlist-switcher
|
||||
class="switcher"
|
||||
[currentTitle]="currentPlaylist()?.name || currentPlaylist()?.title || 'Playlist'"
|
||||
[subtitle]="'Xtream Code'"
|
||||
/>
|
||||
<button
|
||||
mat-icon-button
|
||||
class="manage-categories-btn"
|
||||
|
||||
@@ -14,6 +14,7 @@ import { MatListModule } from '@angular/material/list';
|
||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { TranslatePipe } from '@ngx-translate/core';
|
||||
import { PlaylistSwitcherComponent } from 'components';
|
||||
import { XtreamCategory } from 'shared-interfaces';
|
||||
import { EpgViewComponent, WebPlayerViewComponent } from 'shared-portals';
|
||||
import { SettingsStore } from '../../services/settings-store.service';
|
||||
@@ -41,6 +42,7 @@ import { XtreamStore } from '../xtream.store';
|
||||
MatListModule,
|
||||
MatTooltipModule,
|
||||
/* MpvPlayerBarComponent, */
|
||||
PlaylistSwitcherComponent,
|
||||
PortalChannelsListComponent,
|
||||
TranslatePipe,
|
||||
WebPlayerViewComponent,
|
||||
@@ -56,6 +58,7 @@ export class LiveStreamLayoutComponent implements OnInit {
|
||||
|
||||
readonly categories = this.xtreamStore.getCategoriesBySelectedType;
|
||||
readonly categoryItemCounts = this.xtreamStore.getCategoryItemCounts;
|
||||
readonly currentPlaylist = this.xtreamStore.currentPlaylist;
|
||||
readonly epgItems = this.xtreamStore.epgItems;
|
||||
readonly selectedCategoryId = this.xtreamStore.selectedCategoryId;
|
||||
|
||||
|
||||
@@ -23,6 +23,11 @@
|
||||
app-region: no-drag;
|
||||
}
|
||||
|
||||
.switcher {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.manage-categories-btn {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
<div class="sidebar">
|
||||
<div class="sidebar-header">
|
||||
<button mat-icon-button disabled>
|
||||
<mat-icon>list</mat-icon>
|
||||
</button>
|
||||
<h2>{{ 'PORTALS.ALL_CATEGORIES' | translate }}</h2>
|
||||
<app-playlist-switcher
|
||||
class="switcher"
|
||||
[currentTitle]="currentPlaylist()?.name || currentPlaylist()?.title || 'Playlist'"
|
||||
[subtitle]="'Xtream Code'"
|
||||
/>
|
||||
<button
|
||||
mat-icon-button
|
||||
class="manage-categories-btn"
|
||||
|
||||
@@ -5,6 +5,7 @@ import { MatIcon } from '@angular/material/icon';
|
||||
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||
import { ActivatedRoute, Router, RouterOutlet } from '@angular/router';
|
||||
import { TranslateModule, TranslateService } from '@ngx-translate/core';
|
||||
import { PlaylistSwitcherComponent } from 'components';
|
||||
import { XtreamCategory } from 'shared-interfaces';
|
||||
import {
|
||||
CategoryManagementDialogComponent,
|
||||
@@ -19,12 +20,12 @@ import { XtreamStore } from './xtream.store';
|
||||
styleUrls: ['./xtream-main-container.component.scss', './sidebar.scss'],
|
||||
imports: [
|
||||
CategoryViewComponent,
|
||||
TranslateModule,
|
||||
RouterOutlet,
|
||||
/* MpvPlayerBarComponent, */
|
||||
MatIcon,
|
||||
MatIconButton,
|
||||
MatTooltipModule,
|
||||
PlaylistSwitcherComponent,
|
||||
RouterOutlet,
|
||||
TranslateModule,
|
||||
],
|
||||
})
|
||||
export class XtreamMainContainerComponent implements OnInit {
|
||||
@@ -36,7 +37,7 @@ export class XtreamMainContainerComponent implements OnInit {
|
||||
|
||||
readonly categories = this.xtreamStore.getCategoriesBySelectedType;
|
||||
readonly categoryItemCounts = this.xtreamStore.getCategoryItemCounts;
|
||||
|
||||
readonly currentPlaylist = this.xtreamStore.currentPlaylist;
|
||||
readonly selectedCategoryId = this.xtreamStore.selectedCategoryId;
|
||||
|
||||
ngOnInit(): void {
|
||||
|
||||
@@ -1,50 +1,18 @@
|
||||
<div class="current-playlist">
|
||||
<div class="left">
|
||||
<button
|
||||
mat-icon-button
|
||||
[matTooltip]="'SETTINGS.BACK_TO_HOME' | translate"
|
||||
(click)="goBack()"
|
||||
>
|
||||
<mat-icon>arrow_back_ios</mat-icon>
|
||||
</button>
|
||||
<div class="playlist-info">
|
||||
<div class="name">
|
||||
@if (sidebarView === 'CHANNELS') {
|
||||
{{ playlistTitle$ | async }}
|
||||
} @else {
|
||||
{{ 'HOME.PLAYLISTS.MY_PLAYLISTS' | translate }}
|
||||
}
|
||||
</div>
|
||||
<div class="channels-count">
|
||||
{{
|
||||
sidebarView === 'CHANNELS'
|
||||
? channels()?.length +
|
||||
' ' +
|
||||
('HOME.PLAYLISTS.CHANNELS' | translate)
|
||||
: ('HOME.PLAYLISTS.MY_PLAYLISTS_SUBTITLE' | translate)
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
mat-icon-button
|
||||
routerLink="/"
|
||||
[matTooltip]="'SETTINGS.BACK_TO_HOME' | translate"
|
||||
class="home-btn"
|
||||
>
|
||||
<mat-icon>home</mat-icon>
|
||||
</button>
|
||||
|
||||
@if (sidebarView === 'CHANNELS') {
|
||||
<button
|
||||
mat-icon-button
|
||||
routerLink="/"
|
||||
[matTooltip]="
|
||||
'CHANNELS.UPLOAD_OR_SELECT_OTHER_PLAYLIST' | translate
|
||||
"
|
||||
>
|
||||
<mat-icon>playlist_add</mat-icon>
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
@if (sidebarView === 'CHANNELS') {
|
||||
<app-channel-list-container [channelList]="channels()" />
|
||||
} @else {
|
||||
<app-recent-playlists
|
||||
class="recent-playlists"
|
||||
[sidebarMode]="true"
|
||||
(playlistClicked)="selectPlaylist()"
|
||||
<app-playlist-switcher
|
||||
class="switcher"
|
||||
[currentTitle]="playlistTitle()"
|
||||
[subtitle]="subtitle()"
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
|
||||
<app-channel-list-container [channelList]="channels()" />
|
||||
@@ -2,45 +2,21 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 8px;
|
||||
justify-content: space-between;
|
||||
gap: 4px;
|
||||
app-region: drag;
|
||||
|
||||
.left {
|
||||
display: flex;
|
||||
gap: 5px;
|
||||
}
|
||||
|
||||
button {
|
||||
app-region: no-drag;
|
||||
}
|
||||
}
|
||||
|
||||
.playlist-info {
|
||||
flex: 1;
|
||||
max-width: 300px;
|
||||
|
||||
.name {
|
||||
font-size: 1.1em;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
.switcher {
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.channels-count {
|
||||
font-size: 0.8em;
|
||||
}
|
||||
}
|
||||
|
||||
.recent-playlists {
|
||||
height: calc(100vh - 60px);
|
||||
overflow: auto;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@media only screen and (max-width: 480px) {
|
||||
.playlist-info {
|
||||
.name {
|
||||
max-width: 105px;
|
||||
}
|
||||
.current-playlist {
|
||||
padding: 6px;
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,13 @@
|
||||
import { AsyncPipe } from '@angular/common';
|
||||
import { Component, inject, input } from '@angular/core';
|
||||
import { Component, computed, inject, input } from '@angular/core';
|
||||
import { MatIconButton } from '@angular/material/button';
|
||||
import { MatIcon } from '@angular/material/icon';
|
||||
import { MatTooltip } from '@angular/material/tooltip';
|
||||
import { Router, RouterLink } from '@angular/router';
|
||||
import { RouterLink } from '@angular/router';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { TranslatePipe } from '@ngx-translate/core';
|
||||
import { ChannelActions } from 'm3u-state';
|
||||
import { TranslatePipe, TranslateService } from '@ngx-translate/core';
|
||||
import { selectPlaylistTitle } from 'm3u-state';
|
||||
import { Channel, SidebarView } from 'shared-interfaces';
|
||||
import { RecentPlaylistsComponent } from '../../recent-playlists/recent-playlists.component';
|
||||
import { Channel } from 'shared-interfaces';
|
||||
import { PlaylistSwitcherComponent } from '../../playlist-switcher/playlist-switcher.component';
|
||||
import { ChannelListContainerComponent } from './../../channel-list-container/channel-list-container.component';
|
||||
|
||||
@Component({
|
||||
@@ -17,12 +15,11 @@ import { ChannelListContainerComponent } from './../../channel-list-container/ch
|
||||
templateUrl: './sidebar.component.html',
|
||||
styleUrls: ['./sidebar.component.scss'],
|
||||
imports: [
|
||||
AsyncPipe,
|
||||
ChannelListContainerComponent,
|
||||
MatIcon,
|
||||
MatIconButton,
|
||||
MatTooltip,
|
||||
RecentPlaylistsComponent,
|
||||
PlaylistSwitcherComponent,
|
||||
RouterLink,
|
||||
TranslatePipe,
|
||||
],
|
||||
@@ -30,22 +27,13 @@ import { ChannelListContainerComponent } from './../../channel-list-container/ch
|
||||
export class SidebarComponent {
|
||||
readonly channels = input<Channel[]>([]);
|
||||
|
||||
private readonly router = inject(Router);
|
||||
private readonly store = inject(Store);
|
||||
private readonly translate = inject(TranslateService);
|
||||
|
||||
readonly playlistTitle$ = this.store.select(selectPlaylistTitle);
|
||||
sidebarView: SidebarView = 'CHANNELS';
|
||||
readonly playlistTitle = this.store.selectSignal(selectPlaylistTitle);
|
||||
|
||||
goBack() {
|
||||
if (this.sidebarView === 'PLAYLISTS') {
|
||||
this.store.dispatch(ChannelActions.resetActiveChannel());
|
||||
this.router.navigate(['/']);
|
||||
} else {
|
||||
this.sidebarView = 'PLAYLISTS';
|
||||
}
|
||||
}
|
||||
|
||||
selectPlaylist() {
|
||||
this.sidebarView = 'CHANNELS';
|
||||
}
|
||||
readonly subtitle = computed(() => {
|
||||
const count = this.channels()?.length ?? 0;
|
||||
return `${count} ${this.translate.instant('HOME.PLAYLISTS.CHANNELS')}`;
|
||||
});
|
||||
}
|
||||
Reference in new issue
Block a user