~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.
765da5d1
—
pyrossh 2 years ago
improve verse list
- README.md +16 -5
- lib/theme.dart +5 -0
- lib/widgets/verse_list.dart +52 -17
- lib/widgets/verse_view.dart +31 -14
README.md
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
# Only Bible App
|
|
2
2
|
|
|
3
|
+
The only bible app you will ever need. No ads, No in-app purchases, No unwanted menus, No images, No Additional downloads,
|
|
3
|
-
|
|
4
|
+
Optimized for reading and highlighting.
|
|
5
|
+
Just the bibles which are freely available in the public domain.
|
|
6
|
+
Verse by verse audio is also supported for some of the languages generated using Azure TTS.
|
|
7
|
+
|
|
8
|
+
Most of the major Indian languages are supported such as Hindi, Kannada, Tamil, Malayalam, Nepali.
|
|
4
9
|
|
|
5
10
|
## Setup
|
|
6
11
|
|
|
@@ -9,12 +14,14 @@ brew install fluttter cocoapods firebase-cli
|
|
|
9
14
|
```
|
|
10
15
|
|
|
11
16
|
## Lint
|
|
17
|
+
|
|
12
18
|
```agsl
|
|
13
19
|
dart fix --apply
|
|
14
20
|
dart format lib
|
|
15
21
|
```
|
|
16
22
|
|
|
17
23
|
## Build
|
|
24
|
+
|
|
18
25
|
```agsl
|
|
19
26
|
dart pub global activate flutterfire_cli
|
|
20
27
|
flutterfire configure --project=only-bible-app
|
|
@@ -23,6 +30,7 @@ dart run flutter_native_splash:create
|
|
|
23
30
|
```
|
|
24
31
|
|
|
25
32
|
## Run
|
|
33
|
+
|
|
26
34
|
```agsl
|
|
27
35
|
flutter clean
|
|
28
36
|
flutter run
|
|
@@ -30,17 +38,20 @@ firebase emulators:start
|
|
|
30
38
|
```
|
|
31
39
|
|
|
32
40
|
## Test
|
|
41
|
+
|
|
33
42
|
```agsl
|
|
34
43
|
flutter test
|
|
35
44
|
```
|
|
36
45
|
|
|
37
46
|
## Deploy
|
|
47
|
+
|
|
38
48
|
```agsl
|
|
39
49
|
flutter build web
|
|
40
50
|
firebase deploy
|
|
41
51
|
```
|
|
42
52
|
|
|
43
53
|
## Web
|
|
54
|
+
|
|
44
55
|
```agsl
|
|
45
56
|
https://only-bible-app.web.app
|
|
46
57
|
https://only-bible-app.firebaseapp.com/
|
|
@@ -48,6 +59,7 @@ https://onlybible.app
|
|
|
48
59
|
```
|
|
49
60
|
|
|
50
61
|
## Sync audio files
|
|
62
|
+
|
|
51
63
|
```agsl
|
|
52
64
|
gsutil -m cp -r scripts/audio/Kannada gs://only-bible-app.appspot.com/
|
|
53
65
|
```
|
|
@@ -56,12 +68,11 @@ Note:
|
|
|
56
68
|
> For crashanalytics to work in dev/debug mode in macos this has to be set DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
|
57
69
|
|
|
58
70
|
## Bugs
|
|
59
|
-
1. Fix verse number layout flow
|
|
60
|
-
|
|
71
|
+
1. Swipe left should pop context if chapter/book index is previous to the current one to maintain scroll history.
|
|
61
|
-
3. Reduce verse line spacing
|
|
62
72
|
|
|
63
73
|
## Todo
|
|
74
|
+
|
|
64
75
|
1. Add Sqlite for highlighting, notes, chapter verses
|
|
65
|
-
2. Custom Selection should show action bar instead of tooltip/popup menu
|
|
76
|
+
2. Custom Selection should show action bar instead of tooltip/popup menu
|
|
66
77
|
3. Figure out history
|
|
67
78
|
4. Add more text compact/loose maybe spacing
|
lib/theme.dart
CHANGED
|
@@ -12,6 +12,11 @@ final lightTheme = ThemeData(
|
|
|
12
12
|
hoverColor: const Color(0xAAF8D0DC),
|
|
13
13
|
dividerColor: Colors.black,
|
|
14
14
|
shadowColor: Colors.black,
|
|
15
|
+
// textSelectionTheme: TextSelectionThemeData(
|
|
16
|
+
// cursorColor: Colors.black,
|
|
17
|
+
// selectionHandleColor: Colors.black,
|
|
18
|
+
// selectionColor: const Color(0xAAF8D0DC),
|
|
19
|
+
// ),
|
|
15
20
|
appBarTheme: const AppBarTheme(
|
|
16
21
|
backgroundColor: Colors.white,
|
|
17
22
|
toolbarHeight: 30,
|
lib/widgets/verse_list.dart
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
+
import "package:flutter/gestures.dart";
|
|
1
2
|
import "package:flutter/material.dart";
|
|
2
|
-
import "package:only_bible_app/widgets/verse_view.dart";
|
|
3
3
|
import "package:only_bible_app/state.dart";
|
|
4
4
|
|
|
5
5
|
class VerseList extends StatelessWidget {
|
|
@@ -7,24 +7,59 @@ class VerseList extends StatelessWidget {
|
|
|
7
7
|
|
|
8
8
|
@override
|
|
9
9
|
Widget build(BuildContext context) {
|
|
10
|
+
final model = ChapterViewModel.of(context);
|
|
10
11
|
final chapter = ChapterViewModel.selectedChapter(context);
|
|
11
|
-
return
|
|
12
|
+
return SingleChildScrollView(
|
|
12
|
-
child: ListView.builder(
|
|
13
|
-
|
|
13
|
+
physics: const BouncingScrollPhysics(),
|
|
14
|
-
shrinkWrap: false,
|
|
15
|
-
|
|
14
|
+
padding: const EdgeInsets.symmetric(horizontal: 20),
|
|
15
|
+
child: SelectableText.rich(
|
|
16
|
+
contextMenuBuilder: null,
|
|
16
|
-
|
|
17
|
+
textScaleFactor: 1,
|
|
17
|
-
|
|
18
|
+
onSelectionChanged: (selection, _) {
|
|
19
|
+
// Show copy, highlight, note, audio, share
|
|
18
|
-
bottom: 55, // TODO: maybe make this 55 only when actions bar is show else 20
|
|
20
|
+
//bottom: 55, // TODO: maybe make this 55 only when actions bar is show else 20
|
|
19
|
-
),
|
|
20
|
-
itemCount: chapter.verses.length,
|
|
21
|
-
itemBuilder: (BuildContext context, int index) {
|
|
22
|
-
final v = chapter.verses[index];
|
|
23
|
-
return Container(
|
|
24
|
-
margin: const EdgeInsets.symmetric(vertical: 6),
|
|
25
|
-
child: VerseText(index: index, text: v.text),
|
|
26
|
-
);
|
|
27
21
|
},
|
|
22
|
+
TextSpan(
|
|
23
|
+
style: DefaultTextStyle.of(context).style,
|
|
24
|
+
children: chapter.verses
|
|
25
|
+
.asMap()
|
|
26
|
+
.entries
|
|
27
|
+
.map(
|
|
28
|
+
(e) => [
|
|
29
|
+
WidgetSpan(
|
|
30
|
+
child: Transform.translate(
|
|
31
|
+
offset: const Offset(0, -2),
|
|
32
|
+
child: Text("${e.key + 1} ", style: Theme.of(context).textTheme.labelMedium),
|
|
33
|
+
),
|
|
34
|
+
),
|
|
35
|
+
TextSpan(
|
|
36
|
+
text: "${e.value.text}\n",
|
|
37
|
+
style: model.isVerseSelected(e.key)
|
|
38
|
+
? TextStyle(
|
|
39
|
+
backgroundColor: Theme.of(context).highlightColor,
|
|
40
|
+
)
|
|
41
|
+
: null,
|
|
42
|
+
recognizer: TapGestureRecognizer()..onTap = () => model.onVerseSelected(context, e.key),
|
|
43
|
+
),
|
|
44
|
+
const WidgetSpan(
|
|
45
|
+
child: Padding(
|
|
46
|
+
padding: EdgeInsets.only(bottom: 30),
|
|
47
|
+
),
|
|
48
|
+
),
|
|
49
|
+
],
|
|
50
|
+
)
|
|
51
|
+
.expand((element) => element)
|
|
52
|
+
.toList(),
|
|
53
|
+
),
|
|
54
|
+
// userSelections: model.selectedVerses
|
|
55
|
+
// .map(
|
|
56
|
+
// (e) => UserSelection(
|
|
57
|
+
// hasCaret: false,
|
|
58
|
+
// highlightStyle: _primaryHighlightStyle,
|
|
59
|
+
// selection: TextSelection(baseOffset: e , extentOffset: 10),
|
|
60
|
+
// ),
|
|
61
|
+
// )
|
|
62
|
+
// .toList(),
|
|
28
63
|
),
|
|
29
64
|
);
|
|
30
65
|
}
|
lib/widgets/verse_view.dart
CHANGED
|
@@ -22,24 +22,41 @@ class VerseText extends StatelessWidget {
|
|
|
22
22
|
decoration: BoxDecoration(
|
|
23
23
|
color: selected ? Theme.of(context).highlightColor : Theme.of(context).colorScheme.background,
|
|
24
24
|
),
|
|
25
|
-
child:
|
|
25
|
+
child: RichText(
|
|
26
|
+
text: TextSpan(
|
|
26
|
-
|
|
27
|
+
style: DefaultTextStyle.of(context).style,
|
|
27
|
-
|
|
28
|
+
children: [
|
|
28
|
-
|
|
29
|
+
WidgetSpan(
|
|
29
|
-
margin: const EdgeInsets.only(right: 4),
|
|
30
|
-
|
|
30
|
+
child: Transform.translate(
|
|
31
|
-
|
|
31
|
+
offset: const Offset(0, -2),
|
|
32
|
-
|
|
32
|
+
child: Text("${index + 1} ", style: Theme.of(context).textTheme.labelMedium),
|
|
33
|
+
),
|
|
33
34
|
),
|
|
34
|
-
),
|
|
35
|
-
|
|
35
|
+
TextSpan(
|
|
36
|
-
|
|
36
|
+
text: text,
|
|
37
|
-
text,
|
|
38
37
|
style: TextStyle(fontSize: bodySize, fontWeight: weight),
|
|
39
38
|
),
|
|
40
|
-
)
|
|
41
|
-
|
|
39
|
+
],
|
|
40
|
+
),
|
|
42
41
|
),
|
|
42
|
+
// Row(
|
|
43
|
+
// crossAxisAlignment: CrossAxisAlignment.start,
|
|
44
|
+
// children: [
|
|
45
|
+
// Container(
|
|
46
|
+
// margin: const EdgeInsets.only(right: 4),
|
|
47
|
+
// child: Transform.translate(
|
|
48
|
+
// offset: const Offset(0, 2),
|
|
49
|
+
// child: Text("${index + 1}", style: Theme.of(context).textTheme.labelMedium),
|
|
50
|
+
// ),
|
|
51
|
+
// ),
|
|
52
|
+
// Flexible(
|
|
53
|
+
// child: Text(
|
|
54
|
+
// text,
|
|
55
|
+
// style: TextStyle(fontSize: bodySize, fontWeight: weight),
|
|
56
|
+
// ),
|
|
57
|
+
// )
|
|
58
|
+
// ],
|
|
59
|
+
// ),
|
|
43
60
|
),
|
|
44
61
|
);
|
|
45
62
|
}
|