diff --git a/src/views/TodoNotes.vue b/src/views/TodoNotes.vue
index 9aca62d..1123977 100644
--- a/src/views/TodoNotes.vue
+++ b/src/views/TodoNotes.vue
@@ -23,6 +23,7 @@ type Prop = {
}
const TODO_PATH = "todo.txt"
+const DONE_PATH = "done.txt"
const FluxNote = defineAsyncComponent(() => import("@/components/FluxNote.vue"))
@@ -58,6 +59,34 @@ watch(
{ immediate: true }
)
+const doneFile = computed(() => store.files.find((f) => f.path === DONE_PATH))
+const doneSha = computed(() => doneFile.value?.sha ?? "")
+const donePath = computed(() => doneFile.value?.path ?? DONE_PATH)
+
+// Reuse useTodoTxtCommit as a read-only loader. We never call its `mutate`,
+// so nothing is ever written to done.txt from this view — the file is
+// produced by an external tool.
+const { items: doneItems, syncContent: syncDoneContent } = useTodoTxtCommit({
+ user: props.user,
+ repo: props.repo,
+ path: donePath,
+ initialContent: "",
+ initialSha: doneSha,
+ debounceMs: 1000
+})
+
+watch(
+ doneSha,
+ async (newSha) => {
+ if (!newSha) return
+ const base64 = await queryFileContent(props.user, props.repo, newSha)
+ if (base64) {
+ syncDoneContent(decodeBase64ToUTF8(base64), newSha)
+ }
+ },
+ { immediate: true }
+)
+
// Rank `A` = 65 .. `Z` = 90; absent priority is Infinity so it sorts last
// regardless of locale collation quirks.
const priorityRank = (p?: string): number =>
@@ -75,6 +104,10 @@ const taskEntries = computed(() => {
return out
})
+const archivedTasks = computed(() =>
+ doneItems.value.filter((line): line is Task => !isBlank(line))
+)
+
const allProjects = computed(() => {
const set = new Set