mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-08 17:06:15 -08:00
feat(xtream): show category page info and preserve page state
Update category header and list views to provide clearer context and improve navigation state handling. - Display category name with current page/total pages when viewing a category (non-detail) so users see which page they're on. - Add i18n "PAGE" key and fill "SELECT_CATEGORY" in translations for en/de/ru to support the new page label and existing messaging. - Tidy live-stream layout template formatting and fix filter pipe spacing for consistency. - Change no-channel-selected fallback to use the translated "PORTALS.SELECT_CATEGORY" string. - Preserve category selection state on CategoryContentView init: only set selected category when the route category differs from the current selection to keep paging/scroll position when returning from a detail view. These changes improve UX by making pagination explicit and avoiding unnecessary state resets when navigating between list and detail.
This commit is contained in:
1 parent
8bc8eab167
commit
c34bdf73e1
6 files changed
+41
-17
No files matched your search
+5
-1
@@ -46,7 +46,11 @@ export class CategoryContentViewComponent implements OnInit {
|
||||
|
||||
ngOnInit() {
|
||||
const { categoryId } = this.activatedRoute.snapshot.params;
|
||||
if (categoryId) this.store.setSelectedCategory(categoryId);
|
||||
// Only set category if it's different from the currently selected one
|
||||
// This preserves the page state when navigating back from detail view
|
||||
if (categoryId && this.store.selectedCategoryId() !== Number(categoryId)) {
|
||||
this.store.setSelectedCategory(categoryId);
|
||||
}
|
||||
}
|
||||
|
||||
onPageChange(event: PageEvent) {
|
||||
|
||||
@@ -53,9 +53,19 @@ export class XtreamMainContainerComponent implements OnInit {
|
||||
return this.translateService.instant('PORTALS.SELECT_CATEGORY');
|
||||
} else {
|
||||
const selectedCategory = this.xtreamStore.getSelectedCategory();
|
||||
return selectedCategory
|
||||
? `Content for ${(selectedCategory as any).name}`
|
||||
const categoryName = selectedCategory
|
||||
? (selectedCategory as any).name
|
||||
: 'Category Content';
|
||||
|
||||
// Show page number when viewing category content (not detail view)
|
||||
if (!this.xtreamStore.selectedItem() && this.xtreamStore.getTotalPages() > 1) {
|
||||
const currentPage = this.xtreamStore.page() + 1; // +1 because page is 0-indexed
|
||||
const totalPages = this.xtreamStore.getTotalPages();
|
||||
const pageLabel = this.translateService.instant('PORTALS.PAGE');
|
||||
return `${categoryName} (${pageLabel} ${currentPage}/${totalPages})`;
|
||||
}
|
||||
|
||||
return `Content for ${categoryName}`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -310,7 +310,9 @@
|
||||
"NO_SEARCH_RESULTS": "Nichts gefunden. Versuchen Sie, Ihre Suchanfrage zu ändern"
|
||||
},
|
||||
"REMOVED_FROM_FAVORITES": "Aus den Favoriten entfernt",
|
||||
"ADDED_TO_FAVORITES": "Zu den Favoriten hinzugefügt"
|
||||
"ADDED_TO_FAVORITES": "Zu den Favoriten hinzugefügt",
|
||||
"SELECT_CATEGORY": "Wählen Sie eine Kategorie aus",
|
||||
"PAGE": "Seite"
|
||||
},
|
||||
"ABOUT": {
|
||||
"TITLE": "Über IPTVnator",
|
||||
|
||||
@@ -363,7 +363,8 @@
|
||||
},
|
||||
"STREAM_URL_COPIED": "Stream URL copied to clipboard",
|
||||
"COPY_STREAM_URL": "Copy Stream URL",
|
||||
"SELECT_CATEGORY": "Select a category"
|
||||
"SELECT_CATEGORY": "Select a category",
|
||||
"PAGE": "Page"
|
||||
},
|
||||
"INFORMATION": "Information",
|
||||
"REMOTE_CONTROL": {
|
||||
|
||||
@@ -306,7 +306,9 @@
|
||||
"NO_SEARCH_RESULTS": "Ничего не найдено, попробуйте изменить поисковый запрос"
|
||||
},
|
||||
"REMOVED_FROM_FAVORITES": "Удалено из избранного",
|
||||
"ADDED_TO_FAVORITES": "Добавлено в избранное"
|
||||
"ADDED_TO_FAVORITES": "Добавлено в избранное",
|
||||
"SELECT_CATEGORY": "Выберите категорию",
|
||||
"PAGE": "Страница"
|
||||
},
|
||||
"INFORMATION": "Инфо"
|
||||
}
|
||||
+16
-11
@@ -26,7 +26,7 @@
|
||||
<mat-list-option
|
||||
*cdkVirtualFor="
|
||||
let item of channels
|
||||
| filterBy : searchString() : 'name';
|
||||
| filterBy: searchString() : 'name';
|
||||
trackBy: trackBy;
|
||||
templateCacheSize: 0
|
||||
"
|
||||
@@ -51,17 +51,22 @@
|
||||
</mat-selection-list>
|
||||
</div>
|
||||
</div>
|
||||
@if (player === 'videojs' || player === 'html5') { @if (streamUrl) {
|
||||
<div class="video-player">
|
||||
<app-web-player-view [streamUrl]="streamUrl" />
|
||||
</div>
|
||||
} } @if (streamUrl) {
|
||||
<div class="epg">
|
||||
<div class="epg-content">
|
||||
<app-epg-view [epgItems]="epgItems" />
|
||||
@if (player === 'videojs' || player === 'html5') {
|
||||
@if (streamUrl) {
|
||||
<div class="video-player">
|
||||
<app-web-player-view [streamUrl]="streamUrl" />
|
||||
</div>
|
||||
}
|
||||
}
|
||||
@if (streamUrl) {
|
||||
<div class="epg">
|
||||
<div class="epg-content">
|
||||
<app-epg-view [epgItems]="epgItems" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
} @else {
|
||||
<div class="no-channel-selected">Please select a channel</div>
|
||||
<div class="no-channel-selected">
|
||||
{{ 'PORTALS.SELECT_CATEGORY' | translate }}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
Reference in new issue
Block a user