diff --git a/package.json b/package.json index 8f477f8..247ece8 100644 --- a/package.json +++ b/package.json @@ -7,12 +7,9 @@ "@reduxjs/toolkit": "^1.8.3", "@volcengine/rtc": "4.66.1", "@arco-design/web-react": "^2.65.0", - "autolinker": "^4.0.0", - "i18next": "^21.8.16", "react": "^18.2.0", "react-dom": "^18.2.0", "react-helmet": "^6.1.0", - "react-i18next": "^11.18.3", "react-redux": "^8.0.2", "react-router": "^6.3.0", "react-router-dom": "^6.3.0", diff --git a/src/components/BubbleMsg/index.module.less b/src/components/BubbleMsg/index.module.less deleted file mode 100644 index 94231a2..0000000 --- a/src/components/BubbleMsg/index.module.less +++ /dev/null @@ -1,38 +0,0 @@ -/** - * Copyright 2025 Beijing Volcano Engine Technology Co., Ltd. All Rights Reserved. - * SPDX-license-identifier: BSD-3-Clause - */ - -.bubbleWrapper { - position: relative; - width: 118px; - height: 46px; - - .bubbleLogo { - width: 100%; - height: 100%; - object-fit: contain; - object-position: center; - z-index: 1; - } - - .bubbleText { - position: absolute; - z-index: 2; - width: 100%; - height: 100%; - display: flex; - justify-content: center; - align-items: center; - font-size: 13px; - color: black; - font-weight: 400; - line-height: 16px; - text-align: center; - top: 0px; - } - - .bubble-direction-left { - transform: scaleX(-1); - } -} \ No newline at end of file diff --git a/src/components/BubbleMsg/index.tsx b/src/components/BubbleMsg/index.tsx deleted file mode 100644 index db8df20..0000000 --- a/src/components/BubbleMsg/index.tsx +++ /dev/null @@ -1,35 +0,0 @@ -/** - * Copyright 2025 Beijing Volcano Engine Technology Co., Ltd. All Rights Reserved. - * SPDX-license-identifier: BSD-3-Clause - */ - -import React from 'react'; -import Bubble from '@/assets/img/bubble.svg'; -import styles from './index.module.less'; - -type IBubbleMsgProps = { - text?: string; - direction?: 'left' | 'right'; -} & React.HTMLAttributes; - -enum Direction { - Left = 'left', - Right = 'right', -} - -function BubbleMsg(props: IBubbleMsgProps) { - const { text = '', direction = Direction.Right, style = {}, className = '' } = props; - - return ( -
- Logo -
{text}
-
- ); -} - -export default BubbleMsg; diff --git a/src/components/ButtonRadio/index.module.less b/src/components/ButtonRadio/index.module.less deleted file mode 100644 index 0346511..0000000 --- a/src/components/ButtonRadio/index.module.less +++ /dev/null @@ -1,48 +0,0 @@ -/** - * Copyright 2025 Beijing Volcano Engine Technology Co., Ltd. All Rights Reserved. - * SPDX-license-identifier: BSD-3-Clause - */ - -.wrapper { - width: max-content; - padding: 4px 4px; - border-radius: 4px; - border: 1px solid; - display: flex; - flex-direction: row; - justify-content: flex-start; - gap: 4px; - align-items: center; - background: var(--background-color-bg-5, rgba(241, 243, 245, 1)); - border: 0px; - - .item { - cursor: pointer; - color: var(--text-color-text-2, rgba(66, 70, 78, 1)); - font-family: PingFang SC; - font-size: 13px; - font-weight: 400; - line-height: 22px; - letter-spacing: 0.003em; - text-align: center; - border: 0px; - } - - .selected { - box-shadow: 0px 0px 0px 1px rgba(213, 219, 227, 0.7); - background: var(--background-color-bg-1, rgba(255, 255, 255, 1)); - border-radius: 4px; - } - - .selected-text { - background: linear-gradient(90deg, #004FFF 38.86%, #9865FF 100%); - -webkit-background-clip: text; - background-clip: text; - color: transparent; - font-family: PingFang SC; - font-size: 13px; - font-weight: 500; - line-height: 22px; - letter-spacing: 0.003em; - } -} \ No newline at end of file diff --git a/src/components/ButtonRadio/index.tsx b/src/components/ButtonRadio/index.tsx deleted file mode 100644 index 1e46776..0000000 --- a/src/components/ButtonRadio/index.tsx +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Copyright 2025 Beijing Volcano Engine Technology Co., Ltd. All Rights Reserved. - * SPDX-license-identifier: BSD-3-Clause - */ - -import { useMemo } from 'react'; -import { Button } from '@arco-design/web-react'; -import styles from './index.module.less'; - -interface IProps { - value?: string; - onChange: (key: string) => void; - options: { - label: string; - key: string; - }[]; -} - -function ButtonRadio(props: IProps) { - const { value, onChange, options } = props; - const selected = - useMemo(() => options.find((item) => item.key === value), [value]) || options?.[0]; - const handleClick = (key: string) => { - onChange?.(key); - }; - - return ( -
- {options.map(({ label, key }) => ( - - ))} -
- ); -} - -export default ButtonRadio; diff --git a/src/components/Icon/index.tsx b/src/components/Icon/index.tsx deleted file mode 100644 index 6ac61be..0000000 --- a/src/components/Icon/index.tsx +++ /dev/null @@ -1,36 +0,0 @@ -/** - * Copyright 2025 Beijing Volcano Engine Technology Co., Ltd. All Rights Reserved. - * SPDX-license-identifier: BSD-3-Clause - */ - -import { useEffect, useRef } from 'react'; - -const getDom = async (url: string) => { - const res = await fetch(url); - if (res) { - const text = await res.text(); - // https://developer.mozilla.org/zh-CN/docs/Web/API/DOMParser - return new window.DOMParser().parseFromString(text, 'text/xml'); - } - return undefined; -}; - -function MenuIcon({ src, className = '' }: { src: string; className?: string }) { - const wrapper = useRef(null); - - const renderSVG = async () => { - const svg = await getDom(src); - - if (svg?.documentElement instanceof SVGSVGElement) { - wrapper.current?.replaceChildren(svg.documentElement); - } - }; - - useEffect(() => { - src && renderSVG(); - }, [src]); - - return ; -} - -export default MenuIcon; diff --git a/src/components/RippleWave/index.module.less b/src/components/RippleWave/index.module.less deleted file mode 100644 index 6493e6b..0000000 --- a/src/components/RippleWave/index.module.less +++ /dev/null @@ -1,69 +0,0 @@ -/** - * Copyright 2025 Beijing Volcano Engine Technology Co., Ltd. All Rights Reserved. - * SPDX-license-identifier: BSD-3-Clause - */ - -/* AudioWave.css */ -@keyframes audioWave { - 0% { - transform: scale(0.5); - opacity: 1; - } - 100% { - transform: scale(2.5); - opacity: 0; - } -} - -.wave-container { - position: absolute; - width: 150px; - height: 150px; -} - -.wave { - position: absolute; - border: 1px solid gray; - border-color: rgba(0, 0, 0, .06); - border-radius: 50%; - width: 100%; - height: 100%; - animation: audioWave 9s infinite; - opacity: 0; -} - -.wave:nth-child(1) { - animation-delay: -1s; -} - -.wave:nth-child(2) { - animation-delay: -2s; -} - -.wave:nth-child(3) { - animation-delay: -3s; -} - -.wave:nth-child(4) { - animation-delay: -4s; -} - -.wave:nth-child(5) { - animation-delay: -5s; -} - -.wave:nth-child(6) { - animation-delay: -6s; -} - -.wave:nth-child(7) { - animation-delay: -7s; -} - -.wave:nth-child(8) { - animation-delay: -8s; -} - -.wave:nth-child(9) { - animation-delay: -9s; -} \ No newline at end of file diff --git a/src/components/RippleWave/index.tsx b/src/components/RippleWave/index.tsx deleted file mode 100644 index d34a590..0000000 --- a/src/components/RippleWave/index.tsx +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Copyright 2025 Beijing Volcano Engine Technology Co., Ltd. All Rights Reserved. - * SPDX-license-identifier: BSD-3-Clause - */ - -import React from 'react'; -import styles from './index.module.less'; - -type IRippleWaveProps = React.HTMLAttributes; - -const LEVEL = 9; - -function RippleWave(props: IRippleWaveProps) { - const { className = '', style = {} } = props; - return ( -
- {Array(LEVEL) - .fill(0) - .map((_, index) => { - return
; - })} -
- ); -} - -export default RippleWave; diff --git a/src/store/slices/room.ts b/src/store/slices/room.ts index 89e6af4..348cbe0 100644 --- a/src/store/slices/room.ts +++ b/src/store/slices/room.ts @@ -230,40 +230,18 @@ export const roomSlice = createSlice({ }, setHistoryMsg: (state, { payload }) => { const { paragraph, definite } = payload; + const lastMsg = state.msgHistory.at(-1)! || {}; /** 是否需要再创建新句子 */ - const shouldCreateSentence = payload.definite; - state.isUserTalking = payload.user === state.localUser.userId; + const fromBot = payload.user === config.BotName; + /** + * Bot 的语句以 definite 判断是否需要追加新内容 + * User 的语句以 paragraph 判断是否需要追加新内容 + */ + const lastMsgCompleted = fromBot ? lastMsg.definite : lastMsg.paragraph; + if (state.msgHistory.length) { - const lastMsg = state.msgHistory.at(-1)!; - /** 当前讲话人更新字幕 */ - if (lastMsg.user === payload.user) { - /** 如果上一句话是完整的 & 本次的话也是完整的, 则直接塞入 */ - if (lastMsg.definite) { - state.msgHistory.push({ - value: payload.text, - time: new Date().toString(), - user: payload.user, - definite, - paragraph, - }); - } else { - /** 话未说完, 更新文字内容 */ - lastMsg.value = payload.text; - lastMsg.time = new Date().toString(); - lastMsg.paragraph = paragraph; - lastMsg.definite = definite; - lastMsg.user = payload.user; - } - /** 如果本次的话已经说完了, 提前塞入空字符串做准备 */ - if (shouldCreateSentence) { - state.msgHistory.push({ - value: '', - time: new Date().toString(), - user: '', - }); - } - } else { - /** 换人说话了,塞入新句子 */ + /** 如果上一句话是完整的则新增语句 */ + if (lastMsgCompleted) { state.msgHistory.push({ value: payload.text, time: new Date().toString(), @@ -271,6 +249,13 @@ export const roomSlice = createSlice({ definite, paragraph, }); + } else { + /** 话未说完, 更新文字内容 */ + lastMsg.value = payload.text; + lastMsg.time = new Date().toString(); + lastMsg.paragraph = paragraph; + lastMsg.definite = definite; + lastMsg.user = payload.user; } } else { /** 首句话首字不会被打断 */ diff --git a/yarn.lock b/yarn.lock index 2f1e555..428416f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1059,7 +1059,7 @@ dependencies: regenerator-runtime "^0.14.0" -"@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.14.5", "@babel/runtime@^7.16.3", "@babel/runtime@^7.17.2", "@babel/runtime@^7.18.9", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": +"@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.16.3", "@babel/runtime@^7.18.9", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": version "7.18.9" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.18.9.tgz#b4fcfce55db3d2e5e080d2490f608a3b9f407f4a" integrity sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw== @@ -2638,13 +2638,6 @@ at-least-node@^1.0.0: resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== -autolinker@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/autolinker/-/autolinker-4.0.0.tgz#aa1f9a52786b727b0ecee8cd7d4a97e0e3ef59f1" - integrity sha512-fl5Kh6BmEEZx+IWBfEirnRUU5+cOiV0OK7PEt0RBKvJMJ8GaRseIOeDU3FKf4j3CE5HVefcjHmhYPOcaVt0bZw== - dependencies: - tslib "^2.3.0" - autoprefixer@^10.4.7: version "10.4.8" resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.8.tgz#92c7a0199e1cfb2ad5d9427bd585a3d75895b9e5" @@ -4971,13 +4964,6 @@ html-minifier-terser@^6.0.2: relateurl "^0.2.7" terser "^5.10.0" -html-parse-stringify@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz#dfc1017347ce9f77c8141a507f233040c59c55d2" - integrity sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg== - dependencies: - void-elements "3.1.0" - html-tags@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.2.0.tgz#dbb3518d20b726524e4dd43de397eb0a95726961" @@ -5077,13 +5063,6 @@ human-signals@^2.1.0: resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== -i18next@^21.8.16: - version "21.8.16" - resolved "https://registry.yarnpkg.com/i18next/-/i18next-21.8.16.tgz#31fe4682e4e2077dbf229a88e5a58b7020e4ddc8" - integrity sha512-acJLCk38YMfEPjBR/1vS13SFY7rBQLs9E5m1tSRnWc9UW3f+SZszgH+NP1fZRA1+O+CdG2eLGGmuUMJW52EwzQ== - dependencies: - "@babel/runtime" "^7.17.2" - iconv-lite@0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" @@ -7759,14 +7738,6 @@ react-helmet@^6.1.0: react-fast-compare "^3.1.1" react-side-effect "^2.1.0" -react-i18next@^11.18.3: - version "11.18.3" - resolved "https://registry.yarnpkg.com/react-i18next/-/react-i18next-11.18.3.tgz#50211810bcc9fdea2d70c8aefdfff5f1eb39a923" - integrity sha512-EttTX31HbqzZymUM3SIrMPuvamfSXFZVsDHm/ZAqoDfTLjhzlwyxqfbDNxcKNAGOi2mjZaXfR7hSNMlvLNpB/g== - dependencies: - "@babel/runtime" "^7.14.5" - html-parse-stringify "^3.0.1" - react-is@^16.13.1, react-is@^16.7.0: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" @@ -9327,11 +9298,6 @@ vary@~1.1.2: resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== -void-elements@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-3.1.0.tgz#614f7fbf8d801f0bb5f0661f5b2f5785750e4f09" - integrity sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w== - w3c-hr-time@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd"