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)