feat(frontend): add loading empty and error states for chat operations

This commit is contained in:
nav
2026-05-12 16:08:17 +00:00
parent 763f06ab8c
commit 25bd1df290

View File

@@ -26,6 +26,8 @@ export default function ChatPage() {
const [socketState, setSocketState] = useState<'offline' | 'online'>('offline') const [socketState, setSocketState] = useState<'offline' | 'online'>('offline')
const [onlineCount, setOnlineCount] = useState(0) const [onlineCount, setOnlineCount] = useState(0)
const [typingUsers, setTypingUsers] = useState<string[]>([]) const [typingUsers, setTypingUsers] = useState<string[]>([])
const [loading, setLoading] = useState(false)
const [error, setError] = useState('')
const [seqFrom, setSeqFrom] = useState('1') const [seqFrom, setSeqFrom] = useState('1')
const [seqTo, setSeqTo] = useState('999999') const [seqTo, setSeqTo] = useState('999999')
const [limit, setLimit] = useState('50') const [limit, setLimit] = useState('50')
@@ -86,40 +88,63 @@ export default function ChatPage() {
async function pullMessages() { async function pullMessages() {
if (!channelId) return if (!channelId) return
const res = await getApiClient().get(`/channels/${channelId}/messages`, { setLoading(true)
params: { setError('')
seq_from: Number(seqFrom || '1'), try {
seq_to: Number(seqTo || '999999'), const res = await getApiClient().get(`/channels/${channelId}/messages`, {
limit: Number(limit || '50'), params: {
}, seq_from: Number(seqFrom || '1'),
}) seq_to: Number(seqTo || '999999'),
setMessages(res.data.items ?? []) limit: Number(limit || '50'),
setPageInfo(res.data.page ?? null) },
})
setMessages(res.data.items ?? [])
setPageInfo(res.data.page ?? null)
} catch {
setError('消息拉取失败')
} finally {
setLoading(false)
}
} }
async function sendMessage() { async function sendMessage() {
if (!channelId || !content.trim()) return if (!channelId || !content.trim()) return
await getApiClient().post(`/channels/${channelId}/messages`, { setError('')
content, try {
authorUserId: 'frontend-user', await getApiClient().post(`/channels/${channelId}/messages`, {
}) content,
socket.emit('typing.stop', { channelId }) authorUserId: 'frontend-user',
setContent('') })
socket.emit('typing.stop', { channelId })
setContent('')
} catch {
setError('发送失败')
}
} }
async function editMessage() { async function editMessage() {
if (!channelId || !editingMessageId || !editingContent.trim()) return if (!channelId || !editingMessageId || !editingContent.trim()) return
await getApiClient().patch(`/channels/${channelId}/messages/${editingMessageId}`, { setError('')
content: editingContent, try {
}) await getApiClient().patch(`/channels/${channelId}/messages/${editingMessageId}`, {
setEditingContent('') content: editingContent,
await pullMessages() })
setEditingContent('')
await pullMessages()
} catch {
setError('编辑失败')
}
} }
async function deleteMessage(messageId: string) { async function deleteMessage(messageId: string) {
if (!channelId || !messageId) return if (!channelId || !messageId) return
await getApiClient().delete(`/channels/${channelId}/messages/${messageId}`) setError('')
await pullMessages() try {
await getApiClient().delete(`/channels/${channelId}/messages/${messageId}`)
await pullMessages()
} catch {
setError('删除失败')
}
} }
function onChangeChannel(value: string) { function onChangeChannel(value: string) {
@@ -155,6 +180,8 @@ export default function ChatPage() {
<p>Guild: {guildId || '-'}</p> <p>Guild: {guildId || '-'}</p>
<p>Socket: {socketState}</p> <p>Socket: {socketState}</p>
<p>线: {onlineCount}</p> <p>线: {onlineCount}</p>
{loading ? <p>...</p> : null}
{error ? <p style={{ color: 'crimson' }}>{error}</p> : null}
{typingUsers.length ? <p>: {typingUsers.join(', ')}</p> : null} {typingUsers.length ? <p>: {typingUsers.join(', ')}</p> : null}
<div style={{ display: 'flex', gap: 8, marginBottom: 8 }}> <div style={{ display: 'flex', gap: 8, marginBottom: 8 }}>
<input value={channelId} onChange={(e) => onChangeChannel(e.target.value)} placeholder="Channel ID" /> <input value={channelId} onChange={(e) => onChangeChannel(e.target.value)} placeholder="Channel ID" />
@@ -186,6 +213,7 @@ export default function ChatPage() {
</li> </li>
))} ))}
</ul> </ul>
{!loading && !messages.length ? <p></p> : null}
{pageInfo ? ( {pageInfo ? (
<p> <p>
next_expected_seq: {pageInfo.nextExpectedSeq ?? '-'} | highest_committed_seq:{' '} next_expected_seq: {pageInfo.nextExpectedSeq ?? '-'} | highest_committed_seq:{' '}