~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.


.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 18:21:58.914600","version":"3.41.5","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}],"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}],"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}],"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":[]}],"date_created":"2026-03-24 21:47:01.129777","version":"3.41.5","swift_package_manager_enabled":{"ios":false,"macos":false}}
android/app/build.gradle.kts CHANGED
@@ -24,7 +24,7 @@ android {
24
24
  applicationId = "sh.pyros.only_bible_app"
25
25
  // You can update the following values to match your application needs.
26
26
  // For more information, see: https://flutter.dev/to/review-gradle-config.
27
- minSdk = flutter.minSdkVersion
27
+ minSdk = Math.max(flutter.minSdkVersion, 26)
28
28
  targetSdk = flutter.targetSdkVersion
29
29
  versionCode = flutter.versionCode
30
30
  versionName = flutter.versionName
lib/app.dart CHANGED
@@ -1,129 +1,31 @@
1
1
  import "package:async_redux/async_redux.dart" show Store, StoreProvider;
2
2
  import "package:flutter/material.dart";
3
- import "package:go_router/go_router.dart";
4
3
  import "package:only_bible_app/gen/l10n/app_localizations.dart";
5
- import "package:only_bible_app/screens/bible_select_screen.dart";
6
- import "package:only_bible_app/screens/book_select_screen.dart";
7
- import "package:only_bible_app/screens/chapter_select_screen.dart";
8
- import "package:only_bible_app/screens/chapter_view_screen.dart";
9
- import "package:only_bible_app/screens/webview_screen.dart";
10
- import "package:only_bible_app/store/actions_state.dart";
4
+ import "package:only_bible_app/home.dart";
11
- import "package:only_bible_app/store/app_navigator.dart";
12
5
  import "package:only_bible_app/store/app_state.dart";
13
- import "package:only_bible_app/store/actions_navigation.dart";
14
6
  import "package:only_bible_app/theme.dart";
15
7
  import "package:only_bible_app/utils.dart";
16
8
 
17
9
  class App extends StatelessWidget {
18
- final GlobalKey<NavigatorState> globalNavigatorKey;
19
10
  final Store<AppState> store;
20
- late final GoRouter _router;
21
11
 
22
- App({super.key, required this.globalNavigatorKey, required this.store}) {
12
+ const App({super.key, required this.store});
23
- final s = store.state;
24
- _router = GoRouter(
25
- navigatorKey: globalNavigatorKey,
26
- initialLocation:
27
- s.firstOpen ? "/bible" : "/chapter/${Uri.encodeComponent(s.bibleName)}/${s.savedBook}/${s.savedChapter}",
28
- redirect: (context, state) {
29
- store.dispatch(HideActionsAction());
30
- return null;
31
- },
32
- routes: [
33
- GoRoute(
34
- path: "/bible",
35
- pageBuilder: (context, state) => const NoTransitionPage(
36
- child: BibleSelectScreen(),
37
- ),
38
- ),
39
- GoRoute(
40
- path: "/chapter/:bibleName/:bookIndex/:chapterIndex",
41
- pageBuilder: (context, state) {
42
- final bibleName = Uri.decodeComponent(state.pathParameters["bibleName"]!);
43
- final bookIndex = int.parse(state.pathParameters["bookIndex"]!);
44
- final chapterIndex = int.parse(state.pathParameters["chapterIndex"]!);
45
- final slideDir = state.extra as TextDirection?;
46
- if (slideDir != null) {
47
- return CustomTransitionPage(
48
- key: state.pageKey,
49
- child: ChapterViewScreen(
50
- bibleName: bibleName,
51
- bookIndex: bookIndex,
52
- chapterIndex: chapterIndex,
53
- ),
54
- transitionsBuilder: (context, animation, secondaryAnimation, child) {
55
- const begin = Offset(1.0, 0.0);
56
- const end = Offset.zero;
57
- const curve = Curves.ease;
58
- final tween = Tween(begin: begin, end: end).chain(CurveTween(curve: curve));
59
- return SlideTransition(
60
- textDirection: slideDir,
61
- position: animation.drive(tween),
62
- child: child,
63
- );
64
- },
65
- );
66
- }
67
- return NoTransitionPage(
68
- key: state.pageKey,
69
- child: ChapterViewScreen(
70
- bibleName: bibleName,
71
- bookIndex: bookIndex,
72
- chapterIndex: chapterIndex,
73
- ),
74
- );
75
- },
76
- ),
77
- GoRoute(
78
- path: "/books/:bibleName",
79
- pageBuilder: (context, state) {
80
- final bibleName = Uri.decodeComponent(state.pathParameters["bibleName"]!);
81
- return NoTransitionPage(
82
- child: BookSelectScreen(bibleName: bibleName),
83
- );
84
- },
85
- ),
86
- GoRoute(
87
- path: "/chapters/:bibleName/:bookIndex",
88
- pageBuilder: (context, state) {
89
- final bibleName = Uri.decodeComponent(state.pathParameters["bibleName"]!);
90
- final bookIndex = int.parse(state.pathParameters["bookIndex"]!);
91
- return NoTransitionPage(
92
- child: ChapterSelectScreen(bibleName: bibleName, bookIndex: bookIndex),
93
- );
94
- },
95
- ),
96
- GoRoute(
97
- path: "/webview",
98
- pageBuilder: (context, state) {
99
- final url = state.extra as String;
100
- return NoTransitionPage(
101
- child: WebViewScreen(url: url),
102
- );
103
- },
104
- ),
105
- ],
106
- );
107
- }
108
13
 
109
14
  @override
110
15
  Widget build(BuildContext context) {
111
16
  return StoreProvider<AppState>(
112
17
  store: store,
113
- child: AppRouterScope(
114
- router: _router,
115
- child: Builder(
18
+ child: Builder(
116
- builder: (context) => MaterialApp.router(
19
+ builder: (context) => MaterialApp(
117
- routerConfig: _router,
118
- onGenerateTitle: (context) => context.l.title,
20
+ onGenerateTitle: (context) => context.l.title,
119
- localizationsDelegates: AppLocalizations.localizationsDelegates,
21
+ localizationsDelegates: AppLocalizations.localizationsDelegates,
120
- supportedLocales: AppLocalizations.supportedLocales,
22
+ supportedLocales: AppLocalizations.supportedLocales,
121
- debugShowCheckedModeBanner: false,
23
+ debugShowCheckedModeBanner: false,
122
- themeMode: context.select((s) => s.darkMode) ? ThemeMode.dark : ThemeMode.light,
24
+ themeMode: context.select((s) => s.darkMode) ? ThemeMode.dark : ThemeMode.light,
123
- theme: lightTheme,
25
+ theme: lightTheme,
124
- darkTheme: darkTheme,
26
+ darkTheme: darkTheme,
125
- locale: Locale(context.select((s) => s.languageCode)),
27
+ locale: Locale(context.select((s) => s.languageCode)),
126
- ),
28
+ home: const Home(),
127
29
  ),
128
30
  ),
129
31
  );
lib/dialog.dart CHANGED
@@ -1,7 +1,6 @@
1
1
  import "dart:ui";
2
2
  import "package:flutter/material.dart";
3
- import "package:only_bible_app/store/actions_state.dart";
3
+ import "package:only_bible_app/gen/bible.gen.dart";
4
- import "package:only_bible_app/store/app_navigator.dart";
5
4
  import "package:only_bible_app/store/actions_navigation.dart";
6
5
  import "package:only_bible_app/utils.dart";
7
6
 
@@ -34,6 +33,193 @@ void showError(BuildContext context, String message) {
34
33
  showAlert(context, "Error", message);
35
34
  }
36
35
 
36
+ void showBibleSelectDialog(BuildContext context) {
37
+ showDialog(
38
+ context: context,
39
+ builder: (_) {
40
+ return BackdropFilter(
41
+ filter: ImageFilter.blur(sigmaX: 6, sigmaY: 6),
42
+ child: AlertDialog(
43
+ title: Text(context.l.bibleSelectTitle),
44
+ contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
45
+ content: SizedBox(
46
+ width: double.maxFinite,
47
+ height: 400,
48
+ child: ListView.separated(
49
+ itemCount: context.supportedLocalizations.length,
50
+ separatorBuilder: (_, __) => const Divider(height: 1),
51
+ itemBuilder: (_, index) {
52
+ final l = context.supportedLocalizations[index];
53
+ final isSelected = context.read().bibleName == l.languageTitle;
54
+ return ListTile(
55
+ selected: isSelected,
56
+ leading: const Icon(Icons.menu_book),
57
+ title: Text(l.localeLanguageTitle),
58
+ subtitle: (l.localeLanguageTitle != l.languageTitle) ? Text(l.languageTitle) : null,
59
+ trailing: isSelected ? const Icon(Icons.check) : null,
60
+ onTap: () {
61
+ final s = context.read();
62
+ Navigator.of(_).pop();
63
+ context.dispatch(
64
+ UpdateCurrentBibleAction(l.languageTitle, l.localeName, s.savedBook, s.savedChapter),
65
+ );
66
+ },
67
+ );
68
+ },
69
+ ),
70
+ ),
71
+ ),
72
+ );
73
+ },
74
+ );
75
+ }
76
+
77
+ void showBookSelectDialog(BuildContext context, Bible bible) {
78
+ void onBookSelected(BuildContext dialogContext, int index) {
79
+ final book = bible.books![index];
80
+ Navigator.of(dialogContext).pop();
81
+ if (book.chapters!.length == 1) {
82
+ context.dispatch(GoToChapterAction(bible.name!, index, 0));
83
+ } else {
84
+ showChapterSelectDialog(context, bible, book);
85
+ }
86
+ }
87
+
88
+ showDialog(
89
+ context: context,
90
+ builder: (_) {
91
+ final colorScheme = Theme.of(context).colorScheme;
92
+ final currentBook = context.read().savedBook;
93
+ final oldBooks = bible.getOldBooks();
94
+ final newBooks = bible.getNewBooks();
95
+
96
+ Widget bookTile(Book book) {
97
+ final isSelected = currentBook == book.index;
98
+ return Material(
99
+ color: isSelected ? colorScheme.primaryContainer : colorScheme.surfaceContainerHighest,
100
+ borderRadius: BorderRadius.circular(12),
101
+ child: InkWell(
102
+ borderRadius: BorderRadius.circular(12),
103
+ onTap: () => onBookSelected(_, book.index),
104
+ child: Center(
105
+ child: Text(
106
+ book.shortName(context.bookNames[book.index]),
107
+ textAlign: TextAlign.center,
108
+ style: TextStyle(
109
+ fontSize: 13,
110
+ fontWeight: isSelected ? FontWeight.bold : FontWeight.w500,
111
+ color: isSelected ? colorScheme.onPrimaryContainer : colorScheme.onSurface,
112
+ ),
113
+ ),
114
+ ),
115
+ ),
116
+ );
117
+ }
118
+
119
+ return BackdropFilter(
120
+ filter: ImageFilter.blur(sigmaX: 6, sigmaY: 6),
121
+ child: AlertDialog(
122
+ contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
123
+ content: SizedBox(
124
+ width: double.maxFinite,
125
+ height: 500,
126
+ child: ListView(
127
+ children: [
128
+ Padding(
129
+ padding: const EdgeInsets.only(bottom: 8),
130
+ child: Text(
131
+ context.l.oldTestamentTitle,
132
+ style: Theme.of(context).textTheme.headlineMedium,
133
+ ),
134
+ ),
135
+ GridView.count(
136
+ shrinkWrap: true,
137
+ physics: const NeverScrollableScrollPhysics(),
138
+ crossAxisCount: 4,
139
+ crossAxisSpacing: 8.0,
140
+ mainAxisSpacing: 8.0,
141
+ children: oldBooks.map(bookTile).toList(),
142
+ ),
143
+ Padding(
144
+ padding: const EdgeInsets.only(top: 16, bottom: 8),
145
+ child: Text(
146
+ context.l.newTestamentTitle,
147
+ style: Theme.of(context).textTheme.headlineMedium,
148
+ ),
149
+ ),
150
+ GridView.count(
151
+ shrinkWrap: true,
152
+ physics: const NeverScrollableScrollPhysics(),
153
+ crossAxisCount: 4,
154
+ crossAxisSpacing: 8.0,
155
+ mainAxisSpacing: 8.0,
156
+ children: newBooks.map(bookTile).toList(),
157
+ ),
158
+ ],
159
+ ),
160
+ ),
161
+ ),
162
+ );
163
+ },
164
+ );
165
+ }
166
+
167
+ void showChapterSelectDialog(BuildContext context, Bible bible, Book book) {
168
+ final currentChapter = context.read().savedChapter;
169
+ final currentBook = context.read().savedBook;
170
+ showDialog(
171
+ context: context,
172
+ builder: (_) {
173
+ final colorScheme = Theme.of(context).colorScheme;
174
+ return BackdropFilter(
175
+ filter: ImageFilter.blur(sigmaX: 6, sigmaY: 6),
176
+ child: AlertDialog(
177
+ title: Text(context.bookNames[book.index]),
178
+ contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
179
+ content: SizedBox(
180
+ width: double.maxFinite,
181
+ height: 400,
182
+ child: GridView.builder(
183
+ gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
184
+ crossAxisCount: 5,
185
+ crossAxisSpacing: 8.0,
186
+ mainAxisSpacing: 8.0,
187
+ ),
188
+ itemCount: book.chapters!.length,
189
+ itemBuilder: (_, index) {
190
+ final isSelected = currentBook == book.index && currentChapter == index;
191
+ return Material(
192
+ color: isSelected ? colorScheme.primaryContainer : colorScheme.surfaceContainerHighest,
193
+ borderRadius: BorderRadius.circular(12),
194
+ child: InkWell(
195
+ borderRadius: BorderRadius.circular(12),
196
+ onTap: () {
197
+ Navigator.of(_).pop();
198
+ context.dispatch(
199
+ GoToChapterAction(bible.name!, book.index, index),
200
+ );
201
+ },
202
+ child: Center(
203
+ child: Text(
204
+ "${index + 1}",
205
+ style: TextStyle(
206
+ fontSize: 16,
207
+ fontWeight: isSelected ? FontWeight.bold : FontWeight.w500,
208
+ color: isSelected ? colorScheme.onPrimaryContainer : colorScheme.onSurface,
209
+ ),
210
+ ),
211
+ ),
212
+ ),
213
+ );
214
+ },
215
+ ),
216
+ ),
217
+ ),
218
+ );
219
+ },
220
+ );
221
+ }
222
+
37
223
  void showReportError(BuildContext context, String message, StackTrace? st) {
38
224
  if (message.contains("LateInitializationError") || message.contains("HardwareKeyboard")) {
39
225
  return;
@@ -52,13 +238,15 @@ void showReportError(BuildContext context, String message, StackTrace? st) {
52
238
  TextButton(
53
239
  onPressed: () {
54
240
  recordError(message, st);
241
+ Navigator.of(context).pop();
55
- context.dispatch(ChangeBibleAction(context.router));
242
+ showBibleSelectDialog(context);
56
243
  },
57
244
  child: const Text("Yes"),
58
245
  ),
59
246
  TextButton(
60
247
  onPressed: () {
248
+ Navigator.of(context).pop();
61
- context.dispatch(ChangeBibleAction(context.router));
249
+ showBibleSelectDialog(context);
62
250
  },
63
251
  child: const Text("No"),
64
252
  ),
lib/home.dart ADDED
@@ -0,0 +1,24 @@
1
+ import "package:flutter/material.dart";
2
+ import "package:only_bible_app/utils.dart";
3
+ import "package:only_bible_app/widgets/home_app_bar.dart";
4
+ import "package:only_bible_app/widgets/verses_view.dart";
5
+
6
+ class Home extends StatelessWidget {
7
+ const Home({super.key});
8
+
9
+ @override
10
+ Widget build(BuildContext context) {
11
+ final bible = context.select((s) => s.bible);
12
+ final bookIndex = context.select((s) => s.savedBook);
13
+ final chapterIndex = context.select((s) => s.savedChapter);
14
+ final book = bible.books![bookIndex];
15
+ final chapter = book.chapters![chapterIndex];
16
+ return Scaffold(
17
+ appBar: HomeAppBar(bible: bible, book: book, chapter: chapter),
18
+ backgroundColor: Theme.of(context).colorScheme.surface,
19
+ body: SafeArea(
20
+ child: VersesView(bible: bible, chapter: chapter),
21
+ ),
22
+ );
23
+ }
24
+ }
lib/main.dart CHANGED
@@ -62,7 +62,6 @@ void main() async {
62
62
  region: "centralindia",
63
63
  withLogs: true,
64
64
  );
65
- final globalNavigatorKey = GlobalKey<NavigatorState>();
66
65
  final persistor = AppPersistor();
67
66
  final json = await persistor.readJson();
68
67
  final bibleName = json?["bibleName"] as String? ?? "English";
@@ -73,6 +72,6 @@ void main() async {
73
72
  persistor: persistor,
74
73
  );
75
74
  updateStatusBar(store.state.darkMode);
76
- runApp(App(globalNavigatorKey: globalNavigatorKey, store: store));
75
+ runApp(App(store: store));
77
76
  FlutterNativeSplash.remove();
78
77
  }
lib/screens/bible_select_screen.dart DELETED
@@ -1,55 +0,0 @@
1
- import "package:flutter/material.dart";
2
- import "package:only_bible_app/store/actions_state.dart";
3
- import "package:only_bible_app/store/app_navigator.dart";
4
- import "package:only_bible_app/store/actions_navigation.dart";
5
- import "package:only_bible_app/utils.dart";
6
- import "package:only_bible_app/widgets/scaffold_menu.dart";
7
- import "package:only_bible_app/widgets/sliver_heading.dart";
8
- import "package:only_bible_app/widgets/sliver_tile_grid.dart";
9
-
10
- class BibleSelectScreen extends StatelessWidget {
11
- const BibleSelectScreen({super.key});
12
-
13
- @override
14
- Widget build(BuildContext context) {
15
- return ScaffoldMenu(
16
- child: CustomScrollView(
17
- physics: const BouncingScrollPhysics(),
18
- slivers: [
19
- SliverHeading(
20
- title: context.l.bibleSelectTitle,
21
- showClose: !context.select((s) => s.firstOpen),
22
- ),
23
- SliverTileGrid(
24
- listType: ListType.extraLarge,
25
- children: List.of(
26
- context.supportedLocalizations.map((l) {
27
- return TextButton(
28
- child: (l.localeLanguageTitle != l.languageTitle)
29
- ? Column(
30
- mainAxisAlignment: MainAxisAlignment.center,
31
- children: [
32
- Text(l.localeLanguageTitle, textScaleFactor: 1.3),
33
- Text("(${l.languageTitle})", textScaleFactor: 0.8),
34
- ],
35
- )
36
- : Text(l.languageTitle, textScaleFactor: 1.1),
37
- onPressed: () {
38
- final s = context.read();
39
- if (s.firstOpen) {
40
- context.dispatch(FirstOpenDoneAction());
41
- }
42
- context.dispatch(
43
- UpdateCurrentBibleAction(
44
- context.router, l.languageTitle, l.localeName, s.savedBook, s.savedChapter),
45
- );
46
- },
47
- );
48
- }),
49
- ),
50
- ),
51
- ],
52
- ),
53
- );
54
- }
55
- }
lib/screens/book_select_screen.dart DELETED
@@ -1,57 +0,0 @@
1
- import "package:flutter/material.dart";
2
- import "package:only_bible_app/store/actions_state.dart";
3
- import "package:only_bible_app/store/app_navigator.dart";
4
- import "package:only_bible_app/store/actions_navigation.dart";
5
- import "package:only_bible_app/utils.dart";
6
- import "package:only_bible_app/widgets/scaffold_menu.dart";
7
- import "package:only_bible_app/widgets/sliver_heading.dart";
8
- import "package:only_bible_app/widgets/sliver_tile_grid.dart";
9
- import "package:only_bible_app/gen/bible.gen.dart";
10
-
11
- class BookSelectScreen extends StatelessWidget {
12
- final String bibleName;
13
-
14
- const BookSelectScreen({super.key, required this.bibleName});
15
-
16
- dynamic onBookSelected(BuildContext context, Bible bible, int index) {
17
- final book = bible.books![index];
18
- if (book.chapters!.length == 1) {
19
- return context.dispatch(ReplaceBookChapterAction(context.router, bible.name!, index, 0));
20
- }
21
- context.dispatch(ChangeChapterAction(context.router, bible, book));
22
- }
23
-
24
- @override
25
- Widget build(BuildContext context) {
26
- final bible = context.select((s) => s.bible);
27
- return ScaffoldMenu(
28
- child: CustomScrollView(
29
- physics: const BouncingScrollPhysics(),
30
- slivers: [
31
- SliverHeading(title: context.l.oldTestamentTitle, showClose: true),
32
- SliverTileGrid(
33
- children: List.of(
34
- bible.getOldBooks().map((book) {
35
- return TextButton(
36
- child: Text(book.shortName(context.bookNames[book.index])),
37
- onPressed: () => onBookSelected(context, bible, book.index),
38
- );
39
- }),
40
- ),
41
- ),
42
- SliverHeading(title: context.l.newTestamentTitle, top: 30, bottom: 20),
43
- SliverTileGrid(
44
- children: List.of(
45
- bible.getNewBooks().map((book) {
46
- return TextButton(
47
- child: Text(book.shortName(context.bookNames[book.index])),
48
- onPressed: () => onBookSelected(context, bible, book.index),
49
- );
50
- }),
51
- ),
52
- ),
53
- ],
54
- ),
55
- );
56
- }
57
- }
lib/screens/chapter_select_screen.dart DELETED
@@ -1,38 +0,0 @@
1
- import "package:flutter/material.dart";
2
- import "package:only_bible_app/store/actions_state.dart";
3
- import "package:only_bible_app/store/app_navigator.dart";
4
- import "package:only_bible_app/store/actions_navigation.dart";
5
- import "package:only_bible_app/utils.dart";
6
- import "package:only_bible_app/widgets/scaffold_menu.dart";
7
- import "package:only_bible_app/widgets/sliver_tile_grid.dart";
8
- import "package:only_bible_app/widgets/sliver_heading.dart";
9
-
10
- class ChapterSelectScreen extends StatelessWidget {
11
- final String bibleName;
12
- final int bookIndex;
13
-
14
- const ChapterSelectScreen({super.key, required this.bibleName, required this.bookIndex});
15
-
16
- @override
17
- Widget build(BuildContext context) {
18
- final bible = context.select((s) => s.bible);
19
- final book = bible.books![bookIndex];
20
- return ScaffoldMenu(
21
- child: CustomScrollView(
22
- physics: const BouncingScrollPhysics(),
23
- slivers: [
24
- SliverHeading(title: context.bookNames[book.index], showClose: true),
25
- SliverTileGrid(
26
- children: List.generate(book.chapters!.length, (index) {
27
- return TextButton(
28
- child: Text("${index + 1}"),
29
- onPressed: () =>
30
- context.dispatch(ReplaceBookChapterAction(context.router, bible.name!, bookIndex, index)),
31
- );
32
- }),
33
- ),
34
- ],
35
- ),
36
- );
37
- }
38
- }
lib/screens/chapter_view_screen.dart DELETED
@@ -1,35 +0,0 @@
1
- import "package:flutter/material.dart";
2
- import "package:only_bible_app/utils.dart";
3
- import "package:only_bible_app/widgets/chapter_app_bar.dart";
4
- import "package:only_bible_app/widgets/verses_view.dart";
5
-
6
- class ChapterViewScreen extends StatelessWidget {
7
- final String bibleName;
8
- final int bookIndex;
9
- final int chapterIndex;
10
-
11
- const ChapterViewScreen({
12
- super.key,
13
- required this.bibleName,
14
- required this.bookIndex,
15
- required this.chapterIndex,
16
- });
17
-
18
- @override
19
- Widget build(BuildContext context) {
20
- final bible = context.select((s) => s.bible);
21
- final book = bible.books![bookIndex];
22
- final chapter = book.chapters![chapterIndex];
23
- return Scaffold(
24
- appBar: ChapterAppBar(bible: bible, book: book, chapter: chapter),
25
- backgroundColor: Theme.of(context).colorScheme.surface,
26
- body: SafeArea(
27
- child: Column(
28
- children: [
29
- Expanded(child: VersesView(bible: bible, chapter: chapter)),
30
- ],
31
- ),
32
- ),
33
- );
34
- }
35
- }
lib/screens/webview_screen.dart DELETED
@@ -1,22 +0,0 @@
1
- import "package:flutter/material.dart";
2
- import "package:webview_flutter/webview_flutter.dart";
3
-
4
- class WebViewScreen extends StatelessWidget {
5
- final String url;
6
-
7
- const WebViewScreen({super.key, required this.url});
8
-
9
- @override
10
- Widget build(BuildContext context) {
11
- final controller = WebViewController()
12
- ..setJavaScriptMode(JavaScriptMode.unrestricted)
13
- ..loadRequest(Uri.parse(url));
14
- return Scaffold(
15
- backgroundColor: Theme.of(context).colorScheme.surface,
16
- appBar: AppBar(),
17
- body: SafeArea(
18
- child: WebViewWidget(controller: controller),
19
- ),
20
- );
21
- }
22
- }
lib/store/actions_navigation.dart CHANGED
@@ -1,21 +1,13 @@
1
1
  import "package:app_review/app_review.dart";
2
2
  import "package:async_redux/async_redux.dart";
3
3
  import "package:flutter/material.dart";
4
- import "package:go_router/go_router.dart";
5
4
  import "package:only_bible_app/gen/bible.gen.dart";
6
5
  import "package:only_bible_app/store/actions_state.dart" show audioPlayer;
7
6
  import "package:only_bible_app/store/app_state.dart";
8
7
  import "package:only_bible_app/utils.dart";
9
8
  import "package:only_bible_app/widgets/settings_sheet.dart";
10
- import "package:only_bible_app/widgets/verses_view.dart";
11
9
  import "package:share_plus/share_plus.dart";
12
-
13
- class HideActionsAction extends ReduxAction<AppState> {
10
+ import "package:url_launcher/url_launcher.dart";
14
- @override
15
- AppState? reduce() {
16
- return state.selectedVerses.isEmpty ? null : state.copy(selectedVerses: []);
17
- }
18
- }
19
11
 
20
12
  class ShowSettingsAction extends ReduxAction<AppState> {
21
13
  final BuildContext buildContext;
@@ -37,42 +29,16 @@ class ShowSettingsAction extends ReduxAction<AppState> {
37
29
  }
38
30
  }
39
31
 
40
- class PushBookChapterAction extends ReduxAction<AppState> {
32
+ class GoToChapterAction extends ReduxAction<AppState> {
41
- final GoRouter router;
42
33
  final String bibleName;
43
34
  final int book;
44
35
  final int chapter;
45
- final TextDirection? dir;
46
36
 
47
- PushBookChapterAction(this.router, this.bibleName, this.book, this.chapter, [this.dir]);
37
+ GoToChapterAction(this.bibleName, this.book, this.chapter);
48
38
 
49
39
  @override
50
40
  AppState reduce() {
51
41
  audioPlayer.pause();
52
- router.push(
53
- "/chapter/${Uri.encodeComponent(bibleName)}/$book/$chapter",
54
- extra: dir,
55
- );
56
- return state.copy(
57
- savedBook: book,
58
- savedChapter: chapter,
59
- selectedVerses: [],
60
- );
61
- }
62
- }
63
-
64
- class ReplaceBookChapterAction extends ReduxAction<AppState> {
65
- final GoRouter router;
66
- final String bibleName;
67
- final int book;
68
- final int chapter;
69
-
70
- ReplaceBookChapterAction(this.router, this.bibleName, this.book, this.chapter);
71
-
72
- @override
73
- AppState reduce() {
74
- audioPlayer.pause();
75
- router.go("/chapter/${Uri.encodeComponent(bibleName)}/$book/$chapter");
76
42
  return state.copy(
77
43
  savedBook: book,
78
44
  savedChapter: chapter,
@@ -82,12 +48,11 @@ class ReplaceBookChapterAction extends ReduxAction<AppState> {
82
48
  }
83
49
 
84
50
  class NextChapterAction extends ReduxAction<AppState> {
85
- final GoRouter router;
86
51
  final Bible bible;
87
52
  final int book;
88
53
  final int chapter;
89
54
 
90
- NextChapterAction(this.router, this.bible, this.book, this.chapter);
55
+ NextChapterAction(this.bible, this.book, this.chapter);
91
56
 
92
57
  @override
93
58
  AppState? reduce() {
@@ -106,10 +71,6 @@ class NextChapterAction extends ReduxAction<AppState> {
106
71
 
107
72
  if (newBook == null) return null;
108
73
  audioPlayer.pause();
109
- router.push(
110
- "/chapter/${Uri.encodeComponent(bible.name!)}/$newBook/$newChapter",
111
- extra: TextDirection.ltr,
112
- );
113
74
  return state.copy(
114
75
  savedBook: newBook,
115
76
  savedChapter: newChapter,
@@ -119,12 +80,11 @@ class NextChapterAction extends ReduxAction<AppState> {
119
80
  }
120
81
 
121
82
  class PreviousChapterAction extends ReduxAction<AppState> {
122
- final GoRouter router;
123
83
  final Bible bible;
124
84
  final int book;
125
85
  final int chapter;
126
86
 
127
- PreviousChapterAction(this.router, this.bible, this.book, this.chapter);
87
+ PreviousChapterAction(this.bible, this.book, this.chapter);
128
88
 
129
89
  @override
130
90
  AppState? reduce() {
@@ -143,10 +103,6 @@ class PreviousChapterAction extends ReduxAction<AppState> {
143
103
 
144
104
  if (newBook == null) return null;
145
105
  audioPlayer.pause();
146
- router.push(
147
- "/chapter/${Uri.encodeComponent(bible.name!)}/$newBook/$newChapter",
148
- extra: TextDirection.rtl,
149
- );
150
106
  return state.copy(
151
107
  savedBook: newBook,
152
108
  savedChapter: newChapter,
@@ -155,58 +111,17 @@ class PreviousChapterAction extends ReduxAction<AppState> {
155
111
  }
156
112
  }
157
113
 
158
- class ChangeBibleAction extends ReduxAction<AppState> {
159
- final GoRouter router;
160
-
161
- ChangeBibleAction(this.router);
162
-
163
- @override
164
- AppState? reduce() {
165
- router.push("/bible");
166
- return null;
167
- }
168
- }
169
-
170
- class ChangeBookAction extends ReduxAction<AppState> {
171
- final GoRouter router;
172
- final Bible bible;
173
-
174
- ChangeBookAction(this.router, this.bible);
175
-
176
- @override
177
- AppState? reduce() {
178
- router.push("/books/${Uri.encodeComponent(bible.name!)}");
179
- return null;
180
- }
181
- }
182
-
183
- class ChangeChapterAction extends ReduxAction<AppState> {
184
- final GoRouter router;
185
- final Bible bible;
186
- final Book book;
187
-
188
- ChangeChapterAction(this.router, this.bible, this.book);
189
-
190
- @override
191
- AppState? reduce() {
192
- router.push("/chapters/${Uri.encodeComponent(bible.name!)}/${book.index}");
193
- return null;
194
- }
195
- }
196
-
197
114
  class UpdateCurrentBibleAction extends ReduxAction<AppState> {
198
- final GoRouter router;
199
115
  final String name;
200
116
  final String code;
201
117
  final int book;
202
118
  final int chapter;
203
119
 
204
- UpdateCurrentBibleAction(this.router, this.name, this.code, this.book, this.chapter);
120
+ UpdateCurrentBibleAction(this.name, this.code, this.book, this.chapter);
205
121
 
206
122
  @override
207
123
  Future<AppState> reduce() async {
208
124
  final bible = await loadBible(name);
209
- router.go("/chapter/${Uri.encodeComponent(name)}/$book/$chapter");
210
125
  return state.copy(
211
126
  bibleName: name,
212
127
  languageCode: code,
@@ -218,38 +133,14 @@ class UpdateCurrentBibleAction extends ReduxAction<AppState> {
218
133
  }
219
134
  }
220
135
 
221
- class ShowAboutUsAction extends ReduxAction<AppState> {
136
+ class LaunchUrlAction extends ReduxAction<AppState> {
222
- final GoRouter router;
137
+ final String url;
223
-
224
- ShowAboutUsAction(this.router);
225
-
226
- @override
227
- AppState? reduce() {
228
- router.push("/webview", extra: "https://pyrossh.dev/only-bible-app");
229
- return null;
230
- }
231
- }
232
-
233
- class ShowPrivacyPolicyAction extends ReduxAction<AppState> {
234
- final GoRouter router;
235
-
236
- ShowPrivacyPolicyAction(this.router);
237
-
238
- @override
239
- AppState? reduce() {
240
- router.push("/webview", extra: "https://pyrossh.dev/only-bible-app/privacy-policy");
241
- return null;
242
- }
243
- }
244
-
245
- class ShowTermsAndConditionsAction extends ReduxAction<AppState> {
246
- final GoRouter router;
247
138
 
248
- ShowTermsAndConditionsAction(this.router);
139
+ LaunchUrlAction(this.url);
249
140
 
250
141
  @override
251
142
  AppState? reduce() {
252
- router.push("/webview", extra: "https://pyrossh.dev/only-bible-app/terms-and-conditions");
143
+ launchUrl(Uri.parse(url), mode: LaunchMode.externalApplication);
253
144
  return null;
254
145
  }
255
146
  }
lib/store/actions_state.dart CHANGED
@@ -11,11 +11,6 @@ import "package:only_bible_app/utils.dart";
11
11
 
12
12
  final audioPlayer = AudioPlayer();
13
13
 
14
- class FirstOpenDoneAction extends ReduxAction<AppState> {
15
- @override
16
- AppState reduce() => state.copy(firstOpen: false);
17
- }
18
-
19
14
  class UpdateBibleAction extends ReduxAction<AppState> {
20
15
  final String name;
21
16
  final String code;
@@ -137,7 +132,7 @@ class SetHighlightAction extends ReduxAction<AppState> {
137
132
  for (final v in verses) {
138
133
  updated["${v.book}:${v.chapter}:${v.index}"] = colorIndex;
139
134
  }
140
- return state.copy(highlights: updated);
135
+ return state.copy(highlights: updated, selectedVerses: []);
141
136
  }
142
137
  }
143
138
 
@@ -152,6 +147,6 @@ class RemoveHighlightAction extends ReduxAction<AppState> {
152
147
  for (final v in verses) {
153
148
  updated.remove("${v.book}:${v.chapter}:${v.index}");
154
149
  }
155
- return state.copy(highlights: updated);
150
+ return state.copy(highlights: updated, selectedVerses: []);
156
151
  }
157
152
  }
lib/store/app_navigator.dart DELETED
@@ -1,21 +0,0 @@
1
- import "package:flutter/material.dart";
2
- import "package:go_router/go_router.dart";
3
-
4
- class AppRouterScope extends InheritedWidget {
5
- final GoRouter router;
6
-
7
- const AppRouterScope({
8
- super.key,
9
- required this.router,
10
- required super.child,
11
- });
12
-
13
- static AppRouterScope of(BuildContext context) => context.dependOnInheritedWidgetOfExactType<AppRouterScope>()!;
14
-
15
- @override
16
- bool updateShouldNotify(AppRouterScope old) => false;
17
- }
18
-
19
- extension AppRouterContext on BuildContext {
20
- GoRouter get router => AppRouterScope.of(this).router;
21
- }
lib/store/app_state.dart CHANGED
@@ -3,7 +3,6 @@ import "package:only_bible_app/gen/bible.gen.dart";
3
3
  import "package:only_bible_app/theme.dart";
4
4
 
5
5
  class AppState {
6
- final bool firstOpen;
7
6
  final String languageCode;
8
7
  final String bibleName;
9
8
  final bool engTitles;
@@ -17,7 +16,6 @@ class AppState {
17
16
  final Bible bible;
18
17
 
19
18
  AppState({
20
- this.firstOpen = true,
21
19
  this.languageCode = "en",
22
20
  this.bibleName = "English",
23
21
  this.engTitles = false,
@@ -32,7 +30,6 @@ class AppState {
32
30
  });
33
31
 
34
32
  AppState copy({
35
- bool? firstOpen,
36
33
  String? languageCode,
37
34
  String? bibleName,
38
35
  bool? engTitles,
@@ -46,7 +43,6 @@ class AppState {
46
43
  Bible? bible,
47
44
  }) {
48
45
  return AppState(
49
- firstOpen: firstOpen ?? this.firstOpen,
50
46
  languageCode: languageCode ?? this.languageCode,
51
47
  bibleName: bibleName ?? this.bibleName,
52
48
  engTitles: engTitles ?? this.engTitles,
@@ -62,7 +58,6 @@ class AppState {
62
58
  }
63
59
 
64
60
  Map<String, dynamic> toJson() => {
65
- "firstOpen": firstOpen,
66
61
  "languageCode": languageCode,
67
62
  "bibleName": bibleName,
68
63
  "engTitles": engTitles,
@@ -75,7 +70,6 @@ class AppState {
75
70
  };
76
71
 
77
72
  factory AppState.fromJson(Map<String, dynamic> json, Bible bible) => AppState(
78
- firstOpen: json["firstOpen"] as bool? ?? true,
79
73
  languageCode: json["languageCode"] as String? ?? "en",
80
74
  bibleName: json["bibleName"] as String? ?? "English",
81
75
  engTitles: json["engTitles"] as bool? ?? false,
lib/theme.dart CHANGED
@@ -40,6 +40,7 @@ final lightTheme = ThemeData(
40
40
  brightness: Brightness.light,
41
41
  colorScheme: lightColorScheme,
42
42
  useMaterial3: true,
43
+ applyElevationOverlayColor: false,
43
44
  fontFamily: "Roboto",
44
45
  primaryColor: const Color(0xFF602C2C),
45
46
  primaryColorDark: const Color(0xFF482122),
@@ -172,7 +173,7 @@ final lightTheme = ThemeData(
172
173
  letterSpacing: 0.5,
173
174
  ),
174
175
  labelMedium: TextStyle(
175
- fontSize: 14,
176
+ fontSize: 13,
176
177
  fontWeight: FontWeight.w700,
177
178
  color: lightColorScheme.primary,
178
179
  letterSpacing: 0,
lib/utils.dart CHANGED
@@ -62,7 +62,7 @@ extension AppContext on BuildContext {
62
62
 
63
63
  List<AppLocalizations> get supportedLocalizations {
64
64
  return AppLocalizations.supportedLocales
65
- .sortedBy((e) => e.languageCode)
65
+ .sortedBy((e) => e.languageCode == "en" ? "" : e.languageCode)
66
66
  .map((e) => lookupAppLocalizations(e))
67
67
  .toList();
68
68
  }
lib/widgets/{chapter_app_bar.dart → home_app_bar.dart} RENAMED
@@ -1,16 +1,15 @@
1
1
  import "package:flutter/material.dart";
2
+ import "package:only_bible_app/dialog.dart";
2
3
  import "package:only_bible_app/gen/bible.gen.dart";
3
- import "package:only_bible_app/store/actions_state.dart";
4
- import "package:only_bible_app/store/app_navigator.dart";
5
4
  import "package:only_bible_app/store/actions_navigation.dart";
6
5
  import "package:only_bible_app/utils.dart";
7
6
 
8
- class ChapterAppBar extends StatelessWidget implements PreferredSizeWidget {
7
+ class HomeAppBar extends StatelessWidget implements PreferredSizeWidget {
9
8
  final Bible bible;
10
9
  final Book book;
11
10
  final Chapter chapter;
12
11
 
13
- const ChapterAppBar({
12
+ const HomeAppBar({
14
13
  super.key,
15
14
  required this.book,
16
15
  required this.chapter,
@@ -32,7 +31,7 @@ class ChapterAppBar extends StatelessWidget implements PreferredSizeWidget {
32
31
  children: [
33
32
  InkWell(
34
33
  enableFeedback: true,
35
- onTap: () => context.dispatch(ChangeBookAction(context.router, bible)),
34
+ onTap: () => showBookSelectDialog(context, bible),
36
35
  child: Text(
37
36
  bookName,
38
37
  style: Theme.of(context).textTheme.headlineMedium,
@@ -41,7 +40,7 @@ class ChapterAppBar extends StatelessWidget implements PreferredSizeWidget {
41
40
  ),
42
41
  InkWell(
43
42
  enableFeedback: true,
44
- onTap: () => context.dispatch(ChangeChapterAction(context.router, bible, book)),
43
+ onTap: () => showChapterSelectDialog(context, bible, book),
45
44
  child: Padding(
46
45
  padding: const EdgeInsets.only(left: 16),
47
46
  child: Text(
@@ -57,11 +56,11 @@ class ChapterAppBar extends StatelessWidget implements PreferredSizeWidget {
57
56
  children: [
58
57
  InkWell(
59
58
  enableFeedback: true,
60
- onTap: () => context.dispatch(ChangeBibleAction(context.router)),
59
+ onTap: () => showBibleSelectDialog(context),
61
60
  child: Padding(
62
61
  padding: const EdgeInsets.only(left: 16),
63
62
  child: Text(
64
- context.l.languageTitle,
63
+ context.l.languageCode.toUpperCase(),
65
64
  style: Theme.of(context).textTheme.headlineMedium,
66
65
  key: const Key("bible"),
67
66
  ),
lib/widgets/icon_button_text.dart DELETED
@@ -1,17 +0,0 @@
1
- import "package:flutter/material.dart";
2
-
3
- class IconButtonText extends StatelessWidget {
4
- final Widget leading, trailing;
5
-
6
- const IconButtonText({super.key, required this.leading, required this.trailing});
7
-
8
- @override
9
- Widget build(BuildContext context) {
10
- return Column(
11
- children: [
12
- leading,
13
- trailing,
14
- ],
15
- );
16
- }
17
- }
lib/widgets/menu_overlay.dart CHANGED
@@ -25,7 +25,6 @@ class MenuOverlay extends StatelessWidget {
25
25
  index,
26
26
  ),
27
27
  );
28
- context.dispatch(HideActionsAction());
29
28
  }
30
29
 
31
30
  return Material(
@@ -50,7 +49,6 @@ class MenuOverlay extends StatelessWidget {
50
49
  List<Verse>.from(context.read().selectedVerses),
51
50
  ),
52
51
  );
53
- context.dispatch(HideActionsAction());
54
52
  },
55
53
  icon: Icon(Icons.cancel_outlined, size: 28, color: iconColor),
56
54
  ),
lib/widgets/modal_button.dart DELETED
@@ -1,43 +0,0 @@
1
- import "package:flutter/material.dart";
2
-
3
- class ModalButton extends StatelessWidget {
4
- final VoidCallback onPressed;
5
- final IconData icon;
6
- final String label;
7
-
8
- const ModalButton({super.key, required this.onPressed, required this.icon, required this.label});
9
-
10
- @override
11
- Widget build(BuildContext context) {
12
- final theme = Theme.of(context);
13
- return SizedBox(
14
- width: 100,
15
- child: TextButton.icon(
16
- onPressed: onPressed,
17
- icon: Icon(icon, size: 24, color: theme.colorScheme.primary),
18
- label: Text(
19
- label,
20
- style: const TextStyle(
21
- fontSize: 16,
22
- fontWeight: FontWeight.w500,
23
- letterSpacing: 0,
24
- ),
25
- ),
26
- style: TextButton.styleFrom(
27
- enableFeedback: true,
28
- elevation: 0,
29
- padding: EdgeInsets.zero,
30
- shape: RoundedRectangleBorder(
31
- side: BorderSide(
32
- color: theme.colorScheme.primary,
33
- width: 1,
34
- ),
35
- ),
36
- shadowColor: theme.shadowColor,
37
- backgroundColor: theme.colorScheme.surface,
38
- foregroundColor: theme.colorScheme.primary,
39
- ),
40
- ),
41
- );
42
- }
43
- }
lib/widgets/scaffold_menu.dart DELETED
@@ -1,25 +0,0 @@
1
- import "package:flutter/material.dart";
2
- import "package:only_bible_app/utils.dart";
3
-
4
- class ScaffoldMenu extends StatelessWidget {
5
- final Widget child;
6
- final Color? backgroundColor;
7
-
8
- const ScaffoldMenu({super.key, required this.child, this.backgroundColor});
9
-
10
- @override
11
- Widget build(BuildContext context) {
12
- return Scaffold(
13
- backgroundColor: context.theme.colorScheme.surface,
14
- body: SafeArea(
15
- child: ColoredBox(
16
- color: Colors.black.withOpacity(0.7),
17
- child: ColoredBox(
18
- color: backgroundColor ?? context.theme.colorScheme.surface,
19
- child: child,
20
- ),
21
- ),
22
- ),
23
- );
24
- }
25
- }
lib/widgets/settings_sheet.dart CHANGED
@@ -1,7 +1,6 @@
1
1
  import "package:flutter/material.dart";
2
2
  import "package:only_bible_app/gen/bible.gen.dart";
3
3
  import "package:only_bible_app/store/actions_state.dart";
4
- import "package:only_bible_app/store/app_navigator.dart";
5
4
  import "package:only_bible_app/store/actions_navigation.dart";
6
5
  import "package:only_bible_app/utils.dart";
7
6
  import "package:settings_ui/settings_ui.dart";
@@ -33,12 +32,6 @@ class SettingsSheet extends StatelessWidget {
33
32
  ),
34
33
  margin: const EdgeInsetsDirectional.symmetric(horizontal: 20),
35
34
  tiles: [
36
- SettingsTile.navigation(
37
- leading: const Icon(Icons.book_outlined, color: Colors.blueAccent),
38
- title: Text(context.l.bibleTitle),
39
- value: Text(bible.name!),
40
- onPressed: (_) => context.dispatch(ChangeBibleAction(context.router)),
41
- ),
42
35
  SettingsTile.navigation(
43
36
  leading: const Icon(Icons.color_lens_outlined, color: Colors.green),
44
37
  title: Text(context.l.themeTitle),
@@ -111,49 +104,6 @@ class SettingsSheet extends StatelessWidget {
111
104
  ),
112
105
  ],
113
106
  ),
114
- SettingsSection(
115
- title: Text(
116
- context.l.aboutUsTitle,
117
- style: context.theme.textTheme.headlineMedium,
118
- ),
119
- margin: const EdgeInsetsDirectional.symmetric(
120
- horizontal: 20,
121
- vertical: 20,
122
- ),
123
- tiles: [
124
- SettingsTile.navigation(
125
- leading: const Icon(Icons.policy_outlined, color: Colors.brown),
126
- title: Text(context.l.privacyPolicyTitle),
127
- onPressed: (_) => context.dispatch(ShowPrivacyPolicyAction(context.router)),
128
- ),
129
- SettingsTile.navigation(
130
- leading: const Icon(
131
- Icons.description_outlined,
132
- color: Colors.blueGrey,
133
- ),
134
- title: Text(context.l.termsAndConditionsTitle),
135
- onPressed: (_) => context.dispatch(ShowTermsAndConditionsAction(context.router)),
136
- ),
137
- SettingsTile.navigation(
138
- leading: const Icon(Icons.share_outlined, color: Colors.blueAccent),
139
- title: Text(context.l.shareAppTitle),
140
- onPressed: (_) => context.dispatch(ShareAppLinkAction()),
141
- ),
142
- SettingsTile.navigation(
143
- leading: Icon(Icons.star, color: Colors.yellowAccent.shade700),
144
- title: Text(context.l.rateAppTitle),
145
- onPressed: (_) => context.dispatch(RateAppAction()),
146
- ),
147
- SettingsTile.navigation(
148
- leading: Icon(
149
- Icons.info_outline,
150
- color: context.theme.colorScheme.onSurface,
151
- ),
152
- title: Text(context.l.aboutUsTitle),
153
- onPressed: (_) => context.dispatch(ShowAboutUsAction(context.router)),
154
- ),
155
- ],
156
- ),
157
107
  ],
158
108
  );
159
109
  }
lib/widgets/sliver_heading.dart DELETED
@@ -1,52 +0,0 @@
1
- import "package:flutter/material.dart";
2
- import "package:go_router/go_router.dart";
3
-
4
- class SliverHeading extends StatelessWidget {
5
- final String title;
6
- final bool showClose;
7
- final double top;
8
- final double bottom;
9
-
10
- const SliverHeading({
11
- super.key,
12
- required this.title,
13
- this.showClose = false,
14
- this.top = 0,
15
- this.bottom = 10,
16
- });
17
-
18
- @override
19
- Widget build(BuildContext context) {
20
- return SliverToBoxAdapter(
21
- child: Container(
22
- margin: EdgeInsets.only(top: top, bottom: bottom, left: 20, right: 10),
23
- child: Row(
24
- mainAxisAlignment: MainAxisAlignment.center,
25
- crossAxisAlignment: CrossAxisAlignment.center,
26
- children: [
27
- Expanded(
28
- child: Text(
29
- title,
30
- style: Theme.of(context).textTheme.headlineMedium?.copyWith(
31
- shadows: [
32
- Shadow(
33
- color: Theme.of(context).shadowColor.withOpacity(0.3),
34
- offset: const Offset(1, 1),
35
- ),
36
- ],
37
- ),
38
- ),
39
- ),
40
- if (showClose)
41
- IconButton(
42
- icon: const Icon(Icons.close, size: 26),
43
- onPressed: () {
44
- context.pop();
45
- },
46
- ),
47
- ],
48
- ),
49
- ),
50
- );
51
- }
52
- }
lib/widgets/sliver_tile_grid.dart DELETED
@@ -1,50 +0,0 @@
1
- import "package:flutter/material.dart";
2
-
3
- enum ListType {
4
- small,
5
- large,
6
- extraLarge;
7
-
8
- int crossAxisCount() {
9
- switch (this) {
10
- case ListType.small:
11
- return 5;
12
- case ListType.large:
13
- return 2;
14
- case ListType.extraLarge:
15
- return 2;
16
- }
17
- }
18
-
19
- double childAspectRatio() {
20
- switch (this) {
21
- case ListType.small:
22
- return 1.4;
23
- case ListType.large:
24
- return 4;
25
- case ListType.extraLarge:
26
- return 2.8;
27
- }
28
- }
29
- }
30
-
31
- class SliverTileGrid extends StatelessWidget {
32
- final ListType listType;
33
- final List<Widget> children;
34
-
35
- const SliverTileGrid({super.key, this.listType = ListType.small, required this.children});
36
-
37
- @override
38
- Widget build(BuildContext context) {
39
- return SliverPadding(
40
- padding: const EdgeInsets.symmetric(horizontal: 20),
41
- sliver: SliverGrid.count(
42
- crossAxisCount: listType.crossAxisCount(),
43
- crossAxisSpacing: 12.0,
44
- mainAxisSpacing: 12.0,
45
- childAspectRatio: listType.childAspectRatio(),
46
- children: children,
47
- ),
48
- );
49
- }
50
- }
lib/widgets/verses_view.dart CHANGED
@@ -4,7 +4,6 @@ import "package:only_bible_app/gen/bible.gen.dart";
4
4
  import "package:only_bible_app/store/actions_navigation.dart";
5
5
  import "package:only_bible_app/widgets/menu_overlay.dart";
6
6
  import "package:only_bible_app/store/actions_state.dart";
7
- import "package:only_bible_app/store/app_navigator.dart";
8
7
  import "package:only_bible_app/utils.dart";
9
8
 
10
9
  class VersesView extends StatelessWidget {
@@ -20,14 +19,14 @@ class VersesView extends StatelessWidget {
20
19
  final appState = context.read();
21
20
  final textStyle = DefaultTextStyle.of(context).style;
22
21
  final theme = Theme.of(context).textTheme;
22
+ final baseStyle = boldFont
23
- final baseStyle = boldFont ? textStyle.copyWith(fontWeight: FontWeight.w500) : textStyle;
23
+ ? textStyle.copyWith(fontWeight: FontWeight.w500, fontSize: 16 + textScale)
24
+ : textStyle.copyWith(fontSize: 16 + textScale);
24
25
  return Stack(
25
26
  children: [
26
27
  SwipeDetector(
27
- onSwipeLeft: (offset) =>
28
- context.dispatch(NextChapterAction(context.router, bible, chapter.book, chapter.index)),
28
+ onSwipeLeft: (offset) => context.dispatch(NextChapterAction(bible, chapter.book, chapter.index)),
29
- onSwipeRight: (offset) =>
30
- context.dispatch(PreviousChapterAction(context.router, bible, chapter.book, chapter.index)),
29
+ onSwipeRight: (offset) => context.dispatch(PreviousChapterAction(bible, chapter.book, chapter.index)),
31
30
  child: SingleChildScrollView(
32
31
  physics: const BouncingScrollPhysics(),
33
32
  padding: const EdgeInsets.symmetric(horizontal: 20),
@@ -56,7 +55,6 @@ class VersesView extends StatelessWidget {
56
55
  ),
57
56
  ],
58
57
  ),
59
- textScaler: TextScaler.linear(1.1 + textScale / 2),
60
58
  ),
61
59
  ),
62
60
  ),
pubspec.lock CHANGED
@@ -455,14 +455,6 @@ packages:
455
455
  url: "https://pub.dev"
456
456
  source: hosted
457
457
  version: "2.1.3"
458
- go_router:
459
- dependency: "direct main"
460
- description:
461
- name: go_router
462
- sha256: "7974313e217a7771557add6ff2238acb63f635317c35fa590d348fb238f00896"
463
- url: "https://pub.dev"
464
- source: hosted
465
- version: "17.1.0"
466
458
  graphs:
467
459
  dependency: transitive
468
460
  description:
@@ -1281,38 +1273,6 @@ packages:
1281
1273
  url: "https://pub.dev"
1282
1274
  source: hosted
1283
1275
  version: "1.2.1"
1284
- webview_flutter:
1285
- dependency: "direct main"
1286
- description:
1287
- name: webview_flutter
1288
- sha256: a3da219916aba44947d3a5478b1927876a09781174b5a2b67fa5be0555154bf9
1289
- url: "https://pub.dev"
1290
- source: hosted
1291
- version: "4.13.1"
1292
- webview_flutter_android:
1293
- dependency: transitive
1294
- description:
1295
- name: webview_flutter_android
1296
- sha256: "2a03df01df2fd30b075d1e7f24c28aee593f2e5d5ac4c3c4283c5eda63717b24"
1297
- url: "https://pub.dev"
1298
- source: hosted
1299
- version: "4.10.13"
1300
- webview_flutter_platform_interface:
1301
- dependency: transitive
1302
- description:
1303
- name: webview_flutter_platform_interface
1304
- sha256: "63d26ee3aca7256a83ccb576a50272edd7cfc80573a4305caa98985feb493ee0"
1305
- url: "https://pub.dev"
1306
- source: hosted
1307
- version: "2.14.0"
1308
- webview_flutter_wkwebview:
1309
- dependency: transitive
1310
- description:
1311
- name: webview_flutter_wkwebview
1312
- sha256: "0d85e8bc5db9a7c49f6ff57cbeafc6cd8216ad9c9ebc70b2c4579d955698933a"
1313
- url: "https://pub.dev"
1314
- source: hosted
1315
- version: "3.24.1"
1316
1276
  win32:
1317
1277
  dependency: transitive
1318
1278
  description:
pubspec.yaml CHANGED
@@ -26,9 +26,8 @@ dependencies:
26
26
  package_info_plus: ^9.0.0
27
27
  flutter_azure_tts: ^1.0.0
28
28
  http: ^1.6.0
29
- webview_flutter: ^4.13.1
30
29
  app_review: ^3.0.0
31
- go_router: ^17.1.0
30
+
32
31
  async_redux: ^27.1.1
33
32
  flat_buffers: ^25.9.23
34
33