Translate-Flutter/lib/page/home/home_logic.dart
2024-07-12 16:19:05 +08:00

263 lines
8.9 KiB
Dart
Executable File

import 'dart:convert';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_text_detect_area/flutter_text_detect_area.dart';
import 'package:get/get.dart';
import 'package:image_picker/image_picker.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:speech_to_text/speech_recognition_result.dart';
import 'package:trans_lark/core/router/router.dart';
import 'package:trans_lark/entity/language_entity.dart';
import 'package:trans_lark/entity/scene_entity.dart';
import 'package:trans_lark/generated/assets.dart';
import 'package:trans_lark/global/app_tracking_authorization_manager.dart';
import 'package:trans_lark/global/speech_to_text_manager.dart';
import 'package:trans_lark/global/translate_language.dart';
import 'package:trans_lark/global/tts_manager.dart';
import 'package:trans_lark/page/settings/settings_view.dart';
import 'package:trans_lark/util/device_info_util.dart';
import 'package:trans_lark/util/num_util.dart';
import 'package:trans_lark/util/obj_util.dart';
import 'package:trans_lark/util/permission_util.dart';
import 'package:trans_lark/widget/base_easyloading.dart';
import 'package:trans_lark/widget/photo_picker_bottom_sheet.dart';
import 'package:trans_lark/widget/speak_dialog.dart';
/// @description:
/// @author
/// @date: 2024-06-26 14:23:43
class HomeLogic extends GetxController {
var lastWords = '';
var fromLanguage = Rx<LanguageEntity?>(null);
var toLanguage = Rx<LanguageEntity?>(null);
var fromStr = Rx<String?>(null);
var toStr = Rx<String?>(null);
@override
void onInit() {
super.onInit();
AppTrackingAuthorizationManager().requestTrackingAuthorization();
}
@override
void onReady() {
super.onReady();
_getDailyQuote();
}
Future<void> _getDailyQuote() async {
var languageScene = <LanguageEntity>[
LanguageEntity(languageCode: 'ar', languageName: 'Arabic'),
LanguageEntity(languageCode: 'bn', languageName: 'Bengali'),
LanguageEntity(languageCode: 'zh-cn', languageName: 'Chinese (Simplified)'),
LanguageEntity(languageCode: 'en', languageName: 'English'),
LanguageEntity(languageCode: 'fr', languageName: 'French'),
LanguageEntity(languageCode: 'de', languageName: 'German'),
LanguageEntity(languageCode: 'hi', languageName: 'Hindi'),
LanguageEntity(languageCode: 'ja', languageName: 'Japanese'),
LanguageEntity(languageCode: 'jv', languageName: 'Javanese'),
LanguageEntity(languageCode: 'ko', languageName: 'Korean'),
LanguageEntity(languageCode: 'pt', languageName: 'Portuguese'),
LanguageEntity(languageCode: 'pa', languageName: 'Punjabi'),
LanguageEntity(languageCode: 'ru', languageName: 'Russian'),
LanguageEntity(languageCode: 'es', languageName: 'Spanish'),
];
final f = NumUtil.getRandomNumber(0, languageScene.length);
final t = NumUtil.getRandomNumberExcludingCurrent(0, languageScene.length, f);
fromLanguage.value = languageScene[f];
toLanguage.value = languageScene[t];
var data = jsonDecode(await rootBundle.loadString(Assets.jsonTranslationScene));
if (data != null && data is List) {
var sceneTypeList = data.map((e) => SceneEntity.fromMap(e)).toList();
if (sceneTypeList.isNotEmpty) {
var x = NumUtil.getRandomNumber(0, sceneTypeList.length);
SceneEntity entity = sceneTypeList[x];
if (entity.sceneList != null && entity.sceneList!.isNotEmpty) {
var y = NumUtil.getRandomNumber(0, entity.sceneList!.length);
fromStr.value = _getSentence(true, entity.sceneList![y]);
toStr.value = _getSentence(false, entity.sceneList![y]);
}
}
}
}
String _getSentence(bool isFrom, SceneList item) {
List keys = item.toMap().keys.toList();
int index = 0;
for (var i = 0; i < keys.length; ++i) {
var e = keys[i];
if (e == (isFrom ? fromLanguage.value?.languageName : toLanguage.value?.languageName)) {
index = i;
break;
}
}
if (item.toMap().values.toList()[index] != null) {
return item.toMap().values.toList()[index];
}
return 'loading';
}
void translatorTtsPlay(bool isFrom) {
if (fromLanguage.value != null && toLanguage.value != null) {
TtsManager().translatorTtsPlay(
isFrom ? fromStr.value! : toStr.value!,
isFrom ? fromLanguage.value!.languageCode : toLanguage.value!.languageCode,
);
}
}
void openSettings() {
Get.bottomSheet(
isScrollControlled: true,
SettingsView(),
);
}
void openSceneType() {
Get.toNamed(GetRouter.sceneType);
}
Future<void> onTapPhotos() async {
Get.bottomSheet(
isScrollControlled: true,
PhotoPickerBottomSheet(
funCamera: () async {
bool result = await PermissionUtil.checkPermission([Permission.camera]);
if (!result) return;
_openCameraGallery(ImageSource.camera);
},
funGallery: () async {
Permission permission = Permission.photos;
if (Platform.isAndroid) {
int sdkInt = await DeviceInfoUtil.getAndroidSDKInt();
if (sdkInt <= 32) {
permission = Permission.storage;
} else {
permission = Permission.photos;
}
}
bool result = await PermissionUtil.checkPermission([permission]);
if (!result) return;
_openCameraGallery(ImageSource.gallery);
},
),
);
}
Future<void> _openCameraGallery(ImageSource source) async {
String detectedValue = "";
final ImagePicker picker = ImagePicker();
final XFile? photo = await picker.pickImage(source: source);
if (photo != null) {
Get.to(() => SelectImageAreaTextDetect(
detectOnce: true,
enableImageInteractions: true,
imagePath: photo.path,
onDetectText: (v) {
if (v is String) {
detectedValue = v;
}
if (v is List) {
int counter = 0;
for (var element in v) {
detectedValue += "$counter. \t\t $element \n\n";
counter++;
}
}
},
onDetectError: (error) {
///This error will occurred in Android only while user will try to crop image at max zoom level then ml kit will throw max 32 height/width exception
if (error is PlatformException && (error.message?.contains("InputImage width and height should be at least 32!") ?? false)) {
BaseEasyLoading.toast('Selected area should be able to crop image with at least 32 width and height.');
}
},
))?.then(
(onValue) {
if (ObjUtil.isEmpty(detectedValue)) {
BaseEasyLoading.toast('No text recognized');
return;
}
Get.toNamed(
GetRouter.translateResult,
arguments: {"sourceText": detectedValue},
);
},
);
}
}
Future<void> onTapSpeak() async {
bool micResult = await PermissionUtil.checkPermission([Permission.microphone]);
if (!micResult) return;
if (Platform.isIOS) {
bool speechResult = await PermissionUtil.checkPermission([Permission.speech]);
if (!speechResult) return;
}
await Get.dialog(
barrierDismissible: true,
useSafeArea: false,
SpeakDialog(
isListening: SpeechToTextManager().isListening,
onTap: () async {
if (!SpeechToTextManager().hasSpeech) {
await SpeechToTextManager().initSpeech();
}
if (SpeechToTextManager().hasSpeech) {
if (SpeechToTextManager().isListening.value) {
_openTranslatorResultPage();
} else {
SpeechToTextManager().startListening(TranslateLanguage().fromLanguageEntity.value.languageCode, _onSpeechResult);
}
} else {
Get.back();
BaseEasyLoading.toast('Speech not available');
}
},
),
);
if (Get.isDialogOpen != null && !Get.isDialogOpen!) {
SpeechToTextManager().stopListening();
}
}
void _onSpeechResult(SpeechRecognitionResult result) {
debugPrint('识别结果:${result.recognizedWords}');
lastWords = result.recognizedWords;
}
void _openTranslatorResultPage() {
if (ObjUtil.isEmpty(lastWords)) {
BaseEasyLoading.toast('No text recognized');
return;
}
Get.back();
Get.toNamed(
GetRouter.translateResult,
arguments: {"sourceText": lastWords},
);
}
void openTranslate() {
Get.toNamed(GetRouter.translate);
}
Future<void> openFaceToFace() async {
bool micResult = await PermissionUtil.checkPermission([Permission.microphone]);
if (!micResult) return;
if (Platform.isIOS) {
bool speechResult = await PermissionUtil.checkPermission([Permission.speech]);
if (!speechResult) return;
}
Get.toNamed(GetRouter.faceToFace);
}
void openTranslateHistory() {
Get.toNamed(GetRouter.translateHistory);
}
}