|
|
@@ -59,7 +59,11 @@ const ENABLE_CHATBOT_TIPS = false;
|
|
|
|
|
|
const luyinDefault = getOssUrl('luyin-default.png');
|
|
|
const luyinDisable = getOssUrl('luyin-disable.png');
|
|
|
-const duihuaYinying = getOssUrl('duihuayinying.svg');
|
|
|
+// 录音态四边对话阴影图(OSS)
|
|
|
+const chatBgTop = getOssUrl('chat-bg-top.svg');
|
|
|
+const chatBgRight = getOssUrl('chat-bg-right.svg');
|
|
|
+const chatBgBottom = getOssUrl('chat-bg-bottom.svg');
|
|
|
+const chatBgLeft = getOssUrl('chat-bg-left.svg');
|
|
|
const settingIcon = getOssUrl('setting-icon.png');
|
|
|
const funcLockIcon = getOssUrl('func-Lock.png');
|
|
|
const profileMenuIcon = getOssUrl('profile-icon.png');
|
|
|
@@ -75,6 +79,7 @@ const conversationEnergyStoneHint = getOssUrl('Conversation-Energy-Stone-hint.pn
|
|
|
const heartFilled = getOssUrl('Heart.png');
|
|
|
const heartBroken = getOssUrl('Heart_broken.png');
|
|
|
const conversationEnergyStoneCountBg = getOssUrl('conversion-energy-stone-count.png');
|
|
|
+const qinmiduImage = getOssUrl('qinmidu.png');
|
|
|
const YpImage = getOssUrl('yp.png');
|
|
|
const audioWaveGif = getOssUrl('audio-wave.gif');
|
|
|
import { useEnergyStones, type EnergyStoneEventPayload } from '@/hooks/useEnergyStones';
|
|
|
@@ -146,6 +151,7 @@ const getEmotionGifDuration = (_avatarId: string | null, emotionCategory: 'posit
|
|
|
export const ChatBotPage = () => {
|
|
|
const { t: tCommon } = useTranslation('common');
|
|
|
const { t: tProfile } = useTranslation('profile');
|
|
|
+ const { t: tWelcome } = useTranslation('welcome');
|
|
|
const navigate = useNavigate();
|
|
|
const [searchParams] = useSearchParams();
|
|
|
const location = useLocation();
|
|
|
@@ -234,6 +240,7 @@ export const ChatBotPage = () => {
|
|
|
const [showMissionStoneModal, setShowMissionStoneModal] = useState(false);
|
|
|
const [energyStoneModalType, setEnergyStoneModalType] = useState<'mission' | 'conversation'>('mission');
|
|
|
const [showIntimacyModal, setShowIntimacyModal] = useState(false);
|
|
|
+ const [showBondLevelModal, setShowBondLevelModal] = useState(false);
|
|
|
const [showFuncMenuPopup, setShowFuncMenuPopup] = useState(false);
|
|
|
const [intimacyHeartCount, setIntimacyHeartCount] = useState(3);
|
|
|
const [intimacyDaysSinceLastVisit, setIntimacyDaysSinceLastVisit] = useState(0);
|
|
|
@@ -2820,7 +2827,7 @@ export const ChatBotPage = () => {
|
|
|
|
|
|
// 根据背景图片获取对应的树木装饰图片URL(/chatbot 界面统一使用默认图片,不随用户选择的新年等背景切换)
|
|
|
const getTreesImage = (): string | null => {
|
|
|
- return getOssUrl('init1.svg');
|
|
|
+ return getOssUrl('init2.svg');
|
|
|
};
|
|
|
|
|
|
// 根据背景图片ID获取树木装饰图片的样式配置(/chatbot 使用默认背景,透明度固定为 1)
|
|
|
@@ -2866,20 +2873,15 @@ export const ChatBotPage = () => {
|
|
|
|
|
|
{/* 说话时的阴影蒙层:仅录音中出现,发送/取消后立即消失 */}
|
|
|
{currentState === 'recording' && (
|
|
|
- <img
|
|
|
- src={duihuaYinying}
|
|
|
- alt=""
|
|
|
- className="pointer-events-none absolute"
|
|
|
- style={{
|
|
|
- top: 0,
|
|
|
- left: 0,
|
|
|
- width: '100%',
|
|
|
- height: '100%',
|
|
|
- objectFit: 'cover',
|
|
|
- zIndex: 2,
|
|
|
- }}
|
|
|
- draggable={false}
|
|
|
- />
|
|
|
+ <div
|
|
|
+ className="pointer-events-none absolute inset-0 overflow-hidden"
|
|
|
+ style={{ zIndex: 2 }}
|
|
|
+ >
|
|
|
+ <img src={chatBgTop} alt="" className="absolute left-0 right-0 top-0 w-full object-contain object-top" style={{ display: 'block' }} draggable={false} />
|
|
|
+ <img src={chatBgRight} alt="" className="absolute right-0 top-0 bottom-0 h-full object-contain object-right" style={{ display: 'block' }} draggable={false} />
|
|
|
+ <img src={chatBgBottom} alt="" className="absolute left-0 right-0 bottom-0 w-full object-contain object-bottom" style={{ display: 'block' }} draggable={false} />
|
|
|
+ <img src={chatBgLeft} alt="" className="absolute left-0 top-0 bottom-0 h-full object-contain object-left" style={{ display: 'block' }} draggable={false} />
|
|
|
+ </div>
|
|
|
)}
|
|
|
|
|
|
{/* 隐藏的能量石容器 - 用于 useEnergyStones hook 计算位置 */}
|
|
|
@@ -2912,8 +2914,21 @@ export const ChatBotPage = () => {
|
|
|
zIndex: 6,
|
|
|
}}
|
|
|
>
|
|
|
- {/* 亲密度心形展示:顶部 6,宽 58,高 14,左右居中 */}
|
|
|
+ {/* 亲密度心形展示:点击弹出羁绊指数说明弹窗 */}
|
|
|
<div
|
|
|
+ role="button"
|
|
|
+ tabIndex={0}
|
|
|
+ aria-label={tWelcome('bondLevelTitle')}
|
|
|
+ onClick={(e) => {
|
|
|
+ e.stopPropagation();
|
|
|
+ setShowBondLevelModal(true);
|
|
|
+ }}
|
|
|
+ onKeyDown={(e) => {
|
|
|
+ if (e.key === 'Enter' || e.key === ' ') {
|
|
|
+ e.preventDefault();
|
|
|
+ setShowBondLevelModal(true);
|
|
|
+ }
|
|
|
+ }}
|
|
|
style={{
|
|
|
position: 'absolute',
|
|
|
top: px2vmin(6, 'v2'),
|
|
|
@@ -2924,6 +2939,7 @@ export const ChatBotPage = () => {
|
|
|
display: 'flex',
|
|
|
alignItems: 'center',
|
|
|
justifyContent: 'space-between',
|
|
|
+ cursor: 'pointer',
|
|
|
}}
|
|
|
>
|
|
|
{Array.from({ length: 3 }, (_, index) => {
|
|
|
@@ -3646,6 +3662,105 @@ export const ChatBotPage = () => {
|
|
|
stoneType={energyStoneModalType}
|
|
|
/>
|
|
|
|
|
|
+ {/* 羁绊指数底部弹窗:点击亲密度心形时展示,中英文随语言切换 */}
|
|
|
+ {showBondLevelModal && (
|
|
|
+ <>
|
|
|
+ <div
|
|
|
+ className="mission-energy-stone-modal-mask"
|
|
|
+ style={{
|
|
|
+ position: 'fixed',
|
|
|
+ top: 0,
|
|
|
+ left: 0,
|
|
|
+ right: 0,
|
|
|
+ bottom: 0,
|
|
|
+ zIndex: 9998,
|
|
|
+ animation: 'fadeIn 0.3s ease-out',
|
|
|
+ }}
|
|
|
+ onClick={() => setShowBondLevelModal(false)}
|
|
|
+ aria-hidden
|
|
|
+ />
|
|
|
+ <div
|
|
|
+ className="mission-energy-stone-modal"
|
|
|
+ style={{
|
|
|
+ position: 'fixed',
|
|
|
+ bottom: 0,
|
|
|
+ left: 0,
|
|
|
+ right: 0,
|
|
|
+ width: '100%',
|
|
|
+ height: px2vmin(192),
|
|
|
+ backgroundColor: '#34313D',
|
|
|
+ borderTopLeftRadius: px2vmin(32),
|
|
|
+ borderTopRightRadius: px2vmin(32),
|
|
|
+ zIndex: 9999,
|
|
|
+ display: 'flex',
|
|
|
+ flexDirection: 'column',
|
|
|
+ alignItems: 'center',
|
|
|
+ paddingTop: px2vmin(12),
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ <div
|
|
|
+ style={{
|
|
|
+ width: px2vmin(32),
|
|
|
+ height: px2vmin(4),
|
|
|
+ backgroundColor: '#79747E',
|
|
|
+ borderRadius: px2vmin(4),
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ <div
|
|
|
+ style={{
|
|
|
+ marginTop: px2vmin(54 - 12 - 4),
|
|
|
+ height: px2vmin(100),
|
|
|
+ display: 'flex',
|
|
|
+ flexDirection: 'row',
|
|
|
+ alignItems: 'center',
|
|
|
+ gap: px2vmin(32),
|
|
|
+ marginLeft: px2vmin(32),
|
|
|
+ marginRight: px2vmin(32),
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ <img
|
|
|
+ src={qinmiduImage}
|
|
|
+ alt={tWelcome('bondLevelTitle')}
|
|
|
+ style={{
|
|
|
+ width: px2vmin(80),
|
|
|
+ height: px2vmin(80),
|
|
|
+ flexShrink: 0,
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ <div
|
|
|
+ style={{
|
|
|
+ flex: 1,
|
|
|
+ display: 'flex',
|
|
|
+ flexDirection: 'column',
|
|
|
+ justifyContent: 'center',
|
|
|
+ gap: px2vmin(8),
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ <div
|
|
|
+ style={{
|
|
|
+ color: '#FFFFFF',
|
|
|
+ fontSize: px2vmin(20),
|
|
|
+ fontWeight: 'bold',
|
|
|
+ lineHeight: 1.2,
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ {tWelcome('bondLevelTitle')}
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ style={{
|
|
|
+ color: '#FFFFFF',
|
|
|
+ fontSize: px2vmin(14),
|
|
|
+ lineHeight: 1.4,
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ {tWelcome('bondLevelDescription')}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </>
|
|
|
+ )}
|
|
|
+
|
|
|
{/* 亲密度弹窗:不满 3 颗心时展示,点击「点亮」增加一颗并关闭 */}
|
|
|
<IntimacyModal
|
|
|
visible={showIntimacyModal}
|