diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 59a28dd5ed..365b4dadc7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,7 +41,7 @@ jobs: # Build independent apk. - name: Build - run: flutter build apk --release --flavor independent && mv build/app/outputs/flutter-apk/app-independent-release.apk build/app/outputs/flutter-apk/ente-auth.apk + run: flutter build apk --release --flavor independent --dart-define=app.flavor=independent && mv build/app/outputs/flutter-apk/app-independent-release.apk build/app/outputs/flutter-apk/ente-auth.apk env: SIGNING_KEY_PATH: "/home/runner/work/_temp/keystore/ente_auth_key.jks" SIGNING_KEY_ALIAS: ${{ secrets.SIGNING_KEY_ALIAS }} @@ -50,7 +50,7 @@ jobs: # Build Play store aab. - name: Build - run: flutter build appbundle --release --flavor playstore + run: flutter build appbundle --release --flavor playstore --dart-define=app.flavor=playstore env: SIGNING_KEY_PATH: "/home/runner/work/_temp/keystore/ente_auth_key.jks" SIGNING_KEY_ALIAS: ${{ secrets.SIGNING_KEY_ALIAS }} diff --git a/lib/services/update_service.dart b/lib/services/update_service.dart index 7d0fd3314a..ff37741522 100644 --- a/lib/services/update_service.dart +++ b/lib/services/update_service.dart @@ -5,17 +5,18 @@ import 'dart:io'; import 'package:ente_auth/core/constants.dart'; import 'package:ente_auth/core/network.dart'; import 'package:ente_auth/services/notification_service.dart'; -import 'package:flutter/foundation.dart'; import 'package:logging/logging.dart'; import 'package:package_info_plus/package_info_plus.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:tuple/tuple.dart'; +import 'package:url_launcher/url_launcher_string.dart'; class UpdateService { UpdateService._privateConstructor(); static final UpdateService instance = UpdateService._privateConstructor(); static const kUpdateAvailableShownTimeKey = "update_available_shown_time_key"; + static const String flavor = String.fromEnvironment('app.flavor'); LatestVersionInfo? _latestVersion; final _logger = Logger("UpdateService"); @@ -93,6 +94,12 @@ class UpdateService { // Note: in auth, currently we don't have a way to identify if the // app was installed from play store, f-droid or github based on pkg name if (Platform.isAndroid) { + if(flavor == "playstore") { + return const Tuple2( + "Play Store", + "market://details??id=io.ente.auth", + ); + } return const Tuple2( "AlternativeTo", "https://alternativeto.net/software/ente-authenticator/about/", @@ -104,11 +111,25 @@ class UpdateService { ); } - bool isIndependent() { - if (Platform.isIOS) { - return false; + Future launchReviewUrl() async { + final String url = getRateDetails().item2; + try { + await launchUrlString(url, mode: LaunchMode.externalApplication); + } catch (e) { + _logger.severe("Failed top open launch url $url", e); + // Fall back if we fail to open play-store market app on android + if (Platform.isAndroid && url.startsWith("market://")) { + launchUrlString( + "https://play.google.com/store/apps/details?id=io" + ".ente.auth", + mode: LaunchMode.externalApplication, + ).ignore(); + } } - return kDebugMode || _packageInfo.packageName.endsWith("independent"); + } + + bool isIndependent() { + return flavor == "independent" || _packageInfo.packageName.endsWith("independent"); } } diff --git a/lib/ui/settings/data/import/encrypted_ente_import.dart b/lib/ui/settings/data/import/encrypted_ente_import.dart index 50616ef6cb..986d3f5772 100644 --- a/lib/ui/settings/data/import/encrypted_ente_import.dart +++ b/lib/ui/settings/data/import/encrypted_ente_import.dart @@ -10,6 +10,7 @@ import 'package:ente_auth/store/code_store.dart'; import 'package:ente_auth/ui/components/buttons/button_widget.dart'; import 'package:ente_auth/ui/components/dialog_widget.dart'; import 'package:ente_auth/ui/components/models/button_type.dart'; +import 'package:ente_auth/ui/settings/data/import/import_success.dart'; import 'package:ente_auth/utils/crypto_util.dart'; import 'package:ente_auth/utils/dialog_util.dart'; import 'package:ente_auth/utils/toast_util.dart'; @@ -129,18 +130,7 @@ Future _decryptExportData( }, ); if (importedCodeCount != null) { - final DialogWidget dialog = choiceDialog( - title: context.l10n.importSuccessTitle, - body: context.l10n.importSuccessDesc(importedCodeCount!), - firstButtonLabel: l10n.ok, - firstButtonType: ButtonType.primary, - ); - await showConfettiDialog( - context: context, - dialogBuilder: (BuildContext context) { - return dialog; - }, - ); + await importSuccessDialog(context, importedCodeCount!); } } diff --git a/lib/ui/settings/data/import/google_auth_import.dart b/lib/ui/settings/data/import/google_auth_import.dart index f1ea5a35a8..6834f81e18 100644 --- a/lib/ui/settings/data/import/google_auth_import.dart +++ b/lib/ui/settings/data/import/google_auth_import.dart @@ -11,7 +11,7 @@ import 'package:ente_auth/ui/components/buttons/button_widget.dart'; import 'package:ente_auth/ui/components/dialog_widget.dart'; import 'package:ente_auth/ui/components/models/button_type.dart'; import 'package:ente_auth/ui/scanner_gauth_page.dart'; -import 'package:ente_auth/utils/dialog_util.dart'; +import 'package:ente_auth/ui/settings/data/import/import_success.dart'; import 'package:flutter/material.dart'; import 'package:flutter/widgets.dart'; import 'package:logging/logging.dart'; @@ -57,18 +57,7 @@ Future showGoogleAuthInstruction(BuildContext context) async { await CodeStore.instance.addCode(code, shouldSync: false); } unawaited(AuthenticatorService.instance.sync()); - final DialogWidget dialog = choiceDialog( - title: context.l10n.importSuccessTitle, - body: context.l10n.importSuccessDesc(codes.length ?? 0), - firstButtonLabel: l10n.ok, - firstButtonType: ButtonType.primary, - ); - await showConfettiDialog( - context: context, - dialogBuilder: (BuildContext context) { - return dialog; - }, - ); + importSuccessDialog(context, codes.length); } } } diff --git a/lib/ui/settings/data/import/import_service.dart b/lib/ui/settings/data/import/import_service.dart index 0d4782e822..5a71a3753a 100644 --- a/lib/ui/settings/data/import/import_service.dart +++ b/lib/ui/settings/data/import/import_service.dart @@ -1,4 +1,3 @@ - import 'package:ente_auth/ui/settings/data/import/encrypted_ente_import.dart'; import 'package:ente_auth/ui/settings/data/import/google_auth_import.dart'; import 'package:ente_auth/ui/settings/data/import/plain_text_import.dart'; @@ -7,14 +6,14 @@ import 'package:ente_auth/ui/settings/data/import_page.dart'; import 'package:flutter/cupertino.dart'; class ImportService { - static final ImportService _instance = ImportService._internal(); + factory ImportService() => _instance; + ImportService._internal(); - Future initiateImport(BuildContext context,ImportType type) async { - switch(type) { - + Future initiateImport(BuildContext context, ImportType type) async { + switch (type) { case ImportType.plainText: showImportInstructionDialog(context); break; @@ -31,4 +30,4 @@ class ImportService { break; } } -} \ No newline at end of file +} diff --git a/lib/ui/settings/data/import/import_success.dart b/lib/ui/settings/data/import/import_success.dart new file mode 100644 index 0000000000..cc77248e8b --- /dev/null +++ b/lib/ui/settings/data/import/import_success.dart @@ -0,0 +1,26 @@ +import 'package:ente_auth/l10n/l10n.dart'; +import 'package:ente_auth/ui/components/dialog_widget.dart'; +import 'package:ente_auth/ui/components/models/button_type.dart'; +import 'package:ente_auth/utils/dialog_util.dart'; +import 'package:flutter/cupertino.dart'; + +Future importSuccessDialog(BuildContext context, int count) async { + final DialogWidget dialog = choiceDialog( + title: context.l10n.importSuccessTitle, + body: context.l10n.importSuccessDesc(count), + firstButtonLabel: context.l10n.ok, + firstButtonOnTap: () async { + Navigator.of(context).pop(); + if(Navigator.of(context).canPop()) { + Navigator.of(context).pop(); + } + }, + firstButtonType: ButtonType.primary, + ); + await showConfettiDialog( + context: context, + dialogBuilder: (BuildContext context) { + return dialog; + }, + ); +} diff --git a/lib/ui/settings/data/import/plain_text_import.dart b/lib/ui/settings/data/import/plain_text_import.dart index 2731df2651..e61e0891ba 100644 --- a/lib/ui/settings/data/import/plain_text_import.dart +++ b/lib/ui/settings/data/import/plain_text_import.dart @@ -7,8 +7,7 @@ import 'package:ente_auth/l10n/l10n.dart'; import 'package:ente_auth/models/code.dart'; import 'package:ente_auth/services/authenticator_service.dart'; import 'package:ente_auth/store/code_store.dart'; -import 'package:ente_auth/ui/components/dialog_widget.dart'; -import 'package:ente_auth/ui/components/models/button_type.dart'; +import 'package:ente_auth/ui/settings/data/import/import_success.dart'; import 'package:ente_auth/utils/dialog_util.dart'; import 'package:file_picker/file_picker.dart'; import 'package:flutter/cupertino.dart'; @@ -125,18 +124,7 @@ Future _pickImportFile(BuildContext context) async { } unawaited(AuthenticatorService.instance.sync()); await progressDialog.hide(); - final DialogWidget dialog = choiceDialog( - title: context.l10n.importSuccessTitle, - body: context.l10n.importSuccessDesc(parsedCodes.length), - firstButtonLabel: l10n.ok, - firstButtonType: ButtonType.primary, - ); - await showConfettiDialog( - context: context, - dialogBuilder: (BuildContext context) { - return dialog; - }, - ); + await importSuccessDialog(context, parsedCodes.length); } catch (e) { await progressDialog.hide(); await showErrorDialog( diff --git a/lib/ui/settings/data/import/raivo_plain_text_import.dart b/lib/ui/settings/data/import/raivo_plain_text_import.dart index e118a85ec8..ab5d018829 100644 --- a/lib/ui/settings/data/import/raivo_plain_text_import.dart +++ b/lib/ui/settings/data/import/raivo_plain_text_import.dart @@ -9,6 +9,7 @@ import 'package:ente_auth/store/code_store.dart'; import 'package:ente_auth/ui/components/buttons/button_widget.dart'; import 'package:ente_auth/ui/components/dialog_widget.dart'; import 'package:ente_auth/ui/components/models/button_type.dart'; +import 'package:ente_auth/ui/settings/data/import/import_success.dart'; import 'package:ente_auth/utils/dialog_util.dart'; import 'package:file_picker/file_picker.dart'; import 'package:flutter/cupertino.dart'; @@ -57,18 +58,7 @@ Future _pickRaivoJsonFile(BuildContext context) async { int? count = await _processRaivoExportFile(context, path); await progressDialog.hide(); if(count != null) { - final DialogWidget dialog = choiceDialog( - title: context.l10n.importSuccessTitle, - body: context.l10n.importSuccessDesc(count ?? 0), - firstButtonLabel: l10n.ok, - firstButtonType: ButtonType.primary, - ); - await showConfettiDialog( - context: context, - dialogBuilder: (BuildContext context) { - return dialog; - }, - ); + await importSuccessDialog(context, count); } } catch (e) { await progressDialog.hide();