|
|
|
@ -341,80 +341,127 @@ class _AgentViewState extends State<AgentView> with WidgetsBindingObserver { |
|
|
|
child: Column( |
|
|
|
children: [ |
|
|
|
// 图片预览区域 - 仅在图片输入模式下显示 |
|
|
|
Obx(() { |
|
|
|
if (controller.isImageInputActive.value && |
|
|
|
controller.selectedImagePath.value != null) { |
|
|
|
return Column( |
|
|
|
children: [ |
|
|
|
// 图片预览和关闭按钮 |
|
|
|
Stack( |
|
|
|
children: [ |
|
|
|
ClipRRect( |
|
|
|
borderRadius: BorderRadius.circular(12.w), |
|
|
|
child: Image.file( |
|
|
|
File(controller.selectedImagePath.value!), |
|
|
|
height: 150.h, |
|
|
|
width: double.infinity, |
|
|
|
fit: BoxFit.cover, |
|
|
|
Obx( |
|
|
|
() { |
|
|
|
if (controller.isImageInputActive.value && |
|
|
|
controller.selectedImagePath.value != null) { |
|
|
|
return Column( |
|
|
|
children: [ |
|
|
|
// 图片预览和关闭按钮 |
|
|
|
Stack( |
|
|
|
children: [ |
|
|
|
ClipRRect( |
|
|
|
borderRadius: BorderRadius.circular(12.w), |
|
|
|
child: Image.file( |
|
|
|
File(controller.selectedImagePath.value!), |
|
|
|
height: 150.h, |
|
|
|
width: double.infinity, |
|
|
|
fit: BoxFit.cover, |
|
|
|
), |
|
|
|
), |
|
|
|
), |
|
|
|
Positioned( |
|
|
|
top: 8.h, |
|
|
|
right: 8.w, |
|
|
|
child: GestureDetector( |
|
|
|
onTap: () => controller.clearImageInput(), |
|
|
|
child: Container( |
|
|
|
padding: EdgeInsets.all(4.w), |
|
|
|
decoration: BoxDecoration( |
|
|
|
color: Colors.black.withOpacity(0.6), |
|
|
|
shape: BoxShape.circle, |
|
|
|
), |
|
|
|
child: Icon( |
|
|
|
Icons.close, |
|
|
|
color: Colors.white, |
|
|
|
size: 16.sp, |
|
|
|
Positioned( |
|
|
|
top: 8.h, |
|
|
|
right: 8.w, |
|
|
|
child: GestureDetector( |
|
|
|
onTap: () => controller.clearImageInput(), |
|
|
|
child: Container( |
|
|
|
padding: EdgeInsets.all(4.w), |
|
|
|
decoration: BoxDecoration( |
|
|
|
color: Colors.black.withOpacity(0.6), |
|
|
|
shape: BoxShape.circle, |
|
|
|
), |
|
|
|
child: Icon( |
|
|
|
Icons.close, |
|
|
|
color: Colors.white, |
|
|
|
size: 16.sp, |
|
|
|
), |
|
|
|
), |
|
|
|
), |
|
|
|
), |
|
|
|
), |
|
|
|
], |
|
|
|
), |
|
|
|
|
|
|
|
// 预设提示选项 |
|
|
|
SizedBox(height: 12.h), |
|
|
|
SingleChildScrollView( |
|
|
|
scrollDirection: Axis.horizontal, |
|
|
|
child: Row( |
|
|
|
children: [ |
|
|
|
_buildPromptChip( |
|
|
|
context: context, |
|
|
|
label: 'summarizeImageContent'.tr, //总结图片内容 |
|
|
|
onTap: () => controller.summarizeImage(), |
|
|
|
), |
|
|
|
SizedBox(width: 8.w), |
|
|
|
_buildPromptChip( |
|
|
|
context: context, |
|
|
|
label: 'extractImageText'.tr, //抽取图像文字 |
|
|
|
onTap: () => |
|
|
|
controller.extractTextFromImage(), |
|
|
|
), |
|
|
|
SizedBox(width: 8.w), |
|
|
|
_buildPromptChip( |
|
|
|
context: context, |
|
|
|
label: 'translateImageText'.tr, //翻译图像文字 |
|
|
|
onTap: () => |
|
|
|
controller.translateImageText(), |
|
|
|
), |
|
|
|
], |
|
|
|
), |
|
|
|
), |
|
|
|
SizedBox(height: 12.h), |
|
|
|
], |
|
|
|
); |
|
|
|
} else { |
|
|
|
return const SizedBox.shrink(); |
|
|
|
} |
|
|
|
}), |
|
|
|
|
|
|
|
// 预设提示选项 |
|
|
|
SizedBox(height: 12.h), |
|
|
|
SingleChildScrollView( |
|
|
|
scrollDirection: Axis.horizontal, |
|
|
|
child: Row( |
|
|
|
children: [ |
|
|
|
_buildPromptChip( |
|
|
|
context: context, |
|
|
|
label: |
|
|
|
'summarizeImageContent'.tr, //总结图片内容 |
|
|
|
onTap: () => controller.summarizeImage(), |
|
|
|
), |
|
|
|
SizedBox(width: 8.w), |
|
|
|
_buildPromptChip( |
|
|
|
context: context, |
|
|
|
label: 'extractImageText'.tr, //抽取图像文字 |
|
|
|
onTap: () => |
|
|
|
controller.extractTextFromImage(), |
|
|
|
), |
|
|
|
SizedBox(width: 8.w), |
|
|
|
_buildPromptChip( |
|
|
|
context: context, |
|
|
|
label: 'translateImageText'.tr, //翻译图像文字 |
|
|
|
onTap: () => |
|
|
|
controller.translateImageText(), |
|
|
|
), |
|
|
|
], |
|
|
|
), |
|
|
|
), |
|
|
|
SizedBox(height: 12.h), |
|
|
|
], |
|
|
|
); |
|
|
|
} else if (controller.isTextInputMode.value && |
|
|
|
!controller.hasTextInput.value) { |
|
|
|
// 文本输入模式下,且输入框为空 |
|
|
|
return Column( |
|
|
|
children: [ |
|
|
|
SingleChildScrollView( |
|
|
|
scrollDirection: Axis.horizontal, |
|
|
|
child: Row( |
|
|
|
children: [ |
|
|
|
_buildPromptChip( |
|
|
|
context: context, |
|
|
|
label: 'presetMusic'.tr, // 来点音乐 |
|
|
|
onTap: () => controller |
|
|
|
.preSetPromptAction('Music')), |
|
|
|
SizedBox(width: 8.w), |
|
|
|
_buildPromptChip( |
|
|
|
context: context, |
|
|
|
label: 'presetNavigation'.tr, // 导航 |
|
|
|
onTap: () => |
|
|
|
controller.preSetPromptAction( |
|
|
|
'Navigation')), |
|
|
|
SizedBox(width: 8.w), |
|
|
|
_buildPromptChip( |
|
|
|
context: context, |
|
|
|
label: 'presetWeather'.tr, // 天气 |
|
|
|
onTap: () => controller |
|
|
|
.preSetPromptAction('Weather')), |
|
|
|
SizedBox(width: 8.w), |
|
|
|
_buildPromptChip( |
|
|
|
context: context, |
|
|
|
label: 'presetNews'.tr, // 新闻 |
|
|
|
onTap: () => controller |
|
|
|
.preSetPromptAction('News')), |
|
|
|
SizedBox(width: 8.w), |
|
|
|
_buildPromptChip( |
|
|
|
context: context, |
|
|
|
label: 'presetFood'.tr, // 美食 |
|
|
|
onTap: () => controller |
|
|
|
.preSetPromptAction('Food')), |
|
|
|
], |
|
|
|
)), |
|
|
|
SizedBox(height: 12.h), |
|
|
|
], |
|
|
|
); |
|
|
|
} else { |
|
|
|
return const SizedBox.shrink(); |
|
|
|
} |
|
|
|
}, |
|
|
|
), |
|
|
|
|
|
|
|
// 输入控件区域 - 包含输入行和展开的选项 |
|
|
|
Column( |
|
|
|
|