0.4.0
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)}
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user