Browse Source

[new]修改聊天AI回复框&增加AI生成标签

zk 1 year ago
parent
commit
ce7a1b99c4

+ 1 - 0
assets/string/base/string.xml

@@ -141,4 +141,5 @@
     <string name="dialog_send_friend">发送给朋友</string>
     <string name="translating">正在翻译...</string>
     <string name="audio_picker_all_file">全部文件</string>
+    <string name="chat_item_ai_tag">内容由AI生成</string>
 </resources>

+ 8 - 0
lib/module/chat/controller.dart

@@ -35,6 +35,8 @@ class ChatController extends BaseController {
   final Rxn<TalkBean> talkInfo = Rxn<TalkBean>();
   final Rxn<Agenda> agenda = Rxn<Agenda>();
 
+  final Rxn<String> chatAiTagId = Rxn<String>();
+
   ChatFromType? fromType;
 
   bool isConsumeElectric = false;
@@ -124,6 +126,11 @@ class ChatController extends BaseController {
         .whenComplete(() => refreshController.loadComplete())
         .whenComplete(() {
       if (isEmpty) {
+        for (var element in chatItems.reversed) {
+          if (element is ChatItem && element.role == "assistant") {
+            chatAiTagId.value = element.id;
+          }
+        }
         _scrollToBottom();
       }
     });
@@ -197,6 +204,7 @@ class ChatController extends BaseController {
           }
           isConsumeElectric = true;
           progressingChatItem.append(delta.content ?? "");
+          chatAiTagId.value = progressingChatItem.id;
         } catch (ignore) {}
       }, onDone: () {
         progressingChatItem.content = progressingChatItem.streamContent.value;

+ 145 - 48
lib/module/chat/view.dart

@@ -6,6 +6,7 @@ import 'package:electronic_assistant/data/bean/reference_chat_item.dart';
 import 'package:electronic_assistant/module/browser/view.dart';
 import 'package:electronic_assistant/module/chat/controller.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:flutter/cupertino.dart';
 import 'package:flutter/material.dart';
@@ -253,7 +254,8 @@ class ChatPage extends BasePage<ChatController> {
       alignment: Alignment.centerLeft,
       child: IntrinsicWidth(
         child: progressingChatItem == null
-            ? _buildAssistantChatItemContent(null, chatItem.content)
+            ? _buildAssistantChatItemContent(
+                null, chatItem.content, chatItem.id)
             : Obx(() {
                 bool? isStreamStarted = progressingChatItem == null
                     ? null
@@ -264,59 +266,154 @@ class ChatPage extends BasePage<ChatController> {
                     isStreamStarted,
                     progressingChatItem!.isFailed.value
                         ? progressingChatItem.error.value
-                        : progressingChatItem.streamContent.value);
+                        : progressingChatItem.streamContent.value,
+                    chatItem.id);
               }),
       ),
     );
   }
 
-  Container _buildAssistantChatItemContent(
-      bool? isStreamStarted, String content) {
-    return Container(
-        padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 8.h),
-        margin: EdgeInsets.symmetric(vertical: 10.h),
-        alignment: Alignment.centerLeft,
-        constraints: BoxConstraints(
-          maxWidth: 0.78.sw,
-        ),
-        decoration: BoxDecoration(
-            border: isStreamStarted == null || isStreamStarted == true
-                ? null
-                : Border.all(color: ColorName.colorPrimary, width: 1.w),
-            color: ColorName.white,
-            borderRadius: BorderRadius.only(
-                topRight: Radius.circular(20.w),
-                bottomRight: Radius.circular(20.w),
-                bottomLeft: Radius.circular(20.w))),
-        child: isStreamStarted != null && isStreamStarted == false
-            ? Lottie.asset("assets/anim/anim_chat_response_loading.zip",
-                width: 46.w, height: 20.w)
-            : SelectionArea(
-                child: HtmlWidget(
-                  onTapUrl: (url) {
-                    BrowserPage.start(url);
-                    return true;
-                  },
-                  md.markdownToHtml(content, inlineSyntaxes: [
-                    md.InlineHtmlSyntax(),
-                    md.StrikethroughSyntax(),
-                    md.EmojiSyntax(),
-                    md.ColorSwatchSyntax(),
-                    md.AutolinkExtensionSyntax(),
-                    md.ImageSyntax()
-                  ], blockSyntaxes: [
-                    const md.FencedCodeBlockSyntax(),
-                    const md.HeaderWithIdSyntax(),
-                    const md.SetextHeaderWithIdSyntax(),
-                    const md.UnorderedListWithCheckboxSyntax(),
-                    const md.OrderedListWithCheckboxSyntax(),
-                    const md.FootnoteDefSyntax(),
-                    const md.AlertBlockSyntax(),
-                  ]),
-                  textStyle: TextStyle(
-                      fontSize: 14.w, color: ColorName.primaryTextColor),
+  Widget _buildAssistantChatItemContent(
+      bool? isStreamStarted, String content, String id) {
+    return Column(
+      crossAxisAlignment: CrossAxisAlignment.start,
+      children: [
+        SizedBox(height: 10.h),
+        isStreamStarted != null && isStreamStarted == false
+            ? Container(
+                padding: const EdgeInsets.all(1),
+                decoration: BoxDecoration(
+                    color: ColorName.colorPrimary,
+                    gradient: LinearGradient(
+                      colors: ['#B57AFF'.toColor(), '#4466FF'.toColor()],
+                      stops: const [0, 1.0],
+                      begin: Alignment.topLeft,
+                      end: Alignment.bottomRight,
+                    ),
+                    borderRadius: BorderRadius.only(
+                        topRight: Radius.circular(20.w),
+                        bottomRight: Radius.circular(20.w),
+                        bottomLeft: Radius.circular(20.w))),
+                child: Container(
+                    decoration: BoxDecoration(
+                        color: ColorName.white,
+                        borderRadius: BorderRadius.only(
+                            topRight: Radius.circular(20.w),
+                            bottomRight: Radius.circular(20.w),
+                            bottomLeft: Radius.circular(20.w))),
+                    padding:
+                        EdgeInsets.symmetric(horizontal: 12.w, vertical: 8.h),
+                    child: Lottie.asset(
+                        "assets/anim/anim_chat_response_loading.zip",
+                        width: 46.w,
+                        height: 20.w)),
+              )
+            : Container(
+                decoration: BoxDecoration(
+                    color: ColorName.white,
+                    border: Border.all(color: '#ECECEC'.color, width: 1.w),
+                    borderRadius: BorderRadius.only(
+                        topRight: Radius.circular(20.w),
+                        bottomRight: Radius.circular(20.w),
+                        bottomLeft: Radius.circular(20.w))),
+                padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 8.h),
+                alignment: Alignment.centerLeft,
+                constraints: BoxConstraints(
+                  maxWidth: 0.78.sw,
                 ),
-              ));
+                child: SelectionArea(
+                  child: HtmlWidget(
+                    onTapUrl: (url) {
+                      BrowserPage.start(url);
+                      return true;
+                    },
+                    md.markdownToHtml(content, inlineSyntaxes: [
+                      md.InlineHtmlSyntax(),
+                      md.StrikethroughSyntax(),
+                      md.EmojiSyntax(),
+                      md.ColorSwatchSyntax(),
+                      md.AutolinkExtensionSyntax(),
+                      md.ImageSyntax()
+                    ], blockSyntaxes: [
+                      const md.FencedCodeBlockSyntax(),
+                      const md.HeaderWithIdSyntax(),
+                      const md.SetextHeaderWithIdSyntax(),
+                      const md.UnorderedListWithCheckboxSyntax(),
+                      const md.OrderedListWithCheckboxSyntax(),
+                      const md.FootnoteDefSyntax(),
+                      const md.AlertBlockSyntax(),
+                    ]),
+                    textStyle: TextStyle(
+                        fontSize: 14.w, color: ColorName.primaryTextColor),
+                  ),
+                ),
+              ),
+        // Container(
+        //     padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 8.h),
+        //     alignment: Alignment.centerLeft,
+        //     constraints: BoxConstraints(
+        //       maxWidth: 0.78.sw,
+        //     ),
+        //     decoration: BoxDecoration(
+        //         border: isStreamStarted == null || isStreamStarted == true
+        //             ? null
+        //             : Border.all(color: ColorName.colorPrimary, width: 1.w),
+        //         color: ColorName.white,
+        //         borderRadius: BorderRadius.only(
+        //             topRight: Radius.circular(20.w),
+        //             bottomRight: Radius.circular(20.w),
+        //             bottomLeft: Radius.circular(20.w))),
+        //     child: isStreamStarted != null && isStreamStarted == false
+        //         ? Lottie.asset("assets/anim/anim_chat_response_loading.zip",
+        //             width: 46.w, height: 20.w)
+        //         : SelectionArea(
+        //             child: HtmlWidget(
+        //               onTapUrl: (url) {
+        //                 BrowserPage.start(url);
+        //                 return true;
+        //               },
+        //               md.markdownToHtml(content, inlineSyntaxes: [
+        //                 md.InlineHtmlSyntax(),
+        //                 md.StrikethroughSyntax(),
+        //                 md.EmojiSyntax(),
+        //                 md.ColorSwatchSyntax(),
+        //                 md.AutolinkExtensionSyntax(),
+        //                 md.ImageSyntax()
+        //               ], blockSyntaxes: [
+        //                 const md.FencedCodeBlockSyntax(),
+        //                 const md.HeaderWithIdSyntax(),
+        //                 const md.SetextHeaderWithIdSyntax(),
+        //                 const md.UnorderedListWithCheckboxSyntax(),
+        //                 const md.OrderedListWithCheckboxSyntax(),
+        //                 const md.FootnoteDefSyntax(),
+        //                 const md.AlertBlockSyntax(),
+        //               ]),
+        //               textStyle: TextStyle(
+        //                   fontSize: 14.w, color: ColorName.primaryTextColor),
+        //             ),
+        //           )),
+        Obx(() {
+          return Visibility(
+            visible: id == controller.chatAiTagId.value,
+            child: Container(
+              margin: EdgeInsets.only(top: 6.h),
+              padding: EdgeInsets.symmetric(horizontal: 6.w, vertical: 3.w),
+              decoration: BoxDecoration(
+                  borderRadius: BorderRadius.all(Radius.circular(12.w)),
+                  color: "#EFEEF1".color),
+              child: Text(
+                StringName.chatItemAiTag.tr,
+                style: TextStyle(
+                    height: 1,
+                    fontSize: 10.sp,
+                    color: ColorName.tertiaryTextColor),
+              ),
+            ),
+          );
+        }),
+        SizedBox(height: 10.h)
+      ],
+    );
   }
 
   Widget _buildUserChatItem(BuildContext context, ChatItem chatItem) {

+ 6 - 6
lib/module/files/search/view.dart

@@ -27,7 +27,7 @@ class FileSearchPage extends BasePage<FileSearchController> {
           padding: EdgeInsets.only(bottom: 8.w),
           child: GestureDetector(
             onTap: () {
-              if (talkBean.status == TalkStatus.analysisSuccess) {
+              if (talkBean.status.value == TalkStatus.analysisSuccess) {
                 Get.back(result: talkBean);
               } else {
                 ToastUtil.showToast("谈话未分析,请选择其他文件");
@@ -43,8 +43,8 @@ class FileSearchPage extends BasePage<FileSearchController> {
                 crossAxisAlignment: CrossAxisAlignment.start,
                 children: [
                   Image(
-                      image: (talkBean.status == TalkStatus.analysing ||
-                              talkBean.status == TalkStatus.waitAnalysis)
+                      image: (talkBean.status.value == TalkStatus.analysing ||
+                              talkBean.status.value == TalkStatus.waitAnalysis)
                           ? Assets.images.iconTalkAnalysis.provider()
                           : Assets.images.iconFilesFile.provider(),
                       width: 28.w,
@@ -67,9 +67,9 @@ class FileSearchPage extends BasePage<FileSearchController> {
                             overflow: TextOverflow.ellipsis,
                             style: TextStyle(
                                 fontSize: 12.sp,
-                                color:
-                                    talkBean.status == TalkStatus.analysisFail
-                                        ? "#F5574E".toColor()
+                                color: talkBean.status.value ==
+                                        TalkStatus.analysisFail
+                                    ? "#F5574E".toColor()
                                         : ColorName.secondaryTextColor)),
                         Container(
                           margin: EdgeInsets.only(top: 6.w),

+ 0 - 2
lib/module/files/view.dart

@@ -1,11 +1,9 @@
 import 'package:electronic_assistant/base/base_page.dart';
 import 'package:electronic_assistant/data/bean/talks.dart';
-import 'package:electronic_assistant/dialog/alert_dialog.dart';
 import 'package:electronic_assistant/module/files/controller.dart';
 import 'package:electronic_assistant/module/talk/view.dart';
 import 'package:electronic_assistant/resource/colors.gen.dart';
 import 'package:electronic_assistant/resource/string.gen.dart';
-import 'package:electronic_assistant/router/app_pages.dart';
 import 'package:electronic_assistant/utils/expand.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_screenutil/flutter_screenutil.dart';