Skip to content

Commit 59d2e78

Browse files
authored
Merge pull request #18 from headlines-toolkit/refactor_add_content_lifecyle_management_for_the_content_management_feature
Refactor add content lifecyle management for the content management feature
2 parents 6a2c49a + ae7d7ba commit 59d2e78

38 files changed

+583
-118
lines changed

lib/bloc_observer.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,13 @@ class AppBlocObserver extends BlocObserver {
99
void onChange(BlocBase<dynamic> bloc, Change<dynamic> change) {
1010
super.onChange(bloc, change);
1111
log('onChange(${bloc.runtimeType}, $change)');
12+
print('onChange(${bloc.runtimeType}, $change)');
1213
}
1314

1415
@override
1516
void onError(BlocBase<dynamic> bloc, Object error, StackTrace stackTrace) {
1617
log('onError(${bloc.runtimeType}, $error, $stackTrace)');
18+
print('onError(${bloc.runtimeType}, $error, $stackTrace)');
1719
super.onError(bloc, error, stackTrace);
1820
}
1921
}

lib/content_management/bloc/create_category/create_category_bloc.dart

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ class CreateCategoryBloc
1717
on<CreateCategoryNameChanged>(_onNameChanged);
1818
on<CreateCategoryDescriptionChanged>(_onDescriptionChanged);
1919
on<CreateCategoryIconUrlChanged>(_onIconUrlChanged);
20+
on<CreateCategoryStatusChanged>(_onStatusChanged);
2021
on<CreateCategorySubmitted>(_onSubmitted);
2122
}
2223

@@ -58,6 +59,18 @@ class CreateCategoryBloc
5859
);
5960
}
6061

62+
void _onStatusChanged(
63+
CreateCategoryStatusChanged event,
64+
Emitter<CreateCategoryState> emit,
65+
) {
66+
emit(
67+
state.copyWith(
68+
contentStatus: event.status,
69+
status: CreateCategoryStatus.initial,
70+
),
71+
);
72+
}
73+
6174
Future<void> _onSubmitted(
6275
CreateCategorySubmitted event,
6376
Emitter<CreateCategoryState> emit,
@@ -70,6 +83,7 @@ class CreateCategoryBloc
7083
name: state.name,
7184
description: state.description.isNotEmpty ? state.description : null,
7285
iconUrl: state.iconUrl.isNotEmpty ? state.iconUrl : null,
86+
status: state.contentStatus,
7387
);
7488

7589
await _categoriesRepository.create(item: newCategory);

lib/content_management/bloc/create_category/create_category_event.dart

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,31 +5,40 @@ sealed class CreateCategoryEvent extends Equatable {
55
const CreateCategoryEvent();
66

77
@override
8-
List<Object> get props => [];
8+
List<Object?> get props => [];
99
}
1010

1111
/// Event for when the category's name is changed.
1212
final class CreateCategoryNameChanged extends CreateCategoryEvent {
1313
const CreateCategoryNameChanged(this.name);
1414
final String name;
1515
@override
16-
List<Object> get props => [name];
16+
List<Object?> get props => [name];
1717
}
1818

1919
/// Event for when the category's description is changed.
2020
final class CreateCategoryDescriptionChanged extends CreateCategoryEvent {
2121
const CreateCategoryDescriptionChanged(this.description);
2222
final String description;
2323
@override
24-
List<Object> get props => [description];
24+
List<Object?> get props => [description];
2525
}
2626

2727
/// Event for when the category's icon URL is changed.
2828
final class CreateCategoryIconUrlChanged extends CreateCategoryEvent {
2929
const CreateCategoryIconUrlChanged(this.iconUrl);
3030
final String iconUrl;
3131
@override
32-
List<Object> get props => [iconUrl];
32+
List<Object?> get props => [iconUrl];
33+
}
34+
35+
/// Event for when the category's status is changed.
36+
final class CreateCategoryStatusChanged extends CreateCategoryEvent {
37+
const CreateCategoryStatusChanged(this.status);
38+
39+
final ContentStatus status;
40+
@override
41+
List<Object?> get props => [status];
3342
}
3443

3544
/// Event to signal that the form should be submitted.

lib/content_management/bloc/create_category/create_category_state.dart

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,15 @@ final class CreateCategoryState extends Equatable {
2323
this.name = '',
2424
this.description = '',
2525
this.iconUrl = '',
26+
this.contentStatus = ContentStatus.active,
2627
this.errorMessage,
2728
});
2829

2930
final CreateCategoryStatus status;
3031
final String name;
3132
final String description;
3233
final String iconUrl;
34+
final ContentStatus contentStatus;
3335
final String? errorMessage;
3436

3537
/// Returns true if the form is valid and can be submitted.
@@ -41,17 +43,26 @@ final class CreateCategoryState extends Equatable {
4143
String? name,
4244
String? description,
4345
String? iconUrl,
46+
ContentStatus? contentStatus,
4447
String? errorMessage,
4548
}) {
4649
return CreateCategoryState(
4750
status: status ?? this.status,
4851
name: name ?? this.name,
4952
description: description ?? this.description,
5053
iconUrl: iconUrl ?? this.iconUrl,
54+
contentStatus: contentStatus ?? this.contentStatus,
5155
errorMessage: errorMessage,
5256
);
5357
}
5458

5559
@override
56-
List<Object?> get props => [status, name, description, iconUrl, errorMessage];
60+
List<Object?> get props => [
61+
status,
62+
name,
63+
description,
64+
iconUrl,
65+
contentStatus,
66+
errorMessage,
67+
];
5768
}

lib/content_management/bloc/create_headline/create_headline_bloc.dart

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ class CreateHeadlineBloc
2626
on<CreateHeadlineImageUrlChanged>(_onImageUrlChanged);
2727
on<CreateHeadlineSourceChanged>(_onSourceChanged);
2828
on<CreateHeadlineCategoryChanged>(_onCategoryChanged);
29+
on<CreateHeadlineStatusChanged>(_onStatusChanged);
2930
on<CreateHeadlineSubmitted>(_onSubmitted);
3031
}
3132

@@ -114,6 +115,18 @@ class CreateHeadlineBloc
114115
emit(state.copyWith(category: () => event.category));
115116
}
116117

118+
void _onStatusChanged(
119+
CreateHeadlineStatusChanged event,
120+
Emitter<CreateHeadlineState> emit,
121+
) {
122+
emit(
123+
state.copyWith(
124+
contentStatus: event.status,
125+
status: CreateHeadlineStatus.initial,
126+
),
127+
);
128+
}
129+
117130
Future<void> _onSubmitted(
118131
CreateHeadlineSubmitted event,
119132
Emitter<CreateHeadlineState> emit,
@@ -129,6 +142,7 @@ class CreateHeadlineBloc
129142
imageUrl: state.imageUrl.isNotEmpty ? state.imageUrl : null,
130143
source: state.source,
131144
category: state.category,
145+
status: state.contentStatus,
132146
);
133147

134148
await _headlinesRepository.create(item: newHeadline);

lib/content_management/bloc/create_headline/create_headline_event.dart

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,77 @@
11
part of 'create_headline_bloc.dart';
22

33
/// Base class for all events related to the [CreateHeadlineBloc].
4-
abstract class CreateHeadlineEvent extends Equatable {
4+
sealed class CreateHeadlineEvent extends Equatable {
55
const CreateHeadlineEvent();
66

77
@override
88
List<Object?> get props => [];
99
}
1010

1111
/// Event to signal that the data for dropdowns should be loaded.
12-
class CreateHeadlineDataLoaded extends CreateHeadlineEvent {
12+
final class CreateHeadlineDataLoaded extends CreateHeadlineEvent {
1313
const CreateHeadlineDataLoaded();
1414
}
1515

1616
/// Event for when the headline's title is changed.
17-
class CreateHeadlineTitleChanged extends CreateHeadlineEvent {
17+
final class CreateHeadlineTitleChanged extends CreateHeadlineEvent {
1818
const CreateHeadlineTitleChanged(this.title);
1919
final String title;
2020
@override
21-
List<Object> get props => [title];
21+
List<Object?> get props => [title];
2222
}
2323

2424
/// Event for when the headline's description is changed.
25-
class CreateHeadlineDescriptionChanged extends CreateHeadlineEvent {
25+
final class CreateHeadlineDescriptionChanged extends CreateHeadlineEvent {
2626
const CreateHeadlineDescriptionChanged(this.description);
2727
final String description;
2828
@override
29-
List<Object> get props => [description];
29+
List<Object?> get props => [description];
3030
}
3131

3232
/// Event for when the headline's URL is changed.
33-
class CreateHeadlineUrlChanged extends CreateHeadlineEvent {
33+
final class CreateHeadlineUrlChanged extends CreateHeadlineEvent {
3434
const CreateHeadlineUrlChanged(this.url);
3535
final String url;
3636
@override
37-
List<Object> get props => [url];
37+
List<Object?> get props => [url];
3838
}
3939

4040
/// Event for when the headline's image URL is changed.
41-
class CreateHeadlineImageUrlChanged extends CreateHeadlineEvent {
41+
final class CreateHeadlineImageUrlChanged extends CreateHeadlineEvent {
4242
const CreateHeadlineImageUrlChanged(this.imageUrl);
4343
final String imageUrl;
4444
@override
45-
List<Object> get props => [imageUrl];
45+
List<Object?> get props => [imageUrl];
4646
}
4747

4848
/// Event for when the headline's source is changed.
49-
class CreateHeadlineSourceChanged extends CreateHeadlineEvent {
49+
final class CreateHeadlineSourceChanged extends CreateHeadlineEvent {
5050
const CreateHeadlineSourceChanged(this.source);
5151
final Source? source;
5252
@override
5353
List<Object?> get props => [source];
5454
}
5555

5656
/// Event for when the headline's category is changed.
57-
class CreateHeadlineCategoryChanged extends CreateHeadlineEvent {
57+
final class CreateHeadlineCategoryChanged extends CreateHeadlineEvent {
5858
const CreateHeadlineCategoryChanged(this.category);
5959
final Category? category;
6060
@override
6161
List<Object?> get props => [category];
6262
}
6363

64+
/// Event for when the headline's status is changed.
65+
final class CreateHeadlineStatusChanged extends CreateHeadlineEvent {
66+
const CreateHeadlineStatusChanged(this.status);
67+
68+
final ContentStatus status;
69+
70+
@override
71+
List<Object?> get props => [status];
72+
}
73+
6474
/// Event to signal that the form should be submitted.
65-
class CreateHeadlineSubmitted extends CreateHeadlineEvent {
75+
final class CreateHeadlineSubmitted extends CreateHeadlineEvent {
6676
const CreateHeadlineSubmitted();
6777
}
68-

lib/content_management/bloc/create_headline/create_headline_state.dart

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ final class CreateHeadlineState extends Equatable {
3030
this.category,
3131
this.sources = const [],
3232
this.categories = const [],
33+
this.contentStatus = ContentStatus.active,
3334
this.errorMessage,
3435
});
3536

@@ -42,6 +43,7 @@ final class CreateHeadlineState extends Equatable {
4243
final Category? category;
4344
final List<Source> sources;
4445
final List<Category> categories;
46+
final ContentStatus contentStatus;
4547
final String? errorMessage;
4648

4749
/// Returns true if the form is valid and can be submitted.
@@ -57,6 +59,7 @@ final class CreateHeadlineState extends Equatable {
5759
ValueGetter<Category?>? category,
5860
List<Source>? sources,
5961
List<Category>? categories,
62+
ContentStatus? contentStatus,
6063
String? errorMessage,
6164
}) {
6265
return CreateHeadlineState(
@@ -69,22 +72,23 @@ final class CreateHeadlineState extends Equatable {
6972
category: category != null ? category() : this.category,
7073
sources: sources ?? this.sources,
7174
categories: categories ?? this.categories,
75+
contentStatus: contentStatus ?? this.contentStatus,
7276
errorMessage: errorMessage ?? this.errorMessage,
7377
);
7478
}
7579

7680
@override
7781
List<Object?> get props => [
78-
status,
79-
title,
80-
description,
81-
url,
82-
imageUrl,
83-
source,
84-
category,
85-
sources,
86-
categories,
87-
errorMessage,
88-
];
82+
status,
83+
title,
84+
description,
85+
url,
86+
imageUrl,
87+
source,
88+
category,
89+
sources,
90+
categories,
91+
contentStatus,
92+
errorMessage,
93+
];
8994
}
90-

lib/content_management/bloc/create_source/create_source_bloc.dart

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ class CreateSourceBloc extends Bloc<CreateSourceEvent, CreateSourceState> {
2323
on<CreateSourceTypeChanged>(_onSourceTypeChanged);
2424
on<CreateSourceLanguageChanged>(_onLanguageChanged);
2525
on<CreateSourceHeadquartersChanged>(_onHeadquartersChanged);
26+
on<CreateSourceStatusChanged>(_onStatusChanged);
2627
on<CreateSourceSubmitted>(_onSubmitted);
2728
}
2829

@@ -103,6 +104,18 @@ class CreateSourceBloc extends Bloc<CreateSourceEvent, CreateSourceState> {
103104
emit(state.copyWith(headquarters: () => event.headquarters));
104105
}
105106

107+
void _onStatusChanged(
108+
CreateSourceStatusChanged event,
109+
Emitter<CreateSourceState> emit,
110+
) {
111+
emit(
112+
state.copyWith(
113+
contentStatus: event.status,
114+
status: CreateSourceStatus.initial,
115+
),
116+
);
117+
}
118+
106119
Future<void> _onSubmitted(
107120
CreateSourceSubmitted event,
108121
Emitter<CreateSourceState> emit,
@@ -118,6 +131,7 @@ class CreateSourceBloc extends Bloc<CreateSourceEvent, CreateSourceState> {
118131
sourceType: state.sourceType,
119132
language: state.language.isNotEmpty ? state.language : null,
120133
headquarters: state.headquarters,
134+
status: state.contentStatus,
121135
);
122136

123137
await _sourcesRepository.create(item: newSource);

0 commit comments

Comments
 (0)