From c7a15d291e51d9be971741a3f4d5d0ea7db00062 Mon Sep 17 00:00:00 2001 From: one Date: Thu, 15 May 2025 01:42:18 +0800 Subject: [PATCH] fix: update current topic id and support EmojiAvatar for ChatFlowHistory (#5861) * fix: update current topic id for ChatFlowHistory to work * refactor: set current topic id early in loadTopicMessagesThunk * refactor: extract EmojiAvatar * fix: style --- .../src/components/Avatar/EmojiAvatar.tsx | 52 +++++++++++++++++++ .../src/components/Popups/UserPopup.tsx | 26 +++------- src/renderer/src/components/app/Sidebar.tsx | 28 ++++------ .../pages/home/Messages/ChatFlowHistory.tsx | 11 +++- .../pages/home/Messages/MessageAnchorLine.tsx | 24 ++++----- .../src/pages/home/Messages/MessageHeader.tsx | 19 ++----- src/renderer/src/store/thunk/messageThunk.ts | 1 + 7 files changed, 95 insertions(+), 66 deletions(-) create mode 100644 src/renderer/src/components/Avatar/EmojiAvatar.tsx diff --git a/src/renderer/src/components/Avatar/EmojiAvatar.tsx b/src/renderer/src/components/Avatar/EmojiAvatar.tsx new file mode 100644 index 0000000000..553869698a --- /dev/null +++ b/src/renderer/src/components/Avatar/EmojiAvatar.tsx @@ -0,0 +1,52 @@ +import React, { memo } from 'react' +import styled from 'styled-components' + +interface EmojiAvatarProps { + children: string + size?: number + fontSize?: number + onClick?: React.MouseEventHandler + className?: string + style?: React.CSSProperties +} + +const EmojiAvatar = ({ + ref, + children, + size = 31, + fontSize, + onClick, + className, + style +}: EmojiAvatarProps & { ref?: React.RefObject }) => ( + + {children} + +) + +EmojiAvatar.displayName = 'EmojiAvatar' + +const StyledEmojiAvatar = styled.div<{ $size: number; $fontSize: number }>` + display: flex; + align-items: center; + justify-content: center; + background-color: var(--color-background-soft); + border: 0.5px solid var(--color-border); + border-radius: 20%; + cursor: pointer; + width: ${(props) => props.$size}px; + height: ${(props) => props.$size}px; + font-size: ${(props) => props.$fontSize}px; + transition: opacity 0.3s ease; + &:hover { + opacity: 0.8; + } +` + +export default memo(EmojiAvatar) diff --git a/src/renderer/src/components/Popups/UserPopup.tsx b/src/renderer/src/components/Popups/UserPopup.tsx index 9d7569effa..ac4b9eca93 100644 --- a/src/renderer/src/components/Popups/UserPopup.tsx +++ b/src/renderer/src/components/Popups/UserPopup.tsx @@ -1,4 +1,5 @@ import DefaultAvatar from '@renderer/assets/images/avatar.png' +import EmojiAvatar from '@renderer/components/Avatar/EmojiAvatar' import useAvatar from '@renderer/hooks/useAvatar' import { useSettings } from '@renderer/hooks/useSettings' import ImageStorage from '@renderer/services/ImageStorage' @@ -154,7 +155,13 @@ const PopupContainer: React.FC = ({ resolve }) => { } }} placement="bottom"> - {isEmoji(avatar) ? {avatar} : } + {isEmoji(avatar) ? ( + + {avatar} + + ) : ( + + )} @@ -182,23 +189,6 @@ const UserAvatar = styled(Avatar)` } ` -const EmojiAvatar = styled.div` - cursor: pointer; - width: 80px; - height: 80px; - border-radius: 20%; - background-color: var(--color-background-soft); - display: flex; - align-items: center; - justify-content: center; - font-size: 40px; - transition: opacity 0.3s ease; - border: 0.5px solid var(--color-border); - &:hover { - opacity: 0.8; - } -` - export default class UserPopup { static topviewId = 0 static hide() { diff --git a/src/renderer/src/components/app/Sidebar.tsx b/src/renderer/src/components/app/Sidebar.tsx index 8b50bdd7d2..c319123d29 100644 --- a/src/renderer/src/components/app/Sidebar.tsx +++ b/src/renderer/src/components/app/Sidebar.tsx @@ -1,3 +1,4 @@ +import EmojiAvatar from '@renderer/components/Avatar/EmojiAvatar' import { isMac } from '@renderer/config/constant' import { AppLogo, UserAvatar } from '@renderer/config/env' import { useTheme } from '@renderer/context/ThemeProvider' @@ -70,7 +71,9 @@ const Sidebar: FC = () => { return ( {isEmoji(avatar) ? ( - {avatar} + + {avatar} + ) : ( )} @@ -319,6 +322,12 @@ const Container = styled.div` height: ${isMac ? 'calc(100vh - var(--navbar-height))' : '100vh'}; -webkit-app-region: drag !important; margin-top: ${isMac ? 'var(--navbar-height)' : 0}; + + .sidebar-avatar { + margin-bottom: ${isMac ? '12px' : '12px'}; + margin-top: ${isMac ? '0px' : '2px'}; + -webkit-app-region: none; + } ` const AvatarImg = styled(Avatar)` @@ -331,23 +340,6 @@ const AvatarImg = styled(Avatar)` cursor: pointer; ` -const EmojiAvatar = styled.div` - width: 31px; - height: 31px; - background-color: var(--color-background-soft); - margin-bottom: ${isMac ? '12px' : '12px'}; - margin-top: ${isMac ? '0px' : '2px'}; - border-radius: 20%; - display: flex; - align-items: center; - justify-content: center; - font-size: 16px; - cursor: pointer; - -webkit-app-region: none; - border: 0.5px solid var(--color-border); - font-size: 20px; -` - const MainMenusContainer = styled.div` display: flex; flex: 1; diff --git a/src/renderer/src/pages/home/Messages/ChatFlowHistory.tsx b/src/renderer/src/pages/home/Messages/ChatFlowHistory.tsx index 73a3208ca2..99d3c51193 100644 --- a/src/renderer/src/pages/home/Messages/ChatFlowHistory.tsx +++ b/src/renderer/src/pages/home/Messages/ChatFlowHistory.tsx @@ -1,14 +1,17 @@ import '@xyflow/react/dist/style.css' import { RobotOutlined, UserOutlined } from '@ant-design/icons' +import EmojiAvatar from '@renderer/components/Avatar/EmojiAvatar' import ModelAvatar from '@renderer/components/Avatar/ModelAvatar' import { getModelLogo } from '@renderer/config/models' import { useTheme } from '@renderer/context/ThemeProvider' +import useAvatar from '@renderer/hooks/useAvatar' import { useSettings } from '@renderer/hooks/useSettings' import { EVENT_NAMES, EventEmitter } from '@renderer/services/EventService' import { RootState } from '@renderer/store' import { selectMessagesForTopic } from '@renderer/store/newMessage' import { Model } from '@renderer/types' +import { isEmoji } from '@renderer/utils' import { getMainTextContent } from '@renderer/utils/messageUtils/find' import { Controls, Handle, MiniMap, ReactFlow, ReactFlowProvider } from '@xyflow/react' import { Edge, Node, NodeTypes, Position, useEdgesState, useNodesState } from '@xyflow/react' @@ -63,7 +66,11 @@ const CustomNode: FC<{ data: any }> = ({ data }) => { // 用户头像 if (data.userAvatar) { - avatar = + if (isEmoji(data.userAvatar)) { + avatar = {data.userAvatar} + } else { + avatar = + } } else { avatar = } style={{ backgroundColor: 'var(--color-info)' }} /> } @@ -221,7 +228,7 @@ const ChatFlowHistory: FC = ({ conversationId }) => { ) // 获取用户头像 - const userAvatar = useSelector((state: RootState) => state.runtime.avatar) + const userAvatar = useAvatar() // 消息过滤 const { userMessages, assistantMessages } = useMemo(() => { diff --git a/src/renderer/src/pages/home/Messages/MessageAnchorLine.tsx b/src/renderer/src/pages/home/Messages/MessageAnchorLine.tsx index adffe18737..258c9d264e 100644 --- a/src/renderer/src/pages/home/Messages/MessageAnchorLine.tsx +++ b/src/renderer/src/pages/home/Messages/MessageAnchorLine.tsx @@ -1,4 +1,5 @@ import { DownOutlined } from '@ant-design/icons' +import EmojiAvatar from '@renderer/components/Avatar/EmojiAvatar' import { APP_NAME, AppLogo, isLocalAi } from '@renderer/config/env' import { getModelLogo } from '@renderer/config/models' import { useTheme } from '@renderer/context/ThemeProvider' @@ -16,6 +17,7 @@ import { Avatar } from 'antd' import { type FC, useCallback, useEffect, useRef, useState } from 'react' import { useTranslation } from 'react-i18next' import styled from 'styled-components' + interface MessageLineProps { messages: Message[] } @@ -230,7 +232,15 @@ const MessageAnchorLine: FC = ({ messages }) => { ) : ( <> {isEmoji(avatar) ? ( - {avatar} + + {avatar} + ) : ( )} @@ -314,16 +324,4 @@ const MessageItemContent = styled.div` max-width: 200px; ` -const EmojiAvatar = styled.div<{ size: number }>` - width: ${(props) => props.size}px; - height: ${(props) => props.size}px; - background-color: var(--color-background-soft); - border-radius: 20%; - display: flex; - align-items: center; - justify-content: center; - font-size: ${(props) => props.size * 0.6}px; - border: 0.5px solid var(--color-border); -` - export default MessageAnchorLine diff --git a/src/renderer/src/pages/home/Messages/MessageHeader.tsx b/src/renderer/src/pages/home/Messages/MessageHeader.tsx index cf25fd36f1..eaed4b08a5 100644 --- a/src/renderer/src/pages/home/Messages/MessageHeader.tsx +++ b/src/renderer/src/pages/home/Messages/MessageHeader.tsx @@ -1,3 +1,4 @@ +import EmojiAvatar from '@renderer/components/Avatar/EmojiAvatar' import UserPopup from '@renderer/components/Popups/UserPopup' import { APP_NAME, AppLogo, isLocalAi } from '@renderer/config/env' import { getModelLogo } from '@renderer/config/models' @@ -87,7 +88,9 @@ const MessageHeader: FC = memo(({ assistant, model, message }) => { ) : ( <> {isEmoji(avatar) ? ( - UserPopup.show()}>{avatar} + UserPopup.show()} size={35} fontSize={20}> + {avatar} + ) : ( = memo(({ assistant, model, message }) => { MessageHeader.displayName = 'MessageHeader' -const EmojiAvatar = styled.div` - width: 35px; - height: 35px; - background-color: var(--color-background-soft); - border-radius: 20%; - display: flex; - align-items: center; - justify-content: center; - font-size: 18px; - cursor: pointer; - border: 0.5px solid var(--color-border); - font-size: 20px; -` - const Container = styled.div` display: flex; flex-direction: row; diff --git a/src/renderer/src/store/thunk/messageThunk.ts b/src/renderer/src/store/thunk/messageThunk.ts index d090c392e9..95019b02ed 100644 --- a/src/renderer/src/store/thunk/messageThunk.ts +++ b/src/renderer/src/store/thunk/messageThunk.ts @@ -726,6 +726,7 @@ export const loadTopicMessagesThunk = async (dispatch: AppDispatch, getState: () => RootState) => { const state = getState() const topicMessagesExist = !!state.messages.messageIdsByTopic[topicId] + dispatch(newMessagesActions.setCurrentTopicId(topicId)) if (topicMessagesExist && !forceReload) { return