diff --git a/music-player/client/src/client.ts b/music-player/client/src/client.ts index 61f1ba8..c39a0ea 100644 --- a/music-player/client/src/client.ts +++ b/music-player/client/src/client.ts @@ -9,3 +9,10 @@ export interface TrackInfo { export const getTracks = (): Promise => fetch("/api/v1/tracks").then((r) => r.json()); + +export const playTrack = (id: string): Promise => + fetch("/api/v1/play", { + method: "POST", + headers: { "content-type": "application/json" }, + body: JSON.stringify({ id: id }), + }); diff --git a/music-player/client/src/components/PlaylistRow.ts b/music-player/client/src/components/PlaylistRow.ts new file mode 100644 index 0000000..0a63b27 --- /dev/null +++ b/music-player/client/src/components/PlaylistRow.ts @@ -0,0 +1,34 @@ +export class PlaylistRow extends HTMLElement { + onPlay: (trackId: string) => void; + + static get observedAttributes() { + return ["trackId"]; + } + + constructor() { + super(); + this.onPlay = (_) => {}; + } + + get trackId(): string | null { + return this.getAttribute("trackId"); + } + + set trackId(id: string | null) { + id ? this.setAttribute("trackId", id) : this.removeAttribute("trackId"); + } + + connectedCallback() { + this.classList.add("playlist-row"); + const playButton = document.createElement("button"); + playButton.innerHTML = "Play"; + + playButton.addEventListener("click", (_) => { + if (this.trackId) { + this.onPlay(this.trackId); + } + }); + + this.appendChild(playButton); + } +} diff --git a/music-player/client/src/components/TrackCard.ts b/music-player/client/src/components/TrackCard.ts index 241a9ce..0c902a7 100644 --- a/music-player/client/src/components/TrackCard.ts +++ b/music-player/client/src/components/TrackCard.ts @@ -8,7 +8,7 @@ export class TrackCard extends HTMLElement { durationContainer: TextField; static get observedAttributes() { - return ["id", "trackNumber", "name", "album", "artist", "duration"]; + return ["trackId", "trackNumber", "name", "album", "artist", "duration"]; } constructor() { @@ -29,6 +29,18 @@ export class TrackCard extends HTMLElement { this.durationContainer.classList.add("track-card__duration"); } + get trackId(): string | null { + return this.getAttribute("id"); + } + + set trackId(id: string | null) { + if (id) { + this.setAttribute("trackId", id); + } else { + this.removeAttribute("trackId"); + } + } + get name(): string | null { return this.getAttribute("name"); } diff --git a/music-player/client/src/main.ts b/music-player/client/src/main.ts index 2b6b2a3..880d155 100644 --- a/music-player/client/src/main.ts +++ b/music-player/client/src/main.ts @@ -1,14 +1,16 @@ import * as _ from "lodash"; -import { TrackInfo, getTracks } from "./client"; +import { TrackInfo, getTracks, playTrack } from "./client"; import { DataCard } from "./components/DataCard"; import { NowPlaying } from "./components/NowPlaying"; import { TextField } from "./components/TextField"; import { TrackCard } from "./components/TrackCard"; +import { PlaylistRow } from "./components/PlaylistRow"; window.customElements.define("data-card", DataCard); window.customElements.define("now-playing", NowPlaying); window.customElements.define("text-field", TextField); window.customElements.define("track-card", TrackCard); +window.customElements.define("playlist-row", PlaylistRow); declare global { interface HTMLElementTagNameMap { @@ -16,25 +18,30 @@ declare global { "now-playing": NowPlaying; "text-field": TextField; "track-card": TrackCard; + "playlist-row": PlaylistRow; } } const updateTrackList = (tracks: TrackInfo[]) => { - const track_list = document.querySelector(".track-list__tracks"); - if (track_list) { - let track_formats = _.map(tracks, (info) => { + const playlist = document.querySelector(".track-list__tracks"); + if (playlist) { + _.map(tracks, (info) => { let card: TrackCard = document.createElement("track-card"); + let listItem: PlaylistRow = document.createElement("playlist-row"); + + card.trackId = info.id; card.name = info.name || null; card.album = info.album || null; card.artist = info.artist || null; card.duration = (info.duration && `${info.duration}`) || null; - return card; - }); - _.map(track_formats, (trackCard) => { - let listItem = document.createElement("li"); - listItem.classList.add("track-list__row"); - listItem.appendChild(trackCard); - track_list.appendChild(listItem); + + listItem.appendChild(card); + listItem.trackId = info.id; + listItem.onPlay = (id: string) => { + console.log("time to play ", id); + playTrack(id); + }; + playlist.appendChild(listItem); }); } else { console.log("track_list does not exist"); diff --git a/music-player/client/styles.scss b/music-player/client/styles.scss index a3d8f05..0f8280b 100644 --- a/music-player/client/styles.scss +++ b/music-player/client/styles.scss @@ -143,6 +143,11 @@ body { list-style: none; } +.playlist-row { + display: flex; + margin-top: 32px; +} + .track-list__row { margin-top: 32px; }