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


a7e5a479 pyrossh

2 years ago
add play button
bible_app/android/app/build.gradle CHANGED
@@ -48,8 +48,8 @@ android {
48
48
  applicationId "com.example.bible_app"
49
49
  // You can update the following values to match your application needs.
50
50
  // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
51
- minSdkVersion flutter.minSdkVersion
51
+ minSdkVersion 30
52
- targetSdkVersion flutter.targetSdkVersion
52
+ targetSdkVersion 31
53
53
  versionCode flutterVersionCode.toInteger()
54
54
  versionName flutterVersionName
55
55
  }
bible_app/ios/Podfile.lock CHANGED
@@ -1,22 +1,41 @@
1
1
  PODS:
2
+ - audio_session (0.0.1):
3
+ - Flutter
2
4
  - Flutter (1.0.0)
5
+ - just_audio (0.0.1):
6
+ - Flutter
3
7
  - path_provider_foundation (0.0.1):
4
8
  - Flutter
5
9
  - FlutterMacOS
10
+ - shared_preferences_foundation (0.0.1):
11
+ - Flutter
12
+ - FlutterMacOS
6
13
 
7
14
  DEPENDENCIES:
15
+ - audio_session (from `.symlinks/plugins/audio_session/ios`)
8
16
  - Flutter (from `Flutter`)
17
+ - just_audio (from `.symlinks/plugins/just_audio/ios`)
9
18
  - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
19
+ - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
10
20
 
11
21
  EXTERNAL SOURCES:
22
+ audio_session:
23
+ :path: ".symlinks/plugins/audio_session/ios"
12
24
  Flutter:
13
25
  :path: Flutter
26
+ just_audio:
27
+ :path: ".symlinks/plugins/just_audio/ios"
14
28
  path_provider_foundation:
15
29
  :path: ".symlinks/plugins/path_provider_foundation/darwin"
30
+ shared_preferences_foundation:
31
+ :path: ".symlinks/plugins/shared_preferences_foundation/darwin"
16
32
 
17
33
  SPEC CHECKSUMS:
34
+ audio_session: 4f3e461722055d21515cf3261b64c973c062f345
18
35
  Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
36
+ just_audio: baa7252489dbcf47a4c7cc9ca663e9661c99aafa
19
37
  path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943
38
+ shared_preferences_foundation: 5b919d13b803cadd15ed2dc053125c68730e5126
20
39
 
21
40
  PODFILE CHECKSUM: 70d9d25280d0dd177a5f637cdb0f0b0b12c6a189
22
41
 
bible_app/lib/components/books_list.dart CHANGED
@@ -19,8 +19,8 @@ class BooksList extends StatelessWidget {
19
19
  tabBookIndex.value = offset + index;
20
20
  },
21
21
  child: Container(
22
- width: 90,
22
+ width: isDesktop() ? 90 : 50,
23
- height: 50,
23
+ height: isDesktop() ? 50 : 40,
24
24
  margin: const EdgeInsets.all(8),
25
25
  child: Material(
26
26
  elevation: 3,
bible_app/lib/components/chapters_list.dart CHANGED
@@ -25,8 +25,8 @@ class ChaptersList extends StatelessWidget {
25
25
  saveState(bookIndex, index);
26
26
  },
27
27
  child: Container(
28
- width: 90,
28
+ width: isDesktop() ? 90 : 50,
29
- height: 50,
29
+ height: isDesktop() ? 50 : 40,
30
30
  margin: const EdgeInsets.all(8),
31
31
  child: Material(
32
32
  elevation: 3,
bible_app/lib/components/header.dart CHANGED
@@ -1,10 +1,10 @@
1
1
  import "dart:math";
2
2
  import "package:flutter/material.dart";
3
3
  import "package:just_audio/just_audio.dart";
4
+ import "package:kannada_bible_app/components/play_button.dart";
4
5
  import "package:kannada_bible_app/domain/book.dart";
5
6
  import "../routes/select.dart";
6
7
  import "../state.dart";
7
- import "../domain/kannada_gen.dart";
8
8
 
9
9
  class Header extends StatelessWidget {
10
10
  final int book;
@@ -19,8 +19,8 @@ class Header extends StatelessWidget {
19
19
  @override
20
20
  Widget build(BuildContext context) {
21
21
  return Container(
22
- margin: const EdgeInsets.symmetric(horizontal: 40),
22
+ margin: EdgeInsets.symmetric(horizontal: isDesktop() ? 40 : 20),
23
- padding: const EdgeInsets.symmetric(vertical: 15),
23
+ padding: EdgeInsets.symmetric(vertical: isDesktop() ? 15 : 0),
24
24
  decoration: const BoxDecoration(
25
25
  border: Border(bottom: BorderSide(width: 1.5)),
26
26
  ),
@@ -46,27 +46,7 @@ class Header extends StatelessWidget {
46
46
  ),
47
47
  ),
48
48
  const Spacer(flex: 8),
49
- IconButton(
50
- icon: const Icon(Icons.play_circle_fill, size: 36),
51
- onPressed: () async {
52
- final verses = kannadaBible[book].chapters[chapter].verses;
49
+ PlayButton(book: book, chapter: chapter),
53
- final filteredVerses =
54
- verses.asMap().keys.where((it) => selectedVerses.value.contains(it)).map((it) => verses[it]);
55
- // Todo: play/pause button
56
- for (final v in filteredVerses) {
57
- try {
58
- await player.setClip(
59
- start: Duration(milliseconds: (v.audioRange.start * 1000).toInt()),
60
- end: Duration(milliseconds: (v.audioRange.end * 1000).toInt()),
61
- );
62
- await player.play();
63
- await player.pause();
64
- } catch (err) {
65
- // show
66
- }
67
- }
68
- },
69
- ),
70
50
  const Spacer(flex: 1),
71
51
  ],
72
52
  ),
bible_app/lib/main.dart CHANGED
@@ -1,4 +1,5 @@
1
1
  import "package:flutter/material.dart";
2
+ import 'package:flutter/services.dart';
2
3
  import 'package:go_router/go_router.dart';
3
4
  import 'package:kannada_bible_app/domain/book.dart';
4
5
  import 'package:kannada_bible_app/state.dart';
@@ -27,15 +28,24 @@ final _router = GoRouter(
27
28
  $selectScreenRoute,
28
29
  ],
29
30
  builder: (context, state, child) {
31
+ SystemChrome.setSystemUIOverlayStyle(const SystemUiOverlayStyle(
32
+ systemNavigationBarColor: Colors.white,
33
+ statusBarColor: Colors.white,
34
+ systemNavigationBarIconBrightness: Brightness.dark,
35
+ statusBarIconBrightness: Brightness.light,
36
+ ));
30
37
  return Scaffold(
31
38
  backgroundColor: Colors.white,
39
+ body: SafeArea(
40
+ // minimum: EdgeInsets.all(16),
32
- body: Row(
41
+ child: Row(
33
- children: [
42
+ children: [
34
- const Sidebar(),
43
+ isDesktop() ? const Sidebar() : Container(),
35
- Flexible(
44
+ Flexible(
36
- child: child,
45
+ child: child,
37
- ),
46
+ ),
38
- ],
47
+ ],
48
+ ),
39
49
  ),
40
50
  );
41
51
  },
bible_app/lib/routes/index.dart CHANGED
@@ -32,9 +32,9 @@ class HomeScreenRoute extends GoRouteData {
32
32
  Header(book: allBooks.indexWhere((it) => it == book), chapter: chapter),
33
33
  Flexible(
34
34
  child: ListView.builder(
35
- padding: const EdgeInsets.symmetric(
35
+ padding: EdgeInsets.symmetric(
36
36
  vertical: 20,
37
- horizontal: 40,
37
+ horizontal: isDesktop() ? 40 : 20,
38
38
  ),
39
39
  itemCount: verses.length,
40
40
  itemBuilder: (BuildContext context, int index) {
bible_app/lib/routes/select.dart CHANGED
@@ -4,6 +4,7 @@ import 'package:go_router/go_router.dart';
4
4
  import '../components/books_list.dart';
5
5
  import '../components/chapters_list.dart';
6
6
  import '../domain/book.dart';
7
+ import '../state.dart';
7
8
  import '../utils/dialog.dart';
8
9
 
9
10
  part 'select.g.dart';
@@ -16,21 +17,22 @@ class SelectScreenRoute extends GoRouteData {
16
17
  @override
17
18
  Page buildPage(BuildContext context, GoRouterState state) {
18
19
  final width = MediaQuery.of(context).size.width;
19
- final right = width / 10;
20
+ final right = isDesktop() ? width / 10 : 0.0;
21
+ final left = isDesktop() ? 40.0 : 10.0;
20
22
  return NoPageTransition(
21
23
  child: Column(
22
24
  crossAxisAlignment: CrossAxisAlignment.start,
23
25
  children: [
24
26
  Flexible(
25
27
  child: Container(
26
- margin: EdgeInsets.only(left: 40, top: 20, right: right),
28
+ margin: EdgeInsets.only(left: left, top: 20, right: right),
27
29
  child: DefaultTabController(
28
30
  length: 2,
29
31
  // animationDuration: Platform.isMacOS ? Duration.zero: const Duration(milliseconds: 300),
30
32
  child: Column(
31
33
  children: [
32
34
  SizedBox(
33
- width: 250,
35
+ width: 350,
34
36
  child: TabBar(
35
37
  labelPadding: EdgeInsets.zero,
36
38
  labelColor: Colors.black,
@@ -67,7 +69,7 @@ class SelectScreenRoute extends GoRouteData {
67
69
  ),
68
70
  ),
69
71
  Container(
70
- margin: const EdgeInsets.symmetric(vertical: 20),
72
+ margin: const EdgeInsets.symmetric(vertical: 20, horizontal: 10),
71
73
  decoration: const BoxDecoration(
72
74
  border: Border(bottom: BorderSide(width: 1.5)),
73
75
  ),
bible_app/lib/state.dart CHANGED
@@ -1,8 +1,18 @@
1
+ import 'dart:io' show Platform;
1
2
  import 'package:flutter/material.dart';
2
3
  import 'package:flutter_reactive_value/flutter_reactive_value.dart';
3
4
  import 'package:shared_preferences/shared_preferences.dart';
4
5
 
5
6
  final selectedVerses = ValueNotifier([]);
7
+ final isPlaying = ValueNotifier(false);
8
+
9
+ onPlay() {
10
+ isPlaying.value = true;
11
+ }
12
+
13
+ onPause() {
14
+ isPlaying.value = false;
15
+ }
6
16
 
7
17
  isVerseSelected(BuildContext context, int i) {
8
18
  return selectedVerses.reactiveValue(context).contains(i);
@@ -33,4 +43,8 @@ Future<(int, int)> loadState() async {
33
43
  final bookIndex = prefs.getInt("bookIndex") ?? 0;
34
44
  final chapterIndex = prefs.getInt("chapterIndex") ?? 0;
35
45
  return (bookIndex, chapterIndex);
46
+ }
47
+
48
+ bool isDesktop() {
49
+ return Platform.isMacOS || Platform.isLinux || Platform.isWindows;
36
50
  }
bible_app/lib/utils/dialog.dart CHANGED
@@ -26,134 +26,41 @@ Future<T?> showCustomDialog<T>(BuildContext context, Widget child) {
26
26
  );
27
27
  }
28
28
 
29
- class DialogUtils {
30
- static final DialogUtils _instance = DialogUtils.internal();
29
+ showAlert(BuildContext context, String title, String message) {
31
-
32
- DialogUtils.internal();
33
-
34
- factory DialogUtils() => _instance;
35
-
36
- static void showCustomDialog(BuildContext context,
37
- {required String title,
38
- String okBtnText = "Ok",
39
- String cancelBtnText = "Cancel",
40
- required Function okBtnFunction}) {
41
- showDialog(
30
+ showDialog(
42
- context: context,
43
- builder: (_) {
44
- return AlertDialog(
45
- title: Text(title),
46
- // content:
47
- actions: <Widget>[
48
- TextButton(
49
- child: Text(okBtnText),
50
- onPressed: () {},
51
- ),
52
- TextButton(child: Text(cancelBtnText), onPressed: () => Navigator.pop(context))
53
- ],
54
- );
55
- });
56
- }
57
- }
58
-
59
- class PlaceholderDialog extends StatelessWidget {
60
- const PlaceholderDialog({
61
- this.icon,
62
- this.title,
63
- this.message,
64
- this.actions = const [],
65
- Key? key,
66
- }) : super(key: key);
67
-
68
- final Widget? icon;
69
- final String? title;
70
- final String? message;
71
- final List<Widget> actions;
72
-
73
- @override
74
- Widget build(BuildContext context) {
75
- return AlertDialog(
76
- shape: RoundedRectangleBorder(
77
- borderRadius: BorderRadius.circular(20.0),
78
- ),
79
- icon: icon,
80
- title: title == null
81
- ? null
82
- : Text(
83
- title!,
84
- textAlign: TextAlign.center,
85
- ),
86
- // titleTextStyle: AppStyle.bodyBlack,
87
- content: message == null
88
- ? null
89
- : Text(
90
- message!,
91
- textAlign: TextAlign.center,
92
- ),
93
- // contentTextStyle: AppStyle.textBlack,
94
- actionsAlignment: MainAxisAlignment.center,
95
- actionsOverflowButtonSpacing: 8.0,
96
- actions: actions,
97
- );
98
- }
99
- }
100
-
101
-
102
- void showSlideCustomDialog(BuildContext context) {
103
- showGeneralDialog(
104
31
  context: context,
105
- barrierLabel: "Barrier",
106
- barrierDismissible: true,
107
- barrierColor: Colors.black.withOpacity(0.5),
108
- transitionDuration: const Duration(milliseconds: 700),
109
- pageBuilder: (_, __, ___) {
32
+ builder: (_) {
110
- return Center(
33
+ return AlertDialog(
111
- child: Container(
34
+ title: Text(title, textAlign: TextAlign.center),
112
- height: 240,
35
+ content: Text(message, textAlign: TextAlign.center),
113
- margin: const EdgeInsets.symmetric(horizontal: 20),
36
+ actionsAlignment: MainAxisAlignment.center,
114
- decoration: BoxDecoration(color: Colors.white, borderRadius: BorderRadius.circular(40)),
37
+ actionsOverflowButtonSpacing: 8.0,
38
+ actions: <Widget>[
39
+ TextButton(
115
- child: const SizedBox.expand(child: FlutterLogo()),
40
+ child: const Text("Ok"),
41
+ onPressed: () {
42
+ context.pop();
43
+ },
116
- ),
44
+ ),
117
- );
118
- },
45
+ ],
119
- transitionBuilder: (_, anim, __, child) {
120
- Tween<Offset> tween;
121
- if (anim.status == AnimationStatus.reverse) {
122
- tween = Tween(begin: const Offset(-1, 0), end: Offset.zero);
123
- } else {
124
- tween = Tween(begin: const Offset(1, 0), end: Offset.zero);
125
- }
126
-
127
- return SlideTransition(
128
- position: tween.animate(anim),
129
- child: FadeTransition(
130
- opacity: anim,
131
- child: child,
132
- ),
133
46
  );
134
47
  },
135
48
  );
136
49
  }
137
50
 
138
- // showCustomDialog<(int, int)>(context, const BookSelector()).then((rec) {
51
+ showError(BuildContext context, String message) {
139
- // if (rec != null) {
140
- // selectedVerses.value.clear();
52
+ showAlert(context, "Error", message);
141
- // onBookChange(rec.$1);
142
- // onChapterChange(rec.$2);
143
- // SchedulerBinding.instance.addPostFrameCallback((duration) {
144
- // tabIndex.value = 0;
145
- // });
146
- // }
53
+ }
147
- // });
54
+
148
55
  class NoPageTransition extends CustomTransitionPage {
149
56
  NoPageTransition({required super.child})
150
57
  : super(
151
- transitionDuration: const Duration(milliseconds: 0),
58
+ transitionDuration: const Duration(milliseconds: 0),
152
- reverseTransitionDuration: const Duration(milliseconds: 0),
59
+ reverseTransitionDuration: const Duration(milliseconds: 0),
153
- transitionsBuilder: (context, animation, secondaryAnimation, child) {
60
+ transitionsBuilder: (context, animation, secondaryAnimation, child) {
154
- return FadeTransition(
61
+ return FadeTransition(
155
- opacity: animation,
62
+ opacity: animation,
156
- child: child,
63
+ child: child,
157
- );
64
+ );
158
- });
65
+ });
159
- }
66
+ }
bible_app/macos/Runner/Info.plist CHANGED
@@ -13,7 +13,7 @@
13
13
  <key>CFBundleInfoDictionaryVersion</key>
14
14
  <string>6.0</string>
15
15
  <key>CFBundleName</key>
16
- <string>$(PRODUCT_NAME)</string>
16
+ <string>Only Bible App</string>
17
17
  <key>CFBundlePackageType</key>
18
18
  <string>APPL</string>
19
19
  <key>CFBundleShortVersionString</key>