Merge branch 'develop_sky_liyi' into 'develop_sky'
Develop sky liyi See merge request StarlockTeam/app-starlock!219
This commit is contained in:
commit
92a2407fb4
@ -71,21 +71,45 @@ class FirebaseHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> initSdk() async {
|
Future<void> initSdk() async {
|
||||||
FirebaseAnalytics.instance.setAnalyticsCollectionEnabled(true);
|
const bool isProductVmMode = bool.fromEnvironment('dart.vm.product');
|
||||||
|
if (F.isProductionEnv &&
|
||||||
|
isProductVmMode &&
|
||||||
|
defaultTargetPlatform == TargetPlatform.android) {
|
||||||
|
FirebaseAnalytics.instance.setAnalyticsCollectionEnabled(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> login(String userId) async {
|
Future<void> login(String userId) async {
|
||||||
FirebaseAnalytics.instance.setUserId(id: userId);
|
const bool isProductVmMode = bool.fromEnvironment('dart.vm.product');
|
||||||
|
if (F.isProductionEnv &&
|
||||||
|
isProductVmMode &&
|
||||||
|
defaultTargetPlatform == TargetPlatform.android) {
|
||||||
|
FirebaseAnalytics.instance.setUserId(id: userId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> trackEvent(
|
Future<void> trackEvent(
|
||||||
String eventName, Map<String, Object>? parameters) async {
|
String eventName,
|
||||||
FirebaseAnalytics.instance
|
Map<String, Object>? parameters,
|
||||||
.logEvent(name: eventName, parameters: parameters);
|
) async {
|
||||||
|
const bool isProductVmMode = bool.fromEnvironment('dart.vm.product');
|
||||||
|
if (F.isProductionEnv &&
|
||||||
|
isProductVmMode &&
|
||||||
|
defaultTargetPlatform == TargetPlatform.android) {
|
||||||
|
FirebaseAnalytics.instance.logEvent(
|
||||||
|
name: eventName,
|
||||||
|
parameters: parameters,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> logout() async {
|
Future<void> logout() async {
|
||||||
FirebaseAnalytics.instance.setUserId(id: '');
|
const bool isProductVmMode = bool.fromEnvironment('dart.vm.product');
|
||||||
|
if (F.isProductionEnv &&
|
||||||
|
isProductVmMode &&
|
||||||
|
defaultTargetPlatform == TargetPlatform.android) {
|
||||||
|
FirebaseAnalytics.instance.setUserId(id: '');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//</com>
|
//</com>
|
||||||
|
|||||||
@ -27,6 +27,7 @@ import 'package:star_lock/main/lockDetail/lockSet/liveVideo/liveVideo_page.dart'
|
|||||||
import 'package:star_lock/main/lockDetail/lockSet/motorPower/motorPower_page.dart';
|
import 'package:star_lock/main/lockDetail/lockSet/motorPower/motorPower_page.dart';
|
||||||
import 'package:star_lock/main/lockDetail/lockSet/openDoorDirection/openDoorDirection_page.dart';
|
import 'package:star_lock/main/lockDetail/lockSet/openDoorDirection/openDoorDirection_page.dart';
|
||||||
import 'package:star_lock/main/lockDetail/lockSet/speechLanguageSettings/speech_language_settings_page.dart';
|
import 'package:star_lock/main/lockDetail/lockSet/speechLanguageSettings/speech_language_settings_page.dart';
|
||||||
|
import 'package:star_lock/main/lockDetail/lockSet/thirdPartyPlatform/third_party_platform_page.dart';
|
||||||
import 'package:star_lock/main/lockDetail/messageWarn/addFamily/addFamily_page.dart';
|
import 'package:star_lock/main/lockDetail/messageWarn/addFamily/addFamily_page.dart';
|
||||||
import 'package:star_lock/main/lockDetail/messageWarn/lockUser/lockUser_page.dart';
|
import 'package:star_lock/main/lockDetail/messageWarn/lockUser/lockUser_page.dart';
|
||||||
import 'package:star_lock/main/lockDetail/messageWarn/msgNotification/coerceOpenDoor/coerceFingerprint/coerceFingerprint_page.dart';
|
import 'package:star_lock/main/lockDetail/messageWarn/msgNotification/coerceOpenDoor/coerceFingerprint/coerceFingerprint_page.dart';
|
||||||
@ -443,6 +444,8 @@ abstract class Routers {
|
|||||||
static const String motorPowerPage = '/motorPowerPage'; //电机功率设置
|
static const String motorPowerPage = '/motorPowerPage'; //电机功率设置
|
||||||
static const String speechLanguageSettingsPage =
|
static const String speechLanguageSettingsPage =
|
||||||
'/speechLanguageSettingsPage'; //锁语音包设置
|
'/speechLanguageSettingsPage'; //锁语音包设置
|
||||||
|
static const String thirdPartyPlatformPage =
|
||||||
|
'/thirdPartyPlatformPage'; //第三方平台设置
|
||||||
static const String openDoorDirectionPage = '/openDoorDirectionPage'; //开门方向设置
|
static const String openDoorDirectionPage = '/openDoorDirectionPage'; //开门方向设置
|
||||||
static const String catEyeWorkModePage = '/catEyeWorkModePage'; //猫眼工作模式
|
static const String catEyeWorkModePage = '/catEyeWorkModePage'; //猫眼工作模式
|
||||||
static const String msgNotificationPage = '/msgNotificationPage'; //消息提醒
|
static const String msgNotificationPage = '/msgNotificationPage'; //消息提醒
|
||||||
@ -528,8 +531,7 @@ abstract class Routers {
|
|||||||
'/imageTransmissionView'; //星图对讲页面(图传)
|
'/imageTransmissionView'; //星图对讲页面(图传)
|
||||||
static const String permissionGuidancePage =
|
static const String permissionGuidancePage =
|
||||||
'/permissionGuidancePage'; // 锁屏权限通知引导页面
|
'/permissionGuidancePage'; // 锁屏权限通知引导页面
|
||||||
static const String lockVoiceSettingPage =
|
static const String lockVoiceSettingPage = '/lockVoiceSetting'; // 锁屏权限通知引导页面
|
||||||
'/lockVoiceSetting'; // 锁屏权限通知引导页面
|
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class AppRouters {
|
abstract class AppRouters {
|
||||||
@ -1218,8 +1220,10 @@ abstract class AppRouters {
|
|||||||
name: Routers.permissionGuidancePage,
|
name: Routers.permissionGuidancePage,
|
||||||
page: () => PermissionGuidancePage()),
|
page: () => PermissionGuidancePage()),
|
||||||
GetPage<dynamic>(
|
GetPage<dynamic>(
|
||||||
name: Routers.lockVoiceSettingPage,
|
name: Routers.lockVoiceSettingPage, page: () => LockVoiceSetting()),
|
||||||
page: () => LockVoiceSetting()),
|
GetPage<dynamic>(
|
||||||
|
name: Routers.thirdPartyPlatformPage,
|
||||||
|
page: () => ThirdPartyPlatformPage()),
|
||||||
// 插件播放页面
|
// 插件播放页面
|
||||||
// GetPage<dynamic>(name: Routers.h264View, page: () => H264WebView()), // webview播放页面
|
// GetPage<dynamic>(name: Routers.h264View, page: () => H264WebView()), // webview播放页面
|
||||||
];
|
];
|
||||||
|
|||||||
@ -5,11 +5,13 @@ class TimbreItem {
|
|||||||
final String timbre;
|
final String timbre;
|
||||||
final String name;
|
final String name;
|
||||||
final String timbrePackUrl;
|
final String timbrePackUrl;
|
||||||
|
final int isFemale;
|
||||||
|
|
||||||
TimbreItem({
|
TimbreItem({
|
||||||
required this.timbre,
|
required this.timbre,
|
||||||
required this.name,
|
required this.name,
|
||||||
required this.timbrePackUrl,
|
required this.timbrePackUrl,
|
||||||
|
required this.isFemale,
|
||||||
});
|
});
|
||||||
|
|
||||||
factory TimbreItem.fromJson(Map<String, dynamic> json) {
|
factory TimbreItem.fromJson(Map<String, dynamic> json) {
|
||||||
@ -17,6 +19,7 @@ class TimbreItem {
|
|||||||
timbre: json['timbre'] ?? '',
|
timbre: json['timbre'] ?? '',
|
||||||
name: json['name'] ?? '',
|
name: json['name'] ?? '',
|
||||||
timbrePackUrl: json['timbrePackUrl'] ?? '',
|
timbrePackUrl: json['timbrePackUrl'] ?? '',
|
||||||
|
isFemale: json['isFemale'] ?? 0,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -25,23 +28,27 @@ class TimbreItem {
|
|||||||
'timbre': timbre,
|
'timbre': timbre,
|
||||||
'name': name,
|
'name': name,
|
||||||
'timbrePackUrl': timbrePackUrl,
|
'timbrePackUrl': timbrePackUrl,
|
||||||
|
'isFemale': isFemale,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'TimbreItem{timbre: $timbre, name: $name, timbrePackUrl: $timbrePackUrl}';
|
return 'TimbreItem{timbre: $timbre, name: $name, timbrePackUrl: '
|
||||||
|
'$timbrePackUrl},isFemale: $isFemale}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 透传项主类
|
// 透传项主类
|
||||||
class PassthroughItem {
|
class PassthroughItem {
|
||||||
final String lang;
|
final String lang;
|
||||||
|
final String langText;
|
||||||
final List<TimbreItem> timbres;
|
final List<TimbreItem> timbres;
|
||||||
|
|
||||||
PassthroughItem({
|
PassthroughItem({
|
||||||
required this.lang,
|
required this.lang,
|
||||||
required this.timbres,
|
required this.timbres,
|
||||||
|
required this.langText,
|
||||||
});
|
});
|
||||||
|
|
||||||
factory PassthroughItem.fromJson(Map<String, dynamic> json) {
|
factory PassthroughItem.fromJson(Map<String, dynamic> json) {
|
||||||
@ -53,6 +60,7 @@ class PassthroughItem {
|
|||||||
: <TimbreItem>[];
|
: <TimbreItem>[];
|
||||||
return PassthroughItem(
|
return PassthroughItem(
|
||||||
lang: json['lang'] ?? '',
|
lang: json['lang'] ?? '',
|
||||||
|
langText: json['langText'] ?? '',
|
||||||
timbres: timbresList,
|
timbres: timbresList,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -60,6 +68,7 @@ class PassthroughItem {
|
|||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
return {
|
return {
|
||||||
'lang': lang,
|
'lang': lang,
|
||||||
|
'langText': langText,
|
||||||
'timbres': timbres.map((e) => e.toJson()).toList(),
|
'timbres': timbres.map((e) => e.toJson()).toList(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@ -686,7 +686,7 @@ class LockSetLogic extends BaseGetXController {
|
|||||||
updataLockSet(getTokenList);
|
updataLockSet(getTokenList);
|
||||||
} else if (connectionState == BluetoothConnectionState.disconnected) {
|
} else if (connectionState == BluetoothConnectionState.disconnected) {
|
||||||
// cancelBlueConnetctToastTimer();
|
// cancelBlueConnetctToastTimer();
|
||||||
// if(state.ifCurrentScreen.value == true){
|
// if (state.ifCurrentScreen.value == true) {
|
||||||
// showBlueConnetctToast();
|
// showBlueConnetctToast();
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
@ -745,12 +745,13 @@ class LockSetLogic extends BaseGetXController {
|
|||||||
// _scanListDiscoveredDeviceSubscription.cancel();
|
// _scanListDiscoveredDeviceSubscription.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 发送获取型号蓝牙命令
|
// 发送获取型号蓝牙命令
|
||||||
sendGetDeviceModelBleMessage() {
|
sendGetDeviceModelBleMessage() {
|
||||||
showEasyLoading();
|
// showEasyLoading();
|
||||||
showBlueConnetctToastTimer(action: () {
|
// showBlueConnetctToastTimer(action: () {
|
||||||
dismissEasyLoading();
|
// dismissEasyLoading();
|
||||||
});
|
// });
|
||||||
BlueManage().blueSendData(BlueManage().connectDeviceName,
|
BlueManage().blueSendData(BlueManage().connectDeviceName,
|
||||||
(BluetoothConnectionState deviceConnectionState) async {
|
(BluetoothConnectionState deviceConnectionState) async {
|
||||||
if (deviceConnectionState == BluetoothConnectionState.connected) {
|
if (deviceConnectionState == BluetoothConnectionState.connected) {
|
||||||
@ -761,13 +762,19 @@ class LockSetLogic extends BaseGetXController {
|
|||||||
);
|
);
|
||||||
} else if (deviceConnectionState ==
|
} else if (deviceConnectionState ==
|
||||||
BluetoothConnectionState.disconnected) {
|
BluetoothConnectionState.disconnected) {
|
||||||
dismissEasyLoading();
|
// dismissEasyLoading();
|
||||||
cancelBlueConnetctToastTimer();
|
// cancelBlueConnetctToastTimer();
|
||||||
showBlueConnetctToast();
|
// showBlueConnetctToast();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_replySubscription.cancel();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
void _handlerDeviceModelReply(GetDeviceModelReply reply) async {
|
void _handlerDeviceModelReply(GetDeviceModelReply reply) async {
|
||||||
final int status = reply.data[2];
|
final int status = reply.data[2];
|
||||||
switch (status) {
|
switch (status) {
|
||||||
@ -783,7 +790,6 @@ class LockSetLogic extends BaseGetXController {
|
|||||||
String rawData = String.fromCharCodes(deviceModelBytes);
|
String rawData = String.fromCharCodes(deviceModelBytes);
|
||||||
int firstNullIndex = rawData.indexOf('\u0000');
|
int firstNullIndex = rawData.indexOf('\u0000');
|
||||||
String deviceModelValue = rawData.substring(0, firstNullIndex);
|
String deviceModelValue = rawData.substring(0, firstNullIndex);
|
||||||
print(deviceModelValue); // 输出: 2403
|
|
||||||
print('获取到 DeviceModel (原始): $deviceModelValue');
|
print('获取到 DeviceModel (原始): $deviceModelValue');
|
||||||
await Storage.setString(deviceModel, deviceModelValue);
|
await Storage.setString(deviceModel, deviceModelValue);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -540,6 +540,19 @@ class _LockSetPageState extends State<LockSetPage>
|
|||||||
'lockSetInfoData': state.lockSetInfoData.value
|
'lockSetInfoData': state.lockSetInfoData.value
|
||||||
});
|
});
|
||||||
})),
|
})),
|
||||||
|
// 锁语音包设置
|
||||||
|
CommonItem(
|
||||||
|
leftTitel: '第三方平台'.tr,
|
||||||
|
rightTitle: '',
|
||||||
|
isHaveLine: true,
|
||||||
|
isHaveDirection: true,
|
||||||
|
action: () {
|
||||||
|
Get.toNamed(Routers.thirdPartyPlatformPage,
|
||||||
|
arguments: <String, LockSetInfoData>{
|
||||||
|
'lockSetInfoData': state.lockSetInfoData.value
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
// 蓝牙广播(关闭则不能使用蓝牙主动开锁)
|
// 蓝牙广播(关闭则不能使用蓝牙主动开锁)
|
||||||
/* 2024-01-12 会议确定去掉“蓝牙广播” by DaisyWu
|
/* 2024-01-12 会议确定去掉“蓝牙广播” by DaisyWu
|
||||||
Obx(() => Visibility(
|
Obx(() => Visibility(
|
||||||
@ -606,7 +619,7 @@ class _LockSetPageState extends State<LockSetPage>
|
|||||||
state.lockFeature.value.appUnlockOnline == 1,
|
state.lockFeature.value.appUnlockOnline == 1,
|
||||||
child: otherItem(
|
child: otherItem(
|
||||||
leftTitle: '开锁时是否需联网'.tr,
|
leftTitle: '开锁时是否需联网'.tr,
|
||||||
isHaveLine: false,
|
isHaveLine: true,
|
||||||
rightWidget: _openLockNeedOnlineSwitch()),
|
rightWidget: _openLockNeedOnlineSwitch()),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@ -27,6 +27,7 @@ import 'package:http/http.dart' as http;
|
|||||||
import 'package:star_lock/tools/commonDataManage.dart';
|
import 'package:star_lock/tools/commonDataManage.dart';
|
||||||
import 'package:star_lock/tools/eventBusEventManage.dart';
|
import 'package:star_lock/tools/eventBusEventManage.dart';
|
||||||
import 'package:star_lock/tools/storage.dart';
|
import 'package:star_lock/tools/storage.dart';
|
||||||
|
import 'package:star_lock/translations/app_dept.dart';
|
||||||
|
|
||||||
class SpeechLanguageSettingsLogic extends BaseGetXController {
|
class SpeechLanguageSettingsLogic extends BaseGetXController {
|
||||||
final SpeechLanguageSettingsState state = SpeechLanguageSettingsState();
|
final SpeechLanguageSettingsState state = SpeechLanguageSettingsState();
|
||||||
@ -34,6 +35,8 @@ class SpeechLanguageSettingsLogic extends BaseGetXController {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void onInit() async {
|
void onInit() async {
|
||||||
|
final findLocaleIndex = _findLocaleIndex();
|
||||||
|
state.selectPassthroughListIndex.value = findLocaleIndex;
|
||||||
super.onInit();
|
super.onInit();
|
||||||
_replySubscription =
|
_replySubscription =
|
||||||
EventBusManager().eventBus!.on<Reply>().listen((Reply reply) async {
|
EventBusManager().eventBus!.on<Reply>().listen((Reply reply) async {
|
||||||
@ -47,28 +50,7 @@ class SpeechLanguageSettingsLogic extends BaseGetXController {
|
|||||||
} else if (reply is VoicePackageConfigureProcessReply) {
|
} else if (reply is VoicePackageConfigureProcessReply) {
|
||||||
_handlerVoicePackageConfigureProcess(reply);
|
_handlerVoicePackageConfigureProcess(reply);
|
||||||
} else if (reply is VoicePackageConfigureConfirmationReply) {
|
} else if (reply is VoicePackageConfigureConfirmationReply) {
|
||||||
final PassthroughItem item =
|
_handlerVoicePackageConfigureConfirmation(reply);
|
||||||
state.languages[state.selectPassthroughListIndex.value];
|
|
||||||
final timbre = item.timbres[state.selectLanguageIndex.value];
|
|
||||||
final LoginEntity entity =
|
|
||||||
await ApiRepository.to.settingCurrentVoiceTimbre(
|
|
||||||
data: {
|
|
||||||
'lang': item.lang,
|
|
||||||
'timbre': timbre.timbre,
|
|
||||||
},
|
|
||||||
lockId: state.lockSetInfoData.value.lockId!,
|
|
||||||
);
|
|
||||||
if (entity.errorCode!.codeIsSuccessful) {
|
|
||||||
showSuccess('设置成功'.tr, something: () {
|
|
||||||
state.lockSetInfoData.value.lockSettingInfo?.currentVoiceTimbre
|
|
||||||
?.lang = item.lang;
|
|
||||||
state.lockSetInfoData.value.lockSettingInfo?.currentVoiceTimbre
|
|
||||||
?.timbre = timbre.timbre;
|
|
||||||
eventBus.fire(
|
|
||||||
PassCurrentLockInformationEvent(state.lockSetInfoData.value));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
dismissEasyLoading();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
state.deviceModel.value = await Storage.getString(deviceModel) ?? '';
|
state.deviceModel.value = await Storage.getString(deviceModel) ?? '';
|
||||||
@ -76,35 +58,37 @@ class SpeechLanguageSettingsLogic extends BaseGetXController {
|
|||||||
if (state.deviceModel.value != null) {
|
if (state.deviceModel.value != null) {
|
||||||
await initList();
|
await initList();
|
||||||
}
|
}
|
||||||
|
|
||||||
// await sendGetDeviceModelBleMessage();
|
// await sendGetDeviceModelBleMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// 获取列表
|
/// 获取列表
|
||||||
|
/// //{ "vendor": "XL", "model": "JL-BLE-01"}
|
||||||
initList() async {
|
initList() async {
|
||||||
showEasyLoading();
|
showEasyLoading();
|
||||||
try {
|
try {
|
||||||
final PassthroughListResponse entity = await ApiRepository.to
|
final vendor = state.lockSetInfoData.value.lockBasicInfo?.vendor;
|
||||||
.getPassthroughList(data: {'deviceType': state.deviceModel.value});
|
final model = state.lockSetInfoData.value.lockBasicInfo?.model;
|
||||||
|
|
||||||
|
final PassthroughListResponse entity =
|
||||||
|
await ApiRepository.to.getPassthroughList(data: {
|
||||||
|
'vendor': vendor!,
|
||||||
|
'model': model!,
|
||||||
|
});
|
||||||
if (entity.errorCode!.codeIsSuccessful) {
|
if (entity.errorCode!.codeIsSuccessful) {
|
||||||
state.languages.value = entity.data!!;
|
state.languages.value = entity.data!!;
|
||||||
final oldTimbre = state
|
final lang = state
|
||||||
.lockSetInfoData.value.lockSettingInfo?.currentVoiceTimbre?.timbre;
|
|
||||||
final oldLang = state
|
|
||||||
.lockSetInfoData.value.lockSettingInfo?.currentVoiceTimbre?.lang;
|
.lockSetInfoData.value.lockSettingInfo?.currentVoiceTimbre?.lang;
|
||||||
|
final timbre = state
|
||||||
for (int index = 0; index < state.languages.value.length; index++) {
|
.lockSetInfoData.value.lockSettingInfo?.currentVoiceTimbre?.timbre;
|
||||||
final element = state.languages.value[index];
|
state.languages.value.forEach((element) {
|
||||||
final timbres = element.timbres;
|
final timbres = element.timbres;
|
||||||
for (int i = 0; i < timbres.length; i++) {
|
timbres.forEach((item) {
|
||||||
final timbre = timbres[i].timbre;
|
if (lang == element.lang && item.timbre == timbre) {
|
||||||
if ((oldLang != null && oldLang == element.lang) &&
|
state.selectSoundTypeIndex.value = item.isFemale;
|
||||||
(oldTimbre != null && oldTimbre == timbre)) {
|
|
||||||
state.selectPassthroughListIndex.value = index;
|
|
||||||
state.selectLanguageIndex.value = i;
|
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
debugPrint('获取语音包出现错误:$e');
|
debugPrint('获取语音包出现错误:$e');
|
||||||
@ -113,26 +97,56 @@ class SpeechLanguageSettingsLogic extends BaseGetXController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void saveSpeechLanguageSettings() async {
|
/// 查找 locales 中 code 等于 lang 的元素下标(不存在返回 -1)
|
||||||
// 如果已经开始发送中则不处理保存点击事件
|
int _findLocaleIndex() {
|
||||||
if (state.progress.value > 0) {
|
// 1. 获取 lang(可能为 null)
|
||||||
return;
|
final lang =
|
||||||
}
|
|
||||||
final oldTimbre =
|
|
||||||
state.lockSetInfoData.value.lockSettingInfo?.currentVoiceTimbre?.timbre;
|
|
||||||
final oldLang =
|
|
||||||
state.lockSetInfoData.value.lockSettingInfo?.currentVoiceTimbre?.lang;
|
state.lockSetInfoData.value.lockSettingInfo?.currentVoiceTimbre?.lang;
|
||||||
|
|
||||||
EasyLoading.showProgress(state.progress.value, status: '正在发送数据');
|
// 2. 如果 lang 为 null,直接返回 -1
|
||||||
final PassthroughItem item =
|
if (lang == null) return -1;
|
||||||
state.languages[state.selectPassthroughListIndex.value];
|
|
||||||
final timbre = item.timbres[state.selectLanguageIndex.value];
|
// 3. 获取 locales 集合(假设非空,若可能为空需额外判空)
|
||||||
debugPrint('选中的语音是:${timbre}');
|
final locales = appDept.deptSupportedLocales;
|
||||||
if ((oldLang != null && oldLang == item.lang) &&
|
|
||||||
(oldTimbre != null && oldTimbre == timbre.timbre)) {
|
// 4. 遍历查找符合条件的下标(使用 indexWhere 高效实现)
|
||||||
showToast('已设置为当前选择的语音包'.tr);
|
return locales.indexWhere((element) {
|
||||||
}
|
// 处理 countryCode 可能为 null 的情况(根据业务需求调整)
|
||||||
await downloadFile(timbre.timbrePackUrl);
|
if (element.countryCode == null) return false;
|
||||||
|
|
||||||
|
// 构造当前 locale 的 code(格式:languageCode_countryCode)
|
||||||
|
final currentCode = '${element.languageCode}_${element.countryCode}';
|
||||||
|
|
||||||
|
// 比较是否等于目标 lang
|
||||||
|
return currentCode == lang;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void saveSpeechLanguageSettings() async {
|
||||||
|
final language =
|
||||||
|
state.appLocalLanguages[state.selectPassthroughListIndex.value];
|
||||||
|
// 从选中的语言中获取languageCode和countryCode
|
||||||
|
final locales = appDept.deptSupportedLocales;
|
||||||
|
locales.forEach((element) {
|
||||||
|
final lanTitle = ExtensionLanguageType.fromLocale(element).lanTitle;
|
||||||
|
if (lanTitle == language) {
|
||||||
|
if (element.countryCode != null) {
|
||||||
|
String code = element.languageCode + '_' + element.countryCode!;
|
||||||
|
|
||||||
|
state.languages.forEach((item) async {
|
||||||
|
if (item.lang == code) {
|
||||||
|
item.timbres.forEach((timbre) async {
|
||||||
|
if (timbre.isFemale == state.selectSoundTypeIndex.value) {
|
||||||
|
state.tempLangStr.value = item.lang;
|
||||||
|
state.tempTimbreStr.value = timbre.timbre;
|
||||||
|
await downloadFile(timbre.timbrePackUrl);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void changeSelectIndex(int index) {
|
void changeSelectIndex(int index) {
|
||||||
@ -363,4 +377,37 @@ class SpeechLanguageSettingsLogic extends BaseGetXController {
|
|||||||
state.data = null;
|
state.data = null;
|
||||||
super.onClose();
|
super.onClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _handlerVoicePackageConfigureConfirmation(
|
||||||
|
VoicePackageConfigureConfirmationReply reply,
|
||||||
|
) async {
|
||||||
|
final int status = reply.data[2];
|
||||||
|
switch (status) {
|
||||||
|
case 0x00:
|
||||||
|
cancelBlueConnetctToastTimer();
|
||||||
|
final LoginEntity entity =
|
||||||
|
await ApiRepository.to.settingCurrentVoiceTimbre(
|
||||||
|
data: {
|
||||||
|
'lang': state.tempLangStr.value,
|
||||||
|
'timbre': state.tempTimbreStr.value,
|
||||||
|
},
|
||||||
|
lockId: state.lockSetInfoData.value.lockId!,
|
||||||
|
);
|
||||||
|
if (entity.errorCode!.codeIsSuccessful) {
|
||||||
|
showSuccess('设置成功'.tr, something: () {
|
||||||
|
state.lockSetInfoData.value.lockSettingInfo?.currentVoiceTimbre
|
||||||
|
?.lang = state.tempLangStr.value;
|
||||||
|
state.lockSetInfoData.value.lockSettingInfo?.currentVoiceTimbre
|
||||||
|
?.timbre = state.tempTimbreStr.value;
|
||||||
|
eventBus.fire(
|
||||||
|
PassCurrentLockInformationEvent(state.lockSetInfoData.value));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
dismissEasyLoading();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
showToast('语音设置失败'.tr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,6 +8,7 @@ import 'package:star_lock/main/lockDetail/lockDetail/passthrough_item.dart';
|
|||||||
import 'package:star_lock/main/lockDetail/lockSet/speechLanguageSettings/speech_language_settings_logic.dart';
|
import 'package:star_lock/main/lockDetail/lockSet/speechLanguageSettings/speech_language_settings_logic.dart';
|
||||||
import 'package:star_lock/main/lockDetail/lockSet/speechLanguageSettings/speech_language_settings_state.dart';
|
import 'package:star_lock/main/lockDetail/lockSet/speechLanguageSettings/speech_language_settings_state.dart';
|
||||||
import 'package:star_lock/tools/EasyRefreshTool.dart';
|
import 'package:star_lock/tools/EasyRefreshTool.dart';
|
||||||
|
import 'package:star_lock/tools/commonItem.dart';
|
||||||
import 'package:star_lock/tools/titleAppBar.dart';
|
import 'package:star_lock/tools/titleAppBar.dart';
|
||||||
|
|
||||||
class SpeechLanguageSettingsPage extends StatefulWidget {
|
class SpeechLanguageSettingsPage extends StatefulWidget {
|
||||||
@ -47,12 +48,7 @@ class _SpeechLanguageSettingsPageState
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
body: EasyRefreshTool(
|
body: _buildBody(),
|
||||||
child: _buildBody(),
|
|
||||||
onRefresh: () {
|
|
||||||
logic.sendGetDeviceModelBleMessage();
|
|
||||||
},
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,30 +57,57 @@ class _SpeechLanguageSettingsPageState
|
|||||||
() => SingleChildScrollView(
|
() => SingleChildScrollView(
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
// Container(
|
Container(
|
||||||
// width: 1.sw,
|
width: 1.sw,
|
||||||
// decoration: BoxDecoration(color: Colors.white),
|
decoration: BoxDecoration(color: Colors.white),
|
||||||
// child: Column(
|
child: ListView.builder(
|
||||||
// children: [
|
itemCount: state.soundTypeList.length,
|
||||||
// RadioListTile(
|
itemBuilder: (BuildContext context, int index) {
|
||||||
// title: Text("男声".tr),
|
// 判断是否是最后一个元素(索引等于 itemCount - 1)
|
||||||
// value: 1,
|
final isLastItem = index == state.soundTypeList.length - 1;
|
||||||
// groupValue: state.selectedValue.value,
|
|
||||||
// onChanged: (value) {
|
// 获取当前平台数据(假设 platFormSet 是 RxList<Platform>)
|
||||||
// state.selectedValue.value = int.parse(value.toString());
|
final platform = state.soundTypeList.value[index];
|
||||||
// },
|
return CommonItem(
|
||||||
// ),
|
leftTitel: state.soundTypeList.value[index],
|
||||||
// RadioListTile(
|
rightTitle: '',
|
||||||
// title: Text("女声".tr),
|
isHaveLine: !isLastItem,
|
||||||
// value: 2,
|
// 最后一个元素不显示分割线(取反)
|
||||||
// groupValue: state.selectedValue.value,
|
isHaveDirection: false,
|
||||||
// onChanged: (value) {
|
isHaveRightWidget: true,
|
||||||
// state.selectedValue.value = int.parse(value.toString());
|
rightWidget: Radio<String>(
|
||||||
// },
|
// Radio 的值:使用平台的唯一标识(如 id)
|
||||||
// )
|
value: platform,
|
||||||
// ],
|
// 当前选中的值:与 selectPlatFormIndex 关联的 id
|
||||||
// ),
|
groupValue: state.soundTypeList
|
||||||
// ),
|
.value[state.selectSoundTypeIndex.value],
|
||||||
|
// 选中颜色(可选,默认主题色)
|
||||||
|
activeColor: AppColors.mainColor,
|
||||||
|
// 点击 Radio 时回调(更新选中索引)
|
||||||
|
onChanged: (value) {
|
||||||
|
if (value != null) {
|
||||||
|
setState(() {
|
||||||
|
// 找到当前选中平台的索引(根据 id 匹配)
|
||||||
|
final newIndex = state.soundTypeList.value
|
||||||
|
.indexWhere((p) => p == value);
|
||||||
|
if (newIndex != -1) {
|
||||||
|
state.selectSoundTypeIndex.value = newIndex;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
action: () {
|
||||||
|
setState(() {
|
||||||
|
state.selectSoundTypeIndex.value = index;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
shrinkWrap: true,
|
||||||
|
physics: const AlwaysScrollableScrollPhysics(),
|
||||||
|
),
|
||||||
|
),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: 8.h,
|
height: 8.h,
|
||||||
),
|
),
|
||||||
@ -98,72 +121,42 @@ class _SpeechLanguageSettingsPageState
|
|||||||
}
|
}
|
||||||
|
|
||||||
List<Widget> _buildList() {
|
List<Widget> _buildList() {
|
||||||
final languages = state.languages;
|
final appLocalLanguages = state.appLocalLanguages;
|
||||||
return List.generate(
|
return List.generate(
|
||||||
languages.length,
|
appLocalLanguages.length,
|
||||||
(index) => _buildItem(languages[index], index),
|
(index) => _buildItem(
|
||||||
);
|
appLocalLanguages[index],
|
||||||
}
|
index,
|
||||||
|
|
||||||
_buildItem(PassthroughItem language, int index) {
|
|
||||||
final timbres = language.timbres;
|
|
||||||
final isSelected = state.selectPassthroughListIndex == index;
|
|
||||||
return ExpansionTile(
|
|
||||||
title: Text(
|
|
||||||
PassthroughLangHelper.getLangText(language.lang),
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 24.sp,
|
|
||||||
fontWeight: isSelected ? FontWeight.bold : null,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
onExpansionChanged: (bool expanded) {},
|
|
||||||
initiallyExpanded: false,
|
|
||||||
backgroundColor: Colors.white,
|
|
||||||
collapsedBackgroundColor: Colors.white,
|
|
||||||
expandedCrossAxisAlignment: CrossAxisAlignment.center,
|
|
||||||
expandedAlignment: Alignment.center,
|
|
||||||
shape: InputBorder.none,
|
|
||||||
maintainState: true,
|
|
||||||
// 去除展开状态下的边框
|
|
||||||
collapsedShape: InputBorder.none,
|
|
||||||
// 去除折叠状态下的边框
|
|
||||||
childrenPadding: EdgeInsets.only(left: 12.w),
|
|
||||||
children: List.generate(
|
|
||||||
timbres.length,
|
|
||||||
(int languageIndex) => ListTile(
|
|
||||||
title: Text(
|
|
||||||
timbres[languageIndex].name,
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 22.sp,
|
|
||||||
fontWeight:
|
|
||||||
state.selectLanguageIndex == languageIndex && isSelected
|
|
||||||
? FontWeight.bold
|
|
||||||
: null,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
trailing: state.selectLanguageIndex == languageIndex && isSelected
|
|
||||||
? Icon(
|
|
||||||
Icons.check_circle,
|
|
||||||
color: AppColors.mainColor,
|
|
||||||
) // 仅当选中时显示图标
|
|
||||||
: null, // 默认不显示
|
|
||||||
onTap: () {
|
|
||||||
// 更新选中的语音包
|
|
||||||
state.selectLanguageIndex.value = languageIndex;
|
|
||||||
// 更新选中的语言
|
|
||||||
state.selectPassthroughListIndex.value = index;
|
|
||||||
}, // 默认图标, // 右侧的图标
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
// TODO: implement dispose
|
|
||||||
super.dispose();
|
super.dispose();
|
||||||
if (EasyLoading.isShow) {
|
if (EasyLoading.isShow) {
|
||||||
EasyLoading.dismiss(animation: true);
|
EasyLoading.dismiss(animation: true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_buildItem(String appLocalLanguages, index) {
|
||||||
|
return CommonItem(
|
||||||
|
leftTitel: appLocalLanguages,
|
||||||
|
rightTitle: '',
|
||||||
|
isHaveLine: true,
|
||||||
|
isHaveDirection: false,
|
||||||
|
isHaveRightWidget: true,
|
||||||
|
rightWidget: state.selectPassthroughListIndex.value == index
|
||||||
|
? Image(
|
||||||
|
image: const AssetImage('images/icon_item_checked.png'),
|
||||||
|
width: 30.w,
|
||||||
|
height: 30.w,
|
||||||
|
fit: BoxFit.contain,
|
||||||
|
)
|
||||||
|
: Container(),
|
||||||
|
action: () {
|
||||||
|
state.selectPassthroughListIndex.value = index;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import 'package:flutter/widgets.dart';
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:star_lock/main/lockDetail/lockDetail/passthrough_item.dart';
|
import 'package:star_lock/main/lockDetail/lockDetail/passthrough_item.dart';
|
||||||
import 'package:star_lock/main/lockDetail/lockSet/lockSet/lockSetInfo_entity.dart';
|
import 'package:star_lock/main/lockDetail/lockSet/lockSet/lockSetInfo_entity.dart';
|
||||||
|
import 'package:star_lock/translations/app_dept.dart';
|
||||||
|
|
||||||
class SpeechLanguageSettingsState {
|
class SpeechLanguageSettingsState {
|
||||||
SpeechLanguageSettingsState() {
|
SpeechLanguageSettingsState() {
|
||||||
@ -11,6 +12,25 @@ class SpeechLanguageSettingsState {
|
|||||||
lockSetInfoData.value = map['lockSetInfoData'];
|
lockSetInfoData.value = map['lockSetInfoData'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<String> get appLocalLanguages {
|
||||||
|
final locales = appDept.deptSupportedLocales;
|
||||||
|
|
||||||
|
final languageCode = locales[1].languageCode;
|
||||||
|
final countryCode = locales[1].countryCode;
|
||||||
|
String localeStr = '';
|
||||||
|
if (countryCode != null) {
|
||||||
|
localeStr = languageCode + '_' + countryCode;
|
||||||
|
appLocalLanguageCodes.add(localeStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
final list = locales
|
||||||
|
.map((e) => ExtensionLanguageType.fromLocale(e).lanTitle)
|
||||||
|
.toList();
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> appLocalLanguageCodes = [];
|
||||||
|
|
||||||
Rx<LockSetInfoData> lockSetInfoData = LockSetInfoData().obs;
|
Rx<LockSetInfoData> lockSetInfoData = LockSetInfoData().obs;
|
||||||
|
|
||||||
// 选中的语音包列表下标
|
// 选中的语音包列表下标
|
||||||
@ -21,8 +41,6 @@ class SpeechLanguageSettingsState {
|
|||||||
|
|
||||||
final RxList<PassthroughItem> languages = <PassthroughItem>[].obs;
|
final RxList<PassthroughItem> languages = <PassthroughItem>[].obs;
|
||||||
|
|
||||||
Map<int, String> languageSpeechDeviceTypeMapping = {0: '2403'};
|
|
||||||
|
|
||||||
RxBool otaUpdateIng = false.obs;
|
RxBool otaUpdateIng = false.obs;
|
||||||
RxDouble otaProgress = 0.00.obs;
|
RxDouble otaProgress = 0.00.obs;
|
||||||
RxString deviceModel = '2403'.obs;
|
RxString deviceModel = '2403'.obs;
|
||||||
@ -40,7 +58,17 @@ class SpeechLanguageSettingsState {
|
|||||||
// 分包发送进度(0.0~1.0)
|
// 分包发送进度(0.0~1.0)
|
||||||
RxDouble progress = 0.0.obs;
|
RxDouble progress = 0.0.obs;
|
||||||
|
|
||||||
RxInt selectedValue = 1.obs;
|
RxInt selectedValue = 1.obs;
|
||||||
|
|
||||||
|
// 响应式字符串集合(自动触发 UI 更新)
|
||||||
|
final RxList<String> soundTypeList = List.of({
|
||||||
|
'男声'.tr,
|
||||||
|
'女声'.tr,
|
||||||
|
}).obs;
|
||||||
|
|
||||||
|
RxInt selectSoundTypeIndex = 0.obs;
|
||||||
|
|
||||||
|
|
||||||
|
RxString tempLangStr=''.obs;
|
||||||
|
RxString tempTimbreStr=''.obs;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,19 @@
|
|||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:star_lock/main/lockDetail/lockSet/thirdPartyPlatform/third_party_platform_state.dart';
|
||||||
|
import 'package:star_lock/tools/baseGetXController.dart';
|
||||||
|
|
||||||
|
class ThirdPartyPlatformLogic extends BaseGetXController {
|
||||||
|
ThirdPartyPlatformState state = ThirdPartyPlatformState();
|
||||||
|
|
||||||
|
void savePlatFormSetting() {
|
||||||
|
// showEasyLoading();
|
||||||
|
showToast('功能待开放'.tr);
|
||||||
|
// dismissEasyLoading();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
dismissEasyLoading();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,97 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/widgets.dart';
|
||||||
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:star_lock/app_settings/app_colors.dart';
|
||||||
|
import 'package:star_lock/main/lockDetail/lockSet/thirdPartyPlatform/third_party_platform_logic.dart';
|
||||||
|
import 'package:star_lock/main/lockDetail/lockSet/thirdPartyPlatform/third_party_platform_state.dart';
|
||||||
|
import 'package:star_lock/tools/commonItem.dart';
|
||||||
|
import 'package:star_lock/tools/titleAppBar.dart';
|
||||||
|
|
||||||
|
class ThirdPartyPlatformPage extends StatefulWidget {
|
||||||
|
const ThirdPartyPlatformPage();
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<ThirdPartyPlatformPage> createState() => _ThirdPartyPlatformPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ThirdPartyPlatformPageState extends State<ThirdPartyPlatformPage> {
|
||||||
|
final ThirdPartyPlatformLogic logic = Get.put(ThirdPartyPlatformLogic());
|
||||||
|
final ThirdPartyPlatformState state =
|
||||||
|
Get.find<ThirdPartyPlatformLogic>().state;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: TitleAppBar(
|
||||||
|
barTitle: '第三方平台设置'.tr,
|
||||||
|
haveBack: true,
|
||||||
|
backgroundColor: AppColors.mainColor,
|
||||||
|
actionsList: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: logic.savePlatFormSetting,
|
||||||
|
child: Text(
|
||||||
|
'保存'.tr,
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.white,
|
||||||
|
fontSize: 24.sp,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
body: _buildBody(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildBody() {
|
||||||
|
return ListView.builder(
|
||||||
|
itemCount: state.platFormSet.length,
|
||||||
|
itemBuilder: (BuildContext context, int index) {
|
||||||
|
// 判断是否是最后一个元素(索引等于 itemCount - 1)
|
||||||
|
final isLastItem = index == state.platFormSet.length - 1;
|
||||||
|
|
||||||
|
// 获取当前平台数据(假设 platFormSet 是 RxList<Platform>)
|
||||||
|
final platform = state.platFormSet.value[index];
|
||||||
|
return CommonItem(
|
||||||
|
leftTitel: state.platFormSet.value[index],
|
||||||
|
rightTitle: '',
|
||||||
|
isHaveLine: !isLastItem,
|
||||||
|
// 最后一个元素不显示分割线(取反)
|
||||||
|
isHaveDirection: false,
|
||||||
|
isHaveRightWidget: true,
|
||||||
|
rightWidget: Radio<String>(
|
||||||
|
// Radio 的值:使用平台的唯一标识(如 id)
|
||||||
|
value: platform,
|
||||||
|
// 当前选中的值:与 selectPlatFormIndex 关联的 id
|
||||||
|
groupValue:
|
||||||
|
state.platFormSet.value[state.selectPlatFormIndex.value],
|
||||||
|
// 选中颜色(可选,默认主题色)
|
||||||
|
activeColor: AppColors.mainColor,
|
||||||
|
// 点击 Radio 时回调(更新选中索引)
|
||||||
|
onChanged: (value) {
|
||||||
|
if (value != null) {
|
||||||
|
setState(() {
|
||||||
|
// 找到当前选中平台的索引(根据 id 匹配)
|
||||||
|
final newIndex =
|
||||||
|
state.platFormSet.value.indexWhere((p) => p == value);
|
||||||
|
if (newIndex != -1) {
|
||||||
|
state.selectPlatFormIndex.value = newIndex;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
action: () {
|
||||||
|
setState(() {
|
||||||
|
state.selectPlatFormIndex.value = index;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
shrinkWrap: true,
|
||||||
|
physics: const AlwaysScrollableScrollPhysics(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,24 @@
|
|||||||
|
import 'dart:ui';
|
||||||
|
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
import 'package:star_lock/main/lockDetail/lockSet/lockSet/lockSetInfo_entity.dart';
|
||||||
|
import 'package:star_lock/translations/app_dept.dart';
|
||||||
|
|
||||||
|
class ThirdPartyPlatformState {
|
||||||
|
ThirdPartyPlatformState() {
|
||||||
|
final map = Get.arguments;
|
||||||
|
lockSetInfoData.value = map['lockSetInfoData'];
|
||||||
|
}
|
||||||
|
|
||||||
|
Rx<LockSetInfoData> lockSetInfoData = LockSetInfoData().obs;
|
||||||
|
|
||||||
|
// 响应式字符串集合(自动触发 UI 更新)
|
||||||
|
final RxList<String> platFormSet = List.of({
|
||||||
|
'锁通通'.tr,
|
||||||
|
'涂鸦智能'.tr,
|
||||||
|
}).obs;
|
||||||
|
|
||||||
|
RxInt selectPlatFormIndex = 0.obs;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@ -25,6 +25,7 @@ import 'package:star_lock/tools/eventBusEventManage.dart';
|
|||||||
import 'package:star_lock/tools/showTipView.dart';
|
import 'package:star_lock/tools/showTipView.dart';
|
||||||
import 'package:star_lock/tools/storage.dart';
|
import 'package:star_lock/tools/storage.dart';
|
||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
|
import 'package:star_lock/translations/app_dept.dart';
|
||||||
|
|
||||||
class LockVoiceSettingLogic extends BaseGetXController {
|
class LockVoiceSettingLogic extends BaseGetXController {
|
||||||
LockVoiceSettingState state = LockVoiceSettingState();
|
LockVoiceSettingState state = LockVoiceSettingState();
|
||||||
@ -122,25 +123,30 @@ class LockVoiceSettingLogic extends BaseGetXController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void saveSpeechLanguageSettings() async {
|
void saveSpeechLanguageSettings() async {
|
||||||
// 如果已经开始发送中则不处理保存点击事件
|
final language =
|
||||||
if (state.progress.value > 0) {
|
state.appLocalLanguages[state.selectPassthroughListIndex.value];
|
||||||
return;
|
// 从选中的语言中获取languageCode和countryCode
|
||||||
}
|
final locales = appDept.deptSupportedLocales;
|
||||||
final oldTimbre =
|
locales.forEach((element) {
|
||||||
state.lockSetInfoData.value.lockSettingInfo?.currentVoiceTimbre?.timbre;
|
final lanTitle = ExtensionLanguageType.fromLocale(element).lanTitle;
|
||||||
final oldLang =
|
if (lanTitle == language) {
|
||||||
state.lockSetInfoData.value.lockSettingInfo?.currentVoiceTimbre?.lang;
|
if (element.countryCode != null) {
|
||||||
|
String code = element.languageCode + '_' + element.countryCode!;
|
||||||
|
|
||||||
EasyLoading.showProgress(state.progress.value, status: '正在发送数据');
|
state.languages.forEach((item) async {
|
||||||
final PassthroughItem item =
|
if (item.lang == code) {
|
||||||
state.languages[state.selectPassthroughListIndex.value];
|
item.timbres.forEach((timbre) async {
|
||||||
final timbre = item.timbres[state.selectLanguageIndex.value];
|
if (timbre.isFemale == state.selectSoundTypeIndex.value) {
|
||||||
debugPrint('选中的语音是:${timbre}');
|
state.tempLangStr.value = item.lang;
|
||||||
if ((oldLang != null && oldLang == item.lang) &&
|
state.tempTimbreStr.value = timbre.timbre;
|
||||||
(oldTimbre != null && oldTimbre == timbre.timbre)) {
|
await downloadFile(timbre.timbrePackUrl);
|
||||||
showToast('已设置为当前选择的语音包'.tr);
|
}
|
||||||
}
|
});
|
||||||
await downloadFile(timbre.timbrePackUrl);
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
//下载语音包
|
//下载语音包
|
||||||
@ -263,27 +269,28 @@ class LockVoiceSettingLogic extends BaseGetXController {
|
|||||||
initList() async {
|
initList() async {
|
||||||
showEasyLoading();
|
showEasyLoading();
|
||||||
try {
|
try {
|
||||||
final PassthroughListResponse entity = await ApiRepository.to
|
final vendor = state.lockSetInfoData.value.lockBasicInfo?.vendor;
|
||||||
.getPassthroughList(data: {'deviceType': state.deviceModel.value});
|
final model = state.lockSetInfoData.value.lockBasicInfo?.model;
|
||||||
|
|
||||||
|
final PassthroughListResponse entity =
|
||||||
|
await ApiRepository.to.getPassthroughList(data: {
|
||||||
|
'vendor': vendor!,
|
||||||
|
'model': model!,
|
||||||
|
});
|
||||||
if (entity.errorCode!.codeIsSuccessful) {
|
if (entity.errorCode!.codeIsSuccessful) {
|
||||||
state.languages.value = entity.data!!;
|
state.languages.value = entity.data!!;
|
||||||
final oldTimbre = state
|
final lang = state
|
||||||
.lockSetInfoData.value.lockSettingInfo?.currentVoiceTimbre?.timbre;
|
|
||||||
final oldLang = state
|
|
||||||
.lockSetInfoData.value.lockSettingInfo?.currentVoiceTimbre?.lang;
|
.lockSetInfoData.value.lockSettingInfo?.currentVoiceTimbre?.lang;
|
||||||
|
final timbre = state
|
||||||
for (int index = 0; index < state.languages.value.length; index++) {
|
.lockSetInfoData.value.lockSettingInfo?.currentVoiceTimbre?.timbre;
|
||||||
final element = state.languages.value[index];
|
state.languages.value.forEach((element) {
|
||||||
final timbres = element.timbres;
|
final timbres = element.timbres;
|
||||||
for (int i = 0; i < timbres.length; i++) {
|
timbres.forEach((item) {
|
||||||
final timbre = timbres[i].timbre;
|
if (lang == element.lang && item.timbre == timbre) {
|
||||||
if ((oldLang != null && oldLang == element.lang) &&
|
state.selectSoundTypeIndex.value = item.isFemale;
|
||||||
(oldTimbre != null && oldTimbre == timbre)) {
|
|
||||||
state.selectPassthroughListIndex.value = index;
|
|
||||||
state.selectLanguageIndex.value = i;
|
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
debugPrint('获取语音包出现错误:$e');
|
debugPrint('获取语音包出现错误:$e');
|
||||||
|
|||||||
@ -10,6 +10,7 @@ import 'package:star_lock/main/lockDetail/lockDetail/passthrough_item.dart';
|
|||||||
import 'package:star_lock/mine/addLock/lock_voice_setting/lock_voice_setting_logic.dart';
|
import 'package:star_lock/mine/addLock/lock_voice_setting/lock_voice_setting_logic.dart';
|
||||||
import 'package:star_lock/mine/addLock/lock_voice_setting/lock_voice_setting_state.dart';
|
import 'package:star_lock/mine/addLock/lock_voice_setting/lock_voice_setting_state.dart';
|
||||||
import 'package:star_lock/tools/EasyRefreshTool.dart';
|
import 'package:star_lock/tools/EasyRefreshTool.dart';
|
||||||
|
import 'package:star_lock/tools/commonItem.dart';
|
||||||
import 'package:star_lock/tools/titleAppBar.dart';
|
import 'package:star_lock/tools/titleAppBar.dart';
|
||||||
|
|
||||||
class LockVoiceSetting extends StatefulWidget {
|
class LockVoiceSetting extends StatefulWidget {
|
||||||
@ -25,22 +26,31 @@ class _LockVoiceSettingState extends State<LockVoiceSetting> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return EasyRefreshTool(
|
return Scaffold(
|
||||||
onRefresh: () {
|
backgroundColor: AppColors.mainBackgroundColor,
|
||||||
logic.sendGetDeviceModelBleMessage();
|
appBar: TitleAppBar(
|
||||||
},
|
barTitle: '锁语音包设置'.tr,
|
||||||
child: Scaffold(
|
haveBack: false,
|
||||||
backgroundColor: AppColors.mainBackgroundColor,
|
haveOtherLeftWidget: true,
|
||||||
appBar: TitleAppBar(
|
leftWidget: TextButton(
|
||||||
barTitle: '锁语音包设置'.tr,
|
onPressed: () {
|
||||||
haveBack: false,
|
Get.offAllNamed(Routers.starLockMain);
|
||||||
haveOtherLeftWidget: true,
|
},
|
||||||
leftWidget: TextButton(
|
child: Text(
|
||||||
onPressed: () {
|
'跳过'.tr,
|
||||||
Get.offAllNamed(Routers.starLockMain);
|
style: TextStyle(
|
||||||
},
|
color: Colors.white,
|
||||||
|
fontSize: 24.sp,
|
||||||
|
fontWeight: FontWeight.w500,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
backgroundColor: AppColors.mainColor,
|
||||||
|
actionsList: [
|
||||||
|
TextButton(
|
||||||
|
onPressed: logic.saveSpeechLanguageSettings,
|
||||||
child: Text(
|
child: Text(
|
||||||
'跳过'.tr,
|
'保存'.tr,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
fontSize: 24.sp,
|
fontSize: 24.sp,
|
||||||
@ -48,23 +58,9 @@ class _LockVoiceSettingState extends State<LockVoiceSetting> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
backgroundColor: AppColors.mainColor,
|
],
|
||||||
actionsList: [
|
|
||||||
TextButton(
|
|
||||||
onPressed: logic.saveSpeechLanguageSettings,
|
|
||||||
child: Text(
|
|
||||||
'保存'.tr,
|
|
||||||
style: TextStyle(
|
|
||||||
color: Colors.white,
|
|
||||||
fontSize: 24.sp,
|
|
||||||
fontWeight: FontWeight.w500,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
body: _buildBody(),
|
|
||||||
),
|
),
|
||||||
|
body: _buildBody(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,70 +68,99 @@ class _LockVoiceSettingState extends State<LockVoiceSetting> {
|
|||||||
return Obx(
|
return Obx(
|
||||||
() => SingleChildScrollView(
|
() => SingleChildScrollView(
|
||||||
child: Column(
|
child: Column(
|
||||||
children: _buildList(),
|
children: [
|
||||||
|
Container(
|
||||||
|
width: 1.sw,
|
||||||
|
decoration: BoxDecoration(color: Colors.white),
|
||||||
|
child: ListView.builder(
|
||||||
|
itemCount: state.soundTypeList.length,
|
||||||
|
itemBuilder: (BuildContext context, int index) {
|
||||||
|
// 判断是否是最后一个元素(索引等于 itemCount - 1)
|
||||||
|
final isLastItem = index == state.soundTypeList.length - 1;
|
||||||
|
|
||||||
|
// 获取当前平台数据(假设 platFormSet 是 RxList<Platform>)
|
||||||
|
final platform = state.soundTypeList.value[index];
|
||||||
|
return CommonItem(
|
||||||
|
leftTitel: state.soundTypeList.value[index],
|
||||||
|
rightTitle: '',
|
||||||
|
isHaveLine: !isLastItem,
|
||||||
|
// 最后一个元素不显示分割线(取反)
|
||||||
|
isHaveDirection: false,
|
||||||
|
isHaveRightWidget: true,
|
||||||
|
rightWidget: Radio<String>(
|
||||||
|
// Radio 的值:使用平台的唯一标识(如 id)
|
||||||
|
value: platform,
|
||||||
|
// 当前选中的值:与 selectPlatFormIndex 关联的 id
|
||||||
|
groupValue: state.soundTypeList
|
||||||
|
.value[state.selectSoundTypeIndex.value],
|
||||||
|
// 选中颜色(可选,默认主题色)
|
||||||
|
activeColor: AppColors.mainColor,
|
||||||
|
// 点击 Radio 时回调(更新选中索引)
|
||||||
|
onChanged: (value) {
|
||||||
|
if (value != null) {
|
||||||
|
setState(() {
|
||||||
|
// 找到当前选中平台的索引(根据 id 匹配)
|
||||||
|
final newIndex = state.soundTypeList.value
|
||||||
|
.indexWhere((p) => p == value);
|
||||||
|
if (newIndex != -1) {
|
||||||
|
state.selectSoundTypeIndex.value = newIndex;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
),
|
||||||
|
action: () {
|
||||||
|
setState(() {
|
||||||
|
state.selectSoundTypeIndex.value = index;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
shrinkWrap: true,
|
||||||
|
physics: const AlwaysScrollableScrollPhysics(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 8.h,
|
||||||
|
),
|
||||||
|
Column(
|
||||||
|
children: _buildList(),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Widget> _buildList() {
|
List<Widget> _buildList() {
|
||||||
final languages = state.languages;
|
final appLocalLanguages = state.appLocalLanguages;
|
||||||
return List.generate(
|
return List.generate(
|
||||||
languages.length,
|
appLocalLanguages.length,
|
||||||
(index) => _buildItem(languages[index], index),
|
(index) => _buildItem(
|
||||||
|
appLocalLanguages[index],
|
||||||
|
index,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
_buildItem(PassthroughItem language, int index) {
|
_buildItem(String appLocalLanguages, index) {
|
||||||
final timbres = language.timbres;
|
return CommonItem(
|
||||||
final isSelected = state.selectPassthroughListIndex == index;
|
leftTitel: appLocalLanguages,
|
||||||
return ExpansionTile(
|
rightTitle: '',
|
||||||
title: Text(
|
isHaveLine: true,
|
||||||
PassthroughLangHelper.getLangText(language.lang),
|
isHaveDirection: false,
|
||||||
style: TextStyle(
|
isHaveRightWidget: true,
|
||||||
fontSize: 24.sp,
|
rightWidget: state.selectPassthroughListIndex.value == index
|
||||||
fontWeight: isSelected ? FontWeight.bold : null,
|
? Image(
|
||||||
),
|
image: const AssetImage('images/icon_item_checked.png'),
|
||||||
),
|
width: 30.w,
|
||||||
onExpansionChanged: (bool expanded) {},
|
height: 30.w,
|
||||||
initiallyExpanded: false,
|
fit: BoxFit.contain,
|
||||||
backgroundColor: Colors.white,
|
)
|
||||||
collapsedBackgroundColor: Colors.white,
|
: Container(),
|
||||||
expandedCrossAxisAlignment: CrossAxisAlignment.center,
|
action: () {
|
||||||
expandedAlignment: Alignment.center,
|
state.selectPassthroughListIndex.value = index;
|
||||||
shape: InputBorder.none,
|
},
|
||||||
maintainState: true,
|
|
||||||
// 去除展开状态下的边框
|
|
||||||
collapsedShape: InputBorder.none,
|
|
||||||
// 去除折叠状态下的边框
|
|
||||||
childrenPadding: EdgeInsets.only(left: 12.w),
|
|
||||||
children: List.generate(
|
|
||||||
timbres.length,
|
|
||||||
(int languageIndex) => ListTile(
|
|
||||||
title: Text(
|
|
||||||
timbres[languageIndex].name,
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 22.sp,
|
|
||||||
fontWeight:
|
|
||||||
state.selectLanguageIndex == languageIndex && isSelected
|
|
||||||
? FontWeight.bold
|
|
||||||
: null,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
trailing: state.selectLanguageIndex == languageIndex && isSelected
|
|
||||||
? Icon(
|
|
||||||
Icons.check_circle,
|
|
||||||
color: AppColors.mainColor,
|
|
||||||
) // 仅当选中时显示图标
|
|
||||||
: null, // 默认不显示
|
|
||||||
onTap: () {
|
|
||||||
// 更新选中的语音包
|
|
||||||
state.selectLanguageIndex.value = languageIndex;
|
|
||||||
// 更新选中的语言
|
|
||||||
state.selectPassthroughListIndex.value = index;
|
|
||||||
}, // 默认图标, // 右侧的图标
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import 'dart:typed_data';
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:star_lock/main/lockDetail/lockDetail/passthrough_item.dart';
|
import 'package:star_lock/main/lockDetail/lockDetail/passthrough_item.dart';
|
||||||
import 'package:star_lock/main/lockDetail/lockSet/lockSet/lockSetInfo_entity.dart';
|
import 'package:star_lock/main/lockDetail/lockSet/lockSet/lockSetInfo_entity.dart';
|
||||||
|
import 'package:star_lock/translations/app_dept.dart';
|
||||||
|
|
||||||
class LockVoiceSettingState {
|
class LockVoiceSettingState {
|
||||||
LockVoiceSettingState() {
|
LockVoiceSettingState() {
|
||||||
@ -17,6 +18,24 @@ class LockVoiceSettingState {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
List<String> get appLocalLanguages {
|
||||||
|
final locales = appDept.deptSupportedLocales;
|
||||||
|
|
||||||
|
final languageCode = locales[1].languageCode;
|
||||||
|
final countryCode = locales[1].countryCode;
|
||||||
|
String localeStr = '';
|
||||||
|
if (countryCode != null) {
|
||||||
|
localeStr = languageCode + '_' + countryCode;
|
||||||
|
appLocalLanguageCodes.add(localeStr);
|
||||||
|
}
|
||||||
|
|
||||||
|
final list = locales
|
||||||
|
.map((e) => ExtensionLanguageType.fromLocale(e).lanTitle)
|
||||||
|
.toList();
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> appLocalLanguageCodes = [];
|
||||||
// 选中的语音包列表下标
|
// 选中的语音包列表下标
|
||||||
RxInt selectPassthroughListIndex = 0.obs;
|
RxInt selectPassthroughListIndex = 0.obs;
|
||||||
|
|
||||||
@ -43,5 +62,13 @@ class LockVoiceSettingState {
|
|||||||
|
|
||||||
// 分包发送进度(0.0~1.0)
|
// 分包发送进度(0.0~1.0)
|
||||||
RxDouble progress = 0.0.obs;
|
RxDouble progress = 0.0.obs;
|
||||||
|
// 响应式字符串集合(自动触发 UI 更新)
|
||||||
|
final RxList<String> soundTypeList = List.of({
|
||||||
|
'男声'.tr,
|
||||||
|
'女声'.tr,
|
||||||
|
}).obs;
|
||||||
|
|
||||||
|
RxInt selectSoundTypeIndex = 0.obs;
|
||||||
|
RxString tempLangStr=''.obs;
|
||||||
|
RxString tempTimbreStr=''.obs;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user