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 'package:hive/hive.dart';

View File

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

View File

@ -1,4 +1,3 @@
// ignore_for_file: public_member_api_docs, sort_constructors_first
import 'dart:convert';
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:io';
import 'package:app_tracking_transparency/app_tracking_transparency.dart';
import 'package:flutter/material.dart';
import 'package:trans_lark/util/log_print.dart';
class AppTrackingAuthorizationManager {
AppTrackingAuthorizationManager._();
@ -26,7 +23,7 @@ class AppTrackingAuthorizationManager {
if (status == TrackingStatus.notDetermined) {
if (_timer != null && _timer!.isActive) {
final TrackingStatus status = await AppTrackingTransparency.requestTrackingAuthorization();
debugPrint('跟踪授权状态: $status');
LogPrint.d('跟踪授权状态: $status');
} else {
_startTimer();
}

View File

@ -1,20 +1,20 @@
import 'package:flutter/foundation.dart';
import 'package:flutter_tts/flutter_tts.dart';
import 'package:trans_lark/util/log_print.dart';
import 'package:trans_lark/widget/base_easyloading.dart';
class TtsManager {
TtsManager._();
class FlutterTtsManager {
FlutterTtsManager._();
static final TtsManager _instance = TtsManager._();
static final FlutterTtsManager _instance = FlutterTtsManager._();
factory TtsManager() {
factory FlutterTtsManager() {
return _instance;
}
late FlutterTts ttsController;
Future<void> initTts() async {
debugPrint("TTS Service init start");
Future<void> init() async {
LogPrint.d("TTS Service init start");
ttsController = FlutterTts();
await ttsController.setSharedInstance(true);
await ttsController.setIosAudioCategory(
@ -27,7 +27,7 @@ class TtsManager {
IosTextToSpeechAudioMode.voicePrompt);
await ttsController.awaitSpeakCompletion(true);
await ttsController.awaitSynthCompletion(true);
debugPrint("TTS Service init success");
LogPrint.d("TTS Service init success");
}
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:speech_to_text/speech_recognition_error.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';
class SpeechToTextManager {
@ -32,12 +28,12 @@ class SpeechToTextManager {
_speechToText.statusListener ??= _statusListener;
_speechToText.errorListener ??= _errorListener;
} catch (e) {
debugPrint('Speech recognition failed: ${e.toString()}');
LogPrint.d('Speech recognition failed: ${e.toString()}');
}
}
void _statusListener(String status) {
debugPrint('状态:$status');
LogPrint.d('状态:$status');
if (status == 'listening') {
isListening.value = true;
} else {
@ -46,7 +42,7 @@ class SpeechToTextManager {
}
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}');
}
@ -67,9 +63,9 @@ class SpeechToTextManager {
BaseEasyLoading.dismiss();
} catch (e) {
if (e.runtimeType == ListenFailedException) {
debugPrint('speechToText.listen${(e as ListenFailedException).message}');
LogPrint.d('speechToText.listen${(e as ListenFailedException).message}');
} else {
debugPrint('speechToText.listen${e.toString()}');
LogPrint.d('speechToText.listen${e.toString()}');
}
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:ui';
@ -12,12 +8,12 @@ import 'package:trans_lark/entity/language_entity.dart';
import 'package:trans_lark/generated/assets.dart';
import 'package:trans_lark/util/num_util.dart';
class TranslateLanguage {
TranslateLanguage._();
class TranslateManager {
TranslateManager._();
static final TranslateLanguage _instance = TranslateLanguage._();
static final TranslateManager _instance = TranslateManager._();
factory TranslateLanguage() {
factory TranslateManager() {
return _instance;
}

View File

@ -5,10 +5,10 @@ import 'package:flutter/services.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_keyboard_visibility/flutter_keyboard_visibility.dart';
import 'package:get/get.dart';
import 'package:trans_lark/core/router/router.dart';
import 'package:trans_lark/global/app_config.dart';
import 'package:trans_lark/global/translate_language.dart';
import 'package:trans_lark/global/tts_manager.dart';
import 'package:trans_lark/global/flutter_tts_manager.dart';
import 'package:trans_lark/global/global_config.dart';
import 'package:trans_lark/global/translate_manager.dart';
import 'package:trans_lark/router/router.dart';
import 'package:trans_lark/storage/hive_storage.dart';
import 'package:trans_lark/widget/base_easyloading.dart';
@ -31,8 +31,8 @@ void main() async {
));
}
await TranslateLanguage().init();
await TtsManager().initTts();
await TranslateManager().init();
await FlutterTtsManager().init();
runApp(const MyApp());
}
@ -46,9 +46,11 @@ class MyApp extends StatelessWidget {
return KeyboardDismissOnTap(
child: GetMaterialApp(
debugShowCheckedModeBanner: false,
title: AppConfig.appName,
title: GlobalConfig.appName,
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,
),
initialRoute: GetRouter.home,

View File

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

View File

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

View File

@ -3,13 +3,12 @@ import 'package:flutter_svg/svg.dart';
import 'package:get/get.dart';
import 'package:trans_lark/generated/assets.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/widget/base_appbar.dart';
import 'package:wave/config.dart';
import 'package:wave/wave.dart';
import 'face_to_face_controller.dart';
class FaceToFaceView extends StatelessWidget {
FaceToFaceView({super.key});

View File

@ -1,23 +1,23 @@
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/flutter_tts_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/global/translate_manager.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/log_print.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';
@ -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/speak_dialog.dart';
/// @description:
/// @author
/// @date: 2024-06-26 14:23:43
class HomeLogic extends GetxController {
static HomeLogic get to => Get.find<HomeLogic>();
var lastWords = '';
@ -51,9 +48,8 @@ class HomeLogic extends GetxController {
Future<void> getDailyQuote() async {
LanguageEntity fromLanguageEntity =
TranslateLanguage().fromLanguageEntity.value;
LanguageEntity toLanguageEntity =
TranslateLanguage().toLanguageEntity.value;
TranslateManager().fromLanguageEntity.value;
LanguageEntity toLanguageEntity = TranslateManager().toLanguageEntity.value;
var languageScene = <LanguageEntity>[
LanguageEntity(languageCode: 'ar', languageName: 'Arabic'),
LanguageEntity(languageCode: 'bn', languageName: 'Bengali'),
@ -128,7 +124,7 @@ class HomeLogic extends GetxController {
void translatorTtsPlay(bool isFrom) {
if (fromLanguage.value != null && toLanguage.value != null) {
TtsManager().translatorTtsPlay(
FlutterTtsManager().translatorTtsPlay(
isFrom ? fromStr.value! : toStr.value!,
isFrom
? fromLanguage.value!.languageCode
@ -245,7 +241,7 @@ class HomeLogic extends GetxController {
_openTranslatorResultPage();
} else {
SpeechToTextManager().startListening(
TranslateLanguage().fromLanguageEntity.value.languageCode,
TranslateManager().fromLanguageEntity.value.languageCode,
_onSpeechResult);
}
} else {
@ -261,7 +257,7 @@ class HomeLogic extends GetxController {
}
void _onSpeechResult(SpeechRecognitionResult result) {
debugPrint('识别结果:${result.recognizedWords}');
LogPrint.d('识别结果:${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/widget/language_bar.dart';
/// @description:
/// @author : lifu
/// @date: 2024-06-26 14:23:43
class HomePage extends StatelessWidget {
final HomeLogic logic = Get.put(HomeLogic());
@ -145,8 +142,12 @@ class HomePage extends StatelessWidget {
height: 76,
alignment: Alignment.center,
decoration: BoxDecoration(
color:
const Color.fromARGB(213, 69, 168, 254),
color: const Color.fromARGB(
213,
69,
168,
254,
),
borderRadius: BorderRadius.circular(16),
border: Border.all(
width: 1.5,
@ -169,8 +170,9 @@ class HomePage extends StatelessWidget {
),
),
Padding(
padding:
const EdgeInsets.only(right: 20),
padding: const EdgeInsets.only(
right: 20,
),
child: GestureDetector(
onTap: logic.onTapSpeak,
child: Container(
@ -183,10 +185,11 @@ class HomePage extends StatelessWidget {
BorderRadius.circular(18),
),
child: SvgPicture.asset(
Assets.svgHomeVoice),
Assets.svgHomeVoice,
),
),
),
),
)
],
),
),

View File

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

View File

@ -1,7 +1,7 @@
import 'package:get/get.dart';
import 'package:trans_lark/entity/language_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';
class SceneListController extends GetxController {
@ -57,7 +57,10 @@ class SceneListController extends GetxController {
int index = 0;
for (var i = 0; i < keys.length; ++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;
break;
}
@ -69,8 +72,9 @@ class SceneListController extends GetxController {
}
void translatorTtsPlay(bool isFrom, SceneList item) {
TtsManager().translatorTtsPlay(
getSentence(isFrom, item), isFrom ? fromLanguage.value.languageCode : toLanguage.value.languageCode
FlutterTtsManager().translatorTtsPlay(
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:trans_lark/entity/scene_entity.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_scrollbar.dart';
import 'package:trans_lark/widget/language_scene_bar.dart';
import 'scene_list_controller.dart';
class SceneListView extends StatelessWidget {
SceneListView({super.key});
@ -33,7 +32,8 @@ class SceneListView extends StatelessWidget {
Expanded(
child: BaseScrollbar(
child: ListView.separated(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
padding:
const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
itemCount: controller.sceneList.length,
itemBuilder: (context, index) {
var item = controller.sceneList[index];

View File

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

View File

@ -2,9 +2,9 @@ import 'dart:convert';
import 'package:flutter/services.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/generated/assets.dart';
import 'package:trans_lark/router/router.dart';
import 'package:trans_lark/widget/view_state_widget.dart';
class SceneTypeController extends GetxController {

View File

@ -3,13 +3,12 @@ import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart';
import 'package:trans_lark/entity/scene_entity.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/widget/base_appbar.dart';
import 'package:trans_lark/widget/base_scrollbar.dart';
import 'package:trans_lark/widget/view_state_widget.dart';
import 'scene_type_controller.dart';
class SceneTypeView extends StatelessWidget {
SceneTypeView({super.key});

View File

@ -1,6 +1,6 @@
import 'package:get/get.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 {
var versionName = ''.obs;

View File

@ -1,7 +1,7 @@
import 'package:flutter/material.dart';
import 'package:get/get.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 'settings_controller.dart';
@ -53,7 +53,7 @@ class SettingsView extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
AppConfig.appName,
GlobalConfig.appName,
style: TextStyle(
color: Colors.black,
fontSize: 22,

View File

@ -1,6 +1,6 @@
import 'package:flutter/material.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 {
var processValue = 0.0.obs;

View File

@ -1,14 +1,14 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:get/get.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/history_model.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/util/log_print.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';
@ -48,10 +48,12 @@ class TranslatorLogic extends GetxController {
}
Future<void> _onTapSpeak() async {
bool micResult = await PermissionUtil.checkPermission([Permission.microphone]);
bool micResult =
await PermissionUtil.checkPermission([Permission.microphone]);
if (!micResult) return;
if (Platform.isIOS) {
bool speechResult = await PermissionUtil.checkPermission([Permission.speech]);
bool speechResult =
await PermissionUtil.checkPermission([Permission.speech]);
if (!speechResult) return;
}
await Get.dialog(
@ -67,7 +69,9 @@ class TranslatorLogic extends GetxController {
if (SpeechToTextManager().isListening.value) {
_openTranslatorResultPage();
} else {
SpeechToTextManager().startListening(TranslateLanguage().fromLanguageEntity.value.languageCode, _onSpeechResult);
SpeechToTextManager().startListening(
TranslateManager().fromLanguageEntity.value.languageCode,
_onSpeechResult);
}
} else {
Get.back();
@ -82,7 +86,7 @@ class TranslatorLogic extends GetxController {
}
void _onSpeechResult(SpeechRecognitionResult result) {
debugPrint('识别结果:${result.recognizedWords}');
LogPrint.d('识别结果:${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:get/get.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/widget/base_appbar.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 {
const TranslatorPage({super.key});
@ -84,7 +80,8 @@ class _TranslatorPageState extends State<TranslatorPage> {
),
Obx(() {
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(
onTap: logic.onTapSuffix,
child: ClipOval(
@ -113,7 +110,8 @@ class _TranslatorPageState extends State<TranslatorPage> {
],
),
),
Obx(() => state.historyList.isNotEmpty
Obx(
() => state.historyList.isNotEmpty
? Expanded(
child: Column(
children: [
@ -157,7 +155,8 @@ class _TranslatorPageState extends State<TranslatorPage> {
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
color: Colors.black,
borderRadius: BorderRadius.circular(8),
borderRadius:
BorderRadius.circular(8),
),
child: Image.asset(
Assets.imagesDeleteIcon,
@ -168,12 +167,15 @@ class _TranslatorPageState extends State<TranslatorPage> {
);
},
child: InkWell(
onTap: () => logic.onTapHistoryItem(historyEntity),
onTap: () =>
logic.onTapHistoryItem(historyEntity),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Padding(
padding: const EdgeInsets.symmetric(vertical: 10),
padding: const EdgeInsets.symmetric(
vertical: 10),
child: RichText(
maxLines: 1,
overflow: TextOverflow.ellipsis,

View File

@ -1,15 +1,11 @@
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/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/util/obj_util.dart';
import 'translator_history_state.dart';
/// @description:
/// @author
/// @date: 2024-06-28 16:26:22
class TranslatorHistoryLogic extends GetxController {
final state = TranslatorHistoryState();
@ -34,7 +30,10 @@ class TranslatorHistoryLogic extends GetxController {
void translatorTtsPlay(HistoryEntity entity) {
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) {
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) {
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:trans_lark/entity/history_model.dart';
/// @description:
/// @author
/// @date: 2024-06-28 16:26:22
class TranslatorHistoryState {
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:get/get.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/widget/base_appbar.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 {
static String routName = "/translateHistory";

View File

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

View File

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

View File

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

View File

@ -26,8 +26,7 @@ class WebPageController extends GetxController {
onPageFinished: (String url) {
viewState.value = ViewState.normal;
},
onWebResourceError: (WebResourceError error) {
},
onWebResourceError: (WebResourceError error) {},
onNavigationRequest: (NavigationRequest request) {
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_type/scene_type_binding.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_history/translator_history_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:trans_lark/entity/history_model.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: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 {
static String full = 'yyyy-MM-dd HH:mm:ss';
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';
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';
class NumUtil {

View File

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

View File

@ -1,7 +1,3 @@
// Author: fengshengxiong
// Date: 2024/5/10
// Description:
import 'dart:io';
import 'package:get/get.dart';
@ -11,7 +7,8 @@ import 'package:trans_lark/widget/remind_dialog.dart';
class PermissionUtil {
///
/// [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 = [];
//
@ -25,7 +22,8 @@ class PermissionUtil {
//
if (newPermissionList.isNotEmpty) {
PermissionStatus permissionStatus = await _requestPermission(newPermissionList);
PermissionStatus permissionStatus =
await _requestPermission(newPermissionList);
switch (permissionStatus) {
//
case PermissionStatus.denied:
@ -39,7 +37,8 @@ class PermissionUtil {
case PermissionStatus.provisional:
case PermissionStatus.restricted:
case PermissionStatus.permanentlyDenied:
if (showDialog) _showFailedDialog(newPermissionList, isPermanentlyDenied: true);
if (showDialog)
_showFailedDialog(newPermissionList, isPermanentlyDenied: true);
break;
}
} else {
@ -49,7 +48,8 @@ class PermissionUtil {
}
/// false
static Future<PermissionStatus> _requestPermission(List<Permission> permissionList) async {
static Future<PermissionStatus> _requestPermission(
List<Permission> permissionList) async {
Map<Permission, PermissionStatus> statuses = await permissionList.request();
PermissionStatus currentPermissionStatus = PermissionStatus.granted;
statuses.forEach((key, value) {
@ -81,7 +81,8 @@ class PermissionUtil {
return true;
} else {
//
_showFailedDialog([Permission.locationWhenInUse, Permission.locationAlways],
_showFailedDialog(
[Permission.locationWhenInUse, Permission.locationAlways],
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(
barrierDismissible: false,
RemindDialog(
@ -131,15 +133,20 @@ class PermissionUtil {
String description = '';
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) {
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) {
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) {
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) {
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;
}

View File

@ -1,7 +1,3 @@
// Author: fengshengxiong
// Date: 2024/5/7
// Description: BaseAppBar
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:trans_lark/generated/assets.dart';
@ -69,7 +65,8 @@ class BaseAppBar extends StatelessWidget implements PreferredSizeWidget {
),
),
Expanded(
child: titleWidget ?? Text(
child: titleWidget ??
Text(
title ?? '',
overflow: TextOverflow.ellipsis,
style: const TextStyle(

View File

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

View File

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

View File

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

View File

@ -1,7 +1,7 @@
import 'package:flutter/material.dart';
import 'package:get/get.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';
class LanguageBar extends StatelessWidget {
@ -34,9 +34,17 @@ class LanguageBar extends StatelessWidget {
const SizedBox(width: 8),
Flexible(
child: Text(
TranslateLanguage().fromLanguageEntity.value.languageName,
TranslateManager()
.fromLanguageEntity
.value
.languageName,
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,
fontWeight: FontWeight.w500,
overflow: TextOverflow.ellipsis,
@ -91,9 +99,17 @@ class LanguageBar extends StatelessWidget {
const SizedBox(width: 8),
Flexible(
child: Text(
TranslateLanguage().toLanguageEntity.value.languageName,
TranslateManager()
.toLanguageEntity
.value
.languageName,
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,
fontWeight: FontWeight.w500,
overflow: TextOverflow.ellipsis,
@ -118,21 +134,25 @@ class LanguageBar extends StatelessWidget {
}
void _exchangeOnTap() {
var tempLanguageCode = TranslateLanguage().toLanguageEntity.value.languageCode;
var tempLanguageName = TranslateLanguage().toLanguageEntity.value.languageName;
var tempLanguageCode =
TranslateManager().toLanguageEntity.value.languageCode;
var tempLanguageName =
TranslateManager().toLanguageEntity.value.languageName;
TranslateLanguage().toLanguageEntity.update((fn) {
fn?.languageCode = TranslateLanguage().fromLanguageEntity.value.languageCode;
fn?.languageName = TranslateLanguage().fromLanguageEntity.value.languageName;
TranslateManager().toLanguageEntity.update((fn) {
fn?.languageCode =
TranslateManager().fromLanguageEntity.value.languageCode;
fn?.languageName =
TranslateManager().fromLanguageEntity.value.languageName;
});
TranslateLanguage().fromLanguageEntity.update((fn) {
TranslateManager().fromLanguageEntity.update((fn) {
fn?.languageCode = tempLanguageCode;
fn?.languageName = tempLanguageName;
});
}
void _onTapFrom() {
TranslateLanguage().isSelectFromLanguage.value = true;
TranslateManager().isSelectFromLanguage.value = true;
Get.bottomSheet(
isScrollControlled: true,
const LanguageBottomSheet(),
@ -140,7 +160,7 @@ class LanguageBar extends StatelessWidget {
}
void _onTapTo() {
TranslateLanguage().isSelectFromLanguage.value = false;
TranslateManager().isSelectFromLanguage.value = false;
Get.bottomSheet(
isScrollControlled: true,
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:trans_lark/entity/language_entity.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/widget/base_scrollbar.dart';
import 'package:trans_lark/widget/language_bar.dart';
@ -19,7 +19,8 @@ class LanguageBottomSheet extends StatelessWidget {
decoration: const BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.only(
topLeft: Radius.circular(26), topRight: Radius.circular(26),
topLeft: Radius.circular(26),
topRight: Radius.circular(26),
),
),
child: Column(
@ -50,15 +51,16 @@ class LanguageBottomSheet extends StatelessWidget {
return Expanded(
child: BaseScrollbar(
child: ListView.builder(
itemCount: TranslateLanguage().languageList.length,
itemCount: TranslateManager().languageList.length,
itemBuilder: (context, index) {
var item = TranslateLanguage().languageList[index];
var item = TranslateManager().languageList[index];
return Material(
color: Colors.transparent,
child: InkWell(
onTap: () => _itemOnTap(item),
child: Container(
padding: const EdgeInsets.symmetric(vertical: 13, horizontal: 33),
padding:
const EdgeInsets.symmetric(vertical: 13, horizontal: 33),
child: Row(
children: [
Expanded(
@ -66,9 +68,22 @@ class LanguageBottomSheet extends StatelessWidget {
return Text(
item.languageName,
style: TextStyle(
color: TranslateLanguage().isSelectFromLanguage.value
? (item.languageName == TranslateLanguage().fromLanguageEntity.value.languageName ? const Color(0xff4ECA8C) : const Color(0xff152A3D))
: (item.languageName == TranslateLanguage().toLanguageEntity.value.languageName ? const Color(0xff4ECA8C) : const Color(0xff152A3D)),
color:
TranslateManager().isSelectFromLanguage.value
? (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,
overflow: TextOverflow.ellipsis,
),
@ -77,9 +92,17 @@ class LanguageBottomSheet extends StatelessWidget {
),
Obx(() {
return Visibility(
visible: TranslateLanguage().isSelectFromLanguage.value
? (item.languageName == TranslateLanguage().fromLanguageEntity.value.languageName)
: (item.languageName == TranslateLanguage().toLanguageEntity.value.languageName),
visible: TranslateManager().isSelectFromLanguage.value
? (item.languageName ==
TranslateManager()
.fromLanguageEntity
.value
.languageName)
: (item.languageName ==
TranslateManager()
.toLanguageEntity
.value
.languageName),
child: Padding(
padding: const EdgeInsets.only(left: 10),
child: Image.asset(
@ -102,13 +125,13 @@ class LanguageBottomSheet extends StatelessWidget {
}
void _itemOnTap(LanguageEntity item) {
if (TranslateLanguage().isSelectFromLanguage.value) {
TranslateLanguage().fromLanguageEntity.update((fn) {
if (TranslateManager().isSelectFromLanguage.value) {
TranslateManager().fromLanguageEntity.update((fn) {
fn?.languageCode = item.languageCode;
fn?.languageName = item.languageName;
});
} else {
TranslateLanguage().toLanguageEntity.update((fn) {
TranslateManager().toLanguageEntity.update((fn) {
fn?.languageCode = item.languageCode;
fn?.languageName = item.languageName;
});
@ -119,10 +142,10 @@ class LanguageBottomSheet extends StatelessWidget {
}
void _onTapFrom() {
TranslateLanguage().isSelectFromLanguage.value = true;
TranslateManager().isSelectFromLanguage.value = true;
}
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:get/get.dart';

View File

@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.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 {
const SpeakDialog({
@ -44,7 +44,8 @@ class SpeakDialog extends StatelessWidget {
clipBehavior: Clip.antiAlias,
decoration: const BoxDecoration(
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(
children: [
@ -73,7 +74,10 @@ class SpeakDialog extends StatelessWidget {
),
Flexible(
child: Text(
TranslateLanguage().fromLanguageEntity.value.languageName,
TranslateManager()
.fromLanguageEntity
.value
.languageName,
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: const TextStyle(
@ -89,7 +93,9 @@ class SpeakDialog extends StatelessWidget {
}),
Obx(() {
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,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.center,

View File

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

View File

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

View File

@ -1,39 +1,16 @@
name: trans_lark
description: "A new Flutter project."
# The following line prevents the package from being accidentally published to
# 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
publish_to: 'none'
# 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
environment:
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:
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
get: ^4.6.6
flutter_tts: ^4.0.2
@ -85,6 +62,9 @@ dependencies:
# 获取当前设备信息
device_info_plus: ^10.1.0
# 日志打印
logger: ^2.3.0
flutter_launcher_icons:
android: "launcher_icon"
ios: true
@ -94,57 +74,16 @@ flutter_launcher_icons:
dev_dependencies:
flutter_test:
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
hive_generator: ^2.0.1
build_runner: ^2.4.11
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:
# 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
# To add assets to your application, add an assets section, like this:
assets:
- assets/launcher_icon/
- assets/images/
- assets/svg/
- 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