Fix tags, some parts of the markdown hydration, change how icon works
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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) " />
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -6,11 +6,11 @@
|
|||
"@types/diff": "^5.2.2",
|
||||
"@vueuse/nuxt": "^11.0.3",
|
||||
"hast-util-to-html": "^9.0.2",
|
||||
"nuxt": "^3.13.0",
|
||||
"nuxt": "^3.13.1",
|
||||
"nuxt-security": "^2.0.0-rc.9",
|
||||
"remark-breaks": "^4.0.0",
|
||||
"remark-ofm": "link:remark-ofm",
|
||||
"vue": "^3.5.0",
|
||||
"vue": "^3.5.3",
|
||||
"vue-router": "^4.4.3",
|
||||
"zod": "^3.23.8"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ const { data, status } = await useFetch(`/api/project/${route.params.projectId}/
|
|||
<template v-if="!!data && data.type == 'Markdown' && !!data.content">
|
||||
<div class="md:px-24 ps-8 my-1 whitespace-break-spaces">
|
||||
<ProseH1>{{ data.title }}</ProseH1>
|
||||
<Markdown v-model="data.content"></Markdown>
|
||||
<Markdown :content="data.content"></Markdown>
|
||||
</div>
|
||||
<CommentSide class="hidden" :comments="data.comments"></CommentSide>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ Le logo a été créé grace aux icones de [Game Icons](https://game-icons.net).
|
|||
<div class="publish-renderer">
|
||||
<div class="markdown-preview-view markdown-rendered node-insert-event hide-title">
|
||||
<div class="markdown-preview-sizer markdown-preview-section" style="padding-bottom: 0px;">
|
||||
<Markdown v-model="data" />
|
||||
<Markdown :content="data" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ async function submit()
|
|||
}
|
||||
else if(status.value === 'success' && login.success)
|
||||
{
|
||||
console.log(await navigateTo('/user/profile'));
|
||||
await navigateTo('/user/profile');
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ async function submit()
|
|||
}
|
||||
else if(status.value === 'success' && login.success)
|
||||
{
|
||||
console.log(await navigateTo('/user/profile'));
|
||||
await navigateTo('/user/profile');
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 256 256"><path fill="white" d="M200 156a27.87 27.87 0 0 0-19.4 7.84l-28.28-22A27.8 27.8 0 0 0 156 128a28 28 0 0 0-.45-5l19.45-6.45a28.07 28.07 0 1 0-2.53-7.58L153 115.45A28 28 0 0 0 128 100a27.7 27.7 0 0 0-7.6 1.06l-9.5-21.37A28 28 0 1 0 96 84a27.7 27.7 0 0 0 7.6-1.06l9.5 21.37a27.95 27.95 0 0 0-8.46 39.1L74 170.61a28 28 0 1 0 5.32 6l30.6-27.2a27.92 27.92 0 0 0 37.44-1.23l28.28 22A28 28 0 1 0 200 156m0-72a20 20 0 1 1-20 20a20 20 0 0 1 20-20M76 56a20 20 0 1 1 20 20a20 20 0 0 1-20-20M56 212a20 20 0 1 1 20-20a20 20 0 0 1-20 20m72-64a20 20 0 1 1 20-20a20 20 0 0 1-20 20m72 56a20 20 0 1 1 20-20a20 20 0 0 1-20 20"/></svg>
|
||||
|
Before Width: | Height: | Size: 700 B |
|
|
@ -1 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 256 256"><path fill="black" d="M200 156a27.87 27.87 0 0 0-19.4 7.84l-28.28-22A27.8 27.8 0 0 0 156 128a28 28 0 0 0-.45-5l19.45-6.45a28.07 28.07 0 1 0-2.53-7.58L153 115.45A28 28 0 0 0 128 100a27.7 27.7 0 0 0-7.6 1.06l-9.5-21.37A28 28 0 1 0 96 84a27.7 27.7 0 0 0 7.6-1.06l9.5 21.37a27.95 27.95 0 0 0-8.46 39.1L74 170.61a28 28 0 1 0 5.32 6l30.6-27.2a27.92 27.92 0 0 0 37.44-1.23l28.28 22A28 28 0 1 0 200 156m0-72a20 20 0 1 1-20 20a20 20 0 0 1 20-20M76 56a20 20 0 1 1 20 20a20 20 0 0 1-20-20M56 212a20 20 0 1 1 20-20a20 20 0 0 1-20 20m72-64a20 20 0 1 1 20-20a20 20 0 0 1-20 20m72 56a20 20 0 1 1 20-20a20 20 0 0 1-20 20"/></svg>
|
||||
|
Before Width: | Height: | Size: 700 B |
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 256 256"><path d="M200 156a27.87 27.87 0 0 0-19.4 7.84l-28.28-22A27.8 27.8 0 0 0 156 128a28 28 0 0 0-.45-5l19.45-6.45a28.07 28.07 0 1 0-2.53-7.58L153 115.45A28 28 0 0 0 128 100a27.7 27.7 0 0 0-7.6 1.06l-9.5-21.37A28 28 0 1 0 96 84a27.7 27.7 0 0 0 7.6-1.06l9.5 21.37a27.95 27.95 0 0 0-8.46 39.1L74 170.61a28 28 0 1 0 5.32 6l30.6-27.2a27.92 27.92 0 0 0 37.44-1.23l28.28 22A28 28 0 1 0 200 156m0-72a20 20 0 1 1-20 20a20 20 0 0 1 20-20M76 56a20 20 0 1 1 20 20a20 20 0 0 1-20-20M56 212a20 20 0 1 1 20-20a20 20 0 0 1-20 20m72-64a20 20 0 1 1 20-20a20 20 0 0 1-20 20m72 56a20 20 0 1 1 20-20a20 20 0 0 1-20 20"/></svg>
|
||||
|
After Width: | Height: | Size: 687 B |
|
|
@ -1 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 256 256"><path fill="white" d="m210.83 85.17l-56-56A4 4 0 0 0 152 28H56a12 12 0 0 0-12 12v176a12 12 0 0 0 12 12h144a12 12 0 0 0 12-12V88a4 4 0 0 0-1.17-2.83M156 41.65L198.34 84H156ZM200 220H56a4 4 0 0 1-4-4V40a4 4 0 0 1 4-4h92v52a4 4 0 0 0 4 4h52v124a4 4 0 0 1-4 4m-36-84a4 4 0 0 1-4 4H96a4 4 0 0 1 0-8h64a4 4 0 0 1 4 4m0 32a4 4 0 0 1-4 4H96a4 4 0 0 1 0-8h64a4 4 0 0 1 4 4"/></svg>
|
||||
|
Before Width: | Height: | Size: 459 B |
|
|
@ -1 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 256 256"><path fill="black" d="m210.83 85.17l-56-56A4 4 0 0 0 152 28H56a12 12 0 0 0-12 12v176a12 12 0 0 0 12 12h144a12 12 0 0 0 12-12V88a4 4 0 0 0-1.17-2.83M156 41.65L198.34 84H156ZM200 220H56a4 4 0 0 1-4-4V40a4 4 0 0 1 4-4h92v52a4 4 0 0 0 4 4h52v124a4 4 0 0 1-4 4m-36-84a4 4 0 0 1-4 4H96a4 4 0 0 1 0-8h64a4 4 0 0 1 4 4m0 32a4 4 0 0 1-4 4H96a4 4 0 0 1 0-8h64a4 4 0 0 1 4 4"/></svg>
|
||||
|
Before Width: | Height: | Size: 459 B |
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 256 256"><path d="m210.83 85.17l-56-56A4 4 0 0 0 152 28H56a12 12 0 0 0-12 12v176a12 12 0 0 0 12 12h144a12 12 0 0 0 12-12V88a4 4 0 0 0-1.17-2.83M156 41.65L198.34 84H156ZM200 220H56a4 4 0 0 1-4-4V40a4 4 0 0 1 4-4h92v52a4 4 0 0 0 4 4h52v124a4 4 0 0 1-4 4m-36-84a4 4 0 0 1-4 4H96a4 4 0 0 1 0-8h64a4 4 0 0 1 4 4m0 32a4 4 0 0 1-4 4H96a4 4 0 0 1 0-8h64a4 4 0 0 1 4 4"/></svg>
|
||||
|
After Width: | Height: | Size: 446 B |
|
|
@ -1 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 256 256"><path fill="white" d="M241.72 113a11.88 11.88 0 0 0-9.73-5H212V88a12 12 0 0 0-12-12h-70.67l-28.8-21.6a12.05 12.05 0 0 0-7.2-2.4H40a12 12 0 0 0-12 12v144a4 4 0 0 0 4 4h179.09a4 4 0 0 0 3.79-2.74l28.49-85.47a11.86 11.86 0 0 0-1.65-10.79M40 60h53.33a4 4 0 0 1 2.4.8l29.87 22.4a4 4 0 0 0 2.4.8h72a4 4 0 0 1 4 4v20H69.76a12 12 0 0 0-11.38 8.21L36 183.35V64a4 4 0 0 1 4-4m195.78 61.26L208.2 204H37.55L66 118.74a4 4 0 0 1 3.76-2.74H232a4 4 0 0 1 3.79 5.26Z"/></svg>
|
||||
|
Before Width: | Height: | Size: 545 B |
|
|
@ -1 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 256 256"><path fill="black" d="M241.72 113a11.88 11.88 0 0 0-9.73-5H212V88a12 12 0 0 0-12-12h-70.67l-28.8-21.6a12.05 12.05 0 0 0-7.2-2.4H40a12 12 0 0 0-12 12v144a4 4 0 0 0 4 4h179.09a4 4 0 0 0 3.79-2.74l28.49-85.47a11.86 11.86 0 0 0-1.65-10.79M40 60h53.33a4 4 0 0 1 2.4.8l29.87 22.4a4 4 0 0 0 2.4.8h72a4 4 0 0 1 4 4v20H69.76a12 12 0 0 0-11.38 8.21L36 183.35V64a4 4 0 0 1 4-4m195.78 61.26L208.2 204H37.55L66 118.74a4 4 0 0 1 3.76-2.74H232a4 4 0 0 1 3.79 5.26Z"/></svg>
|
||||
|
Before Width: | Height: | Size: 545 B |
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 256 256"><path d="M241.72 113a11.88 11.88 0 0 0-9.73-5H212V88a12 12 0 0 0-12-12h-70.67l-28.8-21.6a12.05 12.05 0 0 0-7.2-2.4H40a12 12 0 0 0-12 12v144a4 4 0 0 0 4 4h179.09a4 4 0 0 0 3.79-2.74l28.49-85.47a11.86 11.86 0 0 0-1.65-10.79M40 60h53.33a4 4 0 0 1 2.4.8l29.87 22.4a4 4 0 0 0 2.4.8h72a4 4 0 0 1 4 4v20H69.76a12 12 0 0 0-11.38 8.21L36 183.35V64a4 4 0 0 1 4-4m195.78 61.26L208.2 204H37.55L66 118.74a4 4 0 0 1 3.76-2.74H232a4 4 0 0 1 3.79 5.26Z"/></svg>
|
||||
|
After Width: | Height: | Size: 532 B |
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 256 256"><path d="M254 136a6 6 0 0 1-6 6h-18v18a6 6 0 0 1-12 0v-18h-18a6 6 0 0 1 0-12h18v-18a6 6 0 0 1 12 0v18h18a6 6 0 0 1 6 6m-57.41 60.14a6 6 0 1 1-9.18 7.72C166.9 179.45 138.69 166 108 166s-58.89 13.45-79.41 37.86a6 6 0 0 1-9.18-7.72C35.14 177.41 55 164.48 77 158.25a66 66 0 1 1 62 0c22 6.23 41.86 19.16 57.59 37.89M108 154a54 54 0 1 0-54-54a54.06 54.06 0 0 0 54 54"/></svg>
|
||||
|
After Width: | Height: | Size: 456 B |
|
|
@ -1 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 256 256"><path fill="white" d="M128 28a100 100 0 1 0 100 100A100.11 100.11 0 0 0 128 28M68.87 198.42a68 68 0 0 1 118.26 0a91.8 91.8 0 0 1-118.26 0m124.3-5.55a75.6 75.6 0 0 0-44.51-34a44 44 0 1 0-41.32 0a75.6 75.6 0 0 0-44.51 34a92 92 0 1 1 130.34 0M128 156a36 36 0 1 1 36-36a36 36 0 0 1-36 36"/></svg>
|
||||
|
Before Width: | Height: | Size: 379 B |
|
|
@ -1 +0,0 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 256 256"><path fill="black" d="M128 28a100 100 0 1 0 100 100A100.11 100.11 0 0 0 128 28M68.87 198.42a68 68 0 0 1 118.26 0a91.8 91.8 0 0 1-118.26 0m124.3-5.55a75.6 75.6 0 0 0-44.51-34a44 44 0 1 0-41.32 0a75.6 75.6 0 0 0-44.51 34a92 92 0 1 1 130.34 0M128 156a36 36 0 1 1 36-36a36 36 0 0 1-36 36"/></svg>
|
||||
|
Before Width: | Height: | Size: 379 B |
|
|
@ -0,0 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 256 256"><path fill="currentColor" d="M229.19 213c-15.81-27.32-40.63-46.49-69.47-54.62a70 70 0 1 0-63.44 0C67.44 166.5 42.62 185.67 26.81 213a6 6 0 1 0 10.38 6c19.21-33.19 53.15-53 90.81-53s71.6 19.81 90.81 53a6 6 0 1 0 10.38-6M70 96a58 58 0 1 1 58 58a58.07 58.07 0 0 1-58-58"/></svg>
|
||||
|
After Width: | Height: | Size: 362 B |
|
|
@ -2,34 +2,42 @@ import useDatabase from '~/composables/useDatabase';
|
|||
import type { Tag } from '~/types/api';
|
||||
|
||||
export default defineCachedEventHandler(async (e) => {
|
||||
const project = getRouterParam(e, "projectId");
|
||||
const tag = getRouterParam(e, "tag");
|
||||
const query = getQuery(e);
|
||||
|
||||
if(!project)
|
||||
try
|
||||
{
|
||||
const project = getRouterParam(e, "projectId");
|
||||
const tag = getRouterParam(e, "tag");
|
||||
const query = getQuery(e);
|
||||
|
||||
if(!project)
|
||||
{
|
||||
setResponseStatus(e, 404);
|
||||
return;
|
||||
}
|
||||
if(!tag)
|
||||
{
|
||||
setResponseStatus(e, 404);
|
||||
return;
|
||||
}
|
||||
|
||||
const where = ["project = $project", "tag = $tag"];
|
||||
const criteria: Record<string, any> = { $project: project, $tag: tag };
|
||||
|
||||
const db = useDatabase();
|
||||
|
||||
const content = db.query(`SELECT * FROM explorer_tags WHERE ${where.join(" and ")}`).get(criteria) as Tag;
|
||||
|
||||
if(content !== undefined)
|
||||
{
|
||||
return content;
|
||||
}
|
||||
|
||||
setResponseStatus(e, 404);
|
||||
return;
|
||||
}
|
||||
if(!tag)
|
||||
catch(err)
|
||||
{
|
||||
setResponseStatus(e, 404);
|
||||
return;
|
||||
console.error(err);
|
||||
setResponseStatus(e, 500);
|
||||
}
|
||||
|
||||
const where = ["project = $project", "tag = $tag"];
|
||||
const criteria: Record<string, any> = { $project: project, $tag: tag };
|
||||
|
||||
const db = useDatabase();
|
||||
|
||||
const content = db.query(`SELECT * FROM explorer_tags WHERE ${where.join(" and ")}`).get(criteria) as Tag;
|
||||
|
||||
if(content !== undefined)
|
||||
{
|
||||
return content;
|
||||
}
|
||||
|
||||
setResponseStatus(e, 404);
|
||||
}, {
|
||||
maxAge: 60*60*24,
|
||||
getKey: (e) => `tag-${getRouterParam(e, "projectId")}-${getRouterParam(e, "tag")}`
|
||||
|
|
|
|||
|
|
@ -121,14 +121,11 @@ export default defineTask({
|
|||
updateTags.finalize();
|
||||
|
||||
useStorage('cache').clear();
|
||||
|
||||
console.log("Sync finished");
|
||||
|
||||
return { result: true };
|
||||
}
|
||||
catch(e)
|
||||
{
|
||||
console.error(e);
|
||||
return { result: false };
|
||||
}
|
||||
},
|
||||
|
|
|
|||