feat(xtream): add category item counts to category view

This commit is contained in:
4gray committed 2026-01-07 19:10:17 +01:00
1 parent bc30acf4a7
commit 8e15e89858
9 files changed
+45 -1

No files matched your search

@@ -1,3 +1,7 @@
::ng-deep .mat-mdc-dialog-content {
overflow: hidden !important;
}
.loading-container {
display: flex;
flex-direction: column;
@@ -9,6 +9,7 @@
{{
item.category_name || $any(item).name || 'No category name'
}}
<span class="item-count">({{ getItemCount(item) }})</span>
</mat-list-item>
} @empty {
<app-playlist-error-view
@@ -16,6 +16,12 @@
background-color: rgba(63, 81, 181, 0.1);
margin-left: 4px;
}
.item-count {
opacity: 0.6;
font-size: 0.85em;
margin-left: 4px;
}
}
mat-card-content {
@@ -19,6 +19,7 @@ import { PlaylistErrorViewComponent } from '../playlist-error-view/playlist-erro
export class CategoryViewComponent {
readonly items = input([]);
readonly selectedCategoryId = input<number>();
readonly itemCounts = input<Map<number, number>>(new Map());
readonly categoryClicked = output<XtreamCategory>();
@@ -31,4 +32,9 @@ export class CategoryViewComponent {
String(selectedCategory) === String(itemId)
);
}
getItemCount(item: XtreamCategory): number {
const itemId = Number((item as any).category_id ?? item.id);
return this.itemCounts().get(itemId) ?? 0;
}
}
@@ -28,6 +28,7 @@
} @else {
<app-category-view
[items]="categories()"
[itemCounts]="categoryItemCounts()"
(categoryClicked)="selectCategory($event)"
/>
}
@@ -55,6 +55,7 @@ export class LiveStreamLayoutComponent implements OnInit {
private readonly route = inject(ActivatedRoute);
readonly categories = this.xtreamStore.getCategoriesBySelectedType;
readonly categoryItemCounts = this.xtreamStore.getCategoryItemCounts;
readonly epgItems = this.xtreamStore.epgItems;
readonly selectedCategoryId = this.xtreamStore.selectedCategoryId;
@@ -75,7 +76,7 @@ export class LiveStreamLayoutComponent implements OnInit {
});
}
const { categoryId } = this.route.firstChild.snapshot.params;
const categoryId = this.route.firstChild?.snapshot.params['categoryId'];
if (categoryId)
this.xtreamStore.setSelectedCategory(Number(categoryId));
}
@@ -16,6 +16,7 @@
<app-category-view
[items]="categories()"
[selectedCategoryId]="selectedCategoryId()"
[itemCounts]="categoryItemCounts()"
(categoryClicked)="categoryClicked($event)"
/>
</div>
@@ -35,6 +35,7 @@ export class XtreamMainContainerComponent implements OnInit {
private readonly dialog = inject(MatDialog);
readonly categories = this.xtreamStore.getCategoriesBySelectedType;
readonly categoryItemCounts = this.xtreamStore.getCategoryItemCounts;
readonly selectedCategoryId = this.xtreamStore.selectedCategoryId;
@@ -87,6 +87,29 @@ export const XtreamStore = signalStore(
? store.vodCategories()
: store.serialCategories();
}),
/**
* Memoized category item counts map.
* Returns a Map<categoryId, count> for the currently selected content type.
* The Map is recomputed only when streams or content type changes.
*/
getCategoryItemCounts: computed(() => {
const type = store.selectedContentType();
const streams =
type === 'live'
? store.liveStreams()
: type === 'vod'
? store.vodStreams()
: store.serialStreams();
const countMap = new Map<number, number>();
for (const item of streams) {
const catId = Number(item.category_id);
if (!isNaN(catId)) {
countMap.set(catId, (countMap.get(catId) || 0) + 1);
}
}
return countMap;
}),
getSelectedCategory: computed(() => {
const categoryId = store.selectedCategoryId();
return [