Initial Commit

This commit is contained in:
2026-10-03 20:07:49 +02:00
commit a1346c98b1
427 changed files with 59320 additions and 0 deletions
+84
View File
@@ -0,0 +1,84 @@
import { toast } from 'vue-sonner'
import type { ReactionEventPayload } from '@/composables/useCommentReactions'
import type { UploadReactionEventPayload } from '@/composables/useUploadReactions'
import type { LiveComment } from '@/composables/useLiveComments'
import type { AppNotification } from '@/composables/useNotifications'
export default defineNuxtPlugin(() => {
const { user } = useAuth()
const { fetchAll, addLive, reset } = useNotifications()
const { pushLive } = useLiveComments()
const motd = useMotd()
const { applyEvent } = useCommentReactions()
const { applyEvent: applyUploadEvent } = useUploadReactions()
let ws: WebSocket | null = null
let reconnectTimer: ReturnType<typeof setTimeout> | undefined
function connect() {
if (ws) return
const protocol = location.protocol === 'https:' ? 'wss' : 'ws'
const socket = new WebSocket(`${protocol}://${location.host}/_ws`)
ws = socket
socket.onmessage = (event) => {
try {
const message = JSON.parse(event.data as string)
if (message.type === 'comment') {
pushLive(message.comment as LiveComment)
}
else if (message.type === 'reaction') {
applyEvent(message as ReactionEventPayload)
}
else if (message.type === 'upload-reaction') {
applyUploadEvent(message as UploadReactionEventPayload)
}
else if (message.type === 'motd') {
motd.value = typeof message.message === 'string' ? message.message : ''
}
else if (message.type === 'notification') {
const n = message.notification as AppNotification
addLive(n, typeof message.unreadCount === 'number' ? message.unreadCount : undefined)
toast(n.isMention ? `${n.actorName} hat dich erwähnt` : `${n.actorName} hat in einem abonnierten Thread kommentiert`, {
id: `notification-${n.uploadId}`,
description: n.content?.slice(0, 80) || undefined,
action: {
label: 'Ansehen',
onClick: () => navigateTo(`/thread/${n.uploadId}#comment-${n.commentId}`),
},
})
}
}
catch {
// ungültige Nachricht ignorieren
}
}
socket.onclose = () => {
if (ws === socket) ws = null
reconnectTimer = setTimeout(connect, 3000)
}
socket.onerror = () => {
socket.close()
}
}
function disconnect() {
clearTimeout(reconnectTimer)
ws?.close()
ws = null
}
// Bei Login/Logout neu verbinden, damit die Server-seitige User-Zuordnung stimmt
watch(() => user.value?.id, (id) => {
disconnect()
connect()
if (id) {
fetchAll().catch(() => {})
}
else {
reset()
}
}, { immediate: true })
})