From 0e9586bffc633a92ea5fcb6b8db42d5fc78c5cb3 Mon Sep 17 00:00:00 2001 From: Lukas Schreiner Date: Fri, 8 Dec 2023 09:37:35 +0100 Subject: [PATCH 01/10] Update dependencies + switch to mobile_scanner for more stable scan experience --- .gitlab-ci.yml | 4 +- android/app/build.gradle | 4 +- lib/main.dart | 9 +- lib/storage/config.dart | 2 +- lib/ui/authscanui.dart | 33 +++---- lib/ui/authui.dart | 7 +- lib/ui/settings/mainsettings.dart | 6 +- lib/ui/settings/plansettingsui.dart | 2 +- lib/ui/wizard.dart | 90 +++++++++---------- macos/Flutter/GeneratedPluginRegistrant.swift | 2 + pubspec.lock | 90 +++++++++---------- pubspec.yaml | 23 +++-- web/index.html | 1 + 13 files changed, 139 insertions(+), 134 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 3a4974c..6a10fe0 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -256,8 +256,8 @@ build:ios: - | echo "Reset default keychain" security default-keychain -d user -s "login.keychain" - echo "Delete keychain again" - security delete-keychain "$MATCH_KEYCHAIN_NAME" + #echo "Delete keychain again" + #security delete-keychain "$MATCH_KEYCHAIN_NAME" echo "Delete downloaded mobile provision profiles" rm -Rf "$HOME/Library/MobileDevice/Provisioning Profiles/*.mobileprovision" tags: diff --git a/android/app/build.gradle b/android/app/build.gradle index 49d3535..9ade351 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -57,7 +57,7 @@ android { applicationId "de.fls_wiesbaden.vplan" // You can update the following values to match your application needs. // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration. - minSdkVersion 20 + minSdkVersion 21 targetSdkVersion 34 versionCode flutterVersionCode.toInteger() versionName flutterVersionName @@ -100,5 +100,5 @@ dependencies { implementation 'androidx.window:window:1.0.0' implementation 'androidx.window:window-java:1.0.0' implementation('com.github.UnifiedPush:android-foss_embedded_fcm_distributor:1.0.0-beta3') - coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5' + coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.2.2' } diff --git a/lib/main.dart b/lib/main.dart index 36d1909..92008a8 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -156,10 +156,15 @@ class _FlsVplanAppState extends State { @override void initState() { super.initState(); + final log = getVPlanLogger(); BackgroundPush.initialize(); _isAndroidPermissionGranted(); - _requestPermissions(); + try { + _requestPermissions(); + } catch(e) { + log.severe("Got exception on requesting permission: ${e.toString()}"); + } } Future _isAndroidPermissionGranted() async { @@ -210,7 +215,7 @@ class _FlsVplanAppState extends State { flutterLocalNotificationsPlugin.resolvePlatformSpecificImplementation< AndroidFlutterLocalNotificationsPlugin>(); - granted = await androidImplementation?.requestPermission(); + granted = await androidImplementation?.requestNotificationsPermission(); } else { log.info("Notifications disabled as not supported."); } diff --git a/lib/storage/config.dart b/lib/storage/config.dart index 714be92..1d2f700 100644 --- a/lib/storage/config.dart +++ b/lib/storage/config.dart @@ -190,7 +190,7 @@ class Config extends ChangeNotifier { if (await _storage.containsKey(key: configKeyAddRegularPlan)) { return (await _storage.read(key: configKeyAddRegularPlan))! == 'true'; } else { - return false; + return true; } } diff --git a/lib/ui/authscanui.dart b/lib/ui/authscanui.dart index 9c8e8ad..760153d 100644 --- a/lib/ui/authscanui.dart +++ b/lib/ui/authscanui.dart @@ -1,8 +1,10 @@ +import 'dart:typed_data'; + import 'package:de_fls_wiesbaden_vplan/ui/helper/consts.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter/material.dart'; import 'package:logging/logging.dart'; -import 'package:qr_code_scanner/qr_code_scanner.dart'; +import 'package:mobile_scanner/mobile_scanner.dart'; /// Provides widget to scan some kind of /// login card for authentication. @@ -17,32 +19,22 @@ class AuthScanUi extends StatefulWidget { } class _AuthScanUi extends State { - final GlobalKey qrKey = GlobalKey(debugLabel: 'QR'); - Barcode? result; - QRViewController? controller; - String? scanResult; @override Widget build(BuildContext context) { final log = Logger(vplanLoggerId); - - void onQRViewCreated(QRViewController controller) { - this.controller = controller; - controller.scannedDataStream.listen((scanData) { - setState(() { - result = scanData; - scanResult = scanData.code; - }); - log.finest("Scanned barcode: $scanResult"); - Navigator.pop(context, scanResult); - }); - } return Scaffold( appBar: AppBar(title: Text(AppLocalizations.of(context)!.loginLoginCard)), - body: QRView( - key: qrKey, - onQRViewCreated: onQRViewCreated, + body: MobileScanner( + onDetect: (capture) { + final List barcodes = capture.barcodes; + if (barcodes.isNotEmpty) { + String? scanResult = barcodes.first.rawValue; + log.finest("Scanned barcode: $scanResult"); + Navigator.pop(context, scanResult); + } + }, ) ); @@ -50,7 +42,6 @@ class _AuthScanUi extends State { @override void dispose() { - controller?.dispose(); super.dispose(); } } \ No newline at end of file diff --git a/lib/ui/authui.dart b/lib/ui/authui.dart index 1169c9c..3dab887 100644 --- a/lib/ui/authui.dart +++ b/lib/ui/authui.dart @@ -67,7 +67,7 @@ class _AuthUi extends State { body: FutureBuilder( future: _authController.isLoggedIn().then((value) { log.finer( - "Got a value whether we're logged in: ${value.toString()}"); + "[authui] Got a value whether we're logged in: ${value.toString()}"); if (value) { Navigator.pushReplacement( context, @@ -348,20 +348,21 @@ class _AuthUi extends State { Future _login() async { final log = Logger(vplanLoggerId); bool before = isLoggedIn.value; + final appLocalizer = AppLocalizations.of(context)!; // login call happens here ↓ errorMessage = null; bool loginOK = await _authController .login() .timeout(const Duration(seconds: 2), onTimeout: () { - errorMessage = AppLocalizations.of(context)!.loginNotPossibleInternet; + errorMessage = appLocalizer.loginNotPossibleInternet; return false; }); log.finest( "Login triggered and got result: ${loginOK ? "Perfect!" : "Failed!"}"); if (!loginOK && errorMessage == null) { - errorMessage = AppLocalizations.of(context)!.loginNotPossibleCredentials; + errorMessage = appLocalizer.loginNotPossibleCredentials; } bool after = await _authController.isLoggedIn(); if (before != after) { diff --git a/lib/ui/settings/mainsettings.dart b/lib/ui/settings/mainsettings.dart index ed4e8ad..2bd0e11 100644 --- a/lib/ui/settings/mainsettings.dart +++ b/lib/ui/settings/mainsettings.dart @@ -14,8 +14,9 @@ import 'package:provider/provider.dart'; /// E.g. plan mode /// and offers possibility to log out. class GeneralSettingsUi extends StatefulWidget { + final bool isWizard; - const GeneralSettingsUi({super.key}); + const GeneralSettingsUi({super.key, this.isWizard = false}); @override State createState() => _GeneralSettingsUi(); @@ -55,7 +56,7 @@ class _GeneralSettingsUi extends State { return FutureBuilder( future: _authController.isLoggedIn().then((value) { - log.finer("Got a value whether we're logged in: ${value.toString()}"); + log.finer("[mainsettings] Got a value whether we're logged in: ${value.toString()}"); if (!value) { Navigator.pushReplacement( context, @@ -166,6 +167,7 @@ class _GeneralSettingsUi extends State { onPressed: () { setState(() { AuthController.getInstance().logout(); + Config.getInstance().setFirstCallDone(false); Navigator.of(context).pop(); }); }, diff --git a/lib/ui/settings/plansettingsui.dart b/lib/ui/settings/plansettingsui.dart index 083d6aa..199f5f5 100644 --- a/lib/ui/settings/plansettingsui.dart +++ b/lib/ui/settings/plansettingsui.dart @@ -51,7 +51,7 @@ class _PlanSettingsUi extends State { child: Text(AppLocalizations.of(context)!.general, style: TextStyle(color: PlanColors.PrimaryTextColor, fontWeight: FontWeight.bold, fontSize: 16)) ), Divider(color: PlanColors.BorderColor, height: 5), - const GeneralSettingsUi() + GeneralSettingsUi(isWizard: widget.isWizard) ]; return Padding( diff --git a/lib/ui/wizard.dart b/lib/ui/wizard.dart index b4ddcbc..5b4a48c 100644 --- a/lib/ui/wizard.dart +++ b/lib/ui/wizard.dart @@ -9,60 +9,54 @@ import 'package:provider/provider.dart'; class Wizard extends StatefulWidget { const Wizard({super.key}); - + @override State createState() => _Wizard(); - } class _Wizard extends State { @override Widget build(BuildContext context) { PlanStorage ps = context.select((PlanStorage ps) => ps); - - return FutureBuilder(future: ps.load(), builder: (context, snapshot) { - if (snapshot.connectionState != ConnectionState.done) { - return const Center(child: CircularProgressIndicator()); - } else { - return Scaffold( - backgroundColor: PlanColors.AppBackgroundColor, - body: const SafeArea( - bottom: false, - child: PlanSettingsUi(isWizard: true) - ), - bottomNavigationBar: SafeArea( - top: false, - left: false, - right: false, - child: BottomNavigationBar( - items: [ - BottomNavigationBarItem( - icon: const Icon(Icons.cancel_outlined), - label: AppLocalizations.of(context)!.cancel, - ), - BottomNavigationBarItem( - icon: const Icon(Icons.navigate_next), - label: AppLocalizations.of(context)!.go - ) - ], - currentIndex: 1, - onTap: (value) async { - if (value == 0) { - await AuthController.getInstance().logout(); - // ignore: use_build_context_synchronously - Navigator.of(context).pop(); - } else { - await Config.getInstance().setFirstCallDone(true); - ps.refresh(); - // ignore: use_build_context_synchronously - Navigator.of(context).pop(); - } - }, - ) - ) - ); - } - }); - } -} \ No newline at end of file + return FutureBuilder( + future: ps.load(), + builder: (context, snapshot) { + if (snapshot.connectionState != ConnectionState.done) { + return const Center(child: CircularProgressIndicator()); + } else { + return Scaffold( + backgroundColor: PlanColors.AppBackgroundColor, + body: const SafeArea( + bottom: false, child: PlanSettingsUi(isWizard: true)), + bottomNavigationBar: SafeArea( + top: false, + left: false, + right: false, + child: BottomNavigationBar( + items: [ + BottomNavigationBarItem( + icon: const Icon(Icons.cancel_outlined), + label: AppLocalizations.of(context)!.cancel, + ), + BottomNavigationBarItem( + icon: const Icon(Icons.navigate_next), + label: AppLocalizations.of(context)!.go) + ], + currentIndex: 1, + onTap: (value) async { + final navigator = + Navigator.of(context); // store the Navigator + if (value == 0) { + await AuthController.getInstance().logout(); + } else { + await Config.getInstance().setFirstCallDone(true); + await ps.refresh(); + } + navigator.pop(); + }, + ))); + } + }); + } +} diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index a75ce44..3ea8893 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -7,6 +7,7 @@ import Foundation import flutter_local_notifications import flutter_secure_storage_macos +import mobile_scanner import package_info_plus import path_provider_foundation import share_plus @@ -16,6 +17,7 @@ import url_launcher_macos func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { FlutterLocalNotificationsPlugin.register(with: registry.registrar(forPlugin: "FlutterLocalNotificationsPlugin")) FlutterSecureStoragePlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStoragePlugin")) + MobileScannerPlugin.register(with: registry.registrar(forPlugin: "MobileScannerPlugin")) FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin")) diff --git a/pubspec.lock b/pubspec.lock index adc44a3..22b3303 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,26 +5,26 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: ae92f5d747aee634b87f89d9946000c2de774be1d6ac3e58268224348cd0101a + sha256: eb376e9acf6938204f90eb3b1f00b578640d3188b4c8a8ec054f9f479af8d051 url: "https://pub.dev" source: hosted - version: "61.0.0" + version: "64.0.0" add_2_calendar: dependency: "direct main" description: name: add_2_calendar - sha256: dbcd0bf296fbbe00861a6f101af8cdb3c163a8c3ff5d3c99a4b081c2f37c724f + sha256: "8d7a82aba607d35f2a5bc913419e12f865a96a350a8ad2509a59322bc161f200" url: "https://pub.dev" source: hosted - version: "2.2.5" + version: "3.0.1" analyzer: dependency: transitive description: name: analyzer - sha256: ea3d8652bda62982addfd92fdc2d0214e5f82e43325104990d4f4c4a2a313562 + sha256: "69f54f967773f6c26c7dcb13e93d7ccee8b17a641689da39e878d5cf13b06893" url: "https://pub.dev" source: hosted - version: "5.13.0" + version: "6.2.0" args: dependency: transitive description: @@ -85,10 +85,10 @@ packages: dependency: "direct dev" description: name: build_runner - sha256: "10c6bcdbf9d049a0b666702cf1cee4ddfdc38f02a19d35ae392863b47519848b" + sha256: "67d591d602906ef9201caf93452495ad1812bea2074f04e25dbd7c133785821b" url: "https://pub.dev" source: hosted - version: "2.4.6" + version: "2.4.7" build_runner_core: dependency: transitive description: @@ -109,10 +109,10 @@ packages: dependency: transitive description: name: built_value - sha256: "723b4021e903217dfc445ec4cf5b42e27975aece1fc4ebbc1ca6329c2d9fb54e" + sha256: "69acb7007eb2a31dc901512bfe0f7b767168be34cb734835d54c070bfa74c1b2" url: "https://pub.dev" source: hosted - version: "8.7.0" + version: "8.8.0" characters: dependency: transitive description: @@ -141,10 +141,10 @@ packages: dependency: transitive description: name: code_builder - sha256: "1be9be30396d7e4c0db42c35ea6ccd7cc6a1e19916b5dc64d6ac216b5544d677" + sha256: b2151ce26a06171005b379ecff6e08d34c470180ffe16b8e14b6d52be292b55f url: "https://pub.dev" source: hosted - version: "4.7.0" + version: "4.8.0" collection: dependency: transitive description: @@ -165,10 +165,10 @@ packages: dependency: transitive description: name: cross_file - sha256: "445db18de832dba8d851e287aff8ccf169bed30d2e94243cb54c7d2f1ed2142c" + sha256: "2f9d2cbccb76127ba28528cb3ae2c2326a122446a83de5a056aaa3880d3882c5" url: "https://pub.dev" source: hosted - version: "0.3.3+6" + version: "0.3.3+7" crypto: dependency: transitive description: @@ -189,18 +189,18 @@ packages: dependency: transitive description: name: dart_style - sha256: "1efa911ca7086affd35f463ca2fc1799584fb6aa89883cf0af8e3664d6a02d55" + sha256: "40ae61a5d43feea6d24bd22c0537a6629db858963b99b4bc1c3db80676f32368" url: "https://pub.dev" source: hosted - version: "2.3.2" + version: "2.3.4" dbus: dependency: transitive description: name: dbus - sha256: "6f07cba3f7b3448d42d015bfd3d53fe12e5b36da2423f23838efc1d5fb31a263" + sha256: "365c771ac3b0e58845f39ec6deebc76e3276aa9922b0cc60840712094d9047ac" url: "https://pub.dev" source: hosted - version: "0.7.8" + version: "0.7.10" dependency_validator: dependency: transitive description: @@ -258,18 +258,18 @@ packages: dependency: "direct dev" description: name: flutter_lints - sha256: a25a15ebbdfc33ab1cd26c63a6ee519df92338a9c10f122adda92938253bef04 + sha256: e2a421b7e59244faef694ba7b30562e489c2b489866e505074eb005cd7060db7 url: "https://pub.dev" source: hosted - version: "2.0.3" + version: "3.0.1" flutter_local_notifications: dependency: "direct main" description: name: flutter_local_notifications - sha256: "501ed9d54f1c8c0535b7991bade36f9e7e3b45a2346401f03775c1ec7a3c06ae" + sha256: bb5cd63ff7c91d6efe452e41d0d0ae6348925c82eafd10ce170ef585ea04776e url: "https://pub.dev" source: hosted - version: "15.1.2" + version: "16.2.0" flutter_local_notifications_linux: dependency: transitive description: @@ -295,10 +295,10 @@ packages: dependency: "direct main" description: name: flutter_secure_storage - sha256: "22dbf16f23a4bcf9d35e51be1c84ad5bb6f627750565edd70dab70f3ff5fff8f" + sha256: ffdbb60130e4665d2af814a0267c481bcf522c41ae2e43caf69fa0146876d685 url: "https://pub.dev" source: hosted - version: "8.1.0" + version: "9.0.0" flutter_secure_storage_linux: dependency: transitive description: @@ -335,10 +335,10 @@ packages: dependency: transitive description: name: flutter_secure_storage_windows - sha256: "38f9501c7cb6f38961ef0e1eacacee2b2d4715c63cc83fe56449c4d3d0b47255" + sha256: "5809c66f9dd3b4b93b0a6e2e8561539405322ee767ac2f64d084e2ab5429d108" url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "3.0.0" flutter_svg: dependency: "direct main" description: @@ -449,10 +449,10 @@ packages: dependency: transitive description: name: lints - sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452" + sha256: cbf8d4b858bb0134ef3ef87841abdf8d63bfc255c266b7bf6b39daa1085c4290 url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "3.0.0" localstorage: dependency: "direct main" description: @@ -509,14 +509,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.4" + mobile_scanner: + dependency: "direct main" + description: + name: mobile_scanner + sha256: c3e5bba1cb626b6ab4fc46610f72a136803f6854267967e19f4a4a6a31ff9b74 + url: "https://pub.dev" + source: hosted + version: "3.5.5" mockito: dependency: "direct dev" description: name: mockito - sha256: "7d5b53bcd556c1bc7ffbe4e4d5a19c3e112b7e925e9e172dd7c6ad0630812616" + sha256: "4b693867cee1853c9d1d7ecc1871f27f39b2ef2c13c0d8d8507dfe5bebd8aaf1" url: "https://pub.dev" source: hosted - version: "5.4.2" + version: "5.4.3" nested: dependency: transitive description: @@ -633,10 +641,10 @@ packages: dependency: transitive description: name: plugin_platform_interface - sha256: da3fdfeccc4d4ff2da8f8c556704c08f912542c5fb3cf2233ed75372384a034d + sha256: f4f88d4a900933e7267e2b353594774fc0d07fb072b47eedcd5b54e1ea3269f8 url: "https://pub.dev" source: hosted - version: "2.1.6" + version: "2.1.7" pool: dependency: transitive description: @@ -669,14 +677,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.2.3" - qr_code_scanner: - dependency: "direct main" - description: - name: qr_code_scanner - sha256: f23b68d893505a424f0bd2e324ebea71ed88465d572d26bb8d2e78a4749591fd - url: "https://pub.dev" - source: hosted - version: "1.0.1" share_plus: dependency: "direct main" description: @@ -910,10 +910,10 @@ packages: dependency: transitive description: name: url_launcher_ios - sha256: "4ac97281cf60e2e8c5cc703b2b28528f9b50c8f7cebc71df6bdf0845f647268a" + sha256: bba3373219b7abb6b5e0d071b0fe66dfbe005d07517a68e38d4fc3638f35c6d3 url: "https://pub.dev" source: hosted - version: "6.2.0" + version: "6.2.1" url_launcher_linux: dependency: transitive description: @@ -1022,10 +1022,10 @@ packages: dependency: transitive description: name: win32 - sha256: "350a11abd2d1d97e0cc7a28a81b781c08002aa2864d9e3f192ca0ffa18b06ed3" + sha256: b0f37db61ba2f2e9b7a78a1caece0052564d1bc70668156cf3a29d676fe4e574 url: "https://pub.dev" source: hosted - version: "5.0.9" + version: "5.1.1" workmanager: dependency: "direct main" description: @@ -1059,5 +1059,5 @@ packages: source: hosted version: "3.1.2" sdks: - dart: ">=3.1.2 <4.0.0" + dart: ">=3.1.3 <4.0.0" flutter: ">=3.13.0" diff --git a/pubspec.yaml b/pubspec.yaml index 73dd9d1..e7dadce 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -18,7 +18,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # In Windows, build-name is used as the major, minor, and patch parts # of the product and file versions while build-number is used as the build suffix. -version: 3.0.7+30007 +version: 3.0.8+30008 environment: sdk: '>=2.19.4 <3.0.0' @@ -41,16 +41,25 @@ dependencies: provider: ^6.0.5 localstore: ^1.3.5 localstorage: ^4.0.1+2 - flutter_secure_storage: ^8.0.0 + flutter_secure_storage: ^9.0.0 intl: ^0.18.0 dots_indicator: ^3.0.0 flutter_svg: ^2.0.4 workmanager: ^0.5.1 - flutter_local_notifications: ^15.1.0+1 + flutter_local_notifications: ^16.2.0 share_plus: ^7.0.2 - add_2_calendar: ^2.2.3 - # mobile_scanner: ^3.2.0 > anti-feature (uses ml-kit) - qr_code_scanner: ^1.0.1 # maintenance mode + add_2_calendar: ^3.0.1 + # for scanning login cards, we need a QR scanner. + # We really would love to see a free library, which is not + # depending on google or firebase. Unfortunately, its pretty + # difficult. The qr_code_scanner is in maintenance mode and + # the last tests like: + # - https://github.com/juliuscanute/qr_code_scanner/issues/633 + # - https://github.com/juliuscanute/qr_code_scanner/issues/719 + # That means for now, when using mobile_scanner, we really have + # a problem to be available in projects like F-Droid. + mobile_scanner: ^3.5.0 # > anti-feature (uses ml-kit) + #qr_code_scanner: ^1.0.1 # maintenance mode; has some ugly bugs. logging: ^1.1.1 package_info_plus: ^4.0.2 url_launcher: ^6.1.10 @@ -68,7 +77,7 @@ dev_dependencies: # activated in the `analysis_options.yaml` file located at the root of your # package. See that file for information about deactivating specific lint # rules and activating additional ones. - flutter_lints: ^2.0.0 + flutter_lints: ^3.0.1 mockito: ^5.4.0 build_runner: ^2.3.3 diff --git a/web/index.html b/web/index.html index 756638a..e15ae63 100644 --- a/web/index.html +++ b/web/index.html @@ -31,6 +31,7 @@ FLS VPlan App +