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


e0d7a1c0 pyrossh

2 years ago
Add notes
lib/state.dart CHANGED
@@ -14,6 +14,7 @@ import "package:only_bible_app/screens/chapter_view_screen.dart";
14
14
  import "package:only_bible_app/dialog.dart";
15
15
  import "package:only_bible_app/models.dart";
16
16
  import "package:only_bible_app/widgets/actions_sheet.dart";
17
+ import "package:only_bible_app/widgets/note_sheet.dart";
17
18
  import "package:only_bible_app/widgets/scaffold_menu.dart";
18
19
  import "package:only_bible_app/widgets/settings_sheet.dart";
19
20
  import "package:provider/provider.dart";
@@ -36,6 +37,7 @@ class AppModel extends ChangeNotifier {
36
37
  bool fontBold = false;
37
38
  double textScaleFactor = 0;
38
39
  bool actionsShown = false;
40
+ final TextEditingController noteTextController = TextEditingController();
39
41
  List<HistoryFrame> history = [];
40
42
  final box = GetStorage("only-bible-app-backup");
41
43
 
@@ -200,6 +202,45 @@ class AppModel extends ChangeNotifier {
200
202
  notifyListeners();
201
203
  }
202
204
  }
205
+
206
+ bool hasNote(Verse v) {
207
+ return box.hasData("${v.book}:${v.chapter}:${v.index}:note");
208
+ }
209
+
210
+ showNoteField(BuildContext context, Verse v) {
211
+ final noteText = box.read("${v.book}:${v.chapter}:${v.index}:note") ?? "";
212
+ noteTextController.text = noteText;
213
+ showModalBottomSheet(
214
+ context: context,
215
+ isDismissible: true,
216
+ enableDrag: true,
217
+ showDragHandle: true,
218
+ useSafeArea: true,
219
+ builder: (context) => NoteSheet(verse: v),
220
+ );
221
+ }
222
+
223
+ saveNote(BuildContext context, Verse v) {
224
+ final note = noteTextController.text;
225
+ box.write("${v.book}:${v.chapter}:${v.index}:note", note);
226
+ box.save();
227
+ // Close the bottom sheet
228
+ // if (!mounted) return;
229
+ // Navigator.of(context).pop();
230
+ notifyListeners();
231
+ hideNoteField(context);
232
+ }
233
+
234
+ deleteNote(BuildContext context, Verse v) {
235
+ box.remove("${v.book}:${v.chapter}:${v.index}:note");
236
+ box.save();
237
+ notifyListeners();
238
+ hideNoteField(context);
239
+ }
240
+
241
+ hideNoteField(BuildContext context) {
242
+ Navigator.of(context).pop();
243
+ }
203
244
  }
204
245
 
205
246
  class ChapterViewModel extends ChangeNotifier {
lib/widgets/actions_sheet.dart CHANGED
@@ -94,7 +94,9 @@ class ActionsSheet extends StatelessWidget {
94
94
  IconButtonText(
95
95
  leading: IconButton(
96
96
  padding: EdgeInsets.zero,
97
- onPressed: () {},
97
+ onPressed: () {
98
+ app.showNoteField(context, model.selectedVerses.first);
99
+ },
98
100
  icon: Icon(Icons.post_add_outlined, size: 32 + iconSize, color: iconColor),
99
101
  ),
100
102
  trailing: Text("Note", style: bodySmall),
lib/widgets/note_sheet.dart ADDED
@@ -0,0 +1,60 @@
1
+ import "package:flutter/material.dart";
2
+ import "package:only_bible_app/models.dart";
3
+ import "package:only_bible_app/state.dart";
4
+
5
+ class NoteSheet extends StatelessWidget {
6
+ final Verse verse;
7
+
8
+ const NoteSheet({super.key, required this.verse});
9
+
10
+ @override
11
+ Widget build(BuildContext context) {
12
+ final app = AppModel.of(context);
13
+ return Container(
14
+ padding: EdgeInsets.only(
15
+ top: 15,
16
+ left: 15,
17
+ right: 15,
18
+ // this will prevent the soft keyboard from covering the text fields
19
+ bottom: MediaQuery.of(context).viewInsets.bottom + 120,
20
+ ),
21
+ child: Column(
22
+ mainAxisSize: MainAxisSize.min,
23
+ crossAxisAlignment: CrossAxisAlignment.end,
24
+ children: [
25
+ Container(
26
+ margin: const EdgeInsets.all(12),
27
+ height: 5 * 24.0,
28
+ child: TextField(
29
+ controller: app.noteTextController,
30
+ maxLines: 5,
31
+ keyboardType: TextInputType.multiline,
32
+ decoration: const InputDecoration(filled: true, hintText: "Add a note"),
33
+ ),
34
+ ),
35
+ const SizedBox(
36
+ height: 20,
37
+ ),
38
+ Row(
39
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
40
+ children: [
41
+ if (app.noteTextController.value.text != "")
42
+ ElevatedButton(
43
+ onPressed: () {
44
+ app.deleteNote(context, verse);
45
+ },
46
+ child: const Text("Delete"),
47
+ ),
48
+ ElevatedButton(
49
+ onPressed: () {
50
+ app.saveNote(context, verse);
51
+ },
52
+ child: const Text("Save"),
53
+ ),
54
+ ],
55
+ )
56
+ ],
57
+ ),
58
+ );
59
+ }
60
+ }
lib/widgets/verses_view.dart CHANGED
@@ -2,6 +2,7 @@ import "package:flutter/gestures.dart";
2
2
  import "package:flutter/material.dart";
3
3
  import "package:flutter_swipe_detector/flutter_swipe_detector.dart";
4
4
  import "package:only_bible_app/state.dart";
5
+ import "package:provider/provider.dart";
5
6
 
6
7
  class VersesView extends StatelessWidget {
7
8
  const VersesView({super.key});
@@ -50,9 +51,25 @@ class VersesView extends StatelessWidget {
50
51
  child: Text("${v.index + 1} ", style: Theme.of(context).textTheme.labelMedium),
51
52
  ),
52
53
  ),
54
+ if (app.hasNote(v))
55
+ WidgetSpan(
56
+ child: Padding(
57
+ padding: const EdgeInsets.only(left: 3, right: 3),
58
+ child: GestureDetector(
59
+ onTap: () {
60
+ app.showNoteField(context, v);
61
+ },
62
+ child: const Icon(
63
+ Icons.sticky_note_2_outlined,
64
+ size: 18,
65
+ color: Colors.blue,
66
+ ),
67
+ ),
68
+ ),
69
+ ),
53
70
  TextSpan(
54
71
  text: "${v.text}\n",
55
- style: model.isVerseSelected(v)
72
+ style: context.watch<ChapterViewModel>().isVerseSelected(v)
56
73
  ? TextStyle(
57
74
  backgroundColor: Theme.of(context).highlightColor,
58
75
  )