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


99a21873 pyrossh

2 years ago
revamp state management
integration_test/home_screen_test.dart CHANGED
@@ -2,7 +2,7 @@ import "package:flutter/material.dart";
2
2
  import "package:flutter_test/flutter_test.dart";
3
3
  import "package:integration_test/integration_test.dart";
4
4
  import "package:only_bible_app/main.dart" as app;
5
- import "package:only_bible_app/state.dart";
5
+ import 'package:only_bible_app/store/state.dart';
6
6
 
7
7
  void main() {
8
8
  IntegrationTestWidgetsFlutterBinding.ensureInitialized();
@@ -11,8 +11,8 @@ void main() {
11
11
  testWidgets("should render", (tester) async {
12
12
  app.main();
13
13
  await tester.pumpAndSettle();
14
- languageCode.value = "en";
14
+ languageCodeAtom.value = "en";
15
- bibleName.update!("English");
15
+ bibleNameAtom.update!("English");
16
16
  bibleCache.value = loadBible("English");
17
17
  await tester.pumpAndSettle();
18
18
  final bookTitle = find.byKey(const Key("bookTitle"));
lib/actions.dart DELETED
@@ -1,8 +0,0 @@
1
- import "package:freezed_annotation/freezed_annotation.dart";
2
- part "actions.freezed.dart";
3
-
4
- @freezed
5
- class AppAction with _$AppAction {
6
- const factory AppAction.firstOpenDone() = FirstOpenDone;
7
- const factory AppAction.setLanguageCode(String code) = SetLanguageCode;
8
- }
lib/actions.freezed.dart DELETED
@@ -1,309 +0,0 @@
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 'actions.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 _$AppAction {
19
- @optionalTypeArgs
20
- TResult when<TResult extends Object?>({
21
- required TResult Function() firstOpenDone,
22
- required TResult Function(String code) setLanguageCode,
23
- }) =>
24
- throw _privateConstructorUsedError;
25
- @optionalTypeArgs
26
- TResult? whenOrNull<TResult extends Object?>({
27
- TResult? Function()? firstOpenDone,
28
- TResult? Function(String code)? setLanguageCode,
29
- }) =>
30
- throw _privateConstructorUsedError;
31
- @optionalTypeArgs
32
- TResult maybeWhen<TResult extends Object?>({
33
- TResult Function()? firstOpenDone,
34
- TResult Function(String code)? setLanguageCode,
35
- required TResult orElse(),
36
- }) =>
37
- throw _privateConstructorUsedError;
38
- @optionalTypeArgs
39
- TResult map<TResult extends Object?>({
40
- required TResult Function(FirstOpenDone value) firstOpenDone,
41
- required TResult Function(SetLanguageCode value) setLanguageCode,
42
- }) =>
43
- throw _privateConstructorUsedError;
44
- @optionalTypeArgs
45
- TResult? mapOrNull<TResult extends Object?>({
46
- TResult? Function(FirstOpenDone value)? firstOpenDone,
47
- TResult? Function(SetLanguageCode value)? setLanguageCode,
48
- }) =>
49
- throw _privateConstructorUsedError;
50
- @optionalTypeArgs
51
- TResult maybeMap<TResult extends Object?>({
52
- TResult Function(FirstOpenDone value)? firstOpenDone,
53
- TResult Function(SetLanguageCode value)? setLanguageCode,
54
- required TResult orElse(),
55
- }) =>
56
- throw _privateConstructorUsedError;
57
- }
58
-
59
- /// @nodoc
60
- abstract class $AppActionCopyWith<$Res> {
61
- factory $AppActionCopyWith(AppAction value, $Res Function(AppAction) then) =
62
- _$AppActionCopyWithImpl<$Res, AppAction>;
63
- }
64
-
65
- /// @nodoc
66
- class _$AppActionCopyWithImpl<$Res, $Val extends AppAction>
67
- implements $AppActionCopyWith<$Res> {
68
- _$AppActionCopyWithImpl(this._value, this._then);
69
-
70
- // ignore: unused_field
71
- final $Val _value;
72
- // ignore: unused_field
73
- final $Res Function($Val) _then;
74
- }
75
-
76
- /// @nodoc
77
- abstract class _$$FirstOpenDoneCopyWith<$Res> {
78
- factory _$$FirstOpenDoneCopyWith(
79
- _$FirstOpenDone value, $Res Function(_$FirstOpenDone) then) =
80
- __$$FirstOpenDoneCopyWithImpl<$Res>;
81
- }
82
-
83
- /// @nodoc
84
- class __$$FirstOpenDoneCopyWithImpl<$Res>
85
- extends _$AppActionCopyWithImpl<$Res, _$FirstOpenDone>
86
- implements _$$FirstOpenDoneCopyWith<$Res> {
87
- __$$FirstOpenDoneCopyWithImpl(
88
- _$FirstOpenDone _value, $Res Function(_$FirstOpenDone) _then)
89
- : super(_value, _then);
90
- }
91
-
92
- /// @nodoc
93
-
94
- class _$FirstOpenDone implements FirstOpenDone {
95
- const _$FirstOpenDone();
96
-
97
- @override
98
- String toString() {
99
- return 'AppAction.firstOpenDone()';
100
- }
101
-
102
- @override
103
- bool operator ==(dynamic other) {
104
- return identical(this, other) ||
105
- (other.runtimeType == runtimeType && other is _$FirstOpenDone);
106
- }
107
-
108
- @override
109
- int get hashCode => runtimeType.hashCode;
110
-
111
- @override
112
- @optionalTypeArgs
113
- TResult when<TResult extends Object?>({
114
- required TResult Function() firstOpenDone,
115
- required TResult Function(String code) setLanguageCode,
116
- }) {
117
- return firstOpenDone();
118
- }
119
-
120
- @override
121
- @optionalTypeArgs
122
- TResult? whenOrNull<TResult extends Object?>({
123
- TResult? Function()? firstOpenDone,
124
- TResult? Function(String code)? setLanguageCode,
125
- }) {
126
- return firstOpenDone?.call();
127
- }
128
-
129
- @override
130
- @optionalTypeArgs
131
- TResult maybeWhen<TResult extends Object?>({
132
- TResult Function()? firstOpenDone,
133
- TResult Function(String code)? setLanguageCode,
134
- required TResult orElse(),
135
- }) {
136
- if (firstOpenDone != null) {
137
- return firstOpenDone();
138
- }
139
- return orElse();
140
- }
141
-
142
- @override
143
- @optionalTypeArgs
144
- TResult map<TResult extends Object?>({
145
- required TResult Function(FirstOpenDone value) firstOpenDone,
146
- required TResult Function(SetLanguageCode value) setLanguageCode,
147
- }) {
148
- return firstOpenDone(this);
149
- }
150
-
151
- @override
152
- @optionalTypeArgs
153
- TResult? mapOrNull<TResult extends Object?>({
154
- TResult? Function(FirstOpenDone value)? firstOpenDone,
155
- TResult? Function(SetLanguageCode value)? setLanguageCode,
156
- }) {
157
- return firstOpenDone?.call(this);
158
- }
159
-
160
- @override
161
- @optionalTypeArgs
162
- TResult maybeMap<TResult extends Object?>({
163
- TResult Function(FirstOpenDone value)? firstOpenDone,
164
- TResult Function(SetLanguageCode value)? setLanguageCode,
165
- required TResult orElse(),
166
- }) {
167
- if (firstOpenDone != null) {
168
- return firstOpenDone(this);
169
- }
170
- return orElse();
171
- }
172
- }
173
-
174
- abstract class FirstOpenDone implements AppAction {
175
- const factory FirstOpenDone() = _$FirstOpenDone;
176
- }
177
-
178
- /// @nodoc
179
- abstract class _$$SetLanguageCodeCopyWith<$Res> {
180
- factory _$$SetLanguageCodeCopyWith(
181
- _$SetLanguageCode value, $Res Function(_$SetLanguageCode) then) =
182
- __$$SetLanguageCodeCopyWithImpl<$Res>;
183
- @useResult
184
- $Res call({String code});
185
- }
186
-
187
- /// @nodoc
188
- class __$$SetLanguageCodeCopyWithImpl<$Res>
189
- extends _$AppActionCopyWithImpl<$Res, _$SetLanguageCode>
190
- implements _$$SetLanguageCodeCopyWith<$Res> {
191
- __$$SetLanguageCodeCopyWithImpl(
192
- _$SetLanguageCode _value, $Res Function(_$SetLanguageCode) _then)
193
- : super(_value, _then);
194
-
195
- @pragma('vm:prefer-inline')
196
- @override
197
- $Res call({
198
- Object? code = null,
199
- }) {
200
- return _then(_$SetLanguageCode(
201
- null == code
202
- ? _value.code
203
- : code // ignore: cast_nullable_to_non_nullable
204
- as String,
205
- ));
206
- }
207
- }
208
-
209
- /// @nodoc
210
-
211
- class _$SetLanguageCode implements SetLanguageCode {
212
- const _$SetLanguageCode(this.code);
213
-
214
- @override
215
- final String code;
216
-
217
- @override
218
- String toString() {
219
- return 'AppAction.setLanguageCode(code: $code)';
220
- }
221
-
222
- @override
223
- bool operator ==(dynamic other) {
224
- return identical(this, other) ||
225
- (other.runtimeType == runtimeType &&
226
- other is _$SetLanguageCode &&
227
- (identical(other.code, code) || other.code == code));
228
- }
229
-
230
- @override
231
- int get hashCode => Object.hash(runtimeType, code);
232
-
233
- @JsonKey(ignore: true)
234
- @override
235
- @pragma('vm:prefer-inline')
236
- _$$SetLanguageCodeCopyWith<_$SetLanguageCode> get copyWith =>
237
- __$$SetLanguageCodeCopyWithImpl<_$SetLanguageCode>(this, _$identity);
238
-
239
- @override
240
- @optionalTypeArgs
241
- TResult when<TResult extends Object?>({
242
- required TResult Function() firstOpenDone,
243
- required TResult Function(String code) setLanguageCode,
244
- }) {
245
- return setLanguageCode(code);
246
- }
247
-
248
- @override
249
- @optionalTypeArgs
250
- TResult? whenOrNull<TResult extends Object?>({
251
- TResult? Function()? firstOpenDone,
252
- TResult? Function(String code)? setLanguageCode,
253
- }) {
254
- return setLanguageCode?.call(code);
255
- }
256
-
257
- @override
258
- @optionalTypeArgs
259
- TResult maybeWhen<TResult extends Object?>({
260
- TResult Function()? firstOpenDone,
261
- TResult Function(String code)? setLanguageCode,
262
- required TResult orElse(),
263
- }) {
264
- if (setLanguageCode != null) {
265
- return setLanguageCode(code);
266
- }
267
- return orElse();
268
- }
269
-
270
- @override
271
- @optionalTypeArgs
272
- TResult map<TResult extends Object?>({
273
- required TResult Function(FirstOpenDone value) firstOpenDone,
274
- required TResult Function(SetLanguageCode value) setLanguageCode,
275
- }) {
276
- return setLanguageCode(this);
277
- }
278
-
279
- @override
280
- @optionalTypeArgs
281
- TResult? mapOrNull<TResult extends Object?>({
282
- TResult? Function(FirstOpenDone value)? firstOpenDone,
283
- TResult? Function(SetLanguageCode value)? setLanguageCode,
284
- }) {
285
- return setLanguageCode?.call(this);
286
- }
287
-
288
- @override
289
- @optionalTypeArgs
290
- TResult maybeMap<TResult extends Object?>({
291
- TResult Function(FirstOpenDone value)? firstOpenDone,
292
- TResult Function(SetLanguageCode value)? setLanguageCode,
293
- required TResult orElse(),
294
- }) {
295
- if (setLanguageCode != null) {
296
- return setLanguageCode(this);
297
- }
298
- return orElse();
299
- }
300
- }
301
-
302
- abstract class SetLanguageCode implements AppAction {
303
- const factory SetLanguageCode(final String code) = _$SetLanguageCode;
304
-
305
- String get code;
306
- @JsonKey(ignore: true)
307
- _$$SetLanguageCodeCopyWith<_$SetLanguageCode> get copyWith =>
308
- throw _privateConstructorUsedError;
309
- }
lib/app.dart CHANGED
@@ -2,7 +2,7 @@ import "package:flutter/material.dart";
2
2
  import "package:flutter_gen/gen_l10n/app_localizations.dart";
3
3
  import "package:only_bible_app/screens/bible_select_screen.dart";
4
4
  import "package:only_bible_app/screens/chapter_view_screen.dart";
5
- import "package:only_bible_app/state.dart";
5
+ import 'package:only_bible_app/store/state.dart';
6
6
  import "package:only_bible_app/theme.dart";
7
7
  import "package:only_bible_app/utils.dart";
8
8
  import "package:only_bible_app/widgets/scaffold_markdown.dart";
@@ -17,10 +17,10 @@ class App extends StatelessWidget {
17
17
  localizationsDelegates: AppLocalizations.localizationsDelegates,
18
18
  supportedLocales: AppLocalizations.supportedLocales,
19
19
  debugShowCheckedModeBanner: false,
20
- themeMode: darkMode.watch(context) ? ThemeMode.dark : ThemeMode.light,
20
+ themeMode: darkModeAtom.watch(context) ? ThemeMode.dark : ThemeMode.light,
21
21
  theme: lightTheme,
22
22
  darkTheme: darkTheme,
23
- locale: Locale(languageCode.watch(context)),
23
+ locale: Locale(languageCodeAtom.watch(context)),
24
24
  // initialRoute: "",
25
25
  routes: {
26
26
  // TODO: maybe have a landing page
@@ -28,12 +28,12 @@ class App extends StatelessWidget {
28
28
  "/privacy-policy": (context) => const ScaffoldMarkdown(title: "Privacy Policy", file: "privacy-policy.md"),
29
29
  "/about-us": (context) => const ScaffoldMarkdown(title: "About Us", file: "about-us.md"),
30
30
  },
31
- home: firstOpen.value
31
+ home: firstOpenAtom.value
32
32
  ? const BibleSelectScreen()
33
33
  : ChapterViewScreen(
34
- bibleName: bibleName.value,
34
+ bibleName: bibleNameAtom.value,
35
- bookIndex: savedBook.value,
35
+ bookIndex: savedBookAtom.value,
36
- chapterIndex: savedChapter.value,
36
+ chapterIndex: savedChapterAtom.value,
37
37
  ),
38
38
  );
39
39
  }
lib/atom.dart CHANGED
@@ -4,22 +4,17 @@ import "package:get_storage/get_storage.dart";
4
4
 
5
5
  final List<Atom2> atoms = [];
6
6
 
7
- void dispatch<A>(A a) {
7
+ void dispatch<T, A>(A a) {
8
8
  for (final atom in atoms) {
9
- final typeName = a.runtimeType.toString().replaceAll("_\$", "");
10
- for (final entry in atom.reducer.entries) {
11
- if (typeName == entry.key.toString()) {
12
- final newValue = entry.value.call(atom.valueNotifier.value, a);
9
+ final newValue = atom.reducer(atom.valueNotifier.value, a);
13
- atom.valueNotifier.value = newValue;
10
+ atom.valueNotifier.value = newValue;
14
- if (atom.box != null) {
11
+ if (atom.box != null) {
15
- if (newValue == null) {
12
+ if (newValue == null) {
16
- atom.box!.remove(atom.key);
13
+ atom.box!.remove(atom.key);
17
- } else {
14
+ } else {
18
- atom.box!.write(atom.key, newValue);
15
+ atom.box!.write(atom.key, newValue);
19
- }
20
- atom.box!.save();
21
- }
22
16
  }
17
+ atom.box!.save();
23
18
  }
24
19
  }
25
20
  }
@@ -28,7 +23,7 @@ class Atom2<T, A> {
28
23
  late ValueNotifier<T> valueNotifier;
29
24
  final String key;
30
25
  final GetStorage? box;
31
- final Map<Type, dynamic Function(dynamic, dynamic)> reducer;
26
+ final dynamic Function(dynamic, dynamic) reducer;
32
27
 
33
28
  Atom2({required this.key, required T initialState, this.box, required this.reducer}) {
34
29
  valueNotifier = ValueNotifier(box != null ? box!.read<T>(key) ?? initialState : initialState);
lib/main.dart CHANGED
@@ -9,7 +9,7 @@ import "package:only_bible_app/firebase_options.dart";
9
9
  import "package:flutter_native_splash/flutter_native_splash.dart";
10
10
  import "package:only_bible_app/app.dart";
11
11
  import "package:only_bible_app/navigation.dart";
12
- import "package:only_bible_app/state.dart";
12
+ import "package:only_bible_app/store/state.dart";
13
13
 
14
14
  void main() async {
15
15
  WidgetsBinding widgetsBinding = WidgetsFlutterBinding.ensureInitialized();
@@ -33,7 +33,7 @@ void main() async {
33
33
  withLogs: false,
34
34
  );
35
35
  await initState();
36
- updateStatusBar(darkMode.value);
36
+ updateStatusBar(darkModeAtom.value);
37
37
  runApp(const App());
38
38
  FlutterNativeSplash.remove();
39
39
  }
lib/models.dart CHANGED
@@ -1,17 +1,14 @@
1
1
  import "package:flutter/material.dart";
2
- import "package:freezed_annotation/freezed_annotation.dart";
3
2
  import "package:only_bible_app/utils.dart";
4
- part "models.freezed.dart";
5
3
 
6
- @freezed
7
- class Bible with _$Bible {
4
+ class Bible {
5
+ final String name;
6
+ final List<Book> books;
8
7
 
9
- const Bible._();
8
+ const Bible({
10
-
11
- const factory Bible({
12
- required String name,
9
+ required this.name,
13
- required List<Book> books,
10
+ required this.books,
14
- }) = _Bible;
11
+ });
15
12
 
16
13
  String shortName() {
17
14
  return name.substring(0, 3).toUpperCase();
@@ -98,22 +95,22 @@ List<Book> getBibleFromText(String bibleName, String text) {
98
95
  }
99
96
  if (books[book - 1].chapters.length < chapter) {
100
97
  books[book - 1].chapters.add(
101
- Chapter(
98
+ Chapter(
102
- index: chapter - 1,
99
+ index: chapter - 1,
103
- book: book - 1,
100
+ book: book - 1,
104
- verses: [],
101
+ verses: [],
105
- ),
102
+ ),
106
- );
103
+ );
107
104
  }
108
105
  books[book - 1].chapters[chapter - 1].verses.add(
109
- Verse(
106
+ Verse(
110
- index: verseNo - 1,
107
+ index: verseNo - 1,
111
- text: verseText,
108
+ text: verseText,
112
- bibleName: bibleName,
109
+ bibleName: bibleName,
113
- chapter: chapter - 1,
110
+ chapter: chapter - 1,
114
- book: book - 1,
111
+ book: book - 1,
115
- ),
112
+ ),
116
- );
113
+ );
117
114
  }
118
115
  return books;
119
116
  }
lib/models.freezed.dart DELETED
@@ -1,152 +0,0 @@
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 'models.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 _$Bible {
19
- String get name => throw _privateConstructorUsedError;
20
- List<Book> get books => throw _privateConstructorUsedError;
21
-
22
- @JsonKey(ignore: true)
23
- $BibleCopyWith<Bible> get copyWith => throw _privateConstructorUsedError;
24
- }
25
-
26
- /// @nodoc
27
- abstract class $BibleCopyWith<$Res> {
28
- factory $BibleCopyWith(Bible value, $Res Function(Bible) then) =
29
- _$BibleCopyWithImpl<$Res, Bible>;
30
- @useResult
31
- $Res call({String name, List<Book> books});
32
- }
33
-
34
- /// @nodoc
35
- class _$BibleCopyWithImpl<$Res, $Val extends Bible>
36
- implements $BibleCopyWith<$Res> {
37
- _$BibleCopyWithImpl(this._value, this._then);
38
-
39
- // ignore: unused_field
40
- final $Val _value;
41
- // ignore: unused_field
42
- final $Res Function($Val) _then;
43
-
44
- @pragma('vm:prefer-inline')
45
- @override
46
- $Res call({
47
- Object? name = null,
48
- Object? books = null,
49
- }) {
50
- return _then(_value.copyWith(
51
- name: null == name
52
- ? _value.name
53
- : name // ignore: cast_nullable_to_non_nullable
54
- as String,
55
- books: null == books
56
- ? _value.books
57
- : books // ignore: cast_nullable_to_non_nullable
58
- as List<Book>,
59
- ) as $Val);
60
- }
61
- }
62
-
63
- /// @nodoc
64
- abstract class _$$_BibleCopyWith<$Res> implements $BibleCopyWith<$Res> {
65
- factory _$$_BibleCopyWith(_$_Bible value, $Res Function(_$_Bible) then) =
66
- __$$_BibleCopyWithImpl<$Res>;
67
- @override
68
- @useResult
69
- $Res call({String name, List<Book> books});
70
- }
71
-
72
- /// @nodoc
73
- class __$$_BibleCopyWithImpl<$Res> extends _$BibleCopyWithImpl<$Res, _$_Bible>
74
- implements _$$_BibleCopyWith<$Res> {
75
- __$$_BibleCopyWithImpl(_$_Bible _value, $Res Function(_$_Bible) _then)
76
- : super(_value, _then);
77
-
78
- @pragma('vm:prefer-inline')
79
- @override
80
- $Res call({
81
- Object? name = null,
82
- Object? books = null,
83
- }) {
84
- return _then(_$_Bible(
85
- name: null == name
86
- ? _value.name
87
- : name // ignore: cast_nullable_to_non_nullable
88
- as String,
89
- books: null == books
90
- ? _value._books
91
- : books // ignore: cast_nullable_to_non_nullable
92
- as List<Book>,
93
- ));
94
- }
95
- }
96
-
97
- /// @nodoc
98
-
99
- class _$_Bible extends _Bible {
100
- const _$_Bible({required this.name, required final List<Book> books})
101
- : _books = books,
102
- super._();
103
-
104
- @override
105
- final String name;
106
- final List<Book> _books;
107
- @override
108
- List<Book> get books {
109
- if (_books is EqualUnmodifiableListView) return _books;
110
- // ignore: implicit_dynamic_type
111
- return EqualUnmodifiableListView(_books);
112
- }
113
-
114
- @override
115
- String toString() {
116
- return 'Bible(name: $name, books: $books)';
117
- }
118
-
119
- @override
120
- bool operator ==(dynamic other) {
121
- return identical(this, other) ||
122
- (other.runtimeType == runtimeType &&
123
- other is _$_Bible &&
124
- (identical(other.name, name) || other.name == name) &&
125
- const DeepCollectionEquality().equals(other._books, _books));
126
- }
127
-
128
- @override
129
- int get hashCode => Object.hash(
130
- runtimeType, name, const DeepCollectionEquality().hash(_books));
131
-
132
- @JsonKey(ignore: true)
133
- @override
134
- @pragma('vm:prefer-inline')
135
- _$$_BibleCopyWith<_$_Bible> get copyWith =>
136
- __$$_BibleCopyWithImpl<_$_Bible>(this, _$identity);
137
- }
138
-
139
- abstract class _Bible extends Bible {
140
- const factory _Bible(
141
- {required final String name, required final List<Book> books}) = _$_Bible;
142
- const _Bible._() : super._();
143
-
144
- @override
145
- String get name;
146
- @override
147
- List<Book> get books;
148
- @override
149
- @JsonKey(ignore: true)
150
- _$$_BibleCopyWith<_$_Bible> get copyWith =>
151
- throw _privateConstructorUsedError;
152
- }
lib/navigation.dart CHANGED
@@ -7,7 +7,8 @@ import "package:only_bible_app/screens/chapter_view_screen.dart";
7
7
  import "package:only_bible_app/sheets/actions_sheet.dart";
8
8
  import "package:only_bible_app/sheets/highlight_sheet.dart";
9
9
  import "package:only_bible_app/sheets/settings_sheet.dart";
10
- import "package:only_bible_app/state.dart";
10
+ import "package:only_bible_app/store/actions.dart";
11
+ import 'package:only_bible_app/store/state.dart';
11
12
  import "package:only_bible_app/utils.dart";
12
13
  import "package:only_bible_app/widgets/note_sheet.dart";
13
14
  import "package:only_bible_app/widgets/scaffold_markdown.dart";
@@ -82,8 +83,7 @@ updateStatusBar(bool v) {
82
83
  }
83
84
 
84
85
  pushBookChapter(BuildContext context, String bibleName, int book, int chapter, TextDirection? dir) {
85
- savedBook.update!(book);
86
- savedChapter.update!(chapter);
86
+ dispatch(UpdateChapter(book, chapter));
87
87
  clearEvents(context);
88
88
  Navigator.of(context).push(
89
89
  createSlideRoute(
@@ -95,8 +95,7 @@ pushBookChapter(BuildContext context, String bibleName, int book, int chapter, T
95
95
  }
96
96
 
97
97
  replaceBookChapter(BuildContext context, String bibleName, int book, int chapter) {
98
- savedBook.update!(book);
99
- savedChapter.update!(chapter);
98
+ dispatch(UpdateChapter(book, chapter));
100
99
  clearEvents(context);
101
100
  Navigator.of(context).pushReplacement(
102
101
  createNoTransitionPageRoute(
@@ -173,6 +172,12 @@ changeBook(BuildContext context, Bible bible) {
173
172
  );
174
173
  }
175
174
 
175
+ updateCurrentBible(BuildContext context, String name, String code, int book, int chapter) async {
176
+ hideActions(context);
177
+ dispatch(UpdateBible(name, code));
178
+ pushBookChapter(context, name, book, chapter, null);
179
+ }
180
+
176
181
  shareAppLink(BuildContext context) {
177
182
  if (isAndroid()) {
178
183
  Share.share(
lib/screens/bible_select_screen.dart CHANGED
@@ -1,7 +1,8 @@
1
1
  import "package:flutter/material.dart";
2
- import "package:only_bible_app/actions.dart";
2
+ import "package:only_bible_app/navigation.dart";
3
+ import "package:only_bible_app/store/actions.dart";
3
4
  import "package:only_bible_app/atom.dart";
4
- import "package:only_bible_app/state.dart";
5
+ import "package:only_bible_app/store/state.dart";
5
6
  import "package:only_bible_app/utils.dart";
6
7
  import "package:only_bible_app/widgets/scaffold_menu.dart";
7
8
  import "package:only_bible_app/widgets/sliver_heading.dart";
@@ -16,7 +17,7 @@ class BibleSelectScreen extends StatelessWidget {
16
17
  child: CustomScrollView(
17
18
  physics: const BouncingScrollPhysics(),
18
19
  slivers: [
19
- SliverHeading(title: context.l.bibleSelectTitle, showClose: !firstOpen.value),
20
+ SliverHeading(title: context.l.bibleSelectTitle, showClose: !firstOpenAtom.value),
20
21
  SliverTileGrid(
21
22
  listType: ListType.extraLarge,
22
23
  children: List.of(
@@ -32,10 +33,16 @@ class BibleSelectScreen extends StatelessWidget {
32
33
  )
33
34
  : Text(l.languageTitle, textScaleFactor: 1.1),
34
35
  onPressed: () {
35
- if (firstOpen.value) {
36
+ if (firstOpenAtom.value) {
36
- dispatch(const FirstOpenDone());
37
+ dispatch(FirstOpenDone());
37
38
  }
38
- updateCurrentBible(context, l.localeName, l.languageTitle);
39
+ updateCurrentBible(
40
+ context,
41
+ l.languageTitle,
42
+ l.localeName,
43
+ savedBookAtom.value,
44
+ savedChapterAtom.value,
45
+ );
39
46
  },
40
47
  );
41
48
  }),
lib/screens/chapter_view_screen.dart CHANGED
@@ -1,6 +1,6 @@
1
1
  import "package:flutter/material.dart";
2
2
  import "package:only_bible_app/models.dart";
3
- import "package:only_bible_app/state.dart";
3
+ import 'package:only_bible_app/store/state.dart';
4
4
  import "package:only_bible_app/utils.dart";
5
5
  import "package:only_bible_app/widgets/chapter_app_bar.dart";
6
6
  import "package:only_bible_app/widgets/sidebar.dart";
lib/sheets/actions_sheet.dart CHANGED
@@ -1,7 +1,7 @@
1
1
  import "package:flutter/material.dart";
2
2
  import "package:only_bible_app/models.dart";
3
3
  import "package:only_bible_app/navigation.dart";
4
- import "package:only_bible_app/state.dart";
4
+ import 'package:only_bible_app/store/state.dart';
5
5
  import "package:only_bible_app/utils.dart";
6
6
 
7
7
  class ActionsSheet extends StatelessWidget {
@@ -12,7 +12,7 @@ class ActionsSheet extends StatelessWidget {
12
12
  @override
13
13
  Widget build(BuildContext context) {
14
14
  final bottom = isIOS() ? 20.0 : 0.0;
15
- final iconColor = darkMode.value ? Colors.white.withOpacity(0.9) : Colors.black.withOpacity(0.9);
15
+ final iconColor = darkModeAtom.value ? Colors.white.withOpacity(0.9) : Colors.black.withOpacity(0.9);
16
16
  final audioIcon = isPlaying.watch(context) ? Icons.pause_circle_outline : Icons.play_circle_outline;
17
17
  return Container(
18
18
  height: context.actionsHeight,
lib/sheets/highlight_sheet.dart CHANGED
@@ -1,5 +1,5 @@
1
1
  import "package:flutter/material.dart";
2
- import "package:only_bible_app/state.dart";
2
+ import 'package:only_bible_app/store/state.dart';
3
3
  import "package:only_bible_app/theme.dart";
4
4
  import "package:only_bible_app/utils.dart";
5
5
  import "package:only_bible_app/widgets/highlight_button.dart";
@@ -10,7 +10,7 @@ class HighlightSheet extends StatelessWidget {
10
10
  @override
11
11
  Widget build(BuildContext context) {
12
12
  final bottom = isIOS() ? 20.0 : 0.0;
13
- final iconColor = darkMode.value ? Colors.white.withOpacity(0.9) : Colors.black.withOpacity(0.9);
13
+ final iconColor = darkModeAtom.value ? Colors.white.withOpacity(0.9) : Colors.black.withOpacity(0.9);
14
14
  void onHighlight(int index) {
15
15
  setHighlight(context, index);
16
16
  }
@@ -29,22 +29,22 @@ class HighlightSheet extends StatelessWidget {
29
29
  ),
30
30
  HighlightButton(
31
31
  index: 0,
32
- color: darkMode.value ? darkHighlights[0] : lightHighlights[0],
32
+ color: darkModeAtom.value ? darkHighlights[0] : lightHighlights[0],
33
33
  onHighlightSelected: onHighlight,
34
34
  ),
35
35
  HighlightButton(
36
36
  index: 1,
37
- color: darkMode.value ? darkHighlights[1] : lightHighlights[1],
37
+ color: darkModeAtom.value ? darkHighlights[1] : lightHighlights[1],
38
38
  onHighlightSelected: onHighlight,
39
39
  ),
40
40
  HighlightButton(
41
41
  index: 2,
42
- color: darkMode.value ? darkHighlights[2] : lightHighlights[2],
42
+ color: darkModeAtom.value ? darkHighlights[2] : lightHighlights[2],
43
43
  onHighlightSelected: onHighlight,
44
44
  ),
45
45
  HighlightButton(
46
46
  index: 3,
47
- color: darkMode.value ? darkHighlights[3] : lightHighlights[3],
47
+ color: darkModeAtom.value ? darkHighlights[3] : lightHighlights[3],
48
48
  onHighlightSelected: onHighlight,
49
49
  ),
50
50
  ],
lib/sheets/settings_sheet.dart CHANGED
@@ -1,12 +1,15 @@
1
1
  import "package:flutter/material.dart";
2
+ import "package:only_bible_app/atom.dart";
2
3
  import "package:only_bible_app/models.dart";
3
4
  import "package:only_bible_app/navigation.dart";
5
+ import "package:only_bible_app/store/actions.dart";
4
- import "package:only_bible_app/state.dart";
6
+ import "package:only_bible_app/store/state.dart";
5
7
  import "package:only_bible_app/utils.dart";
6
8
  import "package:settings_ui/settings_ui.dart";
7
9
 
8
10
  class SettingsSheet extends StatelessWidget {
9
11
  final Bible bible;
12
+
10
13
  const SettingsSheet({super.key, required this.bible});
11
14
 
12
15
  @override
@@ -36,12 +39,12 @@ class SettingsSheet extends StatelessWidget {
36
39
  title: Text(context.l.themeTitle),
37
40
  trailing: ToggleButtons(
38
41
  onPressed: (int index) {
39
- darkMode.set!();
42
+ dispatch(ToggleDarkMode());
40
43
  },
41
44
  highlightColor: Colors.transparent,
42
45
  borderColor: Colors.grey,
43
46
  borderRadius: const BorderRadius.all(Radius.circular(25)),
44
- selectedColor: darkMode.value ? Colors.lightBlue.shade300 : Colors.yellowAccent.shade700,
47
+ selectedColor: darkModeAtom.value ? Colors.lightBlue.shade300 : Colors.yellowAccent.shade700,
45
48
  selectedBorderColor: Colors.grey,
46
49
  color: Colors.grey,
47
50
  fillColor: Colors.transparent,
@@ -49,7 +52,7 @@ class SettingsSheet extends StatelessWidget {
49
52
  minHeight: 36.0,
50
53
  minWidth: 50.0,
51
54
  ),
52
- isSelected: [!darkMode.value, darkMode.value],
55
+ isSelected: [!darkModeAtom.value, darkModeAtom.value],
53
56
  children: const [
54
57
  Icon(Icons.light_mode),
55
58
  Icon(Icons.dark_mode),
@@ -60,7 +63,7 @@ class SettingsSheet extends StatelessWidget {
60
63
  title: Text(context.l.incrementFontTitle),
61
64
  leading: Icon(Icons.font_download, color: context.theme.colorScheme.onBackground),
62
65
  trailing: IconButton(
63
- onPressed: () => textScale.update!(0.1),
66
+ onPressed: () => dispatch(const UpdateTextScale(0.1)),
64
67
  icon: const Icon(Icons.add_circle_outline, size: 32, color: Colors.redAccent),
65
68
  ),
66
69
  ),
@@ -68,21 +71,21 @@ class SettingsSheet extends StatelessWidget {
68
71
  title: Text(context.l.decrementFontTitle),
69
72
  leading: Icon(Icons.font_download, color: context.theme.colorScheme.onBackground),
70
73
  trailing: IconButton(
71
- onPressed: () => textScale.update!(-0.1),
74
+ onPressed: () => dispatch(const UpdateTextScale(-0.1)),
72
75
  icon: const Icon(Icons.remove_circle_outline, size: 32, color: Colors.blueAccent),
73
76
  ),
74
77
  ),
75
78
  SettingsTile.switchTile(
76
- initialValue: fontBold.watch(context),
79
+ initialValue: boldFontAtom.watch(context),
77
80
  leading: Icon(Icons.format_bold, color: context.theme.colorScheme.onBackground),
78
81
  title: Text(context.l.boldFontTitle),
79
- onToggle: (value) => fontBold.set!(),
82
+ onToggle: (value) => dispatch(ToggleBoldFont()),
80
83
  ),
81
84
  SettingsTile.switchTile(
82
- initialValue: engTitles.watch(context),
85
+ initialValue: engTitlesAtom.watch(context),
83
86
  leading: Icon(Icons.abc, color: context.theme.colorScheme.onBackground),
84
87
  title: Text(context.l.engTitles),
85
- onToggle: (value) => engTitles.set!(),
88
+ onToggle: (value) => dispatch(ToggleEngTitles()),
86
89
  ),
87
90
  ],
88
91
  ),
lib/store/actions.dart ADDED
@@ -0,0 +1,27 @@
1
+ sealed class AppAction {}
2
+
3
+ class FirstOpenDone implements AppAction {}
4
+
5
+ class UpdateBible implements AppAction {
6
+ final String name;
7
+ final String code;
8
+
9
+ const UpdateBible(this.name, this.code);
10
+ }
11
+
12
+ class ToggleEngTitles implements AppAction {}
13
+ class ToggleBoldFont implements AppAction {}
14
+ class ToggleDarkMode implements AppAction {}
15
+
16
+ class UpdateTextScale implements AppAction {
17
+ final double value;
18
+
19
+ const UpdateTextScale(this.value);
20
+ }
21
+
22
+ class UpdateChapter implements AppAction {
23
+ final int book;
24
+ final int chapter;
25
+
26
+ const UpdateChapter(this.book, this.chapter);
27
+ }
lib/{state.dart → store/state.dart} RENAMED
@@ -4,13 +4,13 @@ import "package:flutter/material.dart";
4
4
  import "package:flutter/services.dart";
5
5
  import "package:get_storage/get_storage.dart";
6
6
  import "package:just_audio/just_audio.dart";
7
- import "package:only_bible_app/actions.dart";
8
7
  import "package:only_bible_app/atom.dart";
9
8
  import "package:only_bible_app/dialog.dart";
10
9
  import "package:only_bible_app/models.dart";
11
10
  import "package:only_bible_app/theme.dart";
12
11
  import "package:only_bible_app/utils.dart";
13
12
  import "package:only_bible_app/navigation.dart";
13
+ import "package:only_bible_app/store/actions.dart";
14
14
 
15
15
  final box = GetStorage("only-bible-app-prefs");
16
16
  final player = AudioPlayer();
@@ -24,92 +24,112 @@ final bibleAtom = AsyncAtom(
24
24
  callback: loadBible,
25
25
  );
26
26
 
27
- final firstOpen = Atom2<bool, AppAction>(
27
+ final firstOpenAtom = Atom2(
28
28
  box: box,
29
29
  key: "firstOpen",
30
30
  initialState: true,
31
- reducer: {
32
- FirstOpenDone: (state, action) => false,
31
+ reducer: (state, action) {
32
+ if (action is FirstOpenDone) {
33
+ return false;
34
+ }
35
+ return state;
33
36
  },
34
37
  );
35
38
 
36
- final languageCode = Atom2<String, AppAction>(
39
+ final languageCodeAtom = Atom2(
37
40
  box: box,
38
41
  key: "languageCode",
39
42
  initialState: "en",
43
+ reducer: (state, action) {
44
+ if (action is UpdateBible) {
45
+ return action.code;
46
+ }
40
- reducer: {
47
+ return state;
41
- SetLanguageCode: (state, action) => (action as SetLanguageCode).code,
42
48
  },
43
49
  );
44
50
 
45
- final Atom<String> bibleName = Atom<String>(
51
+ final bibleNameAtom = Atom2(
46
52
  box: box,
47
53
  key: "bibleName",
48
- initialValue: "English",
54
+ initialState: "English",
49
- update: (String v) {
55
+ reducer: (state, action) {
56
+ if (action is UpdateBible) {
50
- bibleName.value = v;
57
+ return action.name;
58
+ }
59
+ return state;
51
60
  },
52
61
  );
53
62
 
54
- updateCurrentBible(BuildContext context, String code, String name) async {
55
- hideActions(context);
56
- dispatch(SetLanguageCode(code));
57
- bibleName.update!(name);
58
- pushBookChapter(context, name, 0, 0, null);
59
- }
60
-
61
- final Atom<bool> engTitles = Atom<bool>(
63
+ final engTitlesAtom = Atom2(
62
64
  box: box,
63
65
  key: "engTitles",
64
- initialValue: false,
66
+ initialState: false,
65
- set: () {
67
+ reducer: (state, action) {
66
- engTitles.value = !engTitles.value;
68
+ if (action is ToggleEngTitles) {
69
+ return !state;
70
+ }
71
+ return state;
67
72
  },
68
73
  );
69
74
 
70
- final Atom<bool> darkMode = Atom<bool>(
75
+ final boldFontAtom = Atom2(
71
76
  box: box,
72
- key: "darkMode",
77
+ key: "boldFont",
73
- initialValue: false,
78
+ initialState: false,
79
+ reducer: (state, action) {
80
+ if (action is ToggleBoldFont) {
81
+ return !state;
82
+ }
74
- set: () {
83
+ return state;
75
- darkMode.value = !darkMode.value;
76
- updateStatusBar(darkMode.value);
77
84
  },
78
85
  );
79
86
 
80
- final Atom<bool> fontBold = Atom<bool>(
87
+ final darkModeAtom = Atom2(
81
88
  box: box,
82
- key: "fontBold",
89
+ key: "darkMode",
83
- initialValue: false,
90
+ initialState: false,
91
+ reducer: (state, action) {
92
+ if (action is ToggleDarkMode) {
93
+ updateStatusBar(!state);
94
+ return !state;
95
+ }
84
- set: () {
96
+ return state;
85
- fontBold.value = !fontBold.value;
86
97
  },
87
98
  );
88
99
 
89
- final Atom<double> textScale = Atom<double>(
100
+ final textScaleAtom = Atom2(
90
101
  box: box,
91
102
  key: "textScale",
92
- initialValue: 0,
103
+ initialState: 0.0,
93
- update: (double v) {
104
+ reducer: (state, action) {
105
+ if (action is UpdateTextScale) {
94
- textScale.value += v;
106
+ return state += action.value;
107
+ }
108
+ return state;
95
109
  },
96
110
  );
97
111
 
98
- final Atom<int> savedBook = Atom<int>(
112
+ final savedBookAtom = Atom2(
99
113
  box: box,
100
114
  key: "savedBook",
101
- initialValue: 0,
115
+ initialState: 0,
102
- update: (int v) {
116
+ reducer: (state, action) {
117
+ if (action is UpdateChapter) {
118
+ return action.book;
119
+ }
103
- savedBook.value = v;
120
+ return state;
104
121
  },
105
122
  );
106
123
 
107
- final Atom<int> savedChapter = Atom<int>(
124
+ final savedChapterAtom = Atom2(
108
125
  box: box,
109
126
  key: "savedChapter",
110
- initialValue: 0,
127
+ initialState: 0,
111
- update: (int v) {
128
+ reducer: (state, action) {
129
+ if (action is UpdateChapter) {
112
- savedChapter.value = v;
130
+ return action.chapter;
131
+ }
132
+ return state;
113
133
  },
114
134
  );
115
135
 
@@ -143,7 +163,7 @@ Color? getHighlight(Verse v) {
143
163
  if (index == null) {
144
164
  return null;
145
165
  }
146
- return darkMode.value ? darkHighlights[index] : lightHighlights[index];
166
+ return darkModeAtom.value ? darkHighlights[index] : lightHighlights[index];
147
167
  }
148
168
  return null;
149
169
  }
@@ -189,10 +209,10 @@ void onVerseSelected(BuildContext context, Bible bible, Verse v) {
189
209
  TextStyle getHighlightStyle(BuildContext context, Verse v) {
190
210
  if (watchVerseSelected(context, v)) {
191
211
  return TextStyle(
192
- backgroundColor: darkMode.value ? Colors.grey.shade800 : Colors.grey.shade200,
212
+ backgroundColor: darkModeAtom.value ? Colors.grey.shade800 : Colors.grey.shade200,
193
213
  );
194
214
  }
195
- if (darkMode.watch(context)) {
215
+ if (darkModeAtom.watch(context)) {
196
216
  // return TextStyle(
197
217
  // color: getHighlight(v) ?? context.theme.colorScheme.onBackground,
198
218
  // );
lib/utils.dart CHANGED
@@ -2,7 +2,7 @@ import "dart:convert";
2
2
  import "package:flutter/services.dart";
3
3
  import "package:only_bible_app/dialog.dart";
4
4
  import "package:only_bible_app/models.dart";
5
- import "package:only_bible_app/state.dart";
5
+ import "package:only_bible_app/store/state.dart";
6
6
  import "package:url_launcher/url_launcher.dart";
7
7
  import "package:flutter/foundation.dart" show defaultTargetPlatform, TargetPlatform;
8
8
  import "package:flutter/material.dart";
@@ -36,11 +36,11 @@ extension AsyncSnapshotUtils<E> on AsyncSnapshot<E> {
36
36
  extension AppContext on BuildContext {
37
37
  ThemeData get theme => Theme.of(this);
38
38
 
39
- AppLocalizations get l => engTitles.watch(this) && languageCode.watch(this) != "en"
39
+ AppLocalizations get l => engTitlesAtom.watch(this) && languageCodeAtom.watch(this) != "en"
40
40
  ? lookupAppLocalizations(const Locale("en"))
41
41
  : AppLocalizations.of(this)!;
42
42
 
43
- AppLocalizations get currentLang => supportedLocalizations.firstWhere((el) => el.languageCode == languageCode.value);
43
+ AppLocalizations get currentLang => supportedLocalizations.firstWhere((el) => el.languageCode == languageCodeAtom.value);
44
44
 
45
45
  double get actionsHeight {
46
46
  if (isIOS()) {
@@ -193,3 +193,4 @@ Future<Bible> loadBible(String name) async {
193
193
  books: books,
194
194
  );
195
195
  }
196
+
lib/widgets/chapter_app_bar.dart CHANGED
@@ -1,7 +1,7 @@
1
1
  import "package:flutter/material.dart";
2
2
  import "package:only_bible_app/models.dart";
3
3
  import "package:only_bible_app/navigation.dart";
4
- import "package:only_bible_app/state.dart";
4
+ import 'package:only_bible_app/store/state.dart';
5
5
  import "package:only_bible_app/utils.dart";
6
6
 
7
7
  class ChapterAppBar extends StatelessWidget implements PreferredSizeWidget {
lib/widgets/note_sheet.dart CHANGED
@@ -1,6 +1,6 @@
1
1
  import "package:flutter/material.dart";
2
2
  import "package:only_bible_app/models.dart";
3
- import "package:only_bible_app/state.dart";
3
+ import 'package:only_bible_app/store/state.dart';
4
4
  import "package:only_bible_app/widgets/modal_button.dart";
5
5
 
6
6
  class NoteSheet extends StatelessWidget {
lib/widgets/scaffold_menu.dart CHANGED
@@ -1,5 +1,5 @@
1
1
  import "package:flutter/material.dart";
2
- import "package:only_bible_app/state.dart";
2
+ import 'package:only_bible_app/store/state.dart';
3
3
  import "package:only_bible_app/utils.dart";
4
4
 
5
5
  class ScaffoldMenu extends StatelessWidget {
@@ -11,7 +11,7 @@ class ScaffoldMenu extends StatelessWidget {
11
11
  @override
12
12
  Widget build(BuildContext context) {
13
13
  final pageWidth = MediaQuery.of(context).size.width;
14
- final isWide = context.isWide && !firstOpen.value;
14
+ final isWide = context.isWide && !firstOpenAtom.value;
15
15
  return Scaffold(
16
16
  backgroundColor: isWide ? Colors.transparent : context.theme.colorScheme.background,
17
17
  body: SafeArea(
lib/widgets/verses_view.dart CHANGED
@@ -3,7 +3,7 @@ import "package:flutter/material.dart";
3
3
  import "package:flutter_swipe_detector/flutter_swipe_detector.dart";
4
4
  import "package:only_bible_app/models.dart";
5
5
  import "package:only_bible_app/navigation.dart";
6
- import "package:only_bible_app/state.dart";
6
+ import 'package:only_bible_app/store/state.dart';
7
7
 
8
8
  class VersesView extends StatelessWidget {
9
9
  final Bible bible;
@@ -35,10 +35,10 @@ class VersesView extends StatelessWidget {
35
35
  Align(
36
36
  alignment: Alignment.centerLeft,
37
37
  child: Text.rich(
38
- textScaleFactor: 1.1 + textScale.watch(context),
38
+ textScaleFactor: 1.1 + textScaleAtom.watch(context),
39
39
  textAlign: TextAlign.left,
40
40
  TextSpan(
41
- style: fontBold.watch(context)
41
+ style: boldFontAtom.watch(context)
42
42
  ? textStyle.copyWith(
43
43
  fontWeight: FontWeight.w500,
44
44
  )
pubspec.lock CHANGED
@@ -98,7 +98,7 @@ packages:
98
98
  source: hosted
99
99
  version: "2.2.1"
100
100
  build_runner:
101
- dependency: "direct dev"
101
+ dependency: transitive
102
102
  description:
103
103
  name: build_runner
104
104
  sha256: "10c6bcdbf9d049a0b666702cf1cee4ddfdc38f02a19d35ae392863b47519848b"
@@ -234,7 +234,7 @@ packages:
234
234
  source: hosted
235
235
  version: "2.3.2"
236
236
  equatable:
237
- dependency: "direct main"
237
+ dependency: transitive
238
238
  description:
239
239
  name: equatable
240
240
  sha256: c2b87cb7756efdf69892005af546c56c0b5037f54d2a88269b4f347a505e3ca2
@@ -426,22 +426,6 @@ packages:
426
426
  description: flutter
427
427
  source: sdk
428
428
  version: "0.0.0"
429
- freezed:
430
- dependency: "direct main"
431
- description:
432
- name: freezed
433
- sha256: "2df89855fe181baae3b6d714dc3c4317acf4fccd495a6f36e5e00f24144c6c3b"
434
- url: "https://pub.dev"
435
- source: hosted
436
- version: "2.4.1"
437
- freezed_annotation:
438
- dependency: "direct main"
439
- description:
440
- name: freezed_annotation
441
- sha256: c3fd9336eb55a38cc1bbd79ab17573113a8deccd0ecbbf926cca3c62803b5c2d
442
- url: "https://pub.dev"
443
- source: hosted
444
- version: "2.4.1"
445
429
  frontend_server_client:
446
430
  dependency: transitive
447
431
  description:
@@ -945,14 +929,6 @@ packages:
945
929
  description: flutter
946
930
  source: sdk
947
931
  version: "0.0.99"
948
- source_gen:
949
- dependency: transitive
950
- description:
951
- name: source_gen
952
- sha256: fc0da689e5302edb6177fdd964efcb7f58912f43c28c2047a808f5bfff643d16
953
- url: "https://pub.dev"
954
- source: hosted
955
- version: "1.4.0"
956
932
  source_map_stack_trace:
957
933
  dependency: transitive
958
934
  description:
pubspec.yaml CHANGED
@@ -33,9 +33,6 @@ dependencies:
33
33
  package_info_plus: ^4.1.0
34
34
  flutter_azure_tts: ^0.1.6
35
35
  flutter_dotenv: ^5.1.0
36
- freezed: ^2.4.1
37
- freezed_annotation: ^2.4.1
38
- equatable: ^2.0.5
39
36
 
40
37
  dev_dependencies:
41
38
  flutter_test:
@@ -45,7 +42,6 @@ dev_dependencies:
45
42
  flutter_lints: ^2.0.0
46
43
  flutter_launcher_icons: ^0.13.1
47
44
  test: ^1.24.3
48
- build_runner: ^2.4.6
49
45
 
50
46
  flutter:
51
47
  generate: true