feat: indicate loading while fetching details

This commit is contained in:
4gray committed 2026-01-11 21:20:50 +01:00
1 parent 5ad74e44ab
commit afd8da0c25
9 files changed
+198 -63

No files matched your search

@@ -72,5 +72,7 @@
(episodeClicked)="playEpisode($event)"
/>
</app-content-hero>
} @else {
<app-content-hero [isLoading]="true" (backClicked)="goBack()" />
}
@@ -17,6 +17,7 @@ export interface SelectionState {
selectedItem: any | null;
page: number;
limit: number;
isLoadingDetails: boolean;
}
/**
@@ -28,6 +29,7 @@ const initialSelectionState: SelectionState = {
selectedItem: null,
page: 0,
limit: Number(localStorage.getItem('xtream-page-size') ?? 25),
isLoadingDetails: false,
};
/**
@@ -242,6 +244,13 @@ export function withSelection() {
patchState(store, { selectedItem: item });
},
/**
* Set the loading details state
*/
setIsLoadingDetails(isLoading: boolean): void {
patchState(store, { isLoadingDetails: isLoading });
},
/**
* Set the current page
*/
@@ -121,6 +121,7 @@ export const XtreamStore = signalStore(
const playlist = ngrxStore.selectSignal(selectActivePlaylist)();
if (!playlist) return;
store.setIsLoadingDetails(true);
dataService.fetchData(
`${playlist.serverUrl}/player_api.php`,
{
@@ -137,6 +138,8 @@ export const XtreamStore = signalStore(
});
}).catch((error: unknown) => {
console.error('Error fetching VOD details:', error);
}).finally(() => {
store.setIsLoadingDetails(false);
});
},
@@ -150,6 +153,7 @@ export const XtreamStore = signalStore(
const playlist = ngrxStore.selectSignal(selectActivePlaylist)();
if (!playlist) return;
store.setIsLoadingDetails(true);
dataService.fetchData(
`${playlist.serverUrl}/player_api.php`,
{
@@ -166,6 +170,8 @@ export const XtreamStore = signalStore(
});
}).catch((error: unknown) => {
console.error('Error fetching series details:', error);
}).finally(() => {
store.setIsLoadingDetails(false);
});
},
@@ -100,5 +100,7 @@
</div>
}
</app-content-hero>
} @else {
<app-content-hero [isLoading]="true" (backClicked)="goBack()" />
}
@@ -24,7 +24,7 @@
</div>
<div class="main-content">
@if (!xtreamStore.selectedItem()) {
@if (!xtreamStore.selectedItem() && !xtreamStore.isLoadingDetails()) {
<div class="content-header">
<h2>
<button mat-icon-button disabled>
@@ -36,7 +36,7 @@
}
<div
class="scrollable-content"
[class.no-header]="xtreamStore.selectedItem()"
[class.no-header]="xtreamStore.selectedItem() || xtreamStore.isLoadingDetails()"
>
<router-outlet />
</div>
@@ -54,7 +54,7 @@ export class XtreamShellComponent {
constructor() {
// Subscribe to route params to handle switching between playlists
this.route.params.pipe(takeUntilDestroyed()).subscribe((params) => {
this.route.params.pipe(takeUntilDestroyed()).subscribe(async (params) => {
const newPlaylistId = params['id'];
if (this.isFirstLoad) {
@@ -72,8 +72,11 @@ export class XtreamShellComponent {
playlistId: newPlaylistId,
})
);
this.xtreamStore.fetchXtreamPlaylist();
this.xtreamStore.checkPortalStatus();
// Must await fetchXtreamPlaylist before checking status
// because checkPortalStatus needs currentPlaylist to be set
await this.xtreamStore.fetchXtreamPlaylist();
await this.xtreamStore.checkPortalStatus();
});
effect(