@@ -8,26 +8,20 @@ import 'package:uuid/uuid.dart';
8
8
part 'create_source_event.dart' ;
9
9
part 'create_source_state.dart' ;
10
10
11
- final class _FetchNextCountryPage extends CreateSourceEvent {
12
- const _FetchNextCountryPage ();
13
- }
14
-
15
- final class _FetchNextLanguagePage extends CreateSourceEvent {
16
- const _FetchNextLanguagePage ();
17
- }
18
-
19
11
/// A BLoC to manage the state of creating a new source.
20
12
class CreateSourceBloc extends Bloc <CreateSourceEvent , CreateSourceState > {
21
13
/// {@macro create_source_bloc}
22
14
CreateSourceBloc ({
23
15
required DataRepository <Source > sourcesRepository,
24
- required DataRepository <Country > countriesRepository,
25
- required DataRepository <Language > languagesRepository,
26
- }) : _sourcesRepository = sourcesRepository,
27
- _countriesRepository = countriesRepository,
28
- _languagesRepository = languagesRepository,
29
- super (const CreateSourceState ()) {
30
- on < CreateSourceDataLoaded > (_onDataLoaded);
16
+ required List <Country > countries,
17
+ required List <Language > languages,
18
+ }) : _sourcesRepository = sourcesRepository,
19
+ super (
20
+ CreateSourceState (
21
+ countries: countries,
22
+ languages: languages,
23
+ ),
24
+ ) {
31
25
on < CreateSourceNameChanged > (_onNameChanged);
32
26
on < CreateSourceDescriptionChanged > (_onDescriptionChanged);
33
27
on < CreateSourceUrlChanged > (_onUrlChanged);
@@ -36,65 +30,11 @@ class CreateSourceBloc extends Bloc<CreateSourceEvent, CreateSourceState> {
36
30
on < CreateSourceHeadquartersChanged > (_onHeadquartersChanged);
37
31
on < CreateSourceStatusChanged > (_onStatusChanged);
38
32
on < CreateSourceSubmitted > (_onSubmitted);
39
- on < _FetchNextCountryPage > (_onFetchNextCountryPage);
40
- on < _FetchNextLanguagePage > (_onFetchNextLanguagePage);
41
33
}
42
34
43
35
final DataRepository <Source > _sourcesRepository;
44
- final DataRepository <Country > _countriesRepository;
45
- final DataRepository <Language > _languagesRepository;
46
36
final _uuid = const Uuid ();
47
37
48
- Future <void > _onDataLoaded (
49
- CreateSourceDataLoaded event,
50
- Emitter <CreateSourceState > emit,
51
- ) async {
52
- emit (state.copyWith (status: CreateSourceStatus .loading));
53
- try {
54
- final responses = await Future .wait ([
55
- _countriesRepository.readAll (
56
- sort: [const SortOption ('name' , SortOrder .asc)],
57
- filter: {'status' : ContentStatus .active.name},
58
- ),
59
- _languagesRepository.readAll (
60
- sort: [const SortOption ('name' , SortOrder .asc)],
61
- filter: {'status' : ContentStatus .active.name},
62
- ),
63
- ]);
64
- final countriesPaginated = responses[0 ] as PaginatedResponse <Country >;
65
- final languagesPaginated = responses[1 ] as PaginatedResponse <Language >;
66
- emit (
67
- state.copyWith (
68
- status: CreateSourceStatus .initial,
69
- countries: countriesPaginated.items,
70
- countriesCursor: countriesPaginated.cursor,
71
- countriesHasMore: countriesPaginated.hasMore,
72
- languages: languagesPaginated.items,
73
- languagesCursor: languagesPaginated.cursor,
74
- languagesHasMore: languagesPaginated.hasMore,
75
- ),
76
- );
77
-
78
- // After the initial page is loaded, start background processes to
79
- // fetch all remaining pages for countries and languages.
80
- if (state.countriesHasMore) {
81
- add (const _FetchNextCountryPage ());
82
- }
83
- if (state.languagesHasMore) {
84
- add (const _FetchNextLanguagePage ());
85
- }
86
- } on HttpException catch (e) {
87
- emit (state.copyWith (status: CreateSourceStatus .failure, exception: e));
88
- } catch (e) {
89
- emit (
90
- state.copyWith (
91
- status: CreateSourceStatus .failure,
92
- exception: UnknownException ('An unexpected error occurred: $e ' ),
93
- ),
94
- );
95
- }
96
- }
97
-
98
38
void _onNameChanged (
99
39
CreateSourceNameChanged event,
100
40
Emitter <CreateSourceState > emit,
@@ -150,84 +90,6 @@ class CreateSourceBloc extends Bloc<CreateSourceEvent, CreateSourceState> {
150
90
}
151
91
152
92
// --- Background Data Fetching for Dropdown ---
153
- // The DropdownButtonFormField widget does not natively support on-scroll
154
- // pagination. To preserve UI consistency across the application, this BLoC
155
- // employs an event-driven background fetching mechanism.
156
- //
157
- // After the first page of items is loaded, a chain of events is initiated
158
- // to progressively fetch all remaining pages. This process is throttled
159
- // and runs in the background, ensuring the UI remains responsive while the
160
- // full list of dropdown options is populated over time.
161
- Future <void > _onFetchNextCountryPage (
162
- _FetchNextCountryPage event,
163
- Emitter <CreateSourceState > emit,
164
- ) async {
165
- if (! state.countriesHasMore || state.countriesIsLoadingMore) return ;
166
-
167
- try {
168
- emit (state.copyWith (countriesIsLoadingMore: true ));
169
-
170
- // ignore: inference_failure_on_instance_creation
171
- await Future .delayed (const Duration (milliseconds: 400 ));
172
-
173
- final nextCountries = await _countriesRepository.readAll (
174
- pagination: PaginationOptions (cursor: state.countriesCursor),
175
- sort: [const SortOption ('name' , SortOrder .asc)],
176
- );
177
-
178
- emit (
179
- state.copyWith (
180
- countries: List .of (state.countries)..addAll (nextCountries.items),
181
- countriesCursor: nextCountries.cursor,
182
- countriesHasMore: nextCountries.hasMore,
183
- countriesIsLoadingMore: false ,
184
- ),
185
- );
186
-
187
- if (nextCountries.hasMore) {
188
- add (const _FetchNextCountryPage ());
189
- }
190
- } catch (e) {
191
- emit (state.copyWith (countriesIsLoadingMore: false ));
192
- // Optionally log the error without disrupting the user
193
- }
194
- }
195
-
196
- Future <void > _onFetchNextLanguagePage (
197
- _FetchNextLanguagePage event,
198
- Emitter <CreateSourceState > emit,
199
- ) async {
200
- if (! state.languagesHasMore || state.languagesIsLoadingMore) return ;
201
-
202
- try {
203
- emit (state.copyWith (languagesIsLoadingMore: true ));
204
-
205
- // ignore: inference_failure_on_instance_creation
206
- await Future .delayed (const Duration (milliseconds: 400 ));
207
-
208
- final nextLanguages = await _languagesRepository.readAll (
209
- pagination: PaginationOptions (cursor: state.languagesCursor),
210
- sort: [const SortOption ('name' , SortOrder .asc)],
211
- );
212
-
213
- emit (
214
- state.copyWith (
215
- languages: List .of (state.languages)..addAll (nextLanguages.items),
216
- languagesCursor: nextLanguages.cursor,
217
- languagesHasMore: nextLanguages.hasMore,
218
- languagesIsLoadingMore: false ,
219
- ),
220
- );
221
-
222
- if (nextLanguages.hasMore) {
223
- add (const _FetchNextLanguagePage ());
224
- }
225
- } catch (e) {
226
- emit (state.copyWith (languagesIsLoadingMore: false ));
227
- // Optionally log the error without disrupting the user
228
- }
229
- }
230
-
231
93
Future <void > _onSubmitted (
232
94
CreateSourceSubmitted event,
233
95
Emitter <CreateSourceState > emit,
0 commit comments