feat(tasks): dual-write tasks to SQLite alongside localStorage; boot-load from SQLite on startup
This commit is contained in:
@@ -201,6 +201,18 @@ function loadTasks() {
|
|||||||
|
|
||||||
export const tasks = $state(loadTasks());
|
export const tasks = $state(loadTasks());
|
||||||
|
|
||||||
|
// On boot in the desktop runtime, load canonical tasks from SQLite.
|
||||||
|
// localStorage remains the warm cache and fallback.
|
||||||
|
if (typeof window !== "undefined" && hasTauriRuntime()) {
|
||||||
|
invoke("list_tasks_cmd")
|
||||||
|
.then((sqliteTasks) => {
|
||||||
|
tasks.length = 0;
|
||||||
|
tasks.push(...sqliteTasks);
|
||||||
|
saveTasks();
|
||||||
|
})
|
||||||
|
.catch(() => {});
|
||||||
|
}
|
||||||
|
|
||||||
export function saveTasks() {
|
export function saveTasks() {
|
||||||
try {
|
try {
|
||||||
localStorage.setItem(TASKS_KEY, JSON.stringify(tasks));
|
localStorage.setItem(TASKS_KEY, JSON.stringify(tasks));
|
||||||
@@ -208,7 +220,7 @@ export function saveTasks() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function addTask(task) {
|
export function addTask(task) {
|
||||||
tasks.unshift({
|
const newTask = {
|
||||||
id: crypto.randomUUID(),
|
id: crypto.randomUUID(),
|
||||||
text: task.text,
|
text: task.text,
|
||||||
bucket: task.bucket || "inbox",
|
bucket: task.bucket || "inbox",
|
||||||
@@ -220,9 +232,20 @@ export function addTask(task) {
|
|||||||
createdAt: new Date().toISOString(),
|
createdAt: new Date().toISOString(),
|
||||||
sourceTranscriptId: task.sourceTranscriptId || null,
|
sourceTranscriptId: task.sourceTranscriptId || null,
|
||||||
notes: "",
|
notes: "",
|
||||||
});
|
};
|
||||||
|
tasks.unshift(newTask);
|
||||||
saveTasks();
|
saveTasks();
|
||||||
broadcastTasks();
|
broadcastTasks();
|
||||||
|
if (hasTauriRuntime()) {
|
||||||
|
invoke("create_task_cmd", {
|
||||||
|
request: {
|
||||||
|
id: newTask.id,
|
||||||
|
text: newTask.text,
|
||||||
|
bucket: newTask.bucket,
|
||||||
|
sourceTranscriptId: newTask.sourceTranscriptId,
|
||||||
|
},
|
||||||
|
}).catch(() => {});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function updateTask(id, updates) {
|
export function updateTask(id, updates) {
|
||||||
@@ -240,15 +263,24 @@ export function deleteTask(id) {
|
|||||||
tasks.splice(idx, 1);
|
tasks.splice(idx, 1);
|
||||||
saveTasks();
|
saveTasks();
|
||||||
broadcastTasks();
|
broadcastTasks();
|
||||||
|
if (hasTauriRuntime()) {
|
||||||
|
invoke("delete_task_cmd", { id }).catch(() => {});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function completeTask(id) {
|
export function completeTask(id) {
|
||||||
updateTask(id, { done: true, doneAt: new Date().toISOString() });
|
updateTask(id, { done: true, doneAt: new Date().toISOString() });
|
||||||
|
if (hasTauriRuntime()) {
|
||||||
|
invoke("complete_task_cmd", { id }).catch(() => {});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function uncompleteTask(id) {
|
export function uncompleteTask(id) {
|
||||||
updateTask(id, { done: false, doneAt: null });
|
updateTask(id, { done: false, doneAt: null });
|
||||||
|
if (hasTauriRuntime()) {
|
||||||
|
invoke("uncomplete_task_cmd", { id }).catch(() => {});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---- BroadcastChannel for multi-window task sync ----
|
// ---- BroadcastChannel for multi-window task sync ----
|
||||||
|
|||||||
Reference in New Issue
Block a user