diff --git a/src/backend/src/playlist/playlist.controller.ts b/src/backend/src/playlist/playlist.controller.ts index 971637f..15e6f3f 100644 --- a/src/backend/src/playlist/playlist.controller.ts +++ b/src/backend/src/playlist/playlist.controller.ts @@ -1,4 +1,4 @@ -import {Body, Controller, Get, Post} from '@nestjs/common'; +import {Body, Controller, Delete, Get, Param, Post} from '@nestjs/common'; import {PlaylistService} from "./playlist.service"; import {PlaylistModel} from "./playlist.model"; @@ -19,4 +19,9 @@ export class PlaylistController { async create(@Body() playlist: PlaylistModel): Promise { await this.service.create(playlist); } + + @Delete(':id') + remove(@Param('id') id: number): Promise { + return this.service.remove(id); + } } \ No newline at end of file diff --git a/src/backend/src/playlist/playlist.service.ts b/src/backend/src/playlist/playlist.service.ts index ec25252..d6d1be7 100644 --- a/src/backend/src/playlist/playlist.service.ts +++ b/src/backend/src/playlist/playlist.service.ts @@ -30,6 +30,7 @@ export class PlaylistService { async remove(id: number): Promise { await this.repository.delete(id); + this.io.emit('playlistDelete', {id}); } async create(playlist: PlaylistEntity): Promise { diff --git a/src/backend/src/track/track.controller.ts b/src/backend/src/track/track.controller.ts index 993b88a..1d00858 100644 --- a/src/backend/src/track/track.controller.ts +++ b/src/backend/src/track/track.controller.ts @@ -1,4 +1,4 @@ -import {Controller, Get, Param, Res, StreamableFile} from '@nestjs/common'; +import {Controller, Delete, Get, Param, Res, StreamableFile} from '@nestjs/common'; import {TrackService} from "./track.service"; import {TrackModel} from "./track.model"; import {createReadStream} from "fs"; @@ -30,4 +30,9 @@ export class TrackController { res.set({'Content-Disposition': `attachment; filename="${track.artist} - ${track.song}.mp3"`,}); return new StreamableFile(file); } + + @Delete(':id') + remove(@Param('id') id: number): Promise { + return this.service.remove(id); + } } \ No newline at end of file diff --git a/src/backend/src/track/track.entity.ts b/src/backend/src/track/track.entity.ts index a92a66b..7664c60 100644 --- a/src/backend/src/track/track.entity.ts +++ b/src/backend/src/track/track.entity.ts @@ -29,6 +29,6 @@ export class TrackEntity { @Column({default: Date.now()}) createdAt?: number; - @ManyToOne(() => PlaylistEntity, playlist => playlist.tracks) + @ManyToOne(() => PlaylistEntity, playlist => playlist.tracks, {onDelete: "CASCADE"}) playlist?: PlaylistEntity; } \ No newline at end of file diff --git a/src/backend/src/track/track.service.ts b/src/backend/src/track/track.service.ts index c7a2f13..e946f1e 100644 --- a/src/backend/src/track/track.service.ts +++ b/src/backend/src/track/track.service.ts @@ -40,6 +40,7 @@ export class TrackService { async remove(id: number): Promise { await this.repository.delete(id); + this.io.emit('trackDelete', {id}); } async create(track: TrackEntity, playlist?: PlaylistEntity): Promise { diff --git a/src/frontend/src/app/components/playlist-box/playlist-box.component.html b/src/frontend/src/app/components/playlist-box/playlist-box.component.html index 4142e38..63a5a86 100644 --- a/src/frontend/src/app/components/playlist-box/playlist-box.component.html +++ b/src/frontend/src/app/components/playlist-box/playlist-box.component.html @@ -15,8 +15,9 @@ - - {{trackCompletedCount$ | async}}/{{trackCount$ | async}}  + +   + {{trackCompletedCount$ | async}}/{{trackCount$ | async}} 

diff --git a/src/frontend/src/app/components/playlist-box/playlist-box.component.scss b/src/frontend/src/app/components/playlist-box/playlist-box.component.scss index 58891b6..5a005c9 100644 --- a/src/frontend/src/app/components/playlist-box/playlist-box.component.scss +++ b/src/frontend/src/app/components/playlist-box/playlist-box.component.scss @@ -1,6 +1,14 @@ +.hover-icon { + display: none; +} + .panel-heading { padding: 5px 10px; border-radius: 10px; + + &:hover .hover-icon { + display: inline; + } } .panel { diff --git a/src/frontend/src/app/components/playlist-box/playlist-box.component.ts b/src/frontend/src/app/components/playlist-box/playlist-box.component.ts index 8ac6789..36c6b01 100644 --- a/src/frontend/src/app/components/playlist-box/playlist-box.component.ts +++ b/src/frontend/src/app/components/playlist-box/playlist-box.component.ts @@ -29,9 +29,9 @@ export class PlaylistBoxComponent { @Input() set playlist(val: Playlist & PlaylistUi) { this._playlist = val; - this.trackCount$ = this.playlistService.getTrackCount(val.id); - this.trackCompletedCount$ = this.playlistService.getCompletedTrackCount(val.id); - this.statusClass$ = this.playlistService.getStatus$(val.id).pipe( + this.trackCount$ = this.service.getTrackCount(val.id); + this.trackCompletedCount$ = this.service.getCompletedTrackCount(val.id); + this.statusClass$ = this.service.getStatus$(val.id).pipe( map(status => STATUS2CLASS[status]) ); } @@ -43,10 +43,14 @@ export class PlaylistBoxComponent { trackCompletedCount$!: Observable; statusClass$!: Observable; - constructor(private readonly playlistService: PlaylistService) { } + constructor(private readonly service: PlaylistService) { } toggleCollapse(playlistId: number): void { - this.playlistService.toggleCollapsed(playlistId); + this.service.toggleCollapsed(playlistId); + } + + delete(id: number): void { + this.service.delete(id); } } diff --git a/src/frontend/src/app/components/track-list/track-list.component.html b/src/frontend/src/app/components/track-list/track-list.component.html index bc9297a..57151ac 100644 --- a/src/frontend/src/app/components/track-list/track-list.component.html +++ b/src/frontend/src/app/components/track-list/track-list.component.html @@ -20,6 +20,7 @@
+   New Searching diff --git a/src/frontend/src/app/components/track-list/track-list.component.scss b/src/frontend/src/app/components/track-list/track-list.component.scss index aabde9b..345a702 100644 --- a/src/frontend/src/app/components/track-list/track-list.component.scss +++ b/src/frontend/src/app/components/track-list/track-list.component.scss @@ -1,3 +1,11 @@ +.hover-icon { + display: none; +} + .panel-block { padding: 5px 10px; + + &:hover .hover-icon { + display: inline; + } } diff --git a/src/frontend/src/app/components/track-list/track-list.component.ts b/src/frontend/src/app/components/track-list/track-list.component.ts index a72d189..3b87eaf 100644 --- a/src/frontend/src/app/components/track-list/track-list.component.ts +++ b/src/frontend/src/app/components/track-list/track-list.component.ts @@ -13,7 +13,6 @@ import {Observable} from "rxjs"; export class TrackListComponent { @Input() set playlistId(value: number) { - console.log(value); this.tracks$ = this.service.getAllByPlaylist(value); } tracks$!: Observable; @@ -21,6 +20,9 @@ export class TrackListComponent { constructor( private readonly service: TrackService, - ) { + ) { } + + delete(id: number): void { + this.service.delete(id); } } diff --git a/src/frontend/src/app/services/playlist.service.ts b/src/frontend/src/app/services/playlist.service.ts index 86ee05f..256ac0e 100644 --- a/src/frontend/src/app/services/playlist.service.ts +++ b/src/frontend/src/app/services/playlist.service.ts @@ -2,8 +2,9 @@ import { Injectable } from '@angular/core'; import {createStore} from "@ngneat/elf"; import {HttpClient} from "@angular/common/http"; import { + deleteEntities, getEntityByPredicate, - selectAllEntities, selectEntities, + selectAllEntities, selectEntities, selectEntity, selectEntityByPredicate, setEntities, UIEntitiesRef, @@ -64,6 +65,7 @@ export class PlaylistService { 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), @@ -72,8 +74,8 @@ export class PlaylistService { ); } - getById(playlistId: number): Observable { - return this.store.pipe(selectEntityByPredicate(({id}) => id === playlistId)); + getById(id: number): Observable { + return this.store.pipe(selectEntity(id)); } getTrackCount(id: number): Observable { @@ -126,4 +128,8 @@ export class PlaylistService { toggleCollapsed(id: number): void { this.store.update(updateEntities(id, old => ({...old, collapsed: !old.collapsed}), { ref: UIEntitiesRef })) } + + delete(id: number): void { + this.http.delete(`${ENDPOINT}/${id}`).subscribe(); + } } diff --git a/src/frontend/src/app/services/track.service.ts b/src/frontend/src/app/services/track.service.ts index 34d1e1f..e05eed5 100644 --- a/src/frontend/src/app/services/track.service.ts +++ b/src/frontend/src/app/services/track.service.ts @@ -1,6 +1,6 @@ import { Injectable } from '@angular/core'; import {createStore} from "@ngneat/elf"; -import {selectManyByPredicate, upsertEntities, withEntities} from "@ngneat/elf-entities"; +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"; @@ -41,7 +41,7 @@ export class TrackService { getAllByPlaylist(id: number, status?: TrackStatusEnum): Observable { return this.store.pipe( - selectManyByPredicate(({playlistId}) => playlistId === id), + selectManyByPredicate((track) => track?.playlistId === id), map(data => data.filter(item => status === undefined || item.status === status)), ); } @@ -59,6 +59,7 @@ export class TrackService { 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}])) ); @@ -70,4 +71,8 @@ export class TrackService { trackRequestResult([STORE_NAME], { skipCache: true }), ).subscribe(); } + + delete(id: number): void { + this.http.delete(`${ENDPOINT}/${id}`).subscribe(); + } }