You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tailchat/web/src/components/ChatBox/index.tsx

79 lines
2.5 KiB
TypeScript

import { Skeleton } from 'antd';
import React, { useRef } from 'react';
import { useConverseMessage } from 'tailchat-shared';
import { AlertErrorView } from '../AlertErrorView';
import { ChatInputBox } from './ChatInputBox';
import { ChatMessageList, ChatMessageListRef } from './ChatMessageList';
import { useMessageAck } from './useMessageAck';
const ChatBoxPlaceholder: React.FC = React.memo(() => {
return (
<div className="px-2 w-2/3">
<Skeleton className="mb-2" avatar={true} paragraph={{ rows: 1 }} />
<Skeleton className="mb-2" avatar={true} paragraph={{ rows: 1 }} />
<Skeleton className="mb-2" avatar={true} paragraph={{ rows: 1 }} />
<Skeleton className="mb-2" avatar={true} paragraph={{ rows: 1 }} />
<Skeleton className="mb-2" avatar={true} paragraph={{ rows: 1 }} />
<Skeleton className="mb-2" avatar={true} paragraph={{ rows: 1 }} />
<Skeleton className="mb-2" avatar={true} paragraph={{ rows: 1 }} />
<Skeleton className="mb-2" avatar={true} paragraph={{ rows: 1 }} />
<Skeleton className="mb-2" avatar={true} paragraph={{ rows: 1 }} />
<Skeleton className="mb-2" avatar={true} paragraph={{ rows: 1 }} />
</div>
);
});
ChatBoxPlaceholder.displayName = 'ChatBoxPlaceholder';
type ChatBoxProps =
| {
converseId: string;
isGroup: false;
groupId?: string;
}
| {
converseId: string;
isGroup: true;
groupId: string;
};
export const ChatBox: React.FC<ChatBoxProps> = React.memo((props) => {
const { converseId, isGroup } = props;
const { messages, loading, error, handleSendMessage } = useConverseMessage({
converseId,
isGroup,
});
const chatMessageListRef = useRef<ChatMessageListRef>(null);
const { updateConverseAck } = useMessageAck(converseId, messages);
if (loading) {
return <ChatBoxPlaceholder />;
}
if (error) {
return <AlertErrorView error={error} />;
}
return (
<div className="w-full h-full flex flex-col select-text">
<ChatMessageList
ref={chatMessageListRef}
messages={messages}
onUpdateReadedMessage={updateConverseAck}
/>
<ChatInputBox
onSendMsg={(msg) => {
// 发送消息后滚动到底部
handleSendMessage({
converseId: props.converseId,
groupId: props.groupId,
content: msg,
}).then(() => {
chatMessageListRef.current?.scrollToBottom();
});
}}
/>
</div>
);
});
ChatBox.displayName = 'ChatBox';