import 'package:flutter/material.dart'; import 'package:get/get.dart'; import '../controllers/ota_upgrade_controller.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; class OtaUpgradeView extends GetView { const OtaUpgradeView({Key? key}) : super(key: key); @override Widget build(BuildContext context) { final isDarkMode = Theme.of(context).brightness == Brightness.dark; return WillPopScope( onWillPop: () async { if (controller.isUpgrade.value) { // 显示确认弹窗 await Get.dialog( AlertDialog( title: Text('提示'), content: Text('当前正在升级,退出将中断升级进程,确定要退出吗?'), actions: [ TextButton( onPressed: () => Get.back(), // 关闭弹窗 child: Text('取消'), ), TextButton( onPressed: () { controller.stopUpgrading(); Get.back(); // 关闭弹窗 Get.back(); // 返回上一页 }, child: Text('确定'), ), ], ), ); return false; // 阻止默认返回 } return true; // 允许返回 }, child: Scaffold( backgroundColor: isDarkMode ? Colors.black : Colors.grey[100], 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: () { if (controller.isUpgrade.value) { // 显示确认弹窗 Get.dialog( AlertDialog( title: Text('提示'), content: Text('当前正在升级,退出将中断升级进程,确定要退出吗?'), actions: [ TextButton( onPressed: () => Get.back(), // 关闭弹窗 child: Text('取消'), ), TextButton( onPressed: () { controller.stopUpgrading(); Get.back(); // 关闭弹窗 Get.back(); // 返回上一页 }, child: Text('确定'), ), ], ), ); } else { Get.back(); // 正常返回 } }, ), title: Text( '固件升级'.tr, style: TextStyle( fontSize: 20.sp, color: isDarkMode ? Colors.white : Colors.black, ), ), ), body: SingleChildScrollView( child: Padding( padding: EdgeInsets.all(20), child: Column( mainAxisSize: MainAxisSize.min, children: [ // 设备信息卡片 Card( elevation: 2, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(16), ), color: isDarkMode ? Colors.grey[900] : Colors.white, child: Padding( padding: EdgeInsets.all(20), child: Column( children: [ _buildDeviceIcon(isDarkMode), SizedBox(height: 20), _buildVersionInfo(isDarkMode), ], ), ), ), SizedBox(height: 20), // 更新说明 _buildUpdateNotes(isDarkMode), SizedBox(height: 20), // 状态显示区域 Obx(() { if (controller.isFetchingDeviceInfo.value) { return _buildLoadingIndicator(isDarkMode); } if (controller.errorMessage.value.isNotEmpty) { return _buildErrorInfo(isDarkMode); } return _buildUpdateButton(isDarkMode); }), ], ), ), ), ), ); } // 设备图标 Widget _buildDeviceIcon(bool isDarkMode) => Image.asset( isDarkMode ? 'assets/images/headphone_dark.png' : 'assets/images/headphone_light.png', height: 180.h, fit: BoxFit.contain, ); Widget _buildVersionInfo(bool isDarkMode) => Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( crossAxisAlignment: CrossAxisAlignment.center, // 改为center对齐 children: [ Text('当前固件版本:'.tr, style: TextStyle( fontSize: 18, color: isDarkMode ? Colors.grey[300] : Colors.black)), SizedBox(width: 8), // 改为width Obx(() => Text('V ${controller.currentVersion}', style: TextStyle( fontSize: 24, fontWeight: FontWeight.normal, color: isDarkMode ? Colors.blue[300] : Colors.blue))), ], ), SizedBox(height: 8), // 改为height Row( crossAxisAlignment: CrossAxisAlignment.center, // 改为center对齐 children: [ Text('最新固件版本:'.tr, style: TextStyle( fontSize: 18, color: isDarkMode ? Colors.grey[300] : Colors.black)), SizedBox(width: 8), // 改为width Obx(() => Text('V ${controller.latestVersion}', style: TextStyle( fontSize: 24, fontWeight: FontWeight.normal, color: isDarkMode ? Colors.blue[300] : Colors.blue))), ], ), ], ); // 添加固件更新说明 Widget _buildUpdateNotes(bool isDarkMode) => Obx(() => controller.isUpdateAvailable.value ? Card( elevation: 2, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(16), ), color: isDarkMode ? Colors.grey[900] : Colors.white, child: Padding( padding: EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Icon( Icons.new_releases, color: isDarkMode ? Colors.amber[300] : Colors.amber, size: 20, ), SizedBox(width: 8), Text( '更新内容'.tr, style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, color: isDarkMode ? Colors.white : Colors.black, ), ), ], ), Divider(), SizedBox(height: 8), // 这里可以从controller中获取更新说明,如果有的话 Text( '1. 优化音质表现\n2. 提升连接稳定性\n3. 修复已知问题'.tr, style: TextStyle( fontSize: 14, color: isDarkMode ? Colors.grey[300] : Colors.grey[800], ), ), ], ), ), ) : SizedBox.shrink()); Widget _buildLoadingIndicator(bool isDarkMode) => Column( children: [ CircularProgressIndicator( valueColor: AlwaysStoppedAnimation( isDarkMode ? Colors.blue[300] : Colors.blue), ), SizedBox(height: 20), Text('正在获取设备信息...', style: TextStyle(color: isDarkMode ? Colors.grey[300] : Colors.grey)) ], ); Widget _buildErrorInfo(bool isDarkMode) => Container( padding: EdgeInsets.all(16), decoration: BoxDecoration( color: isDarkMode ? Colors.red[900]!.withOpacity(0.2) : Colors.red[50], borderRadius: BorderRadius.circular(12), border: Border.all( color: isDarkMode ? Colors.red[700]! : Colors.red[200]!, width: 1, ), ), child: Column( children: [ Icon(Icons.error_outline, color: Colors.red, size: 40), SizedBox(height: 10), Text(controller.errorMessage.value, textAlign: TextAlign.center, style: TextStyle( color: isDarkMode ? Colors.red[300] : Colors.red, fontSize: 16)), SizedBox(height: 20), ElevatedButton.icon( icon: Icon(Icons.refresh), label: Text('重试连接'.tr), style: ElevatedButton.styleFrom( backgroundColor: isDarkMode ? Colors.blue[700] : Colors.blue, foregroundColor: Colors.white, padding: EdgeInsets.symmetric(horizontal: 20, vertical: 10), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(16.r), ), ), onPressed: controller.retryConnection, ) ], ), ); Widget _buildUpdateButton(bool isDarkMode) { return controller.isUpgrade.value ? _buildProgressIndicator(isDarkMode) : Container( width: double.infinity, padding: EdgeInsets.symmetric(vertical: 10), child: Column( children: [ ElevatedButton.icon( icon: Icon( controller.isUpdateAvailable.value ? Icons.system_update : Icons.check_circle, ), label: Text( controller.isUpdateAvailable.value ? '立即更新' : '已是最新版本', style: TextStyle(fontSize: 16), ), style: ElevatedButton.styleFrom( backgroundColor: controller.isUpdateAvailable.value ? (isDarkMode ? Colors.blue[700] : Colors.blue) : (isDarkMode ? Colors.grey[800] : Colors.grey), foregroundColor: Colors.white, padding: EdgeInsets.symmetric(horizontal: 40, vertical: 15), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(30), ), minimumSize: Size(240, 50), ), onPressed: controller.isUpdateAvailable.value ? controller.startUpdate : null, ), if (controller.isUpdateAvailable.value) ...[ SizedBox(height: 8), Text( '取出双耳机,并保证电量均为30%以上的状态'.tr, style: TextStyle( fontSize: 14, color: isDarkMode ? Colors.grey[400] : Colors.grey[600], ), ), ], ], ), ); } Widget _buildProgressIndicator(bool isDarkMode) { return Obx(() { final progress = controller.progress.value; final type = controller.type.value; // // 处理升级失败状态:弹出 snackbar 并显示错误提示 // if (type == OtaUpgradeController.UPGRADE_FAILED || // type == OtaUpgradeController.CONNECTION_DISCONNECTION) { // // 使用延迟确保在 build 完成后执行 // Future.delayed(Duration.zero, () { // Get.snackbar('升级失败', '重新连接设备后重试'); // }); // return Container( // width: double.infinity, // padding: const EdgeInsets.symmetric(vertical: 10), // child: Text( // '升级失败,请重新连接设备', // style: TextStyle( // fontSize: 18, // fontWeight: FontWeight.bold, // color: Colors.red[700], // ), // ), // ); // } // 正常升级状态 return Container( width: double.infinity, padding: const EdgeInsets.symmetric(vertical: 10), child: Column( children: [ Text( controller.getStatusMessage(type), style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold, color: isDarkMode ? Colors.blue[300] : Colors.blue[700], ), ), const SizedBox(height: 16), LinearProgressIndicator( value: progress / 100.0, // 转换为 0.0-1.0 backgroundColor: isDarkMode ? Colors.grey[800] : Colors.grey[200], valueColor: AlwaysStoppedAnimation( isDarkMode ? Colors.blue[300]! : Colors.blue, ), ), const SizedBox(height: 8), Text( '${progress.toStringAsFixed(1)}%', style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, color: isDarkMode ? Colors.blue[300] : Colors.blue[700], ), ), ], ), ); }); } }