ソースを参照

refactor(chat): 优化聊天功能的会话管理和滚动行为

- 移除 demoPostSse 方法中的 topicId 参数,改为使用类成员变量 currentTopicId
- 添加 currentTopicId 成员变量用于复用会话主题ID,避免重复请求
- 修改 prepareTopic 方法逻辑,统一管理 topicId 的获取和设置流程
- 更新 RecyclerView 滚动偏移量计算,添加额外像素补偿实现更精确定位
- 简化 SSE 请求流程,所有后续请求都复用首次获取的主题ID
徐勤民 16 時間 前
コミット
e9a3e87fd8

+ 4 - 3
app/src/main/java/com/nova/brain/glass/ui/ChatActivity.kt

@@ -64,7 +64,8 @@ class ChatActivity : BaseListFormLayoutNormalActivity<ChatItem, ChatVM, Activity
         val lastRealIndex = (recyclerView.adapter?.itemCount ?: 2) - 2
         if (lastRealIndex < 0) return
         val lm = recyclerView.layoutManager as? androidx.recyclerview.widget.LinearLayoutManager ?: return
-        lm.scrollToPositionWithOffset(lastRealIndex, 0)
+        val extraPx = (2 * resources.displayMetrics.density).toInt()
+        lm.scrollToPositionWithOffset(lastRealIndex, -extraPx)
     }
 
     override fun adapter() = object : CommonPagedAdapter<ChatItem>(R.layout.item_chat) {
@@ -106,10 +107,10 @@ class ChatActivity : BaseListFormLayoutNormalActivity<ChatItem, ChatVM, Activity
         OfflineCmdServiceHelper.addOnLineListener(listener)
         AsrHelper.scene = "decision"
         AsrHelper.onGoToDecisionCenter = { action ->
-            viewModel.prepareTopic(action.params.question)
+            viewModel.demoPostSse(action.params.question)
         }
         AsrHelper.onDirectChat = { text ->
-            viewModel.prepareTopic(text)
+            viewModel.demoPostSse(text)
         }
     }
 

+ 11 - 7
app/src/main/java/com/nova/brain/glass/viewmodel/ChatVM.kt

@@ -39,6 +39,9 @@ class ChatVM : BaseListViewModel<ChatItem>() {
     private var dataSourceReady = false
     private val mainHandler = Handler(Looper.getMainLooper())
 
+    /** 进入页面时由 prepareTopic 设置,后续所有 demoPostSse 复用 */
+    private var currentTopicId: Int = DEFAULT_TOPIC_ID
+
     /** 最后一个真实 item 的索引(占位 item 之前) */
     private val lastRealIndex get() = chatItems.size - 2
 
@@ -78,8 +81,8 @@ class ChatVM : BaseListViewModel<ChatItem>() {
     }
 
     /**
-     * 先请求 tbtopic 接口拿 topicId,成功则使用返回值,失败/code≠0 则用默认值,再发起 SSE。
-     * 进入 Chat 界面时用此方法替代直接调 demoPostSse
+     * 进入 Chat 页面时调用一次:请求 tbtopic 接口设置本次会话的 topicId,
+     * 成功(code==0)使用返回值,否则沿用默认值 14478,然后发起第一次 SSE
      */
     fun prepareTopic(question: String) {
         HttpManager.getApi(Service::class.java)
@@ -87,14 +90,15 @@ class ChatVM : BaseListViewModel<ChatItem>() {
             .subscribeOn(Schedulers.io())
             .observeOn(AndroidSchedulers.mainThread())
             .subscribe({ model ->
-                val topicId = if (model.code == 0) model.data else DEFAULT_TOPIC_ID
-                demoPostSse(question, topicId)
+                currentTopicId = if (model.code == 0) model.data else DEFAULT_TOPIC_ID
+                demoPostSse(question)
             }, { _ ->
-                demoPostSse(question, DEFAULT_TOPIC_ID)
+                currentTopicId = DEFAULT_TOPIC_ID
+                demoPostSse(question)
             }).also { add(it) }
     }
 
-    fun demoPostSse(question: String, topicId: Int = DEFAULT_TOPIC_ID) {
+    fun demoPostSse(question: String) {
         currentTask?.dispose()
         currentTask = null
         stopThinkingAnimation()
@@ -106,7 +110,7 @@ class ChatVM : BaseListViewModel<ChatItem>() {
         result.postValue(UUID.randomUUID().toString())
         loading.postValue(true)
 
-        currentTask = HttpManager.getApi(Service::class.java).chat(ChatData(question, topicId))
+        currentTask = HttpManager.getApi(Service::class.java).chat(ChatData(question, currentTopicId))
             .subscribeOn(Schedulers.io())
             .subscribe({ body ->
                 var content = ""