From 510c8fd6fafe4e9e296eae44af09f7410bd65e86 Mon Sep 17 00:00:00 2001 From: xue <2144439972@qq.com> Date: Thu, 4 Dec 2025 20:03:19 +0800 Subject: [PATCH] =?utf8?q?=E4=BC=98=E5=8C=96=E5=93=84=E7=9D=A1=E6=A8=A1?= =?utf8?q?=E5=BC=8F=E7=9A=84=E8=A1=A8=E6=83=85=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- .../thunderbird/include/ThunderBirdModel.h | 7 ++ .../thunderbird/src/ThunderBirdModel.cpp | 109 +++++++++++++++++- 2 files changed, 111 insertions(+), 5 deletions(-) diff --git a/code/sdk/application/wearable/ln/nativeapp/nativeui/thunderbird/include/ThunderBirdModel.h b/code/sdk/application/wearable/ln/nativeapp/nativeui/thunderbird/include/ThunderBirdModel.h index 04df4d800..49e4b8d3b 100644 --- a/code/sdk/application/wearable/ln/nativeapp/nativeui/thunderbird/include/ThunderBirdModel.h +++ b/code/sdk/application/wearable/ln/nativeapp/nativeui/thunderbird/include/ThunderBirdModel.h @@ -273,6 +273,12 @@ namespace OHOS // 退出对话模式时恢复表情 void OnExitDialogueMode(); + + // 进入哄睡模式时记录当前表情 + void OnEnterLullabyMode(); + + // 退出哄睡模式时恢复表情 + void OnExitLullabyMode(); // 音频文本队列操作函数 void EnqueueAudioText(const std::string& text); @@ -378,6 +384,7 @@ namespace OHOS std::string m_currentExpression; // 当前表情状态 std::string m_currentStatusText; // 当前状态文本 std::string m_dialogueExpression; // 对话界面表情状态 + std::string m_lullabyExpression; // 哄睡模式进入前的表情状态 bool close_battery_flag = false; // 电量过低即将关机标志位 diff --git a/code/sdk/application/wearable/ln/nativeapp/nativeui/thunderbird/src/ThunderBirdModel.cpp b/code/sdk/application/wearable/ln/nativeapp/nativeui/thunderbird/src/ThunderBirdModel.cpp index a9f90a1ec..ab3964a35 100644 --- a/code/sdk/application/wearable/ln/nativeapp/nativeui/thunderbird/src/ThunderBirdModel.cpp +++ b/code/sdk/application/wearable/ln/nativeapp/nativeui/thunderbird/src/ThunderBirdModel.cpp @@ -2604,6 +2604,8 @@ extern "C" { WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::HandleSleepModeStart: 非意图识别结果,跳转到4"); // 重置故事模式finished标志,确保每次进入故事模式时标志位是干净的 m_storyModeFinished = false; + // 进入哄睡模式时切换为眨眼表情 + OnEnterLullabyMode(); ThunderBirdMainView::GetInstance()->ChangeView(currentView, THUNDERBIRD_LULLABYVIEW, ThunderBirdLullabyView::THUNDERBIRD_LULLABYVIEW_4); //清空文本队列 ClearAudioTextQueue(); @@ -2645,6 +2647,11 @@ extern "C" { if (ThunderBirdMainView::GetInstance()) { int currentView = ThunderBirdMainView::GetInstance()->GetCurrentView(); //获取当前视图 + // 退出哄睡模式时恢复时间线表情 + OnExitLullabyMode(); + if (ThunderBirdMainView::GetInstance() && ThunderBirdMainView::GetInstance()->listenIcon) { + ThunderBirdMainView::GetInstance()->listenIcon->SetVisible(false); + } ln_ws_audio_deinit();//功耗优化 //直接退出到状态显示界面 AI_ForceInterrupt(); @@ -2897,6 +2904,10 @@ extern "C" { // 停止动效 ThunderBirdDialogueView::GetInstance()->AudioPlaybackEnd(); ThunderBirdDialogueView::GetInstance()->IsNormalEnd = true; + //可以开始说话了,显示小绿点 + if (ThunderBirdMainView::GetInstance() && ThunderBirdMainView::GetInstance()->listenIcon) { + ThunderBirdMainView::GetInstance()->listenIcon->SetVisible(true); + } // 启动8秒定时器,时间到就退出对话 StartCountUpTimer(10); WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::HandleAudioPlaybackEnd: 启动10秒定时器,时间到就退出对话"); @@ -2910,6 +2921,9 @@ extern "C" { WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::HandleAudioPlaybackEnd: THUNDERBIRD_LULLABYVIEW_3界面,角色询问完毕,重新启动音频聊天"); // 重置标志 m_lullabyView3InquiryStarted = false; + if (ThunderBirdMainView::GetInstance() && ThunderBirdMainView::GetInstance()->listenIcon) { + ThunderBirdMainView::GetInstance()->listenIcon->SetVisible(true); + } int ret = ln_ws_start_audio_chat(LN_AUDIO_CHAT_CHOOSE_STORY_REQUEST); if (ret == 0) { WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "THUNDERBIRD_LULLABYVIEW_3: 音频聊天已重新启动"); @@ -2964,7 +2978,7 @@ extern "C" { { // isLullabyRecording = true; ThunderBirdLullabyView::GetInstance()->listenAnimator->Start(); - ThunderBirdDialogueView::GetInstance()->listenIcon->SetVisible(true); + // ThunderBirdDialogueView::GetInstance()->listenIcon->SetVisible(true); WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::HandleAudioRecordingStart: 在哄睡界面(故事模式),忽略录音开始事件"); return; } @@ -2973,7 +2987,6 @@ extern "C" { || ThunderBirdDialogueView::GetInstance()->DialogueFirst == false) { WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "录音开始,跳转到聆听状态"); view->ChangeView(currentView, THUNDERBIRD_DIALOGUEVIEW, ThunderBirdDialogueView::THUNDERBIRD_DIALOGUEVIEW_LISTENING); - ThunderBirdDialogueView::GetInstance()->listenIcon->SetVisible(true); ThunderBirdDialogueView::GetInstance()->IsNormalEnd = false; // ThunderBirdDialogueView::GetInstance()->UpdateDialogueText("超认真聆听中"); } @@ -3005,13 +3018,19 @@ extern "C" { currentSubView == ThunderBirdDialogueView::THUNDERBIRD_DIALOGUEVIEW_LISTENING) { WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "录音结束,跳转到播放界面"); view->ChangeView(currentView, THUNDERBIRD_DIALOGUEVIEW, ThunderBirdDialogueView::THUNDERBIRD_DIALOGUEVIEW_SPEAKING); - ThunderBirdDialogueView::GetInstance()->listenIcon->SetVisible(false); + if (ThunderBirdMainView::GetInstance() && ThunderBirdMainView::GetInstance()->listenIcon) { + ThunderBirdMainView::GetInstance()->listenIcon->SetVisible(false); + } } else if (currentView == THUNDERBIRD_LULLABYVIEW && currentSubView == ThunderBirdLullabyView::THUNDERBIRD_LULLABYVIEW_3 ) { ThunderBirdLullabyView::GetInstance()->listenAnimator->Stop(); - ThunderBirdDialogueView::GetInstance()->listenIcon->SetVisible(false); + if (ThunderBirdMainView::GetInstance() && ThunderBirdMainView::GetInstance()->listenIcon) { + ThunderBirdMainView::GetInstance()->listenIcon->SetVisible(false); + } WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "录音结束,跳转到故事界面"); + // 进入哄睡模式时切换为眨眼表情 + OnEnterLullabyMode(); view->ChangeView(currentView, THUNDERBIRD_LULLABYVIEW, ThunderBirdLullabyView::THUNDERBIRD_LULLABYVIEW_4); return; } @@ -3175,7 +3194,7 @@ extern "C" { // 重置对话模式finished标志 m_dialogueModeFinished = false; //如果本来就是眨眼的表情直接返回 - if (m_currentExpression == "winking") { + if (m_currentExpression == "winking" || m_currentExpression.empty() == true) { return; } // 记录进入对话模式前的时间线表情(用于退出时恢复) @@ -3198,6 +3217,9 @@ extern "C" { // 退出对话模式时恢复表情 void ThunderBirdModel::OnExitDialogueMode() { + if (ThunderBirdMainView::GetInstance() && ThunderBirdMainView::GetInstance()->listenIcon) { + ThunderBirdMainView::GetInstance()->listenIcon->SetVisible(false); + } // 重置对话模式finished标志 m_dialogueModeFinished = false; @@ -3248,6 +3270,83 @@ extern "C" { } } + // 进入哄睡模式时记录当前表情(进入THUNDERBIRD_LULLABYVIEW_4时调用) + void ThunderBirdModel::OnEnterLullabyMode() + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::OnEnterLullabyMode"); + //如果本来就是眨眼的表情直接返回 + if (m_currentExpression == "winking" || m_currentExpression.empty() == true) { + return; + } + // 记录进入哄睡模式前的时间线表情(用于退出时恢复) + m_lullabyExpression = m_currentExpression; + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::OnEnterLullabyMode: 记录时间线表情: %s", m_currentExpression.c_str()); + + // 切换到眨眼表情(winking) + std::string winkingExpressionPath = "/user/res/video/CloseEyes/" + eyesShape_ + "/" + eyesColor_ + ".mp4"; + + // 检查文件是否存在 + if (access(winkingExpressionPath.c_str(), F_OK) == 0) { + // 切换到眨眼表情(但不更新m_currentExpression,因为退出时要恢复时间线表情) + SwitchExpressionVideo(winkingExpressionPath.c_str()); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::OnEnterLullabyMode: 切换到眨眼表情: %s", winkingExpressionPath.c_str()); + } else { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::OnEnterLullabyMode: 眨眼表情文件不存在: %s", winkingExpressionPath.c_str()); + } + } + + // 退出哄睡模式时恢复表情(退出THUNDERBIRD_LULLABYVIEW_4时调用) + void ThunderBirdModel::OnExitLullabyMode() + { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::OnExitLullabyMode"); + + // 恢复到进入哄睡模式前记录的时间线表情 + if (!m_lullabyExpression.empty()) { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::OnExitLullabyMode: 恢复时间线表情: %s", m_lullabyExpression.c_str()); + //如果相同直接返回 + if(m_lullabyExpression == m_currentExpression) + { + return; + } + // 恢复表情状态 + // 构建表情文件路径并切换表情 + std::string expressionPath; + if (screenImageAsEmoji_ == false) { + // 不为屏保模式,根据角色配置构建表情路径 + if (eyesColor_.empty() || eyesShape_.empty() || + (eyesShape_ == "calm-eyes" && eyesColor_ == "amber")) { + // 默认表情 + std::string emotionFileName = MapEmotionToFileName(m_lullabyExpression.c_str()); + expressionPath = "/user/res/video/Default/" + emotionFileName + ".mp4"; + } else { + // 非默认表情 + if (m_lullabyExpression == "winking") { + // 眨眼表情 + expressionPath = "/user/res/video/CloseEyes/" + eyesShape_ + "/" + eyesColor_ + ".mp4"; + } else if (m_lullabyExpression == "sleeping") { + // 睡眠表情 + expressionPath = "/user/res/video/Default/sleeping.mp4"; + } else { + // 其他表情 + expressionPath = "/user/userdata/leiniao/emoji/" + eyesShape_ + "/" + eyesColor_ + "/" + m_lullabyExpression + ".mp4"; + } + } + + // 检查文件是否存在并切换表情 + if (access(expressionPath.c_str(), F_OK) == 0) { + SwitchExpressionVideo(expressionPath.c_str()); + HandleHairIconChange(m_lullabyExpression); + SetCurrentExpression(m_lullabyExpression); + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::OnExitLullabyMode: 恢复表情成功: %s", expressionPath.c_str()); + } else { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::OnExitLullabyMode: 表情文件不存在: %s", expressionPath.c_str()); + } + } + } else { + WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::OnExitLullabyMode: 没有记录的表情,无法恢复"); + } + } + // 设置当前表情状态 void ThunderBirdModel::SetCurrentExpression(const std::string& expression) { -- 2.17.1