Ai语音修改
authorluozheng <1732036298@qq.com>
Wed, 3 Jul 2024 10:39:59 +0000 (18:39 +0800)
committerSnickerSun <snickersun@163.com>
Fri, 5 Jul 2024 02:16:45 +0000 (10:16 +0800)
16 files changed:
code/sdk/application/wearable/fd230app/nativeui/aivoice/include/AiVoiceModel.h
code/sdk/application/wearable/fd230app/nativeui/aivoice/include/AiVoicePresenter.h
code/sdk/application/wearable/fd230app/nativeui/aivoice/include/AivoiceChatContentListAdapter.h [new file with mode: 0644]
code/sdk/application/wearable/fd230app/nativeui/aivoice/include/AivoiceChatContentListItemView.h [new file with mode: 0644]
code/sdk/application/wearable/fd230app/nativeui/aivoice/include/ChatContentItem.h [new file with mode: 0644]
code/sdk/application/wearable/fd230app/nativeui/aivoice/src/AiVoiceModel.cpp
code/sdk/application/wearable/fd230app/nativeui/aivoice/src/AiVoicePresenter.cpp
code/sdk/application/wearable/fd230app/nativeui/aivoice/src/AiVoiceView.cpp
code/sdk/application/wearable/fd230app/nativeui/aivoice/src/AivoiceChatContentListAdapter.cpp [new file with mode: 0644]
code/sdk/application/wearable/fd230app/nativeui/aivoice/src/AivoiceChatContentListItemView.cpp [new file with mode: 0644]
code/sdk/application/wearable/fd230app/nativeui/aivoice/src/AivoiceConnectTimeoutView.cpp
code/sdk/application/wearable/fd230app/nativeui/aivoice/src/AivoiceListeningView.cpp
code/sdk/application/wearable/fd230app/nativeui/aivoice/src/AivoiceMobileDataFailedStartView.cpp
code/sdk/application/wearable/fd230app/nativeui/aivoice/src/AivoiceReturnResultTextView.cpp
code/sdk/application/wearable/fd230app/nativeui/aivoice/src/AivoiceThinkingView.cpp
code/sdk/application/wearable/service/ble_service/blemoder/bletest.cpp

index c77fc93..248a498 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * @Author: luozheng 1732036298@qq.com
  * @Date: 2024-06-20 15:14:43
- * @LastEditors: luozheng 1732036298@qq.com
- * @LastEditTime: 2024-06-26 17:39:41
+ * @LastEditors: SnickerSun snickersun@163.com
+ * @LastEditTime: 2024-07-05 10:13:59
  * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/aivoice/include/AiVoiceModel.h
  */
 #ifndef AI_VOICE_MODEL_H
@@ -12,6 +12,7 @@
 #include "string"
 #include "iostream"
 #include "string"
+#include "ChatContentItem.h"
 namespace OHOS
 {
     class AiVoiceModel
@@ -25,12 +26,21 @@ namespace OHOS
         bool GetMobileDataIsOpen(void);
         bool GetAiVoiceConnectStatus(void);
 
+        bool InitchatContentItems(void);
+        bool AddChatContentToItemArray(ChatContentItem &item);
+        uint8_t GetChatContentListCount(void);
+
+        void CheckFileAndSendAIIsReady();
+        bool GetEntryTimeoutFlag(void);
+        void SetEntryTimeoutFlag(bool flag);
+        void StatusResume(void);
+        bool UpdateUserQuestionStr(void);
+        bool UpdateAiAnswerStr(void);
         std::string GetUserQuestionStr(void);
         void SetUserQuestionStr(std::string str);
-
-        std::string GetAiAnswerStrStr(void);
-        void SetaiAnswerStrStr(std::string str);
-
+        std::string GetAiAnswerStr(void);
+        void SetAiAnswerStrStr(std::string str);
+        void ClearQuestionAndAiAnswerStr(void);
         std::string GetAIAudioPath(void);
 
         void StartListenAndRecordingUserQuestion(void);
@@ -45,9 +55,12 @@ namespace OHOS
         AiVoiceModel(const AiVoiceModel &) = delete;
         AiVoiceModel &operator=(const AiVoiceModel &) = delete;
         std::string AIAIAudioPath = "/user/userdata/AiRecording/AIAudio.pcm"; // ai录音的文件名
-
-        std::string userQuestionStr; // 存储用户提出的问题
-        std::string aiAnswerStr;     // 存储ai回答的问题
+        std::string userQuestionStr;                                          // 存储用户提出的问题
+        std::string aiAnswerStr;                                              // 存储ai回答的问题
+        bool entryTimeoutFlag{false};                                         // 进入超时界面标志
+        uint8_t ChatContentListCount{0};                                      // 列表数量
+        static const uint16_t MaxChatContentListCount = 2;                    // 对话列表最大数量
+        ChatContentItem chatTtems[MaxChatContentListCount] = {0, "", false};
     };
 }
 
index bddff30..e84c7e8 100644 (file)
@@ -2,7 +2,7 @@
  * @Author: luozheng 1732036298@qq.com
  * @Date: 2024-06-20 14:44:22
  * @LastEditors: luozheng 1732036298@qq.com
- * @LastEditTime: 2024-06-25 17:39:55
+ * @LastEditTime: 2024-07-02 18:58:24
  * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/aivoice/include/AiVoicePresenter.h
  */
 #ifndef AI_VOICE_PRESENTER_H
@@ -18,7 +18,8 @@ namespace OHOS
     class AiVoicePresenter : public Presenter<AiVoiceView>,
                              public UIView::OnClickListener,
                              public UIView::OnDragListener,
-                             public RootView::OnKeyActListener
+                             public RootView::OnKeyActListener,
+                             public UIView::OnTouchListener
     {
     public:
         AiVoicePresenter();
@@ -31,9 +32,11 @@ namespace OHOS
         void OnStop() override;
 
         bool JumpToReturnResultTextView(void);
+        bool ChangeViewAndLogicOperator(int16_t hideView, int16_t showView);
 
     private:
         bool OnClick(UIView &view, const ClickEvent &event) override;
+        bool OnRelease(UIView &view, const ReleaseEvent &event) override;
         bool OnDrag(UIView &view, const DragEvent &event) override;
         bool OnDragEnd(UIView &view, const DragEvent &event) override;
         bool OnKeyAct(UIView &view, const KeyEvent &event) override; // 增加按键事件
diff --git a/code/sdk/application/wearable/fd230app/nativeui/aivoice/include/AivoiceChatContentListAdapter.h b/code/sdk/application/wearable/fd230app/nativeui/aivoice/include/AivoiceChatContentListAdapter.h
new file mode 100644 (file)
index 0000000..cc1bd10
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * @Author: luozheng 1732036298@qq.com
+ * @Date: 2024-03-28 14:26:55
+ * @LastEditors: luozheng 1732036298@qq.com
+ * @LastEditTime: 2024-07-03 18:34:22
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/language/include/AivoiceChatContentListAdapter.h
+ */
+#ifndef AIVOICE_CHAT_CONTENT_LIST_ADAPTER_H
+#define AIVOICE_CHAT_CONTENT_LIST_ADAPTER_H
+
+#include "components/abstract_adapter.h"
+#include "components/ui_label_button_ext.h"
+#include "components/ui_list.h"
+#include "language/LanguageInit.h"
+#include "UiConfig.h"
+#include <list>
+#include "aivoice/include/AivoiceChatContentListItemView.h"
+#include "iostream"
+
+namespace OHOS
+{
+
+    class AivoiceChatContentListAdapter : public AbstractAdapter
+    {
+    public:
+        AivoiceChatContentListAdapter();
+        ~AivoiceChatContentListAdapter();
+
+        void SetData(std::list<ChatContentItem> &data);
+        void ClearData(void);
+        std::list<ChatContentItem> &GetChatContentItem();
+        virtual uint16_t GetCount(void) override;
+        virtual UIView *GetView(UIView *inView, int16_t index) override;
+        void AddListItem(const ChatContentItem &item);
+        void SetItemClickListener(UIView::OnClickListener *itemclicklistener);
+        void calculateChatContentItemViewHeight(std::string text, bool flag);
+
+    private:
+        std::list<ChatContentItem> listData;
+        UIView::OnClickListener *itemClickListener{nullptr};
+        int16_t itemViewHeight{0};
+        bool aiAnswerFalg{false};
+    };
+
+}
+
+#endif
diff --git a/code/sdk/application/wearable/fd230app/nativeui/aivoice/include/AivoiceChatContentListItemView.h b/code/sdk/application/wearable/fd230app/nativeui/aivoice/include/AivoiceChatContentListItemView.h
new file mode 100644 (file)
index 0000000..0297f9a
--- /dev/null
@@ -0,0 +1,34 @@
+/*
+ * @Author: luozheng 1732036298@qq.com
+ * @Date: 2024-06-29 17:26:19
+ * @LastEditors: luozheng 1732036298@qq.com
+ * @LastEditTime: 2024-07-02 09:48:43
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/aivoice/include/AivoiceChatContentListItemView.h
+ */
+
+#ifndef AIVOICE_CHAT_CONTENT_LIST_ITEM_VIEW_H
+#define AIVOICE_CHAT_CONTENT_LIST_ITEM_VIEW_H
+
+#include "components/ui_view_group.h"
+#include "components/ui_label_ext.h"
+#include "View.h"
+#include "iostream"
+#include "ChatContentItem.h"
+namespace OHOS
+{
+    class AivoiceChatContentListItemView : public UIViewGroup
+    {
+    public:
+        AivoiceChatContentListItemView(int16_t viewHeight, bool isAiAnswerFalg);
+        ~AivoiceChatContentListItemView();
+        void SetItemInfo(const ChatContentItem itemInfo);
+        void SetUpChild();
+
+    private:
+        UILabelExt chatContentLabel;
+        int16_t m_viewHeight{250};
+        bool m_isAiAnswerFalg{false};
+    };
+}
+
+#endif
diff --git a/code/sdk/application/wearable/fd230app/nativeui/aivoice/include/ChatContentItem.h b/code/sdk/application/wearable/fd230app/nativeui/aivoice/include/ChatContentItem.h
new file mode 100644 (file)
index 0000000..9222a2d
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * @Author: luozheng 1732036298@qq.com
+ * @Date: 2024-07-02 09:46:24
+ * @LastEditors: luozheng 1732036298@qq.com
+ * @LastEditTime: 2024-07-02 09:48:05
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/aivoice/include/ChatContentItem.h
+ */
+#ifndef CHAT_CONTENT_ITEM_H
+#define CHAT_CONTENT_ITEM_H
+
+#include <iostream>
+#include "string"
+namespace OHOS
+{
+    typedef struct
+    {
+        int index;
+        std::string text;
+        bool isAiAnswer;
+    } ChatContentItem;
+}
+#endif
\ No newline at end of file
index 2f14a16..8e5d390 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * @Author: luozheng 1732036298@qq.com
  * @Date: 2024-06-20 15:14:50
- * @LastEditors: luozheng 1732036298@qq.com
- * @LastEditTime: 2024-06-26 17:39:53
+ * @LastEditors: SnickerSun snickersun@163.com
+ * @LastEditTime: 2024-07-05 10:13:25
  * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/aivoice/src/AiVoiceModel.cpp
  */
 #include "aivoice/include/AiVoiceModel.h"
 #include <ohos_types.h>
 #include <service/graphic_service.h>
 #include <iostream>
+#include "uiservice/include/ui_service.h"
+#include <custom_utils.h>
+#include <bleEvent.h>
 namespace OHOS
 {
+    // 声明定时器变量
+    static osTimerId_t g_timer = NULL;
+    static constexpr uint16_t THIRTY_TIME = 30; // 30秒超时
+    static int Time = THIRTY_TIME;
+
     AiVoiceModel::AiVoiceModel() {}
 
     AiVoiceModel::~AiVoiceModel() {}
@@ -42,6 +50,7 @@ namespace OHOS
         return true;
     }
 
+    // 如果文件不存在就创建
     bool AiVoiceModel::CreateIfNotExists()
     {
         WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceModel::CreateIfNotExists");
@@ -68,6 +77,35 @@ namespace OHOS
         return true;
     }
 
+    uint8_t AiVoiceModel::GetChatContentListCount(void)
+    {
+        return ChatContentListCount;
+    }
+
+    bool AiVoiceModel::AddChatContentToItemArray(ChatContentItem &item)
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceModel::InitchatContentItems");
+        AivoiceReturnResultTextView *p_AivoiceReturnResultTextView = AivoiceReturnResultTextView::GetInstance();
+        if (p_AivoiceReturnResultTextView == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceReturnResultTextView::GetInstance fail!! ");
+            return false;
+        }
+        if (ChatContentListCount < MaxChatContentListCount)
+        {
+            chatTtems[ChatContentListCount].index = item.index;
+            chatTtems[ChatContentListCount].text = item.text;
+            chatTtems[ChatContentListCount].isAiAnswer = item.isAiAnswer;
+            ChatContentListCount += 1;
+        }
+        else
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ChatContentListCount out of bounds!!");
+            return false;
+        }
+        return true;
+    }
+
     // 获取蓝牙是否打开
     bool AiVoiceModel::GetBluetoothIsOpen(void)
     {
@@ -86,33 +124,130 @@ namespace OHOS
         return true;
     }
 
+    /*初始化历史对话数据*/
+    bool AiVoiceModel::InitchatContentItems(void)
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceModel::UpdateUserQuestionAndAiAnswerStr");
+        AivoiceReturnResultTextView *p_AivoiceReturnResultTextView = AivoiceReturnResultTextView::GetInstance();
+        if (p_AivoiceReturnResultTextView == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceReturnResultTextView::GetInstance fail!! ");
+            return false;
+        }
+        /* -------------------------------------------------------------------------- */
+        ChatContentItem UserQuestionStrItem;
+        UserQuestionStrItem.index = GetChatContentListCount();
+        UserQuestionStrItem.text = GetUserQuestionStr();
+        UserQuestionStrItem.isAiAnswer = false;
+        AddChatContentToItemArray(UserQuestionStrItem);
+        /* -------------------------------------------------------------------------- */
+        ChatContentItem AiAnswerStrItem;
+        AiAnswerStrItem.index = GetChatContentListCount();
+        AiAnswerStrItem.text = GetAiAnswerStr();
+        AiAnswerStrItem.isAiAnswer = true;
+        AddChatContentToItemArray(AiAnswerStrItem);
+        /* -------------------------------------------------------------------------- */
+        for (uint8_t i = 0; i < ChatContentListCount; i++)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "chatTtems[%d]", i);
+            p_AivoiceReturnResultTextView->AddChatContentToList(chatTtems[i]);
+        }
+        /* -------------------------------------------------------------------------- */
+        if (p_AivoiceReturnResultTextView->GetAivoiceChatContentListAdapter() != nullptr && p_AivoiceReturnResultTextView->GetChatContentList() != nullptr)
+        {
+            p_AivoiceReturnResultTextView->GetChatContentList()->SetAdapter(p_AivoiceReturnResultTextView->GetAivoiceChatContentListAdapter());
+            p_AivoiceReturnResultTextView->GetChatContentList()->RefreshList();
+        }
+        else
+        {
+            return false;
+        }
+        return true;
+    }
+
+    /*更新用户问题字符串*/
+    bool AiVoiceModel::UpdateUserQuestionStr(void)
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceModel::UpdateUserQuestionStr");
+
+        return true;
+    }
+
+    /*更新Ai答案字符串*/
+    bool AiVoiceModel::UpdateAiAnswerStr(void)
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceModel::UpdateAiAnswerStr");
+        int index = GetChatContentListCount() - 1;
+        if (index < 0)
+        {
+            index = 0;
+        }
+        chatTtems[index].index = index;
+        chatTtems[index].text = GetAiAnswerStr();
+        chatTtems[index].isAiAnswer = true;
+
+        AivoiceReturnResultTextView *p_AivoiceReturnResultTextView = AivoiceReturnResultTextView::GetInstance();
+        if (p_AivoiceReturnResultTextView == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceReturnResultTextView::GetInstance fail!! ");
+            return false;
+        }
+
+        if (p_AivoiceReturnResultTextView->GetAivoiceChatContentListAdapter() != nullptr)
+        {
+            if (!p_AivoiceReturnResultTextView->GetAivoiceChatContentListAdapter()->GetChatContentItem().empty())
+            {
+                if (p_AivoiceReturnResultTextView->GetAivoiceChatContentListAdapter()->GetChatContentItem().back().isAiAnswer == true) // 如果是ai答案
+                {
+                    p_AivoiceReturnResultTextView->GetAivoiceChatContentListAdapter()->GetChatContentItem().pop_back();
+                }
+            }
+            p_AivoiceReturnResultTextView->GetAivoiceChatContentListAdapter()->GetChatContentItem().push_back(chatTtems[index]);
+            p_AivoiceReturnResultTextView->GetChatContentList()->RefreshList();
+        }
+
+        return true;
+    }
+
+    /*获取用户问题的字符串*/
     std::string AiVoiceModel::GetUserQuestionStr(void)
     {
         // userQuestionStr = "写一篇100字文章";
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "userQuestionStr:\n", userQuestionStr.c_str());
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GetUserQuestionStr:%s\n", userQuestionStr.c_str());
         return userQuestionStr;
     }
 
+    /*设置用户问题的字符串*/
     void AiVoiceModel::SetUserQuestionStr(std::string str)
     {
         userQuestionStr = str;
     }
 
-    std::string AiVoiceModel::GetAiAnswerStrStr(void)
+    /*获取Ai回答的字符串*/
+    std::string AiVoiceModel::GetAiAnswerStr(void)
     {
         // aiAnswerStr = "春风化雨,时光荏苒。百年之内,生命如白驹过隙,转瞬即逝。唯有心存善念,用爱化解芥蒂,用智慧建构未来,才是人生的真正意义。让我们携手共进,用每一分时光去关爱他人,用每一滴汗水去创造奇迹,用每一个眼神去传递温暖。让这个世界因我们的存在而变得更加美好。生命短暂,但只要我们怀着虔诚的心,坚韧前行,我们就一定能在有限的时光里留下无限的可能。";
-        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "aiAnswerStr:\n", aiAnswerStr.c_str());
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "GetAiAnswerStr:%s\n", aiAnswerStr.c_str());
         return aiAnswerStr;
     }
 
-    void AiVoiceModel::SetaiAnswerStrStr(std::string str)
+    /*设置Ai回答的字符串*/
+    void AiVoiceModel::SetAiAnswerStrStr(std::string str)
     {
-        aiAnswerStr = str;
+        SendMsgToUIService(UI_AI_RESPONSE_USERDATA, 0, nullptr, 0);
+        aiAnswerStr += str;
+    }
+
+    /*清空上次用户问题和Ai回答字符串*/
+    void AiVoiceModel::ClearQuestionAndAiAnswerStr(void)
+    {
+        userQuestionStr = "";
+        aiAnswerStr = "";
     }
 
     std::string AiVoiceModel::GetAIAudioPath(void)
     {
-        CreateIfNotExists();
+        // CreateIfNotExists();
         return AIAIAudioPath;
     }
 
@@ -129,7 +264,7 @@ namespace OHOS
     // 开始聆听并录取用户问题
     void AiVoiceModel::StartListenAndRecordingUserQuestion(void)
     {
-        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceModel::RecordingUserQuestion");
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceModel::StartListenAndRecordingUserQuestion");
         AiVoiceView *view_ = AiVoiceView::GetInstance();
         if (view_ == nullptr)
         {
@@ -139,50 +274,113 @@ namespace OHOS
         if ((view_->GetAiVoiceScrollView(AIVOICE_LISTENING_VIEWID) != nullptr) &&
             (view_->GetAiVoiceScrollView(AIVOICE_LISTENING_VIEWID)->IsVisible()))
         {
-            const char *defaultArgs[6] = {"01", "pcm", "16000", "1", "16", AiVoiceModel::GetInstance().GetAIAudioPath().c_str()};
+            std::string audioPath = AiVoiceModel::GetInstance().GetAIAudioPath();
+            if (uapi_delete_files(audioPath.c_str())) // 先删除文件
+            {
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "uapi_delete_files,%s", audioPath.c_str());
+            }
+            else
+            {
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "uapi_delete_files fail!!");
+            }
+            const char *defaultArgs[6] = {"01", "pcm", "16000", "1", "16", audioPath.c_str()};
             AudioCaptureSample(6, (const char **)defaultArgs);
         }
-        // 开启定时器
-        AIVoice_StartTimer();
-
         return;
     }
 
     // 停止聆听用户问题
     void AiVoiceModel::StopListenAndRecordingUserQuestion(void)
     {
-        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoiceModel::StopListenAndRecordingUserQuestion");
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceModel::StopListenAndRecordingUserQuestion");
         int32_t argc = 1;
         uint8_t *argv = (uint8_t *)"stop";
         AudioCaptureSample(argc, (const char **)&argv);
+        return;
+    }
+
+    /*检查录音文件是否存在并发送语音准备操作*/
+    void AiVoiceModel::CheckFileAndSendAIIsReady(void)
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceModel::CheckFileAndSendAIIsReady");
+        const std::string &filePath = AIAIAudioPath;
+        FILE *file = fopen(filePath.c_str(), "r");
+        if (file != nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "File already exists: %s", filePath.c_str());
+
+            fseek(file, 0, SEEK_END);
+            long size = ftell(file);
+            fseek(file, 0, SEEK_SET);
+            if (size != 0)
+            {
+                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "size = %ld", size);
+                send_AI_is_ready(0);
+                ClearQuestionAndAiAnswerStr(); // 清空上次用户问题和Ai回答字符串
+            }
+            fclose(file);
+        }
+        else
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "File does not exist: %s", filePath.c_str());
+            // Handle the case where the file doesn't exist, if needed
+        }
+    }
+
+    bool AiVoiceModel::GetEntryTimeoutFlag(void)
+    {
+        return entryTimeoutFlag;
+    }
+
+    void AiVoiceModel::SetEntryTimeoutFlag(bool flag)
+    {
+        entryTimeoutFlag = flag;
+    }
+
+    void AiVoiceModel::StatusResume(void)
+    {
+        Time = THIRTY_TIME;
+
+        for (int i = 0; i < ChatContentListCount; i++)
+        {
+            chatTtems[i].index = 0;
+            chatTtems[i].text = "";
+            chatTtems[i].isAiAnswer = false;
+        }
+        ChatContentListCount = 0;
+        
+        entryTimeoutFlag = false;
+        AIVoice_StopTimer();
+        ClearQuestionAndAiAnswerStr();
+        StopListenAndRecordingUserQuestion();
     }
 
     /* -------------------------------------------------------------------------- */
-    // 声明定时器变量
-    static osTimerId_t g_timer = NULL;
-    static int Time = 15;
-    static constexpr int ONE_MINUTE = 60; // 一分钟
-    static bool START_FLAG = false;
     /*定时器到期时的处理*/
     static void AIVoice_TimerCallbackProc(int data)
     {
-        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AIVoice_TimerCallbackProc,Time = %d", Time);
-        Time--;
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AIVoice_TimerCallbackProc,Time = %d", Time);
+        Time -= 1;
         AiVoiceView *view_ = AiVoiceView::GetInstance();
         if (view_ == nullptr)
         {
             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoiceView::GetInstance fail!!");
             return;
         }
-        if (Time <= 0)
+
+        AiVoicePresenter *p_AiVoicePresenter = AiVoicePresenter::GetInstance();
+        if (p_AiVoicePresenter == nullptr)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoicePresenter::GetInstance fail!!");
+            return;
+        }
+
+        if (Time < 0) // 如果思考时间超时30s,进入连接超时界面
         {
-            if ((view_->GetAiVoiceScrollView(AIVOICE_LISTENING_VIEWID) != nullptr) &&
-                (view_->GetAiVoiceScrollView(AIVOICE_LISTENING_VIEWID)->IsVisible()))
+            if ((view_->GetAiVoiceScrollView(AIVOICE_THINKING_VIEWID) != nullptr) &&
+                (view_->GetAiVoiceScrollView(AIVOICE_THINKING_VIEWID)->IsVisible()))
             {
-                if (AiVoiceModel::GetInstance().GetAiVoiceConnectStatus() == true)
-                    view_->ChangeView(AIVOICE_LISTENING_VIEWID, AIVOICE_THINKING_VIEWID);
-                else
-                    view_->ChangeView(AIVOICE_LISTENING_VIEWID, AIVOICE_CONNECT_TIMEOUT_VIEWID);
+                p_AiVoicePresenter->ChangeViewAndLogicOperator(AIVOICE_THINKING_VIEWID, AIVOICE_CONNECT_TIMEOUT_VIEWID);
             }
             AiVoiceModel::GetInstance().AIVoice_StopTimer();
         }
@@ -255,6 +453,7 @@ namespace OHOS
                 WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "osTimerDelete failed, ret = %lx!!", ret);
             }
             g_timer = NULL;
+            Time = THIRTY_TIME;
         }
     }
 }
index 7be738e..f8a593d 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * @Author: luozheng 1732036298@qq.com
  * @Date: 2024-06-20 15:11:17
- * @LastEditors: luozheng 1732036298@qq.com
- * @LastEditTime: 2024-06-26 17:40:11
+ * @LastEditors: SnickerSun snickersun@163.com
+ * @LastEditTime: 2024-07-05 10:12:51
  * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/aivoice/src/AiVoicePresenter.cpp
  */
 #include "AppViewIDs.h"
@@ -18,7 +18,8 @@
 #include <unordered_map> // For std::unordered_map
 #include <string>        // For std::string
 #include <unordered_map> // For std::unordered_map
-
+#include "bleEvent.h"
+#include <unistd.h>
 namespace OHOS
 {
 
@@ -47,7 +48,6 @@ namespace OHOS
         WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoicePresenter::OnStart");
         Presenter<AiVoiceView>::OnStart();
         ScreenAlwaysOnCtr(OPEN_SCREEN_ALWAYS_ON);
-        ScreenAlwaysOnCtr(OPEN_SCREEN_ALWAYS_ON);
     }
 
     // 页面已经展示后的调用逻辑
@@ -74,60 +74,237 @@ namespace OHOS
         WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoicePresenter::OnStop");
         Presenter<AiVoiceView>::OnStop();
         ScreenAlwaysOnCtr(CANCEL_SCREEN_ALWAYS_ON);
-        AiVoiceModel::GetInstance().AIVoice_StopTimer();
+        model->StatusResume();
     }
 
+    /*调转到返回结果界面*/
     bool AiVoicePresenter::JumpToReturnResultTextView(void)
     {
-        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoicePresenter::JumpToReturnResultTextView");
-        if (view_ == nullptr)
-        {
-            return false;
-        }
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoicePresenter::JumpToReturnResultTextView");
         if (view_->GetAiVoiceScrollView(AIVOICE_THINKING_VIEWID) != nullptr && view_->GetAiVoiceScrollView(AIVOICE_THINKING_VIEWID)->IsVisible())
         {
-            view_->ChangeView(AIVOICE_THINKING_VIEWID, AIVOICE_RETURN_RESULT_TEXT_VIEWID); // 思考中界面->返回结果
+            // view_->ChangeView(AIVOICE_THINKING_VIEWID, AIVOICE_RETURN_RESULT_TEXT_VIEWID); // 思考中界面->返回结果
+            ChangeViewAndLogicOperator(AIVOICE_THINKING_VIEWID, AIVOICE_RETURN_RESULT_TEXT_VIEWID);
         }
         else
         {
             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoicePresenter::JumpToReturnResultTextView fail");
+           // return false;
+        }
+        if (!model->UpdateAiAnswerStr())
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "UpdateUserQuestionAndAiAnswerStr fail");
+            return false;
+        }
+        return true;
+    }
+
+#if 0
+    /*切换视图的逻辑操作*/
+    bool AiVoicePresenter::ChangeViewAndLogicOperator(int16_t hideView, int16_t showView)
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoicePresenter::ChangeViewOperator");
+        if (hideView > MAX_AIVOICE_VIEWID)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Overstep ones bounds");
+            return false;
+        }
+        if (hideView == AIVOICE_STARTCHAT_VIEWID && showView == AIVOICE_LISTENING_VIEWID) // 开始对话->聆听中界面
+        {
+            view_->ChangeView(hideView, showView);
+            // 开始聆听并录取用户问题
+            model->StartListenAndRecordingUserQuestion();
+        }
+        else if (hideView == AIVOICE_LISTENING_VIEWID && showView == AIVOICE_THINKING_VIEWID) // 聆听中->思考中界面
+        {
+            // 停止聆听用户问题
+            model->StopListenAndRecordingUserQuestion();
+            model->CheckFileAndSendAIIsReady();
+            view_->ChangeView(hideView, showView);
+            // 在思考中界面开启定时器
+            model->AIVoice_StartTimer();
+        }
+        else if (hideView == AIVOICE_LISTENING_VIEWID && showView == AIVOICE_STARTCHAT_VIEWID) // 聆听中->开始对话界面
+        {
+            view_->ChangeView(hideView, showView);
+            // 停止聆听用户问题
+            model->StopListenAndRecordingUserQuestion();
+        }
+        else if (hideView == AIVOICE_THINKING_VIEWID && showView == AIVOICE_CONNECT_TIMEOUT_VIEWID) // 思考中->连接超时界面
+        {
+            // 停止定时器
+            model->AIVoice_StopTimer();
+            // 设置进入超时界面的标志
+            model->SetEntryTimeoutFlag(true);
+            view_->ChangeView(hideView, showView);
+        }
+        else if (hideView == AIVOICE_THINKING_VIEWID && showView == AIVOICE_RETURN_RESULT_TEXT_VIEWID) // 思考中->返回结果文本界面
+        {
+            // 停止定时器
+            model->AIVoice_StopTimer();
+            view_->ChangeView(hideView, showView);
+        }
+        else if (hideView == AIVOICE_THINKING_VIEWID && showView == AIVOICE_LISTENING_VIEWID) // 思考中->聆听中界面
+        {
+            // 停止定时器
+            model->AIVoice_StopTimer();
+            view_->ChangeView(hideView, showView);
+            // 开始聆听并录取用户问题
+            model->StartListenAndRecordingUserQuestion();
+        }
+        else if (hideView == AIVOICE_CONNECT_TIMEOUT_VIEWID && showView == AIVOICE_LISTENING_VIEWID) // 连接超时界面->聆听中界面
+        {
+            bool flag = model->GetEntryTimeoutFlag();
+            if (flag)
+            {
+                model->StartListenAndRecordingUserQuestion(); // 重新开始录音
+            }
+            view_->ChangeView(hideView, showView);
+        }
+        else if (hideView == AIVOICE_THINKING_VIEWID && showView == AIVOICE_STARTCHAT_VIEWID) // 思考中界面->开始对话界面
+        {
+            // 停止定时器
+            model->AIVoice_StopTimer();
+            view_->ChangeView(hideView, showView);
+        }
+        else if (hideView == AIVOICE_STARTCHAT_VIEWID && showView == AIVOICE_BLUETOOTH_FAILEDSTART_VIEWID) // 开始对话->移动数据未开启界面
+        {
+            view_->ChangeView(hideView, showView);
+        }
+        else if (hideView == AIVOICE_BLUETOOTH_FAILEDSTART_VIEWID && showView == AIVOICE_STARTCHAT_VIEWID) // 蓝牙未开启界面->开始对话界面
+        {
+            view_->ChangeView(hideView, showView);
+        }
+        else if (hideView == AIVOICE_MOBILEDATA_FAILEDSTART_VIEWID && showView == AIVOICE_BLUETOOTH_FAILEDSTART_VIEWID) // 移动数据未开启界面->开始对话界面
+        {
+            view_->ChangeView(hideView, showView);
+        }
+        else if (hideView == AIVOICE_RETURN_RESULT_TEXT_VIEWID && showView == AIVOICE_STARTCHAT_VIEWID) // 返回结果文本界面->开始对话界面
+        {
+            view_->ChangeView(hideView, showView);
+        }
+        else if (hideView == AIVOICE_RETURN_RESULT_TEXT_VIEWID && showView == AIVOICE_LISTENING_VIEWID) // 返回结果文本界面->聆听中界面
+        {
+            model->StartListenAndRecordingUserQuestion(); // 重新开始录音
+            view_->ChangeView(hideView, showView);
+        }
+        return true;
+    }
+#else
+    bool AiVoicePresenter::ChangeViewAndLogicOperator(int16_t hideView, int16_t showView)
+    {
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoicePresenter::ChangeViewOperator");
+
+        if (hideView > MAX_AIVOICE_VIEWID)
+        {
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Overstep ones bounds");
             return false;
         }
 
+        view_->ChangeView(hideView, showView); // 默认先进行视图切换
+
+        switch (hideView)
+        {
+        case AIVOICE_STARTCHAT_VIEWID:
+            if (showView == AIVOICE_LISTENING_VIEWID)
+            {
+                model->StartListenAndRecordingUserQuestion();
+            }
+            break;
+
+        case AIVOICE_LISTENING_VIEWID:
+            model->StopListenAndRecordingUserQuestion();
+            if (showView == AIVOICE_THINKING_VIEWID) // 聆听中->思考中界面
+            {
+                // osal_msleep(500);
+                model->CheckFileAndSendAIIsReady();
+                model->AIVoice_StartTimer();
+            }
+            else if (showView == AIVOICE_STARTCHAT_VIEWID) // 聆听中->开始对话界面:(右滑不想录音了)
+            {
+                // No additional actions needed
+            }
+            break;
+
+        case AIVOICE_THINKING_VIEWID:
+            model->AIVoice_StopTimer();
+            if (showView == AIVOICE_CONNECT_TIMEOUT_VIEWID) // 思考中界面->连接超时界面
+            {
+                model->SetEntryTimeoutFlag(true);
+            }
+            else if (showView == AIVOICE_RETURN_RESULT_TEXT_VIEWID) // 思考中界面->返回结果文本界面
+            {
+                // No additional actions needed
+            }
+            else if (showView == AIVOICE_LISTENING_VIEWID) // 思考中界面->聆听中界面
+            {
+                model->StartListenAndRecordingUserQuestion();
+            }
+            break;
+
+        case AIVOICE_CONNECT_TIMEOUT_VIEWID:
+            if (showView == AIVOICE_LISTENING_VIEWID && model->GetEntryTimeoutFlag()) // 连接超时界面->聆听中界面
+            {
+                model->SetEntryTimeoutFlag(false);
+                model->StartListenAndRecordingUserQuestion();
+            }
+            break;
+        case AIVOICE_RETURN_RESULT_TEXT_VIEWID:
+            if (showView == AIVOICE_LISTENING_VIEWID) // 连接超时界面->聆听中界面
+            {
+                model->StartListenAndRecordingUserQuestion();
+            }
+            break;
+
+        default:
+            // Handle other cases if needed
+            break;
+        }
+
         return true;
     }
+#endif
 
     bool AiVoicePresenter::OnClick(UIView &view, const ClickEvent &event)
+    {
+        UNUSED(view);
+        UNUSED(event);
+        return true;
+    }
+
+    bool AiVoicePresenter::OnRelease(UIView &view, const ReleaseEvent &event)
     {
         UNUSED(event);
-        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoicePresenter::OnClick");
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AiVoicePresenter::OnRelease");
         std::string viewId = view.GetViewId();
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AiVoicePresenter::OnRelease %s", viewId.c_str());
 
         if (viewId == START_CHAT_BUTTON_VIEW_ID) // 如果点击的是开始对话按钮
         {
+#if 0
             if (model->GetMobileDataIsOpen() == false) // 判断移动数据是否开启
             {
                 view_->ChangeView(AIVOICE_STARTCHAT_VIEWID, AIVOICE_MOBILEDATA_FAILEDSTART_VIEWID); // 开始对话->移动数据未开启界面
             }
             else
             {
-                view_->ChangeView(AIVOICE_STARTCHAT_VIEWID, AIVOICE_LISTENING_VIEWID); // 开始对话->聆听中界面
-                model->StartListenAndRecordingUserQuestion();
+                ChangeViewAndLogicOperator(AIVOICE_STARTCHAT_VIEWID,AIVOICE_LISTENING_VIEWID);
             }
+#else
+            bool state = model->GetBluetoothIsOpen();
+            (state == false)
+                ? ChangeViewAndLogicOperator(AIVOICE_STARTCHAT_VIEWID, AIVOICE_BLUETOOTH_FAILEDSTART_VIEWID)
+                : ChangeViewAndLogicOperator(AIVOICE_STARTCHAT_VIEWID, AIVOICE_LISTENING_VIEWID);
+#endif
             return true;
         }
 
         if (viewId == FINISH_SPEAKING_BUTTON_VIEW_ID) // 如果点击的是说话完毕按钮
         {
-            if (model->GetAiVoiceConnectStatus() == false) // 判断与AI模型的连接状态
-            {
-                view_->ChangeView(AIVOICE_LISTENING_VIEWID, AIVOICE_CONNECT_TIMEOUT_VIEWID); // 聆听中->连接超时界面
-            }
-            else
-            {
-                view_->ChangeView(AIVOICE_LISTENING_VIEWID, AIVOICE_THINKING_VIEWID); // 聆听中->思考中界面
-                model->StopListenAndRecordingUserQuestion();
-            }
+            bool state = model->GetAiVoiceConnectStatus();
+            (state == false)
+                ? ChangeViewAndLogicOperator(AIVOICE_LISTENING_VIEWID, AIVOICE_CONNECT_TIMEOUT_VIEWID)
+                : ChangeViewAndLogicOperator(AIVOICE_LISTENING_VIEWID, AIVOICE_THINKING_VIEWID);
             return true;
         }
 
@@ -142,7 +319,7 @@ namespace OHOS
         auto it = viewIdMap.find(viewId);
         if (it != viewIdMap.end())
         {
-            view_->ChangeView(it->second.first, it->second.second);
+            ChangeViewAndLogicOperator(it->second.first, it->second.second);
             return true;
         }
         else
@@ -182,11 +359,13 @@ namespace OHOS
             }
             else if (scrollView == view_->GetAiVoiceScrollView(AIVOICE_LISTENING_VIEWID))
             {
-                view_->ChangeView(AIVOICE_LISTENING_VIEWID, AIVOICE_STARTCHAT_VIEWID); // 聆听中->开始对话界面
+                // view_->ChangeView(AIVOICE_LISTENING_VIEWID, AIVOICE_STARTCHAT_VIEWID); // 聆听中->开始对话界面
+                ChangeViewAndLogicOperator(AIVOICE_LISTENING_VIEWID, AIVOICE_STARTCHAT_VIEWID);
             }
             else if (scrollView == view_->GetAiVoiceScrollView(AIVOICE_THINKING_VIEWID))
             {
-                view_->ChangeView(AIVOICE_THINKING_VIEWID, AIVOICE_STARTCHAT_VIEWID); // 思考中->开始对话界面
+                // view_->ChangeView(AIVOICE_THINKING_VIEWID, AIVOICE_STARTCHAT_VIEWID); // 思考中->开始对话界面
+                ChangeViewAndLogicOperator(AIVOICE_THINKING_VIEWID, AIVOICE_STARTCHAT_VIEWID);
             }
             AiVoicePresenter::X_DRAG_FLAG = false;
         }
index f1e0843..9257f42 100644 (file)
@@ -2,7 +2,7 @@
  * @Author: luozheng 1732036298@qq.com
  * @Date: 2024-05-07 11:25:58
  * @LastEditors: luozheng 1732036298@qq.com
- * @LastEditTime: 2024-06-25 17:43:03
+ * @LastEditTime: 2024-07-03 18:38:55
  * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/AiVoice/src/AiVoiceView.cpp
  */
 #include "aivoice/include/AiVoicePresenter.h"
@@ -141,7 +141,7 @@ namespace OHOS
         button->SetStyle(STYLE_BACKGROUND_COLOR, 0xff4fc34c);
         button->SetStyle(STYLE_BACKGROUND_OPA, 0xff);
         button->SetStyleForState(STYLE_BACKGROUND_COLOR, 0xff383838, UIButton::PRESSED);
-        button->SetOnClickListener(presenter_);
+        button->SetOnTouchListener(presenter_);
 
         return button;
     }
@@ -426,21 +426,6 @@ namespace OHOS
             AiVoiceScrollView[thisView] = p_AivoiceReturnResultTextView->CreateAivoiceReturnResultTextView();
             container_->Add(AiVoiceScrollView[thisView]);
         }
-        else
-        {
-            container_->Remove(AiVoiceScrollView[thisView]);
-            delete p_AivoiceReturnResultTextView;
-            p_AivoiceReturnResultTextView = nullptr;
-            
-            p_AivoiceReturnResultTextView = new AivoiceReturnResultTextView();
-            if (p_AivoiceReturnResultTextView == nullptr)
-            {
-                WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "new AiVoiceScrollView[%d] fail", thisView);
-                return false;
-            }
-            AiVoiceScrollView[thisView] = p_AivoiceReturnResultTextView->CreateAivoiceReturnResultTextView();
-            container_->Add(AiVoiceScrollView[thisView]);
-        }
         return true;
     }
 
diff --git a/code/sdk/application/wearable/fd230app/nativeui/aivoice/src/AivoiceChatContentListAdapter.cpp b/code/sdk/application/wearable/fd230app/nativeui/aivoice/src/AivoiceChatContentListAdapter.cpp
new file mode 100644 (file)
index 0000000..86af65c
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * @Author: luozheng 1732036298@qq.com
+ * @Date: 2024-03-28 14:27:05
+ * @LastEditors: luozheng 1732036298@qq.com
+ * @LastEditTime: 2024-07-03 15:27:02
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/language/src/AivoiceChatContentListAdapter.cpp
+ */
+#include "aivoice/include/AivoiceChatContentListAdapter.h"
+#include "wearable_log.h"
+#include <UiConfig.h>
+
+namespace OHOS
+{
+
+    AivoiceChatContentListAdapter::AivoiceChatContentListAdapter()
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AivoiceChatContentListAdapter::AivoiceChatContentListAdapter");
+    }
+
+    AivoiceChatContentListAdapter::~AivoiceChatContentListAdapter()
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AivoiceChatContentListAdapter::~AivoiceChatContentListAdapter");
+        listData.clear();
+    }
+
+    uint16_t AivoiceChatContentListAdapter::GetCount(void)
+    {
+        return listData.size();
+    }
+
+    std::list<ChatContentItem> &AivoiceChatContentListAdapter::GetChatContentItem()
+    {
+        return listData;
+    }
+
+    void AivoiceChatContentListAdapter::SetData(std::list<ChatContentItem> &data)
+    {
+        if (!listData.empty())
+        {
+            listData.clear();
+        }
+        std::list<ChatContentItem>::iterator it;
+        for (it = data.begin(); it != data.end(); it++)
+        {
+            listData.push_back(*it);
+        }
+    }
+
+    void AivoiceChatContentListAdapter::ClearData(void)
+    {
+        if (!listData.empty())
+        {
+            listData.clear();
+        }
+    }
+
+    void AivoiceChatContentListAdapter::calculateChatContentItemViewHeight(std::string text, bool flag)
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AivoiceChatContentListAdapter::calculateChatContentItemViewHeight");
+
+        const char *Text = text.c_str();
+        aiAnswerFalg = flag;
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "Text:%s,aiAnswerFalg:%d", Text, aiAnswerFalg);
+
+        UILabel label;
+        label.SetPosition(53, 100);
+        label.Resize(360, 60);
+        label.SetStyle(STYLE_TEXT_FONT, 26);
+        label.SetStyle(STYLE_LINE_HEIGHT, 30);
+        label.SetText(Text);
+        label.SetLineBreakMode(UILabel::LINE_BREAK_WRAP);
+        label.SetAlign(TEXT_ALIGNMENT_CENTER, TEXT_ALIGNMENT_CENTER);
+        label.SetFont(DEFAULT_VECTOR_FONT_FILENAME, 26);
+
+        WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "label.GetHeight:%d,label.GetTextHeight:%d", label.GetHeight(), label.GetTextHeight());
+        itemViewHeight = label.GetTextHeight();
+    }
+
+    UIView *AivoiceChatContentListAdapter::GetView(UIView *inView, int16_t index)
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AivoiceChatContentListAdapter::GetView,index %d", index);
+        // 1.先检查列表数据是否为空,若为空则返回空指针
+        if (listData.empty())
+        {
+            return nullptr;
+        }
+        // 2.接着检查索引是否小于0,若小于0则返回空指针
+        if (index < 0)
+        {
+            return nullptr;
+        }
+        // 3.检查是否超出列表数据大小,若超出则返回空指针
+        size_t uindex = index;
+        if (uindex >= listData.size())
+        {
+            return nullptr;
+        }
+        // 4.通过迭代器访问列表中指定索引位置的元素,将其赋值给itemData变量
+        std::list<ChatContentItem>::iterator it = listData.begin();
+        for (int i = 0; i < index; i++)
+        {
+            it++;
+        }
+        ChatContentItem itemData = *it;
+        AivoiceChatContentListItemView *item = nullptr;
+        /* -------------------------------------------------------------------------- */
+        calculateChatContentItemViewHeight(itemData.text, itemData.isAiAnswer);
+        /* -------------------------------------------------------------------------- */
+        // 5.根据传入的inView参数是否已经存在一个视图对象,若为空则创建一个新的LanguageSwitchListItemView对象,否则将inView转换成LanguageSwitchListItemView类型的指针
+        if (inView == nullptr)
+        {
+            item = new AivoiceChatContentListItemView(itemViewHeight, aiAnswerFalg);
+        }
+        else
+        {
+            item = dynamic_cast<AivoiceChatContentListItemView *>(inView);
+        }
+        item->SetItemInfo(itemData);
+        return item;
+    }
+
+    void AivoiceChatContentListAdapter::SetItemClickListener(UIView::OnClickListener *itemclicklistener)
+    {
+        itemClickListener = itemclicklistener;
+    }
+
+    void AivoiceChatContentListAdapter::AddListItem(const ChatContentItem &item)
+    {
+        listData.push_back(item);
+    }
+
+}
\ No newline at end of file
diff --git a/code/sdk/application/wearable/fd230app/nativeui/aivoice/src/AivoiceChatContentListItemView.cpp b/code/sdk/application/wearable/fd230app/nativeui/aivoice/src/AivoiceChatContentListItemView.cpp
new file mode 100644 (file)
index 0000000..c7e499f
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+ * @Author: luozheng 1732036298@qq.com
+ * @Date: 2024-06-29 17:27:25
+ * @LastEditors: luozheng 1732036298@qq.com
+ * @LastEditTime: 2024-07-03 18:34:57
+ * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/aivoice/src/AivoiceChatContentListItemView.cpp
+ */
+
+#include "aivoice/include/AivoiceChatContentListItemView.h"
+#include "wearable_log.h"
+
+namespace OHOS
+{
+    static constexpr int16_t QUESTION_ITEM_VIEW_X = 112;
+    static constexpr int16_t ANSWER_ITEM_VIEW_X = 53;
+
+    static constexpr int16_t QUESTION_ITEM_VIEW_Y = 0;
+    static constexpr int16_t ANSWER_ITEM_VIEW_Y = 30;
+
+    static constexpr int16_t QUESTION_ITEM_VIEW_W = 280;
+    static constexpr int16_t ANSWER_ITEM_VIEW_W = 360;
+
+    static constexpr int64_t QUESTION_ITEM_VIEW_COLOR = 0xff4fc34c;
+    static constexpr int64_t ANSWER_ITEM_VIEW_COLOR = 0xff191919;
+
+    static constexpr int64_t ITEM_VIEW_RADIUS = 20;
+
+    static constexpr int16_t CHATCONTENTLABEL_TEXT_FONT = 26;
+    static constexpr int16_t CHATCONTENTLABEL_LINE_HEIGHT = 30;
+    static constexpr int16_t CHATCONTENTLABEL_ROLLSPEED = 40;
+    static constexpr int16_t NUM_2 = 2;
+
+    AivoiceChatContentListItemView::AivoiceChatContentListItemView(int16_t viewHeight, bool isAiAnswerFalg)
+    {
+        m_viewHeight = viewHeight;
+        m_isAiAnswerFalg = isAiAnswerFalg;
+        SetPosition(0, 0);
+        Resize(ANSWER_ITEM_VIEW_W, m_viewHeight + 50);
+        SetStyle(STYLE_BACKGROUND_COLOR, m_isAiAnswerFalg ? ANSWER_ITEM_VIEW_COLOR : QUESTION_ITEM_VIEW_COLOR);
+        SetStyle(STYLE_BACKGROUND_OPA, 0xff);
+        SetStyle(STYLE_BORDER_RADIUS, ITEM_VIEW_RADIUS);
+        SetTouchable(true);
+        SetUpChild();
+        Add(&chatContentLabel);
+    }
+
+    AivoiceChatContentListItemView::~AivoiceChatContentListItemView()
+    {
+        Remove(&chatContentLabel);
+    }
+
+    void AivoiceChatContentListItemView::SetItemInfo(const ChatContentItem itemInfo)
+    {
+        chatContentLabel.SetText(itemInfo.text.c_str());
+        Resize(ANSWER_ITEM_VIEW_W, m_viewHeight + 50);
+        chatContentLabel.Resize((GetWidth() - chatContentLabel.GetX() * 2), (GetHeight() - chatContentLabel.GetY() * 2));
+    }
+
+    void AivoiceChatContentListItemView::SetUpChild()
+    {
+        chatContentLabel.SetPosition(0, 0);
+        chatContentLabel.Resize((GetWidth() - chatContentLabel.GetX() * 2), (GetHeight() - chatContentLabel.GetY() * 2));
+        chatContentLabel.SetStyle(STYLE_TEXT_FONT, CHATCONTENTLABEL_TEXT_FONT);
+        chatContentLabel.SetStyle(STYLE_LINE_HEIGHT, CHATCONTENTLABEL_LINE_HEIGHT);
+        chatContentLabel.SetLineBreakMode(UILabel::LINE_BREAK_WRAP);
+        chatContentLabel.SetAlign(TEXT_ALIGNMENT_LEFT, TEXT_ALIGNMENT_CENTER);
+        chatContentLabel.SetFont(DEFAULT_VECTOR_FONT_FILENAME, CHATCONTENTLABEL_TEXT_FONT);
+        chatContentLabel.SetTextColor(m_isAiAnswerFalg ? Color::GetColorFromRGBA(0x99, 0x99, 0x99, 0xff) : Color::GetColorFromRGBA(0xff, 0xff, 0xff, 0xcc));
+    }
+}
\ No newline at end of file
index 9dbf012..ce220d8 100644 (file)
@@ -2,7 +2,7 @@
  * @Author: luozheng 1732036298@qq.com
  * @Date: 2024-05-07 11:25:58
  * @LastEditors: luozheng 1732036298@qq.com
- * @LastEditTime: 2024-06-24 10:38:42
+ * @LastEditTime: 2024-07-03 09:34:11
  * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/AiVoice/src/AivoiceConnectTimeoutView.cpp
  */
 #include "aivoice/include/AiVoicePresenter.h"
@@ -209,13 +209,13 @@ namespace OHOS
             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ensureButton new fail!");
             return false;
         }
-        UIView::OnClickListener *clickListener = static_cast<UIView::OnClickListener *>(AiVoicePresenter::GetInstance());
-        if (clickListener == nullptr)
+        UIView::OnTouchListener *touchListener = static_cast<UIView::OnTouchListener *>(AiVoicePresenter::GetInstance());
+        if (touchListener == nullptr)
         {
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceConnectTimeoutView::draglistener can not be nullptr!");
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceConnectTimeoutView::touchListener can not be nullptr!");
             return false;
         }
-        ensureButton->SetOnClickListener(clickListener);
+        ensureButton->SetOnTouchListener(touchListener);
 
         return true;
     }
index 010ff29..7cb7e89 100644 (file)
@@ -2,7 +2,7 @@
  * @Author: luozheng 1732036298@qq.com
  * @Date: 2024-05-07 11:25:58
  * @LastEditors: luozheng 1732036298@qq.com
- * @LastEditTime: 2024-06-24 16:39:51
+ * @LastEditTime: 2024-07-03 18:38:35
  * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/AiVoice/src/AivoiceListeningView.cpp
  */
 #include "aivoice/include/AiVoicePresenter.h"
@@ -243,13 +243,13 @@ namespace OHOS
             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "finishSpeakButton new fail!");
             return false;
         }
-        UIView::OnClickListener *clickListener = static_cast<UIView::OnClickListener *>(AiVoicePresenter::GetInstance());
-        if (clickListener == nullptr)
+        UIView::OnTouchListener *touchListener = static_cast<UIView::OnTouchListener *>(AiVoicePresenter::GetInstance());
+        if (touchListener == nullptr)
         {
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceListeningView::draglistener can not be nullptr!");
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceListeningView::touchListener can not be nullptr!");
             return false;
         }
-        finishSpeakButton->SetOnClickListener(clickListener);
+        finishSpeakButton->SetOnTouchListener(touchListener);
 
         return true;
     }
index b76f9e6..9aaec87 100644 (file)
@@ -2,7 +2,7 @@
  * @Author: luozheng 1732036298@qq.com
  * @Date: 2024-05-07 11:25:58
  * @LastEditors: luozheng 1732036298@qq.com
- * @LastEditTime: 2024-06-24 10:39:26
+ * @LastEditTime: 2024-07-03 09:34:25
  * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/AiVoice/src/AivoiceMobileDataFailedStartView.cpp
  */
 #include "aivoice/include/AiVoicePresenter.h"
@@ -209,13 +209,13 @@ namespace OHOS
             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "ensureButton new fail!");
             return false;
         }
-        UIView::OnClickListener *clickListener = static_cast<UIView::OnClickListener *>(AiVoicePresenter::GetInstance());
-        if (clickListener == nullptr)
+        UIView::OnTouchListener *touchListener = static_cast<UIView::OnTouchListener *>(AiVoicePresenter::GetInstance());
+        if (touchListener == nullptr)
         {
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceMobileDataFailedStartView::draglistener can not be nullptr!");
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceThinkingView::touchListener can not be nullptr!");
             return false;
         }
-        ensureButton->SetOnClickListener(clickListener);
+        ensureButton->SetOnTouchListener(touchListener);
 
         return true;
     }
index 1e6c112..7097057 100644 (file)
@@ -1,8 +1,8 @@
 /*
  * @Author: luozheng 1732036298@qq.com
  * @Date: 2024-05-07 11:25:58
- * @LastEditors: luozheng 1732036298@qq.com
- * @LastEditTime: 2024-06-25 17:45:39
+ * @LastEditors: SnickerSun snickersun@163.com
+ * @LastEditTime: 2024-07-05 10:12:30
  * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/AiVoice/src/AivoiceReturnResultTextView.cpp
  */
 #include "aivoice/include/AiVoicePresenter.h"
@@ -18,41 +18,15 @@ namespace OHOS
 {
 
     /* -------------------------------------------------------------------------- */
-    static constexpr const int16_t QUESTION_SCROLLVIEW_X = 112;
-    static constexpr const int16_t QUESTION_SCROLLVIEW_Y = 120;
-    static constexpr const int16_t QUESTION_SCROLLVIEW_W = 280;
-    static constexpr const int16_t QUESTION_SCROLLVIEW_H = 80;
-    static constexpr const int64_t QUESTION_BACKGROUND_COLOR = 0xff4fc34c;
-
-    static constexpr const int16_t QUESTION_LABEL_W = 200;
-    static constexpr const int16_t QUESTION_LABEL_H = 30;
-    static constexpr const int16_t QUESTION_LABEL_FONTSIZE = 26;
-    static constexpr const int16_t QUESTION_LABEL_LINEHEIGHT = 30;
-    /* -------------------------------------------------------------------------- */
-
-    static constexpr const int16_t ANSWER_SCROLLVIEW_X = 53;
-    static constexpr const int16_t ANSWER_SCROLLVIEW_Y = QUESTION_SCROLLVIEW_Y + QUESTION_SCROLLVIEW_H + 30;
-    static constexpr const int16_t ANSWER_SCROLLVIEW_W = 360;
-    static constexpr const int16_t ANSWER_SCROLLVIEW_H = 250;
-    static constexpr const int64_t ANSWER_BACKGROUND_COLOR = 0xff191919;
-
-    static constexpr const int16_t ANSWER_LABEL_W = 270;
-    static constexpr const int16_t ANSWER_LABEL_H = 194;
-    static constexpr const int16_t ANSWER_LABEL_FONTSIZE = 26;
-    static constexpr const int16_t ANSWER_LABEL_LINEHEIGHT = 30;
+    static constexpr const int16_t CHATCONTENT_LIST_X = 53;
+    static constexpr const int16_t CHATCONTENT_LIST_Y = 120;
+    static constexpr const int16_t CHATCONTENT_LIST_W = 360;
+    static constexpr const int16_t CHATCONTENT_LIST_H = 200;
+    static constexpr const int16_t REBOUNDSIZE = 35;
+    static constexpr const int16_t CHATCONTENT_SCROLLBLANKSIZE = 35;
+    static constexpr const int16_t MAX_SCR_DIS = 1000;
+    static constexpr const int16_t SNUM_2 = 2;
 
-    /* -------------------------------------------------------------------------- */
-    static constexpr const int16_t RECGREEN_IMAGE_X = 342;
-    static constexpr const int16_t RECGREEN_IMAGE_Y = QUESTION_SCROLLVIEW_Y;
-    static constexpr const int16_t RECGREEN_IMAGE_W = 70;
-    static constexpr const int16_t RECGREEN_IMAGE_H = 30;
-    static constexpr const char *RECGREEN_IMAGE_PATH = "/user/res/AIVoice/AI_RecGreen.bin";
-
-    static constexpr const int16_t RECBLACK_IMAGE_X = 32;
-    static constexpr const int16_t RECBLACK_IMAGE_Y = ANSWER_SCROLLVIEW_Y;
-    static constexpr const int16_t RECBLACK_IMAGE_W = 70;
-    static constexpr const int16_t RECBLACK_IMAGE_H = 30;
-    static constexpr const char *RECBLACK_IMAGE_PATH = "/user/res/AIVoice/AI_RecBlack.bin";
     /* -------------------------------------------------------------------------- */
     static constexpr const int16_t RETURN_BUTTON_X = 73;
     static constexpr const int16_t RETURN_BUTTON_Y = ANSWER_SCROLLVIEW_Y + ANSWER_SCROLLVIEW_H + 20;
@@ -377,21 +351,26 @@ namespace OHOS
             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceReturnResultTextView::recGreenImage is nullptr!");
             return false;
         }
-        /* -------------------------------------------------------------------------- */
-        imageconfig = {
-            .x = RECBLACK_IMAGE_X,
-            .y = RECBLACK_IMAGE_Y,
-            .w = RECBLACK_IMAGE_W,
-            .h = RECBLACK_IMAGE_H,
-            .src = RECBLACK_IMAGE_PATH,
-        };
-        recBlackImage = AivoiceReturnResultTextImageInit(imageconfig);
-        if (recBlackImage == nullptr)
+        chatContentListAdapter->SetItemClickListener(clickListener);
+
+        chatContentList = new UIList(UIList::VERTICAL);
+        if (chatContentList == nullptr)
         {
             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceReturnResultTextView::recBlackImage is nullptr!");
             return false;
         }
-
+        chatContentList->SetPosition(CHATCONTENT_LIST_X, CHATCONTENT_LIST_Y, CHATCONTENT_LIST_W, CHATCONTENT_LIST_H);
+        chatContentList->SetStyle(STYLE_BACKGROUND_COLOR, 0xff000000);
+        chatContentList->EnableAutoAlign(true);
+        chatContentList->SetTouchable(true);
+        chatContentList->SetDraggable(true);
+        chatContentList->SetThrowDrag(true);
+        chatContentList->SetReboundSize(REBOUNDSIZE);
+        chatContentList->SetMaxScrollDistance(MAX_SCR_DIS);
+        chatContentList->SetIntercept(true);
+        /* -------------------------------------------------------------------------- */
+        AiVoiceModel::GetInstance().InitchatContentItems();
+        /* -------------------------------------------------------------------------- */
         return true;
     }
 
@@ -413,13 +392,13 @@ namespace OHOS
         }
         returnButton->SetImagePosition(39, 39);
         returnButton->SetImageSrc(RETURN_BUTTON_PATH, RETURN_BUTTON_PATH);
-        UIView::OnClickListener *clickListener = static_cast<UIView::OnClickListener *>(AiVoicePresenter::GetInstance());
-        if (clickListener == nullptr)
+        UIView::OnTouchListener *touchListener = static_cast<UIView::OnTouchListener *>(AiVoicePresenter::GetInstance());
+        if (touchListener == nullptr)
         {
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceReturnResultTextView::draglistener can not be nullptr!");
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceReturnResultTextView::touchListener can not be nullptr!");
             return false;
         }
-        returnButton->SetOnClickListener(clickListener);
+        returnButton->SetOnTouchListener(touchListener);
         /* -------------------------------------------------------------------------- */
         buttonconfig = {
             .x = CONTINUECHAT_BUTTON_X,
@@ -434,7 +413,7 @@ namespace OHOS
             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "continueChatButton new fail!");
             return false;
         }
-        continueChatButton->SetOnClickListener(clickListener);
+        continueChatButton->SetOnTouchListener(touchListener);
 
         return true;
     }
@@ -462,4 +441,21 @@ namespace OHOS
         }
         return scrollView;
     }
+
+    /*添加对话内容到List*/
+    void AivoiceReturnResultTextView::AddChatContentToList(const ChatContentItem &item)
+    {
+        WEARABLE_LOGD(WEARABLE_LOG_MODULE_APP, "AivoiceReturnResultTextView::AddChatContentToList");
+        chatContentListAdapter->AddListItem(item);
+    }
+
+    AivoiceChatContentListAdapter *AivoiceReturnResultTextView::GetAivoiceChatContentListAdapter(void)
+    {
+        return chatContentListAdapter;
+    }
+
+    UIList *AivoiceReturnResultTextView::GetChatContentList(void)
+    {
+        return chatContentList;
+    }
 }
\ No newline at end of file
index 10298ad..5aa19e9 100644 (file)
@@ -2,7 +2,7 @@
  * @Author: luozheng 1732036298@qq.com
  * @Date: 2024-05-07 11:25:58
  * @LastEditors: luozheng 1732036298@qq.com
- * @LastEditTime: 2024-06-24 16:39:53
+ * @LastEditTime: 2024-07-03 09:34:58
  * @FilePath: /FD230/code/sdk/application/wearable/fd230app/nativeui/AiVoice/src/AivoiceThinkingView.cpp
  */
 #include "aivoice/include/AiVoicePresenter.h"
@@ -244,13 +244,13 @@ namespace OHOS
             WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "cancelThinkButton new fail!");
             return false;
         }
-        UIView::OnClickListener *clickListener = static_cast<UIView::OnClickListener *>(AiVoicePresenter::GetInstance());
-        if (clickListener == nullptr)
+        UIView::OnTouchListener *touchListener = static_cast<UIView::OnTouchListener *>(AiVoicePresenter::GetInstance());
+        if (touchListener == nullptr)
         {
-            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceThinkingView::draglistener can not be nullptr!");
+            WEARABLE_LOGE(WEARABLE_LOG_MODULE_APP, "AivoiceThinkingView::touchListener can not be nullptr!");
             return false;
         }
-        cancelThinkButton->SetOnClickListener(clickListener);
+        cancelThinkButton->SetOnTouchListener(touchListener);
 
         return true;
     }
index c384250..637da88 100644 (file)
@@ -80,7 +80,7 @@ void ble_set_ai_Question_str(char *buf)
 
 void ble_set_ai_Answer_str(char *buf)
 {
-    OHOS::AiVoiceModel::GetInstance().SetaiAnswerStrStr(std::string(buf));
+    OHOS::AiVoiceModel::GetInstance().SetAiAnswerStrStr(std::string(buf));
 }
 
 // {