30 lines
1.7 KiB
Vue
30 lines
1.7 KiB
Vue
<script setup lang="ts">
|
|
import { ChevronRight, Files, Flame, HardDrive, Radio, Repeat2 } from '@lucide/vue'
|
|
|
|
import { availabilityLabel, formatBytes, heatLabel, relativeDate } from '@/lib/format'
|
|
import type { SearchHit } from '@/types/api'
|
|
|
|
defineProps<{ hit: SearchHit }>()
|
|
defineEmits<{ select: [hit: SearchHit] }>()
|
|
</script>
|
|
|
|
<template>
|
|
<button class="group w-full rounded-xl border bg-card p-5 text-left shadow-xs transition hover:-translate-y-0.5 hover:border-foreground/20 hover:shadow-md" type="button" @click="$emit('select', hit)">
|
|
<div class="flex items-start gap-4">
|
|
<div class="min-w-0 flex-1">
|
|
<h2 class="truncate text-base font-semibold tracking-tight">{{ hit.name }}</h2>
|
|
<p class="mt-1.5 truncate font-mono text-[11px] text-muted-foreground">{{ hit.info_hash }}</p>
|
|
</div>
|
|
<ChevronRight class="mt-1 size-4 shrink-0 text-muted-foreground transition group-hover:translate-x-0.5 group-hover:text-foreground" />
|
|
</div>
|
|
<div class="mt-4 flex flex-wrap gap-x-5 gap-y-2 text-xs text-muted-foreground">
|
|
<span class="result-meta"><HardDrive />{{ formatBytes(hit.total_size) }}</span>
|
|
<span class="result-meta"><Files />{{ hit.file_count.toLocaleString() }} 个文件</span>
|
|
<span class="result-meta"><Repeat2 />{{ hit.variant_count }} 个版本</span>
|
|
<span class="result-meta"><Flame />{{ heatLabel[hit.heat.level] }} {{ hit.heat.score }}</span>
|
|
<span class="result-meta" :class="hit.availability.status === 'active' && 'text-emerald-600'"><Radio />{{ availabilityLabel[hit.availability.status] }}</span>
|
|
<span class="ml-auto">最近发现 {{ relativeDate(hit.last_seen) }}</span>
|
|
</div>
|
|
</button>
|
|
</template>
|