~repos /only-bible-app

#kotlin#android#ios

git clone https://pyrossh.dev/repos/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.


0ad8d9db pyrossh

2 years ago
remove reactive
lib/app.dart CHANGED
@@ -1,6 +1,5 @@
1
1
  import "package:flutter/material.dart";
2
2
  import "package:flutter_gen/gen_l10n/app_localizations.dart";
3
- import "package:flutter_reactive_value/flutter_reactive_value.dart";
4
3
  import "package:only_bible_app/screens/chapter_view_screen.dart";
5
4
  import "package:only_bible_app/state.dart";
6
5
  import "package:only_bible_app/theme.dart";
@@ -13,12 +12,13 @@ class App extends StatelessWidget {
13
12
 
14
13
  @override
15
14
  Widget build(BuildContext context) {
15
+ final model = AppModel.of(context);
16
16
  return MaterialApp(
17
17
  title: "Only Bible App",
18
18
  localizationsDelegates: AppLocalizations.localizationsDelegates,
19
19
  supportedLocales: AppLocalizations.supportedLocales,
20
20
  debugShowCheckedModeBanner: false,
21
- themeMode: darkMode.reactiveValue(context) ? ThemeMode.dark : ThemeMode.light,
21
+ themeMode: model.darkMode ? ThemeMode.dark : ThemeMode.light,
22
22
  theme: lightTheme,
23
23
  darkTheme: darkTheme,
24
24
  home: ChapterViewScreen(book: initialBook, chapter: initialChapter),
lib/main.dart CHANGED
@@ -4,7 +4,6 @@ import "package:firebase_core/firebase_core.dart";
4
4
 
5
5
  // import 'package:firebase_crashlytics/firebase_crashlytics.dart';
6
6
  import "package:only_bible_app/options.dart";
7
- import "package:flutter_persistent_value_notifier/flutter_persistent_value_notifier.dart";
8
7
  import "package:flutter_native_splash/flutter_native_splash.dart";
9
8
  import "package:only_bible_app/state.dart";
10
9
  import "package:only_bible_app/app.dart";
@@ -30,12 +29,11 @@ void main() async {
30
29
  // return true;
31
30
  // };
32
31
  FlutterNativeSplash.preserve(widgetsBinding: widgetsBinding);
33
- await initPersistentValueNotifier();
32
+ final model = AppModel();
34
- final (bible, book, chapter, darkMode, fontBold) = await loadData();
33
+ final (book, chapter) = await model.loadData();
35
- await updateStatusBar();
36
34
  runApp(
37
35
  ChangeNotifierProvider(
38
- create: (context) => AppModel(bible: bible, darkMode: darkMode, fontBold: fontBold),
36
+ create: (context) => model,
39
37
  child: App(initialBook: book, initialChapter: chapter),
40
38
  ),
41
39
  );
lib/screens/chapter_view_screen.dart CHANGED
@@ -1,5 +1,4 @@
1
1
  import "package:flutter/material.dart";
2
- import "package:flutter_reactive_value/flutter_reactive_value.dart";
3
2
  import "package:flutter_swipe_detector/flutter_swipe_detector.dart";
4
3
  import "package:only_bible_app/widgets/actions_bar.dart";
5
4
  import "package:only_bible_app/widgets/header.dart";
lib/state.dart CHANGED
@@ -2,7 +2,6 @@ import "dart:convert";
2
2
  import "package:flutter/foundation.dart" show defaultTargetPlatform, TargetPlatform;
3
3
  import "package:flutter/services.dart";
4
4
  import "package:flutter/material.dart";
5
- import "package:flutter_persistent_value_notifier/flutter_persistent_value_notifier.dart";
6
5
  import "package:just_audio/just_audio.dart";
7
6
  import "package:only_bible_app/screens/chapter_view_screen.dart";
8
7
  import "package:only_bible_app/utils/dialog.dart";
@@ -11,14 +10,11 @@ import "package:provider/provider.dart";
11
10
  import "package:shared_preferences/shared_preferences.dart";
12
11
 
13
12
  class AppModel extends ChangeNotifier {
14
- final Bible bible;
13
+ Bible bible = bibles.first;
15
- bool darkMode;
16
- bool fontBold;
17
- bool isPlaying = false;
14
+ bool darkMode = false;
15
+ bool fontBold = false;
18
16
  int fontSizeDelta = 0;
19
17
 
20
- AppModel({required this.bible, this.darkMode = false, this.fontBold = false});
21
-
22
18
  static AppModel of(BuildContext context) {
23
19
  return Provider.of(context, listen: true);
24
20
  }
@@ -34,6 +30,26 @@ class AppModel extends ChangeNotifier {
34
30
  // save fontBold
35
31
  }
36
32
 
33
+ Future<(int, int)> loadData() async {
34
+ final prefs = await SharedPreferences.getInstance();
35
+ final bibleId = prefs.getInt("bibleId") ?? 1;
36
+ darkMode = prefs.getBool("darkMode") ?? false;
37
+ fontBold = prefs.getBool("fontBold") ?? false;
38
+ fontSizeDelta = prefs.getInt("fontSizeDelta") ?? 0;
39
+ final selectedBible = bibles.firstWhere((it) => it.id == bibleId);
40
+ final books = await getBibleFromAsset(selectedBible.name);
41
+ bible = Bible.withBooks(
42
+ id: selectedBible.id,
43
+ name: selectedBible.name,
44
+ books: books,
45
+ );
46
+ // await Future.delayed(Duration(seconds: 3));
47
+ final book = prefs.getInt("book") ?? 0;
48
+ final chapter = prefs.getInt("chapter") ?? 0;
49
+ updateStatusBar();
50
+ return (book, chapter);
51
+ }
52
+
37
53
  // changeBible() {
38
54
  // save();
39
55
  // }
@@ -41,6 +57,49 @@ class AppModel extends ChangeNotifier {
41
57
  // final Future<Bible>
42
58
  // load() {
43
59
  // }
60
+
61
+ toggleMode() async {
62
+ darkMode = !darkMode;
63
+ updateStatusBar();
64
+ notifyListeners();
65
+ (await SharedPreferences.getInstance()).setBool("darkMode", darkMode);
66
+ }
67
+
68
+ updateStatusBar() {
69
+ if (darkMode) {
70
+ SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle(
71
+ systemNavigationBarColor: Color(0xFF1F1F22),
72
+ statusBarColor: Color(0xFF1F1F22),
73
+ systemNavigationBarIconBrightness: Brightness.light,
74
+ statusBarIconBrightness: Brightness.light,
75
+ ));
76
+ } else {
77
+ SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle(
78
+ systemNavigationBarColor: Colors.white,
79
+ statusBarColor: Colors.white,
80
+ systemNavigationBarIconBrightness: Brightness.dark,
81
+ statusBarIconBrightness: Brightness.dark,
82
+ ));
83
+ }
84
+ }
85
+
86
+ toggleBold() async {
87
+ fontBold = !fontBold;
88
+ notifyListeners();
89
+ (await SharedPreferences.getInstance()).setBool("fontBold", fontBold);
90
+ }
91
+
92
+ increaseFont() async {
93
+ fontSizeDelta += 1;
94
+ notifyListeners();
95
+ (await SharedPreferences.getInstance()).setInt("fontSizeDelta", fontSizeDelta);
96
+ }
97
+
98
+ decreaseFont() async {
99
+ fontSizeDelta -= 1;
100
+ notifyListeners();
101
+ (await SharedPreferences.getInstance()).setInt("fontSizeDelta", fontSizeDelta);
102
+ }
44
103
  }
45
104
 
46
105
  class ChapterViewModel extends ChangeNotifier {
@@ -48,6 +107,7 @@ class ChapterViewModel extends ChangeNotifier {
48
107
  final int chapter;
49
108
  final List<int> selectedVerses;
50
109
  final player = AudioPlayer();
110
+ bool isPlaying = false;
51
111
 
52
112
  static ChapterViewModel of(BuildContext context) {
53
113
  return Provider.of(context, listen: true);
@@ -88,12 +148,14 @@ class ChapterViewModel extends ChangeNotifier {
88
148
  onPlay(BuildContext context) async {
89
149
  final bibleModel = AppModel.ofEvent(context);
90
150
  final model = ChapterViewModel.ofEvent(context);
91
- if (isPlaying.value) {
151
+ if (isPlaying) {
92
152
  await player.pause();
93
- isPlaying.value = false;
153
+ isPlaying = false;
154
+ notifyListeners();
94
155
  } else {
95
156
  try {
96
- isPlaying.value = true;
157
+ isPlaying = true;
158
+ notifyListeners();
97
159
  for (final v in selectedVerses) {
98
160
  final bibleName = bibleModel.bible.name;
99
161
  final book = (model.book + 1).toString().padLeft(2, "0");
@@ -111,43 +173,13 @@ class ChapterViewModel extends ChangeNotifier {
111
173
  showError(context, "Could not play audio");
112
174
  } finally {
113
175
  await player.pause();
114
- isPlaying.value = false;
176
+ isPlaying = false;
177
+ notifyListeners();
115
178
  }
116
179
  }
117
180
  }
118
181
  }
119
182
 
120
- Future<(Bible, int, int, bool, bool)> loadData() async {
121
- final prefs = await SharedPreferences.getInstance();
122
- final bibleId = prefs.getInt("bibleId") ?? 1;
123
- final book = prefs.getInt("book") ?? 0;
124
- final chapter = prefs.getInt("chapter") ?? 0;
125
- final darkMode = prefs.getBool("darkMode") ?? false;
126
- final fontBold = prefs.getBool("fontBold") ?? false;
127
- final selectedBible = bibles.firstWhere((it) => it.id == bibleId);
128
- final books = await getBibleFromAsset(selectedBible.name);
129
- final loadedBible = Bible.withBooks(
130
- id: selectedBible.id,
131
- name: selectedBible.name,
132
- books: books,
133
- );
134
- // await Future.delayed(Duration(seconds: 3));
135
- return (loadedBible, book, chapter, darkMode, fontBold);
136
- }
137
-
138
- final darkMode = PersistentValueNotifier<bool>(
139
- sharedPreferencesKey: "darkMode",
140
- initialValue: false,
141
- );
142
-
143
- final fontBold = PersistentValueNotifier<bool>(
144
- sharedPreferencesKey: "fontBold",
145
- initialValue: false,
146
- );
147
-
148
- final isPlaying = ValueNotifier(false);
149
- final fontSizeDelta = ValueNotifier(0);
150
-
151
183
  bool isWide(BuildContext context) {
152
184
  if (defaultTargetPlatform == TargetPlatform.android || defaultTargetPlatform == TargetPlatform.iOS) {
153
185
  return false;
@@ -156,41 +188,6 @@ bool isWide(BuildContext context) {
156
188
  return width > 600;
157
189
  }
158
190
 
159
- toggleMode() {
160
- darkMode.value = !darkMode.value;
161
- updateStatusBar();
162
- }
163
-
164
- toggleBold() {
165
- fontBold.value = !fontBold.value;
166
- }
167
-
168
- increaseFont() {
169
- fontSizeDelta.value += 1;
170
- }
171
-
172
- decreaseFont() {
173
- fontSizeDelta.value -= 1;
174
- }
175
-
176
- updateStatusBar() {
177
- if (darkMode.value) {
178
- SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle(
179
- systemNavigationBarColor: Color(0xFF1F1F22),
180
- statusBarColor: Color(0xFF1F1F22),
181
- systemNavigationBarIconBrightness: Brightness.light,
182
- statusBarIconBrightness: Brightness.light,
183
- ));
184
- } else {
185
- SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle(
186
- systemNavigationBarColor: Colors.white,
187
- statusBarColor: Colors.white,
188
- systemNavigationBarIconBrightness: Brightness.dark,
189
- statusBarIconBrightness: Brightness.dark,
190
- ));
191
- }
192
- }
193
-
194
191
  changeBible(BuildContext context, int i) {
195
192
  // TODO: maybe use a future as the bible needs to load
196
193
  // loadBible();
lib/widgets/menu.dart CHANGED
@@ -1,5 +1,4 @@
1
1
  import "package:flutter/material.dart";
2
- import "package:flutter_reactive_value/flutter_reactive_value.dart";
3
2
  import "package:only_bible_app/state.dart";
4
3
 
5
4
  class Menu extends StatelessWidget {
@@ -19,34 +18,32 @@ class Menu extends StatelessWidget {
19
18
  value: 1,
20
19
  child: StatefulBuilder(
21
20
  builder: (BuildContext menuContext, StateSetter setState) {
21
+ final model = AppModel.of(context);
22
- final modeIcon = darkMode.reactiveValue(menuContext) ? Icons.dark_mode : Icons.light_mode;
22
+ final modeIcon = model.darkMode ? Icons.dark_mode : Icons.light_mode;
23
- final boldColor = fontBold.reactiveValue(menuContext) ? Colors.red : Colors.grey;
23
+ final boldColor = model.fontBold ? Colors.red : Colors.grey;
24
24
  return Column(
25
25
  crossAxisAlignment: CrossAxisAlignment.center,
26
26
  mainAxisAlignment: MainAxisAlignment.center,
27
27
  children: [
28
28
  IconButton(
29
29
  icon: Icon(modeIcon, size: 28),
30
- onPressed: toggleMode,
30
+ onPressed: model.toggleMode,
31
31
  ),
32
32
  Container(margin: const EdgeInsets.only(top: spacing)),
33
33
  // TODO: figure out bold active/inactive color
34
- const IconButton(
34
+ IconButton(
35
- icon: Icon(Icons.format_bold, size: 28),
35
+ icon: const Icon(Icons.format_bold, size: 28),
36
- onPressed: toggleBold,
36
+ onPressed: model.toggleBold,
37
37
  ),
38
38
  Container(margin: const EdgeInsets.only(top: spacing)),
39
- const IconButton(
39
+ IconButton(
40
- icon: Icon(Icons.add_circle, size: 28),
40
+ icon: const Icon(Icons.add_circle, size: 28),
41
- onPressed: increaseFont,
41
+ onPressed: model.increaseFont,
42
42
  ),
43
43
  Container(margin: const EdgeInsets.only(top: spacing)),
44
- const IconButton(
44
+ IconButton(
45
- icon: Icon(
46
- Icons.remove_circle,
45
+ icon: const Icon(Icons.remove_circle, size: 28),
47
- size: 28,
48
- ),
49
- onPressed: decreaseFont,
46
+ onPressed: model.decreaseFont,
50
47
  ),
51
48
  ],
52
49
  );
lib/widgets/play_button.dart CHANGED
@@ -1,5 +1,4 @@
1
1
  import "package:flutter/material.dart";
2
- import "package:flutter_reactive_value/flutter_reactive_value.dart";
3
2
  import "package:only_bible_app/state.dart";
4
3
 
5
4
  class PlayButton extends StatelessWidget {
@@ -7,13 +6,14 @@ class PlayButton extends StatelessWidget {
7
6
 
8
7
  @override
9
8
  Widget build(BuildContext context) {
9
+ final model = ChapterViewModel.of(context);
10
- final icon = isPlaying.reactiveValue(context) ? Icons.pause_circle_filled : Icons.play_circle_fill;
10
+ final icon = model.isPlaying ? Icons.pause_circle_filled : Icons.play_circle_fill;
11
11
  final size = isWide(context) ? 28.0 : 42.0;
12
12
 
13
13
  return IconButton(
14
14
  icon: Icon(icon, size: size),
15
15
  onPressed: () {
16
- ChapterViewModel.ofEvent(context).onPlay(context);
16
+ model.onPlay(context);
17
17
  },
18
18
  );
19
19
  }
lib/widgets/verse_list.dart CHANGED
@@ -1,5 +1,4 @@
1
1
  import "package:flutter/material.dart";
2
- import "package:flutter_reactive_value/flutter_reactive_value.dart";
3
2
  import "package:only_bible_app/widgets/verse_view.dart";
4
3
  import "package:only_bible_app/state.dart";
5
4
 
lib/widgets/verse_view.dart CHANGED
@@ -1,6 +1,5 @@
1
1
  import "package:flutter/material.dart";
2
- import "package:flutter_reactive_value/flutter_reactive_value.dart";
3
- import 'package:only_bible_app/state.dart';
2
+ import "package:only_bible_app/state.dart";
4
3
 
5
4
  class VerseText extends StatelessWidget {
6
5
  final int index;
@@ -10,18 +9,15 @@ class VerseText extends StatelessWidget {
10
9
 
11
10
  @override
12
11
  Widget build(BuildContext context) {
12
+ final model = AppModel.of(context);
13
13
  final selected = ChapterViewModel.of(context).isVerseSelected(index);
14
- final delta = fontSizeDelta.reactiveValue(context);
15
- final bodySize = Theme.of(context).textTheme.bodyMedium!.fontSize! + delta;
14
+ final bodySize = Theme.of(context).textTheme.bodyMedium!.fontSize! + model.fontSizeDelta;
16
- final weight =
17
- fontBold.reactiveValue(context) ? FontWeight.w600 : Theme.of(context).textTheme.bodyMedium!.fontWeight;
15
+ final weight = model.fontBold ? FontWeight.w600 : Theme.of(context).textTheme.bodyMedium!.fontWeight;
18
-
19
- onTap() {
20
- ChapterViewModel.ofEvent(context).onVerseSelected(index);
21
- }
22
16
 
23
17
  return GestureDetector(
24
- onTap: onTap,
18
+ onTap: () {
19
+ ChapterViewModel.ofEvent(context).onVerseSelected(index);
20
+ },
25
21
  child: DecoratedBox(
26
22
  decoration: BoxDecoration(
27
23
  color: selected ? Theme.of(context).highlightColor : Theme.of(context).colorScheme.background,
pubspec.lock CHANGED
@@ -320,22 +320,6 @@ packages:
320
320
  url: "https://pub.dev"
321
321
  source: hosted
322
322
  version: "2.3.1"
323
- flutter_persistent_value_notifier:
324
- dependency: "direct main"
325
- description:
326
- name: flutter_persistent_value_notifier
327
- sha256: ed949e8081346f9bb2f709a3dd1f71bdf842e5bfed332650c046321ec935013a
328
- url: "https://pub.dev"
329
- source: hosted
330
- version: "1.0.2"
331
- flutter_reactive_value:
332
- dependency: "direct main"
333
- description:
334
- name: flutter_reactive_value
335
- sha256: aa3432e96233e4186fdaf0a1e2f7dd8169957d03252dbde24f1dd6e177e6bdd7
336
- url: "https://pub.dev"
337
- source: hosted
338
- version: "1.0.4"
339
323
  flutter_swipe_detector:
340
324
  dependency: "direct main"
341
325
  description:
@@ -931,4 +915,4 @@ packages:
931
915
  version: "3.1.2"
932
916
  sdks:
933
917
  dart: ">=3.0.6 <4.0.0"
934
- flutter: ">=3.7.0"
918
+ flutter: ">=3.3.0"
pubspec.yaml CHANGED
@@ -13,8 +13,6 @@ dependencies:
13
13
  sdk: flutter
14
14
  intl: any
15
15
  path_provider: ^2.0.15
16
- flutter_persistent_value_notifier: ^1.0.2
17
- flutter_reactive_value: ^1.0.4
18
16
  just_audio: ^0.9.34
19
17
  shared_preferences: ^2.2.0
20
18
  flutter_native_splash: ^2.3.1