~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.
0a263db5
—
pyrossh 2 years ago
use bloc
- lib/app.dart +35 -22
- lib/atom.dart +39 -0
- lib/blocs/bible_bloc.dart +28 -0
- lib/blocs/bible_bloc.freezed.dart +725 -0
- lib/blocs/bible_event.dart +7 -0
- lib/blocs/bible_state.dart +8 -0
- lib/main.dart +0 -1
- lib/models.dart +10 -2
- lib/screens/bible_select_screen.dart +3 -0
- lib/screens/chapter_view_screen.dart +67 -40
- lib/state.dart +4 -15
- lib/widgets/bible_loader.dart +0 -27
- macos/Podfile.lock +0 -29
lib/app.dart
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import "package:flutter/material.dart";
|
|
2
|
+
import "package:flutter_bloc/flutter_bloc.dart";
|
|
2
3
|
import "package:flutter_gen/gen_l10n/app_localizations.dart";
|
|
4
|
+
import "package:only_bible_app/blocs/bible_bloc.dart";
|
|
3
5
|
import "package:only_bible_app/screens/bible_select_screen.dart";
|
|
4
6
|
import "package:only_bible_app/screens/chapter_view_screen.dart";
|
|
5
7
|
import "package:only_bible_app/state.dart";
|
|
@@ -12,28 +14,39 @@ class App extends StatelessWidget {
|
|
|
12
14
|
|
|
13
15
|
@override
|
|
14
16
|
Widget build(BuildContext context) {
|
|
17
|
+
return BlocProvider<BibleBloc>(
|
|
18
|
+
create: (context) => BibleBloc(null)
|
|
19
|
+
..add(
|
|
20
|
+
firstOpen.value ? const BibleEvent.firstLoad() : BibleEvent.load(bibleName.value),
|
|
21
|
+
),
|
|
22
|
+
child: Builder(
|
|
23
|
+
builder: (context) {
|
|
15
|
-
|
|
24
|
+
return MaterialApp(
|
|
16
|
-
|
|
25
|
+
onGenerateTitle: (context) => context.l.title,
|
|
17
|
-
|
|
26
|
+
localizationsDelegates: AppLocalizations.localizationsDelegates,
|
|
18
|
-
|
|
27
|
+
supportedLocales: AppLocalizations.supportedLocales,
|
|
19
|
-
|
|
28
|
+
debugShowCheckedModeBanner: false,
|
|
20
|
-
|
|
29
|
+
themeMode: darkMode.watch(context) ? ThemeMode.dark : ThemeMode.light,
|
|
21
|
-
|
|
30
|
+
theme: lightTheme,
|
|
22
|
-
|
|
31
|
+
darkTheme: darkTheme,
|
|
23
|
-
|
|
32
|
+
locale: Locale(languageCode.watch(context)),
|
|
24
|
-
|
|
33
|
+
// initialRoute: "",
|
|
25
|
-
|
|
34
|
+
routes: {
|
|
26
|
-
|
|
35
|
+
// TODO: maybe have a landing page
|
|
27
|
-
|
|
36
|
+
// "/": (context) => const ScaffoldMarkdown(title: "Privacy Policy", file: "privacy-policy.md"),
|
|
37
|
+
"/privacy-policy": (context) =>
|
|
28
|
-
|
|
38
|
+
const ScaffoldMarkdown(title: "Privacy Policy", file: "privacy-policy.md"),
|
|
29
|
-
|
|
39
|
+
"/about-us": (context) => const ScaffoldMarkdown(title: "About Us", file: "about-us.md"),
|
|
30
|
-
|
|
40
|
+
},
|
|
31
|
-
|
|
41
|
+
home: firstOpen.value
|
|
32
|
-
|
|
42
|
+
? const BibleSelectScreen()
|
|
33
|
-
|
|
43
|
+
: ChapterViewScreen(
|
|
34
|
-
|
|
44
|
+
bookIndex: savedBook.value,
|
|
35
|
-
|
|
45
|
+
chapterIndex: savedChapter.value,
|
|
36
|
-
|
|
46
|
+
),
|
|
47
|
+
);
|
|
48
|
+
},
|
|
49
|
+
),
|
|
37
50
|
);
|
|
38
51
|
}
|
|
39
52
|
}
|
lib/atom.dart
CHANGED
|
@@ -64,3 +64,42 @@ class Atom<T> extends ValueNotifier<T> {
|
|
|
64
64
|
class _ListenerWrapper {
|
|
65
65
|
void Function()? listener;
|
|
66
66
|
}
|
|
67
|
+
|
|
68
|
+
class AsyncAtom<T> extends ValueNotifier<T> {
|
|
69
|
+
final T Function(T) callback;
|
|
70
|
+
|
|
71
|
+
AsyncAtom(super._value, this.callback);
|
|
72
|
+
|
|
73
|
+
@override
|
|
74
|
+
get value {
|
|
75
|
+
return callback(this.value);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
T watch(BuildContext context) {
|
|
79
|
+
final elementRef = WeakReference(context as Element);
|
|
80
|
+
final listenerWrapper = _ListenerWrapper();
|
|
81
|
+
listenerWrapper.listener = () {
|
|
82
|
+
assert(
|
|
83
|
+
SchedulerBinding.instance.schedulerPhase != SchedulerPhase.persistentCallbacks,
|
|
84
|
+
"""
|
|
85
|
+
Do not mutate state (by setting the value of the ValueNotifier
|
|
86
|
+
that you are subscribed to) during a `build` method. If you need
|
|
87
|
+
to schedule a value update after `build` has completed, use
|
|
88
|
+
`SchedulerBinding.instance.scheduleTask(updateTask, Priority.idle)`,
|
|
89
|
+
`SchedulerBinding.addPostFrameCallback(updateTask)`, '
|
|
90
|
+
or similar.
|
|
91
|
+
""",
|
|
92
|
+
);
|
|
93
|
+
// If the element has not been garbage collected (causing
|
|
94
|
+
// `elementRef.target` to be null), or unmounted
|
|
95
|
+
if (elementRef.target?.mounted ?? false) {
|
|
96
|
+
// Mark the element as needing to be rebuilt
|
|
97
|
+
elementRef.target!.markNeedsBuild();
|
|
98
|
+
}
|
|
99
|
+
// Remove the listener -- only listen to one change per `build`
|
|
100
|
+
removeListener(listenerWrapper.listener!);
|
|
101
|
+
};
|
|
102
|
+
addListener(listenerWrapper.listener!);
|
|
103
|
+
return value;
|
|
104
|
+
}
|
|
105
|
+
}
|
lib/blocs/bible_bloc.dart
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import "package:bloc/bloc.dart";
|
|
2
|
+
import "package:freezed_annotation/freezed_annotation.dart";
|
|
3
|
+
import "package:only_bible_app/models.dart";
|
|
4
|
+
import "package:only_bible_app/state.dart";
|
|
5
|
+
|
|
6
|
+
part "bible_bloc.freezed.dart";
|
|
7
|
+
|
|
8
|
+
part "bible_event.dart";
|
|
9
|
+
|
|
10
|
+
part "bible_state.dart";
|
|
11
|
+
|
|
12
|
+
class BibleBloc extends Bloc<BibleEvent, BibleState> {
|
|
13
|
+
final String? bibleName;
|
|
14
|
+
BibleBloc(this.bibleName) : super(const _Loading()) {
|
|
15
|
+
on<NoBible>((event, emit) {
|
|
16
|
+
emit(const _Loading());
|
|
17
|
+
});
|
|
18
|
+
on<LoadBible>((event, emit) async {
|
|
19
|
+
try {
|
|
20
|
+
emit(const _Loading());
|
|
21
|
+
final bible = await loadBible(event.name);
|
|
22
|
+
emit(_Success(bible!));
|
|
23
|
+
} catch (e) {
|
|
24
|
+
emit(const _Error());
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
}
|
lib/blocs/bible_bloc.freezed.dart
ADDED
|
@@ -0,0 +1,725 @@
|
|
|
1
|
+
// coverage:ignore-file
|
|
2
|
+
// GENERATED CODE - DO NOT MODIFY BY HAND
|
|
3
|
+
// ignore_for_file: type=lint
|
|
4
|
+
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
|
5
|
+
|
|
6
|
+
part of 'bible_bloc.dart';
|
|
7
|
+
|
|
8
|
+
// **************************************************************************
|
|
9
|
+
// FreezedGenerator
|
|
10
|
+
// **************************************************************************
|
|
11
|
+
|
|
12
|
+
T _$identity<T>(T value) => value;
|
|
13
|
+
|
|
14
|
+
final _privateConstructorUsedError = UnsupportedError(
|
|
15
|
+
'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#custom-getters-and-methods');
|
|
16
|
+
|
|
17
|
+
/// @nodoc
|
|
18
|
+
mixin _$BibleEvent {
|
|
19
|
+
@optionalTypeArgs
|
|
20
|
+
TResult when<TResult extends Object?>({
|
|
21
|
+
required TResult Function() firstLoad,
|
|
22
|
+
required TResult Function(String name) load,
|
|
23
|
+
}) =>
|
|
24
|
+
throw _privateConstructorUsedError;
|
|
25
|
+
@optionalTypeArgs
|
|
26
|
+
TResult? whenOrNull<TResult extends Object?>({
|
|
27
|
+
TResult? Function()? firstLoad,
|
|
28
|
+
TResult? Function(String name)? load,
|
|
29
|
+
}) =>
|
|
30
|
+
throw _privateConstructorUsedError;
|
|
31
|
+
@optionalTypeArgs
|
|
32
|
+
TResult maybeWhen<TResult extends Object?>({
|
|
33
|
+
TResult Function()? firstLoad,
|
|
34
|
+
TResult Function(String name)? load,
|
|
35
|
+
required TResult orElse(),
|
|
36
|
+
}) =>
|
|
37
|
+
throw _privateConstructorUsedError;
|
|
38
|
+
@optionalTypeArgs
|
|
39
|
+
TResult map<TResult extends Object?>({
|
|
40
|
+
required TResult Function(NoBible value) firstLoad,
|
|
41
|
+
required TResult Function(LoadBible value) load,
|
|
42
|
+
}) =>
|
|
43
|
+
throw _privateConstructorUsedError;
|
|
44
|
+
@optionalTypeArgs
|
|
45
|
+
TResult? mapOrNull<TResult extends Object?>({
|
|
46
|
+
TResult? Function(NoBible value)? firstLoad,
|
|
47
|
+
TResult? Function(LoadBible value)? load,
|
|
48
|
+
}) =>
|
|
49
|
+
throw _privateConstructorUsedError;
|
|
50
|
+
@optionalTypeArgs
|
|
51
|
+
TResult maybeMap<TResult extends Object?>({
|
|
52
|
+
TResult Function(NoBible value)? firstLoad,
|
|
53
|
+
TResult Function(LoadBible value)? load,
|
|
54
|
+
required TResult orElse(),
|
|
55
|
+
}) =>
|
|
56
|
+
throw _privateConstructorUsedError;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/// @nodoc
|
|
60
|
+
abstract class $BibleEventCopyWith<$Res> {
|
|
61
|
+
factory $BibleEventCopyWith(
|
|
62
|
+
BibleEvent value, $Res Function(BibleEvent) then) =
|
|
63
|
+
_$BibleEventCopyWithImpl<$Res, BibleEvent>;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/// @nodoc
|
|
67
|
+
class _$BibleEventCopyWithImpl<$Res, $Val extends BibleEvent>
|
|
68
|
+
implements $BibleEventCopyWith<$Res> {
|
|
69
|
+
_$BibleEventCopyWithImpl(this._value, this._then);
|
|
70
|
+
|
|
71
|
+
// ignore: unused_field
|
|
72
|
+
final $Val _value;
|
|
73
|
+
// ignore: unused_field
|
|
74
|
+
final $Res Function($Val) _then;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/// @nodoc
|
|
78
|
+
abstract class _$$NoBibleCopyWith<$Res> {
|
|
79
|
+
factory _$$NoBibleCopyWith(_$NoBible value, $Res Function(_$NoBible) then) =
|
|
80
|
+
__$$NoBibleCopyWithImpl<$Res>;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/// @nodoc
|
|
84
|
+
class __$$NoBibleCopyWithImpl<$Res>
|
|
85
|
+
extends _$BibleEventCopyWithImpl<$Res, _$NoBible>
|
|
86
|
+
implements _$$NoBibleCopyWith<$Res> {
|
|
87
|
+
__$$NoBibleCopyWithImpl(_$NoBible _value, $Res Function(_$NoBible) _then)
|
|
88
|
+
: super(_value, _then);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/// @nodoc
|
|
92
|
+
|
|
93
|
+
class _$NoBible implements NoBible {
|
|
94
|
+
const _$NoBible();
|
|
95
|
+
|
|
96
|
+
@override
|
|
97
|
+
String toString() {
|
|
98
|
+
return 'BibleEvent.firstLoad()';
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
@override
|
|
102
|
+
bool operator ==(dynamic other) {
|
|
103
|
+
return identical(this, other) ||
|
|
104
|
+
(other.runtimeType == runtimeType && other is _$NoBible);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
@override
|
|
108
|
+
int get hashCode => runtimeType.hashCode;
|
|
109
|
+
|
|
110
|
+
@override
|
|
111
|
+
@optionalTypeArgs
|
|
112
|
+
TResult when<TResult extends Object?>({
|
|
113
|
+
required TResult Function() firstLoad,
|
|
114
|
+
required TResult Function(String name) load,
|
|
115
|
+
}) {
|
|
116
|
+
return firstLoad();
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
@override
|
|
120
|
+
@optionalTypeArgs
|
|
121
|
+
TResult? whenOrNull<TResult extends Object?>({
|
|
122
|
+
TResult? Function()? firstLoad,
|
|
123
|
+
TResult? Function(String name)? load,
|
|
124
|
+
}) {
|
|
125
|
+
return firstLoad?.call();
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
@override
|
|
129
|
+
@optionalTypeArgs
|
|
130
|
+
TResult maybeWhen<TResult extends Object?>({
|
|
131
|
+
TResult Function()? firstLoad,
|
|
132
|
+
TResult Function(String name)? load,
|
|
133
|
+
required TResult orElse(),
|
|
134
|
+
}) {
|
|
135
|
+
if (firstLoad != null) {
|
|
136
|
+
return firstLoad();
|
|
137
|
+
}
|
|
138
|
+
return orElse();
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
@override
|
|
142
|
+
@optionalTypeArgs
|
|
143
|
+
TResult map<TResult extends Object?>({
|
|
144
|
+
required TResult Function(NoBible value) firstLoad,
|
|
145
|
+
required TResult Function(LoadBible value) load,
|
|
146
|
+
}) {
|
|
147
|
+
return firstLoad(this);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
@override
|
|
151
|
+
@optionalTypeArgs
|
|
152
|
+
TResult? mapOrNull<TResult extends Object?>({
|
|
153
|
+
TResult? Function(NoBible value)? firstLoad,
|
|
154
|
+
TResult? Function(LoadBible value)? load,
|
|
155
|
+
}) {
|
|
156
|
+
return firstLoad?.call(this);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
@override
|
|
160
|
+
@optionalTypeArgs
|
|
161
|
+
TResult maybeMap<TResult extends Object?>({
|
|
162
|
+
TResult Function(NoBible value)? firstLoad,
|
|
163
|
+
TResult Function(LoadBible value)? load,
|
|
164
|
+
required TResult orElse(),
|
|
165
|
+
}) {
|
|
166
|
+
if (firstLoad != null) {
|
|
167
|
+
return firstLoad(this);
|
|
168
|
+
}
|
|
169
|
+
return orElse();
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
abstract class NoBible implements BibleEvent {
|
|
174
|
+
const factory NoBible() = _$NoBible;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/// @nodoc
|
|
178
|
+
abstract class _$$LoadBibleCopyWith<$Res> {
|
|
179
|
+
factory _$$LoadBibleCopyWith(
|
|
180
|
+
_$LoadBible value, $Res Function(_$LoadBible) then) =
|
|
181
|
+
__$$LoadBibleCopyWithImpl<$Res>;
|
|
182
|
+
@useResult
|
|
183
|
+
$Res call({String name});
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
/// @nodoc
|
|
187
|
+
class __$$LoadBibleCopyWithImpl<$Res>
|
|
188
|
+
extends _$BibleEventCopyWithImpl<$Res, _$LoadBible>
|
|
189
|
+
implements _$$LoadBibleCopyWith<$Res> {
|
|
190
|
+
__$$LoadBibleCopyWithImpl(
|
|
191
|
+
_$LoadBible _value, $Res Function(_$LoadBible) _then)
|
|
192
|
+
: super(_value, _then);
|
|
193
|
+
|
|
194
|
+
@pragma('vm:prefer-inline')
|
|
195
|
+
@override
|
|
196
|
+
$Res call({
|
|
197
|
+
Object? name = null,
|
|
198
|
+
}) {
|
|
199
|
+
return _then(_$LoadBible(
|
|
200
|
+
null == name
|
|
201
|
+
? _value.name
|
|
202
|
+
: name // ignore: cast_nullable_to_non_nullable
|
|
203
|
+
as String,
|
|
204
|
+
));
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/// @nodoc
|
|
209
|
+
|
|
210
|
+
class _$LoadBible implements LoadBible {
|
|
211
|
+
const _$LoadBible(this.name);
|
|
212
|
+
|
|
213
|
+
@override
|
|
214
|
+
final String name;
|
|
215
|
+
|
|
216
|
+
@override
|
|
217
|
+
String toString() {
|
|
218
|
+
return 'BibleEvent.load(name: $name)';
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
@override
|
|
222
|
+
bool operator ==(dynamic other) {
|
|
223
|
+
return identical(this, other) ||
|
|
224
|
+
(other.runtimeType == runtimeType &&
|
|
225
|
+
other is _$LoadBible &&
|
|
226
|
+
(identical(other.name, name) || other.name == name));
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
@override
|
|
230
|
+
int get hashCode => Object.hash(runtimeType, name);
|
|
231
|
+
|
|
232
|
+
@JsonKey(ignore: true)
|
|
233
|
+
@override
|
|
234
|
+
@pragma('vm:prefer-inline')
|
|
235
|
+
_$$LoadBibleCopyWith<_$LoadBible> get copyWith =>
|
|
236
|
+
__$$LoadBibleCopyWithImpl<_$LoadBible>(this, _$identity);
|
|
237
|
+
|
|
238
|
+
@override
|
|
239
|
+
@optionalTypeArgs
|
|
240
|
+
TResult when<TResult extends Object?>({
|
|
241
|
+
required TResult Function() firstLoad,
|
|
242
|
+
required TResult Function(String name) load,
|
|
243
|
+
}) {
|
|
244
|
+
return load(name);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
@override
|
|
248
|
+
@optionalTypeArgs
|
|
249
|
+
TResult? whenOrNull<TResult extends Object?>({
|
|
250
|
+
TResult? Function()? firstLoad,
|
|
251
|
+
TResult? Function(String name)? load,
|
|
252
|
+
}) {
|
|
253
|
+
return load?.call(name);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
@override
|
|
257
|
+
@optionalTypeArgs
|
|
258
|
+
TResult maybeWhen<TResult extends Object?>({
|
|
259
|
+
TResult Function()? firstLoad,
|
|
260
|
+
TResult Function(String name)? load,
|
|
261
|
+
required TResult orElse(),
|
|
262
|
+
}) {
|
|
263
|
+
if (load != null) {
|
|
264
|
+
return load(name);
|
|
265
|
+
}
|
|
266
|
+
return orElse();
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
@override
|
|
270
|
+
@optionalTypeArgs
|
|
271
|
+
TResult map<TResult extends Object?>({
|
|
272
|
+
required TResult Function(NoBible value) firstLoad,
|
|
273
|
+
required TResult Function(LoadBible value) load,
|
|
274
|
+
}) {
|
|
275
|
+
return load(this);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
@override
|
|
279
|
+
@optionalTypeArgs
|
|
280
|
+
TResult? mapOrNull<TResult extends Object?>({
|
|
281
|
+
TResult? Function(NoBible value)? firstLoad,
|
|
282
|
+
TResult? Function(LoadBible value)? load,
|
|
283
|
+
}) {
|
|
284
|
+
return load?.call(this);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
@override
|
|
288
|
+
@optionalTypeArgs
|
|
289
|
+
TResult maybeMap<TResult extends Object?>({
|
|
290
|
+
TResult Function(NoBible value)? firstLoad,
|
|
291
|
+
TResult Function(LoadBible value)? load,
|
|
292
|
+
required TResult orElse(),
|
|
293
|
+
}) {
|
|
294
|
+
if (load != null) {
|
|
295
|
+
return load(this);
|
|
296
|
+
}
|
|
297
|
+
return orElse();
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
abstract class LoadBible implements BibleEvent {
|
|
302
|
+
const factory LoadBible(final String name) = _$LoadBible;
|
|
303
|
+
|
|
304
|
+
String get name;
|
|
305
|
+
@JsonKey(ignore: true)
|
|
306
|
+
_$$LoadBibleCopyWith<_$LoadBible> get copyWith =>
|
|
307
|
+
throw _privateConstructorUsedError;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/// @nodoc
|
|
311
|
+
mixin _$BibleState {
|
|
312
|
+
@optionalTypeArgs
|
|
313
|
+
TResult when<TResult extends Object?>({
|
|
314
|
+
required TResult Function() loading,
|
|
315
|
+
required TResult Function(Bible bible) success,
|
|
316
|
+
required TResult Function() error,
|
|
317
|
+
}) =>
|
|
318
|
+
throw _privateConstructorUsedError;
|
|
319
|
+
@optionalTypeArgs
|
|
320
|
+
TResult? whenOrNull<TResult extends Object?>({
|
|
321
|
+
TResult? Function()? loading,
|
|
322
|
+
TResult? Function(Bible bible)? success,
|
|
323
|
+
TResult? Function()? error,
|
|
324
|
+
}) =>
|
|
325
|
+
throw _privateConstructorUsedError;
|
|
326
|
+
@optionalTypeArgs
|
|
327
|
+
TResult maybeWhen<TResult extends Object?>({
|
|
328
|
+
TResult Function()? loading,
|
|
329
|
+
TResult Function(Bible bible)? success,
|
|
330
|
+
TResult Function()? error,
|
|
331
|
+
required TResult orElse(),
|
|
332
|
+
}) =>
|
|
333
|
+
throw _privateConstructorUsedError;
|
|
334
|
+
@optionalTypeArgs
|
|
335
|
+
TResult map<TResult extends Object?>({
|
|
336
|
+
required TResult Function(_Loading value) loading,
|
|
337
|
+
required TResult Function(_Success value) success,
|
|
338
|
+
required TResult Function(_Error value) error,
|
|
339
|
+
}) =>
|
|
340
|
+
throw _privateConstructorUsedError;
|
|
341
|
+
@optionalTypeArgs
|
|
342
|
+
TResult? mapOrNull<TResult extends Object?>({
|
|
343
|
+
TResult? Function(_Loading value)? loading,
|
|
344
|
+
TResult? Function(_Success value)? success,
|
|
345
|
+
TResult? Function(_Error value)? error,
|
|
346
|
+
}) =>
|
|
347
|
+
throw _privateConstructorUsedError;
|
|
348
|
+
@optionalTypeArgs
|
|
349
|
+
TResult maybeMap<TResult extends Object?>({
|
|
350
|
+
TResult Function(_Loading value)? loading,
|
|
351
|
+
TResult Function(_Success value)? success,
|
|
352
|
+
TResult Function(_Error value)? error,
|
|
353
|
+
required TResult orElse(),
|
|
354
|
+
}) =>
|
|
355
|
+
throw _privateConstructorUsedError;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
/// @nodoc
|
|
359
|
+
abstract class $BibleStateCopyWith<$Res> {
|
|
360
|
+
factory $BibleStateCopyWith(
|
|
361
|
+
BibleState value, $Res Function(BibleState) then) =
|
|
362
|
+
_$BibleStateCopyWithImpl<$Res, BibleState>;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
/// @nodoc
|
|
366
|
+
class _$BibleStateCopyWithImpl<$Res, $Val extends BibleState>
|
|
367
|
+
implements $BibleStateCopyWith<$Res> {
|
|
368
|
+
_$BibleStateCopyWithImpl(this._value, this._then);
|
|
369
|
+
|
|
370
|
+
// ignore: unused_field
|
|
371
|
+
final $Val _value;
|
|
372
|
+
// ignore: unused_field
|
|
373
|
+
final $Res Function($Val) _then;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
/// @nodoc
|
|
377
|
+
abstract class _$$_LoadingCopyWith<$Res> {
|
|
378
|
+
factory _$$_LoadingCopyWith(
|
|
379
|
+
_$_Loading value, $Res Function(_$_Loading) then) =
|
|
380
|
+
__$$_LoadingCopyWithImpl<$Res>;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
/// @nodoc
|
|
384
|
+
class __$$_LoadingCopyWithImpl<$Res>
|
|
385
|
+
extends _$BibleStateCopyWithImpl<$Res, _$_Loading>
|
|
386
|
+
implements _$$_LoadingCopyWith<$Res> {
|
|
387
|
+
__$$_LoadingCopyWithImpl(_$_Loading _value, $Res Function(_$_Loading) _then)
|
|
388
|
+
: super(_value, _then);
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
/// @nodoc
|
|
392
|
+
|
|
393
|
+
class _$_Loading implements _Loading {
|
|
394
|
+
const _$_Loading();
|
|
395
|
+
|
|
396
|
+
@override
|
|
397
|
+
String toString() {
|
|
398
|
+
return 'BibleState.loading()';
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
@override
|
|
402
|
+
bool operator ==(dynamic other) {
|
|
403
|
+
return identical(this, other) ||
|
|
404
|
+
(other.runtimeType == runtimeType && other is _$_Loading);
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
@override
|
|
408
|
+
int get hashCode => runtimeType.hashCode;
|
|
409
|
+
|
|
410
|
+
@override
|
|
411
|
+
@optionalTypeArgs
|
|
412
|
+
TResult when<TResult extends Object?>({
|
|
413
|
+
required TResult Function() loading,
|
|
414
|
+
required TResult Function(Bible bible) success,
|
|
415
|
+
required TResult Function() error,
|
|
416
|
+
}) {
|
|
417
|
+
return loading();
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
@override
|
|
421
|
+
@optionalTypeArgs
|
|
422
|
+
TResult? whenOrNull<TResult extends Object?>({
|
|
423
|
+
TResult? Function()? loading,
|
|
424
|
+
TResult? Function(Bible bible)? success,
|
|
425
|
+
TResult? Function()? error,
|
|
426
|
+
}) {
|
|
427
|
+
return loading?.call();
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
@override
|
|
431
|
+
@optionalTypeArgs
|
|
432
|
+
TResult maybeWhen<TResult extends Object?>({
|
|
433
|
+
TResult Function()? loading,
|
|
434
|
+
TResult Function(Bible bible)? success,
|
|
435
|
+
TResult Function()? error,
|
|
436
|
+
required TResult orElse(),
|
|
437
|
+
}) {
|
|
438
|
+
if (loading != null) {
|
|
439
|
+
return loading();
|
|
440
|
+
}
|
|
441
|
+
return orElse();
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
@override
|
|
445
|
+
@optionalTypeArgs
|
|
446
|
+
TResult map<TResult extends Object?>({
|
|
447
|
+
required TResult Function(_Loading value) loading,
|
|
448
|
+
required TResult Function(_Success value) success,
|
|
449
|
+
required TResult Function(_Error value) error,
|
|
450
|
+
}) {
|
|
451
|
+
return loading(this);
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
@override
|
|
455
|
+
@optionalTypeArgs
|
|
456
|
+
TResult? mapOrNull<TResult extends Object?>({
|
|
457
|
+
TResult? Function(_Loading value)? loading,
|
|
458
|
+
TResult? Function(_Success value)? success,
|
|
459
|
+
TResult? Function(_Error value)? error,
|
|
460
|
+
}) {
|
|
461
|
+
return loading?.call(this);
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
@override
|
|
465
|
+
@optionalTypeArgs
|
|
466
|
+
TResult maybeMap<TResult extends Object?>({
|
|
467
|
+
TResult Function(_Loading value)? loading,
|
|
468
|
+
TResult Function(_Success value)? success,
|
|
469
|
+
TResult Function(_Error value)? error,
|
|
470
|
+
required TResult orElse(),
|
|
471
|
+
}) {
|
|
472
|
+
if (loading != null) {
|
|
473
|
+
return loading(this);
|
|
474
|
+
}
|
|
475
|
+
return orElse();
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
abstract class _Loading implements BibleState {
|
|
480
|
+
const factory _Loading() = _$_Loading;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
/// @nodoc
|
|
484
|
+
abstract class _$$_SuccessCopyWith<$Res> {
|
|
485
|
+
factory _$$_SuccessCopyWith(
|
|
486
|
+
_$_Success value, $Res Function(_$_Success) then) =
|
|
487
|
+
__$$_SuccessCopyWithImpl<$Res>;
|
|
488
|
+
@useResult
|
|
489
|
+
$Res call({Bible bible});
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
/// @nodoc
|
|
493
|
+
class __$$_SuccessCopyWithImpl<$Res>
|
|
494
|
+
extends _$BibleStateCopyWithImpl<$Res, _$_Success>
|
|
495
|
+
implements _$$_SuccessCopyWith<$Res> {
|
|
496
|
+
__$$_SuccessCopyWithImpl(_$_Success _value, $Res Function(_$_Success) _then)
|
|
497
|
+
: super(_value, _then);
|
|
498
|
+
|
|
499
|
+
@pragma('vm:prefer-inline')
|
|
500
|
+
@override
|
|
501
|
+
$Res call({
|
|
502
|
+
Object? bible = null,
|
|
503
|
+
}) {
|
|
504
|
+
return _then(_$_Success(
|
|
505
|
+
null == bible
|
|
506
|
+
? _value.bible
|
|
507
|
+
: bible // ignore: cast_nullable_to_non_nullable
|
|
508
|
+
as Bible,
|
|
509
|
+
));
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
/// @nodoc
|
|
514
|
+
|
|
515
|
+
class _$_Success implements _Success {
|
|
516
|
+
const _$_Success(this.bible);
|
|
517
|
+
|
|
518
|
+
@override
|
|
519
|
+
final Bible bible;
|
|
520
|
+
|
|
521
|
+
@override
|
|
522
|
+
String toString() {
|
|
523
|
+
return 'BibleState.success(bible: $bible)';
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
@override
|
|
527
|
+
bool operator ==(dynamic other) {
|
|
528
|
+
return identical(this, other) ||
|
|
529
|
+
(other.runtimeType == runtimeType &&
|
|
530
|
+
other is _$_Success &&
|
|
531
|
+
(identical(other.bible, bible) || other.bible == bible));
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
@override
|
|
535
|
+
int get hashCode => Object.hash(runtimeType, bible);
|
|
536
|
+
|
|
537
|
+
@JsonKey(ignore: true)
|
|
538
|
+
@override
|
|
539
|
+
@pragma('vm:prefer-inline')
|
|
540
|
+
_$$_SuccessCopyWith<_$_Success> get copyWith =>
|
|
541
|
+
__$$_SuccessCopyWithImpl<_$_Success>(this, _$identity);
|
|
542
|
+
|
|
543
|
+
@override
|
|
544
|
+
@optionalTypeArgs
|
|
545
|
+
TResult when<TResult extends Object?>({
|
|
546
|
+
required TResult Function() loading,
|
|
547
|
+
required TResult Function(Bible bible) success,
|
|
548
|
+
required TResult Function() error,
|
|
549
|
+
}) {
|
|
550
|
+
return success(bible);
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
@override
|
|
554
|
+
@optionalTypeArgs
|
|
555
|
+
TResult? whenOrNull<TResult extends Object?>({
|
|
556
|
+
TResult? Function()? loading,
|
|
557
|
+
TResult? Function(Bible bible)? success,
|
|
558
|
+
TResult? Function()? error,
|
|
559
|
+
}) {
|
|
560
|
+
return success?.call(bible);
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
@override
|
|
564
|
+
@optionalTypeArgs
|
|
565
|
+
TResult maybeWhen<TResult extends Object?>({
|
|
566
|
+
TResult Function()? loading,
|
|
567
|
+
TResult Function(Bible bible)? success,
|
|
568
|
+
TResult Function()? error,
|
|
569
|
+
required TResult orElse(),
|
|
570
|
+
}) {
|
|
571
|
+
if (success != null) {
|
|
572
|
+
return success(bible);
|
|
573
|
+
}
|
|
574
|
+
return orElse();
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
@override
|
|
578
|
+
@optionalTypeArgs
|
|
579
|
+
TResult map<TResult extends Object?>({
|
|
580
|
+
required TResult Function(_Loading value) loading,
|
|
581
|
+
required TResult Function(_Success value) success,
|
|
582
|
+
required TResult Function(_Error value) error,
|
|
583
|
+
}) {
|
|
584
|
+
return success(this);
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
@override
|
|
588
|
+
@optionalTypeArgs
|
|
589
|
+
TResult? mapOrNull<TResult extends Object?>({
|
|
590
|
+
TResult? Function(_Loading value)? loading,
|
|
591
|
+
TResult? Function(_Success value)? success,
|
|
592
|
+
TResult? Function(_Error value)? error,
|
|
593
|
+
}) {
|
|
594
|
+
return success?.call(this);
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
@override
|
|
598
|
+
@optionalTypeArgs
|
|
599
|
+
TResult maybeMap<TResult extends Object?>({
|
|
600
|
+
TResult Function(_Loading value)? loading,
|
|
601
|
+
TResult Function(_Success value)? success,
|
|
602
|
+
TResult Function(_Error value)? error,
|
|
603
|
+
required TResult orElse(),
|
|
604
|
+
}) {
|
|
605
|
+
if (success != null) {
|
|
606
|
+
return success(this);
|
|
607
|
+
}
|
|
608
|
+
return orElse();
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
abstract class _Success implements BibleState {
|
|
613
|
+
const factory _Success(final Bible bible) = _$_Success;
|
|
614
|
+
|
|
615
|
+
Bible get bible;
|
|
616
|
+
@JsonKey(ignore: true)
|
|
617
|
+
_$$_SuccessCopyWith<_$_Success> get copyWith =>
|
|
618
|
+
throw _privateConstructorUsedError;
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
/// @nodoc
|
|
622
|
+
abstract class _$$_ErrorCopyWith<$Res> {
|
|
623
|
+
factory _$$_ErrorCopyWith(_$_Error value, $Res Function(_$_Error) then) =
|
|
624
|
+
__$$_ErrorCopyWithImpl<$Res>;
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
/// @nodoc
|
|
628
|
+
class __$$_ErrorCopyWithImpl<$Res>
|
|
629
|
+
extends _$BibleStateCopyWithImpl<$Res, _$_Error>
|
|
630
|
+
implements _$$_ErrorCopyWith<$Res> {
|
|
631
|
+
__$$_ErrorCopyWithImpl(_$_Error _value, $Res Function(_$_Error) _then)
|
|
632
|
+
: super(_value, _then);
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
/// @nodoc
|
|
636
|
+
|
|
637
|
+
class _$_Error implements _Error {
|
|
638
|
+
const _$_Error();
|
|
639
|
+
|
|
640
|
+
@override
|
|
641
|
+
String toString() {
|
|
642
|
+
return 'BibleState.error()';
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
@override
|
|
646
|
+
bool operator ==(dynamic other) {
|
|
647
|
+
return identical(this, other) ||
|
|
648
|
+
(other.runtimeType == runtimeType && other is _$_Error);
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
@override
|
|
652
|
+
int get hashCode => runtimeType.hashCode;
|
|
653
|
+
|
|
654
|
+
@override
|
|
655
|
+
@optionalTypeArgs
|
|
656
|
+
TResult when<TResult extends Object?>({
|
|
657
|
+
required TResult Function() loading,
|
|
658
|
+
required TResult Function(Bible bible) success,
|
|
659
|
+
required TResult Function() error,
|
|
660
|
+
}) {
|
|
661
|
+
return error();
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
@override
|
|
665
|
+
@optionalTypeArgs
|
|
666
|
+
TResult? whenOrNull<TResult extends Object?>({
|
|
667
|
+
TResult? Function()? loading,
|
|
668
|
+
TResult? Function(Bible bible)? success,
|
|
669
|
+
TResult? Function()? error,
|
|
670
|
+
}) {
|
|
671
|
+
return error?.call();
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
@override
|
|
675
|
+
@optionalTypeArgs
|
|
676
|
+
TResult maybeWhen<TResult extends Object?>({
|
|
677
|
+
TResult Function()? loading,
|
|
678
|
+
TResult Function(Bible bible)? success,
|
|
679
|
+
TResult Function()? error,
|
|
680
|
+
required TResult orElse(),
|
|
681
|
+
}) {
|
|
682
|
+
if (error != null) {
|
|
683
|
+
return error();
|
|
684
|
+
}
|
|
685
|
+
return orElse();
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
@override
|
|
689
|
+
@optionalTypeArgs
|
|
690
|
+
TResult map<TResult extends Object?>({
|
|
691
|
+
required TResult Function(_Loading value) loading,
|
|
692
|
+
required TResult Function(_Success value) success,
|
|
693
|
+
required TResult Function(_Error value) error,
|
|
694
|
+
}) {
|
|
695
|
+
return error(this);
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
@override
|
|
699
|
+
@optionalTypeArgs
|
|
700
|
+
TResult? mapOrNull<TResult extends Object?>({
|
|
701
|
+
TResult? Function(_Loading value)? loading,
|
|
702
|
+
TResult? Function(_Success value)? success,
|
|
703
|
+
TResult? Function(_Error value)? error,
|
|
704
|
+
}) {
|
|
705
|
+
return error?.call(this);
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
@override
|
|
709
|
+
@optionalTypeArgs
|
|
710
|
+
TResult maybeMap<TResult extends Object?>({
|
|
711
|
+
TResult Function(_Loading value)? loading,
|
|
712
|
+
TResult Function(_Success value)? success,
|
|
713
|
+
TResult Function(_Error value)? error,
|
|
714
|
+
required TResult orElse(),
|
|
715
|
+
}) {
|
|
716
|
+
if (error != null) {
|
|
717
|
+
return error(this);
|
|
718
|
+
}
|
|
719
|
+
return orElse();
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
|
|
723
|
+
abstract class _Error implements BibleState {
|
|
724
|
+
const factory _Error() = _$_Error;
|
|
725
|
+
}
|
lib/blocs/bible_event.dart
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
part of "bible_bloc.dart";
|
|
2
|
+
|
|
3
|
+
@freezed
|
|
4
|
+
class BibleEvent with _$BibleEvent {
|
|
5
|
+
const factory BibleEvent.firstLoad() = NoBible;
|
|
6
|
+
const factory BibleEvent.load(String name) = LoadBible;
|
|
7
|
+
}
|
lib/blocs/bible_state.dart
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
part of "bible_bloc.dart";
|
|
2
|
+
|
|
3
|
+
@freezed
|
|
4
|
+
class BibleState with _$BibleState {
|
|
5
|
+
const factory BibleState.loading() = _Loading;
|
|
6
|
+
const factory BibleState.success(Bible bible) = _Success;
|
|
7
|
+
const factory BibleState.error() = _Error;
|
|
8
|
+
}
|
lib/main.dart
CHANGED
|
@@ -34,7 +34,6 @@ void main() async {
|
|
|
34
34
|
);
|
|
35
35
|
await initState();
|
|
36
36
|
updateStatusBar(darkMode.value);
|
|
37
|
-
bibleCache.value = loadBible(bibleName.value);
|
|
38
37
|
runApp(const App());
|
|
39
38
|
FlutterNativeSplash.remove();
|
|
40
39
|
}
|
lib/models.dart
CHANGED
|
@@ -63,14 +63,21 @@ class Chapter {
|
|
|
63
63
|
|
|
64
64
|
class Verse {
|
|
65
65
|
final int index;
|
|
66
|
+
final String bibleName;
|
|
66
67
|
final int book;
|
|
67
68
|
final int chapter;
|
|
68
69
|
final String text;
|
|
69
70
|
|
|
71
|
+
const Verse({
|
|
72
|
+
required this.index,
|
|
73
|
+
required this.text,
|
|
74
|
+
required this.bibleName,
|
|
70
|
-
|
|
75
|
+
required this.chapter,
|
|
76
|
+
required this.book,
|
|
77
|
+
});
|
|
71
78
|
}
|
|
72
79
|
|
|
73
|
-
List<Book> getBibleFromText(String text) {
|
|
80
|
+
List<Book> getBibleFromText(String bibleName, String text) {
|
|
74
81
|
final List<Book> books = [];
|
|
75
82
|
final lines = text.split("\n");
|
|
76
83
|
for (var (index, line) in lines.indexed) {
|
|
@@ -103,6 +110,7 @@ List<Book> getBibleFromText(String text) {
|
|
|
103
110
|
Verse(
|
|
104
111
|
index: verseNo - 1,
|
|
105
112
|
text: verseText,
|
|
113
|
+
bibleName: bibleName,
|
|
106
114
|
chapter: chapter - 1,
|
|
107
115
|
book: book - 1,
|
|
108
116
|
),
|
lib/screens/bible_select_screen.dart
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import "package:flutter/material.dart";
|
|
2
|
+
import "package:flutter_bloc/flutter_bloc.dart";
|
|
3
|
+
import "package:only_bible_app/blocs/bible_bloc.dart";
|
|
2
4
|
import "package:only_bible_app/navigation.dart";
|
|
3
5
|
import "package:only_bible_app/state.dart";
|
|
4
6
|
import "package:only_bible_app/utils.dart";
|
|
@@ -29,6 +31,7 @@ class BibleSelectScreen extends StatelessWidget {
|
|
|
29
31
|
// ],
|
|
30
32
|
// ),
|
|
31
33
|
onPressed: () {
|
|
34
|
+
context.read<BibleBloc>().add(BibleEvent.load(l.languageTitle));
|
|
32
35
|
updateCurrentBible(context, Locale(l.localeName), l.languageTitle);
|
|
33
36
|
if (firstOpen.value) {
|
|
34
37
|
firstOpen.set!();
|
lib/screens/chapter_view_screen.dart
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import "package:flutter/material.dart";
|
|
2
|
+
import "package:flutter_bloc/flutter_bloc.dart";
|
|
3
|
+
import "package:only_bible_app/blocs/bible_bloc.dart";
|
|
4
|
+
import "package:only_bible_app/models.dart";
|
|
2
5
|
import "package:only_bible_app/utils.dart";
|
|
3
|
-
import "package:only_bible_app/widgets/bible_loader.dart";
|
|
4
6
|
import "package:only_bible_app/widgets/chapter_app_bar.dart";
|
|
5
7
|
import "package:only_bible_app/widgets/sidebar.dart";
|
|
6
8
|
import "package:only_bible_app/widgets/verses_view.dart";
|
|
7
9
|
|
|
8
10
|
class ChapterViewScreen extends StatelessWidget {
|
|
11
|
+
// final String bibleName;
|
|
9
12
|
final int bookIndex;
|
|
10
13
|
final int chapterIndex;
|
|
11
14
|
|
|
@@ -13,50 +16,74 @@ class ChapterViewScreen extends StatelessWidget {
|
|
|
13
16
|
|
|
14
17
|
@override
|
|
15
18
|
Widget build(BuildContext context) {
|
|
19
|
+
return BlocBuilder<BibleBloc, BibleState>(builder: (context, state) {
|
|
16
|
-
|
|
20
|
+
if (!context.isWide) {
|
|
21
|
+
return state.when(
|
|
22
|
+
loading: () => ColoredBox(
|
|
23
|
+
color: Theme.of(context).colorScheme.background,
|
|
24
|
+
child: const Center(
|
|
25
|
+
child: CircularProgressIndicator(),
|
|
26
|
+
),
|
|
27
|
+
),
|
|
28
|
+
success: (Bible bible) {
|
|
29
|
+
final book = bible.books[bookIndex];
|
|
30
|
+
final chapter = book.chapters[chapterIndex];
|
|
31
|
+
return Scaffold(
|
|
32
|
+
appBar: ChapterAppBar(book: book, chapter: chapter),
|
|
33
|
+
backgroundColor: Theme.of(context).colorScheme.background,
|
|
34
|
+
body: SafeArea(
|
|
35
|
+
child: VersesView(chapter: chapter),
|
|
36
|
+
),
|
|
37
|
+
);
|
|
38
|
+
},
|
|
39
|
+
error: () => ColoredBox(
|
|
40
|
+
color: Theme.of(context).colorScheme.background,
|
|
41
|
+
child: const Center(
|
|
42
|
+
child: Text("Could not load the bible"),
|
|
43
|
+
),
|
|
44
|
+
),
|
|
45
|
+
);
|
|
46
|
+
}
|
|
17
47
|
return Scaffold(
|
|
18
48
|
backgroundColor: Theme.of(context).colorScheme.background,
|
|
19
|
-
body: SafeArea(
|
|
20
|
-
|
|
49
|
+
body: Row(
|
|
21
|
-
|
|
50
|
+
children: [
|
|
22
|
-
|
|
51
|
+
const Sidebar(),
|
|
23
|
-
|
|
52
|
+
Flexible(
|
|
24
|
-
|
|
53
|
+
child: state.when(
|
|
54
|
+
loading: () => ColoredBox(
|
|
55
|
+
color: Theme.of(context).colorScheme.background,
|
|
56
|
+
child: const Center(
|
|
57
|
+
child: CircularProgressIndicator(),
|
|
58
|
+
),
|
|
59
|
+
),
|
|
25
|
-
|
|
60
|
+
success: (Bible bible) {
|
|
26
|
-
|
|
61
|
+
final book = bible.books[bookIndex];
|
|
27
|
-
|
|
62
|
+
final chapter = book.chapters[chapterIndex];
|
|
28
|
-
|
|
63
|
+
return Column(
|
|
29
|
-
|
|
64
|
+
children: [
|
|
30
|
-
|
|
65
|
+
ChapterAppBar(book: book, chapter: chapter),
|
|
31
|
-
|
|
66
|
+
const Padding(
|
|
32
|
-
|
|
67
|
+
padding: EdgeInsets.only(bottom: 10),
|
|
33
|
-
|
|
68
|
+
child: Divider(height: 5, indent: 20, endIndent: 20, thickness: 1.5),
|
|
34
|
-
|
|
69
|
+
),
|
|
35
|
-
|
|
70
|
+
Flexible(
|
|
36
|
-
|
|
71
|
+
child: VersesView(chapter: chapter),
|
|
37
|
-
|
|
72
|
+
),
|
|
38
|
-
|
|
73
|
+
],
|
|
39
|
-
|
|
74
|
+
);
|
|
40
|
-
|
|
75
|
+
},
|
|
76
|
+
error: () => ColoredBox(
|
|
77
|
+
color: Theme.of(context).colorScheme.background,
|
|
78
|
+
child: const Center(
|
|
79
|
+
child: Text("Could not load the bible"),
|
|
80
|
+
),
|
|
41
81
|
),
|
|
42
82
|
),
|
|
83
|
+
),
|
|
43
|
-
|
|
84
|
+
],
|
|
44
|
-
),
|
|
45
85
|
),
|
|
46
86
|
);
|
|
47
|
-
}
|
|
48
|
-
return BibleLoader(
|
|
49
|
-
builder: (bible) {
|
|
50
|
-
final book = bible.books[bookIndex];
|
|
51
|
-
final chapter = book.chapters[chapterIndex];
|
|
52
|
-
return Scaffold(
|
|
53
|
-
appBar: ChapterAppBar(book: book, chapter: chapter),
|
|
54
|
-
backgroundColor: Theme.of(context).colorScheme.background,
|
|
55
|
-
body: SafeArea(
|
|
56
|
-
child: VersesView(chapter: chapter),
|
|
57
|
-
),
|
|
58
|
-
|
|
87
|
+
});
|
|
59
|
-
},
|
|
60
|
-
);
|
|
61
88
|
}
|
|
62
89
|
}
|
lib/state.dart
CHANGED
|
@@ -55,34 +55,23 @@ final Atom<Bible> bible = Atom<Bible>(
|
|
|
55
55
|
},
|
|
56
56
|
);
|
|
57
57
|
|
|
58
|
-
final bibleCache = Atom<Future<Bible?>?>(
|
|
59
|
-
key: "bible",
|
|
60
|
-
initialValue: null,
|
|
61
|
-
);
|
|
62
|
-
|
|
63
58
|
updateCurrentBible(BuildContext context, Locale l, String name) async {
|
|
64
59
|
hideActions(context);
|
|
65
60
|
languageCode.value = l.languageCode;
|
|
66
61
|
bibleName.update!(name);
|
|
67
|
-
bibleCache.value = loadBible(name);
|
|
68
62
|
}
|
|
69
63
|
|
|
70
|
-
Future<Bible> getBibleFromAsset(String
|
|
64
|
+
Future<Bible> getBibleFromAsset(String bibleName) async {
|
|
71
|
-
final bytes = await rootBundle.load("assets/bibles/$
|
|
65
|
+
final bytes = await rootBundle.load("assets/bibles/$bibleName.txt");
|
|
72
|
-
final books = getBibleFromText(utf8.decode(bytes.buffer.asUint8List(), allowMalformed: false));
|
|
66
|
+
final books = getBibleFromText(bibleName, utf8.decode(bytes.buffer.asUint8List(), allowMalformed: false));
|
|
73
67
|
// await Future.delayed(Duration(seconds: 1));
|
|
74
68
|
return Bible.withBooks(
|
|
75
|
-
name: bibleName
|
|
69
|
+
name: bibleName,
|
|
76
70
|
books: books,
|
|
77
71
|
);
|
|
78
72
|
}
|
|
79
73
|
|
|
80
|
-
// CachedValue(
|
|
81
|
-
// () => factorial(originalValue),
|
|
82
|
-
// ).withDependency(() => originalValue)
|
|
83
|
-
|
|
84
74
|
Future<Bible?> loadBible(String name) async {
|
|
85
|
-
print("loadBible ${name}");
|
|
86
75
|
return getBibleFromAsset(name).then((value) {
|
|
87
76
|
bible.update!(value);
|
|
88
77
|
return value;
|
lib/widgets/bible_loader.dart
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
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 BibleLoader extends StatelessWidget {
|
|
6
|
-
final Function(Bible) builder;
|
|
7
|
-
|
|
8
|
-
const BibleLoader({super.key, required this.builder});
|
|
9
|
-
|
|
10
|
-
@override
|
|
11
|
-
Widget build(BuildContext context) {
|
|
12
|
-
return FutureBuilder(
|
|
13
|
-
future: bibleCache.watch(context),
|
|
14
|
-
builder: (context, snapshot) {
|
|
15
|
-
if (snapshot.connectionState == ConnectionState.done) {
|
|
16
|
-
return builder(snapshot.data!);
|
|
17
|
-
}
|
|
18
|
-
return ColoredBox(
|
|
19
|
-
color: Theme.of(context).colorScheme.background,
|
|
20
|
-
child: const Center(
|
|
21
|
-
child: CircularProgressIndicator(),
|
|
22
|
-
),
|
|
23
|
-
);
|
|
24
|
-
},
|
|
25
|
-
);
|
|
26
|
-
}
|
|
27
|
-
}
|
macos/Podfile.lock
CHANGED
|
@@ -6,9 +6,6 @@ PODS:
|
|
|
6
6
|
- Firebase/Crashlytics (10.12.0):
|
|
7
7
|
- Firebase/CoreOnly
|
|
8
8
|
- FirebaseCrashlytics (~> 10.12.0)
|
|
9
|
-
- Firebase/Storage (10.12.0):
|
|
10
|
-
- Firebase/CoreOnly
|
|
11
|
-
- FirebaseStorage (~> 10.12.0)
|
|
12
9
|
- firebase_core (2.15.0):
|
|
13
10
|
- Firebase/CoreOnly (~> 10.12.0)
|
|
14
11
|
- FlutterMacOS
|
|
@@ -17,13 +14,6 @@ PODS:
|
|
|
17
14
|
- Firebase/Crashlytics (~> 10.12.0)
|
|
18
15
|
- firebase_core
|
|
19
16
|
- FlutterMacOS
|
|
20
|
-
- firebase_storage (11.2.5):
|
|
21
|
-
- Firebase/CoreOnly (~> 10.12.0)
|
|
22
|
-
- Firebase/Storage (~> 10.12.0)
|
|
23
|
-
- firebase_core
|
|
24
|
-
- FlutterMacOS
|
|
25
|
-
- FirebaseAppCheckInterop (10.13.0)
|
|
26
|
-
- FirebaseAuthInterop (10.13.0)
|
|
27
17
|
- FirebaseCore (10.12.0):
|
|
28
18
|
- FirebaseCoreInternal (~> 10.0)
|
|
29
19
|
- GoogleUtilities/Environment (~> 7.8)
|
|
@@ -53,12 +43,6 @@ PODS:
|
|
|
53
43
|
- GoogleUtilities/Environment (~> 7.10)
|
|
54
44
|
- nanopb (< 2.30910.0, >= 2.30908.0)
|
|
55
45
|
- PromisesSwift (~> 2.1)
|
|
56
|
-
- FirebaseStorage (10.12.0):
|
|
57
|
-
- FirebaseAppCheckInterop (~> 10.0)
|
|
58
|
-
- FirebaseAuthInterop (~> 10.0)
|
|
59
|
-
- FirebaseCore (~> 10.0)
|
|
60
|
-
- FirebaseCoreExtension (~> 10.0)
|
|
61
|
-
- GTMSessionFetcher/Core (< 4.0, >= 2.1)
|
|
62
46
|
- FlutterMacOS (1.0.0)
|
|
63
47
|
- GoogleDataTransport (9.2.5):
|
|
64
48
|
- GoogleUtilities/Environment (~> 7.7)
|
|
@@ -71,7 +55,6 @@ PODS:
|
|
|
71
55
|
- "GoogleUtilities/NSData+zlib (7.11.5)"
|
|
72
56
|
- GoogleUtilities/UserDefaults (7.11.5):
|
|
73
57
|
- GoogleUtilities/Logger
|
|
74
|
-
- GTMSessionFetcher/Core (3.1.1)
|
|
75
58
|
- just_audio (0.0.1):
|
|
76
59
|
- FlutterMacOS
|
|
77
60
|
- nanopb (2.30909.0):
|
|
@@ -99,7 +82,6 @@ DEPENDENCIES:
|
|
|
99
82
|
- audio_session (from `Flutter/ephemeral/.symlinks/plugins/audio_session/macos`)
|
|
100
83
|
- firebase_core (from `Flutter/ephemeral/.symlinks/plugins/firebase_core/macos`)
|
|
101
84
|
- firebase_crashlytics (from `Flutter/ephemeral/.symlinks/plugins/firebase_crashlytics/macos`)
|
|
102
|
-
- firebase_storage (from `Flutter/ephemeral/.symlinks/plugins/firebase_storage/macos`)
|
|
103
85
|
- FlutterMacOS (from `Flutter/ephemeral`)
|
|
104
86
|
- just_audio (from `Flutter/ephemeral/.symlinks/plugins/just_audio/macos`)
|
|
105
87
|
- package_info_plus (from `Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos`)
|
|
@@ -111,18 +93,14 @@ DEPENDENCIES:
|
|
|
111
93
|
SPEC REPOS:
|
|
112
94
|
trunk:
|
|
113
95
|
- Firebase
|
|
114
|
-
- FirebaseAppCheckInterop
|
|
115
|
-
- FirebaseAuthInterop
|
|
116
96
|
- FirebaseCore
|
|
117
97
|
- FirebaseCoreExtension
|
|
118
98
|
- FirebaseCoreInternal
|
|
119
99
|
- FirebaseCrashlytics
|
|
120
100
|
- FirebaseInstallations
|
|
121
101
|
- FirebaseSessions
|
|
122
|
-
- FirebaseStorage
|
|
123
102
|
- GoogleDataTransport
|
|
124
103
|
- GoogleUtilities
|
|
125
|
-
- GTMSessionFetcher
|
|
126
104
|
- nanopb
|
|
127
105
|
- PromisesObjC
|
|
128
106
|
- PromisesSwift
|
|
@@ -134,8 +112,6 @@ EXTERNAL SOURCES:
|
|
|
134
112
|
:path: Flutter/ephemeral/.symlinks/plugins/firebase_core/macos
|
|
135
113
|
firebase_crashlytics:
|
|
136
114
|
:path: Flutter/ephemeral/.symlinks/plugins/firebase_crashlytics/macos
|
|
137
|
-
firebase_storage:
|
|
138
|
-
:path: Flutter/ephemeral/.symlinks/plugins/firebase_storage/macos
|
|
139
115
|
FlutterMacOS:
|
|
140
116
|
:path: Flutter/ephemeral
|
|
141
117
|
just_audio:
|
|
@@ -156,20 +132,15 @@ SPEC CHECKSUMS:
|
|
|
156
132
|
Firebase: 07150e75d142fb9399f6777fa56a187b17f833a0
|
|
157
133
|
firebase_core: ff59797157ca9adda4440071643761b41fcd03b3
|
|
158
134
|
firebase_crashlytics: 223f1e85437fa85822439e51db3cd0be7dd35b23
|
|
159
|
-
firebase_storage: d873afdc6a0b5307ffa2bb4a5ca9282cb0b922f3
|
|
160
|
-
FirebaseAppCheckInterop: 5e12dc623d443dedffcde9c6f3ed41510125d8ef
|
|
161
|
-
FirebaseAuthInterop: 74875bde5d15636522a8fe98beb561df7a54db58
|
|
162
135
|
FirebaseCore: f86a1394906b97ac445ae49c92552a9425831bed
|
|
163
136
|
FirebaseCoreExtension: ce60f9db46d83944cf444664d6d587474128eeca
|
|
164
137
|
FirebaseCoreInternal: b342e37cd4f5b4454ec34308f073420e7920858e
|
|
165
138
|
FirebaseCrashlytics: c4d111b7430c49744c74bcc6346ea00868661ac8
|
|
166
139
|
FirebaseInstallations: b28af1b9f997f1a799efe818c94695a3728c352f
|
|
167
140
|
FirebaseSessions: 991fb4c20b3505eef125f7cbfa20a5b5b189c2a4
|
|
168
|
-
FirebaseStorage: 1d7ca8c8953fc61ccacaa7c612696b5402968a0d
|
|
169
141
|
FlutterMacOS: 8f6f14fa908a6fb3fba0cd85dbd81ec4b251fb24
|
|
170
142
|
GoogleDataTransport: 54dee9d48d14580407f8f5fbf2f496e92437a2f2
|
|
171
143
|
GoogleUtilities: 13e2c67ede716b8741c7989e26893d151b2b2084
|
|
172
|
-
GTMSessionFetcher: e8647203b65cee28c5f73d0f473d096653945e72
|
|
173
144
|
just_audio: 9b67ca7b97c61cfc9784ea23cd8cc55eb226d489
|
|
174
145
|
nanopb: b552cce312b6c8484180ef47159bc0f65a1f0431
|
|
175
146
|
package_info_plus: 02d7a575e80f194102bef286361c6c326e4c29ce
|