diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 389d714..08e67bd 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -75,9 +75,9 @@ PODS: - FMDB (2.7.5): - FMDB/standard (= 2.7.5) - FMDB/standard (2.7.5) - - geolocator (5.3.1): + - geolocator (5.3.0): - Flutter - - google_api_availability (2.0.4): + - google_api_availability (2.0.3): - Flutter - google_maps_flutter (0.0.1): - Flutter @@ -260,8 +260,8 @@ SPEC CHECKSUMS: Flutter: 0e3d915762c693b495b44d77113d4970485de6ec flutter_plugin_android_lifecycle: 47de533a02850f070f5696a623995e93eddcdb9b FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a - geolocator: 460cc8e850b616f8c0e90944c86517d91ccbb686 - google_api_availability: 15fa42a8cd83c0a6738507ffe6e87096f12abcb8 + geolocator: 7cdcf71180b80913b3cd84ab715d3b5365b378af + google_api_availability: 526574c9a5a0ae541e18c65f98e47afc11f53c8b google_maps_flutter: d0dd62f5a7d39bae61057eb9f52dd778d99c7c6c GoogleAppMeasurement: 434cc7be25e71dc04b8d0e3079125127b330e84a GoogleDataTransport: 166f9b9f82cbf60a204e8fe2daa9db3e3ec1fb15 diff --git a/lib/constants.dart b/lib/constants.dart index fc10903..7b339ed 100644 --- a/lib/constants.dart +++ b/lib/constants.dart @@ -1,3 +1,11 @@ final bool debugRelease = false; //final String testingServer = "https://test.covid-19.health.gov.lk/api"; final String testingServer = "https://test.covid-19.health.gov.lk/api"; + +//Constants defined for version checking +const String ANDROID_APP_BUILD_NUMBER_KEY = "android_app_builder_number_Key"; +const String IOS_APP_BUILD_NUMBER_KEY = "ios_app_builder_number_key"; +const String ANDROID_APP_URL = + "https://play.google.com/store/apps/details?id=app.ceylon.selftrackingapp"; +const String IOS_APP_URL = + "https://apps.apple.com/us/app/myhealth-sri-lanka/id1503349513"; \ No newline at end of file diff --git a/lib/main.dart b/lib/main.dart index 3d57bcc..1ce76fd 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,9 +1,10 @@ import 'dart:async'; -import 'dart:async'; -import 'dart:io'; - +import 'package:connectivity/connectivity.dart'; +import 'package:dropdown_banner/dropdown_banner.dart'; +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:get_it/get_it.dart'; import 'package:selftrackingapp/app_localizations.dart'; @@ -12,10 +13,8 @@ import 'package:selftrackingapp/networking/db.dart'; import 'package:selftrackingapp/page/screen/root_screen.dart'; import 'package:selftrackingapp/page/screen/welcome_screen.dart'; import 'package:shared_preferences/shared_preferences.dart'; -import 'package:connectivity/connectivity.dart'; -import 'package:flutter/services.dart'; + import 'utils/tracker_colors.dart'; -import 'package:dropdown_banner/dropdown_banner.dart'; void main() { runApp(MyApp()); @@ -79,6 +78,7 @@ class _HomeScreenState extends State { @override void initState() { super.initState(); + _isTimeoutCompleted = false; SystemChrome.setPreferredOrientations([ DeviceOrientation.portraitUp, diff --git a/lib/page/screen/root_screen.dart b/lib/page/screen/root_screen.dart index df66714..a6811e0 100644 --- a/lib/page/screen/root_screen.dart +++ b/lib/page/screen/root_screen.dart @@ -1,5 +1,9 @@ +import 'dart:io'; + import 'package:async/async.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; +import 'package:firebase_remote_config/firebase_remote_config.dart'; +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:package_info/package_info.dart'; import 'package:provider/provider.dart'; @@ -8,20 +12,17 @@ import 'package:selftrackingapp/models/news_article.dart'; import 'package:selftrackingapp/networking/api_client.dart'; import 'package:selftrackingapp/notifiers/registered_cases_model.dart'; import 'package:selftrackingapp/notifiers/stories_model.dart'; -import 'package:selftrackingapp/page/screen/case_list_screen.dart'; -import 'package:selftrackingapp/page/screen/contact_us_screen.dart'; import 'package:selftrackingapp/page/screen/dashboard_screen.dart'; import 'package:selftrackingapp/page/screen/faq_screen.dart'; import 'package:selftrackingapp/page/screen/privacy_policy_screen.dart'; import 'package:selftrackingapp/page/screen/welcome_screen.dart'; import 'package:selftrackingapp/utils/tracker_colors.dart'; -import 'package:selftrackingapp/widgets/custom_text.dart'; import 'package:titled_navigation_bar/titled_navigation_bar.dart'; +import 'package:url_launcher/url_launcher.dart'; import '../../app_localizations.dart'; -import '../ios_faq.dart'; -import 'case_details_screen.dart'; import 'case_details_map_screen.dart'; +import 'case_details_screen.dart'; enum RootTab { HomeTab, CaseTab, ContactTab, RegisterTab } @@ -67,6 +68,7 @@ class _RootScreenState extends State { } }); _fetchCaseLatest(); + _appVersionCheck(); } void _handleFCM(Map message) async { @@ -240,4 +242,99 @@ class _RootScreenState extends State { ]; } } + +//check for the latest build number set in the firebase remote config +//and show update dialog if necessary + void _appVersionCheck() async { + String key = Platform.isIOS + ? IOS_APP_BUILD_NUMBER_KEY + : ANDROID_APP_BUILD_NUMBER_KEY; + + //Get Current buildNumber of the app + final PackageInfo info = await PackageInfo.fromPlatform(); + + //In Android this refers to [versionCode]. In iOS [CFBundleVersion] + int currentBuildNumber = int.parse(info.buildNumber); + + //Get Latest version info from firebase config + final RemoteConfig remoteConfig = await RemoteConfig.instance; + + try { + await remoteConfig + .setDefaults({key: currentBuildNumber}); + + // Using default duration to force fetching from remote server. + await remoteConfig.fetch(expiration: const Duration(seconds: 0)); + await remoteConfig.activateFetched(); + + int remoteBuildNumber = remoteConfig.getInt(key); + + if (remoteBuildNumber > currentBuildNumber) { + _showUpdateDialog(); + } + } on FetchThrottledException catch (exception) { + // Fetch throttled. + print(exception); + } catch (exception) { + print('Unable to fetch remote config. Default value will be used'); + } + } + + void _showUpdateDialog() async { + bool isIOS = Platform.isIOS; + String title = "New Update Available"; + String message = + "There is a newer version of the app available. Please update now."; + String affirmativeLabel = "Update Now"; + String negativeLabel = "Later"; + + isIOS + ? showCupertinoDialog( + context: context, + builder: (context) { + return CupertinoAlertDialog( + title: Text(title), + content: Text(message), + actions: [ + CupertinoDialogAction( + isDefaultAction: true, + child: Text(affirmativeLabel), + onPressed: () => launchAppStore(IOS_APP_URL), + ), + CupertinoDialogAction( + child: Text(negativeLabel), + onPressed: () => Navigator.pop(context), + ), + ], + ); + }) + : showDialog( + context: context, + builder: (BuildContext context) { + return AlertDialog( + title: Text(title), + content: Text(message), + actions: [ + FlatButton( + child: Text( + affirmativeLabel.toUpperCase(), + style: TextStyle(color: Colors.blue), + ), + onPressed: () => launchAppStore(ANDROID_APP_URL), + ), + FlatButton( + child: Text(negativeLabel.toUpperCase()), + onPressed: () => Navigator.pop(context), + ), + ], + ); + }, + ); + } + + void launchAppStore(String url) async { + if (await canLaunch(url)) { + launch(url); + } + } } diff --git a/pubspec.yaml b/pubspec.yaml index 355616d..36c1bef 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -11,7 +11,7 @@ description: Self tracking app # 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.14.0+31 +version: 1.14.0+32 environment: sdk: ">=2.1.0 <3.0.0"