🚸 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 { HomeComponent } from './components/home/home.component';
|
||||||
import { ArtistsComponent } from './components/artists/artists.component';
|
import { ArtistsComponent } from './components/artists/artists.component';
|
||||||
import { AlbumsComponent } from './components/albums/albums.component';
|
import { AlbumsComponent } from './components/albums/albums.component';
|
||||||
import { SongComponent } from './components/song/song.component';
|
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{ path: '', component: HomeComponent },
|
{ path: '', component: HomeComponent },
|
||||||
{ path: 'artists/:id', component: ArtistsComponent },
|
{ path: 'artists/:id', component: ArtistsComponent },
|
||||||
{ path: 'artists', component: ArtistsComponent },
|
{ path: 'artists', component: ArtistsComponent },
|
||||||
{ path: 'albums/:id', component: AlbumsComponent },
|
{ path: 'albums/:id', component: AlbumsComponent },
|
||||||
{ path: 'albums', component: AlbumsComponent },
|
{ path: 'albums', component: AlbumsComponent }
|
||||||
{ path: 'songs', component: SongComponent }
|
|
||||||
];
|
];
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
|
@ -8,19 +8,19 @@ import { FormsModule } from '@angular/forms';
|
|||||||
import { AppRoutingModule } from './app-routing.module';
|
import { AppRoutingModule } from './app-routing.module';
|
||||||
import { AppComponent } from './app.component';
|
import { AppComponent } from './app.component';
|
||||||
import { HomeComponent } from './components/home/home.component';
|
import { HomeComponent } from './components/home/home.component';
|
||||||
import { SongComponent } from './components/song/song.component';
|
|
||||||
import { ArtistsComponent } from './components/artists/artists.component';
|
import { ArtistsComponent } from './components/artists/artists.component';
|
||||||
import { AlbumsComponent } from './components/albums/albums.component';
|
import { AlbumsComponent } from './components/albums/albums.component';
|
||||||
import { ControlsComponent } from './components/controls/controls.component';
|
import { ControlsComponent } from './components/controls/controls.component';
|
||||||
|
import { SonglistComponent } from './components/songlist/songlist.component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
declarations: [
|
declarations: [
|
||||||
AppComponent,
|
AppComponent,
|
||||||
HomeComponent,
|
HomeComponent,
|
||||||
SongComponent,
|
|
||||||
ArtistsComponent,
|
ArtistsComponent,
|
||||||
AlbumsComponent,
|
AlbumsComponent,
|
||||||
ControlsComponent
|
ControlsComponent,
|
||||||
|
SonglistComponent
|
||||||
],
|
],
|
||||||
imports: [
|
imports: [
|
||||||
BrowserModule,
|
BrowserModule,
|
||||||
|
@ -32,8 +32,9 @@ export class Song {
|
|||||||
return new Album(await this.data.getAlbum(this.album));
|
return new Album(await this.data.getAlbum(this.album));
|
||||||
}
|
}
|
||||||
|
|
||||||
async getDuration() {
|
async getDuration(): Promise<number> {
|
||||||
return await this.data.getDuration(this.path);
|
const apiData = await this.data.getDuration(this.path);
|
||||||
|
return apiData.data.result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,26 +10,16 @@
|
|||||||
|
|
||||||
<ng-template #artistInfo>
|
<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>
|
<ul>
|
||||||
<li *ngFor="let album of data.albums">
|
<li *ngFor="let song of songs">
|
||||||
{{ album }}
|
{{ song.name }}
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h4>{{ data.name }}'s songs</h4>
|
|
||||||
<ul>
|
|
||||||
<li *ngFor="let song of data.songs">
|
|
||||||
{{ song }}
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
{{ data | json}}
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { ActivatedRoute } from '@angular/router';
|
import { ActivatedRoute } from '@angular/router';
|
||||||
import { ApiService } from 'src/app/services/api.service';
|
import { ApiService } from 'src/app/services/api.service';
|
||||||
|
import { Artist, Song } from '../../classes/entities';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-artists',
|
selector: 'app-artists',
|
||||||
@ -9,8 +10,9 @@ import { ApiService } from 'src/app/services/api.service';
|
|||||||
})
|
})
|
||||||
export class ArtistsComponent implements OnInit {
|
export class ArtistsComponent implements OnInit {
|
||||||
|
|
||||||
artistData;
|
artistData: Artist;
|
||||||
artists;
|
artists: Promise<Array<Artist>>;
|
||||||
|
songs: Array<Song>;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private api: ApiService,
|
private api: ApiService,
|
||||||
@ -25,7 +27,10 @@ export class ArtistsComponent implements OnInit {
|
|||||||
if (params.has('id')) {
|
if (params.has('id')) {
|
||||||
|
|
||||||
// ... then get artist data ...
|
// ... 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 {
|
} else {
|
||||||
|
|
||||||
|
@ -17,8 +17,9 @@
|
|||||||
<span class="duration">{{ duration > 0 ? audio.formatTime(duration) : '00:00' }}</span>
|
<span class="duration">{{ duration > 0 ? audio.formatTime(duration) : '00:00' }}</span>
|
||||||
</div>
|
</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">
|
<input min="0" max="1" step="0.05" [(ngModel)]="audio.player.volume" type="range" class="form-control-range" id="volume-range">
|
||||||
</span>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
padding: 18px;
|
padding: 18px;
|
||||||
line-height: 1.5em;
|
line-height: 1.5em;
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 25% 10% 55% 10%
|
grid-template-columns: 25% 5% 55% 15%
|
||||||
}
|
}
|
||||||
.form-control-range {
|
.form-control-range {
|
||||||
display: inline-block;
|
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 {
|
figure {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ export class ControlsComponent implements OnInit {
|
|||||||
this.currentSong = await this.api.getSong(id);
|
this.currentSong = await this.api.getSong(id);
|
||||||
this.currentArtist = await this.currentSong.getArtist();
|
this.currentArtist = await this.currentSong.getArtist();
|
||||||
this.currentAlbum = await this.currentSong.getAlbum();
|
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">
|
<app-songlist *ngIf="( songs | async ) as songs" [songs]="songs"></app-songlist>
|
||||||
<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>
|
|
||||||
|
@ -10,7 +10,7 @@ import { ApiService } from 'src/app/services/api.service';
|
|||||||
})
|
})
|
||||||
export class HomeComponent implements OnInit {
|
export class HomeComponent implements OnInit {
|
||||||
|
|
||||||
songs: Song[];
|
songs: Promise<Song[]>;
|
||||||
artists: Artist[] = [];
|
artists: Artist[] = [];
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@ -21,12 +21,7 @@ export class HomeComponent implements OnInit {
|
|||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
// Load the first song from the API
|
// Load the first song from the API
|
||||||
// Removing the async / await from the .then() callback will load the artists async from the songs.
|
// 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 = this.api.getSong('all');
|
||||||
this.songs = res;
|
|
||||||
await res.forEach(async (song: Song) => {
|
|
||||||
this.artists.push(await song.getArtist());
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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 { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
import { SongComponent } from './song.component';
|
import { SonglistComponent } from './songlist.component';
|
||||||
|
|
||||||
describe('SongComponent', () => {
|
describe('SonglistComponent', () => {
|
||||||
let component: SongComponent;
|
let component: SonglistComponent;
|
||||||
let fixture: ComponentFixture<SongComponent>;
|
let fixture: ComponentFixture<SonglistComponent>;
|
||||||
|
|
||||||
beforeEach(async(() => {
|
beforeEach(async(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
declarations: [ SongComponent ]
|
declarations: [ SonglistComponent ]
|
||||||
})
|
})
|
||||||
.compileComponents();
|
.compileComponents();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(SongComponent);
|
fixture = TestBed.createComponent(SonglistComponent);
|
||||||
component = fixture.componentInstance;
|
component = fixture.componentInstance;
|
||||||
fixture.detectChanges();
|
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.
|
* 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) {
|
setSong(song: Song) {
|
||||||
this.player.src = this.data.apiUrl + '/play/' + song.path;
|
this.player.src = this.data.apiUrl + '/play/' + song.path;
|
||||||
|
Loading…
Reference in New Issue
Block a user