Skip to content

Commit 0f8b2cf

Browse files
committed
feat(create-source): add create source bloc
- Manages state for source creation form - Handles input changes for source fields - Submits new source data to repository - Loads country data for headquarters selection - Implements error handling for API calls
1 parent ed63804 commit 0f8b2cf

File tree

1 file changed

+141
-0
lines changed

1 file changed

+141
-0
lines changed
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
import 'package:bloc/bloc.dart';
2+
import 'package:equatable/equatable.dart';
3+
import 'package:flutter/foundation.dart';
4+
import 'package:ht_data_repository/ht_data_repository.dart';
5+
import 'package:ht_shared/ht_shared.dart';
6+
7+
part 'create_source_event.dart';
8+
part 'create_source_state.dart';
9+
10+
/// A BLoC to manage the state of creating a new source.
11+
class CreateSourceBloc extends Bloc<CreateSourceEvent, CreateSourceState> {
12+
/// {@macro create_source_bloc}
13+
CreateSourceBloc({
14+
required HtDataRepository<Source> sourcesRepository,
15+
required HtDataRepository<Country> countriesRepository,
16+
}) : _sourcesRepository = sourcesRepository,
17+
_countriesRepository = countriesRepository,
18+
super(const CreateSourceState()) {
19+
on<CreateSourceDataLoaded>(_onDataLoaded);
20+
on<CreateSourceNameChanged>(_onNameChanged);
21+
on<CreateSourceDescriptionChanged>(_onDescriptionChanged);
22+
on<CreateSourceUrlChanged>(_onUrlChanged);
23+
on<CreateSourceTypeChanged>(_onSourceTypeChanged);
24+
on<CreateSourceLanguageChanged>(_onLanguageChanged);
25+
on<CreateSourceHeadquartersChanged>(_onHeadquartersChanged);
26+
on<CreateSourceSubmitted>(_onSubmitted);
27+
}
28+
29+
final HtDataRepository<Source> _sourcesRepository;
30+
final HtDataRepository<Country> _countriesRepository;
31+
32+
Future<void> _onDataLoaded(
33+
CreateSourceDataLoaded event,
34+
Emitter<CreateSourceState> emit,
35+
) async {
36+
emit(state.copyWith(status: CreateSourceStatus.loading));
37+
try {
38+
final countriesResponse = await _countriesRepository.readAll();
39+
final countries = (countriesResponse as PaginatedResponse<Country>).items;
40+
41+
emit(
42+
state.copyWith(
43+
status: CreateSourceStatus.initial,
44+
countries: countries,
45+
),
46+
);
47+
} on HtHttpException catch (e) {
48+
emit(
49+
state.copyWith(
50+
status: CreateSourceStatus.failure,
51+
errorMessage: e.message,
52+
),
53+
);
54+
} catch (e) {
55+
emit(
56+
state.copyWith(
57+
status: CreateSourceStatus.failure,
58+
errorMessage: e.toString(),
59+
),
60+
);
61+
}
62+
}
63+
64+
void _onNameChanged(
65+
CreateSourceNameChanged event,
66+
Emitter<CreateSourceState> emit,
67+
) {
68+
emit(state.copyWith(name: event.name));
69+
}
70+
71+
void _onDescriptionChanged(
72+
CreateSourceDescriptionChanged event,
73+
Emitter<CreateSourceState> emit,
74+
) {
75+
emit(state.copyWith(description: event.description));
76+
}
77+
78+
void _onUrlChanged(
79+
CreateSourceUrlChanged event,
80+
Emitter<CreateSourceState> emit,
81+
) {
82+
emit(state.copyWith(url: event.url));
83+
}
84+
85+
void _onSourceTypeChanged(
86+
CreateSourceTypeChanged event,
87+
Emitter<CreateSourceState> emit,
88+
) {
89+
emit(state.copyWith(sourceType: () => event.sourceType));
90+
}
91+
92+
void _onLanguageChanged(
93+
CreateSourceLanguageChanged event,
94+
Emitter<CreateSourceState> emit,
95+
) {
96+
emit(state.copyWith(language: event.language));
97+
}
98+
99+
void _onHeadquartersChanged(
100+
CreateSourceHeadquartersChanged event,
101+
Emitter<CreateSourceState> emit,
102+
) {
103+
emit(state.copyWith(headquarters: () => event.headquarters));
104+
}
105+
106+
Future<void> _onSubmitted(
107+
CreateSourceSubmitted event,
108+
Emitter<CreateSourceState> emit,
109+
) async {
110+
if (!state.isFormValid) return;
111+
112+
emit(state.copyWith(status: CreateSourceStatus.submitting));
113+
try {
114+
final newSource = Source(
115+
name: state.name,
116+
description: state.description.isNotEmpty ? state.description : null,
117+
url: state.url.isNotEmpty ? state.url : null,
118+
sourceType: state.sourceType,
119+
language: state.language.isNotEmpty ? state.language : null,
120+
headquarters: state.headquarters,
121+
);
122+
123+
await _sourcesRepository.create(item: newSource);
124+
emit(state.copyWith(status: CreateSourceStatus.success));
125+
} on HtHttpException catch (e) {
126+
emit(
127+
state.copyWith(
128+
status: CreateSourceStatus.failure,
129+
errorMessage: e.message,
130+
),
131+
);
132+
} catch (e) {
133+
emit(
134+
state.copyWith(
135+
status: CreateSourceStatus.failure,
136+
errorMessage: e.toString(),
137+
),
138+
);
139+
}
140+
}
141+
}

0 commit comments

Comments
 (0)