瀏覽代碼

[New]新增聊天页面跳转

zhipeng 1 年之前
父節點
當前提交
a8d316d328

二進制
assets/images/icon_reference_chat_arrow.webp


二進制
assets/images/icon_reference_chat_delete_file.webp


二進制
assets/images/icon_reference_chat_file.webp


+ 1 - 1
lib/data/api/request/agenda_status_request.dart

@@ -6,7 +6,7 @@ part 'agenda_status_request.g.dart';
 @JsonSerializable()
 class AgendaStatusRequest extends AppBaseRequest {
   @JsonKey(name: 'id')
-  int? id;
+  String? id;
 
   @JsonKey(name: 'complete')
   late bool complete;

+ 1 - 1
lib/data/api/request/agenda_todo_request.dart

@@ -6,7 +6,7 @@ part 'agenda_todo_request.g.dart';
 @JsonSerializable()
 class AgendaTodoRequest extends AppBaseRequest {
   @JsonKey(name: 'id')
-  int? id;
+  String? id;
 
   @JsonKey(name: 'isTodo')
   bool? isTodo;

+ 7 - 1
lib/data/api/request/chat_request.dart

@@ -8,7 +8,13 @@ class ChatRequest extends AppBaseRequest {
   @JsonKey(name: "content")
   late String content;
 
-  ChatRequest(this.content);
+  @JsonKey(name: "talkId")
+  String? talkId;
+
+  @JsonKey(name: "agendaId")
+  String? agendaId;
+
+  ChatRequest(this.content, {this.talkId, this.agendaId});
 
   @override
   Map<String, dynamic> toJson() => _$ChatRequestToJson(this);

+ 8 - 6
lib/data/bean/agenda.dart

@@ -5,11 +5,11 @@ part 'agenda.g.dart';
 
 @JsonSerializable()
 class Agenda {
-  @JsonKey(name: 'id')
-  int? id;
+  @JsonKey(name: 'id', fromJson: _intToString, toJson: _stringToInt)
+  String id;
 
   @JsonKey(name: 'talkId')
-  String? talkId;
+  String talkId;
 
   @JsonKey(name: 'name')
   String? name;
@@ -31,10 +31,9 @@ class Agenda {
 
   bool? isDone;
 
-
   Agenda(
-      {this.id,
-      this.talkId,
+      {required this.id,
+      required this.talkId,
       this.name,
       this.content,
       this.createTime,
@@ -47,4 +46,7 @@ class Agenda {
         json.containsKey('todo') ? json['todo'] as bool? ?? false : false;
     return agenda;
   }
+
+  static String _intToString(int value) => value.toString();
+  static int _stringToInt(String value) => int.parse(value);
 }

+ 11 - 2
lib/data/bean/chat_item.dart

@@ -4,8 +4,8 @@ part 'chat_item.g.dart';
 
 @JsonSerializable()
 class ChatItem {
-  @JsonKey(name: "id")
-  final int id;
+  @JsonKey(name: "id", fromJson: _intToString, toJson: _stringToInt)
+  final String id;
 
   @JsonKey(name: "chatId")
   final String conversationId;
@@ -19,6 +19,12 @@ class ChatItem {
   @JsonKey(name: "createTime")
   final String createTime;
 
+  @JsonKey(name: "talkId")
+  String? talkId;
+
+  @JsonKey(name: "title")
+  String? talkTitle;
+
   ChatItem({
     required this.id,
     required this.conversationId,
@@ -28,4 +34,7 @@ class ChatItem {
   });
 
   factory ChatItem.fromJson(Map<String, dynamic> json) => _$ChatItemFromJson(json);
+
+  static String _intToString(int value) => value.toString();
+  static int _stringToInt(String value) => int.parse(value);
 }

+ 13 - 0
lib/data/bean/file_chat_item.dart

@@ -0,0 +1,13 @@
+import 'package:electronic_assistant/data/bean/chat_item.dart';
+import 'package:electronic_assistant/data/bean/talk_info.dart';
+
+class FileChatItem extends ChatItem {
+  final TalkInfo talkInfo;
+
+  FileChatItem(this.talkInfo,
+      {required super.id,
+      required super.conversationId,
+      required super.role,
+      required super.content,
+      required super.createTime});
+}

+ 14 - 0
lib/data/bean/reference_chat_item.dart

@@ -0,0 +1,14 @@
+import 'package:electronic_assistant/data/bean/chat_item.dart';
+import 'package:electronic_assistant/data/bean/talk_info.dart';
+
+class ReferenceChatItem extends ChatItem {
+  final TalkInfo talkInfo;
+
+  ReferenceChatItem(
+      {required this.talkInfo,
+      required super.id,
+      required super.conversationId,
+      required super.role,
+      required super.content,
+      required super.createTime});
+}

+ 5 - 1
lib/data/bean/talk_info.dart

@@ -34,6 +34,9 @@ class TalkInfo {
   @JsonKey(name: 'example')
   bool? example;
 
+  @JsonKey(name: 'oversizeFile')
+  bool? oversizeFile;
+
   TalkInfo(
       {this.id,
       this.taskId,
@@ -44,7 +47,8 @@ class TalkInfo {
       this.title,
       this.summary,
       this.createTime,
-      this.example});
+      this.example,
+      this.oversizeFile});
 
   factory TalkInfo.fromJson(Map<String, dynamic> json) =>
       _$TalkInfoFromJson(json);

+ 2 - 2
lib/data/repositories/agenda_repository.dart

@@ -56,7 +56,7 @@ class AgendaRepository {
         .then(HttpHandler.handle(true));
   }
 
-  Future<void> agendaFinish(int? id, bool complete) {
+  Future<void> agendaFinish(String? id, bool complete) {
     return atmobApi
         .agendaFinish(AgendaStatusRequest(id, complete))
         .then(HttpHandler.handle(true));
@@ -74,7 +74,7 @@ class AgendaRepository {
         .then(HttpHandler.handle(true));
   }
 
-  Future<void> agendaTodo(int id, bool isTodo) {
+  Future<void> agendaTodo(String id, bool isTodo) {
     return atmobApi
         .agendaTodo(AgendaTodoRequest(id, isTodo))
         .then(HttpHandler.handle(true));

+ 5 - 2
lib/data/repositories/chat_repository.dart

@@ -13,8 +13,11 @@ import '../api/atmob_stream_api.dart';
 class ChatRepository {
   ChatRepository._() {}
 
-  Future<Stream<Message>> streamChat(String chatContent) {
-    return atmobStreamApi.chat(ChatRequest(chatContent)).then((response) async {
+  Future<Stream<Message>> streamChat(String chatContent,
+      {String? talkId, String? agendaId}) {
+    return atmobStreamApi
+        .chat(ChatRequest(chatContent, talkId: talkId, agendaId: agendaId))
+        .then((response) async {
       List<String>? contentType = response.headers['Content-Type'];
       if (contentType != null) {
         for (var value in contentType) {

+ 96 - 18
lib/module/chat/controller.dart

@@ -1,15 +1,21 @@
 import 'dart:convert';
 
 import 'package:electronic_assistant/base/base_controller.dart';
+import 'package:electronic_assistant/data/bean/agenda.dart';
 import 'package:electronic_assistant/data/bean/chat_item.dart';
+import 'package:electronic_assistant/data/bean/file_chat_item.dart';
 import 'package:electronic_assistant/data/bean/progressing_chat_item.dart';
+import 'package:electronic_assistant/data/bean/reference_chat_item.dart';
 import 'package:electronic_assistant/data/bean/stream_chat_origin_data.dart';
+import 'package:electronic_assistant/data/bean/talk_info.dart';
 import 'package:electronic_assistant/data/repositories/chat_repository.dart';
+import 'package:electronic_assistant/data/repositories/talk_repository.dart';
 import 'package:electronic_assistant/module/chat/start/view.dart';
 import 'package:electronic_assistant/resource/colors.gen.dart';
 import 'package:flutter/material.dart';
 import 'package:get/get.dart';
 import 'package:pull_to_refresh/pull_to_refresh.dart';
+import 'package:uuid/uuid.dart';
 
 import '../../utils/http_handler.dart';
 
@@ -19,15 +25,69 @@ class ChatController extends BaseController {
   final TextEditingController inputController = TextEditingController();
 
   final RxList chatItems = [].obs;
+  final Rxn<TalkInfo> talkInfo = Rxn<TalkInfo>();
+  final Rxn<Agenda> agenda = Rxn<Agenda>();
 
   var isOpenStart = false;
 
   @override
+  void onInit() {
+    super.onInit();
+    checkArguments();
+  }
+
+  void checkArguments() {
+    List<dynamic> arguments = Get.arguments ?? [];
+    if (arguments.isEmpty) {
+      return;
+    }
+    if (arguments[0] is TalkInfo) {
+      talkInfo.value = arguments[0];
+      sendInitialMessage();
+    } else if (arguments[0] is String) {
+      talkRepository
+          .talkInfo(arguments[0])
+          .then((response) => talkInfo.value = response.talkInfo)
+          .then((_) => sendInitialMessage());
+    }
+    if (arguments.length > 1 && arguments[1] is Agenda) {
+      agenda.value = arguments[1];
+    }
+  }
+
+  void sendInitialMessage() {
+    final talkInfo = this.talkInfo.value;
+    if (talkInfo == null) {
+      return;
+    }
+    chatItems.insert(
+        0,
+        FileChatItem(talkInfo,
+            id: const Uuid().v4(),
+            conversationId: "",
+            role: "user",
+            content: "",
+            createTime: DateTime.now().toString()));
+    if (agenda.value != null) {
+      _sendMessage("以这份谈话为背景,你为我执行“${agenda.value?.content}”这一事项");
+    }
+  }
+
+  @override
   void onReady() {
     super.onReady();
     refreshController.requestLoading();
   }
 
+  onSendClick() {
+    if (inputController.text.isEmpty) {
+      return;
+    }
+    String chatContent = inputController.text;
+    inputController.clear();
+    _sendMessage(chatContent);
+  }
+
   void loadMoreHistory() {
     bool isEmpty = chatItems.isEmpty;
 
@@ -59,25 +119,11 @@ class ChatController extends BaseController {
     }
   }
 
-  sendMessage() {
-    if (inputController.text.isEmpty) {
-      return;
-    }
-    String chatContent = inputController.text;
-    inputController.clear();
-
-    chatItems.insert(
-        0,
-        ChatItem(
-            id: chatItems.isEmpty ? 0 : chatItems.last.id + 1,
-            conversationId:
-                chatItems.isEmpty ? "" : chatItems.last.conversationId,
-            role: "user",
-            content: chatContent,
-            createTime: DateTime.now().toString()));
+  void _sendMessage(String chatContent) {
+    chatItems.insert(0, createUserChatItem(chatContent));
 
     ProgressingChatItem progressingChatItem = ProgressingChatItem(
-      id: chatItems.last.id + 1,
+      id: const Uuid().v4(),
       conversationId: chatItems.last.conversationId,
       role: "assistant",
       content: "",
@@ -87,7 +133,10 @@ class ChatController extends BaseController {
 
     scrollToBottom();
 
-    chatRepository.streamChat(chatContent).then((stream) {
+    chatRepository
+        .streamChat(chatContent,
+            talkId: talkInfo.value?.id, agendaId: agenda.value?.id)
+        .then((stream) {
       stream.listen((event) {
         try {
           Map<String, dynamic> json = jsonDecode(event.data);
@@ -134,4 +183,33 @@ class ChatController extends BaseController {
       );
     });
   }
+
+  createUserChatItem(String chatContent) {
+    final id = const Uuid().v4();
+    final conversationId =
+        chatItems.isEmpty ? "" : chatItems.last.conversationId;
+    const role = "user";
+    final content = chatContent;
+    final createTime = DateTime.now().toString();
+    final talkInfo = this.talkInfo.value;
+    return talkInfo == null
+        ? ChatItem(
+            id: id,
+            conversationId: conversationId,
+            role: role,
+            content: chatContent,
+            createTime: createTime)
+        : ReferenceChatItem(
+            talkInfo: talkInfo,
+            id: id,
+            conversationId: conversationId,
+            role: role,
+            content: content,
+            createTime: createTime);
+  }
+
+  onDeleteReference() {
+    talkInfo.value = null;
+    agenda.value = null;
+  }
 }

+ 242 - 21
lib/module/chat/view.dart

@@ -1,5 +1,8 @@
 import 'package:electronic_assistant/base/base_page.dart';
+import 'package:electronic_assistant/data/bean/agenda.dart';
 import 'package:electronic_assistant/data/bean/chat_item.dart';
+import 'package:electronic_assistant/data/bean/file_chat_item.dart';
+import 'package:electronic_assistant/data/bean/reference_chat_item.dart';
 import 'package:electronic_assistant/module/chat/controller.dart';
 import 'package:electronic_assistant/resource/colors.gen.dart';
 import 'package:electronic_assistant/utils/expand.dart';
@@ -12,11 +15,25 @@ import 'package:lottie/lottie.dart';
 import 'package:pull_to_refresh/pull_to_refresh.dart';
 
 import '../../data/bean/progressing_chat_item.dart';
+import '../../data/bean/talk_info.dart';
 import '../../resource/assets.gen.dart';
+import '../../router/app_pages.dart';
 
 class ChatPage extends BasePage<ChatController> {
   const ChatPage({super.key});
 
+  static start() {
+    Get.toNamed(RoutePath.chat);
+  }
+
+  static startByTalk(TalkInfo talkInfo, {Agenda? agenda}) {
+    Get.toNamed(RoutePath.chat, arguments: [talkInfo, agenda]);
+  }
+
+  static startByTalkId(String talkId, {Agenda? agenda}) {
+    Get.toNamed(RoutePath.chat, arguments: [talkId, agenda]);
+  }
+
   @override
   bool immersive() {
     return true;
@@ -34,8 +51,8 @@ class ChatPage extends BasePage<ChatController> {
 
     return Stack(
       children: [
-        buildBackgroundGradient(),
-        buildTopGradient(),
+        _buildBackgroundGradient(),
+        _buildTopGradient(),
         Scaffold(
           backgroundColor: Colors.transparent,
           appBar: AppBar(
@@ -139,6 +156,14 @@ class ChatPage extends BasePage<ChatController> {
             padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
             child: Column(
               children: [
+                Obx(() {
+                  TalkInfo? talkInfo = controller.talkInfo.value;
+                  if (talkInfo == null) {
+                    return Container();
+                  } else {
+                    return _buildReferenceFile(talkInfo);
+                  }
+                }),
                 Row(
                   crossAxisAlignment: CrossAxisAlignment.end,
                   children: [
@@ -170,7 +195,7 @@ class ChatPage extends BasePage<ChatController> {
                       margin: EdgeInsets.only(left: 16.w),
                       child: GestureDetector(
                         onTap: () {
-                          controller.sendMessage();
+                          controller.onSendClick();
                         },
                         child: Image(
                             image: Assets.images.iconChatSend.provider(),
@@ -232,7 +257,7 @@ class ChatPage extends BasePage<ChatController> {
       margin: EdgeInsets.symmetric(vertical: 10.h),
       alignment: Alignment.centerLeft,
       constraints: BoxConstraints(
-        maxWidth: 0.78.sw, // 65% of screen width
+        maxWidth: 0.78.sw,
       ),
       decoration: BoxDecoration(
           border: isStreamStarted == null || isStreamStarted == true
@@ -253,30 +278,226 @@ class ChatPage extends BasePage<ChatController> {
   }
 
   Widget _buildUserChatItem(BuildContext context, ChatItem chatItem) {
+    if (chatItem is FileChatItem) {
+      return _buildUserFileChatItem(context, chatItem);
+    } else if (chatItem is ReferenceChatItem) {
+      return _buildUserNormalChatItem(context, chatItem,
+          referenceTalkTitle: chatItem.talkInfo.title);
+    }
+    return _buildUserNormalChatItem(context, chatItem,
+        referenceTalkTitle: chatItem.talkTitle);
+  }
+
+  Widget _buildUserNormalChatItem(BuildContext context, ChatItem chatItem,
+      {String? referenceTalkTitle}) {
     return Align(
       alignment: Alignment.centerRight,
-      child: IntrinsicWidth(
-        child: Container(
-          padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 8.h),
-          margin: EdgeInsets.symmetric(vertical: 10.h),
-          alignment: Alignment.centerRight,
-          constraints: BoxConstraints(
-            maxWidth: 0.78.sw, // 65% of screen width
+      child: Column(
+        crossAxisAlignment: CrossAxisAlignment.end,
+        children: [
+          IntrinsicWidth(
+            child: Container(
+              padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 8.h),
+              margin: referenceTalkTitle == null
+                  ? EdgeInsets.symmetric(vertical: 10.h)
+                  : EdgeInsets.only(top: 10.h),
+              alignment: Alignment.centerRight,
+              constraints: BoxConstraints(
+                maxWidth: 0.78.sw,
+              ),
+              decoration: BoxDecoration(
+                  color: ColorName.colorPrimary,
+                  borderRadius: BorderRadius.only(
+                      topLeft: Radius.circular(16.w),
+                      bottomRight: Radius.circular(16.w),
+                      bottomLeft: Radius.circular(16.w))),
+              child: Text(chatItem.content,
+                  style: TextStyle(fontSize: 14.w, color: ColorName.white)),
+            ),
           ),
-          decoration: BoxDecoration(
-              color: ColorName.colorPrimary,
-              borderRadius: BorderRadius.only(
-                  topLeft: Radius.circular(16.w),
-                  bottomRight: Radius.circular(16.w),
-                  bottomLeft: Radius.circular(16.w))),
-          child: Text(chatItem.content,
-              style: TextStyle(fontSize: 14.w, color: ColorName.white)),
+          if (referenceTalkTitle != null)
+            Container(
+              padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 8.h),
+              margin: EdgeInsets.only(top: 8.h, bottom: 10.h),
+              constraints: BoxConstraints(
+                maxWidth: 0.78.sw,
+              ),
+              decoration: BoxDecoration(
+                  color: "#EFEFEF".color,
+                  borderRadius: BorderRadius.all(Radius.circular(10.w))),
+              child: Row(
+                children: [
+                  Image(
+                      image: Assets.images.iconReferenceChatArrow.provider(),
+                      width: 16.w,
+                      height: 16.w),
+                  Container(
+                    margin: EdgeInsets.only(right: 2.w, left: 4.w),
+                    child: Image(
+                        image: Assets.images.iconReferenceChatFile.provider(),
+                        width: 16.w,
+                        height: 16.w),
+                  ),
+                  Text(referenceTalkTitle,
+                      style: TextStyle(
+                          fontSize: 12.w,
+                          color: ColorName.secondaryTextColor,
+                          overflow: TextOverflow.ellipsis)),
+                ],
+              ),
+            ),
+        ],
+      ),
+    );
+  }
+
+  Widget _buildUserFileChatItem(BuildContext context, FileChatItem chatItem) {
+    return Align(
+      alignment: Alignment.centerRight,
+      child: Container(
+        padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 16.h),
+        margin: EdgeInsets.symmetric(vertical: 10.h),
+        constraints: BoxConstraints(
+          maxWidth: 0.56.sw,
+        ),
+        decoration: BoxDecoration(
+          color: ColorName.white,
+          borderRadius: BorderRadius.only(
+              topLeft: Radius.circular(16.w),
+              bottomRight: Radius.circular(16.w),
+              bottomLeft: Radius.circular(16.w)),
+          border: Border.all(color: "#ECECEC".color, width: 1.w),
         ),
+        child: Row(
+          crossAxisAlignment: CrossAxisAlignment.center,
+          children: [
+            Container(
+              margin: EdgeInsets.only(right: 6.w),
+              child: Image(
+                  image: Assets.images.iconFilesFile.provider(),
+                  width: 30.w,
+                  height: 32.w),
+            ),
+            Flexible(
+              child: Column(
+                crossAxisAlignment: CrossAxisAlignment.start,
+                children: [
+                  Text(chatItem.talkInfo.title ?? '',
+                      maxLines: 1,
+                      style: TextStyle(
+                          fontSize: 14.w,
+                          color: ColorName.primaryTextColor,
+                          fontWeight: FontWeight.bold,
+                          overflow: TextOverflow.ellipsis)),
+                  Text(chatItem.talkInfo.summary ?? '',
+                      maxLines: 1,
+                      style: TextStyle(
+                          fontSize: 12.w,
+                          color: ColorName.secondaryTextColor,
+                          overflow: TextOverflow.ellipsis)),
+                ],
+              ),
+            ),
+          ],
+        ),
+      ),
+    );
+  }
+
+  _buildReferenceFile(TalkInfo talkInfo) {
+    if (talkInfo.oversizeFile == true) {
+      return _buildOverSizeReference(talkInfo);
+    } else {
+      return _buildNormalReference(talkInfo);
+    }
+  }
+
+  Container _buildOverSizeReference(TalkInfo talkInfo) {
+    return Container(
+      margin: EdgeInsets.only(bottom: 14.h),
+      padding: EdgeInsets.only(left: 8.w, top: 8.h, right: 10.w, bottom: 8.h),
+      decoration: BoxDecoration(
+        borderRadius: BorderRadius.all(Radius.circular(8.w)),
+        border: Border.all(color: "#F0F0F0".color, width: 1.w),
+      ),
+      child: Column(
+        children: [
+          Row(
+            children: [
+              Text(talkInfo.title ?? '',
+                  style: TextStyle(
+                      fontWeight: FontWeight.bold,
+                      fontSize: 14.w,
+                      color: ColorName.primaryTextColor)),
+              const Spacer(),
+              Container(
+                margin: EdgeInsets.only(left: 8.w),
+                child: Image(
+                    image: Assets.images.iconReferenceChatDeleteFile.provider(),
+                    width: 18.w,
+                    height: 18.w),
+              ),
+            ],
+          ),
+          Container(
+            margin: EdgeInsets.only(top: 11.h),
+            child: Row(
+              children: [
+                Container(
+                  margin: EdgeInsets.only(right: 2.w),
+                  child: Image(
+                      image: Assets.images.iconReferenceChatFile.provider(),
+                      width: 16.w,
+                      height: 16.w),
+                ),
+                Text("谈话·超长内容",
+                    style: TextStyle(
+                        fontSize: 12.w, color: ColorName.tertiaryTextColor)),
+              ],
+            ),
+          )
+        ],
       ),
     );
   }
 
-  Widget buildTopGradient() {
+  _buildNormalReference(TalkInfo talkInfo) {
+    return Row(
+      children: [
+        Image(
+            image: Assets.images.iconReferenceChatArrow.provider(),
+            width: 16.w,
+            height: 16.w),
+        Container(
+          margin: EdgeInsets.only(right: 2.w, left: 4.w),
+          child: Image(
+              image: Assets.images.iconReferenceChatFile.provider(),
+              width: 16.w,
+              height: 16.w),
+        ),
+        Text(talkInfo.title ?? '',
+            overflow: TextOverflow.ellipsis,
+            maxLines: 1,
+            style: TextStyle(
+                fontSize: 12.w,
+                color: ColorName.primaryTextColor,
+                overflow: TextOverflow.ellipsis)),
+        const Spacer(),
+        Container(
+          margin: EdgeInsets.only(left: 8.w),
+          child: GestureDetector(
+            onTap: ()=> controller.onDeleteReference(),
+            child: Image(
+                image: Assets.images.iconReferenceChatDeleteFile.provider(),
+                width: 18.w,
+                height: 18.w),
+          ),
+        ),
+      ],
+    );
+  }
+
+  Widget _buildTopGradient() {
     return Container(
         width: 1.sw,
         height: 128.h,
@@ -290,7 +511,7 @@ class ChatPage extends BasePage<ChatController> {
         ));
   }
 
-  Widget buildBackgroundGradient() {
+  Widget _buildBackgroundGradient() {
     return Container(
       width: 1.sw,
       height: 1.sh,

+ 1 - 2
lib/module/home/view.dart

@@ -1,14 +1,13 @@
 import 'package:electronic_assistant/base/base_page.dart';
 import 'package:electronic_assistant/data/bean/talks.dart';
-import 'package:electronic_assistant/data/repositories/account_repository.dart';
 import 'package:electronic_assistant/dialog/rename_dialog.dart';
 import 'package:electronic_assistant/dialog/talk_delete_dialog.dart';
+import 'package:electronic_assistant/module/chat/view.dart';
 import 'package:electronic_assistant/popup/talk_popup.dart';
 import 'package:electronic_assistant/resource/assets.gen.dart';
 import 'package:electronic_assistant/resource/colors.gen.dart';
 import 'package:electronic_assistant/resource/string.gen.dart';
 import 'package:electronic_assistant/utils/expand.dart';
-import 'package:electronic_assistant/utils/toast_util.dart';
 import 'package:electronic_assistant/widget/pull_to_refresh.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_screenutil/flutter_screenutil.dart';

+ 10 - 6
lib/module/task/task_item_view.dart

@@ -3,6 +3,7 @@ import 'package:electronic_assistant/utils/expand.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_screenutil/flutter_screenutil.dart';
 import 'package:get/get.dart';
+
 import '../../resource/assets.gen.dart';
 import '../../resource/colors.gen.dart';
 import '../../resource/string.gen.dart';
@@ -57,12 +58,15 @@ Widget taskItemView(Agenda item,
                     color: ColorName.primaryTextColor)),
           ),
         ),
-        Container(
-          decoration: getPrimaryBtnDecoration(6),
-          padding: const EdgeInsets.symmetric(horizontal: 9, vertical: 4).w,
-          child: Text(
-            StringName.homeTalkThinking.tr,
-            style: TextStyle(fontSize: 13.sp, color: ColorName.white),
+        GestureDetector(
+          onTap: onThinkingClick,
+          child: Container(
+            decoration: getPrimaryBtnDecoration(6),
+            padding: const EdgeInsets.symmetric(horizontal: 9, vertical: 4).w,
+            child: Text(
+              StringName.homeTalkThinking.tr,
+              style: TextStyle(fontSize: 13.sp, color: ColorName.white),
+            ),
           ),
         )
       ],

+ 72 - 0
pubspec.lock

@@ -41,6 +41,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "2.11.0"
+  audio_session:
+    dependency: transitive
+    description:
+      name: audio_session
+      sha256: "343e83bc7809fbda2591a49e525d6b63213ade10c76f15813be9aed6657b3261"
+      url: "https://pub.dev"
+    source: hosted
+    version: "0.1.21"
   boolean_selector:
     dependency: transitive
     description:
@@ -169,6 +177,22 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "3.0.0"
+  connectivity_plus:
+    dependency: "direct main"
+    description:
+      name: connectivity_plus
+      sha256: "2056db5241f96cdc0126bd94459fc4cdc13876753768fc7a31c425e50a7177d0"
+      url: "https://pub.dev"
+    source: hosted
+    version: "6.0.5"
+  connectivity_plus_platform_interface:
+    dependency: transitive
+    description:
+      name: connectivity_plus_platform_interface
+      sha256: "42657c1715d48b167930d5f34d00222ac100475f73d10162ddf43e714932f204"
+      url: "https://pub.dev"
+    source: hosted
+    version: "2.0.1"
   convert:
     dependency: transitive
     description:
@@ -209,6 +233,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "1.2.0"
+  dbus:
+    dependency: transitive
+    description:
+      name: dbus
+      sha256: "365c771ac3b0e58845f39ec6deebc76e3276aa9922b0cc60840712094d9047ac"
+      url: "https://pub.dev"
+    source: hosted
+    version: "0.7.10"
   dio:
     dependency: "direct main"
     description:
@@ -432,6 +464,30 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "6.8.0"
+  just_audio:
+    dependency: "direct main"
+    description:
+      name: just_audio
+      sha256: d8e8aaf417d33e345299c17f6457f72bd4ba0c549dc34607abb5183a354edc4d
+      url: "https://pub.dev"
+    source: hosted
+    version: "0.9.40"
+  just_audio_platform_interface:
+    dependency: transitive
+    description:
+      name: just_audio_platform_interface
+      sha256: "0243828cce503c8366cc2090cefb2b3c871aa8ed2f520670d76fd47aa1ab2790"
+      url: "https://pub.dev"
+    source: hosted
+    version: "4.3.0"
+  just_audio_web:
+    dependency: transitive
+    description:
+      name: just_audio_web
+      sha256: b163878529d9b028c53a6972fcd58cae2405bcd11cbfcea620b6fb9f151429d6
+      url: "https://pub.dev"
+    source: hosted
+    version: "0.4.12"
   leak_tracker:
     dependency: transitive
     description:
@@ -552,6 +608,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "1.0.1"
+  nm:
+    dependency: transitive
+    description:
+      name: nm
+      sha256: "2c9aae4127bdc8993206464fcc063611e0e36e72018696cd9631023a31b24254"
+      url: "https://pub.dev"
+    source: hosted
+    version: "0.5.0"
   package_config:
     dependency: transitive
     description:
@@ -768,6 +832,14 @@ packages:
       url: "https://pub.dev"
     source: hosted
     version: "7.0.8"
+  rxdart:
+    dependency: transitive
+    description:
+      name: rxdart
+      sha256: "5c3004a4a8dbb94bd4bf5412a4def4acdaa12e12f269737a5751369e12d1a962"
+      url: "https://pub.dev"
+    source: hosted
+    version: "0.28.0"
   shelf:
     dependency: transitive
     description: