import 'dart:async'; import 'dart:io'; import 'package:dio/dio.dart'; import 'package:easy_app_installer/easy_app_installer.dart'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_progress_hud/flutter_progress_hud.dart'; import 'package:flutter_svg/svg.dart'; import 'package:path_provider/path_provider.dart'; import 'package:permission_handler/permission_handler.dart'; import 'package:unit2/bloc/bloc/user_bloc.dart'; import 'package:unit2/screens/unit2/login/components/showAlert.dart'; import 'package:unit2/theme-data.dart/btn-style.dart'; import '../../../../theme-data.dart/colors.dart'; import '../../../../utils/cpu_architecture.dart'; import '../../../../utils/text_container.dart'; import '../../../../widgets/wave.dart'; class Update extends StatefulWidget { final String apkVersion; final String currenVersion; const Update( {super.key, required this.apkVersion, required this.currenVersion}); @override State createState() => _UpdateState(); } class _UpdateState extends State { String progressRating = '0'; bool downloading = false; bool isDownloaded = false; bool asyncCall = false; Dio dio = Dio(); @override Widget build(BuildContext context) { return SafeArea( child: Stack(children: [ BlocBuilder( builder: (context, state) { if (state is VersionLoaded) { return ProgressHUD( child: SingleChildScrollView( child: Container( padding: const EdgeInsets.symmetric( horizontal: 40, vertical: 25), height: MediaQuery.of(context).size.height, alignment: Alignment.center, child: Column( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: [ Column( crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, children: [ SvgPicture.asset( 'assets/svgs/download.svg', height: 200.0, width: 200.0, allowDrawingOutsideViewBox: true, ), const SizedBox( height: 5, ), Text("UPDATE REQUIRED!", textAlign: TextAlign.center, style: Theme.of(context) .textTheme .displaySmall! .copyWith(color: primary, fontSize: 28)), ], ), const SizedBox( height: 10, ), RichText( textAlign: TextAlign.justify, text: TextSpan( text: 'Your app version ', style: const TextStyle( fontSize: 16, color: Colors.black, ), children: [ TextSpan( text: widget.apkVersion, style: const TextStyle( color: primary, fontWeight: FontWeight.bold)), const TextSpan( text: " did not match with the latest version ", style: TextStyle(color: Colors.black)), TextSpan( text: widget.currenVersion.toString(), style: const TextStyle( color: primary, fontWeight: FontWeight.bold)), const TextSpan( text: ". Download the app latest version to procceed using the uniT-App.", style: TextStyle(color: Colors.black)), ])), const SizedBox( height: 12.0, ), Container( child: downloading ? FittedBox( child: Text( 'Downloading application $progressRating%', textAlign: TextAlign.center, style: Theme.of(context) .textTheme .headlineSmall! .copyWith(fontWeight: FontWeight.bold), ), ) : Container(), ), SizedBox( height: 60, width: MediaQuery.of(context).size.width, child: downloading ? Container() : ElevatedButton.icon( icon: const Icon(Icons.download), style: mainBtnStyle( primary, Colors.transparent, second), onPressed: () async { final progress = ProgressHUD.of(context); progress?.showWithText( 'Please wait...', ); setState(() { downloading = true; progressRating = '0'; }); await openFile(); }, label: const Text( "Download Latest App Version.")), ), ], ), ), ), ); } if (state is UserError) { showAlert(context, () { setState(() { downloading = false; }); }); } return Container(); }, ), const Positioned(bottom: 0, child: WaveReverse(height: 80)) ]), ); } Future openFile() async { try { final filePath = await downloadFile(); await openAPK(filePath); } catch (e) { print(e.toString()); } } Future openAPK(String path) async { PermissionStatus result = await Permission.storage.request(); if (result.isGranted) { await EasyAppInstaller.instance.installApk(path); } } Future downloadFile() async { final progress = ProgressHUD.of(context); final appStorage = await getApplicationDocumentsDirectory(); try { String url = await getCPUArchitecture(); final response = await dio.download(url, '${appStorage.path}/uniT.apk', deleteOnError: true, options: Options( receiveTimeout: 20000, sendTimeout: 20000, receiveDataWhenStatusError: true, responseType: ResponseType.bytes, followRedirects: false, validateStatus: (status) { return status! < 500; }), onReceiveProgress: (recv, total) { setState(() { progressRating = ((recv / total) * 100).toStringAsFixed(0); downloading = true; }); if (progressRating == '100') { final progress = ProgressHUD.of(context); progress!.dismiss(); setState(() { downloading = false; isDownloaded = true; }); } }); } on TimeoutException catch (_) { progress!.dismiss(); showAlert(context, () { setState(() { downloading = false; }); }); throw TimeoutException(timeoutError); } on SocketException catch (_) { progress!.dismiss(); showAlert(context, () { setState(() { downloading = false; }); }); throw const SocketException(timeoutError); } on DioError catch (_) { progress!.dismiss(); showAlert(context, () { setState(() { downloading = false; }); }); throw TimeoutException(timeoutError); } catch (_) { progress!.dismiss(); showAlert(context, () { setState(() { downloading = false; }); }); throw TimeoutException(timeoutError); } return '${appStorage.path}/uniT.apk'; } }