Repair: copy legacy joinDate into new user's created_at when creating users from legacy wallz
This commit is contained in:
88
resources/js/components/social/MessageInboxBadge.jsx
Normal file
88
resources/js/components/social/MessageInboxBadge.jsx
Normal file
@@ -0,0 +1,88 @@
|
||||
import React, { useEffect, useMemo, useState } from 'react'
|
||||
import { getEcho } from '../../bootstrap'
|
||||
|
||||
export default function MessageInboxBadge({ initialUnreadCount = 0, userId = null, href = '/messages' }) {
|
||||
const [unreadCount, setUnreadCount] = useState(Math.max(0, Number(initialUnreadCount || 0)))
|
||||
|
||||
useEffect(() => {
|
||||
let cancelled = false
|
||||
|
||||
const loadUnreadState = async () => {
|
||||
try {
|
||||
const response = await fetch('/api/messages/conversations', {
|
||||
headers: { Accept: 'application/json' },
|
||||
credentials: 'same-origin',
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to load unread conversations')
|
||||
}
|
||||
|
||||
const payload = await response.json()
|
||||
if (cancelled) {
|
||||
return
|
||||
}
|
||||
|
||||
if (cancelled) {
|
||||
return
|
||||
}
|
||||
|
||||
const nextUnreadTotal = Number(payload?.summary?.unread_total)
|
||||
if (Number.isFinite(nextUnreadTotal)) {
|
||||
setUnreadCount(Math.max(0, nextUnreadTotal))
|
||||
}
|
||||
} catch {
|
||||
// Keep server-rendered count if bootstrap fetch fails.
|
||||
}
|
||||
}
|
||||
|
||||
loadUnreadState()
|
||||
|
||||
return () => {
|
||||
cancelled = true
|
||||
}
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
if (!userId) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
const echo = getEcho()
|
||||
if (!echo) {
|
||||
return undefined
|
||||
}
|
||||
|
||||
const channel = echo.private(`user.${userId}`)
|
||||
const handleConversationUpdated = (payload) => {
|
||||
const nextUnreadTotal = Number(payload?.summary?.unread_total)
|
||||
if (Number.isFinite(nextUnreadTotal)) {
|
||||
setUnreadCount(Math.max(0, nextUnreadTotal))
|
||||
}
|
||||
}
|
||||
|
||||
channel.listen('.conversation.updated', handleConversationUpdated)
|
||||
|
||||
return () => {
|
||||
channel.stopListening('.conversation.updated', handleConversationUpdated)
|
||||
echo.leaveChannel(`private-user.${userId}`)
|
||||
}
|
||||
}, [userId])
|
||||
|
||||
return (
|
||||
<a
|
||||
href={href}
|
||||
className="relative w-10 h-10 inline-flex items-center justify-center rounded-lg hover:bg-white/5"
|
||||
title="Messages"
|
||||
>
|
||||
<svg className="w-5 h-5" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2">
|
||||
<path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z" />
|
||||
</svg>
|
||||
{unreadCount > 0 ? (
|
||||
<span className="absolute -bottom-1 right-0 text-[11px] tabular-nums px-1.5 py-0.5 rounded bg-red-700/70 text-white border border-sb-line">
|
||||
{unreadCount > 99 ? '99+' : unreadCount}
|
||||
</span>
|
||||
) : null}
|
||||
</a>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user