From e5bfca3e2a3e2bd3242f1741ba80b2149f1d1e3e Mon Sep 17 00:00:00 2001 From: Bibash Shrestha Date: Mon, 16 Jan 2023 11:56:44 +0530 Subject: [PATCH] redirect to app upgrade page when app needs update #1100 --- lib/app/shared/enum/status/splash_status.dart | 7 +- lib/app_upgrade/app_upgrade.dart | 1 + lib/app_upgrade/view/app_upgrade_page.dart | 135 ++++++++++++++++++ lib/splash/bloclisteners/blocklisteners.dart | 36 +++-- lib/splash/cubit/splash_cubit.dart | 23 +++ lib/splash/cubit/splash_state.dart | 42 ++++++ pubspec.lock | 7 + pubspec.yaml | 3 +- 8 files changed, 240 insertions(+), 14 deletions(-) create mode 100644 lib/app_upgrade/app_upgrade.dart create mode 100644 lib/app_upgrade/view/app_upgrade_page.dart diff --git a/lib/app/shared/enum/status/splash_status.dart b/lib/app/shared/enum/status/splash_status.dart index eb40dd49b..790549514 100644 --- a/lib/app/shared/enum/status/splash_status.dart +++ b/lib/app/shared/enum/status/splash_status.dart @@ -1 +1,6 @@ -enum SplashStatus { init, routeToPassCode, routeToOnboarding } +enum SplashStatus { + init, + routeToPassCode, + routeToOnboarding, + routeToAppUpdate, +} diff --git a/lib/app_upgrade/app_upgrade.dart b/lib/app_upgrade/app_upgrade.dart new file mode 100644 index 000000000..9c2afcee5 --- /dev/null +++ b/lib/app_upgrade/app_upgrade.dart @@ -0,0 +1 @@ +export 'view/app_upgrade_page.dart'; diff --git a/lib/app_upgrade/view/app_upgrade_page.dart b/lib/app_upgrade/view/app_upgrade_page.dart new file mode 100644 index 000000000..f3512acc4 --- /dev/null +++ b/lib/app_upgrade/view/app_upgrade_page.dart @@ -0,0 +1,135 @@ +import 'package:altme/app/app.dart'; +import 'package:altme/dashboard/dashboard.dart'; +import 'package:altme/l10n/l10n.dart'; +import 'package:altme/onboarding/onboarding.dart'; +import 'package:altme/splash/splash.dart'; +import 'package:altme/theme/theme.dart'; +import 'package:altme/wallet/wallet.dart'; +import 'package:cryptocurrency_keys/cryptocurrency_keys.dart'; +import 'package:file_saver/file_saver.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:secure_storage/secure_storage.dart'; + +class AppUpgradePage extends StatelessWidget { + const AppUpgradePage({Key? key, required this.storeInfo}) : super(key: key); + + final StoreInfo storeInfo; + + static Route route({required StoreInfo storeInfo}) => MaterialPageRoute( + builder: (_) => AppUpgradePage(storeInfo: storeInfo), + settings: const RouteSettings(name: '/AppUpgradePage'), + ); + + @override + Widget build(BuildContext context) { + return AppUpgradeView(storeInfo: storeInfo); + } +} + +class AppUpgradeView extends StatelessWidget { + const AppUpgradeView({ + Key? key, + required this.storeInfo, + }) : super(key: key); + + final StoreInfo storeInfo; + + @override + Widget build(BuildContext context) { + final textTheme = Theme.of(context).textTheme; + final l10n = context.l10n; + + return WillPopScope( + onWillPop: () async => false, + child: BasePage( + scrollView: false, + padding: const EdgeInsets.symmetric(horizontal: 20), + body: SingleChildScrollView( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + mainAxisSize: MainAxisSize.max, + children: [ + const SizedBox(height: 20), + Image.asset( + ImageStrings.splashImage, + fit: BoxFit.fitWidth, + height: MediaQuery.of(context).size.longestSide * 0.3, + ), + const SizedBox(height: 30), + Text( + 'Time to update', + style: textTheme.titleLarge, + ), + const SizedBox(height: 20), + Text( + '''We have added lots of features and fixed some bugs to make your experience as much as possible.''', + textAlign: TextAlign.center, + style: textTheme.bodyLarge, + ), + const SizedBox(height: 20), + Text( + '''A new version of Altme is avaible! You can now update this app from v${storeInfo.localVersion} to v${storeInfo.storeVersion}.''', + textAlign: TextAlign.center, + style: textTheme.bodyLarge, + ), + if (storeInfo.releaseNotes.isNotEmpty) ...[ + const SizedBox(height: 10), + TextButton( + onPressed: () { + showDialog( + context: context, + builder: (context) => InfoDialog( + title: storeInfo.releaseNotes, + button: l10n.ok, + ), + ); + }, + child: Text( + "What's new in v${storeInfo.storeVersion}?", + style: Theme.of(context).textTheme.copyToClipBoard, + ), + ), + ], + const SizedBox(height: 30), + MyGradientButton( + onPressed: () {}, + text: 'Update Now', + ), + const SizedBox(height: 10), + FutureBuilder>( + future: CredentialsRepository(getSecureStorage).findAll(), + builder: (context, snapshot) { + switch (snapshot.connectionState) { + case ConnectionState.done: + final credentials = snapshot.data ?? []; + + if (credentials.isNotEmpty) { + return TextButton( + onPressed: () { + Navigator.of(context) + .push(BackupCredentialPage.route()); + }, + child: Text( + 'Backup your Credential', + style: Theme.of(context).textTheme.copyToClipBoard, + ), + ); + } else { + return const SizedBox(); + } + case ConnectionState.waiting: + case ConnectionState.none: + case ConnectionState.active: + return const SizedBox(); + } + }, + ), + const SizedBox(height: 10), + ], + ), + ), + ), + ); + } +} diff --git a/lib/splash/bloclisteners/blocklisteners.dart b/lib/splash/bloclisteners/blocklisteners.dart index 843b93bb2..fda51cca1 100644 --- a/lib/splash/bloclisteners/blocklisteners.dart +++ b/lib/splash/bloclisteners/blocklisteners.dart @@ -1,4 +1,5 @@ import 'package:altme/app/app.dart'; +import 'package:altme/app_upgrade/app_upgrade.dart'; import 'package:altme/connection_bridge/connection_bridge.dart'; import 'package:altme/dashboard/dashboard.dart'; import 'package:altme/l10n/l10n.dart'; @@ -16,20 +17,31 @@ import 'package:flutter_bloc/flutter_bloc.dart'; final splashBlocListener = BlocListener( listener: (BuildContext context, SplashState state) { - if (state.status == SplashStatus.routeToPassCode) { - Navigator.of(context).push( - PinCodePage.route( - isValidCallback: () { - Navigator.of(context).push(DashboardPage.route()); - }, - ), - ); - } - - if (state.status == SplashStatus.routeToOnboarding) { - Navigator.of(context).push(StarterPage.route()); + switch (state.status) { + case SplashStatus.init: + break; + case SplashStatus.routeToPassCode: + Navigator.of(context).push( + PinCodePage.route( + isValidCallback: () { + Navigator.of(context).push(DashboardPage.route()); + }, + ), + ); + break; + case SplashStatus.routeToOnboarding: + Navigator.of(context).push(StarterPage.route()); + break; + case SplashStatus.routeToAppUpdate: + Navigator.of(context).push( + AppUpgradePage.route( + storeInfo: state.storeInfo, + ), + ); + break; } + // TODO(all): remove // just for next build -> 117 and then we should remove for build -> 118 context.read().setState( Parameters.defaultAdvanceSettingsState, diff --git a/lib/splash/cubit/splash_cubit.dart b/lib/splash/cubit/splash_cubit.dart index 2d3f5ebb8..d591f9dda 100644 --- a/lib/splash/cubit/splash_cubit.dart +++ b/lib/splash/cubit/splash_cubit.dart @@ -8,6 +8,7 @@ import 'package:altme/wallet/cubit/wallet_cubit.dart'; import 'package:bloc/bloc.dart'; import 'package:equatable/equatable.dart'; import 'package:json_annotation/json_annotation.dart'; +import 'package:new_version/new_version.dart'; import 'package:package_info_plus/package_info_plus.dart'; import 'package:secure_storage/secure_storage.dart'; @@ -32,6 +33,28 @@ class SplashCubit extends Cubit { final DioClient client; Future initialiseApp() async { + final newVersion = NewVersion( + iOSId: 'io.altme.wallet', + androidId: 'co.altme.alt.me.altme', + ); + + final VersionStatus? versionStatus = await newVersion.getVersionStatus(); + + if (versionStatus != null && versionStatus.canUpdate) { + emit( + state.copyWith( + status: SplashStatus.routeToAppUpdate, + storeInfo: StoreInfo( + localVersion: versionStatus.localVersion, + storeVersion: versionStatus.storeVersion, + appStoreLink: versionStatus.appStoreLink, + releaseNotes: versionStatus.releaseNotes ?? '', + ), + ), + ); + return; + } + final bool hasWallet = await isWalletCreated( secureStorageProvider: secureStorageProvider, didCubit: didCubit, diff --git a/lib/splash/cubit/splash_state.dart b/lib/splash/cubit/splash_state.dart index 0dabfccbb..d80b261de 100644 --- a/lib/splash/cubit/splash_state.dart +++ b/lib/splash/cubit/splash_state.dart @@ -6,6 +6,7 @@ class SplashState extends Equatable { this.status = SplashStatus.init, this.versionNumber = '', this.buildNumber = '', + this.storeInfo = const StoreInfo(), }); factory SplashState.fromJson(Map json) => @@ -14,16 +15,19 @@ class SplashState extends Equatable { final SplashStatus status; final String versionNumber; final String buildNumber; + final StoreInfo storeInfo; SplashState copyWith({ SplashStatus? status, String? versionNumber, String? buildNumber, + StoreInfo? storeInfo, }) { return SplashState( status: status ?? this.status, versionNumber: versionNumber ?? this.versionNumber, buildNumber: buildNumber ?? this.buildNumber, + storeInfo: storeInfo ?? this.storeInfo, ); } @@ -32,3 +36,41 @@ class SplashState extends Equatable { @override List get props => [status, versionNumber, buildNumber]; } + +@JsonSerializable() +class StoreInfo extends Equatable { + const StoreInfo({ + this.localVersion = '', + this.storeVersion = '', + this.appStoreLink = '', + this.releaseNotes = '', + }); + + factory StoreInfo.fromJson(Map json) => + _$StoreInfoFromJson(json); + + final String localVersion; + final String storeVersion; + final String appStoreLink; + final String releaseNotes; + + StoreInfo copyWith({ + String? localVersion, + String? storeVersion, + String? appStoreLink, + String? releaseNotes, + }) { + return StoreInfo( + localVersion: localVersion ?? this.localVersion, + storeVersion: storeVersion ?? this.storeVersion, + appStoreLink: appStoreLink ?? this.appStoreLink, + releaseNotes: releaseNotes ?? this.releaseNotes, + ); + } + + Map toJson() => _$StoreInfoToJson(this); + + @override + List get props => + [localVersion, storeVersion, appStoreLink, releaseNotes]; +} diff --git a/pubspec.lock b/pubspec.lock index d702165a5..da9b584c9 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -993,6 +993,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.1" + new_version: + dependency: "direct main" + description: + name: new_version + url: "https://pub.dartlang.org" + source: hosted + version: "0.3.1" nm: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index bee3cdac0..9a7787487 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: altme description: AltMe Flutter App -version: 1.8.11+140 +version: 1.0.0+100 publish_to: none environment: @@ -69,6 +69,7 @@ dependencies: logger: ^1.1.0 mobile_scanner: ^3.0.0-beta.1 network_image_mock: ^2.1.0 + new_version: ^0.3.1 package_info_plus: ^1.3.0 passbase_flutter: ^2.13.3 path: ^1.8.0