refactor(frontend): refactor frontend services code

This commit is contained in:
raiper34
2024-09-30 14:29:40 +02:00
parent 7359a13a7c
commit 887ac2237a
6 changed files with 71 additions and 57 deletions
@@ -1,8 +1,9 @@
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 {PlaylistService, PlaylistStatusEnum, PlaylistUi} from "../../services/playlist.service";
import {Observable, map} from "rxjs";
import {Playlist} from "../../models/playlist";
const STATUS2CLASS = {
[PlaylistStatusEnum.Completed]: 'is-success',
@@ -1,7 +1,8 @@
import {Component, Input} from '@angular/core';
import {CommonModule, NgFor, NgSwitch, NgSwitchCase} from "@angular/common";
import {Track, TrackService, TrackStatusEnum} from "../../services/track.service";
import {TrackService} from "../../services/track.service";
import {Observable} from "rxjs";
import {Track, TrackStatusEnum} from "../../models/track";
@Component({
selector: 'app-track-list',
+8
View File
@@ -0,0 +1,8 @@
export interface Playlist {
id: number;
name?: string;
spotifyUrl: string;
error?: string;
active: boolean;
createdAt: number;
}
+19
View File
@@ -0,0 +1,19 @@
export interface Track {
id: number;
artist: string;
name: string;
spotifyUrl: string;
youtubeUrl: string;
status: TrackStatusEnum;
playlistId?: number;
error?: string;
}
export enum TrackStatusEnum {
New,
Searching,
Queued,
Downloading,
Completed,
Error,
}
@@ -3,9 +3,7 @@ import {createStore} from "@ngneat/elf";
import {HttpClient} from "@angular/common/http";
import {
deleteEntities,
getEntityByPredicate,
selectAllEntities, selectEntities, selectEntity,
selectEntityByPredicate,
setEntities,
UIEntitiesRef,
unionEntities, updateEntities, upsertEntities,
@@ -14,20 +12,17 @@ import {
} from "@ngneat/elf-entities";
import {joinRequestResult, trackRequestResult} from "@ngneat/elf-requests";
import {combineLatest, filter, first, map, Observable, of, switchMap, tap} from "rxjs";
import {Track, TrackService} from "./track.service";
import {TrackService} from "./track.service";
import {Socket} from "ngx-socket-io";
import {Playlist} from "../models/playlist";
const STORE_NAME = 'playlist';
const ENDPOINT = '/api/playlist';
const CREATE_LOADING = 'CREATE_LOADING';
export interface Playlist {
id: number;
name?: string;
spotifyUrl: string;
error?: string;
active: boolean;
createdAt: number;
enum WsPlaylistOperation {
New = 'playlistNew',
Update = 'playlistUpdate',
Delete = 'playlistDelete',
}
export interface PlaylistUi {
@@ -53,26 +48,18 @@ export class PlaylistService {
withEntities<Playlist>(),
withUIEntities<PlaylistUi>()
);
all$ = this.store.combine({
entities: this.store.pipe(selectAllEntities()),
UIEntities: this.store.pipe(selectEntities({ ref: UIEntitiesRef })),
}).pipe(unionEntities(), map(data => data.sort((a, b) => this.sort(a, b))));
loading$ = this.store.pipe(joinRequestResult([STORE_NAME]));
}).pipe(unionEntities(), map(data => data.sort((a, b) => this.groupActiveAndSortByCreation(a, b))));
createLoading$ = this.store.pipe(joinRequestResult([CREATE_LOADING], { initialStatus: 'idle' }));
constructor(private readonly http: HttpClient,
private readonly socket: Socket,
private readonly trackService: TrackService,
) {
this.socket.on('playlistUpdate', (playlist: Playlist) => this.store.update(upsertEntities(playlist)));
this.socket.on('playlistDelete', ({id}: {id: number}) => this.store.update(deleteEntities(Number(id))));
this.socket.on('playlistNew', (playlist: Playlist) =>
this.store.update(
upsertEntities(playlist),
upsertEntities({id: playlist.id, collapsed: false}, {ref: UIEntitiesRef})
)
);
this.initWsConnection();
}
getById(id: number): Observable<Playlist | undefined> {
@@ -133,7 +120,6 @@ export class PlaylistService {
setEntities(data.map(item => ({id: item.id, collapsed: false})), {ref: UIEntitiesRef})
)),
tap((data: Playlist[]) => data.forEach(playlist => this.trackService.fetch(playlist.id))),
trackRequestResult([STORE_NAME], { skipCache: true }),
).subscribe();
}
@@ -144,17 +130,13 @@ export class PlaylistService {
}
toggleCollapsed(id: number): void {
this.store.update(updateEntities(id, old => ({...old, collapsed: !old.collapsed}), { ref: UIEntitiesRef }))
this.store.update(updateEntities(id, old => ({...old, collapsed: !old.collapsed}), { ref: UIEntitiesRef }));
}
delete(id: number): void {
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();
}
@@ -163,7 +145,22 @@ export class PlaylistService {
this.http.put<void>(`${ENDPOINT}/${id}`, {active}).subscribe();
}
private sort(a: Playlist & PlaylistUi, b: Playlist & PlaylistUi): number {
private delete$(id: number): Observable<void> {
return this.http.delete<void>(`${ENDPOINT}/${id}`);
}
private groupActiveAndSortByCreation(a: Playlist & PlaylistUi, b: Playlist & PlaylistUi): number {
return a.active === b.active ? (b.createdAt - a.createdAt) : (a.active < b.active ? 1 : -1);
}
private initWsConnection(): void {
this.socket.on(WsPlaylistOperation.Update, (playlist: Playlist) => this.store.update(upsertEntities(playlist)));
this.socket.on(WsPlaylistOperation.Delete, ({id}: {id: number}) => this.store.update(deleteEntities(Number(id))));
this.socket.on(WsPlaylistOperation.New, (playlist: Playlist) =>
this.store.update(
upsertEntities(playlist),
upsertEntities({id: playlist.id, collapsed: false}, {ref: UIEntitiesRef})
)
);
}
}
+14 -26
View File
@@ -3,30 +3,15 @@ import {createStore} from "@ngneat/elf";
import {deleteEntities, selectManyByPredicate, upsertEntities, withEntities} from "@ngneat/elf-entities";
import {Socket} from "ngx-socket-io";
import {map, Observable, tap} from "rxjs";
import {trackRequestResult} from "@ngneat/elf-requests";
import {HttpClient} from "@angular/common/http";
import {Track, TrackStatusEnum} from "../models/track";
const STORE_NAME = 'track';
const ENDPOINT = '/api/track';
export interface Track {
id: number;
artist: string;
name: string;
spotifyUrl: string;
youtubeUrl: string;
status: TrackStatusEnum;
playlistId?: number;
error?: string;
}
export enum TrackStatusEnum {
New,
Searching,
Queued,
Downloading,
Completed,
Error,
enum WsTrackOperation {
New = 'trackNew',
Update = 'trackUpdate',
Delete = 'trackDelete',
}
@Injectable({
@@ -58,17 +43,12 @@ export class TrackService {
private readonly http: HttpClient,
private readonly socket: Socket,
) {
this.socket.on('trackUpdate', (track: Track) => this.store.update(upsertEntities(track)));
this.socket.on('trackDelete', ({id}: {id: number}) => this.store.update(deleteEntities(id)));
this.socket.on('trackNew', ({track, playlistId}: {track: Track, playlistId: number}) =>
this.store.update(upsertEntities([{...track, playlistId}]))
);
this.initWsConnection();
}
fetch(playlistId: number): void {
this.http.get<Track[]>(`${ENDPOINT}/playlist/${playlistId}`).pipe(
tap((data: Track[]) => this.store.update(upsertEntities(data.map(track => ({...track, playlistId}))))),
trackRequestResult([STORE_NAME], { skipCache: true }),
).subscribe();
}
@@ -79,4 +59,12 @@ export class TrackService {
retry(id: number): void {
this.http.get(`${ENDPOINT}/retry/${id}`).subscribe();
}
private initWsConnection(): void {
this.socket.on(WsTrackOperation.Update, (track: Track) => this.store.update(upsertEntities(track)));
this.socket.on(WsTrackOperation.Delete, ({id}: {id: number}) => this.store.update(deleteEntities(id)));
this.socket.on(WsTrackOperation.New, ({track, playlistId}: {track: Track, playlistId: number}) =>
this.store.update(upsertEntities([{...track, playlistId}]))
);
}
}