Skip to content

Commit f303c01

Browse files
authored
Merge pull request brianegan#131 from felangel/bloc-library-updates
Update Bloc Library Sample
2 parents 21cb33f + ee330f7 commit f303c01

29 files changed

+345
-154
lines changed

bloc_library/lib/blocs/blocs.dart

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// in the LICENSE file.
44

55
export './filtered_todos/filtered_todos.dart';
6+
export './stats/stats.dart';
67
export './tab/tab.dart';
78
export './todos/todos.dart';
89
export './simple_bloc_delegate.dart';

bloc_library/lib/blocs/filtered_todos/filtered_todos_bloc.dart

+31-26
Original file line numberDiff line numberDiff line change
@@ -16,27 +16,26 @@ class FilteredTodosBloc extends Bloc<FilteredTodosEvent, FilteredTodosState> {
1616
FilteredTodosBloc({@required this.todosBloc}) {
1717
todosSubscription = todosBloc.state.listen((state) {
1818
if (state is TodosLoaded) {
19-
dispatch(TodosUpdated((todosBloc.currentState as TodosLoaded).todos));
19+
dispatch(UpdateTodos((todosBloc.currentState as TodosLoaded).todos));
2020
}
2121
});
2222
}
2323

2424
@override
25-
FilteredTodosState get initialState => todosBloc.currentState is TodosLoaded
26-
? FilteredTodosState(
27-
(todosBloc.currentState as TodosLoaded).todos,
28-
VisibilityFilter.all,
29-
)
30-
: FilteredTodosState([], VisibilityFilter.all);
25+
FilteredTodosState get initialState {
26+
return todosBloc.currentState is TodosLoaded
27+
? FilteredTodosLoaded(
28+
(todosBloc.currentState as TodosLoaded).todos,
29+
VisibilityFilter.all,
30+
)
31+
: FilteredTodosLoading();
32+
}
3133

3234
@override
33-
Stream<FilteredTodosState> mapEventToState(
34-
FilteredTodosState currentState,
35-
FilteredTodosEvent event,
36-
) async* {
35+
Stream<FilteredTodosState> mapEventToState(FilteredTodosEvent event) async* {
3736
if (event is UpdateFilter) {
3837
yield* _mapUpdateFilterToState(currentState, event);
39-
} else if (event is TodosUpdated) {
38+
} else if (event is UpdateTodos) {
4039
yield* _mapTodosUpdatedToState(currentState, event);
4140
}
4241
}
@@ -46,34 +45,34 @@ class FilteredTodosBloc extends Bloc<FilteredTodosEvent, FilteredTodosState> {
4645
UpdateFilter event,
4746
) async* {
4847
if (todosBloc.currentState is TodosLoaded) {
49-
yield FilteredTodosState(
48+
yield FilteredTodosLoaded(
5049
_mapTodosToFilteredTodos(
51-
(todosBloc.currentState as TodosLoaded).todos, event.newFilter),
52-
event.newFilter,
50+
(todosBloc.currentState as TodosLoaded).todos,
51+
event.filter,
52+
),
53+
event.filter,
5354
);
5455
}
5556
}
5657

5758
Stream<FilteredTodosState> _mapTodosUpdatedToState(
5859
FilteredTodosState currentState,
59-
TodosUpdated event,
60+
UpdateTodos event,
6061
) async* {
61-
yield FilteredTodosState(
62+
final visibilityFilter = currentState is FilteredTodosLoaded
63+
? currentState.activeFilter
64+
: VisibilityFilter.all;
65+
yield FilteredTodosLoaded(
6266
_mapTodosToFilteredTodos(
6367
(todosBloc.currentState as TodosLoaded).todos,
64-
currentState.activeFilter,
68+
visibilityFilter,
6569
),
66-
currentState.activeFilter,
70+
visibilityFilter,
6771
);
6872
}
6973

70-
@override
71-
void dispose() {
72-
todosSubscription.cancel();
73-
super.dispose();
74-
}
75-
76-
_mapTodosToFilteredTodos(List<Todo> todos, VisibilityFilter filter) {
74+
List<Todo> _mapTodosToFilteredTodos(
75+
List<Todo> todos, VisibilityFilter filter) {
7776
return todos.where((todo) {
7877
if (filter == VisibilityFilter.all) {
7978
return true;
@@ -84,4 +83,10 @@ class FilteredTodosBloc extends Bloc<FilteredTodosEvent, FilteredTodosState> {
8483
}
8584
}).toList();
8685
}
86+
87+
@override
88+
void dispose() {
89+
todosSubscription.cancel();
90+
super.dispose();
91+
}
8792
}

bloc_library/lib/blocs/filtered_todos/filtered_todos_event.dart

+8-7
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,28 @@
33
// in the LICENSE file.
44

55
import 'package:equatable/equatable.dart';
6-
6+
import 'package:meta/meta.dart';
77
import 'package:bloc_library/models/models.dart';
88

9+
@immutable
910
abstract class FilteredTodosEvent extends Equatable {
1011
FilteredTodosEvent([List props = const []]) : super(props);
1112
}
1213

1314
class UpdateFilter extends FilteredTodosEvent {
14-
final VisibilityFilter newFilter;
15+
final VisibilityFilter filter;
1516

16-
UpdateFilter(this.newFilter) : super([newFilter]);
17+
UpdateFilter(this.filter) : super([filter]);
1718

1819
@override
19-
String toString() => 'UpdateFilter { newFilter: $newFilter }';
20+
String toString() => 'UpdateFilter { filter: $filter }';
2021
}
2122

22-
class TodosUpdated extends FilteredTodosEvent {
23+
class UpdateTodos extends FilteredTodosEvent {
2324
final List<Todo> todos;
2425

25-
TodosUpdated(this.todos) : super([todos]);
26+
UpdateTodos(this.todos) : super([todos]);
2627

2728
@override
28-
String toString() => 'TodosUpdated { todos: $todos }';
29+
String toString() => 'UpdateTodos { todos: $todos }';
2930
}

bloc_library/lib/blocs/filtered_todos/filtered_todos_state.dart

+16-4
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,28 @@
33
// in the LICENSE file.
44

55
import 'package:equatable/equatable.dart';
6+
import 'package:meta/meta.dart';
67
import 'package:bloc_library/models/models.dart';
78

8-
class FilteredTodosState extends Equatable {
9+
@immutable
10+
abstract class FilteredTodosState extends Equatable {
11+
FilteredTodosState([List props = const []]) : super(props);
12+
}
13+
14+
class FilteredTodosLoading extends FilteredTodosState {
15+
@override
16+
String toString() => 'FilteredTodosLoading';
17+
}
18+
19+
class FilteredTodosLoaded extends FilteredTodosState {
920
final List<Todo> filteredTodos;
1021
final VisibilityFilter activeFilter;
1122

12-
FilteredTodosState(this.filteredTodos, this.activeFilter)
23+
FilteredTodosLoaded(this.filteredTodos, this.activeFilter)
1324
: super([filteredTodos, activeFilter]);
1425

1526
@override
16-
String toString() =>
17-
'FilteredTodosState { filteredTodos: $filteredTodos, activeFilter: $activeFilter }';
27+
String toString() {
28+
return 'FilteredTodosLoaded { filteredTodos: $filteredTodos, activeFilter: $activeFilter }';
29+
}
1830
}

bloc_library/lib/blocs/simple_bloc_delegate.dart

+2
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,13 @@ import 'package:bloc/bloc.dart';
99
class SimpleBlocDelegate extends BlocDelegate {
1010
@override
1111
void onTransition(Transition transition) {
12+
super.onTransition(transition);
1213
print(transition);
1314
}
1415

1516
@override
1617
void onError(Object error, StackTrace stacktrace) {
18+
super.onError(error, stacktrace);
1719
print(error);
1820
}
1921
}
+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export 'stats_bloc.dart';
2+
export 'stats_event.dart';
3+
export 'stats_state.dart';
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import 'dart:async';
2+
import 'package:meta/meta.dart';
3+
import 'package:bloc/bloc.dart';
4+
import 'package:bloc_library/blocs/blocs.dart';
5+
6+
class StatsBloc extends Bloc<StatsEvent, StatsState> {
7+
final TodosBloc todosBloc;
8+
StreamSubscription todosSubscription;
9+
10+
StatsBloc({@required this.todosBloc}) {
11+
todosSubscription = todosBloc.state.listen((state) {
12+
if (state is TodosLoaded) {
13+
dispatch(UpdateStats(state.todos));
14+
}
15+
});
16+
}
17+
18+
@override
19+
StatsState get initialState => StatsLoading();
20+
21+
@override
22+
Stream<StatsState> mapEventToState(StatsEvent event) async* {
23+
if (event is UpdateStats) {
24+
int numActive =
25+
event.todos.where((todo) => !todo.complete).toList().length;
26+
int numCompleted =
27+
event.todos.where((todo) => todo.complete).toList().length;
28+
yield StatsLoaded(numActive, numCompleted);
29+
}
30+
}
31+
32+
@override
33+
void dispose() {
34+
todosSubscription.cancel();
35+
super.dispose();
36+
}
37+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import 'package:equatable/equatable.dart';
2+
import 'package:meta/meta.dart';
3+
import 'package:bloc_library/models/models.dart';
4+
5+
@immutable
6+
abstract class StatsEvent extends Equatable {
7+
StatsEvent([List props = const []]) : super(props);
8+
}
9+
10+
class UpdateStats extends StatsEvent {
11+
final List<Todo> todos;
12+
13+
UpdateStats(this.todos) : super([todos]);
14+
15+
@override
16+
String toString() => 'UpdateStats { todos: $todos }';
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import 'package:equatable/equatable.dart';
2+
import 'package:meta/meta.dart';
3+
4+
@immutable
5+
abstract class StatsState extends Equatable {
6+
StatsState([List props = const []]) : super(props);
7+
}
8+
9+
class StatsLoading extends StatsState {
10+
@override
11+
String toString() => 'StatsLoading';
12+
}
13+
14+
class StatsLoaded extends StatsState {
15+
final int numActive;
16+
final int numCompleted;
17+
18+
StatsLoaded(this.numActive, this.numCompleted)
19+
: super([numActive, numCompleted]);
20+
21+
@override
22+
String toString() {
23+
return 'StatsLoaded { numActive: $numActive, numCompleted: $numCompleted }';
24+
}
25+
}

bloc_library/lib/blocs/tab/tab_bloc.dart

+1-4
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,7 @@ class TabBloc extends Bloc<TabEvent, AppTab> {
1313
AppTab get initialState => AppTab.todos;
1414

1515
@override
16-
Stream<AppTab> mapEventToState(
17-
AppTab currentState,
18-
TabEvent event,
19-
) async* {
16+
Stream<AppTab> mapEventToState(TabEvent event) async* {
2017
if (event is UpdateTab) {
2118
yield event.tab;
2219
}

bloc_library/lib/blocs/tab/tab_event.dart

+2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
// in the LICENSE file.
44

55
import 'package:equatable/equatable.dart';
6+
import 'package:meta/meta.dart';
67
import 'package:bloc_library/models/models.dart';
78

9+
@immutable
810
abstract class TabEvent extends Equatable {
911
TabEvent([List props = const []]) : super(props);
1012
}

bloc_library/lib/blocs/todos/todos_bloc.dart

+1-4
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,7 @@ class TodosBloc extends Bloc<TodosEvent, TodosState> {
1919
TodosState get initialState => TodosLoading();
2020

2121
@override
22-
Stream<TodosState> mapEventToState(
23-
TodosState currentState,
24-
TodosEvent event,
25-
) async* {
22+
Stream<TodosState> mapEventToState(TodosEvent event) async* {
2623
if (event is LoadTodos) {
2724
yield* _mapLoadTodosToState();
2825
} else if (event is AddTodo) {

bloc_library/lib/blocs/todos/todos_event.dart

+2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
// in the LICENSE file.
44

55
import 'package:equatable/equatable.dart';
6+
import 'package:meta/meta.dart';
67
import 'package:bloc_library/models/models.dart';
78

9+
@immutable
810
abstract class TodosEvent extends Equatable {
911
TodosEvent([List props = const []]) : super(props);
1012
}

bloc_library/lib/blocs/todos/todos_state.dart

+2
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@
33
// in the LICENSE file.
44

55
import 'package:equatable/equatable.dart';
6+
import 'package:meta/meta.dart';
67
import 'package:bloc_library/models/models.dart';
78

9+
@immutable
810
abstract class TodosState extends Equatable {
911
TodosState([List props = const []]) : super(props);
1012
}

bloc_library/lib/screens/home_screen.dart

+8-4
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,23 @@ class HomeScreen extends StatefulWidget {
1717
HomeScreen({@required this.onInit}) : super(key: ArchSampleKeys.homeScreen);
1818

1919
@override
20-
HomeScreenState createState() {
21-
return new HomeScreenState();
22-
}
20+
State<HomeScreen> createState() => _HomeScreenState();
2321
}
2422

25-
class HomeScreenState extends State<HomeScreen> {
23+
class _HomeScreenState extends State<HomeScreen> {
2624
final TabBloc _tabBloc = TabBloc();
2725
FilteredTodosBloc _filteredTodosBloc;
26+
StatsBloc _statsBloc;
2827

2928
@override
3029
void initState() {
3130
widget.onInit();
3231
_filteredTodosBloc = FilteredTodosBloc(
3332
todosBloc: BlocProvider.of<TodosBloc>(context),
3433
);
34+
_statsBloc = StatsBloc(
35+
todosBloc: BlocProvider.of<TodosBloc>(context),
36+
);
3537
super.initState();
3638
}
3739

@@ -44,6 +46,7 @@ class HomeScreenState extends State<HomeScreen> {
4446
blocProviders: [
4547
BlocProvider<TabBloc>(bloc: _tabBloc),
4648
BlocProvider<FilteredTodosBloc>(bloc: _filteredTodosBloc),
49+
BlocProvider<StatsBloc>(bloc: _statsBloc),
4750
],
4851
child: Scaffold(
4952
appBar: AppBar(
@@ -74,6 +77,7 @@ class HomeScreenState extends State<HomeScreen> {
7477

7578
@override
7679
void dispose() {
80+
_statsBloc.dispose();
7781
_filteredTodosBloc.dispose();
7882
_tabBloc.dispose();
7983
super.dispose();

bloc_library/lib/widgets/filter_button.dart

+3-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,9 @@ class FilterButton extends StatelessWidget {
2929
onSelected: (filter) {
3030
filteredTodosBloc.dispatch(UpdateFilter(filter));
3131
},
32-
activeFilter: state.activeFilter,
32+
activeFilter: state is FilteredTodosLoaded
33+
? state.activeFilter
34+
: VisibilityFilter.all,
3335
activeStyle: activeStyle,
3436
defaultStyle: defaultStyle,
3537
);

0 commit comments

Comments
 (0)