Skip to content

Commit 3c7e8d1

Browse files
authored
Merge pull request #45 from flutter-news-app-full-source-code/enhance-content-management-dropdown-fetching-performance
Enhance content management dropdown fetching performance
2 parents f266df8 + 2109f44 commit 3c7e8d1

File tree

9 files changed

+145
-56
lines changed

9 files changed

+145
-56
lines changed

lib/content_management/bloc/create_headline/create_headline_bloc.dart

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,11 @@ class CreateHeadlineBloc
2020
required DataRepository<Source> sourcesRepository,
2121
required DataRepository<Topic> topicsRepository,
2222
required DataRepository<Country> countriesRepository,
23-
}) : _headlinesRepository = headlinesRepository,
24-
_sourcesRepository = sourcesRepository,
25-
_topicsRepository = topicsRepository,
26-
_countriesRepository = countriesRepository,
27-
super(const CreateHeadlineState()) {
23+
}) : _headlinesRepository = headlinesRepository,
24+
_sourcesRepository = sourcesRepository,
25+
_topicsRepository = topicsRepository,
26+
_countriesRepository = countriesRepository,
27+
super(const CreateHeadlineState()) {
2828
on<CreateHeadlineDataLoaded>(_onDataLoaded);
2929
on<CreateHeadlineTitleChanged>(_onTitleChanged);
3030
on<CreateHeadlineExcerptChanged>(_onExcerptChanged);
@@ -37,10 +37,9 @@ class CreateHeadlineBloc
3737
on<CreateHeadlineSubmitted>(_onSubmitted);
3838
on<CreateHeadlineCountrySearchChanged>(
3939
_onCountrySearchChanged,
40-
transformer: restartable(),
40+
transformer: droppable(),
4141
);
42-
on<CreateHeadlineLoadMoreCountriesRequested>(
43-
_onLoadMoreCountriesRequested);
42+
on<CreateHeadlineLoadMoreCountriesRequested>(_onLoadMoreCountriesRequested);
4443
}
4544

4645
final DataRepository<Headline> _headlinesRepository;
@@ -204,8 +203,7 @@ class CreateHeadlineBloc
204203
emit(state.copyWith(countrySearchTerm: event.searchTerm));
205204
try {
206205
final countriesResponse = await _countriesRepository.readAll(
207-
filter:
208-
event.searchTerm.isNotEmpty ? {'name': event.searchTerm} : null,
206+
filter: event.searchTerm.isNotEmpty ? {'name': event.searchTerm} : null,
209207
sort: [const SortOption('name', SortOrder.asc)],
210208
);
211209

@@ -232,7 +230,9 @@ class CreateHeadlineBloc
232230
CreateHeadlineLoadMoreCountriesRequested event,
233231
Emitter<CreateHeadlineState> emit,
234232
) async {
235-
if (!state.countriesHasMore) return;
233+
if (!state.countriesHasMore || state.countriesIsLoadingMore) return;
234+
235+
emit(state.copyWith(countriesIsLoadingMore: true));
236236

237237
try {
238238
final countriesResponse = await _countriesRepository.readAll(
@@ -250,15 +250,23 @@ class CreateHeadlineBloc
250250
countries: List.of(state.countries)..addAll(countriesResponse.items),
251251
countriesCursor: countriesResponse.cursor,
252252
countriesHasMore: countriesResponse.hasMore,
253+
countriesIsLoadingMore: false,
253254
),
254255
);
255256
} on HttpException catch (e) {
256-
emit(state.copyWith(status: CreateHeadlineStatus.failure, exception: e));
257+
emit(
258+
state.copyWith(
259+
status: CreateHeadlineStatus.failure,
260+
exception: e,
261+
countriesIsLoadingMore: false,
262+
),
263+
);
257264
} catch (e) {
258265
emit(
259266
state.copyWith(
260267
status: CreateHeadlineStatus.failure,
261268
exception: UnknownException('An unexpected error occurred: $e'),
269+
countriesIsLoadingMore: false,
262270
),
263271
);
264272
}

lib/content_management/bloc/create_headline/create_headline_state.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ final class CreateHeadlineState extends Equatable {
3333
this.topics = const [],
3434
this.countries = const [],
3535
this.countriesHasMore = true,
36+
this.countriesIsLoadingMore = false,
3637
this.countriesCursor,
3738
this.countrySearchTerm = '',
3839
this.contentStatus = ContentStatus.active,
@@ -52,6 +53,7 @@ final class CreateHeadlineState extends Equatable {
5253
final List<Topic> topics;
5354
final List<Country> countries;
5455
final bool countriesHasMore;
56+
final bool countriesIsLoadingMore;
5557
final String? countriesCursor;
5658
final String countrySearchTerm;
5759
final ContentStatus contentStatus;
@@ -81,6 +83,7 @@ final class CreateHeadlineState extends Equatable {
8183
List<Topic>? topics,
8284
List<Country>? countries,
8385
bool? countriesHasMore,
86+
bool? countriesIsLoadingMore,
8487
String? countriesCursor,
8588
String? countrySearchTerm,
8689
ContentStatus? contentStatus,
@@ -100,6 +103,8 @@ final class CreateHeadlineState extends Equatable {
100103
topics: topics ?? this.topics,
101104
countries: countries ?? this.countries,
102105
countriesHasMore: countriesHasMore ?? this.countriesHasMore,
106+
countriesIsLoadingMore:
107+
countriesIsLoadingMore ?? this.countriesIsLoadingMore,
103108
countriesCursor: countriesCursor ?? this.countriesCursor,
104109
countrySearchTerm: countrySearchTerm ?? this.countrySearchTerm,
105110
contentStatus: contentStatus ?? this.contentStatus,
@@ -122,6 +127,7 @@ final class CreateHeadlineState extends Equatable {
122127
topics,
123128
countries,
124129
countriesHasMore,
130+
countriesIsLoadingMore,
125131
countriesCursor,
126132
countrySearchTerm,
127133
contentStatus,

lib/content_management/bloc/create_source/create_source_bloc.dart

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,10 @@ class CreateSourceBloc extends Bloc<CreateSourceEvent, CreateSourceState> {
1818
required DataRepository<Source> sourcesRepository,
1919
required DataRepository<Country> countriesRepository,
2020
required DataRepository<Language> languagesRepository,
21-
}) : _sourcesRepository = sourcesRepository,
22-
_countriesRepository = countriesRepository,
23-
_languagesRepository = languagesRepository,
24-
super(const CreateSourceState()) {
21+
}) : _sourcesRepository = sourcesRepository,
22+
_countriesRepository = countriesRepository,
23+
_languagesRepository = languagesRepository,
24+
super(const CreateSourceState()) {
2525
on<CreateSourceDataLoaded>(_onDataLoaded);
2626
on<CreateSourceNameChanged>(_onNameChanged);
2727
on<CreateSourceDescriptionChanged>(_onDescriptionChanged);
@@ -33,14 +33,14 @@ class CreateSourceBloc extends Bloc<CreateSourceEvent, CreateSourceState> {
3333
on<CreateSourceSubmitted>(_onSubmitted);
3434
on<CreateSourceCountrySearchChanged>(
3535
_onCountrySearchChanged,
36-
transformer: restartable(),
36+
transformer: droppable(),
3737
);
3838
on<CreateSourceLoadMoreCountriesRequested>(
3939
_onLoadMoreCountriesRequested,
4040
);
4141
on<CreateSourceLanguageSearchChanged>(
4242
_onLanguageSearchChanged,
43-
transformer: restartable(),
43+
transformer: droppable(),
4444
);
4545
on<CreateSourceLoadMoreLanguagesRequested>(
4646
_onLoadMoreLanguagesRequested,
@@ -194,8 +194,7 @@ class CreateSourceBloc extends Bloc<CreateSourceEvent, CreateSourceState> {
194194
emit(state.copyWith(countrySearchTerm: event.searchTerm));
195195
try {
196196
final countriesResponse = await _countriesRepository.readAll(
197-
filter:
198-
event.searchTerm.isNotEmpty ? {'name': event.searchTerm} : null,
197+
filter: event.searchTerm.isNotEmpty ? {'name': event.searchTerm} : null,
199198
sort: [const SortOption('name', SortOrder.asc)],
200199
);
201200

@@ -222,7 +221,9 @@ class CreateSourceBloc extends Bloc<CreateSourceEvent, CreateSourceState> {
222221
CreateSourceLoadMoreCountriesRequested event,
223222
Emitter<CreateSourceState> emit,
224223
) async {
225-
if (!state.countriesHasMore) return;
224+
if (!state.countriesHasMore || state.countriesIsLoadingMore) return;
225+
226+
emit(state.copyWith(countriesIsLoadingMore: true));
226227

227228
try {
228229
final countriesResponse = await _countriesRepository.readAll(
@@ -240,15 +241,23 @@ class CreateSourceBloc extends Bloc<CreateSourceEvent, CreateSourceState> {
240241
countries: List.of(state.countries)..addAll(countriesResponse.items),
241242
countriesCursor: countriesResponse.cursor,
242243
countriesHasMore: countriesResponse.hasMore,
244+
countriesIsLoadingMore: false,
243245
),
244246
);
245247
} on HttpException catch (e) {
246-
emit(state.copyWith(status: CreateSourceStatus.failure, exception: e));
248+
emit(
249+
state.copyWith(
250+
status: CreateSourceStatus.failure,
251+
exception: e,
252+
countriesIsLoadingMore: false,
253+
),
254+
);
247255
} catch (e) {
248256
emit(
249257
state.copyWith(
250258
status: CreateSourceStatus.failure,
251259
exception: UnknownException('An unexpected error occurred: $e'),
260+
countriesIsLoadingMore: false,
252261
),
253262
);
254263
}
@@ -262,8 +271,7 @@ class CreateSourceBloc extends Bloc<CreateSourceEvent, CreateSourceState> {
262271
emit(state.copyWith(languageSearchTerm: event.searchTerm));
263272
try {
264273
final languagesResponse = await _languagesRepository.readAll(
265-
filter:
266-
event.searchTerm.isNotEmpty ? {'name': event.searchTerm} : null,
274+
filter: event.searchTerm.isNotEmpty ? {'name': event.searchTerm} : null,
267275
sort: [const SortOption('name', SortOrder.asc)],
268276
);
269277

@@ -290,7 +298,9 @@ class CreateSourceBloc extends Bloc<CreateSourceEvent, CreateSourceState> {
290298
CreateSourceLoadMoreLanguagesRequested event,
291299
Emitter<CreateSourceState> emit,
292300
) async {
293-
if (!state.languagesHasMore) return;
301+
if (!state.languagesHasMore || state.languagesIsLoadingMore) return;
302+
303+
emit(state.copyWith(languagesIsLoadingMore: true));
294304

295305
try {
296306
final languagesResponse = await _languagesRepository.readAll(
@@ -305,19 +315,26 @@ class CreateSourceBloc extends Bloc<CreateSourceEvent, CreateSourceState> {
305315

306316
emit(
307317
state.copyWith(
308-
languages: List.of(state.languages)
309-
..addAll(languagesResponse.items),
318+
languages: List.of(state.languages)..addAll(languagesResponse.items),
310319
languagesCursor: languagesResponse.cursor,
311320
languagesHasMore: languagesResponse.hasMore,
321+
languagesIsLoadingMore: false,
312322
),
313323
);
314324
} on HttpException catch (e) {
315-
emit(state.copyWith(status: CreateSourceStatus.failure, exception: e));
325+
emit(
326+
state.copyWith(
327+
status: CreateSourceStatus.failure,
328+
exception: e,
329+
languagesIsLoadingMore: false,
330+
),
331+
);
316332
} catch (e) {
317333
emit(
318334
state.copyWith(
319335
status: CreateSourceStatus.failure,
320336
exception: UnknownException('An unexpected error occurred: $e'),
337+
languagesIsLoadingMore: false,
321338
),
322339
);
323340
}

lib/content_management/bloc/create_source/create_source_state.dart

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,12 @@ final class CreateSourceState extends Equatable {
3131
this.headquarters,
3232
this.countries = const [],
3333
this.countriesHasMore = true,
34+
this.countriesIsLoadingMore = false,
3435
this.countriesCursor,
3536
this.countrySearchTerm = '',
3637
this.languages = const [],
3738
this.languagesHasMore = true,
39+
this.languagesIsLoadingMore = false,
3840
this.languagesCursor,
3941
this.languageSearchTerm = '',
4042
this.contentStatus = ContentStatus.active,
@@ -51,10 +53,12 @@ final class CreateSourceState extends Equatable {
5153
final Country? headquarters;
5254
final List<Country> countries;
5355
final bool countriesHasMore;
56+
final bool countriesIsLoadingMore;
5457
final String? countriesCursor;
5558
final String countrySearchTerm;
5659
final List<Language> languages;
5760
final bool languagesHasMore;
61+
final bool languagesIsLoadingMore;
5862
final String? languagesCursor;
5963
final String languageSearchTerm;
6064
final ContentStatus contentStatus;
@@ -80,10 +84,12 @@ final class CreateSourceState extends Equatable {
8084
ValueGetter<Country?>? headquarters,
8185
List<Country>? countries,
8286
bool? countriesHasMore,
87+
bool? countriesIsLoadingMore,
8388
String? countriesCursor,
8489
String? countrySearchTerm,
8590
List<Language>? languages,
8691
bool? languagesHasMore,
92+
bool? languagesIsLoadingMore,
8793
String? languagesCursor,
8894
String? languageSearchTerm,
8995
ContentStatus? contentStatus,
@@ -100,10 +106,14 @@ final class CreateSourceState extends Equatable {
100106
headquarters: headquarters != null ? headquarters() : this.headquarters,
101107
countries: countries ?? this.countries,
102108
countriesHasMore: countriesHasMore ?? this.countriesHasMore,
109+
countriesIsLoadingMore:
110+
countriesIsLoadingMore ?? this.countriesIsLoadingMore,
103111
countriesCursor: countriesCursor ?? this.countriesCursor,
104112
countrySearchTerm: countrySearchTerm ?? this.countrySearchTerm,
105113
languages: languages ?? this.languages,
106114
languagesHasMore: languagesHasMore ?? this.languagesHasMore,
115+
languagesIsLoadingMore:
116+
languagesIsLoadingMore ?? this.languagesIsLoadingMore,
107117
languagesCursor: languagesCursor ?? this.languagesCursor,
108118
languageSearchTerm: languageSearchTerm ?? this.languageSearchTerm,
109119
contentStatus: contentStatus ?? this.contentStatus,
@@ -123,10 +133,12 @@ final class CreateSourceState extends Equatable {
123133
headquarters,
124134
countries,
125135
countriesHasMore,
136+
countriesIsLoadingMore,
126137
countriesCursor,
127138
countrySearchTerm,
128139
languages,
129140
languagesHasMore,
141+
languagesIsLoadingMore,
130142
languagesCursor,
131143
languageSearchTerm,
132144
contentStatus,

lib/content_management/bloc/edit_headline/edit_headline_bloc.dart

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@ class EditHeadlineBloc extends Bloc<EditHeadlineEvent, EditHeadlineState> {
1919
required DataRepository<Topic> topicsRepository,
2020
required DataRepository<Country> countriesRepository,
2121
required String headlineId,
22-
}) : _headlinesRepository = headlinesRepository,
23-
_sourcesRepository = sourcesRepository,
24-
_topicsRepository = topicsRepository,
25-
_countriesRepository = countriesRepository,
26-
_headlineId = headlineId,
27-
super(const EditHeadlineState()) {
22+
}) : _headlinesRepository = headlinesRepository,
23+
_sourcesRepository = sourcesRepository,
24+
_topicsRepository = topicsRepository,
25+
_countriesRepository = countriesRepository,
26+
_headlineId = headlineId,
27+
super(const EditHeadlineState()) {
2828
on<EditHeadlineLoaded>(_onLoaded);
2929
on<EditHeadlineTitleChanged>(_onTitleChanged);
3030
on<EditHeadlineExcerptChanged>(_onExcerptChanged);
@@ -37,7 +37,7 @@ class EditHeadlineBloc extends Bloc<EditHeadlineEvent, EditHeadlineState> {
3737
on<EditHeadlineSubmitted>(_onSubmitted);
3838
on<EditHeadlineCountrySearchChanged>(
3939
_onCountrySearchChanged,
40-
transformer: restartable(),
40+
transformer: droppable(),
4141
);
4242
on<EditHeadlineLoadMoreCountriesRequested>(
4343
_onLoadMoreCountriesRequested,
@@ -253,8 +253,7 @@ class EditHeadlineBloc extends Bloc<EditHeadlineEvent, EditHeadlineState> {
253253
emit(state.copyWith(countrySearchTerm: event.searchTerm));
254254
try {
255255
final countriesResponse = await _countriesRepository.readAll(
256-
filter:
257-
event.searchTerm.isNotEmpty ? {'name': event.searchTerm} : null,
256+
filter: event.searchTerm.isNotEmpty ? {'name': event.searchTerm} : null,
258257
sort: [const SortOption('name', SortOrder.asc)],
259258
);
260259

@@ -281,7 +280,9 @@ class EditHeadlineBloc extends Bloc<EditHeadlineEvent, EditHeadlineState> {
281280
EditHeadlineLoadMoreCountriesRequested event,
282281
Emitter<EditHeadlineState> emit,
283282
) async {
284-
if (!state.countriesHasMore) return;
283+
if (!state.countriesHasMore || state.countriesIsLoadingMore) return;
284+
285+
emit(state.copyWith(countriesIsLoadingMore: true));
285286

286287
try {
287288
final countriesResponse = await _countriesRepository.readAll(
@@ -299,15 +300,23 @@ class EditHeadlineBloc extends Bloc<EditHeadlineEvent, EditHeadlineState> {
299300
countries: List.of(state.countries)..addAll(countriesResponse.items),
300301
countriesCursor: countriesResponse.cursor,
301302
countriesHasMore: countriesResponse.hasMore,
303+
countriesIsLoadingMore: false,
302304
),
303305
);
304306
} on HttpException catch (e) {
305-
emit(state.copyWith(status: EditHeadlineStatus.failure, exception: e));
307+
emit(
308+
state.copyWith(
309+
status: EditHeadlineStatus.failure,
310+
exception: e,
311+
countriesIsLoadingMore: false,
312+
),
313+
);
306314
} catch (e) {
307315
emit(
308316
state.copyWith(
309317
status: EditHeadlineStatus.failure,
310318
exception: UnknownException('An unexpected error occurred: $e'),
319+
countriesIsLoadingMore: false,
311320
),
312321
);
313322
}

0 commit comments

Comments
 (0)