~repos /only-bible-app
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 +41 -0
- lib/widgets/actions_sheet.dart +3 -1
- lib/widgets/note_sheet.dart +60 -0
- lib/widgets/verses_view.dart +18 -1
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:
|
|
72
|
+
style: context.watch<ChapterViewModel>().isVerseSelected(v)
|
|
56
73
|
? TextStyle(
|
|
57
74
|
backgroundColor: Theme.of(context).highlightColor,
|
|
58
75
|
)
|