~repos /only-bible-app

#kotlin#android#ios

GIT_CONFIG_PARAMETERS="'http.version=HTTP/1.1'" git clone https://git.pyrossh.dev/only-bible-app.git
Discussions: https://groups.google.com/g/rust-embed-devs

The only bible app you will ever need. No ads. No in-app purchases. No distractions.


Files changed (44) hide show
  1. .flutter-plugins-dependencies +1 -1
  2. .gitignore +2 -16
  3. l10n.yaml +3 -2
  4. lib/app.dart +87 -83
  5. lib/dialog.dart +3 -3
  6. lib/{bible_generated.dart → gen/bible.gen.dart} +0 -0
  7. lib/{l10n → gen/l10n}/app_localizations.dart +0 -0
  8. lib/{l10n → gen/l10n}/app_localizations_bn.dart +0 -0
  9. lib/{l10n → gen/l10n}/app_localizations_en.dart +0 -0
  10. lib/{l10n → gen/l10n}/app_localizations_gu.dart +0 -0
  11. lib/{l10n → gen/l10n}/app_localizations_hi.dart +0 -0
  12. lib/{l10n → gen/l10n}/app_localizations_kn.dart +0 -0
  13. lib/{l10n → gen/l10n}/app_localizations_ml.dart +0 -0
  14. lib/{l10n → gen/l10n}/app_localizations_ne.dart +0 -0
  15. lib/{l10n → gen/l10n}/app_localizations_or.dart +0 -0
  16. lib/{l10n → gen/l10n}/app_localizations_pa.dart +0 -0
  17. lib/{l10n → gen/l10n}/app_localizations_ta.dart +0 -0
  18. lib/{l10n → gen/l10n}/app_localizations_te.dart +0 -0
  19. lib/main.dart +24 -1
  20. lib/navigation.dart +0 -231
  21. lib/screens/bible_select_screen.dart +2 -2
  22. lib/screens/book_select_screen.dart +3 -3
  23. lib/screens/chapter_select_screen.dart +2 -2
  24. lib/sheets/actions_sheet.dart +5 -5
  25. lib/sheets/highlight_sheet.dart +0 -67
  26. lib/sheets/settings_sheet.dart +8 -8
  27. lib/store/actions.dart +1 -1
  28. lib/store/app_navigator.dart +231 -0
  29. lib/store/app_state.dart +1 -1
  30. lib/utils.dart +2 -2
  31. lib/widgets/chapter_app_bar.dart +9 -18
  32. lib/widgets/verses_view.dart +6 -6
  33. pubspec.yaml +3 -3
  34. {lib/l10n → scripts/arb}/app_bn.arb +0 -0
  35. {lib/l10n → scripts/arb}/app_en.arb +0 -0
  36. {lib/l10n → scripts/arb}/app_gu.arb +0 -0
  37. {lib/l10n → scripts/arb}/app_hi.arb +0 -0
  38. {lib/l10n → scripts/arb}/app_kn.arb +0 -0
  39. {lib/l10n → scripts/arb}/app_ml.arb +0 -0
  40. {lib/l10n → scripts/arb}/app_ne.arb +0 -0
  41. {lib/l10n → scripts/arb}/app_or.arb +0 -0
  42. {lib/l10n → scripts/arb}/app_pa.arb +0 -0
  43. {lib/l10n → scripts/arb}/app_ta.arb +0 -0
  44. {lib/l10n → scripts/arb}/app_te.arb +0 -0
.flutter-plugins-dependencies CHANGED
@@ -1 +1 @@
1
- {"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"app_review","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/app_review-3.0.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"audio_session","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/audio_session-0.2.3/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"connectivity_plus","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/connectivity_plus-7.0.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"flutter_native_splash","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/flutter_native_splash-2.4.7/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"integration_test","path":"/opt/homebrew/share/flutter/packages/integration_test/","native_build":true,"dependencies":[],"dev_dependency":true},{"name":"just_audio","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/just_audio-0.10.5/","shared_darwin_source":true,"native_build":true,"dependencies":["audio_session"],"dev_dependency":false},{"name":"package_info_plus","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/package_info_plus-9.0.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"path_provider_foundation","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/path_provider_foundation-2.6.0/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"share_plus","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/share_plus-12.0.1/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_foundation","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/shared_preferences_foundation-2.5.6/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"url_launcher_ios","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/url_launcher_ios-6.4.1/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"webview_flutter_wkwebview","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/webview_flutter_wkwebview-3.24.1/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false}],"android":[{"name":"app_review","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/app_review-3.0.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"audio_session","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/audio_session-0.2.3/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"connectivity_plus","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/connectivity_plus-7.0.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"flutter_native_splash","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/flutter_native_splash-2.4.7/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"integration_test","path":"/opt/homebrew/share/flutter/packages/integration_test/","native_build":true,"dependencies":[],"dev_dependency":true},{"name":"just_audio","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/just_audio-0.10.5/","native_build":true,"dependencies":["audio_session"],"dev_dependency":false},{"name":"package_info_plus","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/package_info_plus-9.0.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"path_provider_android","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/path_provider_android-2.2.22/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"share_plus","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/share_plus-12.0.1/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_android","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/shared_preferences_android-2.4.21/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"url_launcher_android","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/url_launcher_android-6.3.28/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"webview_flutter_android","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/webview_flutter_android-4.10.13/","native_build":true,"dependencies":[],"dev_dependency":false}],"macos":[{"name":"app_review","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/app_review-3.0.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"audio_session","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/audio_session-0.2.3/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"connectivity_plus","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/connectivity_plus-7.0.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"just_audio","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/just_audio-0.10.5/","shared_darwin_source":true,"native_build":true,"dependencies":["audio_session"],"dev_dependency":false},{"name":"package_info_plus","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/package_info_plus-9.0.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"path_provider_foundation","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/path_provider_foundation-2.6.0/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"share_plus","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/share_plus-12.0.1/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_foundation","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/shared_preferences_foundation-2.5.6/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"url_launcher_macos","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/url_launcher_macos-3.2.5/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"webview_flutter_wkwebview","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/webview_flutter_wkwebview-3.24.1/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false}],"linux":[{"name":"connectivity_plus","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/connectivity_plus-7.0.0/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"package_info_plus","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/package_info_plus-9.0.0/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"path_provider_linux","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/path_provider_linux-2.2.1/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"share_plus","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/share_plus-12.0.1/","native_build":false,"dependencies":["url_launcher_linux"],"dev_dependency":false},{"name":"shared_preferences_linux","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/shared_preferences_linux-2.4.1/","native_build":false,"dependencies":["path_provider_linux"],"dev_dependency":false},{"name":"url_launcher_linux","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/url_launcher_linux-3.2.2/","native_build":true,"dependencies":[],"dev_dependency":false}],"windows":[{"name":"connectivity_plus","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/connectivity_plus-7.0.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"package_info_plus","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/package_info_plus-9.0.0/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"path_provider_windows","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/path_provider_windows-2.3.0/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"share_plus","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/share_plus-12.0.1/","native_build":true,"dependencies":["url_launcher_windows"],"dev_dependency":false},{"name":"shared_preferences_windows","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/shared_preferences_windows-2.4.1/","native_build":false,"dependencies":["path_provider_windows"],"dev_dependency":false},{"name":"url_launcher_windows","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/url_launcher_windows-3.1.5/","native_build":true,"dependencies":[],"dev_dependency":false}],"web":[{"name":"audio_session","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/audio_session-0.2.3/","dependencies":[],"dev_dependency":false},{"name":"connectivity_plus","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/connectivity_plus-7.0.0/","dependencies":[],"dev_dependency":false},{"name":"flutter_native_splash","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/flutter_native_splash-2.4.7/","dependencies":[],"dev_dependency":false},{"name":"just_audio_web","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/just_audio_web-0.4.16/","dependencies":[],"dev_dependency":false},{"name":"package_info_plus","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/package_info_plus-9.0.0/","dependencies":[],"dev_dependency":false},{"name":"share_plus","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/share_plus-12.0.1/","dependencies":["url_launcher_web"],"dev_dependency":false},{"name":"shared_preferences_web","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/shared_preferences_web-2.4.3/","dependencies":[],"dev_dependency":false},{"name":"url_launcher_web","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/url_launcher_web-2.4.2/","dependencies":[],"dev_dependency":false}]},"dependencyGraph":[{"name":"app_review","dependencies":[]},{"name":"audio_session","dependencies":[]},{"name":"connectivity_plus","dependencies":[]},{"name":"flutter_native_splash","dependencies":[]},{"name":"integration_test","dependencies":[]},{"name":"just_audio","dependencies":["just_audio_web","audio_session","path_provider"]},{"name":"just_audio_web","dependencies":[]},{"name":"package_info_plus","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_android","path_provider_foundation","path_provider_linux","path_provider_windows"]},{"name":"path_provider_android","dependencies":[]},{"name":"path_provider_foundation","dependencies":[]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"share_plus","dependencies":["url_launcher_web","url_launcher_windows","url_launcher_linux"]},{"name":"shared_preferences","dependencies":["shared_preferences_android","shared_preferences_foundation","shared_preferences_linux","shared_preferences_web","shared_preferences_windows"]},{"name":"shared_preferences_android","dependencies":[]},{"name":"shared_preferences_foundation","dependencies":[]},{"name":"shared_preferences_linux","dependencies":["path_provider_linux"]},{"name":"shared_preferences_web","dependencies":[]},{"name":"shared_preferences_windows","dependencies":["path_provider_windows"]},{"name":"url_launcher","dependencies":["url_launcher_android","url_launcher_ios","url_launcher_linux","url_launcher_macos","url_launcher_web","url_launcher_windows"]},{"name":"url_launcher_android","dependencies":[]},{"name":"url_launcher_ios","dependencies":[]},{"name":"url_launcher_linux","dependencies":[]},{"name":"url_launcher_macos","dependencies":[]},{"name":"url_launcher_web","dependencies":[]},{"name":"url_launcher_windows","dependencies":[]},{"name":"webview_flutter","dependencies":["webview_flutter_android","webview_flutter_wkwebview"]},{"name":"webview_flutter_android","dependencies":[]},{"name":"webview_flutter_wkwebview","dependencies":[]}],"date_created":"2026-03-22 15:10:29.334091","version":"3.41.4","swift_package_manager_enabled":{"ios":false,"macos":false}}
1
+ {"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"app_review","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/app_review-3.0.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"audio_session","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/audio_session-0.2.3/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"connectivity_plus","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/connectivity_plus-7.0.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"flutter_native_splash","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/flutter_native_splash-2.4.7/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"integration_test","path":"/opt/homebrew/share/flutter/packages/integration_test/","native_build":true,"dependencies":[],"dev_dependency":true},{"name":"just_audio","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/just_audio-0.10.5/","shared_darwin_source":true,"native_build":true,"dependencies":["audio_session"],"dev_dependency":false},{"name":"package_info_plus","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/package_info_plus-9.0.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"path_provider_foundation","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/path_provider_foundation-2.6.0/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"share_plus","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/share_plus-12.0.1/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_foundation","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/shared_preferences_foundation-2.5.6/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"url_launcher_ios","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/url_launcher_ios-6.4.1/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"webview_flutter_wkwebview","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/webview_flutter_wkwebview-3.24.1/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false}],"android":[{"name":"app_review","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/app_review-3.0.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"audio_session","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/audio_session-0.2.3/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"connectivity_plus","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/connectivity_plus-7.0.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"flutter_native_splash","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/flutter_native_splash-2.4.7/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"integration_test","path":"/opt/homebrew/share/flutter/packages/integration_test/","native_build":true,"dependencies":[],"dev_dependency":true},{"name":"just_audio","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/just_audio-0.10.5/","native_build":true,"dependencies":["audio_session"],"dev_dependency":false},{"name":"package_info_plus","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/package_info_plus-9.0.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"path_provider_android","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/path_provider_android-2.2.22/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"share_plus","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/share_plus-12.0.1/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_android","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/shared_preferences_android-2.4.21/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"url_launcher_android","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/url_launcher_android-6.3.28/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"webview_flutter_android","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/webview_flutter_android-4.10.13/","native_build":true,"dependencies":[],"dev_dependency":false}],"macos":[{"name":"app_review","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/app_review-3.0.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"audio_session","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/audio_session-0.2.3/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"connectivity_plus","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/connectivity_plus-7.0.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"just_audio","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/just_audio-0.10.5/","shared_darwin_source":true,"native_build":true,"dependencies":["audio_session"],"dev_dependency":false},{"name":"package_info_plus","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/package_info_plus-9.0.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"path_provider_foundation","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/path_provider_foundation-2.6.0/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"share_plus","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/share_plus-12.0.1/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"shared_preferences_foundation","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/shared_preferences_foundation-2.5.6/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false},{"name":"url_launcher_macos","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/url_launcher_macos-3.2.5/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"webview_flutter_wkwebview","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/webview_flutter_wkwebview-3.24.1/","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false}],"linux":[{"name":"connectivity_plus","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/connectivity_plus-7.0.0/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"package_info_plus","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/package_info_plus-9.0.0/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"path_provider_linux","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/path_provider_linux-2.2.1/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"share_plus","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/share_plus-12.0.1/","native_build":false,"dependencies":["url_launcher_linux"],"dev_dependency":false},{"name":"shared_preferences_linux","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/shared_preferences_linux-2.4.1/","native_build":false,"dependencies":["path_provider_linux"],"dev_dependency":false},{"name":"url_launcher_linux","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/url_launcher_linux-3.2.2/","native_build":true,"dependencies":[],"dev_dependency":false}],"windows":[{"name":"connectivity_plus","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/connectivity_plus-7.0.0/","native_build":true,"dependencies":[],"dev_dependency":false},{"name":"package_info_plus","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/package_info_plus-9.0.0/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"path_provider_windows","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/path_provider_windows-2.3.0/","native_build":false,"dependencies":[],"dev_dependency":false},{"name":"share_plus","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/share_plus-12.0.1/","native_build":true,"dependencies":["url_launcher_windows"],"dev_dependency":false},{"name":"shared_preferences_windows","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/shared_preferences_windows-2.4.1/","native_build":false,"dependencies":["path_provider_windows"],"dev_dependency":false},{"name":"url_launcher_windows","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/url_launcher_windows-3.1.5/","native_build":true,"dependencies":[],"dev_dependency":false}],"web":[{"name":"audio_session","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/audio_session-0.2.3/","dependencies":[],"dev_dependency":false},{"name":"connectivity_plus","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/connectivity_plus-7.0.0/","dependencies":[],"dev_dependency":false},{"name":"flutter_native_splash","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/flutter_native_splash-2.4.7/","dependencies":[],"dev_dependency":false},{"name":"just_audio_web","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/just_audio_web-0.4.16/","dependencies":[],"dev_dependency":false},{"name":"package_info_plus","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/package_info_plus-9.0.0/","dependencies":[],"dev_dependency":false},{"name":"share_plus","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/share_plus-12.0.1/","dependencies":["url_launcher_web"],"dev_dependency":false},{"name":"shared_preferences_web","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/shared_preferences_web-2.4.3/","dependencies":[],"dev_dependency":false},{"name":"url_launcher_web","path":"/Users/pyrossh/.pub-cache/hosted/pub.dev/url_launcher_web-2.4.2/","dependencies":[],"dev_dependency":false}]},"dependencyGraph":[{"name":"app_review","dependencies":[]},{"name":"audio_session","dependencies":[]},{"name":"connectivity_plus","dependencies":[]},{"name":"flutter_native_splash","dependencies":[]},{"name":"integration_test","dependencies":[]},{"name":"just_audio","dependencies":["just_audio_web","audio_session","path_provider"]},{"name":"just_audio_web","dependencies":[]},{"name":"package_info_plus","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_android","path_provider_foundation","path_provider_linux","path_provider_windows"]},{"name":"path_provider_android","dependencies":[]},{"name":"path_provider_foundation","dependencies":[]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_windows","dependencies":[]},{"name":"share_plus","dependencies":["url_launcher_web","url_launcher_windows","url_launcher_linux"]},{"name":"shared_preferences","dependencies":["shared_preferences_android","shared_preferences_foundation","shared_preferences_linux","shared_preferences_web","shared_preferences_windows"]},{"name":"shared_preferences_android","dependencies":[]},{"name":"shared_preferences_foundation","dependencies":[]},{"name":"shared_preferences_linux","dependencies":["path_provider_linux"]},{"name":"shared_preferences_web","dependencies":[]},{"name":"shared_preferences_windows","dependencies":["path_provider_windows"]},{"name":"url_launcher","dependencies":["url_launcher_android","url_launcher_ios","url_launcher_linux","url_launcher_macos","url_launcher_web","url_launcher_windows"]},{"name":"url_launcher_android","dependencies":[]},{"name":"url_launcher_ios","dependencies":[]},{"name":"url_launcher_linux","dependencies":[]},{"name":"url_launcher_macos","dependencies":[]},{"name":"url_launcher_web","dependencies":[]},{"name":"url_launcher_windows","dependencies":[]},{"name":"webview_flutter","dependencies":["webview_flutter_android","webview_flutter_wkwebview"]},{"name":"webview_flutter_android","dependencies":[]},{"name":"webview_flutter_wkwebview","dependencies":[]}],"date_created":"2026-03-22 18:21:58.914600","version":"3.41.5","swift_package_manager_enabled":{"ios":false,"macos":false}}
.gitignore CHANGED
@@ -1,25 +1,11 @@
1
1
  *.iml
2
2
  .gradle
3
- .kotlin
4
- /local.properties
5
- /.idea/caches
6
- /.idea/libraries
7
- /.idea/modules.xml
8
- /.idea/workspace.xml
9
- /.idea/navEditor.xml
10
- /.idea/assetWizardSettings.xml
11
3
  .DS_Store
12
4
  /build
13
- /app/release
14
- /captures
15
- .externalNativeBuild
16
- .cxx
17
5
  local.properties
18
6
  keystore.properties
19
7
  upload-keystore.jks
20
8
  svc.json
21
9
  .dart_tool
22
- .idea
23
- composeApp
24
- target
25
- ui
10
+ ui
11
+ .flutter-plugins-dependencies
l10n.yaml CHANGED
@@ -1,3 +1,4 @@
1
- arb-dir: lib/l10n
1
+ arb-dir: scripts/arb
2
2
  template-arb-file: app_en.arb
3
- output-localization-file: app_localizations.dart
3
+ output-localization-file: app_localizations.dart
4
+ output-dir: lib/gen/l10n
lib/app.dart CHANGED
@@ -1,7 +1,8 @@
1
1
  import "package:async_redux/async_redux.dart";
2
2
  import "package:flutter/material.dart";
3
3
  import "package:go_router/go_router.dart";
4
- import "package:only_bible_app/l10n/app_localizations.dart";
4
+ import "package:only_bible_app/gen/l10n/app_localizations.dart";
5
+ import "package:only_bible_app/store/app_navigator.dart";
5
6
  import "package:only_bible_app/screens/bible_select_screen.dart";
6
7
  import "package:only_bible_app/screens/book_select_screen.dart";
7
8
  import "package:only_bible_app/screens/chapter_select_screen.dart";
@@ -20,97 +21,100 @@ class App extends StatelessWidget {
20
21
  Widget build(BuildContext context) {
21
22
  return StoreProvider<AppState>(
22
23
  store: store,
24
+ child: AppNavigatorProvider(
25
+ navigator: AppNavigator(),
23
- child: StoreConnector<AppState, _AppVm>(
26
+ child: StoreConnector<AppState, _AppVm>(
24
- vm: () => _AppVmFactory(),
27
+ vm: () => _AppVmFactory(),
25
- builder: (context, vm) => MaterialApp.router(
28
+ builder: (context, vm) => MaterialApp.router(
26
- routerConfig: GoRouter(
29
+ routerConfig: GoRouter(
27
- navigatorKey: globalNavigatorKey,
30
+ navigatorKey: globalNavigatorKey,
28
- initialLocation: context.state.firstOpen
31
+ initialLocation: context.state.firstOpen
29
- ? "/bible"
32
+ ? "/bible"
30
- : "/chapter/${Uri.encodeComponent(context.state.bibleName)}/${context.state.savedBook}/${context.state.savedChapter}",
33
+ : "/chapter/${Uri.encodeComponent(context.state.bibleName)}/${context.state.savedBook}/${context.state.savedChapter}",
31
- routes: [
34
+ routes: [
32
- GoRoute(
35
+ GoRoute(
33
- path: "/bible",
36
+ path: "/bible",
34
- pageBuilder: (context, state) => const NoTransitionPage(
37
+ pageBuilder: (context, state) => const NoTransitionPage(
35
- child: BibleSelectScreen(),
38
+ child: BibleSelectScreen(),
39
+ ),
36
40
  ),
41
+ GoRoute(
42
+ path: "/chapter/:bibleName/:bookIndex/:chapterIndex",
43
+ pageBuilder: (context, state) {
44
+ final bibleName = Uri.decodeComponent(state.pathParameters["bibleName"]!);
45
+ final bookIndex = int.parse(state.pathParameters["bookIndex"]!);
46
+ final chapterIndex = int.parse(state.pathParameters["chapterIndex"]!);
47
+ final slideDir = state.extra as TextDirection?;
48
+ if (slideDir != null) {
49
+ return CustomTransitionPage(
50
+ key: state.pageKey,
51
+ child: ChapterViewScreen(
52
+ bibleName: bibleName,
53
+ bookIndex: bookIndex,
54
+ chapterIndex: chapterIndex,
37
- ),
55
+ ),
38
- GoRoute(
39
- path: "/chapter/:bibleName/:bookIndex/:chapterIndex",
40
- pageBuilder: (context, state) {
56
+ transitionsBuilder: (context, animation, secondaryAnimation, child) {
57
+ const begin = Offset(1.0, 0.0);
58
+ const end = Offset.zero;
59
+ const curve = Curves.ease;
41
- final bibleName = Uri.decodeComponent(state.pathParameters["bibleName"]!);
60
+ final tween = Tween(begin: begin, end: end).chain(CurveTween(curve: curve));
42
- final bookIndex = int.parse(state.pathParameters["bookIndex"]!);
43
- final chapterIndex = int.parse(state.pathParameters["chapterIndex"]!);
44
- final slideDir = state.extra as TextDirection?;
45
- if (slideDir != null) {
61
+ return SlideTransition(
62
+ textDirection: slideDir,
63
+ position: animation.drive(tween),
64
+ child: child,
65
+ );
66
+ },
67
+ );
68
+ }
46
- return CustomTransitionPage(
69
+ return NoTransitionPage(
47
70
  key: state.pageKey,
48
71
  child: ChapterViewScreen(
49
72
  bibleName: bibleName,
50
73
  bookIndex: bookIndex,
51
74
  chapterIndex: chapterIndex,
52
75
  ),
53
- transitionsBuilder: (context, animation, secondaryAnimation, child) {
54
- const begin = Offset(1.0, 0.0);
55
- const end = Offset.zero;
56
- const curve = Curves.ease;
57
- final tween = Tween(begin: begin, end: end).chain(CurveTween(curve: curve));
58
- return SlideTransition(
59
- textDirection: slideDir,
60
- position: animation.drive(tween),
61
- child: child,
62
- );
63
- },
64
76
  );
65
- }
77
+ },
78
+ ),
79
+ GoRoute(
80
+ path: "/books/:bibleName",
81
+ pageBuilder: (context, state) {
82
+ final bibleName = Uri.decodeComponent(state.pathParameters["bibleName"]!);
66
- return NoTransitionPage(
83
+ return NoTransitionPage(
67
- key: state.pageKey,
68
- child: ChapterViewScreen(
69
- bibleName: bibleName,
84
+ child: BookSelectScreen(bibleName: bibleName),
85
+ );
70
- bookIndex: bookIndex,
86
+ },
71
- chapterIndex: chapterIndex,
72
- ),
87
+ ),
88
+ GoRoute(
89
+ path: "/chapters/:bibleName/:bookIndex",
90
+ pageBuilder: (context, state) {
91
+ final bibleName = Uri.decodeComponent(state.pathParameters["bibleName"]!);
92
+ final bookIndex = int.parse(state.pathParameters["bookIndex"]!);
93
+ return NoTransitionPage(
94
+ child: ChapterSelectScreen(bibleName: bibleName, bookIndex: bookIndex),
73
- );
95
+ );
74
- },
96
+ },
75
- ),
97
+ ),
76
- GoRoute(
98
+ GoRoute(
77
- path: "/books/:bibleName",
99
+ path: "/webview",
78
- pageBuilder: (context, state) {
100
+ pageBuilder: (context, state) {
79
- final bibleName = Uri.decodeComponent(state.pathParameters["bibleName"]!);
101
+ final url = state.extra as String;
80
- return NoTransitionPage(
102
+ return NoTransitionPage(
81
- child: BookSelectScreen(bibleName: bibleName),
103
+ child: WebViewScreen(url: url),
82
- );
104
+ );
83
- },
105
+ },
84
- ),
106
+ ),
85
- GoRoute(
86
- path: "/chapters/:bibleName/:bookIndex",
87
- pageBuilder: (context, state) {
88
- final bibleName = Uri.decodeComponent(state.pathParameters["bibleName"]!);
89
- final bookIndex = int.parse(state.pathParameters["bookIndex"]!);
90
- return NoTransitionPage(
91
- child: ChapterSelectScreen(bibleName: bibleName, bookIndex: bookIndex),
92
- );
93
- },
107
+ ],
94
- ),
108
+ ),
95
- GoRoute(
96
- path: "/webview",
97
- pageBuilder: (context, state) {
109
+ onGenerateTitle: (context) => context.l.title,
98
- final url = state.extra as String;
110
+ localizationsDelegates: AppLocalizations.localizationsDelegates,
111
+ supportedLocales: AppLocalizations.supportedLocales,
99
- return NoTransitionPage(
112
+ debugShowCheckedModeBanner: false,
113
+ themeMode: vm.darkMode ? ThemeMode.dark : ThemeMode.light,
114
+ theme: lightTheme,
115
+ darkTheme: darkTheme,
100
- child: WebViewScreen(url: url),
116
+ locale: Locale(vm.languageCode),
101
- );
102
- },
103
- ),
104
- ],
105
117
  ),
106
- onGenerateTitle: (context) => context.l.title,
107
- localizationsDelegates: AppLocalizations.localizationsDelegates,
108
- supportedLocales: AppLocalizations.supportedLocales,
109
- debugShowCheckedModeBanner: false,
110
- themeMode: vm.darkMode ? ThemeMode.dark : ThemeMode.light,
111
- theme: lightTheme,
112
- darkTheme: darkTheme,
113
- locale: Locale(vm.languageCode),
114
118
  ),
115
119
  ),
116
120
  );
lib/dialog.dart CHANGED
@@ -1,7 +1,7 @@
1
1
  import "dart:ui";
2
2
  import "package:flutter/material.dart";
3
3
  import "package:only_bible_app/utils.dart";
4
- import "package:only_bible_app/navigation.dart";
4
+ import "package:only_bible_app/store/app_navigator.dart";
5
5
 
6
6
  void showAlert(BuildContext context, String title, String message) {
7
7
  showDialog(
@@ -50,13 +50,13 @@ void showReportError(BuildContext context, String message, StackTrace? st) {
50
50
  TextButton(
51
51
  onPressed: () {
52
52
  recordError(message, st);
53
- changeBible(context);
53
+ context.nav.changeBible(context);
54
54
  },
55
55
  child: const Text("Yes"),
56
56
  ),
57
57
  TextButton(
58
58
  onPressed: () {
59
- changeBible(context);
59
+ context.nav.changeBible(context);
60
60
  },
61
61
  child: const Text("No"),
62
62
  ),
lib/{bible_generated.dart → gen/bible.gen.dart} RENAMED
File without changes
lib/{l10n → gen/l10n}/app_localizations.dart RENAMED
File without changes
lib/{l10n → gen/l10n}/app_localizations_bn.dart RENAMED
File without changes
lib/{l10n → gen/l10n}/app_localizations_en.dart RENAMED
File without changes
lib/{l10n → gen/l10n}/app_localizations_gu.dart RENAMED
File without changes
lib/{l10n → gen/l10n}/app_localizations_hi.dart RENAMED
File without changes
lib/{l10n → gen/l10n}/app_localizations_kn.dart RENAMED
File without changes
lib/{l10n → gen/l10n}/app_localizations_ml.dart RENAMED
File without changes
lib/{l10n → gen/l10n}/app_localizations_ne.dart RENAMED
File without changes
lib/{l10n → gen/l10n}/app_localizations_or.dart RENAMED
File without changes
lib/{l10n → gen/l10n}/app_localizations_pa.dart RENAMED
File without changes
lib/{l10n → gen/l10n}/app_localizations_ta.dart RENAMED
File without changes
lib/{l10n → gen/l10n}/app_localizations_te.dart RENAMED
File without changes
lib/main.dart CHANGED
@@ -1,4 +1,5 @@
1
1
  import "package:flutter/material.dart";
2
+ import "package:flutter/services.dart";
2
3
  import "package:flutter/foundation.dart";
3
4
  import "package:flutter/scheduler.dart";
4
5
  import "package:flutter_azure_tts/flutter_azure_tts.dart";
@@ -7,11 +8,33 @@ import "package:flutter_native_splash/flutter_native_splash.dart";
7
8
  import "package:async_redux/async_redux.dart";
8
9
  import "package:only_bible_app/app.dart";
9
10
  import "package:only_bible_app/dialog.dart";
10
- import "package:only_bible_app/navigation.dart";
11
+ import "package:only_bible_app/store/app_navigator.dart";
11
12
  import "package:only_bible_app/store/actions.dart";
12
13
  import "package:only_bible_app/store/app_persistor.dart";
13
14
  import "package:only_bible_app/store/app_state.dart";
14
15
 
16
+ void updateStatusBar(bool v) {
17
+ if (v) {
18
+ SystemChrome.setSystemUIOverlayStyle(
19
+ const SystemUiOverlayStyle(
20
+ systemNavigationBarColor: Color(0xFF1F1F22),
21
+ statusBarColor: Color(0xFF1F1F22),
22
+ systemNavigationBarIconBrightness: Brightness.light,
23
+ statusBarIconBrightness: Brightness.light,
24
+ ),
25
+ );
26
+ } else {
27
+ SystemChrome.setSystemUIOverlayStyle(
28
+ const SystemUiOverlayStyle(
29
+ systemNavigationBarColor: Colors.white,
30
+ statusBarColor: Colors.white,
31
+ systemNavigationBarIconBrightness: Brightness.dark,
32
+ statusBarIconBrightness: Brightness.dark,
33
+ ),
34
+ );
35
+ }
36
+ }
37
+
15
38
  void main() async {
16
39
  final globalNavigatorKey = GlobalKey<NavigatorState>();
17
40
  final persistor = AppPersistor();
lib/navigation.dart DELETED
@@ -1,231 +0,0 @@
1
- import "package:flutter/material.dart";
2
- import "package:flutter/services.dart";
3
- import "package:app_review/app_review.dart";
4
- import "package:go_router/go_router.dart";
5
- import "package:only_bible_app/bible_generated.dart";
6
- import "package:only_bible_app/sheets/actions_sheet.dart";
7
- import "package:only_bible_app/sheets/settings_sheet.dart";
8
- import "package:only_bible_app/store/actions.dart";
9
- import "package:only_bible_app/store/app_state.dart";
10
- import "package:only_bible_app/utils.dart";
11
- import "package:share_plus/share_plus.dart";
12
-
13
- String _chapterPath(String bibleName, int book, int chapter) {
14
- return "/chapter/${Uri.encodeComponent(bibleName)}/$book/$chapter";
15
- }
16
-
17
- void updateStatusBar(bool v) {
18
- if (v) {
19
- SystemChrome.setSystemUIOverlayStyle(
20
- const SystemUiOverlayStyle(
21
- systemNavigationBarColor: Color(0xFF1F1F22),
22
- statusBarColor: Color(0xFF1F1F22),
23
- systemNavigationBarIconBrightness: Brightness.light,
24
- statusBarIconBrightness: Brightness.light,
25
- ),
26
- );
27
- } else {
28
- SystemChrome.setSystemUIOverlayStyle(
29
- const SystemUiOverlayStyle(
30
- systemNavigationBarColor: Colors.white,
31
- statusBarColor: Colors.white,
32
- systemNavigationBarIconBrightness: Brightness.dark,
33
- statusBarIconBrightness: Brightness.dark,
34
- ),
35
- );
36
- }
37
- }
38
-
39
- void pushBookChapter(
40
- BuildContext context,
41
- String bibleName,
42
- int book,
43
- int chapter,
44
- TextDirection? dir,
45
- ) {
46
- context.dispatch(UpdateChapterAction(book, chapter));
47
- if (context.state.isPlaying) {
48
- AppState.player.pause();
49
- context.dispatch(SetPlayingAction(false));
50
- }
51
- hideActions(context);
52
- context.push(_chapterPath(bibleName, book, chapter), extra: dir);
53
- }
54
-
55
- void replaceBookChapter(
56
- BuildContext context,
57
- String bibleName,
58
- int book,
59
- int chapter,
60
- ) {
61
- context.dispatch(UpdateChapterAction(book, chapter));
62
- if (context.state.isPlaying) {
63
- AppState.player.pause();
64
- context.dispatch(SetPlayingAction(false));
65
- }
66
- hideActions(context);
67
- context.go(_chapterPath(bibleName, book, chapter));
68
- }
69
-
70
- void nextChapter(BuildContext context, Bible bible, int book, int chapter) {
71
- final selectedBook = bible.books![book];
72
- if (selectedBook.chapters!.length > chapter + 1) {
73
- pushBookChapter(
74
- context,
75
- bible.name!,
76
- selectedBook.index,
77
- chapter + 1,
78
- TextDirection.ltr,
79
- );
80
- } else {
81
- if (selectedBook.index + 1 < bible.books!.length) {
82
- final nextBook = bible.books![selectedBook.index + 1];
83
- pushBookChapter(
84
- context,
85
- bible.name!,
86
- nextBook.index,
87
- 0,
88
- TextDirection.ltr,
89
- );
90
- }
91
- }
92
- }
93
-
94
- void previousChapter(BuildContext context, Bible bible, int book, int chapter) {
95
- final selectedBook = bible.books![book];
96
- if (chapter - 1 >= 0) {
97
- pushBookChapter(
98
- context,
99
- bible.name!,
100
- selectedBook.index,
101
- chapter - 1,
102
- TextDirection.rtl,
103
- );
104
- } else {
105
- if (selectedBook.index - 1 >= 0) {
106
- final prevBook = bible.books![selectedBook.index - 1];
107
- pushBookChapter(
108
- context,
109
- bible.name!,
110
- prevBook.index,
111
- prevBook.chapters!.length - 1,
112
- TextDirection.rtl,
113
- );
114
- }
115
- }
116
- }
117
-
118
- void showAboutUs(BuildContext context) {
119
- context.push("/webview", extra: "https://onlybible.app/about-us");
120
- }
121
-
122
- void showPrivacyPolicy(BuildContext context) {
123
- context.push("/webview", extra: "https://onlybible.app/privacy-policy");
124
- }
125
-
126
- void showTermsAndConditions(BuildContext context) {
127
- context.push("/webview", extra: "https://onlybible.app/terms-and-conditions");
128
- }
129
-
130
- void changeBible(BuildContext context) {
131
- context.go("/bible");
132
- }
133
-
134
- void changeBibleFromHeader(BuildContext context) {
135
- context.push("/bible");
136
- }
137
-
138
- void changeBook(BuildContext context, Bible bible) {
139
- context.push("/books/${Uri.encodeComponent(bible.name!)}");
140
- }
141
-
142
- void changeChapter(BuildContext context, Bible bible, Book book, int index) {
143
- context.push("/chapters/${Uri.encodeComponent(bible.name!)}/${book.index}");
144
- }
145
-
146
- Future<void> updateCurrentBible(
147
- BuildContext context,
148
- String name,
149
- String code,
150
- int book,
151
- int chapter,
152
- ) async {
153
- hideActions(context);
154
- await context.dispatchAndWait(UpdateBibleAction(name, code));
155
- await context.dispatchAndWait(LoadBibleAction());
156
- context.go(_chapterPath(name, book, chapter));
157
- }
158
-
159
- void shareAppLink(BuildContext context) {
160
- if (isAndroid()) {
161
- Share.share(
162
- subject: "Only Bible App",
163
- "https://play.google.com/store/apps/details?id=sh.pyros.only_bible_app",
164
- );
165
- } else {
166
- Share.share(
167
- subject: "Only Bible App",
168
- "https://apps.apple.com/us/app/only-bible-app/id6467606465",
169
- );
170
- }
171
- }
172
-
173
- Future<void> rateApp(BuildContext context) async {
174
- AppReview.requestReview;
175
- }
176
-
177
- Future<void> shareVerses(BuildContext context, Bible bible, List<Verse> verses) async {
178
- final name = context.bookNames[verses.first.book];
179
- final chapter = verses.first.chapter + 1;
180
- final items = verses.sortedBy((e) => e.index).map((e) => e.index + 1);
181
- final versesThrough = items.length >= 3 ? "${items.first}-${items.last}" : items.join(",");
182
- final version = context.currentLang.languageCode == "en" ? "KJV" : "";
183
- final title = "$name $chapter:$versesThrough $version";
184
- final text = verses.map((e) => e.text ?? "").join("\n");
185
- await SharePlus.instance.share(
186
- ShareParams(
187
- title: title,
188
- subject: title,
189
- text: "$title\n$text",
190
- ),
191
- );
192
- hideActions(context);
193
- }
194
-
195
- void showSettings(BuildContext context, Bible bible) {
196
- showModalBottomSheet(
197
- context: context,
198
- isDismissible: true,
199
- enableDrag: true,
200
- showDragHandle: true,
201
- useSafeArea: true,
202
- builder: (context) => SettingsSheet(bible: bible),
203
- );
204
- }
205
-
206
- OverlayEntry? _actionsOverlay;
207
-
208
- void showActions(BuildContext context, Bible bible) {
209
- _actionsOverlay?.remove();
210
- _actionsOverlay = null;
211
- final overlay = Overlay.of(context);
212
- _actionsOverlay = OverlayEntry(
213
- builder: (context) {
214
- final bottomPadding = MediaQuery.of(context).padding.bottom;
215
- return Align(
216
- alignment: Alignment.bottomCenter,
217
- child: Padding(
218
- padding: EdgeInsets.only(bottom: bottomPadding + 40, left: 20, right: 20),
219
- child: ActionsSheet(bible: bible),
220
- ),
221
- );
222
- },
223
- );
224
- overlay.insert(_actionsOverlay!);
225
- }
226
-
227
- void hideActions(BuildContext context) {
228
- _actionsOverlay?.remove();
229
- _actionsOverlay = null;
230
- context.dispatch(ClearSelectedVersesAction());
231
- }
lib/screens/bible_select_screen.dart CHANGED
@@ -1,5 +1,5 @@
1
1
  import "package:flutter/material.dart";
2
- import "package:only_bible_app/navigation.dart";
2
+ import "package:only_bible_app/store/app_navigator.dart";
3
3
  import "package:only_bible_app/store/actions.dart";
4
4
  import "package:only_bible_app/utils.dart";
5
5
  import "package:only_bible_app/widgets/scaffold_menu.dart";
@@ -37,7 +37,7 @@ class BibleSelectScreen extends StatelessWidget {
37
37
  if (context.state.firstOpen) {
38
38
  context.dispatch(FirstOpenDoneAction());
39
39
  }
40
- updateCurrentBible(
40
+ context.nav.updateCurrentBible(
41
41
  context,
42
42
  l.languageTitle,
43
43
  l.localeName,
lib/screens/book_select_screen.dart CHANGED
@@ -1,11 +1,11 @@
1
1
  import "package:flutter/material.dart";
2
2
  import "package:go_router/go_router.dart";
3
- import "package:only_bible_app/navigation.dart";
3
+ import "package:only_bible_app/store/app_navigator.dart";
4
4
  import "package:only_bible_app/utils.dart";
5
5
  import "package:only_bible_app/widgets/scaffold_menu.dart";
6
6
  import "package:only_bible_app/widgets/sliver_heading.dart";
7
7
  import "package:only_bible_app/widgets/sliver_tile_grid.dart";
8
- import "package:only_bible_app/bible_generated.dart";
8
+ import "package:only_bible_app/gen/bible.gen.dart";
9
9
 
10
10
  class BookSelectScreen extends StatelessWidget {
11
11
  final String bibleName;
@@ -15,7 +15,7 @@ class BookSelectScreen extends StatelessWidget {
15
15
  dynamic onBookSelected(BuildContext context, Bible bible, int index) {
16
16
  final book = bible.books![index];
17
17
  if (book.chapters!.length == 1) {
18
- return replaceBookChapter(context, bible.name!, index, 0);
18
+ return context.nav.replaceBookChapter(context, bible.name!, index, 0);
19
19
  }
20
20
  context.go("/chapters/${Uri.encodeComponent(bible.name!)}/${book.index}");
21
21
  }
lib/screens/chapter_select_screen.dart CHANGED
@@ -1,5 +1,5 @@
1
1
  import "package:flutter/material.dart";
2
- import "package:only_bible_app/navigation.dart";
2
+ import "package:only_bible_app/store/app_navigator.dart";
3
3
  import "package:only_bible_app/utils.dart";
4
4
  import "package:only_bible_app/widgets/scaffold_menu.dart";
5
5
  import "package:only_bible_app/widgets/sliver_tile_grid.dart";
@@ -30,7 +30,7 @@ class ChapterSelectScreen extends StatelessWidget {
30
30
  children: List.generate(book.chapters!.length, (index) {
31
31
  return TextButton(
32
32
  child: Text("${index + 1}"),
33
- onPressed: () => replaceBookChapter(context, bible.name!, bookIndex, index),
33
+ onPressed: () => context.nav.replaceBookChapter(context, bible.name!, bookIndex, index),
34
34
  );
35
35
  }),
36
36
  ),
lib/sheets/actions_sheet.dart CHANGED
@@ -1,6 +1,6 @@
1
1
  import "package:flutter/material.dart";
2
- import "package:only_bible_app/bible_generated.dart";
3
- import "package:only_bible_app/navigation.dart";
2
+ import "package:only_bible_app/gen/bible.gen.dart";
3
+ import "package:only_bible_app/store/app_navigator.dart";
4
4
  import "package:only_bible_app/store/actions.dart";
5
5
  import "package:only_bible_app/theme.dart";
6
6
  import "package:only_bible_app/utils.dart";
@@ -23,7 +23,7 @@ class ActionsSheet extends StatelessWidget {
23
23
  index,
24
24
  ),
25
25
  );
26
- hideActions(context);
26
+ context.nav.hideActions(context);
27
27
  }
28
28
 
29
29
  return Material(
@@ -44,7 +44,7 @@ class ActionsSheet extends StatelessWidget {
44
44
  List<Verse>.from(context.state.selectedVerses),
45
45
  ),
46
46
  );
47
- hideActions(context);
47
+ context.nav.hideActions(context);
48
48
  },
49
49
  icon: Icon(Icons.cancel_outlined, size: 28, color: iconColor),
50
50
  ),
@@ -77,7 +77,7 @@ class ActionsSheet extends StatelessWidget {
77
77
  ),
78
78
  IconButton(
79
79
  padding: EdgeInsets.zero,
80
- onPressed: () => shareVerses(context, bible, context.state.selectedVerses),
80
+ onPressed: () => context.nav.shareVerses(context, bible, context.state.selectedVerses),
81
81
  icon: Icon(Icons.share_outlined, size: 34, color: iconColor),
82
82
  ),
83
83
  ],
lib/sheets/highlight_sheet.dart DELETED
@@ -1,67 +0,0 @@
1
- import "package:flutter/material.dart";
2
- import "package:only_bible_app/app.dart";
3
- import "package:only_bible_app/bible_generated.dart";
4
- import "package:only_bible_app/navigation.dart";
5
- import "package:only_bible_app/store/actions.dart";
6
- import "package:only_bible_app/theme.dart";
7
- import "package:only_bible_app/utils.dart";
8
- import "package:only_bible_app/widgets/highlight_button.dart";
9
-
10
- class HighlightSheet extends StatelessWidget {
11
- const HighlightSheet({super.key});
12
-
13
- @override
14
- Widget build(BuildContext context) {
15
- final iconColor = store.state.darkMode ? Colors.white.withOpacity(0.9) : Colors.black.withOpacity(0.9);
16
- void onHighlight(int index) {
17
- store.dispatch(SetHighlightAction(
18
- List<Verse>.from(store.state.selectedVerses),
19
- index,
20
- ));
21
- hideActions(context);
22
- }
23
-
24
- return Container(
25
- height: 50,
26
- color: context.theme.colorScheme.surface,
27
- padding: const EdgeInsets.only(left: 20, right: 20),
28
- child: Row(
29
- mainAxisAlignment: MainAxisAlignment.spaceAround,
30
- children: [
31
- IconButton(
32
- padding: EdgeInsets.zero,
33
- onPressed: () {
34
- store.dispatch(
35
- RemoveHighlightAction(
36
- List<Verse>.from(store.state.selectedVerses),
37
- ),
38
- );
39
- hideActions(context);
40
- },
41
- icon: Icon(Icons.cancel_outlined, size: 28, color: iconColor),
42
- ),
43
- HighlightButton(
44
- index: 0,
45
- color: store.state.darkMode ? darkHighlights[0] : lightHighlights[0],
46
- onHighlightSelected: onHighlight,
47
- ),
48
- HighlightButton(
49
- index: 1,
50
- color: store.state.darkMode ? darkHighlights[1] : lightHighlights[1],
51
- onHighlightSelected: onHighlight,
52
- ),
53
- HighlightButton(
54
- index: 2,
55
- color: store.state.darkMode ? darkHighlights[2] : lightHighlights[2],
56
- onHighlightSelected: onHighlight,
57
- ),
58
- HighlightButton(
59
- index: 3,
60
- color: store.state.darkMode ? darkHighlights[3] : lightHighlights[3],
61
- onHighlightSelected: onHighlight,
62
- ),
63
- ],
64
- ),
65
- );
66
- }
67
- }
lib/sheets/settings_sheet.dart CHANGED
@@ -1,6 +1,6 @@
1
1
  import "package:flutter/material.dart";
2
- import "package:only_bible_app/bible_generated.dart";
3
- import "package:only_bible_app/navigation.dart";
2
+ import "package:only_bible_app/gen/bible.gen.dart";
3
+ import "package:only_bible_app/store/app_navigator.dart";
4
4
  import "package:only_bible_app/store/actions.dart";
5
5
  import "package:only_bible_app/utils.dart";
6
6
  import "package:settings_ui/settings_ui.dart";
@@ -33,7 +33,7 @@ class SettingsSheet extends StatelessWidget {
33
33
  leading: const Icon(Icons.book_outlined, color: Colors.blueAccent),
34
34
  title: Text(context.l.bibleTitle),
35
35
  value: Text(bible.name!),
36
- onPressed: changeBible,
36
+ onPressed: context.nav.changeBible,
37
37
  ),
38
38
  SettingsTile.navigation(
39
39
  leading: const Icon(Icons.color_lens_outlined, color: Colors.green),
@@ -120,7 +120,7 @@ class SettingsSheet extends StatelessWidget {
120
120
  SettingsTile.navigation(
121
121
  leading: const Icon(Icons.policy_outlined, color: Colors.brown),
122
122
  title: Text(context.l.privacyPolicyTitle),
123
- onPressed: showPrivacyPolicy,
123
+ onPressed: context.nav.showPrivacyPolicy,
124
124
  ),
125
125
  SettingsTile.navigation(
126
126
  leading: const Icon(
@@ -128,17 +128,17 @@ class SettingsSheet extends StatelessWidget {
128
128
  color: Colors.blueGrey,
129
129
  ),
130
130
  title: Text(context.l.termsAndConditionsTitle),
131
- onPressed: showTermsAndConditions,
131
+ onPressed: context.nav.showTermsAndConditions,
132
132
  ),
133
133
  SettingsTile.navigation(
134
134
  leading: const Icon(Icons.share_outlined, color: Colors.blueAccent),
135
135
  title: Text(context.l.shareAppTitle),
136
- onPressed: shareAppLink,
136
+ onPressed: context.nav.shareAppLink,
137
137
  ),
138
138
  SettingsTile.navigation(
139
139
  leading: Icon(Icons.star, color: Colors.yellowAccent.shade700),
140
140
  title: Text(context.l.rateAppTitle),
141
- onPressed: rateApp,
141
+ onPressed: context.nav.rateApp,
142
142
  ),
143
143
  SettingsTile.navigation(
144
144
  leading: Icon(
@@ -146,7 +146,7 @@ class SettingsSheet extends StatelessWidget {
146
146
  color: context.theme.colorScheme.onSurface,
147
147
  ),
148
148
  title: Text(context.l.aboutUsTitle),
149
- onPressed: showAboutUs,
149
+ onPressed: context.nav.showAboutUs,
150
150
  ),
151
151
  ],
152
152
  ),
lib/store/actions.dart CHANGED
@@ -1,5 +1,5 @@
1
1
  import "package:async_redux/async_redux.dart";
2
- import "package:only_bible_app/bible_generated.dart";
2
+ import "package:only_bible_app/gen/bible.gen.dart";
3
3
  import "package:only_bible_app/store/app_state.dart";
4
4
  import "package:only_bible_app/utils.dart";
5
5
 
lib/store/app_navigator.dart ADDED
@@ -0,0 +1,231 @@
1
+ import "package:flutter/material.dart";
2
+ import "package:app_review/app_review.dart";
3
+ import "package:go_router/go_router.dart";
4
+ import "package:only_bible_app/gen/bible.gen.dart";
5
+ import "package:only_bible_app/sheets/actions_sheet.dart";
6
+ import "package:only_bible_app/sheets/settings_sheet.dart";
7
+ import "package:only_bible_app/store/actions.dart";
8
+ import "package:only_bible_app/store/app_state.dart";
9
+ import "package:only_bible_app/utils.dart";
10
+ import "package:share_plus/share_plus.dart";
11
+
12
+ class AppNavigatorProvider extends InheritedWidget {
13
+ final AppNavigator navigator;
14
+
15
+ const AppNavigatorProvider({
16
+ super.key,
17
+ required this.navigator,
18
+ required super.child,
19
+ });
20
+
21
+ static AppNavigator of(BuildContext context) {
22
+ return context.dependOnInheritedWidgetOfExactType<AppNavigatorProvider>()!.navigator;
23
+ }
24
+
25
+ @override
26
+ bool updateShouldNotify(AppNavigatorProvider oldWidget) => false;
27
+ }
28
+
29
+ extension AppNavigatorContext on BuildContext {
30
+ AppNavigator get nav => AppNavigatorProvider.of(this);
31
+ }
32
+
33
+ class AppNavigator {
34
+ OverlayEntry? _actionsOverlay;
35
+
36
+ String _chapterPath(String bibleName, int book, int chapter) {
37
+ return "/chapter/${Uri.encodeComponent(bibleName)}/$book/$chapter";
38
+ }
39
+
40
+ void pushBookChapter(
41
+ BuildContext context,
42
+ String bibleName,
43
+ int book,
44
+ int chapter,
45
+ TextDirection? dir,
46
+ ) {
47
+ context.dispatch(UpdateChapterAction(book, chapter));
48
+ if (context.state.isPlaying) {
49
+ AppState.player.pause();
50
+ context.dispatch(SetPlayingAction(false));
51
+ }
52
+ hideActions(context);
53
+ context.push(_chapterPath(bibleName, book, chapter), extra: dir);
54
+ }
55
+
56
+ void replaceBookChapter(
57
+ BuildContext context,
58
+ String bibleName,
59
+ int book,
60
+ int chapter,
61
+ ) {
62
+ context.dispatch(UpdateChapterAction(book, chapter));
63
+ if (context.state.isPlaying) {
64
+ AppState.player.pause();
65
+ context.dispatch(SetPlayingAction(false));
66
+ }
67
+ hideActions(context);
68
+ context.go(_chapterPath(bibleName, book, chapter));
69
+ }
70
+
71
+ void nextChapter(BuildContext context, Bible bible, int book, int chapter) {
72
+ final selectedBook = bible.books![book];
73
+ if (selectedBook.chapters!.length > chapter + 1) {
74
+ pushBookChapter(
75
+ context,
76
+ bible.name!,
77
+ selectedBook.index,
78
+ chapter + 1,
79
+ TextDirection.ltr,
80
+ );
81
+ } else {
82
+ if (selectedBook.index + 1 < bible.books!.length) {
83
+ final nextBook = bible.books![selectedBook.index + 1];
84
+ pushBookChapter(
85
+ context,
86
+ bible.name!,
87
+ nextBook.index,
88
+ 0,
89
+ TextDirection.ltr,
90
+ );
91
+ }
92
+ }
93
+ }
94
+
95
+ void previousChapter(BuildContext context, Bible bible, int book, int chapter) {
96
+ final selectedBook = bible.books![book];
97
+ if (chapter - 1 >= 0) {
98
+ pushBookChapter(
99
+ context,
100
+ bible.name!,
101
+ selectedBook.index,
102
+ chapter - 1,
103
+ TextDirection.rtl,
104
+ );
105
+ } else {
106
+ if (selectedBook.index - 1 >= 0) {
107
+ final prevBook = bible.books![selectedBook.index - 1];
108
+ pushBookChapter(
109
+ context,
110
+ bible.name!,
111
+ prevBook.index,
112
+ prevBook.chapters!.length - 1,
113
+ TextDirection.rtl,
114
+ );
115
+ }
116
+ }
117
+ }
118
+
119
+ void showAboutUs(BuildContext context) {
120
+ context.push("/webview", extra: "https://onlybible.app/about-us");
121
+ }
122
+
123
+ void showPrivacyPolicy(BuildContext context) {
124
+ context.push("/webview", extra: "https://onlybible.app/privacy-policy");
125
+ }
126
+
127
+ void showTermsAndConditions(BuildContext context) {
128
+ context.push("/webview", extra: "https://onlybible.app/terms-and-conditions");
129
+ }
130
+
131
+ void changeBible(BuildContext context) {
132
+ context.go("/bible");
133
+ }
134
+
135
+ void changeBibleFromHeader(BuildContext context) {
136
+ context.push("/bible");
137
+ }
138
+
139
+ void changeBook(BuildContext context, Bible bible) {
140
+ context.push("/books/${Uri.encodeComponent(bible.name!)}");
141
+ }
142
+
143
+ void changeChapter(BuildContext context, Bible bible, Book book, int index) {
144
+ context.push("/chapters/${Uri.encodeComponent(bible.name!)}/${book.index}");
145
+ }
146
+
147
+ Future<void> updateCurrentBible(
148
+ BuildContext context,
149
+ String name,
150
+ String code,
151
+ int book,
152
+ int chapter,
153
+ ) async {
154
+ hideActions(context);
155
+ await context.dispatchAndWait(UpdateBibleAction(name, code));
156
+ await context.dispatchAndWait(LoadBibleAction());
157
+ context.go(_chapterPath(name, book, chapter));
158
+ }
159
+
160
+ void shareAppLink(BuildContext context) {
161
+ if (isAndroid()) {
162
+ Share.share(
163
+ subject: "Only Bible App",
164
+ "https://play.google.com/store/apps/details?id=sh.pyros.only_bible_app",
165
+ );
166
+ } else {
167
+ Share.share(
168
+ subject: "Only Bible App",
169
+ "https://apps.apple.com/us/app/only-bible-app/id6467606465",
170
+ );
171
+ }
172
+ }
173
+
174
+ Future<void> rateApp(BuildContext context) async {
175
+ AppReview.requestReview;
176
+ }
177
+
178
+ Future<void> shareVerses(BuildContext context, Bible bible, List<Verse> verses) async {
179
+ final name = context.bookNames[verses.first.book];
180
+ final chapter = verses.first.chapter + 1;
181
+ final items = verses.sortedBy((e) => e.index).map((e) => e.index + 1);
182
+ final versesThrough = items.length >= 3 ? "${items.first}-${items.last}" : items.join(",");
183
+ final version = context.currentLang.languageCode == "en" ? "KJV" : "";
184
+ final title = "$name $chapter:$versesThrough $version";
185
+ final text = verses.map((e) => e.text ?? "").join("\n");
186
+ await SharePlus.instance.share(
187
+ ShareParams(
188
+ title: title,
189
+ subject: title,
190
+ text: "$title\n$text",
191
+ ),
192
+ );
193
+ hideActions(context);
194
+ }
195
+
196
+ void showSettings(BuildContext context, Bible bible) {
197
+ showModalBottomSheet(
198
+ context: context,
199
+ isDismissible: true,
200
+ enableDrag: true,
201
+ showDragHandle: true,
202
+ useSafeArea: true,
203
+ builder: (context) => SettingsSheet(bible: bible),
204
+ );
205
+ }
206
+
207
+ void showActions(BuildContext context, Bible bible) {
208
+ _actionsOverlay?.remove();
209
+ _actionsOverlay = null;
210
+ final overlay = Overlay.of(context);
211
+ _actionsOverlay = OverlayEntry(
212
+ builder: (context) {
213
+ final bottomPadding = MediaQuery.of(context).padding.bottom;
214
+ return Align(
215
+ alignment: Alignment.bottomCenter,
216
+ child: Padding(
217
+ padding: EdgeInsets.only(bottom: bottomPadding + 40, left: 20, right: 20),
218
+ child: ActionsSheet(bible: bible),
219
+ ),
220
+ );
221
+ },
222
+ );
223
+ overlay.insert(_actionsOverlay!);
224
+ }
225
+
226
+ void hideActions(BuildContext context) {
227
+ _actionsOverlay?.remove();
228
+ _actionsOverlay = null;
229
+ context.dispatch(ClearSelectedVersesAction());
230
+ }
231
+ }
lib/store/app_state.dart CHANGED
@@ -2,7 +2,7 @@ import "dart:developer";
2
2
  import "package:flutter/material.dart";
3
3
  import "package:just_audio/just_audio.dart";
4
4
  import "package:only_bible_app/dialog.dart";
5
- import "package:only_bible_app/bible_generated.dart";
5
+ import "package:only_bible_app/gen/bible.gen.dart";
6
6
  import "package:only_bible_app/store/actions.dart";
7
7
  import "package:only_bible_app/store/buffer_audio_source.dart";
8
8
  import "package:only_bible_app/theme.dart";
lib/utils.dart CHANGED
@@ -7,11 +7,11 @@ import "package:package_info_plus/package_info_plus.dart";
7
7
  import "package:url_launcher/url_launcher.dart";
8
8
  import "package:flutter/foundation.dart" show TargetPlatform, defaultTargetPlatform, kDebugMode;
9
9
  import "package:flutter/material.dart";
10
- import "package:only_bible_app/l10n/app_localizations.dart";
10
+ import "package:only_bible_app/gen/l10n/app_localizations.dart";
11
11
  import "package:flutter_azure_tts/flutter_azure_tts.dart";
12
12
  import "package:only_bible_app/dialog.dart";
13
13
  import "package:only_bible_app/env.dart";
14
- import "package:only_bible_app/bible_generated.dart";
14
+ import "package:only_bible_app/gen/bible.gen.dart";
15
15
  import "package:only_bible_app/store/app_state.dart";
16
16
 
17
17
  extension BibleExt on Bible {
lib/widgets/chapter_app_bar.dart CHANGED
@@ -1,6 +1,6 @@
1
1
  import "package:flutter/material.dart";
2
- import "package:only_bible_app/bible_generated.dart";
3
- import "package:only_bible_app/navigation.dart";
2
+ import "package:only_bible_app/gen/bible.gen.dart";
3
+ import "package:only_bible_app/store/app_navigator.dart";
4
4
  import "package:only_bible_app/utils.dart";
5
5
 
6
6
  class ChapterAppBar extends StatelessWidget implements PreferredSizeWidget {
@@ -30,21 +30,12 @@ class ChapterAppBar extends StatelessWidget implements PreferredSizeWidget {
30
30
  children: [
31
31
  InkWell(
32
32
  enableFeedback: true,
33
- onTap: () => changeChapter(context, bible, book, book.index),
33
+ onTap: () => context.nav.changeChapter(context, bible, book, book.index),
34
- onLongPress: () => changeBook(context, bible),
34
+ onLongPress: () => context.nav.changeBook(context, bible),
35
- child: Row(
35
+ child: Text(
36
- children: [
37
- Text(
38
- "$bookName ${chapter.index + 1}",
36
+ "$bookName ${chapter.index + 1}",
39
- style: Theme.of(context).textTheme.headlineMedium,
37
+ style: Theme.of(context).textTheme.headlineMedium,
40
- key: const Key("bookTitle"),
38
+ key: const Key("bookTitle"),
41
- ),
42
- Icon(
43
- Icons.expand_more,
44
- size: 28,
45
- color: Theme.of(context).textTheme.headlineMedium!.color,
46
- ),
47
- ],
48
39
  ),
49
40
  ),
50
41
  Expanded(
@@ -56,7 +47,7 @@ class ChapterAppBar extends StatelessWidget implements PreferredSizeWidget {
56
47
  child: IconButton(
57
48
  padding: EdgeInsets.zero,
58
49
  icon: const Icon(Icons.more_vert, size: 24),
59
- onPressed: () => showSettings(context, bible),
50
+ onPressed: () => context.nav.showSettings(context, bible),
60
51
  ),
61
52
  ),
62
53
  ],
lib/widgets/verses_view.dart CHANGED
@@ -1,7 +1,7 @@
1
1
  import "package:flutter/material.dart";
2
2
  import "package:flutter_swipe_detector/flutter_swipe_detector.dart";
3
- import "package:only_bible_app/bible_generated.dart";
4
- import "package:only_bible_app/navigation.dart";
3
+ import "package:only_bible_app/gen/bible.gen.dart";
4
+ import "package:only_bible_app/store/app_navigator.dart";
5
5
  import "package:only_bible_app/store/actions.dart";
6
6
  import "package:only_bible_app/utils.dart";
7
7
 
@@ -14,9 +14,9 @@ class VersesView extends StatelessWidget {
14
14
  void _onVerseTap(BuildContext context, Verse v) {
15
15
  context.dispatch(SelectVerseAction(v));
16
16
  if (context.state.selectedVerses.isNotEmpty) {
17
- showActions(context, bible);
17
+ context.nav.showActions(context, bible);
18
18
  } else {
19
- hideActions(context);
19
+ context.nav.hideActions(context);
20
20
  }
21
21
  }
22
22
 
@@ -27,8 +27,8 @@ class VersesView extends StatelessWidget {
27
27
  final theme = Theme.of(context).textTheme;
28
28
  final baseStyle = appState.boldFont ? textStyle.copyWith(fontWeight: FontWeight.w500) : textStyle;
29
29
  return SwipeDetector(
30
- onSwipeLeft: (offset) => nextChapter(context, bible, chapter.book, chapter.index),
30
+ onSwipeLeft: (offset) => context.nav.nextChapter(context, bible, chapter.book, chapter.index),
31
- onSwipeRight: (offset) => previousChapter(context, bible, chapter.book, chapter.index),
31
+ onSwipeRight: (offset) => context.nav.previousChapter(context, bible, chapter.book, chapter.index),
32
32
  child: SingleChildScrollView(
33
33
  physics: const BouncingScrollPhysics(),
34
34
  padding: const EdgeInsets.symmetric(horizontal: 20),
pubspec.yaml CHANGED
@@ -39,11 +39,11 @@ dev_dependencies:
39
39
  sdk: flutter
40
40
  flutter_lints: ^6.0.0
41
41
  flutter_launcher_icons: ^0.14.4
42
- test: ^1.24.3
42
+ test: ^1.30.0
43
43
  build_runner: any
44
44
  flutter_gen_runner: any
45
-
46
45
  html: any
46
+
47
47
  flutter:
48
48
  generate: true
49
49
  uses-material-design: true
@@ -61,7 +61,7 @@ flutter:
61
61
  weight: 700
62
62
 
63
63
  flutter_launcher_icons:
64
- android: false
64
+ android: true
65
65
  ios: true
66
66
  image_path: "assets/icon.png"
67
67
  remove_alpha_ios: true
{lib/l10n → scripts/arb}/app_bn.arb RENAMED
File without changes
{lib/l10n → scripts/arb}/app_en.arb RENAMED
File without changes
{lib/l10n → scripts/arb}/app_gu.arb RENAMED
File without changes
{lib/l10n → scripts/arb}/app_hi.arb RENAMED
File without changes
{lib/l10n → scripts/arb}/app_kn.arb RENAMED
File without changes
{lib/l10n → scripts/arb}/app_ml.arb RENAMED
File without changes
{lib/l10n → scripts/arb}/app_ne.arb RENAMED
File without changes
{lib/l10n → scripts/arb}/app_or.arb RENAMED
File without changes
{lib/l10n → scripts/arb}/app_pa.arb RENAMED
File without changes
{lib/l10n → scripts/arb}/app_ta.arb RENAMED
File without changes
{lib/l10n → scripts/arb}/app_te.arb RENAMED
File without changes