mirror of
https://gitlab.com/PronounsPage/PronounsPage.git
synced 2025-10-04 10:34:07 -04:00
95 lines
3.2 KiB
Vue
95 lines
3.2 KiB
Vue
<script setup lang="ts">
|
|
import Columnist from 'avris-columnist';
|
|
import type { RouteLocationRaw } from 'vue-router';
|
|
|
|
import useConfig from '~/composables/useConfig.ts';
|
|
import type { Post } from '~/server/blog.ts';
|
|
|
|
const props = defineProps<{
|
|
posts: string[] | Post[];
|
|
details?: boolean;
|
|
}>();
|
|
|
|
const { data: postsFull } = useAsyncData(`posts-${JSON.stringify(props.posts)}`, async () => {
|
|
if (!props.posts.length) {
|
|
return [];
|
|
}
|
|
if (typeof props.posts[0] === 'object') {
|
|
return props.posts as Post[];
|
|
}
|
|
return await $fetch('/api/blog', {
|
|
params: {
|
|
slugs: props.posts,
|
|
},
|
|
});
|
|
});
|
|
|
|
const config = useConfig();
|
|
|
|
const shortcuts: Record<string, string | undefined> = {};
|
|
if (config.blog && config.blog.shortcuts) {
|
|
for (const shortcut in config.blog.shortcuts) {
|
|
if (!config.blog.shortcuts.hasOwnProperty(shortcut)) {
|
|
continue;
|
|
}
|
|
shortcuts[config.blog.shortcuts[shortcut]] = shortcut;
|
|
}
|
|
}
|
|
|
|
const generateLink = (slug: string): RouteLocationRaw => {
|
|
const keepFullPath = config.blog?.keepFullPath || [];
|
|
return shortcuts[slug] !== undefined && !keepFullPath.includes(slug)
|
|
? `/${shortcuts[slug]}`
|
|
: { name: 'blogEntry', params: { slug } };
|
|
};
|
|
|
|
const entries = useTemplateRef<HTMLDivElement>('entries');
|
|
onMounted(async () => {
|
|
if (entries.value) {
|
|
const columnist = new Columnist(entries.value);
|
|
columnist.start();
|
|
}
|
|
});
|
|
</script>
|
|
|
|
<template>
|
|
<div ref="entries" class="columnist-wall row">
|
|
<div v-for="post in postsFull" class="columnist-column col-12 col-sm-6 col-md-4 mb-3">
|
|
<div class="card shadow">
|
|
<nuxt-link v-if="post.hero" :to="generateLink(post.slug)">
|
|
<img :src="post.hero.src" :class="['w-100', post.hero.class]" :alt="post.hero.alt" loading="lazy">
|
|
</nuxt-link>
|
|
<nuxt-link :to="generateLink(post.slug)" class="card-body text-center h4 p-3 mb-0 post-title">
|
|
<Spelling :text="post.title" />
|
|
</nuxt-link>
|
|
<div v-if="details" class="card-footer small">
|
|
<ul class="list-inline mb-0">
|
|
<li class="list-inline-item small">
|
|
<Icon v="calendar" />
|
|
{{ post.date }}
|
|
</li>
|
|
<li v-for="author in post.authors" class="list-inline-item">
|
|
<nuxt-link v-if="author.startsWith('@')" :to="`/${author}`" class="badge bg-light text-dark border">
|
|
<Icon v="collective-logo.svg" class="invertible" />
|
|
{{ author }}
|
|
</nuxt-link>
|
|
<span v-else class="badge bg-light text-dark border">
|
|
{{ author }}
|
|
</span>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<style lang="scss" scoped>
|
|
.columnist-wall > .columnist-column {
|
|
transition: margin-top .2s ease-in-out;
|
|
}
|
|
.post-title {
|
|
text-wrap: balance;
|
|
}
|
|
</style>
|