From d830028531dee8c19111bc4d5009931a7cde996b Mon Sep 17 00:00:00 2001 From: lxm <1274844347@qq.com> Date: Mon, 7 Jul 2025 17:12:14 +0800 Subject: [PATCH] =?UTF-8?q?refactor(translation):=20=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E5=8E=86=E5=8F=B2=E8=AE=B0=E5=BD=95=E5=92=8C=E8=AF=A6=E6=83=85?= =?UTF-8?q?=E9=A1=B5=E7=9A=84UI=E5=B8=83=E5=B1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 调整历史记录项的删除按钮位置至右上角 - 在详情页的翻译项右侧添加删除按钮 - 改进代码格式和缩进一致性 --- .../views/translation_detail_view.dart | 188 ++++++++++-------- .../views/translation_history_view.dart | 91 +++++---- 2 files changed, 163 insertions(+), 116 deletions(-) diff --git a/lib/modules/translation/views/translation_detail_view.dart b/lib/modules/translation/views/translation_detail_view.dart index fe0105f51..afe3e668d 100644 --- a/lib/modules/translation/views/translation_detail_view.dart +++ b/lib/modules/translation/views/translation_detail_view.dart @@ -35,9 +35,10 @@ class TranslationDetailView extends GetView { @override Widget build(BuildContext context) { final isDarkMode = Theme.of(context).brightness == Brightness.dark; - + return Scaffold( - backgroundColor: isDarkMode ? AppColors.darkBackground : Color(0xFFF5F5F8), + backgroundColor: + isDarkMode ? AppColors.darkBackground : Color(0xFFF5F5F8), appBar: _buildAppBar(isDarkMode), body: Obx(() { // 显示加载状态 @@ -48,7 +49,7 @@ class TranslationDetailView extends GetView { ), ); } - + return Column( children: [ _buildTabButtons(isDarkMode), @@ -58,11 +59,12 @@ class TranslationDetailView extends GetView { }), ); } - + // 构建应用栏 PreferredSizeWidget _buildAppBar(bool isDarkMode) { return AppBar( - backgroundColor: isDarkMode ? AppColors.cardBackground : Color(0xFFF5F5F8), + backgroundColor: + isDarkMode ? AppColors.cardBackground : Color(0xFFF5F5F8), elevation: 0, leading: IconButton( icon: Icon( @@ -93,7 +95,7 @@ class TranslationDetailView extends GetView { ], ); } - + // 构建选项卡按钮 Widget _buildTabButtons(bool isDarkMode) { return Padding( @@ -102,11 +104,11 @@ class TranslationDetailView extends GetView { children: [ Expanded( child: Obx(() => _buildTabButton( - title: 'originalRecord'.tr, // 原始记录 - isSelected: controller.selectedTabIndex.value == 0, - onTap: () => controller.switchTab(0), - isDarkMode: isDarkMode, - )), + title: 'originalRecord'.tr, // 原始记录 + isSelected: controller.selectedTabIndex.value == 0, + onTap: () => controller.switchTab(0), + isDarkMode: isDarkMode, + )), ), //屏蔽“记录摘要”,需要是开启 // SizedBox(width: 12.w), @@ -122,7 +124,7 @@ class TranslationDetailView extends GetView { ), ); } - + // 构建内容区域 Widget _buildContentArea(bool isDarkMode) { return Expanded( @@ -134,13 +136,13 @@ class TranslationDetailView extends GetView { children: [ _buildTimestamp(isDarkMode), SizedBox(height: 8.h), - + // 根据选中的选项卡显示不同内容 if (controller.selectedTabIndex.value == 0) ..._buildOriginalRecords(isDarkMode) else _buildSummaryWidget(isDarkMode), - + SizedBox(height: 24.h), ], ); @@ -148,7 +150,7 @@ class TranslationDetailView extends GetView { ), ); } - + // 构建时间戳 Widget _buildTimestamp(bool isDarkMode) { return Padding( @@ -164,12 +166,14 @@ class TranslationDetailView extends GetView { ), ); } - + // 构建原始记录列表 List _buildOriginalRecords(bool isDarkMode) { - return controller.sessionItems.map((sessionItem) => _buildSessionItemWidget(sessionItem, isDarkMode)).toList(); + return controller.sessionItems + .map((sessionItem) => _buildSessionItemWidget(sessionItem, isDarkMode)) + .toList(); } - + // 构建选项卡按钮 Widget _buildTabButton({ required String title, @@ -182,8 +186,8 @@ class TranslationDetailView extends GetView { child: Container( height: 40.h, decoration: BoxDecoration( - color: isSelected - ? (isDarkMode ? AppColors.primary : Colors.blue) + color: isSelected + ? (isDarkMode ? AppColors.primary : Colors.blue) : (isDarkMode ? AppColors.cardBackground : Colors.white), borderRadius: BorderRadius.circular(20.r), boxShadow: [ @@ -200,15 +204,15 @@ class TranslationDetailView extends GetView { style: TextStyle( fontSize: 15.sp, fontWeight: isSelected ? FontWeight.bold : FontWeight.normal, - color: isSelected - ? Colors.white + color: isSelected + ? Colors.white : (isDarkMode ? Colors.white : Colors.black87), ), ), ), ); } - + // 构建会话详情中的翻译项 Widget _buildSessionItemWidget(TranslationItem item, bool isDarkMode) { final context = Get.context!; @@ -218,7 +222,8 @@ class TranslationDetailView extends GetView { decoration: BoxDecoration( color: item.isIntermediate ? Colors.grey.withOpacity(0.1) // 中间结果使用浅灰色底色 - : (item.sourceLanguageCode == controller.currentItem.sourceLanguageCode + : (item.sourceLanguageCode == + controller.currentItem.sourceLanguageCode ? Theme.of(context) .colorScheme .primary @@ -238,13 +243,35 @@ class TranslationDetailView extends GetView { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - // 源文本 - Text( - item.sourceText, - style: TextStyle( - fontSize: 16, - color: Theme.of(context).textTheme.bodyLarge?.color, - ), + Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + // 源文本 + Expanded( + child: Text( + item.sourceText, + style: TextStyle( + fontSize: 16, + color: Theme.of(context).textTheme.bodyLarge?.color, + ), + )), + // 删除按钮 + if (!item.isIntermediate) + InkWell( + onTap: () => _showDeleteItemConfirmDialog(item), + borderRadius: BorderRadius.circular(6.r), + splashColor: Colors.red.withValues(alpha: 0.1), + highlightColor: Colors.red.withValues(alpha: 0.05), + child: Container( + padding: EdgeInsets.all(6.w), + child: Icon( + Icons.delete_outline, + size: 16.sp, + color: isDarkMode ? Colors.grey[500] : Colors.grey[400], + ), + ), + ), + ], ), if (item.translatedText.isNotEmpty) ...[ const SizedBox(height: 8), @@ -273,22 +300,6 @@ class TranslationDetailView extends GetView { Row( mainAxisSize: MainAxisSize.min, children: [ - // 删除按钮 - if (!item.isIntermediate) - InkWell( - onTap: () => _showDeleteItemConfirmDialog(item), - borderRadius: BorderRadius.circular(6.r), - splashColor: Colors.red.withValues(alpha: 0.1), - highlightColor: Colors.red.withValues(alpha: 0.05), - child: Container( - padding: EdgeInsets.all(6.w), - child: Icon( - Icons.delete_outline, - size: 16.sp, - color: isDarkMode ? Colors.grey[500] : Colors.grey[400], - ), - ), - ), // 播放按钮 if (!item.isIntermediate) ...[ SizedBox(width: 8.w), @@ -310,25 +321,25 @@ class TranslationDetailView extends GetView { ); } - // 构建总结视图 Widget _buildSummaryWidget(bool isDarkMode) { final String combinedSourceText = _getCombinedSourceText(); - + return Column( children: [ // 摘要内容容器 _buildSummaryContainer(isDarkMode), - + // 提取摘要按钮 Obx(() => _buildExtractSummaryButton(combinedSourceText, isDarkMode)), - + // 重新生成按钮 - Obx(() => _buildRegenerateSummaryButton(combinedSourceText, isDarkMode)), + Obx(() => + _buildRegenerateSummaryButton(combinedSourceText, isDarkMode)), ], ); } - + // 构建摘要容器 Widget _buildSummaryContainer(bool isDarkMode) { return Container( @@ -354,7 +365,7 @@ class TranslationDetailView extends GetView { }), ); } - + // 构建空摘要提示 Widget _buildEmptySummaryPrompt(bool isDarkMode) { return Padding( @@ -372,7 +383,7 @@ class TranslationDetailView extends GetView { ), ); } - + // 构建摘要内容 Widget _buildSummaryContent(bool isDarkMode) { return Column( @@ -417,9 +428,12 @@ class TranslationDetailView extends GetView { Material( color: Colors.transparent, child: InkWell( - onTap: () => controller.playText(controller.summaryResult.value), + onTap: () => + controller.playText(controller.summaryResult.value), borderRadius: BorderRadius.circular(20.r), - splashColor: isDarkMode ? AppColors.primary.withOpacity(0.2) : Colors.blue.withOpacity(0.2), + splashColor: isDarkMode + ? AppColors.primary.withOpacity(0.2) + : Colors.blue.withOpacity(0.2), child: Padding( padding: EdgeInsets.all(8.r), child: Icon( @@ -437,7 +451,9 @@ class TranslationDetailView extends GetView { child: InkWell( onTap: _copySummaryToClipboard, borderRadius: BorderRadius.circular(20.r), - splashColor: isDarkMode ? AppColors.primary.withOpacity(0.2) : Colors.blue.withOpacity(0.2), + splashColor: isDarkMode + ? AppColors.primary.withOpacity(0.2) + : Colors.blue.withOpacity(0.2), child: Padding( padding: EdgeInsets.all(8.r), child: Icon( @@ -454,7 +470,7 @@ class TranslationDetailView extends GetView { ], ); } - + // 复制摘要到剪贴板 void _copySummaryToClipboard() { Clipboard.setData(ClipboardData(text: controller.summaryResult.value)); @@ -465,16 +481,19 @@ class TranslationDetailView extends GetView { duration: Duration(seconds: 2), ); } - + // 构建提取摘要按钮 - Widget _buildExtractSummaryButton(String combinedSourceText, bool isDarkMode) { - final bool isDisabled = controller.isGeneratingSummary.value || controller.summaryResult.value.isNotEmpty; - + Widget _buildExtractSummaryButton( + String combinedSourceText, bool isDarkMode) { + final bool isDisabled = controller.isGeneratingSummary.value || + controller.summaryResult.value.isNotEmpty; + return Container( width: double.infinity, margin: EdgeInsets.only(bottom: 16.h), child: ElevatedButton( - onPressed: isDisabled ? null : () => _extractSummary(combinedSourceText), + onPressed: + isDisabled ? null : () => _extractSummary(combinedSourceText), style: ElevatedButton.styleFrom( backgroundColor: isDarkMode ? AppColors.primary : Colors.blue, foregroundColor: Colors.white, @@ -483,14 +502,18 @@ class TranslationDetailView extends GetView { borderRadius: BorderRadius.circular(16.r), ), elevation: 0, - disabledBackgroundColor: controller.isGeneratingSummary.value - ? isDarkMode ? AppColors.primary.withAlpha(128) : Colors.blue.withAlpha(128) + disabledBackgroundColor: controller.isGeneratingSummary.value + ? isDarkMode + ? AppColors.primary.withAlpha(128) + : Colors.blue.withAlpha(128) : Colors.grey.withAlpha(128), ), child: controller.isGeneratingSummary.value ? _buildGeneratingIndicator(isDarkMode) : Text( - controller.summaryResult.value.isEmpty ? 'extractSummary'.tr : 'summaryGenerated'.tr, // 提取摘要 : 已生成摘要 + controller.summaryResult.value.isEmpty + ? 'extractSummary'.tr + : 'summaryGenerated'.tr, // 提取摘要 : 已生成摘要 style: TextStyle( fontSize: 16.sp, fontWeight: FontWeight.w600, @@ -499,7 +522,7 @@ class TranslationDetailView extends GetView { ), ); } - + // 构建生成中指示器 Widget _buildGeneratingIndicator(bool isDarkMode) { return Row( @@ -524,13 +547,15 @@ class TranslationDetailView extends GetView { ], ); } - + // 构建重新生成按钮 - Widget _buildRegenerateSummaryButton(String combinedSourceText, bool isDarkMode) { - if (controller.summaryResult.value.isEmpty || controller.isGeneratingSummary.value) { + Widget _buildRegenerateSummaryButton( + String combinedSourceText, bool isDarkMode) { + if (controller.summaryResult.value.isEmpty || + controller.isGeneratingSummary.value) { return SizedBox.shrink(); } - + return Container( width: double.infinity, margin: EdgeInsets.only(bottom: 16.h), @@ -554,17 +579,17 @@ class TranslationDetailView extends GetView { ), ); } - + // 提取摘要方法 void _extractSummary(String text) async { final result = await controller.extractSummary(text); - + // 检查是否超时,如果超时则显示重试选项 if (result.contains('超时')) { _showTimeoutDialog(text); } } - + // 显示超时对话框 void _showTimeoutDialog(String text) { Get.dialog( @@ -720,11 +745,13 @@ class TranslationDetailView extends GetView { // 分享原始记录 final String sourceText = _getCombinedSourceText(); final String translatedText = _getCombinedTranslatedText(); - shareText = '${'originalText'.tr}:\n$sourceText\n\n${'translatedText'.tr}:\n$translatedText'; // 原文:译文: + shareText = + '${'originalText'.tr}:\n$sourceText\n\n${'translatedText'.tr}:\n$translatedText'; // 原文:译文: } else { // 分享摘要 if (controller.summaryResult.value.isNotEmpty) { - shareText = '${'sessionSummary'.tr}:\n${controller.summaryResult.value}'; // 会话摘要: + shareText = + '${'sessionSummary'.tr}:\n${controller.summaryResult.value}'; // 会话摘要: } else { Get.snackbar( 'cannotShare'.tr, // 无法分享 @@ -735,11 +762,12 @@ class TranslationDetailView extends GetView { return; } } - + // 调用系统分享 Share.share( shareText, - subject: '${'translationSessionRecord'.tr} - ${DateFormat('yyyy-MM-dd HH:mm').format(controller.currentItem.timestamp)}', // 翻译会话记录 + subject: + '${'translationSessionRecord'.tr} - ${DateFormat('yyyy-MM-dd HH:mm').format(controller.currentItem.timestamp)}', // 翻译会话记录 ); } -} \ No newline at end of file +} diff --git a/lib/modules/translation/views/translation_history_view.dart b/lib/modules/translation/views/translation_history_view.dart index 52b35faca..fe43db5b7 100644 --- a/lib/modules/translation/views/translation_history_view.dart +++ b/lib/modules/translation/views/translation_history_view.dart @@ -15,9 +15,10 @@ class TranslationHistoryView extends GetView { @override Widget build(BuildContext context) { final isDarkMode = Theme.of(context).brightness == Brightness.dark; - + return Scaffold( - backgroundColor: isDarkMode ? AppColors.darkBackground : Color(0xFFF5F5F8), + backgroundColor: + isDarkMode ? AppColors.darkBackground : Color(0xFFF5F5F8), appBar: _buildAppBar(isDarkMode), body: Obx(() { if (!controller.hasHistory) { @@ -46,7 +47,7 @@ class TranslationHistoryView extends GetView { itemBuilder: (context, index) { final date = controller.sortedDates[index]; final items = controller.groupedHistory.value[date]!; - + return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -70,9 +71,10 @@ class TranslationHistoryView extends GetView { }), ); } - + // 构建日期组容器 - Widget _buildDateGroupContainer(List items, bool isDarkMode) { + Widget _buildDateGroupContainer( + List items, bool isDarkMode) { return Container( margin: EdgeInsets.only(bottom: 16.h), decoration: BoxDecoration( @@ -104,7 +106,7 @@ class TranslationHistoryView extends GetView { ), ); } - + // 构建组内的历史记录项 Widget _buildHistoryItemInGroup(TranslationItem item, bool isDarkMode) { return InkWell( @@ -117,10 +119,11 @@ class TranslationHistoryView extends GetView { borderRadius: BorderRadius.circular(8.r), child: Padding( padding: EdgeInsets.symmetric(horizontal: 20.w, vertical: 16.h), - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, + child: Stack( children: [ - Expanded( + // 主要内容区域 + Padding( + padding: EdgeInsets.only(right: 50.w), // 为右侧图标留出空间 child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ @@ -155,7 +158,8 @@ class TranslationHistoryView extends GetView { _formatSessionTime(item.timestamp), style: TextStyle( fontSize: 12.sp, - color: isDarkMode ? Colors.grey[500] : Colors.grey[600], + color: + isDarkMode ? Colors.grey[500] : Colors.grey[600], ), ), SizedBox(width: 12.w), @@ -165,7 +169,9 @@ class TranslationHistoryView extends GetView { _formatLanguagePair(item), style: TextStyle( fontSize: 12.sp, - color: isDarkMode ? Colors.grey[500] : Colors.grey[600], + color: isDarkMode + ? Colors.grey[500] + : Colors.grey[600], ), overflow: TextOverflow.ellipsis, ), @@ -175,37 +181,45 @@ class TranslationHistoryView extends GetView { ], ), ), - SizedBox(width: 12.w), - // 删除会话按钮 - InkWell( - onTap: () => _showDeleteSessionConfirmDialog(item.sessionId), - borderRadius: BorderRadius.circular(6.r), - splashColor: Colors.red.withOpacity(0.1), - highlightColor: Colors.red.withOpacity(0.05), - child: Container( - padding: EdgeInsets.all(8.w), - child: Icon( - Icons.delete_outline, - color: isDarkMode ? Colors.grey[500] : Colors.grey[400], - size: 18.sp, + // 右上角删除按钮 + Positioned( + top: 0, + right: -8.w, + child: InkWell( + onTap: () => _showDeleteSessionConfirmDialog(item.sessionId), + borderRadius: BorderRadius.circular(6.r), + splashColor: Colors.red.withOpacity(0.1), + highlightColor: Colors.red.withOpacity(0.05), + child: Container( + padding: EdgeInsets.all(8.w), + child: Icon( + Icons.delete_outline, + color: isDarkMode ? Colors.grey[500] : Colors.grey[400], + size: 18.sp, + ), ), ), ), - SizedBox(width: 8.w), - Icon( - Icons.chevron_right, - color: isDarkMode ? Colors.grey[600] : Colors.grey[350], - size: 20.sp, + // 右下角箭头图标 + Positioned( + bottom: 0, + right: 0.w, // 与删除图标垂直对齐 + child: Icon( + Icons.chevron_right, + color: isDarkMode ? Colors.grey[600] : Colors.grey[350], + size: 20.sp, + ), ), ], ), ), ); } - + void _showTranslationDetail(TranslationItem item) { // 获取该会话的所有翻译项 - final List sessionItems = controller.getSessionItems(item.sessionId); + final List sessionItems = + controller.getSessionItems(item.sessionId); Get.to( () => TranslationDetailView(), @@ -238,8 +252,12 @@ class TranslationHistoryView extends GetView { final languageManager = Get.find(); // 获取源语言和目标语言的中文名称 - final sourceName = languageManager.getChineseNameByAsrCode(item.sourceLanguageCode) ?? 'unknownLanguage'.tr; // 未知语言 - final targetName = languageManager.getChineseNameByAsrCode(item.targetLanguageCode) ?? 'unknownLanguage'.tr; // 未知语言 + final sourceName = + languageManager.getChineseNameByAsrCode(item.sourceLanguageCode) ?? + 'unknownLanguage'.tr; // 未知语言 + final targetName = + languageManager.getChineseNameByAsrCode(item.targetLanguageCode) ?? + 'unknownLanguage'.tr; // 未知语言 // 使用双向箭头符号表示翻译方向 return '$sourceName ⇄ $targetName'; @@ -355,11 +373,12 @@ class TranslationHistoryView extends GetView { ), ); } - + // 构建应用栏 PreferredSizeWidget _buildAppBar(bool isDarkMode) { return AppBar( - backgroundColor: isDarkMode ? AppColors.cardBackground : Color(0xFFF5F5F8), + backgroundColor: + isDarkMode ? AppColors.cardBackground : Color(0xFFF5F5F8), elevation: 0, leading: IconButton( icon: Icon( @@ -392,4 +411,4 @@ class TranslationHistoryView extends GetView { ], ); } -} \ No newline at end of file +}