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 }); } }) } } }); } }