Files
we_bstly-web/src/app/pages/jukebox/jukebox.compontent.ts
T
2025-05-11 18:05:06 +02:00

175 lines
4.5 KiB
TypeScript

import { Component, OnDestroy, OnInit } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { MatSnackBar } from '@angular/material/snack-bar';
import { FormControl } from '@angular/forms';
import { JukeboxService } from 'src/app/services/jukebox.service';
import { I18nService } from '../../services/i18n.service';
import { ConfirmDialog } from '../../ui/confirm/confirm.component';
@Component({
standalone: false,
selector: 'app-jukebox',
templateUrl: './jukebox.component.html',
styleUrls: ['./jukebox.component.scss']
})
export class JukeboxComponent implements OnInit, OnDestroy {
timeout: number = 0;
timer;
searchResult: any;
currentTrack: any;
checking: boolean = false;
active: boolean = false;
wait: boolean = false;
forbidden: boolean = false;
unavailable: boolean = false;
searchDisabled = true;
searchFormControl = new FormControl();
automaticCheck;
constructor(
public dialog: MatDialog,
private snackBar: MatSnackBar,
private i18n: I18nService,
private jukeboxService: JukeboxService) { }
ngOnInit(): void {
this.check();
this.searchFormControl.valueChanges.subscribe({
next: (value) => {
this.searchDisabled = false;
}
})
this.automaticCheck = setInterval(() => {
this.check();
}, 15000);
}
ngOnDestroy(): void {
if (this.automaticCheck) {
clearInterval(this.automaticCheck);
}
}
check() {
this.timeout = 0;
this.wait = false;
this.checking = true;
this.forbidden = false;
this.unavailable = false;
this.jukeboxService.check().subscribe({
next: (response) => {
if (response) {
this.currentTrack = response;
}
this.active = true;
this.checking = false;
},
error: (error) => {
this.active = false;
if (error.status == 403) {
this.forbidden = true;
} else if (error.status == 410) {
this.unavailable = true;
} else if (error.status == 402) {
this.wait = true;
this.timeout = 60 - error.error;
this.jukeboxService.current().subscribe({
next: (response) => {
this.currentTrack = response;
}
});
this.timer = setInterval(() => {
this.timeout--;
if (this.timeout == 0) {
clearInterval(this.timer);
this.check();
}
}, 1000)
}
this.checking = false;
}
})
}
search() {
this.searchDisabled = true;
this.jukeboxService.search(this.searchFormControl.value).subscribe({
next: (data: any) => {
this.searchResult = data.tracks;
}
})
}
searchMore() {
this.searchDisabled = true;
this.jukeboxService.searchOffset(this.searchFormControl.value, this.searchResult.offset + this.searchResult.limit).subscribe({
next: (data: any) => {
this.searchResult.offset = data.tracks.offset;
this.searchResult.total = data.tracks.total;
for (let track of data.tracks.items) {
this.searchResult.items.push(track);
}
}
})
}
getImageUrl(track: any) {
let url = "";
let width;
if (track.album && track.album.images) {
for (let image of track.album.images) {
if (!width || width > image.width) {
url = image.url;
}
}
}
return url;
}
queue(track: any) {
const dialogRef = this.dialog.open(ConfirmDialog, {
data: {
'label': 'jukebox.addToQueue.confirm',
'args': [track.artists[0].name, track.name]
}
})
dialogRef.afterClosed().subscribe({
next: (result) => {
if (result) {
this.jukeboxService.queue(track.uri).subscribe({
next: () => {
this.active = false;
this.wait = true;
this.timeout = 60;
this.timer = setInterval(() => {
this.timeout--;
if (this.timeout == 0) {
clearInterval(this.timer);
this.check();
}
}, 1000)
this.snackBar.open(this.i18n.get("jukebox.addToQueue.success", []), this.i18n.get("close", []), {
duration: 3000
});
},
error: (error) => {
this.snackBar.open(this.i18n.get("jukebox.addToQueue.error", []), this.i18n.get("close", []), {
duration: 3000
});
}
})
}
}
});
}
}