Whoops, didn't commit for a while. Added button toggling logic, doesn't work
This commit is contained in:
parent
da4f4ba151
commit
a60a4c4885
21 changed files with 353 additions and 106 deletions
|
|
@ -6,6 +6,7 @@
|
|||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "vue-tsc && vite build",
|
||||
"watch": "vue-tsc --watch & sleep 3 && vite build --watch",
|
||||
"preview": "vite preview"
|
||||
},
|
||||
"dependencies": {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,14 @@
|
|||
<script setup lang="ts">
|
||||
import Table from "./components/Table.vue";
|
||||
import { state } from "./state";
|
||||
|
||||
state.populate()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Table></Table>
|
||||
<div class="container">
|
||||
<Table></Table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
<tr v-for="date in dates" :key="date.valueOf()">
|
||||
<th>{{ dateString(date) }}</th>
|
||||
<td v-for="track in state.tracks" :key="track.id">
|
||||
<TickComponent :isSet="track.isSetOn(date)" :trackID="track.id" />
|
||||
<TickComponent :date="date" :track="track" />
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
|
|
|||
|
|
@ -1,23 +1,22 @@
|
|||
<template>
|
||||
<button :class="className()" @click="toggle"></button>
|
||||
<button :class="className" @click="toggle"></button>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { Ref, ref } from 'vue';
|
||||
import { computed } from 'vue';
|
||||
import { state } from '../state';
|
||||
import { Track } from '../track';
|
||||
|
||||
const tick: Ref<Tick | undefined> = ref()
|
||||
const props = defineProps<{ isSet: boolean, track: Track }>()
|
||||
const props = defineProps<{ date: Date, track: Track }>()
|
||||
|
||||
const className = () => props.isSet ? "button is-rounded is-info" : "button is-rounded"
|
||||
const isSet = computed(() => props.track.isSetOn(props.date))
|
||||
|
||||
const className = computed(() => isSet.value ? "button is-rounded is-info" : "button is-rounded")
|
||||
|
||||
async function toggle() {
|
||||
const $tick = tick.value
|
||||
if ($tick) {
|
||||
await state.taskMarkedIncomplete($tick)
|
||||
tick.value = undefined
|
||||
if (isSet.value) {
|
||||
await state.taskMarkedIncomplete(props.track)
|
||||
} else
|
||||
tick.value = await state.taskCompleted(props.track)
|
||||
await state.taskCompleted(props.track, props.date)
|
||||
}
|
||||
</script>
|
||||
|
|
@ -2,32 +2,87 @@ import { reactive } from "vue"
|
|||
import { Track } from "./track"
|
||||
import { error } from "./error"
|
||||
|
||||
enum State {
|
||||
Unfetched,
|
||||
Fetching,
|
||||
Fetched,
|
||||
}
|
||||
|
||||
export const state = reactive({
|
||||
tracks: new Array<Track>,
|
||||
isPopulating: false,
|
||||
async populate() {
|
||||
if (this.isPopulating) return
|
||||
this.isPopulating = true
|
||||
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)
|
||||
}
|
||||
}
|
||||
// this.tracks = this.tracks.map(track => {
|
||||
// if (track.id === tick.track_id) {
|
||||
// const ticks = track.ticks ?? []
|
||||
// ticks.push(tick)
|
||||
// track.ticks = ticks
|
||||
// }
|
||||
// return track
|
||||
// })
|
||||
})
|
||||
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)
|
||||
// this.tracks = this.tracks.map(track => {
|
||||
// if (track.id === tick.track_id) {
|
||||
// track.ticks = track.ticks?.filter($tick => $tick.id === tick.id)
|
||||
// }
|
||||
// return track
|
||||
// })
|
||||
})
|
||||
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()
|
||||
this.isPopulating = false
|
||||
},
|
||||
async taskCompleted(track: Track): Promise<Tick> {
|
||||
const result = await fetch(`/api/v1/tracks/${track.id}/ticked`, { method: "PATCH" })
|
||||
const body = await result.text()
|
||||
if (!result.ok) {
|
||||
async populate() {
|
||||
if (this.state != State.Unfetched) return
|
||||
await this.repopulate()
|
||||
this.streamUpdatesFromServer()
|
||||
this.state = State.Fetched
|
||||
},
|
||||
async taskCompleted(track: Track, date: Date): Promise<Tick> {
|
||||
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}"): ${result.status} ${result.statusText}`)
|
||||
throw new Error(`error setting tick for track ${track.id} ("${track.name}"): ${response.status} ${response.statusText}`)
|
||||
}
|
||||
const tick: Tick = JSON.parse(body)
|
||||
track.ticks = track.ticks ?? []
|
||||
track.ticks.push(tick)
|
||||
const tracks = this.tracks.map($track => track.id === $track.id ? track : $track)
|
||||
this.tracks = tracks
|
||||
return tick
|
||||
return JSON.parse(body)
|
||||
},
|
||||
async taskMarkedIncomplete(tick: Tick) {
|
||||
const { ok, status, statusText } = await fetch(`/api/v1/ticks/${tick.id}`, { method: 'DELETE' })
|
||||
async taskMarkedIncomplete(track: Track) {
|
||||
const { ok, status, statusText } = await fetch(`/api/v1/tracks/${track.id}/all-ticks`, { method: 'DELETE' })
|
||||
if (!ok)
|
||||
error(`error deleting tick ${tick.id}: ${statusText} (${status})`)
|
||||
error(`error deleting ticks for ${track.id}: ${statusText} (${status})`)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -58,8 +58,8 @@ class Tick implements ITick {
|
|||
|
||||
date(): Date | null {
|
||||
if (this.year && this.month && this.day && this.hour && this.minute && this.second) {
|
||||
return null
|
||||
return new Date(this.year!, this.month!, this.day, this.hour, this.minute, this.second)
|
||||
}
|
||||
return new Date(this.year!, this.month!, this.day, this.hour, this.minute, this.second)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,7 +55,8 @@ export class Track implements ITrack {
|
|||
for (var tick of (this.ticks ?? [])) {
|
||||
if (
|
||||
date.getUTCFullYear() == tick.year &&
|
||||
date.getUTCMonth() == tick.month &&
|
||||
(date.getUTCMonth() + 1) == tick.month &&
|
||||
// Javascript Date ^^^ uses 0-index for dates of months 🤦
|
||||
date.getDate() == tick.day
|
||||
) return true
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue