File
Implements
Metadata
selector |
app-music-list |
styleUrls |
app-music-list.component.css |
templateUrl |
./app-music-list.component.html |
Methods
dragEnd
|
dragEnd(pos: , i: )
|
|
Parameters :
Name |
Optional |
pos |
No
|
i |
No
|
|
fileChangeEvent
|
fileChangeEvent(fileInput: any)
|
|
Parameters :
Name |
Type |
Optional |
fileInput |
any
|
No
|
|
loadOnDeck
|
loadOnDeck(deck: , song: )
|
|
Parameters :
Name |
Optional |
deck |
No
|
song |
No
|
|
recievedFiles
|
recievedFiles(files: FileList)
|
|
Parameters :
Name |
Type |
Optional |
files |
FileList
|
No
|
|
removeAllSongs
|
removeAllSongs()
|
|
|
removeSong
|
removeSong(song: )
|
|
|
saveStartPos
|
saveStartPos(event: )
|
|
|
updateMusic
|
updateMusic()
|
|
|
index
|
index:
|
Default value : -1
|
|
musicList
|
musicList: File[]
|
Type : File[]
|
|
shownMusic
|
shownMusic: File[]
|
Type : File[]
|
|
songs
|
songs: any
|
Type : any
|
Decorators : ViewChildren
|
|
import { Component, OnInit, OnDestroy, ViewChildren, ViewChild, ElementRef } from '@angular/core';
import { MusicLoaderService } from '../../services/music-loader.service';
import { Subscription, iif } from 'rxjs';
import { AngularDraggableDirective } from 'angular2-draggable';
@Component({
selector: 'app-music-list',
templateUrl: './app-music-list.component.html',
styleUrls: ['./app-music-list.component.css']
})
export class AppMusicListComponent implements OnDestroy {
musicService: MusicLoaderService;
private musicSubscription: Subscription;
musicList: File[];
shownMusic: File[];
query: string;
dragging: boolean;
startX;
startY;
@ViewChildren(AngularDraggableDirective)
songs: any;
@ViewChild('container')
scrollable: ElementRef;
offSet;
index = -1;
constructor(musicService: MusicLoaderService) {
this.musicService = musicService;
this.musicList = musicService.music;
this.updateMusic();
this.musicSubscription = musicService.music$.subscribe(a => {
this.musicList = a as File[];
this.updateMusic();
});
}
ngOnDestroy(): void {
if (this.musicSubscription) {
this.musicSubscription.unsubscribe();
}
}
loadOnDeck(deck, song) {
this.musicService.load(deck, song);
}
removeSong(song) {
this.musicService.deleteSong(song);
}
updateMusic() {
if (!this.query) {
this.shownMusic = this.musicList;
} else {
const searchMusic = (searchQuery, music: any[]) => {
const lowSearch = searchQuery
.toLowerCase()
.normalize('NFD')
.replace(/[\u0300-\u036f]/g, '');
return music.filter(mus => {
return String(mus.name)
.toLowerCase()
.normalize('NFD')
.replace(/[\u0300-\u036f]/g, '')
.includes(lowSearch);
});
};
this.shownMusic = searchMusic(this.query, this.musicList);
}
}
fileChangeEvent(fileInput: any) {
this.recievedFiles(fileInput.target.files);
}
recievedFiles(files: FileList) {
if (files) {
for (let i = 0; i < files.length; i++) {
if (files.item(i).type.includes('audio')) {
this.musicService.addSong(files.item(i));
}
}
}
}
removeAllSongs() {
this.musicService.deleteAllSongs();
}
dragStart(i) {
this.index = i;
this.offSet = { x: 0, y: -(this.scrollable.nativeElement as HTMLElement).scrollTop };
this.dragging = true;
}
dragEnd(pos, i) {
this.offSet = { x: 0, y: 0 };
this.dragging = false;
// TODO: search a more elegant solution than by cursor position
if (window.outerHeight * 0.5 > this.startY + pos.y) {
if (window.outerWidth * 0.4 > this.startX + pos.x) {
this.loadOnDeck(0, this.shownMusic[i]);
} else if (window.outerWidth * 0.6 < this.startX + pos.x) {
this.loadOnDeck(1, this.shownMusic[i]);
}
}
this.songs._results[i].resetPosition();
}
saveStartPos(event) {
this.startX = event.clientX;
this.startY = event.clientY;
}
}
<!--
This file is part of Web Virtual DJ.
Web Virtual DJ is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Web Virtual DJ is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Web Virtual DJ. If not, see <https://www.gnu.org/licenses/>.
-->
<div class="music-container" id="app_music_list_container" [ngClass]="{'music-container-dragging':dragging}" #container>
<table *ngIf="musicList.length>0" id="app_music_list">
<tr class="header">
<td></td>
<td>
<div class="music-search">
<div>{{ 'MUSIC.SONG' | translate }}</div>
<div class="centered">
<input class="hide-input" id="load_music" type="file" (input)="fileChangeEvent($event)" accept="audio/*"
multiple=true />
<label class="button button--green" for="load_music" id="load_music_button">{{ 'MUSIC.CHOOSE' | translate
}}</label>
</div>
<div class="searchbar">
<input type="text" class="searchbox" [(ngModel)]="query" (ngModelChange)="updateMusic()" />
<div id="b" class="searchbutton"></div>
</div>
</div>
</td>
<!-- <td class="header">Artist</td> -->
<td>
<div title="Remove all" class="icon-container" (click)="removeAllSongs()">
<img (dragstart)="$event.preventDefault()" class="icon icon--clickable" src="assets/images/error.svg">
</div>
</td>
</tr>
<tr class="elements" *ngFor="let song of shownMusic;let i = index" ngDraggable [zIndexMoving]="9999"
(started)="dragStart(i)" (endOffset)="dragEnd($event,i)" (mousedown)="saveStartPos($event)" [lockAxis]="x"
[position]="index===i?offSet:{x:0,y:0}">
<td class="icon-container">
<img (dragstart)="$event.preventDefault()" class="icon" src="assets/images/music-player.svg">
</td>
<td title="" class="info">{{song.name}}</td>
<!-- <td title="" class="info"></td> -->
<td>
<div class="icons-container">
<div title="Load in deck 1" class="icon-container" (click)="loadOnDeck(0, song)"
(mousedown)="$event.stopPropagation()" (touchstart)="$event.stopPropagation()">
<img (dragstart)="$event.preventDefault()" class="icon icon--clickable" src="assets/images/uno.svg">
</div>
<div title="Load in deck 2" class="icon-container" (click)="loadOnDeck(1, song)"
(mousedown)="$event.stopPropagation()" (touchstart)="$event.stopPropagation()">
<img (dragstart)="$event.preventDefault()" class="icon icon--clickable" src="assets/images/dos.svg">
</div>
<div title="Remove" class="icon-container" (click)="removeSong(song)" (mousedown)="$event.stopPropagation()"
(touchstart)="$event.stopPropagation()">
<img (dragstart)="$event.preventDefault()" class="icon icon--clickable" src="assets/images/error.svg">
</div>
</div>
</td>
</tr>
<tr *ngIf="shownMusic.length === 0">
<td COLSPAN="3">{{ 'MUSIC.NOMATCH' | translate }} {{query}}</td>
</tr>
</table>
<div *ngIf="musicList.length === 0" class="start-instructions" id="app_start_instructions">
<div class="start-text">{{ 'MUSIC.START' | translate }}</div>
<div class="centered margintop">
<input class="hide-input" id="load_music" type="file" (input)="fileChangeEvent($event)" accept="audio/*"
multiple=true />
<label class="button button--green" for="load_music"
id="load_music_button">{{ 'MUSIC.CHOOSE' | translate }}</label>
</div>
</div>
<!-- {{musicService.music}} -->
</div>