passo_mobile_app/lib/screens/unit2/login/components/update_required.dart

249 lines
9.4 KiB
Dart
Raw Normal View History

import 'dart:async';
import 'dart:io';
2023-01-23 08:43:02 +00:00
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/screens/unit2/login/components/showAlert.dart';
import 'package:unit2/theme-data.dart/btn-style.dart';
import '../../../../bloc/user/user_bloc.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<Update> createState() => _UpdateState();
}
class _UpdateState extends State<Update> {
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<UserBloc, UserState>(
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: <Widget>[
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>[
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<void> openFile() async {
try {
final filePath = await downloadFile();
await openAPK(filePath);
} catch (e) {
print(e.toString());
}
}
Future<void> openAPK(String path) async {
PermissionStatus result = await Permission.storage.request();
if (result.isGranted) {
await EasyAppInstaller.instance.installApk(path);
}
}
Future<String> 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';
}
}