This commit is contained in:
metacryst
2026-04-28 20:05:00 -05:00
commit 0d6c7683ff
123 changed files with 20922 additions and 0 deletions

144
tasks/desktop/tasks.js Normal file
View File

@@ -0,0 +1,144 @@
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)