diff --git a/web/ascoltami/Light9SongListing.ts b/web/ascoltami/Light9SongListing.ts new file mode 100644 --- /dev/null +++ b/web/ascoltami/Light9SongListing.ts @@ -0,0 +1,122 @@ +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` +
+ + ${song.label.slice(0, 2)} + ${song.label.slice(2).trim()} + + | ++ + | +