🚸 Added SongList component for consistent song visuals everywhere.
This commit is contained in:
parent
29d8d978aa
commit
91a0cdfd57
@ -3,15 +3,13 @@ import { Routes, RouterModule } from '@angular/router';
|
||||
import { HomeComponent } from './components/home/home.component';
|
||||
import { ArtistsComponent } from './components/artists/artists.component';
|
||||
import { AlbumsComponent } from './components/albums/albums.component';
|
||||
import { SongComponent } from './components/song/song.component';
|
||||
|
||||
const routes: Routes = [
|
||||
{ path: '', component: HomeComponent },
|
||||
{ path: 'artists/:id', component: ArtistsComponent },
|
||||
{ path: 'artists', component: ArtistsComponent },
|
||||
{ path: 'albums/:id', component: AlbumsComponent },
|
||||
{ path: 'albums', component: AlbumsComponent },
|
||||
{ path: 'songs', component: SongComponent }
|
||||
{ path: 'albums', component: AlbumsComponent }
|
||||
];
|
||||
|
||||
@NgModule({
|
||||
|
@ -8,19 +8,19 @@ import { FormsModule } from '@angular/forms';
|
||||
import { AppRoutingModule } from './app-routing.module';
|
||||
import { AppComponent } from './app.component';
|
||||
import { HomeComponent } from './components/home/home.component';
|
||||
import { SongComponent } from './components/song/song.component';
|
||||
import { ArtistsComponent } from './components/artists/artists.component';
|
||||
import { AlbumsComponent } from './components/albums/albums.component';
|
||||
import { ControlsComponent } from './components/controls/controls.component';
|
||||
import { SonglistComponent } from './components/songlist/songlist.component';
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AppComponent,
|
||||
HomeComponent,
|
||||
SongComponent,
|
||||
ArtistsComponent,
|
||||
AlbumsComponent,
|
||||
ControlsComponent
|
||||
ControlsComponent,
|
||||
SonglistComponent
|
||||
],
|
||||
imports: [
|
||||
BrowserModule,
|
||||
|
@ -32,8 +32,9 @@ export class Song {
|
||||
return new Album(await this.data.getAlbum(this.album));
|
||||
}
|
||||
|
||||
async getDuration() {
|
||||
return await this.data.getDuration(this.path);
|
||||
async getDuration(): Promise<number> {
|
||||
const apiData = await this.data.getDuration(this.path);
|
||||
return apiData.data.result;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,26 +10,16 @@
|
||||
|
||||
<ng-template #artistInfo>
|
||||
|
||||
<div *ngIf="( artistData | async ) as data">
|
||||
<h2>{{ artistData.name }}'s profile</h2>
|
||||
|
||||
<h1>{{ data.name }}'s profile</h1>
|
||||
<hr>
|
||||
|
||||
<h4>{{ artistData.name }}'s songs</h4>
|
||||
|
||||
<h4>{{ data.name }}'s albums</h4>
|
||||
<ul>
|
||||
<li *ngFor="let album of data.albums">
|
||||
{{ album }}
|
||||
<li *ngFor="let song of songs">
|
||||
{{ song.name }}
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h4>{{ data.name }}'s songs</h4>
|
||||
<ul>
|
||||
<li *ngFor="let song of data.songs">
|
||||
{{ song }}
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
{{ data | json}}
|
||||
|
||||
</div>
|
||||
|
||||
</ng-template>
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
import { ApiService } from 'src/app/services/api.service';
|
||||
import { Artist, Song } from '../../classes/entities';
|
||||
|
||||
@Component({
|
||||
selector: 'app-artists',
|
||||
@ -9,8 +10,9 @@ import { ApiService } from 'src/app/services/api.service';
|
||||
})
|
||||
export class ArtistsComponent implements OnInit {
|
||||
|
||||
artistData;
|
||||
artists;
|
||||
artistData: Artist;
|
||||
artists: Promise<Array<Artist>>;
|
||||
songs: Array<Song>;
|
||||
|
||||
constructor(
|
||||
private api: ApiService,
|
||||
@ -25,7 +27,10 @@ export class ArtistsComponent implements OnInit {
|
||||
if (params.has('id')) {
|
||||
|
||||
// ... then get artist data ...
|
||||
this.artistData = this.api.getArtist(Number(params.get('id')));
|
||||
this.api.getArtist(Number(params.get('id'))).then(async res => {
|
||||
this.artistData = res;
|
||||
this.songs = await this.api.getSong(res.songs.join());
|
||||
});
|
||||
|
||||
} else {
|
||||
|
||||
|
@ -17,8 +17,9 @@
|
||||
<span class="duration">{{ duration > 0 ? audio.formatTime(duration) : '00:00' }}</span>
|
||||
</div>
|
||||
|
||||
<span class="volume">
|
||||
<div class="volume">
|
||||
<fa-icon [icon]="audio.player.volume === 0 ? faVolumeMute : ( audio.player.volume > 0.5 ? faVolumeUp : faVolumeDown )"></fa-icon>
|
||||
<input min="0" max="1" step="0.05" [(ngModel)]="audio.player.volume" type="range" class="form-control-range" id="volume-range">
|
||||
</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -3,7 +3,7 @@
|
||||
padding: 18px;
|
||||
line-height: 1.5em;
|
||||
display: grid;
|
||||
grid-template-columns: 25% 10% 55% 10%
|
||||
grid-template-columns: 25% 5% 55% 15%
|
||||
}
|
||||
.form-control-range {
|
||||
display: inline-block;
|
||||
@ -18,6 +18,16 @@ div.time {
|
||||
}
|
||||
}
|
||||
|
||||
div.volume {
|
||||
display: grid;
|
||||
grid-template-columns: auto auto;
|
||||
text-align: center;
|
||||
|
||||
input {
|
||||
width: 90%;
|
||||
}
|
||||
}
|
||||
|
||||
figure {
|
||||
margin: 0;
|
||||
|
||||
|
@ -39,7 +39,7 @@ export class ControlsComponent implements OnInit {
|
||||
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;
|
||||
this.duration = await this.currentSong.getDuration();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -1,3 +1 @@
|
||||
<div *ngIf="songs && artists">
|
||||
<p *ngFor="let song of songs; let i=index" (click)="audio.setSong(song)">{{ song.name }} by <span *ngIf="artists[i]">{{ artists[i].name }}</span></p>
|
||||
</div>
|
||||
<app-songlist *ngIf="( songs | async ) as songs" [songs]="songs"></app-songlist>
|
||||
|
@ -10,7 +10,7 @@ import { ApiService } from 'src/app/services/api.service';
|
||||
})
|
||||
export class HomeComponent implements OnInit {
|
||||
|
||||
songs: Song[];
|
||||
songs: Promise<Song[]>;
|
||||
artists: Artist[] = [];
|
||||
|
||||
constructor(
|
||||
@ -21,12 +21,7 @@ export class HomeComponent implements OnInit {
|
||||
ngOnInit() {
|
||||
// Load the first song from the API
|
||||
// Removing the async / await from the .then() callback will load the artists async from the songs.
|
||||
this.api.getSong('all').then(async res => {
|
||||
this.songs = res;
|
||||
await res.forEach(async (song: Song) => {
|
||||
this.artists.push(await song.getArtist());
|
||||
});
|
||||
});
|
||||
this.songs = this.api.getSong('all');
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1 +0,0 @@
|
||||
<p>song works!</p>
|
@ -1,15 +0,0 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'app-song',
|
||||
templateUrl: './song.component.html',
|
||||
styleUrls: ['./song.component.scss']
|
||||
})
|
||||
export class SongComponent implements OnInit {
|
||||
|
||||
constructor() { }
|
||||
|
||||
ngOnInit() {
|
||||
}
|
||||
|
||||
}
|
23
src/app/components/songlist/songlist.component.html
Normal file
23
src/app/components/songlist/songlist.component.html
Normal file
@ -0,0 +1,23 @@
|
||||
<table class="table">
|
||||
|
||||
<thead>
|
||||
<th scope="col">#</th>
|
||||
<th scope="col"></th>
|
||||
<th scope="col">Song name</th>
|
||||
<th scope="col">Artist name</th>
|
||||
<th scope="col">Album name</th>
|
||||
<th scope="col">Duration</th>
|
||||
</thead>
|
||||
|
||||
<tbody *ngIf="songsInfo">
|
||||
<tr *ngFor="let song of songsInfo; let i = index">
|
||||
<th scope="row">{{ i + 1 }}</th>
|
||||
<th><fa-icon (click)="audio.setSong(songs[i])" [icon]="faPlay"></fa-icon></th>
|
||||
<td>{{ song.name }}</td>
|
||||
<td *ngIf="song.artistInfo">{{ song.artistInfo.name }}</td>
|
||||
<td *ngIf="song.albumInfo">{{ song.albumInfo.name }}</td>
|
||||
<td *ngIf="song.duration">{{ audio.formatTime(song.duration) }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
||||
</table>
|
@ -1,20 +1,20 @@
|
||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { SongComponent } from './song.component';
|
||||
import { SonglistComponent } from './songlist.component';
|
||||
|
||||
describe('SongComponent', () => {
|
||||
let component: SongComponent;
|
||||
let fixture: ComponentFixture<SongComponent>;
|
||||
describe('SonglistComponent', () => {
|
||||
let component: SonglistComponent;
|
||||
let fixture: ComponentFixture<SonglistComponent>;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [ SongComponent ]
|
||||
declarations: [ SonglistComponent ]
|
||||
})
|
||||
.compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(SongComponent);
|
||||
fixture = TestBed.createComponent(SonglistComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
46
src/app/components/songlist/songlist.component.ts
Normal file
46
src/app/components/songlist/songlist.component.ts
Normal file
@ -0,0 +1,46 @@
|
||||
import { Component, OnInit, Input } from '@angular/core';
|
||||
import { Song, Artist, Album } from '../../classes/entities';
|
||||
import { faPlay } from '@fortawesome/free-solid-svg-icons';
|
||||
import { AudioService } from 'src/app/services/audio.service';
|
||||
|
||||
@Component({
|
||||
selector: 'app-songlist',
|
||||
templateUrl: './songlist.component.html',
|
||||
styleUrls: ['./songlist.component.scss']
|
||||
})
|
||||
export class SonglistComponent implements OnInit {
|
||||
@Input() songs: Song[];
|
||||
|
||||
songsInfo = [];
|
||||
|
||||
// ? fontAwesome imports
|
||||
faPlay = faPlay;
|
||||
|
||||
constructor(public audio: AudioService) { }
|
||||
|
||||
ngOnInit() {
|
||||
this.songs.forEach(song => {
|
||||
const index = this.songsInfo.push({}) - 1;
|
||||
const result = {
|
||||
...song,
|
||||
artistInfo: null as Artist,
|
||||
albumInfo: null as Album,
|
||||
duration: null as number
|
||||
};
|
||||
song.getArtist().then((artist: Artist) => {
|
||||
result.artistInfo = artist;
|
||||
|
||||
song.getAlbum().then((album: Album) => {
|
||||
result.albumInfo = album;
|
||||
|
||||
song.getDuration().then((duration: number) => {
|
||||
result.duration = duration;
|
||||
|
||||
this.songsInfo[index] = result;
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@ -78,7 +78,7 @@ export class AudioService {
|
||||
|
||||
/**
|
||||
* The setSong function set the song for the player.
|
||||
* @param id The id of the song that needs to be played
|
||||
* @param song The song object
|
||||
*/
|
||||
setSong(song: Song) {
|
||||
this.player.src = this.data.apiUrl + '/play/' + song.path;
|
||||
|
Loading…
Reference in New Issue
Block a user