Add playlists

This commit is contained in:
Myx
2025-03-21 23:00:06 +01:00
committed by Myx
parent b5658ce37f
commit 50a69c9598
14 changed files with 418 additions and 3 deletions

View File

@@ -0,0 +1,67 @@
<div class="collapse navbar grid bg-base-100 overflow-visible rounded-none border-t-base-200 border-t">
<input
type="text"
placeholder="Search..."
class="input input-bordered pr-14 ng-pristine ng-valid ng-touched"
[(ngModel)]="searchTerm"
(keyup)="filterSongs()" />
</div>
<div
*ngIf="filteredSongs.length > 0"
class="basis-2/3 flex-1 overflow-y-auto scrollbar scrollbar-w-2 scrollbar-h-2 scrollbar-track-base-300 scrollbar-thumb-neutral scrollbar-thumb-rounded-full h-[calc(100vh-164px)]">
<table id="resultTable" class="table table-zebra table-pin-rows" [class.table-xs]="settingsService.isCompactTable">
<thead>
<tr>
<th class="collapsing" id="checkboxColumn">
<button type="button" class="btn btn-sm min-w-[108px] hover:btn-primary" (click)="toggleSelectAll()">
{{ allRowsSelected ? 'Deselect All' : 'Select All' }}
</button>
</th>
<th [ngClass]="sortDirection" class="cursor-pointer" (click)="onColClicked('name')">
Name <i *ngIf="sortColumn === 'name'" class="bi bi-caret-{{ sortDirection === 'asc' ? 'down' : 'up' }}-fill"></i>
</th>
<th [ngClass]="sortDirection" class="cursor-pointer" (click)="onColClicked('artist')">
Artist
<i *ngIf="sortColumn === 'artist'" class="bi bi-caret-{{ sortDirection === 'asc' ? 'down' : 'up' }}-fill"></i>
</th>
<th [ngClass]="sortDirection" class="cursor-pointer" (click)="onColClicked('album')">
Album <i *ngIf="sortColumn === 'album'" class="bi bi-caret-{{ sortDirection === 'asc' ? 'down' : 'up' }}-fill"></i>
</th>
<th [ngClass]="sortDirection" class="cursor-pointer" (click)="onColClicked('genre')">
Genre <i *ngIf="sortColumn === 'genre'" class="bi bi-caret-{{ sortDirection === 'asc' ? 'down' : 'up' }}-fill"></i>
</th>
<th [ngClass]="sortDirection" class="cursor-pointer" (click)="onColClicked('year')">
Year <i *ngIf="sortColumn === 'year'" class="bi bi-caret-{{ sortDirection === 'asc' ? 'down' : 'up' }}-fill"></i>
</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let song of filteredSongs; trackBy: trackByFn">
<td>
<input
type="checkbox"
class="checkbox"
#inputBox
(change)="onCheckboxChange(song, $event.target!)"
[checked]="selectedSongs.includes(song)" />
</td>
<td>{{ song.name }}</td>
<td>{{ song.artist }}</td>
<td>{{ song.album || 'Various' }}</td>
<td>{{ song.genre || 'Various' }}</td>
<td>{{ song.year || 'Various' }}</td>
</tr>
</tbody>
</table>
</div>
<div
class="align-center h-[calc(100vh-169.5px)]"
*ngIf="songs.length > 1 && filteredSongs.length < 1"
style="display: flex; justify-content: center; align-items: center">
<p class="text-center" style="font-size: 1.5rem">No songs found!</p>
</div>
<div class="flex align-center justify-center items-center h-[calc(100vh-169.5px)]" *ngIf="songs.length < 1 && filteredSongs.length === 0">
<p class="text-center" style="font-size: 1.5rem">No songs added!</p>
</div>

View File

@@ -0,0 +1,127 @@
import { Component, OnInit, OnDestroy } from '@angular/core'
import { PlaylistService } from 'src-angular/app/core/services/playlist.service'
import { SelectionService } from 'src-angular/app/core/services/selection.service'
import { ChartData } from 'src-shared/interfaces/search.interface'
import { SettingsService } from '../../../core/services/settings.service'
import { Subscription } from 'rxjs'
type SortColumn = 'name' | 'artist' | 'album' | 'genre' | 'year' | 'charter' | 'length' | 'modifiedTime' | null
@Component({
selector: 'app-playlist-table',
templateUrl: './playlist-table.component.html',
standalone: false,
})
export class PlaylistTableComponent implements OnInit, OnDestroy {
songs: ChartData[] = []
sortDirection: 'asc' | 'desc' = 'asc'
sortColumn: SortColumn = null
filteredSongs: ChartData[] = []
searchTerm: string = ''
allRowsSelected: boolean = false
subscriptions: Subscription[] = []
selectedSongs: ChartData[] = []
constructor(
public playlistService: PlaylistService,
public settingsService: SettingsService,
private selectionService: SelectionService
) { }
get allSelected() {
return this.selectionService.isAllSelected()
}
set allSelected(value: boolean) {
if (value) {
this.selectionService.selectAll()
} else {
this.selectionService.deselectAll()
}
}
ngOnInit(): void {
this.subscriptions.push(
this.playlistService.tracks$
.subscribe(tracks => {
this.songs = tracks
this.filterSongs()
})
)
this.filteredSongs = [...this.songs]
this.subscriptions.push(
this.playlistService.selectedSongs$.subscribe(songs =>
this.selectedSongs = songs
)
)
}
filterSongs(): void {
const term = this.searchTerm.toLowerCase()
this.filteredSongs = this.songs.filter(
song =>
song.name?.toLowerCase().includes(term) ||
song.artist?.toLowerCase().includes(term) ||
song.album?.toLowerCase().includes(term) ||
song.genre?.toLowerCase().includes(term) ||
song.year?.toLowerCase().includes(term) ||
song.charter?.toLowerCase().includes(term)
)
}
trackByFn(index: number): number {
return index
}
onColClicked(column: SortColumn) {
if (this.filteredSongs.length === 0) { return }
if (this.sortColumn !== column) {
this.sortColumn = column
this.sortDirection = 'asc'
} else if (this.sortDirection === 'asc') {
this.sortDirection = 'desc'
} else {
this.sortDirection = 'asc'
this.sortColumn = null
}
if (this.sortColumn) {
this.filteredSongs.sort((a, b) => {
const valueA = a[this.sortColumn! as keyof ChartData]
const valueB = b[this.sortColumn! as keyof ChartData]
if (valueA == null && valueB == null) return 0
if (valueA == null) return this.sortDirection === 'asc' ? -1 : 1
if (valueB == null) return this.sortDirection === 'asc' ? 1 : -1
if (valueA < valueB) return this.sortDirection === 'asc' ? -1 : 1
if (valueA > valueB) return this.sortDirection === 'asc' ? 1 : -1
return 0
})
}
}
onCheckboxChange(song: ChartData, target?: EventTarget): void {
const input = target as HTMLInputElement
if (input.checked) {
this.playlistService.addToSelectedSongs(song)
} else {
this.playlistService.removeFromSelectedSongs(song)
}
}
toggleSelectAll(): void {
this.allRowsSelected = !this.allRowsSelected
if (this.allRowsSelected) {
this.filteredSongs.forEach(song => this.playlistService.addToSelectedSongs(song))
} else {
this.playlistService.clearSelectedSongs()
}
}
ngOnDestroy(): void {
this.subscriptions.forEach(subscription => subscription.unsubscribe())
}
}