Browse Source

Merge branch 'ble' of https://github.com/deepcloud2048/deep_voice into ble

newdev_shunjiawei
tanlongsheng 1 year ago
parent
commit
504efa3dae
  1. 3
      lib/data/services/network/nw_api.dart
  2. 31
      lib/modules/agent/controllers/agent_controller.dart
  3. 78
      lib/modules/agent/views/agent_view.dart
  4. 2
      lib/modules/agent/views/message_bubble.dart
  5. 3
      lib/modules/home/bindings/home_binding.dart
  6. 9
      lib/modules/home/controllers/home_controller.dart
  7. 6
      lib/modules/home/views/home_view.dart
  8. 12
      lib/modules/ota_upgrade/views/ota_upgrade_view.dart

3
lib/data/services/network/nw_api.dart

@ -1,4 +1,5 @@
class NWApi {
// static const baseApi = "https://www.deapsound.com";
static const baseApi = "https://api.deapsound.com";
// static const baseApi = "https://api.deapsound.com";
static const baseApi = "https://api.ideapsound.com";
}

31
lib/modules/agent/controllers/agent_controller.dart

@ -13,15 +13,16 @@ import 'package:permission_handler/permission_handler.dart';
import 'package:app_settings/app_settings.dart';
class Message {
final bool isUser;
final String text;
final DateTime timestamp;
final bool isUser; //标识信息是否来自用户还是AI
final String text; //信息文本内容
final DateTime timestamp; // 消息时间戳
final bool isRecognizing; // 是否为语音识别中的临时消息
final bool hasImage; // 是否包含图片
final String? imagePath; // 图片路径
final Map? meta; //卡片数据
Message({
// 构造函数
required this.isUser,
required this.text,
DateTime? timestamp,
@ -33,14 +34,14 @@ class Message {
}
class AgentController extends GetxController {
static AgentController get to => Get.find();
static AgentController get to => Get.find(); //单例访问模式
final logger = Logger();
// 聊天消息列表
final messages = <Message>[].obs;
// 控制器
// UI控制器
final TextEditingController textController = TextEditingController();
final ScrollController scrollController = ScrollController();
@ -49,10 +50,10 @@ class AgentController extends GetxController {
var isPlaying = false.obs;
var currentUrl = "".obs;
// 状态标志
// 各种状态标志
final isInitialized = false.obs;
final isListening = false.obs;
final isSpeaking = false.obs;
final isListening = false.obs; //是否正在语音识别
final isSpeaking = false.obs; //是否正在播放tts
final isProcessing = false.obs;
// TTS启用状态
final isTtsEnabled = true.obs;
@ -61,7 +62,7 @@ class AgentController extends GetxController {
final isImageProcessing = false.obs;
// 输入模式控制
final isTextInputMode = true.obs;
final isTextInputMode = true.obs; //文本输入模式vs语音输入模式
// 当前输入的文本内容
final currentText = ''.obs;
@ -86,15 +87,15 @@ class AgentController extends GetxController {
@override
void onInit() {
super.onInit();
_loadTtsPreference();
_loadChatHistory();
_subscribeToEvents();
_loadTtsPreference(); //加载TTS偏好设置
_loadChatHistory(); //加载聊天历史记录
_subscribeToEvents(); //订阅代理服务事件
}
@override
void onClose() {
AgentService.stopConversation();
AgentService.stopTts();
AgentService.stopConversation(); // 停止当前会话
AgentService.stopTts(); // 停止当前语音
textController.dispose();
scrollController.dispose();
_eventSubscription?.cancel();
@ -179,7 +180,7 @@ class AgentController extends GetxController {
void _addWelcomeMessage() {
messages.add(Message(
isUser: false,
text: '你好!我是DeepVoice AI助手,我能帮你:\n\n'
text: '你好!我是Emma,我能帮你:\n\n'
'• 回答问题和提供信息\n'
'• 实时语音翻译\n'
'• 推荐音乐和播客\n'

78
lib/modules/agent/views/agent_view.dart

@ -14,15 +14,14 @@ class AgentView extends StatelessWidget {
final primaryColor = theme.primaryColor;
final backgroundColor = theme.scaffoldBackgroundColor;
final isDarkMode = Theme.of(context).brightness == Brightness.dark;
return Scaffold(
appBar: AppBar(
elevation: 1,
backgroundColor: backgroundColor,
leading: IconButton(
icon: Icon(Icons.arrow_back_ios,
color: isDarkMode ? Colors.white : Colors.black87,
size: 20),
icon: Icon(Icons.arrow_back_ios,
color: isDarkMode ? Colors.white : Colors.black87, size: 20),
onPressed: () => Get.back(),
),
titleSpacing: 0,
@ -53,7 +52,7 @@ class AgentView extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'DeepVoice AI',
'Emma',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
@ -72,7 +71,7 @@ class AgentView extends StatelessWidget {
),
const SizedBox(width: 4),
Text(
'在线',
'在线'.tr,
style: TextStyle(
fontSize: 12,
color: Colors.green,
@ -88,26 +87,27 @@ class AgentView extends StatelessWidget {
actions: [
// TTS开关
Obx(() => IconButton(
icon: Icon(
controller.isTtsEnabled.value
? Icons.volume_up
: Icons.volume_off,
color: controller.isTtsEnabled.value
? primaryColor
: isDarkMode
? Colors.grey[400]
: Colors.grey,
),
onPressed: () => controller.toggleTts(),
)),
icon: Icon(
controller.isTtsEnabled.value
? Icons.volume_up
: Icons.volume_off,
color: controller.isTtsEnabled.value
? primaryColor
: isDarkMode
? Colors.grey[400]
: Colors.grey,
),
onPressed: () => controller.toggleTts(),
)),
// 更多选项
Container(
width: 34,
height: 34,
margin: const EdgeInsets.only(right: 8),
decoration: BoxDecoration(
color: isDarkMode ? Colors.white.withOpacity(0.1) : Colors.grey[100],
color:
isDarkMode ? Colors.white.withOpacity(0.1) : Colors.grey[100],
shape: BoxShape.circle,
boxShadow: [
if (!isDarkMode)
@ -119,9 +119,8 @@ class AgentView extends StatelessWidget {
],
),
child: PopupMenuButton(
icon: Icon(Icons.more_vert,
color: isDarkMode ? Colors.white : Colors.black87,
size: 20),
icon: Icon(Icons.more_vert,
color: isDarkMode ? Colors.white : Colors.black87, size: 20),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
@ -132,7 +131,7 @@ class AgentView extends StatelessWidget {
children: [
Icon(Icons.delete_outline, color: primaryColor, size: 20),
const SizedBox(width: 8),
const Text('清除聊天记录', style: TextStyle(fontSize: 14)),
Text('清除聊天记录'.tr, style: TextStyle(fontSize: 14)),
],
),
onTap: () => Future.delayed(
@ -153,10 +152,12 @@ class AgentView extends StatelessWidget {
() => ListView.builder(
controller: controller.scrollController,
reverse: true,
padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 16),
padding:
const EdgeInsets.symmetric(vertical: 16, horizontal: 16),
itemCount: controller.messages.length,
itemBuilder: (context, index) {
final message = controller.messages[controller.messages.length - 1 - index];
final message = controller
.messages[controller.messages.length - 1 - index];
return Padding(
padding: const EdgeInsets.only(bottom: 8),
child: MessageBubble(
@ -245,19 +246,19 @@ class AgentView extends StatelessWidget {
children: [
_buildPromptChip(
context: context,
label: '总结图片内容',
label: '总结图片内容'.tr,
onTap: () => controller.summarizeImage(),
),
const SizedBox(width: 8),
_buildPromptChip(
context: context,
label: '抽取图像文字',
label: '抽取图像文字'.tr,
onTap: () => controller.extractTextFromImage(),
),
const SizedBox(width: 8),
_buildPromptChip(
context: context,
label: '翻译图像文字',
label: '翻译图像文字'.tr,
onTap: () => controller.translateImageText(),
),
],
@ -307,6 +308,7 @@ class AgentView extends StatelessWidget {
if (isTextMode) {
// 文本输入模式 - 注意观察图片模式时的高度变化
return Container(
height: 44,
padding: const EdgeInsets.symmetric(horizontal: 16),
decoration: BoxDecoration(
color: Colors.grey[200],
@ -330,7 +332,9 @@ class AgentView extends StatelessWidget {
minLines: isImageActive ? 2 : 1,
style: TextStyle(
fontSize: 15,
color: isDarkMode ? Colors.white : Colors.black87,
color: isDarkMode
? Colors.white
: Colors.black87,
),
decoration: InputDecoration(
hintText: isImageActive
@ -470,7 +474,8 @@ class AgentView extends StatelessWidget {
Icon(Icons.camera_alt,
color: primaryColor, size: 20),
const SizedBox(width: 8),
const Text('拍照', style: TextStyle(fontSize: 14)),
const Text('拍照',
style: TextStyle(fontSize: 14)),
],
),
),
@ -481,7 +486,8 @@ class AgentView extends StatelessWidget {
Icon(Icons.photo_library,
color: primaryColor, size: 20),
const SizedBox(width: 8),
const Text('从相册选择', style: TextStyle(fontSize: 14)),
const Text('从相册选择',
style: TextStyle(fontSize: 14)),
],
),
),
@ -506,7 +512,7 @@ class AgentView extends StatelessWidget {
}) {
final theme = Theme.of(context);
final primaryColor = theme.primaryColor;
return GestureDetector(
onTap: onTap,
child: Container(
@ -614,14 +620,14 @@ class _SoundBarState extends State<_SoundBar>
@override
Widget build(BuildContext context) {
final primaryColor = Theme.of(context).primaryColor;
return Container(
width: 2.5,
height: widget.isActive ? _animation.value : 3,
margin: const EdgeInsets.symmetric(horizontal: 1),
decoration: BoxDecoration(
color: widget.isActive
? primaryColor.withOpacity(0.8)
color: widget.isActive
? primaryColor.withOpacity(0.8)
: Colors.grey.withOpacity(0.4),
borderRadius: BorderRadius.circular(1.5),
),

2
lib/modules/agent/views/message_bubble.dart

@ -311,7 +311,7 @@ class MessageBubble extends GetView<AgentController> {
),
const SizedBox(width: 6),
Text(
'雨天时光 · 播放列表',
'播放列表'.tr,
style: TextStyle(
fontSize: 13,
fontWeight: FontWeight.w600,

3
lib/modules/home/bindings/home_binding.dart

@ -1,4 +1,3 @@
import '../../explore/controllers/explore_controller.dart';
import 'package:get/get.dart';
import '../controllers/home_controller.dart';
@ -6,7 +5,5 @@ class HomeBinding extends Bindings {
@override
void dependencies() {
Get.lazyPut<HomeController>(() => HomeController());
Get.lazyPut<ExploreController>(
() => ExploreController()); // 注册ExploreController
}
}

9
lib/modules/home/controllers/home_controller.dart

@ -3,7 +3,6 @@ import 'dart:async';
import '../../../routes/app_routes.dart';
import '../../../core/utils/logger.dart';
import 'package:flutter/material.dart';
import '../../explore/controllers/explore_controller.dart';
import 'package:classic_bluetooth/classic_bluetooth.dart' show BluetoothDevice;
import '../../../data/services/bluetooth_manager.dart';
import '../../../data/services/ble_manager.dart';
@ -20,9 +19,6 @@ enum ConnectionStatus {
class HomeController extends GetxController {
static HomeController get to => Get.find();
// 依赖的控制器
final ExploreController exploreController = Get.find<ExploreController>();
// 连接状态相关
final _connectionStatus = ConnectionStatus.disconnected.obs;
final _connectionErrorMsg = ''.obs;
@ -197,11 +193,6 @@ class HomeController extends GetxController {
Get.toNamed(Routes.translation);
}
/// 打开AI伴侣功能
void openAIGirlfriend() {
exploreController.onAIFeatureTap(2);
}
/// 展示AI功能
void exploreAIFeatures() {
Get.toNamed(Routes.agent);

6
lib/modules/home/views/home_view.dart

@ -461,8 +461,8 @@ class HomeView extends GetView<HomeController> {
),
SizedBox(height: 12.h),
_buildBatteryInfoGrid(isDarkMode),
SizedBox(height: 16.h),
_buildDeviceDetailsCard(isDarkMode),
// SizedBox(height: 16.h),
// _buildDeviceDetailsCard(isDarkMode),
],
);
}
@ -875,7 +875,7 @@ class HomeView extends GetView<HomeController> {
Color(0xFFFF5252).withOpacity(0.3),
],
),
onTap: controller.openAIGirlfriend,
onTap: () {},
height: 85.h, // 增加高度
isDarkMode: isDarkMode,
iconColor: const Color(0xFFE91E63),

12
lib/modules/ota_upgrade/views/ota_upgrade_view.dart

@ -289,8 +289,16 @@ class OtaUpgradeView extends GetView<OtaUpgradeController> {
fontWeight: FontWeight.bold,
color: isDarkMode ? Colors.blue[300] : Colors.blue[700])),
SizedBox(height: 16),
SizedBox(
width: 240,
//SizedBox(
//width: 240,
Container(
decoration: BoxDecoration(
border: Border.all(
color: isDarkMode ? Colors.blue[400]! : Colors.blue[300]!,
width: 1.5,
),
borderRadius: BorderRadius.circular(12),
),
child: LinearProgressIndicator(
value: controller.downloadProgress.value,
backgroundColor:

Loading…
Cancel
Save