playlist statuses
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
<article class="panel" [ngClass]="playlist.error ? 'is-danger' : 'is-primary'">
|
<article class="panel" [ngClass]="statusClass$ | async">
|
||||||
<p class="panel-heading is-flex is-justify-content-space-between">
|
<p class="panel-heading is-flex is-justify-content-space-between">
|
||||||
<span>
|
<span>
|
||||||
<i class="is-clickable fa-solid"
|
<i class="is-clickable fa-solid"
|
||||||
|
|||||||
@@ -1,8 +1,16 @@
|
|||||||
import {Component, Input} from '@angular/core';
|
import {Component, Input} from '@angular/core';
|
||||||
import {AsyncPipe, CommonModule, NgForOf, NgIf} from "@angular/common";
|
import {AsyncPipe, CommonModule, NgForOf, NgIf} from "@angular/common";
|
||||||
import {TrackListComponent} from "../track-list/track-list.component";
|
import {TrackListComponent} from "../track-list/track-list.component";
|
||||||
import {Playlist, PlaylistService, PlaylistUi} from "../../services/playlist.service";
|
import {Playlist, PlaylistService, PLaylistStatusEnum, PlaylistUi} from "../../services/playlist.service";
|
||||||
import {Observable} from "rxjs";
|
import {Observable, map} from "rxjs";
|
||||||
|
|
||||||
|
const STATUS2CLASS = {
|
||||||
|
[PLaylistStatusEnum.Completed]: 'is-success',
|
||||||
|
[PLaylistStatusEnum.InProgress]: 'is-info',
|
||||||
|
[PLaylistStatusEnum.Warning]: 'is-warning',
|
||||||
|
[PLaylistStatusEnum.Error]: 'is-danger',
|
||||||
|
[PLaylistStatusEnum.Subscribed]: 'is-primary',
|
||||||
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-playlist-box',
|
selector: 'app-playlist-box',
|
||||||
@@ -23,6 +31,9 @@ export class PlaylistBoxComponent {
|
|||||||
this._playlist = val;
|
this._playlist = val;
|
||||||
this.trackCount$ = this.playlistService.getTrackCount(val.id);
|
this.trackCount$ = this.playlistService.getTrackCount(val.id);
|
||||||
this.trackCompletedCount$ = this.playlistService.getCompletedTrackCount(val.id);
|
this.trackCompletedCount$ = this.playlistService.getCompletedTrackCount(val.id);
|
||||||
|
this.statusClass$ = this.playlistService.getStatus$(val.id).pipe(
|
||||||
|
map(status => STATUS2CLASS[status])
|
||||||
|
);
|
||||||
}
|
}
|
||||||
get playlist(): Playlist & PlaylistUi {
|
get playlist(): Playlist & PlaylistUi {
|
||||||
return this._playlist;
|
return this._playlist;
|
||||||
@@ -30,6 +41,7 @@ export class PlaylistBoxComponent {
|
|||||||
_playlist!: Playlist & PlaylistUi;
|
_playlist!: Playlist & PlaylistUi;
|
||||||
trackCount$!: Observable<number>;
|
trackCount$!: Observable<number>;
|
||||||
trackCompletedCount$!: Observable<number>;
|
trackCompletedCount$!: Observable<number>;
|
||||||
|
statusClass$!: Observable<string>;
|
||||||
|
|
||||||
constructor(private readonly playlistService: PlaylistService) { }
|
constructor(private readonly playlistService: PlaylistService) { }
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,9 @@ import { Injectable } from '@angular/core';
|
|||||||
import {createStore} from "@ngneat/elf";
|
import {createStore} from "@ngneat/elf";
|
||||||
import {HttpClient} from "@angular/common/http";
|
import {HttpClient} from "@angular/common/http";
|
||||||
import {
|
import {
|
||||||
|
getEntityByPredicate,
|
||||||
selectAllEntities, selectEntities,
|
selectAllEntities, selectEntities,
|
||||||
|
selectEntityByPredicate,
|
||||||
setEntities,
|
setEntities,
|
||||||
UIEntitiesRef,
|
UIEntitiesRef,
|
||||||
unionEntities, updateEntities, upsertEntities,
|
unionEntities, updateEntities, upsertEntities,
|
||||||
@@ -10,7 +12,7 @@ import {
|
|||||||
withUIEntities
|
withUIEntities
|
||||||
} from "@ngneat/elf-entities";
|
} from "@ngneat/elf-entities";
|
||||||
import {joinRequestResult, trackRequestResult} from "@ngneat/elf-requests";
|
import {joinRequestResult, trackRequestResult} from "@ngneat/elf-requests";
|
||||||
import {map, Observable, tap} from "rxjs";
|
import {combineLatest, map, Observable, tap} from "rxjs";
|
||||||
import {Track, TrackService} from "./track.service";
|
import {Track, TrackService} from "./track.service";
|
||||||
import {Socket} from "ngx-socket-io";
|
import {Socket} from "ngx-socket-io";
|
||||||
|
|
||||||
@@ -31,6 +33,14 @@ export interface PlaylistUi {
|
|||||||
collapsed: boolean;
|
collapsed: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export enum PLaylistStatusEnum {
|
||||||
|
InProgress,
|
||||||
|
Completed,
|
||||||
|
Warning,
|
||||||
|
Error,
|
||||||
|
Subscribed,
|
||||||
|
}
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
})
|
})
|
||||||
@@ -62,6 +72,10 @@ export class PlaylistService {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getById(playlistId: number): Observable<Playlist | undefined> {
|
||||||
|
return this.store.pipe(selectEntityByPredicate(({id}) => id === playlistId));
|
||||||
|
}
|
||||||
|
|
||||||
getTrackCount(id: number): Observable<number> {
|
getTrackCount(id: number): Observable<number> {
|
||||||
return this.trackService.getAllByPlaylist(id).pipe(map(data => data.length));
|
return this.trackService.getAllByPlaylist(id).pipe(map(data => data.length));
|
||||||
}
|
}
|
||||||
@@ -70,6 +84,28 @@ export class PlaylistService {
|
|||||||
return this.trackService.getCompletedByPlaylist(id).pipe(map(data => data.length));
|
return this.trackService.getCompletedByPlaylist(id).pipe(map(data => data.length));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getErrorTrackCount(id: number): Observable<number> {
|
||||||
|
return this.trackService.getErrorByPlaylist(id).pipe(map(data => data.length));
|
||||||
|
}
|
||||||
|
|
||||||
|
getStatus$(id: number): Observable<PLaylistStatusEnum> {
|
||||||
|
return combineLatest([
|
||||||
|
this.getById(id),
|
||||||
|
this.getTrackCount(id),
|
||||||
|
this.getCompletedTrackCount(id),
|
||||||
|
this.getErrorTrackCount(id),
|
||||||
|
]).pipe(map(([playlist, trackCount, completedCount, errorCount]) => {
|
||||||
|
if (playlist?.error || errorCount === trackCount) {
|
||||||
|
return PLaylistStatusEnum.Error;
|
||||||
|
} else if (trackCount === completedCount) {
|
||||||
|
return PLaylistStatusEnum.Completed;
|
||||||
|
} else if (errorCount > 1) {
|
||||||
|
return PLaylistStatusEnum.Warning;
|
||||||
|
}
|
||||||
|
return PLaylistStatusEnum.InProgress;
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
fetch(): void {
|
fetch(): void {
|
||||||
this.http.get<Playlist[]>(ENDPOINT).pipe(
|
this.http.get<Playlist[]>(ENDPOINT).pipe(
|
||||||
tap((data: Playlist[]) => this.store.update(
|
tap((data: Playlist[]) => this.store.update(
|
||||||
|
|||||||
@@ -39,12 +39,19 @@ export class TrackService {
|
|||||||
withEntities<Track>(),
|
withEntities<Track>(),
|
||||||
);
|
);
|
||||||
|
|
||||||
getAllByPlaylist(id: number): Observable<Track[]> {
|
getAllByPlaylist(id: number, status?: TrackStatusEnum): Observable<Track[]> {
|
||||||
return this.store.pipe(selectManyByPredicate(({playlistId}) => playlistId === id))
|
return this.store.pipe(
|
||||||
|
selectManyByPredicate(({playlistId}) => playlistId === id),
|
||||||
|
map(data => data.filter(item => status === undefined || item.status === status)),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
getCompletedByPlaylist(id: number): Observable<Track[]> {
|
getCompletedByPlaylist(id: number): Observable<Track[]> {
|
||||||
return this.getAllByPlaylist(id).pipe(map(data => data.filter(item => item.status === TrackStatusEnum.Completed)));
|
return this.getAllByPlaylist(id, TrackStatusEnum.Completed);
|
||||||
|
}
|
||||||
|
|
||||||
|
getErrorByPlaylist(id: number): Observable<Track[]> {
|
||||||
|
return this.getAllByPlaylist(id, TrackStatusEnum.Error);
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
|||||||
Reference in New Issue
Block a user