浏览代码

Merge branch 'main' into release

DaiQiangReal 1 年之前
父节点
当前提交
22965b0599

+ 4 - 1
packages/semi-foundation/chat/chat.scss

@@ -233,6 +233,7 @@ $module: #{$prefix}-chat;
             .#{$module}-attachment-file, .#{$module}-attachment-img  {
                 margin-top: $spacing-chat_chatBox_content_attachment-marginY;
                 margin-bottom: $spacing-chat_chatBox_content_attachment-marginY;
+                margin-right: $spacing-chat_chatBox_content_attachment-marginRight;
             }
         
             &-user {
@@ -457,6 +458,8 @@ $module: #{$prefix}-chat;
         flex-wrap: wrap;
         column-gap: $spacing-chat_attachment-columnGap;
         row-gap: $spacing-chat_attachment-RowGap;
+        margin-left: $spacing-chat_attachment-marginX;
+        margin-right: $spacing-chat_attachment-marginX;
 
         &-item {
             position: relative;
@@ -493,7 +496,7 @@ $module: #{$prefix}-chat;
         }
 
         &-file {
-            display: flex;
+            display: inline-flex;
             flex-direction: row;
             align-items: center;
             height: $width-chat_attachment_file;

+ 2 - 0
packages/semi-foundation/chat/variables.scss

@@ -67,6 +67,7 @@ $spacing-chat_inputBox_inner-columnGap: 4px; // 输入框容器列间距
 $spacing-chat_inputBox-marginY: 4px;
 $spacing-chat_attachment-columnGap: 10px; // 附件列间距
 $spacing-chat_attachment-RowGap: 5px; // 附件行间距
+$spacing-chat_attachment-marginX: 12px; // 附件左右外边距
 $spacing-chat_attachment_clear-top: 8px;  // 附件清除图标顶部间距
 $spacing-chat_attachment_clear-right: 8px;  // 附件清除图标右内边距
 $spacing-chat_attachment_file-columnGap: 5px; // 文件附件列间距
@@ -74,6 +75,7 @@ $spacing-chat_attachment_file-padding: 5px;  // 文件附件内边距
 $spacing-chat_chatBox_loading_item-gap: 15px; // 聊天内容加载图标间距 
 $spacing-chat_divider-marginY: 12px; // 分割线上下外边距
 $spacing-chat_chatBox_content_attachment-marginY: 4px; // 聊天框内容文件/图片上下外间距
+$spacing-chat_chatBox_content_attachment-marginRight: 4px; //聊天框内容文件/图片上下右间距
 $spacing-chat_chatBox_content_code_topSlot-paddingX: 5px; // 聊天框代码块顶部上下内边距
 $spacing-chat_chatBox_content_code_topSlot-paddingY: 8px; // 聊天框代码块顶部左右内边距
 $spacing-chat_chatBox_content_code_topSlot_copy-columnGap: 5px; // 聊天框代码块顶部复制按钮列间距: 

+ 7 - 1
packages/semi-ui/chat/_story/constant.js

@@ -69,7 +69,13 @@ const infoWithAttachment = [
             {
                 type: 'image_url',
                 image_url: {
-                    url: 'https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/edit-bag.jpeg'
+                    url: 'https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/root-web-sites/edit-bag.jpeg',
+                },
+            },
+            {
+                type: 'image_url',
+                image_url: {
+                    url: 'https://lf3-static.bytednsdoc.com/obj/eden-cn/ptlz_zlp/ljhwZthlaukjlkulzlp/SemiLogo.jpg'
                 },
             }
         ],

+ 18 - 12
packages/semi-ui/chat/chatBox/chatBoxContent.tsx

@@ -47,28 +47,34 @@ const ChatBoxContent = (props: ChatBoxContentProps) => {
                 <span className={`${PREFIX_CHAT_BOX}-content-loading-item`} />
             </span>;
         } else {
-            let realContent = '';
+            let realContent;
             if (typeof content === 'string') {
-                realContent = content;
+                realContent = <MarkdownRender
+                    format='md'
+                    raw={content}
+                    components={markdownComponents as any}
+                />;
             } else if (Array.isArray(content)) {
-                realContent = content.map((item)=> {
+                realContent = content.map((item, index)=> {
                     if (item.type === 'text') {
-                        return item.text;
+                        return <MarkdownRender
+                            key={`index`}
+                            format='md'
+                            raw={item.text}
+                            components={markdownComponents as any}
+                        />;
                     } else if (item.type === 'image_url') {
-                        return `![image](${item.image_url.url})`;
+                        return <ImageAttachment key={`index`} src={item.image_url.url} />;
                     } else if (item.type === 'file_url') {
                         const { name, size, url, type } = item.file_url;
                         const realType = name.split('.').pop() ?? type?.split('/').pop();
-                        return `<SemiFile url={'${url}'} name={'${name}'} size={'${size}'} type={'${realType}'}></SemiFile>`;
+                        return <FileAttachment key={`index`} url={name} name={name} size={size} type={realType}></FileAttachment>;
                     }
-                    return '';
-                }).join('\n\n');
+                    return null;
+                });
             }
             return (<>
-                <MarkdownRender
-                    raw={realContent}
-                    components={markdownComponents as any}
-                />
+                {realContent}
             </>);
         }
     }, [status, content]);

+ 11 - 1
packages/semi-ui/chat/index.tsx

@@ -29,6 +29,7 @@ class Chat extends BaseComponent<ChatProps, ChatState> {
     foundation: ChatFoundation;
     uploadRef: React.RefObject<Upload>;
     dropAreaRef: React.RefObject<HTMLDivElement>;
+    scrollTargetRef: React.RefObject<HTMLElement>;
 
     static propTypes = {
         className: PropTypes.string,
@@ -80,6 +81,7 @@ class Chat extends BaseComponent<ChatProps, ChatState> {
         this.dropAreaRef = React.createRef();
         this.wheelEventHandler = null;
         this.foundation = new ChatFoundation(this.adapter);
+        this.scrollTargetRef = React.createRef();
 
         this.state = {
             backBottomVisible: false,
@@ -144,7 +146,14 @@ class Chat extends BaseComponent<ChatProps, ChatState> {
                     return ;
                 }
                 this.wheelEventHandler = (e: any) => {
-                    if (e.target !== containerElement) {
+                    /**
+                     * Why use this.scrollTargetRef.current and wheel's currentTarget target comparison?
+                     * Both scroll and wheel events are on the container
+                     * his.scrollTargetRef.current is the object where scrolling actually occurs
+                     * wheel's currentTarget is the container,
+                     * Only when the wheel event occurs and there is scroll, the following logic(show scroll bar) needs to be executed
+                     */
+                    if (this.scrollTargetRef?.current !== e.currentTarget) {
                         return;
                     }
                     this.adapter.setWheelScroll(true);
@@ -261,6 +270,7 @@ class Chat extends BaseComponent<ChatProps, ChatState> {
     }
 
     containerScroll = (e: React.UIEvent<HTMLDivElement>) => {
+        (this.scrollTargetRef as any).current = e.target as HTMLElement;
         if (e.target !== e.currentTarget) {
             return;
         }

+ 1 - 1
packages/semi-ui/dropdown/index.tsx

@@ -134,7 +134,7 @@ class Dropdown extends BaseComponent<DropdownProps, DropdownState> {
         return {
             ...super.adapter,
             setPopVisible: (popVisible: boolean) => this.setState({ popVisible }),
-            notifyVisibleChange: (visible: boolean) => this.props.onVisibleChange(visible),
+            notifyVisibleChange: (visible: boolean) => this.props.onVisibleChange?.(visible),
             getPopupId: () => this.tooltipRef.current.getPopupId()
         };
     }