Skip to content

Commit 52e4ab3

Browse files
committed
feat(headlines-feed): implement followed sources filter functionality
- Add AppBloc and UserContentPreferences repository dependencies to SourcesFilterBloc - Implement _onSourcesFilterApplyFollowedRequested event handler - Add loading, success, and failure states for followed sources - Handle unauthorized and empty followed sources scenarios - Update SourcesFilterState to include followed sources and related status
1 parent 1295ea9 commit 52e4ab3

File tree

1 file changed

+73
-4
lines changed

1 file changed

+73
-4
lines changed

lib/headlines-feed/bloc/sources_filter_bloc.dart

Lines changed: 73 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import 'package:bloc/bloc.dart';
44
import 'package:core/core.dart';
55
import 'package:data_repository/data_repository.dart';
66
import 'package:equatable/equatable.dart';
7+
import 'package:flutter_news_app_mobile_client_full_source_code/app/bloc/app_bloc.dart'; // Import AppBloc
78

89
part 'sources_filter_event.dart';
910
part 'sources_filter_state.dart';
@@ -12,20 +13,29 @@ class SourcesFilterBloc extends Bloc<SourcesFilterEvent, SourcesFilterState> {
1213
SourcesFilterBloc({
1314
required DataRepository<Source> sourcesRepository,
1415
required DataRepository<Country> countriesRepository,
15-
}) : _sourcesRepository = sourcesRepository,
16-
_countriesRepository = countriesRepository,
17-
super(const SourcesFilterState()) {
16+
required DataRepository<UserContentPreferences>
17+
userContentPreferencesRepository,
18+
required AppBloc appBloc,
19+
}) : _sourcesRepository = sourcesRepository,
20+
_countriesRepository = countriesRepository,
21+
_userContentPreferencesRepository = userContentPreferencesRepository,
22+
_appBloc = appBloc,
23+
super(const SourcesFilterState()) {
1824
on<LoadSourceFilterData>(_onLoadSourceFilterData);
1925
on<CountryCapsuleToggled>(_onCountryCapsuleToggled);
2026
on<AllSourceTypesCapsuleToggled>(_onAllSourceTypesCapsuleToggled);
2127
on<SourceTypeCapsuleToggled>(_onSourceTypeCapsuleToggled);
2228
on<SourceCheckboxToggled>(_onSourceCheckboxToggled);
2329
on<ClearSourceFiltersRequested>(_onClearSourceFiltersRequested);
24-
// Removed _FetchFilteredSourcesRequested event listener
30+
on<SourcesFilterApplyFollowedRequested>(
31+
_onSourcesFilterApplyFollowedRequested,
32+
);
2533
}
2634

2735
final DataRepository<Source> _sourcesRepository;
2836
final DataRepository<Country> _countriesRepository;
37+
final DataRepository<UserContentPreferences> _userContentPreferencesRepository;
38+
final AppBloc _appBloc;
2939

3040
Future<void> _onLoadSourceFilterData(
3141
LoadSourceFilterData event,
@@ -182,6 +192,65 @@ class SourcesFilterBloc extends Bloc<SourcesFilterEvent, SourcesFilterState> {
182192
);
183193
}
184194

195+
/// Handles the request to apply the user's followed sources as filters.
196+
Future<void> _onSourcesFilterApplyFollowedRequested(
197+
SourcesFilterApplyFollowedRequested event,
198+
Emitter<SourcesFilterState> emit,
199+
) async {
200+
emit(state.copyWith(followedSourcesStatus: SourceFilterDataLoadingStatus.loading));
201+
202+
final currentUser = _appBloc.state.user;
203+
204+
if (currentUser == null) {
205+
emit(
206+
state.copyWith(
207+
followedSourcesStatus: SourceFilterDataLoadingStatus.failure,
208+
error: const UnauthorizedException(
209+
'User must be logged in to apply followed sources.',
210+
),
211+
),
212+
);
213+
return;
214+
}
215+
216+
try {
217+
final preferences = await _userContentPreferencesRepository.read(
218+
id: currentUser.id,
219+
userId: currentUser.id,
220+
);
221+
222+
if (preferences.followedSources.isEmpty) {
223+
emit(
224+
state.copyWith(
225+
followedSourcesStatus: SourceFilterDataLoadingStatus.success,
226+
followedSources: const [],
227+
error: const OperationFailedException('No followed sources found.'),
228+
clearFollowedSourcesError: true,
229+
),
230+
);
231+
return;
232+
}
233+
234+
emit(
235+
state.copyWith(
236+
followedSourcesStatus: SourceFilterDataLoadingStatus.success,
237+
followedSources: preferences.followedSources,
238+
finallySelectedSourceIds: preferences.followedSources.map((s) => s.id).toSet(),
239+
clearFollowedSourcesError: true,
240+
),
241+
);
242+
} on HttpException catch (e) {
243+
emit(state.copyWith(followedSourcesStatus: SourceFilterDataLoadingStatus.failure, error: e));
244+
} catch (e) {
245+
emit(
246+
state.copyWith(
247+
followedSourcesStatus: SourceFilterDataLoadingStatus.failure,
248+
error: UnknownException(e.toString()),
249+
),
250+
);
251+
}
252+
}
253+
185254
// Helper method to filter sources based on selected countries and types
186255
List<Source> _getFilteredSources({
187256
required List<Source> allSources,

0 commit comments

Comments
 (0)