102 lines
2.3 KiB
Vue
102 lines
2.3 KiB
Vue
<script setup lang="ts">
|
|
import { computed, defineAsyncComponent, nextTick, ref, watch } from "vue"
|
|
import { useUserRepoStore } from "@/modules/repo/store/userRepo.store"
|
|
import { useCheckboxCommit } from "@/hooks/useCheckboxCommit.hook"
|
|
import { markdownBuilder } from "@/hooks/useMarkdown.hook"
|
|
import { queryFileContent } from "@/modules/repo/services/repo"
|
|
import { decodeBase64ToUTF8 } from "@/utils/decodeBase64ToUTF8"
|
|
|
|
type Prop = {
|
|
user: string
|
|
repo: string
|
|
}
|
|
|
|
const FluxNote = defineAsyncComponent(() => import("@/components/FluxNote.vue"))
|
|
const props = defineProps<Prop>()
|
|
const user = computed(() => props.user)
|
|
const repo = computed(() => props.repo)
|
|
|
|
const store = useUserRepoStore()
|
|
|
|
const todoNote = computed(() =>
|
|
store.files.find((file) => file.path?.endsWith("_todo/todo.md")),
|
|
)
|
|
|
|
const sha = computed(() => todoNote.value?.sha ?? "")
|
|
const path = computed(() => todoNote.value?.path)
|
|
|
|
const { toHTML } = markdownBuilder(repo)
|
|
|
|
// Setup checkbox commit handler
|
|
const { pendingContent, syncContent, listenToCheckboxes, hasPendingChanges } =
|
|
useCheckboxCommit({
|
|
user: props.user,
|
|
repo: props.repo,
|
|
path,
|
|
initialContent: "",
|
|
initialSha: sha,
|
|
containerSelector: ".todo-notes .note-display",
|
|
debounceMs: 1000,
|
|
})
|
|
|
|
// Render pending content to HTML for display
|
|
const renderedContent = computed(() => {
|
|
if (!pendingContent.value) {
|
|
return ""
|
|
}
|
|
return toHTML(pendingContent.value)
|
|
})
|
|
|
|
// Fetch raw content when sha changes
|
|
watch(
|
|
sha,
|
|
async (newSha) => {
|
|
if (!newSha || hasPendingChanges.value) {
|
|
return
|
|
}
|
|
const base64Content = await queryFileContent(props.user, props.repo, newSha)
|
|
if (base64Content) {
|
|
const rawContent = decodeBase64ToUTF8(base64Content)
|
|
syncContent(rawContent, newSha)
|
|
}
|
|
},
|
|
{ immediate: true },
|
|
)
|
|
|
|
// Setup checkbox listeners when content renders
|
|
watch(
|
|
renderedContent,
|
|
async () => {
|
|
await nextTick()
|
|
listenToCheckboxes()
|
|
},
|
|
{ immediate: true },
|
|
)
|
|
</script>
|
|
|
|
<template>
|
|
<div class="todo-notes">
|
|
<flux-note
|
|
key="todo-notes"
|
|
:user="user"
|
|
:repo="repo"
|
|
:content="renderedContent"
|
|
:parse-content="false"
|
|
/>
|
|
</div>
|
|
</template>
|
|
|
|
<style lang="scss">
|
|
.todo-notes {
|
|
.note-display {
|
|
h1 {
|
|
font-size: 1.8rem;
|
|
}
|
|
}
|
|
|
|
input[type="checkbox"] {
|
|
margin-right: 0.5rem;
|
|
}
|
|
}
|
|
</style>
|