meow
This commit is contained in:
parent
2c66a9b678
commit
9aa81ef675
28 changed files with 1735 additions and 242 deletions
|
@ -3,7 +3,6 @@
|
|||
<NuxtParticles
|
||||
class="w-full h-full z-0"
|
||||
id="tsparticles"
|
||||
@load="onLoad"
|
||||
:particlesInit="particlesInit"
|
||||
:options="{
|
||||
fullScreen: {
|
||||
|
|
|
@ -1,63 +1,13 @@
|
|||
<script setup lang="ts">
|
||||
import { globalMarkdown, MarkdownInput } from '~/assets/markdown_conf';
|
||||
import { useSlots } from 'vue';
|
||||
import fm, { type FrontMatterResult } from 'front-matter';
|
||||
<script setup>
|
||||
import '~/assets/style/markdown.scss';
|
||||
|
||||
// External inputs (reactive)
|
||||
const input = defineProps({
|
||||
input: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: "markdown",
|
||||
validator: (value: string) => ["markdown", "html"].includes(value)
|
||||
}
|
||||
input: Object
|
||||
});
|
||||
|
||||
// Internal state
|
||||
const contents = ref("");
|
||||
const loading = ref(false);
|
||||
const error = ref("");
|
||||
|
||||
const emit = defineEmits(["metadata"]);
|
||||
|
||||
function updateContents(input: string | undefined, type: "markdown" | "html" | undefined) {
|
||||
if (input === "" || input === undefined) {
|
||||
contents.value = "";
|
||||
error.value = "";
|
||||
return;
|
||||
}
|
||||
const markdown_input: MarkdownInput = type ?
|
||||
type === "markdown" ?
|
||||
MarkdownInput.from_markdown(input) : type == "html" ?
|
||||
MarkdownInput.from_html(input) :
|
||||
MarkdownInput.from_markdown(input) : MarkdownInput.from_markdown(input);
|
||||
|
||||
console.log("Rendering...")
|
||||
const render = globalMarkdown.render(markdown_input);
|
||||
console.log("Metadata: ", render.metadata);
|
||||
contents.value = render.contents;
|
||||
emit("metadata", render.metadata);
|
||||
|
||||
}
|
||||
|
||||
watch(() => input.input, (newVal) => {
|
||||
updateContents(newVal, input.type as "markdown" | "html");
|
||||
}, { immediate: true });
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="loading" class="text-center animate-pulse">
|
||||
<h2>Loading...</h2>
|
||||
</div>
|
||||
<div v-else-if="error" class="text-center">
|
||||
<h2>Error: {{ error }}</h2>
|
||||
</div>
|
||||
<div v-else class="md-contents">
|
||||
<div class="md-contents" v-html="contents"></div>
|
||||
</div>
|
||||
<ContentRendererMarkdown :value="input.input" class="md-contents" />
|
||||
</template>
|
|
@ -59,7 +59,6 @@ useSeoMeta({
|
|||
twitterTitle: fullTitle,
|
||||
twitterDescription: description,
|
||||
twitterImage: background
|
||||
|
||||
});
|
||||
|
||||
useHead({
|
||||
|
@ -87,6 +86,15 @@ useHead({
|
|||
]
|
||||
})
|
||||
|
||||
definePageMeta({
|
||||
title: fullTitle,
|
||||
description: description,
|
||||
"og:title": fullTitle,
|
||||
"og:description": description,
|
||||
"og:image": background,
|
||||
"og:url": siteConfig.siteUrl,
|
||||
});
|
||||
|
||||
watch(() => props.title, (newVal) => {
|
||||
title.value = newVal;
|
||||
fullTitle.value = title.value + ' | ' + siteConfig.siteTitle;
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
<script setup>
|
||||
<script setup lang="ts">
|
||||
import { ref, watch } from 'vue';
|
||||
import fm from 'front-matter';
|
||||
import { auto } from '@popperjs/core';
|
||||
|
||||
const props = defineProps({
|
||||
url: String,
|
||||
tagFilter: Array,
|
||||
tagFilter: Array<String>,
|
||||
// Allow sm, md, and lg
|
||||
size: {
|
||||
type: String,
|
||||
|
@ -14,49 +14,59 @@ const props = defineProps({
|
|||
}
|
||||
});
|
||||
|
||||
const url = ref(props.url)
|
||||
url.value = props.url
|
||||
const url: Ref<string> = ref("")
|
||||
url.value = props.url as string
|
||||
|
||||
const loading = ref(false)
|
||||
const data = ref(null)
|
||||
const error = ref(null)
|
||||
const error: Ref<string | null> = ref(null)
|
||||
const markdown: Ref<any> = ref(null)
|
||||
|
||||
const background = ref('');
|
||||
const title = ref(null);
|
||||
const description = ref(null);
|
||||
const date = ref(null);
|
||||
const tags = ref(null);
|
||||
const background: Ref<string> = ref('');
|
||||
const title: Ref<string> = ref("Untitled");
|
||||
const description: Ref<string | null> = ref(null);
|
||||
const date: Ref<string | null> = ref(null);
|
||||
const tags: Ref<string | null> = ref(null);
|
||||
|
||||
watch(url, (newVal) => {
|
||||
fetchData(newVal)
|
||||
}, { immediate: true })
|
||||
|
||||
// watch the params of the route to fetch the data again
|
||||
watch(url, async () => {
|
||||
await fetchData()
|
||||
}, {
|
||||
immediate: true
|
||||
});
|
||||
watch(markdown, (newVal) => {
|
||||
if (newVal) {
|
||||
title.value = newVal.title ? newVal.title : ""
|
||||
description.value = newVal.description ? newVal.description : ""
|
||||
date.value = newVal.date ? new Date(newVal.date).toLocaleDateString() : ""
|
||||
tags.value = newVal.tags ? newVal.tags : []
|
||||
background.value = newVal.background ? newVal.background : ""
|
||||
|
||||
async function fetchData() {
|
||||
error.value = data.value = null
|
||||
console.log("Title: " + title.value)
|
||||
console.log("Description: " + description.value)
|
||||
console.log("Date: " + date.value)
|
||||
console.log("Tags: " + tags.value)
|
||||
console.log("Background: " + background.value)
|
||||
}
|
||||
})
|
||||
|
||||
async function fetchData(url: string) {
|
||||
loading.value = true
|
||||
|
||||
// remove all .md extensions
|
||||
const temp_url = url.replace(/\.md$/, '')
|
||||
console.log("Fetching article: " + temp_url)
|
||||
try {
|
||||
data.value = await (await fetch(url.value)).text()
|
||||
console.log(url.value)
|
||||
const processed = fm(data.value)
|
||||
background.value = processed.attributes.background
|
||||
title.value = processed.attributes.title
|
||||
description.value = processed.attributes.description
|
||||
console.log(JSON.stringify(processed.attributes.date))
|
||||
date.value = processed.attributes.date
|
||||
tags.value = processed.attributes.tags
|
||||
const {data} = await useAsyncData(temp_url, () => queryContent(temp_url).findOne())
|
||||
|
||||
date.value = new Date(date.value).toLocaleDateString()
|
||||
} catch (err) {
|
||||
markdown.value = data.value;
|
||||
} catch (err: any) {
|
||||
error.value = err.toString()
|
||||
loading.value = false
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
fetchData(url.value)
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -79,7 +89,7 @@ async function fetchData() {
|
|||
</div>
|
||||
<div class="flex justify-center">
|
||||
<div v-for="tag in tags" :key="tag" class="m-1 text-center">
|
||||
<div v-if="props.tagFilter.includes(tag)">
|
||||
<div v-if="props.tagFilter?.includes(tag)">
|
||||
<span class="text-xs bg-slate-700 border-white border-2 text-white p-1 rounded-md">{{ tag }}</span>
|
||||
</div>
|
||||
<div v-else>
|
||||
|
@ -111,13 +121,13 @@ async function fetchData() {
|
|||
</div>
|
||||
<div class="flex justify-center">
|
||||
<div v-for="tag in tags" :key="tag" class="m-1 text-center">
|
||||
<div v-if="props.tagFilter.includes(tag)">
|
||||
<div v-if="props.tagFilter?.includes(tag)">
|
||||
<span class="text-xs bg-slate-700 border-white border-2 text-white p-1 rounded-md">{{ tag }}</span>
|
||||
</div>
|
||||
<div v-else>
|
||||
<div class="flex justify-center">
|
||||
<div v-for="tag in tags" :key="tag" class="m-1 text-center">
|
||||
<div v-if="props.tagFilter.includes(tag)">
|
||||
<div v-if="props.tagFilter?.includes(tag)">
|
||||
<span class="text-xs bg-slate-700 border-white border-2 text-white p-1 rounded-md">{{ tag }}</span>
|
||||
</div>
|
||||
<div v-else>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue