You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

345 lines
11 KiB

import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get/get.dart';
import 'package:get_storage/get_storage.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import '../../../data/services/volcano_translation_service.dart';
import '../../../data/services/language_manager.dart';
import '../../../core/utils/logger.dart';
import '../../translation/views/dialogs/language_selection_dialog.dart';
/// 文本翻译控制器
class TextTranslationController extends GetxController {
// 依赖服务
final VolcanoTranslationService _translationService =
Get.find<VolcanoTranslationService>();
final LanguageManager _languageManager = Get.find<LanguageManager>();
final GetStorage _storage = GetStorage();
// 文本输入控制器
final TextEditingController textController = TextEditingController();
// 响应式状态
final sourceLanguageChineseName = '中文(简体)'.obs;
final targetLanguageChineseName = '英语'.obs;
final sourceLanguageCode = 'zh-CN'.obs;
final targetLanguageCode = 'en-US'.obs;
final translatedText = ''.obs;
final isTranslating = false.obs;
final inputText = ''.obs;
// 支持的语言列表
List<String> get supportedLanguages => _languageManager.getAllChineseNames();
@override
void onInit() {
super.onInit();
// 初始化翻译服务
_initializeTranslationService();
_loadSavedLanguages();
// 监听文本输入变化
textController.addListener(() {
inputText.value = textController.text;
});
}
/// 初始化翻译服务
Future<void> _initializeTranslationService() async {
try {
// 已初始化则跳过
if (_translationService.isInitialized) {
Logger.info('翻译服务已初始化');
return;
}
// final initialized =
final initialized = await _translationService.initialize();
if (!initialized) {
Logger.error('翻译服务初始化失败');
Get.snackbar(
'error'.tr,
'翻译服务初始化失败,请检查网络连接',
snackPosition: SnackPosition.TOP,
backgroundColor: Colors.red.withOpacity(0.9),
colorText: Colors.white,
);
} else {
Logger.info('翻译服务初始化成功');
}
} catch (e) {
Logger.error('翻译服务初始化异常: $e');
}
}
@override
void onClose() {
textController.dispose();
super.onClose();
}
/// 加载保存的语言设置
void _loadSavedLanguages() {
try {
final savedSourceLanguage =
_storage.read('text_translation_source_language');
final savedTargetLanguage =
_storage.read('text_translation_target_language');
if (savedSourceLanguage != null &&
supportedLanguages.contains(savedSourceLanguage)) {
sourceLanguageChineseName.value = savedSourceLanguage;
// 同时更新语言代码
final asrCode =
_languageManager.getAsrCodeByChineseName(savedSourceLanguage);
if (asrCode != null) {
sourceLanguageCode.value = asrCode;
}
}
if (savedTargetLanguage != null &&
supportedLanguages.contains(savedTargetLanguage)) {
targetLanguageChineseName.value = savedTargetLanguage;
// 同时更新语言代码
final asrCode =
_languageManager.getAsrCodeByChineseName(savedTargetLanguage);
if (asrCode != null) {
targetLanguageCode.value = asrCode;
}
}
} catch (e) {
Logger.error('加载语言设置失败: $e');
}
}
/// 保存语言设置
void _saveLanguageSettings() {
try {
_storage.write(
'text_translation_source_language', sourceLanguageChineseName.value);
_storage.write(
'text_translation_target_language', targetLanguageChineseName.value);
} catch (e) {
Logger.error('保存语言设置失败: $e');
}
}
/// 设置源语言
void setSourceLanguage(String language) {
if (language != sourceLanguageChineseName.value) {
sourceLanguageChineseName.value = language;
// 同时更新语言代码;当选择“自动检测”时,将源语言代码置空,后续翻译流程会进行语种检测
if (language == 'autoDetect') {
sourceLanguageCode.value = '';
} else {
final asrCode = _languageManager.getAsrCodeByChineseName(language);
if (asrCode != null) {
sourceLanguageCode.value = asrCode;
}
}
_saveLanguageSettings();
// 如果已有翻译结果,清空结果
if (translatedText.value.isNotEmpty) {
translatedText.value = '';
}
}
}
/// 设置目标语言
void setTargetLanguage(String language) {
if (language != targetLanguageChineseName.value) {
targetLanguageChineseName.value = language;
// 同时更新语言代码
final asrCode = _languageManager.getAsrCodeByChineseName(language);
if (asrCode != null) {
targetLanguageCode.value = asrCode;
}
_saveLanguageSettings();
// 如果已有翻译结果,清空结果
if (translatedText.value.isNotEmpty) {
translatedText.value = '';
}
}
}
/// 交换源语言和目标语言
void swapLanguages() {
final tempSource = sourceLanguageChineseName.value;
final tempTarget = targetLanguageChineseName.value;
final tempSourceCode = sourceLanguageCode.value;
final tempTargetCode = targetLanguageCode.value;
final tempInputText = textController.text;
final tempTranslatedText = translatedText.value;
sourceLanguageChineseName.value = tempTarget;
targetLanguageChineseName.value = tempSource;
sourceLanguageCode.value = tempTargetCode;
targetLanguageCode.value = tempSourceCode;
// 交换输入文本和翻译结果
textController.text = tempTranslatedText;
translatedText.value = tempInputText;
_saveLanguageSettings();
}
/// 执行翻译
Future<void> translateText() async {
final text = textController.text.trim();
// 验证输入
if (text.isEmpty) {
// Get.snackbar(
// 'error'.tr,
// 'pleaseInputText'.tr,
// snackPosition: SnackPosition.TOP,
// backgroundColor: Colors.orange.withOpacity(0.9),
// colorText: Colors.white,
// );
return;
}
if (text.length > 5000) {
// 5000 字符限制
Get.snackbar(
'error'.tr,
'textTooLong'.tr,
snackPosition: SnackPosition.TOP,
backgroundColor: Colors.orange.withOpacity(0.9),
colorText: Colors.white,
);
return;
}
// 检查源语言和目标语言是否相同
if (sourceLanguageChineseName.value == targetLanguageChineseName.value) {
translatedText.value = text;
return;
}
isTranslating.value = true;
translatedText.value = '';
try {
Logger.info('开始翻译: $text');
Logger.info(
'源语言: ${sourceLanguageChineseName.value} -> ${sourceLanguageCode.value}');
Logger.info(
'目标语言: ${targetLanguageChineseName.value} -> ${targetLanguageCode.value}');
// 确保翻译服务已初始化
Logger.info('确保翻译服务已初始化...');
bool initialized = _translationService.isInitialized;
if (!initialized) {
initialized = await _translationService.initialize();
}
Logger.info('翻译服务初始化结果: $initialized');
if (!initialized) {
throw Exception('翻译服务初始化失败');
}
Logger.info('调用翻译服务...');
// 若选择了“自动检测”,先进行语种检测
if (sourceLanguageChineseName.value == 'autoDetect' ||
sourceLanguageCode.value.isEmpty) {
Logger.info('源语言为自动检测,开始语种检测…');
final detectedAsrCode =
await _translationService.detectTextLanguage(text: text);
if (detectedAsrCode == null || detectedAsrCode.isEmpty) {
Logger.error('语种检测失败');
Get.snackbar(
'error'.tr, // 翻译键代表的中文文本内容
'languageDetectionFailed'.tr, // 翻译键代表的中文文本内容
snackPosition: SnackPosition.TOP,
backgroundColor: Colors.red.withOpacity(0.9),
colorText: Colors.white,
);
return;
}
sourceLanguageCode.value = detectedAsrCode;
Logger.info('语种检测结果: $detectedAsrCode');
}
// 调用翻译服务,使用检测或手动选择的源语言代码
final result = await _translationService.translateText(
text: text,
sourceLanguageCode: sourceLanguageCode.value,
targetLanguageCode: targetLanguageCode.value,
);
Logger.info('翻译服务返回结果: $result');
if (result != null && result.isNotEmpty) {
translatedText.value = result;
Logger.info('翻译成功: $result');
} else {
Logger.error('翻译服务返回空结果');
throw Exception('翻译服务返回空结果');
}
} catch (e) {
Logger.error('翻译失败: $e');
Get.snackbar(
'error'.tr,
'translationFailed'.tr,
snackPosition: SnackPosition.TOP,
backgroundColor: Colors.red.withOpacity(0.9),
colorText: Colors.white,
);
} finally {
isTranslating.value = false;
}
}
/// 复制翻译结果
void copyResult() {
if (translatedText.value.isNotEmpty) {
Clipboard.setData(ClipboardData(text: translatedText.value));
Get.snackbar(
'success'.tr,
'copied'.tr,
snackPosition: SnackPosition.TOP,
backgroundColor: Colors.green.withOpacity(0.9),
colorText: Colors.white,
duration: const Duration(seconds: 1),
);
}
}
/// 清空输入
void clearInput() {
textController.clear();
translatedText.value = '';
}
/// 显示语言选择对话框(统一与其它翻译模式的样式)
void showLanguageSelector({required bool isSourceLanguage}) {
final isDarkMode = Theme.of(Get.context!).brightness == Brightness.dark;
// 复用统一语言选择弹窗组件
LanguageSelectionDialog.show(
isSourceLanguage,
isDarkMode,
languages: supportedLanguages,
currentLanguage: isSourceLanguage
? sourceLanguageChineseName.value
: targetLanguageChineseName.value,
includeAutoDetect: true, // 文本翻译源语言保留“自动检测”
translateLanguageNames: true, // 开启多语言显示,语言中文名作为翻译键
onSelected: (name) {
if (isSourceLanguage) {
setSourceLanguage(name);
} else {
setTargetLanguage(name);
}
},
);
}
}