This commit is contained in:
rex
2026-01-01 16:36:12 +08:00
parent a41bf16972
commit bec0684e70
9 changed files with 142 additions and 50 deletions

View File

@@ -7,12 +7,14 @@ import {
DropdownMenu,
DropdownTrigger,
} from '@heroui/react';
import { type Message as BaseMessage } from '@mujian/js-sdk/react';
import { ChevronLeftIcon, ChevronRightIcon, Ellipsis } from 'lucide-react';
import React from 'react';
import { mjChatCls } from '@/utils/cls';
import { useMessageActions } from './useMessageActions';
export type LastMessageActionsProps = {
message: BaseMessage;
isUser: boolean;
isLastMsg: boolean;
isFirstMsg: boolean;
@@ -30,6 +32,7 @@ export type LastMessageActionsProps = {
};
export const MessageActions = ({
// message,
isUser,
isLastMsg,
isFirstMsg,
@@ -94,10 +97,12 @@ export const MessageActions = ({
</DropdownTrigger>
<DropdownMenu
items={dropdownItems}
className={mjChatCls(
['msg-actions-dropdown-menu'],
'text-[initial]',
)}
className={mjChatCls(['msg-actions-dropdown-menu'], 'text-white')}
// disabledKeys={
// message.id.startsWith('not_saved')
// ? ['edit', 'regenerate', 'continue']
// : []
// }
>
{(item) => (
<DropdownItem

View File

@@ -26,6 +26,7 @@ export type MessageBubbleProps = {
};
export const MessageBubble = ({
// message,
isUser,
isEditing,
editedMessage,
@@ -68,7 +69,7 @@ export const MessageBubble = ({
<DropdownTrigger>
<div
className={mjChatCls(
['msg-edit-trigger'],
['msg-edit-trigger', 'msg-content'],
cn(
'h-full rounded-xl dark:prose-invert text-blue-100 p-4 bg-black/50',
{
@@ -83,10 +84,12 @@ export const MessageBubble = ({
</DropdownTrigger>
<DropdownMenu
items={dropdownItems}
className={mjChatCls(
['msg-edit-dropdown-menu'],
'text-[initial]',
)}
className={mjChatCls(['msg-edit-dropdown-menu'], 'text-white')}
// disabledKeys={
// message.id.startsWith('not_saved')
// ? ['edit', 'regenerate', 'continue']
// : []
// }
>
{(item) => (
<DropdownItem
@@ -107,9 +110,9 @@ export const MessageBubble = ({
</DropdownMenu>
</Dropdown>
) : (
// <div className={mjChatCls(['msg-content-wrapper'], "py-4")}>
<MdRenderer content={currentMessage} />
// </div>
<div className={mjChatCls(['msg-content'], 'py-4')}>
<MdRenderer content={currentMessage} />
</div>
)
) : (
<MessageEditArea

View File

@@ -122,7 +122,7 @@ export const MessageItem = React.memo((props: MessageItemProps) => {
addToast({
color: 'success',
description: '复制成功',
timeout: 1500,
timeout: 2000,
});
} catch (error) {
console.error(error);
@@ -216,6 +216,7 @@ export const MessageItem = React.memo((props: MessageItemProps) => {
}}
/>
<MessageActions
message={message}
isUser={isUser}
isLastMsg={Boolean(isLastMsg)}
isFirstMsg={Boolean(isFirstMsg)}

View File

@@ -81,35 +81,37 @@ export const QuickReply = (props: QuickReplyProps) => {
}}
onMouseDown={onmousedown}
>
{quickReplies.map((qr, index) => (
<Chip
key={index}
className={mjChatCls(
['input-quickreply-chip', `input-quickreply-chip-${index + 1}`],
'bg-white/15 text-default shrink-0 cursor-pointer',
)}
classNames={{
base: mjChatCls([
'input-quickreply-chip-base',
`input-quickreply-chip-${index + 1}-base`,
]),
content: mjChatCls([
'input-quickreply-chip-content',
`input-quickreply-chip-${index + 1}-content`,
]),
}}
radius="full"
variant="light"
onClick={() => {
const isClick = Date.now() - lastDragTime.current > 50;
if (isClick && qr.message) {
onSend(qr.message);
}
}}
>
{qr.label}
</Chip>
))}
{quickReplies
.filter((qr) => !qr.isHidden)
.map((qr, index) => (
<Chip
key={index}
className={mjChatCls(
['input-quickreply-chip', `input-quickreply-chip-${index + 1}`],
'bg-white/15 text-default shrink-0 cursor-pointer',
)}
classNames={{
base: mjChatCls([
'input-quickreply-chip-base',
`input-quickreply-chip-${index + 1}-base`,
]),
content: mjChatCls([
'input-quickreply-chip-content',
`input-quickreply-chip-${index + 1}-content`,
]),
}}
radius="full"
variant="light"
onClick={() => {
const isClick = Date.now() - lastDragTime.current > 50;
if (isClick && qr.message) {
onSend(qr.message);
}
}}
>
{qr.label}
</Chip>
))}
</ScrollShadow>
);
};

View File

@@ -170,9 +170,24 @@ export const Chat = () => {
? error.message
: '哎呀,发生了未知错误,刷新页面再试试吧~');
const toastStyle = `
.toast-region {
margin-top: ${paddingTop}px;
}`;
return (
<div className={mjChatCls(['container'], 'size-full relative')}>
<ToastProvider placement="top-center" toastProps={{ color: 'danger' }} />
<style> {toastStyle} </style>
<ToastProvider
placement="top-center"
toastProps={{ color: 'danger' }}
disableAnimation={true}
regionProps={{
classNames: {
base: 'toast-region',
},
}}
/>
<div
className={mjChatCls(
['container-background'],
@@ -195,7 +210,10 @@ export const Chat = () => {
>
<ScrollShadow
hideScrollBar
className={mjChatCls(['container-content-scroll-shadow'], 'h-full pb-2')}
className={mjChatCls(
['container-content-scroll-shadow'],
'h-full pb-2',
)}
size={20}
>
<MessageList
@@ -210,6 +228,19 @@ export const Chat = () => {
onRegenerate={regenerate}
onNeedMore={loadMoreMessage}
/>
{status !== 'streaming' &&
messages.some((m) => m.id.startsWith('not_saved')) && (
<Alert
hideIcon
title="最近一次保存消息失败,请刷新页面后重试"
className="opacity-30"
classNames={{
mainWrapper: 'min-h-4 ml-0 text-white',
}}
color="default"
variant="bordered"
/>
)}
{errorMessage && (
<Alert
hideIcon