~repos /only-bible-app
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.
be8e373c
—
pyrossh 1 month ago
update sheets
- lib/navigation.dart +10 -12
- lib/screens/chapter_view_screen.dart +0 -6
- lib/sheets/actions_sheet.dart +70 -21
- lib/sheets/highlight_sheet.dart +0 -73
- lib/store/actions.dart +0 -18
- lib/store/app_state.dart +0 -8
- lib/widgets/verses_view.dart +2 -1
lib/navigation.dart
CHANGED
|
@@ -3,6 +3,7 @@ import "package:flutter/services.dart";
|
|
|
3
3
|
import "package:app_review/app_review.dart";
|
|
4
4
|
import "package:go_router/go_router.dart";
|
|
5
5
|
import "package:only_bible_app/models.dart";
|
|
6
|
+
import "package:only_bible_app/sheets/actions_sheet.dart";
|
|
6
7
|
import "package:only_bible_app/sheets/settings_sheet.dart";
|
|
7
8
|
import "package:only_bible_app/store/actions.dart";
|
|
8
9
|
import "package:only_bible_app/store/app_state.dart";
|
|
@@ -208,21 +209,18 @@ void showSettings(BuildContext context, Bible bible) {
|
|
|
208
209
|
);
|
|
209
210
|
}
|
|
210
211
|
|
|
212
|
+
PersistentBottomSheetController? _actionsController;
|
|
213
|
+
|
|
211
214
|
void showActions(BuildContext context, Bible bible) {
|
|
215
|
+
hideActions(context);
|
|
216
|
+
_actionsController = showBottomSheet(
|
|
217
|
+
context: context,
|
|
212
|
-
|
|
218
|
+
builder: (context) => ActionsSheet(bible: bible),
|
|
219
|
+
);
|
|
213
220
|
}
|
|
214
221
|
|
|
215
222
|
void hideActions(BuildContext context) {
|
|
216
|
-
|
|
223
|
+
_actionsController?.close();
|
|
224
|
+
_actionsController = null;
|
|
217
225
|
store.dispatch(ClearSelectedVersesAction());
|
|
218
226
|
}
|
|
219
|
-
|
|
220
|
-
void showHighlights(BuildContext context) {
|
|
221
|
-
store.dispatch(SetHighlightsShownAction(true));
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
void hideHighlights(BuildContext context) {
|
|
225
|
-
if (store.state.highlightsShown) {
|
|
226
|
-
store.dispatch(SetHighlightsShownAction(false));
|
|
227
|
-
}
|
|
228
|
-
}
|
lib/screens/chapter_view_screen.dart
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import "package:flutter/material.dart";
|
|
2
2
|
import "package:only_bible_app/models.dart";
|
|
3
|
-
import "package:only_bible_app/sheets/actions_sheet.dart";
|
|
4
|
-
import "package:only_bible_app/sheets/highlight_sheet.dart";
|
|
5
3
|
import "package:only_bible_app/store/actions.dart";
|
|
6
4
|
import "package:only_bible_app/utils.dart";
|
|
7
5
|
import "package:only_bible_app/widgets/chapter_app_bar.dart";
|
|
@@ -41,10 +39,6 @@ class ChapterViewScreen extends StatelessWidget {
|
|
|
41
39
|
child: Column(
|
|
42
40
|
children: [
|
|
43
41
|
Expanded(child: VersesView(bible: bible, chapter: chapter)),
|
|
44
|
-
if (context.state.highlightsShown)
|
|
45
|
-
const HighlightSheet()
|
|
46
|
-
else if (context.state.actionsShown)
|
|
47
|
-
ActionsSheet(bible: bible),
|
|
48
42
|
],
|
|
49
43
|
),
|
|
50
44
|
),
|
lib/sheets/actions_sheet.dart
CHANGED
|
@@ -3,7 +3,9 @@ import "package:only_bible_app/models.dart";
|
|
|
3
3
|
import "package:only_bible_app/navigation.dart";
|
|
4
4
|
import "package:only_bible_app/app.dart";
|
|
5
5
|
import "package:only_bible_app/store/actions.dart";
|
|
6
|
+
import "package:only_bible_app/theme.dart";
|
|
6
7
|
import "package:only_bible_app/utils.dart";
|
|
8
|
+
import "package:only_bible_app/widgets/highlight_button.dart";
|
|
7
9
|
|
|
8
10
|
class ActionsSheet extends StatelessWidget {
|
|
9
11
|
final Bible bible;
|
|
@@ -18,6 +20,15 @@ class ActionsSheet extends StatelessWidget {
|
|
|
18
20
|
final audioIcon = context.state.isPlaying
|
|
19
21
|
? Icons.pause_circle_outline
|
|
20
22
|
: Icons.play_circle_outline;
|
|
23
|
+
|
|
24
|
+
void onHighlight(int index) {
|
|
25
|
+
store.dispatch(SetHighlightAction(
|
|
26
|
+
List<Verse>.from(store.state.selectedVerses),
|
|
27
|
+
index,
|
|
28
|
+
));
|
|
29
|
+
hideActions(context);
|
|
30
|
+
}
|
|
31
|
+
|
|
21
32
|
return Container(
|
|
22
33
|
height: 50,
|
|
23
34
|
color: Theme.of(context).colorScheme.surface,
|
|
@@ -28,31 +39,69 @@ class ActionsSheet extends StatelessWidget {
|
|
|
28
39
|
IconButton(
|
|
29
40
|
padding: EdgeInsets.zero,
|
|
30
41
|
onPressed: () {
|
|
42
|
+
store.dispatch(
|
|
31
|
-
|
|
43
|
+
RemoveHighlightAction(
|
|
32
|
-
|
|
44
|
+
List<Verse>.from(store.state.selectedVerses),
|
|
45
|
+
),
|
|
33
|
-
)
|
|
46
|
+
);
|
|
34
47
|
hideActions(context);
|
|
35
48
|
},
|
|
36
49
|
icon: Icon(Icons.cancel_outlined, size: 28, color: iconColor),
|
|
37
50
|
),
|
|
51
|
+
if (context.state.selectedVerses
|
|
52
|
+
.any((v) => context.state.getHighlight(v) != null)) ...[
|
|
53
|
+
HighlightButton(
|
|
54
|
+
index: 0,
|
|
55
|
+
color:
|
|
56
|
+
store.state.darkMode ? darkHighlights[0] : lightHighlights[0],
|
|
57
|
+
onHighlightSelected: onHighlight,
|
|
58
|
+
),
|
|
59
|
+
HighlightButton(
|
|
60
|
+
index: 1,
|
|
61
|
+
color:
|
|
62
|
+
store.state.darkMode ? darkHighlights[1] : lightHighlights[1],
|
|
63
|
+
onHighlightSelected: onHighlight,
|
|
64
|
+
),
|
|
65
|
+
HighlightButton(
|
|
66
|
+
index: 2,
|
|
67
|
+
color:
|
|
68
|
+
store.state.darkMode ? darkHighlights[2] : lightHighlights[2],
|
|
69
|
+
onHighlightSelected: onHighlight,
|
|
70
|
+
),
|
|
71
|
+
HighlightButton(
|
|
72
|
+
index: 3,
|
|
73
|
+
color:
|
|
74
|
+
store.state.darkMode ? darkHighlights[3] : lightHighlights[3],
|
|
75
|
+
onHighlightSelected: onHighlight,
|
|
76
|
+
),
|
|
77
|
+
] else ...[
|
|
38
|
-
|
|
78
|
+
IconButton(
|
|
39
|
-
|
|
79
|
+
padding: EdgeInsets.zero,
|
|
80
|
+
onPressed: () {
|
|
81
|
+
store.dispatch(
|
|
82
|
+
SetHighlightAction(
|
|
40
|
-
|
|
83
|
+
List<Verse>.from(store.state.selectedVerses),
|
|
41
|
-
|
|
84
|
+
0,
|
|
42
|
-
|
|
85
|
+
),
|
|
86
|
+
);
|
|
87
|
+
},
|
|
88
|
+
icon:
|
|
89
|
+
Icon(Icons.border_color_outlined, size: 28, color: iconColor),
|
|
90
|
+
),
|
|
43
|
-
|
|
91
|
+
IconButton(
|
|
44
|
-
|
|
92
|
+
padding: EdgeInsets.zero,
|
|
45
|
-
|
|
93
|
+
onPressed: () {
|
|
46
|
-
|
|
94
|
+
store.state.onPlay(context, bible);
|
|
47
|
-
|
|
95
|
+
},
|
|
48
|
-
|
|
96
|
+
icon: Icon(audioIcon, size: 34, color: iconColor),
|
|
49
|
-
|
|
97
|
+
),
|
|
50
|
-
|
|
98
|
+
IconButton(
|
|
51
|
-
|
|
99
|
+
padding: EdgeInsets.zero,
|
|
52
|
-
|
|
100
|
+
onPressed: () =>
|
|
53
|
-
|
|
101
|
+
shareVerses(context, bible, store.state.selectedVerses),
|
|
54
|
-
|
|
102
|
+
icon: Icon(Icons.share_outlined, size: 34, color: iconColor),
|
|
55
|
-
|
|
103
|
+
),
|
|
104
|
+
],
|
|
56
105
|
],
|
|
57
106
|
),
|
|
58
107
|
);
|
lib/sheets/highlight_sheet.dart
DELETED
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import "package:flutter/material.dart";
|
|
2
|
-
import "package:only_bible_app/app.dart";
|
|
3
|
-
import "package:only_bible_app/models.dart";
|
|
4
|
-
import "package:only_bible_app/navigation.dart";
|
|
5
|
-
import "package:only_bible_app/store/actions.dart";
|
|
6
|
-
import "package:only_bible_app/theme.dart";
|
|
7
|
-
import "package:only_bible_app/utils.dart";
|
|
8
|
-
import "package:only_bible_app/widgets/highlight_button.dart";
|
|
9
|
-
|
|
10
|
-
class HighlightSheet extends StatelessWidget {
|
|
11
|
-
const HighlightSheet({super.key});
|
|
12
|
-
|
|
13
|
-
@override
|
|
14
|
-
Widget build(BuildContext context) {
|
|
15
|
-
final iconColor = store.state.darkMode
|
|
16
|
-
? Colors.white.withOpacity(0.9)
|
|
17
|
-
: Colors.black.withOpacity(0.9);
|
|
18
|
-
void onHighlight(int index) {
|
|
19
|
-
store.dispatch(SetHighlightAction(
|
|
20
|
-
List<Verse>.from(store.state.selectedVerses),
|
|
21
|
-
index,
|
|
22
|
-
));
|
|
23
|
-
hideActions(context);
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
return Container(
|
|
27
|
-
height: 50,
|
|
28
|
-
color: context.theme.colorScheme.surface,
|
|
29
|
-
padding: const EdgeInsets.only(left: 20, right: 20),
|
|
30
|
-
child: Row(
|
|
31
|
-
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
|
32
|
-
children: [
|
|
33
|
-
IconButton(
|
|
34
|
-
padding: EdgeInsets.zero,
|
|
35
|
-
onPressed: () {
|
|
36
|
-
store.dispatch(
|
|
37
|
-
RemoveHighlightAction(
|
|
38
|
-
List<Verse>.from(store.state.selectedVerses),
|
|
39
|
-
),
|
|
40
|
-
);
|
|
41
|
-
hideActions(context);
|
|
42
|
-
},
|
|
43
|
-
icon: Icon(Icons.cancel_outlined, size: 28, color: iconColor),
|
|
44
|
-
),
|
|
45
|
-
HighlightButton(
|
|
46
|
-
index: 0,
|
|
47
|
-
color:
|
|
48
|
-
store.state.darkMode ? darkHighlights[0] : lightHighlights[0],
|
|
49
|
-
onHighlightSelected: onHighlight,
|
|
50
|
-
),
|
|
51
|
-
HighlightButton(
|
|
52
|
-
index: 1,
|
|
53
|
-
color:
|
|
54
|
-
store.state.darkMode ? darkHighlights[1] : lightHighlights[1],
|
|
55
|
-
onHighlightSelected: onHighlight,
|
|
56
|
-
),
|
|
57
|
-
HighlightButton(
|
|
58
|
-
index: 2,
|
|
59
|
-
color:
|
|
60
|
-
store.state.darkMode ? darkHighlights[2] : lightHighlights[2],
|
|
61
|
-
onHighlightSelected: onHighlight,
|
|
62
|
-
),
|
|
63
|
-
HighlightButton(
|
|
64
|
-
index: 3,
|
|
65
|
-
color:
|
|
66
|
-
store.state.darkMode ? darkHighlights[3] : lightHighlights[3],
|
|
67
|
-
onHighlightSelected: onHighlight,
|
|
68
|
-
),
|
|
69
|
-
],
|
|
70
|
-
),
|
|
71
|
-
);
|
|
72
|
-
}
|
|
73
|
-
}
|
lib/store/actions.dart
CHANGED
|
@@ -92,24 +92,6 @@ class ClearSelectedVersesAction extends ReduxAction<AppState> {
|
|
|
92
92
|
AppState reduce() => state.copy(selectedVerses: []);
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
class SetActionsShownAction extends ReduxAction<AppState> {
|
|
96
|
-
final bool value;
|
|
97
|
-
|
|
98
|
-
SetActionsShownAction(this.value);
|
|
99
|
-
|
|
100
|
-
@override
|
|
101
|
-
AppState reduce() => state.copy(actionsShown: value);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
class SetHighlightsShownAction extends ReduxAction<AppState> {
|
|
105
|
-
final bool value;
|
|
106
|
-
|
|
107
|
-
SetHighlightsShownAction(this.value);
|
|
108
|
-
|
|
109
|
-
@override
|
|
110
|
-
AppState reduce() => state.copy(highlightsShown: value);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
95
|
class SetHighlightAction extends ReduxAction<AppState> {
|
|
114
96
|
final List<Verse> verses;
|
|
115
97
|
final int colorIndex;
|
lib/store/app_state.dart
CHANGED
|
@@ -24,8 +24,6 @@ class AppState {
|
|
|
24
24
|
final int savedChapter;
|
|
25
25
|
final bool isPlaying;
|
|
26
26
|
final List<Verse> selectedVerses;
|
|
27
|
-
final bool actionsShown;
|
|
28
|
-
final bool highlightsShown;
|
|
29
27
|
final Map<String, int> highlights;
|
|
30
28
|
|
|
31
29
|
const AppState({
|
|
@@ -40,8 +38,6 @@ class AppState {
|
|
|
40
38
|
this.savedChapter = 0,
|
|
41
39
|
this.isPlaying = false,
|
|
42
40
|
this.selectedVerses = const [],
|
|
43
|
-
this.actionsShown = false,
|
|
44
|
-
this.highlightsShown = false,
|
|
45
41
|
this.highlights = const {},
|
|
46
42
|
});
|
|
47
43
|
|
|
@@ -57,8 +53,6 @@ class AppState {
|
|
|
57
53
|
int? savedChapter,
|
|
58
54
|
bool? isPlaying,
|
|
59
55
|
List<Verse>? selectedVerses,
|
|
60
|
-
bool? actionsShown,
|
|
61
|
-
bool? highlightsShown,
|
|
62
56
|
Map<String, int>? highlights,
|
|
63
57
|
}) {
|
|
64
58
|
return AppState(
|
|
@@ -73,8 +67,6 @@ class AppState {
|
|
|
73
67
|
savedChapter: savedChapter ?? this.savedChapter,
|
|
74
68
|
isPlaying: isPlaying ?? this.isPlaying,
|
|
75
69
|
selectedVerses: selectedVerses ?? this.selectedVerses,
|
|
76
|
-
actionsShown: actionsShown ?? this.actionsShown,
|
|
77
|
-
highlightsShown: highlightsShown ?? this.highlightsShown,
|
|
78
70
|
highlights: highlights ?? this.highlights,
|
|
79
71
|
);
|
|
80
72
|
}
|
lib/widgets/verses_view.dart
CHANGED
|
@@ -110,7 +110,8 @@ class VersesView extends StatelessWidget {
|
|
|
110
110
|
),
|
|
111
111
|
Padding(
|
|
112
112
|
padding: EdgeInsets.only(
|
|
113
|
+
bottom:
|
|
113
|
-
|
|
114
|
+
context.state.selectedVerses.isNotEmpty ? 120 : 0,
|
|
114
115
|
),
|
|
115
116
|
),
|
|
116
117
|
],
|