1- import 'package:batch_api_demo/main/bloc .dart' ;
2- import 'package:batch_api_demo/main/state .dart' ;
1+ import 'package:batch_api_demo/main/main_bloc .dart' ;
2+ import 'package:batch_api_demo/main/main_state .dart' ;
33import 'package:batch_api_demo/optional.dart' ;
4+ import 'package:batch_api_demo/users_repo.dart' ;
5+ import 'package:built_collection/built_collection.dart' ;
46import 'package:flutter/material.dart' ;
57import 'package:flutter_bloc_pattern/flutter_bloc_pattern.dart' ;
68
@@ -23,14 +25,40 @@ class _MyHomePageState extends State<MyHomePage> {
2325 return Scaffold (
2426 appBar: AppBar (
2527 title: const Text ('Batch API demo' ),
28+ actions: [
29+ IconButton (
30+ onPressed: () => context.bloc <MainBloc >().fetch (),
31+ icon: const Icon (Icons .refresh),
32+ ),
33+ IconButton (
34+ onPressed: () => context.bloc <MainBloc >().cancel (),
35+ icon: const Icon (Icons .cancel),
36+ ),
37+ RxStreamBuilder <bool >(
38+ stream: UsersRepo .failed$,
39+ builder: (context, state) => TextButton (
40+ onPressed: UsersRepo .toggleFailed,
41+ child: Text (
42+ state ? 'failed' : 'succeed' ,
43+ style: TextStyle (color: state ? Colors .red : Colors .green),
44+ ),
45+ ),
46+ ),
47+ ],
2648 ),
2749 body: SizedBox .expand (
2850 child: RxStreamBuilder <MainState >(
2951 stream: context.bloc <MainBloc >().state$,
3052 builder: (context, state) {
53+ if (state.cancelled) {
54+ return const Center (
55+ child: Text ('Cancelled' ),
56+ );
57+ }
58+
3159 if (state.error.isNotEmpty) {
3260 return Center (
33- child: Text ('Error: ${state .error .valueOrNull ()}' ),
61+ child: Text ('Error: ${state .error .valueOrNull ()!. message }' ),
3462 );
3563 }
3664
@@ -49,7 +77,7 @@ class _MyHomePageState extends State<MyHomePage> {
4977}
5078
5179class UsersListView extends StatelessWidget {
52- final List <UserItem > items;
80+ final BuiltList <UserItem > items;
5381
5482 const UsersListView ({Key ? key, required this .items}) : super (key: key);
5583
@@ -59,7 +87,10 @@ class UsersListView extends StatelessWidget {
5987 itemCount: items.length,
6088 itemBuilder: (context, index) {
6189 final item = items[index];
62- return UserItemRow (item: item);
90+ return UserItemRow (
91+ key: ValueKey (item.user.id),
92+ item: item,
93+ );
6394 },
6495 );
6596 }
@@ -74,17 +105,19 @@ class UserItemRow extends StatelessWidget {
74105 Widget build (BuildContext context) {
75106 return ListTile (
76107 title: Text (item.user.name),
77- subtitle: item.isLoading
78- ? Text (
79- 'Loading...' ,
80- style: Theme .of (context)
81- .textTheme
82- .bodyMedium!
83- .copyWith (color: Colors .red),
84- )
85- : item.user.avatarUrl != null
86- ? Text ('Avatar: ${item .user .avatarUrl }' )
87- : const Text ('No avatar' ),
108+ subtitle: switch ((item.isLoading, item.error)) {
109+ (true , _) => Text (
110+ 'Loading...' ,
111+ style: Theme .of (context)
112+ .textTheme
113+ .bodyMedium!
114+ .copyWith (color: Colors .red),
115+ ),
116+ (_, Some (value: final error)) => Text ('Error: ${error .message }' ),
117+ _ => item.user.avatarUrl != null
118+ ? Text ('Avatar: ${item .user .avatarUrl }' )
119+ : const Text ('No avatar' ),
120+ },
88121 leading: const CircleAvatar (
89122 child: Icon (Icons .person),
90123 ),
0 commit comments