fix: Google Font
feat: add a todo view
This commit is contained in:
@@ -9,7 +9,6 @@ import {
|
|||||||
watch,
|
watch,
|
||||||
} from "vue"
|
} from "vue"
|
||||||
|
|
||||||
import LiteLoading from "@/components/LiteLoading.vue"
|
|
||||||
import StackedNote from "@/components/StackedNote.vue"
|
import StackedNote from "@/components/StackedNote.vue"
|
||||||
import { useLinks } from "@/hooks/useLinks.hook"
|
import { useLinks } from "@/hooks/useLinks.hook"
|
||||||
import { useMarkdown } from "@/hooks/useMarkdown.hook"
|
import { useMarkdown } from "@/hooks/useMarkdown.hook"
|
||||||
@@ -19,7 +18,6 @@ import { useVisitRepo } from "@/modules/history/hooks/useVisitRepo.hook"
|
|||||||
import CacheAllNotes from "@/modules/note/components/CacheAllNote.vue"
|
import CacheAllNotes from "@/modules/note/components/CacheAllNote.vue"
|
||||||
import { useUserRepoStore } from "@/modules/repo/store/userRepo.store"
|
import { useUserRepoStore } from "@/modules/repo/store/userRepo.store"
|
||||||
import { useUserSettings } from "@/modules/user/hooks/useUserSettings.hook"
|
import { useUserSettings } from "@/modules/user/hooks/useUserSettings.hook"
|
||||||
import { useRoute } from "vue-router"
|
|
||||||
import SkeletonLoader from "@/components/SkeletonLoader.vue"
|
import SkeletonLoader from "@/components/SkeletonLoader.vue"
|
||||||
|
|
||||||
const HeaderNote = defineAsyncComponent(
|
const HeaderNote = defineAsyncComponent(
|
||||||
@@ -70,8 +68,6 @@ const hasContent = computed(() => !!renderedContent.value)
|
|||||||
watch(
|
watch(
|
||||||
renderedContent,
|
renderedContent,
|
||||||
async () => {
|
async () => {
|
||||||
console.log(renderedContent.value)
|
|
||||||
|
|
||||||
await nextTick()
|
await nextTick()
|
||||||
listenToClick()
|
listenToClick()
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -107,6 +107,28 @@ defineProps<{ user: string; repo: string }>()
|
|||||||
<line x1="9" y1="15" x2="13" y2="15" />
|
<line x1="9" y1="15" x2="13" y2="15" />
|
||||||
</svg>
|
</svg>
|
||||||
</router-link>
|
</router-link>
|
||||||
|
<router-link :to="{ name: 'TodoNotes', params: { user, repo } }">
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="36"
|
||||||
|
height="36"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="1.5"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
class="icon icon-tabler icons-tabler-outline icon-tabler-list-check"
|
||||||
|
>
|
||||||
|
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||||
|
<path d="M3.5 5.5l1.5 1.5l2.5 -2.5" />
|
||||||
|
<path d="M3.5 11.5l1.5 1.5l2.5 -2.5" />
|
||||||
|
<path d="M3.5 17.5l1.5 1.5l2.5 -2.5" />
|
||||||
|
<path d="M11 6l9 0" />
|
||||||
|
<path d="M11 12l9 0" />
|
||||||
|
<path d="M11 18l9 0" />
|
||||||
|
</svg>
|
||||||
|
</router-link>
|
||||||
<router-link :to="{ name: 'FleetingNotes', params: { user, repo } }">
|
<router-link :to="{ name: 'FleetingNotes', params: { user, repo } }">
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
|||||||
@@ -1,33 +1,34 @@
|
|||||||
import { computed, Ref, ref, toValue } from 'vue'
|
import { computed, Ref, ref, toValue } from "vue"
|
||||||
|
|
||||||
import { useMarkdown } from '@/hooks/useMarkdown.hook'
|
import { useMarkdown } from "@/hooks/useMarkdown.hook"
|
||||||
import { prepareNoteCache } from '@/modules/note/cache/prepareNoteCache'
|
import { prepareNoteCache } from "@/modules/note/cache/prepareNoteCache"
|
||||||
import { queryFileContent } from '@/modules/repo/services/repo'
|
import { queryFileContent } from "@/modules/repo/services/repo"
|
||||||
import { useUserRepoStore } from '@/modules/repo/store/userRepo.store'
|
import { useUserRepoStore } from "@/modules/repo/store/userRepo.store"
|
||||||
|
|
||||||
export const useFile = (sha: Ref<string> | string, retrieveContent = true) => {
|
export const useFile = (sha: Ref<string> | string, retrieveContent = true) => {
|
||||||
const store = useUserRepoStore()
|
const store = useUserRepoStore()
|
||||||
|
const shaValue = toValue(sha)
|
||||||
|
|
||||||
const path = computed(() => {
|
const path = computed(() => {
|
||||||
const file = store.files.find((file) => file.sha === toValue(sha))
|
const file = store.files.find((file) => file.sha === shaValue)
|
||||||
return file?.path
|
return file?.path
|
||||||
})
|
})
|
||||||
|
|
||||||
const {
|
const {
|
||||||
render,
|
render,
|
||||||
renderFromUTF8,
|
renderFromUTF8,
|
||||||
getRawContent: getRawContentFromFile
|
getRawContent: getRawContentFromFile,
|
||||||
} = useMarkdown(toValue(sha))
|
} = useMarkdown(shaValue)
|
||||||
|
|
||||||
const { getCachedNote, saveCacheNote } = prepareNoteCache(
|
const { getCachedNote, saveCacheNote } = prepareNoteCache(
|
||||||
toValue(sha),
|
shaValue,
|
||||||
toValue(path)
|
toValue(path),
|
||||||
)
|
)
|
||||||
|
|
||||||
const fromCache = ref(false)
|
const fromCache = ref(false)
|
||||||
const rawContent = ref('')
|
const rawContent = ref("")
|
||||||
const content = computed(() =>
|
const content = computed(() =>
|
||||||
rawContent.value ? renderFromUTF8(rawContent.value) : ''
|
rawContent.value ? renderFromUTF8(rawContent.value) : "",
|
||||||
)
|
)
|
||||||
|
|
||||||
const getEditedSha = async () => {
|
const getEditedSha = async () => {
|
||||||
@@ -46,26 +47,22 @@ export const useFile = (sha: Ref<string> | string, retrieveContent = true) => {
|
|||||||
fromCache.value = !!cachedNote
|
fromCache.value = !!cachedNote
|
||||||
|
|
||||||
if (cachedNote) {
|
if (cachedNote) {
|
||||||
if (from === 'path') {
|
if (from === "path") {
|
||||||
queryFileContent(store.user, store.repo, toValue(sha)).then(
|
queryFileContent(store.user, store.repo, shaValue).then(
|
||||||
(fileContent) => {
|
(fileContent) => {
|
||||||
if (!fileContent) {
|
if (!fileContent) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
saveCacheNote(fileContent)
|
saveCacheNote(fileContent)
|
||||||
rawContent.value = getRawContentFromFile(fileContent)
|
rawContent.value = getRawContentFromFile(fileContent)
|
||||||
}
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return cachedNote.content
|
return cachedNote.content
|
||||||
}
|
}
|
||||||
|
|
||||||
const fileContent = await queryFileContent(
|
const fileContent = await queryFileContent(store.user, store.repo, shaValue)
|
||||||
store.user,
|
|
||||||
store.repo,
|
|
||||||
toValue(sha)
|
|
||||||
)
|
|
||||||
|
|
||||||
if (!fileContent) {
|
if (!fileContent) {
|
||||||
return null
|
return null
|
||||||
@@ -114,6 +111,6 @@ export const useFile = (sha: Ref<string> | string, retrieveContent = true) => {
|
|||||||
getCachedFileContent,
|
getCachedFileContent,
|
||||||
getEditedSha,
|
getEditedSha,
|
||||||
fromCache,
|
fromCache,
|
||||||
saveCacheNote
|
saveCacheNote,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import { computed } from 'vue'
|
import { computed } from "vue"
|
||||||
|
import { useUserRepoStore } from "@/modules/repo/store/userRepo.store"
|
||||||
import { useUserRepoStore } from '@/modules/repo/store/userRepo.store'
|
|
||||||
|
|
||||||
export const useFolderNotes = (folders: string[]) => {
|
export const useFolderNotes = (folders: string[]) => {
|
||||||
const store = useUserRepoStore()
|
const store = useUserRepoStore()
|
||||||
@@ -9,25 +8,25 @@ export const useFolderNotes = (folders: string[]) => {
|
|||||||
store.files.filter(
|
store.files.filter(
|
||||||
(file) =>
|
(file) =>
|
||||||
folders.some((folder) => file.path?.startsWith(folder)) &&
|
folders.some((folder) => file.path?.startsWith(folder)) &&
|
||||||
file.path?.endsWith('.md')
|
file.path?.endsWith(".md"),
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
const content = computed(() =>
|
const content = computed(() =>
|
||||||
filteredNotes.value?.length > 0
|
filteredNotes.value?.length > 0
|
||||||
? filteredNotes.value
|
? filteredNotes.value
|
||||||
.map((note) => {
|
.map((note) => {
|
||||||
const firstFolder = note.path?.split('/').shift()
|
const firstFolder = note.path?.split("/").shift()
|
||||||
|
|
||||||
return `- [${note.path?.replace(`${firstFolder}/`, '')}](${
|
return `- [${note.path?.replace(`${firstFolder}/`, "")}](${
|
||||||
note.path
|
note.path
|
||||||
})`
|
})`
|
||||||
})
|
})
|
||||||
.join('\n')
|
.join("\n")
|
||||||
: ''
|
: "",
|
||||||
)
|
)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
content
|
content,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,14 @@
|
|||||||
import { computed } from 'vue'
|
import { computed } from "vue"
|
||||||
|
import { useUserRepoStore } from "@/modules/repo/store/userRepo.store"
|
||||||
import { useUserRepoStore } from '@/modules/repo/store/userRepo.store'
|
|
||||||
|
|
||||||
export const useNotes = () => {
|
export const useNotes = () => {
|
||||||
const store = useUserRepoStore()
|
const store = useUserRepoStore()
|
||||||
|
|
||||||
const notes = computed(() =>
|
const notes = computed(() =>
|
||||||
store.files.filter((file) => file.path?.endsWith('.md'))
|
store.files.filter((file) => file.path?.endsWith(".md")),
|
||||||
)
|
)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
notes
|
notes,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,73 +1,79 @@
|
|||||||
import { createRouter, createWebHistory, RouteRecordRaw } from 'vue-router'
|
import { createRouter, createWebHistory, RouteRecordRaw } from "vue-router"
|
||||||
|
|
||||||
import Home from '@/views/HomeApp.vue'
|
import Home from "@/views/HomeApp.vue"
|
||||||
|
|
||||||
const routes: Array<RouteRecordRaw> = [
|
const routes: Array<RouteRecordRaw> = [
|
||||||
{
|
{
|
||||||
path: '/repo-list',
|
path: "/repo-list",
|
||||||
name: 'RepoList',
|
name: "RepoList",
|
||||||
component: () => import('@/views/RepoList.vue')
|
component: () => import("@/views/RepoList.vue"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/:user/:repo',
|
path: "/:user/:repo",
|
||||||
name: 'FluxNoteView',
|
name: "FluxNoteView",
|
||||||
props: true,
|
props: true,
|
||||||
component: () => import('@/views/FluxNoteView.vue')
|
component: () => import("@/views/FluxNoteView.vue"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/:user/:repo/share/:note',
|
path: "/:user/:repo/share/:note",
|
||||||
name: 'ShareNotes',
|
name: "ShareNotes",
|
||||||
props: true,
|
props: true,
|
||||||
component: () => import('@/views/ShareNotes.vue')
|
component: () => import("@/views/ShareNotes.vue"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/:user/:repo/inbox',
|
path: "/:user/:repo/inbox",
|
||||||
name: 'FleetingNotes',
|
name: "FleetingNotes",
|
||||||
props: true,
|
props: true,
|
||||||
component: () => import('@/views/FleetingNotes.vue')
|
component: () => import("@/views/FleetingNotes.vue"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/:user/:repo/draft',
|
path: "/:user/:repo/draft",
|
||||||
name: 'DraftNotes',
|
name: "DraftNotes",
|
||||||
props: true,
|
props: true,
|
||||||
component: () => import('@/views/DraftNotes.vue')
|
component: () => import("@/views/DraftNotes.vue"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/:user/:repo/history',
|
path: "/:user/:repo/todo",
|
||||||
name: 'HistoricNotes',
|
name: "TodoNotes",
|
||||||
props: true,
|
props: true,
|
||||||
component: () => import('@/views/HistoricNotes.vue')
|
component: () => import("@/views/TodoNotes.vue"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/:user/:repo/spaced-repetition',
|
path: "/:user/:repo/history",
|
||||||
name: 'SpacedRepetitionCard',
|
name: "HistoricNotes",
|
||||||
props: true,
|
props: true,
|
||||||
component: () => import('@/views/SpacedRepetitionCard.vue')
|
component: () => import("@/views/HistoricNotes.vue"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/:user/:repo/need-review-cards',
|
path: "/:user/:repo/spaced-repetition",
|
||||||
name: 'NeedReviewCards',
|
name: "SpacedRepetitionCard",
|
||||||
props: true,
|
props: true,
|
||||||
component: () => import('@/views/NeedReviewCards.vue')
|
component: () => import("@/views/SpacedRepetitionCard.vue"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/about',
|
path: "/:user/:repo/need-review-cards",
|
||||||
name: 'About',
|
name: "NeedReviewCards",
|
||||||
component: () => import('@/views/AboutApp.vue')
|
props: true,
|
||||||
|
component: () => import("@/views/NeedReviewCards.vue"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/',
|
path: "/about",
|
||||||
name: 'Home',
|
name: "About",
|
||||||
component: Home
|
component: () => import("@/views/AboutApp.vue"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/:catchAll(.*)',
|
path: "/",
|
||||||
name: 'SpaceCowboy',
|
name: "Home",
|
||||||
component: () => import('@/views/SpaceCowboy.vue')
|
component: Home,
|
||||||
}
|
},
|
||||||
|
{
|
||||||
|
path: "/:catchAll(.*)",
|
||||||
|
name: "SpaceCowboy",
|
||||||
|
component: () => import("@/views/SpaceCowboy.vue"),
|
||||||
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
export const router = createRouter({
|
export const router = createRouter({
|
||||||
history: createWebHistory(import.meta.env.BASE_URL),
|
history: createWebHistory(import.meta.env.BASE_URL),
|
||||||
routes
|
routes,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
import FontFaceObserver from "fontfaceobserver"
|
import FontFaceObserver from "fontfaceobserver"
|
||||||
|
|
||||||
const assembleFontLink = (font: string) => {
|
const assembleFontLink = (font: string) => {
|
||||||
return `https://fonts.googleapis.com/css2?display=swap&family=${font.replaceAll(
|
return `https://fonts.googleapis.com/css2?display=swap&family=${font
|
||||||
" ",
|
.replaceAll(",", "&family=")
|
||||||
"+",
|
.replaceAll(" ", "+")}`
|
||||||
)}`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const downloadGoogleFont = async (font: string): Promise<void> => {
|
export const downloadGoogleFont = async (font: string): Promise<void> => {
|
||||||
|
|||||||
@@ -1,3 +1,17 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { computed, defineAsyncComponent } from "vue"
|
||||||
|
|
||||||
|
import { useFolderNotes } from "@/modules/note/hooks/useFolderNotes"
|
||||||
|
|
||||||
|
const FluxNote = defineAsyncComponent(() => import("@/components/FluxNote.vue"))
|
||||||
|
const props = defineProps<{ user: string; repo: string }>()
|
||||||
|
const user = computed(() => props.user)
|
||||||
|
const repo = computed(() => props.repo)
|
||||||
|
|
||||||
|
const DRAFT_FOLDER = ["drafts", "_drafts"]
|
||||||
|
const { content } = useFolderNotes(DRAFT_FOLDER)
|
||||||
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="draft-notes">
|
<div class="draft-notes">
|
||||||
<flux-note key="draft-notes" :user="user" :repo="repo" :content="content">
|
<flux-note key="draft-notes" :user="user" :repo="repo" :content="content">
|
||||||
@@ -6,34 +20,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
import { defineAsyncComponent, defineComponent } from 'vue'
|
|
||||||
|
|
||||||
import { useFolderNotes } from '@/modules/note/hooks/useFolderNotes'
|
|
||||||
|
|
||||||
const FluxNote = defineAsyncComponent(() => import('@/components/FluxNote.vue'))
|
|
||||||
|
|
||||||
const DRAFT_FOLDER = ['drafts', '_drafts']
|
|
||||||
|
|
||||||
export default defineComponent({
|
|
||||||
name: 'DraftNotes',
|
|
||||||
components: {
|
|
||||||
FluxNote
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
user: { type: String, required: true },
|
|
||||||
repo: { type: String, required: true }
|
|
||||||
},
|
|
||||||
setup() {
|
|
||||||
const { content } = useFolderNotes(DRAFT_FOLDER)
|
|
||||||
|
|
||||||
return {
|
|
||||||
content
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.draft-notes {
|
.draft-notes {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
48
src/views/TodoNotes.vue
Normal file
48
src/views/TodoNotes.vue
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { computed, defineAsyncComponent, watch } from "vue"
|
||||||
|
import { useUserRepoStore } from "@/modules/repo/store/userRepo.store"
|
||||||
|
import { useFile } from "@/hooks/useFile.hook"
|
||||||
|
import { computedAsync } from "@vueuse/core"
|
||||||
|
|
||||||
|
const FluxNote = defineAsyncComponent(() => import("@/components/FluxNote.vue"))
|
||||||
|
const props = defineProps<{ user: string; repo: string }>()
|
||||||
|
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 content = computedAsync(() => {
|
||||||
|
if (!todoNote.value) {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
const { getContent } = useFile(todoNote.value?.sha ?? "", false)
|
||||||
|
|
||||||
|
return getContent()
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="todo-notes">
|
||||||
|
<flux-note
|
||||||
|
key="todo-notes"
|
||||||
|
:user="user"
|
||||||
|
:repo="repo"
|
||||||
|
:content="content"
|
||||||
|
:parse-content="false"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.todo-notes {
|
||||||
|
flex: 1;
|
||||||
|
|
||||||
|
input[type="checkbox"] {
|
||||||
|
margin-right: 0.5rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
Reference in New Issue
Block a user