261 lines
8.2 KiB
Dart
261 lines
8.2 KiB
Dart
// 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(仅 Android,iOS 走商店)
|
||
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);
|
||
});
|
||
}
|
||
}
|