|
|
@ -339,14 +339,12 @@ class _AgentViewState extends State<AgentView> with WidgetsBindingObserver { |
|
|
), |
|
|
), |
|
|
), |
|
|
), |
|
|
child: Column( |
|
|
child: Column( |
|
|
mainAxisSize: MainAxisSize.min, |
|
|
|
|
|
children: [ |
|
|
children: [ |
|
|
// 图片预览区域 - 仅在图片输入模式下显示 |
|
|
// 图片预览区域 - 仅在图片输入模式下显示 |
|
|
Obx(() { |
|
|
Obx(() { |
|
|
if (controller.isImageInputActive.value && |
|
|
if (controller.isImageInputActive.value && |
|
|
controller.selectedImagePath.value != null) { |
|
|
controller.selectedImagePath.value != null) { |
|
|
return Column( |
|
|
return Column( |
|
|
mainAxisSize: MainAxisSize.min, |
|
|
|
|
|
children: [ |
|
|
children: [ |
|
|
// 图片预览和关闭按钮 |
|
|
// 图片预览和关闭按钮 |
|
|
Stack( |
|
|
Stack( |
|
|
@ -421,9 +419,7 @@ class _AgentViewState extends State<AgentView> with WidgetsBindingObserver { |
|
|
// 输入控件区域 - 包含输入行和展开的选项 |
|
|
// 输入控件区域 - 包含输入行和展开的选项 |
|
|
Column( |
|
|
Column( |
|
|
children: [ |
|
|
children: [ |
|
|
// 输入控件行 - 使用IntrinsicHeight确保按钮与输入框底部对齐 |
|
|
Row( |
|
|
IntrinsicHeight( |
|
|
|
|
|
child: Row( |
|
|
|
|
|
crossAxisAlignment: |
|
|
crossAxisAlignment: |
|
|
CrossAxisAlignment.end, // 所有元素底部对齐 |
|
|
CrossAxisAlignment.end, // 所有元素底部对齐 |
|
|
children: [ |
|
|
children: [ |
|
|
@ -438,6 +434,7 @@ class _AgentViewState extends State<AgentView> with WidgetsBindingObserver { |
|
|
child: Container( |
|
|
child: Container( |
|
|
width: 44.w, |
|
|
width: 44.w, |
|
|
height: 44.w, |
|
|
height: 44.w, |
|
|
|
|
|
margin: EdgeInsets.symmetric(vertical: 2.w), |
|
|
decoration: BoxDecoration( |
|
|
decoration: BoxDecoration( |
|
|
color: isDarkMode |
|
|
color: isDarkMode |
|
|
? Colors.grey[800] |
|
|
? Colors.grey[800] |
|
|
@ -473,8 +470,8 @@ class _AgentViewState extends State<AgentView> with WidgetsBindingObserver { |
|
|
overlayBuilder: (params) { |
|
|
overlayBuilder: (params) { |
|
|
return IntroOverlayBuilder.aiBuilder( |
|
|
return IntroOverlayBuilder.aiBuilder( |
|
|
params, |
|
|
params, |
|
|
controller.noviceGuideService |
|
|
controller |
|
|
.aiStepsList[ |
|
|
.noviceGuideService.aiStepsList[ |
|
|
controller.noviceGuideService |
|
|
controller.noviceGuideService |
|
|
.aiStep]['start'], |
|
|
.aiStep]['start'], |
|
|
buttonText: '确定输入', |
|
|
buttonText: '确定输入', |
|
|
@ -482,8 +479,7 @@ class _AgentViewState extends State<AgentView> with WidgetsBindingObserver { |
|
|
controller.textController.text = |
|
|
controller.textController.text = |
|
|
controller.noviceGuideService |
|
|
controller.noviceGuideService |
|
|
.aiStepsList[ |
|
|
.aiStepsList[ |
|
|
controller |
|
|
controller.noviceGuideService |
|
|
.noviceGuideService |
|
|
|
|
|
.aiStep]['input']; |
|
|
.aiStep]['input']; |
|
|
}, |
|
|
}, |
|
|
); |
|
|
); |
|
|
@ -492,16 +488,18 @@ class _AgentViewState extends State<AgentView> with WidgetsBindingObserver { |
|
|
controller.noviceGuideService |
|
|
controller.noviceGuideService |
|
|
.startAIGuide(); |
|
|
.startAIGuide(); |
|
|
}, |
|
|
}, |
|
|
builder: (BuildContext context, |
|
|
builder: |
|
|
GlobalKey key) => |
|
|
(BuildContext context, GlobalKey key) => |
|
|
Container( |
|
|
Container( |
|
|
key: key, |
|
|
key: key, |
|
|
constraints: BoxConstraints( |
|
|
constraints: BoxConstraints( |
|
|
minHeight: 44.h, |
|
|
minHeight: 48.w, |
|
|
maxHeight: 120.h, |
|
|
|
|
|
), |
|
|
), |
|
|
padding: EdgeInsets.symmetric( |
|
|
padding: EdgeInsets.symmetric( |
|
|
horizontal: 16.w), |
|
|
horizontal: 16.w, |
|
|
|
|
|
vertical: 5.w, |
|
|
|
|
|
), |
|
|
|
|
|
alignment: Alignment.center, |
|
|
decoration: BoxDecoration( |
|
|
decoration: BoxDecoration( |
|
|
color: isDarkMode |
|
|
color: isDarkMode |
|
|
? Colors.grey[800] |
|
|
? Colors.grey[800] |
|
|
@ -515,36 +513,26 @@ class _AgentViewState extends State<AgentView> with WidgetsBindingObserver { |
|
|
width: 1.w, |
|
|
width: 1.w, |
|
|
), |
|
|
), |
|
|
), |
|
|
), |
|
|
child: Row( |
|
|
|
|
|
crossAxisAlignment: CrossAxisAlignment |
|
|
|
|
|
.end, // 对齐到底部,实现向上扩展 |
|
|
|
|
|
children: [ |
|
|
|
|
|
Expanded( |
|
|
|
|
|
child: Obx(() { |
|
|
child: Obx(() { |
|
|
// 图片模式下使用更高的输入框 |
|
|
// 图片模式下使用更高的输入框 |
|
|
final isImageActive = controller |
|
|
final isImageActive = |
|
|
.isImageInputActive.value; |
|
|
controller.isImageInputActive.value; |
|
|
|
|
|
|
|
|
return TextField( |
|
|
return TextField( |
|
|
controller: |
|
|
controller: controller.textController, |
|
|
controller.textController, |
|
|
|
|
|
maxLines: isImageActive |
|
|
maxLines: isImageActive |
|
|
? 3 |
|
|
? 3 |
|
|
: 5, // 设置合理的最大行数 |
|
|
: 5, // 设置合理的最大行数 |
|
|
minLines: |
|
|
minLines: isImageActive ? 2 : 1, |
|
|
isImageActive ? 2 : 1, |
|
|
keyboardType: |
|
|
keyboardType: TextInputType |
|
|
TextInputType.multiline, // 启用多行键盘 |
|
|
.multiline, // 启用多行键盘 |
|
|
|
|
|
textInputAction: |
|
|
textInputAction: |
|
|
TextInputAction |
|
|
TextInputAction.newline, // 支持回车换行 |
|
|
.newline, // 支持回车换行 |
|
|
|
|
|
onTap: () { |
|
|
onTap: () { |
|
|
// 当点击输入框时,如果'+'选项已展开,则收缩 |
|
|
// 当点击输入框时,如果'+'选项已展开,则收缩 |
|
|
if (controller |
|
|
if (controller |
|
|
.isPlusOptionsExpanded |
|
|
.isPlusOptionsExpanded.value) { |
|
|
.value) { |
|
|
controller.collapsePlusOptions(); |
|
|
controller |
|
|
|
|
|
.collapsePlusOptions(); |
|
|
|
|
|
} |
|
|
} |
|
|
}, |
|
|
}, |
|
|
style: TextStyle( |
|
|
style: TextStyle( |
|
|
@ -557,16 +545,15 @@ class _AgentViewState extends State<AgentView> with WidgetsBindingObserver { |
|
|
hintText: isImageActive |
|
|
hintText: isImageActive |
|
|
? 'addQuestionAboutImage' |
|
|
? 'addQuestionAboutImage' |
|
|
.tr // 添加对图片的问题或描述... |
|
|
.tr // 添加对图片的问题或描述... |
|
|
: 'inputMessage' |
|
|
: 'inputMessage'.tr, // 输入消息... |
|
|
.tr, // 输入消息... |
|
|
|
|
|
hintStyle: TextStyle( |
|
|
hintStyle: TextStyle( |
|
|
color: Colors.grey[500], |
|
|
color: Colors.grey[500], |
|
|
fontSize: 15.sp, |
|
|
fontSize: 15.sp, |
|
|
), |
|
|
), |
|
|
filled: false, |
|
|
filled: false, |
|
|
|
|
|
isDense: true, |
|
|
border: InputBorder.none, |
|
|
border: InputBorder.none, |
|
|
focusedBorder: |
|
|
focusedBorder: OutlineInputBorder( |
|
|
OutlineInputBorder( |
|
|
|
|
|
borderSide: BorderSide( |
|
|
borderSide: BorderSide( |
|
|
color: isDarkMode |
|
|
color: isDarkMode |
|
|
? Colors.grey[800]! |
|
|
? Colors.grey[800]! |
|
|
@ -574,21 +561,13 @@ class _AgentViewState extends State<AgentView> with WidgetsBindingObserver { |
|
|
width: 1.w, |
|
|
width: 1.w, |
|
|
), |
|
|
), |
|
|
), |
|
|
), |
|
|
contentPadding: |
|
|
contentPadding: EdgeInsets.zero, |
|
|
EdgeInsets.symmetric( |
|
|
|
|
|
vertical: |
|
|
|
|
|
isImageActive |
|
|
|
|
|
? 12.h |
|
|
|
|
|
: 8.h), |
|
|
|
|
|
), |
|
|
), |
|
|
onSubmitted: (_) => |
|
|
onSubmitted: (_) => |
|
|
controller.sendMessage(), |
|
|
controller.sendMessage(), |
|
|
); |
|
|
); |
|
|
}), |
|
|
}), |
|
|
), |
|
|
), |
|
|
], |
|
|
|
|
|
), |
|
|
|
|
|
), |
|
|
|
|
|
); |
|
|
); |
|
|
} else { |
|
|
} else { |
|
|
Timer? _holdTimer; // 增加延迟触发的计时器 |
|
|
Timer? _holdTimer; // 增加延迟触发的计时器 |
|
|
@ -640,7 +619,7 @@ class _AgentViewState extends State<AgentView> with WidgetsBindingObserver { |
|
|
controller.isListening.value; |
|
|
controller.isListening.value; |
|
|
|
|
|
|
|
|
return Container( |
|
|
return Container( |
|
|
height: 52.h, |
|
|
height: 48.w, |
|
|
padding: EdgeInsets.symmetric( |
|
|
padding: EdgeInsets.symmetric( |
|
|
horizontal: 16.w), |
|
|
horizontal: 16.w), |
|
|
decoration: BoxDecoration( |
|
|
decoration: BoxDecoration( |
|
|
@ -660,9 +639,8 @@ class _AgentViewState extends State<AgentView> with WidgetsBindingObserver { |
|
|
? Colors.grey[800]! |
|
|
? Colors.grey[800]! |
|
|
: Colors.grey |
|
|
: Colors.grey |
|
|
.withOpacity(0.1)), |
|
|
.withOpacity(0.1)), |
|
|
width: isPushToTalkActive |
|
|
width: |
|
|
? 2.w |
|
|
isPushToTalkActive ? 2.w : 1.w, |
|
|
: 1.w, |
|
|
|
|
|
), |
|
|
), |
|
|
), |
|
|
), |
|
|
child: Row( |
|
|
child: Row( |
|
|
@ -703,11 +681,9 @@ class _AgentViewState extends State<AgentView> with WidgetsBindingObserver { |
|
|
fontSize: 14, |
|
|
fontSize: 14, |
|
|
fontWeight: |
|
|
fontWeight: |
|
|
FontWeight.w500, |
|
|
FontWeight.w500, |
|
|
color: |
|
|
color: isPushToTalkActive |
|
|
isPushToTalkActive |
|
|
|
|
|
? Colors.blue |
|
|
? Colors.blue |
|
|
: Colors |
|
|
: Colors.grey[600], |
|
|
.grey[600], |
|
|
|
|
|
), |
|
|
), |
|
|
), |
|
|
), |
|
|
], |
|
|
], |
|
|
@ -733,8 +709,8 @@ class _AgentViewState extends State<AgentView> with WidgetsBindingObserver { |
|
|
onHighlightWidgetTap: () async { |
|
|
onHighlightWidgetTap: () async { |
|
|
await controller |
|
|
await controller |
|
|
.noviceGuideService.aiStepsList[ |
|
|
.noviceGuideService.aiStepsList[ |
|
|
controller.noviceGuideService |
|
|
controller.noviceGuideService.aiStep] |
|
|
.aiStep]['method'](); |
|
|
['method'](); |
|
|
widgetParams!.onNext!(); |
|
|
widgetParams!.onNext!(); |
|
|
controller.sendMessage(); |
|
|
controller.sendMessage(); |
|
|
}, |
|
|
}, |
|
|
@ -755,21 +731,19 @@ class _AgentViewState extends State<AgentView> with WidgetsBindingObserver { |
|
|
controller.hasTextInput.value; |
|
|
controller.hasTextInput.value; |
|
|
final hasImage = |
|
|
final hasImage = |
|
|
controller.isImageInputActive.value; |
|
|
controller.isImageInputActive.value; |
|
|
final shouldShowSend = |
|
|
final shouldShowSend = hasText || hasImage; |
|
|
hasText || hasImage; |
|
|
final shouldShowExpand = |
|
|
final shouldShowExpand = controller |
|
|
controller.shouldShowExpandButton.value; |
|
|
.shouldShowExpandButton.value; |
|
|
|
|
|
|
|
|
|
|
|
if (shouldShowSend) { |
|
|
if (shouldShowSend) { |
|
|
// 显示发送按钮(可能还有展开按钮) |
|
|
// 显示发送按钮(可能还有展开按钮) |
|
|
return Column( |
|
|
return Column( |
|
|
mainAxisSize: MainAxisSize.min, |
|
|
|
|
|
children: [ |
|
|
children: [ |
|
|
// 展开按钮(在发送按钮上方) |
|
|
// 展开按钮(在发送按钮上方) |
|
|
if (shouldShowExpand && hasText) |
|
|
if (shouldShowExpand && hasText) |
|
|
Padding( |
|
|
Padding( |
|
|
padding: EdgeInsets.only( |
|
|
padding: |
|
|
bottom: 40.h), |
|
|
EdgeInsets.only(bottom: 40.h), |
|
|
child: GestureDetector( |
|
|
child: GestureDetector( |
|
|
onTap: () { |
|
|
onTap: () { |
|
|
// 打开底部弹出编辑模式 |
|
|
// 打开底部弹出编辑模式 |
|
|
@ -816,11 +790,12 @@ class _AgentViewState extends State<AgentView> with WidgetsBindingObserver { |
|
|
child: Container( |
|
|
child: Container( |
|
|
width: 44.w, |
|
|
width: 44.w, |
|
|
height: 44.w, |
|
|
height: 44.w, |
|
|
|
|
|
margin: EdgeInsets.symmetric( |
|
|
|
|
|
vertical: 2.w), |
|
|
decoration: BoxDecoration( |
|
|
decoration: BoxDecoration( |
|
|
color: primaryColor, |
|
|
color: primaryColor, |
|
|
borderRadius: |
|
|
borderRadius: |
|
|
BorderRadius.circular( |
|
|
BorderRadius.circular(22.w), |
|
|
22.w), |
|
|
|
|
|
), |
|
|
), |
|
|
child: Icon( |
|
|
child: Icon( |
|
|
Icons.send, |
|
|
Icons.send, |
|
|
@ -843,6 +818,8 @@ class _AgentViewState extends State<AgentView> with WidgetsBindingObserver { |
|
|
child: Container( |
|
|
child: Container( |
|
|
width: 44.w, |
|
|
width: 44.w, |
|
|
height: 44.w, |
|
|
height: 44.w, |
|
|
|
|
|
margin: EdgeInsets.symmetric( |
|
|
|
|
|
vertical: 2.w), |
|
|
decoration: BoxDecoration( |
|
|
decoration: BoxDecoration( |
|
|
color: isDarkMode |
|
|
color: isDarkMode |
|
|
? Colors.grey[800] |
|
|
? Colors.grey[800] |
|
|
@ -869,7 +846,6 @@ class _AgentViewState extends State<AgentView> with WidgetsBindingObserver { |
|
|
}), |
|
|
}), |
|
|
], |
|
|
], |
|
|
), |
|
|
), |
|
|
), |
|
|
|
|
|
|
|
|
|
|
|
// 展开的'+'选择选项 |
|
|
// 展开的'+'选择选项 |
|
|
Obx(() { |
|
|
Obx(() { |
|
|
|