Files
huangguo_android/lib/alert/splash/update_dialog.dart
T
2026-09-15 15:44:13 +07:00

261 lines
8.2 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// 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<UpdateDialog> createState() => _UpdateDialog();
}
class _UpdateDialog extends State<UpdateDialog> {
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(仅 AndroidiOS 走商店)
Future<void> _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);
});
}
}