diff --git a/.gitignore b/.gitignore index 277a7d5..ed519d7 100644 --- a/.gitignore +++ b/.gitignore @@ -10,9 +10,11 @@ test/full_coverage_test.dart *.swp .DS_Store .atom/ +.build/ .buildlog/ .history .svn/ +.swiftpm/ migrate_working_dir/ # IntelliJ related @@ -47,3 +49,6 @@ app.*.map.json /android/app/debug /android/app/profile /android/app/release + +# FVM Version Cache +.fvm/ \ No newline at end of file diff --git a/ios/Flutter/AppFrameworkInfo.plist b/ios/Flutter/AppFrameworkInfo.plist index 9625e10..1dc6cf7 100644 --- a/ios/Flutter/AppFrameworkInfo.plist +++ b/ios/Flutter/AppFrameworkInfo.plist @@ -21,6 +21,6 @@ CFBundleVersion 1.0 MinimumOSVersion - 11.0 + 13.0 diff --git a/ios/Flutter/Debug.xcconfig b/ios/Flutter/Debug.xcconfig index 592ceee..ec97fc6 100644 --- a/ios/Flutter/Debug.xcconfig +++ b/ios/Flutter/Debug.xcconfig @@ -1 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" #include "Generated.xcconfig" diff --git a/ios/Flutter/Release.xcconfig b/ios/Flutter/Release.xcconfig index 592ceee..c4855bf 100644 --- a/ios/Flutter/Release.xcconfig +++ b/ios/Flutter/Release.xcconfig @@ -1 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" #include "Generated.xcconfig" diff --git a/ios/Podfile b/ios/Podfile new file mode 100644 index 0000000..16e3165 --- /dev/null +++ b/ios/Podfile @@ -0,0 +1,43 @@ +# Uncomment this line to define a global platform for your project +platform :ios, '14.0' + +# CocoaPods analytics sends network stats synchronously affecting flutter build latency. +ENV['COCOAPODS_DISABLE_STATS'] = 'true' + +project 'Runner', { + 'Debug' => :debug, + 'Profile' => :release, + 'Release' => :release, +} + +def flutter_root + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) + unless File.exist?(generated_xcode_build_settings_path) + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" + end + + File.foreach(generated_xcode_build_settings_path) do |line| + matches = line.match(/FLUTTER_ROOT\=(.*)/) + return matches[1].strip if matches + end + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" +end + +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) + +flutter_ios_podfile_setup + +target 'Runner' do + use_frameworks! + + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) +# target 'RunnerTests' do +# inherit! :search_paths +# end +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + flutter_additional_ios_build_settings(target) + end +end diff --git a/ios/Podfile.lock b/ios/Podfile.lock new file mode 100644 index 0000000..1820d93 --- /dev/null +++ b/ios/Podfile.lock @@ -0,0 +1,66 @@ +PODS: + - Flutter (1.0.0) + - integration_test (0.0.1): + - Flutter + - open_filex (0.0.2): + - Flutter + - package_info_plus (0.4.5): + - Flutter + - path_provider_foundation (0.0.1): + - Flutter + - FlutterMacOS + - share_plus (0.0.1): + - Flutter + - shared_preferences_foundation (0.0.1): + - Flutter + - FlutterMacOS + - url_launcher_ios (0.0.1): + - Flutter + - workmanager (0.0.1): + - Flutter + +DEPENDENCIES: + - Flutter (from `Flutter`) + - integration_test (from `.symlinks/plugins/integration_test/ios`) + - open_filex (from `.symlinks/plugins/open_filex/ios`) + - package_info_plus (from `.symlinks/plugins/package_info_plus/ios`) + - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`) + - share_plus (from `.symlinks/plugins/share_plus/ios`) + - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`) + - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) + - workmanager (from `.symlinks/plugins/workmanager/ios`) + +EXTERNAL SOURCES: + Flutter: + :path: Flutter + integration_test: + :path: ".symlinks/plugins/integration_test/ios" + open_filex: + :path: ".symlinks/plugins/open_filex/ios" + package_info_plus: + :path: ".symlinks/plugins/package_info_plus/ios" + path_provider_foundation: + :path: ".symlinks/plugins/path_provider_foundation/darwin" + share_plus: + :path: ".symlinks/plugins/share_plus/ios" + shared_preferences_foundation: + :path: ".symlinks/plugins/shared_preferences_foundation/darwin" + url_launcher_ios: + :path: ".symlinks/plugins/url_launcher_ios/ios" + workmanager: + :path: ".symlinks/plugins/workmanager/ios" + +SPEC CHECKSUMS: + Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467 + integration_test: 4a889634ef21a45d28d50d622cf412dc6d9f586e + open_filex: 432f3cd11432da3e39f47fcc0df2b1603854eff1 + package_info_plus: af8e2ca6888548050f16fa2f1938db7b5a5df499 + path_provider_foundation: bb55f6dbba17d0dccd6737fe6f7f34fbd0376880 + share_plus: 50da8cb520a8f0f65671c6c6a99b3617ed10a58a + shared_preferences_foundation: 7036424c3d8ec98dfe75ff1667cb0cd531ec82bb + url_launcher_ios: 7a95fa5b60cc718a708b8f2966718e93db0cef1b + workmanager: b89e4e4445d8b57ee2fdbf1c3925696ebe5b8990 + +PODFILE CHECKSUM: ec1ad48fafee7989ae02b93f14e4d03d1f0e05bb + +COCOAPODS: 1.16.2 diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index dfa0b35..68c987d 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 50; + objectVersion = 54; objects = { /* Begin PBXBuildFile section */ @@ -13,6 +13,7 @@ 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; + D0190EC4023141C93A5318E8 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9AE0C893C30B85278F5DF6A2 /* Pods_Runner.framework */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -32,6 +33,8 @@ 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 4C17CDF240BC5AE58F5C0AAE /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; + 4CC19D185F571E45AC7BB4FF /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; @@ -42,6 +45,8 @@ 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 9AE0C893C30B85278F5DF6A2 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + F47B29FE948DC5ED2705681A /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -49,12 +54,32 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + D0190EC4023141C93A5318E8 /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 5E3355700D4D226D390B38C6 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 9AE0C893C30B85278F5DF6A2 /* Pods_Runner.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 89E5EBCBCE76D5370988611D /* Pods */ = { + isa = PBXGroup; + children = ( + 4CC19D185F571E45AC7BB4FF /* Pods-Runner.debug.xcconfig */, + F47B29FE948DC5ED2705681A /* Pods-Runner.release.xcconfig */, + 4C17CDF240BC5AE58F5C0AAE /* Pods-Runner.profile.xcconfig */, + ); + name = Pods; + path = Pods; + sourceTree = ""; + }; 9740EEB11CF90186004384FC /* Flutter */ = { isa = PBXGroup; children = ( @@ -72,6 +97,8 @@ 9740EEB11CF90186004384FC /* Flutter */, 97C146F01CF9000F007C117D /* Runner */, 97C146EF1CF9000F007C117D /* Products */, + 89E5EBCBCE76D5370988611D /* Pods */, + 5E3355700D4D226D390B38C6 /* Frameworks */, ); sourceTree = ""; }; @@ -105,12 +132,14 @@ isa = PBXNativeTarget; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( + EB5CECB911C6292CB96F300E /* [CP] Check Pods Manifest.lock */, 9740EEB61CF901F6004384FC /* Run Script */, 97C146EA1CF9000F007C117D /* Sources */, 97C146EB1CF9000F007C117D /* Frameworks */, 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + 0BBD8B8AB681E2B94AB9A6ED /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -127,7 +156,7 @@ 97C146E61CF9000F007C117D /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 1300; + LastUpgradeCheck = 1510; ORGANIZATIONNAME = ""; TargetAttributes = { 97C146ED1CF9000F007C117D = { @@ -169,12 +198,31 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ + 0BBD8B8AB681E2B94AB9A6ED /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); inputPaths = ( + "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", ); name = "Thin Binary"; outputPaths = ( @@ -185,6 +233,7 @@ }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); @@ -197,6 +246,28 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; }; + EB5CECB911C6292CB96F300E /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -272,7 +343,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; @@ -349,7 +420,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -398,7 +469,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 11.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; diff --git a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index c87d15a..9c12df5 100644 --- a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -1,6 +1,6 @@ diff --git a/ios/Runner.xcworkspace/contents.xcworkspacedata b/ios/Runner.xcworkspace/contents.xcworkspacedata index 1d526a1..21a3cc1 100644 --- a/ios/Runner.xcworkspace/contents.xcworkspacedata +++ b/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -4,4 +4,7 @@ + + diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift index 70693e4..b636303 100644 --- a/ios/Runner/AppDelegate.swift +++ b/ios/Runner/AppDelegate.swift @@ -1,7 +1,7 @@ import UIKit import Flutter -@UIApplicationMain +@main @objc class AppDelegate: FlutterAppDelegate { override func application( _ application: UIApplication, diff --git a/l10n.yaml b/l10n.yaml index f80ae89..f06f950 100644 --- a/l10n.yaml +++ b/l10n.yaml @@ -1,4 +1,3 @@ -synthetic-package: false arb-dir: lib/l10n/locales template-arb-file: app_en.arb output-localization-file: app_localizations.dart diff --git a/lib/routes/about_page.dart b/lib/routes/about_page.dart index fb6a7a2..62f95b2 100644 --- a/lib/routes/about_page.dart +++ b/lib/routes/about_page.dart @@ -15,82 +15,85 @@ class AboutPage extends ConsumerWidget { Widget build(BuildContext context, WidgetRef ref) { return Scaffold( appBar: AppBar(title: Text(context.l10n.about)), - body: SingleChildScrollView( - child: Padding( + body: SafeArea( + child: SingleChildScrollView( + child: Padding( padding: const EdgeInsets.all(16), - child: Column( - children: [ - const PromoBlock(), - const SizedBox(height: 20), - Linkify( - text: context.l10n.appDescription, - // ignore: deprecated_member_use - textScaleFactor: MediaQuery.of(context).textScaleFactor, - style: Theme.of(context).textTheme.bodyMedium, - onOpen: (link) async { - unawaited(launchUrl(Uri.parse(link.url))); - }), - const SizedBox(height: 10), - Text(context.l10n.matthew10_8, - style: const TextStyle(fontStyle: FontStyle.italic)), - const SizedBox(height: 10), - Text(context.l10n.noCopyright), - const SizedBox(height: 20), - Align( - alignment: Alignment.topLeft, - child: Text(context.l10n.worksOffline, - style: Theme.of(context).textTheme.titleLarge)), - const SizedBox(height: 10), - Text(context.l10n.worksOfflineText), - const SizedBox(height: 20), - Align( - alignment: Alignment.topLeft, - child: Text( - context.l10n.secure, - style: Theme.of(context).textTheme.titleLarge, - )), - const SizedBox(height: 10), - Text(context.l10n.secureText), - const SizedBox(height: 20), - Align( - alignment: Alignment.topLeft, - child: Text(context.l10n.contributing, - style: Theme.of(context).textTheme.titleLarge)), - const SizedBox(height: 10), - Linkify( - text: context.l10n.contributingText, - // ignore: deprecated_member_use - textScaleFactor: MediaQuery.of(context).textScaleFactor, - style: Theme.of(context).textTheme.bodyMedium, - onOpen: (link) async { - unawaited(launchUrl(Uri.parse(link.url))); - }), - const SizedBox(height: 20), - Align( - alignment: Alignment.topLeft, - child: Text(context.l10n.openSource, - style: Theme.of(context).textTheme.titleLarge)), - const SizedBox(height: 10), - Linkify( - text: context.l10n.openSourceText, - // ignore: deprecated_member_use - textScaleFactor: MediaQuery.of(context).textScaleFactor, - style: Theme.of(context).textTheme.bodyMedium, - onOpen: (link) async { - unawaited(launchUrl(Uri.parse(link.url))); - }), - const SizedBox(height: 20), - Align( - alignment: Alignment.topLeft, - child: Text(context.l10n.version, - style: Theme.of(context).textTheme.titleLarge)), - const SizedBox(height: 10), - Align( - alignment: Alignment.topLeft, - child: Text(ref.read(packageInfoProvider).version)) - ], - )), - ), + child: Column( + children: [ + const PromoBlock(), + const SizedBox(height: 20), + Linkify( + text: context.l10n.appDescription, + // ignore: deprecated_member_use + textScaleFactor: MediaQuery.of(context).textScaleFactor, + style: Theme.of(context).textTheme.bodyMedium, + onOpen: (link) async { + unawaited(launchUrl(Uri.parse(link.url))); + }), + const SizedBox(height: 10), + Text(context.l10n.matthew10_8, + style: const TextStyle(fontStyle: FontStyle.italic)), + const SizedBox(height: 10), + Text(context.l10n.noCopyright), + const SizedBox(height: 20), + Align( + alignment: Alignment.topLeft, + child: Text(context.l10n.worksOffline, + style: Theme.of(context).textTheme.titleLarge)), + const SizedBox(height: 10), + Text(context.l10n.worksOfflineText), + const SizedBox(height: 20), + Align( + alignment: Alignment.topLeft, + child: Text( + context.l10n.secure, + style: Theme.of(context).textTheme.titleLarge, + )), + const SizedBox(height: 10), + Text(context.l10n.secureText), + const SizedBox(height: 20), + Align( + alignment: Alignment.topLeft, + child: Text(context.l10n.contributing, + style: Theme.of(context).textTheme.titleLarge)), + const SizedBox(height: 10), + Linkify( + text: context.l10n.contributingText, + // ignore: deprecated_member_use + textScaleFactor: MediaQuery.of(context).textScaleFactor, + style: Theme.of(context).textTheme.bodyMedium, + onOpen: (link) async { + unawaited(launchUrl(Uri.parse(link.url))); + }), + const SizedBox(height: 20), + Align( + alignment: Alignment.topLeft, + child: Text(context.l10n.openSource, + style: Theme.of(context).textTheme.titleLarge)), + const SizedBox(height: 10), + Linkify( + text: context.l10n.openSourceText, + // ignore: deprecated_member_use + textScaleFactor: MediaQuery.of(context).textScaleFactor, + style: Theme.of(context).textTheme.bodyMedium, + onOpen: (link) async { + unawaited(launchUrl(Uri.parse(link.url))); + }), + const SizedBox(height: 20), + Align( + alignment: Alignment.topLeft, + child: Text(context.l10n.version, + style: Theme.of(context).textTheme.titleLarge)), + const SizedBox(height: 10), + Align( + alignment: Alignment.topLeft, + child: Text(ref.read(packageInfoProvider).version)) + ], + ), + ), + ), + ), ); } } diff --git a/lib/routes/error_page.dart b/lib/routes/error_page.dart index 44821a3..08abd48 100644 --- a/lib/routes/error_page.dart +++ b/lib/routes/error_page.dart @@ -7,6 +7,7 @@ import 'package:flutter/material.dart'; /// This error page is shown to the user in case of internal errors. class ErrorPage extends StatelessWidget { final String message; + const ErrorPage(this.message, {super.key}); @override @@ -15,7 +16,8 @@ class ErrorPage extends StatelessWidget { return Scaffold( appBar: AppBar(title: const Text(Globals.appTitle)), drawer: const MainDrawer(null, null), - body: ErrorMessage( - context.l10n.error, context.l10n.internalError(message))); + body: SafeArea( + child: ErrorMessage( + context.l10n.error, context.l10n.internalError(message)))); } } diff --git a/lib/routes/home_page.dart b/lib/routes/home_page.dart index 4abecef..9b33073 100644 --- a/lib/routes/home_page.dart +++ b/lib/routes/home_page.dart @@ -18,9 +18,9 @@ class HomePage extends ConsumerWidget { title: const Text(Globals.appTitle), ), drawer: const MainDrawer(null, null), - body: TableOfContent(null, null, + body: SafeArea(child: TableOfContent(null, null, header: Padding( padding: const EdgeInsets.fromLTRB(12, 12, 12, 0), - child: Text(context.l10n.homeExplanation)))); + child: Text(context.l10n.homeExplanation))))); } } diff --git a/lib/routes/onboarding/download_languages_page.dart b/lib/routes/onboarding/download_languages_page.dart index 2649b6d..b5c0591 100644 --- a/lib/routes/onboarding/download_languages_page.dart +++ b/lib/routes/onboarding/download_languages_page.dart @@ -37,52 +37,54 @@ class DownloadLanguagesPage extends ConsumerWidget { return Scaffold( appBar: AppBar(title: Text(context.l10n.downloadLanguages)), - body: Padding( - padding: const EdgeInsets.all(20), - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - const SizedBox(height: 20), - Text(context.l10n.downloadLanguagesExplanation), - const SizedBox(height: 20), - Expanded( - child: LanguagesTable( - highlightLang: appLanguage.languageCode, - )), - const SizedBox(height: 20), - Row(children: [ - const Spacer(flex: 2), - ElevatedButton( - style: ElevatedButton.styleFrom( - shape: const StadiumBorder(), - ), - onPressed: () { - Navigator.pushReplacementNamed(context, '/onboarding/1'); - }, - child: Text(context.l10n.back), - ), - const Spacer(), - ElevatedButton( - style: buttonStyle, - onPressed: () async { - // Show warning if user hasn't downloaded his app language - if (!appLanguageDownloaded) { - await showDialog( - context: context, - builder: (context) { - return const MissingAppLanguageDialog(); - }); - return; - } - unawaited(Navigator.pushReplacementNamed( - context, getNextRoute(ref))); - }, - child: Text(context.l10n.continueText), - ), - const Spacer(flex: 2), - ]) - ], - ))); + body: SafeArea( + child: Padding( + padding: const EdgeInsets.all(20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + const SizedBox(height: 20), + Text(context.l10n.downloadLanguagesExplanation), + const SizedBox(height: 20), + Expanded( + child: LanguagesTable( + highlightLang: appLanguage.languageCode, + )), + const SizedBox(height: 20), + Row(children: [ + const Spacer(flex: 2), + ElevatedButton( + style: ElevatedButton.styleFrom( + shape: const StadiumBorder(), + ), + onPressed: () { + Navigator.pushReplacementNamed( + context, '/onboarding/1'); + }, + child: Text(context.l10n.back), + ), + const Spacer(), + ElevatedButton( + style: buttonStyle, + onPressed: () async { + // Show warning if user hasn't downloaded his app language + if (!appLanguageDownloaded) { + await showDialog( + context: context, + builder: (context) { + return const MissingAppLanguageDialog(); + }); + return; + } + unawaited(Navigator.pushReplacementNamed( + context, getNextRoute(ref))); + }, + child: Text(context.l10n.continueText), + ), + const Spacer(flex: 2), + ]) + ], + )))); } /// Which route should we continue with after this? diff --git a/lib/routes/onboarding/set_update_prefs_page.dart b/lib/routes/onboarding/set_update_prefs_page.dart index addb251..1444cc8 100644 --- a/lib/routes/onboarding/set_update_prefs_page.dart +++ b/lib/routes/onboarding/set_update_prefs_page.dart @@ -16,53 +16,61 @@ class SetUpdatePrefsPage extends ConsumerWidget { Widget build(BuildContext context, WidgetRef ref) { return Scaffold( appBar: AppBar(title: Text(context.l10n.updates)), - body: Padding( - padding: const EdgeInsets.all(20), - child: Column( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - const Spacer(), - Text(context.l10n.updatesExplanation), - const Spacer(flex: 2), - Text(context.l10n.checkFrequency, - style: Theme.of(context).textTheme.labelLarge), - const SizedBox(height: 10), - const DropdownButtonCheckFrequency(), - const Spacer(flex: 2), - Text(context.l10n.doAutomaticUpdates, - style: Theme.of(context).textTheme.labelLarge), - const SizedBox(height: 10), - const DropdownButtonAutomaticUpdates(), - const Spacer(flex: 8), - Row(children: [ - const Spacer(flex: 2), - ElevatedButton( - style: ElevatedButton.styleFrom( - shape: const StadiumBorder(), - ), - onPressed: () { - Navigator.pushReplacementNamed(context, '/onboarding/2'); - }, - child: Text(context.l10n.back), - ), - const Spacer(), - ElevatedButton( - style: ElevatedButton.styleFrom( - shape: const StadiumBorder(), - ), - onPressed: () { - // Make sure settings are saved: onboarding completed - ref.read(automaticUpdatesProvider.notifier).persistNow(); - ref.read(checkFrequencyProvider.notifier).persistNow(); - // Make sure background task gets scheduled - ref.read(backgroundSchedulerProvider.notifier).schedule(); - Navigator.pushReplacementNamed(context, '/home'); - }, - child: Text(context.l10n.letsGo), - ), - const Spacer(flex: 2), - ]) - ], - ))); + body: SafeArea( + child: Padding( + padding: const EdgeInsets.all(20), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + const Spacer(), + Text(context.l10n.updatesExplanation), + const Spacer(flex: 2), + Text(context.l10n.checkFrequency, + style: Theme.of(context).textTheme.labelLarge), + const SizedBox(height: 10), + const DropdownButtonCheckFrequency(), + const Spacer(flex: 2), + Text(context.l10n.doAutomaticUpdates, + style: Theme.of(context).textTheme.labelLarge), + const SizedBox(height: 10), + const DropdownButtonAutomaticUpdates(), + const Spacer(flex: 8), + Row(children: [ + const Spacer(flex: 2), + ElevatedButton( + style: ElevatedButton.styleFrom( + shape: const StadiumBorder(), + ), + onPressed: () { + Navigator.pushReplacementNamed( + context, '/onboarding/2'); + }, + child: Text(context.l10n.back), + ), + const Spacer(), + ElevatedButton( + style: ElevatedButton.styleFrom( + shape: const StadiumBorder(), + ), + onPressed: () { + // Make sure settings are saved: onboarding completed + ref + .read(automaticUpdatesProvider.notifier) + .persistNow(); + ref + .read(checkFrequencyProvider.notifier) + .persistNow(); + // Make sure background task gets scheduled + ref + .read(backgroundSchedulerProvider.notifier) + .schedule(); + Navigator.pushReplacementNamed(context, '/home'); + }, + child: Text(context.l10n.letsGo), + ), + const Spacer(flex: 2), + ]) + ], + )))); } } diff --git a/lib/routes/onboarding/welcome_page.dart b/lib/routes/onboarding/welcome_page.dart index 2417913..9d2c3bb 100644 --- a/lib/routes/onboarding/welcome_page.dart +++ b/lib/routes/onboarding/welcome_page.dart @@ -15,7 +15,7 @@ class WelcomePage extends StatelessWidget { Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: const Text(Globals.appTitle)), - body: const WelcomeScreen()); + body: const SafeArea(child: WelcomeScreen())); } } diff --git a/lib/routes/settings_page.dart b/lib/routes/settings_page.dart index 68e3eb2..5ae4728 100644 --- a/lib/routes/settings_page.dart +++ b/lib/routes/settings_page.dart @@ -16,24 +16,26 @@ class SettingsPage extends StatelessWidget { Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text(context.l10n.settings)), - body: Padding( - padding: const EdgeInsets.all(16), - child: Column(children: [ - // Set app language - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Text(context.l10n.appLanguage, - style: Theme.of(context).textTheme.bodyMedium), - const DropdownButtonAppLanguage(), - ], - ), - const SizedBox(height: 10), - const Expanded(child: LanguageSettings()), - const UpdateSettings() - // const SizedBox(height: 10), - // const DesignSettings() - ]), + body: SafeArea( + child: Padding( + padding: const EdgeInsets.all(16), + child: Column(children: [ + // Set app language + Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Text(context.l10n.appLanguage, + style: Theme.of(context).textTheme.bodyMedium), + const DropdownButtonAppLanguage(), + ], + ), + const SizedBox(height: 10), + const Expanded(child: LanguageSettings()), + const UpdateSettings() + // const SizedBox(height: 10), + // const DesignSettings() + ]), + ), ), ); } diff --git a/lib/routes/startup_page.dart b/lib/routes/startup_page.dart index 28a886d..37ce526 100644 --- a/lib/routes/startup_page.dart +++ b/lib/routes/startup_page.dart @@ -64,29 +64,30 @@ class StartupPage extends ConsumerWidget { Future initResult = ((initFunction != null) ? initFunction!() : init(ref)); return FutureBuilder( - future: initResult.then((String navigateTo) => - Navigator.pushReplacementNamed(context, navigateTo)), - initialData: "Loading", - builder: (BuildContext context, AsyncSnapshot snapshot) { - debugPrint(snapshot.connectionState.toString()); + future: initResult.then((String navigateTo) => + Navigator.pushReplacementNamed(context, navigateTo)), + initialData: "Loading", + builder: (BuildContext context, AsyncSnapshot snapshot) { + debugPrint(snapshot.connectionState.toString()); - switch (snapshot.connectionState) { - case ConnectionState.none: - case ConnectionState.waiting: - case ConnectionState.active: - return loadingAnimation('Loading'); - case ConnectionState.done: - debugPrint( - 'Done, hasData: ${snapshot.hasData}, Error: ${snapshot.hasError}'); - if (snapshot.hasError) { - // TODO do something more helpful for the user ("try again...") - return ErrorPage(snapshot.error.toString()); - } else { - // This is actually never called because as soon - // as we push the new route he's out of here... - return loadingAnimation('Redirecting ...'); - } - } - }); + switch (snapshot.connectionState) { + case ConnectionState.none: + case ConnectionState.waiting: + case ConnectionState.active: + return loadingAnimation('Loading'); + case ConnectionState.done: + debugPrint( + 'Done, hasData: ${snapshot.hasData}, Error: ${snapshot.hasError}'); + if (snapshot.hasError) { + // TODO do something more helpful for the user ("try again...") + return ErrorPage(snapshot.error.toString()); + } else { + // This is actually never called because as soon + // as we push the new route he's out of here... + return loadingAnimation('Redirecting ...'); + } + } + }, + ); } } diff --git a/lib/routes/view_page.dart b/lib/routes/view_page.dart index 881e78b..568fe1f 100644 --- a/lib/routes/view_page.dart +++ b/lib/routes/view_page.dart @@ -18,6 +18,7 @@ import 'package:app4training/widgets/language_selection_button.dart'; class ViewPage extends ConsumerWidget { final String page; // Name of the currently selected page final String langCode; + const ViewPage(this.page, this.langCode, {super.key}); /// First check whether the background process did something since @@ -86,11 +87,13 @@ class ViewPage extends ConsumerWidget { ref .read(sharedPrefsProvider) .setString('recentLang', langCode); - return HtmlView( - content, - (Globals.rtlLanguages.contains(langCode)) - ? TextDirection.rtl - : TextDirection.ltr); + return SafeArea( + child: HtmlView( + content, + (Globals.rtlLanguages.contains(langCode)) + ? TextDirection.rtl + : TextDirection.ltr), + ); } } })); diff --git a/lib/widgets/language_selection_button.dart b/lib/widgets/language_selection_button.dart index c5dce0b..4daebba 100644 --- a/lib/widgets/language_selection_button.dart +++ b/lib/widgets/language_selection_button.dart @@ -40,62 +40,68 @@ class LanguageSelectionButton extends ConsumerWidget { final menuController = MenuController(); return MenuAnchor( - controller: menuController, - builder: - (BuildContext context, MenuController controller, Widget? child) { - return IconButton( - onPressed: () { - if (controller.isOpen) { - controller.close(); - } else { - controller.open(); - } - }, - icon: const Icon(Icons.translate), - tooltip: 'Language selection', - ); - }, - menuChildren: [ - Padding( - padding: const EdgeInsets.fromLTRB(10, 0, 10, 0), - child: Column( - children: [ - Text(context.l10n.languageSelectionHeader), - // Split list into two columns if we have many languages - // TODO improve decision on when to make two columns - // TODO better 2-column design for odd numbers of languages - menuItems.length > 10 - ? Row( - mainAxisSize: MainAxisSize.min, - children: [ - Flexible( - fit: FlexFit.loose, - child: Column( - children: - menuItems.sublist(0, menuItems.length ~/ 2), - ), - ), - Flexible( - fit: FlexFit.loose, - child: Column( - children: - menuItems.sublist(menuItems.length ~/ 2)), - ) - ], + style: MenuStyle( + maximumSize: WidgetStatePropertyAll( + Size(400, 500), + ), + ), + controller: menuController, + builder: + (BuildContext context, MenuController controller, Widget? child) { + return IconButton( + onPressed: () { + if (controller.isOpen) { + controller.close(); + } else { + controller.open(); + } + }, + icon: const Icon(Icons.translate), + tooltip: 'Language selection', + ); + }, + menuChildren: [ + Padding( + padding: const EdgeInsets.fromLTRB(10, 0, 10, 0), + child: Column( + children: [ + Text(context.l10n.languageSelectionHeader), + // Split list into two columns if we have many languages + // TODO improve decision on when to make two columns + // TODO better 2-column design for odd numbers of languages + menuItems.length > 10 + ? Row( + children: [ + Flexible( + fit: FlexFit.loose, + child: Column( + children: + menuItems.sublist(0, menuItems.length ~/ 2), + ), + ), + Flexible( + fit: FlexFit.loose, + child: Column( + children: + menuItems.sublist(menuItems.length ~/ 2)), ) - : Column(children: menuItems), - const Divider(), - ListTile( - dense: true, - title: Text(context.l10n.manageLanguages), - leading: const Icon(Icons.settings), - onTap: () { - menuController.close(); - Navigator.pushNamed(context, '/settings'); - }, - ), - ], - )) - ]); + ], + ) + : Column(children: menuItems), + const Divider(), + ListTile( + dense: true, + title: Text(context.l10n.manageLanguages), + leading: const Icon(Icons.settings), + onTap: () { + menuController.close(); + Navigator.pushNamed(context, '/settings'); + }, + ), + ], + ), + ), + ], + ); } } diff --git a/pubspec.lock b/pubspec.lock index 76670fa..c0cbe5c 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,34 +5,34 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: e55636ed79578b9abca5fecf9437947798f5ef7456308b5cb85720b793eac92f + sha256: da0d9209ca76bde579f2da330aeb9df62b6319c834fa7baae052021b0462401f url: "https://pub.dev" source: hosted - version: "82.0.0" + version: "85.0.0" analyzer: dependency: transitive description: name: analyzer - sha256: "904ae5bb474d32c38fb9482e2d925d5454cda04ddd0e55d2e6826bc72f6ba8c0" + sha256: f4ad0fea5f102201015c9aae9d93bc02f75dd9491529a8c21f88d17a8523d44c url: "https://pub.dev" source: hosted - version: "7.4.5" + version: "7.6.0" analyzer_plugin: dependency: transitive description: name: analyzer_plugin - sha256: ee188b6df6c85f1441497c7171c84f1392affadc0384f71089cb10a3bc508cef + sha256: a5ab7590c27b779f3d4de67f31c4109dbe13dd7339f86461a6f2a8ab2594d8ce url: "https://pub.dev" source: hosted - version: "0.13.1" + version: "0.13.4" archive: dependency: transitive description: name: archive - sha256: "2fde1607386ab523f7a36bb3e7edb43bd58e6edaf2ffb29d8a6d578b297fdbbd" + sha256: a96e8b390886ee8abb49b7bd3ac8df6f451c621619f52a26e815fdcf568959ff url: "https://pub.dev" source: hosted - version: "4.0.7" + version: "4.0.9" args: dependency: transitive description: @@ -125,26 +125,26 @@ packages: dependency: transitive description: name: coverage - sha256: aa07dbe5f2294c827b7edb9a87bba44a9c15a3cc81bc8da2ca19b37322d30080 + sha256: "5da775aa218eaf2151c721b16c01c7676fbfdd99cebba2bf64e8b807a28ff94d" url: "https://pub.dev" source: hosted - version: "1.14.1" + version: "1.15.0" cross_file: dependency: transitive description: name: cross_file - sha256: "7caf6a750a0c04effbb52a676dce9a4a592e10ad35c34d6d2d0e4811160d5670" + sha256: "28bb3ae56f117b5aec029d702a90f57d285cd975c3c5c281eaca38dbc47c5937" url: "https://pub.dev" source: hosted - version: "0.3.4+2" + version: "0.3.5+2" crypto: dependency: transitive description: name: crypto - sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855" + sha256: c8ea0233063ba03258fbcf2ca4d6dadfefe14f02fab57702265467a19f27fadf url: "https://pub.dev" source: hosted - version: "3.0.6" + version: "3.0.7" csslib: dependency: transitive description: @@ -181,34 +181,34 @@ packages: dependency: transitive description: name: custom_lint_visitor - sha256: cba5b6d7a6217312472bf4468cdf68c949488aed7ffb0eab792cd0b6c435054d + sha256: "4a86a0d8415a91fbb8298d6ef03e9034dc8e323a599ddc4120a0e36c433983a2" url: "https://pub.dev" source: hosted - version: "1.0.0+7.4.5" + version: "1.0.0+7.7.0" dart_style: dependency: transitive description: name: dart_style - sha256: "5b236382b47ee411741447c1f1e111459c941ea1b3f2b540dde54c210a3662af" + sha256: "8a0e5fba27e8ee025d2ffb4ee820b4e6e2cf5e4246a6b1a477eb66866947e0bb" url: "https://pub.dev" source: hosted - version: "3.1.0" + version: "3.1.1" dio: dependency: "direct main" description: name: dio - sha256: "253a18bbd4851fecba42f7343a1df3a9a4c1d31a2c1b37e221086b4fa8c8dbc9" + sha256: b9d46faecab38fc8cc286f80bc4d61a3bb5d4ac49e51ed877b4d6706efe57b25 url: "https://pub.dev" source: hosted - version: "5.8.0+1" + version: "5.9.1" dio_web_adapter: dependency: transitive description: name: dio_web_adapter - sha256: "0a2e95fc6bdeb623bb623fc41e90e6924e9a3bbd65089f9221f83c185366b479" + sha256: "7586e476d70caecaf1686d21eee7247ea43ef5c345eab9e0cc3583ff13378d78" url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "2.1.1" download_assets: dependency: "direct main" description: @@ -229,10 +229,10 @@ packages: dependency: transitive description: name: ffi - sha256: "289279317b4b16eb2bb7e271abccd4bf84ec9bdcbe999e278a94b804f5630418" + sha256: "6d7fd89431262d8f3125e81b50d3847a091d846eafcd4fdb88dd06f36d705a45" url: "https://pub.dev" source: hosted - version: "2.1.4" + version: "2.2.0" file: dependency: "direct main" description: @@ -342,10 +342,10 @@ packages: dependency: transitive description: name: freezed_annotation - sha256: c87ff004c8aa6af2d531668b46a4ea379f7191dc6dfa066acd53d506da6e044b + sha256: "7294967ff0a6d98638e7acb774aac3af2550777accd8149c90af5b014e6d44d8" url: "https://pub.dev" source: hosted - version: "3.0.0" + version: "3.1.0" frontend_server_client: dependency: transitive description: @@ -395,10 +395,10 @@ packages: dependency: "direct main" description: name: http - sha256: "2c11f3f94c687ee9bad77c171151672986360b2b001d109814ee7140b2cf261b" + sha256: "87721a4a50b19c7f1d49001e51409bddc46303966ce89a65af4f4e6004896412" url: "https://pub.dev" source: hosted - version: "1.4.0" + version: "1.6.0" http_multi_server: dependency: transitive description: @@ -448,10 +448,10 @@ packages: dependency: transitive description: name: json_annotation - sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1" + sha256: cb09e7dac6210041fad964ed7fbee004f14258b4eca4040f72d1234062ace4c8 url: "https://pub.dev" source: hosted - version: "4.9.0" + version: "4.11.0" leak_tracker: dependency: transitive description: @@ -488,10 +488,10 @@ packages: dependency: transitive description: name: lints - sha256: a5e2b223cb7c9c8efdc663ef484fdd95bb243bff242ef5b13e26883547fce9a0 + sha256: "12f842a479589fea194fe5c5a3095abc7be0c1f2ddfa9a0e76aed1dbd26a87df" url: "https://pub.dev" source: hosted - version: "6.0.0" + version: "6.1.0" list_counter: dependency: transitive description: @@ -536,10 +536,10 @@ packages: dependency: transitive description: name: mime - sha256: "801fd0b26f14a4a58ccb09d5892c3fbdeff209594300a542492cf13fba9d247a" + sha256: "41a20518f0cb1256669420fdba0cd90d21561e560ac240f26ef8322e45bb7ed6" url: "https://pub.dev" source: hosted - version: "1.0.6" + version: "2.0.0" mocktail: dependency: "direct main" description: @@ -608,18 +608,18 @@ packages: dependency: transitive description: name: path_provider_android - sha256: d0d310befe2c8ab9e7f393288ccbb11b60c019c6b5afc21973eeee4dda2b35e9 + sha256: f2c65e21139ce2c3dad46922be8272bb5963516045659e71bb16e151c93b580e url: "https://pub.dev" source: hosted - version: "2.2.17" + version: "2.2.22" path_provider_foundation: dependency: transitive description: name: path_provider_foundation - sha256: "4843174df4d288f5e29185bd6e72a6fbdf5a4a4602717eed565497429f179942" + sha256: "6d13aece7b3f5c5a9731eaf553ff9dcbc2eff41087fd2df587fd0fed9a3eb0c4" url: "https://pub.dev" source: hosted - version: "2.4.1" + version: "2.5.1" path_provider_linux: dependency: transitive description: @@ -664,26 +664,26 @@ packages: dependency: transitive description: name: pool - sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a" + sha256: "978783255c543aa3586a1b3c21f6e9d720eb315376a915872c61ef8b5c20177d" url: "https://pub.dev" source: hosted - version: "1.5.1" + version: "1.5.2" posix: dependency: transitive description: name: posix - sha256: f0d7856b6ca1887cfa6d1d394056a296ae33489db914e365e2044fdada449e62 + sha256: "185ef7606574f789b40f289c233efa52e96dead518aed988e040a10737febb07" url: "https://pub.dev" source: hosted - version: "6.0.2" + version: "6.5.0" process: dependency: transitive description: name: process - sha256: "107d8be718f120bbba9dcd1e95e3bd325b1b4a4f07db64154635ba03f2567a0d" + sha256: c6248e4526673988586e8c00bb22a49210c258dc91df5227d5da9748ecf79744 url: "https://pub.dev" source: hosted - version: "5.0.3" + version: "5.0.5" pub_semver: dependency: transitive description: @@ -760,26 +760,26 @@ packages: dependency: "direct main" description: name: shared_preferences - sha256: d3bbe5553a986e83980916ded2f0b435ef2e1893dfaa29d5a7a790d0eca12180 + sha256: "2939ae520c9024cb197fc20dee269cd8cdbf564c8b5746374ec6cacdc5169e64" url: "https://pub.dev" source: hosted - version: "2.2.3" + version: "2.5.4" shared_preferences_android: dependency: transitive description: name: shared_preferences_android - sha256: "20cbd561f743a342c76c151d6ddb93a9ce6005751e7aa458baad3858bfbfb6ac" + sha256: cbc40be9be1c5af4dab4d6e0de4d5d3729e6f3d65b89d21e1815d57705644a6f url: "https://pub.dev" source: hosted - version: "2.4.10" + version: "2.4.20" shared_preferences_foundation: dependency: transitive description: name: shared_preferences_foundation - sha256: "6a52cfcdaeac77cad8c97b539ff688ccfc458c007b4db12be584fbe5c0e49e03" + sha256: "4e7eaffc2b17ba398759f1151415869a34771ba11ebbccd1b0145472a619a64f" url: "https://pub.dev" source: hosted - version: "2.5.4" + version: "2.5.6" shared_preferences_linux: dependency: transitive description: @@ -869,18 +869,10 @@ packages: dependency: transitive description: name: source_span - sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c" - url: "https://pub.dev" - source: hosted - version: "1.10.1" - sprintf: - dependency: transitive - description: - name: sprintf - sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23" + sha256: "56a02f1f4cd1a2d96303c0144c93bd6d909eea6bee6bf5a0e0b685edbd4c47ab" url: "https://pub.dev" source: hosted - version: "7.0.0" + version: "1.10.2" stack_trace: dependency: transitive description: @@ -981,34 +973,34 @@ packages: dependency: transitive description: name: url_launcher_android - sha256: "8582d7f6fe14d2652b4c45c9b6c14c0b678c2af2d083a11b604caeba51930d79" + sha256: "767344bf3063897b5cf0db830e94f904528e6dd50a6dfaf839f0abf509009611" url: "https://pub.dev" source: hosted - version: "6.3.16" + version: "6.3.28" url_launcher_ios: dependency: transitive description: name: url_launcher_ios - sha256: "7f2022359d4c099eea7df3fdf739f7d3d3b9faf3166fb1dd390775176e0b76cb" + sha256: cfde38aa257dae62ffe79c87fab20165dfdf6988c1d31b58ebf59b9106062aad url: "https://pub.dev" source: hosted - version: "6.3.3" + version: "6.3.6" url_launcher_linux: dependency: transitive description: name: url_launcher_linux - sha256: "4e9ba368772369e3e08f231d2301b4ef72b9ff87c31192ef471b380ef29a4935" + sha256: d5e14138b3bc193a0f63c10a53c94b91d399df0512b1f29b94a043db7482384a url: "https://pub.dev" source: hosted - version: "3.2.1" + version: "3.2.2" url_launcher_macos: dependency: transitive description: name: url_launcher_macos - sha256: "17ba2000b847f334f16626a574c702b196723af2a289e7a93ffcb79acff855c2" + sha256: "368adf46f71ad3c21b8f06614adb38346f193f3a59ba8fe9a2fd74133070ba18" url: "https://pub.dev" source: hosted - version: "3.2.2" + version: "3.2.5" url_launcher_platform_interface: dependency: transitive description: @@ -1029,18 +1021,18 @@ packages: dependency: transitive description: name: url_launcher_windows - sha256: "3284b6d2ac454cf34f114e1d3319866fdd1e19cdc329999057e44ffe936cfa77" + sha256: "712c70ab1b99744ff066053cbe3e80c73332b38d46e5e945c98689b2e66fc15f" url: "https://pub.dev" source: hosted - version: "3.1.4" + version: "3.1.5" uuid: dependency: transitive description: name: uuid - sha256: a5be9ef6618a7ac1e964353ef476418026db906c4facdedaa299b7a2e71690ff + sha256: "1fef9e8e11e2991bb773070d4656b7bd5d850967a2456cfc83cf47925ba79489" url: "https://pub.dev" source: hosted - version: "4.5.1" + version: "4.5.3" vector_math: dependency: transitive description: @@ -1053,18 +1045,18 @@ packages: dependency: transitive description: name: vm_service - sha256: ddfa8d30d89985b96407efce8acbdd124701f96741f2d981ca860662f1c0dc02 + sha256: "45caa6c5917fa127b5dbcfbd1fa60b14e583afdc08bfc96dda38886ca252eb60" url: "https://pub.dev" source: hosted - version: "15.0.0" + version: "15.0.2" watcher: dependency: transitive description: name: watcher - sha256: "0b7fd4a0bbc4b92641dbf20adfd7e3fd1398fe17102d94b674234563e110088a" + sha256: "1398c9f081a753f9226febe8900fce8f7d0a67163334e1c94a2438339d79d635" url: "https://pub.dev" source: hosted - version: "1.1.2" + version: "1.2.1" web: dependency: transitive description: @@ -1109,10 +1101,10 @@ packages: dependency: transitive description: name: win32 - sha256: "66814138c3562338d05613a6e368ed8cfb237ad6d64a9e9334be3f309acfca03" + sha256: d7cb55e04cd34096cd3a79b3330245f54cb96a370a1c27adb3c84b917de8b08e url: "https://pub.dev" source: hosted - version: "5.14.0" + version: "5.15.0" workmanager: dependency: "direct main" description: @@ -1138,5 +1130,5 @@ packages: source: hosted version: "3.1.3" sdks: - dart: ">=3.8.0 <4.0.0" + dart: ">=3.9.0 <4.0.0" flutter: ">=3.38.0"