Browse Source

优化按住说话的输入控件布局

weicu
lxm 1 year ago
parent
commit
ff8826841c
  1. 138
      lib/modules/agent/views/agent_view.dart

138
lib/modules/agent/views/agent_view.dart

@ -197,8 +197,8 @@ class _AgentViewState extends State<AgentView> with WidgetsBindingObserver {
controller: controller.scrollController, controller: controller.scrollController,
shrinkWrap: true, shrinkWrap: true,
reverse: true, reverse: true,
padding: padding: const EdgeInsets.symmetric(
const EdgeInsets.symmetric(vertical: 16, horizontal: 16), vertical: 16, horizontal: 16),
itemCount: controller.messages.length, itemCount: controller.messages.length,
itemBuilder: (context, index) { itemBuilder: (context, index) {
final message = controller final message = controller
@ -206,7 +206,8 @@ class _AgentViewState extends State<AgentView> with WidgetsBindingObserver {
return Padding( return Padding(
padding: const EdgeInsets.only(bottom: 8), padding: const EdgeInsets.only(bottom: 8),
child: GestureDetector( child: GestureDetector(
onLongPressStart: (LongPressStartDetails details) { onLongPressStart:
(LongPressStartDetails details) {
messageActionController.onLongPressMessage( messageActionController.onLongPressMessage(
context, isDarkMode, details, message); context, isDarkMode, details, message);
}, },
@ -228,7 +229,8 @@ class _AgentViewState extends State<AgentView> with WidgetsBindingObserver {
// 输入区域 // 输入区域
Container( Container(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), padding:
const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
decoration: BoxDecoration( decoration: BoxDecoration(
color: backgroundColor, color: backgroundColor,
boxShadow: [ boxShadow: [
@ -304,13 +306,15 @@ class _AgentViewState extends State<AgentView> with WidgetsBindingObserver {
_buildPromptChip( _buildPromptChip(
context: context, context: context,
label: '抽取图像文字'.tr, label: '抽取图像文字'.tr,
onTap: () => controller.extractTextFromImage(), onTap: () =>
controller.extractTextFromImage(),
), ),
const SizedBox(width: 8), const SizedBox(width: 8),
_buildPromptChip( _buildPromptChip(
context: context, context: context,
label: '翻译图像文字'.tr, label: '翻译图像文字'.tr,
onTap: () => controller.translateImageText(), onTap: () =>
controller.translateImageText(),
), ),
], ],
), ),
@ -329,11 +333,13 @@ class _AgentViewState extends State<AgentView> with WidgetsBindingObserver {
// 输入控件行 - 使用IntrinsicHeight确保按钮与输入框底部对齐 // 输入控件行 - 使用IntrinsicHeight确保按钮与输入框底部对齐
IntrinsicHeight( IntrinsicHeight(
child: Row( child: Row(
crossAxisAlignment: CrossAxisAlignment.end, // 所有元素底部对齐 crossAxisAlignment:
CrossAxisAlignment.end, // 所有元素底部对齐
children: [ children: [
// 键盘/语音切换按钮 // 键盘/语音切换按钮
Obx(() { Obx(() {
final isTextMode = controller.isTextInputMode.value; final isTextMode =
controller.isTextInputMode.value;
return GestureDetector( return GestureDetector(
onTap: () { onTap: () {
controller.toggleInputMode(); controller.toggleInputMode();
@ -348,7 +354,9 @@ class _AgentViewState extends State<AgentView> with WidgetsBindingObserver {
borderRadius: BorderRadius.circular(22), borderRadius: BorderRadius.circular(22),
), ),
child: Icon( child: Icon(
isTextMode ? Icons.mic_none : Icons.keyboard, isTextMode
? Icons.mic_none
: Icons.keyboard,
color: isDarkMode color: isDarkMode
? Colors.grey[300] ? Colors.grey[300]
: Colors.grey[700], : Colors.grey[700],
@ -389,8 +397,8 @@ class _AgentViewState extends State<AgentView> with WidgetsBindingObserver {
), ),
), ),
child: Row( child: Row(
crossAxisAlignment: crossAxisAlignment: CrossAxisAlignment
CrossAxisAlignment.end, // 对齐到底部,实现向上扩展 .end, // 对齐到底部,实现向上扩展
children: [ children: [
Expanded( Expanded(
child: Obx(() { child: Obx(() {
@ -434,7 +442,8 @@ class _AgentViewState extends State<AgentView> with WidgetsBindingObserver {
), ),
filled: false, filled: false,
border: InputBorder.none, border: InputBorder.none,
focusedBorder: OutlineInputBorder( focusedBorder:
OutlineInputBorder(
borderSide: BorderSide( borderSide: BorderSide(
color: isDarkMode color: isDarkMode
? Colors.grey[800]! ? Colors.grey[800]!
@ -458,22 +467,24 @@ class _AgentViewState extends State<AgentView> with WidgetsBindingObserver {
); );
} else { } else {
// 语音输入模式 - 按住说话模式 // 语音输入模式 - 按住说话模式
return GestureDetector( return Listener(
onLongPressStart: (_) { onPointerDown: (_) {
// 开始按住说话 // 开始按住说话
controller.startPushToTalk(); controller.startPushToTalk();
}, },
onLongPressEnd: (_) { onPointerUp: (_) {
// 结束按住说话 // 结束按住说话
controller.endPushToTalk(); controller.endPushToTalk();
}, },
onLongPressCancel: () { // onLongPressCancel: () {
// 取消按住说话 // // 取消按住说话
controller.endPushToTalk(); // controller.endPushToTalk();
}, // },
child: Obx(() { child: Obx(() {
final isPushToTalkActive = controller.isPushToTalkActive.value; final isPushToTalkActive =
final isListening = controller.isListening.value; controller.isPushToTalkActive.value;
final isListening =
controller.isListening.value;
return Container( return Container(
height: 50, height: 50,
@ -481,16 +492,24 @@ class _AgentViewState extends State<AgentView> with WidgetsBindingObserver {
horizontal: 16), horizontal: 16),
decoration: BoxDecoration( decoration: BoxDecoration(
color: isPushToTalkActive color: isPushToTalkActive
? (isDarkMode ? Colors.blue[900] : Colors.blue[100]) ? (isDarkMode
: (isDarkMode ? Colors.grey[800] : Colors.grey[200]), ? Colors.blue[900]
borderRadius: BorderRadius.circular(22), : Colors.blue[100])
: (isDarkMode
? Colors.grey[800]
: Colors.grey[200]),
borderRadius:
BorderRadius.circular(22),
border: Border.all( border: Border.all(
color: isPushToTalkActive color: isPushToTalkActive
? Colors.blue ? Colors.blue
: (isDarkMode : (isDarkMode
? Colors.grey[800]! ? Colors.grey[800]!
: Colors.grey.withOpacity(0.1)), : Colors.grey
width: isPushToTalkActive ? 2.0 : 1.0, .withOpacity(0.1)),
width: isPushToTalkActive
? 2.0
: 1.0,
), ),
), ),
child: Row( child: Row(
@ -498,18 +517,23 @@ class _AgentViewState extends State<AgentView> with WidgetsBindingObserver {
// 语音波形图 - 只在按住时显示 // 语音波形图 - 只在按住时显示
if (isPushToTalkActive) ...[ if (isPushToTalkActive) ...[
const AgentSoundBarsWidget(), const AgentSoundBarsWidget(),
const Spacer(), //const Spacer(),
], ],
// 状态文字和图标 // 状态文字和图标
Expanded( Expanded(
child: Row( child: Row(
mainAxisAlignment: isPushToTalkActive mainAxisAlignment:
? MainAxisAlignment.end isPushToTalkActive
: MainAxisAlignment.center, ? MainAxisAlignment
.center
: MainAxisAlignment
.center,
children: [ children: [
Icon( Icon(
isPushToTalkActive ? Icons.mic : Icons.mic_none, isPushToTalkActive
? Icons.mic
: Icons.mic_none,
size: 16, size: 16,
color: isPushToTalkActive color: isPushToTalkActive
? Colors.blue ? Colors.blue
@ -522,10 +546,13 @@ class _AgentViewState extends State<AgentView> with WidgetsBindingObserver {
: '按住说话', : '按住说话',
style: TextStyle( style: TextStyle(
fontSize: 14, fontSize: 14,
fontWeight: FontWeight.w500, fontWeight:
color: isPushToTalkActive FontWeight.w500,
color:
isPushToTalkActive
? Colors.blue ? Colors.blue
: Colors.grey[600], : Colors
.grey[600],
), ),
), ),
], ],
@ -568,12 +595,14 @@ class _AgentViewState extends State<AgentView> with WidgetsBindingObserver {
showModalBottomSheet( showModalBottomSheet(
context: context, context: context,
isScrollControlled: true, isScrollControlled: true,
backgroundColor: Colors.transparent, backgroundColor:
Colors.transparent,
builder: (context) => builder: (context) =>
const FullScreenEditor(), const FullScreenEditor(),
).then((_) { ).then((_) {
// 弹出页关闭时的回调 // 弹出页关闭时的回调
controller.closeFullScreenEdit(); controller
.closeFullScreenEdit();
}); });
}, },
child: Container( child: Container(
@ -604,7 +633,8 @@ class _AgentViewState extends State<AgentView> with WidgetsBindingObserver {
height: 44, height: 44,
decoration: BoxDecoration( decoration: BoxDecoration(
color: primaryColor, color: primaryColor,
borderRadius: BorderRadius.circular(22), borderRadius:
BorderRadius.circular(22),
), ),
child: const Icon( child: const Icon(
Icons.send, Icons.send,
@ -631,7 +661,8 @@ class _AgentViewState extends State<AgentView> with WidgetsBindingObserver {
color: isDarkMode color: isDarkMode
? Colors.grey[800] ? Colors.grey[800]
: Colors.grey[200], : Colors.grey[200],
borderRadius: BorderRadius.circular(22), borderRadius:
BorderRadius.circular(22),
), ),
child: Icon( child: Icon(
isExpanded ? Icons.close : Icons.add, isExpanded ? Icons.close : Icons.add,
@ -660,9 +691,11 @@ class _AgentViewState extends State<AgentView> with WidgetsBindingObserver {
child: isExpanded child: isExpanded
? Container( ? Container(
margin: EdgeInsets.only(top: 8.h), margin: EdgeInsets.only(top: 8.h),
padding: EdgeInsets.symmetric(horizontal:16.w), // 添加左右边距 padding: EdgeInsets.symmetric(
horizontal: 16.w), // 添加左右边距
child: Row( child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly, // 改为均匀分布 mainAxisAlignment: MainAxisAlignment
.spaceEvenly, // 改为均匀分布
children: [ children: [
// 相机按钮 // 相机按钮
_buildPlusOptionButton( _buildPlusOptionButton(
@ -734,12 +767,6 @@ class _AgentViewState extends State<AgentView> with WidgetsBindingObserver {
); );
} }
// 构建提示选项芯片 // 构建提示选项芯片
Widget _buildPromptChip({ Widget _buildPromptChip({
required BuildContext context, required BuildContext context,
@ -773,8 +800,6 @@ class _AgentViewState extends State<AgentView> with WidgetsBindingObserver {
); );
} }
// 构建"+"号展开选项按钮 // 构建"+"号展开选项按钮
Widget _buildPlusOptionButton({ Widget _buildPlusOptionButton({
required BuildContext context, required BuildContext context,
@ -923,7 +948,8 @@ class _AgentViewState extends State<AgentView> with WidgetsBindingObserver {
children: [ children: [
// 音频可视化圆圈 // 音频可视化圆圈
Obx(() { Obx(() {
final isActive = controller.isListening.value || controller.isSpeaking.value; final isActive =
controller.isListening.value || controller.isSpeaking.value;
return AnimatedContainer( return AnimatedContainer(
duration: const Duration(milliseconds: 300), duration: const Duration(milliseconds: 300),
width: isActive ? 200 : 160, width: isActive ? 200 : 160,
@ -982,7 +1008,9 @@ class _AgentViewState extends State<AgentView> with WidgetsBindingObserver {
children: [ children: [
// 静音按钮 // 静音按钮
Obx(() => _buildPhoneControlButton( Obx(() => _buildPhoneControlButton(
icon: controller.isTtsEnabled.value ? Icons.volume_up : Icons.volume_off, icon: controller.isTtsEnabled.value
? Icons.volume_up
: Icons.volume_off,
onTap: () => controller.toggleTts(), onTap: () => controller.toggleTts(),
isDarkMode: isDarkMode, isDarkMode: isDarkMode,
isActive: controller.isTtsEnabled.value, isActive: controller.isTtsEnabled.value,
@ -1007,7 +1035,8 @@ class _AgentViewState extends State<AgentView> with WidgetsBindingObserver {
color: isActive ? Colors.red : Colors.green, color: isActive ? Colors.red : Colors.green,
boxShadow: [ boxShadow: [
BoxShadow( BoxShadow(
color: (isActive ? Colors.red : Colors.green).withOpacity(0.3), color: (isActive ? Colors.red : Colors.green)
.withOpacity(0.3),
blurRadius: 12, blurRadius: 12,
spreadRadius: 2, spreadRadius: 2,
), ),
@ -1050,7 +1079,8 @@ class _AgentViewState extends State<AgentView> with WidgetsBindingObserver {
height: 56, height: 56,
decoration: BoxDecoration( decoration: BoxDecoration(
shape: BoxShape.circle, shape: BoxShape.circle,
color: backgroundColor ?? (isDarkMode ? Colors.grey[800] : Colors.grey[200]), color: backgroundColor ??
(isDarkMode ? Colors.grey[800] : Colors.grey[200]),
border: isActive ? Border.all(color: Colors.blue, width: 2) : null, border: isActive ? Border.all(color: Colors.blue, width: 2) : null,
), ),
child: Icon( child: Icon(
@ -1064,7 +1094,3 @@ class _AgentViewState extends State<AgentView> with WidgetsBindingObserver {
); );
} }
} }

Loading…
Cancel
Save