import 'package:dating_touchme_app/extension/ex_widget.dart'; import 'package:dating_touchme_app/generated/assets.dart'; import 'package:dating_touchme_app/model/mine/app_version.dart'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:get/get.dart'; import 'package:ota_update/ota_update.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:tdesign_flutter/tdesign_flutter.dart'; class UpdateDialog extends StatefulWidget { final AppVersion version; const UpdateDialog({super.key, required this.version}); @override State createState() => _UpdateDialogState(); } class _UpdateDialogState extends State { bool updating = false; TDLabelWidget buttonLabel = const TDTextLabel('0%'); double progressValue = 0.0; @override Widget build(BuildContext context) { return PopScope( canPop: !widget.version.isForcingUpdate!, onPopInvokedWithResult: (bool didPop, Object? result) async { if (didPop) { Get.back(); } }, child: Center( child: Container( color: Colors.transparent, width: 299.w, padding: EdgeInsets.only(top: 56.w), child: Stack( clipBehavior: Clip.none, children: [ Container( width: 299.w, padding: EdgeInsets.only( top: 147.w, left: 30.w, right: 30.w, bottom: 25.w ), decoration: BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(18.w)), color: Colors.white ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ Text( widget.version.title!, style: TextStyle( fontSize: 16.w, fontWeight: FontWeight.w500 ), ), SizedBox(height: 14.w,), Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox( width: 204.w, child: Text( widget.version.description!, style: TextStyle( fontSize: 12.w, ), ), ) ], ), SizedBox(height: 32.w,), updating ? TDProgress( type: TDProgressType.button, strokeWidth: 40.w, value: progressValue, onTap: manualApkInstaller, label: buttonLabel, ) : !widget.version.isForcingUpdate! ? Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Container( width: 113.w, height: 40.w, decoration: BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(9.w)), color: const Color.fromRGBO(245, 245, 245, 1) ), child: Center( child: Text( "暂不更新", style: TextStyle( fontSize: 15.w, color: const Color.fromRGBO(144, 144, 144, 1) ), ), ), ).onTap((){ Navigator.of(context).pop(); }), Container( width: 113.w, height: 40.w, decoration: BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(9.w)), color: const Color.fromRGBO(245, 245, 245, 1), gradient: const LinearGradient( begin: Alignment.centerLeft, end: Alignment.centerRight, // 对应 CSS 90deg colors: [ Color.fromRGBO(131, 89, 255, 1), // rgba(131, 89, 255, 1) Color.fromRGBO(61, 138, 224, 1), // rgba(61, 138, 224, 1) ], ), ), child: Center( child: Text( "立即升级", style: TextStyle( fontSize: 15.w, fontWeight: FontWeight.w500, color: Colors.white ), ), ), ).onTap((){ downloadAndInstall(widget.version); }), ], ) : Container( width: 240.w, height: 40.w, decoration: BoxDecoration( borderRadius: BorderRadius.all(Radius.circular(9.w)), color: const Color.fromRGBO(245, 245, 245, 1), gradient: const LinearGradient( begin: Alignment.centerLeft, end: Alignment.centerRight, // 对应 CSS 90deg colors: [ Color.fromRGBO(131, 89, 255, 1), // rgba(131, 89, 255, 1) Color.fromRGBO(61, 138, 224, 1), // rgba(61, 138, 224, 1) ], ), ), child: Center( child: Text( "立即升级", style: TextStyle( fontSize: 15.w, fontWeight: FontWeight.w500, color: Colors.white ), ), ), ).onTap((){ downloadAndInstall(widget.version); }) ], ), ), Positioned( left: 0, top: -56.w, child: Image.asset( Assets.imagesUpdataBg, width: 299.w, ), ), Positioned( left: 11.w, top: -14.w, child: Image.asset( Assets.imagesUpdataIcon, width: 36.w, ), ), Positioned( left: 43.w, top: 29.w, child: Image.asset( Assets.imagesUpdataFont, width: 76.w, ), ) ], ), ) ), ); } downloadAndInstall(AppVersion version) async { // 请求权限 final status = await Permission.storage.status; if (!status.isGranted) { final requestStatus = await Permission.storage.request(); if (!requestStatus.isGranted) { throw Exception('需要存储权限才能下载更新'); } } if (mounted) { setState(() { progressValue = 0.0; updating = true; }); } Get.log('url:${version.url!}'); try { OtaUpdate().execute(version.url!, destinationFilename: '趣恋恋_${version.version}.apk').listen( (OtaEvent event) { if(event.status == OtaStatus.DOWNLOADING){ setState(() { progressValue = int.parse(event.value!) / 100; buttonLabel = TDTextLabel('${(progressValue * 100).toInt()}%'); }); } else if(event.status == OtaStatus.INSTALLING){ setState(() { buttonLabel = const TDTextLabel('开始安装'); }); } }, onError: (error){ if (mounted) { setState(() { progressValue = 0.0; buttonLabel = const TDTextLabel('开始'); updating = false; }); } }, onDone: (){ if(progressValue == 1){ setState(() { buttonLabel = const TDTextLabel('重新安装'); }); } } ); } catch (e) { print('Failed to make OTA update. Details: $e'); } } manualApkInstaller(){ if(progressValue == 1){ downloadAndInstall(widget.version); } } }