Fix tags, some parts of the markdown hydration, change how icon works

This commit is contained in:
2024-09-07 22:56:03 +02:00
parent d7a8087c6c
commit 0d1332dcd4
30 changed files with 88 additions and 83 deletions

View File

@@ -2,7 +2,7 @@
const route = useRoute();
const project = computed(() => parseInt(route.params.projectId as string));
const { data: navigation, refresh } = await useLazyFetch(() => `/api/project/${project.value}/navigation`, { immediate: false });
const { data: navigation, refresh } = await useFetch(() => `/api/project/${project.value}/navigation`, { immediate: false });
if(!isNaN(project.value))
{
await refresh();

View File

@@ -6,7 +6,7 @@
<template v-else-if="!!file">
<div v-if="file.type === 'Markdown'" class="p-6 ms-6">
<ProseH1>{{ file.title }}</ProseH1>
<Markdown v-model="file.content"></Markdown>
<Markdown :content="file.content"></Markdown>
</div>
<div v-else-if="file.type === 'Canvas'" class="w-[550px] h-[450px] overflow-hidden">
<CanvasRenderer :canvas="JSON.parse(file.content) " />

View File

@@ -5,15 +5,15 @@
<PreviewContent :project="project" :path="data[0].path" :anchor="hash">
<div class="inline-flex items-center">
<slot v-bind="$attrs"></slot>
<ThemeIcon class="w-4 h-4 inline-block" v-if="data && data[0] && data[0].type !== 'Markdown'" :height="20" :width="20"
:icon="`link-${data[0].type.toLowerCase()}`" />
<Icon class="w-4 h-4 inline-block" v-if="data && data[0] && data[0].type !== 'Markdown'" :height="20" :width="20"
:icon="`icons/link-${data[0].type.toLowerCase()}`" />
</div>
</PreviewContent>
</NuxtLink>
<NuxtLink no-prefetch v-else-if="href" :to="href" :class="class" class="text-accent-blue inline-flex items-center">
<slot v-bind="$attrs"></slot>
<ThemeIcon class="w-4 h-4 inline-block" v-if="data && data[0] && data[0].type !== 'Markdown'" :height="20" :width="20"
:icon="`link-${data[0].type.toLowerCase()}`" />
<Icon class="w-4 h-4 inline-block" v-if="data && data[0] && data[0].type !== 'Markdown'" :height="20" :width="20"
:icon="`icons/link-${data[0].type.toLowerCase()}`" />
</NuxtLink>
<slot :class="class" v-else v-bind="$attrs"></slot>
</Suspense>

View File

@@ -1,12 +1,12 @@
<template>
<HoverPopup @before-show="status === 'idle' && project && tag && execute()">
<HoverPopup class="mw-[400px]">
<template #content>
<Suspense>
<div v-if="status === 'pending'" class="loading w-[550px] h-[450px]"></div>
<div v-if="status === 'pending'" class="loading w-[400px] h-[150px]"></div>
<template v-else-if="!!data">
<div v-if="data.description" class="p-6 ms-6">
<ProseH2>{{ data.tag }}</ProseH2>
<Markdown v-model="data.description"></Markdown>
<div v-if="data.description" class="pb-4 pt-3 px-8">
<span class="text-2xl font-semibold">#{{ data.tag }}</span>
<Markdown :content="data.description"></Markdown>
</div>
<div class="h-100 w-100 flex flex-1 flex-col justify-center items-center" v-else>
<div class="text-3xl font-extralight tracking-wide text-light-60 dark:text-dark-60">Fichier vide</div>
@@ -19,7 +19,7 @@
</div>
</Suspense>
</template>
<template>
<template #default>
<span class="before:content-['#'] cursor-default bg-accent-blue bg-opacity-10 hover:bg-opacity-20 text-accent-blue text-sm px-1 ms-1 pb-0.5 rounded-full rounded-se-none border border-accent-blue border-opacity-30">
<slot></slot>
</span>
@@ -33,12 +33,9 @@ const { tag } = defineProps({
type: String,
required: true,
}
})
});
const route = useRoute();
const project = computed(() => parseInt(Array.isArray(route.params.projectId) ? '0' : route.params.projectId));
const { data, status, execute } = useFetch(`/api/project/${project.value}/tags/${tag}`, {
immediate: false,
key: `file:${project.value}:%${tag}`,
});
const { data, status } = useLazyFetch(`/api/project/${project.value}/tags/${tag}`);
</script>

View File

@@ -6,7 +6,7 @@
</div>
</Teleport>
<span ref="el" @mouseenter="debounce(show, 250)" @mouseleave="debounce(() => { emit('beforeHide'); display = false }, 250)">
<slot></slot>
<slot name="default"></slot>
</span>
</template>

View File

@@ -0,0 +1,13 @@
<script setup lang="ts">
interface Prop
{
icon: string;
width: number;
height: number;
}
defineProps<Prop>();
</script>
<template>
<span :class="$attrs.class" class="inline-block bg-light-100 dark:bg-dark-100 [mask-size:100%] [mask-repeat:no-repeat] [mask-position:center]" :style="`width: ${width}px; height: ${height}px; mask-image: url(/${icon}.svg)`"></span>
</template>

View File

@@ -1,6 +1,6 @@
<template>
<template
v-if="model && model.length > 0">
v-if="content && content.length > 0">
<Suspense>
<MarkdownRenderer #default :key="key" v-if="node" :node="node"></MarkdownRenderer>
<template #fallback><div class="loading"></div></template>
@@ -10,20 +10,15 @@
<script setup lang="ts">
import { hash } from 'ohash'
import { watch, computed } from 'vue'
import type { Root } from 'hast';
const model = defineModel<string>();
const { content } = defineProps({
content: {
type: String,
required: true,
}
})
const parser = useMarkdown();
const key = computed(() => hash(model.value));
const node = ref<Root>();
watch(model, async () => {
if(model.value && model.value)
{
node.value = parser(model.value);
}
}, { immediate: true });
const key = computed(() => hash(content));
const node = computed(() => content ? parser(content) : undefined);
</script>

View File

@@ -70,14 +70,6 @@ export default defineComponent({
default: () => ({})
}
},
watch: {
node: {
handler: function(val, old) {
},
deep: true,
}
},
async setup(props) {
if(props.proses)
{
@@ -111,8 +103,7 @@ function renderNode(node: RootContent, tags: Record<string, any>): VNode | undef
}
else if(node.type === 'element')
{
node.tagName === 'tag' && console.log(node);
return h(tags[node.tagName] ?? node.tagName, { ...node.properties, class: node.properties.className }, {default: () => node.children.map(e => renderNode(e, tags)).filter(e => !!e)});
return h(tags[node.tagName] ?? node.tagName, { ...node.properties, class: node.properties.className }, { default: () => node.children.map(e => renderNode(e, tags)).filter(e => !!e) });
}
return undefined;

View File

@@ -2,6 +2,7 @@
import { useTemplateRef } from 'vue';
const containerRef = useTemplateRef("container");
const { loggedIn, user } = useUserSession();
const { direction } = useSwipe(window, { threshold: 150 });
watch(direction, () => {
@@ -55,7 +56,13 @@ onUnmounted(() => {
<NuxtLink @click="hideNavigation" class=" text-light-100 dark:text-dark-100 hover:text-opacity-70 max-sm:ps-6" aria-label="Accueil" :to="{ path: '/', force: true }"><ThemeIcon class="inline" icon="logo" :width=56 :height=56 /></NuxtLink>
<div class="flex gap-4 items-center">
<ThemeSwitch />
<NuxtLink @click="hideNavigation" class="" :to="{ path: '/user/profile', force: true }"><ThemeIcon icon="user" :width=32 :height=32 /></NuxtLink>
<NuxtLink @click="hideNavigation" class="" :to="{ path: '/user/profile', force: true }"><div class=" hover:border-opacity-70 flex border p-px border-light-70 dark:border-dark-70">
<Icon v-if="!loggedIn" icon="icons/user-login" :width=28 :height=28 />
<picture v-else :width=28 :height=28 class="flex" >
<source :src="`/users/${user?.id}/small.jpg`" :width=28 :height=28 />
<Icon :icon="`users/unknown`" :width=28 :height=28 ></Icon>
</picture>
</div></NuxtLink>
</div>
</div>
<div class="flex"><SearchView @navigate="hideNavigation" /></div>