diff --git a/src/renderer/src/components/Popups/UserPopup.tsx b/src/renderer/src/components/Popups/UserPopup.tsx index 33bea081..e803df4c 100644 --- a/src/renderer/src/components/Popups/UserPopup.tsx +++ b/src/renderer/src/components/Popups/UserPopup.tsx @@ -4,15 +4,15 @@ import ImageStorage from '@renderer/services/ImageStorage' import { useAppDispatch } from '@renderer/store' import { setAvatar } from '@renderer/store/runtime' import { setUserName } from '@renderer/store/settings' -import { compressImage } from '@renderer/utils' -import { Avatar , Input, Modal, Popover, Upload, Dropdown } from 'antd' +import { compressImage, isEmoji } from '@renderer/utils' +import { Avatar, Dropdown, Input, Modal, Popover, Upload } from 'antd' import { useState } from 'react' import { useTranslation } from 'react-i18next' import styled from 'styled-components' +import EmojiPicker from '../EmojiPicker' import { Center, HStack, VStack } from '../Layout' import { TopView } from '../TopView' -import EmojiPicker from '../EmojiPicker' interface Props { resolve: (data: any) => void @@ -51,12 +51,6 @@ const PopupContainer: React.FC = ({ resolve }) => { } } - // modify the judgment function, more accurately detect Emoji - const isEmoji = (str: string) => { - // check if it is a string and is not base64 or URL format - return str && typeof str === 'string' && !str.startsWith('data:') && !str.startsWith('http'); - } - const items = [ { key: 'upload', @@ -88,11 +82,12 @@ const PopupContainer: React.FC = ({ resolve }) => { { key: 'emoji', label: ( -
{ - e.stopPropagation() - setEmojiPickerOpen(true) - setDropdownOpen(false) - }}> +
{ + e.stopPropagation() + setEmojiPickerOpen(true) + setDropdownOpen(false) + }}> {t('settings.general.emoji_picker')}
) @@ -111,8 +106,8 @@ const PopupContainer: React.FC = ({ resolve }) => { centered>
- = ({ resolve }) => { } }} placement="bottom"> - {isEmoji(avatar) ? ( - {avatar} - ) : ( - - )} + {isEmoji(avatar) ? {avatar} : } @@ -147,7 +138,7 @@ const PopupContainer: React.FC = ({ resolve }) => { dispatch(setUserName(e.target.value))} + onChange={(e) => dispatch(setUserName(e.target.value.trim()))} style={{ flex: 1, textAlign: 'center', width: '100%' }} maxLength={30} /> @@ -201,4 +192,4 @@ export default class UserPopup { ) }) } -} \ No newline at end of file +} diff --git a/src/renderer/src/components/app/Sidebar.tsx b/src/renderer/src/components/app/Sidebar.tsx index 4a46d4d7..c3ebfb1a 100644 --- a/src/renderer/src/components/app/Sidebar.tsx +++ b/src/renderer/src/components/app/Sidebar.tsx @@ -12,6 +12,7 @@ import useAvatar from '@renderer/hooks/useAvatar' import { useMinapps } from '@renderer/hooks/useMinapps' import { modelGenerating, useRuntime } from '@renderer/hooks/useRuntime' import { useSettings } from '@renderer/hooks/useSettings' +import { isEmoji } from '@renderer/utils' import type { MenuProps } from 'antd' import { Tooltip } from 'antd' import { Avatar } from 'antd' @@ -57,10 +58,6 @@ const Sidebar: FC = () => { }) } - const isEmoji = (str: string) => { - return str && typeof str === 'string' && !str.startsWith('data:') && !str.startsWith('http'); - } - return ( { zIndex: minappShow ? 10000 : 'initial' }}> {isEmoji(avatar) ? ( - {avatar} + {avatar} ) : ( )} @@ -229,7 +226,7 @@ const AvatarImg = styled(Avatar)` cursor: pointer; ` -const EmojiAvatarSidebar = styled.div` +const EmojiAvatar = styled.div` width: 31px; height: 31px; background-color: var(--color-background-soft); @@ -242,6 +239,7 @@ const EmojiAvatarSidebar = styled.div` font-size: 16px; cursor: pointer; -webkit-app-region: none; + border: 0.5px solid var(--color-border); ` const MainMenusContainer = styled.div` diff --git a/src/renderer/src/pages/home/Messages/MessageHeader.tsx b/src/renderer/src/pages/home/Messages/MessageHeader.tsx index 616367f0..3ba02ebb 100644 --- a/src/renderer/src/pages/home/Messages/MessageHeader.tsx +++ b/src/renderer/src/pages/home/Messages/MessageHeader.tsx @@ -8,17 +8,13 @@ import { useMessageStyle, useSettings } from '@renderer/hooks/useSettings' import { getMessageModelId } from '@renderer/services/MessagesService' import { getModelName } from '@renderer/services/ModelService' import { Assistant, Message, Model } from '@renderer/types' -import { firstLetter, removeLeadingEmoji } from '@renderer/utils' +import { firstLetter, isEmoji, removeLeadingEmoji } from '@renderer/utils' import { Avatar } from 'antd' import dayjs from 'dayjs' import { CSSProperties, FC, memo, useCallback, useMemo } from 'react' import { useTranslation } from 'react-i18next' import styled from 'styled-components' -const isEmoji = (str: string) => { - return str && typeof str === 'string' && !str.startsWith('data:') && !str.startsWith('http'); -} - interface Props { message: Message assistant: Assistant diff --git a/src/renderer/src/utils/index.ts b/src/renderer/src/utils/index.ts index f702a036..7ce1ee03 100644 --- a/src/renderer/src/utils/index.ts +++ b/src/renderer/src/utils/index.ts @@ -123,6 +123,19 @@ export function getLeadingEmoji(str: string): string { return match ? match[0] : '' } +export function isEmoji(str: string) { + if (str.startsWith('data:')) { + return false + } + + if (str.startsWith('http')) { + return false + } + + const emojiRegex = /^(\p{Emoji_Presentation}|\p{Emoji}\uFE0F)+/u + return str.match(emojiRegex) +} + export function isFreeModel(model: Model) { return (model.id + model.name).toLocaleLowerCase().includes('free') }