feat(xtream): refactor layout structure and add new shell component for improved navigation

This commit is contained in:
4gray committed 2024-12-24 01:01:00 +01:00
1 parent 483f0525f3
commit e4569556a1
6 files changed
+123 -129

No files matched your search

@@ -1,46 +1,23 @@
@if (xtreamStore.isImporting()) {
<app-loading-overlay
[current]="xtreamStore.getImportCount()"
[total]="xtreamStore.itemsToImport()"
/>
}
<div class="xtream-container">
<div class="sidebar navigation-sidebar">
<app-navigation />
</div>
@if (
xtreamStore.selectedContentType() === 'vod' ||
xtreamStore.selectedContentType() === 'series'
) {
<div class="sidebar">
<div class="sidebar-header">
<h2>Categories</h2>
</div>
<app-category-view (categoryClicked)="categoryClicked($event)" />
</div>
}
<div class="main-content">
@if (
xtreamStore.selectedContentType() === 'vod' ||
xtreamStore.selectedContentType() === 'series'
) {
<div class="content-header">
<h2>
@if (xtreamStore.selectedItem()) {
<button mat-icon-button (click)="historyBack()">
<mat-icon>chevron_left</mat-icon>
</button>
}
{{ getContentLabel() }}
</h2>
</div>
}
<div class="scrollable-content">
<router-outlet />
</div>
<app-mpv-player-bar />
<div class="sidebar">
<div class="sidebar-header">
<h2>Categories</h2>
</div>
<app-category-view (categoryClicked)="categoryClicked($event)" />
</div>
<div class="main-content">
<div class="content-header">
<h2>
@if (xtreamStore.selectedItem()) {
<button mat-icon-button (click)="historyBack()">
<mat-icon>chevron_left</mat-icon>
</button>
}
{{ getContentLabel() }}
</h2>
</div>
<div class="scrollable-content">
<router-outlet />
</div>
<app-mpv-player-bar />
</div>
@@ -1,37 +1,9 @@
:host {
display: flex;
flex-direction: column;
flex-direction: row; // Changed from column to row
overflow: hidden;
height: 100%;
}
.xtream-container {
display: flex;
flex: 1;
overflow: hidden;
min-height: 0; // Important for proper flex behavior
}
.sidebar {
width: 300px;
border-right: 1px solid #333;
display: flex;
flex-direction: column;
.sidebar-header {
padding: 16px;
border-bottom: 1px solid rgba(0, 0, 0, 0.12);
h2 {
margin: 0;
font-size: 1.2rem;
font-weight: 500;
}
}
}
.navigation-sidebar {
width: 200px;
width: 100%; // Added to ensure full width
}
.main-content {
@@ -39,23 +11,23 @@
display: flex;
flex-direction: column;
min-height: 0; // Important for proper flex behavior
}
.content-header {
padding: 16px;
border-bottom: 1px solid rgba(0, 0, 0, 0.12);
.content-header {
padding: 16px;
border-bottom: 1px solid rgba(0, 0, 0, 0.12);
h2 {
margin: 0;
font-size: 1.2rem;
font-weight: 500;
display: flex;
align-items: center;
gap: 10px;
}
h2 {
margin: 0;
font-size: 1.2rem;
font-weight: 500;
display: flex;
align-items: center;
gap: 10px;
}
}
.scrollable-content {
flex: 1;
overflow-y: auto;
}
}
.scrollable-content {
flex: 1;
overflow-y: auto;
}
@@ -1,4 +1,4 @@
import { Component, effect, inject } from '@angular/core';
import { Component, inject } from '@angular/core';
import { Store } from '@ngrx/store';
import { CategoryViewComponent } from './category-view/category-view.component';
@@ -8,27 +8,21 @@ import { ActivatedRoute, Router, RouterOutlet } from '@angular/router';
import { TranslateModule } from '@ngx-translate/core';
import { XtreamCategory } from '../../../shared/xtream-category.interface';
import { MpvPlayerBarComponent } from '../shared/components/mpv-player-bar/mpv-player-bar.component';
import * as PlaylistActions from '../state/actions';
import { LoadingOverlayComponent } from './loading-overlay/loading-overlay.component';
import { NavigationComponent } from './navigation/navigation.component';
import { XtreamStore } from './xtream.store';
@Component({
selector: 'app-xtream-main-container',
templateUrl: './xtream-main-container.component.html',
styleUrls: ['./xtream-main-container.component.scss'],
styleUrls: ['./xtream-main-container.component.scss', './sidebar.scss'],
standalone: true,
imports: [
CategoryViewComponent,
TranslateModule,
RouterOutlet,
NavigationComponent,
LoadingOverlayComponent,
MpvPlayerBarComponent,
MatIcon,
MatIconButton,
],
providers: [XtreamStore],
})
export class XtreamMainContainerComponent {
readonly xtreamStore = inject(XtreamStore);
@@ -38,33 +32,10 @@ export class XtreamMainContainerComponent {
constructor(
private router: Router,
private route: ActivatedRoute
) {
effect(
() => {
if (this.xtreamStore.currentPlaylist() !== null) {
console.log(
'Initializing content...',
this.xtreamStore.currentPlaylist()
);
this.xtreamStore.initializeContent();
}
},
{ allowSignalWrites: true }
);
}
ngOnInit() {
this.store.dispatch(
PlaylistActions.setActivePlaylist({
playlistId: this.route.snapshot.params.id,
})
);
//this.xtreamStore.fetchXtreamPlaylist();
}
) {}
categoryClicked(category: XtreamCategory) {
const categoryId = (category as any).category_id ?? category.id;
console.log('Category clicked:', category);
this.xtreamStore.setSelectedCategory(Number(categoryId));
this.router.navigate([categoryId], {
@@ -79,8 +50,6 @@ export class XtreamMainContainerComponent {
) {
return 'Select a category';
} else {
// TODO: Fix this
//console.log(this.xtreamStore.getSelectedCategory());
const selectedCategory = this.xtreamStore.getSelectedCategory();
return selectedCategory
? `Content for ${(selectedCategory as any).name}`
@@ -89,10 +58,8 @@ export class XtreamMainContainerComponent {
}
historyBack() {
this.router.navigate([
'./xtreams',
this.xtreamStore.currentPlaylist().id,
this.xtreamStore.selectedCategoryId(),
]);
this.router.navigate(['.', this.xtreamStore.selectedCategoryId()], {
relativeTo: this.route,
});
}
}
@@ -0,0 +1,11 @@
@if (isImporting()) {
<app-loading-overlay
[current]="getImportCount()"
[total]="itemsToImport()"
/>
}
<div class="xtream-container">
<app-navigation class="navigation-sidebar" />
<router-outlet />
</div>
@@ -0,0 +1,18 @@
:host {
display: flex;
flex-direction: column;
overflow: hidden;
height: 100%;
}
.xtream-container {
display: flex;
flex: 1;
overflow: hidden;
min-height: 0; // Important for proper flex behavior
}
.navigation-sidebar {
width: 200px;
border-right: 1px solid #333;
}
@@ -0,0 +1,49 @@
import { Component, effect, inject } from '@angular/core';
import { ActivatedRoute, RouterOutlet } from '@angular/router';
import { Store } from '@ngrx/store';
import { TranslateModule } from '@ngx-translate/core';
import * as PlaylistActions from '../../state/actions';
import { LoadingOverlayComponent } from '../loading-overlay/loading-overlay.component';
import { NavigationComponent } from '../navigation/navigation.component';
import { XtreamStore } from '../xtream.store';
@Component({
templateUrl: './xtream-shell.component.html',
styleUrls: ['./xtream-shell.component.scss'],
standalone: true,
imports: [
LoadingOverlayComponent,
NavigationComponent,
RouterOutlet,
TranslateModule,
],
providers: [XtreamStore],
})
export class XtreamShellComponent {
private readonly route = inject(ActivatedRoute);
private readonly store = inject(Store);
private readonly xtreamStore = inject(XtreamStore);
readonly getImportCount = this.xtreamStore.getImportCount;
readonly isImporting = this.xtreamStore.isImporting;
readonly itemsToImport = this.xtreamStore.itemsToImport;
constructor() {
effect(
() => {
if (this.xtreamStore.currentPlaylist() !== null) {
this.xtreamStore.initializeContent();
}
},
{ allowSignalWrites: true }
);
}
ngOnInit() {
this.store.dispatch(
PlaylistActions.setActivePlaylist({
playlistId: this.route.snapshot.params.id,
})
);
}
}