diff --git a/ios/Runner/Runner.entitlements b/ios/Runner/Runner.entitlements
index b3fdc75e..9a632605 100644
--- a/ios/Runner/Runner.entitlements
+++ b/ios/Runner/Runner.entitlements
@@ -4,6 +4,15 @@
aps-environment
development
+ com.apple.developer.networking.HotspotConfiguration
+
+ com.apple.developer.networking.wifi-info
+
+ com.apple.developer.nfc.readersession.formats
+
+ NDEF
+ TAG
+
inter-app-audio
diff --git a/lib/controllers/api_routes/urls.dart b/lib/controllers/api_routes/urls.dart
index 137d2f3a..cf8cabe6 100644
--- a/lib/controllers/api_routes/urls.dart
+++ b/lib/controllers/api_routes/urls.dart
@@ -1,6 +1,7 @@
class URLs {
URLs._();
+ static const String appReleaseBuildNumber = "14";
// static const host1 = "https://atomsm.hmg.com"; // production url
static const host1 = "https://atomsmdev.hmg.com"; // local UAT url
@@ -19,6 +20,7 @@ class URLs {
// API Routes
static get login => "$_baseUrl/MobileAuth/Login"; // web login
static get checkLoginValidation => "$_baseUrl/Account/Authenticate"; // web login
+ static get checkAppVersion => "$_baseUrl/Account/CheckAppVersion"; // web login
//Reset Password Apis...
static get sendForgetPasswordOtp => "$_baseUrl/Account/SendForgotPasswordOtp"; // send OTP.
static get sendForgetPasswordValidateOtp => "$_baseUrl/Account/SendForgotPasswordValidateOtp"; // validate OTP.
diff --git a/lib/controllers/providers/api/user_provider.dart b/lib/controllers/providers/api/user_provider.dart
index 53ba507b..f5ae0bbf 100644
--- a/lib/controllers/providers/api/user_provider.dart
+++ b/lib/controllers/providers/api/user_provider.dart
@@ -313,6 +313,7 @@ class UserProvider extends ChangeNotifier {
"userId": userId,
"dateFrom": dateFrom.toIso8601String(),
"dateTo": dateTo.toIso8601String(),
+ "IsSucces":true,
};
try {
response = await ApiManager.instance.post(URLs.getSwipeTransactionHistoryUrl, body: body);
diff --git a/lib/controllers/providers/settings/setting_provider.dart b/lib/controllers/providers/settings/setting_provider.dart
index cb97341c..bcfeb2ed 100644
--- a/lib/controllers/providers/settings/setting_provider.dart
+++ b/lib/controllers/providers/settings/setting_provider.dart
@@ -2,6 +2,7 @@ import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
+import 'package:http/http.dart';
import 'package:local_auth/local_auth.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:test_sa/controllers/api_routes/api_manager.dart';
@@ -166,4 +167,19 @@ class SettingProvider extends ChangeNotifier {
return false;
}
}
+
+ Future checkAppUpdate(String buildNumber, String osType) async {
+ Response response;
+ bool isValid = false;
+ try {
+ Map body = {"buildNumber": buildNumber, "osType": osType};
+ response = await ApiManager.instance.post(URLs.checkAppVersion, body: body);
+ if (response.statusCode >= 200 && response.statusCode < 300) {
+ isValid = (jsonDecode(response.body)["data"]);
+ }
+ return isValid;
+ } catch (error) {
+ return isValid;
+ }
+ }
}
diff --git a/lib/main.dart b/lib/main.dart
index cff76122..b16998bd 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -30,8 +30,10 @@ import 'package:test_sa/new_views/pages/login_page.dart';
import 'package:test_sa/new_views/pages/report_bug_page.dart';
import 'package:test_sa/new_views/pages/settings_page.dart';
import 'package:test_sa/new_views/pages/splash_page.dart';
+import 'package:test_sa/new_views/pages/unsafe_device_view.dart';
import 'package:test_sa/new_views/swipe_module/swipe_history_view.dart';
import 'package:test_sa/new_views/swipe_module/swipe_success_view.dart';
+import 'package:test_sa/new_views/swipe_module/swipe_view.dart';
import 'package:test_sa/providers/asset_transfer/asset_transfer_status_provider.dart';
import 'package:test_sa/providers/department_provider.dart';
import 'package:test_sa/providers/gas_request_providers/cylinder_size_provider.dart';
@@ -93,6 +95,7 @@ import 'providers/service_request_providers/reject_reason_provider.dart';
import 'package:flutter_timezone/flutter_timezone.dart';
import 'package:timezone/data/latest_all.dart' as tz;
import 'package:timezone/timezone.dart' as tz;
+import 'package:test_sa/views/update_available_screen.dart';
void main() async {
@@ -278,7 +281,11 @@ class MyApp extends StatelessWidget {
routes: {
SplashPage.routeName: (_) => const SplashPage(),
LoginPage.routeName: (_) => const LoginPage(),
-
+ UnsafeDeviceScreen.routeName: (_) => const UnsafeDeviceScreen(),
+ SwipeSuccessView.routeName: (_) => const SwipeSuccessView(),
+ SwipeHistoryView.routeName: (_) => SwipeHistoryView(),
+ SwipeView.routeName: (_) => const SwipeView(),
+ UpdateAvailableScreen.routeName: (_) => UpdateAvailableScreen(),
///todo deleted
//old.LandPage.id: (_) => const old.LandPage(),
LandPage.routeName: (_) => const LandPage(),
diff --git a/lib/models/user.dart b/lib/models/user.dart
index ac3ace61..7f6d3e83 100644
--- a/lib/models/user.dart
+++ b/lib/models/user.dart
@@ -9,6 +9,7 @@ class User {
List? departmentId;
List? departmentName;
String? message;
+
String? username;
String? userID;
String? email;
@@ -39,7 +40,8 @@ class User {
bool? employeeIsHMG;
bool? enableWifi;
bool? enableNFC;
- bool?enableQR;
+ bool? enableQR;
+ bool? onlySwipe;
User({
this.clientId,
@@ -76,6 +78,7 @@ class User {
this.enableNFC,
this.enableQR,
this.enableWifi,
+ this.onlySwipe,
});
bool get isLiveToken => tokenlife != null && (DateTime.tryParse(tokenlife!)?.isAfter(DateTime.now()) ?? false);
@@ -162,6 +165,7 @@ class User {
map['enableWifi'] = enableWifi;
map['enableNFC'] = enableNFC;
map['enableQR'] = enableQR;
+ map['onlySwipe'] = onlySwipe;
return map;
}
@@ -223,6 +227,7 @@ class User {
enableWifi = json['enableWifi'];
enableNFC = json['enableNFC'];
enableQR = json['enableQR'];
+ onlySwipe = json['onlySwipe'];
}
}
diff --git a/lib/new_views/pages/splash_page.dart b/lib/new_views/pages/splash_page.dart
index 8de05715..9cc574c8 100644
--- a/lib/new_views/pages/splash_page.dart
+++ b/lib/new_views/pages/splash_page.dart
@@ -2,14 +2,21 @@ import 'dart:io';
import 'package:firebase_core/firebase_core.dart';
import 'package:flare_flutter/flare_actor.dart';
+import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:local_auth/local_auth.dart';
import 'package:provider/provider.dart';
+import 'package:safe_device/safe_device.dart';
+import 'package:test_sa/controllers/api_routes/urls.dart';
+import 'package:test_sa/controllers/notification/firebase_notification_manger.dart';
import 'package:test_sa/controllers/providers/api/user_provider.dart';
import 'package:test_sa/controllers/providers/settings/setting_provider.dart';
import 'package:test_sa/extensions/widget_extensions.dart';
import 'package:test_sa/new_views/pages/land_page/land_page.dart';
import 'package:test_sa/new_views/pages/login_page.dart';
+import 'package:test_sa/new_views/pages/unsafe_device_view.dart';
+import 'package:test_sa/new_views/swipe_module/swipe_view.dart';
+import 'package:test_sa/views/update_available_screen.dart';
import '../../models/size_config.dart';
@@ -54,20 +61,44 @@ class _SplashPageState extends State {
loading = true;
});
- bool isValid = await _settingProvider.checkUserTokenValidation(token);
- setState(() {
- loading = false;
- });
- if (isValid && _settingProvider.isLocalAuthEnable) {
- bool isSuccess = await checkDualAuthentication();
- if (isSuccess) {
- _userProvider.setUser(_settingProvider.user!);
- Navigator.of(context).pushNamedAndRemoveUntil(LandPage.routeName, (routes) => true);
+ String osType;
+ if (Platform.isIOS) {
+ osType = "IOS";
+ } else {
+ if (await FirebaseNotificationManger.isGoogleServicesAvailable()) {
+ osType = "GOOGLE";
} else {
- Navigator.of(context).pushNamedAndRemoveUntil(LoginPage.routeName, (routes) => true);
+ osType = "HUAWEI";
}
+ }
+
+ bool isAppUpdateAvailable = await _settingProvider.checkAppUpdate(URLs.appReleaseBuildNumber, osType);
+ if (isAppUpdateAvailable) {
+ setState(() {
+ loading = false;
+ });
+ Navigator.of(context).pushNamedAndRemoveUntil(UpdateAvailableScreen.routeName, (routes) => true);
} else {
- Navigator.of(context).pushNamedAndRemoveUntil(LoginPage.routeName, (routes) => true);
+ bool isValid = await _settingProvider.checkUserTokenValidation(token);
+ setState(() {
+ loading = false;
+ });
+ if (isValid && _settingProvider.isLocalAuthEnable) {
+ bool isSuccess = await checkDualAuthentication();
+ if (isSuccess) {
+ _userProvider.setUser(_settingProvider.user!);
+
+ if (_userProvider.user!.onlySwipe!) {
+ Navigator.of(context).pushNamedAndRemoveUntil(SwipeView.routeName, (routes) => true);
+ } else {
+ Navigator.of(context).pushNamedAndRemoveUntil(LandPage.routeName, (routes) => true);
+ }
+ } else {
+ Navigator.of(context).pushNamedAndRemoveUntil(LoginPage.routeName, (routes) => true);
+ }
+ } else {
+ Navigator.of(context).pushNamedAndRemoveUntil(LoginPage.routeName, (routes) => true);
+ }
}
}
@@ -100,33 +131,68 @@ class _SplashPageState extends State {
)),
SizedBox(
width: MediaQuery.of(context).size.width / 1.1,
- child: FlareActor(
- "assets/rives/atoms_splash.flr",
- fit: BoxFit.contain,
- animation: "splash",
- callback: (animation) async {
- if (_settingProvider.isLoaded && (_settingProvider.user != null)) {
- checkTokenValidity(_settingProvider.user!.token!);
- } else {
- Navigator.of(context).pushNamedAndRemoveUntil(LoginPage.routeName, (routes) => true);
- }
-
- // if (_settingProvider.isLoaded && (_settingProvider.user?.isLiveToken ?? false)) {
- // _userProvider.user = _settingProvider.user;
- // Navigator.of(context).pushNamedAndRemoveUntil(LandPage.routeName, (routes) => true);
- // // if(isnotificationCame)
- // // Navigator.of(context).push(MaterialPageRoute(
- // // builder: (_) => ServiceRequestDetailsPage(
- // // serviceRequest: ServiceRequest(id: "72348"),
- // // )));
- // /// The below line for the new design
- // // Navigator.of(context).pushNamedAndRemoveUntil(LandPage.routeName, (routes) => true);
- // }
- },
+ child: Hero(
+ tag: "logo",
+ child: FlareActor(
+ "assets/rives/atoms_splash.flr",
+ fit: BoxFit.contain,
+ animation: "splash",
+ callback: (animation) async {
+ bool isSafe = await checkDeviceSafety();
+ print('is safe is ${isSafe}');
+ if (!isSafe) {
+ Navigator.pushNamedAndRemoveUntil(context, UnsafeDeviceScreen.routeName, (_) => false);
+ } else {
+ if (_settingProvider.isLoaded && (_settingProvider.user != null)) {
+ checkTokenValidity(_settingProvider.user!.token!);
+ } else {
+ Navigator.of(context).pushNamedAndRemoveUntil(LoginPage.routeName, (routes) => true);
+ }
+ }
+
+ // if (_settingProvider.isLoaded && (_settingProvider.user?.isLiveToken ?? false)) {
+ // _userProvider.user = _settingProvider.user;
+ // Navigator.of(context).pushNamedAndRemoveUntil(LandPage.routeName, (routes) => true);
+ // // if(isnotificationCame)
+ // // Navigator.of(context).push(MaterialPageRoute(
+ // // builder: (_) => ServiceRequestDetailsPage(
+ // // serviceRequest: ServiceRequest(id: "72348"),
+ // // )));
+ // /// The below line for the new design
+ // // Navigator.of(context).pushNamedAndRemoveUntil(LandPage.routeName, (routes) => true);
+ // }
+ },
+ ),
),
).center,
],
),
);
}
+
+ Future checkDeviceSafety() async {
+ if (!kReleaseMode) return true;
+ bool isOnExternalStorage = false;
+ bool isDevelopmentModeEnable = false;
+ bool isJailBroken = false;
+ bool isRealDevice = false;
+
+ try {
+ isJailBroken = await SafeDevice.isJailBroken;
+ isRealDevice = await SafeDevice.isRealDevice;
+ if (Platform.isAndroid) {
+ isOnExternalStorage = await SafeDevice.isOnExternalStorage;
+ isDevelopmentModeEnable = await SafeDevice.isDevelopmentModeEnable;
+ }
+ //TODO correct isDevelopmentModeEnable when publish to prod...
+ if (isJailBroken || !isRealDevice || isOnExternalStorage || isDevelopmentModeEnable) {
+ return false;
+ } else {
+ return true;
+ }
+ } catch (error) {
+ print(error);
+ return false;
+ }
+ }
}
diff --git a/lib/new_views/pages/unsafe_device_view.dart b/lib/new_views/pages/unsafe_device_view.dart
new file mode 100644
index 00000000..6b482553
--- /dev/null
+++ b/lib/new_views/pages/unsafe_device_view.dart
@@ -0,0 +1,80 @@
+import 'dart:io';
+
+import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+import 'package:test_sa/extensions/context_extension.dart';
+import 'package:test_sa/extensions/int_extensions.dart';
+import 'package:test_sa/extensions/text_extensions.dart';
+import 'package:test_sa/extensions/widget_extensions.dart';
+import 'package:test_sa/new_views/app_style/app_color.dart';
+import 'package:test_sa/new_views/common_widgets/app_filled_button.dart';
+
+class UnsafeDeviceScreen extends StatefulWidget {
+ const UnsafeDeviceScreen({Key? key}) : super(key: key);
+ static const String routeName = "/unSafeDevice";
+
+
+ @override
+ State createState() => _UnsafeDeviceScreenState();
+}
+
+class _UnsafeDeviceScreenState extends State {
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ body: SafeArea(
+ child: Column(
+ mainAxisSize: MainAxisSize.min,
+ crossAxisAlignment: CrossAxisAlignment.center,
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ 21.height,
+ // Center(child: Image.asset("assets/images/logos/main_mohemm_logo.png", width: 200, height: 50)),
+ "logo".toSvgAsset(height: 64),
+ 50.height,
+ "Sorry".heading5(context),
+ 21.height,
+ "You are using Atoms app on an unsafe device. To be able to use the app with all it's features, Please make sure that the below points are considered: "
+ .heading5(context).paddingOnly(start: 20, end: 20),
+ 48.height,
+ passwordConstraintsUI("The device is not jailbroken or rooted.", true).paddingOnly(start: 24, end: 5),
+ 8.height,
+ passwordConstraintsUI("The app is not installed on external storage.", true).paddingOnly(start: 24, end: 5),
+ 8.height,
+ passwordConstraintsUI("Development mode is disabled.", true).paddingOnly(start: 24, end: 5),
+ 21.height,
+ AppFilledButton(label: context.translation.done, maxWidth: true, onPressed: () async {
+ if (Platform.isAndroid) {
+ SystemChannels.platform.invokeMethod('SystemNavigator.pop');
+ } else {
+ // MinimizeApp.minimizeApp();
+ }
+ }).paddingAll(24),
+ // DefaultButton(LocaleKeys.ok.tr(), () async {
+ // if (Platform.isAndroid) {
+ // SystemChannels.platform.invokeMethod('SystemNavigator.pop');
+ // } else {
+ // // MinimizeApp.minimizeApp();
+ // }
+ // })
+ ],
+ ),
+ ),
+ );
+ }
+
+ Widget passwordConstraintsUI(String description, bool check) {
+ return Row(
+ children: [
+ 4.width,
+ SizedBox(
+ width: 12,
+ height: 12,
+ child: Checkbox(fillColor: MaterialStateProperty.all(AppColor.backgroundDark), shape: const CircleBorder(), value: check, onChanged: null),
+ ),
+ 8.width,
+ description.heading6(context)
+ ],
+ );
+ }
+}
\ No newline at end of file
diff --git a/lib/new_views/swipe_module/swipe_history_view.dart b/lib/new_views/swipe_module/swipe_history_view.dart
index 84169833..5dbc1865 100644
--- a/lib/new_views/swipe_module/swipe_history_view.dart
+++ b/lib/new_views/swipe_module/swipe_history_view.dart
@@ -119,7 +119,6 @@ class _SwipeHistoryViewState extends State {
],
),
12.height,
-
AppFilledButton(label: context.translation.search, maxWidth: false, onPressed: getSwipeHistory),
8.height,
const Divider(thickness: 2,color:AppColor.white60 ,),
diff --git a/lib/new_views/swipe_module/swipe_view.dart b/lib/new_views/swipe_module/swipe_view.dart
new file mode 100644
index 00000000..455b3cc0
--- /dev/null
+++ b/lib/new_views/swipe_module/swipe_view.dart
@@ -0,0 +1,159 @@
+import 'package:flutter/material.dart';
+import 'package:nfc_manager/nfc_manager.dart';
+import 'package:provider/provider.dart';
+import 'package:test_sa/controllers/providers/api/user_provider.dart';
+import 'package:test_sa/controllers/providers/settings/setting_provider.dart';
+import 'package:test_sa/extensions/context_extension.dart';
+import 'package:test_sa/extensions/int_extensions.dart';
+import 'package:test_sa/extensions/text_extensions.dart';
+import 'package:test_sa/extensions/widget_extensions.dart';
+import 'package:test_sa/new_views/app_style/app_color.dart';
+import 'package:test_sa/new_views/common_widgets/app_drawer.dart';
+import 'package:test_sa/new_views/swipe_module/circular_animated_widget.dart';
+import 'package:test_sa/new_views/swipe_module/swipe_history_view.dart';
+import 'package:test_sa/new_views/swipe_module/utils/swipe_general_utils.dart';
+import 'package:test_sa/views/widgets/dialogs/dialog.dart';
+
+class SwipeView extends StatefulWidget {
+ static const String routeName = "/swipe-view";
+
+ const SwipeView({
+ Key? key,
+ }) : super(key: key);
+
+ @override
+ State createState() => _SwipeViewState();
+}
+
+class _SwipeViewState extends State {
+ late UserProvider _userProvider;
+ final GlobalKey _scaffoldKey = GlobalKey();
+
+ @override
+ void initState() {
+ super.initState();
+ _userProvider = Provider.of(context, listen: false);
+ if (_userProvider.user != null) {
+ WidgetsBinding.instance.addPostFrameCallback((_) {
+ _userProvider.getSwipeLastTransaction(userId: _userProvider.user!.userID!);
+ });
+ }
+ }
+
+ @override
+ void dispose() {
+ super.dispose();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return WillPopScope(
+ onWillPop: () async {
+ bool result = await showDialog(
+ context: context,
+ builder: (_) => AAlertDialog(title: context.translation.signOut, content: context.translation.logoutAlert),
+ );
+ if (result) {
+ Provider.of(context, listen: false).resetSettings();
+ Provider.of(context, listen: false).reset();
+ Navigator.of(context).pop();
+ Navigator.of(context).pop();
+ }
+ return false;
+ },
+ child: Scaffold(
+ key: _scaffoldKey,
+ drawer: const AppDrawer(),
+ appBar: AppBar(
+ automaticallyImplyLeading: false,
+ backgroundColor: Theme.of(context).scaffoldBackgroundColor,
+ titleSpacing: 0,
+ title: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ crossAxisAlignment: CrossAxisAlignment.center,
+ children: [
+ Consumer(builder: (context, snapshot, _) {
+ return CircleAvatar(
+ radius: 24,
+ backgroundColor: context.isDark ? AppColor.neutral50 : AppColor.neutral40,
+ child: Padding(
+ padding: const EdgeInsets.all(1), // Border radius
+ child: ClipOval(
+ child: snapshot.profileImage != null
+ ? Image.file(snapshot.profileImage!)
+ : (snapshot.user?.profilePhotoName?.isNotEmpty ?? false)
+ ? Image.network(snapshot.user!.profilePhotoName!)
+ : const Icon(Icons.person, size: 24, color: Colors.white),
+ ),
+ ),
+ ).onPress(() {
+ _scaffoldKey.currentState!.isDrawerOpen ? _scaffoldKey.currentState!.closeDrawer() : _scaffoldKey.currentState!.openDrawer();
+ });
+ }),
+ ],
+ ).paddingOnly(start: 16, end: 16),
+ ),
+ body: Stack(
+ children: [
+ Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ Column(
+ mainAxisSize: MainAxisSize.min,
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Text(
+ context.translation.welcome,
+ style: AppTextStyles.heading6.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral20),
+ ),
+ Text(
+ _userProvider.user?.username ?? "",
+ style: AppTextStyles.heading2.copyWith(color: context.isDark ? AppColor.neutral30 : AppColor.neutral50, fontWeight: FontWeight.w600),
+ ),
+ ],
+ ).paddingOnly(start: 16, end: 16, top: 8, bottom: 4),
+ SwipeHistoryView().expanded,
+ ],
+ ),
+ Positioned(
+ right: 20.toScreenWidth,
+ bottom: 60.toScreenHeight,
+ child: GestureDetector(
+ onTap: () async {
+ bool isNfcSupported = await NfcManager.instance.isAvailable();
+ SwipeGeneralUtils.instance.showSwipeTypeBottomSheetSheet(isNfcSupported: isNfcSupported);
+ },
+ child: CircularAnimatedContainer(
+ child: Container(
+ width: 100.toScreenWidth,
+ height: 100.toScreenHeight,
+ decoration: BoxDecoration(
+ shape: BoxShape.circle,
+ color: AppColor.white10,
+ border: Border.all(color: AppColor.primary80.withOpacity(0.5), width: 2),
+ ),
+ child: Consumer(builder: (context, userProvider, child) {
+ return Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ crossAxisAlignment: CrossAxisAlignment.center,
+ children: [
+ 'swipe'.toSvgAsset(width: 32, height: 32),
+ 8.height,
+ Text(
+ ("${context.translation.checkIn}\n${userProvider.swipeTransactionModel != null && userProvider.swipeTransactionModel.swipeTime != null ? SwipeGeneralUtils.instance.formatTimeOnly(userProvider.swipeTransactionModel.swipeTime!) : '--:--'}"),
+ style: AppTextStyles.bodyText2.copyWith(color: AppColor.neutral80, fontWeight: FontWeight.w500, fontFamily: "Poppins"),
+ ),
+ ],
+ );
+ }),
+ ),
+ ),
+ ),
+ ),
+ ],
+ ),
+ ),
+ );
+ }
+}
diff --git a/lib/views/pages/splash_screen.dart b/lib/views/pages/splash_screen.dart
deleted file mode 100644
index 046e4ebd..00000000
--- a/lib/views/pages/splash_screen.dart
+++ /dev/null
@@ -1,77 +0,0 @@
-///todo deleted
-// import 'package:firebase_core/firebase_core.dart';
-// import 'package:flare_flutter/flare_actor.dart';
-// import 'package:flutter/material.dart';
-// import 'package:provider/provider.dart';
-// import 'package:test_sa/controllers/notification/notification_manger.dart';
-// import 'package:test_sa/controllers/providers/api/user_provider.dart';
-// import 'package:test_sa/controllers/providers/settings/setting_provider.dart';
-// import 'package:test_sa/models/user.dart';
-// import 'package:test_sa/new_views/pages/land_page/land_page.dart';
-//
-// import 'login.dart';
-//
-// class SplashScreen extends StatefulWidget {
-// static const String id = '/splash';
-//
-// const SplashScreen({Key? key}) : super(key: key);
-//
-// @override
-// State createState() => _SplashScreenState();
-// }
-//
-// class _SplashScreenState extends State {
-// SettingProvider _settingProvider;
-// UserProvider _userProvider;
-//
-// _goToUserScreen(User user) {
-// if (user.tokenlife != null && (DateTime.tryParse(user.tokenlife)?.isAfter(DateTime.now()) ?? false)) {
-// _userProvider.user = user;
-// // Navigator.of(context).pushNamed(Login.id);
-// Navigator.of(context).pushNamed(LandPage.routeName);
-// }
-// }
-//
-// @override
-// void initState() {
-// Firebase.initializeApp();
-//
-// NotificationManger.initialisation((notificationDetails) {
-// // todo @sikander, check notifications payload, because notification model is different to need to check from backend
-// // SystemNotificationModel notification = SystemNotificationModel.fromJson(json.decode(notificationDetails.payload));
-// // if (notification.path == null || notification.path.isEmpty) return;
-// // Navigator.pushNamed(context, notification.path, arguments: notification.requestId);
-// }, (id, title, body, payload) async {});
-// super.initState();
-// }
-//
-// @override
-// Widget build(BuildContext context) {
-// _settingProvider = Provider.of(context, listen: false);
-// _userProvider = Provider.of(context, listen: false);
-// return Scaffold(
-// backgroundColor: Colors.white,
-// body: Center(
-// child: SizedBox(
-// width: MediaQuery.of(context).size.width / 1.1,
-// child: FlareActor(
-// "assets/rives/atoms_splash.flr",
-// fit: BoxFit.contain,
-// animation: "splash",
-// callback: (animation) async {
-// Navigator.of(context).pushNamed(Login.id);
-// if (_settingProvider.isLoaded && _settingProvider.user != null) {
-// _goToUserScreen(_settingProvider.user);
-// }
-// },
-// ),
-// //const Center(child: CircularProgressIndicator())
-//
-// // Image.asset("assets/images/logo.png",
-// // fit: BoxFit.contain,
-// // ),
-// ),
-// ),
-// );
-// }
-// }
diff --git a/lib/views/update_available_screen.dart b/lib/views/update_available_screen.dart
new file mode 100644
index 00000000..558a0233
--- /dev/null
+++ b/lib/views/update_available_screen.dart
@@ -0,0 +1,54 @@
+import 'dart:io';
+
+import 'package:flutter/material.dart';
+import 'package:test_sa/extensions/context_extension.dart';
+import 'package:test_sa/extensions/int_extensions.dart';
+import 'package:test_sa/extensions/text_extensions.dart';
+import 'package:test_sa/extensions/widget_extensions.dart';
+import 'package:test_sa/new_views/app_style/app_color.dart';
+import 'package:test_sa/new_views/common_widgets/app_filled_button.dart';
+import 'package:url_launcher/url_launcher.dart';
+
+class UpdateAvailableScreen extends StatelessWidget {
+ static const String routeName = "/UpdateAvailableScreen";
+
+ UpdateAvailableScreen({Key? key}) : super(key: key);
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ body: Column(
+ crossAxisAlignment: CrossAxisAlignment.center,
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ Hero(tag: "logo", child: "logo".toSvgAsset(height: 64)),
+ 48.height,
+ Text(
+ "Update Available",
+ style: AppTextStyles.heading4.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral50),
+ ),
+ 24.height,
+ Text(
+ "A new update is available on store.\nUpdate now to enjoy the latest features, improvements, and bug fixes for a smoother experience! ",
+ textAlign: TextAlign.center,
+ style: AppTextStyles.heading6.copyWith(color: context.isDark ? AppColor.neutral10 : AppColor.neutral20),
+ ),
+ 24.height,
+ AppFilledButton(
+ label: context.translation.update,
+ maxWidth: true,
+ onPressed: () {
+ if (Platform.isAndroid || Platform.isIOS) {
+ final appId = Platform.isAndroid ? 'com.hmg.atoms' : '6446684161';
+ final url = Uri.parse(Platform.isAndroid ? "market://details?id=$appId" : "https://apps.apple.com/app/id$appId");
+ launchUrl(
+ url,
+ mode: LaunchMode.externalApplication,
+ );
+ }
+ }),
+ ],
+ ).paddingAll(24),
+ );
+ }
+}
diff --git a/pubspec.lock b/pubspec.lock
index 9ff16b2f..7e051fcd 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -1325,6 +1325,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "0.28.0"
+ safe_device:
+ dependency: "direct main"
+ description:
+ name: safe_device
+ sha256: "953aeac3486180df9118a1a3f5fb842d84015e8aa6f2607edeb5fb881b67a669"
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.2.0"
share_plus:
dependency: "direct main"
description:
diff --git a/pubspec.yaml b/pubspec.yaml
index 88bda3c5..9d81d41e 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -15,7 +15,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
-version: 1.3.1+14
+version: 1.2.6+14
environment:
sdk: ">=3.5.0 <4.0.0"
@@ -92,6 +92,7 @@ dependencies:
nfc_manager: ^3.2.0
wifi_iot: ^0.3.19+1
just_audio: ^0.9.30
+ safe_device: ^1.1.9
local_auth_darwin: any
dev_dependencies: