This commit is contained in:
xh 2024-07-23 16:16:11 +08:00
parent a1bfd4a3f8
commit 577a4e6b8f
54 changed files with 423 additions and 460 deletions

View File

@ -1,7 +1,3 @@
// Author: fengshengxiong
// Date: 2024/6/4
// Description:
import 'dart:convert'; import 'dart:convert';
import 'package:hive/hive.dart'; import 'package:hive/hive.dart';

View File

@ -1,7 +1,3 @@
// Author: fengshengxiong
// Date: 2024/7/8
// Description:
import 'dart:convert'; import 'dart:convert';
class SceneEntity { class SceneEntity {

View File

@ -1,4 +1,3 @@
// ignore_for_file: public_member_api_docs, sort_constructors_first
import 'dart:convert'; import 'dart:convert';
class TranslatorHistoryEntity { class TranslatorHistoryEntity {

View File

@ -1,9 +0,0 @@
// Author: fengshengxiong
// Date: 2024/6/13
// Description: App配置
class AppConfig {
/// App名称
static const appName = 'TransLark';
}

View File

@ -1,12 +1,9 @@
// Author: fengshengxiong
// Date: 2024/6/26
// Description: iOS跟踪授权工具
import 'dart:async'; import 'dart:async';
import 'dart:io'; import 'dart:io';
import 'package:app_tracking_transparency/app_tracking_transparency.dart'; import 'package:app_tracking_transparency/app_tracking_transparency.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:trans_lark/util/log_print.dart';
class AppTrackingAuthorizationManager { class AppTrackingAuthorizationManager {
AppTrackingAuthorizationManager._(); AppTrackingAuthorizationManager._();
@ -26,7 +23,7 @@ class AppTrackingAuthorizationManager {
if (status == TrackingStatus.notDetermined) { if (status == TrackingStatus.notDetermined) {
if (_timer != null && _timer!.isActive) { if (_timer != null && _timer!.isActive) {
final TrackingStatus status = await AppTrackingTransparency.requestTrackingAuthorization(); final TrackingStatus status = await AppTrackingTransparency.requestTrackingAuthorization();
debugPrint('跟踪授权状态: $status'); LogPrint.d('跟踪授权状态: $status');
} else { } else {
_startTimer(); _startTimer();
} }

View File

@ -1,20 +1,20 @@
import 'package:flutter/foundation.dart';
import 'package:flutter_tts/flutter_tts.dart'; import 'package:flutter_tts/flutter_tts.dart';
import 'package:trans_lark/util/log_print.dart';
import 'package:trans_lark/widget/base_easyloading.dart'; import 'package:trans_lark/widget/base_easyloading.dart';
class TtsManager { class FlutterTtsManager {
TtsManager._(); FlutterTtsManager._();
static final TtsManager _instance = TtsManager._(); static final FlutterTtsManager _instance = FlutterTtsManager._();
factory TtsManager() { factory FlutterTtsManager() {
return _instance; return _instance;
} }
late FlutterTts ttsController; late FlutterTts ttsController;
Future<void> initTts() async { Future<void> init() async {
debugPrint("TTS Service init start"); LogPrint.d("TTS Service init start");
ttsController = FlutterTts(); ttsController = FlutterTts();
await ttsController.setSharedInstance(true); await ttsController.setSharedInstance(true);
await ttsController.setIosAudioCategory( await ttsController.setIosAudioCategory(
@ -27,7 +27,7 @@ class TtsManager {
IosTextToSpeechAudioMode.voicePrompt); IosTextToSpeechAudioMode.voicePrompt);
await ttsController.awaitSpeakCompletion(true); await ttsController.awaitSpeakCompletion(true);
await ttsController.awaitSynthCompletion(true); await ttsController.awaitSynthCompletion(true);
debugPrint("TTS Service init success"); LogPrint.d("TTS Service init success");
} }
Future<void> translatorTtsPlay(String text, String language) async { Future<void> translatorTtsPlay(String text, String language) async {

View File

@ -0,0 +1,4 @@
class GlobalConfig {
static const appName = 'TransLark';
}

View File

@ -1,11 +1,7 @@
// Author: fengshengxiong
// Date: 2024/5/8
// Description:
import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:speech_to_text/speech_recognition_error.dart'; import 'package:speech_to_text/speech_recognition_error.dart';
import 'package:speech_to_text/speech_to_text.dart'; import 'package:speech_to_text/speech_to_text.dart';
import 'package:trans_lark/util/log_print.dart';
import 'package:trans_lark/widget/base_easyloading.dart'; import 'package:trans_lark/widget/base_easyloading.dart';
class SpeechToTextManager { class SpeechToTextManager {
@ -32,12 +28,12 @@ class SpeechToTextManager {
_speechToText.statusListener ??= _statusListener; _speechToText.statusListener ??= _statusListener;
_speechToText.errorListener ??= _errorListener; _speechToText.errorListener ??= _errorListener;
} catch (e) { } catch (e) {
debugPrint('Speech recognition failed: ${e.toString()}'); LogPrint.d('Speech recognition failed: ${e.toString()}');
} }
} }
void _statusListener(String status) { void _statusListener(String status) {
debugPrint('状态:$status'); LogPrint.d('状态:$status');
if (status == 'listening') { if (status == 'listening') {
isListening.value = true; isListening.value = true;
} else { } else {
@ -46,7 +42,7 @@ class SpeechToTextManager {
} }
void _errorListener(SpeechRecognitionError error) { void _errorListener(SpeechRecognitionError error) {
debugPrint('Received error status: $error, listening: ${_speechToText.isListening}'); LogPrint.d('Received error status: $error, listening: ${_speechToText.isListening}');
BaseEasyLoading.toast('Speech recognition failed: ${error.errorMsg}'); BaseEasyLoading.toast('Speech recognition failed: ${error.errorMsg}');
} }
@ -67,9 +63,9 @@ class SpeechToTextManager {
BaseEasyLoading.dismiss(); BaseEasyLoading.dismiss();
} catch (e) { } catch (e) {
if (e.runtimeType == ListenFailedException) { if (e.runtimeType == ListenFailedException) {
debugPrint('speechToText.listen${(e as ListenFailedException).message}'); LogPrint.d('speechToText.listen${(e as ListenFailedException).message}');
} else { } else {
debugPrint('speechToText.listen${e.toString()}'); LogPrint.d('speechToText.listen${e.toString()}');
} }
BaseEasyLoading.toast('The current language does not support speech recognition'); BaseEasyLoading.toast('The current language does not support speech recognition');
} }

View File

@ -1,7 +1,3 @@
// Author: fengshengxiong
// Date: 2024/5/8
// Description:
import 'dart:convert'; import 'dart:convert';
import 'dart:ui'; import 'dart:ui';
@ -12,12 +8,12 @@ import 'package:trans_lark/entity/language_entity.dart';
import 'package:trans_lark/generated/assets.dart'; import 'package:trans_lark/generated/assets.dart';
import 'package:trans_lark/util/num_util.dart'; import 'package:trans_lark/util/num_util.dart';
class TranslateLanguage { class TranslateManager {
TranslateLanguage._(); TranslateManager._();
static final TranslateLanguage _instance = TranslateLanguage._(); static final TranslateManager _instance = TranslateManager._();
factory TranslateLanguage() { factory TranslateManager() {
return _instance; return _instance;
} }

View File

@ -5,10 +5,10 @@ import 'package:flutter/services.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart'; import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:trans_lark/core/router/router.dart'; import 'package:trans_lark/global/flutter_tts_manager.dart';
import 'package:trans_lark/global/app_config.dart'; import 'package:trans_lark/global/global_config.dart';
import 'package:trans_lark/global/translate_language.dart'; import 'package:trans_lark/global/translate_manager.dart';
import 'package:trans_lark/global/tts_manager.dart'; import 'package:trans_lark/router/router.dart';
import 'package:trans_lark/storage/hive_storage.dart'; import 'package:trans_lark/storage/hive_storage.dart';
import 'package:trans_lark/widget/base_easyloading.dart'; import 'package:trans_lark/widget/base_easyloading.dart';
@ -31,8 +31,8 @@ void main() async {
)); ));
} }
await TranslateLanguage().init(); await TranslateManager().init();
await TtsManager().initTts(); await FlutterTtsManager().init();
runApp(const MyApp()); runApp(const MyApp());
} }
@ -46,9 +46,11 @@ class MyApp extends StatelessWidget {
return KeyboardDismissOnTap( return KeyboardDismissOnTap(
child: GetMaterialApp( child: GetMaterialApp(
debugShowCheckedModeBanner: false, debugShowCheckedModeBanner: false,
title: AppConfig.appName, title: GlobalConfig.appName,
theme: ThemeData( theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: const Color.fromARGB(255, 185, 239, 200)), colorScheme: ColorScheme.fromSeed(
seedColor: const Color.fromARGB(255, 185, 239, 200),
),
useMaterial3: true, useMaterial3: true,
), ),
initialRoute: GetRouter.home, initialRoute: GetRouter.home,

View File

@ -1,6 +1,5 @@
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:trans_lark/page/face_to_face/face_to_face_controller.dart';
import 'face_to_face_controller.dart';
class FaceToFaceBinding extends Bindings { class FaceToFaceBinding extends Bindings {
@override @override

View File

@ -1,9 +1,10 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:speech_to_text/speech_recognition_result.dart'; import 'package:speech_to_text/speech_recognition_result.dart';
import 'package:trans_lark/global/translate_manager.dart';
import 'package:trans_lark/util/log_print.dart';
import 'package:translator/translator.dart'; import 'package:translator/translator.dart';
import 'package:trans_lark/global/speech_to_text_manager.dart'; import 'package:trans_lark/global/speech_to_text_manager.dart';
import 'package:trans_lark/global/translate_language.dart';
import 'package:trans_lark/util/obj_util.dart'; import 'package:trans_lark/util/obj_util.dart';
import 'package:trans_lark/widget/base_easyloading.dart'; import 'package:trans_lark/widget/base_easyloading.dart';
@ -58,14 +59,14 @@ class FaceToFaceController extends GetxController with GetSingleTickerProviderSt
} }
selectedUnder.value = true; selectedUnder.value = true;
_scrollToBottom(); _scrollToBottom();
SpeechToTextManager().startListening(TranslateLanguage().fromLanguageEntity.value.languageCode, _onSpeechResult); SpeechToTextManager().startListening(TranslateManager().fromLanguageEntity.value.languageCode, _onSpeechResult);
} else { } else {
if (selectedUnder.value) { if (selectedUnder.value) {
await SpeechToTextManager().stopListening(); await SpeechToTextManager().stopListening();
} }
selectedUnder.value = false; selectedUnder.value = false;
_scrollToBottom(); _scrollToBottom();
SpeechToTextManager().startListening(TranslateLanguage().toLanguageEntity.value.languageCode, _onSpeechResult); SpeechToTextManager().startListening(TranslateManager().toLanguageEntity.value.languageCode, _onSpeechResult);
} }
} else { } else {
BaseEasyLoading.toast('Speech not available'); BaseEasyLoading.toast('Speech not available');
@ -73,19 +74,19 @@ class FaceToFaceController extends GetxController with GetSingleTickerProviderSt
} }
Future<void> _onSpeechResult(SpeechRecognitionResult result) async { Future<void> _onSpeechResult(SpeechRecognitionResult result) async {
debugPrint('识别结果:${result.recognizedWords}'); LogPrint.d('识别结果:${result.recognizedWords}');
if (ObjUtil.isNotEmptyStr(result.recognizedWords)) { if (ObjUtil.isNotEmptyStr(result.recognizedWords)) {
if (selectedUnder.value) { if (selectedUnder.value) {
underText.value += '${result.recognizedWords}\n'; underText.value += '${result.recognizedWords}\n';
var translateText = await _translation(result.recognizedWords); var translateText = await _translation(result.recognizedWords);
debugPrint('翻译结果:${result.recognizedWords}'); LogPrint.d('翻译结果:${result.recognizedWords}');
if (ObjUtil.isNotEmptyStr(translateText)) { if (ObjUtil.isNotEmptyStr(translateText)) {
aboveText.value += '$translateText\n'; aboveText.value += '$translateText\n';
} }
} else { } else {
aboveText.value += '${result.recognizedWords}\n'; aboveText.value += '${result.recognizedWords}\n';
var translateText = await _translation(result.recognizedWords); var translateText = await _translation(result.recognizedWords);
debugPrint('翻译结果:${result.recognizedWords}'); LogPrint.d('翻译结果:${result.recognizedWords}');
if (ObjUtil.isNotEmptyStr(translateText)) { if (ObjUtil.isNotEmptyStr(translateText)) {
underText.value += '$translateText\n'; underText.value += '$translateText\n';
} }
@ -96,8 +97,8 @@ class FaceToFaceController extends GetxController with GetSingleTickerProviderSt
Future<String> _translation(String sourceText) async { Future<String> _translation(String sourceText) async {
try { try {
String from = selectedUnder.value ? TranslateLanguage().fromLanguageEntity.value.languageCode : TranslateLanguage().toLanguageEntity.value.languageCode; String from = selectedUnder.value ? TranslateManager().fromLanguageEntity.value.languageCode : TranslateManager().toLanguageEntity.value.languageCode;
String to = selectedUnder.value ? TranslateLanguage().toLanguageEntity.value.languageCode : TranslateLanguage().fromLanguageEntity.value.languageCode; String to = selectedUnder.value ? TranslateManager().toLanguageEntity.value.languageCode : TranslateManager().fromLanguageEntity.value.languageCode;
Translation translate = await _translator.translate( Translation translate = await _translator.translate(
sourceText, sourceText,
from: from, from: from,
@ -105,7 +106,7 @@ class FaceToFaceController extends GetxController with GetSingleTickerProviderSt
); );
return translate.text; return translate.text;
} catch (e) { } catch (e) {
debugPrint('Translation failed,${e.toString()}'); LogPrint.d('Translation failed,${e.toString()}');
} }
return ''; return '';
} }

View File

@ -3,13 +3,12 @@ import 'package:flutter_svg/svg.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:trans_lark/generated/assets.dart'; import 'package:trans_lark/generated/assets.dart';
import 'package:trans_lark/global/speech_to_text_manager.dart'; import 'package:trans_lark/global/speech_to_text_manager.dart';
import 'package:trans_lark/page/face_to_face/face_to_face_controller.dart';
import 'package:trans_lark/util/obj_util.dart'; import 'package:trans_lark/util/obj_util.dart';
import 'package:trans_lark/widget/base_appbar.dart'; import 'package:trans_lark/widget/base_appbar.dart';
import 'package:wave/config.dart'; import 'package:wave/config.dart';
import 'package:wave/wave.dart'; import 'package:wave/wave.dart';
import 'face_to_face_controller.dart';
class FaceToFaceView extends StatelessWidget { class FaceToFaceView extends StatelessWidget {
FaceToFaceView({super.key}); FaceToFaceView({super.key});

View File

@ -1,23 +1,23 @@
import 'dart:convert'; import 'dart:convert';
import 'dart:io'; import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_text_detect_area/flutter_text_detect_area.dart'; import 'package:flutter_text_detect_area/flutter_text_detect_area.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:image_picker/image_picker.dart'; import 'package:image_picker/image_picker.dart';
import 'package:permission_handler/permission_handler.dart'; import 'package:permission_handler/permission_handler.dart';
import 'package:speech_to_text/speech_recognition_result.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/language_entity.dart';
import 'package:trans_lark/entity/scene_entity.dart'; import 'package:trans_lark/entity/scene_entity.dart';
import 'package:trans_lark/generated/assets.dart'; import 'package:trans_lark/generated/assets.dart';
import 'package:trans_lark/global/app_tracking_authorization_manager.dart'; import 'package:trans_lark/global/app_tracking_authorization_manager.dart';
import 'package:trans_lark/global/flutter_tts_manager.dart';
import 'package:trans_lark/global/speech_to_text_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/translate_manager.dart';
import 'package:trans_lark/global/tts_manager.dart';
import 'package:trans_lark/page/settings/settings_view.dart'; import 'package:trans_lark/page/settings/settings_view.dart';
import 'package:trans_lark/router/router.dart';
import 'package:trans_lark/util/device_info_util.dart'; import 'package:trans_lark/util/device_info_util.dart';
import 'package:trans_lark/util/log_print.dart';
import 'package:trans_lark/util/num_util.dart'; import 'package:trans_lark/util/num_util.dart';
import 'package:trans_lark/util/obj_util.dart'; import 'package:trans_lark/util/obj_util.dart';
import 'package:trans_lark/util/permission_util.dart'; import 'package:trans_lark/util/permission_util.dart';
@ -25,9 +25,6 @@ import 'package:trans_lark/widget/base_easyloading.dart';
import 'package:trans_lark/widget/photo_picker_bottom_sheet.dart'; import 'package:trans_lark/widget/photo_picker_bottom_sheet.dart';
import 'package:trans_lark/widget/speak_dialog.dart'; import 'package:trans_lark/widget/speak_dialog.dart';
/// @description:
/// @author
/// @date: 2024-06-26 14:23:43
class HomeLogic extends GetxController { class HomeLogic extends GetxController {
static HomeLogic get to => Get.find<HomeLogic>(); static HomeLogic get to => Get.find<HomeLogic>();
var lastWords = ''; var lastWords = '';
@ -51,9 +48,8 @@ class HomeLogic extends GetxController {
Future<void> getDailyQuote() async { Future<void> getDailyQuote() async {
LanguageEntity fromLanguageEntity = LanguageEntity fromLanguageEntity =
TranslateLanguage().fromLanguageEntity.value; TranslateManager().fromLanguageEntity.value;
LanguageEntity toLanguageEntity = LanguageEntity toLanguageEntity = TranslateManager().toLanguageEntity.value;
TranslateLanguage().toLanguageEntity.value;
var languageScene = <LanguageEntity>[ var languageScene = <LanguageEntity>[
LanguageEntity(languageCode: 'ar', languageName: 'Arabic'), LanguageEntity(languageCode: 'ar', languageName: 'Arabic'),
LanguageEntity(languageCode: 'bn', languageName: 'Bengali'), LanguageEntity(languageCode: 'bn', languageName: 'Bengali'),
@ -128,7 +124,7 @@ class HomeLogic extends GetxController {
void translatorTtsPlay(bool isFrom) { void translatorTtsPlay(bool isFrom) {
if (fromLanguage.value != null && toLanguage.value != null) { if (fromLanguage.value != null && toLanguage.value != null) {
TtsManager().translatorTtsPlay( FlutterTtsManager().translatorTtsPlay(
isFrom ? fromStr.value! : toStr.value!, isFrom ? fromStr.value! : toStr.value!,
isFrom isFrom
? fromLanguage.value!.languageCode ? fromLanguage.value!.languageCode
@ -245,7 +241,7 @@ class HomeLogic extends GetxController {
_openTranslatorResultPage(); _openTranslatorResultPage();
} else { } else {
SpeechToTextManager().startListening( SpeechToTextManager().startListening(
TranslateLanguage().fromLanguageEntity.value.languageCode, TranslateManager().fromLanguageEntity.value.languageCode,
_onSpeechResult); _onSpeechResult);
} }
} else { } else {
@ -261,7 +257,7 @@ class HomeLogic extends GetxController {
} }
void _onSpeechResult(SpeechRecognitionResult result) { void _onSpeechResult(SpeechRecognitionResult result) {
debugPrint('识别结果:${result.recognizedWords}'); LogPrint.d('识别结果:${result.recognizedWords}');
lastWords = result.recognizedWords; lastWords = result.recognizedWords;
} }

View File

@ -6,9 +6,6 @@ import 'package:trans_lark/page/home/home_logic.dart';
import 'package:trans_lark/util/obj_util.dart'; import 'package:trans_lark/util/obj_util.dart';
import 'package:trans_lark/widget/language_bar.dart'; import 'package:trans_lark/widget/language_bar.dart';
/// @description:
/// @author : lifu
/// @date: 2024-06-26 14:23:43
class HomePage extends StatelessWidget { class HomePage extends StatelessWidget {
final HomeLogic logic = Get.put(HomeLogic()); final HomeLogic logic = Get.put(HomeLogic());
@ -145,8 +142,12 @@ class HomePage extends StatelessWidget {
height: 76, height: 76,
alignment: Alignment.center, alignment: Alignment.center,
decoration: BoxDecoration( decoration: BoxDecoration(
color: color: const Color.fromARGB(
const Color.fromARGB(213, 69, 168, 254), 213,
69,
168,
254,
),
borderRadius: BorderRadius.circular(16), borderRadius: BorderRadius.circular(16),
border: Border.all( border: Border.all(
width: 1.5, width: 1.5,
@ -169,8 +170,9 @@ class HomePage extends StatelessWidget {
), ),
), ),
Padding( Padding(
padding: padding: const EdgeInsets.only(
const EdgeInsets.only(right: 20), right: 20,
),
child: GestureDetector( child: GestureDetector(
onTap: logic.onTapSpeak, onTap: logic.onTapSpeak,
child: Container( child: Container(
@ -183,10 +185,11 @@ class HomePage extends StatelessWidget {
BorderRadius.circular(18), BorderRadius.circular(18),
), ),
child: SvgPicture.asset( child: SvgPicture.asset(
Assets.svgHomeVoice), Assets.svgHomeVoice,
),
), ),
), ),
) ),
], ],
), ),
), ),

View File

@ -1,6 +1,5 @@
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:trans_lark/page/scene_list/scene_list_controller.dart';
import 'scene_list_controller.dart';
class SceneListBinding extends Bindings { class SceneListBinding extends Bindings {
@override @override

View File

@ -1,7 +1,7 @@
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:trans_lark/entity/language_entity.dart'; import 'package:trans_lark/entity/language_entity.dart';
import 'package:trans_lark/entity/scene_entity.dart'; import 'package:trans_lark/entity/scene_entity.dart';
import 'package:trans_lark/global/tts_manager.dart'; import 'package:trans_lark/global/flutter_tts_manager.dart';
import 'package:trans_lark/widget/language_scene_bottom_sheet.dart'; import 'package:trans_lark/widget/language_scene_bottom_sheet.dart';
class SceneListController extends GetxController { class SceneListController extends GetxController {
@ -57,7 +57,10 @@ class SceneListController extends GetxController {
int index = 0; int index = 0;
for (var i = 0; i < keys.length; ++i) { for (var i = 0; i < keys.length; ++i) {
var e = keys[i]; var e = keys[i];
if (e == (isFrom ? fromLanguage.value.languageName : toLanguage.value.languageName)) { if (e ==
(isFrom
? fromLanguage.value.languageName
: toLanguage.value.languageName)) {
index = i; index = i;
break; break;
} }
@ -69,8 +72,9 @@ class SceneListController extends GetxController {
} }
void translatorTtsPlay(bool isFrom, SceneList item) { void translatorTtsPlay(bool isFrom, SceneList item) {
TtsManager().translatorTtsPlay( FlutterTtsManager().translatorTtsPlay(
getSentence(isFrom, item), isFrom ? fromLanguage.value.languageCode : toLanguage.value.languageCode getSentence(isFrom, item),
isFrom ? fromLanguage.value.languageCode : toLanguage.value.languageCode,
); );
} }
} }

View File

@ -3,12 +3,11 @@ import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:trans_lark/entity/scene_entity.dart'; import 'package:trans_lark/entity/scene_entity.dart';
import 'package:trans_lark/generated/assets.dart'; import 'package:trans_lark/generated/assets.dart';
import 'package:trans_lark/page/scene_list/scene_list_controller.dart';
import 'package:trans_lark/widget/base_appbar.dart'; import 'package:trans_lark/widget/base_appbar.dart';
import 'package:trans_lark/widget/base_scrollbar.dart'; import 'package:trans_lark/widget/base_scrollbar.dart';
import 'package:trans_lark/widget/language_scene_bar.dart'; import 'package:trans_lark/widget/language_scene_bar.dart';
import 'scene_list_controller.dart';
class SceneListView extends StatelessWidget { class SceneListView extends StatelessWidget {
SceneListView({super.key}); SceneListView({super.key});
@ -33,7 +32,8 @@ class SceneListView extends StatelessWidget {
Expanded( Expanded(
child: BaseScrollbar( child: BaseScrollbar(
child: ListView.separated( child: ListView.separated(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), padding:
const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
itemCount: controller.sceneList.length, itemCount: controller.sceneList.length,
itemBuilder: (context, index) { itemBuilder: (context, index) {
var item = controller.sceneList[index]; var item = controller.sceneList[index];

View File

@ -1,6 +1,5 @@
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:trans_lark/page/scene_type/scene_type_controller.dart';
import 'scene_type_controller.dart';
class SceneTypeBinding extends Bindings { class SceneTypeBinding extends Bindings {
@override @override

View File

@ -2,9 +2,9 @@ import 'dart:convert';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:trans_lark/core/router/router.dart';
import 'package:trans_lark/entity/scene_entity.dart'; import 'package:trans_lark/entity/scene_entity.dart';
import 'package:trans_lark/generated/assets.dart'; import 'package:trans_lark/generated/assets.dart';
import 'package:trans_lark/router/router.dart';
import 'package:trans_lark/widget/view_state_widget.dart'; import 'package:trans_lark/widget/view_state_widget.dart';
class SceneTypeController extends GetxController { class SceneTypeController extends GetxController {

View File

@ -3,13 +3,12 @@ import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:trans_lark/entity/scene_entity.dart'; import 'package:trans_lark/entity/scene_entity.dart';
import 'package:trans_lark/generated/assets.dart'; import 'package:trans_lark/generated/assets.dart';
import 'package:trans_lark/page/scene_type/scene_type_controller.dart';
import 'package:trans_lark/util/obj_util.dart'; import 'package:trans_lark/util/obj_util.dart';
import 'package:trans_lark/widget/base_appbar.dart'; import 'package:trans_lark/widget/base_appbar.dart';
import 'package:trans_lark/widget/base_scrollbar.dart'; import 'package:trans_lark/widget/base_scrollbar.dart';
import 'package:trans_lark/widget/view_state_widget.dart'; import 'package:trans_lark/widget/view_state_widget.dart';
import 'scene_type_controller.dart';
class SceneTypeView extends StatelessWidget { class SceneTypeView extends StatelessWidget {
SceneTypeView({super.key}); SceneTypeView({super.key});

View File

@ -1,6 +1,6 @@
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:package_info_plus/package_info_plus.dart'; import 'package:package_info_plus/package_info_plus.dart';
import 'package:trans_lark/core/router/router.dart'; import 'package:trans_lark/router/router.dart';
class SettingsController extends GetxController { class SettingsController extends GetxController {
var versionName = ''.obs; var versionName = ''.obs;

View File

@ -1,7 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:trans_lark/generated/assets.dart'; import 'package:trans_lark/generated/assets.dart';
import 'package:trans_lark/global/app_config.dart'; import 'package:trans_lark/global/global_config.dart';
import 'package:trans_lark/widget/divider_widget.dart'; import 'package:trans_lark/widget/divider_widget.dart';
import 'settings_controller.dart'; import 'settings_controller.dart';
@ -53,7 +53,7 @@ class SettingsView extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
const Text( const Text(
AppConfig.appName, GlobalConfig.appName,
style: TextStyle( style: TextStyle(
color: Colors.black, color: Colors.black,
fontSize: 22, fontSize: 22,

View File

@ -1,6 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:trans_lark/core/router/router.dart'; import 'package:trans_lark/router/router.dart';
class SplashController extends GetxController with GetTickerProviderStateMixin { class SplashController extends GetxController with GetTickerProviderStateMixin {
var processValue = 0.0.obs; var processValue = 0.0.obs;

View File

@ -1,14 +1,14 @@
import 'dart:io'; import 'dart:io';
import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:permission_handler/permission_handler.dart'; import 'package:permission_handler/permission_handler.dart';
import 'package:speech_to_text/speech_recognition_result.dart'; import 'package:speech_to_text/speech_recognition_result.dart';
import 'package:trans_lark/core/router/router.dart';
import 'package:trans_lark/entity/history_model.dart'; import 'package:trans_lark/entity/history_model.dart';
import 'package:trans_lark/global/speech_to_text_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/translate_manager.dart';
import 'package:trans_lark/router/router.dart';
import 'package:trans_lark/storage/history_data.dart'; import 'package:trans_lark/storage/history_data.dart';
import 'package:trans_lark/util/log_print.dart';
import 'package:trans_lark/util/obj_util.dart'; import 'package:trans_lark/util/obj_util.dart';
import 'package:trans_lark/util/permission_util.dart'; import 'package:trans_lark/util/permission_util.dart';
import 'package:trans_lark/widget/base_easyloading.dart'; import 'package:trans_lark/widget/base_easyloading.dart';
@ -48,10 +48,12 @@ class TranslatorLogic extends GetxController {
} }
Future<void> _onTapSpeak() async { Future<void> _onTapSpeak() async {
bool micResult = await PermissionUtil.checkPermission([Permission.microphone]); bool micResult =
await PermissionUtil.checkPermission([Permission.microphone]);
if (!micResult) return; if (!micResult) return;
if (Platform.isIOS) { if (Platform.isIOS) {
bool speechResult = await PermissionUtil.checkPermission([Permission.speech]); bool speechResult =
await PermissionUtil.checkPermission([Permission.speech]);
if (!speechResult) return; if (!speechResult) return;
} }
await Get.dialog( await Get.dialog(
@ -67,7 +69,9 @@ class TranslatorLogic extends GetxController {
if (SpeechToTextManager().isListening.value) { if (SpeechToTextManager().isListening.value) {
_openTranslatorResultPage(); _openTranslatorResultPage();
} else { } else {
SpeechToTextManager().startListening(TranslateLanguage().fromLanguageEntity.value.languageCode, _onSpeechResult); SpeechToTextManager().startListening(
TranslateManager().fromLanguageEntity.value.languageCode,
_onSpeechResult);
} }
} else { } else {
Get.back(); Get.back();
@ -82,7 +86,7 @@ class TranslatorLogic extends GetxController {
} }
void _onSpeechResult(SpeechRecognitionResult result) { void _onSpeechResult(SpeechRecognitionResult result) {
debugPrint('识别结果:${result.recognizedWords}'); LogPrint.d('识别结果:${result.recognizedWords}');
state.lastWords = result.recognizedWords; state.lastWords = result.recognizedWords;
} }

View File

@ -3,16 +3,12 @@ import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart'; import 'package:flutter_svg/svg.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:trans_lark/generated/assets.dart'; import 'package:trans_lark/generated/assets.dart';
import 'package:trans_lark/page/translator/translator_logic.dart';
import 'package:trans_lark/page/translator/translator_state.dart';
import 'package:trans_lark/util/obj_util.dart'; import 'package:trans_lark/util/obj_util.dart';
import 'package:trans_lark/widget/base_appbar.dart'; import 'package:trans_lark/widget/base_appbar.dart';
import 'package:trans_lark/widget/language_bar.dart'; import 'package:trans_lark/widget/language_bar.dart';
import 'translator_logic.dart';
import 'translator_state.dart';
/// @description:
/// @lifu
/// @date: 2024-06-27 13:55:27
class TranslatorPage extends StatefulWidget { class TranslatorPage extends StatefulWidget {
const TranslatorPage({super.key}); const TranslatorPage({super.key});
@ -84,7 +80,8 @@ class _TranslatorPageState extends State<TranslatorPage> {
), ),
Obx(() { Obx(() {
return Padding( return Padding(
padding: EdgeInsets.only(top: state.isValue.value ? 26 : 20, right: 20), padding: EdgeInsets.only(
top: state.isValue.value ? 26 : 20, right: 20),
child: GestureDetector( child: GestureDetector(
onTap: logic.onTapSuffix, onTap: logic.onTapSuffix,
child: ClipOval( child: ClipOval(
@ -113,118 +110,123 @@ class _TranslatorPageState extends State<TranslatorPage> {
], ],
), ),
), ),
Obx(() => state.historyList.isNotEmpty Obx(
? Expanded( () => state.historyList.isNotEmpty
child: Column( ? Expanded(
children: [ child: Column(
const SizedBox(height: 30), children: [
Row( const SizedBox(height: 30),
mainAxisAlignment: MainAxisAlignment.spaceBetween, Row(
children: [ mainAxisAlignment: MainAxisAlignment.spaceBetween,
const Text( children: [
"History", const Text(
style: TextStyle( "History",
fontSize: 16, style: TextStyle(
color: Color(0xff979797), fontSize: 16,
fontWeight: FontWeight.w500, color: Color(0xff979797),
), fontWeight: FontWeight.w500,
),
IconButton(
onPressed: logic.cleanAllHistory,
icon: Image.asset(
Assets.imagesDeleteIcon,
width: 24,
height: 24,
),
),
],
),
Expanded(
child: ListView.builder(
itemCount: state.historyList.length,
itemBuilder: (context, index) {
final historyEntity = state.historyList[index];
return CustomPopupMenu(
arrowColor: Colors.black,
barrierColor: Colors.transparent,
position: PreferredPosition.top,
verticalMargin: 0,
pressType: PressType.longPress,
menuBuilder: () {
return GestureDetector(
onTap: () => logic.deleteItem(index),
child: Container(
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
color: Colors.black,
borderRadius: BorderRadius.circular(8),
), ),
child: Image.asset( ),
IconButton(
onPressed: logic.cleanAllHistory,
icon: Image.asset(
Assets.imagesDeleteIcon, Assets.imagesDeleteIcon,
width: 24, width: 24,
height: 24, height: 24,
), ),
), ),
); ],
}, ),
child: InkWell( Expanded(
onTap: () => logic.onTapHistoryItem(historyEntity), child: ListView.builder(
child: Column( itemCount: state.historyList.length,
crossAxisAlignment: CrossAxisAlignment.start, itemBuilder: (context, index) {
children: [ final historyEntity = state.historyList[index];
Padding( return CustomPopupMenu(
padding: const EdgeInsets.symmetric(vertical: 10), arrowColor: Colors.black,
child: RichText( barrierColor: Colors.transparent,
maxLines: 1, position: PreferredPosition.top,
overflow: TextOverflow.ellipsis, verticalMargin: 0,
text: TextSpan( pressType: PressType.longPress,
menuBuilder: () {
return GestureDetector(
onTap: () => logic.deleteItem(index),
child: Container(
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
color: Colors.black,
borderRadius:
BorderRadius.circular(8),
),
child: Image.asset(
Assets.imagesDeleteIcon,
width: 24,
height: 24,
),
),
);
},
child: InkWell(
onTap: () =>
logic.onTapHistoryItem(historyEntity),
child: Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [ children: [
TextSpan( Padding(
text: ObjUtil.getStr( padding: const EdgeInsets.symmetric(
historyEntity.sourceText), vertical: 10),
style: const TextStyle( child: RichText(
fontWeight: FontWeight.w500, maxLines: 1,
fontSize: 16, overflow: TextOverflow.ellipsis,
color: Color(0xff212121), text: TextSpan(
), children: [
), TextSpan(
const WidgetSpan( text: ObjUtil.getStr(
child: SizedBox( historyEntity.sourceText),
width: 6, style: const TextStyle(
), fontWeight: FontWeight.w500,
), fontSize: 16,
TextSpan( color: Color(0xff212121),
text: ObjUtil.getStr( ),
historyEntity.targetText), ),
style: const TextStyle( const WidgetSpan(
color: Color(0xff979797), child: SizedBox(
fontSize: 13, width: 6,
fontWeight: FontWeight.w400, ),
),
TextSpan(
text: ObjUtil.getStr(
historyEntity.targetText),
style: const TextStyle(
color: Color(0xff979797),
fontSize: 13,
fontWeight: FontWeight.w400,
),
),
],
),
), ),
), ),
], ],
), ),
), ),
), );
], },
), ),
), ),
); ],
}, ),
)
: Expanded(
child: Center(
child: Image.asset(
Assets.imagesRabbitSayGood,
width: 90,
height: 90,
),
),
), ),
),
],
),
)
: Expanded(
child: Center(
child: Image.asset(
Assets.imagesRabbitSayGood,
width: 90,
height: 90,
),
),
),
), ),
], ],
), ),

View File

@ -1,15 +1,11 @@
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:trans_lark/core/router/router.dart';
import 'package:trans_lark/entity/history_model.dart'; import 'package:trans_lark/entity/history_model.dart';
import 'package:trans_lark/global/tts_manager.dart'; import 'package:trans_lark/global/flutter_tts_manager.dart';
import 'package:trans_lark/page/translator_history/translator_history_state.dart';
import 'package:trans_lark/router/router.dart';
import 'package:trans_lark/storage/history_data.dart'; import 'package:trans_lark/storage/history_data.dart';
import 'package:trans_lark/util/obj_util.dart'; import 'package:trans_lark/util/obj_util.dart';
import 'translator_history_state.dart';
/// @description:
/// @author
/// @date: 2024-06-28 16:26:22
class TranslatorHistoryLogic extends GetxController { class TranslatorHistoryLogic extends GetxController {
final state = TranslatorHistoryState(); final state = TranslatorHistoryState();
@ -34,7 +30,10 @@ class TranslatorHistoryLogic extends GetxController {
void translatorTtsPlay(HistoryEntity entity) { void translatorTtsPlay(HistoryEntity entity) {
if (ObjUtil.isNotEmpty(entity.targetText)) { if (ObjUtil.isNotEmpty(entity.targetText)) {
TtsManager().translatorTtsPlay(entity.targetText!, entity.targetLanguageCode!); FlutterTtsManager().translatorTtsPlay(
entity.targetText!,
entity.targetLanguageCode!,
);
} }
} }
@ -46,7 +45,8 @@ class TranslatorHistoryLogic extends GetxController {
if (state.historyList[key] != null && state.historyList[key]!.isEmpty) { if (state.historyList[key] != null && state.historyList[key]!.isEmpty) {
state.historyList.remove(key); state.historyList.remove(key);
} }
final deleteEntity = list.firstWhereOrNull((item) => item.translationTime == entity.translationTime); final deleteEntity = list.firstWhereOrNull(
(item) => item.translationTime == entity.translationTime);
if (deleteEntity != null) { if (deleteEntity != null) {
HistoryData().delete(list.indexOf(deleteEntity)); HistoryData().delete(list.indexOf(deleteEntity));
} }

View File

@ -3,9 +3,6 @@ import 'package:get/get_rx/get_rx.dart';
import 'package:get/get_rx/src/rx_types/rx_types.dart'; import 'package:get/get_rx/src/rx_types/rx_types.dart';
import 'package:trans_lark/entity/history_model.dart'; import 'package:trans_lark/entity/history_model.dart';
/// @description:
/// @author
/// @date: 2024-06-28 16:26:22
class TranslatorHistoryState { class TranslatorHistoryState {
RxMap<String, List<HistoryEntity>> historyList = <String, List<HistoryEntity>>{}.obs; RxMap<String, List<HistoryEntity>> historyList = <String, List<HistoryEntity>>{}.obs;
} }

View File

@ -2,16 +2,12 @@ import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart'; import 'package:flutter_svg/svg.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:trans_lark/generated/assets.dart'; import 'package:trans_lark/generated/assets.dart';
import 'package:trans_lark/page/translator_history/translator_history_logic.dart';
import 'package:trans_lark/page/translator_history/translator_history_state.dart';
import 'package:trans_lark/util/obj_util.dart'; import 'package:trans_lark/util/obj_util.dart';
import 'package:trans_lark/widget/base_appbar.dart'; import 'package:trans_lark/widget/base_appbar.dart';
import 'package:trans_lark/widget/base_scrollbar.dart'; import 'package:trans_lark/widget/base_scrollbar.dart';
import 'translator_history_logic.dart';
import 'translator_history_state.dart';
/// @description:
/// @author
/// @date: 2024-06-28 16:26:22
class TranslatorHistoryPage extends StatefulWidget { class TranslatorHistoryPage extends StatefulWidget {
static String routName = "/translateHistory"; static String routName = "/translateHistory";

View File

@ -1,21 +1,17 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:trans_lark/global/flutter_tts_manager.dart';
import 'package:trans_lark/global/translate_manager.dart';
import 'package:trans_lark/page/translator_result/translator_result_state.dart';
import 'package:trans_lark/util/log_print.dart';
import 'package:translator/translator.dart'; import 'package:translator/translator.dart';
import 'package:trans_lark/entity/history_model.dart'; import 'package:trans_lark/entity/history_model.dart';
import 'package:trans_lark/global/translate_language.dart';
import 'package:trans_lark/global/tts_manager.dart';
import 'package:trans_lark/page/translator/translator_logic.dart'; import 'package:trans_lark/page/translator/translator_logic.dart';
import 'package:trans_lark/storage/history_data.dart'; import 'package:trans_lark/storage/history_data.dart';
import 'package:trans_lark/util/obj_util.dart'; import 'package:trans_lark/util/obj_util.dart';
import 'package:trans_lark/widget/base_easyloading.dart'; import 'package:trans_lark/widget/base_easyloading.dart';
import 'package:trans_lark/widget/translate_text_full_screen_page.dart'; import 'package:trans_lark/widget/translate_text_full_screen_page.dart';
import 'translator_result_state.dart';
/// @description:
/// @author
/// @date: 2024-06-27 16:53:29
class TranslatorResultPageLogic extends GetxController { class TranslatorResultPageLogic extends GetxController {
final state = TranslatorResultPageState(); final state = TranslatorResultPageState();
@ -44,14 +40,14 @@ class TranslatorResultPageLogic extends GetxController {
try { try {
Translation translate = await state.translator.translate( Translation translate = await state.translator.translate(
state.sourceText.value, state.sourceText.value,
from: TranslateLanguage().fromLanguageEntity.value.languageCode, from: TranslateManager().fromLanguageEntity.value.languageCode,
to: TranslateLanguage().toLanguageEntity.value.languageCode, to: TranslateManager().toLanguageEntity.value.languageCode,
); );
state.targetText.value = translate.text; state.targetText.value = translate.text;
addHistory(); addHistory();
} catch (e) { } catch (e) {
BaseEasyLoading.toast('Translation failed'); BaseEasyLoading.toast('Translation failed');
debugPrint('Translation failed,${e.toString()}'); LogPrint.d('Translation failed,${e.toString()}');
} }
state.isTranslationCompleted.value = true; state.isTranslationCompleted.value = true;
} }
@ -62,13 +58,13 @@ class TranslatorResultPageLogic extends GetxController {
sourceText: state.sourceText.value, sourceText: state.sourceText.value,
targetText: state.targetText.value, targetText: state.targetText.value,
sourceLanguageName: sourceLanguageName:
TranslateLanguage().fromLanguageEntity.value.languageName, TranslateManager().fromLanguageEntity.value.languageName,
sourceLanguageCode: sourceLanguageCode:
TranslateLanguage().fromLanguageEntity.value.languageCode, TranslateManager().fromLanguageEntity.value.languageCode,
targetLanguageName: targetLanguageName:
TranslateLanguage().toLanguageEntity.value.languageName, TranslateManager().toLanguageEntity.value.languageName,
targetLanguageCode: targetLanguageCode:
TranslateLanguage().toLanguageEntity.value.languageCode, TranslateManager().toLanguageEntity.value.languageCode,
); );
HistoryData().addData(entity); HistoryData().addData(entity);
if (Get.isRegistered<TranslatorLogic>()) { if (Get.isRegistered<TranslatorLogic>()) {
@ -79,16 +75,19 @@ class TranslatorResultPageLogic extends GetxController {
void translatorTtsPlay(String text, type) { void translatorTtsPlay(String text, type) {
if (ObjUtil.isNotEmpty(text)) { if (ObjUtil.isNotEmpty(text)) {
String language = TranslateLanguage().fromLanguageEntity.value.languageCode; String language =
TranslateManager().fromLanguageEntity.value.languageCode;
switch (type) { switch (type) {
case "from": case "from":
language = state.fromLanguage ?? TranslateLanguage().fromLanguageEntity.value.languageCode; language = state.fromLanguage ??
TranslateManager().fromLanguageEntity.value.languageCode;
break; break;
case "to": case "to":
language = state.toLanguage ?? TranslateLanguage().toLanguageEntity.value.languageCode; language = state.toLanguage ??
TranslateManager().toLanguageEntity.value.languageCode;
break; break;
} }
TtsManager().translatorTtsPlay(text, language); FlutterTtsManager().translatorTtsPlay(text, language);
} }
} }

View File

@ -1,10 +1,6 @@
import 'package:get/get_rx/src/rx_types/rx_types.dart'; import 'package:get/get_rx/src/rx_types/rx_types.dart';
import 'package:translator/translator.dart'; import 'package:translator/translator.dart';
import 'package:trans_lark/entity/history_model.dart';
/// @description:
/// @author
/// @date: 2024-06-27 16:53:29
class TranslatorResultPageState { class TranslatorResultPageState {
var translator = GoogleTranslator(); var translator = GoogleTranslator();
RxString sourceText = "".obs; RxString sourceText = "".obs;

View File

@ -2,16 +2,13 @@ import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart'; import 'package:flutter_svg/svg.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:trans_lark/generated/assets.dart'; import 'package:trans_lark/generated/assets.dart';
import 'package:trans_lark/global/translate_language.dart'; import 'package:trans_lark/global/translate_manager.dart';
import 'package:trans_lark/page/translator_result/translator_result_logic.dart'; import 'package:trans_lark/page/translator_result/translator_result_logic.dart';
import 'package:trans_lark/page/translator_result/translator_result_state.dart'; import 'package:trans_lark/page/translator_result/translator_result_state.dart';
import 'package:trans_lark/util/obj_util.dart'; import 'package:trans_lark/util/obj_util.dart';
import 'package:trans_lark/widget/base_appbar.dart'; import 'package:trans_lark/widget/base_appbar.dart';
import 'package:trans_lark/widget/language_result_bar.dart'; import 'package:trans_lark/widget/language_result_bar.dart';
/// @description:
/// @author
/// @date: 2024-06-27 16:53:29
class TranslatorResultPage extends StatefulWidget { class TranslatorResultPage extends StatefulWidget {
const TranslatorResultPage({super.key}); const TranslatorResultPage({super.key});
@ -22,7 +19,8 @@ class TranslatorResultPage extends StatefulWidget {
class _TranslatorResultPageState extends State<TranslatorResultPage> { class _TranslatorResultPageState extends State<TranslatorResultPage> {
final TranslatorResultPageLogic logic = Get.put(TranslatorResultPageLogic()); final TranslatorResultPageLogic logic = Get.put(TranslatorResultPageLogic());
final TranslatorResultPageState state = Get.find<TranslatorResultPageLogic>().state; final TranslatorResultPageState state =
Get.find<TranslatorResultPageLogic>().state;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -43,10 +41,10 @@ class _TranslatorResultPageState extends State<TranslatorResultPage> {
titleWidget: LanguageResultBar( titleWidget: LanguageResultBar(
fromLanguage: state.isHistory fromLanguage: state.isHistory
? (state.fromLanguage != null ? state.fromLanguage! : '') ? (state.fromLanguage != null ? state.fromLanguage! : '')
: TranslateLanguage().fromLanguageEntity.value.languageName, : TranslateManager().fromLanguageEntity.value.languageName,
toLanguage: state.isHistory toLanguage: state.isHistory
? (state.toLanguage != null ? state.toLanguage! : '') ? (state.toLanguage != null ? state.toLanguage! : '')
: TranslateLanguage().toLanguageEntity.value.languageName, : TranslateManager().toLanguageEntity.value.languageName,
), ),
), ),
Expanded( Expanded(
@ -92,7 +90,8 @@ class _TranslatorResultPageState extends State<TranslatorResultPage> {
height: 30, height: 30,
), ),
GestureDetector( GestureDetector(
onTap: () => logic.translatorTtsPlay(state.sourceText.value, "from"), onTap: () => logic.translatorTtsPlay(
state.sourceText.value, "from"),
child: ClipOval( child: ClipOval(
child: Container( child: Container(
width: 32, width: 32,
@ -131,7 +130,10 @@ class _TranslatorResultPageState extends State<TranslatorResultPage> {
children: [ children: [
Flexible( Flexible(
child: Text( child: Text(
TranslateLanguage().toLanguageEntity.value.languageName, TranslateManager()
.toLanguageEntity
.value
.languageName,
style: const TextStyle( style: const TextStyle(
color: Color(0xff949494), color: Color(0xff949494),
fontSize: 16, fontSize: 16,
@ -170,11 +172,13 @@ class _TranslatorResultPageState extends State<TranslatorResultPage> {
), ),
Obx(() { Obx(() {
return Visibility( return Visibility(
visible: ObjUtil.isNotEmptyStr(state.targetText.value), visible:
ObjUtil.isNotEmptyStr(state.targetText.value),
child: Row( child: Row(
children: [ children: [
GestureDetector( GestureDetector(
onTap: () => logic.translatorTtsPlay(state.targetText.value, "to"), onTap: () => logic.translatorTtsPlay(
state.targetText.value, "to"),
child: ClipOval( child: ClipOval(
child: Container( child: Container(
width: 32, width: 32,

View File

@ -1,6 +1,5 @@
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:trans_lark/page/web_page/web_page_controller.dart';
import 'web_page_controller.dart';
class WebPageBinding extends Bindings { class WebPageBinding extends Bindings {
@override @override

View File

@ -26,8 +26,7 @@ class WebPageController extends GetxController {
onPageFinished: (String url) { onPageFinished: (String url) {
viewState.value = ViewState.normal; viewState.value = ViewState.normal;
}, },
onWebResourceError: (WebResourceError error) { onWebResourceError: (WebResourceError error) {},
},
onNavigationRequest: (NavigationRequest request) { onNavigationRequest: (NavigationRequest request) {
return NavigationDecision.navigate; return NavigationDecision.navigate;
}, },

2
lib/core/router/router.dart → lib/router/router.dart Executable file → Normal file
View File

@ -6,8 +6,6 @@ import 'package:trans_lark/page/scene_list/scene_list_binding.dart';
import 'package:trans_lark/page/scene_list/scene_list_view.dart'; import 'package:trans_lark/page/scene_list/scene_list_view.dart';
import 'package:trans_lark/page/scene_type/scene_type_binding.dart'; import 'package:trans_lark/page/scene_type/scene_type_binding.dart';
import 'package:trans_lark/page/scene_type/scene_type_view.dart'; import 'package:trans_lark/page/scene_type/scene_type_view.dart';
import 'package:trans_lark/page/splash/splash_binding.dart';
import 'package:trans_lark/page/splash/splash_view.dart';
import 'package:trans_lark/page/translator/translator_view.dart'; import 'package:trans_lark/page/translator/translator_view.dart';
import 'package:trans_lark/page/translator_history/translator_history_view.dart'; import 'package:trans_lark/page/translator_history/translator_history_view.dart';
import 'package:trans_lark/page/translator_result/translator_result_view.dart'; import 'package:trans_lark/page/translator_result/translator_result_view.dart';

View File

@ -1,7 +1,3 @@
// Author: fengshengxiong
// Date: 2024/5/8
// Description:
import 'package:collection/collection.dart'; import 'package:collection/collection.dart';
import 'package:trans_lark/entity/history_model.dart'; import 'package:trans_lark/entity/history_model.dart';
import 'package:trans_lark/storage/hive_storage.dart'; import 'package:trans_lark/storage/hive_storage.dart';

View File

@ -1,7 +1,3 @@
// Author: fengshengxiong
// Date: 2024/5/8
// Description:
import 'package:hive_flutter/hive_flutter.dart'; import 'package:hive_flutter/hive_flutter.dart';
import 'package:trans_lark/entity/history_model.dart'; import 'package:trans_lark/entity/history_model.dart';

View File

@ -1,11 +1,3 @@
// Author: fengshengxiong
// Date: 2024/5/11
// Description:
/// 'yyyy/MM/dd HH:mm:ss''yyyy/M/d HH:mm:ss'
///
/// year -> yyyy/yy month -> MM/M day -> dd/d
/// hour -> HH/H minute -> mm/m second -> ss/s
class DateFormats { class DateFormats {
static String full = 'yyyy-MM-dd HH:mm:ss'; static String full = 'yyyy-MM-dd HH:mm:ss';
static String yMoDHM = 'yyyy-MM-dd HH:mm'; static String yMoDHM = 'yyyy-MM-dd HH:mm';

View File

@ -1,7 +1,3 @@
// Author: fengshengxiong
// Date: 2024/5/11
// Description:
import 'package:device_info_plus/device_info_plus.dart'; import 'package:device_info_plus/device_info_plus.dart';
class DeviceInfoUtil { class DeviceInfoUtil {

46
lib/util/log_print.dart Normal file
View File

@ -0,0 +1,46 @@
import 'package:logger/logger.dart';
final _logger = Logger(
printer: PrettyPrinter(
//
methodCount: 0,
// stacktrace
errorMethodCount: 8,
//
lineLength: 120,
//
colors: true,
//
printEmojis: true,
//
printTime: false,
),
);
class LogPrint {
static const String _tag = 'LogPrint';
LogPrint.t(dynamic msg, {String tag = _tag}) {
_logger.t('[$tag]: $msg');
}
LogPrint.d(dynamic msg, {String tag = _tag}) {
_logger.d('[$tag]: $msg');
}
LogPrint.i(dynamic msg, {String tag = _tag}) {
_logger.i('[$tag]: $msg');
}
LogPrint.w(dynamic msg, {String tag = _tag}) {
_logger.w('[$tag]: $msg');
}
LogPrint.e(dynamic msg, {String tag = _tag}) {
_logger.e('[$tag]: $msg');
}
LogPrint.f(dynamic msg, {String tag = _tag}) {
_logger.f('[$tag]: $msg');
}
}

View File

@ -1,7 +1,3 @@
// Author: fengshengxiong
// Date: 2024/5/7
// Description:
import 'dart:math'; import 'dart:math';
class NumUtil { class NumUtil {
@ -20,4 +16,4 @@ class NumUtil {
} while (newNumber == current); } while (newNumber == current);
return newNumber; return newNumber;
} }
} }

View File

@ -1,7 +1,3 @@
// Author: fengshengxiong
// Date: 2024/5/7
// Description:
class ObjUtil { class ObjUtil {
static bool isNotEmptyStr(String? str) { static bool isNotEmptyStr(String? str) {
return str != null && str.trim().isNotEmpty; return str != null && str.trim().isNotEmpty;
@ -48,4 +44,4 @@ class ObjUtil {
} }
return true; return true;
} }
} }

View File

@ -1,7 +1,3 @@
// Author: fengshengxiong
// Date: 2024/5/10
// Description:
import 'dart:io'; import 'dart:io';
import 'package:get/get.dart'; import 'package:get/get.dart';
@ -11,7 +7,8 @@ import 'package:trans_lark/widget/remind_dialog.dart';
class PermissionUtil { class PermissionUtil {
/// ///
/// [permissionList] /// [permissionList]
static Future<bool> checkPermission(List<Permission> permissionList, {bool showDialog = true}) async { static Future<bool> checkPermission(List<Permission> permissionList,
{bool showDialog = true}) async {
// //
List<Permission> newPermissionList = []; List<Permission> newPermissionList = [];
// //
@ -25,7 +22,8 @@ class PermissionUtil {
// //
if (newPermissionList.isNotEmpty) { if (newPermissionList.isNotEmpty) {
PermissionStatus permissionStatus = await _requestPermission(newPermissionList); PermissionStatus permissionStatus =
await _requestPermission(newPermissionList);
switch (permissionStatus) { switch (permissionStatus) {
// //
case PermissionStatus.denied: case PermissionStatus.denied:
@ -39,7 +37,8 @@ class PermissionUtil {
case PermissionStatus.provisional: case PermissionStatus.provisional:
case PermissionStatus.restricted: case PermissionStatus.restricted:
case PermissionStatus.permanentlyDenied: case PermissionStatus.permanentlyDenied:
if (showDialog) _showFailedDialog(newPermissionList, isPermanentlyDenied: true); if (showDialog)
_showFailedDialog(newPermissionList, isPermanentlyDenied: true);
break; break;
} }
} else { } else {
@ -49,7 +48,8 @@ class PermissionUtil {
} }
/// false /// false
static Future<PermissionStatus> _requestPermission(List<Permission> permissionList) async { static Future<PermissionStatus> _requestPermission(
List<Permission> permissionList) async {
Map<Permission, PermissionStatus> statuses = await permissionList.request(); Map<Permission, PermissionStatus> statuses = await permissionList.request();
PermissionStatus currentPermissionStatus = PermissionStatus.granted; PermissionStatus currentPermissionStatus = PermissionStatus.granted;
statuses.forEach((key, value) { statuses.forEach((key, value) {
@ -81,7 +81,8 @@ class PermissionUtil {
return true; return true;
} else { } else {
// //
_showFailedDialog([Permission.locationWhenInUse, Permission.locationAlways], _showFailedDialog(
[Permission.locationWhenInUse, Permission.locationAlways],
isPermanentlyDenied: Platform.isIOS ? true : false, isPermanentlyDenied: Platform.isIOS ? true : false,
); );
} }
@ -102,7 +103,8 @@ class PermissionUtil {
} }
/// ///
static _showFailedDialog(List<Permission> permissionList, {bool isPermanentlyDenied = false}) async { static _showFailedDialog(List<Permission> permissionList,
{bool isPermanentlyDenied = false}) async {
Get.dialog( Get.dialog(
barrierDismissible: false, barrierDismissible: false,
RemindDialog( RemindDialog(
@ -131,15 +133,20 @@ class PermissionUtil {
String description = ''; String description = '';
if (failedPermission == Permission.camera) { if (failedPermission == Permission.camera) {
description = 'This will enable you to take photos and recognize text within them for translation.'; description =
'This will enable you to take photos and recognize text within them for translation.';
} else if (failedPermission == Permission.photos) { } else if (failedPermission == Permission.photos) {
description = 'This will enable you to select photos from your library for text recognition and translation.'; description =
'This will enable you to select photos from your library for text recognition and translation.';
} else if (failedPermission == Permission.microphone) { } else if (failedPermission == Permission.microphone) {
description = 'This will enable you to input content through voice for recognition and translation.'; description =
'This will enable you to input content through voice for recognition and translation.';
} else if (failedPermission == Permission.speech) { } else if (failedPermission == Permission.speech) {
description = 'This will enable you to use speech recognition to convert voice content to text for translation.'; description =
'This will enable you to use speech recognition to convert voice content to text for translation.';
} else if (failedPermission == Permission.appTrackingTransparency) { } else if (failedPermission == Permission.appTrackingTransparency) {
description = 'This will help us provide a more personalized advertising experience. Your data privacy will be protected.'; description =
'This will help us provide a more personalized advertising experience. Your data privacy will be protected.';
} }
return description; return description;
} }

View File

@ -1,7 +1,3 @@
// Author: fengshengxiong
// Date: 2024/5/7
// Description: BaseAppBar
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:trans_lark/generated/assets.dart'; import 'package:trans_lark/generated/assets.dart';
@ -69,15 +65,16 @@ class BaseAppBar extends StatelessWidget implements PreferredSizeWidget {
), ),
), ),
Expanded( Expanded(
child: titleWidget ?? Text( child: titleWidget ??
title ?? '', Text(
overflow: TextOverflow.ellipsis, title ?? '',
style: const TextStyle( overflow: TextOverflow.ellipsis,
color: Colors.black, style: const TextStyle(
fontSize: 16, color: Colors.black,
fontWeight: FontWeight.w500, fontSize: 16,
), fontWeight: FontWeight.w500,
), ),
),
), ),
SizedBox( SizedBox(
width: 60, width: 60,

View File

@ -1,7 +1,3 @@
// Author: fengshengxiong
// Date: 2024/5/7
// Description:
import 'package:flutter_easyloading/flutter_easyloading.dart'; import 'package:flutter_easyloading/flutter_easyloading.dart';
class BaseEasyLoading { class BaseEasyLoading {

View File

@ -1,7 +1,3 @@
// Author: fengshengxiong
// Date: 2024/6/17
// Description:
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class BaseScrollbar extends StatelessWidget { class BaseScrollbar extends StatelessWidget {

View File

@ -1,7 +1,3 @@
// Author: fengshengxiong
// Date: 2024/5/9
// Description: 线
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class DividerWidget extends StatelessWidget { class DividerWidget extends StatelessWidget {

View File

@ -1,7 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:trans_lark/generated/assets.dart'; import 'package:trans_lark/generated/assets.dart';
import 'package:trans_lark/global/translate_language.dart'; import 'package:trans_lark/global/translate_manager.dart';
import 'package:trans_lark/widget/language_bottom_sheet.dart'; import 'package:trans_lark/widget/language_bottom_sheet.dart';
class LanguageBar extends StatelessWidget { class LanguageBar extends StatelessWidget {
@ -34,9 +34,17 @@ class LanguageBar extends StatelessWidget {
const SizedBox(width: 8), const SizedBox(width: 8),
Flexible( Flexible(
child: Text( child: Text(
TranslateLanguage().fromLanguageEntity.value.languageName, TranslateManager()
.fromLanguageEntity
.value
.languageName,
style: TextStyle( style: TextStyle(
color: !isSelect || !TranslateLanguage().isSelectFromLanguage.value ? const Color(0xff435561) : const Color(0xff4ECA8C), color: !isSelect ||
!TranslateManager()
.isSelectFromLanguage
.value
? const Color(0xff435561)
: const Color(0xff4ECA8C),
fontSize: 14, fontSize: 14,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
@ -91,9 +99,17 @@ class LanguageBar extends StatelessWidget {
const SizedBox(width: 8), const SizedBox(width: 8),
Flexible( Flexible(
child: Text( child: Text(
TranslateLanguage().toLanguageEntity.value.languageName, TranslateManager()
.toLanguageEntity
.value
.languageName,
style: TextStyle( style: TextStyle(
color: !isSelect || TranslateLanguage().isSelectFromLanguage.value ? const Color(0xff435561) : const Color(0xff4ECA8C), color: !isSelect ||
TranslateManager()
.isSelectFromLanguage
.value
? const Color(0xff435561)
: const Color(0xff4ECA8C),
fontSize: 14, fontSize: 14,
fontWeight: FontWeight.w500, fontWeight: FontWeight.w500,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
@ -118,21 +134,25 @@ class LanguageBar extends StatelessWidget {
} }
void _exchangeOnTap() { void _exchangeOnTap() {
var tempLanguageCode = TranslateLanguage().toLanguageEntity.value.languageCode; var tempLanguageCode =
var tempLanguageName = TranslateLanguage().toLanguageEntity.value.languageName; TranslateManager().toLanguageEntity.value.languageCode;
var tempLanguageName =
TranslateManager().toLanguageEntity.value.languageName;
TranslateLanguage().toLanguageEntity.update((fn) { TranslateManager().toLanguageEntity.update((fn) {
fn?.languageCode = TranslateLanguage().fromLanguageEntity.value.languageCode; fn?.languageCode =
fn?.languageName = TranslateLanguage().fromLanguageEntity.value.languageName; TranslateManager().fromLanguageEntity.value.languageCode;
fn?.languageName =
TranslateManager().fromLanguageEntity.value.languageName;
}); });
TranslateLanguage().fromLanguageEntity.update((fn) { TranslateManager().fromLanguageEntity.update((fn) {
fn?.languageCode = tempLanguageCode; fn?.languageCode = tempLanguageCode;
fn?.languageName = tempLanguageName; fn?.languageName = tempLanguageName;
}); });
} }
void _onTapFrom() { void _onTapFrom() {
TranslateLanguage().isSelectFromLanguage.value = true; TranslateManager().isSelectFromLanguage.value = true;
Get.bottomSheet( Get.bottomSheet(
isScrollControlled: true, isScrollControlled: true,
const LanguageBottomSheet(), const LanguageBottomSheet(),
@ -140,7 +160,7 @@ class LanguageBar extends StatelessWidget {
} }
void _onTapTo() { void _onTapTo() {
TranslateLanguage().isSelectFromLanguage.value = false; TranslateManager().isSelectFromLanguage.value = false;
Get.bottomSheet( Get.bottomSheet(
isScrollControlled: true, isScrollControlled: true,
const LanguageBottomSheet(), const LanguageBottomSheet(),

View File

@ -3,7 +3,7 @@ import 'package:get/get.dart';
import 'package:get/get_state_manager/get_state_manager.dart'; import 'package:get/get_state_manager/get_state_manager.dart';
import 'package:trans_lark/entity/language_entity.dart'; import 'package:trans_lark/entity/language_entity.dart';
import 'package:trans_lark/generated/assets.dart'; import 'package:trans_lark/generated/assets.dart';
import 'package:trans_lark/global/translate_language.dart'; import 'package:trans_lark/global/translate_manager.dart';
import 'package:trans_lark/page/home/home_logic.dart'; import 'package:trans_lark/page/home/home_logic.dart';
import 'package:trans_lark/widget/base_scrollbar.dart'; import 'package:trans_lark/widget/base_scrollbar.dart';
import 'package:trans_lark/widget/language_bar.dart'; import 'package:trans_lark/widget/language_bar.dart';
@ -19,7 +19,8 @@ class LanguageBottomSheet extends StatelessWidget {
decoration: const BoxDecoration( decoration: const BoxDecoration(
color: Colors.white, color: Colors.white,
borderRadius: BorderRadius.only( borderRadius: BorderRadius.only(
topLeft: Radius.circular(26), topRight: Radius.circular(26), topLeft: Radius.circular(26),
topRight: Radius.circular(26),
), ),
), ),
child: Column( child: Column(
@ -50,15 +51,16 @@ class LanguageBottomSheet extends StatelessWidget {
return Expanded( return Expanded(
child: BaseScrollbar( child: BaseScrollbar(
child: ListView.builder( child: ListView.builder(
itemCount: TranslateLanguage().languageList.length, itemCount: TranslateManager().languageList.length,
itemBuilder: (context, index) { itemBuilder: (context, index) {
var item = TranslateLanguage().languageList[index]; var item = TranslateManager().languageList[index];
return Material( return Material(
color: Colors.transparent, color: Colors.transparent,
child: InkWell( child: InkWell(
onTap: () => _itemOnTap(item), onTap: () => _itemOnTap(item),
child: Container( child: Container(
padding: const EdgeInsets.symmetric(vertical: 13, horizontal: 33), padding:
const EdgeInsets.symmetric(vertical: 13, horizontal: 33),
child: Row( child: Row(
children: [ children: [
Expanded( Expanded(
@ -66,9 +68,22 @@ class LanguageBottomSheet extends StatelessWidget {
return Text( return Text(
item.languageName, item.languageName,
style: TextStyle( style: TextStyle(
color: TranslateLanguage().isSelectFromLanguage.value color:
? (item.languageName == TranslateLanguage().fromLanguageEntity.value.languageName ? const Color(0xff4ECA8C) : const Color(0xff152A3D)) TranslateManager().isSelectFromLanguage.value
: (item.languageName == TranslateLanguage().toLanguageEntity.value.languageName ? const Color(0xff4ECA8C) : const Color(0xff152A3D)), ? (item.languageName ==
TranslateManager()
.fromLanguageEntity
.value
.languageName
? const Color(0xff4ECA8C)
: const Color(0xff152A3D))
: (item.languageName ==
TranslateManager()
.toLanguageEntity
.value
.languageName
? const Color(0xff4ECA8C)
: const Color(0xff152A3D)),
fontSize: 16, fontSize: 16,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
), ),
@ -77,9 +92,17 @@ class LanguageBottomSheet extends StatelessWidget {
), ),
Obx(() { Obx(() {
return Visibility( return Visibility(
visible: TranslateLanguage().isSelectFromLanguage.value visible: TranslateManager().isSelectFromLanguage.value
? (item.languageName == TranslateLanguage().fromLanguageEntity.value.languageName) ? (item.languageName ==
: (item.languageName == TranslateLanguage().toLanguageEntity.value.languageName), TranslateManager()
.fromLanguageEntity
.value
.languageName)
: (item.languageName ==
TranslateManager()
.toLanguageEntity
.value
.languageName),
child: Padding( child: Padding(
padding: const EdgeInsets.only(left: 10), padding: const EdgeInsets.only(left: 10),
child: Image.asset( child: Image.asset(
@ -102,27 +125,27 @@ class LanguageBottomSheet extends StatelessWidget {
} }
void _itemOnTap(LanguageEntity item) { void _itemOnTap(LanguageEntity item) {
if (TranslateLanguage().isSelectFromLanguage.value) { if (TranslateManager().isSelectFromLanguage.value) {
TranslateLanguage().fromLanguageEntity.update((fn) { TranslateManager().fromLanguageEntity.update((fn) {
fn?.languageCode = item.languageCode; fn?.languageCode = item.languageCode;
fn?.languageName = item.languageName; fn?.languageName = item.languageName;
}); });
} else { } else {
TranslateLanguage().toLanguageEntity.update((fn) { TranslateManager().toLanguageEntity.update((fn) {
fn?.languageCode = item.languageCode; fn?.languageCode = item.languageCode;
fn?.languageName = item.languageName; fn?.languageName = item.languageName;
}); });
} }
if(Get.isRegistered<HomeLogic>()) { if (Get.isRegistered<HomeLogic>()) {
HomeLogic.to.getDailyQuote(); HomeLogic.to.getDailyQuote();
} }
} }
void _onTapFrom() { void _onTapFrom() {
TranslateLanguage().isSelectFromLanguage.value = true; TranslateManager().isSelectFromLanguage.value = true;
} }
void _onTapTo() { void _onTapTo() {
TranslateLanguage().isSelectFromLanguage.value = false; TranslateManager().isSelectFromLanguage.value = false;
} }
} }

View File

@ -1,7 +1,3 @@
// Author: fengshengxiong
// Date: 2024/5/11
// Description:
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';

View File

@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:trans_lark/generated/assets.dart'; import 'package:trans_lark/generated/assets.dart';
import 'package:trans_lark/global/translate_language.dart'; import 'package:trans_lark/global/translate_manager.dart';
class SpeakDialog extends StatelessWidget { class SpeakDialog extends StatelessWidget {
const SpeakDialog({ const SpeakDialog({
@ -44,7 +44,8 @@ class SpeakDialog extends StatelessWidget {
clipBehavior: Clip.antiAlias, clipBehavior: Clip.antiAlias,
decoration: const BoxDecoration( decoration: const BoxDecoration(
color: Colors.white, color: Colors.white,
borderRadius: BorderRadius.only(topLeft: Radius.circular(20), topRight: Radius.circular(20)), borderRadius: BorderRadius.only(
topLeft: Radius.circular(20), topRight: Radius.circular(20)),
), ),
child: Column( child: Column(
children: [ children: [
@ -73,7 +74,10 @@ class SpeakDialog extends StatelessWidget {
), ),
Flexible( Flexible(
child: Text( child: Text(
TranslateLanguage().fromLanguageEntity.value.languageName, TranslateManager()
.fromLanguageEntity
.value
.languageName,
maxLines: 2, maxLines: 2,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
style: const TextStyle( style: const TextStyle(
@ -89,7 +93,9 @@ class SpeakDialog extends StatelessWidget {
}), }),
Obx(() { Obx(() {
return Text( return Text(
isListening.value ? 'I am listening, Click the button to end and translate' : 'Click the button to start speaking', isListening.value
? 'I am listening, Click the button to end and translate'
: 'Click the button to start speaking',
maxLines: 2, maxLines: 2,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
textAlign: TextAlign.center, textAlign: TextAlign.center,

View File

@ -3,8 +3,8 @@ import 'package:flutter/services.dart';
import 'package:flutter_svg/svg.dart'; import 'package:flutter_svg/svg.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:trans_lark/generated/assets.dart'; import 'package:trans_lark/generated/assets.dart';
import 'package:trans_lark/global/translate_language.dart'; import 'package:trans_lark/global/flutter_tts_manager.dart';
import 'package:trans_lark/global/tts_manager.dart'; import 'package:trans_lark/global/translate_manager.dart';
class TranslateTextFullScreenPage extends StatefulWidget { class TranslateTextFullScreenPage extends StatefulWidget {
const TranslateTextFullScreenPage({super.key}); const TranslateTextFullScreenPage({super.key});
@ -65,7 +65,10 @@ class _TranslateTextFullScreenPageState
), ),
GestureDetector( GestureDetector(
onTap: () { onTap: () {
TtsManager().translatorTtsPlay(showData, TranslateLanguage().toLanguageEntity.value.languageCode); FlutterTtsManager().translatorTtsPlay(
showData,
TranslateManager().toLanguageEntity.value.languageCode,
);
}, },
child: Padding( child: Padding(
padding: const EdgeInsets.only(top: 20), padding: const EdgeInsets.only(top: 20),

View File

@ -1,7 +1,3 @@
// Author: fengshengxiong
// Date: 2024/5/7
// Description:
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
/// ///

View File

@ -1,39 +1,16 @@
name: trans_lark name: trans_lark
description: "A new Flutter project." description: "A new Flutter project."
# The following line prevents the package from being accidentally published to publish_to: 'none'
# pub.dev using `flutter pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# The following defines the version and build number for your application.
# A version number is three numbers separated by dots, like 1.2.43
# followed by an optional build number separated by a +.
# Both the version and the builder number may be overridden in flutter
# build by specifying --build-name and --build-number, respectively.
# In Android, build-name is used as versionName while build-number used as versionCode.
# Read more about Android versioning at https://developer.android.com/studio/publish/versioning
# In iOS, build-name is used as CFBundleShortVersionString while build-number is used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix.
version: 1.0.0+1 version: 1.0.0+1
environment: environment:
sdk: '>=3.3.1 <4.0.0' sdk: '>=3.3.1 <4.0.0'
# Dependencies specify other packages that your package needs in order to work.
# To automatically upgrade your package dependencies to the latest versions
# consider running `flutter pub upgrade --major-versions`. Alternatively,
# dependencies can be manually updated by changing the version numbers below to
# the latest version available on pub.dev. To see which dependencies have newer
# versions available, run `flutter pub outdated`.
dependencies: dependencies:
flutter: flutter:
sdk: flutter sdk: flutter
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.6 cupertino_icons: ^1.0.6
get: ^4.6.6 get: ^4.6.6
flutter_tts: ^4.0.2 flutter_tts: ^4.0.2
@ -85,6 +62,9 @@ dependencies:
# 获取当前设备信息 # 获取当前设备信息
device_info_plus: ^10.1.0 device_info_plus: ^10.1.0
# 日志打印
logger: ^2.3.0
flutter_launcher_icons: flutter_launcher_icons:
android: "launcher_icon" android: "launcher_icon"
ios: true ios: true
@ -94,57 +74,16 @@ flutter_launcher_icons:
dev_dependencies: dev_dependencies:
flutter_test: flutter_test:
sdk: flutter sdk: flutter
# The "flutter_lints" package below contains a set of recommended lints to
# encourage good coding practices. The lint set provided by the package is
# activated in the `analysis_options.yaml` file located at the root of your
# package. See that file for information about deactivating specific lint
# rules and activating additional ones.
flutter_lints: ^3.0.0 flutter_lints: ^3.0.0
hive_generator: ^2.0.1 hive_generator: ^2.0.1
build_runner: ^2.4.11 build_runner: ^2.4.11
flutter_launcher_icons: ^0.13.1 flutter_launcher_icons: ^0.13.1
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
# The following section is specific to Flutter packages.
flutter: flutter:
# The following line ensures that the Material Icons font is
# included with your application, so that you can use the icons in
# the material Icons class.
uses-material-design: true uses-material-design: true
# To add assets to your application, add an assets section, like this:
assets: assets:
- assets/launcher_icon/ - assets/launcher_icon/
- assets/images/ - assets/images/
- assets/svg/ - assets/svg/
- assets/json/ - assets/json/
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware
# For details regarding adding assets from package dependencies, see
# https://flutter.dev/assets-and-images/#from-packages
# To add custom fonts to your application, add a fonts section here,
# in this "flutter" section. Each entry in this list should have a
# "family" key with the font family name, and a "fonts" key with a
# list giving the asset and other descriptors for the font. For
# example:
# fonts:
# - family: Schyler
# fonts:
# - asset: fonts/Schyler-Regular.ttf
# - asset: fonts/Schyler-Italic.ttf
# style: italic
# - family: Trajan Pro
# fonts:
# - asset: fonts/TrajanPro.ttf
# - asset: fonts/TrajanPro_Bold.ttf
# weight: 700
#
# For details regarding fonts from package dependencies,
# see https://flutter.dev/custom-fonts/#from-packages