clear playlist mass operations and retry functionality

This commit is contained in:
raiper34
2024-07-20 14:38:09 +02:00
parent 893bc438f8
commit da78603db2
12 changed files with 106 additions and 24 deletions
+10 -2
View File
@@ -25,8 +25,16 @@
</div>
<hr>
<div class="box">
<div class="is-flex is-align-items-center">
<p class="subtitle">Playlists</p>&nbsp;
<div class="is-flex is-justify-content-space-between">
<p class="subtitle">Playlists</p>
<div class="buttons has-addons">
<button class="button is-outlined is-success" title="Remove completed from list" (click)="deleteCompleted()">
<i class="fa-solid fa-check"></i>
</button>
<button class="button is-outlined is-danger" title="Remove failed from list" (click)="deleteFailed()">
<i class="fa-solid fa-xmark"></i>
</button>
</div>
</div>
<app-playlist-box *ngFor="let playlist of playlists$ | async" [playlist]="playlist"></app-playlist-box>
</div>
+11 -3
View File
@@ -1,8 +1,8 @@
import { Component } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import {Component} from '@angular/core';
import {RouterOutlet} from '@angular/router';
import {FormsModule} from "@angular/forms";
import {CommonModule, NgFor} from "@angular/common";
import {PlaylistService} from "./services/playlist.service";
import {PlaylistService, PlaylistStatusEnum} from "./services/playlist.service";
import {PlaylistBoxComponent} from "./components/playlist-box/playlist-box.component";
@Component({
@@ -30,4 +30,12 @@ export class AppComponent {
this.url && this.playlistService.create(this.url);
this.url = '';
}
deleteCompleted(): void {
this.playlistService.deleteAllByStatus(PlaylistStatusEnum.Completed);
}
deleteFailed(): void {
this.playlistService.deleteAllByStatus(PlaylistStatusEnum.Error);
}
}
@@ -16,7 +16,8 @@
</a>
</span>
<span>
<i class="fa-solid fa-xmark is-clickable hover-icon" title="Remove track from list" (click)="delete(playlist.id)"></i>&nbsp;
<i class="fa-solid fa-repeat is-clickable hover-icon" title="Retry download failed tracks" (click)="retryFailed(playlist.id)"></i>&nbsp;
<i class="fa-solid fa-xmark is-clickable hover-icon" title="Remove playlist from list" (click)="delete(playlist.id)"></i>&nbsp;
<span *ngIf="!playlist.error" class="is-size-6 has-text-weight-medium">{{trackCompletedCount$ | async}}/{{trackCount$ | async}}</span>&nbsp;
</span>
</p>
@@ -1,15 +1,15 @@
import {Component, Input} from '@angular/core';
import {AsyncPipe, CommonModule, NgForOf, NgIf} from "@angular/common";
import {TrackListComponent} from "../track-list/track-list.component";
import {Playlist, PlaylistService, PLaylistStatusEnum, PlaylistUi} from "../../services/playlist.service";
import {Playlist, PlaylistService, PlaylistStatusEnum, PlaylistUi} from "../../services/playlist.service";
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',
[PlaylistStatusEnum.Completed]: 'is-success',
[PlaylistStatusEnum.InProgress]: 'is-info',
[PlaylistStatusEnum.Warning]: 'is-warning',
[PlaylistStatusEnum.Error]: 'is-danger',
[PlaylistStatusEnum.Subscribed]: 'is-primary',
}
@Component({
@@ -53,4 +53,8 @@ export class PlaylistBoxComponent {
delete(id: number): void {
this.service.delete(id);
}
retryFailed(id: number): void {
this.service.retryFailed(id);
}
}
@@ -20,6 +20,7 @@
</a>
</div>
<div>
<i *ngIf="track.status === trackStatuses.Error" class="fa-solid fa-repeat hover-icon" title="Retry to download" (click)="retry(track.id)"></i>&nbsp;
<i class="fa-solid fa-xmark hover-icon" title="Remove track from list" (click)="delete(track.id)"></i>&nbsp;
<ng-container [ngSwitch]="track.status">
<span *ngSwitchCase="trackStatuses.New" class="tag is-info">New</span>
@@ -25,4 +25,8 @@ export class TrackListComponent {
delete(id: number): void {
this.service.delete(id);
}
retry(id: number): void {
this.service.retry(id);
}
}
@@ -13,7 +13,7 @@ import {
withUIEntities
} from "@ngneat/elf-entities";
import {joinRequestResult, trackRequestResult} from "@ngneat/elf-requests";
import {combineLatest, map, Observable, tap} from "rxjs";
import {combineLatest, filter, first, map, Observable, of, switchMap, tap} from "rxjs";
import {Track, TrackService} from "./track.service";
import {Socket} from "ngx-socket-io";
@@ -34,7 +34,7 @@ export interface PlaylistUi {
collapsed: boolean;
}
export enum PLaylistStatusEnum {
export enum PlaylistStatusEnum {
InProgress,
Completed,
Warning,
@@ -90,7 +90,7 @@ export class PlaylistService {
return this.trackService.getErrorByPlaylist(id).pipe(map(data => data.length));
}
getStatus$(id: number): Observable<PLaylistStatusEnum> {
getStatus$(id: number): Observable<PlaylistStatusEnum> {
return combineLatest([
this.getById(id),
this.getTrackCount(id),
@@ -98,16 +98,33 @@ export class PlaylistService {
this.getErrorTrackCount(id),
]).pipe(map(([playlist, trackCount, completedCount, errorCount]) => {
if (playlist?.error || errorCount === trackCount) {
return PLaylistStatusEnum.Error;
return PlaylistStatusEnum.Error;
} else if (trackCount === completedCount) {
return PLaylistStatusEnum.Completed;
return PlaylistStatusEnum.Completed;
} else if (errorCount > 1) {
return PLaylistStatusEnum.Warning;
return PlaylistStatusEnum.Warning;
}
return PLaylistStatusEnum.InProgress;
return PlaylistStatusEnum.InProgress;
}));
}
deleteAllByStatus(status: PlaylistStatusEnum): void {
this.all$.pipe(
first(),
switchMap(playlists =>
combineLatest(playlists.map(item => this.deleteIfStatusEquals$(item.id, status)))
)
).subscribe();
}
private deleteIfStatusEquals$(id: number, status2Filter: PlaylistStatusEnum): Observable<void> {
return combineLatest([of(id), this.getStatus$(id)]).pipe(
first(),
filter(([_, status]) => status === status2Filter),
switchMap(([id]) => this.delete$(id)),
);
}
fetch(): void {
this.http.get<Playlist[]>(ENDPOINT).pipe(
tap((data: Playlist[]) => this.store.update(
@@ -130,6 +147,14 @@ export class PlaylistService {
}
delete(id: number): void {
this.http.delete(`${ENDPOINT}/${id}`).subscribe();
this.delete$(id).subscribe();
}
private delete$(id: number): Observable<void> {
return this.http.delete<void>(`${ENDPOINT}/${id}`);
}
retryFailed(id: number): void {
this.http.get<void>(`${ENDPOINT}/retry/${id}`).subscribe();
}
}
@@ -75,4 +75,8 @@ export class TrackService {
delete(id: number): void {
this.http.delete(`${ENDPOINT}/${id}`).subscribe();
}
retry(id: number): void {
this.http.get(`${ENDPOINT}/retry/${id}`).subscribe();
}
}