Skip to content

Refactor streamline headline and source country #39

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Jul 30, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions lib/app/view/app.dart
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ class App extends StatelessWidget {
required AuthRepository authenticationRepository,
required DataRepository<Headline> headlinesRepository,
required DataRepository<Topic> topicsRepository,
required DataRepository<Country> countriesRepository,
required DataRepository<Source> sourcesRepository,
required DataRepository<UserAppSettings> userAppSettingsRepository,
required DataRepository<UserContentPreferences>
Expand All @@ -39,7 +38,6 @@ class App extends StatelessWidget {
}) : _authenticationRepository = authenticationRepository,
_headlinesRepository = headlinesRepository,
_topicsRepository = topicsRepository,
_countriesRepository = countriesRepository,
_sourcesRepository = sourcesRepository,
_userAppSettingsRepository = userAppSettingsRepository,
_userContentPreferencesRepository = userContentPreferencesRepository,
Expand All @@ -51,7 +49,6 @@ class App extends StatelessWidget {
final AuthRepository _authenticationRepository;
final DataRepository<Headline> _headlinesRepository;
final DataRepository<Topic> _topicsRepository;
final DataRepository<Country> _countriesRepository;
final DataRepository<Source> _sourcesRepository;
final DataRepository<UserAppSettings> _userAppSettingsRepository;
final DataRepository<UserContentPreferences>
Expand All @@ -68,7 +65,6 @@ class App extends StatelessWidget {
RepositoryProvider.value(value: _authenticationRepository),
RepositoryProvider.value(value: _headlinesRepository),
RepositoryProvider.value(value: _topicsRepository),
RepositoryProvider.value(value: _countriesRepository),
RepositoryProvider.value(value: _sourcesRepository),
RepositoryProvider.value(value: _userAppSettingsRepository),
RepositoryProvider.value(value: _userContentPreferencesRepository),
Expand Down
25 changes: 0 additions & 25 deletions lib/bootstrap.dart
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ Future<Widget> bootstrap(

DataClient<Headline> headlinesClient;
DataClient<Topic> topicsClient;
DataClient<Country> countriesClient;
DataClient<Source> sourcesClient;
DataClient<UserContentPreferences> userContentPreferencesClient;
DataClient<UserAppSettings> userAppSettingsClient;
Expand All @@ -75,12 +74,6 @@ Future<Widget> bootstrap(
initialData: topicsFixturesData,
logger: Logger('DataInMemory<Topic>'),
);
countriesClient = DataInMemory<Country>(
toJson: (i) => i.toJson(),
getId: (i) => i.id,
initialData: countriesFixturesData,
logger: Logger('DataInMemory<Country>'),
);
sourcesClient = DataInMemory<Source>(
toJson: (i) => i.toJson(),
getId: (i) => i.id,
Expand Down Expand Up @@ -124,13 +117,6 @@ Future<Widget> bootstrap(
toJson: (topic) => topic.toJson(),
logger: Logger('DataApi<Topic>'),
);
countriesClient = DataApi<Country>(
httpClient: httpClient,
modelName: 'country',
fromJson: Country.fromJson,
toJson: (country) => country.toJson(),
logger: Logger('DataApi<Country>'),
);
sourcesClient = DataApi<Source>(
httpClient: httpClient,
modelName: 'source',
Expand Down Expand Up @@ -181,13 +167,6 @@ Future<Widget> bootstrap(
toJson: (topic) => topic.toJson(),
logger: Logger('DataApi<Topic>'),
);
countriesClient = DataApi<Country>(
httpClient: httpClient,
modelName: 'country',
fromJson: Country.fromJson,
toJson: (country) => country.toJson(),
logger: Logger('DataApi<Country>'),
);
sourcesClient = DataApi<Source>(
httpClient: httpClient,
modelName: 'source',
Expand Down Expand Up @@ -229,9 +208,6 @@ Future<Widget> bootstrap(
dataClient: headlinesClient,
);
final topicsRepository = DataRepository<Topic>(dataClient: topicsClient);
final countriesRepository = DataRepository<Country>(
dataClient: countriesClient,
);
final sourcesRepository = DataRepository<Source>(dataClient: sourcesClient);
final userContentPreferencesRepository =
DataRepository<UserContentPreferences>(
Expand All @@ -251,7 +227,6 @@ Future<Widget> bootstrap(
authenticationRepository: authenticationRepository,
headlinesRepository: headlinesRepository,
topicsRepository: topicsRepository,
countriesRepository: countriesRepository,
sourcesRepository: sourcesRepository,
userAppSettingsRepository: userAppSettingsRepository,
userContentPreferencesRepository: userContentPreferencesRepository,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import 'package:bloc/bloc.dart';
import 'package:core/core.dart';
import 'package:country_picker/country_picker.dart' as picker;
import 'package:data_repository/data_repository.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_news_app_web_dashboard_full_source_code/shared/shared.dart';
import 'package:uuid/uuid.dart';

part 'create_headline_event.dart';
Expand All @@ -16,11 +18,9 @@ class CreateHeadlineBloc
required DataRepository<Headline> headlinesRepository,
required DataRepository<Source> sourcesRepository,
required DataRepository<Topic> topicsRepository,
required DataRepository<Country> countriesRepository,
}) : _headlinesRepository = headlinesRepository,
_sourcesRepository = sourcesRepository,
_topicsRepository = topicsRepository,
_countriesRepository = countriesRepository,
super(const CreateHeadlineState()) {
on<CreateHeadlineDataLoaded>(_onDataLoaded);
on<CreateHeadlineTitleChanged>(_onTitleChanged);
Expand All @@ -37,7 +37,6 @@ class CreateHeadlineBloc
final DataRepository<Headline> _headlinesRepository;
final DataRepository<Source> _sourcesRepository;
final DataRepository<Topic> _topicsRepository;
final DataRepository<Country> _countriesRepository;
final _uuid = const Uuid();

Future<void> _onDataLoaded(
Expand All @@ -49,29 +48,23 @@ class CreateHeadlineBloc
final [
sourcesResponse,
topicsResponse,
countriesResponse,
] = await Future.wait([
_sourcesRepository.readAll(
sort: [const SortOption('updatedAt', SortOrder.desc)],
),
_topicsRepository.readAll(
sort: [const SortOption('updatedAt', SortOrder.desc)],
),
_countriesRepository.readAll(
sort: [const SortOption('updatedAt', SortOrder.desc)],
),
]);

final sources = (sourcesResponse as PaginatedResponse<Source>).items;
final topics = (topicsResponse as PaginatedResponse<Topic>).items;
final countries = (countriesResponse as PaginatedResponse<Country>).items;

emit(
state.copyWith(
status: CreateHeadlineStatus.initial,
sources: sources,
topics: topics,
countries: countries,
),
);
} on HttpException catch (e) {
Expand Down Expand Up @@ -132,7 +125,13 @@ class CreateHeadlineBloc
CreateHeadlineCountryChanged event,
Emitter<CreateHeadlineState> emit,
) {
emit(state.copyWith(eventCountry: () => event.country));
final packageCountry = event.country;
if (packageCountry == null) {
emit(state.copyWith(eventCountry: () => null));
} else {
final coreCountry = adaptPackageCountryToCoreCountry(packageCountry);
emit(state.copyWith(eventCountry: () => coreCountry));
}
}

void _onStatusChanged(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ final class CreateHeadlineTopicChanged extends CreateHeadlineEvent {
/// Event for when the headline's country is changed.
final class CreateHeadlineCountryChanged extends CreateHeadlineEvent {
const CreateHeadlineCountryChanged(this.country);
final Country? country;
final picker.Country? country;
@override
List<Object?> get props => [country];
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ final class CreateHeadlineState extends Equatable {
this.eventCountry,
this.sources = const [],
this.topics = const [],
this.countries = const [],
this.contentStatus = ContentStatus.active,
this.exception,
this.createdHeadline,
Expand All @@ -47,7 +46,6 @@ final class CreateHeadlineState extends Equatable {
final Country? eventCountry;
final List<Source> sources;
final List<Topic> topics;
final List<Country> countries;
final ContentStatus contentStatus;
final HttpException? exception;
final Headline? createdHeadline;
Expand All @@ -73,7 +71,6 @@ final class CreateHeadlineState extends Equatable {
ValueGetter<Country?>? eventCountry,
List<Source>? sources,
List<Topic>? topics,
List<Country>? countries,
ContentStatus? contentStatus,
HttpException? exception,
Headline? createdHeadline,
Expand All @@ -89,7 +86,6 @@ final class CreateHeadlineState extends Equatable {
eventCountry: eventCountry != null ? eventCountry() : this.eventCountry,
sources: sources ?? this.sources,
topics: topics ?? this.topics,
countries: countries ?? this.countries,
contentStatus: contentStatus ?? this.contentStatus,
exception: exception,
createdHeadline: createdHeadline ?? this.createdHeadline,
Expand All @@ -108,7 +104,6 @@ final class CreateHeadlineState extends Equatable {
eventCountry,
sources,
topics,
countries,
contentStatus,
exception,
createdHeadline,
Expand Down
39 changes: 12 additions & 27 deletions lib/content_management/bloc/create_source/create_source_bloc.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import 'package:bloc/bloc.dart';
import 'package:core/core.dart';
import 'package:country_picker/country_picker.dart' as picker;
import 'package:data_repository/data_repository.dart';
import 'package:equatable/equatable.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_news_app_web_dashboard_full_source_code/shared/shared.dart';
import 'package:uuid/uuid.dart';

part 'create_source_event.dart';
Expand All @@ -13,9 +15,7 @@ class CreateSourceBloc extends Bloc<CreateSourceEvent, CreateSourceState> {
/// {@macro create_source_bloc}
CreateSourceBloc({
required DataRepository<Source> sourcesRepository,
required DataRepository<Country> countriesRepository,
}) : _sourcesRepository = sourcesRepository,
_countriesRepository = countriesRepository,
super(const CreateSourceState()) {
on<CreateSourceDataLoaded>(_onDataLoaded);
on<CreateSourceNameChanged>(_onNameChanged);
Expand All @@ -29,36 +29,15 @@ class CreateSourceBloc extends Bloc<CreateSourceEvent, CreateSourceState> {
}

final DataRepository<Source> _sourcesRepository;
final DataRepository<Country> _countriesRepository;
final _uuid = const Uuid();

Future<void> _onDataLoaded(
CreateSourceDataLoaded event,
Emitter<CreateSourceState> emit,
) async {
emit(state.copyWith(status: CreateSourceStatus.loading));
try {
final countriesResponse = await _countriesRepository.readAll(
sort: [const SortOption('updatedAt', SortOrder.desc)],
);
final countries = countriesResponse.items;

emit(
state.copyWith(
status: CreateSourceStatus.initial,
countries: countries,
),
);
} on HttpException catch (e) {
emit(state.copyWith(status: CreateSourceStatus.failure, exception: e));
} catch (e) {
emit(
state.copyWith(
status: CreateSourceStatus.failure,
exception: UnknownException('An unexpected error occurred: $e'),
),
);
}
// This event is now a no-op since we don't need to load countries.
// We just ensure the BLoC is in the initial state.
emit(state.copyWith(status: CreateSourceStatus.initial));
}

void _onNameChanged(
Expand Down Expand Up @@ -100,7 +79,13 @@ class CreateSourceBloc extends Bloc<CreateSourceEvent, CreateSourceState> {
CreateSourceHeadquartersChanged event,
Emitter<CreateSourceState> emit,
) {
emit(state.copyWith(headquarters: () => event.headquarters));
final packageCountry = event.headquarters;
if (packageCountry == null) {
emit(state.copyWith(headquarters: () => null));
} else {
final coreCountry = adaptPackageCountryToCoreCountry(packageCountry);
emit(state.copyWith(headquarters: () => coreCountry));
}
}

void _onStatusChanged(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ final class CreateSourceLanguageChanged extends CreateSourceEvent {
/// Event for when the source's headquarters is changed.
final class CreateSourceHeadquartersChanged extends CreateSourceEvent {
const CreateSourceHeadquartersChanged(this.headquarters);
final Country? headquarters;
final picker.Country? headquarters;
@override
List<Object?> get props => [headquarters];
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ final class CreateSourceState extends Equatable {
this.sourceType,
this.language = '',
this.headquarters,
this.countries = const [],
this.contentStatus = ContentStatus.active,
this.exception,
this.createdSource,
Expand All @@ -42,7 +41,6 @@ final class CreateSourceState extends Equatable {
final SourceType? sourceType;
final String language;
final Country? headquarters;
final List<Country> countries;
final ContentStatus contentStatus;
final HttpException? exception;
final Source? createdSource;
Expand All @@ -64,7 +62,6 @@ final class CreateSourceState extends Equatable {
ValueGetter<SourceType?>? sourceType,
String? language,
ValueGetter<Country?>? headquarters,
List<Country>? countries,
ContentStatus? contentStatus,
HttpException? exception,
Source? createdSource,
Expand All @@ -77,7 +74,6 @@ final class CreateSourceState extends Equatable {
sourceType: sourceType != null ? sourceType() : this.sourceType,
language: language ?? this.language,
headquarters: headquarters != null ? headquarters() : this.headquarters,
countries: countries ?? this.countries,
contentStatus: contentStatus ?? this.contentStatus,
exception: exception,
createdSource: createdSource ?? this.createdSource,
Expand All @@ -93,7 +89,6 @@ final class CreateSourceState extends Equatable {
sourceType,
language,
headquarters,
countries,
contentStatus,
exception,
createdSource,
Expand Down
Loading
Loading