|
|
|
@ -26,24 +26,6 @@ class TranslationView extends GetView<TranslationController> { |
|
|
|
} |
|
|
|
|
|
|
|
PreferredSizeWidget _buildAppBar(bool isDarkMode) { |
|
|
|
// 在同一个类中添加辅助方法 |
|
|
|
PopupMenuItem<String> _buildPopupMenuItem(String value, String text, |
|
|
|
{bool enabled = true // 默认启用 |
|
|
|
}) { |
|
|
|
return PopupMenuItem( |
|
|
|
value: value, |
|
|
|
enabled: enabled, // 设置启用状态 |
|
|
|
child: Text( |
|
|
|
text, |
|
|
|
style: TextStyle( |
|
|
|
color: enabled |
|
|
|
? null // 使用默认颜色 |
|
|
|
: Colors.grey, // 禁用时显示灰色 |
|
|
|
), |
|
|
|
), |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
return AppBar( |
|
|
|
backgroundColor: isDarkMode ? AppColors.cardBackground : Colors.white, |
|
|
|
elevation: 1, |
|
|
|
@ -59,53 +41,20 @@ class TranslationView extends GetView<TranslationController> { |
|
|
|
Get.back(); |
|
|
|
}, |
|
|
|
), |
|
|
|
title: Obx(() => PopupMenuButton<String>( |
|
|
|
onSelected: (value) { |
|
|
|
controller.changeTranslationMode(value); |
|
|
|
title: Obx(() => GestureDetector( |
|
|
|
onTap: () { |
|
|
|
// 点击标题时弹出翻译模式选择器 |
|
|
|
_showTranslationModeSelector(isDarkMode); |
|
|
|
}, |
|
|
|
color: isDarkMode ? AppColors.cardBackground : Colors.white, |
|
|
|
itemBuilder: (BuildContext context) => [ |
|
|
|
_buildPopupMenuItem('simultaneous', 'simultaneousTranslation'.tr), |
|
|
|
_buildPopupMenuItem('faceToFace', 'faceToFaceTranslation'.tr), |
|
|
|
_buildPopupMenuItem( |
|
|
|
'audioVideo', |
|
|
|
'audioVideoTranslation'.tr, |
|
|
|
enabled: controller.bleManager.isConnected, // 根据连接状态启用/禁用 |
|
|
|
), |
|
|
|
_buildPopupMenuItem( |
|
|
|
'call', |
|
|
|
'callTranslation'.tr, |
|
|
|
enabled: controller.bleManager.isConnected, // 根据连接状态启用/禁用 |
|
|
|
child: Text( |
|
|
|
controller.currentModeTitle.value.tr, |
|
|
|
style: TextStyle( |
|
|
|
fontSize: 18.sp, |
|
|
|
fontWeight: FontWeight.w600, |
|
|
|
color: isDarkMode ? Colors.white : Colors.black, |
|
|
|
), |
|
|
|
], |
|
|
|
child: Row( |
|
|
|
mainAxisSize: MainAxisSize.min, // 关键修改:让宽度自适应内容 |
|
|
|
mainAxisAlignment: MainAxisAlignment.center, |
|
|
|
children: [ |
|
|
|
Flexible( |
|
|
|
// 防止文本溢出 |
|
|
|
child: FittedBox( |
|
|
|
// 保持文本缩放比例 |
|
|
|
fit: BoxFit.scaleDown, |
|
|
|
child: Text( |
|
|
|
controller.currentModeTitle.value.tr, |
|
|
|
style: TextStyle( |
|
|
|
fontSize: 18.sp, |
|
|
|
fontWeight: FontWeight.w600, // 保持字体加粗 |
|
|
|
color: isDarkMode ? Colors.white : Colors.black, |
|
|
|
), |
|
|
|
overflow: TextOverflow.ellipsis, // 长文本显示省略号 |
|
|
|
maxLines: 1, |
|
|
|
), |
|
|
|
), |
|
|
|
), |
|
|
|
SizedBox(width: 4), // 添加间距 |
|
|
|
Icon( |
|
|
|
Icons.arrow_drop_down, |
|
|
|
color: isDarkMode ? Colors.white : Colors.black, |
|
|
|
size: 20.sp, |
|
|
|
), |
|
|
|
], |
|
|
|
overflow: TextOverflow.ellipsis, |
|
|
|
maxLines: 1, |
|
|
|
), |
|
|
|
)), |
|
|
|
centerTitle: true, |
|
|
|
@ -499,7 +448,8 @@ class TranslationView extends GetView<TranslationController> { |
|
|
|
if (isRecognizing) { |
|
|
|
controller.stopAll(); |
|
|
|
} else { |
|
|
|
controller.startRecognition(); |
|
|
|
// 弹出翻译模式选择器 |
|
|
|
_showTranslationModeSelector(isDarkMode); |
|
|
|
} |
|
|
|
}, |
|
|
|
child: Container( |
|
|
|
@ -1118,4 +1068,153 @@ class TranslationView extends GetView<TranslationController> { |
|
|
|
); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// 显示翻译模式选择器 |
|
|
|
void _showTranslationModeSelector(bool isDarkMode) { |
|
|
|
Get.bottomSheet( |
|
|
|
_buildTranslationModeSelector(), |
|
|
|
isScrollControlled: true, |
|
|
|
backgroundColor: Colors.transparent, |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
// 构建翻译模式选择器 - 参考会议模块样式 |
|
|
|
Widget _buildTranslationModeSelector() { |
|
|
|
return Builder( |
|
|
|
builder: (BuildContext context) { |
|
|
|
return SafeArea( |
|
|
|
child: Column( |
|
|
|
mainAxisSize: MainAxisSize.min, |
|
|
|
children: [ |
|
|
|
_buildModeItem( |
|
|
|
context, |
|
|
|
'simultaneousTranslation'.tr, |
|
|
|
Icons.translate, |
|
|
|
Colors.blue, |
|
|
|
onTap: () async { |
|
|
|
Get.back(); |
|
|
|
await controller.changeTranslationMode('simultaneous'); |
|
|
|
controller.startRecognition(); |
|
|
|
}, |
|
|
|
), |
|
|
|
_buildModeItem( |
|
|
|
context, |
|
|
|
'faceToFaceTranslation'.tr, |
|
|
|
Icons.people, |
|
|
|
Colors.green, |
|
|
|
onTap: () async { |
|
|
|
Get.back(); |
|
|
|
await controller.changeTranslationMode('faceToFace'); |
|
|
|
controller.startRecognition(); |
|
|
|
}, |
|
|
|
), |
|
|
|
_buildModeItem( |
|
|
|
context, |
|
|
|
'audioVideoTranslation'.tr, |
|
|
|
Icons.videocam, |
|
|
|
Colors.orange, |
|
|
|
onTap: controller.bleManager.isConnected |
|
|
|
? () async { |
|
|
|
Get.back(); |
|
|
|
await controller.changeTranslationMode('audioVideo'); |
|
|
|
controller.startRecognition(); |
|
|
|
} |
|
|
|
: null, |
|
|
|
), |
|
|
|
_buildModeItem( |
|
|
|
context, |
|
|
|
'callTranslation'.tr, |
|
|
|
Icons.phone, |
|
|
|
Colors.purple, |
|
|
|
onTap: controller.bleManager.isConnected |
|
|
|
? () async { |
|
|
|
Get.back(); |
|
|
|
await controller.changeTranslationMode('call'); |
|
|
|
controller.startRecognition(); |
|
|
|
} |
|
|
|
: null, |
|
|
|
), |
|
|
|
SizedBox(height: 24.w), |
|
|
|
GestureDetector( |
|
|
|
onTap: () => Get.back(), |
|
|
|
child: Container( |
|
|
|
width: 42, |
|
|
|
height: 42, |
|
|
|
decoration: BoxDecoration( |
|
|
|
color: Colors.black.withValues(alpha: 0.8), |
|
|
|
borderRadius: BorderRadius.circular(50), |
|
|
|
), |
|
|
|
child: const Icon(Icons.close, color: Colors.white), |
|
|
|
), |
|
|
|
), |
|
|
|
const SizedBox(height: 19), |
|
|
|
], |
|
|
|
), |
|
|
|
); |
|
|
|
}, |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
// 构建单个模式选项 - 完全参考会议模块的 _buildItem 方法 |
|
|
|
Widget _buildModeItem( |
|
|
|
BuildContext context, |
|
|
|
String title, |
|
|
|
IconData icon, |
|
|
|
Color color, { |
|
|
|
Function()? onTap, |
|
|
|
}) { |
|
|
|
final isDarkMode = Theme.of(context).brightness == Brightness.dark; |
|
|
|
|
|
|
|
return GestureDetector( |
|
|
|
onTap: onTap, |
|
|
|
child: Container( |
|
|
|
width: 220.w, |
|
|
|
height: 60.w, |
|
|
|
padding: EdgeInsets.all(5.w), |
|
|
|
margin: EdgeInsets.only(top: 15.w), |
|
|
|
decoration: BoxDecoration( |
|
|
|
color: isDarkMode |
|
|
|
? Colors.grey[800]!.withValues(alpha: onTap != null ? 1 : 0.5) |
|
|
|
: Colors.white.withValues(alpha: onTap != null ? 1 : 0.5), |
|
|
|
borderRadius: BorderRadius.circular(60.w), |
|
|
|
), |
|
|
|
child: Row( |
|
|
|
children: [ |
|
|
|
Container( |
|
|
|
width: 46.w, |
|
|
|
height: 46.w, |
|
|
|
margin: EdgeInsets.only(right: 5.w), |
|
|
|
decoration: BoxDecoration( |
|
|
|
color: color.withValues(alpha: onTap != null ? 0.3 : 0.2), |
|
|
|
borderRadius: BorderRadius.circular(60.w), |
|
|
|
), |
|
|
|
child: Icon( |
|
|
|
icon, |
|
|
|
color: color.withValues(alpha: onTap != null ? 1 : 0.5), |
|
|
|
), |
|
|
|
), |
|
|
|
Expanded( |
|
|
|
child: Text( |
|
|
|
title, |
|
|
|
style: TextStyle( |
|
|
|
fontSize: 15.sp, |
|
|
|
color: isDarkMode |
|
|
|
? Colors.white.withValues(alpha: onTap != null ? 1 : 0.5) |
|
|
|
: Colors.black87 |
|
|
|
.withValues(alpha: onTap != null ? 1 : 0.5), |
|
|
|
fontWeight: FontWeight.bold, |
|
|
|
), |
|
|
|
), |
|
|
|
), |
|
|
|
Icon( |
|
|
|
Icons.arrow_forward_ios, |
|
|
|
size: 16.w, |
|
|
|
color: Colors.grey.withValues(alpha: onTap != null ? 1 : 0.5), |
|
|
|
), |
|
|
|
SizedBox(width: 5.w), |
|
|
|
], |
|
|
|
), |
|
|
|
), |
|
|
|
); |
|
|
|
} |
|
|
|
} |
|
|
|
|