145 lines
5.9 KiB
JavaScript
145 lines
5.9 KiB
JavaScript
import "../../components/AppTitle.js"
|
||
import taskServer from "/tasks/@server/tasks.js"
|
||
|
||
class Tasks extends Shadow {
|
||
tasks = []
|
||
newTitle = ""
|
||
|
||
render() {
|
||
VStack(() => {
|
||
AppTitle("Tasks")
|
||
.marginTop(1, em)
|
||
.marginBottom(2, em)
|
||
.marginLeft(7, vw)
|
||
|
||
VStack(() => {
|
||
this.tasks.forEach((task) => {
|
||
HStack(() => {
|
||
// Circular checkbox
|
||
VStack(() => {})
|
||
.width(1.1, em).height(1.1, em)
|
||
.minWidth(1.1, em)
|
||
.borderRadius(50, pct)
|
||
.border(task.done ? "none" : "1.5px solid var(--divider)")
|
||
.background(task.done ? "var(--accent)" : "transparent")
|
||
.cursor("pointer")
|
||
.flexShrink(0)
|
||
.onClick(async (end) => {
|
||
if(end) {
|
||
const updated = await taskServer.updateTaskDone(task.id, !task.done)
|
||
console.log(updated)
|
||
if (updated && updated.id) {
|
||
const idx = this.tasks.findIndex(t => t.id === task.id)
|
||
if (idx >= 0) this.tasks[idx] = updated
|
||
this.rerender()
|
||
}
|
||
}
|
||
})
|
||
|
||
p(`#${task.id}`)
|
||
.margin(0)
|
||
.fontSize(0.75, em)
|
||
.color("var(--headertext)")
|
||
.opacity(0.4)
|
||
.flexShrink(0)
|
||
|
||
input("", "100%")
|
||
.attr({ value: task.title, placeholder: "Task title" })
|
||
.background("transparent")
|
||
.border("none")
|
||
.outline("none")
|
||
.fontSize(0.9, em)
|
||
.color(task.done ? "var(--headertext)" : "var(--text)")
|
||
.textDecoration(task.done ? "line-through" : "none")
|
||
.opacity(task.done ? 0.5 : 1)
|
||
.padding(0)
|
||
.onBlur(async function () {
|
||
const newVal = this.value.trim()
|
||
if (newVal && newVal !== task.title) {
|
||
await taskServer.editTaskTitle(task.id, newVal)
|
||
task.title = newVal
|
||
}
|
||
})
|
||
.onKeyDown(function (e) {
|
||
if (e.key === "Enter") this.blur()
|
||
})
|
||
|
||
// Delete button
|
||
p("×")
|
||
.margin(0)
|
||
.fontSize(1.1, em)
|
||
.color("var(--headertext)")
|
||
.opacity(0.3)
|
||
.cursor("pointer")
|
||
.flexShrink(0)
|
||
.onHover(function (hovering) {
|
||
this.style.opacity = hovering ? "1" : "0.3"
|
||
this.style.color = hovering ? "var(--quillred)" : "var(--headertext)"
|
||
})
|
||
.onClick(async () => {
|
||
await taskServer.deleteTask(task.id)
|
||
this.tasks = this.tasks.filter(t => t.id !== task.id)
|
||
this.rerender()
|
||
})
|
||
})
|
||
.gap(0.65, em)
|
||
.alignItems("center")
|
||
.paddingVertical(0.4, em)
|
||
.paddingHorizontal(0.5, em)
|
||
.marginRight(0)
|
||
})
|
||
})
|
||
.width(70, pct)
|
||
.marginLeft(7, vw)
|
||
.border("1px solid var(--divider)")
|
||
.borderRadius(8, px)
|
||
.overflow("hidden")
|
||
|
||
// Add task input
|
||
input("", "70%")
|
||
.attr({ placeholder: "New task..." })
|
||
.marginLeft(7, vw)
|
||
.marginTop(0.5, em)
|
||
.padding(0.5, em)
|
||
.paddingHorizontal(0.75, em)
|
||
.background("var(--darkaccent)")
|
||
.border("1px solid var(--divider)")
|
||
.borderRadius(8, px)
|
||
.outline("none")
|
||
.fontSize(0.9, em)
|
||
.boxSizing("border-box")
|
||
.color("var(--text)")
|
||
.onKeyDown(async (e) => {
|
||
if (e.key === "Enter") {
|
||
console.log("enter")
|
||
const val = e.target.value.trim()
|
||
if (!val) return
|
||
const task = await taskServer.addTask(global.currentNetwork.id, val)
|
||
if (task && task.id) {
|
||
this.tasks.push(task)
|
||
e.target.value = ""
|
||
this.rerender()
|
||
} else {
|
||
if(task.error) console.error("Error making task: ", task.error)
|
||
}
|
||
}
|
||
})
|
||
})
|
||
.onAppear(async () => {
|
||
const tasks = await taskServer.getTasks(global.currentNetwork.id)
|
||
if (tasks && !tasks.error && tasks.length !== this.tasks.length) {
|
||
this.tasks = tasks
|
||
this.rerender()
|
||
}
|
||
})
|
||
.gap(0)
|
||
.paddingTop(2, pct)
|
||
.paddingBottom(4, pct)
|
||
.width(80, vw)
|
||
.height(100, pct)
|
||
.overflow("auto")
|
||
}
|
||
}
|
||
|
||
register(Tasks)
|