import debug from "debug"; import { css, html, LitElement } from "lit"; import { customElement, property, state } from "lit/decorators.js"; import { NamedNode } from "n3"; import { getTopGraph } from "../RdfdbSyncedGraph"; import { show } from "../show_specific"; import { SyncedGraph } from "../SyncedGraph"; export { Light9TimelineAudio } from "../light9-timeline-audio"; export { Light9CursorCanvas } from "../Light9CursorCanvas"; export { RdfdbSyncedGraph } from "../RdfdbSyncedGraph"; export { ResourceDisplay } from "../ResourceDisplay"; const log = debug("songs"); async function postJson(url: string, jsBody: Object) { return fetch(url, { method: "POST", headers: { "Content-Type": "applcation/json" }, body: JSON.stringify(jsBody), }); } class SongRow { constructor(public uri: NamedNode, public label: string) {} } @customElement("light9-song-listing") export class Light9SongListing extends LitElement { static styles = [ css` td { font-size: 18pt; white-space: nowrap; padding: 0 10px; background: #9b9b9b; } tr.current td { background: #dbf5e4; } tr td:first-child { box-shadow: initial; } tr.current td:first-child { box-shadow: inset 0px 2px 10px 0px black; } button { min-height: 30pt; min-width: 65pt; } `, ]; graph!: SyncedGraph; @state() playingSong: NamedNode | null = null; @property() selectedSong: NamedNode | null = null; @state() songs: SongRow[] = []; @state() isPlaying = false; constructor() { super(); getTopGraph().then((g) => { this.graph = g; this.graph.runHandler(this.getSongs.bind(this), "getsongs"); this.graph.runHandler(this.playState.bind(this), "playstate"); }); } getSongs() { this.songs = []; const U = this.graph.U(); try { const playlist: NamedNode = this.graph.uriValue(show, U(":playList")); (this.graph.items(playlist) as NamedNode[]).forEach((song: NamedNode) => { this.songs.push(new SongRow(song, this.graph.labelOrTail(song))); }); } catch (e) { // likely it's startup- no graph yet log(e); } } playState() { const U = this.graph.U(); try { this.isPlaying = this.graph.booleanValue(U(":ascoltami"), U(":playing")); this.playingSong = this.graph.uriValue(U(":ascoltami"), U(":song")); } catch (e) { log(e); } } render() { return html` ${this.songs.map((song) => { const playing = this.playingSong && song.uri.equals(this.playingSong); const selected = this.selectedSong && song.uri.equals(this.selectedSong); // could use return html` `; })}
${song.label.slice(0, 2)} ${song.label.slice(2).trim()}
`; } clickSongRow(ev: MouseEvent) { ev.preventDefault(); const row = (ev.target as HTMLElement).closest(".song") as HTMLElement; const song = new NamedNode(row.dataset.uri!); if (this.selectedSong && song.equals(this.selectedSong)) { this.selectedSong = null; } else { this.selectedSong = song; } this.dispatchEvent(new CustomEvent("selectsong", { detail: { song: this.selectedSong } })); } }