Skip to content

Commit e495b1f

Browse files
committed
refactor(content_management): simplify country dropdown pagination
- Remove background fetching mechanism for countries list - Load all countries at once in EditHeadlineBloc initialization - Update EditHeadlineState to remove pagination-related variables - Modify EditHeadlinePage to use a predefined list of countries - Remove loading indicator and related logic from the dropdown
1 parent c6f1e51 commit e495b1f

File tree

3 files changed

+15
-94
lines changed

3 files changed

+15
-94
lines changed

lib/content_management/bloc/edit_headline/edit_headline_bloc.dart

Lines changed: 6 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,20 @@ import 'package:flutter/foundation.dart';
77
part 'edit_headline_event.dart';
88
part 'edit_headline_state.dart';
99

10-
final class _FetchNextCountryPage extends EditHeadlineEvent {
11-
const _FetchNextCountryPage();
12-
}
13-
1410
/// A BLoC to manage the state of editing a single headline.
1511
class EditHeadlineBloc extends Bloc<EditHeadlineEvent, EditHeadlineState> {
1612
/// {@macro edit_headline_bloc}
1713
EditHeadlineBloc({
1814
required DataRepository<Headline> headlinesRepository,
1915
required DataRepository<Source> sourcesRepository,
2016
required DataRepository<Topic> topicsRepository,
21-
required DataRepository<Country> countriesRepository,
17+
required List<Country> countries,
2218
required String headlineId,
23-
}) : _headlinesRepository = headlinesRepository,
24-
_sourcesRepository = sourcesRepository,
25-
_topicsRepository = topicsRepository,
26-
_countriesRepository = countriesRepository,
27-
_headlineId = headlineId,
28-
super(const EditHeadlineState()) {
19+
}) : _headlinesRepository = headlinesRepository,
20+
_sourcesRepository = sourcesRepository,
21+
_topicsRepository = topicsRepository,
22+
_headlineId = headlineId,
23+
super(EditHeadlineState(countries: countries)) {
2924
on<EditHeadlineLoaded>(_onLoaded);
3025
on<EditHeadlineTitleChanged>(_onTitleChanged);
3126
on<EditHeadlineExcerptChanged>(_onExcerptChanged);
@@ -36,13 +31,11 @@ class EditHeadlineBloc extends Bloc<EditHeadlineEvent, EditHeadlineState> {
3631
on<EditHeadlineCountryChanged>(_onCountryChanged);
3732
on<EditHeadlineStatusChanged>(_onStatusChanged);
3833
on<EditHeadlineSubmitted>(_onSubmitted);
39-
on<_FetchNextCountryPage>(_onFetchNextCountryPage);
4034
}
4135

4236
final DataRepository<Headline> _headlinesRepository;
4337
final DataRepository<Source> _sourcesRepository;
4438
final DataRepository<Topic> _topicsRepository;
45-
final DataRepository<Country> _countriesRepository;
4639
final String _headlineId;
4740

4841
Future<void> _onLoaded(
@@ -67,10 +60,6 @@ class EditHeadlineBloc extends Bloc<EditHeadlineEvent, EditHeadlineState> {
6760
final sources = (responses[1] as PaginatedResponse<Source>).items;
6861
final topics = (responses[2] as PaginatedResponse<Topic>).items;
6962

70-
final countriesResponse = await _countriesRepository.readAll(
71-
sort: [const SortOption('name', SortOrder.asc)],
72-
);
73-
7463
emit(
7564
state.copyWith(
7665
status: EditHeadlineStatus.initial,
@@ -84,18 +73,9 @@ class EditHeadlineBloc extends Bloc<EditHeadlineEvent, EditHeadlineState> {
8473
eventCountry: () => headline.eventCountry,
8574
sources: sources,
8675
topics: topics,
87-
countries: countriesResponse.items,
88-
countriesCursor: countriesResponse.cursor,
89-
countriesHasMore: countriesResponse.hasMore,
9076
contentStatus: headline.status,
9177
),
9278
);
93-
94-
// After the initial page of countries is loaded, start a background
95-
// process to fetch all remaining pages.
96-
if (state.countriesHasMore) {
97-
add(const _FetchNextCountryPage());
98-
}
9979
} on HttpException catch (e) {
10080
emit(state.copyWith(status: EditHeadlineStatus.failure, exception: e));
10181
} catch (e) {
@@ -197,49 +177,6 @@ class EditHeadlineBloc extends Bloc<EditHeadlineEvent, EditHeadlineState> {
197177
}
198178

199179
// --- Background Data Fetching for Dropdown ---
200-
// The DropdownButtonFormField widget does not natively support on-scroll
201-
// pagination. To preserve UI consistency across the application, this BLoC
202-
// employs an event-driven background fetching mechanism.
203-
//
204-
// After the first page of items is loaded, a chain of events is initiated
205-
// to progressively fetch all remaining pages. This process is throttled
206-
// and runs in the background, ensuring the UI remains responsive while the
207-
// full list of dropdown options is populated over time.
208-
Future<void> _onFetchNextCountryPage(
209-
_FetchNextCountryPage event,
210-
Emitter<EditHeadlineState> emit,
211-
) async {
212-
if (!state.countriesHasMore || state.countriesIsLoadingMore) return;
213-
214-
try {
215-
emit(state.copyWith(countriesIsLoadingMore: true));
216-
217-
// ignore: inference_failure_on_instance_creation
218-
await Future.delayed(const Duration(milliseconds: 400));
219-
220-
final nextCountries = await _countriesRepository.readAll(
221-
pagination: PaginationOptions(cursor: state.countriesCursor),
222-
sort: [const SortOption('name', SortOrder.asc)],
223-
);
224-
225-
emit(
226-
state.copyWith(
227-
countries: List.of(state.countries)..addAll(nextCountries.items),
228-
countriesCursor: nextCountries.cursor,
229-
countriesHasMore: nextCountries.hasMore,
230-
countriesIsLoadingMore: false,
231-
),
232-
);
233-
234-
if (nextCountries.hasMore) {
235-
add(const _FetchNextCountryPage());
236-
}
237-
} catch (e) {
238-
emit(state.copyWith(countriesIsLoadingMore: false));
239-
// Optionally log the error without disrupting the user
240-
}
241-
}
242-
243180
Future<void> _onSubmitted(
244181
EditHeadlineSubmitted event,
245182
Emitter<EditHeadlineState> emit,

lib/content_management/bloc/edit_headline/edit_headline_state.dart

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,6 @@ final class EditHeadlineState extends Equatable {
3333
this.sources = const [],
3434
this.topics = const [],
3535
this.countries = const [],
36-
this.countriesHasMore = true,
37-
this.countriesIsLoadingMore = false,
38-
this.countriesCursor,
3936
this.contentStatus = ContentStatus.active,
4037
this.exception,
4138
this.updatedHeadline,
@@ -53,9 +50,6 @@ final class EditHeadlineState extends Equatable {
5350
final List<Source> sources;
5451
final List<Topic> topics;
5552
final List<Country> countries;
56-
final bool countriesHasMore;
57-
final bool countriesIsLoadingMore;
58-
final String? countriesCursor;
5953
final ContentStatus contentStatus;
6054
final HttpException? exception;
6155
final Headline? updatedHeadline;
@@ -83,9 +77,6 @@ final class EditHeadlineState extends Equatable {
8377
List<Source>? sources,
8478
List<Topic>? topics,
8579
List<Country>? countries,
86-
bool? countriesHasMore,
87-
bool? countriesIsLoadingMore,
88-
String? countriesCursor,
8980
ContentStatus? contentStatus,
9081
HttpException? exception,
9182
Headline? updatedHeadline,
@@ -103,10 +94,6 @@ final class EditHeadlineState extends Equatable {
10394
sources: sources ?? this.sources,
10495
topics: topics ?? this.topics,
10596
countries: countries ?? this.countries,
106-
countriesHasMore: countriesHasMore ?? this.countriesHasMore,
107-
countriesIsLoadingMore:
108-
countriesIsLoadingMore ?? this.countriesIsLoadingMore,
109-
countriesCursor: countriesCursor ?? this.countriesCursor,
11097
contentStatus: contentStatus ?? this.contentStatus,
11198
exception: exception,
11299
updatedHeadline: updatedHeadline ?? this.updatedHeadline,
@@ -127,9 +114,6 @@ final class EditHeadlineState extends Equatable {
127114
sources,
128115
topics,
129116
countries,
130-
countriesHasMore,
131-
countriesIsLoadingMore,
132-
countriesCursor,
133117
contentStatus,
134118
exception,
135119
updatedHeadline,

lib/content_management/view/edit_headline_page.dart

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,17 @@ class EditHeadlinePage extends StatelessWidget {
2323

2424
@override
2525
Widget build(BuildContext context) {
26+
// The list of all countries is fetched once and cached in the
27+
// ContentManagementBloc. We read it here and provide it to the
28+
// EditHeadlineBloc.
29+
final allCountries =
30+
context.read<ContentManagementBloc>().state.allCountries;
2631
return BlocProvider(
2732
create: (context) => EditHeadlineBloc(
2833
headlinesRepository: context.read<DataRepository<Headline>>(),
2934
sourcesRepository: context.read<DataRepository<Source>>(),
3035
topicsRepository: context.read<DataRepository<Topic>>(),
31-
countriesRepository: context.read<DataRepository<Country>>(),
36+
countries: allCountries,
3237
headlineId: headlineId,
3338
)..add(const EditHeadlineLoaded()),
3439
child: const _EditHeadlineView(),
@@ -288,9 +293,6 @@ class _EditHeadlineViewState extends State<_EditHeadlineView> {
288293
decoration: InputDecoration(
289294
labelText: l10n.countryName,
290295
border: const OutlineInputBorder(),
291-
helperText: state.countriesIsLoadingMore
292-
? l10n.loadingFullList
293-
: null,
294296
),
295297
items: [
296298
DropdownMenuItem(value: null, child: Text(l10n.none)),
@@ -317,11 +319,9 @@ class _EditHeadlineViewState extends State<_EditHeadlineView> {
317319
),
318320
),
319321
],
320-
onChanged: state.countriesIsLoadingMore
321-
? null
322-
: (value) => context.read<EditHeadlineBloc>().add(
323-
EditHeadlineCountryChanged(value),
324-
),
322+
onChanged: (value) => context
323+
.read<EditHeadlineBloc>()
324+
.add(EditHeadlineCountryChanged(value)),
325325
),
326326
const SizedBox(height: AppSpacing.lg),
327327
DropdownButtonFormField<ContentStatus>(

0 commit comments

Comments
 (0)