1
0
Fork 0
forked from TWS/kalkutago

Whoops, didn't commit for a while. Added button toggling logic, doesn't work

This commit is contained in:
D. Scott Boggs 2023-06-20 08:40:35 -04:00
parent da4f4ba151
commit a60a4c4885
21 changed files with 353 additions and 106 deletions

View file

@ -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": {

View file

@ -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>

View file

@ -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>

View file

@ -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>

View file

@ -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})`)
}
})
})

View file

@ -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
}
}

View file

@ -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
}