// ignore_for_file: depend_on_referenced_packages import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:get/get.dart'; import 'package:hgdj/assets_tool/app_colors.dart'; import 'package:hgdj/hj_utils/install_util.dart'; import 'package:hgdj/hj_utils/screen.dart'; import 'package:hgdj/tools_base/toast.dart'; import 'package:hgdj/tools_base/widget/common_dialog.dart'; import 'package:path/path.dart' as path; import 'package:path_provider/path_provider.dart'; import '../../hj_model/splash/domain_source_model.dart'; import '../../hj_page/mine/identity/mine_identity_page.dart'; import '../../routers/jump_router.dart'; import '../../tools_base/net/load_apk/dio_cli.dart'; import '../../tools_base/net/load_apk/dio_slice_downloader.dart'; import '../../track_event_manager/device_service.dart'; //升级版本对话框 class UpdateDialog extends StatefulWidget { static Future show(CheckVersionInfo phoneBean) async { return await Get.dialog( UpdateDialog(updateInfo: phoneBean), barrierDismissible: false, ); } final CheckVersionInfo updateInfo; const UpdateDialog({super.key, required this.updateInfo}); @override State createState() => _UpdateDialog(); } class _UpdateDialog extends State { bool isDownloading = false; // 下载中:既防重入,也决定进度条露不露 var progress = .0; String apkPath = ""; /// 点「立即升级」:iOS 跳商店,Android 下载 apk,下完再点就是安装 void _onUpdate() async { //iOS 没有下载安装 apk 那一套,直接跳 App Store;进度条也就不用起(isDownloading 不置位) if (Platform.isIOS) { final iosUrl = widget.updateInfo.iosUrl ?? ''; iosUrl.isEmpty ? showToast("暂无更新地址,请稍后再试") : await launchUrlToWeb(iosUrl); return; } if (progress == 1.0) { await InstallUtil.installApk(apkPath); return; } if (isDownloading) { return; } //开始下载 isDownloading = true; String devId = DeviceInfoService.deviceId; Clipboard.setData(ClipboardData(text: "***$devId^^^")); _downloadApk(widget.updateInfo.url ?? ""); setState(() {}); } @override Widget build(BuildContext context) { return CommonDialog( //强更场景要挡住点空白关闭,Get.dialog 的 barrierDismissible 到不了这层 barrierDismissible: false, canTapClose: false, child: Column( mainAxisSize: MainAxisSize.min, children: [ Column( mainAxisAlignment: MainAxisAlignment.start, children: [ Text( '系统升级', style: TextStyle( color: Colors.white.withValues(alpha: .9), fontSize: 20, fontWeight: FontWeight.w500, ), ), 12.sizeBoxH, 0.5.line, 12.sizeBoxH, Row( children: [ Text( "更新版本 v ${widget.updateInfo.verName}", style: TextStyle( color: Colors.white.withValues(alpha: .9), fontSize: 12, ), ), ], ), 12.sizeBoxH, SizedBox( height: 175, child: SingleChildScrollView( physics: const ClampingScrollPhysics(), child: Row( children: [ //Row 不给约束,Text 会按自然宽度排版撑出去,必须 Expanded 收回可用宽度才会换行 Expanded( child: Text( widget.updateInfo.description ?.replaceAll("|", "\n") ?? "", style: TextStyle( color: Colors.white.withValues(alpha: .55), fontSize: 12, height: 1.6, ), ), ), ], ), ), ), ], ), 18.sizeBoxH, InkWell( enableFeedback: false, onTap: () => Get.to(() => const MineAccountIdentityPage()), child: Row( mainAxisSize: MainAxisSize.min, children: [ Text( "保存账号凭证", style: TextStyle( color: Colors.white.withValues(alpha: .55), fontSize: 14, ), ), 3.sizeBoxW, Icon( Icons.arrow_forward_ios_outlined, size: 14, color: Color(0xffDCDCDC), ) ], ), ), 18.sizeBoxH, if (isDownloading) ...[ Container( padding: EdgeInsets.zero, child: Column( mainAxisSize: MainAxisSize.min, children: [ ClipRRect( borderRadius: BorderRadius.circular(3), child: LinearProgressIndicator( value: progress, minHeight: 3, backgroundColor: const Color(0xffBEBEBE), valueColor: AlwaysStoppedAnimation(AppColors.actionRed), ), ), 12.sizeBoxH, Text( "${((progress * 100).toInt())}%", style: TextStyle( fontSize: 16, color: Colors.white.withValues(alpha: .55), ), ), ], ), ), ] else _buildButtonMenu(), ], ), ); } Widget _buildButtonMenu() { if (widget.updateInfo.forcedUpdate == true) { return _buildUpdateBtn(); } else { return Row( children: [ Expanded( child: GestureDetector( onTap: () => Get.back(), child: Container( height: 44, alignment: Alignment.center, decoration: BoxDecoration( borderRadius: BorderRadius.circular(3), color: Colors.white.withValues(alpha: .1), ), child: Text( "暂不升级", style: TextStyle( fontSize: 14, fontWeight: FontWeight.w500, color: Color(0xff989898), ), ), ), ), ), const SizedBox(width: 12), Expanded(child: _buildUpdateBtn()), ], ); } } Widget _buildUpdateBtn() { return GestureDetector( onTap: _onUpdate, child: Container( height: 44, alignment: Alignment.center, decoration: BoxDecoration( color: AppColors.actionRed, borderRadius: BorderRadius.circular(3), ), child: const Text( "立即升级", style: TextStyle( fontSize: 14, color: Colors.white, fontWeight: FontWeight.w500, ), ), ), ); } ///下载 apk(仅 Android,iOS 走商店) Future _downloadApk(String url) async { final saveDirectory = path.join((await getExternalStorageDirectory())?.path ?? "", "apk"); DioSliceRetryDownloader(DioCli(), url, null, saveDirectory, "paofu.apk", onReceiveProgress: (count, total) { progress = (count / total); setState(() {}); }, onRetry: (int retryCount) { showToast("下载发生错误正在自动重试中...($retryCount)"); }).download().then((String savePath) async { apkPath = savePath; await InstallUtil.installApk(apkPath); }).catchError((e) { showToast("下载发生错误,点击重新进行下载."); setState(() => isDownloading = false); }); } }