56 lines
2.1 KiB
Vue
56 lines
2.1 KiB
Vue
<script setup lang="ts">
|
|
import type { Entry } from '../types/entry'
|
|
|
|
const props = defineProps<{ entry: Entry, search: string }>()
|
|
|
|
const COLLAPSE_AFTER_CHARS = 320
|
|
const COLLAPSE_AFTER_LINES = 5
|
|
|
|
const { showCovers } = useAppConfig().diary
|
|
const expanded = ref(false)
|
|
|
|
const searching = computed(() => searchTerms(props.search).length > 0)
|
|
const isLong = computed(() =>
|
|
props.entry.text.length > COLLAPSE_AFTER_CHARS || props.entry.text.split('\n').length > COLLAPSE_AFTER_LINES
|
|
)
|
|
const collapsed = computed(() => isLong.value && !expanded.value && !searching.value)
|
|
const wordCount = computed(() => props.entry.text.split(/\s+/).filter(Boolean).length)
|
|
const parts = computed(() => highlight(props.entry.text, props.search))
|
|
</script>
|
|
|
|
<template>
|
|
<div class="flex gap-4">
|
|
<div
|
|
v-if="showCovers && entry.kind === 'review'"
|
|
class="aspect-2/3 w-16 shrink-0 self-start overflow-hidden rounded shadow-sm ring-1 ring-default"
|
|
>
|
|
<CoverTile :title="entry.review.title" :subtitle="entry.review.author" />
|
|
</div>
|
|
|
|
<article class="min-w-0 flex-1">
|
|
<div class="flex min-w-0 items-baseline gap-3">
|
|
<span class="shrink-0 text-xs text-muted tabular-nums">{{ formatDate(entry.date) }}</span>
|
|
<p v-if="entry.kind === 'review'" class="min-w-0 truncate">
|
|
<span class="font-medium text-highlighted">{{ entry.review.title }}</span>
|
|
<span v-if="entry.review.author" class="ml-3 text-sm text-muted">{{ entry.review.author }}</span>
|
|
</p>
|
|
</div>
|
|
|
|
<p
|
|
class="mt-1.5 text-sm leading-relaxed whitespace-pre-line text-default"
|
|
:class="{ 'line-clamp-5': collapsed }"
|
|
><template v-for="(part, index) in parts" :key="index"><mark v-if="part.hit" class="rounded-sm bg-primary/30 px-0.5 text-highlighted">{{ part.text }}</mark><template v-else>{{ part.text }}</template></template></p>
|
|
|
|
<UButton
|
|
v-if="isLong && !searching"
|
|
size="xs"
|
|
color="neutral"
|
|
variant="link"
|
|
class="mt-1 px-0"
|
|
:label="expanded ? 'Show less' : `Read more (${wordCount} words)`"
|
|
@click="expanded = !expanded"
|
|
/>
|
|
</article>
|
|
</div>
|
|
</template>
|