💥 Finished up controls for so far!
Yay!
This commit is contained in:
parent
319104dee8
commit
29d8d978aa
@ -31,7 +31,7 @@
|
||||
<button type="button" class="btn btn-outline-secondary" (click)="toggleNav();">
|
||||
<fa-icon [icon]="this.navToggled ? faChevronLeft : faChevronRight" [fixedWidth]="true"></fa-icon>
|
||||
</button>
|
||||
<span class="navbar-brand">Route name here</span>
|
||||
<span class="navbar-brand">{{ router.url }}</span>
|
||||
<form class="form-inline" id="navbar-search">
|
||||
<input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search">
|
||||
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { faGlobeEurope, faMusic, faCompactDisc, faUsers, faCog, faChevronLeft, faChevronRight } from '@fortawesome/free-solid-svg-icons';
|
||||
import { Router, UrlSegment } from '@angular/router';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
@ -20,11 +21,10 @@ export class AppComponent implements OnInit {
|
||||
faChevronRight = faChevronRight;
|
||||
|
||||
|
||||
constructor() {
|
||||
this.navToggled = false;
|
||||
}
|
||||
constructor(public router: Router) { }
|
||||
|
||||
ngOnInit() {
|
||||
this.navToggled = false;
|
||||
}
|
||||
|
||||
toggleNav() {
|
||||
|
@ -3,6 +3,7 @@ import { NgModule } from '@angular/core';
|
||||
|
||||
import { HttpClientModule } from '@angular/common/http';
|
||||
import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
|
||||
import { AppRoutingModule } from './app-routing.module';
|
||||
import { AppComponent } from './app.component';
|
||||
@ -25,7 +26,8 @@ import { ControlsComponent } from './components/controls/controls.component';
|
||||
BrowserModule,
|
||||
AppRoutingModule,
|
||||
HttpClientModule,
|
||||
FontAwesomeModule
|
||||
FontAwesomeModule,
|
||||
FormsModule
|
||||
],
|
||||
providers: [],
|
||||
bootstrap: [AppComponent]
|
||||
|
@ -26,6 +26,15 @@ export class Song {
|
||||
// tslint:disable-next-line: no-use-before-declare
|
||||
return new Artist(await this.data.getArtist(this.artist));
|
||||
}
|
||||
|
||||
async getAlbum() {
|
||||
// tslint:disable-next-line: no-use-before-declare
|
||||
return new Album(await this.data.getAlbum(this.album));
|
||||
}
|
||||
|
||||
async getDuration() {
|
||||
return await this.data.getDuration(this.path);
|
||||
}
|
||||
}
|
||||
|
||||
/** This class represents one artist */
|
||||
|
@ -1,20 +1,24 @@
|
||||
<div class="navbar navbar-light bg-light border-top controls-wrapper">
|
||||
|
||||
<span *ngIf="( currentSong | async ) as song" class="songInfo">
|
||||
{{ song.name }}
|
||||
</span>
|
||||
<div class="figure-container">
|
||||
<figure *ngIf="currentSong && currentArtist && currentAlbum" class="songInfo">
|
||||
<img [src]="data.apiUrl + '/image/' + currentAlbum.image" [alt]="'Album art for ' + currentAlbum.name">
|
||||
<figcaption>{{ currentSong.name }} by {{ currentArtist.name }}</figcaption>
|
||||
</figure>
|
||||
</div>
|
||||
|
||||
<span class="buttons">
|
||||
<fa-icon (click)="audio.isCurrentlyPlaying ? audio.pause() : audio.play()" [icon]="audio.isCurrentlyPlaying ? faPause : faPlay"></fa-icon>
|
||||
</span>
|
||||
|
||||
<span class="time">
|
||||
<input type="range" class="form-control-range" id="song-range">
|
||||
</span>
|
||||
<div class="time">
|
||||
<span class="currentTime">{{ audio.currentTime > 0 ? audio.formatTime(audio.currentTime) : '00:00' }}</span>
|
||||
<input type="range" min="0" [max]="duration ? duration : 100" [(ngModel)]="audio.time" [value]="audio.currentTime" class="form-control-range" id="song-range">
|
||||
<span class="duration">{{ duration > 0 ? audio.formatTime(duration) : '00:00' }}</span>
|
||||
</div>
|
||||
|
||||
<span class="volume">
|
||||
<fa-icon [icon]="faMusic" [fixedWidth]="true"></fa-icon>
|
||||
<input type="range" class="form-control-range" id="volume-range">
|
||||
<input min="0" max="1" step="0.05" [(ngModel)]="audio.player.volume" type="range" class="form-control-range" id="volume-range">
|
||||
</span>
|
||||
|
||||
</div>
|
||||
|
@ -2,9 +2,33 @@
|
||||
width: 100%;
|
||||
padding: 18px;
|
||||
line-height: 1.5em;
|
||||
display: grid;
|
||||
grid-template-columns: 25% 10% 55% 10%
|
||||
}
|
||||
.form-control-range {
|
||||
display: inline;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
div.time {
|
||||
display: grid;
|
||||
grid-template-columns: min-content auto min-content;
|
||||
|
||||
span {
|
||||
padding: 0 5px;
|
||||
}
|
||||
}
|
||||
|
||||
figure {
|
||||
margin: 0;
|
||||
|
||||
img {
|
||||
height: 2rem;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
figcaption {
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
// #song-range {
|
||||
// width: 50%;
|
||||
|
@ -1,8 +1,9 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { faPlay, faPause, faVolumeMute, faVolumeDown, faVolumeUp } from '@fortawesome/free-solid-svg-icons';
|
||||
import { faPlay, faPause, faVolumeMute, faVolumeDown, faVolumeUp, faMusic } from '@fortawesome/free-solid-svg-icons';
|
||||
import { AudioService } from 'src/app/services/audio.service';
|
||||
import { Song } from '../../classes/entities';
|
||||
import { Song, Artist, Album } from '../../classes/entities';
|
||||
import { ApiService } from 'src/app/services/api.service';
|
||||
import { DataService } from 'src/app/services/data.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-controls',
|
||||
@ -17,17 +18,28 @@ export class ControlsComponent implements OnInit {
|
||||
faVolumeMute = faVolumeMute;
|
||||
faVolumeDown = faVolumeDown;
|
||||
faVolumeUp = faVolumeUp;
|
||||
faMusic = faMusic;
|
||||
|
||||
currentSong: Promise<Song>;
|
||||
Math = Math;
|
||||
NaN = NaN;
|
||||
|
||||
currentSong: Song;
|
||||
currentArtist: Artist;
|
||||
currentAlbum: Album;
|
||||
duration: number;
|
||||
|
||||
constructor(
|
||||
public audio: AudioService,
|
||||
private api: ApiService
|
||||
private api: ApiService,
|
||||
public data: DataService
|
||||
) { }
|
||||
|
||||
ngOnInit() {
|
||||
this.audio.currentSong.subscribe(id => {
|
||||
this.currentSong = this.api.getSong(id);
|
||||
this.audio.currentSong.subscribe(async id => {
|
||||
this.currentSong = await this.api.getSong(id);
|
||||
this.currentArtist = await this.currentSong.getArtist();
|
||||
this.currentAlbum = await this.currentSong.getAlbum();
|
||||
this.duration = (await this.currentSong.getDuration()).data.result;
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -18,11 +18,22 @@ export class AudioService {
|
||||
return !this.player.paused;
|
||||
}
|
||||
|
||||
constructor(private data: DataService) { }
|
||||
constructor(private data: DataService) {
|
||||
// Make sure that the currentTime property is always up to date.
|
||||
this.player.addEventListener('timeupdate', () => {
|
||||
this.currentTime = this.player.currentTime;
|
||||
});
|
||||
}
|
||||
|
||||
player = new Audio();
|
||||
|
||||
currentSong = new Subject<number>();
|
||||
currentTime: number;
|
||||
|
||||
// Use audio.time to set the time
|
||||
set time(value: number) {
|
||||
this.player.currentTime = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* The play function sets the playstate of the player to playing.
|
||||
@ -38,6 +49,33 @@ export class AudioService {
|
||||
this.player.pause();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This function will format the number of seconds to a nices human-readable format.
|
||||
* @param input The number of seconds.
|
||||
* @returns a string like: '01:34', standing for 1 minute and 34 seconds.
|
||||
*/
|
||||
formatTime(input: number): string {
|
||||
const minutes = Math.floor(input / 60);
|
||||
const seconds = Math.floor(input % 60);
|
||||
|
||||
return this.addZero(minutes) + ':' + this.addZero(seconds);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This function prepends a 0 when the number is smaller than 10.
|
||||
* @param input The number
|
||||
* @returns a string with a 0 prepended if the number is smaller than 10.
|
||||
*/
|
||||
addZero(input: number): string {
|
||||
if (input < 10) {
|
||||
return '0' + String(input);
|
||||
} else {
|
||||
return String(input);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The setSong function set the song for the player.
|
||||
* @param id The id of the song that needs to be played
|
||||
|
@ -37,6 +37,10 @@ export class DataService {
|
||||
return this.axiosInstance.get(`${this.apiUrl}/get/${type}/${id}`);
|
||||
}
|
||||
|
||||
getDuration(path: string): Promise<AxiosResponse<ApiData>> {
|
||||
return this.axiosInstance.get(`${this.apiUrl}/duration/${path}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param id The id of the artist. It can be a number representing the id, multiple numbers seperated by commas or the string 'all'.
|
||||
* @returns A Promise<AxiosResponse<object>> containing the returned data from the API.
|
||||
|
Loading…
Reference in New Issue
Block a user