15 changed files with 562 additions and 59 deletions
@ -0,0 +1,11 @@ |
|||
import 'package:deep_voice/modules/devices/controllers/devices_controller.dart'; |
|||
import 'package:get/get.dart'; |
|||
|
|||
class DevicesBinding extends Bindings { |
|||
@override |
|||
void dependencies() { |
|||
Get.lazyPut<DevicesController>( |
|||
() => DevicesController(), |
|||
); |
|||
} |
|||
} |
|||
@ -0,0 +1,61 @@ |
|||
import 'package:deep_voice/core/utils/logger.dart'; |
|||
import 'package:deep_voice/data/models/user_Info.dart'; |
|||
import 'package:deep_voice/data/services/ble_manager.dart'; |
|||
import 'package:deep_voice/data/services/network/api.dart'; |
|||
import 'package:deep_voice/routes/app_routes.dart'; |
|||
import 'package:get/get.dart'; |
|||
import 'package:get/get_rx/get_rx.dart'; |
|||
import 'package:get/get_state_manager/src/simple/get_controllers.dart'; |
|||
|
|||
/* |
|||
设备管理 |
|||
*/ |
|||
class DevicesController extends GetxController { |
|||
late final BleManager _bleManager; |
|||
//耳机绑定 |
|||
final isearphone = false.obs; |
|||
final earphoneName = "".obs; |
|||
final earphoneMac = "".obs; |
|||
final earphoneCode = "".obs; |
|||
|
|||
//录音笔 |
|||
final isvoicepen = false.obs; |
|||
final voicepenName = "".obs; |
|||
final voicepenMac = "".obs; |
|||
|
|||
@override |
|||
void onInit() { |
|||
super.onInit(); |
|||
_bleManager = Get.find<BleManager>(); |
|||
earphoneName.value = User.instance.earphonename; |
|||
earphoneMac.value = User.instance.earphonemac; |
|||
earphoneCode.value = User.instance.earphoneauthcode; |
|||
if (earphoneCode.value != "") { |
|||
isearphone.value = true; |
|||
} |
|||
} |
|||
|
|||
@override |
|||
void onClose() { |
|||
super.onClose(); |
|||
} |
|||
|
|||
void unbindearphone() async { |
|||
final response = await Api.unbindearphone({ |
|||
"code": earphoneCode.value, |
|||
"earphonname": earphoneMac.value, |
|||
}); |
|||
if (response != null) { |
|||
User.instance.earphonename = ""; |
|||
User.instance.earphonemac = ""; |
|||
User.instance.earphoneauthcode = ""; |
|||
isearphone.value = false; |
|||
_bleManager.clearPairedDevices(); |
|||
_bleManager.disconnect(); |
|||
Get.toNamed(Routes.pairing); |
|||
return; |
|||
} else { |
|||
return; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,290 @@ |
|||
import 'dart:ui'; |
|||
|
|||
import 'package:deep_voice/modules/devices/controllers/devices_controller.dart'; |
|||
import 'package:flutter/material.dart'; |
|||
import 'package:flutter_screenutil/flutter_screenutil.dart'; |
|||
import 'package:get/get.dart'; |
|||
|
|||
class DevicesView extends GetView<DevicesController> { |
|||
const DevicesView({Key? key}) : super(key: key); |
|||
|
|||
@override |
|||
Widget build(BuildContext context) { |
|||
// 直接使用 Theme.of(context) 获取当前主题 |
|||
final isDarkMode = Theme.of(context).brightness == Brightness.dark; |
|||
|
|||
return Scaffold( |
|||
backgroundColor: isDarkMode ? Colors.black : Colors.grey[50], |
|||
appBar: AppBar( |
|||
automaticallyImplyLeading: false, |
|||
centerTitle: true, |
|||
elevation: 0, |
|||
backgroundColor: isDarkMode ? Colors.black : Colors.white, |
|||
leading: IconButton( |
|||
icon: Icon( |
|||
Icons.arrow_back_ios, |
|||
size: 20.sp, |
|||
color: isDarkMode ? Colors.white : Colors.black, |
|||
), |
|||
onPressed: () { |
|||
Get.back(); // 正常返回 |
|||
}, |
|||
), |
|||
title: Text( |
|||
'设备管理'.tr, |
|||
style: TextStyle( |
|||
fontSize: 20.sp, |
|||
color: isDarkMode ? Colors.white : Colors.black, |
|||
), |
|||
), |
|||
), |
|||
body: ListView( |
|||
padding: EdgeInsets.symmetric(horizontal: 16.w, vertical: 16.h), |
|||
children: [ |
|||
_buildEarphoneCard(isDarkMode), |
|||
SizedBox(height: 20.h), |
|||
_buildVoiceRecorderCard(isDarkMode), |
|||
SizedBox(height: 20.h), |
|||
], |
|||
), |
|||
); |
|||
} |
|||
|
|||
// 耳机 |
|||
Widget _buildEarphoneCard(bool isDarkMode) { |
|||
return Column( |
|||
crossAxisAlignment: CrossAxisAlignment.start, |
|||
children: [ |
|||
Padding( |
|||
padding: EdgeInsets.only(left: 4.w, bottom: 8.h), |
|||
child: Text( |
|||
'earphone'.tr, // AI设置 |
|||
style: TextStyle( |
|||
fontSize: 12.sp, |
|||
fontWeight: FontWeight.w500, |
|||
color: isDarkMode ? Colors.blue[400] : Colors.blue[600], |
|||
letterSpacing: 1, |
|||
), |
|||
), |
|||
), |
|||
Container( |
|||
decoration: BoxDecoration( |
|||
color: isDarkMode ? Colors.white.withOpacity(0.05) : Colors.white, |
|||
borderRadius: BorderRadius.circular(16.r), |
|||
boxShadow: [ |
|||
BoxShadow( |
|||
color: isDarkMode |
|||
? Colors.black.withOpacity(0.2) |
|||
: Colors.black.withOpacity(0.05), |
|||
blurRadius: 10, |
|||
offset: const Offset(0, 2), |
|||
), |
|||
], |
|||
), |
|||
child: ClipRRect( |
|||
borderRadius: BorderRadius.circular(16.r), |
|||
child: BackdropFilter( |
|||
filter: isDarkMode |
|||
? ImageFilter.blur(sigmaX: 5, sigmaY: 5) |
|||
: ImageFilter.blur(sigmaX: 0, sigmaY: 0), |
|||
child: Column( |
|||
children: [ |
|||
Obx( |
|||
() => |
|||
// 耳机列表 |
|||
_buildSimpleNavigationSetting( |
|||
title: controller.isearphone.value |
|||
? controller.earphoneName.value |
|||
: "未绑定", |
|||
subtitle: controller.isearphone.value |
|||
? controller.earphoneMac.value |
|||
: "还未绑定设备", |
|||
icon: Icons.headphones, |
|||
iconBgColor: isDarkMode |
|||
? const Color.fromARGB(255, 255, 255, 255)! |
|||
.withOpacity(0.3) |
|||
: const Color.fromARGB(255, 0, 0, 0)!, |
|||
iconColor: isDarkMode |
|||
? const Color.fromARGB(255, 0, 0, 0)! |
|||
: const Color.fromARGB(255, 255, 255, 255)!, |
|||
titleColor: isDarkMode ? Colors.white : null, |
|||
subtitleColor: isDarkMode ? Colors.white70 : null, |
|||
isDarkMode: isDarkMode, |
|||
showbutt: controller.isearphone.value, |
|||
onPressed: () { |
|||
controller.unbindearphone(); |
|||
}, |
|||
), |
|||
) |
|||
], |
|||
), |
|||
), |
|||
), |
|||
), |
|||
], |
|||
); |
|||
} |
|||
|
|||
// 录音笔 |
|||
Widget _buildVoiceRecorderCard(bool isDarkMode) { |
|||
return Column( |
|||
crossAxisAlignment: CrossAxisAlignment.start, |
|||
children: [ |
|||
Padding( |
|||
padding: EdgeInsets.only(left: 4.w, bottom: 8.h), |
|||
child: Text( |
|||
'voicerecorder'.tr, //AI设置 |
|||
style: TextStyle( |
|||
fontSize: 12.sp, |
|||
fontWeight: FontWeight.w500, |
|||
color: isDarkMode ? Colors.blue[400] : Colors.blue[600], |
|||
letterSpacing: 1, |
|||
), |
|||
), |
|||
), |
|||
Container( |
|||
decoration: BoxDecoration( |
|||
color: isDarkMode ? Colors.white.withOpacity(0.05) : Colors.white, |
|||
borderRadius: BorderRadius.circular(16.r), |
|||
boxShadow: [ |
|||
BoxShadow( |
|||
color: isDarkMode |
|||
? Colors.black.withOpacity(0.2) |
|||
: Colors.black.withOpacity(0.05), |
|||
blurRadius: 10, |
|||
offset: const Offset(0, 2), |
|||
), |
|||
], |
|||
), |
|||
child: ClipRRect( |
|||
borderRadius: BorderRadius.circular(16.r), |
|||
child: BackdropFilter( |
|||
filter: isDarkMode |
|||
? ImageFilter.blur(sigmaX: 5, sigmaY: 5) |
|||
: ImageFilter.blur(sigmaX: 0, sigmaY: 0), |
|||
child: Column( |
|||
children: [ |
|||
// 实时对话入口 |
|||
Obx( |
|||
() => _buildSimpleNavigationSetting( |
|||
title: '未绑定', |
|||
subtitle: '还未绑定设备', |
|||
icon: Icons.edit, |
|||
iconBgColor: isDarkMode |
|||
? const Color.fromARGB(255, 255, 255, 255)! |
|||
.withOpacity(0.3) |
|||
: const Color.fromARGB(255, 0, 0, 0)!, |
|||
iconColor: isDarkMode |
|||
? const Color.fromARGB(255, 0, 0, 0)! |
|||
: const Color.fromARGB(255, 255, 255, 255)!, |
|||
titleColor: isDarkMode ? Colors.white : null, |
|||
subtitleColor: isDarkMode ? Colors.white70 : null, |
|||
isDarkMode: isDarkMode, |
|||
showbutt: controller.isvoicepen.value, |
|||
onPressed: () {}, |
|||
), |
|||
) |
|||
], |
|||
), |
|||
), |
|||
), |
|||
), |
|||
], |
|||
); |
|||
} |
|||
|
|||
// 简单导航设置项 |
|||
Widget _buildSimpleNavigationSetting({ |
|||
required String title, |
|||
String? subtitle, |
|||
required IconData icon, |
|||
required Color iconBgColor, |
|||
required Color iconColor, |
|||
Color? titleColor, |
|||
Color? subtitleColor, |
|||
required bool isDarkMode, |
|||
required bool showbutt, |
|||
required VoidCallback onPressed, |
|||
}) { |
|||
return InkWell( |
|||
child: Padding( |
|||
padding: EdgeInsets.all(16.w), |
|||
child: Row( |
|||
mainAxisAlignment: MainAxisAlignment.spaceBetween, |
|||
children: [ |
|||
Expanded( |
|||
child: Row( |
|||
children: [ |
|||
Container( |
|||
width: 32.w, |
|||
height: 32.w, |
|||
decoration: BoxDecoration( |
|||
color: iconBgColor, |
|||
borderRadius: BorderRadius.circular(16.r), |
|||
), |
|||
child: Icon( |
|||
icon, |
|||
size: 16.w, |
|||
color: iconColor, |
|||
), |
|||
), |
|||
SizedBox(width: 12.w), |
|||
Flexible( |
|||
child: Column( |
|||
crossAxisAlignment: CrossAxisAlignment.start, |
|||
children: [ |
|||
Text( |
|||
title, |
|||
style: TextStyle( |
|||
fontSize: 16.sp, |
|||
fontWeight: FontWeight.w500, |
|||
color: titleColor ?? |
|||
(isDarkMode ? Colors.white : Colors.black87), |
|||
), |
|||
overflow: TextOverflow.ellipsis, |
|||
), |
|||
if (subtitle != null) SizedBox(height: 2.h), |
|||
if (subtitle != null) |
|||
Text( |
|||
subtitle, |
|||
style: TextStyle( |
|||
fontSize: 12.sp, |
|||
color: subtitleColor ?? |
|||
(isDarkMode |
|||
? Colors.white70 |
|||
: Colors.black54), |
|||
), |
|||
overflow: TextOverflow.ellipsis, |
|||
), |
|||
], |
|||
), |
|||
), |
|||
], |
|||
), |
|||
), |
|||
if (showbutt) |
|||
Container( |
|||
width: 74.w, |
|||
height: 40.w, |
|||
child: ElevatedButton( |
|||
style: ElevatedButton.styleFrom( |
|||
backgroundColor: Colors.blue, |
|||
shape: RoundedRectangleBorder( |
|||
borderRadius: BorderRadius.circular(12), |
|||
), |
|||
padding: EdgeInsets.symmetric(horizontal: 2, vertical: 2), |
|||
), |
|||
onPressed: onPressed, |
|||
child: const Text( |
|||
'解绑', |
|||
style: TextStyle( |
|||
color: Colors.white, |
|||
), |
|||
), |
|||
)), |
|||
], |
|||
), |
|||
), |
|||
); |
|||
} |
|||
} |
|||
Loading…
Reference in new issue