~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.
e6ba8edc
—
pyrossh 2 years ago
improve desktop header
- lib/screens/bible_select_screen.dart +1 -2
- lib/state.dart +36 -10
- lib/widgets/actions_sheet.dart +16 -10
- lib/widgets/chapter_app_bar.dart +32 -17
- lib/widgets/settings_sheet.dart +11 -16
lib/screens/bible_select_screen.dart
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import "package:flutter/cupertino.dart";
|
|
2
1
|
import "package:flutter/material.dart";
|
|
3
2
|
import "package:only_bible_app/state.dart";
|
|
4
3
|
import "package:only_bible_app/models.dart";
|
|
@@ -24,7 +23,7 @@ class BibleSelectScreen extends StatelessWidget {
|
|
|
24
23
|
return TextButton(
|
|
25
24
|
child: Text(bible.name),
|
|
26
25
|
onPressed: () {
|
|
27
|
-
model.
|
|
26
|
+
model.updateCurrentBible(context, bible.id);
|
|
28
27
|
Navigator.of(context).pop();
|
|
29
28
|
},
|
|
30
29
|
);
|
lib/state.dart
CHANGED
|
@@ -8,8 +8,10 @@ import "package:flutter/foundation.dart" show defaultTargetPlatform, TargetPlatf
|
|
|
8
8
|
import "package:flutter/services.dart";
|
|
9
9
|
import "package:flutter/material.dart";
|
|
10
10
|
import "package:just_audio/just_audio.dart";
|
|
11
|
+
import "package:only_bible_app/screens/bible_select_screen.dart";
|
|
12
|
+
import "package:only_bible_app/screens/book_select_screen.dart";
|
|
11
13
|
import "package:only_bible_app/screens/chapter_view_screen.dart";
|
|
12
|
-
import
|
|
14
|
+
import "package:only_bible_app/dialog.dart";
|
|
13
15
|
import "package:only_bible_app/models.dart";
|
|
14
16
|
import "package:only_bible_app/widgets/actions_sheet.dart";
|
|
15
17
|
import "package:only_bible_app/widgets/scaffold_menu.dart";
|
|
@@ -83,13 +85,37 @@ class AppModel extends ChangeNotifier {
|
|
|
83
85
|
);
|
|
84
86
|
}
|
|
85
87
|
|
|
88
|
+
changeBible(BuildContext context) {
|
|
89
|
+
Navigator.of(context).pushReplacement(
|
|
90
|
+
createNoTransitionPageRoute(
|
|
91
|
+
const BibleSelectScreen(),
|
|
92
|
+
),
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
changeBibleFromHeader(BuildContext context) {
|
|
97
|
+
Navigator.of(context).push(
|
|
98
|
+
createNoTransitionPageRoute(
|
|
99
|
+
const BibleSelectScreen(),
|
|
100
|
+
),
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
|
|
86
|
-
|
|
104
|
+
updateCurrentBible(BuildContext context, int id) async {
|
|
87
105
|
// TODO: maybe use a future as the bible needs to load
|
|
88
106
|
bible = await loadBible(id);
|
|
89
107
|
notifyListeners();
|
|
90
108
|
save();
|
|
91
109
|
}
|
|
92
110
|
|
|
111
|
+
changeBook(BuildContext context) {
|
|
112
|
+
Navigator.of(context).push(
|
|
113
|
+
createNoTransitionPageRoute(
|
|
114
|
+
BookSelectScreen(bible: bible),
|
|
115
|
+
),
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
|
|
93
119
|
toggleMode() async {
|
|
94
120
|
darkMode = !darkMode;
|
|
95
121
|
updateStatusBar();
|
|
@@ -144,14 +170,14 @@ class AppModel extends ChangeNotifier {
|
|
|
144
170
|
// ),
|
|
145
171
|
// );
|
|
146
172
|
// } else {
|
|
147
|
-
|
|
173
|
+
showModalBottomSheet(
|
|
148
|
-
|
|
174
|
+
context: context,
|
|
149
|
-
|
|
175
|
+
isDismissible: true,
|
|
150
|
-
|
|
176
|
+
enableDrag: true,
|
|
151
|
-
|
|
177
|
+
showDragHandle: true,
|
|
152
|
-
|
|
178
|
+
useSafeArea: true,
|
|
153
|
-
|
|
179
|
+
builder: (context) => const SettingsSheet(),
|
|
154
|
-
|
|
180
|
+
);
|
|
155
181
|
// }
|
|
156
182
|
}
|
|
157
183
|
|
lib/widgets/actions_sheet.dart
CHANGED
|
@@ -9,20 +9,26 @@ class ActionsSheet extends StatelessWidget {
|
|
|
9
9
|
@override
|
|
10
10
|
Widget build(BuildContext context) {
|
|
11
11
|
final app = AppModel.of(context);
|
|
12
|
+
final isDesktop = isWide(context);
|
|
13
|
+
final iconSize = isDesktop ? 10.0 : 0.0;
|
|
12
14
|
final iconColor = app.darkMode ? Colors.white.withOpacity(0.9) : Colors.black.withOpacity(0.9);
|
|
13
15
|
final bodySmall = Theme.of(context).textTheme.bodySmall;
|
|
14
16
|
final model = ChapterViewModel.of(context);
|
|
15
17
|
final audioIcon = model.isPlaying ? Icons.pause_circle_outline : Icons.play_circle_outline;
|
|
16
18
|
final audioText = model.isPlaying ? "Pause" : "Play";
|
|
17
|
-
final
|
|
19
|
+
final highlightRowEnabled = !isDesktop && false;
|
|
18
20
|
return Container(
|
|
19
|
-
height:
|
|
21
|
+
height: highlightRowEnabled
|
|
22
|
+
? 160
|
|
23
|
+
: isDesktop
|
|
24
|
+
? 80
|
|
25
|
+
: 100,
|
|
20
26
|
color: Theme.of(context).colorScheme.background,
|
|
21
|
-
padding: EdgeInsets.only(
|
|
27
|
+
padding: EdgeInsets.only(left: 20, right: 20, top: isDesktop ? 10 : 0),
|
|
22
28
|
child: Column(
|
|
23
|
-
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
|
29
|
+
mainAxisAlignment: highlightRowEnabled ? MainAxisAlignment.spaceAround : MainAxisAlignment.start,
|
|
24
30
|
children: [
|
|
25
|
-
if (
|
|
31
|
+
if (highlightRowEnabled)
|
|
26
32
|
Row(
|
|
27
33
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
28
34
|
children: [
|
|
@@ -56,7 +62,7 @@ class ActionsSheet extends StatelessWidget {
|
|
|
56
62
|
leading: IconButton(
|
|
57
63
|
padding: EdgeInsets.zero,
|
|
58
64
|
onPressed: () {},
|
|
59
|
-
icon: Icon(Icons.cancel_outlined, size: 24, color: iconColor),
|
|
65
|
+
icon: Icon(Icons.cancel_outlined, size: 24 + iconSize, color: iconColor),
|
|
60
66
|
),
|
|
61
67
|
trailing: Text("Clear", style: bodySmall),
|
|
62
68
|
),
|
|
@@ -64,7 +70,7 @@ class ActionsSheet extends StatelessWidget {
|
|
|
64
70
|
leading: IconButton(
|
|
65
71
|
padding: EdgeInsets.zero,
|
|
66
72
|
onPressed: () {},
|
|
67
|
-
icon: Icon(Icons.copy, size: 24, color: iconColor),
|
|
73
|
+
icon: Icon(Icons.copy, size: 24 + iconSize, color: iconColor),
|
|
68
74
|
),
|
|
69
75
|
trailing: Text("Copy", style: bodySmall),
|
|
70
76
|
),
|
|
@@ -76,7 +82,7 @@ class ActionsSheet extends StatelessWidget {
|
|
|
76
82
|
model.onPlay(context);
|
|
77
83
|
}
|
|
78
84
|
},
|
|
79
|
-
icon: Icon(audioIcon, size:
|
|
85
|
+
icon: Icon(audioIcon, size: 34 + iconSize, color: app.bible.hasAudio ? iconColor : Colors.grey),
|
|
80
86
|
),
|
|
81
87
|
trailing: Text(audioText, style: bodySmall),
|
|
82
88
|
),
|
|
@@ -84,7 +90,7 @@ class ActionsSheet extends StatelessWidget {
|
|
|
84
90
|
leading: IconButton(
|
|
85
91
|
padding: EdgeInsets.zero,
|
|
86
92
|
onPressed: () {},
|
|
87
|
-
icon: Icon(Icons.post_add_outlined, size: 32, color: iconColor),
|
|
93
|
+
icon: Icon(Icons.post_add_outlined, size: 32 + iconSize, color: iconColor),
|
|
88
94
|
),
|
|
89
95
|
trailing: Text("Note", style: bodySmall),
|
|
90
96
|
),
|
|
@@ -92,7 +98,7 @@ class ActionsSheet extends StatelessWidget {
|
|
|
92
98
|
leading: IconButton(
|
|
93
99
|
padding: EdgeInsets.zero,
|
|
94
100
|
onPressed: () {},
|
|
95
|
-
icon: Icon(Icons.share_outlined, size: 28, color: iconColor),
|
|
101
|
+
icon: Icon(Icons.share_outlined, size: 28 + iconSize, color: iconColor),
|
|
96
102
|
),
|
|
97
103
|
trailing: Text("Share", style: bodySmall),
|
|
98
104
|
),
|
lib/widgets/chapter_app_bar.dart
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import "package:flutter/material.dart";
|
|
2
|
-
import "package:only_bible_app/screens/book_select_screen.dart";
|
|
3
2
|
import "package:only_bible_app/state.dart";
|
|
4
3
|
|
|
5
4
|
class ChapterAppBar extends StatelessWidget implements PreferredSizeWidget {
|
|
@@ -10,27 +9,22 @@ class ChapterAppBar extends StatelessWidget implements PreferredSizeWidget {
|
|
|
10
9
|
|
|
11
10
|
@override
|
|
12
11
|
Widget build(BuildContext context) {
|
|
13
|
-
final
|
|
12
|
+
final app = AppModel.of(context);
|
|
14
13
|
final model = ChapterViewModel.of(context);
|
|
15
|
-
final selectedBook =
|
|
14
|
+
final selectedBook = app.bible.books[model.book];
|
|
16
15
|
final bookName = selectedBook.name;
|
|
16
|
+
final isDesktop = isWide(context);
|
|
17
17
|
return SafeArea(
|
|
18
18
|
child: Container(
|
|
19
|
-
padding:
|
|
19
|
+
padding: EdgeInsets.only(left: 18, right: 5, top: isDesktop ? 5 : 0),
|
|
20
20
|
child: Row(
|
|
21
|
-
mainAxisAlignment: MainAxisAlignment.
|
|
21
|
+
mainAxisAlignment: MainAxisAlignment.start,
|
|
22
|
+
crossAxisAlignment: CrossAxisAlignment.center,
|
|
22
23
|
children: [
|
|
23
24
|
InkWell(
|
|
24
25
|
enableFeedback: true,
|
|
25
|
-
onTap: () {
|
|
26
|
-
Navigator.of(context).push(
|
|
27
|
-
createNoTransitionPageRoute(
|
|
28
|
-
|
|
26
|
+
onTap: () => app.changeBook(context),
|
|
29
|
-
),
|
|
30
|
-
);
|
|
31
|
-
},
|
|
32
27
|
child: Row(
|
|
33
|
-
mainAxisAlignment: MainAxisAlignment.start,
|
|
34
28
|
children: [
|
|
35
29
|
Text(
|
|
36
30
|
"$bookName ${model.chapter + 1}",
|
|
@@ -44,10 +38,31 @@ class ChapterAppBar extends StatelessWidget implements PreferredSizeWidget {
|
|
|
44
38
|
],
|
|
45
39
|
),
|
|
46
40
|
),
|
|
41
|
+
Expanded(
|
|
42
|
+
child: Row(
|
|
43
|
+
mainAxisAlignment: MainAxisAlignment.end,
|
|
44
|
+
children: [
|
|
45
|
+
if (isDesktop)
|
|
46
|
+
TextButton.icon(
|
|
47
|
+
onPressed: () => app.changeBibleFromHeader(context),
|
|
48
|
+
style: ButtonStyle(
|
|
49
|
+
padding: MaterialStateProperty.all(const EdgeInsets.symmetric(horizontal: 10)),
|
|
50
|
+
),
|
|
51
|
+
icon: const Icon(Icons.book_outlined),
|
|
52
|
+
label: Text(
|
|
53
|
+
app.bible.name,
|
|
54
|
+
),
|
|
55
|
+
),
|
|
56
|
+
Padding(
|
|
57
|
+
padding: const EdgeInsets.only(left: 10),
|
|
47
|
-
|
|
58
|
+
child: IconButton(
|
|
48
|
-
|
|
59
|
+
padding: EdgeInsets.zero,
|
|
49
|
-
|
|
60
|
+
onPressed: () => AppModel.ofEvent(context).showSettings(context),
|
|
50
|
-
|
|
61
|
+
icon: Icon(Icons.more_vert, size: isDesktop ? 28 : 24),
|
|
62
|
+
),
|
|
63
|
+
),
|
|
64
|
+
],
|
|
65
|
+
),
|
|
51
66
|
),
|
|
52
67
|
],
|
|
53
68
|
),
|
lib/widgets/settings_sheet.dart
CHANGED
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
import "package:flutter/material.dart";
|
|
2
2
|
import "package:only_bible_app/state.dart";
|
|
3
3
|
import "package:settings_ui/settings_ui.dart";
|
|
4
|
-
import "package:only_bible_app/screens/bible_select_screen.dart";
|
|
5
4
|
|
|
6
5
|
class SettingsSheet extends StatelessWidget {
|
|
7
6
|
const SettingsSheet({super.key});
|
|
8
7
|
|
|
9
8
|
@override
|
|
10
9
|
Widget build(BuildContext context) {
|
|
11
|
-
final
|
|
10
|
+
final app = AppModel.of(context);
|
|
12
|
-
final selectedBible =
|
|
11
|
+
final selectedBible = app.bible;
|
|
13
|
-
final modeIcon =
|
|
12
|
+
final modeIcon = app.darkMode ? Icons.dark_mode : Icons.light_mode;
|
|
14
|
-
final modeIconColor =
|
|
13
|
+
final modeIconColor = app.darkMode ? const Color(0xFF59EEFF) : const Color(0xFFE5B347);
|
|
15
14
|
final iconColor = Theme.of(context).textTheme.bodyMedium!.color;
|
|
16
15
|
return Column(
|
|
17
16
|
children: [
|
|
@@ -46,27 +45,23 @@ class SettingsSheet extends StatelessWidget {
|
|
|
46
45
|
title: const Text("Bible"),
|
|
47
46
|
value: Text(selectedBible.name),
|
|
48
47
|
onPressed: (c) {
|
|
49
|
-
Navigator.of(c).pushReplacement(
|
|
50
|
-
createNoTransitionPageRoute(
|
|
51
|
-
|
|
48
|
+
app.changeBible(c);
|
|
52
|
-
),
|
|
53
|
-
);
|
|
54
49
|
return null;
|
|
55
50
|
},
|
|
56
51
|
),
|
|
57
52
|
SettingsTile.switchTile(
|
|
58
53
|
onToggle: (value) {
|
|
59
|
-
|
|
54
|
+
app.toggleMode();
|
|
60
55
|
},
|
|
61
|
-
initialValue:
|
|
56
|
+
initialValue: app.darkMode,
|
|
62
57
|
leading: Icon(modeIcon, color: modeIconColor),
|
|
63
58
|
title: const Text("Dark mode"),
|
|
64
59
|
),
|
|
65
60
|
SettingsTile.switchTile(
|
|
66
61
|
onToggle: (value) {
|
|
67
|
-
|
|
62
|
+
app.toggleBold();
|
|
68
63
|
},
|
|
69
|
-
initialValue:
|
|
64
|
+
initialValue: app.fontBold,
|
|
70
65
|
leading: Icon(Icons.format_bold, color: iconColor),
|
|
71
66
|
title: const Text("Bold font"),
|
|
72
67
|
),
|
|
@@ -74,7 +69,7 @@ class SettingsSheet extends StatelessWidget {
|
|
|
74
69
|
title: const Text("Increase font size"),
|
|
75
70
|
leading: Icon(Icons.font_download, color: iconColor),
|
|
76
71
|
trailing: IconButton(
|
|
77
|
-
onPressed:
|
|
72
|
+
onPressed: app.increaseFont,
|
|
78
73
|
icon: const Icon(Icons.add_circle_outline, size: 32, color: Colors.redAccent),
|
|
79
74
|
),
|
|
80
75
|
),
|
|
@@ -82,7 +77,7 @@ class SettingsSheet extends StatelessWidget {
|
|
|
82
77
|
title: const Text("Decrease font size"),
|
|
83
78
|
leading: Icon(Icons.font_download, color: iconColor),
|
|
84
79
|
trailing: IconButton(
|
|
85
|
-
onPressed:
|
|
80
|
+
onPressed: app.decreaseFont,
|
|
86
81
|
icon: const Icon(Icons.remove_circle_outline, size: 32, color: Colors.blueAccent),
|
|
87
82
|
),
|
|
88
83
|
),
|