Merge pull request 'feature/unit2/UNIT2-#3-Add-download-new-version-feature' (#4) from feature/unit2/UNIT2-#3-Add-download-new-version-feature into develop
Reviewed-on: http://git.agusandelnorte.gov.ph:3000/SoftwareDevelopmentSection/unit2-null-safety-repository/pulls/4feature/passo/PASSO-#1-Sync-data-from-device-to-postgre-and-vice-versa
commit
1ffc20f3b6
|
@ -51,6 +51,7 @@ android {
|
||||||
targetSdkVersion flutter.targetSdkVersion
|
targetSdkVersion flutter.targetSdkVersion
|
||||||
versionCode flutterVersionCode.toInteger()
|
versionCode flutterVersionCode.toInteger()
|
||||||
versionName flutterVersionName
|
versionName flutterVersionName
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
|
|
|
@ -1,10 +1,25 @@
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="com.example.unit2">
|
package="com.example.unit2">
|
||||||
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
|
||||||
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION"/>
|
||||||
|
<uses-permission android:name="android.permission.INTERNET"/>
|
||||||
<uses-permission android:name="android.permission.CAMERA" />
|
<uses-permission android:name="android.permission.CAMERA" />
|
||||||
|
<uses-permission android:name="android.permission.INSTALL_PACKAGES" />
|
||||||
|
<uses-permission android:name="android.permission.DELETE_PACKAGES" />
|
||||||
<application
|
<application
|
||||||
android:label="unit2"
|
android:label="unit2"
|
||||||
android:name="${applicationName}"
|
android:name="${applicationName}"
|
||||||
android:icon="@mipmap/ic_launcher">
|
android:icon="@mipmap/ic_launcher">
|
||||||
|
<provider
|
||||||
|
android:authorities = "${applicationId}.fileprovider"
|
||||||
|
android:exported = "false"
|
||||||
|
android:grantUriPermissions = "true"
|
||||||
|
android:name = "androidx.core.content.FileProvider">
|
||||||
|
<meta-data
|
||||||
|
android:name = "android.support.FILE_PROVIDER_PATHS"
|
||||||
|
android:resource = "@xml/file_provider_path" />
|
||||||
|
</provider >
|
||||||
<activity
|
<activity
|
||||||
android:name=".MainActivity"
|
android:name=".MainActivity"
|
||||||
android:exported="true"
|
android:exported="true"
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
// Generated file.
|
||||||
|
//
|
||||||
|
// If you wish to remove Flutter's multidex support, delete this entire file.
|
||||||
|
//
|
||||||
|
// Modifications to this file should be done in a copy under a different name
|
||||||
|
// as this file may be regenerated.
|
||||||
|
|
||||||
|
package io.flutter.app;
|
||||||
|
|
||||||
|
import android.app.Application;
|
||||||
|
import android.content.Context;
|
||||||
|
import androidx.annotation.CallSuper;
|
||||||
|
import androidx.multidex.MultiDex;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extension of {@link android.app.Application}, adding multidex support.
|
||||||
|
*/
|
||||||
|
public class FlutterMultiDexApplication extends Application {
|
||||||
|
@Override
|
||||||
|
@CallSuper
|
||||||
|
protected void attachBaseContext(Context base) {
|
||||||
|
super.attachBaseContext(base);
|
||||||
|
MultiDex.install(this);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<paths xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<root-path name="root" path="."/>
|
||||||
|
|
||||||
|
<files-path
|
||||||
|
name="files"
|
||||||
|
path="."/>
|
||||||
|
|
||||||
|
<cache-path
|
||||||
|
name="cache"
|
||||||
|
path="."/>
|
||||||
|
|
||||||
|
<external-path
|
||||||
|
name="external"
|
||||||
|
path="."/>
|
||||||
|
|
||||||
|
<external-cache-path
|
||||||
|
name="external_cache"
|
||||||
|
path="."/>
|
||||||
|
|
||||||
|
<external-files-path
|
||||||
|
name="external_file"
|
||||||
|
path="."/>
|
||||||
|
</paths>
|
|
@ -3,6 +3,7 @@ import 'package:bloc/bloc.dart';
|
||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
import 'package:unit2/model/login_data/user_info/user_data.dart';
|
import 'package:unit2/model/login_data/user_info/user_data.dart';
|
||||||
import 'package:unit2/model/login_data/version_info.dart';
|
import 'package:unit2/model/login_data/version_info.dart';
|
||||||
|
import 'package:unit2/screens/unit2/login/functions/get_app_version.dart';
|
||||||
import 'package:unit2/sevices/login_service/auth_service.dart';
|
import 'package:unit2/sevices/login_service/auth_service.dart';
|
||||||
|
|
||||||
import '../../utils/scanner.dart';
|
import '../../utils/scanner.dart';
|
||||||
|
@ -21,7 +22,8 @@ class UserBloc extends Bloc<UserEvent, UserState> {
|
||||||
emit(SplashScreen());
|
emit(SplashScreen());
|
||||||
VersionInfo versionInfo = await AuthService.instance.getVersionInfo();
|
VersionInfo versionInfo = await AuthService.instance.getVersionInfo();
|
||||||
_versionInfo = versionInfo;
|
_versionInfo = versionInfo;
|
||||||
emit(VersionLoaded(versionInfo: _versionInfo));
|
String apkVersion = await getAppVersion();
|
||||||
|
emit(VersionLoaded(versionInfo: _versionInfo,apkVersion: apkVersion));
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
emit(UserError(
|
emit(UserError(
|
||||||
message: e.toString(),
|
message: e.toString(),
|
||||||
|
|
|
@ -27,6 +27,7 @@ class GetUuid extends UserEvent {
|
||||||
GetUuid();
|
GetUuid();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class LoadVersion extends UserEvent {}
|
class LoadVersion extends UserEvent {}
|
||||||
|
|
||||||
class UuidLogin extends UserEvent {
|
class UuidLogin extends UserEvent {
|
||||||
|
|
|
@ -37,7 +37,8 @@ class UserLoggedIn extends UserState{
|
||||||
|
|
||||||
class VersionLoaded extends UserState {
|
class VersionLoaded extends UserState {
|
||||||
final VersionInfo? versionInfo;
|
final VersionInfo? versionInfo;
|
||||||
VersionLoaded({this.versionInfo});
|
final String? apkVersion;
|
||||||
|
VersionLoaded({this.versionInfo,this.apkVersion});
|
||||||
@override
|
@override
|
||||||
List<Object> get props => [versionInfo!];
|
List<Object> get props => [versionInfo!];
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
import 'package:cool_alert/cool_alert.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import '../../../../theme-data.dart/colors.dart';
|
||||||
|
|
||||||
|
showAlert(context,Function confirm) {
|
||||||
|
CoolAlert.show(
|
||||||
|
context: context,
|
||||||
|
type: CoolAlertType.error,
|
||||||
|
title: 'Download Failed!',
|
||||||
|
text: 'Make sure you have internet connection. Please try again.',
|
||||||
|
loopAnimation: false,
|
||||||
|
confirmBtnText: "Try again",
|
||||||
|
confirmBtnColor: primary,
|
||||||
|
onConfirmBtnTap: confirm(),
|
||||||
|
backgroundColor: Colors.black);
|
||||||
|
}
|
|
@ -1,96 +1,248 @@
|
||||||
|
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/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: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 'package:unit2/theme-data.dart/btn-style.dart';
|
||||||
|
|
||||||
import '../../../../theme-data.dart/colors.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 {
|
class Update extends StatefulWidget {
|
||||||
const Update({super.key});
|
final String apkVersion;
|
||||||
|
final String currenVersion;
|
||||||
|
const Update(
|
||||||
|
{super.key, required this.apkVersion, required this.currenVersion});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<Update> createState() => _UpdateState();
|
State<Update> createState() => _UpdateState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _UpdateState extends State<Update> {
|
class _UpdateState extends State<Update> {
|
||||||
|
String progressRating = '0';
|
||||||
|
bool downloading = false;
|
||||||
|
bool isDownloaded = false;
|
||||||
|
bool asyncCall = false;
|
||||||
|
Dio dio = Dio();
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return SafeArea(
|
return SafeArea(
|
||||||
child: SingleChildScrollView(
|
child: Stack(children: [
|
||||||
child: Container(
|
BlocBuilder<UserBloc, UserState>(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 40, vertical: 25),
|
builder: (context, state) {
|
||||||
height: MediaQuery.of(context).size.height,
|
if (state is VersionLoaded) {
|
||||||
alignment: Alignment.center,
|
return ProgressHUD(
|
||||||
child: Column(
|
child: SingleChildScrollView(
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
child: Container(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
padding: const EdgeInsets.symmetric(
|
||||||
children: <Widget>[
|
horizontal: 40, vertical: 25),
|
||||||
Column(
|
height: MediaQuery.of(context).size.height,
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
alignment: Alignment.center,
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
child: Column(
|
||||||
children: [
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
SvgPicture.asset(
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
'assets/svgs/download.svg',
|
children: <Widget>[
|
||||||
height: 200.0,
|
Column(
|
||||||
width: 200.0,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
allowDrawingOutsideViewBox: true,
|
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.")),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(
|
),
|
||||||
height: 5,
|
);
|
||||||
),
|
}
|
||||||
Text("UPDATE REQUIRED!",
|
if (state is UserError) {
|
||||||
textAlign: TextAlign.center,
|
showAlert(context, () {
|
||||||
style: Theme.of(context)
|
setState(() {
|
||||||
.textTheme
|
downloading = false;
|
||||||
.displaySmall!
|
});
|
||||||
.copyWith(color: primary, fontSize: 28)),
|
});
|
||||||
],
|
}
|
||||||
),
|
return Container();
|
||||||
const SizedBox(
|
},
|
||||||
height: 10,
|
|
||||||
),
|
|
||||||
RichText(
|
|
||||||
textAlign: TextAlign.justify,
|
|
||||||
text: TextSpan(
|
|
||||||
text: 'Your app version ',
|
|
||||||
style: const TextStyle(
|
|
||||||
fontSize: 16,
|
|
||||||
color: Colors.black,
|
|
||||||
),
|
|
||||||
children: <TextSpan>[
|
|
||||||
const TextSpan(
|
|
||||||
text: "mobileVersion",
|
|
||||||
style: TextStyle(
|
|
||||||
color: primary, fontWeight: FontWeight.bold)),
|
|
||||||
const TextSpan(
|
|
||||||
text: " did not match with the latest version ",
|
|
||||||
style: TextStyle(color: Colors.black)),
|
|
||||||
TextSpan(
|
|
||||||
text:
|
|
||||||
"widget.currentVersion.data.version".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,
|
|
||||||
),
|
|
||||||
SizedBox(
|
|
||||||
height: 60,
|
|
||||||
width: MediaQuery.of(context).size.width,
|
|
||||||
child: ElevatedButton.icon(
|
|
||||||
icon: const Icon(Icons.download),
|
|
||||||
style: mainBtnStyle(primary, Colors.transparent, second),
|
|
||||||
onPressed: () async {},
|
|
||||||
label: const Text("Download Latest App Version.")),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
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';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
import 'package:package_info_plus/package_info_plus.dart';
|
||||||
|
|
||||||
|
Future<String> getAppVersion() async{
|
||||||
|
String appVersion;
|
||||||
|
try{
|
||||||
|
PackageInfo packageInfo = await PackageInfo.fromPlatform();
|
||||||
|
appVersion = packageInfo.version;
|
||||||
|
}catch(e){
|
||||||
|
throw(e.toString());
|
||||||
|
}
|
||||||
|
return appVersion;
|
||||||
|
|
||||||
|
}
|
|
@ -4,17 +4,12 @@ import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
import 'package:flutter_form_builder/flutter_form_builder.dart';
|
import 'package:flutter_form_builder/flutter_form_builder.dart';
|
||||||
import 'package:fluttericon/font_awesome5_icons.dart';
|
import 'package:fluttericon/font_awesome5_icons.dart';
|
||||||
import 'package:fluttertoast/fluttertoast.dart';
|
|
||||||
import 'package:form_builder_validators/form_builder_validators.dart';
|
import 'package:form_builder_validators/form_builder_validators.dart';
|
||||||
|
|
||||||
import 'package:flutter_progress_hud/flutter_progress_hud.dart';
|
import 'package:flutter_progress_hud/flutter_progress_hud.dart';
|
||||||
import 'package:unit2/bloc/bloc/user_bloc.dart';
|
import 'package:unit2/bloc/bloc/user_bloc.dart';
|
||||||
import 'package:unit2/model/login_data/user_info/user_data.dart';
|
import 'package:unit2/screens/unit2/login/components/update_required.dart';
|
||||||
import 'package:unit2/screens/unit2/login/qr_login.dart';
|
|
||||||
import 'package:unit2/utils/text_container.dart';
|
import 'package:unit2/utils/text_container.dart';
|
||||||
import 'package:unit2/widgets/error_state.dart';
|
import 'package:unit2/widgets/error_state.dart';
|
||||||
|
|
||||||
import '../../../utils/scanner.dart';
|
|
||||||
import '../../../widgets/splash_screen.dart';
|
import '../../../widgets/splash_screen.dart';
|
||||||
import '../../../widgets/wave.dart';
|
import '../../../widgets/wave.dart';
|
||||||
import '../../../utils/global.dart';
|
import '../../../utils/global.dart';
|
||||||
|
@ -53,10 +48,11 @@ class _UniT2LoginState extends State<UniT2Login> {
|
||||||
}, builder: (context, state) {
|
}, builder: (context, state) {
|
||||||
if (state is VersionLoaded) {
|
if (state is VersionLoaded) {
|
||||||
return Builder(builder: (context) {
|
return Builder(builder: (context) {
|
||||||
return SizedBox(
|
if(state.versionInfo!.version == state.apkVersion){
|
||||||
|
return SizedBox(
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
child: Stack(
|
child: Stack(
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
children: [
|
children: [
|
||||||
Positioned(
|
Positioned(
|
||||||
bottom: 0,
|
bottom: 0,
|
||||||
|
@ -273,6 +269,10 @@ class _UniT2LoginState extends State<UniT2Login> {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
}else{
|
||||||
|
return Update(apkVersion: state.apkVersion!,currenVersion: state.versionInfo!.version!,);
|
||||||
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (state is UserError) {
|
if (state is UserError) {
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
import 'dart:async';
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:dio/dio.dart';
|
||||||
|
import 'package:unit2/model/login_data/version_info.dart';
|
||||||
|
import 'package:system_info2/system_info2.dart';
|
||||||
|
Future<String> getCPUArchitecture() async {
|
||||||
|
String downloadURL = "";
|
||||||
|
String cpuArchitecture = SysInfo.kernelArchitecture;
|
||||||
|
VersionInfo? apkVersion;
|
||||||
|
Dio dio = Dio();
|
||||||
|
const String apkUrl = 'https://unitylb1.agusandelnorte.gov.ph/unit2/api/sys/apk_version/latest/';
|
||||||
|
try {
|
||||||
|
Response response = await dio.get(apkUrl,
|
||||||
|
options: Options(
|
||||||
|
receiveTimeout: 20000,
|
||||||
|
receiveDataWhenStatusError: true,
|
||||||
|
responseType: ResponseType.json,
|
||||||
|
followRedirects: false,
|
||||||
|
validateStatus: (status) {
|
||||||
|
return status! < 500;
|
||||||
|
}));
|
||||||
|
if (response.statusCode == 200) {
|
||||||
|
apkVersion = VersionInfo.fromJson(response.data['data']);
|
||||||
|
if (cpuArchitecture.toUpperCase() == 'ARM' ||
|
||||||
|
cpuArchitecture.toUpperCase() == 'MIPS') {
|
||||||
|
downloadURL = apkVersion.armeabiv7aDownloadUrl!;
|
||||||
|
} else if (cpuArchitecture.toUpperCase() == 'I686' ||
|
||||||
|
cpuArchitecture.toUpperCase() == 'UNKNOWN' ||
|
||||||
|
cpuArchitecture.toUpperCase() == 'X86_64') {
|
||||||
|
downloadURL = apkVersion.x8664DownloadUrl!;
|
||||||
|
} else if (cpuArchitecture.toUpperCase() == 'AARCH64') {
|
||||||
|
downloadURL = apkVersion.arm64v8aDownloadUrl!;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} on TimeoutException catch (_) {
|
||||||
|
throw TimeoutException("Connection timeout");
|
||||||
|
} on SocketException catch (_) {
|
||||||
|
throw const SocketException("Connection timeout");
|
||||||
|
} on DioError catch (_) {
|
||||||
|
throw DioErrorType.connectTimeout;
|
||||||
|
}
|
||||||
|
return downloadURL;
|
||||||
|
}
|
|
@ -19,7 +19,7 @@ class Request {
|
||||||
Map<String, String>? param}) async {
|
Map<String, String>? param}) async {
|
||||||
Response response;
|
Response response;
|
||||||
try {
|
try {
|
||||||
response = await get(Uri.http(host, path!, param), headers: headers)
|
response = await get(Uri.https(host, path!, param), headers: headers)
|
||||||
.timeout(Duration(seconds: requestTimeout));
|
.timeout(Duration(seconds: requestTimeout));
|
||||||
} on TimeoutException catch (_) {
|
} on TimeoutException catch (_) {
|
||||||
Fluttertoast.showToast(
|
Fluttertoast.showToast(
|
||||||
|
@ -60,39 +60,39 @@ class Request {
|
||||||
Map? body,
|
Map? body,
|
||||||
Map<String, String>? param}) async {
|
Map<String, String>? param}) async {
|
||||||
Response response;
|
Response response;
|
||||||
// try {
|
try {
|
||||||
response = await post(Uri.http(host, path!, param), headers: headers,body: jsonEncode(body))
|
response = await post(Uri.https(host, path!, param), headers: headers,body: jsonEncode(body))
|
||||||
.timeout(Duration(seconds: requestTimeout));
|
.timeout(Duration(seconds: requestTimeout));
|
||||||
// } on TimeoutException catch (_) {
|
} on TimeoutException catch (_) {
|
||||||
// Fluttertoast.showToast(
|
Fluttertoast.showToast(
|
||||||
// msg: timeoutError,
|
msg: timeoutError,
|
||||||
// toastLength: Toast.LENGTH_LONG,
|
toastLength: Toast.LENGTH_LONG,
|
||||||
// gravity: ToastGravity.BOTTOM,
|
gravity: ToastGravity.BOTTOM,
|
||||||
// backgroundColor: Colors.black,
|
backgroundColor: Colors.black,
|
||||||
// );
|
);
|
||||||
// throw (timeoutError);
|
throw (timeoutError);
|
||||||
// } on SocketException catch (_) {
|
} on SocketException catch (_) {
|
||||||
// Fluttertoast.showToast(
|
Fluttertoast.showToast(
|
||||||
// msg: timeoutError,
|
msg: timeoutError,
|
||||||
// toastLength: Toast.LENGTH_LONG,
|
toastLength: Toast.LENGTH_LONG,
|
||||||
// gravity: ToastGravity.BOTTOM,
|
gravity: ToastGravity.BOTTOM,
|
||||||
// backgroundColor: Colors.black,
|
backgroundColor: Colors.black,
|
||||||
// );
|
);
|
||||||
// throw (timeoutError);
|
throw (timeoutError);
|
||||||
// } on FormatException catch (_) {
|
} on FormatException catch (_) {
|
||||||
// throw const FormatException(formatError);
|
throw const FormatException(formatError);
|
||||||
// } on HttpException catch (_) {
|
} on HttpException catch (_) {
|
||||||
// throw const HttpException(httpError);
|
throw const HttpException(httpError);
|
||||||
// } on Error catch (e) {
|
} on Error catch (e) {
|
||||||
// debugPrint("post request error: $e");
|
debugPrint("post request error: $e");
|
||||||
// Fluttertoast.showToast(
|
Fluttertoast.showToast(
|
||||||
// msg: onError,
|
msg: onError,
|
||||||
// toastLength: Toast.LENGTH_LONG,
|
toastLength: Toast.LENGTH_LONG,
|
||||||
// gravity: ToastGravity.BOTTOM,
|
gravity: ToastGravity.BOTTOM,
|
||||||
// backgroundColor: Colors.black,
|
backgroundColor: Colors.black,
|
||||||
// );
|
);
|
||||||
// throw (e.toString());
|
throw (e.toString());
|
||||||
// }
|
}
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,9 +3,11 @@ class Url{
|
||||||
static Url get instance => _instance;
|
static Url get instance => _instance;
|
||||||
|
|
||||||
String host(){
|
String host(){
|
||||||
return '192.168.10.219:3000';
|
// return '192.168.10.219:3000';
|
||||||
|
return 'agusandelnorte.gov.ph';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
String authentication(){
|
String authentication(){
|
||||||
return '/api/account/auth/login/';
|
return '/api/account/auth/login/';
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,11 +5,13 @@
|
||||||
import FlutterMacOS
|
import FlutterMacOS
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
|
import package_info_plus
|
||||||
import path_provider_macos
|
import path_provider_macos
|
||||||
import shared_preferences_macos
|
import shared_preferences_macos
|
||||||
import sqflite
|
import sqflite
|
||||||
|
|
||||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||||
|
FLTPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FLTPackageInfoPlusPlugin"))
|
||||||
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
||||||
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
||||||
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
|
SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin"))
|
||||||
|
|
|
@ -120,6 +120,13 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.0+1"
|
version: "3.1.0+1"
|
||||||
|
cool_alert:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: cool_alert
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.1.0"
|
||||||
crypto:
|
crypto:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -148,6 +155,20 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0"
|
version: "1.1.0"
|
||||||
|
dio:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: dio
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "4.0.6"
|
||||||
|
easy_app_installer:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: easy_app_installer
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.0"
|
||||||
equatable:
|
equatable:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -190,6 +211,13 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.1"
|
version: "1.0.1"
|
||||||
|
flare_flutter:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flare_flutter
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.2"
|
||||||
flutter:
|
flutter:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description: flutter
|
description: flutter
|
||||||
|
@ -242,6 +270,13 @@ packages:
|
||||||
description: flutter
|
description: flutter
|
||||||
source: sdk
|
source: sdk
|
||||||
version: "0.0.0"
|
version: "0.0.0"
|
||||||
|
flutter_plugin_android_lifecycle:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flutter_plugin_android_lifecycle
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.7"
|
||||||
flutter_progress_hud:
|
flutter_progress_hud:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -371,6 +406,13 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.1"
|
version: "2.0.1"
|
||||||
|
lottie:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: lottie
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.4.3"
|
||||||
matcher:
|
matcher:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -406,6 +448,20 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.2"
|
version: "1.0.2"
|
||||||
|
package_info_plus:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: package_info_plus
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.2"
|
||||||
|
package_info_plus_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: package_info_plus_platform_interface
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "2.0.1"
|
||||||
path:
|
path:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -428,7 +484,7 @@ packages:
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.1"
|
version: "1.0.1"
|
||||||
path_provider:
|
path_provider:
|
||||||
dependency: transitive
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: path_provider
|
name: path_provider
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
|
@ -483,6 +539,41 @@ packages:
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.11.1"
|
version: "1.11.1"
|
||||||
|
permission_handler:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: permission_handler
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "10.2.0"
|
||||||
|
permission_handler_android:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: permission_handler_android
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "10.2.0"
|
||||||
|
permission_handler_apple:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: permission_handler_apple
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "9.0.7"
|
||||||
|
permission_handler_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: permission_handler_platform_interface
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "3.9.0"
|
||||||
|
permission_handler_windows:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: permission_handler_windows
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "0.1.2"
|
||||||
petitparser:
|
petitparser:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|
|
@ -60,6 +60,12 @@ dependencies:
|
||||||
system_info2: ^2.0.4
|
system_info2: ^2.0.4
|
||||||
flutter_bloc: ^8.0.0
|
flutter_bloc: ^8.0.0
|
||||||
equatable: ^2.0.5
|
equatable: ^2.0.5
|
||||||
|
package_info_plus: ^3.0.2
|
||||||
|
easy_app_installer: ^1.0.0
|
||||||
|
path_provider: ^2.0.11
|
||||||
|
dio: ^4.0.6
|
||||||
|
cool_alert: ^1.1.0
|
||||||
|
permission_handler: ^10.2.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|
|
@ -6,6 +6,9 @@
|
||||||
|
|
||||||
#include "generated_plugin_registrant.h"
|
#include "generated_plugin_registrant.h"
|
||||||
|
|
||||||
|
#include <permission_handler_windows/permission_handler_windows_plugin.h>
|
||||||
|
|
||||||
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||||
|
PermissionHandlerWindowsPluginRegisterWithRegistrar(
|
||||||
|
registry->GetRegistrarForPlugin("PermissionHandlerWindowsPlugin"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
list(APPEND FLUTTER_PLUGIN_LIST
|
list(APPEND FLUTTER_PLUGIN_LIST
|
||||||
|
permission_handler_windows
|
||||||
)
|
)
|
||||||
|
|
||||||
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
||||||
|
|
Loading…
Reference in New Issue