~repos /only-bible-app

#kotlin#android#ios

git clone https://pyrossh.dev/repos/only-bible-app.git

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


ec53f84a pyrossh

2 years ago
update deps
.github/workflows/build.yml CHANGED
@@ -20,6 +20,7 @@ jobs:
20
20
  - run: flutter --version
21
21
  - run: flutter pub get
22
22
  - run: flutter build web --dart-define=TTS_SUBSCRIPTION_KEY=${{ secrets.TTS_SUBSCRIPTION_KEY }} --dart-define=RESEND_API_KEY=${{ secrets.RESEND_API_KEY }}
23
+ - run: cp build/web/index.html build/web/privacy-policy.html
23
24
  - uses: actions/upload-pages-artifact@v1
24
25
  with:
25
26
  path: build/web
lib/atom.dart DELETED
@@ -1,94 +0,0 @@
1
- import "package:flutter/material.dart";
2
- import "package:flutter/scheduler.dart";
3
- import "package:get_storage/get_storage.dart";
4
-
5
- final List<Atom> atoms = [];
6
-
7
- void dispatch<T, A>(A a) {
8
- for (final atom in atoms) {
9
- final newValue = atom.reducer(atom.valueNotifier.value, a);
10
- atom.valueNotifier.value = newValue;
11
- if (atom.box != null) {
12
- if (newValue == null) {
13
- atom.box!.remove(atom.key);
14
- } else {
15
- atom.box!.write(atom.key, newValue);
16
- }
17
- atom.box!.save();
18
- }
19
- }
20
- }
21
-
22
- class Atom<T, A> {
23
- late ValueNotifier<T> valueNotifier;
24
- final String key;
25
- final GetStorage? box;
26
- final dynamic Function(dynamic, dynamic) reducer;
27
-
28
- Atom({required this.key, required T initialState, this.box, required this.reducer}) {
29
- valueNotifier = ValueNotifier(box != null ? box!.read<T>(key) ?? initialState : initialState);
30
- atoms.add(this);
31
- }
32
-
33
- get value => valueNotifier.value;
34
-
35
- T watch(BuildContext context) {
36
- final elementRef = WeakReference(context as Element);
37
- final listenerWrapper = _ListenerWrapper();
38
- listenerWrapper.listener = () {
39
- assert(
40
- SchedulerBinding.instance.schedulerPhase != SchedulerPhase.persistentCallbacks,
41
- """
42
- Do not mutate state (by setting the value of the ValueNotifier
43
- that you are subscribed to) during a `build` method. If you need
44
- to schedule a value update after `build` has completed, use
45
- `SchedulerBinding.instance.scheduleTask(updateTask, Priority.idle)`,
46
- `SchedulerBinding.addPostFrameCallback(updateTask)`, '
47
- or similar.
48
- """,
49
- );
50
- // If the element has not been garbage collected (causing
51
- // `elementRef.target` to be null), or unmounted
52
- if (elementRef.target?.mounted ?? false) {
53
- // Mark the element as needing to be rebuilt
54
- elementRef.target!.markNeedsBuild();
55
- }
56
- // Remove the listener -- only listen to one change per `build`
57
- valueNotifier.removeListener(listenerWrapper.listener!);
58
- };
59
- valueNotifier.addListener(listenerWrapper.listener!);
60
- return valueNotifier.value;
61
- }
62
-
63
- /// Use this method to notify listeners of deeper changes, e.g. when a value
64
- /// is added to or removed from a set which is stored in the value of a
65
- /// `ValueNotifier<Set<T>>`.
66
- void notifyChanged() {
67
- // ignore: invalid_use_of_protected_member, invalid_use_of_visible_for_testing_member
68
- valueNotifier.notifyListeners();
69
- }
70
- }
71
-
72
- class _ListenerWrapper {
73
- void Function()? listener;
74
- }
75
-
76
- class AsyncAtom<P extends String, E extends Future> {
77
- final Map<P, E> cache = {};
78
- final E Function(P) callback;
79
- final int cacheSize;
80
-
81
- AsyncAtom({required this.callback, this.cacheSize = 1});
82
-
83
- E getValue(P param) {
84
- if (cache.containsKey(param)) {
85
- return cache[param]!;
86
- }
87
- final v = callback(param);
88
- if (cache.length >= cacheSize) {
89
- cache.clear();
90
- }
91
- cache[param] = v;
92
- return v;
93
- }
94
- }
lib/store/state.dart CHANGED
@@ -1,11 +1,12 @@
1
1
  import "dart:developer";
2
+ import "package:atoms_state/atoms_state.dart";
2
3
  import "package:flutter/material.dart";
3
4
  import "package:flutter/services.dart";
4
5
  import "package:get_storage/get_storage.dart";
5
6
  import "package:just_audio/just_audio.dart";
6
- import "package:only_bible_app/atom.dart";
7
7
  import "package:only_bible_app/dialog.dart";
8
8
  import "package:only_bible_app/models.dart";
9
+ import "package:only_bible_app/store/storage.dart";
9
10
  import "package:only_bible_app/theme.dart";
10
11
  import "package:only_bible_app/utils.dart";
11
12
  import "package:only_bible_app/navigation.dart";
@@ -14,6 +15,7 @@ import "package:only_bible_app/store/actions.dart";
14
15
  final box = GetStorage("only-bible-app-prefs");
15
16
  final player = AudioPlayer();
16
17
  final noteTextController = TextEditingController();
18
+ final storage = FileStorage(box: box);
17
19
 
18
20
  initState() async {
19
21
  await box.initStorage;
@@ -24,7 +26,7 @@ final bibleAtom = AsyncAtom(
24
26
  );
25
27
 
26
28
  final firstOpenAtom = Atom(
27
- box: box,
29
+ storage: storage,
28
30
  key: "firstOpen",
29
31
  initialState: true,
30
32
  reducer: (state, action) {
@@ -36,7 +38,7 @@ final firstOpenAtom = Atom(
36
38
  );
37
39
 
38
40
  final languageCodeAtom = Atom(
39
- box: box,
41
+ storage: storage,
40
42
  key: "languageCode",
41
43
  initialState: "en",
42
44
  reducer: (state, action) {
@@ -48,7 +50,7 @@ final languageCodeAtom = Atom(
48
50
  );
49
51
 
50
52
  final bibleNameAtom = Atom(
51
- box: box,
53
+ storage: storage,
52
54
  key: "bibleName",
53
55
  initialState: "English",
54
56
  reducer: (state, action) {
@@ -60,7 +62,7 @@ final bibleNameAtom = Atom(
60
62
  );
61
63
 
62
64
  final engTitlesAtom = Atom(
63
- box: box,
65
+ storage: storage,
64
66
  key: "engTitles",
65
67
  initialState: false,
66
68
  reducer: (state, action) {
@@ -72,7 +74,7 @@ final engTitlesAtom = Atom(
72
74
  );
73
75
 
74
76
  final boldFontAtom = Atom(
75
- box: box,
77
+ storage: storage,
76
78
  key: "boldFont",
77
79
  initialState: false,
78
80
  reducer: (state, action) {
@@ -84,7 +86,7 @@ final boldFontAtom = Atom(
84
86
  );
85
87
 
86
88
  final darkModeAtom = Atom(
87
- box: box,
89
+ storage: storage,
88
90
  key: "darkMode",
89
91
  initialState: false,
90
92
  reducer: (state, action) {
@@ -97,7 +99,7 @@ final darkModeAtom = Atom(
97
99
  );
98
100
 
99
101
  final textScaleAtom = Atom(
100
- box: box,
102
+ storage: storage,
101
103
  key: "textScale",
102
104
  initialState: 0.0,
103
105
  reducer: (state, action) {
@@ -109,7 +111,7 @@ final textScaleAtom = Atom(
109
111
  );
110
112
 
111
113
  final savedBookAtom = Atom(
112
- box: box,
114
+ storage: storage,
113
115
  key: "savedBook",
114
116
  initialState: 0,
115
117
  reducer: (state, action) {
@@ -121,7 +123,7 @@ final savedBookAtom = Atom(
121
123
  );
122
124
 
123
125
  final savedChapterAtom = Atom(
124
- box: box,
126
+ storage: storage,
125
127
  key: "savedChapter",
126
128
  initialState: 0,
127
129
  reducer: (state, action) {
lib/store/storage.dart ADDED
@@ -0,0 +1,25 @@
1
+ import "package:atoms_state/atoms_state.dart";
2
+ import "package:get_storage/get_storage.dart";
3
+
4
+ class FileStorage<T> implements Storage {
5
+ GetStorage box;
6
+
7
+ FileStorage({required this.box});
8
+
9
+ @override
10
+ T? get<T>(String key) {
11
+ return box.read(key);
12
+ }
13
+
14
+ @override
15
+ Future<void> delete(String key) async {
16
+ await box.remove(key);
17
+ await box.save();
18
+ }
19
+
20
+ @override
21
+ Future<void> set(String key, value) async {
22
+ await box.write(key, value);
23
+ await box.save();
24
+ }
25
+ }
pubspec.lock CHANGED
@@ -41,6 +41,14 @@ packages:
41
41
  url: "https://pub.dev"
42
42
  source: hosted
43
43
  version: "2.11.0"
44
+ atoms_state:
45
+ dependency: "direct main"
46
+ description:
47
+ name: atoms_state
48
+ sha256: "25ffb62bf5f0bdf4ee437e32d450fa55dc5e6ceadda6056b1b7d13f1549cff9c"
49
+ url: "https://pub.dev"
50
+ source: hosted
51
+ version: "0.0.2"
44
52
  audio_session:
45
53
  dependency: transitive
46
54
  description:
@@ -1130,5 +1138,5 @@ packages:
1130
1138
  source: hosted
1131
1139
  version: "3.1.2"
1132
1140
  sdks:
1133
- dart: ">=3.1.0-185.0.dev <4.0.0"
1141
+ dart: ">=3.1.0 <4.0.0"
1134
1142
  flutter: ">=3.10.0"
pubspec.yaml CHANGED
@@ -30,6 +30,7 @@ dependencies:
30
30
  package_info_plus: ^4.1.0
31
31
  flutter_azure_tts: ^0.1.6
32
32
  http: ^0.13.6
33
+ atoms_state: 0.0.2
33
34
 
34
35
  dev_dependencies:
35
36
  flutter_test:
readme.md CHANGED
@@ -1,11 +1,26 @@
1
1
  # Only Bible App
2
2
 
3
+ The only bible app you will ever need.
3
- The only bible app you will ever need. No ads, No in-app purchases, No distractions.
4
+ No ads, No in-app purchases, No distractions.
4
5
  Optimized for reading and highlighting.
5
- Just the bibles which are freely available in the public domain.
6
+ Only Bibles which are in the public domain are available.
6
7
  Verse by verse audio is also supported for some of the languages generated using Azure TTS.
7
8
 
8
- Most of the major Indian languages are supported such as Hindi, Kannada, Tamil, Malayalam, Nepali.
9
+ ### Languages Supported
10
+
11
+ | Language | Audio |
12
+ |-----------|:-----:|
13
+ | Bengali | ✅ |
14
+ | English | ✅ |
15
+ | Gujarati | ✅ |
16
+ | Hindi | ✅ |
17
+ | Kannada | ✅ |
18
+ | Malayalam | ✅ |
19
+ | Nepali | ✅ |
20
+ | Oriya | ❌ |
21
+ | Punjabi | ❌ |
22
+ | Tamil | ✅ |
23
+ | Telugu | ✅ |
9
24
 
10
25
  ## Setup
11
26
 
@@ -55,10 +70,12 @@ https://onlybible.app
55
70
  ```
56
71
 
57
72
  ## Bugs
73
+
58
74
  1. Swipe left should pop context if chapter/book index is previous to the current one to maintain scroll history.
59
75
 
60
76
  ## Todo
61
77
 
62
78
  1. Figure out history
63
79
  2. Add more text options compact/loose, line spacing
64
- 3. Backups (File, Google Drive)
80
+ 3. Backups (File, Google Drive)
81
+ 4. Add Next/Prev/Home in bottom navigation as optional for mobile users