forked from BRETT/BRETT
Initial Commit
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
<script setup lang="ts">
|
||||
import { Button } from '@/components/ui/button'
|
||||
import {
|
||||
Popover,
|
||||
PopoverContent,
|
||||
PopoverTrigger,
|
||||
} from '@/components/ui/popover'
|
||||
import type { AppNotification } from '@/composables/useNotifications'
|
||||
|
||||
const { notifications, unreadCount, markRead } = useNotifications()
|
||||
const open = ref(false)
|
||||
const timeAgo = useTimeAgo()
|
||||
|
||||
async function goTo(n: AppNotification) {
|
||||
open.value = false
|
||||
await markRead(n.id)
|
||||
await navigateTo(`/thread/${n.uploadId}#comment-${n.commentId}`)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Popover v-model:open="open">
|
||||
<PopoverTrigger as-child>
|
||||
<Button variant="ghost" size="icon" class="relative" aria-label="Benachrichtigungen">
|
||||
<Icon name="ph:bell-fill" class="size-5" />
|
||||
<span
|
||||
v-if="unreadCount"
|
||||
class="absolute -top-1 -right-1 flex h-4 min-w-4 items-center justify-center rounded-full bg-accent px-1 text-[10px] font-semibold text-accent-foreground"
|
||||
>{{ unreadCount > 9 ? '9+' : unreadCount }}</span>
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent align="end" class="w-80 gap-0 p-0">
|
||||
<div class="max-h-96 overflow-y-auto">
|
||||
<p v-if="!notifications.length" class="px-4 py-6 text-center text-sm text-muted-foreground">
|
||||
Keine Benachrichtigungen.
|
||||
</p>
|
||||
<button
|
||||
v-for="n in notifications"
|
||||
:key="n.id"
|
||||
type="button"
|
||||
class="flex w-full items-center gap-3 border-b px-4 py-3 text-left text-sm transition-colors last:border-b-0 hover:bg-accent/10"
|
||||
@click="goTo(n)"
|
||||
>
|
||||
<div class="size-12 shrink-0 overflow-hidden rounded-md bg-muted">
|
||||
<NuxtImg
|
||||
v-if="n.thumbUrl"
|
||||
:src="n.thumbUrl"
|
||||
:alt="n.actorName"
|
||||
width="96"
|
||||
height="96"
|
||||
fit="cover"
|
||||
class="h-full w-full object-cover"
|
||||
/>
|
||||
<video
|
||||
v-else-if="n.uploadType === 'video'"
|
||||
:src="n.url"
|
||||
preload="metadata"
|
||||
muted
|
||||
playsinline
|
||||
class="h-full w-full object-cover"
|
||||
/>
|
||||
<div v-else class="flex h-full w-full items-center justify-center">
|
||||
<Icon name="ph:link-fill" class="size-4 text-muted-foreground" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="min-w-0 flex-1">
|
||||
<div class="flex items-baseline gap-1.5">
|
||||
<span
|
||||
class="truncate font-medium"
|
||||
:style="n.actorColor ? { color: n.actorColor } : undefined"
|
||||
>{{ n.actorName }}</span>
|
||||
<span class="shrink-0 text-muted-foreground">{{ n.isMention ? 'hat dich erwähnt' : 'hat kommentiert' }}</span>
|
||||
<span class="ml-auto shrink-0 text-xs text-muted-foreground">{{ timeAgo(n.createdAt) }}</span>
|
||||
</div>
|
||||
<p class="mt-0.5 line-clamp-2 break-words text-muted-foreground">
|
||||
{{ n.content }}
|
||||
</p>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
</template>
|
||||
Reference in New Issue
Block a user