ChatArea.jsx 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. /*
  2. Copyright (C) 2025 QuantumNous
  3. This program is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU Affero General Public License as
  5. published by the Free Software Foundation, either version 3 of the
  6. License, or (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU Affero General Public License for more details.
  11. You should have received a copy of the GNU Affero General Public License
  12. along with this program. If not, see <https://www.gnu.org/licenses/>.
  13. For commercial licensing, please contact support@quantumnous.com
  14. */
  15. import React from 'react';
  16. import {
  17. Card,
  18. Chat,
  19. Typography,
  20. Button,
  21. } from '@douyinfe/semi-ui';
  22. import {
  23. MessageSquare,
  24. Eye,
  25. EyeOff,
  26. } from 'lucide-react';
  27. import { useTranslation } from 'react-i18next';
  28. import CustomInputRender from './CustomInputRender';
  29. const ChatArea = ({
  30. chatRef,
  31. message,
  32. inputs,
  33. styleState,
  34. showDebugPanel,
  35. roleInfo,
  36. onMessageSend,
  37. onMessageCopy,
  38. onMessageReset,
  39. onMessageDelete,
  40. onStopGenerator,
  41. onClearMessages,
  42. onToggleDebugPanel,
  43. renderCustomChatContent,
  44. renderChatBoxAction,
  45. }) => {
  46. const { t } = useTranslation();
  47. const renderInputArea = React.useCallback((props) => {
  48. return <CustomInputRender {...props} />;
  49. }, []);
  50. return (
  51. <Card
  52. className="h-full"
  53. bordered={false}
  54. bodyStyle={{ padding: 0, height: 'calc(100vh - 66px)', display: 'flex', flexDirection: 'column', overflow: 'hidden' }}
  55. >
  56. {/* 聊天头部 */}
  57. {styleState.isMobile ? (
  58. <div className="pt-4"></div>
  59. ) : (
  60. <div className="px-6 py-4 bg-gradient-to-r from-purple-500 to-blue-500 rounded-t-2xl">
  61. <div className="flex items-center justify-between">
  62. <div className="flex items-center gap-3">
  63. <div className="w-10 h-10 rounded-full bg-white/20 backdrop-blur flex items-center justify-center">
  64. <MessageSquare size={20} className="text-white" />
  65. </div>
  66. <div>
  67. <Typography.Title heading={5} className="!text-white mb-0">
  68. {t('AI 对话')}
  69. </Typography.Title>
  70. <Typography.Text className="!text-white/80 text-sm hidden sm:inline">
  71. {inputs.model || t('选择模型开始对话')}
  72. </Typography.Text>
  73. </div>
  74. </div>
  75. <div className="flex items-center gap-2">
  76. <Button
  77. icon={showDebugPanel ? <EyeOff size={14} /> : <Eye size={14} />}
  78. onClick={onToggleDebugPanel}
  79. theme="borderless"
  80. type="primary"
  81. size="small"
  82. className="!rounded-lg !text-white/80 hover:!text-white hover:!bg-white/10"
  83. >
  84. {showDebugPanel ? t('隐藏调试') : t('显示调试')}
  85. </Button>
  86. </div>
  87. </div>
  88. </div>
  89. )}
  90. {/* 聊天内容区域 */}
  91. <div className="flex-1 overflow-hidden">
  92. <Chat
  93. ref={chatRef}
  94. chatBoxRenderConfig={{
  95. renderChatBoxContent: renderCustomChatContent,
  96. renderChatBoxAction: renderChatBoxAction,
  97. renderChatBoxTitle: () => null,
  98. }}
  99. renderInputArea={renderInputArea}
  100. roleConfig={roleInfo}
  101. style={{
  102. height: '100%',
  103. maxWidth: '100%',
  104. overflow: 'hidden'
  105. }}
  106. chats={message}
  107. onMessageSend={onMessageSend}
  108. onMessageCopy={onMessageCopy}
  109. onMessageReset={onMessageReset}
  110. onMessageDelete={onMessageDelete}
  111. showClearContext
  112. showStopGenerate
  113. onStopGenerator={onStopGenerator}
  114. onClear={onClearMessages}
  115. className="h-full"
  116. placeholder={t('请输入您的问题...')}
  117. />
  118. </div>
  119. </Card>
  120. );
  121. };
  122. export default ChatArea;