From 801e130c344bd94add090f29864ad11a4e66e1bc Mon Sep 17 00:00:00 2001 From: tanlongsheng <252620078@qq.com> Date: Wed, 17 Dec 2025 20:03:54 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E5=A3=B0=E9=9F=B3=E5=A4=8D?= =?UTF-8?q?=E5=88=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../voice_replication_controller.dart | 17 ++- .../views/voice_replication_view.dart | 121 +++++++++++++++--- 2 files changed, 114 insertions(+), 24 deletions(-) diff --git a/lib/modules/voice_replication/controllers/voice_replication_controller.dart b/lib/modules/voice_replication/controllers/voice_replication_controller.dart index 3f2f94c35..686da8313 100644 --- a/lib/modules/voice_replication/controllers/voice_replication_controller.dart +++ b/lib/modules/voice_replication/controllers/voice_replication_controller.dart @@ -1,13 +1,22 @@ import 'package:get/get.dart'; import 'package:get_storage/get_storage.dart'; +import '../../../data/services/tts_service.dart'; + class VoiceReplicationController extends GetxController { + final TtsService _ttsService = Get.find(); + final GetStorage _storage = GetStorage(); RxBool isReplicating = false.obs; RxString speakerProfileId = ''.obs; + RxBool isAgent = false.obs; + RxBool isSimultaneous = false.obs; + RxBool isCall = false.obs; + RxBool isFaceToFace = false.obs; + @override void onInit() { super.onInit(); @@ -19,10 +28,12 @@ class VoiceReplicationController extends GetxController { speakerProfileId.value = _storage.read('speakerProfileId') ?? ''; } - void switchChange(bool value) { - isReplicating.value = value; + void enableVoiceFlocking() { if (speakerProfileId.value.isNotEmpty) { - _storage.write('open_voice_replication', value); + _ttsService.setVoiceFlocking( + isReplicating.value ? speakerProfileId.value : '', + ); + _storage.write('open_voice_replication', isReplicating.value); } } } diff --git a/lib/modules/voice_replication/views/voice_replication_view.dart b/lib/modules/voice_replication/views/voice_replication_view.dart index 24ec9af96..bb46f745a 100644 --- a/lib/modules/voice_replication/views/voice_replication_view.dart +++ b/lib/modules/voice_replication/views/voice_replication_view.dart @@ -84,7 +84,7 @@ class VoiceReplicationView extends GetView { Padding( padding: EdgeInsets.only(top: 20.w, bottom: 10.w), child: Text( - '复刻你的声音', + '首月免费使用', style: TextStyle( color: isDarkMode ? Colors.white : Colors.black87, fontSize: 18.sp, @@ -105,6 +105,7 @@ class VoiceReplicationView extends GetView { ), Container( padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 2.w), + margin: EdgeInsets.only(bottom: 15.w), decoration: BoxDecoration( color: isDarkMode ? Colors.grey[800] : Colors.white, borderRadius: BorderRadius.circular(12.w), @@ -122,31 +123,78 @@ class VoiceReplicationView extends GetView { () => Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text( - '开启声音复刻', - style: TextStyle( - color: isDarkMode ? Colors.white : Colors.black87, - fontSize: 16.sp, - ), - ), - Transform.scale( - scale: 0.9, - alignment: Alignment.centerRight, - child: Switch( - value: controller.isReplicating.value, - onChanged: controller.switchChange, - ), - ), - ], + _buildSwitch( + isDarkMode, + '开启声音复刻', + controller.isReplicating.value, + onChanged: (bool value) { + controller.isReplicating.value = value; + controller.enableVoiceFlocking(); + }, ), if (controller.isReplicating.value) _buildOpen(isDarkMode), ], ), ), ), + Obx( + () => controller.isReplicating.value + ? Container( + padding: + EdgeInsets.symmetric(horizontal: 12.w, vertical: 5.w), + margin: EdgeInsets.only(bottom: 15.w), + decoration: BoxDecoration( + color: isDarkMode ? Colors.grey[800] : Colors.white, + borderRadius: BorderRadius.circular(12.w), + boxShadow: [ + BoxShadow( + color: isDarkMode + ? Colors.black.withValues(alpha: 0.2) + : Colors.black.withValues(alpha: 0.05), + blurRadius: 10, + offset: const Offset(0, 4), + ), + ], + ), + child: Column( + children: [ + _buildSwitch( + isDarkMode, + 'AI全能助手开启', + controller.isAgent.value, + onChanged: (bool value) { + controller.isAgent.value = value; + }, + ), + _buildSwitch( + isDarkMode, + '同声翻译开启', + controller.isSimultaneous.value, + onChanged: (bool value) { + controller.isSimultaneous.value = value; + }, + ), + _buildSwitch( + isDarkMode, + '通话翻译开启', + controller.isCall.value, + onChanged: (bool value) { + controller.isCall.value = value; + }, + ), + _buildSwitch( + isDarkMode, + '面对面翻译开启', + controller.isFaceToFace.value, + onChanged: (bool value) { + controller.isFaceToFace.value = value; + }, + ), + ], + ), + ) + : const SizedBox.shrink(), + ), ], ); } @@ -156,7 +204,7 @@ class VoiceReplicationView extends GetView { padding: EdgeInsets.symmetric(vertical: 10.w), child: controller.speakerProfileId.value.isNotEmpty ? Text( - '个人语音ID:${controller.speakerProfileId.value}', + '个人语音ID:\n${controller.speakerProfileId.value}', style: TextStyle( color: isDarkMode ? Colors.white : Colors.grey, fontSize: 14.sp, @@ -200,4 +248,35 @@ class VoiceReplicationView extends GetView { ), ); } + + Widget _buildSwitch( + bool isDarkMode, + String title, + bool value, { + Function(bool)? onChanged, + }) { + return Padding( + padding: EdgeInsets.symmetric(vertical: 2.w), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text( + title, + style: TextStyle( + color: isDarkMode ? Colors.white : Colors.black87, + fontSize: 16.sp, + ), + ), + Transform.scale( + scale: 0.8, + alignment: Alignment.centerRight, + child: Switch( + value: value, + onChanged: onChanged, + ), + ), + ], + ), + ); + } }