import { reactive } from "vue" import { Track } from "./track" import { error } from "./error" enum State { Unfetched, Fetching, Fetched, } export const state = reactive({ tracks: new Array, state: State.Unfetched, streamUpdatesFromServer() { const source = new EventSource("/api/v1/updates") source.addEventListener("open", () => console.debug("opened event source")) source.addEventListener('message', event => console.log(event)) source.addEventListener('TickAdded', event => { console.log(event) const tick: Tick = JSON.parse(event.data) // for (const track of this.tracks) { // if (track.id === tick.track_id) { // console.debug('pushing tick') // track.ticks?.push(tick) // } // } const tracks = this.tracks.map(track => { if (track.id === tick.track_id) { const ticks = track.ticks ?? [] ticks.push(tick) track.ticks = ticks } return track }) console.debug(tracks) this.tracks = tracks }) source.addEventListener('TickDropped', event => { console.log(event) const tick: Tick = JSON.parse(event.data) // for (const track of this.tracks) // if (track.id === tick.track_id) // track.ticks = track.ticks?.filter($tick => $tick.id === tick.id) const tracks = this.tracks.map(track => { if (track.id === tick.track_id) { track.ticks = track.ticks?.filter($tick => $tick.id !== tick.id) } return track }) console.debug(tracks) this.tracks = tracks }) source.addEventListener('Lagged', event => { console.log(event) // Refresh the page, refetching the list of tracks and ticks window.location = window.location }) source.addEventListener('error', event => { error(event) window.location = window.location }) }, async repopulate() { this.state = State.Fetching this.tracks = await Track.fetchAll() }, async populate() { if (this.state != State.Unfetched) return await this.repopulate() this.streamUpdatesFromServer() this.state = State.Fetched }, async taskCompleted(track: Track, date: Date): Promise { let query = new URLSearchParams() query.append("year", date.getUTCFullYear().toString()) query.append("month", (date.getUTCMonth() + 1).toString()) // good thing I still had this ^^^^^^^^^^^^^^ in mind when I wrote this 😬 query.append("day", date.getUTCDate().toString()) const response: Response = await fetch(`/api/v1/tracks/${track.id}/ticked?${query.toString()}`, { method: "PATCH" }) const body = await response.text() if (!response.ok) { error(body) throw new Error(`error setting tick for track ${track.id} ("${track.name}"): ${response.status} ${response.statusText}`) } return JSON.parse(body) }, async taskMarkedIncomplete(track: Track) { const { ok, status, statusText } = await fetch(`/api/v1/tracks/${track.id}/all-ticks`, { method: 'DELETE' }) if (!ok) error(`error deleting ticks for ${track.id}: ${statusText} (${status})`) } })