增加对话超时操作
authorxue <2144439972@qq.com>
Mon, 13 Oct 2025 02:00:47 +0000 (10:00 +0800)
committerxue <2144439972@qq.com>
Mon, 13 Oct 2025 02:00:47 +0000 (10:00 +0800)
code/sdk/application/wearable/ln/nativeapp/nativeui/thunderbird/include/ThunderBirdModel.h
code/sdk/application/wearable/ln/nativeapp/nativeui/thunderbird/src/ThunderBirdDialogueView.cpp
code/sdk/application/wearable/ln/nativeapp/nativeui/thunderbird/src/ThunderBirdMainView.cpp
code/sdk/application/wearable/ln/nativeapp/nativeui/thunderbird/src/ThunderBirdModel.cpp
code/sdk/application/wearable/ln/nativeapp/nativeui/thunderbird/src/ThunderBirdPresenter.cpp

index 74a208e..fefbc18 100644 (file)
@@ -221,6 +221,13 @@ namespace OHOS
 
         // 音频播放结束处理函数
         void HandleAudioPlaybackEnd();
+        
+        // 对话状态显示相关函数
+        void SetCurrentExpression(const std::string& expression);
+        void SetCurrentStatusText(const std::string& statusText);
+        void SetCurrentExpressionAndStatus();
+        std::string GetCurrentExpression() const;
+        std::string GetCurrentStatusText() const;
 
         void at_set_fps(uint32_t freq);
         uint32_t at_get_fps(void);
@@ -283,6 +290,10 @@ namespace OHOS
         std::string screenImage_;
         bool screenImageAsEmoji_{false};
 
+        // 对话状态显示相关变量
+        std::string m_currentExpression;    // 当前表情状态
+        std::string m_currentStatusText;    // 当前状态文本
+
         int downloadFileType = -1;
     };
 }
index 52a43b9..e96726d 100644 (file)
@@ -122,7 +122,7 @@ namespace OHOS
             TextLabel_Y->SetStyle(STYLE_TEXT_COLOR, 0xff000000);
             TextLabel_Y->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 30);
             TextLabel_Y->SetLineBreakMode(UILabel::LINE_BREAK_MARQUEE); 
-            TextLabel_Y->SetRollSpeed(35);
+            TextLabel_Y->SetRollSpeed(55);
             TextLabel_Y->SetVisible(false);
             group->Add(TextLabel_Y);
         }
@@ -132,7 +132,7 @@ namespace OHOS
             TextLabel->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
             TextLabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 30);
             TextLabel->SetLineBreakMode(UILabel::LINE_BREAK_MARQUEE); 
-            TextLabel->SetRollSpeed(35);
+            TextLabel->SetRollSpeed(55);
             TextLabel->SetVisible(false);
             group->Add(TextLabel);
         }
@@ -178,7 +178,7 @@ namespace OHOS
             }
             if(ThunderBirdModel::GetInstance()->IsTextEmpty() == true)
             {
-                UpdateDialogueText("等待网络连接");
+                UpdateDialogueText("思考中...");
             }
             else
             {
@@ -208,21 +208,34 @@ namespace OHOS
             }
             //动效图标
             if (listenAnimator) { listenAnimator->SetVisible(true); listenAnimator->Start(); }
+            
+            // 启动30秒超时定时器
+            if (ThunderBirdModel::GetInstance()) {
+                ThunderBirdModel::GetInstance()->StartCountUpTimer(30); // 30秒超时
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdDialogueView: 启动聆听超时定时器,30秒后自动跳转");
+            }
             break;
         }
         case THUNDERBIRD_DIALOGUEVIEW_STATUS_SHOW:
         {
+            // 从ThunderBirdModel获取当前表情和状态文本
+            std::string currentStatusText = "发呆中...";
+            
+            if (ThunderBirdModel::GetInstance()) {
+                currentStatusText = ThunderBirdModel::GetInstance()->GetCurrentStatusText();
+            }
             if (TextLabel)
             {
                 TextLabel->SetPosition(0, 64, 360, 42);
-                TextLabel->SetText("发呆中...");
+                TextLabel->SetText(currentStatusText.c_str());
                 TextLabel->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
                 TextLabel->SetVisible(true);
             }
             if (TextLabel_Y)
             {
-                TextLabel_Y->SetPosition(TextLabel->GetX()+2, TextLabel->GetY() + 2, 360, 42);
-                TextLabel_Y->SetText("发呆中...");
+                TextLabel_Y->SetPosition(2, 66, 360, 42);
+                TextLabel_Y->SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
+                TextLabel_Y->SetText(currentStatusText.c_str());
                 TextLabel_Y->SetVisible(true);
             }
             break;
index 81dd0ef..ec2c620 100644 (file)
@@ -280,14 +280,6 @@ namespace OHOS
             AddViewToRootContainer(ScrollView_);
 
             Initback(); // 最底层
-            if(ThunderBirdModel::GetInstance()->ReadlocalScreenImage() == true)//开启屏保模式
-            {
-                OpenScreenImageModel();
-            }
-            else
-            {
-                CloseScreenImageModel();
-            }
 
             iconView = new UIImageView(); //(表情图片)需要遮罩时启用,预先增加在对应图层
             iconView->SetAutoEnable(false);
@@ -306,6 +298,17 @@ namespace OHOS
             //backGroundView->SetVisible(false);
             ScrollView_->Add(backGroundView);
 
+            if(ThunderBirdModel::GetInstance()->ReadlocalScreenImage() == true)//开启屏保模式
+            {
+                printf("开启屏保模式\n");
+                OpenScreenImageModel();
+            }
+            else
+            {
+                printf("关闭屏保模式\n");
+                CloseScreenImageModel();
+            }
+
             // 默认显示主界面
             //ChangeView(MAXVIEW, THUNDERBIRD_GUIDEVIEW, 0); // 文字显示图层
             if(ThunderBirdModel::GetInstance()->GetCurrentView() != -1 && ThunderBirdModel::GetInstance()->GetCurrentSubView() != -1)
@@ -771,10 +774,18 @@ namespace OHOS
    //切换屏保图片的接口
     void ThunderBirdMainView::SwitchIconImage(const char *imagePath)
     {
-        if (iconView == nullptr || imagePath == nullptr) {
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdMainView::SwitchIconImage: Invalid parameters");
-            return;
-        }
+        if (iconView == nullptr )
+            {
+                printf("iconView is nullptr\n");
+                return;
+            }
+        if(imagePath == nullptr) 
+            {
+                printf("imagePath is nullptr\n");
+                return;
+            }
+          
+        
         WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdMainView::SwitchIconImage: Switching to image: %s", imagePath);
         iconView->SetSrc(imagePath);
         iconView->Invalidate();
@@ -900,10 +911,10 @@ namespace OHOS
         };
         // 待添加的 ImageView 信息列表
         std::vector<ImageViewInfo> imageViewList = {
-            {65, 28, 6, 6},
-            {75, 20, 6, 14},
-            {85, 12, 6, 22},
-            {95, 4, 6, 30},
+            {85, 28, 4, 4},
+            {85+7, 20+2, 4, 10},
+            {85+14, 12+4, 4, 16},
+            {85+21, 4+6, 4, 22},
         };
 
         // 循环添加 ImageView 到相应的容器中
@@ -966,7 +977,7 @@ namespace OHOS
             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "batteryLabel new fail");
             return nullptr;
         }
-        batteryLabel->SetPosition(batteryimage->GetX() + 35, (group1->GetHeight() - 14) / 2-2, 32, 30);
+        batteryLabel->SetPosition(batteryimage->GetX() + 35, (group1->GetHeight() - 14) / 2-1, 32, 30);
         batteryLabel->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 15);
         // 先创建黑色电量组件(作为背景)
         batteryLabelBlack = new UILabel();
@@ -975,7 +986,7 @@ namespace OHOS
             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "batteryLabelBlack new fail");
             return nullptr;
         }
-        batteryLabelBlack->SetPosition(batteryimage->GetX() + 37, (group1->GetHeight() - 14) / 2 , 32, 30); // 位置偏移+2
+        batteryLabelBlack->SetPosition(batteryimage->GetX() + 36, (group1->GetHeight() - 14) / 2 , 32, 30); // 位置偏移+2
         batteryLabelBlack->SetFont(DEFAULT_VECTOR_FONT_FILENAME, 15);
         batteryLabelBlack->SetText("100");
         batteryLabelBlack->SetStyle(STYLE_TEXT_COLOR, Color::Black().full); // 黑色
index 7d6c9f8..144bfdc 100644 (file)
@@ -35,6 +35,7 @@
 #include "graphic_service_wrapper.h"
 #include "cJSON.h"
 #include "font/ui_font.h"
+#include "ln_api.h"
  #define JUHEPINGTAI 0
  #if JUHEPINGTAI
  #include "websocket_server_manager.h"
          printf("  eyesColor_ = %s", eyesColor_.c_str());
          printf("  hairStyle_ = %s", hairStyle_.c_str());
          printf("  screenImageAsEmoji_ = %d", screenImageAsEmoji_);
+         
+         // 初始化对话状态显示变量
+         m_currentExpression = " ";
+         m_currentStatusText = "发呆中...";
      }
      
      ThunderBirdModel::~ThunderBirdModel() 
         WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "获取对话文本: %s", m_currentTimeStr.c_str());
          return m_currentTimeStr;
      }
+     /**
+     * @brief 过滤字符串中无法显示的文字(使用GetGlyphPathData接口)
+     * @param input_str 输入字符串
+     * @param output_str 输出字符串缓冲区
+     * @param max_len 输出缓冲区最大长度
+     * @return 过滤后的字符串长度,-1表示失败
+     */
      static int32_t chat_filter_unsupported_chars(const char *input_str, char *output_str, uint32_t max_len)
      {
          if (input_str == NULL || output_str == NULL || max_len == 0)
             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "设置对话文本: textId is null");
             return;
         }
-        if(ThunderBirdDialogueView::GetInstance())
+         // 添加文本内容
+         m_currentTimeStr = textId;
+         WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "设置对话文本: %s", m_currentTimeStr.c_str());
+         int16_t currentView = ThunderBirdMainView::GetInstance()->GetCurrentView();
+         int16_t currentSubView = ThunderBirdMainView::GetInstance()->GetCurrentSubView();
+        if(ThunderBirdDialogueView::GetInstance() && currentSubView == ThunderBirdDialogueView::THUNDERBIRD_DIALOGUEVIEW_SPEAKING)
             ThunderBirdDialogueView::GetInstance()->UpdateDialogueText(m_currentTimeStr.c_str());
-        if(ThunderBirdLullabyView::GetInstance())
+        if(ThunderBirdLullabyView::GetInstance() && currentSubView == ThunderBirdLullabyView::THUNDERBIRD_LULLABYVIEW_4)
             ThunderBirdLullabyView::GetInstance()->UpdateLullabyText(m_currentTimeStr.c_str());
-        //清除录音内容
+            //清除录音内容
         ClearTextStr();
-        
-        // 添加文本内容
-        m_currentTimeStr = textId;
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "设置对话文本: %s", m_currentTimeStr.c_str());
      }
+       
      
      void ThunderBirdModel::ClearTextStr()
      {
                 // 计数完成,停止定时器
                 m_countUpActive = false;
                 WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Count up timer completed: %d/%d", m_countUpValue, m_countUpTarget);
+                
+                // 检查是否是聆听界面超时,需要自动跳转到说话界面
+                ThunderBirdMainView *view = ThunderBirdMainView::GetInstance();
+                if (view) {
+                    int16_t currentView = view->GetCurrentView();
+                    int16_t currentSubView = view->GetCurrentSubView();
+                    
+                    if (currentView == THUNDERBIRD_DIALOGUEVIEW && 
+                        currentSubView == ThunderBirdDialogueView::THUNDERBIRD_DIALOGUEVIEW_LISTENING) {
+                        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "聆听界面超时,自动跳转到说话界面");
+                        view->ChangeView(currentView, THUNDERBIRD_DIALOGUEVIEW, ThunderBirdDialogueView::THUNDERBIRD_DIALOGUEVIEW_SPEAKING);
+                        ln_ws_end_audio_chat();
+                    }
+                }
             } else {
                 // 增加计数值
                 m_countUpValue++;
                 
                 // 更新UI显示
-                ThunderBirdLullabyView::GetInstance()->UpdateTimeText(m_countUpValue, m_countUpTarget);
+                //ThunderBirdLullabyView::GetInstance()->UpdateTimeText(m_countUpValue, m_countUpTarget);
                 WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "Count up: %d/%d", m_countUpValue, m_countUpTarget);
             }
         }
             SwitchHair(hairStyle, hairColor);
         }
 
+        if(screenImageAsEmoji == 0)
+        {
+            //关闭屏保模式
+            ThunderBirdMainView::GetInstance()->CloseScreenImageModel();
+        }
+        else
+        {
+            //打开屏保模式
+            ThunderBirdMainView::GetInstance()->OpenScreenImageModel();
+        }
+
         // SaveCharacterConfig(characterId, characterName, eyesShape, hairColor, eyesColor, hairStyle, screenImageAsEmoji);
     }
     //开机读取表情
             ThunderBirdDialogueView::GetInstance()->AudioPlaybackEnd();
         }
     }
+    
+    // 设置当前表情状态
+    void ThunderBirdModel::SetCurrentExpression(const std::string& expression)
+    {
+        m_currentExpression = expression;
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::SetCurrentExpression: %s", expression.c_str());
+    }
+    
+    // 设置当前状态文本
+    void ThunderBirdModel::SetCurrentStatusText(const std::string& statusText)
+    {
+        m_currentStatusText = statusText;
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::SetCurrentStatusText: %s", statusText.c_str());
+    }
+    
+    // 同时设置当前表情和状态文本
+    void ThunderBirdModel::SetCurrentExpressionAndStatus()
+    {
+        int currentView = ThunderBirdMainView::GetInstance()->GetCurrentView();
+        int currentSubView = ThunderBirdMainView::GetInstance()->GetCurrentSubView();
+        //切换状态文本
+        //亮屏
+        uapi_set_screen_on_api(); // 亮屏
+        if(currentView == THUNDERBIRD_DIALOGUEVIEW && currentSubView == ThunderBirdDialogueView::THUNDERBIRD_DIALOGUEVIEW_STATUS_SHOW)
+        {
+            ThunderBirdDialogueView::GetInstance()->UpdateDialogueText(m_currentStatusText.c_str());
+        }
+        //切换表情
+        //不为屏保模式
+        if(screenImageAsEmoji_ == false)
+        {
+            //获取当前角色配置
+            
+            std::string expressionPath = "/user/res/video/Default/" + eyesShape_ + "/" + eyesColor_ + "/" + m_currentExpression + ".mp4";
+            //std::string expressionPath = "/user/res/video/Default/" + m_currentExpression + ".mp4";
+            SwitchExpressionVideo(expressionPath.c_str());
+        }
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ThunderBirdModel::SetCurrentExpressionAndStatus: expression=%s, statusText=%s", 
+            m_currentExpression.c_str(), m_currentStatusText.c_str());
+    }
+    
+    // 获取当前表情状态
+    std::string ThunderBirdModel::GetCurrentExpression() const
+    {
+        return m_currentExpression;
+    }
+    
+    // 获取当前状态文本
+    std::string ThunderBirdModel::GetCurrentStatusText() const
+    {
+        return m_currentStatusText;
+    }
 
     int ThunderBirdModel::GetDownloadFile()
     {
index 66f5a58..b8a17d5 100644 (file)
@@ -176,32 +176,32 @@ namespace OHOS
                 //更新二维码
                 UpdateQrcodeIfValid();
             }
-            //如果是在对话界面 需要根据对话状态去拿对话数据进行更新
-            if(currentView == THUNDERBIRD_DIALOGUEVIEW && currentSubView == ThunderBirdDialogueView::THUNDERBIRD_DIALOGUEVIEW_SPEAKING)
-            {
-                //每一个界面都需要判断是否存在
-                if(ThunderBirdDialogueView::GetInstance() != nullptr)
-                {
-                    //判断是否为开始对话 如果是开始对话 则更新对话数据
-                    if(ThunderBirdModel::GetInstance()->GetConversationStatus() == 1){
-                        //更新对话数据
-                        std::string dialogueText = ThunderBirdModel::GetInstance()->GetTextStr();  
-                        //只有一行 是拼接 还是直接覆盖?
-                        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "UpdateDialogueText:%s\n",dialogueText.c_str());
-                        ThunderBirdDialogueView::GetInstance()->UpdateDialogueText(dialogueText.c_str());
-                    }
-                }
-            }
-            //如果是哄睡界面 需要更新哄睡文本
-            if(currentView == THUNDERBIRD_LULLABYVIEW && currentSubView == ThunderBirdLullabyView::THUNDERBIRD_LULLABYVIEW_4)
-            {
-                if(ThunderBirdLullabyView::GetInstance() != nullptr)
-                {
-                    std::string lullabyText = ThunderBirdModel::GetInstance()->GetTextStr();
-                    WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "UpdateLullabyText:%s\n",lullabyText.c_str());
-                    ThunderBirdLullabyView::GetInstance()->UpdateLullabyText(lullabyText.c_str());
-                }
-            }
+            // //如果是在对话界面 需要根据对话状态去拿对话数据进行更新
+            // if(currentView == THUNDERBIRD_DIALOGUEVIEW && currentSubView == ThunderBirdDialogueView::THUNDERBIRD_DIALOGUEVIEW_SPEAKING)
+            // {
+            //     //每一个界面都需要判断是否存在
+            //     if(ThunderBirdDialogueView::GetInstance() != nullptr)
+            //     {
+            //         //判断是否为开始对话 如果是开始对话 则更新对话数据
+            //         // if(ThunderBirdModel::GetInstance()->GetConversationStatus() == 1){
+            //             //更新对话数据
+            //             std::string dialogueText = ThunderBirdModel::GetInstance()->GetTextStr();  
+            //             //只有一行 是拼接 还是直接覆盖?
+            //             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "UpdateDialogueText:%s\n",dialogueText.c_str());
+            //             ThunderBirdDialogueView::GetInstance()->UpdateDialogueText(dialogueText.c_str());
+                    
+            //     }
+            // }
+            // //如果是哄睡界面 需要更新哄睡文本
+            // if(currentView == THUNDERBIRD_LULLABYVIEW && currentSubView == ThunderBirdLullabyView::THUNDERBIRD_LULLABYVIEW_4)
+            // {
+            //     if(ThunderBirdLullabyView::GetInstance() != nullptr)
+            //     {
+            //         std::string lullabyText = ThunderBirdModel::GetInstance()->GetTextStr();
+            //         WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "UpdateLullabyText:%s\n",lullabyText.c_str());
+            //         ThunderBirdLullabyView::GetInstance()->UpdateLullabyText(lullabyText.c_str());
+            //     }
+            // }
         }
     }
 
@@ -350,6 +350,8 @@ namespace OHOS
 
         if (currentView == THUNDERBIRD_DIALOGUEVIEW && currentSubView == ThunderBirdDialogueView::THUNDERBIRD_DIALOGUEVIEW_LISTENING) {
             // 停止录音并发送
+            // 停止聆听超时定时器
+            ThunderBirdModel::GetInstance()->StopCountUpTimer();
             ThunderBirdMainView::GetInstance()->ChangeView(currentView, THUNDERBIRD_DIALOGUEVIEW, ThunderBirdDialogueView::THUNDERBIRD_DIALOGUEVIEW_SPEAKING);
             ln_ws_end_audio_chat();
         } else {
@@ -652,6 +654,10 @@ namespace OHOS
             else
             {
                 ThunderBirdMainView::GetInstance()->ChangeView(currentView, THUNDERBIRD_DIALOGUEVIEW, ThunderBirdDialogueView::THUNDERBIRD_DIALOGUEVIEW_STATUS_SHOW);
+                if(currentSubView == ThunderBirdDialogueView::THUNDERBIRD_DIALOGUEVIEW_LISTENING)
+                {
+                    ThunderBirdModel::GetInstance()->StopCountUpTimer();
+                }
                 ln_ws_end_audio_chat();//结束对话
                 isDialogueing = false;
             }