Angular - отображение соответствующих текстов песен на странице трека - Spotify API - PullRequest
0 голосов
/ 20 апреля 2020

Я создаю веб-сайт для написания текстов, используя Angular и Spotify APi. Я использую API, чтобы позволить пользователю искать исполнителя, просматривать его альбомы, треки и просматривать тексты песен. Тексты написаны другими пользователями. Это делается с помощью облачной базы данных Firestore. Пользователь может создавать, обновлять и удалять тексты песен. Моя проблема заключается в том, чтобы текст песни отображался только на соответствующем треке, в настоящий момент все слова, присутствующие в базе данных, будут отображаться на всех треках. И все добавленные тексты покажут на всех страницах. Я не могу придумать, как это решить.

Lyrics/firestore Sevice


import {Injectable} from '@angular/core';
import {AngularFirestore, AngularFirestoreCollection, AngularFirestoreDocument} from '@angular/fire/firestore';
import {Observable} from 'rxjs';
import {Lyric} from "../interfaces/lyric";
import { map } from 'rxjs/operators'


@Injectable({
  providedIn: 'root'
})
export class LyricService {
  lyricsCollection: AngularFirestoreCollection<Lyric>;
  lyrics: Observable<Lyric[]>
lyricDoc: AngularFirestoreDocument<Lyric>;

  constructor(public db: AngularFirestore) {
   // this.lyrics = this.db.collection('lyrics').valueChanges();

   this.lyricsCollection = this.db.collection('lyrics');

  this.lyrics = this.lyricsCollection.snapshotChanges().pipe(map(changes =>
    {
      return changes.map(a => {
        const data = a.payload.doc.data() as Lyric
        data.id = a.payload.doc.id;
        return data;
      });
    }));
   }

getLyrics(){
  return this.lyrics;
}

addLyric(lyric: Lyric){
  this.lyricsCollection.add(lyric);
}

deleteLyric(lyric: Lyric){
this.lyricDoc = this.db.doc(`lyrics/${lyric.id}`);
this.lyricDoc.delete();
}

updateLyric(lyric: Lyric){
  this.lyricDoc = this.db.doc(`lyrics/${lyric.id}`);
this.lyricDoc.update(lyric);
}


  }


Spoify Service

import { Injectable } from '@angular/core';
import {HttpClient, HttpHeaders} from "@angular/common/http";
import {Observable} from "rxjs";
import {IFullArtist} from "../interfaces/api/IFullArtist";
import {IFullAlbum} from "../interfaces/api/IAlbumResponse";
import {IArtistAlbums} from "../interfaces/api/IArtistAlbums";
import {IFullTrack} from "../interfaces/api/itrack-response"

@Injectable({
  providedIn: 'root'
})
export class SpotifyService {
  baseUrl = 'https://api.spotify.com/v1';

  constructor(private _http : HttpClient) { }

  getToken(): Observable<any> {
    // Encode credentials
    const clientId = 'xxxxxx';
    const clientSecret = 'xxxxx';
    const headers = new HttpHeaders({
      'Content-Type':  'application/x-www-form-urlencoded',
      'Authorization': `Basic ${btoa(`${clientId}:${clientSecret}`)}`
    });
    return this._http.post('https://accounts.spotify.com/api/token', 'grant_type=client_credentials', {headers});
  }

  searchMusic(str:string, type='artist' ,token:string): Observable<any> {
    const headers = new HttpHeaders({
      'Authorization' : `Bearer ${token}`
    });
    return this._http.get(`${this.baseUrl}/search?query=${str}&offset=0&limit=50&type=${type}` , {headers});
  }


  getArtist(id:string ,token:string): Observable<IFullArtist> {
    const headers = new HttpHeaders({
      'Authorization' : `Bearer ${token}`
    });
    headers.append('Authorization' , 'Bearer ' + token);
    return this._http.get<IFullArtist>(`${this.baseUrl}/artists/${id}` , {headers : headers});
  }

  getAlbums(artistId:string ,token:string): Observable<IArtistAlbums> {
    const headers = new HttpHeaders({
      'Authorization' : `Bearer ${token}`
    });
    headers.append('Authorization' , 'Bearer ' + token);
    return this._http.get<IArtistAlbums>(`${this.baseUrl}/artists/${artistId}/albums/?query=&limit=50`, {headers});
  }

  getAlbum(albumId: string ,token:string): Observable<IFullAlbum> {
    const headers = new HttpHeaders({
      'Authorization' : `Bearer ${token}`
    });
    headers.append('Authorization' , 'Bearer ' + token);
    return this._http.get<IFullAlbum>(`${this.baseUrl}/albums/${albumId}` ,  {headers : headers});
}

getTrack(trackId: string ,token:string): Observable<IFullTrack> {
  const headers = new HttpHeaders({
    'Authorization' : `Bearer ${token}`
  });
  headers.append('Authorization' , 'Bearer ' + token);
  return this._http.get<IFullTrack>(`${this.baseUrl}/tracks/${trackId}` ,  {headers : headers});
}
}




Lyrics component


import { Component, OnInit, OnDestroy } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import {Lyric} from "../../interfaces/lyric";
import {LyricService} from "../../services/lyric.service";
import { SpotifyService } from 'src/app/services/spotify.service';
import { IFullTrack } from 'src/app/interfaces/api/itrack-response';
import { Observable } from 'rxjs'

@Component({
  selector: 'app-lyric',
  templateUrl: './lyric.component.html',
  styleUrls: ['./lyric.component.css'],
})
export class LyricComponent implements OnInit {
  track: IFullTrack;
  lyrics: Lyric[];
  editState: boolean = false;
  lyricToEdit: Lyric;
  lyric: Observable<Lyric[]>

  constructor(private route: ActivatedRoute,
    private router: Router,
    private lyricService: LyricService,
    private spotifyService: SpotifyService) {}

  ngOnInit() {
      const id = this.route.snapshot.paramMap.get('id');
      this.spotifyService.getToken().subscribe(data => {
        this.spotifyService.getTrack(id, data.access_token).subscribe(response=> {
          this.track = response;
        });
      });

      this.lyricService.getLyrics().subscribe(lyrics => {
        console.log(lyrics);
        this.lyrics = lyrics;
      });

}

deleteLyric(event, lyric: Lyric){
  this.clearState();
  this.lyricService.deleteLyric(lyric);
}

editLyric(event, lyric: Lyric){
  this.editState = true;
  this.lyricToEdit = lyric;
}

updateLyric(lyric: Lyric){
  this.lyricService.updateLyric(lyric);
  this.clearState();
}

clearState(){
  this.editState = false;
  this.lyricToEdit = null;
}

}



Add-Lyric Component

import { Component, OnInit } from '@angular/core';
import { LyricService } from 'src/app/services/lyric.service';
import { Lyric } from 'src/app/interfaces/lyric';


@Component({
  selector: 'app-add-lyric',
  templateUrl: './add-lyric.component.html',
  styleUrls: ['./add-lyric.component.css']
})
export class AddLyricComponent implements OnInit {
lyric: Lyric = {
  author: '',
  content: ''
}

  constructor(private lyricService: LyricService) { }

  ngOnInit() {
  }

onSubmit(){
  if(this.lyric.author != '' &&  this.lyric.content != ''){
    this.lyricService.addLyric(this.lyric);
    this.lyric.author = '';
    this.lyric.content = '';
  }
}

}


...