~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 (31) hide show
  1. android/app/src/main/res/drawable/ic_launcher_background.xml +10 -0
  2. android/app/src/main/res/drawable/ic_launcher_foreground.xml +24 -0
  3. android/app/src/main/res/drawable/ic_launcher_monochrome.xml +24 -0
  4. android/app/src/main/res/mipmap-anydpi/ic_launcher.xml +6 -0
  5. android/app/src/main/res/mipmap-anydpi/ic_launcher_round.xml +6 -0
  6. devtools_options.yaml +2 -0
  7. ios/Runner/Assets.xcassets/AccentColor.colorset/Contents.json +11 -0
  8. ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json +6 -114
  9. ios/Runner/Assets.xcassets/AppIcon.appiconset/[email protected] +0 -0
  10. ios/Runner/Assets.xcassets/AppIcon.appiconset/[email protected] +0 -0
  11. ios/Runner/Assets.xcassets/AppIcon.appiconset/[email protected] +0 -0
  12. ios/Runner/Assets.xcassets/AppIcon.appiconset/[email protected] +0 -0
  13. ios/Runner/Assets.xcassets/AppIcon.appiconset/[email protected] +0 -0
  14. ios/Runner/Assets.xcassets/AppIcon.appiconset/[email protected] +0 -0
  15. ios/Runner/Assets.xcassets/AppIcon.appiconset/[email protected] +0 -0
  16. ios/Runner/Assets.xcassets/AppIcon.appiconset/[email protected] +0 -0
  17. ios/Runner/Assets.xcassets/AppIcon.appiconset/[email protected] +0 -0
  18. ios/Runner/Assets.xcassets/AppIcon.appiconset/[email protected] +0 -0
  19. ios/Runner/Assets.xcassets/AppIcon.appiconset/[email protected] +0 -0
  20. ios/Runner/Assets.xcassets/AppIcon.appiconset/[email protected] +0 -0
  21. ios/Runner/Assets.xcassets/AppIcon.appiconset/[email protected] +0 -0
  22. ios/Runner/Assets.xcassets/AppIcon.appiconset/[email protected] +0 -0
  23. ios/Runner/Assets.xcassets/AppIcon.appiconset/[email protected] +0 -0
  24. ios/Runner/Assets.xcassets/AppIcon.appiconset/app-icon-1024.png +0 -0
  25. lib/app.dart +86 -82
  26. lib/main.dart +5 -1
  27. lib/store/app_navigator.dart +90 -0
  28. screenshots/0x0ss (1).png +0 -0
  29. screenshots/0x0ss (2).png +0 -0
  30. screenshots/0x0ss (3).png +0 -0
  31. screenshots/0x0ss.png +0 -0
android/app/src/main/res/drawable/ic_launcher_background.xml ADDED
@@ -0,0 +1,10 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <vector xmlns:android="http://schemas.android.com/apk/res/android"
3
+ android:width="108dp"
4
+ android:height="108dp"
5
+ android:viewportWidth="108"
6
+ android:viewportHeight="108">
7
+ <path
8
+ android:fillColor="#FFFFFF"
9
+ android:pathData="M0,0h108v108h-108z" />
10
+ </vector>
android/app/src/main/res/drawable/ic_launcher_foreground.xml ADDED
@@ -0,0 +1,24 @@
1
+ <vector xmlns:android="http://schemas.android.com/apk/res/android"
2
+ android:width="108dp"
3
+ android:height="108dp"
4
+ android:viewportWidth="108"
5
+ android:viewportHeight="108">
6
+ <group
7
+ android:scaleX="0.11"
8
+ android:scaleY="0.11"
9
+ android:translateX="26"
10
+ android:translateY="26">
11
+ <path
12
+ android:pathData="m389.57,122.38h-93.69V48.43c0,-22.08 -17.9,-39.98 -39.98,-39.98v0c-22.08,0 -39.98,17.9 -39.98,39.98v73.95h-93.69c-22.08,0 -39.98,17.9 -39.98,39.98v0c0,22.08 17.9,39.98 39.98,39.98h93.69v261.23c0,22.08 17.9,39.98 39.98,39.98v0c22.08,0 39.98,-17.9 39.98,-39.98V202.34h93.69c22.08,0 39.98,-17.9 39.98,-39.98v0c0,-22.08 -17.9,-39.98 -39.98,-39.98z"
13
+ android:fillColor="#FFFCC447"/>
14
+ <path
15
+ android:fillColor="#FF000000"
16
+ android:pathData="M389.67,113.93H304.43V48.43C304.43,21.73 282.7,0 256,0 229.3,0 207.57,21.73 207.57,48.43v65.5H122.33c-26.7,0 -48.43,21.73 -48.43,48.43 0,26.7 21.73,48.43 48.43,48.43h85.24v108.11c0,4.67 8.3,107.72 9.58,29.88 0.08,-4.67 7.32,-30.86 7.32,-95.31V202.34c0,-4.67 -3.78,-8.45 -8.45,-8.45h-93.69c-17.39,0 -31.53,-14.14 -31.53,-31.53 0,-17.39 14.15,-31.53 31.53,-31.53h93.69c4.67,0 8.45,-3.78 8.45,-8.45V48.43c0,-17.39 14.15,-31.53 31.53,-31.53 17.39,0 31.53,14.14 31.53,31.53v73.95c0,4.67 3.78,8.45 8.45,8.45h93.69c17.39,0 31.53,14.15 31.53,31.53 0,17.39 -14.15,31.53 -31.53,31.53h-93.69c-4.67,0 -8.45,3.78 -8.45,8.45V463.57c0,17.39 -14.15,31.53 -31.53,31.53 -17.39,0 -31.53,-14.15 -31.53,-31.53V288.95c0,-4.67 -3.78,-8.45 -8.45,-8.45 -4.67,0 -8.45,3.78 -8.45,8.45v174.62c0,26.7 21.73,48.43 48.43,48.43 26.7,0 48.43,-21.73 48.43,-48.43V210.79h85.24c26.7,0 48.43,-21.73 48.43,-48.43 0,-26.7 -21.73,-48.43 -48.43,-48.43z"/>
17
+ <path
18
+ android:fillColor="#FF000000"
19
+ android:pathData="m388.57,170.81c4.67,0 8.45,-3.78 8.45,-8.45 0,-4.67 -3.78,-8.45 -8.45,-8.45h-52.38c-4.67,0 -8.45,3.78 -8.45,8.45 0,4.67 3.78,8.45 8.45,8.45z"/>
20
+ <path
21
+ android:fillColor="#FF000000"
22
+ android:pathData="m256,32.11c-4.67,0 -8.45,3.78 -8.45,8.45V153.91H123.43c-4.67,0 -8.45,3.78 -8.45,8.45 0,4.67 3.78,8.45 8.45,8.45h124.13v300.64c0,4.67 3.78,8.45 8.45,8.45 4.67,0 8.45,-3.78 8.45,-8.45V170.81h70.66c37.38,0 16.35,-3.78 16.35,-8.45 0,-4.67 30.06,-8.45 -1.68,-8.45H264.45V40.56c-0,-4.67 -3.78,-8.45 -8.45,-8.45z"/>
23
+ </group>
24
+ </vector>
android/app/src/main/res/drawable/ic_launcher_monochrome.xml ADDED
@@ -0,0 +1,24 @@
1
+ <vector xmlns:android="http://schemas.android.com/apk/res/android"
2
+ android:width="108dp"
3
+ android:height="108dp"
4
+ android:viewportWidth="108"
5
+ android:viewportHeight="108">
6
+ <group
7
+ android:scaleX="0.12"
8
+ android:scaleY="0.12"
9
+ android:translateX="23"
10
+ android:translateY="23">
11
+ <path
12
+ android:pathData="m389.57,122.38h-93.69V48.43c0,-22.08 -17.9,-39.98 -39.98,-39.98v0c-22.08,0 -39.98,17.9 -39.98,39.98v73.95h-93.69c-22.08,0 -39.98,17.9 -39.98,39.98v0c0,22.08 17.9,39.98 39.98,39.98h93.69v261.23c0,22.08 17.9,39.98 39.98,39.98v0c22.08,0 39.98,-17.9 39.98,-39.98V202.34h93.69c22.08,0 39.98,-17.9 39.98,-39.98v0c0,-22.08 -17.9,-39.98 -39.98,-39.98z"
13
+ android:fillColor="#FFFFFFFF"/>
14
+ <path
15
+ android:fillColor="#004F55"
16
+ android:pathData="M389.67,113.93H304.43V48.43C304.43,21.73 282.7,0 256,0 229.3,0 207.57,21.73 207.57,48.43v65.5H122.33c-26.7,0 -48.43,21.73 -48.43,48.43 0,26.7 21.73,48.43 48.43,48.43h85.24v108.11c0,4.67 8.3,107.72 9.58,29.88 0.08,-4.67 7.32,-30.86 7.32,-95.31V202.34c0,-4.67 -3.78,-8.45 -8.45,-8.45h-93.69c-17.39,0 -31.53,-14.14 -31.53,-31.53 0,-17.39 14.15,-31.53 31.53,-31.53h93.69c4.67,0 8.45,-3.78 8.45,-8.45V48.43c0,-17.39 14.15,-31.53 31.53,-31.53 17.39,0 31.53,14.14 31.53,31.53v73.95c0,4.67 3.78,8.45 8.45,8.45h93.69c17.39,0 31.53,14.15 31.53,31.53 0,17.39 -14.15,31.53 -31.53,31.53h-93.69c-4.67,0 -8.45,3.78 -8.45,8.45V463.57c0,17.39 -14.15,31.53 -31.53,31.53 -17.39,0 -31.53,-14.15 -31.53,-31.53V288.95c0,-4.67 -3.78,-8.45 -8.45,-8.45 -4.67,0 -8.45,3.78 -8.45,8.45v174.62c0,26.7 21.73,48.43 48.43,48.43 26.7,0 48.43,-21.73 48.43,-48.43V210.79h85.24c26.7,0 48.43,-21.73 48.43,-48.43 0,-26.7 -21.73,-48.43 -48.43,-48.43z"/>
17
+ <path
18
+ android:fillColor="#004F55"
19
+ android:pathData="m388.57,170.81c4.67,0 8.45,-3.78 8.45,-8.45 0,-4.67 -3.78,-8.45 -8.45,-8.45h-52.38c-4.67,0 -8.45,3.78 -8.45,8.45 0,4.67 3.78,8.45 8.45,8.45z"/>
20
+ <path
21
+ android:fillColor="#004F55"
22
+ android:pathData="m256,32.11c-4.67,0 -8.45,3.78 -8.45,8.45V153.91H123.43c-4.67,0 -8.45,3.78 -8.45,8.45 0,4.67 3.78,8.45 8.45,8.45h124.13v300.64c0,4.67 3.78,8.45 8.45,8.45 4.67,0 8.45,-3.78 8.45,-8.45V170.81h70.66c37.38,0 16.35,-3.78 16.35,-8.45 0,-4.67 30.06,-8.45 -1.68,-8.45H264.45V40.56c-0,-4.67 -3.78,-8.45 -8.45,-8.45z"/>
23
+ </group>
24
+ </vector>
android/app/src/main/res/mipmap-anydpi/ic_launcher.xml ADDED
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
3
+ <background android:drawable="@drawable/ic_launcher_background" />
4
+ <foreground android:drawable="@drawable/ic_launcher_foreground" />
5
+ <monochrome android:drawable="@drawable/ic_launcher_monochrome" />
6
+ </adaptive-icon>
android/app/src/main/res/mipmap-anydpi/ic_launcher_round.xml ADDED
@@ -0,0 +1,6 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
3
+ <background android:drawable="@drawable/ic_launcher_background" />
4
+ <foreground android:drawable="@drawable/ic_launcher_foreground" />
5
+ <monochrome android:drawable="@drawable/ic_launcher_foreground" />
6
+ </adaptive-icon>
devtools_options.yaml CHANGED
@@ -1,3 +1,5 @@
1
1
  description: This file stores settings for Dart & Flutter DevTools.
2
2
  documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states
3
3
  extensions:
4
+ l10n:
5
+ enabled: true
ios/Runner/Assets.xcassets/AccentColor.colorset/Contents.json ADDED
@@ -0,0 +1,11 @@
1
+ {
2
+ "colors" : [
3
+ {
4
+ "idiom" : "universal"
5
+ }
6
+ ],
7
+ "info" : {
8
+ "author" : "xcode",
9
+ "version" : 1
10
+ }
11
+ }
ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json CHANGED
@@ -1,122 +1,14 @@
1
1
  {
2
2
  "images" : [
3
3
  {
4
- "size" : "20x20",
5
- "idiom" : "iphone",
6
- "filename" : "Icon-App-20x20@2x.png",
4
+ "filename" : "app-icon-1024.png",
7
- "scale" : "2x"
8
- },
9
- {
10
- "size" : "20x20",
11
- "idiom" : "iphone",
12
- "filename" : "[email protected]",
13
- "scale" : "3x"
14
- },
15
- {
16
- "size" : "29x29",
17
- "idiom" : "iphone",
18
- "filename" : "[email protected]",
19
- "scale" : "1x"
20
- },
21
- {
22
- "size" : "29x29",
23
- "idiom" : "iphone",
24
- "filename" : "[email protected]",
25
- "scale" : "2x"
26
- },
27
- {
28
- "size" : "29x29",
29
- "idiom" : "iphone",
30
- "filename" : "[email protected]",
31
- "scale" : "3x"
32
- },
33
- {
34
- "size" : "40x40",
35
- "idiom" : "iphone",
36
- "filename" : "[email protected]",
37
- "scale" : "2x"
38
- },
39
- {
40
- "size" : "40x40",
41
- "idiom" : "iphone",
42
- "filename" : "[email protected]",
43
- "scale" : "3x"
44
- },
45
- {
46
- "size" : "60x60",
47
- "idiom" : "iphone",
48
- "filename" : "[email protected]",
49
- "scale" : "2x"
50
- },
51
- {
52
- "size" : "60x60",
53
- "idiom" : "iphone",
54
- "filename" : "[email protected]",
55
- "scale" : "3x"
56
- },
57
- {
58
- "size" : "20x20",
59
- "idiom" : "ipad",
5
+ "idiom" : "universal",
60
- "filename" : "[email protected]",
61
- "scale" : "1x"
62
- },
63
- {
64
- "size" : "20x20",
65
- "idiom" : "ipad",
6
+ "platform" : "ios",
66
- "filename" : "[email protected]",
67
- "scale" : "2x"
68
- },
69
- {
70
- "size" : "29x29",
71
- "idiom" : "ipad",
72
- "filename" : "[email protected]",
73
- "scale" : "1x"
74
- },
75
- {
76
- "size" : "29x29",
77
- "idiom" : "ipad",
78
- "filename" : "[email protected]",
79
- "scale" : "2x"
80
- },
81
- {
82
- "size" : "40x40",
83
- "idiom" : "ipad",
84
- "filename" : "[email protected]",
85
- "scale" : "1x"
86
- },
87
- {
88
- "size" : "40x40",
89
- "idiom" : "ipad",
90
- "filename" : "[email protected]",
91
- "scale" : "2x"
92
- },
93
- {
94
- "size" : "76x76",
95
- "idiom" : "ipad",
96
- "filename" : "[email protected]",
97
- "scale" : "1x"
98
- },
99
- {
100
- "size" : "76x76",
101
- "idiom" : "ipad",
102
- "filename" : "[email protected]",
103
- "scale" : "2x"
104
- },
105
- {
106
- "size" : "83.5x83.5",
107
- "idiom" : "ipad",
108
- "filename" : "[email protected]",
109
- "scale" : "2x"
110
- },
111
- {
112
- "size" : "1024x1024",
7
+ "size" : "1024x1024"
113
- "idiom" : "ios-marketing",
114
- "filename" : "[email protected]",
115
- "scale" : "1x"
116
8
  }
117
9
  ],
118
10
  "info" : {
119
- "version" : 1,
120
- "author" : "xcode"
11
+ "author" : "xcode",
12
+ "version" : 1
121
13
  }
122
14
  }
ios/Runner/Assets.xcassets/AppIcon.appiconset/[email protected] DELETED
Binary file
ios/Runner/Assets.xcassets/AppIcon.appiconset/[email protected] DELETED
Binary file
ios/Runner/Assets.xcassets/AppIcon.appiconset/[email protected] DELETED
Binary file
ios/Runner/Assets.xcassets/AppIcon.appiconset/[email protected] DELETED
Binary file
ios/Runner/Assets.xcassets/AppIcon.appiconset/[email protected] DELETED
Binary file
ios/Runner/Assets.xcassets/AppIcon.appiconset/[email protected] DELETED
Binary file
ios/Runner/Assets.xcassets/AppIcon.appiconset/[email protected] DELETED
Binary file
ios/Runner/Assets.xcassets/AppIcon.appiconset/[email protected] DELETED
Binary file
ios/Runner/Assets.xcassets/AppIcon.appiconset/[email protected] DELETED
Binary file
ios/Runner/Assets.xcassets/AppIcon.appiconset/[email protected] DELETED
Binary file
ios/Runner/Assets.xcassets/AppIcon.appiconset/[email protected] DELETED
Binary file
ios/Runner/Assets.xcassets/AppIcon.appiconset/[email protected] DELETED
Binary file
ios/Runner/Assets.xcassets/AppIcon.appiconset/[email protected] DELETED
Binary file
ios/Runner/Assets.xcassets/AppIcon.appiconset/[email protected] DELETED
Binary file
ios/Runner/Assets.xcassets/AppIcon.appiconset/[email protected] DELETED
Binary file
ios/Runner/Assets.xcassets/AppIcon.appiconset/app-icon-1024.png ADDED
Binary file
lib/app.dart CHANGED
@@ -2,12 +2,12 @@ import "package:async_redux/async_redux.dart";
2
2
  import "package:flutter/material.dart";
3
3
  import "package:go_router/go_router.dart";
4
4
  import "package:only_bible_app/gen/l10n/app_localizations.dart";
5
- import "package:only_bible_app/store/app_navigator.dart";
6
5
  import "package:only_bible_app/screens/bible_select_screen.dart";
7
6
  import "package:only_bible_app/screens/book_select_screen.dart";
8
7
  import "package:only_bible_app/screens/chapter_select_screen.dart";
9
8
  import "package:only_bible_app/screens/chapter_view_screen.dart";
10
9
  import "package:only_bible_app/screens/webview_screen.dart";
10
+ import "package:only_bible_app/store/app_navigator.dart";
11
11
  import "package:only_bible_app/store/app_state.dart";
12
12
  import "package:only_bible_app/theme.dart";
13
13
  import "package:only_bible_app/utils.dart";
@@ -15,7 +15,90 @@ import "package:only_bible_app/utils.dart";
15
15
  class App extends StatelessWidget {
16
16
  final GlobalKey<NavigatorState> globalNavigatorKey;
17
17
  final Store<AppState> store;
18
+ late final GoRouter _router;
19
+
18
- const App({super.key, required this.globalNavigatorKey, required this.store});
20
+ App({super.key, required this.globalNavigatorKey, required this.store}) {
21
+ final s = store.state;
22
+ _router = GoRouter(
23
+ navigatorKey: globalNavigatorKey,
24
+ initialLocation:
25
+ s.firstOpen ? "/bible" : "/chapter/${Uri.encodeComponent(s.bibleName)}/${s.savedBook}/${s.savedChapter}",
26
+ routes: [
27
+ GoRoute(
28
+ path: "/bible",
29
+ pageBuilder: (context, state) => const NoTransitionPage(
30
+ child: BibleSelectScreen(),
31
+ ),
32
+ ),
33
+ GoRoute(
34
+ path: "/chapter/:bibleName/:bookIndex/:chapterIndex",
35
+ pageBuilder: (context, state) {
36
+ final bibleName = Uri.decodeComponent(state.pathParameters["bibleName"]!);
37
+ final bookIndex = int.parse(state.pathParameters["bookIndex"]!);
38
+ final chapterIndex = int.parse(state.pathParameters["chapterIndex"]!);
39
+ final slideDir = state.extra as TextDirection?;
40
+ if (slideDir != null) {
41
+ return CustomTransitionPage(
42
+ key: state.pageKey,
43
+ child: ChapterViewScreen(
44
+ bibleName: bibleName,
45
+ bookIndex: bookIndex,
46
+ chapterIndex: chapterIndex,
47
+ ),
48
+ transitionsBuilder: (context, animation, secondaryAnimation, child) {
49
+ const begin = Offset(1.0, 0.0);
50
+ const end = Offset.zero;
51
+ const curve = Curves.ease;
52
+ final tween = Tween(begin: begin, end: end).chain(CurveTween(curve: curve));
53
+ return SlideTransition(
54
+ textDirection: slideDir,
55
+ position: animation.drive(tween),
56
+ child: child,
57
+ );
58
+ },
59
+ );
60
+ }
61
+ return NoTransitionPage(
62
+ key: state.pageKey,
63
+ child: ChapterViewScreen(
64
+ bibleName: bibleName,
65
+ bookIndex: bookIndex,
66
+ chapterIndex: chapterIndex,
67
+ ),
68
+ );
69
+ },
70
+ ),
71
+ GoRoute(
72
+ path: "/books/:bibleName",
73
+ pageBuilder: (context, state) {
74
+ final bibleName = Uri.decodeComponent(state.pathParameters["bibleName"]!);
75
+ return NoTransitionPage(
76
+ child: BookSelectScreen(bibleName: bibleName),
77
+ );
78
+ },
79
+ ),
80
+ GoRoute(
81
+ path: "/chapters/:bibleName/:bookIndex",
82
+ pageBuilder: (context, state) {
83
+ final bibleName = Uri.decodeComponent(state.pathParameters["bibleName"]!);
84
+ final bookIndex = int.parse(state.pathParameters["bookIndex"]!);
85
+ return NoTransitionPage(
86
+ child: ChapterSelectScreen(bibleName: bibleName, bookIndex: bookIndex),
87
+ );
88
+ },
89
+ ),
90
+ GoRoute(
91
+ path: "/webview",
92
+ pageBuilder: (context, state) {
93
+ final url = state.extra as String;
94
+ return NoTransitionPage(
95
+ child: WebViewScreen(url: url),
96
+ );
97
+ },
98
+ ),
99
+ ],
100
+ );
101
+ }
19
102
 
20
103
  @override
21
104
  Widget build(BuildContext context) {
@@ -26,86 +109,7 @@ class App extends StatelessWidget {
26
109
  child: StoreConnector<AppState, _AppVm>(
27
110
  vm: () => _AppVmFactory(),
28
111
  builder: (context, vm) => MaterialApp.router(
29
- routerConfig: GoRouter(
112
+ routerConfig: _router,
30
- navigatorKey: globalNavigatorKey,
31
- initialLocation: context.state.firstOpen
32
- ? "/bible"
33
- : "/chapter/${Uri.encodeComponent(context.state.bibleName)}/${context.state.savedBook}/${context.state.savedChapter}",
34
- routes: [
35
- GoRoute(
36
- path: "/bible",
37
- pageBuilder: (context, state) => const NoTransitionPage(
38
- child: BibleSelectScreen(),
39
- ),
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,
55
- ),
56
- transitionsBuilder: (context, animation, secondaryAnimation, child) {
57
- const begin = Offset(1.0, 0.0);
58
- const end = Offset.zero;
59
- const curve = Curves.ease;
60
- final tween = Tween(begin: begin, end: end).chain(CurveTween(curve: curve));
61
- return SlideTransition(
62
- textDirection: slideDir,
63
- position: animation.drive(tween),
64
- child: child,
65
- );
66
- },
67
- );
68
- }
69
- return NoTransitionPage(
70
- key: state.pageKey,
71
- child: ChapterViewScreen(
72
- bibleName: bibleName,
73
- bookIndex: bookIndex,
74
- chapterIndex: chapterIndex,
75
- ),
76
- );
77
- },
78
- ),
79
- GoRoute(
80
- path: "/books/:bibleName",
81
- pageBuilder: (context, state) {
82
- final bibleName = Uri.decodeComponent(state.pathParameters["bibleName"]!);
83
- return NoTransitionPage(
84
- child: BookSelectScreen(bibleName: bibleName),
85
- );
86
- },
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),
95
- );
96
- },
97
- ),
98
- GoRoute(
99
- path: "/webview",
100
- pageBuilder: (context, state) {
101
- final url = state.extra as String;
102
- return NoTransitionPage(
103
- child: WebViewScreen(url: url),
104
- );
105
- },
106
- ),
107
- ],
108
- ),
109
113
  onGenerateTitle: (context) => context.l.title,
110
114
  localizationsDelegates: AppLocalizations.localizationsDelegates,
111
115
  supportedLocales: AppLocalizations.supportedLocales,
lib/main.dart CHANGED
@@ -74,6 +74,10 @@ void main() async {
74
74
  );
75
75
  updateStatusBar(store.state.darkMode);
76
76
  await store.dispatchAndWait(LoadBibleAction());
77
+ final navigator = AppNavigator(
78
+ navigatorKey: globalNavigatorKey,
79
+ initialState: store.state,
80
+ );
77
- runApp(App(globalNavigatorKey: globalNavigatorKey, store: store));
81
+ runApp(App(store: store, navigator: navigator));
78
82
  FlutterNativeSplash.remove();
79
83
  }
lib/store/app_navigator.dart CHANGED
@@ -2,6 +2,11 @@ import "package:flutter/material.dart";
2
2
  import "package:app_review/app_review.dart";
3
3
  import "package:go_router/go_router.dart";
4
4
  import "package:only_bible_app/gen/bible.gen.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";
5
10
  import "package:only_bible_app/sheets/actions_sheet.dart";
6
11
  import "package:only_bible_app/sheets/settings_sheet.dart";
7
12
  import "package:only_bible_app/store/actions.dart";
@@ -31,8 +36,93 @@ extension AppNavigatorContext on BuildContext {
31
36
  }
32
37
 
33
38
  class AppNavigator {
39
+ final GoRouter router;
34
40
  OverlayEntry? _actionsOverlay;
35
41
 
42
+ AppNavigator({
43
+ required GlobalKey<NavigatorState> navigatorKey,
44
+ required AppState initialState,
45
+ }) : router = GoRouter(
46
+ navigatorKey: navigatorKey,
47
+ initialLocation: initialState.firstOpen
48
+ ? "/bible"
49
+ : "/chapter/${Uri.encodeComponent(initialState.bibleName)}/${initialState.savedBook}/${initialState.savedChapter}",
50
+ routes: [
51
+ GoRoute(
52
+ path: "/bible",
53
+ pageBuilder: (context, state) => const NoTransitionPage(
54
+ child: BibleSelectScreen(),
55
+ ),
56
+ ),
57
+ GoRoute(
58
+ path: "/chapter/:bibleName/:bookIndex/:chapterIndex",
59
+ pageBuilder: (context, state) {
60
+ final bibleName = Uri.decodeComponent(state.pathParameters["bibleName"]!);
61
+ final bookIndex = int.parse(state.pathParameters["bookIndex"]!);
62
+ final chapterIndex = int.parse(state.pathParameters["chapterIndex"]!);
63
+ final slideDir = state.extra as TextDirection?;
64
+ if (slideDir != null) {
65
+ return CustomTransitionPage(
66
+ key: state.pageKey,
67
+ child: ChapterViewScreen(
68
+ bibleName: bibleName,
69
+ bookIndex: bookIndex,
70
+ chapterIndex: chapterIndex,
71
+ ),
72
+ transitionsBuilder: (context, animation, secondaryAnimation, child) {
73
+ const begin = Offset(1.0, 0.0);
74
+ const end = Offset.zero;
75
+ const curve = Curves.ease;
76
+ final tween = Tween(begin: begin, end: end).chain(CurveTween(curve: curve));
77
+ return SlideTransition(
78
+ textDirection: slideDir,
79
+ position: animation.drive(tween),
80
+ child: child,
81
+ );
82
+ },
83
+ );
84
+ }
85
+ return NoTransitionPage(
86
+ key: state.pageKey,
87
+ child: ChapterViewScreen(
88
+ bibleName: bibleName,
89
+ bookIndex: bookIndex,
90
+ chapterIndex: chapterIndex,
91
+ ),
92
+ );
93
+ },
94
+ ),
95
+ GoRoute(
96
+ path: "/books/:bibleName",
97
+ pageBuilder: (context, state) {
98
+ final bibleName = Uri.decodeComponent(state.pathParameters["bibleName"]!);
99
+ return NoTransitionPage(
100
+ child: BookSelectScreen(bibleName: bibleName),
101
+ );
102
+ },
103
+ ),
104
+ GoRoute(
105
+ path: "/chapters/:bibleName/:bookIndex",
106
+ pageBuilder: (context, state) {
107
+ final bibleName = Uri.decodeComponent(state.pathParameters["bibleName"]!);
108
+ final bookIndex = int.parse(state.pathParameters["bookIndex"]!);
109
+ return NoTransitionPage(
110
+ child: ChapterSelectScreen(bibleName: bibleName, bookIndex: bookIndex),
111
+ );
112
+ },
113
+ ),
114
+ GoRoute(
115
+ path: "/webview",
116
+ pageBuilder: (context, state) {
117
+ final url = state.extra as String;
118
+ return NoTransitionPage(
119
+ child: WebViewScreen(url: url),
120
+ );
121
+ },
122
+ ),
123
+ ],
124
+ );
125
+
36
126
  String _chapterPath(String bibleName, int book, int chapter) {
37
127
  return "/chapter/${Uri.encodeComponent(bibleName)}/$book/$chapter";
38
128
  }
screenshots/0x0ss (1).png ADDED
Binary file
screenshots/0x0ss (2).png ADDED
Binary file
screenshots/0x0ss (3).png ADDED
Binary file
screenshots/0x0ss.png ADDED
Binary file