From 2168577c6d3c5e219b6471140f55032e024b3af0 Mon Sep 17 00:00:00 2001 From: stickyPiston Date: Sun, 29 Sep 2019 16:01:10 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=8E=20Added=20search=20functionality?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/app-routing.module.ts | 4 +- src/app/app.component.html | 6 +- src/app/app.component.ts | 16 ++++- src/app/app.module.ts | 9 ++- src/app/classes/entities.ts | 3 + .../components/search/search.component.html | 41 ++++++++++++ .../components/search/search.component.scss | 17 +++++ .../search/search.component.spec.ts | 25 +++++++ src/app/components/search/search.component.ts | 67 +++++++++++++++++++ .../components/songlist/songlist.component.ts | 2 +- src/app/services/api.service.ts | 6 ++ src/app/services/data.service.ts | 4 ++ 12 files changed, 189 insertions(+), 11 deletions(-) create mode 100644 src/app/components/search/search.component.html create mode 100644 src/app/components/search/search.component.scss create mode 100644 src/app/components/search/search.component.spec.ts create mode 100644 src/app/components/search/search.component.ts diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index d65b5cd..aeb280f 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -3,13 +3,15 @@ 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 { SearchComponent } from './components/search/search.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: 'albums', component: AlbumsComponent }, + { path: 'search/:query', component: SearchComponent } ]; @NgModule({ diff --git a/src/app/app.component.html b/src/app/app.component.html index da10324..3765b52 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -29,11 +29,11 @@ diff --git a/src/app/app.component.ts b/src/app/app.component.ts index b9c5359..28c3aa5 100644 --- a/src/app/app.component.ts +++ b/src/app/app.component.ts @@ -1,6 +1,7 @@ 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'; +import { Router } from '@angular/router'; +import { FormBuilder } from '@angular/forms'; @Component({ selector: 'app-root', @@ -8,7 +9,6 @@ import { Router, UrlSegment } from '@angular/router'; styleUrls: ['./app.component.scss'] }) export class AppComponent implements OnInit { - title = 'Cassettea'; navToggled; // FontAwesome @@ -20,8 +20,14 @@ export class AppComponent implements OnInit { faChevronLeft = faChevronLeft; faChevronRight = faChevronRight; + searchForm = this.fb.group({ + query: '' + }); - constructor(public router: Router) { } + constructor( + public router: Router, + private fb: FormBuilder + ) { } ngOnInit() { this.navToggled = false; @@ -30,4 +36,8 @@ export class AppComponent implements OnInit { toggleNav() { this.navToggled = (this.navToggled) ? false : true; } + + onSubmit() { + this.router.navigate([`search/${this.searchForm.value.query}`]); + } } diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 9473d50..ecd9ad9 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -3,7 +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 { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { AppRoutingModule } from './app-routing.module'; import { AppComponent } from './app.component'; @@ -12,6 +12,7 @@ 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'; +import { SearchComponent } from './components/search/search.component'; @NgModule({ declarations: [ @@ -20,14 +21,16 @@ import { SonglistComponent } from './components/songlist/songlist.component'; ArtistsComponent, AlbumsComponent, ControlsComponent, - SonglistComponent + SonglistComponent, + SearchComponent ], imports: [ BrowserModule, AppRoutingModule, HttpClientModule, FontAwesomeModule, - FormsModule + FormsModule, + ReactiveFormsModule ], providers: [], bootstrap: [AppComponent] diff --git a/src/app/classes/entities.ts b/src/app/classes/entities.ts index e8723a0..48deefb 100644 --- a/src/app/classes/entities.ts +++ b/src/app/classes/entities.ts @@ -9,6 +9,7 @@ export class Song { artist: number; album: number; path: string; + type = 'Song'; data: DataService; @@ -46,6 +47,7 @@ export class Artist { name: string; albums: Array; songs: Array; + type = 'Artist'; constructor(data: any) { this.id = data.data.result[0].id; @@ -65,6 +67,7 @@ export class Album { name: string; artist: number; image: string; + type = 'Album'; data: DataService; diff --git a/src/app/components/search/search.component.html b/src/app/components/search/search.component.html new file mode 100644 index 0000000..0d03a08 --- /dev/null +++ b/src/app/components/search/search.component.html @@ -0,0 +1,41 @@ +
+ +
+

+ Artists +

+ + + There were no artists found. + +
+ +
+

+ Albums +

+ + + There were no albums found. + +
+ +
+

Songs

+
+ +
+ + There were no songs found. + +
+ +
diff --git a/src/app/components/search/search.component.scss b/src/app/components/search/search.component.scss new file mode 100644 index 0000000..6656a7d --- /dev/null +++ b/src/app/components/search/search.component.scss @@ -0,0 +1,17 @@ +div.container { + display: grid; + grid-template-areas: 'artists songs' + 'albums songs'; + + div.artists { + grid-area: artists; + } + + div.albums { + grid-area: albums; + } + + div.songs { + grid-area: songs; + } +} diff --git a/src/app/components/search/search.component.spec.ts b/src/app/components/search/search.component.spec.ts new file mode 100644 index 0000000..4372919 --- /dev/null +++ b/src/app/components/search/search.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { SearchComponent } from './search.component'; + +describe('SearchComponent', () => { + let component: SearchComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ SearchComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(SearchComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/search/search.component.ts b/src/app/components/search/search.component.ts new file mode 100644 index 0000000..99e81db --- /dev/null +++ b/src/app/components/search/search.component.ts @@ -0,0 +1,67 @@ +import { Component, OnInit } from '@angular/core'; +import { ActivatedRoute } from '@angular/router'; +import { ApiService } from 'src/app/services/api.service'; +import { faMusic, faCompactDisc, faUser } from '@fortawesome/free-solid-svg-icons'; +import { Song, Album, Artist } from '../../classes/entities'; + +@Component({ + selector: 'app-search', + templateUrl: './search.component.html', + styleUrls: ['./search.component.scss'] +}) +export class SearchComponent implements OnInit { + + // ? fontAwesome imports + faMusic = faMusic; + faCompactDisc = faCompactDisc; + faUser = faUser; + + songs: Song[] = []; + albums: Album[] = []; + artists: Artist[] = []; + + dataLoaded = false; + + constructor( + private route: ActivatedRoute, + private api: ApiService + ) { } + + ngOnInit() { + + this.route.paramMap.subscribe(params => { + + this.songs = []; + this.albums = []; + this.artists = []; + + this.api.search(params.get('query')).then(results => { + + if (results.length) { + results.forEach(result => { + if (result.type === 'Song') { + this.songs.push(result); + } else if (result.type === 'Album') { + this.albums.push(result); + } else if (result.type === 'Artist') { + this.artists.push(result); + } + }); + } else { + if (results.type === 'Song') { + this.songs.push(results); + } else if (results.type === 'Album') { + this.albums.push(results); + } else if (results.type === 'Artist') { + this.artists.push(results); + } + } + + this.dataLoaded = true; + + }); + + }); + } + +} diff --git a/src/app/components/songlist/songlist.component.ts b/src/app/components/songlist/songlist.component.ts index f0746a1..6ccae5b 100644 --- a/src/app/components/songlist/songlist.component.ts +++ b/src/app/components/songlist/songlist.component.ts @@ -9,7 +9,7 @@ import { AudioService } from 'src/app/services/audio.service'; styleUrls: ['./songlist.component.scss'] }) export class SonglistComponent implements OnInit { - @Input() songs: Song[]; + @Input() songs: any; songsInfo = []; currentSongId: number; diff --git a/src/app/services/api.service.ts b/src/app/services/api.service.ts index 5d469ff..5460bfd 100644 --- a/src/app/services/api.service.ts +++ b/src/app/services/api.service.ts @@ -70,4 +70,10 @@ export class ApiService { // ... and convert that data to entities. return this.entityService.createEntityFromData(data); } + + async search(query: string) { + const data = await this.data.search(query); + + return this.entityService.createEntityFromData(data); + } } diff --git a/src/app/services/data.service.ts b/src/app/services/data.service.ts index 692ba8f..91c9b07 100644 --- a/src/app/services/data.service.ts +++ b/src/app/services/data.service.ts @@ -81,4 +81,8 @@ export class DataService { getAllArtists(): Promise> { return this.get('artist', 'all'); } + + search(query: string): Promise> { + return this.axiosInstance.get(`${this.apiUrl}/search/${query}`); + } }