From 836a59e4da6982918d1dc3f961ca49cc3a7d951d Mon Sep 17 00:00:00 2001 From: GibreelAbdullah Date: Thu, 26 Oct 2023 14:40:23 +0530 Subject: [PATCH] Refactor, Updated Dependency --- .github/workflows/main.yml | 12 +- .gitignore | 9 +- .metadata | 31 +- .vscode/launch.json | 13 - analysis_options.yaml | 28 - android/app/build.gradle | 2 +- android/app/google-services.json | 39 -- android/app/src/debug/AndroidManifest.xml | 6 +- .../app/FlutterMultiDexApplication.java | 25 + .../com/example/hans_wehr/MainActivity.kt | 4 +- android/app/src/profile/AndroidManifest.xml | 6 +- android/build.gradle | 4 +- .../gradle/wrapper/gradle-wrapper.properties | 3 +- .../muslimtechnet/hanswehr/BuildConfig.java | 8 - gen/com/muslimtechnet/hanswehr/Manifest.java | 7 - gen/com/muslimtechnet/hanswehr/R.java | 7 - ios/._Podfile | Bin 4096 -> 0 bytes ios/.gitignore | 2 + ios/Flutter/AppFrameworkInfo.plist | 4 +- ios/Flutter/Debug.xcconfig | 1 - ios/Flutter/Release.xcconfig | 1 - ios/Podfile | 41 -- ios/Podfile.lock | 79 --- ios/Runner.xcodeproj/project.pbxproj | 243 ++++--- .../xcshareddata/xcschemes/Runner.xcscheme | 21 +- .../contents.xcworkspacedata | 3 - .../LaunchBackground.imageset/Contents.json | 21 - .../LaunchBackground.imageset/background.png | Bin 68 -> 0 bytes .../LaunchImage.imageset/Contents.json | 10 +- .../LaunchImage.imageset/LaunchImage.png | Bin 68 -> 68 bytes .../LaunchImage.imageset/LaunchImage@2x.png | Bin 68 -> 68 bytes .../LaunchImage.imageset/LaunchImage@3x.png | Bin 68 -> 68 bytes ios/Runner/Base.lproj/LaunchScreen.storyboard | 17 +- ios/Runner/Info.plist | 90 +-- ios/RunnerTests/RunnerTests.swift | 12 + lib/classes/{appTheme.dart => app_theme.dart} | 28 +- lib/classes/definitionClass.dart | 29 - lib/classes/definition_provider.dart | 48 ++ ....dart => search_suggestions_provider.dart} | 8 +- .../{themeModel.dart => theme_model.dart} | 26 +- .../{appConstants.dart => app_constants.dart} | 84 +-- lib/main.dart | 38 +- lib/routes.dart | 28 +- lib/screens/abbreviations.dart | 69 +- lib/screens/{aboutApp.dart => about_app.dart} | 80 +-- lib/screens/browse.dart | 74 +- lib/screens/donate.dart | 28 +- lib/screens/favorites.dart | 24 +- lib/screens/history.dart | 19 +- lib/screens/{moreApps.dart => more_apps.dart} | 22 +- lib/screens/preface.dart | 42 +- .../{quranicWords.dart => quranic_words.dart} | 24 +- lib/screens/search.dart | 161 ++--- lib/screens/settings.dart | 136 ++-- ...rviceLocator.dart => service_locator.dart} | 2 +- lib/services/LocalStorageService.dart | 147 ---- .../{appReview.dart => app_review.dart} | 7 +- ...dates.dart => check_database_updates.dart} | 0 lib/services/{getData.dart => get_data.dart} | 61 +- lib/services/local_storage_service.dart | 138 ++++ ...nitionSpace.dart => definition_space.dart} | 166 ++--- lib/widgets/drawer.dart | 94 +-- ...Alert.dart => quran_occurrence_alert.dart} | 24 +- linux/CMakeLists.txt | 1 + macos/Flutter/GeneratedPluginRegistrant.swift | 12 +- macos/Runner.xcodeproj/project.pbxproj | 125 +++- .../xcshareddata/xcschemes/Runner.xcscheme | 19 +- macos/Runner/MainFlutterWindow.swift | 2 +- macos/RunnerTests/RunnerTests.swift | 12 + pubspec.lock | 656 +++++++++--------- pubspec.yaml | 46 +- test/widget_test.dart | 30 - web/favicon.png | Bin 0 -> 917 bytes web/icons/Icon-192.png | Bin 0 -> 5292 bytes web/icons/Icon-512.png | Bin 0 -> 8252 bytes web/icons/Icon-maskable-192.png | Bin 0 -> 5594 bytes web/icons/Icon-maskable-512.png | Bin 0 -> 20998 bytes web/index.html | 59 ++ web/manifest.json | 35 + windows/CMakeLists.txt | 3 +- windows/runner/flutter_window.cpp | 5 + windows/runner/utils.cpp | 9 +- windows/runner/win32_window.cpp | 2 +- windows/runner/win32_window.h | 2 +- 84 files changed, 1740 insertions(+), 1634 deletions(-) delete mode 100644 .vscode/launch.json delete mode 100644 android/app/google-services.json create mode 100644 android/app/src/main/java/io/flutter/app/FlutterMultiDexApplication.java delete mode 100644 gen/com/muslimtechnet/hanswehr/BuildConfig.java delete mode 100644 gen/com/muslimtechnet/hanswehr/Manifest.java delete mode 100644 gen/com/muslimtechnet/hanswehr/R.java delete mode 100644 ios/._Podfile delete mode 100644 ios/Podfile delete mode 100644 ios/Podfile.lock delete mode 100644 ios/Runner/Assets.xcassets/LaunchBackground.imageset/Contents.json delete mode 100644 ios/Runner/Assets.xcassets/LaunchBackground.imageset/background.png create mode 100644 ios/RunnerTests/RunnerTests.swift rename lib/classes/{appTheme.dart => app_theme.dart} (88%) delete mode 100644 lib/classes/definitionClass.dart create mode 100644 lib/classes/definition_provider.dart rename lib/classes/{searchModel.dart => search_suggestions_provider.dart} (89%) rename lib/classes/{themeModel.dart => theme_model.dart} (89%) rename lib/constants/{appConstants.dart => app_constants.dart} (96%) rename lib/screens/{aboutApp.dart => about_app.dart} (63%) rename lib/screens/{moreApps.dart => more_apps.dart} (70%) rename lib/screens/{quranicWords.dart => quranic_words.dart} (87%) rename lib/{serviceLocator.dart => service_locator.dart} (82%) delete mode 100644 lib/services/LocalStorageService.dart rename lib/services/{appReview.dart => app_review.dart} (78%) rename lib/services/{checkDatabaseUpdates.dart => check_database_updates.dart} (100%) rename lib/services/{getData.dart => get_data.dart} (86%) create mode 100644 lib/services/local_storage_service.dart rename lib/widgets/{definitionSpace.dart => definition_space.dart} (73%) rename lib/widgets/{quranOccurrenceAlert.dart => quran_occurrence_alert.dart} (88%) create mode 100644 macos/RunnerTests/RunnerTests.swift delete mode 100644 test/widget_test.dart create mode 100644 web/favicon.png create mode 100644 web/icons/Icon-192.png create mode 100644 web/icons/Icon-512.png create mode 100644 web/icons/Icon-maskable-192.png create mode 100644 web/icons/Icon-maskable-512.png create mode 100644 web/index.html create mode 100644 web/manifest.json diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 81df50f..950fd97 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -26,7 +26,7 @@ jobs: uses: thedoctor0/zip-release@master with: type: 'zip' - filename: MacRecoveryX-${{github.ref_name}}-linux.zip + filename: HansWehrDictionary-${{github.ref_name}}-linux.zip directory: build/linux/x64/release/bundle - name: Linux Release uses: softprops/action-gh-release@v1 @@ -34,7 +34,7 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: - files: build/linux/x64/release/bundle/MacRecoveryX-${{github.ref_name}}-linux.zip + files: build/linux/x64/release/bundle/HansWehrDictionary-${{github.ref_name}}-linux.zip build-and-release-windows: runs-on: windows-latest @@ -57,7 +57,7 @@ jobs: uses: thedoctor0/zip-release@master with: type: 'zip' - filename: MacRecoveryX-${{github.ref_name}}-windows.zip + filename: HansWehrDictionary-${{github.ref_name}}-windows.zip directory: build/windows/runner/Release - name: Windows Release uses: softprops/action-gh-release@v1 @@ -65,7 +65,7 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: - files: build/windows/runner/Release/MacRecoveryX-${{github.ref_name}}-windows.zip + files: build/windows/runner/Release/HansWehrDictionary-${{github.ref_name}}-windows.zip build-and-release-macos: runs-on: macos-latest @@ -88,7 +88,7 @@ jobs: uses: thedoctor0/zip-release@master with: type: 'zip' - filename: MacRecoveryX-${{github.ref_name}}-macos.zip + filename: HansWehrDictionary-${{github.ref_name}}-macos.zip directory: build/macos/Build/Products/Release - name: macOS Release uses: softprops/action-gh-release@v1 @@ -96,4 +96,4 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: - files: build/macos/Build/Products/Release/MacRecoveryX-${{github.ref_name}}-macos.zip + files: build/macos/Build/Products/Release/HansWehrDictionary-${{github.ref_name}}-macos.zip diff --git a/.gitignore b/.gitignore index 4ab6e6a..24476c5 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ .buildlog/ .history .svn/ +migrate_working_dir/ # IntelliJ related *.iml @@ -31,13 +32,13 @@ .pub/ /build/ -# Web related -lib/generated_plugin_registrant.dart - # Symbolication related app.*.symbols # Obfuscation related app.*.map.json -lib/properties.dart \ No newline at end of file +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release diff --git a/.metadata b/.metadata index 7772fa1..acfc1cf 100644 --- a/.metadata +++ b/.metadata @@ -1,11 +1,11 @@ # This file tracks properties of this Flutter project. # Used by Flutter tool to assess capabilities and perform upgrades etc. # -# This file should be version controlled. +# This file should be version controlled and should not be manually edited. version: - revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf - channel: stable + revision: "6c4930c4ac86fb286f30e31d0ec8bffbcbb9953e" + channel: "stable" project_type: app @@ -13,17 +13,26 @@ project_type: app migration: platforms: - platform: root - create_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf - base_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf + create_revision: 6c4930c4ac86fb286f30e31d0ec8bffbcbb9953e + base_revision: 6c4930c4ac86fb286f30e31d0ec8bffbcbb9953e + - platform: android + create_revision: 6c4930c4ac86fb286f30e31d0ec8bffbcbb9953e + base_revision: 6c4930c4ac86fb286f30e31d0ec8bffbcbb9953e + - platform: ios + create_revision: 6c4930c4ac86fb286f30e31d0ec8bffbcbb9953e + base_revision: 6c4930c4ac86fb286f30e31d0ec8bffbcbb9953e - platform: linux - create_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf - base_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf + create_revision: 6c4930c4ac86fb286f30e31d0ec8bffbcbb9953e + base_revision: 6c4930c4ac86fb286f30e31d0ec8bffbcbb9953e - platform: macos - create_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf - base_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf + create_revision: 6c4930c4ac86fb286f30e31d0ec8bffbcbb9953e + base_revision: 6c4930c4ac86fb286f30e31d0ec8bffbcbb9953e + - platform: web + create_revision: 6c4930c4ac86fb286f30e31d0ec8bffbcbb9953e + base_revision: 6c4930c4ac86fb286f30e31d0ec8bffbcbb9953e - platform: windows - create_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf - base_revision: 4d9e56e694b656610ab87fcf2efbcd226e0ed8cf + create_revision: 6c4930c4ac86fb286f30e31d0ec8bffbcbb9953e + base_revision: 6c4930c4ac86fb286f30e31d0ec8bffbcbb9953e # User provided section diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index b942668..0000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "name": "hans_wehr_dictionary", - "request": "launch", - "type": "dart" - } - ] -} \ No newline at end of file diff --git a/analysis_options.yaml b/analysis_options.yaml index 61b6c4d..f9b3034 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -1,29 +1 @@ -# This file configures the analyzer, which statically analyzes Dart code to -# check for errors, warnings, and lints. -# -# The issues identified by the analyzer are surfaced in the UI of Dart-enabled -# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be -# invoked from the command line by running `flutter analyze`. - -# The following line activates a set of recommended lints for Flutter apps, -# packages, and plugins designed to encourage good coding practices. include: package:flutter_lints/flutter.yaml - -linter: - # The lint rules applied to this project can be customized in the - # section below to disable rules from the `package:flutter_lints/flutter.yaml` - # included above or to enable additional rules. A list of all available lints - # and their documentation is published at - # https://dart-lang.github.io/linter/lints/index.html. - # - # Instead of disabling a lint rule for the entire project in the - # section below, it can also be suppressed for a single line of code - # or a specific dart file by using the `// ignore: name_of_lint` and - # `// ignore_for_file: name_of_lint` syntax on the line or in the file - # producing the lint. - rules: - # avoid_print: false # Uncomment to disable the `avoid_print` rule - # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule - -# Additional information about this file can be found at -# https://dart.dev/guides/language/analysis-options diff --git a/android/app/build.gradle b/android/app/build.gradle index d7a25c1..35d7d64 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -44,7 +44,7 @@ android { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "com.muslimtechnet.hanswehr" minSdkVersion 23 - targetSdkVersion 31 + targetSdkVersion 33 versionCode flutterVersionCode.toInteger() versionName flutterVersionName multiDexEnabled true diff --git a/android/app/google-services.json b/android/app/google-services.json deleted file mode 100644 index 0a977d9..0000000 --- a/android/app/google-services.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "project_info": { - "project_number": "1006524653782", - "project_id": "hans-wehr-dictionary", - "storage_bucket": "hans-wehr-dictionary.appspot.com" - }, - "client": [ - { - "client_info": { - "mobilesdk_app_id": "1:1006524653782:android:d0ad77dfd4d68ee7ea2977", - "android_client_info": { - "package_name": "com.muslimtechnet.hanswehr" - } - }, - "oauth_client": [ - { - "client_id": "1006524653782-mt7d7c5sluvbjs9tfotbkuhhg9rujkra.apps.googleusercontent.com", - "client_type": 3 - } - ], - "api_key": [ - { - "current_key": "AIzaSyBoHG4aA6EmO6qTYh4I9qX9LzmqN-rb_HA" - } - ], - "services": { - "appinvite_service": { - "other_platform_oauth_client": [ - { - "client_id": "1006524653782-mt7d7c5sluvbjs9tfotbkuhhg9rujkra.apps.googleusercontent.com", - "client_type": 3 - } - ] - } - } - } - ], - "configuration_version": "1" -} \ No newline at end of file diff --git a/android/app/src/debug/AndroidManifest.xml b/android/app/src/debug/AndroidManifest.xml index d867380..399f698 100644 --- a/android/app/src/debug/AndroidManifest.xml +++ b/android/app/src/debug/AndroidManifest.xml @@ -1,6 +1,6 @@ - - diff --git a/android/app/src/main/java/io/flutter/app/FlutterMultiDexApplication.java b/android/app/src/main/java/io/flutter/app/FlutterMultiDexApplication.java new file mode 100644 index 0000000..752fc18 --- /dev/null +++ b/android/app/src/main/java/io/flutter/app/FlutterMultiDexApplication.java @@ -0,0 +1,25 @@ +// Generated file. +// +// If you wish to remove Flutter's multidex support, delete this entire file. +// +// Modifications to this file should be done in a copy under a different name +// as this file may be regenerated. + +package io.flutter.app; + +import android.app.Application; +import android.content.Context; +import androidx.annotation.CallSuper; +import androidx.multidex.MultiDex; + +/** + * Extension of {@link android.app.Application}, adding multidex support. + */ +public class FlutterMultiDexApplication extends Application { + @Override + @CallSuper + protected void attachBaseContext(Context base) { + super.attachBaseContext(base); + MultiDex.install(this); + } +} diff --git a/android/app/src/main/kotlin/com/example/hans_wehr/MainActivity.kt b/android/app/src/main/kotlin/com/example/hans_wehr/MainActivity.kt index a223911..91aad04 100644 --- a/android/app/src/main/kotlin/com/example/hans_wehr/MainActivity.kt +++ b/android/app/src/main/kotlin/com/example/hans_wehr/MainActivity.kt @@ -1,4 +1,6 @@ +package com.example.hans_wehr + import io.flutter.embedding.android.FlutterActivity class MainActivity: FlutterActivity() { -} \ No newline at end of file +} diff --git a/android/app/src/profile/AndroidManifest.xml b/android/app/src/profile/AndroidManifest.xml index d867380..399f698 100644 --- a/android/app/src/profile/AndroidManifest.xml +++ b/android/app/src/profile/AndroidManifest.xml @@ -1,6 +1,6 @@ - - diff --git a/android/build.gradle b/android/build.gradle index 4bb0eb4..9eb4834 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -1,5 +1,5 @@ buildscript { - ext.kotlin_version = '1.6.21' + ext.kotlin_version = '1.9.10' repositories { jcenter() google() @@ -26,6 +26,6 @@ subprojects { project.evaluationDependsOn(':app') } -task clean(type: Delete) { +tasks.register("clean", Delete) { delete rootProject.buildDir } diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties index cc5527d..3c472b9 100644 --- a/android/gradle/wrapper/gradle-wrapper.properties +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,5 @@ -#Fri Jun 23 08:50:38 CEST 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip diff --git a/gen/com/muslimtechnet/hanswehr/BuildConfig.java b/gen/com/muslimtechnet/hanswehr/BuildConfig.java deleted file mode 100644 index fdb3ad5..0000000 --- a/gen/com/muslimtechnet/hanswehr/BuildConfig.java +++ /dev/null @@ -1,8 +0,0 @@ -/*___Generated_by_IDEA___*/ - -package com.muslimtechnet.hanswehr; - -/* This stub is only used by the IDE. It is NOT the BuildConfig class actually packed into the APK */ -public final class BuildConfig { - public final static boolean DEBUG = Boolean.parseBoolean(null); -} \ No newline at end of file diff --git a/gen/com/muslimtechnet/hanswehr/Manifest.java b/gen/com/muslimtechnet/hanswehr/Manifest.java deleted file mode 100644 index fd5f944..0000000 --- a/gen/com/muslimtechnet/hanswehr/Manifest.java +++ /dev/null @@ -1,7 +0,0 @@ -/*___Generated_by_IDEA___*/ - -package com.muslimtechnet.hanswehr; - -/* This stub is only used by the IDE. It is NOT the Manifest class actually packed into the APK */ -public final class Manifest { -} \ No newline at end of file diff --git a/gen/com/muslimtechnet/hanswehr/R.java b/gen/com/muslimtechnet/hanswehr/R.java deleted file mode 100644 index 2a43694..0000000 --- a/gen/com/muslimtechnet/hanswehr/R.java +++ /dev/null @@ -1,7 +0,0 @@ -/*___Generated_by_IDEA___*/ - -package com.muslimtechnet.hanswehr; - -/* This stub is only used by the IDE. It is NOT the R class actually packed into the APK */ -public final class R { -} \ No newline at end of file diff --git a/ios/._Podfile b/ios/._Podfile deleted file mode 100644 index 24deed1c8577ba1ce313868548b0099b28e71c37..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4096 zcmZQz6=P>$Vqox1Ojhs@R)|o50+1L3ClDJkFz{^v(m+1nBL)UWIUt(=a103vvYvJF zKST$^44`sLG%bukK2%&ZIX_n~v7jI)Rj;r#u_!UGBr`9S!N9=6*xJm%B+ZXA^|MKrSRBvsj@hwK%`DC^=OjEx#yR uAv3Qe71-^}&r8h7sZ_{GO)F7I%1O-22KI%ax`s4`>VLRbWEkZB{|5jH9W^}w diff --git a/ios/.gitignore b/ios/.gitignore index e96ef60..7a7f987 100644 --- a/ios/.gitignore +++ b/ios/.gitignore @@ -1,3 +1,4 @@ +**/dgph *.mode1v3 *.mode2v3 *.moved-aside @@ -18,6 +19,7 @@ Flutter/App.framework Flutter/Flutter.framework Flutter/Flutter.podspec Flutter/Generated.xcconfig +Flutter/ephemeral/ Flutter/app.flx Flutter/app.zip Flutter/flutter_assets/ diff --git a/ios/Flutter/AppFrameworkInfo.plist b/ios/Flutter/AppFrameworkInfo.plist index f2872cf..9625e10 100644 --- a/ios/Flutter/AppFrameworkInfo.plist +++ b/ios/Flutter/AppFrameworkInfo.plist @@ -3,7 +3,7 @@ CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) + en CFBundleExecutable App CFBundleIdentifier @@ -21,6 +21,6 @@ CFBundleVersion 1.0 MinimumOSVersion - 9.0 + 11.0 diff --git a/ios/Flutter/Debug.xcconfig b/ios/Flutter/Debug.xcconfig index ec97fc6..592ceee 100644 --- a/ios/Flutter/Debug.xcconfig +++ b/ios/Flutter/Debug.xcconfig @@ -1,2 +1 @@ -#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 c4855bf..592ceee 100644 --- a/ios/Flutter/Release.xcconfig +++ b/ios/Flutter/Release.xcconfig @@ -1,2 +1 @@ -#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" #include "Generated.xcconfig" diff --git a/ios/Podfile b/ios/Podfile deleted file mode 100644 index 1e8c3c9..0000000 --- a/ios/Podfile +++ /dev/null @@ -1,41 +0,0 @@ -# Uncomment this line to define a global platform for your project -# platform :ios, '9.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! - use_modular_headers! - - flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) -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 deleted file mode 100644 index bc3c09d..0000000 --- a/ios/Podfile.lock +++ /dev/null @@ -1,79 +0,0 @@ -PODS: - - Flutter (1.0.0) - - FMDB (2.7.5): - - FMDB/standard (= 2.7.5) - - FMDB/standard (2.7.5) - - in_app_review (0.2.0): - - Flutter - - path_provider (0.0.1): - - Flutter - - share (0.0.1): - - Flutter - - shared_preferences (0.0.1): - - Flutter - - sqflite (0.0.2): - - Flutter - - FMDB (>= 2.7.5) - - url_launcher (0.0.1): - - Flutter - - video_player (0.0.1): - - Flutter - - wakelock (0.0.1): - - Flutter - - webview_flutter (0.0.1): - - Flutter - -DEPENDENCIES: - - Flutter (from `Flutter`) - - in_app_review (from `.symlinks/plugins/in_app_review/ios`) - - path_provider (from `.symlinks/plugins/path_provider/ios`) - - share (from `.symlinks/plugins/share/ios`) - - shared_preferences (from `.symlinks/plugins/shared_preferences/ios`) - - sqflite (from `.symlinks/plugins/sqflite/ios`) - - url_launcher (from `.symlinks/plugins/url_launcher/ios`) - - video_player (from `.symlinks/plugins/video_player/ios`) - - wakelock (from `.symlinks/plugins/wakelock/ios`) - - webview_flutter (from `.symlinks/plugins/webview_flutter/ios`) - -SPEC REPOS: - trunk: - - FMDB - -EXTERNAL SOURCES: - Flutter: - :path: Flutter - in_app_review: - :path: ".symlinks/plugins/in_app_review/ios" - path_provider: - :path: ".symlinks/plugins/path_provider/ios" - share: - :path: ".symlinks/plugins/share/ios" - shared_preferences: - :path: ".symlinks/plugins/shared_preferences/ios" - sqflite: - :path: ".symlinks/plugins/sqflite/ios" - url_launcher: - :path: ".symlinks/plugins/url_launcher/ios" - video_player: - :path: ".symlinks/plugins/video_player/ios" - wakelock: - :path: ".symlinks/plugins/wakelock/ios" - webview_flutter: - :path: ".symlinks/plugins/webview_flutter/ios" - -SPEC CHECKSUMS: - Flutter: 434fef37c0980e73bb6479ef766c45957d4b510c - FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a - in_app_review: 4a97249f7a2f539a0f294c2d9196b7fe35e49541 - path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c - share: 0b2c3e82132f5888bccca3351c504d0003b3b410 - shared_preferences: af6bfa751691cdc24be3045c43ec037377ada40d - sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904 - url_launcher: 6fef411d543ceb26efce54b05a0a40bfd74cbbef - video_player: 9cc823b1d9da7e8427ee591e8438bfbcde500e6e - wakelock: b0843b2479edbf6504d8d262c2959446f35373aa - webview_flutter: 9f491a9b5a66f2573946a389b2677987b0ff8c0b - -PODFILE CHECKSUM: aafe91acc616949ddb318b77800a7f51bffa2a4c - -COCOAPODS: 1.10.1 diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index 4828be7..5fc9859 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -3,19 +3,29 @@ archiveVersion = 1; classes = { }; - objectVersion = 46; + objectVersion = 54; objects = { /* Begin PBXBuildFile section */ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; - 43E9CA89F47D1FDB34939265 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C8A13D8857D3BAD074F8435A /* Pods_Runner.framework */; }; 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 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 */; }; + 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; }; /* End PBXBuildFile section */ +/* Begin PBXContainerItemProxy section */ + 331C8085294A63A400263BE5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 97C146E61CF9000F007C117D /* Project object */; + proxyType = 1; + remoteGlobalIDString = 97C146ED1CF9000F007C117D; + remoteInfo = Runner; + }; +/* End PBXContainerItemProxy section */ + /* Begin PBXCopyFilesBuildPhase section */ 9705A1C41CF9048500538489 /* Embed Frameworks */ = { isa = PBXCopyFilesBuildPhase; @@ -43,10 +53,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 = ""; }; - ADB5DAD0D6C181B7E50A1001 /* 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 = ""; }; - B91641690FDC10F7E695EDEE /* 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 = ""; }; - C4F3784223F898177F22886E /* 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 = ""; }; - C8A13D8857D3BAD074F8435A /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; + 331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -54,24 +62,12 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 43E9CA89F47D1FDB34939265 /* Pods_Runner.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 549BAF9DDA4CAEB562D76A62 /* Pods */ = { - isa = PBXGroup; - children = ( - ADB5DAD0D6C181B7E50A1001 /* Pods-Runner.debug.xcconfig */, - B91641690FDC10F7E695EDEE /* Pods-Runner.release.xcconfig */, - C4F3784223F898177F22886E /* Pods-Runner.profile.xcconfig */, - ); - name = Pods; - path = Pods; - sourceTree = ""; - }; 9740EEB11CF90186004384FC /* Flutter */ = { isa = PBXGroup; children = ( @@ -83,14 +79,21 @@ name = Flutter; sourceTree = ""; }; + 331C8082294A63A400263BE5 /* RunnerTests */ = { + isa = PBXGroup; + children = ( + 331C807B294A618700263BE5 /* RunnerTests.swift */, + ); + path = RunnerTests; + sourceTree = ""; + }; 97C146E51CF9000F007C117D = { isa = PBXGroup; children = ( 9740EEB11CF90186004384FC /* Flutter */, 97C146F01CF9000F007C117D /* Runner */, 97C146EF1CF9000F007C117D /* Products */, - 549BAF9DDA4CAEB562D76A62 /* Pods */, - C14DB7DAA58D6214F0B8F980 /* Frameworks */, + 331C8082294A63A400263BE5 /* RunnerTests */, ); sourceTree = ""; }; @@ -98,6 +101,7 @@ isa = PBXGroup; children = ( 97C146EE1CF9000F007C117D /* Runner.app */, + 331C8081294A63A400263BE5 /* RunnerTests.xctest */, ); name = Products; sourceTree = ""; @@ -117,29 +121,37 @@ path = Runner; sourceTree = ""; }; - C14DB7DAA58D6214F0B8F980 /* Frameworks */ = { - isa = PBXGroup; - children = ( - C8A13D8857D3BAD074F8435A /* Pods_Runner.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ + 331C8080294A63A400263BE5 /* RunnerTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; + buildPhases = ( + 331C807D294A63A400263BE5 /* Sources */, + 331C807E294A63A400263BE5 /* Frameworks */, + 331C807F294A63A400263BE5 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 331C8086294A63A400263BE5 /* PBXTargetDependency */, + ); + name = RunnerTests; + productName = RunnerTests; + productReference = 331C8081294A63A400263BE5 /* RunnerTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; 97C146ED1CF9000F007C117D /* Runner */ = { isa = PBXNativeTarget; buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; buildPhases = ( - 9AE148C57AE2E9A95270378B /* [CP] Check Pods Manifest.lock */, 9740EEB61CF901F6004384FC /* Run Script */, 97C146EA1CF9000F007C117D /* Sources */, 97C146EB1CF9000F007C117D /* Frameworks */, 97C146EC1CF9000F007C117D /* Resources */, 9705A1C41CF9048500538489 /* Embed Frameworks */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */, - 4ECFAF3E0D8DCA9597F9188D /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -156,9 +168,14 @@ 97C146E61CF9000F007C117D /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 1020; + BuildIndependentTargetsInParallel = YES; + LastUpgradeCheck = 1430; ORGANIZATIONNAME = ""; TargetAttributes = { + 331C8080294A63A400263BE5 = { + CreatedOnToolsVersion = 14.0; + TestTargetID = 97C146ED1CF9000F007C117D; + }; 97C146ED1CF9000F007C117D = { CreatedOnToolsVersion = 7.3.1; LastSwiftMigration = 1100; @@ -179,11 +196,19 @@ projectRoot = ""; targets = ( 97C146ED1CF9000F007C117D /* Runner */, + 331C8080294A63A400263BE5 /* RunnerTests */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ + 331C807F294A63A400263BE5 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 97C146EC1CF9000F007C117D /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -200,10 +225,12 @@ /* Begin PBXShellScriptBuildPhase section */ 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); inputPaths = ( + "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", ); name = "Thin Binary"; outputPaths = ( @@ -212,25 +239,9 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; }; - 4ECFAF3E0D8DCA9597F9188D /* [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; - }; 9740EEB61CF901F6004384FC /* Run Script */ = { isa = PBXShellScriptBuildPhase; + alwaysOutOfDate = 1; buildActionMask = 2147483647; files = ( ); @@ -243,31 +254,17 @@ shellPath = /bin/sh; shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; }; - 9AE148C57AE2E9A95270378B /* [CP] Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 331C807D294A63A400263BE5 /* Sources */ = { + isa = PBXSourcesBuildPhase; 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", + 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */, ); 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 */ 97C146EA1CF9000F007C117D /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -279,6 +276,14 @@ }; /* End PBXSourcesBuildPhase section */ +/* Begin PBXTargetDependency section */ + 331C8086294A63A400263BE5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 97C146ED1CF9000F007C117D /* Runner */; + targetProxy = 331C8085294A63A400263BE5 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + /* Begin PBXVariantGroup section */ 97C146FA1CF9000F007C117D /* Main.storyboard */ = { isa = PBXVariantGroup; @@ -340,7 +345,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; @@ -357,17 +362,12 @@ CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; ENABLE_BITCODE = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - LIBRARY_SEARCH_PATHS = ( + LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", - "$(PROJECT_DIR)/Flutter", + "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.muslimtechnet.hanswehr; + PRODUCT_BUNDLE_IDENTIFIER = com.example.hansWehr; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; @@ -375,6 +375,56 @@ }; name = Profile; }; + 331C8088294A63A400263BE5 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = AE0B7B92F70575B8D7E0D07E /* Pods-RunnerTests.debug.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.example.hansWehr.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; + }; + name = Debug; + }; + 331C8089294A63A400263BE5 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 89B67EB44CE7B6631473024E /* Pods-RunnerTests.release.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.example.hansWehr.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; + }; + name = Release; + }; + 331C808A294A63A400263BE5 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 640959BDD8F10B91D80A66BE /* Pods-RunnerTests.profile.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.example.hansWehr.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner"; + }; + name = Profile; + }; 97C147031CF9000F007C117D /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -422,7 +472,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -471,11 +521,12 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 9.0; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; - SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; @@ -489,17 +540,12 @@ CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; ENABLE_BITCODE = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - LIBRARY_SEARCH_PATHS = ( + LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", - "$(PROJECT_DIR)/Flutter", + "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.muslimtechnet.hanswehr; + PRODUCT_BUNDLE_IDENTIFIER = com.example.hansWehr; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; @@ -516,17 +562,12 @@ CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; ENABLE_BITCODE = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); INFOPLIST_FILE = Runner/Info.plist; - LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - LIBRARY_SEARCH_PATHS = ( + LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", - "$(PROJECT_DIR)/Flutter", + "@executable_path/Frameworks", ); - PRODUCT_BUNDLE_IDENTIFIER = com.muslimtechnet.hanswehr; + PRODUCT_BUNDLE_IDENTIFIER = com.example.hansWehr; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; SWIFT_VERSION = 5.0; @@ -537,6 +578,16 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ + 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 331C8088294A63A400263BE5 /* Debug */, + 331C8089294A63A400263BE5 /* Release */, + 331C808A294A63A400263BE5 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index a28140c..87131a0 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/Assets.xcassets/LaunchBackground.imageset/Contents.json b/ios/Runner/Assets.xcassets/LaunchBackground.imageset/Contents.json deleted file mode 100644 index 9f447e1..0000000 --- a/ios/Runner/Assets.xcassets/LaunchBackground.imageset/Contents.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "images" : [ - { - "filename" : "background.png", - "idiom" : "universal", - "scale" : "1x" - }, - { - "idiom" : "universal", - "scale" : "2x" - }, - { - "idiom" : "universal", - "scale" : "3x" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/ios/Runner/Assets.xcassets/LaunchBackground.imageset/background.png b/ios/Runner/Assets.xcassets/LaunchBackground.imageset/background.png deleted file mode 100644 index e29b3b59f99290135b0cf3745bc9993ce935b27c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 68 zcmeAS@N?(olHy`uVBq!ia0vp^j3CUx1|;Q0k8}blZci7-kP61+pZqKgT>LDI5tB{+ Q0fiYnUHx3vIVCg!0BB+iu>b%7 diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json index 00cabce..0bedcf2 100644 --- a/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json +++ b/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json @@ -1,23 +1,23 @@ { "images" : [ { - "filename" : "LaunchImage.png", "idiom" : "universal", + "filename" : "LaunchImage.png", "scale" : "1x" }, { - "filename" : "LaunchImage@2x.png", "idiom" : "universal", + "filename" : "LaunchImage@2x.png", "scale" : "2x" }, { - "filename" : "LaunchImage@3x.png", "idiom" : "universal", + "filename" : "LaunchImage@3x.png", "scale" : "3x" } ], "info" : { - "author" : "xcode", - "version" : 1 + "version" : 1, + "author" : "xcode" } } diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png index 67774cf3dacac0ad161013438381c330272b67f7..9da19eacad3b03bb08bbddbbf4ac48dd78b3d838 100644 GIT binary patch delta 48 zcmZ>9nINgn!oa|=RfdNNNO60*IEGZrN&a=7fq{vgk!hBUVIfeM!PC{xWt~$(69DxS B3j+WE delta 48 zcmZ>9nINgn#=yWJFM6aCNO60*IEGX(CMPm5F)&Cnuuk}3_7y11;OXk;vd$@?2>|Y^ B3kv`M diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png index 67774cf3dacac0ad161013438381c330272b67f7..9da19eacad3b03bb08bbddbbf4ac48dd78b3d838 100644 GIT binary patch delta 48 zcmZ>9nINgn!oa|=RfdNNNO60*IEGZrN&a=7fq{vgk!hBUVIfeM!PC{xWt~$(69DxS B3j+WE delta 48 zcmZ>9nINgn#=yWJFM6aCNO60*IEGX(CMPm5F)&Cnuuk}3_7y11;OXk;vd$@?2>|Y^ B3kv`M diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png index 67774cf3dacac0ad161013438381c330272b67f7..9da19eacad3b03bb08bbddbbf4ac48dd78b3d838 100644 GIT binary patch delta 48 zcmZ>9nINgn!oa|=RfdNNNO60*IEGZrN&a=7fq{vgk!hBUVIfeM!PC{xWt~$(69DxS B3j+WE delta 48 zcmZ>9nINgn#=yWJFM6aCNO60*IEGX(CMPm5F)&Cnuuk}3_7y11;OXk;vd$@?2>|Y^ B3kv`M diff --git a/ios/Runner/Base.lproj/LaunchScreen.storyboard b/ios/Runner/Base.lproj/LaunchScreen.storyboard index c9811f0..f2e259c 100644 --- a/ios/Runner/Base.lproj/LaunchScreen.storyboard +++ b/ios/Runner/Base.lproj/LaunchScreen.storyboard @@ -16,19 +16,13 @@ - - + + - - - - - - - - + + @@ -39,6 +33,5 @@ - - \ No newline at end of file + diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist index e4f3b10..fc48e0c 100644 --- a/ios/Runner/Info.plist +++ b/ios/Runner/Info.plist @@ -1,47 +1,49 @@ - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - search - CFBundlePackageType - APPL - CFBundleShortVersionString - $(FLUTTER_BUILD_NAME) - CFBundleSignature - ???? - CFBundleVersion - $(FLUTTER_BUILD_NUMBER) - LSRequiresIPhoneOS - - UILaunchStoryboardName - LaunchScreen - UIMainStoryboardFile - Main - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UIViewControllerBasedStatusBarAppearance - - UIStatusBarHidden - - - \ No newline at end of file + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + Hans Wehr + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + hans_wehr + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + CADisableMinimumFrameDurationOnPhone + + UIApplicationSupportsIndirectInputEvents + + + diff --git a/ios/RunnerTests/RunnerTests.swift b/ios/RunnerTests/RunnerTests.swift new file mode 100644 index 0000000..86a7c3b --- /dev/null +++ b/ios/RunnerTests/RunnerTests.swift @@ -0,0 +1,12 @@ +import Flutter +import UIKit +import XCTest + +class RunnerTests: XCTestCase { + + func testExample() { + // If you add code to the Runner application, consider adding tests here. + // See https://developer.apple.com/documentation/xctest for more information about using XCTest. + } + +} diff --git a/lib/classes/appTheme.dart b/lib/classes/app_theme.dart similarity index 88% rename from lib/classes/appTheme.dart rename to lib/classes/app_theme.dart index 461b26d..220c9d0 100644 --- a/lib/classes/appTheme.dart +++ b/lib/classes/app_theme.dart @@ -1,33 +1,33 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import '../serviceLocator.dart'; -import '../services/LocalStorageService.dart'; +import '../service_locator.dart'; +import '../services/local_storage_service.dart'; ThemeData lightTheme = ThemeData.light().copyWith( textTheme: ThemeData.light().textTheme.copyWith( - bodyText1: TextStyle( + bodyLarge: TextStyle( fontFamily: locator().font, fontSize: 16 + locator().fontSizeDelta, color: Colors.black, ), - bodyText2: TextStyle( + bodyMedium: TextStyle( fontFamily: locator().font, fontSize: 16 + locator().fontSizeDelta, color: hexToColor(locator().highlightTextColor) ?? Colors.blue, ), - subtitle1: TextStyle( + titleMedium: TextStyle( fontFamily: locator().font, fontSize: 16 + locator().fontSizeDelta, color: Colors.black, ), - subtitle2: TextStyle( + titleSmall: TextStyle( fontFamily: locator().font, fontSize: 16 + locator().fontSizeDelta, color: Colors.white, ), - headline6: TextStyle( + titleLarge: TextStyle( fontFamily: locator().font, fontSize: 20 + locator().fontSizeDelta, color: Colors.black, @@ -49,34 +49,34 @@ ThemeData lightTheme = ThemeData.light().copyWith( ), brightness: Brightness.light, cardColor: hexToColor(locator().searchBarColor), - iconTheme: IconThemeData(color: Colors.black), + iconTheme: const IconThemeData(color: Colors.black), ); ThemeData darkTheme = ThemeData.dark().copyWith( textTheme: ThemeData.dark().textTheme.copyWith( - bodyText1: TextStyle( + bodyLarge: TextStyle( fontFamily: locator().font, fontSize: 16 + locator().fontSizeDelta, color: Colors.white, ), - bodyText2: TextStyle( + bodyMedium: TextStyle( fontFamily: locator().font, fontSize: 16 + locator().fontSizeDelta, color: hexToColor(locator().highlightTextColor) ?? Colors.cyan, ), - subtitle1: TextStyle( + titleMedium: TextStyle( fontFamily: locator().font, fontSize: 16 + locator().fontSizeDelta, color: Colors.white, ), - subtitle2: TextStyle( + titleSmall: TextStyle( fontFamily: locator().font, fontSize: 16 + locator().fontSizeDelta, color: Colors.black, ), - headline6: TextStyle( + titleLarge: TextStyle( fontFamily: locator().font, fontSize: 20 + locator().fontSizeDelta, color: Colors.white, @@ -98,7 +98,7 @@ ThemeData darkTheme = ThemeData.dark().copyWith( ), cardColor: hexToColor(locator().searchBarColor), brightness: Brightness.dark, - iconTheme: IconThemeData(color: Colors.white), + iconTheme: const IconThemeData(color: Colors.white), ); Color? hexToColor(String? code) { diff --git a/lib/classes/definitionClass.dart b/lib/classes/definitionClass.dart deleted file mode 100644 index a763e55..0000000 --- a/lib/classes/definitionClass.dart +++ /dev/null @@ -1,29 +0,0 @@ -import 'package:flutter/foundation.dart'; - -class DefinitionClass with ChangeNotifier { - DefinitionClass({ - required this.id, - required this.word, - required this.definition, - required this.isRoot, - required this.highlight, - this.searchWord, - this.quranOccurrence, - required this.favoriteFlag, - }); - - static String? searchType; - String? searchWord; - List id; - List word; - List definition; - List isRoot; - List highlight; - List? quranOccurrence; - List favoriteFlag; - - void updateSearchType(String newSearchType) { - DefinitionClass.searchType = newSearchType; - notifyListeners(); - } -} diff --git a/lib/classes/definition_provider.dart b/lib/classes/definition_provider.dart new file mode 100644 index 0000000..c50e670 --- /dev/null +++ b/lib/classes/definition_provider.dart @@ -0,0 +1,48 @@ +import 'package:flutter/foundation.dart'; + +class DefinitionProvider with ChangeNotifier { + DefinitionProvider({ + required this.id, + required this.word, + required this.definition, + required this.isRoot, + required this.highlight, + this.searchWord, + this.quranOccurrence, + required this.favoriteFlag, + }); + + String? searchType; + String? searchWord; + List id; + List word; + List definition; + List isRoot; + List highlight; + List? quranOccurrence; + List favoriteFlag; + + void updateSearchType(String newSearchType) { + searchType = newSearchType; + notifyListeners(); + } + + void updateDefinition( + List newId, + List newWord, + List newDefinition, + List newIsRoot, + List newHighlight, + String newSearchWord, + List? newQuranOccurrence, + List newFavoriteFlag) { + id = newId; + word = newWord; + definition = newDefinition; + isRoot = newIsRoot; + highlight = newHighlight; + quranOccurrence = newQuranOccurrence; + favoriteFlag = newFavoriteFlag; + notifyListeners(); + } +} diff --git a/lib/classes/searchModel.dart b/lib/classes/search_suggestions_provider.dart similarity index 89% rename from lib/classes/searchModel.dart rename to lib/classes/search_suggestions_provider.dart index 11bd446..9ec00da 100644 --- a/lib/classes/searchModel.dart +++ b/lib/classes/search_suggestions_provider.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; -import '../services/LocalStorageService.dart'; -import '../constants/appConstants.dart'; -import '../serviceLocator.dart'; +import '../services/local_storage_service.dart'; +import '../constants/app_constants.dart'; +import '../service_locator.dart'; -class SearchModel extends ChangeNotifier { +class SearchSuggestionsProvider extends ChangeNotifier { bool _isLoading = false; bool get isLoading => _isLoading; diff --git a/lib/classes/themeModel.dart b/lib/classes/theme_model.dart similarity index 89% rename from lib/classes/themeModel.dart rename to lib/classes/theme_model.dart index 3819021..57b7eb2 100644 --- a/lib/classes/themeModel.dart +++ b/lib/classes/theme_model.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import '../serviceLocator.dart'; -import '../services/LocalStorageService.dart'; -import 'appTheme.dart'; +import '../service_locator.dart'; +import '../services/local_storage_service.dart'; +import 'app_theme.dart'; class ThemeModel extends ChangeNotifier { ThemeData currentTheme = @@ -12,29 +12,29 @@ class ThemeModel extends ChangeNotifier { currentTheme = locator().darkTheme ? darkTheme.copyWith( textTheme: ThemeData.dark().textTheme.copyWith( - bodyText1: TextStyle( + bodyLarge: TextStyle( fontFamily: locator().font, fontSize: 16 + locator().fontSizeDelta, color: Colors.white, ), - bodyText2: TextStyle( + bodyMedium: TextStyle( fontFamily: locator().font, fontSize: 16 + locator().fontSizeDelta, color: hexToColor(locator() .highlightTextColor) ?? Colors.cyan, ), - subtitle1: TextStyle( + titleMedium: TextStyle( fontFamily: locator().font, fontSize: 16 + locator().fontSizeDelta, color: Colors.white, ), - subtitle2: TextStyle( + titleSmall: TextStyle( fontFamily: locator().font, fontSize: 16 + locator().fontSizeDelta, color: Colors.black, ), - headline6: TextStyle( + titleLarge: TextStyle( fontFamily: locator().font, fontSize: 20 + locator().fontSizeDelta, color: Colors.white, @@ -60,29 +60,29 @@ class ThemeModel extends ChangeNotifier { ) : lightTheme.copyWith( textTheme: ThemeData.light().textTheme.copyWith( - bodyText1: TextStyle( + bodyLarge: TextStyle( fontFamily: locator().font, fontSize: 16 + locator().fontSizeDelta, color: Colors.black, ), - bodyText2: TextStyle( + bodyMedium: TextStyle( fontFamily: locator().font, fontSize: 16 + locator().fontSizeDelta, color: hexToColor(locator() .highlightTextColor) ?? Colors.blue, ), - subtitle1: TextStyle( + titleMedium: TextStyle( fontFamily: locator().font, fontSize: 16 + locator().fontSizeDelta, color: Colors.black, ), - subtitle2: TextStyle( + titleSmall: TextStyle( fontFamily: locator().font, fontSize: 16 + locator().fontSizeDelta, color: Colors.white, ), - headline6: TextStyle( + titleLarge: TextStyle( fontFamily: locator().font, fontSize: 20 + locator().fontSizeDelta, color: Colors.black, diff --git a/lib/constants/appConstants.dart b/lib/constants/app_constants.dart similarity index 96% rename from lib/constants/appConstants.dart rename to lib/constants/app_constants.dart index b30a5ff..d637019 100644 --- a/lib/constants/appConstants.dart +++ b/lib/constants/app_constants.dart @@ -1,27 +1,27 @@ import 'dart:core'; -import 'package:sqflite/sqflite.dart'; - -import '../services/getData.dart'; - -const String SETTINGS_SCREEN_TITLE = 'Settings'; -const String ABOUT_APP_SCREEN_TITLE = 'About App'; -const String PREFACE_SCREEN_TITLE = 'Preface & Intro'; -const String ABBREVIATIONS_SCREEN_TITLE = 'Abbreviations'; -const String SEARCH_SCREEN_TITLE = 'Search'; -const String BROWSE_SCREEN_TITLE = 'Browse'; -const String NOTIFICATION_SCREEN_TITLE = 'Notifications'; -const String DONATE_SCREEN_TITLE = 'Donate'; -const String FAVORITES_SCREEN_TITLE = 'Favorites'; -const String HISTORY_SCREEN_TITLE = 'History'; -const String MORE_APPS = 'More Apps'; -const String ALL_MY_APPS = 'All Apps By Me'; - -const String FAV_IMAGE = 'assets/like_button.jpg'; -const String DONATE_IMAGE = 'assets/donate.jpg'; -const String QURANLE_IMAGE = 'assets/Quranle.jpg'; -const String FOR_HIRE_IMAGE = 'assets/ForHire.webp'; -const String QURAN_IMAGE = 'assets/quran.jpg'; -const String HAITHHUB_IMAGE = 'assets/HadithHub.png'; +import 'package:sqflite_common_ffi/sqflite_ffi.dart'; + +import '../services/get_data.dart'; + +const String settingsScreenTitle = 'Settings'; +const String aboutAppScreenTitle = 'About App'; +const String prefaceScreenTitle = 'Preface & Intro'; +const String abbreviationsScreenTitle = 'Abbreviations'; +const String searchScreenTitle = 'Search'; +const String browseScreenTitle = 'Browse'; +const String notificationScreenTitle = 'Notifications'; +const String donateScreenTitle = 'Donate'; +const String favoritesScreenTitle = 'Favorites'; +const String historyScreenTitle = 'History'; +const String moreApps = 'More Apps'; +const String allMyApps = 'All Apps By Me'; + +const String favImage = 'assets/like_button.jpg'; +const String donateImage = 'assets/donate.jpg'; +const String quranleImage = 'assets/Quranle.jpg'; +const String forHireImage = 'assets/ForHire.webp'; +const String quranImage = 'assets/quran.jpg'; +const String hadithhubImage = 'assets/HadithHub.png'; final Uri quranleUri = Uri( scheme: "https", @@ -71,54 +71,54 @@ final Uri donateUri = Uri( host: 'donate.islamic-relief.org', ); -const String ABOUT_APP = ''' +const String aboutApp = '''

The Dictionary of Modern Written Arabic is an Arabic-English dictionary compiled by Hans Wehr and edited by J Milton Cowan.'''; -const String WHATS_NEW = - '''

What's New :
+const String whatsNew = '''

What's New :
- Favorites screen alignment issue fix
- Incorrect Favorite button color fix
- Minor UX improvements
Source Code, Full Release Notes and Future Work


'''; -const String COMMUNITY_INVITE = +const String communityInvite = '''

If you are a Muslim tech professional or aspiring to be one join the
Muslim Tech Network


'''; -const String DISCLAIMER = +const String disclaimer = '''

DISCLAIMER - Not 100% Accurate.
Text was extracted from scanned pages and has many errors which unfortunately is not possible for me to fix manually.
Try Arabic Students Dictionary which has most of these errors corrected.

'''; -const String CONTACT_ME = +const String contactMe = '

CONTACT ME

'; -const String EMAIL = "gibreel.khan@gmail.com"; +const String email = "gibreel.khan@gmail.com"; -const String SOCIAL_PROFILES = +const String socialProfiles = '

SOCAIL PROFILES

'; -const String COURTSEY = '''

COURTSEY +const String courtsey = '''

COURTSEY


'''; -final DatabaseAccess databaseObject = new DatabaseAccess(); + +final DatabaseAccess databaseObject = DatabaseAccess(); final Future databaseConnection = DatabaseAccess().openDatabaseConnection(); -const String PREFACE_TEXT = +const String prefaceText = '''Shortly after the publication of Professor Hans Wehr's Arabisches Wörterbuch für die Schriftsprache der Gegenwart in 1952, the Committee on Language Programs of the American Council of Learned Societies recognized its excellence and began to explore means of providing an up-to-date English edition. Professor Wehr and I readily reached agreement on a plan to translate, edit, and enlarge the dictionary. This task was considerably lightened and hastened by generous financial support from the American Council of Learned Societies, the Arabian American Oil Company, and Cornell University. This dictionary will be welcome not only to English and American users, but to orientalists throughout the world who are more at home with English than with German. It is more accurate and much more comprehensive than the original version, which was produced under extremely unfavorable conditions in Germany during the late war years and the early postwar period.\n'''; -const String PREFACE_POCKET_TEXT = +const String prefacePocketText = 'In order to meet the enormous increase of interest in Arabic brought about by political, economic and social developments of the past decade, we have now published our 3rd Revised Edition of A Dictionary of Modern Written Arabic in this handy, comprehensive and unabridged version.\n'; -const String INTRODUCTION_TEXT = +const String introText = '''This dictionary presents the vocabulary and phraseology of modern written Arabic. It is based on the form of the language which, throughout the Arab world from Iraq to Morocco, is found in the prose of books, newspapers, periodicals, and letters. This form is also employed in formal public address, over radio and television, and in religious ceremonial. The dictionary will be most useful to those working with writings that have appeared since the turn of the century. The morphology and syntax of written Arabic are essentially the same in all Arab countries. Vocabulary differences are limited mainly to the domain of specialized vocabulary. Thus the written language continues, as it has done throughout centuries of the past, to ensure the linguistic unity of the Arab world. It provides a medium of communication over the vast geographical area whose numerous and widely diverse local dialects it transcends. Indeed, it gives the Arab people of many countries a sense of identity and an awareness of their common cultural heritage. @@ -207,7 +207,7 @@ In transcription, two nouns forming a genitive compound are treated as a unit. T In view of the great variety and intricacy of the material presented, it is inevitable that inconsistencies will appear and that similar examples will be treated here and there in a different manner. For such incongruities and for certain redundancies, we must ask the user’s indulgence.\n'''; -const List VERB_FORMS = [ +const List verbForms = [ 'I - فَعَل/فَعُل/فَعِل', 'II - فَعّل', 'III - فَاعَل', @@ -222,7 +222,7 @@ const List VERB_FORMS = [ 'XII - اِفْعَوْعَلَ', ]; -const List VERB_FORM_DESCRIPTIONS = [ +const List verbFormDesc = [ 'Basic root', 'Doing something intensively/ repeatedly, doing or causing something to someone else', 'To try to do something, to do something with someone else', @@ -237,7 +237,7 @@ const List VERB_FORM_DESCRIPTIONS = [ 'Like Form XI tend to refer to a colour or physical quality' ]; -const List VERB_FORM_EXAMPLES = [ +const List verbFormExample = [ 'ضَرَبَ - He hit\n غفر - He forgave', 'علّم - He taught', 'قاتل - He fought', @@ -252,7 +252,7 @@ const List VERB_FORM_EXAMPLES = [ 'اِخْشَوْشَنَ - He became rough, coarse', ]; -const List ALL_ALPHABETS = [ +const List allAlphabets = [ "آ", "ا", "ب", @@ -284,7 +284,7 @@ const List ALL_ALPHABETS = [ "ي" ]; -const List ABBREVIATIONS = [ +const List abbreviations = [ "A", "abstr.", "acc.", @@ -482,7 +482,7 @@ const List ABBREVIATIONS = [ "Z", "zool.", ]; -const List FULL_FORM = [ +const List fullForm = [ "", "abstract", "accusative", diff --git a/lib/main.dart b/lib/main.dart index 6ab6eec..db3d736 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,25 +1,47 @@ import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; -import './classes/themeModel.dart'; -import './serviceLocator.dart'; -import './services/appReview.dart'; +import 'classes/definition_provider.dart'; +import 'classes/search_suggestions_provider.dart'; +import 'classes/theme_model.dart'; +import 'service_locator.dart'; +import 'services/app_review.dart'; import './routes.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); setupLocator().then( (value) => runApp( - ChangeNotifierProvider( - create: (BuildContext context) => ThemeModel(), - child: MyApp(), + MultiProvider( + providers: [ + ChangeNotifierProvider( + create: (BuildContext context) => ThemeModel(), + ), + ChangeNotifierProvider( + create: (_) => SearchSuggestionsProvider(), + ), + ChangeNotifierProvider( + create: (_) => DefinitionProvider( + id: [], + word: [], + definition: [], + isRoot: [], + highlight: [], + quranOccurrence: [], + favoriteFlag: [], + ), + ), + ], + child: const MyApp(), ), ), ); } class MyApp extends StatefulWidget { + const MyApp({Key? key}) : super(key: key); + @override - _MyAppState createState() => _MyAppState(); + State createState() => _MyAppState(); } class _MyAppState extends State { @@ -32,7 +54,7 @@ class _MyAppState extends State { @override Widget build(BuildContext context) { - return new MaterialApp( + return MaterialApp( title: "Hans Wehr Dictionary", theme: Provider.of(context, listen: true).currentTheme, initialRoute: '/search', diff --git a/lib/routes.dart b/lib/routes.dart index 272a8eb..89993e3 100644 --- a/lib/routes.dart +++ b/lib/routes.dart @@ -1,26 +1,26 @@ import 'package:flutter/widgets.dart'; import 'screens/history.dart'; import 'screens/favorites.dart'; -import 'screens/moreApps.dart'; +import 'screens/more_apps.dart'; import 'screens/abbreviations.dart'; -import 'screens/aboutApp.dart'; +import 'screens/about_app.dart'; import 'screens/browse.dart'; import 'screens/search.dart'; import 'screens/settings.dart'; import 'screens/donate.dart'; import 'screens/preface.dart'; -import 'screens/quranicWords.dart'; +import 'screens/quranic_words.dart'; Map routes = { - '/search': (context) => Search(), - '/aboutus': (context) => AboutApp(), - '/preface': (context) => Preface(), - '/browse': (context) => Browse(), - '/abbreviations': (context) => Abbreviations(), - '/moreapps': (context) => MoreApps(), - '/donate': (context) => Donate(), - '/settings': (context) => Settings(), - '/favorites': (context) => Favorites(), - '/history': (context) => History(), - '/quranicWords': (context) => QuranicWords(), + '/search': (context) => const Search(), + '/aboutus': (context) => const AboutApp(), + '/preface': (context) => const Preface(), + '/browse': (context) => const Browse(), + '/abbreviations': (context) => const Abbreviations(), + '/moreapps': (context) => const MoreApps(), + '/donate': (context) => const Donate(), + '/settings': (context) => const Settings(), + '/favorites': (context) => const Favorites(), + '/history': (context) => const History(), + '/quranicWords': (context) => const QuranicWords(), }; diff --git a/lib/screens/abbreviations.dart b/lib/screens/abbreviations.dart index 93cd7e1..dc8924e 100644 --- a/lib/screens/abbreviations.dart +++ b/lib/screens/abbreviations.dart @@ -1,57 +1,54 @@ import 'package:flutter/material.dart'; import '../widgets/drawer.dart'; -import '../constants/appConstants.dart'; +import '../constants/app_constants.dart'; class Abbreviations extends StatelessWidget { + const Abbreviations({Key? key}) : super(key: key); + @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( toolbarHeight: 56, title: Text( - ABBREVIATIONS_SCREEN_TITLE, - style: Theme.of(context).textTheme.headline6, + abbreviationsScreenTitle, + style: Theme.of(context).textTheme.titleLarge, ), backgroundColor: Theme.of(context).appBarTheme.backgroundColor, iconTheme: Theme.of(context).iconTheme, ), - drawer: CommonDrawer(currentScreen: ABBREVIATIONS_SCREEN_TITLE), + drawer: const CommonDrawer(currentScreen: abbreviationsScreenTitle), body: ListView.builder( - padding: EdgeInsets.fromLTRB(8, 8, 8, 8), - itemCount: ABBREVIATIONS.length, + padding: const EdgeInsets.fromLTRB(8, 8, 8, 8), + itemCount: abbreviations.length, itemBuilder: (context, index) { - if (FULL_FORM[index] == "") { - return Container( - // alignment: AlignmentDirectional.bottomStart, - child: Text( - ABBREVIATIONS[index], - textScaleFactor: 2, - textAlign: TextAlign.left, - style: Theme.of(context).textTheme.bodyText1!.copyWith( - color: Colors.grey, - ), - ), + if (fullForm[index] == "") { + return Text( + abbreviations[index], + textScaleFactor: 2, + textAlign: TextAlign.left, + style: Theme.of(context).textTheme.bodyLarge!.copyWith( + color: Colors.grey, + ), ); } else { - return Container( - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Container( - width: MediaQuery.of(context).size.width * .25, - child: Text(ABBREVIATIONS[index], - style: Theme.of(context).textTheme.bodyText1), - ), - SizedBox( - width: 10, - ), - Container( - width: MediaQuery.of(context).size.width * .6, - child: Text(FULL_FORM[index], - style: Theme.of(context).textTheme.bodyText1), - ), - ], - ), + return Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SizedBox( + width: MediaQuery.of(context).size.width * .25, + child: Text(abbreviations[index], + style: Theme.of(context).textTheme.bodyLarge), + ), + const SizedBox( + width: 10, + ), + SizedBox( + width: MediaQuery.of(context).size.width * .6, + child: Text(fullForm[index], + style: Theme.of(context).textTheme.bodyLarge), + ), + ], ); } }, diff --git a/lib/screens/aboutApp.dart b/lib/screens/about_app.dart similarity index 63% rename from lib/screens/aboutApp.dart rename to lib/screens/about_app.dart index 5d76ac0..b250cb2 100644 --- a/lib/screens/aboutApp.dart +++ b/lib/screens/about_app.dart @@ -4,11 +4,13 @@ import 'package:flutter/material.dart'; import 'package:url_launcher/url_launcher.dart'; import '../widgets/drawer.dart'; -import '../constants/appConstants.dart'; +import '../constants/app_constants.dart'; class AboutApp extends StatefulWidget { + const AboutApp({Key? key}) : super(key: key); + @override - _AboutAppState createState() => _AboutAppState(); + State createState() => _AboutAppState(); } class _AboutAppState extends State { @@ -18,88 +20,88 @@ class _AboutAppState extends State { appBar: AppBar( toolbarHeight: 56, title: Text( - ABOUT_APP_SCREEN_TITLE, - style: Theme.of(context).textTheme.headline6, + aboutAppScreenTitle, + style: Theme.of(context).textTheme.titleLarge, ), backgroundColor: Theme.of(context).appBarTheme.backgroundColor, iconTheme: Theme.of(context).iconTheme, ), - drawer: CommonDrawer(currentScreen: ABOUT_APP_SCREEN_TITLE), + drawer: const CommonDrawer(currentScreen: aboutAppScreenTitle), body: SingleChildScrollView( child: Padding( padding: const EdgeInsets.fromLTRB(8, 8, 8, 100), child: Column( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Padding( - padding: const EdgeInsets.all(16.0), + const Padding( + padding: EdgeInsets.all(16.0), child: Divider(), ), HtmlWidget( - DISCLAIMER, - textStyle: Theme.of(context).textTheme.bodyText1!, + disclaimer, + textStyle: Theme.of(context).textTheme.bodyLarge!, ), - Padding( - padding: const EdgeInsets.all(16.0), + const Padding( + padding: EdgeInsets.all(16.0), child: Divider(), ), HtmlWidget( - ABOUT_APP, - textStyle: Theme.of(context).textTheme.bodyText1!, + aboutApp, + textStyle: Theme.of(context).textTheme.bodyLarge!, ), - Padding( - padding: const EdgeInsets.all(16.0), + const Padding( + padding: EdgeInsets.all(16.0), child: Divider(), ), HtmlWidget( - WHATS_NEW, - textStyle: Theme.of(context).textTheme.bodyText1!, + whatsNew, + textStyle: Theme.of(context).textTheme.bodyLarge!, ), - Padding( - padding: const EdgeInsets.all(16.0), + const Padding( + padding: EdgeInsets.all(16.0), child: Divider(), ), HtmlWidget( - COURTSEY, - textStyle: Theme.of(context).textTheme.bodyText1!, + courtsey, + textStyle: Theme.of(context).textTheme.bodyLarge!, ), - Padding( - padding: const EdgeInsets.all(16.0), + const Padding( + padding: EdgeInsets.all(16.0), child: Divider(), ), HtmlWidget( - CONTACT_ME, - textStyle: Theme.of(context).textTheme.bodyText1!, + contactMe, + textStyle: Theme.of(context).textTheme.bodyLarge!, ), GestureDetector( child: Text( - EMAIL, + email, style: TextStyle(color: Theme.of(context).primaryColor), ), onTap: () { Clipboard.setData( - ClipboardData(text: EMAIL), + const ClipboardData(text: email), ); ScaffoldMessenger.of(context).showSnackBar( - SnackBar( + const SnackBar( content: Text("Email Copied"), ), ); }, ), - Padding( - padding: const EdgeInsets.all(16.0), + const Padding( + padding: EdgeInsets.all(16.0), child: Divider(), ), HtmlWidget( - SOCIAL_PROFILES, - textStyle: Theme.of(context).textTheme.bodyText1!, + socialProfiles, + textStyle: Theme.of(context).textTheme.bodyLarge!, ), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ GestureDetector( - child: Image( + child: const Image( image: AssetImage('assets/GitHub.png'), ), onTap: () { @@ -107,9 +109,9 @@ class _AboutAppState extends State { mode: LaunchMode.externalApplication); }, ), - Padding(padding: EdgeInsets.all(16)), + const Padding(padding: EdgeInsets.all(16)), GestureDetector( - child: Image( + child: const Image( image: AssetImage('assets/linkedin.png'), ), onTap: () { @@ -117,9 +119,9 @@ class _AboutAppState extends State { mode: LaunchMode.externalApplication); }, ), - Padding(padding: EdgeInsets.all(16)), + const Padding(padding: EdgeInsets.all(16)), GestureDetector( - child: Image( + child: const Image( image: AssetImage('assets/website.png'), ), onTap: () { @@ -129,8 +131,8 @@ class _AboutAppState extends State { ), ], ), - Padding( - padding: const EdgeInsets.all(16.0), + const Padding( + padding: EdgeInsets.all(16.0), child: Divider(), ), ]), diff --git a/lib/screens/browse.dart b/lib/screens/browse.dart index d77a9dd..b7b10c8 100644 --- a/lib/screens/browse.dart +++ b/lib/screens/browse.dart @@ -2,49 +2,51 @@ import 'dart:core'; import 'package:flutter/material.dart'; import 'package:flutter_widget_from_html/flutter_widget_from_html.dart'; -import 'package:hans_wehr_dictionary/widgets/quranOccurrenceAlert.dart'; -import '../classes/definitionClass.dart'; +import '../classes/definition_provider.dart'; import '../widgets/drawer.dart'; -import '../constants/appConstants.dart'; +import '../constants/app_constants.dart'; +import '../widgets/quran_occurrence_alert.dart'; class Browse extends StatefulWidget { + const Browse({Key? key}) : super(key: key); + @override - _BrowseState createState() => _BrowseState(); + State createState() => _BrowseState(); } class _BrowseState extends State { @override Widget build(BuildContext context) { - return new Scaffold( + return Scaffold( appBar: AppBar( toolbarHeight: 56, title: Text( - BROWSE_SCREEN_TITLE, - style: Theme.of(context).textTheme.headline6, + browseScreenTitle, + style: Theme.of(context).textTheme.titleLarge, ), backgroundColor: Theme.of(context).appBarTheme.backgroundColor, iconTheme: Theme.of(context).iconTheme, ), - drawer: CommonDrawer(currentScreen: BROWSE_SCREEN_TITLE), + drawer: const CommonDrawer(currentScreen: browseScreenTitle), body: buildFirstLevelAlphabets(), ); } ListView buildFirstLevelAlphabets() { return ListView.builder( - padding: EdgeInsets.fromLTRB(0, 0, 0, 100), - itemCount: ALL_ALPHABETS.length, + padding: const EdgeInsets.fromLTRB(0, 0, 0, 100), + itemCount: allAlphabets.length, itemBuilder: (context, i) { return ExpansionTile( - collapsedIconColor: Theme.of(context).textTheme.bodyText1!.color, - collapsedTextColor: Theme.of(context).textTheme.bodyText1!.color, - iconColor: Theme.of(context).textTheme.bodyText2!.color, - textColor: Theme.of(context).textTheme.bodyText2!.color, + collapsedIconColor: Theme.of(context).textTheme.bodyLarge!.color, + collapsedTextColor: Theme.of(context).textTheme.bodyLarge!.color, + iconColor: Theme.of(context).textTheme.bodyMedium!.color, + textColor: Theme.of(context).textTheme.bodyMedium!.color, title: Text( - ALL_ALPHABETS[i], + allAlphabets[i], style: TextStyle( - fontFamily: Theme.of(context).textTheme.bodyText1!.fontFamily, - fontSize: Theme.of(context).textTheme.bodyText1!.fontSize, + fontFamily: Theme.of(context).textTheme.bodyLarge!.fontFamily, + fontSize: Theme.of(context).textTheme.bodyLarge!.fontSize, ), ), children: [buildSecondLevelAlphabets(i)], @@ -55,31 +57,31 @@ class _BrowseState extends State { FutureBuilder> buildSecondLevelAlphabets(int i) { return FutureBuilder>( - future: databaseObject.allXLevelWords(ALL_ALPHABETS[i], 2), + future: databaseObject.allXLevelWords(allAlphabets[i], 2), builder: (context, snapshot) { if (!snapshot.hasData) { return Center( child: Text( 'Loading...', - style: Theme.of(context).textTheme.bodyText1, + style: Theme.of(context).textTheme.bodyLarge, ), ); } else { return ListView.builder( - physics: NeverScrollableScrollPhysics(), + physics: const NeverScrollableScrollPhysics(), shrinkWrap: true, itemCount: snapshot.data!.length, itemBuilder: (context, j) { return ExpansionTile( - iconColor: Theme.of(context).textTheme.bodyText2!.color, - textColor: Theme.of(context).textTheme.bodyText2!.color, - tilePadding: EdgeInsets.fromLTRB(40, 0, 40, 0), + iconColor: Theme.of(context).textTheme.bodyMedium!.color, + textColor: Theme.of(context).textTheme.bodyMedium!.color, + tilePadding: const EdgeInsets.fromLTRB(40, 0, 40, 0), title: Text( snapshot.data![j]!, style: TextStyle( fontFamily: - Theme.of(context).textTheme.bodyText1!.fontFamily, - fontSize: Theme.of(context).textTheme.bodyText1!.fontSize, + Theme.of(context).textTheme.bodyLarge!.fontFamily, + fontSize: Theme.of(context).textTheme.bodyLarge!.fontSize, ), ), children: [buildRootWords(snapshot, j)], @@ -97,7 +99,7 @@ class _BrowseState extends State { builder: (context, snapshot) { if (snapshot.hasData) { return ListView.builder( - physics: NeverScrollableScrollPhysics(), + physics: const NeverScrollableScrollPhysics(), shrinkWrap: true, itemCount: snapshot.data!.length, itemBuilder: (context, j) { @@ -110,7 +112,7 @@ class _BrowseState extends State { ), title: Text( snapshot.data![j]!, - style: Theme.of(context).textTheme.bodyText1, + style: Theme.of(context).textTheme.bodyLarge, ), onTap: () { buildDefinitionAlert(context, snapshot.data![j]); @@ -119,7 +121,7 @@ class _BrowseState extends State { ); }); } else { - return Center( + return const Center( child: CircularProgressIndicator(), ); } @@ -137,21 +139,21 @@ Future buildDefinitionAlert(BuildContext context, String? word) { return showDialog( context: context, builder: (BuildContext context) { - return FutureBuilder( + return FutureBuilder( future: databaseObject.definition(word, "BrowseScreen"), builder: (context, snapshot) { if (snapshot.hasData) { return AlertDialog( actionsAlignment: MainAxisAlignment.spaceBetween, - insetPadding: EdgeInsets.all(0), - contentPadding: EdgeInsets.all(15), + insetPadding: const EdgeInsets.all(0), + contentPadding: const EdgeInsets.all(15), title: Center( child: Text( word!, - style: Theme.of(context).textTheme.bodyText1, + style: Theme.of(context).textTheme.bodyLarge, ), ), - content: Container( + content: SizedBox( height: MediaQuery.of(context).size.height * .7, width: MediaQuery.of(context).size.width * .9, child: ListView.builder( @@ -165,7 +167,7 @@ Future buildDefinitionAlert(BuildContext context, String? word) { 0), title: HtmlWidget( snapshot.data!.definition[index]!, - textStyle: Theme.of(context).textTheme.bodyText1!, + textStyle: Theme.of(context).textTheme.bodyLarge!, ), ); }, @@ -176,7 +178,7 @@ Future buildDefinitionAlert(BuildContext context, String? word) { ? TextButton( child: Text( 'Q - ${snapshot.data!.quranOccurrence![0]}', - style: Theme.of(context).textTheme.bodyText2, + style: Theme.of(context).textTheme.bodyMedium, ), onPressed: () { quranOccurrenceDialog(context, @@ -187,7 +189,7 @@ Future buildDefinitionAlert(BuildContext context, String? word) { TextButton( child: Text( 'DISMISS', - style: Theme.of(context).textTheme.bodyText2, + style: Theme.of(context).textTheme.bodyMedium, ), onPressed: () { Navigator.of(context).pop(); diff --git a/lib/screens/donate.dart b/lib/screens/donate.dart index 0e23221..d87552e 100644 --- a/lib/screens/donate.dart +++ b/lib/screens/donate.dart @@ -1,9 +1,11 @@ import 'package:flutter/material.dart'; import 'package:url_launcher/url_launcher.dart'; -import '../constants/appConstants.dart'; +import '../constants/app_constants.dart'; class Donate extends StatelessWidget { + const Donate({Key? key}) : super(key: key); + @override Widget build(BuildContext context) { return SingleChildScrollView( @@ -14,50 +16,50 @@ class Donate extends StatelessWidget { Text( 'DONATE', textScaleFactor: 2, - style: Theme.of(context).textTheme.bodyText1, + style: Theme.of(context).textTheme.bodyLarge, ), - Padding(padding: EdgeInsets.all(10)), + const Padding(padding: EdgeInsets.all(10)), Text( 'Thanks for considering to donate.', textAlign: TextAlign.center, - style: Theme.of(context).textTheme.bodyText1, + style: Theme.of(context).textTheme.bodyLarge, ), Text( '''There are millions who are facing a devastating decade of crisis and previously unimaginable hardship. Kindly donate to them.''', textAlign: TextAlign.center, - style: Theme.of(context).textTheme.bodyText1, + style: Theme.of(context).textTheme.bodyLarge, ), ElevatedButton( onPressed: () { launchUrl(donateUri, mode: LaunchMode.externalApplication); }, - child: Text( - 'Donate through IslamicRelief', - style: Theme.of(context).textTheme.subtitle2, - ), style: ElevatedButton.styleFrom( backgroundColor: Theme.of(context).primaryColor, ), + child: Text( + 'Donate through IslamicRelief', + style: Theme.of(context).textTheme.titleSmall, + ), ), Center( child: Text( 'Or any other charity of your choice.', - style: Theme.of(context).textTheme.bodyText1, + style: Theme.of(context).textTheme.bodyLarge, ), ), - Padding( + const Padding( padding: EdgeInsets.all(20), ), Text( 'مَّن ذَا ٱلَّذِى يُقْرِضُ ٱللَّهَ قَرْضًا حَسَنًۭا فَيُضَـٰعِفَهُۥ لَهُۥٓ أَضْعَافًۭا كَثِيرَةًۭ ۚ وَٱللَّهُ يَقْبِضُ وَيَبْصُۜطُ وَإِلَيْهِ تُرْجَعُونَ', textAlign: TextAlign.center, - style: Theme.of(context).textTheme.bodyText1, + style: Theme.of(context).textTheme.bodyLarge, ), Text( 'Who will lend to Allah a good loan which Allah will multiply many times over? It is Allah alone who decreases and increases wealth. And to Him you will all be returned.', textAlign: TextAlign.center, - style: Theme.of(context).textTheme.bodyText1, + style: Theme.of(context).textTheme.bodyLarge, ) ], ), diff --git a/lib/screens/favorites.dart b/lib/screens/favorites.dart index 4ebc5fa..28361a7 100644 --- a/lib/screens/favorites.dart +++ b/lib/screens/favorites.dart @@ -1,11 +1,11 @@ import 'package:flutter/material.dart'; -import '../constants/appConstants.dart'; +import '../constants/app_constants.dart'; import 'browse.dart'; class Favorites extends StatefulWidget { const Favorites({Key? key}) : super(key: key); @override - _FavoritesState createState() => _FavoritesState(); + State createState() => _FavoritesState(); } class _FavoritesState extends State { @@ -21,7 +21,7 @@ class _FavoritesState extends State { 'FAVORITES', textAlign: TextAlign.center, textScaleFactor: 2, - style: Theme.of(context).textTheme.bodyText1, + style: Theme.of(context).textTheme.bodyLarge, ), FutureBuilder>>( future: databaseObject.getFavorites(), @@ -29,12 +29,12 @@ class _FavoritesState extends State { if (snapshot.hasData) { List> favData = []; favData.addAll(snapshot.data!); - if (favData.length == 0) { + if (favData.isEmpty) { return Expanded( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - Icon( + const Icon( Icons.heart_broken, size: 72, color: Colors.grey, @@ -42,7 +42,7 @@ class _FavoritesState extends State { Text( 'Favorite some words by selecting ❤️ icon', style: - Theme.of(context).textTheme.bodyText1!.copyWith( + Theme.of(context).textTheme.bodyLarge!.copyWith( color: Colors.grey, ), ), @@ -64,7 +64,7 @@ class _FavoritesState extends State { : Theme.of(context) .primaryColor .withAlpha(20), - borderRadius: BorderRadius.all( + borderRadius: const BorderRadius.all( Radius.circular(10), ), ), @@ -77,20 +77,20 @@ class _FavoritesState extends State { '${j + 1} ', style: Theme.of(context) .textTheme - .bodyText1! + .bodyLarge! .copyWith( color: Theme.of(context) .textTheme - .bodyText1! + .bodyLarge! .color! .withAlpha(100)), ), title: Text( favData[j]['word'], - style: Theme.of(context).textTheme.bodyText1, + style: Theme.of(context).textTheme.bodyLarge, ), trailing: IconButton( - icon: Icon(Icons.delete_forever), + icon: const Icon(Icons.delete_forever), onPressed: () { databaseObject.toggleFavorites( favData[j]['id'], 0); @@ -106,7 +106,7 @@ class _FavoritesState extends State { ), ); } else { - return Center( + return const Center( child: CircularProgressIndicator(), ); } diff --git a/lib/screens/history.dart b/lib/screens/history.dart index 63d504e..94f147c 100644 --- a/lib/screens/history.dart +++ b/lib/screens/history.dart @@ -1,6 +1,6 @@ import 'package:flutter/material.dart'; -import '../classes/searchModel.dart'; -import '../constants/appConstants.dart'; +import '../classes/search_suggestions_provider.dart'; +import '../constants/app_constants.dart'; import '../widgets/drawer.dart'; class History extends StatelessWidget { @@ -8,29 +8,26 @@ class History extends StatelessWidget { @override Widget build(BuildContext context) { - SearchModel().getHistory(); + SearchSuggestionsProvider().getHistory(); return Scaffold( appBar: AppBar( toolbarHeight: 56, title: Text( - HISTORY_SCREEN_TITLE, - style: Theme.of(context).textTheme.headline6, + historyScreenTitle, + style: Theme.of(context).textTheme.titleLarge, ), backgroundColor: Theme.of(context).appBarTheme.backgroundColor, iconTheme: Theme.of(context).iconTheme, ), - drawer: CommonDrawer(currentScreen: HISTORY_SCREEN_TITLE), + drawer: const CommonDrawer(currentScreen: historyScreenTitle), body: ListView.builder( - itemCount: SearchModel().getHistory().length, + itemCount: SearchSuggestionsProvider().getHistory().length, itemBuilder: (context, index) { return ListTile( // leading: Text((index + 1).toString()), title: Text( - (index + 1).toString() + - ' - ' + - SearchModel().getHistory()[ - SearchModel().getHistory().length - index - 1], + '${index + 1} - ${SearchSuggestionsProvider().getHistory()[SearchSuggestionsProvider().getHistory().length - index - 1]}', ), ); }, diff --git a/lib/screens/moreApps.dart b/lib/screens/more_apps.dart similarity index 70% rename from lib/screens/moreApps.dart rename to lib/screens/more_apps.dart index e425740..4e14403 100644 --- a/lib/screens/moreApps.dart +++ b/lib/screens/more_apps.dart @@ -1,50 +1,52 @@ import 'package:flutter/material.dart'; -import '../constants/appConstants.dart'; +import '../constants/app_constants.dart'; import '../widgets/drawer.dart'; import 'package:url_launcher/url_launcher.dart'; class MoreApps extends StatelessWidget { + const MoreApps({Key? key}) : super(key: key); + @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( toolbarHeight: 56, title: Text( - ALL_MY_APPS, - style: Theme.of(context).textTheme.headline6, + allMyApps, + style: Theme.of(context).textTheme.titleLarge, ), backgroundColor: Theme.of(context).appBarTheme.backgroundColor, iconTheme: Theme.of(context).iconTheme, ), - drawer: CommonDrawer(currentScreen: ALL_MY_APPS), + drawer: const CommonDrawer(currentScreen: allMyApps), body: Column( children: [ - Padding(padding: EdgeInsets.all(8)), + const Padding(padding: EdgeInsets.all(8)), ListTile( title: Text( 'Hans Wehr Dictionary', - style: Theme.of(context).textTheme.bodyText1, + style: Theme.of(context).textTheme.bodyLarge, ), leading: Image.asset("assets/hans.png", fit: BoxFit.cover), subtitle: Text( 'A concise Arabic English dictionary', - style: Theme.of(context).textTheme.bodyText1, + style: Theme.of(context).textTheme.bodyLarge, ), onTap: () { launchUrl(hansWehrAndroidUri, mode: LaunchMode.externalApplication); }, ), - Padding(padding: EdgeInsets.all(8)), + const Padding(padding: EdgeInsets.all(8)), ListTile( title: Text( 'Lane\'s Lexicon', - style: Theme.of(context).textTheme.bodyText1, + style: Theme.of(context).textTheme.bodyLarge, ), leading: Image.asset("assets/lane.png", fit: BoxFit.cover), subtitle: Text( 'A comprehensive Arabic English dictionary', - style: Theme.of(context).textTheme.bodyText1, + style: Theme.of(context).textTheme.bodyLarge, ), onTap: () { launchUrl(lanesLexiconAndroidUri, diff --git a/lib/screens/preface.dart b/lib/screens/preface.dart index 50d4524..c15567b 100644 --- a/lib/screens/preface.dart +++ b/lib/screens/preface.dart @@ -1,6 +1,7 @@ import 'package:flutter/material.dart'; -import 'package:hans_wehr_dictionary/constants/appConstants.dart'; -import 'package:hans_wehr_dictionary/widgets/drawer.dart'; + +import '../constants/app_constants.dart'; +import '../widgets/drawer.dart'; class Preface extends StatelessWidget { const Preface({Key? key}) : super(key: key); @@ -11,13 +12,13 @@ class Preface extends StatelessWidget { appBar: AppBar( toolbarHeight: 56, title: Text( - PREFACE_SCREEN_TITLE, - style: Theme.of(context).textTheme.headline6, + prefaceScreenTitle, + style: Theme.of(context).textTheme.titleLarge, ), backgroundColor: Theme.of(context).appBarTheme.backgroundColor, iconTheme: Theme.of(context).iconTheme, ), - drawer: CommonDrawer(currentScreen: PREFACE_SCREEN_TITLE), + drawer: const CommonDrawer(currentScreen: prefaceScreenTitle), body: SingleChildScrollView( child: Padding( padding: const EdgeInsets.all(8.0), @@ -27,58 +28,57 @@ class Preface extends StatelessWidget { 'PREFACE', textScaleFactor: 2, textAlign: TextAlign.center, - style: Theme.of(context).textTheme.bodyText1!.copyWith( + style: Theme.of(context).textTheme.bodyLarge!.copyWith( color: Colors.grey, ), ), - Text(PREFACE_TEXT, style: Theme.of(context).textTheme.bodyText1), + Text(prefaceText, style: Theme.of(context).textTheme.bodyLarge), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text('Ithaca, New York\nNovember 1960', - style: Theme.of(context).textTheme.bodyText1), + style: Theme.of(context).textTheme.bodyLarge), Text('J MILTON COWAN', - style: Theme.of(context).textTheme.bodyText1) + style: Theme.of(context).textTheme.bodyLarge) ], ), - Padding(padding: EdgeInsets.all(16)), + const Padding(padding: EdgeInsets.all(16)), Text( 'PREFACE\n TO THE POCKET-BOOK EDITION', textScaleFactor: 1, textAlign: TextAlign.center, - style: Theme.of(context).textTheme.bodyText1!.copyWith( + style: Theme.of(context).textTheme.bodyLarge!.copyWith( color: Colors.grey, ), ), - Text(PREFACE_POCKET_TEXT, - style: Theme.of(context).textTheme.bodyText1), + Text(prefacePocketText, + style: Theme.of(context).textTheme.bodyLarge), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text('Münster\nIthaca, New York\nFebruary 1976', - style: Theme.of(context).textTheme.bodyText1), + style: Theme.of(context).textTheme.bodyLarge), Text('HANS WEHR\nJ MILTON COWAN', - style: Theme.of(context).textTheme.bodyText1) + style: Theme.of(context).textTheme.bodyLarge) ], ), - Padding(padding: EdgeInsets.all(16)), + const Padding(padding: EdgeInsets.all(16)), Text( 'INTRODUCTION', textScaleFactor: 2, textAlign: TextAlign.center, - style: Theme.of(context).textTheme.bodyText1!.copyWith( + style: Theme.of(context).textTheme.bodyLarge!.copyWith( color: Colors.grey, ), ), - Text(INTRODUCTION_TEXT, - style: Theme.of(context).textTheme.bodyText1), + Text(introText, style: Theme.of(context).textTheme.bodyLarge), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text('Münster\nNovember 1960', - style: Theme.of(context).textTheme.bodyText1), + style: Theme.of(context).textTheme.bodyLarge), Text('HANS WEHR', - style: Theme.of(context).textTheme.bodyText1) + style: Theme.of(context).textTheme.bodyLarge) ], ), ], diff --git a/lib/screens/quranicWords.dart b/lib/screens/quranic_words.dart similarity index 87% rename from lib/screens/quranicWords.dart rename to lib/screens/quranic_words.dart index 44dbc90..284cde7 100644 --- a/lib/screens/quranicWords.dart +++ b/lib/screens/quranic_words.dart @@ -1,11 +1,11 @@ import 'package:flutter/material.dart'; -import '../constants/appConstants.dart'; +import '../constants/app_constants.dart'; import 'browse.dart'; class QuranicWords extends StatefulWidget { const QuranicWords({Key? key}) : super(key: key); @override - _QuranicWordsState createState() => _QuranicWordsState(); + State createState() => _QuranicWordsState(); } class _QuranicWordsState extends State { @@ -21,22 +21,22 @@ class _QuranicWordsState extends State { 'QURANIC WORDS', textAlign: TextAlign.center, textScaleFactor: 2, - style: Theme.of(context).textTheme.bodyText1, + style: Theme.of(context).textTheme.bodyLarge, ), Padding( padding: const EdgeInsets.symmetric(horizontal: 16.0), child: ListTile( - leading: Text(''), + leading: const Text(''), title: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( "WORD", - style: Theme.of(context).textTheme.headline6, + style: Theme.of(context).textTheme.titleLarge, ), Text( "OCCURRENCES", - style: Theme.of(context).textTheme.headline6, + style: Theme.of(context).textTheme.titleLarge, ), ]), ), @@ -59,7 +59,7 @@ class _QuranicWordsState extends State { : Theme.of(context) .primaryColor .withAlpha(20), - borderRadius: BorderRadius.all( + borderRadius: const BorderRadius.all( Radius.circular(10), ), ), @@ -72,11 +72,11 @@ class _QuranicWordsState extends State { '${j + 1} ', style: Theme.of(context) .textTheme - .bodyText1! + .bodyLarge! .copyWith( color: Theme.of(context) .textTheme - .bodyText1! + .bodyLarge! .color! .withAlpha(100)), ), @@ -87,13 +87,13 @@ class _QuranicWordsState extends State { Text( quranicWords.data![j]['word'], style: - Theme.of(context).textTheme.bodyText1, + Theme.of(context).textTheme.bodyLarge, ), Text( quranicWords.data![j]['quran_occurrence'] .toString(), style: - Theme.of(context).textTheme.bodyText2, + Theme.of(context).textTheme.bodyMedium, ), ], ), @@ -104,7 +104,7 @@ class _QuranicWordsState extends State { ), ); } else { - return Expanded( + return const Expanded( child: Center( child: CircularProgressIndicator(), ), diff --git a/lib/screens/search.dart b/lib/screens/search.dart index 20df183..4d7f86d 100644 --- a/lib/screens/search.dart +++ b/lib/screens/search.dart @@ -5,19 +5,19 @@ import 'package:implicitly_animated_reorderable_list_2/implicitly_animated_reord import 'package:implicitly_animated_reorderable_list_2/transitions.dart'; import 'package:provider/provider.dart'; -import 'package:material_floating_search_bar/material_floating_search_bar.dart'; -import '../classes/definitionClass.dart'; +import 'package:material_floating_search_bar_2/material_floating_search_bar_2.dart'; +import '../classes/definition_provider.dart'; -import '../classes/searchModel.dart'; -import '../widgets/definitionSpace.dart'; +import '../classes/search_suggestions_provider.dart'; +import '../widgets/definition_space.dart'; import '../widgets/drawer.dart'; -import '../constants/appConstants.dart'; +import '../constants/app_constants.dart'; class Search extends StatefulWidget { const Search({Key? key}) : super(key: key); @override - _SearchState createState() => _SearchState(); + State createState() => _SearchState(); } class _SearchState extends State { @@ -33,39 +33,27 @@ class _SearchState extends State { @override Widget build(BuildContext context) { - return ChangeNotifierProvider( - create: (_) => SearchModel(), - child: ChangeNotifierProvider( - create: (_) => DefinitionClass( - id: [], - word: [], - definition: [], - isRoot: [], - highlight: [], - quranOccurrence: [], - favoriteFlag: [], - ), - child: WillPopScope( + return Consumer( + builder: (_, definitionListConsumer, __) { + return WillPopScope( onWillPop: () { - if (DefinitionClass.searchType == null) { + if (definitionListConsumer.searchType == null) { return Future.value(true); } - setState(() { - DefinitionClass.searchType = null; - }); + definitionListConsumer.searchType = null; return Future.value(false); }, child: Scaffold( resizeToAvoidBottomInset: false, - drawer: CommonDrawer(currentScreen: SEARCH_SCREEN_TITLE), - body: buildSearchBar(), + drawer: const CommonDrawer(currentScreen: searchScreenTitle), + body: buildSearchBar(definitionListConsumer), ), - ), - ), + ); + }, ); } - Widget buildSearchBar() { + Widget buildSearchBar(DefinitionProvider definitionListConsumer) { final actions = [ FloatingSearchBarAction.searchToClear( showIfClosed: true, @@ -75,7 +63,7 @@ class _SearchState extends State { final isPortrait = MediaQuery.of(context).orientation == Orientation.portrait; - return Consumer( + return Consumer( builder: (context, model, _) => FloatingSearchBar( controller: controller, clearQueryOnClose: false, @@ -95,39 +83,38 @@ class _SearchState extends State { buildDefinitionOnSubmission( context, query, + definitionListConsumer, ); }, onFocusChanged: (isFocused) {}, onQueryChanged: model.onQueryChanged, scrollPadding: EdgeInsets.zero, transition: CircularFloatingSearchBarTransition(), - builder: (context, _) => buildExpandableBody(model), + builder: (context, _) => + buildExpandableBody(model, definitionListConsumer), body: buildDefinitionSpace(), ), ); } - void buildDefinitionOnSubmission( - BuildContext context, String searchWord) async { - final definitionList = Provider.of(context, listen: false); - DefinitionClass.searchType = 'FullTextSearch'; - DefinitionClass value = - await databaseObject.definition(searchWord, DefinitionClass.searchType); - setState( - () { - definitionList.id = value.id; - definitionList.searchWord = searchWord; - definitionList.word = value.word; - definitionList.definition = value.definition; - definitionList.isRoot = value.isRoot; - definitionList.highlight = value.highlight; - definitionList.quranOccurrence = value.quranOccurrence; - definitionList.favoriteFlag = value.favoriteFlag; - }, + void buildDefinitionOnSubmission(BuildContext context, String searchWord, + DefinitionProvider definitionListConsumer) async { + DefinitionProvider value = + await databaseObject.definition(searchWord, 'FullTextSearch'); + definitionListConsumer.updateDefinition( + value.id, + value.word, + value.definition, + value.isRoot, + value.highlight, + searchWord, + value.quranOccurrence, + value.favoriteFlag, ); } - Widget buildExpandableBody(SearchModel model) { + Widget buildExpandableBody(SearchSuggestionsProvider model, + DefinitionProvider definitionListConsumer) { return Material( elevation: 4.0, borderRadius: BorderRadius.circular(8), @@ -137,55 +124,54 @@ class _SearchState extends State { physics: const NeverScrollableScrollPhysics(), items: model.suggestions.take(6).toList(), areItemsTheSame: (a, b) => a == b, - itemBuilder: (context, animation, word, i) { + itemBuilder: (context, animation, searchWord, i) { return SizeFadeTransition( animation: animation, - child: buildItem(context, word), + child: buildItem(context, searchWord, definitionListConsumer), ); }, - updateItemBuilder: (context, animation, word) { + updateItemBuilder: (context, animation, searchWord) { return FadeTransition( opacity: animation, - child: buildItem(context, word), + child: buildItem(context, searchWord, definitionListConsumer), ); }, ), ); } - Widget buildItem(BuildContext context, String word) { - final model = Provider.of(context, listen: false); - final definitionList = Provider.of(context, listen: false); - + Widget buildItem(BuildContext context, String searchWord, + DefinitionProvider definitionList) { + final model = + Provider.of(context, listen: false); return Column( mainAxisSize: MainAxisSize.min, children: [ InkWell( - onTap: () { - DefinitionClass.searchType = - ALL_ALPHABETS.contains(word.substring(0, 1)) + onTap: () async { + definitionList.searchType = + allAlphabets.contains(searchWord.substring(0, 1)) ? 'RootSearch' : 'FullTextSearch'; - definitionList.searchWord = word; - model.addHistory(word); + definitionList.searchWord = searchWord; + model.addHistory(searchWord); Future.delayed( const Duration(milliseconds: 50000), () => model.clear(), ); FloatingSearchBar.of(context)!.close(); - databaseObject.definition(word, DefinitionClass.searchType).then( - (value) => setState( - () { - definitionList.id = value.id; - definitionList.word = value.word; - definitionList.definition = value.definition; - definitionList.isRoot = value.isRoot; - definitionList.highlight = value.highlight; - definitionList.quranOccurrence = value.quranOccurrence; - definitionList.favoriteFlag = value.favoriteFlag; - }, - ), - ); + DefinitionProvider value = await databaseObject.definition( + searchWord, definitionList.searchType); + definitionList.updateDefinition( + value.id, + value.word, + value.definition, + value.isRoot, + value.highlight, + searchWord, + value.quranOccurrence, + value.favoriteFlag, + ); }, child: Padding( padding: const EdgeInsets.all(16), @@ -195,7 +181,7 @@ class _SearchState extends State { width: 36, child: AnimatedSwitcher( duration: const Duration(milliseconds: 50), - child: model.getHistory().contains(word) + child: model.getHistory().contains(searchWord) ? const Icon( Icons.history, key: Key('history'), @@ -213,8 +199,8 @@ class _SearchState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - word, - style: Theme.of(context).textTheme.bodyText1, + searchWord, + style: Theme.of(context).textTheme.bodyLarge, ), ], ), @@ -223,7 +209,8 @@ class _SearchState extends State { ), ), ), - if (model.suggestions.isNotEmpty && word != model.suggestions.last) + if (model.suggestions.isNotEmpty && + searchWord != model.suggestions.last) const Divider(height: 0), ], ); @@ -241,7 +228,7 @@ class _SearchState extends State { Expanded( child: IndexedStack( index: min(index, 2), - children: [ + children: const [ DefinitionSpace(), ], ), @@ -249,20 +236,4 @@ class _SearchState extends State { ], ); } - - void home(BuildContext context) { - final definitionList = Provider.of(context, listen: false); - - setState( - () { - DefinitionClass.searchType = null; - definitionList.searchWord = null; - definitionList.word = []; - definitionList.definition = []; - definitionList.isRoot = []; - definitionList.highlight = []; - definitionList.quranOccurrence = []; - }, - ); - } } diff --git a/lib/screens/settings.dart b/lib/screens/settings.dart index 724a081..db040df 100644 --- a/lib/screens/settings.dart +++ b/lib/screens/settings.dart @@ -1,20 +1,22 @@ import 'dart:async'; import 'package:provider/provider.dart'; -import '../classes/appTheme.dart'; -import '../classes/themeModel.dart'; +import '../classes/app_theme.dart'; +import '../classes/theme_model.dart'; import '../widgets/drawer.dart'; -import '../constants/appConstants.dart'; +import '../constants/app_constants.dart'; import 'package:flutter/material.dart'; -import '../serviceLocator.dart'; -import '../services/LocalStorageService.dart'; +import '../service_locator.dart'; +import '../services/local_storage_service.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:flutter_colorpicker/flutter_colorpicker.dart'; class Settings extends StatefulWidget { + const Settings({Key? key}) : super(key: key); + @override - _SettingsState createState() => _SettingsState(); + State createState() => _SettingsState(); } class _SettingsState extends State { @@ -26,56 +28,56 @@ class _SettingsState extends State { appBar: AppBar( toolbarHeight: 56, title: Text( - SETTINGS_SCREEN_TITLE, - style: Theme.of(context).textTheme.headline6, + settingsScreenTitle, + style: Theme.of(context).textTheme.titleLarge, ), backgroundColor: Theme.of(context).appBarTheme.backgroundColor, iconTheme: Theme.of(context).iconTheme, ), - drawer: CommonDrawer(currentScreen: SETTINGS_SCREEN_TITLE), - body: Container( - child: Column( - children: [ - FontSelector(), - FontSizeModifier(), - ThemeIcon(), - ExpansionTile( - iconColor: Theme.of(context).textTheme.bodyText2!.color, - textColor: Theme.of(context).textTheme.bodyText2!.color, - tilePadding: EdgeInsets.fromLTRB(16, 0, 28, 0), - title: Text( - 'Advanced Theming Options', - style: TextStyle( - fontFamily: Theme.of(context).textTheme.bodyText1!.fontFamily, - fontSize: Theme.of(context).textTheme.bodyText1!.fontSize, - ), + drawer: const CommonDrawer(currentScreen: settingsScreenTitle), + body: Column( + children: [ + const FontSelector(), + const FontSizeModifier(), + const ThemeIcon(), + ExpansionTile( + iconColor: Theme.of(context).textTheme.bodyMedium!.color, + textColor: Theme.of(context).textTheme.bodyMedium!.color, + tilePadding: const EdgeInsets.fromLTRB(16, 0, 28, 0), + title: Text( + 'Advanced Theming Options', + style: TextStyle( + fontFamily: Theme.of(context).textTheme.bodyLarge!.fontFamily, + fontSize: Theme.of(context).textTheme.bodyLarge!.fontSize, ), - childrenPadding: EdgeInsets.symmetric(horizontal: 16), - children: [ - ColorMod( - title: "Highlight Text Color", - ), - ColorMod( - title: "Highlight Tile Color", - ), - ColorMod( - title: "Background Color", - ), - ColorMod( - title: "Search Bar Color", - ), - ], ), - ], - ), + childrenPadding: const EdgeInsets.symmetric(horizontal: 16), + children: const [ + ColorMod( + title: "Highlight Text Color", + ), + ColorMod( + title: "Highlight Tile Color", + ), + ColorMod( + title: "Background Color", + ), + ColorMod( + title: "Search Bar Color", + ), + ], + ), + ], ), ); } } class FontSelector extends StatefulWidget { + const FontSelector({Key? key}) : super(key: key); + @override - _FontSelectorState createState() => _FontSelectorState(); + State createState() => _FontSelectorState(); } class _FontSelectorState extends State { @@ -84,12 +86,12 @@ class _FontSelectorState extends State { return ListTile( title: Text( 'Font', - style: Theme.of(context).textTheme.bodyText1, + style: Theme.of(context).textTheme.bodyLarge, ), - contentPadding: EdgeInsets.fromLTRB(16, 0, 28, 0), + contentPadding: const EdgeInsets.fromLTRB(16, 0, 28, 0), trailing: DropdownButton( value: locator().font, - icon: Icon(Icons.keyboard_arrow_down), + icon: const Icon(Icons.keyboard_arrow_down), iconSize: 24, elevation: 16, // style: TextStyle(color: Colors.deepPurple), @@ -116,8 +118,10 @@ class _FontSelectorState extends State { } class FontSizeModifier extends StatefulWidget { + const FontSizeModifier({Key? key}) : super(key: key); + @override - _FontSizeModifierState createState() => _FontSizeModifierState(); + State createState() => _FontSizeModifierState(); } class _FontSizeModifierState extends State { @@ -126,17 +130,17 @@ class _FontSizeModifierState extends State { return ListTile( title: Text( 'Font Size', - style: Theme.of(context).textTheme.bodyText1, + style: Theme.of(context).textTheme.bodyLarge, ), - trailing: Container( + trailing: SizedBox( width: MediaQuery.of(context).size.width * .3, child: Row( children: [ - Container( + SizedBox( width: MediaQuery.of(context).size.width * .1, child: Center( child: IconButton( - icon: Icon(Icons.remove), + icon: const Icon(Icons.remove), onPressed: () { setState( () { @@ -151,20 +155,20 @@ class _FontSizeModifierState extends State { ), ), ), - Container( + SizedBox( width: MediaQuery.of(context).size.width * .1, child: Center( child: Text( '${locator().fontSizeDelta + 10}', - style: Theme.of(context).textTheme.bodyText1, + style: Theme.of(context).textTheme.bodyLarge, ), ), ), - Container( + SizedBox( width: MediaQuery.of(context).size.width * .1, child: Center( child: IconButton( - icon: Icon(Icons.add), + icon: const Icon(Icons.add), onPressed: () { setState( () { @@ -194,7 +198,7 @@ class ColorMod extends StatefulWidget { this.title, }) : super(key: key); @override - _ColorModState createState() => _ColorModState(); + State createState() => _ColorModState(); } class _ColorModState extends State { @@ -236,9 +240,9 @@ class _ColorModState extends State { return ListTile( title: Text( widget.title!, - style: Theme.of(context).textTheme.bodyText1, + style: Theme.of(context).textTheme.bodyLarge, ), - trailing: Container( + trailing: SizedBox( width: 84, child: Row( mainAxisAlignment: MainAxisAlignment.end, @@ -246,7 +250,7 @@ class _ColorModState extends State { property == null ? Container() : IconButton( - icon: Icon(Icons.restore), + icon: const Icon(Icons.restore), onPressed: () { switch (widget.title) { case 'Highlight Text Color': @@ -303,16 +307,16 @@ class _ColorModState extends State { ), actions: [ TextButton( + onPressed: Navigator.of(context).pop, child: Text( 'CANCEL', - style: Theme.of(context).textTheme.bodyText1, + style: Theme.of(context).textTheme.bodyLarge, ), - onPressed: Navigator.of(context).pop, ), TextButton( child: Text( 'OK', - style: Theme.of(context).textTheme.bodyText1, + style: Theme.of(context).textTheme.bodyLarge, ), onPressed: () { Navigator.of(context).pop(); @@ -359,7 +363,7 @@ class _ColorModState extends State { color: property, border: Border.all(color: Colors.grey)), ) - : Icon( + : const Icon( Icons.error, size: 36, ), @@ -372,8 +376,10 @@ class _ColorModState extends State { } class ThemeIcon extends StatefulWidget { + const ThemeIcon({Key? key}) : super(key: key); + @override - _ThemeIconState createState() => _ThemeIconState(); + State createState() => _ThemeIconState(); } class _ThemeIconState extends State { @@ -386,7 +392,7 @@ class _ThemeIconState extends State { return ListTile( title: Text( "Theme", - style: Theme.of(context).textTheme.bodyText1, + style: Theme.of(context).textTheme.bodyLarge, ), trailing: IconButton( icon: Icon( diff --git a/lib/serviceLocator.dart b/lib/service_locator.dart similarity index 82% rename from lib/serviceLocator.dart rename to lib/service_locator.dart index 9bef8d7..6263faf 100644 --- a/lib/serviceLocator.dart +++ b/lib/service_locator.dart @@ -1,5 +1,5 @@ import 'package:get_it/get_it.dart'; -import './services/LocalStorageService.dart'; +import 'services/local_storage_service.dart'; GetIt locator = GetIt.instance; diff --git a/lib/services/LocalStorageService.dart b/lib/services/LocalStorageService.dart deleted file mode 100644 index 66630b0..0000000 --- a/lib/services/LocalStorageService.dart +++ /dev/null @@ -1,147 +0,0 @@ -import 'dart:async'; -import 'dart:convert'; - -import 'package:shared_preferences/shared_preferences.dart'; - -class LocalStorageService { - static const String UserPreferencesKey = 'userPreferences'; - static const String DarkThemeKey = 'darkTheme'; - static const String HistoryKey = 'history'; - static const String AppUsageKey = 'appUsage'; - static const String HighLightTextKey = 'highlightText'; - static const String HighLightTileKey = 'highlightTile'; - static const String BackgroundKey = 'background'; - static const String SearchBarKey = 'searchBar'; - static const String FontSizeKey = 'fontSize'; - static const String FontKey = 'font'; - - static LocalStorageService? _instance; - static SharedPreferences? _preferences; - static Future getInstance() async { - if (_instance == null) { - _instance = LocalStorageService(); - } - if (_preferences == null) { - _preferences = await SharedPreferences.getInstance(); - } - return _instance; - } - - UserPreferences get userPreferences { - var userPreferencesJson = _getFromDisk(UserPreferencesKey); - if (userPreferencesJson == null) { - return UserPreferences.fromJson(json.decode( - '{"darkTheme":false,"history":"","appUsage":1,"highlightText":null,"highlightTile":null,"background":null,"searchBar":null,"fontSize":0.0,"font":"Amiri"}')); - } - return UserPreferences.fromJson(json.decode(userPreferencesJson)); - } - - set userPreferences(UserPreferences userPreferencesToSave) { - saveStringToDisk( - UserPreferencesKey, json.encode(userPreferencesToSave.toJson())); - } - - dynamic _getFromDisk(String key) { - var value = _preferences!.get(key); - print('(TRACE) LocalStorageService:_getFromDisk. key: $key value: $value'); - return value; - } - - void saveStringToDisk(String key, String content) { - print( - '(TRACE) LocalStorageService:_saveStringToDisk. key: $key value: $content'); - _preferences!.setString(UserPreferencesKey, content); - } - - bool get darkTheme => _getFromDisk(DarkThemeKey) ?? false; - set darkTheme(bool value) => _saveToDisk(DarkThemeKey, value); - - String get history => _getFromDisk(HistoryKey) ?? ""; - set history(String value) => _saveToDisk(HistoryKey, value); - - int get appUsage => _getFromDisk(AppUsageKey) ?? 1; - set appUsage(int value) => _saveToDisk(AppUsageKey, value); - - String? get highlightTextColor => _getFromDisk(HighLightTextKey) ?? null; - set highlightTextColor(String? value) => _saveToDisk(HighLightTextKey, value); - - String? get highlightTileColor => _getFromDisk(HighLightTileKey) ?? null; - set highlightTileColor(String? value) => _saveToDisk(HighLightTileKey, value); - - String? get backgroundColor => _getFromDisk(BackgroundKey) ?? null; - set backgroundColor(String? value) => _saveToDisk(BackgroundKey, value); - - String? get searchBarColor => _getFromDisk(SearchBarKey) ?? null; - set searchBarColor(String? value) => _saveToDisk(SearchBarKey, value); - - double get fontSizeDelta => _getFromDisk(FontSizeKey) ?? 0.0; - set fontSizeDelta(double value) => _saveToDisk(FontSizeKey, value); - - String get font => _getFromDisk(FontKey) ?? 'Amiri'; - set font(String? value) => _saveToDisk(FontKey, value); - - void _saveToDisk(String key, T content) { - print( - '(TRACE) LocalStorageService:_saveStringToDisk. key: $key value: $content'); - if (content is String) { - _preferences!.setString(key, content); - } - if (content is bool) { - _preferences!.setBool(key, content); - } - if (content is int) { - _preferences!.setInt(key, content); - } - if (content is double) { - _preferences!.setDouble(key, content); - } - if (content is List) { - _preferences!.setStringList(key, content); - } - } -} - -class UserPreferences { - final bool? darkTheme; - final String? highlightText; - final String? highlightTile; - final String? history; - final String? background; - final String? searchBar; - final int? fontSize; - final String? font; - - UserPreferences({ - this.darkTheme, - this.highlightText, - this.highlightTile, - this.history, - this.background, - this.searchBar, - this.fontSize, - this.font, - }); - - UserPreferences.fromJson(Map json) - : darkTheme = json['darkTheme'], - highlightText = json['highlightText'], - highlightTile = json['highlightTile'], - history = json['history'], - background = json['background'], - searchBar = json['searchBar'], - fontSize = json['fontSize'], - font = json['font']; - - Map toJson() { - final Map data = new Map(); - data['darkTheme'] = this.darkTheme; - data['highlightText'] = this.highlightText; - data['highlightTile'] = this.highlightTile; - data['history'] = this.history; - data['background'] = this.background; - data['searchBar'] = this.searchBar; - data['fontSize'] = this.fontSize; - data['font'] = this.font; - return data; - } -} diff --git a/lib/services/appReview.dart b/lib/services/app_review.dart similarity index 78% rename from lib/services/appReview.dart rename to lib/services/app_review.dart index 7685691..48bc759 100644 --- a/lib/services/appReview.dart +++ b/lib/services/app_review.dart @@ -1,5 +1,5 @@ -import '../serviceLocator.dart'; -import '../services/LocalStorageService.dart'; +import '../service_locator.dart'; +import 'local_storage_service.dart'; import 'package:in_app_review/in_app_review.dart'; void appReview() async { @@ -8,6 +8,7 @@ void appReview() async { if (await inAppReview.isAvailable()) { inAppReview.requestReview(); } - } else + } else { locator().appUsage++; + } } diff --git a/lib/services/checkDatabaseUpdates.dart b/lib/services/check_database_updates.dart similarity index 100% rename from lib/services/checkDatabaseUpdates.dart rename to lib/services/check_database_updates.dart diff --git a/lib/services/getData.dart b/lib/services/get_data.dart similarity index 86% rename from lib/services/getData.dart rename to lib/services/get_data.dart index 50020b2..87cef1b 100644 --- a/lib/services/getData.dart +++ b/lib/services/get_data.dart @@ -1,29 +1,34 @@ -import '../classes/definitionClass.dart'; +import '../classes/definition_provider.dart'; import 'package:sqflite_common_ffi/sqflite_ffi.dart'; import 'package:path/path.dart'; import 'dart:io'; import 'package:flutter/services.dart'; -import '../constants/appConstants.dart'; +import '../constants/app_constants.dart'; class DatabaseAccess { + static const String _newDBName = "hanswehrV12.db"; + static const String _oldDBName = "hanswehrV11.db"; + Future openDatabaseConnection() async { - sqfliteFfiInit(); - databaseFactory = databaseFactoryFfi; - // Sqflite.devSetDebugModeOn(true); - // var path = join(await getDatabasesPath(), "hanswehrV12.db"); - var path = normalize(absolute(join( - '.dart_tool', 'sqflite_common_ffi', 'databases', 'hanswehrV12.db'))); + var path = ""; + if (Platform.isWindows || Platform.isLinux) { + sqfliteFfiInit(); + databaseFactory = databaseFactoryFfi; + path = normalize(absolute( + join('.dart_tool', 'sqflite_common_ffi', 'databases', _newDBName))); + } + path = join(await getDatabasesPath(), _newDBName); var exists = await databaseExists(path); if (!exists) { try { await Directory(dirname(path)).create(recursive: true); } catch (_) {} - ByteData data = await rootBundle.load(join("assets", "hanswehrV12.db")); + ByteData data = await rootBundle.load(join("assets", _newDBName)); List bytes = data.buffer.asUint8List(data.offsetInBytes, data.lengthInBytes); await File(path).writeAsBytes(bytes, flush: true); - var oldPath = join(await getDatabasesPath(), "hanswehrV11.db"); + var oldPath = join(await getDatabasesPath(), _oldDBName); exists = await databaseExists(oldPath); if (exists) { databaseFactory.deleteDatabase(oldPath); @@ -39,21 +44,19 @@ class DatabaseAccess { List mapOfWords = await db.rawQuery('SELECT WORD FROM DICTIONARY WHERE IS_ROOT = 1'); - mapOfWords.forEach( - (wordMap) { - wordMap.forEach( - (key, word) { - allDictionaryWords.add( - word, - ); - }, - ); - }, - ); + for (var wordMap in mapOfWords) { + wordMap.forEach( + (key, word) { + allDictionaryWords.add( + word, + ); + }, + ); + } return allDictionaryWords; } - Future definition(String? word, String? type) async { + Future definition(String? word, String? type) async { Database db = await databaseConnection; late String query; switch (type) { @@ -74,7 +77,7 @@ class DatabaseAccess { } List> definition = await db.rawQuery(query); - DefinitionClass allDefinitions = DefinitionClass( + DefinitionProvider allDefinitions = DefinitionProvider( id: [], word: [], definition: [], @@ -84,7 +87,7 @@ class DatabaseAccess { favoriteFlag: [], ); - definition.forEach((element) { + for (var element in definition) { element.forEach((key, value) { if (key == 'id') { allDefinitions.id.add(value); @@ -102,7 +105,7 @@ class DatabaseAccess { allDefinitions.favoriteFlag.add(value); } }); - }); + } return allDefinitions; } @@ -114,11 +117,11 @@ class DatabaseAccess { List> definition = await db.rawQuery(query); List allWords = []; - definition.forEach((element) { + for (var element in definition) { element.forEach((key, value) { allWords.add(value); }); - }); + } return allWords; } @@ -142,11 +145,11 @@ class DatabaseAccess { List> definition = await db.rawQuery(query); List allWords = []; - definition.forEach((element) { + for (var element in definition) { element.forEach((key, value) { allWords.add(value); }); - }); + } return allWords; } diff --git a/lib/services/local_storage_service.dart b/lib/services/local_storage_service.dart new file mode 100644 index 0000000..6578f18 --- /dev/null +++ b/lib/services/local_storage_service.dart @@ -0,0 +1,138 @@ +import 'dart:async'; +import 'dart:convert'; + +import 'package:shared_preferences/shared_preferences.dart'; + +class LocalStorageService { + static const String userPreferencesKey = 'userPreferences'; + static const String darkThemeKey = 'darkTheme'; + static const String historyKey = 'history'; + static const String appUsageKey = 'appUsage'; + static const String highLightTextKey = 'highlightText'; + static const String highLightTileKey = 'highlightTile'; + static const String backgroundKey = 'background'; + static const String searchBarKey = 'searchBar'; + static const String fontSizeKey = 'fontSize'; + static const String fontKey = 'font'; + + static LocalStorageService? _instance; + static SharedPreferences? _preferences; + static Future getInstance() async { + _instance ??= LocalStorageService(); + _preferences ??= await SharedPreferences.getInstance(); + return _instance; + } + + UserPreferences get userPreferences { + var userPreferencesJson = _getFromDisk(userPreferencesKey); + if (userPreferencesJson == null) { + return UserPreferences.fromJson(json.decode( + '{"darkTheme":false,"history":"","appUsage":1,"highlightText":null,"highlightTile":null,"background":null,"searchBar":null,"fontSize":0.0,"font":"Amiri"}')); + } + return UserPreferences.fromJson(json.decode(userPreferencesJson)); + } + + set userPreferences(UserPreferences userPreferencesToSave) { + saveStringToDisk( + userPreferencesKey, json.encode(userPreferencesToSave.toJson())); + } + + dynamic _getFromDisk(String key) { + var value = _preferences!.get(key); + return value; + } + + void saveStringToDisk(String key, String content) { + _preferences!.setString(userPreferencesKey, content); + } + + bool get darkTheme => _getFromDisk(darkThemeKey) ?? false; + set darkTheme(bool value) => _saveToDisk(darkThemeKey, value); + + String get history => _getFromDisk(historyKey) ?? ""; + set history(String value) => _saveToDisk(historyKey, value); + + int get appUsage => _getFromDisk(appUsageKey) ?? 1; + set appUsage(int value) => _saveToDisk(appUsageKey, value); + + String? get highlightTextColor => _getFromDisk(highLightTextKey); + set highlightTextColor(String? value) => _saveToDisk(highLightTextKey, value); + + String? get highlightTileColor => _getFromDisk(highLightTileKey); + set highlightTileColor(String? value) => _saveToDisk(highLightTileKey, value); + + String? get backgroundColor => _getFromDisk(backgroundKey); + set backgroundColor(String? value) => _saveToDisk(backgroundKey, value); + + String? get searchBarColor => _getFromDisk(searchBarKey); + set searchBarColor(String? value) => _saveToDisk(searchBarKey, value); + + double get fontSizeDelta => _getFromDisk(fontSizeKey) ?? 0.0; + set fontSizeDelta(double value) => _saveToDisk(fontSizeKey, value); + + String get font => _getFromDisk(fontKey) ?? 'Amiri'; + set font(String? value) => _saveToDisk(fontKey, value); + + void _saveToDisk(String key, T content) { + if (content is String) { + _preferences!.setString(key, content); + } + if (content is bool) { + _preferences!.setBool(key, content); + } + if (content is int) { + _preferences!.setInt(key, content); + } + if (content is double) { + _preferences!.setDouble(key, content); + } + if (content is List) { + _preferences!.setStringList(key, content); + } + } +} + +class UserPreferences { + final bool? darkTheme; + final String? highlightText; + final String? highlightTile; + final String? history; + final String? background; + final String? searchBar; + final int? fontSize; + final String? font; + + UserPreferences({ + this.darkTheme, + this.highlightText, + this.highlightTile, + this.history, + this.background, + this.searchBar, + this.fontSize, + this.font, + }); + + UserPreferences.fromJson(Map json) + : darkTheme = json['darkTheme'], + highlightText = json['highlightText'], + highlightTile = json['highlightTile'], + history = json['history'], + background = json['background'], + searchBar = json['searchBar'], + fontSize = json['fontSize'], + font = json['font']; + + Map toJson() { + final Map data = {}; + data['darkTheme'] = darkTheme; + data['highlightText'] = highlightText; + data['highlightTile'] = highlightTile; + data['history'] = history; + data['background'] = background; + data['searchBar'] = searchBar; + data['fontSize'] = fontSize; + data['font'] = font; + return data; + } +} diff --git a/lib/widgets/definitionSpace.dart b/lib/widgets/definition_space.dart similarity index 73% rename from lib/widgets/definitionSpace.dart rename to lib/widgets/definition_space.dart index 858558a..e60457d 100644 --- a/lib/widgets/definitionSpace.dart +++ b/lib/widgets/definition_space.dart @@ -1,77 +1,80 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_widget_from_html/flutter_widget_from_html.dart'; -import 'package:hans_wehr_dictionary/screens/quranicWords.dart'; import '../screens/donate.dart'; import '../screens/favorites.dart'; -import 'package:material_floating_search_bar/material_floating_search_bar.dart'; +import 'package:material_floating_search_bar_2/material_floating_search_bar_2.dart'; import 'package:provider/provider.dart'; import 'package:url_launcher/url_launcher.dart'; import 'package:html/parser.dart'; -import '../classes/appTheme.dart'; -import '../classes/definitionClass.dart'; -import '../constants/appConstants.dart'; -import '../serviceLocator.dart'; -import '../services/LocalStorageService.dart'; -import 'quranOccurrenceAlert.dart'; +import '../classes/app_theme.dart'; +import '../classes/definition_provider.dart'; +import '../constants/app_constants.dart'; +import '../screens/quranic_words.dart'; +import '../service_locator.dart'; +import '../services/local_storage_service.dart'; +import 'quran_occurrence_alert.dart'; class DefinitionSpace extends StatefulWidget { - DefinitionSpace({ + const DefinitionSpace({ Key? key, }) : super(key: key); @override - _DefinitionSpaceState createState() => _DefinitionSpaceState(); + State createState() => _DefinitionSpaceState(); } class _DefinitionSpaceState extends State { @override Widget build(BuildContext context) { + //The entire screen, not just the AppBar, body contains the rest. return FloatingSearchAppBar( color: Theme.of(context).scaffoldBackgroundColor, colorOnScroll: Theme.of(context).scaffoldBackgroundColor, transitionDuration: const Duration(milliseconds: 800), - body: Consumer( + //The area below the app bar + body: Consumer( builder: (_, definitionList, __) { - if (DefinitionClass.searchType == null) { - return HomeScreen(); - } else if (DefinitionClass.searchType == '/favorites') { - return Favorites(); - } else if (DefinitionClass.searchType == '/donate') { - return Donate(); - } else if (DefinitionClass.searchType == '/quranicWords') { - return QuranicWords(); + if (definitionList.searchType == null) { + return const HomeScreen(); + } else if (definitionList.searchType == '/favorites') { + return const Favorites(); + } else if (definitionList.searchType == '/donate') { + return const Donate(); + } else if (definitionList.searchType == '/quranicWords') { + return const QuranicWords(); } return ListView.separated( - padding: EdgeInsets.fromLTRB(0, 0, 0, 100), + padding: const EdgeInsets.fromLTRB(0, 0, 0, 100), itemCount: definitionList.definition.length + 1, separatorBuilder: (context, index) { return definitionList.isRoot[index] == 1 - ? Divider() + ? const Divider() : Container(); }, itemBuilder: (context, index) { if (index == 0) { - if (DefinitionClass.searchType == 'RootSearch') { + if (definitionList.searchType == 'RootSearch') { return ListTile( title: Text( definitionList.searchWord!, textAlign: TextAlign.center, - style: Theme.of(context).textTheme.bodyText1, + style: Theme.of(context).textTheme.bodyLarge, ), - subtitle: definitionList.definition.length == 0 - ? Text( + subtitle: definitionList.definition.isEmpty + ? const Text( 'No results found.\nTap here for full text search.', textAlign: TextAlign.center, ) - : Text( + : const Text( 'Tap here for full text search.\nTo directly do a full text search press the Enter key instead of selecting from the dropdown.', textAlign: TextAlign.center, ), onTap: () async { - DefinitionClass.searchType = 'FullTextSearch'; - DefinitionClass value = await databaseObject.definition( - definitionList.searchWord, - DefinitionClass.searchType); + definitionList.searchType = 'FullTextSearch'; + DefinitionProvider value = + await databaseObject.definition( + definitionList.searchWord, + definitionList.searchType); setState(() { definitionList.id = value.id; definitionList.word = value.word; @@ -83,21 +86,21 @@ class _DefinitionSpaceState extends State { }); }, ); - } else if (DefinitionClass.searchType == 'FullTextSearch') { + } else if (definitionList.searchType == 'FullTextSearch') { if (definitionList.definition.length > 50 || - definitionList.definition.length == 0) { + definitionList.definition.isEmpty) { return ListTile( title: Text( definitionList.searchWord!, - style: Theme.of(context).textTheme.bodyText1, + style: Theme.of(context).textTheme.bodyLarge, textAlign: TextAlign.center, ), - subtitle: definitionList.definition.length == 0 - ? Text( + subtitle: definitionList.definition.isEmpty + ? const Text( 'No results found', textAlign: TextAlign.center, ) - : Text( + : const Text( 'Too many matches, results might be truncated.', textAlign: TextAlign.center, ), @@ -107,19 +110,17 @@ class _DefinitionSpaceState extends State { return ListTile( title: Text( definitionList.searchWord!, - style: Theme.of(context).textTheme.bodyText1, + style: Theme.of(context).textTheme.bodyLarge, textAlign: TextAlign.center, ), ); } } - return Container( - child: ListTileTheme( - selectedColor: hexToColor( - locator().highlightTextColor), - child: DefinitionTile( - definitionList: definitionList, index: index), - ), + return ListTileTheme( + selectedColor: hexToColor( + locator().highlightTextColor), + child: DefinitionTile( + definitionList: definitionList, index: index), ); }, ); @@ -139,32 +140,32 @@ class HomeScreen extends StatelessWidget { return OrientationBuilder( builder: (context, orientation) { return GridView.count( - padding: EdgeInsets.all(8), + padding: const EdgeInsets.all(8), crossAxisCount: orientation == Orientation.portrait ? 2 : 4, // crossAxisCount: 2, children: [ - HomePageCards( - imagePath: FAV_IMAGE, + const HomePageCards( + imagePath: favImage, route: "/favorites", ), - HomePageCards( - imagePath: QURAN_IMAGE, + const HomePageCards( + imagePath: quranImage, route: "/quranicWords", ), - HomePageCards( - imagePath: DONATE_IMAGE, + const HomePageCards( + imagePath: donateImage, route: "/donate", ), HomePageCards( - imagePath: QURANLE_IMAGE, + imagePath: quranleImage, uri: quranleUri, ), HomePageCards( - imagePath: FOR_HIRE_IMAGE, + imagePath: forHireImage, uri: portfolioUri, ), HomePageCards( - imagePath: HAITHHUB_IMAGE, + imagePath: hadithhubImage, uri: hadithHubUri, ), ], @@ -189,7 +190,7 @@ class HomePageCards extends StatelessWidget { return GestureDetector( onTap: () { route != null - ? Provider.of(context, listen: false) + ? Provider.of(context, listen: false) .updateSearchType(route!) : launchUrl(uri!, mode: LaunchMode.externalApplication); }, @@ -203,15 +204,15 @@ class HomePageCards extends StatelessWidget { ), child: Card( elevation: 0, - child: Column( - mainAxisAlignment: MainAxisAlignment.end, - children: [], - ), shadowColor: Theme.of(context).primaryColor, color: Colors.transparent, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(15.0), ), + child: const Column( + mainAxisAlignment: MainAxisAlignment.end, + children: [], + ), ), ), ), @@ -220,7 +221,7 @@ class HomePageCards extends StatelessWidget { } class DefinitionTile extends StatelessWidget { - final DefinitionClass? definitionList; + final DefinitionProvider? definitionList; final int? index; const DefinitionTile({ Key? key, @@ -230,7 +231,7 @@ class DefinitionTile extends StatelessWidget { @override Widget build(BuildContext context) { - Offset _tapPosition = Offset(10.0, 10.0); + Offset tapPosition = const Offset(10.0, 10.0); return GestureDetector( child: ListTile( isThreeLine: true, @@ -244,8 +245,8 @@ class DefinitionTile extends StatelessWidget { title: HtmlWidget( definitionList!.definition[index! - 1]!, textStyle: TextStyle( - fontFamily: Theme.of(context).textTheme.bodyText1!.fontFamily, - fontSize: Theme.of(context).textTheme.bodyText1!.fontSize, + fontFamily: Theme.of(context).textTheme.bodyLarge!.fontFamily, + fontSize: Theme.of(context).textTheme.bodyLarge!.fontSize, ), ), subtitle: Row( @@ -257,29 +258,31 @@ class DefinitionTile extends StatelessWidget { definitionList!.quranOccurrence![index! - 1] != null ? ElevatedButton( onPressed: () { - if (definitionList!.quranOccurrence![index! - 1] != null) + if (definitionList!.quranOccurrence![index! - 1] != + null) { quranOccurrenceDialog( context, definitionList!.quranOccurrence![index! - 1]!, definitionList!.word[index! - 1]!); + } }, - child: Text( - "Q - ${definitionList!.quranOccurrence![index! - 1]}", - style: Theme.of(context).textTheme.subtitle2, - ), style: ElevatedButton.styleFrom( backgroundColor: Theme.of(context).primaryColor, ), + child: Text( + "Q - ${definitionList!.quranOccurrence![index! - 1]}", + style: Theme.of(context).textTheme.titleSmall, + ), ) : Container(), ], ), onTap: () {}, onLongPress: () { - contextMenu(context, _tapPosition); + contextMenu(context, tapPosition); }, ), - onTapDown: (details) => _tapPosition = details.globalPosition, + onTapDown: (details) => tapPosition = details.globalPosition, ); // } } @@ -289,13 +292,13 @@ class DefinitionTile extends StatelessWidget { position: RelativeRect.fromRect( tapPosition & const Size(40, 40), // smaller rect, the touch area Offset.zero & - Overlay.of(context)! + Overlay.of(context) .context .findRenderObject()! .semanticBounds .size), items: [ - PopupMenuItem( + const PopupMenuItem( value: 0, child: Row( children: [ @@ -307,7 +310,7 @@ class DefinitionTile extends StatelessWidget { ], ), ), - PopupMenuItem( + const PopupMenuItem( value: 1, child: Row( children: [ @@ -329,8 +332,9 @@ class DefinitionTile extends StatelessWidget { .documentElement! .text, )); + if (!context.mounted) return; ScaffoldMessenger.of(context).showSnackBar( - SnackBar( + const SnackBar( content: Text("Copied"), ), ); @@ -339,20 +343,20 @@ class DefinitionTile extends StatelessWidget { String text = ''; for (var i = index! - 1; i >= 0; i--) { text = - definitionList!.definition[i]! + '\n-*-*-*-*-*-*-*-*-*-\n' + text; + '${definitionList!.definition[i]!}\n-*-*-*-*-*-*-*-*-*-\n$text'; if (definitionList!.isRoot[i] == 1) break; } - print(text); for (var i = index!; i < definitionList!.definition.length; i++) { if (definitionList!.isRoot[i] == 1) break; text = - text + definitionList!.definition[i]! + '\n-*-*-*-*-*-*-*-*-*-\n'; + '$text${definitionList!.definition[i]!}\n-*-*-*-*-*-*-*-*-*-\n'; } Clipboard.setData(ClipboardData( text: parse(parse(text).body!.text).documentElement!.text, )); + if (!context.mounted) return; ScaffoldMessenger.of(context).showSnackBar( - SnackBar( + const SnackBar( content: Text("Copied"), ), ); @@ -365,10 +369,10 @@ class DefinitionTile extends StatelessWidget { class FavIconWidget extends StatefulWidget { const FavIconWidget({Key? key, this.definitionList, this.index}) : super(key: key); - final DefinitionClass? definitionList; + final DefinitionProvider? definitionList; final int? index; @override - _FavIconWidgetState createState() => _FavIconWidgetState(); + State createState() => _FavIconWidgetState(); } class _FavIconWidgetState extends State { @@ -400,7 +404,7 @@ class _FavIconWidgetState extends State { } void toggleFavoritesMethod( - DefinitionClass definitionList, int index, BuildContext context) { + DefinitionProvider definitionList, int index, BuildContext context) { int toggleFavoriteFlag = definitionList.favoriteFlag[index - 1] == 1 ? 0 : 1; definitionList.favoriteFlag[index - 1] = toggleFavoriteFlag; databaseObject.toggleFavorites( diff --git a/lib/widgets/drawer.dart b/lib/widgets/drawer.dart index a2a957c..464853d 100644 --- a/lib/widgets/drawer.dart +++ b/lib/widgets/drawer.dart @@ -1,19 +1,19 @@ import 'package:flutter/material.dart'; -import '../constants/appConstants.dart'; +import '../constants/app_constants.dart'; import 'package:url_launcher/url_launcher.dart'; import 'package:share_plus/share_plus.dart'; class CommonDrawer extends StatelessWidget { final String currentScreen; - const CommonDrawer({required this.currentScreen}); + const CommonDrawer({Key? key, required this.currentScreen}) : super(key: key); @override Drawer build(BuildContext context) { return Drawer( child: SafeArea( child: Padding( - padding: EdgeInsets.fromLTRB(0, 0, 0, 65), + padding: const EdgeInsets.fromLTRB(0, 0, 0, 65), child: Column( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ @@ -21,49 +21,49 @@ class CommonDrawer extends StatelessWidget { children: [ DrawerItem( currentScreen: currentScreen, - title: SEARCH_SCREEN_TITLE, + title: searchScreenTitle, route: '/search', icon: Icons.search, ), DrawerItem( currentScreen: currentScreen, - title: BROWSE_SCREEN_TITLE, + title: browseScreenTitle, route: '/browse', icon: Icons.list, ), DrawerItem( currentScreen: currentScreen, - title: PREFACE_SCREEN_TITLE, + title: prefaceScreenTitle, route: '/preface', icon: Icons.article), DrawerItem( currentScreen: currentScreen, - title: ABBREVIATIONS_SCREEN_TITLE, + title: abbreviationsScreenTitle, route: '/abbreviations', icon: Icons.info, ), - VerbForms(), + const VerbForms(), ], ), Column( children: [ - Divider(), + const Divider(), DrawerItem( currentScreen: currentScreen, - title: MORE_APPS, + title: moreApps, route: '/moreapps', icon: Icons.more_horiz), DrawerItem( currentScreen: currentScreen, - title: SETTINGS_SCREEN_TITLE, + title: settingsScreenTitle, route: '/settings', icon: Icons.settings), DrawerItem( currentScreen: currentScreen, - title: ABOUT_APP_SCREEN_TITLE, + title: aboutAppScreenTitle, route: '/aboutus', icon: Icons.people), - RateUs(), + const RateUs(), ], ), ], @@ -75,6 +75,8 @@ class CommonDrawer extends StatelessWidget { } class RateUs extends StatelessWidget { + const RateUs({Key? key}) : super(key: key); + @override Widget build(BuildContext context) { return Row( @@ -88,12 +90,12 @@ class RateUs extends StatelessWidget { Icons.star, color: Theme.of(context).iconTheme.color, ), - SizedBox( + const SizedBox( width: 10, ), Text( "Rate Us", - style: Theme.of(context).textTheme.bodyText1, + style: Theme.of(context).textTheme.bodyLarge, ), ], ), @@ -109,8 +111,8 @@ class RateUs extends StatelessWidget { color: Theme.of(context).iconTheme.color, ), onPressed: () { - Share.share('Check out this Hans Wehr Dictionary App : ' + - hansWehrAndroidUri.toString()); + Share.share( + 'Check out this Hans Wehr Dictionary App : $hansWehrAndroidUri'); }, ), ], @@ -123,26 +125,28 @@ class DrawerItem extends StatelessWidget { final String title; final String route; final IconData icon; - DrawerItem({ + const DrawerItem({ + Key? key, required this.currentScreen, required this.title, required this.route, required this.icon, - }); + }) : super(key: key); @override Widget build(BuildContext context) { return TextButton( onPressed: () { if (currentScreen != title) { - if (currentScreen == SEARCH_SCREEN_TITLE) { + if (currentScreen == searchScreenTitle) { Navigator.pop(context); Navigator.pushNamed(context, route); } else { Navigator.pushNamedAndRemoveUntil(context, route, (route) => false); } - } else + } else { Navigator.pop(context); + } }, child: Row( children: [ @@ -150,12 +154,12 @@ class DrawerItem extends StatelessWidget { icon, color: Theme.of(context).iconTheme.color, ), - SizedBox( + const SizedBox( width: 10, ), Text( title, - style: Theme.of(context).textTheme.bodyText1, + style: Theme.of(context).textTheme.bodyLarge, ) ], ), @@ -164,6 +168,8 @@ class DrawerItem extends StatelessWidget { } class VerbForms extends StatelessWidget { + const VerbForms({Key? key}) : super(key: key); + @override Widget build(BuildContext context) { return TextButton( @@ -176,43 +182,39 @@ class VerbForms extends StatelessWidget { title: Center( child: Text( 'VERB FORMS', - style: Theme.of(context).textTheme.bodyText1, + style: Theme.of(context).textTheme.bodyLarge, )), titlePadding: const EdgeInsets.all(8.0), contentPadding: const EdgeInsets.all(0.0), - content: Container( + content: SizedBox( height: MediaQuery.of(context).size.height * .7, width: MediaQuery.of(context).size.width * .9, child: ListView.builder( - itemCount: VERB_FORMS.length, + itemCount: verbForms.length, itemBuilder: (_, i) { return ExpansionTile( - iconColor: Theme.of(context).textTheme.bodyText2!.color, - textColor: Theme.of(context).textTheme.bodyText2!.color, - childrenPadding: EdgeInsets.fromLTRB(30, 0, 16, 0), + iconColor: Theme.of(context).textTheme.bodyMedium!.color, + textColor: Theme.of(context).textTheme.bodyMedium!.color, + childrenPadding: const EdgeInsets.fromLTRB(30, 0, 16, 0), title: Text( - VERB_FORMS[i], + verbForms[i], style: TextStyle( fontFamily: - Theme.of(context).textTheme.bodyText1!.fontFamily, + Theme.of(context).textTheme.bodyLarge!.fontFamily, fontSize: - Theme.of(context).textTheme.bodyText1!.fontSize, + Theme.of(context).textTheme.bodyLarge!.fontSize, ), ), expandedCrossAxisAlignment: CrossAxisAlignment.start, expandedAlignment: Alignment.topLeft, children: [ - Container( - child: Text( - 'Pattern Meaning : ' + VERB_FORM_DESCRIPTIONS[i], - style: Theme.of(context).textTheme.bodyText1, - ), + Text( + 'Pattern Meaning : ${verbFormDesc[i]}', + style: Theme.of(context).textTheme.bodyLarge, ), - Container( - child: Text( - 'Eg. : ' + VERB_FORM_EXAMPLES[i], - style: Theme.of(context).textTheme.bodyText1, - ), + Text( + 'Eg. : ${verbFormExample[i]}', + style: Theme.of(context).textTheme.bodyLarge, ) ], ); @@ -221,11 +223,11 @@ class VerbForms extends StatelessWidget { ), actions: [ TextButton( + onPressed: Navigator.of(context).pop, child: Text( 'DISMISS', - style: Theme.of(context).textTheme.bodyText2, + style: Theme.of(context).textTheme.bodyMedium, ), - onPressed: Navigator.of(context).pop, ), ], ); @@ -238,12 +240,12 @@ class VerbForms extends StatelessWidget { Icons.info, color: Theme.of(context).iconTheme.color, ), - SizedBox( + const SizedBox( width: 10, ), Text( 'Verb Forms', - style: Theme.of(context).textTheme.bodyText1, + style: Theme.of(context).textTheme.bodyLarge, ) ], ), diff --git a/lib/widgets/quranOccurrenceAlert.dart b/lib/widgets/quran_occurrence_alert.dart similarity index 88% rename from lib/widgets/quranOccurrenceAlert.dart rename to lib/widgets/quran_occurrence_alert.dart index e513de8..5ccfa3d 100644 --- a/lib/widgets/quranOccurrenceAlert.dart +++ b/lib/widgets/quran_occurrence_alert.dart @@ -1,7 +1,7 @@ import 'package:flutter/material.dart'; import 'package:url_launcher/url_launcher.dart'; -import '../constants/appConstants.dart'; +import '../constants/app_constants.dart'; quranOccurrenceDialog( BuildContext context, int quranOccurrences, String word) async { @@ -12,7 +12,7 @@ quranOccurrenceDialog( title: Center( child: Text( '$word appears $quranOccurrences times in the Qur\'an', - style: Theme.of(context).textTheme.bodyText1, + style: Theme.of(context).textTheme.bodyLarge, ), ), // titlePadding: const EdgeInsets.all(16.0), @@ -20,7 +20,7 @@ quranOccurrenceDialog( insetPadding: const EdgeInsets.all(0), content: Padding( padding: const EdgeInsets.all(16.0), - child: Container( + child: SizedBox( height: MediaQuery.of(context).size.height * .7, width: MediaQuery.of(context).size.width * .9, child: FutureBuilder>>( @@ -49,29 +49,29 @@ quranOccurrenceDialog( : Theme.of(context) .primaryColor .withAlpha(20), - borderRadius: BorderRadius.all( + borderRadius: const BorderRadius.all( Radius.circular(10), ), ), child: ListTile( onTap: () async { if (await canLaunchUrl(uriScheme)) { - print(uriScheme); await launchUrl(uriScheme, mode: LaunchMode.externalApplication); - } else + } else { await launchUrl(quranComUri, mode: LaunchMode.externalApplication); + } }, leading: Text( '${j + 1} ', style: Theme.of(context) .textTheme - .bodyText1! + .bodyLarge! .copyWith( color: Theme.of(context) .textTheme - .bodyText1! + .bodyLarge! .color! .withAlpha(100)), ), @@ -79,7 +79,7 @@ quranOccurrenceDialog( "Qur'an ${snapshot.data![j]['SURAH']}:${snapshot.data![j]['AYAH']}/${snapshot.data![j]['POSITION']}", style: Theme.of(context) .textTheme - .bodyText1! + .bodyLarge! .copyWith( color: Theme.of(context).primaryColor, ), @@ -88,7 +88,7 @@ quranOccurrenceDialog( ); }); } else { - return Center( + return const Center( child: CircularProgressIndicator(), ); } @@ -97,11 +97,11 @@ quranOccurrenceDialog( ), actions: [ TextButton( + onPressed: Navigator.of(context).pop, child: Text( 'DISMISS', - style: Theme.of(context).textTheme.bodyText2, + style: Theme.of(context).textTheme.bodyMedium, ), - onPressed: Navigator.of(context).pop, ), ], ); diff --git a/linux/CMakeLists.txt b/linux/CMakeLists.txt index 50050cb..0bbd5de 100644 --- a/linux/CMakeLists.txt +++ b/linux/CMakeLists.txt @@ -86,6 +86,7 @@ set_target_properties(${BINARY_NAME} RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run" ) + # Generated plugin build rules, which manage building the plugins and adding # them to the application. include(flutter/generated_plugins.cmake) diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 2526ea9..c53aa8a 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -8,21 +8,25 @@ import Foundation import audio_session import in_app_review import just_audio -import path_provider_macos +import package_info_plus +import path_provider_foundation import share_plus -import shared_preferences_macos +import shared_preferences_foundation import sqflite import url_launcher_macos -import wakelock_macos +import video_player_avfoundation +import wakelock_plus func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { AudioSessionPlugin.register(with: registry.registrar(forPlugin: "AudioSessionPlugin")) InAppReviewPlugin.register(with: registry.registrar(forPlugin: "InAppReviewPlugin")) JustAudioPlugin.register(with: registry.registrar(forPlugin: "JustAudioPlugin")) + FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin")) PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin")) SharePlusMacosPlugin.register(with: registry.registrar(forPlugin: "SharePlusMacosPlugin")) SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) SqflitePlugin.register(with: registry.registrar(forPlugin: "SqflitePlugin")) UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin")) - WakelockMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockMacosPlugin")) + FVPVideoPlayerPlugin.register(with: registry.registrar(forPlugin: "FVPVideoPlayerPlugin")) + WakelockPlusMacosPlugin.register(with: registry.registrar(forPlugin: "WakelockPlusMacosPlugin")) } diff --git a/macos/Runner.xcodeproj/project.pbxproj b/macos/Runner.xcodeproj/project.pbxproj index f4a04e1..c16ddea 100644 --- a/macos/Runner.xcodeproj/project.pbxproj +++ b/macos/Runner.xcodeproj/project.pbxproj @@ -21,6 +21,7 @@ /* End PBXAggregateTarget section */ /* Begin PBXBuildFile section */ + 331C80D8294CF71000263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C80D7294CF71000263BE5 /* RunnerTests.swift */; }; 335BBD1B22A9A15E00E9071D /* GeneratedPluginRegistrant.swift in Sources */ = {isa = PBXBuildFile; fileRef = 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */; }; 33CC10F12044A3C60003C045 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC10F02044A3C60003C045 /* AppDelegate.swift */; }; 33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; }; @@ -29,6 +30,13 @@ /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ + 331C80D9294CF71000263BE5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 33CC10E52044A3C60003C045 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 33CC10EC2044A3C60003C045; + remoteInfo = Runner; + }; 33CC111F2044C79F0003C045 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 33CC10E52044A3C60003C045 /* Project object */; @@ -52,6 +60,8 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 331C80D5294CF71000263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 331C80D7294CF71000263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; }; 333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = ""; }; 335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = ""; }; 33CC10ED2044A3C60003C045 /* hans_wehr_dictionary.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "hans_wehr_dictionary.app"; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -71,6 +81,13 @@ /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ + 331C80D2294CF70F00263BE5 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 33CC10EA2044A3C60003C045 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -81,6 +98,14 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 331C80D6294CF71000263BE5 /* RunnerTests */ = { + isa = PBXGroup; + children = ( + 331C80D7294CF71000263BE5 /* RunnerTests.swift */, + ); + path = RunnerTests; + sourceTree = ""; + }; 33BA886A226E78AF003329D5 /* Configs */ = { isa = PBXGroup; children = ( @@ -97,6 +122,7 @@ children = ( 33FAB671232836740065AC1E /* Runner */, 33CEB47122A05771004F2AC0 /* Flutter */, + 331C80D6294CF71000263BE5 /* RunnerTests */, 33CC10EE2044A3C60003C045 /* Products */, D73912EC22F37F3D000D13A0 /* Frameworks */, ); @@ -106,7 +132,7 @@ isa = PBXGroup; children = ( 33CC10ED2044A3C60003C045 /* hans_wehr_dictionary.app */, - ); + ); name = Products; sourceTree = ""; }; @@ -155,6 +181,24 @@ /* End PBXGroup section */ /* Begin PBXNativeTarget section */ + 331C80D4294CF70F00263BE5 /* RunnerTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 331C80DE294CF71000263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */; + buildPhases = ( + 331C80D1294CF70F00263BE5 /* Sources */, + 331C80D2294CF70F00263BE5 /* Frameworks */, + 331C80D3294CF70F00263BE5 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 331C80DA294CF71000263BE5 /* PBXTargetDependency */, + ); + name = RunnerTests; + productName = RunnerTests; + productReference = 331C80D5294CF71000263BE5 /* RunnerTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; 33CC10EC2044A3C60003C045 /* Runner */ = { isa = PBXNativeTarget; buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */; @@ -182,9 +226,13 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0920; - LastUpgradeCheck = 1300; + LastUpgradeCheck = 1430; ORGANIZATIONNAME = ""; TargetAttributes = { + 331C80D4294CF70F00263BE5 = { + CreatedOnToolsVersion = 14.0; + TestTargetID = 33CC10EC2044A3C60003C045; + }; 33CC10EC2044A3C60003C045 = { CreatedOnToolsVersion = 9.2; LastSwiftMigration = 1100; @@ -215,12 +263,20 @@ projectRoot = ""; targets = ( 33CC10EC2044A3C60003C045 /* Runner */, + 331C80D4294CF70F00263BE5 /* RunnerTests */, 33CC111A2044C6BA0003C045 /* Flutter Assemble */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ + 331C80D3294CF70F00263BE5 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 33CC10EB2044A3C60003C045 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -274,6 +330,14 @@ /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ + 331C80D1294CF70F00263BE5 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 331C80D8294CF71000263BE5 /* RunnerTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 33CC10E92044A3C60003C045 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -287,6 +351,11 @@ /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ + 331C80DA294CF71000263BE5 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 33CC10EC2044A3C60003C045 /* Runner */; + targetProxy = 331C80D9294CF71000263BE5 /* PBXContainerItemProxy */; + }; 33CC11202044C79F0003C045 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 33CC111A2044C6BA0003C045 /* Flutter Assemble */; @@ -307,6 +376,48 @@ /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ + 331C80DB294CF71000263BE5 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.example.hansWehr.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/hans_wehr.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/hans_wehr"; + }; + name = Debug; + }; + 331C80DC294CF71000263BE5 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.example.hansWehr.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/hans_wehr.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/hans_wehr"; + }; + name = Release; + }; + 331C80DD294CF71000263BE5 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CURRENT_PROJECT_VERSION = 1; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.example.hansWehr.RunnerTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/hans_wehr.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/hans_wehr"; + }; + name = Profile; + }; 338D0CE9231458BD00FA5F75 /* Profile */ = { isa = XCBuildConfiguration; baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; @@ -537,6 +648,16 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ + 331C80DE294CF71000263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 331C80DB294CF71000263BE5 /* Debug */, + 331C80DC294CF71000263BE5 /* Release */, + 331C80DD294CF71000263BE5 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 33CC10E82044A3C60003C045 /* Build configuration list for PBXProject "Runner" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index 6ab5110..d09a052 100644 --- a/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/macos/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -1,6 +1,6 @@ + + + + @@ -71,7 +82,7 @@ diff --git a/macos/Runner/MainFlutterWindow.swift b/macos/Runner/MainFlutterWindow.swift index 2722837..3cc05eb 100644 --- a/macos/Runner/MainFlutterWindow.swift +++ b/macos/Runner/MainFlutterWindow.swift @@ -3,7 +3,7 @@ import FlutterMacOS class MainFlutterWindow: NSWindow { override func awakeFromNib() { - let flutterViewController = FlutterViewController.init() + let flutterViewController = FlutterViewController() let windowFrame = self.frame self.contentViewController = flutterViewController self.setFrame(windowFrame, display: true) diff --git a/macos/RunnerTests/RunnerTests.swift b/macos/RunnerTests/RunnerTests.swift new file mode 100644 index 0000000..5418c9f --- /dev/null +++ b/macos/RunnerTests/RunnerTests.swift @@ -0,0 +1,12 @@ +import FlutterMacOS +import Cocoa +import XCTest + +class RunnerTests: XCTestCase { + + func testExample() { + // If you add code to the Runner application, consider adding tests here. + // See https://developer.apple.com/documentation/xctest for more information about using XCTest. + } + +} diff --git a/pubspec.lock b/pubspec.lock index 13dd024..5b6e0be 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,50 +5,50 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: "4826f97faae3af9761f26c52e56b2aa5ffd18d2c1721d984ad85137721c25f43" + sha256: eb376e9acf6938204f90eb3b1f00b578640d3188b4c8a8ec054f9f479af8d051 url: "https://pub.dev" source: hosted - version: "31.0.0" + version: "64.0.0" analyzer: dependency: transitive description: name: analyzer - sha256: "7337610c3f9cd13e6b7c6bb0f410644091cf63c9a1436e73352a70f3286abb03" + sha256: "69f54f967773f6c26c7dcb13e93d7ccee8b17a641689da39e878d5cf13b06893" url: "https://pub.dev" source: hosted - version: "2.8.0" + version: "6.2.0" archive: dependency: transitive description: name: archive - sha256: ed7cc591a948744994714375caf9a2ce89e1d82e8243997c8a2994d57181c212 + sha256: "7e0d52067d05f2e0324268097ba723b71cb41ac8a6a2b24d1edf9c536b987b03" url: "https://pub.dev" source: hosted - version: "3.3.5" + version: "3.4.6" args: dependency: transitive description: name: args - sha256: b003c3098049a51720352d219b0bb5f219b60fbfb68e7a4748139a06a5676515 + sha256: eef6c46b622e0494a36c5a12d10d77fb4e855501a91c1b9ef9339326e58f0596 url: "https://pub.dev" source: hosted - version: "2.3.1" + version: "2.4.2" async: dependency: transitive description: name: async - sha256: bfe67ef28df125b7dddcea62755991f807aa39a2492a23e1550161692950bbe0 + sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" url: "https://pub.dev" source: hosted - version: "2.10.0" + version: "2.11.0" audio_session: dependency: transitive description: name: audio_session - sha256: e4acc4e9eaa32436dfc5d7aed7f0a370f2d7bb27ee27de30d6c4f220c2a05c73 + sha256: "8a2bc5e30520e18f3fb0e366793d78057fb64cd5287862c76af0c8771f2a52ad" url: "https://pub.dev" source: hosted - version: "0.1.13" + version: "0.1.16" boolean_selector: dependency: transitive description: @@ -61,50 +61,50 @@ packages: dependency: transitive description: name: build - sha256: de3ecca84980ee5e632888a04f4a72d8e3c390104fd5edb3a724785f66e9e97a + sha256: "80184af8b6cb3e5c1c4ec6d8544d27711700bc3e6d2efad04238c7b5290889f0" url: "https://pub.dev" source: hosted - version: "2.0.3" + version: "2.4.1" build_config: dependency: transitive description: name: build_config - sha256: "9160104f468c8117f7dddd3c94d8f440d0f82a324bf29eb84e0b434cff7a0e03" + sha256: bf80fcfb46a29945b423bd9aad884590fb1dc69b330a4d4700cac476af1708d1 url: "https://pub.dev" source: hosted - version: "0.4.7" + version: "1.1.1" build_daemon: dependency: transitive description: name: build_daemon - sha256: "02d9e94f2b7f6e4de0f0cd24dc9e2cd0c00fec082265ca89d3b32282cb7381bc" + sha256: "5f02d73eb2ba16483e693f80bee4f088563a820e47d1027d4cdfe62b5bb43e65" url: "https://pub.dev" source: hosted - version: "2.1.10" + version: "4.0.0" build_resolvers: dependency: transitive description: name: build_resolvers - sha256: "4666aef1d045c5ca15ebba63e400bd4e4fbd9f0dd06e791b51ab210da78a27f7" + sha256: "64e12b0521812d1684b1917bc80945625391cb9bdd4312536b1d69dcb6133ed8" url: "https://pub.dev" source: hosted - version: "2.0.6" + version: "2.4.1" build_runner: dependency: "direct dev" description: name: build_runner - sha256: cd95f4d4a6a13b0dc1408b0a4b086bffdac08dcb61e45a0e1f2f58905d4c97a5 + sha256: "10c6bcdbf9d049a0b666702cf1cee4ddfdc38f02a19d35ae392863b47519848b" url: "https://pub.dev" source: hosted - version: "1.12.2" + version: "2.4.6" build_runner_core: dependency: transitive description: name: build_runner_core - sha256: "653b9dfd0472476ca837ef62786717434b8fa4f5e5521c85d7376dd3234aefeb" + sha256: c9e32d21dd6626b5c163d48b037ce906bbe428bc23ab77bcd77bb21e593b6185 url: "https://pub.dev" source: hosted - version: "6.1.12" + version: "7.2.11" built_collection: dependency: transitive description: @@ -117,66 +117,66 @@ packages: dependency: transitive description: name: built_value - sha256: "31b7c748fd4b9adf8d25d72a4c4a59ef119f12876cf414f94f8af5131d5fa2b0" + sha256: a8de5955205b4d1dbbbc267daddf2178bd737e4bab8987c04a500478c9651e74 url: "https://pub.dev" source: hosted - version: "8.4.4" + version: "8.6.3" cached_network_image: dependency: transitive description: name: cached_network_image - sha256: fd3d0dc1d451f9a252b32d95d3f0c3c487bc41a75eba2e6097cb0b9c71491b15 + sha256: f98972704692ba679db144261172a8e20feb145636c617af0eb4022132a6797f url: "https://pub.dev" source: hosted - version: "3.2.3" + version: "3.3.0" cached_network_image_platform_interface: dependency: transitive description: name: cached_network_image_platform_interface - sha256: bb2b8403b4ccdc60ef5f25c70dead1f3d32d24b9d6117cfc087f496b178594a7 + sha256: "56aa42a7a01e3c9db8456d9f3f999931f1e05535b5a424271e9a38cabf066613" url: "https://pub.dev" source: hosted - version: "2.0.0" + version: "3.0.0" cached_network_image_web: dependency: transitive description: name: cached_network_image_web - sha256: b8eb814ebfcb4dea049680f8c1ffb2df399e4d03bf7a352c775e26fa06e02fa0 + sha256: "759b9a9f8f6ccbb66c185df805fac107f05730b1dab9c64626d1008cca532257" url: "https://pub.dev" source: hosted - version: "1.0.2" + version: "1.1.0" characters: dependency: transitive description: name: characters - sha256: e6a326c8af69605aec75ed6c187d06b349707a27fbff8222ca9cc2cff167975c + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.3.0" checked_yaml: dependency: transitive description: name: checked_yaml - sha256: dd007e4fb8270916820a0d66e24f619266b60773cddd082c6439341645af2659 + sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "2.0.3" chewie: dependency: transitive description: name: chewie - sha256: "7737b1b8b1f9df3b3751abfb0dea5efbebb7060c28eccdc3b0fa4a0d638eaf9f" + sha256: ccfce3350ae9fd419cd336cdf3380f77a08e45171e1e3cb3d499d204de5e7ea8 url: "https://pub.dev" source: hosted - version: "1.3.6" + version: "1.7.1" cli_util: dependency: transitive description: name: cli_util - sha256: "66f86e916d285c1a93d3b79587d94bd71984a66aac4ff74e524cfa7877f1395c" + sha256: b8db3080e59b2503ca9e7922c3df2072cf13992354d5e944074ffa836fba43b7 url: "https://pub.dev" source: hosted - version: "0.3.5" + version: "0.4.0" clock: dependency: transitive description: @@ -189,18 +189,18 @@ packages: dependency: transitive description: name: code_builder - sha256: "48ae73ba8dbf1923de91e0fd65736148f63f6c6fb0925bdda05c1df0298c55e1" + sha256: "1be9be30396d7e4c0db42c35ea6ccd7cc6a1e19916b5dc64d6ac216b5544d677" url: "https://pub.dev" source: hosted - version: "3.7.0" + version: "4.7.0" collection: dependency: transitive description: name: collection - sha256: cfc915e6923fe5ce6e153b0723c753045de46de1b4d63771530504004a45fae0 + sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687 url: "https://pub.dev" source: hosted - version: "1.17.0" + version: "1.17.2" convert: dependency: transitive description: @@ -213,42 +213,50 @@ packages: dependency: transitive description: name: cross_file - sha256: f71079978789bc2fe78d79227f1f8cfe195b31bbd8db2399b0d15a4b96fb843b + sha256: "445db18de832dba8d851e287aff8ccf169bed30d2e94243cb54c7d2f1ed2142c" url: "https://pub.dev" source: hosted - version: "0.3.3+2" + version: "0.3.3+6" crypto: dependency: transitive description: name: crypto - sha256: aa274aa7774f8964e4f4f38cc994db7b6158dd36e9187aaceaddc994b35c6c67 + sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab url: "https://pub.dev" source: hosted - version: "3.0.2" + version: "3.0.3" csslib: dependency: transitive description: name: csslib - sha256: b36c7f7e24c0bdf1bf9a3da461c837d1de64b9f8beb190c9011d8c72a3dfd745 + sha256: "706b5707578e0c1b4b7550f64078f0a0f19dec3f50a178ffae7006b0a9ca58fb" url: "https://pub.dev" source: hosted - version: "0.17.2" + version: "1.0.0" cupertino_icons: dependency: "direct main" description: name: cupertino_icons - sha256: e35129dc44c9118cee2a5603506d823bab99c68393879edb440e0090d07586be + sha256: d57953e10f9f8327ce64a508a355f0b1ec902193f66288e8cb5070e7c47eeb2d url: "https://pub.dev" source: hosted - version: "1.0.5" + version: "1.0.6" dart_style: dependency: transitive description: name: dart_style - sha256: "6e8086e1d3c2f6bc15056ee248c4ddc48c2bc71287c0961bf801a08633ed4333" + sha256: abd7625e16f51f554ea244d090292945ec4d4be7bfbaf2ec8cccea568919d334 url: "https://pub.dev" source: hosted - version: "2.2.1" + version: "2.3.3" + dbus: + dependency: transitive + description: + name: dbus + sha256: "6f07cba3f7b3448d42d015bfd3d53fe12e5b36da2423f23838efc1d5fb31a263" + url: "https://pub.dev" + source: hosted + version: "0.7.8" fake_async: dependency: transitive description: @@ -261,18 +269,18 @@ packages: dependency: transitive description: name: ffi - sha256: a38574032c5f1dd06c4aee541789906c12ccaab8ba01446e800d9c5b79c4a978 + sha256: "7bf0adc28a23d395f19f3f1eb21dd7cfd1dd9f8e1c50051c069122e6853bc878" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "2.1.0" file: dependency: transitive description: name: file - sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d" + sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" url: "https://pub.dev" source: hosted - version: "6.1.4" + version: "7.0.0" fixnum: dependency: transitive description: @@ -286,22 +294,14 @@ packages: description: flutter source: sdk version: "0.0.0" - flutter_blurhash: - dependency: transitive - description: - name: flutter_blurhash - sha256: "05001537bd3fac7644fa6558b09ec8c0a3f2eba78c0765f88912882b1331a5c6" - url: "https://pub.dev" - source: hosted - version: "0.7.0" flutter_cache_manager: dependency: transitive description: name: flutter_cache_manager - sha256: "32cd900555219333326a2d0653aaaf8671264c29befa65bbd9856d204a4c9fb3" + sha256: "8207f27539deb83732fdda03e259349046a39a4c767269285f449ade355d54ba" url: "https://pub.dev" source: hosted - version: "3.3.0" + version: "3.3.1" flutter_colorpicker: dependency: "direct main" description: @@ -314,18 +314,26 @@ packages: dependency: "direct dev" description: name: flutter_launcher_icons - sha256: ce0e501cfc258907842238e4ca605e74b7fd1cdf04b3b43e86c43f3e40a1592c + sha256: "526faf84284b86a4cb36d20a5e45147747b7563d921373d4ee0559c54fcdbcea" + url: "https://pub.dev" + source: hosted + version: "0.13.1" + flutter_lints: + dependency: "direct dev" + description: + name: flutter_lints + sha256: ad76540d21c066228ee3f9d1dad64a9f7e46530e8bb7c85011a88bc1fd874bc5 url: "https://pub.dev" source: hosted - version: "0.11.0" + version: "3.0.0" flutter_svg: dependency: transitive description: name: flutter_svg - sha256: "6ff9fa12892ae074092de2fa6a9938fb21dbabfdaa2ff57dc697ff912fc8d4b2" + sha256: "8c5d68a82add3ca76d792f058b186a0599414f279f00ece4830b9b231b570338" url: "https://pub.dev" source: hosted - version: "1.1.6" + version: "2.0.7" flutter_test: dependency: "direct dev" description: flutter @@ -340,114 +348,114 @@ packages: dependency: "direct main" description: name: flutter_widget_from_html - sha256: c3fe0d934542ef0bc94d8d113ee76d90a10ab46aaa353bd6c262bf441a5bab7b + sha256: eacebafb2d026d9df6f3bf600eaf622b10cd0dc413ad7fe5aba72303b8237742 url: "https://pub.dev" source: hosted - version: "0.9.0+1" + version: "0.14.4" flutter_widget_from_html_core: dependency: transitive description: name: flutter_widget_from_html_core - sha256: "71ebb7ff9ff5a8a17bd2dfedcfbd461b3dbff392e7b90f11732a2bf1888ca616" + sha256: d1366d0421011547a339f03c77672575dd018759f43b37b6e3257e34af77e302 + url: "https://pub.dev" + source: hosted + version: "0.14.4" + frontend_server_client: + dependency: transitive + description: + name: frontend_server_client + sha256: "408e3ca148b31c20282ad6f37ebfa6f4bdc8fede5b74bc2f08d9d92b55db3612" url: "https://pub.dev" source: hosted - version: "0.9.0+2" + version: "3.2.0" fwfh_cached_network_image: dependency: transitive description: name: fwfh_cached_network_image - sha256: "2b6b1f07ce04f52dbaa84258c5c613f1862e81d501cdf0b9208ddd6f7100d6b2" + sha256: "952aea958a5fda7d616cc297ba4bc08427e381459e75526fa375d6d8345630d3" url: "https://pub.dev" source: hosted - version: "0.7.0+3" + version: "0.14.2" fwfh_chewie: dependency: transitive description: name: fwfh_chewie - sha256: a0c871eb487c7c3dd8d52e9cd6838be8baf448cf5ff1e28d8999406b49faee7b + sha256: b74673d1b2f8710df5addd0ceb82c148f28b9fca9fe619048eebc734d055d55b url: "https://pub.dev" source: hosted - version: "0.7.0+3" + version: "0.14.2" fwfh_just_audio: dependency: transitive description: name: fwfh_just_audio - sha256: e2721732cfb8d3da0d5e74bc82af48100312fd4edc305567f2b9b85d53b63a1c + sha256: "4962bc59cf8bbb0a77a55ff56a7b925612b0d8263bc2ede3636b9c86113cb493" url: "https://pub.dev" source: hosted - version: "0.9.0" + version: "0.14.2" fwfh_svg: dependency: transitive description: name: fwfh_svg - sha256: "556df67faf76b98c76dba144daf9fa9b3e874670e35b0a02d918402f8b8e98f5" - url: "https://pub.dev" - source: hosted - version: "0.7.2+1" - fwfh_text_style: - dependency: transitive - description: - name: fwfh_text_style - sha256: "37806ee0222f79b6e8d4c698c322c897eae6a817258156f40aeece4e588fac60" + sha256: "26df142c1784c29c3675ad0d37f589fc5c2173a14fc002d2c38cde3d0f117302" url: "https://pub.dev" source: hosted - version: "2.22.08+1" + version: "0.8.0+4" fwfh_url_launcher: dependency: transitive description: name: fwfh_url_launcher - sha256: cf3a537d74bf01b65d91dc8eac8c889d94b4176002fdc7069138f166f22d3411 + sha256: "2a526c9819f74b4106ba2fba4dac79f0082deecd8d2c7011cd0471cb710e3eff" url: "https://pub.dev" source: hosted - version: "0.9.0" + version: "0.9.0+4" fwfh_webview: dependency: transitive description: name: fwfh_webview - sha256: "987ebaf94f3c42cddb6e0dbac6720a9cfc55c3510b770e925334373d91a12795" + sha256: "86531afae48a5838d2dce9719dfc6d46c3179237dacf47ea2b2c068243b2e88f" url: "https://pub.dev" source: hosted - version: "0.6.2+5" + version: "0.14.2" get_it: dependency: "direct main" description: name: get_it - sha256: "290fde3a86072e4b37dbb03c07bec6126f0ecc28dad403c12ffe2e5a2d751ab7" + sha256: f79870884de16d689cf9a7d15eedf31ed61d750e813c538a6efb92660fea83c3 url: "https://pub.dev" source: hosted - version: "7.2.0" + version: "7.6.4" glob: dependency: transitive description: name: glob - sha256: "4515b5b6ddb505ebdd242a5f2cc5d22d3d6a80013789debfbda7777f47ea308c" + sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63" url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.2" graphs: dependency: transitive description: name: graphs - sha256: e84da18c5bd9854f4222e62d762e0ffd290726ffc5785dcb976f8c16ff797f5e + sha256: aedc5a15e78fc65a6e23bcd927f24c64dd995062bcd1ca6eda65a3cff92a4d19 url: "https://pub.dev" source: hosted - version: "1.0.0" + version: "2.3.1" html: - dependency: transitive + dependency: "direct main" description: name: html - sha256: d9793e10dbe0e6c364f4c59bf3e01fb33a9b2a674bc7a1081693dba0614b6269 + sha256: "3a7812d5bcd2894edf53dfaf8cd640876cf6cef50a8f238745c8b8120ea74d3a" url: "https://pub.dev" source: hosted - version: "0.15.1" + version: "0.15.4" http: dependency: "direct main" description: name: http - sha256: "6aa2946395183537c8b880962d935877325d6a09a2867c3970c05c0fed6ac482" + sha256: "759d1a329847dd0f39226c688d3e06a6b8679668e350e2891a6474f8b4bb8525" url: "https://pub.dev" source: hosted - version: "0.13.5" + version: "1.1.0" http_multi_server: dependency: transitive description: @@ -468,10 +476,10 @@ packages: dependency: transitive description: name: image - sha256: f6ffe2895e3c86c6ad5a27e6302cf807403463e397cb2f0c580f619ac2fa588b + sha256: "028f61960d56f26414eb616b48b04eb37d700cbe477b7fb09bf1d7ce57fd9271" url: "https://pub.dev" source: hosted - version: "3.2.2" + version: "4.1.3" implicitly_animated_reorderable_list_2: dependency: "direct main" description: @@ -484,18 +492,18 @@ packages: dependency: "direct main" description: name: in_app_review - sha256: "16328b8202d36522322b95804ae5d975577aa9f584d634985849ba1099645850" + sha256: "41ec6f30427ab09eb6ae1c85c4a2a624a145fc5d726f023de4d97170ec9e5466" url: "https://pub.dev" source: hosted - version: "2.0.6" + version: "2.0.8" in_app_review_platform_interface: dependency: transitive description: name: in_app_review_platform_interface - sha256: b12ec9aaf6b34d3a72aa95895eb252b381896246bdad4ef378d444affe8410ef + sha256: fed2c755f2125caa9ae10495a3c163aa7fab5af3585a9c62ef4a6920c5b45f10 url: "https://pub.dev" source: hosted - version: "2.0.4" + version: "2.0.5" io: dependency: transitive description: @@ -508,90 +516,98 @@ packages: dependency: transitive description: name: js - sha256: "5528c2f391ededb7775ec1daa69e65a2d61276f7552de2b5f7b8d34ee9fd4ab7" + sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 url: "https://pub.dev" source: hosted - version: "0.6.5" + version: "0.6.7" json_annotation: dependency: transitive description: name: json_annotation - sha256: "3520fa844009431b5d4491a5a778603520cdc399ab3406332dcc50f93547258c" + sha256: b10a7b2ff83d83c777edba3c6a0f97045ddadd56c944e1a23a3fdf43a1bf4467 url: "https://pub.dev" source: hosted - version: "4.7.0" + version: "4.8.1" just_audio: dependency: transitive description: name: just_audio - sha256: ec0bdd51762454542882ec06b3015170d51b37ae074706569e30d3554133bd4c + sha256: "5ed0cd723e17dfd8cd4b0253726221e67f6546841ea4553635cf895061fc335b" url: "https://pub.dev" source: hosted - version: "0.9.30" + version: "0.9.35" just_audio_platform_interface: dependency: transitive description: name: just_audio_platform_interface - sha256: eff112d5138bea3ba544b6338b1e0537a32b5e1425e4d0dc38f732771cda7c84 + sha256: d8409da198bbc59426cd45d4c92fca522a2ec269b576ce29459d6d6fcaeb44df url: "https://pub.dev" source: hosted - version: "4.2.0" + version: "4.2.1" just_audio_web: dependency: transitive description: name: just_audio_web - sha256: "89d8db6f19f3821bb6bf908c4bfb846079afb2ab575b783d781a6bf119e3abaf" + sha256: ff62f733f437b25a0ff590f0e295fa5441dcb465f1edbdb33b3dea264705bc13 + url: "https://pub.dev" + source: hosted + version: "0.4.8" + lints: + dependency: transitive + description: + name: lints + sha256: cbf8d4b858bb0134ef3ef87841abdf8d63bfc255c266b7bf6b39daa1085c4290 url: "https://pub.dev" source: hosted - version: "0.4.7" + version: "3.0.0" logging: dependency: transitive description: name: logging - sha256: "04094f2eb032cbb06c6f6e8d3607edcfcb0455e2bb6cbc010cb01171dcb64e6d" + sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340" url: "https://pub.dev" source: hosted - version: "1.1.1" + version: "1.2.0" matcher: dependency: transitive description: name: matcher - sha256: "16db949ceee371e9b99d22f88fa3a73c4e59fd0afed0bd25fc336eb76c198b72" + sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e" url: "https://pub.dev" source: hosted - version: "0.12.13" + version: "0.12.16" material_color_utilities: dependency: transitive description: name: material_color_utilities - sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724 + sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41" url: "https://pub.dev" source: hosted - version: "0.2.0" - material_floating_search_bar: + version: "0.5.0" + material_floating_search_bar_2: dependency: "direct main" description: - name: material_floating_search_bar - sha256: "970df4bc17a1ae7cacc745012fba442701daa44224e46bc0fd459e3aff0d5362" + name: material_floating_search_bar_2 + sha256: ab0c6d209d9491f98dd4c72f2641d0ba1dd35c87effca1f23d8679bece43add0 url: "https://pub.dev" source: hosted - version: "0.3.7" + version: "0.5.0" meta: dependency: transitive description: name: meta - sha256: "6c268b42ed578a53088d834796959e4a1814b5e9e164f147f580a386e5decf42" + sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3" url: "https://pub.dev" source: hosted - version: "1.8.0" + version: "1.9.1" mime: dependency: transitive description: name: mime - sha256: "52e38f7e1143ef39daf532117d6b8f8f617bf4bcd6044ed8c29040d20d269630" + sha256: e4ff8e8564c03f255408decd16e7899da1733852a9110a58fe6d1b817684a63e url: "https://pub.dev" source: hosted - version: "1.0.3" + version: "1.0.4" nested: dependency: transitive description: @@ -604,10 +620,10 @@ packages: dependency: transitive description: name: octo_image - sha256: "107f3ed1330006a3bea63615e81cf637433f5135a52466c7caa0e7152bca9143" + sha256: "45b40f99622f11901238e18d48f5f12ea36426d8eced9f4cbf58479c7aa2430d" url: "https://pub.dev" source: hosted - version: "1.0.2" + version: "2.0.0" package_config: dependency: transitive description: @@ -616,22 +632,30 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.0" - path: - dependency: "direct main" + package_info_plus: + dependency: transitive description: - name: path - sha256: db9d4f58c908a4ba5953fcee2ae317c94889433e5024c27ce74a37f94267945b + name: package_info_plus + sha256: "7e76fad405b3e4016cd39d08f455a4eb5199723cf594cd1b8916d47140d93017" url: "https://pub.dev" source: hosted - version: "1.8.2" - path_drawing: + version: "4.2.0" + package_info_plus_platform_interface: dependency: transitive description: - name: path_drawing - sha256: bbb1934c0cbb03091af082a6389ca2080345291ef07a5fa6d6e078ba8682f977 + name: package_info_plus_platform_interface + sha256: "9bc8ba46813a4cc42c66ab781470711781940780fd8beddd0c3da62506d3a6c6" url: "https://pub.dev" source: hosted - version: "1.0.1" + version: "2.0.1" + path: + dependency: "direct main" + description: + name: path + sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + url: "https://pub.dev" + source: hosted + version: "1.8.3" path_parsing: dependency: transitive description: @@ -644,98 +668,82 @@ packages: dependency: transitive description: name: path_provider - sha256: "050e8e85e4b7fecdf2bb3682c1c64c4887a183720c802d323de8a5fd76d372dd" + sha256: a1aa8aaa2542a6bc57e381f132af822420216c80d4781f7aa085ca3229208aaa url: "https://pub.dev" source: hosted - version: "2.0.11" + version: "2.1.1" path_provider_android: dependency: transitive description: name: path_provider_android - sha256: a776c088d671b27f6e3aa8881d64b87b3e80201c64e8869b811325de7a76c15e + sha256: "6b8b19bd80da4f11ce91b2d1fb931f3006911477cec227cce23d3253d80df3f1" url: "https://pub.dev" source: hosted - version: "2.0.22" - path_provider_ios: + version: "2.2.0" + path_provider_foundation: dependency: transitive description: - name: path_provider_ios - sha256: "03d639406f5343478352433f00d3c4394d52dac8df3d847869c5e2333e0bbce8" + name: path_provider_foundation + sha256: "19314d595120f82aca0ba62787d58dde2cc6b5df7d2f0daf72489e38d1b57f2d" url: "https://pub.dev" source: hosted - version: "2.0.11" + version: "2.3.1" path_provider_linux: dependency: transitive description: name: path_provider_linux - sha256: ab0987bf95bc591da42dffb38c77398fc43309f0b9b894dcc5d6f40c4b26c379 + sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279 url: "https://pub.dev" source: hosted - version: "2.1.7" - path_provider_macos: - dependency: transitive - description: - name: path_provider_macos - sha256: "2a97e7fbb7ae9dcd0dfc1220a78e9ec3e71da691912e617e8715ff2a13086ae8" - url: "https://pub.dev" - source: hosted - version: "2.0.6" + version: "2.2.1" path_provider_platform_interface: dependency: transitive description: name: path_provider_platform_interface - sha256: f0abc8ebd7253741f05488b4813d936b4d07c6bae3e86148a09e342ee4b08e76 + sha256: "94b1e0dd80970c1ce43d5d4e050a9918fce4f4a775e6142424c30a29a363265c" url: "https://pub.dev" source: hosted - version: "2.0.5" + version: "2.1.1" path_provider_windows: dependency: transitive description: name: path_provider_windows - sha256: bcabbe399d4042b8ee687e17548d5d3f527255253b4a639f5f8d2094a9c2b45c + sha256: "8bc9f22eee8690981c22aa7fc602f5c85b497a6fb2ceb35ee5a5e5ed85ad8170" url: "https://pub.dev" source: hosted - version: "2.1.3" - pedantic: - dependency: transitive - description: - name: pedantic - sha256: "67fc27ed9639506c856c840ccce7594d0bdcd91bc8d53d6e52359449a1d50602" - url: "https://pub.dev" - source: hosted - version: "1.11.1" + version: "2.2.1" petitparser: dependency: transitive description: name: petitparser - sha256: "49392a45ced973e8d94a85fdb21293fbb40ba805fc49f2965101ae748a3683b4" + sha256: cb3798bef7fc021ac45b308f4b51208a152792445cce0448c9a4ba5879dd8750 url: "https://pub.dev" source: hosted - version: "5.1.0" + version: "5.4.0" platform: dependency: transitive description: name: platform - sha256: "4a451831508d7d6ca779f7ac6e212b4023dd5a7d08a27a63da33756410e32b76" + sha256: "0a279f0707af40c890e80b1e9df8bb761694c074ba7e1d4ab1bc4b728e200b59" url: "https://pub.dev" source: hosted - version: "3.1.0" + version: "3.1.3" plugin_platform_interface: dependency: transitive description: name: plugin_platform_interface - sha256: dbf0f707c78beedc9200146ad3cb0ab4d5da13c246336987be6940f026500d3a + sha256: da3fdfeccc4d4ff2da8f8c556704c08f912542c5fb3cf2233ed75372384a034d url: "https://pub.dev" source: hosted - version: "2.1.3" + version: "2.1.6" pointycastle: dependency: transitive description: name: pointycastle - sha256: db7306cf0249f838d1a24af52b5a5887c5bf7f31d8bb4e827d071dc0939ad346 + sha256: "7c1e5f0d23c9016c5bbd8b1473d0d3fb3fc851b876046039509e18e0c7485f2c" url: "https://pub.dev" source: hosted - version: "3.6.2" + version: "3.7.3" pool: dependency: transitive description: @@ -744,14 +752,6 @@ packages: url: "https://pub.dev" source: hosted version: "1.5.1" - process: - dependency: transitive - description: - name: process - sha256: "53fd8db9cec1d37b0574e12f07520d582019cb6c44abf5479a01505099a34a09" - url: "https://pub.dev" - source: hosted - version: "4.2.4" provider: dependency: "direct main" description: @@ -764,18 +764,18 @@ packages: dependency: transitive description: name: pub_semver - sha256: "307de764d305289ff24ad257ad5c5793ce56d04947599ad68b3baa124105fc17" + sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c" url: "https://pub.dev" source: hosted - version: "2.1.3" + version: "2.1.4" pubspec_parse: dependency: transitive description: name: pubspec_parse - sha256: "75f6614d6dde2dc68948dffbaa4fe5dae32cd700eb9fb763fe11dfb45a3c4d0a" + sha256: c63b2876e58e194e4b0828fcb080ad0e06d051cb607a6be51a9e084f47cb9367 url: "https://pub.dev" source: hosted - version: "1.2.1" + version: "1.2.3" rxdart: dependency: transitive description: @@ -788,98 +788,90 @@ packages: dependency: "direct main" description: name: share_plus - sha256: e387077716f80609bb979cd199331033326033ecd1c8f200a90c5f57b1c9f55e + sha256: f74fc3f1cbd99f39760182e176802f693fa0ec9625c045561cfad54681ea93dd url: "https://pub.dev" source: hosted - version: "6.3.0" + version: "7.2.1" share_plus_platform_interface: dependency: transitive description: name: share_plus_platform_interface - sha256: "82ddd4ab9260c295e6e39612d4ff00390b9a7a21f1bb1da771e2f232d80ab8a1" + sha256: df08bc3a07d01f5ea47b45d03ffcba1fa9cd5370fb44b3f38c70e42cced0f956 url: "https://pub.dev" source: hosted - version: "3.2.0" + version: "3.3.1" shared_preferences: dependency: "direct main" description: name: shared_preferences - sha256: "76917b7d4b9526b2ba416808a7eb9fb2863c1a09cf63ec85f1453da240fa818a" + sha256: "81429e4481e1ccfb51ede496e916348668fd0921627779233bd24cc3ff6abd02" url: "https://pub.dev" source: hosted - version: "2.0.15" + version: "2.2.2" shared_preferences_android: dependency: transitive description: name: shared_preferences_android - sha256: "8e251f3c986002b65fed6396bce81f379fb63c27317d49743cf289fd0fd1ab97" + sha256: "8568a389334b6e83415b6aae55378e158fbc2314e074983362d20c562780fb06" url: "https://pub.dev" source: hosted - version: "2.0.14" - shared_preferences_ios: + version: "2.2.1" + shared_preferences_foundation: dependency: transitive description: - name: shared_preferences_ios - sha256: "585a14cefec7da8c9c2fb8cd283a3bb726b4155c0952afe6a0caaa7b2272de34" + name: shared_preferences_foundation + sha256: "7bf53a9f2d007329ee6f3df7268fd498f8373602f943c975598bbb34649b62a7" url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.3.4" shared_preferences_linux: dependency: transitive description: name: shared_preferences_linux - sha256: fbc3cd6826896b66a5f576b025e4f344f780c84ea7f8203097a353370607a2c8 - url: "https://pub.dev" - source: hosted - version: "2.1.2" - shared_preferences_macos: - dependency: transitive - description: - name: shared_preferences_macos - sha256: fbb94bf296576f49be37a1496d5951796211a8db0aa22cc0d68c46440dad808c + sha256: "9f2cbcf46d4270ea8be39fa156d86379077c8a5228d9dfdb1164ae0bb93f1faa" url: "https://pub.dev" source: hosted - version: "2.0.4" + version: "2.3.2" shared_preferences_platform_interface: dependency: transitive description: name: shared_preferences_platform_interface - sha256: da9431745ede5ece47bc26d5d73a9d3c6936ef6945c101a5aca46f62e52c1cf3 + sha256: d4ec5fc9ebb2f2e056c617112aa75dcf92fc2e4faaf2ae999caa297473f75d8a url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.3.1" shared_preferences_web: dependency: transitive description: name: shared_preferences_web - sha256: a4b5bc37fe1b368bbc81f953197d55e12f49d0296e7e412dfe2d2d77d6929958 + sha256: d762709c2bbe80626ecc819143013cc820fa49ca5e363620ee20a8b15a3e3daf url: "https://pub.dev" source: hosted - version: "2.0.4" + version: "2.2.1" shared_preferences_windows: dependency: transitive description: name: shared_preferences_windows - sha256: "07c274c2115d4d5e4280622abb09f0980e2c5b1fcdc98ae9f59a3bad5bfc1f26" + sha256: "841ad54f3c8381c480d0c9b508b89a34036f512482c407e6df7a9c4aa2ef8f59" url: "https://pub.dev" source: hosted - version: "2.1.2" + version: "2.3.2" shelf: dependency: transitive description: name: shelf - sha256: c24a96135a2ccd62c64b69315a14adc5c3419df63b4d7c05832a346fdb73682c + sha256: ad29c505aee705f41a4d8963641f91ac4cee3c8fad5947e033390a7bd8180fa4 url: "https://pub.dev" source: hosted - version: "1.4.0" + version: "1.4.1" shelf_web_socket: dependency: transitive description: name: shelf_web_socket - sha256: a988c0e8d8ffbdb8a28aa7ec8e449c260f3deb808781fe1284d22c5bba7156e8 + sha256: "9ca081be41c60190ebcb4766b2486a7d50261db7bd0f5d9615f2d653637a84c1" url: "https://pub.dev" source: hosted - version: "1.0.3" + version: "1.0.4" sky_engine: dependency: transitive description: flutter @@ -889,42 +881,50 @@ packages: dependency: transitive description: name: source_span - sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250 + sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" url: "https://pub.dev" source: hosted - version: "1.9.1" + version: "1.10.0" + sprintf: + dependency: transitive + description: + name: sprintf + sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23" + url: "https://pub.dev" + source: hosted + version: "7.0.0" sqflite: dependency: transitive description: name: sqflite - sha256: "2b1697c7b78576fdc722c358f16f62171bd56e92dc13422d9e44be3fc446c276" + sha256: "591f1602816e9c31377d5f008c2d9ef7b8aca8941c3f89cc5fd9d84da0c38a9a" url: "https://pub.dev" source: hosted - version: "2.2.2" + version: "2.3.0" sqflite_common: dependency: transitive description: name: sqflite_common - sha256: e77abf6ff961d69dfef41daccbb66b51e9983cdd5cb35bf30733598057401555 + sha256: "1b92f368f44b0dee2425bb861cfa17b6f6cf3961f762ff6f941d20b33355660a" url: "https://pub.dev" source: hosted - version: "2.4.5" + version: "2.5.0" sqflite_common_ffi: dependency: "direct main" description: name: sqflite_common_ffi - sha256: f86de82d37403af491b21920a696b19f01465b596f545d1acd4d29a0a72418ad + sha256: "0d5cc1be2eb18400ac6701c31211d44164393aa75886093002ecdd947be04f93" url: "https://pub.dev" source: hosted - version: "2.2.5" + version: "2.3.0+2" sqlite3: dependency: transitive description: name: sqlite3 - sha256: a3ba4b66a7ab170ce7aa3f5ac43c19ee8d6637afbe7b7c95c94112b4f4d91566 + sha256: db65233e6b99e99b2548932f55a987961bc06d82a31a0665451fa0b4fff4c3fb url: "https://pub.dev" source: hosted - version: "1.11.0" + version: "2.1.0" stack_trace: dependency: transitive description: @@ -961,10 +961,10 @@ packages: dependency: transitive description: name: synchronized - sha256: "7b530acd9cb7c71b0019a1e7fa22c4105e675557a4400b6a401c71c5e0ade1ac" + sha256: "5fcbd27688af6082f5abd611af56ee575342c30e87541d0245f7ff99faa02c60" url: "https://pub.dev" source: hosted - version: "3.0.0+3" + version: "3.1.0" term_glyph: dependency: transitive description: @@ -977,10 +977,10 @@ packages: dependency: transitive description: name: test_api - sha256: ad540f65f92caa91bf21dfc8ffb8c589d6e4dc0c2267818b4cc2792857706206 + sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8" url: "https://pub.dev" source: hosted - version: "0.4.16" + version: "0.6.0" timing: dependency: transitive description: @@ -993,82 +993,106 @@ packages: dependency: transitive description: name: typed_data - sha256: "26f87ade979c47a150c9eaab93ccd2bebe70a27dc0b4b29517f2904f04eb11a5" + sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c url: "https://pub.dev" source: hosted - version: "1.3.1" + version: "1.3.2" url_launcher: dependency: "direct main" description: name: url_launcher - sha256: "3c92b0efb5e9dcb8f846aefabf9f0f739f91682ed486b991ceda51c288e60896" + sha256: "47e208a6711459d813ba18af120d9663c20bdf6985d6ad39fe165d2538378d27" url: "https://pub.dev" source: hosted - version: "6.1.7" + version: "6.1.14" url_launcher_android: dependency: transitive description: name: url_launcher_android - sha256: "6f91d30ce9060c204b2dbe728adb300750fa4b228e8f7ed1b961aa1ceb728799" + sha256: b04af59516ab45762b2ca6da40fa830d72d0f6045cd97744450b73493fa76330 url: "https://pub.dev" source: hosted - version: "6.0.22" + version: "6.1.0" url_launcher_ios: dependency: transitive description: name: url_launcher_ios - sha256: "6ba7dddee26c9fae27c9203c424631109d73c8fa26cfa7bc3e35e751cb87f62e" + sha256: "7c65021d5dee51813d652357bc65b8dd4a6177082a9966bc8ba6ee477baa795f" url: "https://pub.dev" source: hosted - version: "6.0.17" + version: "6.1.5" url_launcher_linux: dependency: transitive description: name: url_launcher_linux - sha256: "360fa359ab06bcb4f7c5cd3123a2a9a4d3364d4575d27c4b33468bd4497dd094" + sha256: b651aad005e0cb06a01dbd84b428a301916dc75f0e7ea6165f80057fee2d8e8e url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "3.0.6" url_launcher_macos: dependency: transitive description: name: url_launcher_macos - sha256: a9b3ea9043eabfaadfa3fb89de67a11210d85569086d22b3854484beab8b3978 + sha256: b55486791f666e62e0e8ff825e58a023fd6b1f71c49926483f1128d3bbd8fe88 url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "3.0.7" url_launcher_platform_interface: dependency: transitive description: name: url_launcher_platform_interface - sha256: "4eae912628763eb48fc214522e58e942fd16ce195407dbf45638239523c759a6" + sha256: "95465b39f83bfe95fcb9d174829d6476216f2d548b79c38ab2506e0458787618" url: "https://pub.dev" source: hosted - version: "2.1.1" + version: "2.1.5" url_launcher_web: dependency: transitive description: name: url_launcher_web - sha256: "5669882643b96bb6d5786637cac727c6e918a790053b09245fd4513b8a07df2a" + sha256: "2942294a500b4fa0b918685aff406773ba0a4cd34b7f42198742a94083020ce5" url: "https://pub.dev" source: hosted - version: "2.0.13" + version: "2.0.20" url_launcher_windows: dependency: transitive description: name: url_launcher_windows - sha256: e3c3b16d3104260c10eea3b0e34272aaa57921f83148b0619f74c2eced9b7ef1 + sha256: "95fef3129dc7cfaba2bc3d5ba2e16063bb561fc6d78e63eee16162bc70029069" url: "https://pub.dev" source: hosted - version: "3.0.1" + version: "3.0.8" uuid: dependency: transitive description: name: uuid - sha256: "648e103079f7c64a36dc7d39369cabb358d377078a051d6ae2ad3aa539519313" + sha256: b715b8d3858b6fa9f68f87d20d98830283628014750c2b09b6f516c1da4af2a7 url: "https://pub.dev" source: hosted - version: "3.0.7" + version: "4.1.0" + vector_graphics: + dependency: transitive + description: + name: vector_graphics + sha256: b16dadf7eb610e20da044c141b4a0199a5e8082ca21daba68322756f953ce714 + url: "https://pub.dev" + source: hosted + version: "1.1.9" + vector_graphics_codec: + dependency: transitive + description: + name: vector_graphics_codec + sha256: a4b01403d5c613db115e30e71eca33f7e9e09f2d3c52c3fb84e16333ecddc539 + url: "https://pub.dev" + source: hosted + version: "1.1.9" + vector_graphics_compiler: + dependency: transitive + description: + name: vector_graphics_compiler + sha256: d26c0e2f237476426523eb25512e4c09fa27c6d33ed659a0e69d79e20b5dc47f + url: "https://pub.dev" + source: hosted + version: "1.1.9" vector_math: dependency: transitive description: @@ -1081,90 +1105,74 @@ packages: dependency: transitive description: name: video_player - sha256: "86b4fb9e30613ef4ff7e47367bfec4b080ab17205b7d969cd12bbebde49476b1" + sha256: "74b86e63529cf5885130c639d74cd2f9232e7c8a66cbecbddd1dcb9dbd060d1e" url: "https://pub.dev" source: hosted - version: "2.4.10" + version: "2.7.2" video_player_android: dependency: transitive description: name: video_player_android - sha256: "984388511230bac63feb53b2911a70e829fe0976b6b2213f5c579c4e0a882db3" + sha256: "3fe89ab07fdbce786e7eb25b58532d6eaf189ceddc091cb66cba712f8d9e8e55" url: "https://pub.dev" source: hosted - version: "2.3.10" + version: "2.4.10" video_player_avfoundation: dependency: transitive description: name: video_player_avfoundation - sha256: d9f7a46d6a77680adb03ec05a381025d6e890ebe636637c6c3014cc3926b97e9 + sha256: "6387c2de77763b45104256b3b00b660089be4f909ded8631457dc11bf635e38f" url: "https://pub.dev" source: hosted - version: "2.3.8" + version: "2.5.0" video_player_platform_interface: dependency: transitive description: name: video_player_platform_interface - sha256: "42bb75de5e9b79e1f20f1d95f688fac0f95beac4d89c6eb2cd421724d4432dae" + sha256: be72301bf2c0150ab35a8c34d66e5a99de525f6de1e8d27c0672b836fe48f73a url: "https://pub.dev" source: hosted - version: "6.0.1" + version: "6.2.1" video_player_web: dependency: transitive description: name: video_player_web - sha256: b649b07b8f8f553bee4a97a0a53d0fe78a70b115eafaf0105b612b32b05ddb99 + sha256: "2dd24f7ba46bfb5d070e9c795001db95e0ca5f2a3d025e98f287c10c9f0fd62f" url: "https://pub.dev" source: hosted - version: "2.0.13" - wakelock: - dependency: transitive - description: - name: wakelock - sha256: "769ecf42eb2d07128407b50cb93d7c10bd2ee48f0276ef0119db1d25cc2f87db" - url: "https://pub.dev" - source: hosted - version: "0.6.2" - wakelock_macos: - dependency: transitive - description: - name: wakelock_macos - sha256: "047c6be2f88cb6b76d02553bca5a3a3b95323b15d30867eca53a19a0a319d4cd" - url: "https://pub.dev" - source: hosted - version: "0.4.0" - wakelock_platform_interface: + version: "2.1.1" + wakelock_plus: dependency: transitive description: - name: wakelock_platform_interface - sha256: "1f4aeb81fb592b863da83d2d0f7b8196067451e4df91046c26b54a403f9de621" + name: wakelock_plus + sha256: f45a6c03aa3f8322e0a9d7f4a0482721c8789cb41d555407367650b8f9c26018 url: "https://pub.dev" source: hosted - version: "0.3.0" - wakelock_web: + version: "1.1.3" + wakelock_plus_platform_interface: dependency: transitive description: - name: wakelock_web - sha256: "1b256b811ee3f0834888efddfe03da8d18d0819317f20f6193e2922b41a501b5" + name: wakelock_plus_platform_interface + sha256: "40fabed5da06caff0796dc638e1f07ee395fb18801fbff3255a2372db2d80385" url: "https://pub.dev" source: hosted - version: "0.4.0" - wakelock_windows: + version: "1.1.0" + watcher: dependency: transitive description: - name: wakelock_windows - sha256: "857f77b3fe6ae82dd045455baa626bc4b93cb9bb6c86bf3f27c182167c3a5567" + name: watcher + sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8" url: "https://pub.dev" source: hosted - version: "0.2.1" - watcher: + version: "1.1.0" + web: dependency: transitive description: - name: watcher - sha256: "6a7f46926b01ce81bfc339da6a7f20afbe7733eff9846f6d6a5466aa4c6667c0" + name: web + sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10 url: "https://pub.dev" source: hosted - version: "1.0.2" + version: "0.1.4-beta" web_socket_channel: dependency: transitive description: @@ -1177,66 +1185,66 @@ packages: dependency: transitive description: name: webview_flutter - sha256: "392c1d83b70fe2495de3ea2c84531268d5b8de2de3f01086a53334d8b6030a88" + sha256: c1ab9b81090705c6069197d9fdc1625e587b52b8d70cdde2339d177ad0dbb98e url: "https://pub.dev" source: hosted - version: "3.0.4" + version: "4.4.1" webview_flutter_android: dependency: transitive description: name: webview_flutter_android - sha256: "8b3b2450e98876c70bfcead876d9390573b34b9418c19e28168b74f6cb252dbd" + sha256: b0cd33dd7d3dd8e5f664e11a19e17ba12c352647269921a3b568406b001f1dff url: "https://pub.dev" source: hosted - version: "2.10.4" + version: "3.12.0" webview_flutter_platform_interface: dependency: transitive description: name: webview_flutter_platform_interface - sha256: "812165e4e34ca677bdfbfa58c01e33b27fd03ab5fa75b70832d4b7d4ca1fa8cf" + sha256: "6d9213c65f1060116757a7c473247c60f3f7f332cac33dc417c9e362a9a13e4f" url: "https://pub.dev" source: hosted - version: "1.9.5" + version: "2.6.0" webview_flutter_wkwebview: dependency: transitive description: name: webview_flutter_wkwebview - sha256: a5364369c758892aa487cbf59ea41d9edd10f9d9baf06a94e80f1bd1b4c7bbc0 + sha256: "30b9af6bdd457b44c08748b9190d23208b5165357cc2eb57914fee1366c42974" url: "https://pub.dev" source: hosted - version: "2.9.5" + version: "3.9.1" win32: dependency: transitive description: name: win32 - sha256: c9ebe7ee4ab0c2194e65d3a07d8c54c5d00bb001b76081c4a04cdb8448b59e46 + sha256: "350a11abd2d1d97e0cc7a28a81b781c08002aa2864d9e3f192ca0ffa18b06ed3" url: "https://pub.dev" source: hosted - version: "3.1.3" + version: "5.0.9" xdg_directories: dependency: transitive description: name: xdg_directories - sha256: "11541eedefbcaec9de35aa82650b695297ce668662bbd6e3911a7fabdbde589f" + sha256: "589ada45ba9e39405c198fe34eb0f607cddb2108527e658136120892beac46d2" url: "https://pub.dev" source: hosted - version: "0.2.0+2" + version: "1.0.3" xml: dependency: transitive description: name: xml - sha256: ac0e3f4bf00ba2708c33fbabbbe766300e509f8c82dbd4ab6525039813f7e2fb + sha256: "5bc72e1e45e941d825fd7468b9b4cc3b9327942649aeb6fc5cdbf135f0a86e84" url: "https://pub.dev" source: hosted - version: "6.1.0" + version: "6.3.0" yaml: dependency: transitive description: name: yaml - sha256: "23812a9b125b48d4007117254bca50abb6c712352927eece9e155207b1db2370" + sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5" url: "https://pub.dev" source: hosted - version: "3.1.1" + version: "3.1.2" sdks: - dart: ">=2.19.0 <3.0.0" - flutter: ">=3.3.0" + dart: ">=3.1.0 <4.0.0" + flutter: ">=3.13.0" diff --git a/pubspec.yaml b/pubspec.yaml index 7433cde..481144c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,37 +1,39 @@ name: hans_wehr_dictionary description: A new Flutter project. -publish_to: 'none' # Remove this line if you wish to publish to pub.dev +publish_to: "none" # Remove this line if you wish to publish to pub.dev -version: 1.14.2+57 +version: 1.15.1+60 environment: - sdk: '>=2.16.0 <3.0.0' - + sdk: ">=2.16.0 <3.0.0" + dependencies: flutter: sdk: flutter - path: ^1.8.2 - http: ^0.13.4 - material_floating_search_bar: ^0.3.7 - provider: ^6.0.2 + path: ^1.8.3 + http: ^1.1.0 + material_floating_search_bar_2: ^0.5.0 + provider: ^6.0.5 implicitly_animated_reorderable_list_2: ^0.5.1 - flutter_widget_from_html: ^0.9.0+1 - url_launcher: ^6.1.2 - cupertino_icons: ^1.0.4 - shared_preferences: ^2.0.15 - share_plus: ^6.3.0 - get_it: ^7.2.0 - in_app_review: ^2.0.3 + flutter_widget_from_html: ^0.14.4 + url_launcher: ^6.1.14 + cupertino_icons: ^1.0.6 + shared_preferences: ^2.2.2 + share_plus: ^7.2.1 + get_it: ^7.6.4 + in_app_review: ^2.0.8 flutter_colorpicker: ^1.0.3 - sqflite_common_ffi: ^2.2.5 + sqflite_common_ffi: ^2.3.0+2 + html: ^0.15.4 dev_dependencies: - flutter_launcher_icons: ^0.11.0 + flutter_launcher_icons: ^0.13.1 flutter_test: sdk: flutter - build_runner: ^1.3.1 - + build_runner: ^2.4.6 + flutter_lints: ^3.0.0 + flutter_icons: # ios: true # android: true @@ -49,6 +51,6 @@ flutter: assets: - assets/ fonts: - - family: Amiri - fonts: - - asset: fonts/Amiri-Regular.ttf \ No newline at end of file + - family: Amiri + fonts: + - asset: fonts/Amiri-Regular.ttf diff --git a/test/widget_test.dart b/test/widget_test.dart deleted file mode 100644 index 0e6de0f..0000000 --- a/test/widget_test.dart +++ /dev/null @@ -1,30 +0,0 @@ -// This is a basic Flutter widget test. -// -// To perform an interaction with a widget in your test, use the WidgetTester -// utility that Flutter provides. For example, you can send tap and scroll -// gestures. You can also use WidgetTester to find child widgets in the widget -// tree, read text, and verify that the values of widget properties are correct. - -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; - -import 'package:hans_wehr_dictionary/main.dart'; - -void main() { - testWidgets('Counter increments smoke test', (WidgetTester tester) async { - // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); - - // Verify that our counter starts at 0. - expect(find.text('0'), findsOneWidget); - expect(find.text('1'), findsNothing); - - // Tap the '+' icon and trigger a frame. - await tester.tap(find.byIcon(Icons.add)); - await tester.pump(); - - // Verify that our counter has incremented. - expect(find.text('0'), findsNothing); - expect(find.text('1'), findsOneWidget); - }); -} diff --git a/web/favicon.png b/web/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..8aaa46ac1ae21512746f852a42ba87e4165dfdd1 GIT binary patch literal 917 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|I14-?iy0X7 zltGxWVyS%@P(fs7NJL45ua8x7ey(0(N`6wRUPW#JP&EUCO@$SZnVVXYs8ErclUHn2 zVXFjIVFhG^g!Ppaz)DK8ZIvQ?0~DO|i&7O#^-S~(l1AfjnEK zjFOT9D}DX)@^Za$W4-*MbbUihOG|wNBYh(yU7!lx;>x^|#0uTKVr7USFmqf|i<65o z3raHc^AtelCMM;Vme?vOfh>Xph&xL%(-1c06+^uR^q@XSM&D4+Kp$>4P^%3{)XKjo zGZknv$b36P8?Z_gF{nK@`XI}Z90TzwSQO}0J1!f2c(B=V`5aP@1P1a|PZ!4!3&Gl8 zTYqUsf!gYFyJnXpu0!n&N*SYAX-%d(5gVjrHJWqXQshj@!Zm{!01WsQrH~9=kTxW#6SvuapgMqt>$=j#%eyGrQzr zP{L-3gsMA^$I1&gsBAEL+vxi1*Igl=8#8`5?A-T5=z-sk46WA1IUT)AIZHx1rdUrf zVJrJn<74DDw`j)Ki#gt}mIT-Q`XRa2-jQXQoI%w`nb|XblvzK${ZzlV)m-XcwC(od z71_OEC5Bt9GEXosOXaPTYOia#R4ID2TiU~`zVMl08TV_C%DnU4^+HE>9(CE4D6?Fz oujB08i7adh9xk7*FX66dWH6F5TM;?E2b5PlUHx3vIVCg!0Dx9vYXATM literal 0 HcmV?d00001 diff --git a/web/icons/Icon-192.png b/web/icons/Icon-192.png new file mode 100644 index 0000000000000000000000000000000000000000..b749bfef07473333cf1dd31e9eed89862a5d52aa GIT binary patch literal 5292 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 literal 0 HcmV?d00001 diff --git a/web/icons/Icon-512.png b/web/icons/Icon-512.png new file mode 100644 index 0000000000000000000000000000000000000000..88cfd48dff1169879ba46840804b412fe02fefd6 GIT binary patch literal 8252 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 literal 0 HcmV?d00001 diff --git a/web/icons/Icon-maskable-192.png b/web/icons/Icon-maskable-192.png new file mode 100644 index 0000000000000000000000000000000000000000..eb9b4d76e525556d5d89141648c724331630325d GIT binary patch literal 5594 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 X>c!)3PgKfL&lX^$Z>Cpu&6)6jvi^Z! literal 0 HcmV?d00001 diff --git a/web/icons/Icon-maskable-512.png b/web/icons/Icon-maskable-512.png new file mode 100644 index 0000000000000000000000000000000000000000..d69c56691fbdb0b7efa65097c7cc1edac12a6d3e GIT binary patch literal 20998 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 MPgg&ebxsLQ025IeI{*Lx literal 0 HcmV?d00001 diff --git a/web/index.html b/web/index.html new file mode 100644 index 0000000..6be9426 --- /dev/null +++ b/web/index.html @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + hans_wehr + + + + + + + + + + diff --git a/web/manifest.json b/web/manifest.json new file mode 100644 index 0000000..ddb4363 --- /dev/null +++ b/web/manifest.json @@ -0,0 +1,35 @@ +{ + "name": "hans_wehr", + "short_name": "hans_wehr", + "start_url": ".", + "display": "standalone", + "background_color": "#0175C2", + "theme_color": "#0175C2", + "description": "A new Flutter project.", + "orientation": "portrait-primary", + "prefer_related_applications": false, + "icons": [ + { + "src": "icons/Icon-192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "icons/Icon-512.png", + "sizes": "512x512", + "type": "image/png" + }, + { + "src": "icons/Icon-maskable-192.png", + "sizes": "192x192", + "type": "image/png", + "purpose": "maskable" + }, + { + "src": "icons/Icon-maskable-512.png", + "sizes": "512x512", + "type": "image/png", + "purpose": "maskable" + } + ] +} diff --git a/windows/CMakeLists.txt b/windows/CMakeLists.txt index 888679f..65dac9b 100644 --- a/windows/CMakeLists.txt +++ b/windows/CMakeLists.txt @@ -8,7 +8,7 @@ set(BINARY_NAME "hans_wehr_dictionary") # Explicitly opt in to modern CMake behaviors to avoid warnings with recent # versions of CMake. -cmake_policy(SET CMP0063 NEW) +cmake_policy(VERSION 3.14...3.25) # Define build configuration option. get_property(IS_MULTICONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) @@ -52,6 +52,7 @@ add_subdirectory(${FLUTTER_MANAGED_DIR}) # Application build; see runner/CMakeLists.txt. add_subdirectory("runner") + # Generated plugin build rules, which manage building the plugins and adding # them to the application. include(flutter/generated_plugins.cmake) diff --git a/windows/runner/flutter_window.cpp b/windows/runner/flutter_window.cpp index b25e363..955ee30 100644 --- a/windows/runner/flutter_window.cpp +++ b/windows/runner/flutter_window.cpp @@ -31,6 +31,11 @@ bool FlutterWindow::OnCreate() { this->Show(); }); + // Flutter can complete the first frame before the "show window" callback is + // registered. The following call ensures a frame is pending to ensure the + // window is shown. It is a no-op if the first frame hasn't completed yet. + flutter_controller_->ForceRedraw(); + return true; } diff --git a/windows/runner/utils.cpp b/windows/runner/utils.cpp index f5bf9fa..b2b0873 100644 --- a/windows/runner/utils.cpp +++ b/windows/runner/utils.cpp @@ -47,16 +47,17 @@ std::string Utf8FromUtf16(const wchar_t* utf16_string) { } int target_length = ::WideCharToMultiByte( CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, - -1, nullptr, 0, nullptr, nullptr); + -1, nullptr, 0, nullptr, nullptr) + -1; // remove the trailing null character + int input_length = (int)wcslen(utf16_string); std::string utf8_string; - if (target_length == 0 || target_length > utf8_string.max_size()) { + if (target_length <= 0 || target_length > utf8_string.max_size()) { return utf8_string; } utf8_string.resize(target_length); int converted_length = ::WideCharToMultiByte( CP_UTF8, WC_ERR_INVALID_CHARS, utf16_string, - -1, utf8_string.data(), - target_length, nullptr, nullptr); + input_length, utf8_string.data(), target_length, nullptr, nullptr); if (converted_length == 0) { return std::string(); } diff --git a/windows/runner/win32_window.cpp b/windows/runner/win32_window.cpp index 041a385..60608d0 100644 --- a/windows/runner/win32_window.cpp +++ b/windows/runner/win32_window.cpp @@ -60,7 +60,7 @@ class WindowClassRegistrar { public: ~WindowClassRegistrar() = default; - // Returns the singleton registar instance. + // Returns the singleton registrar instance. static WindowClassRegistrar* GetInstance() { if (!instance_) { instance_ = new WindowClassRegistrar(); diff --git a/windows/runner/win32_window.h b/windows/runner/win32_window.h index c86632d..e901dde 100644 --- a/windows/runner/win32_window.h +++ b/windows/runner/win32_window.h @@ -77,7 +77,7 @@ class Win32Window { // OS callback called by message pump. Handles the WM_NCCREATE message which // is passed when the non-client area is being created and enables automatic // non-client DPI scaling so that the non-client area automatically - // responsponds to changes in DPI. All other messages are handled by + // responds to changes in DPI. All other messages are handled by // MessageHandler. static LRESULT CALLBACK WndProc(HWND const window, UINT const message,