@@ -16,6 +16,7 @@ class CommentsTabPages extends StatefulWidget {
1616
1717class _CommentsTabPagesState extends State <CommentsTabPages > {
1818 StreamSubscription <CommentsTabMessage > _subscription;
19+ final focusNode = FocusNode ();
1920
2021 @override
2122 void didChangeDependencies () {
@@ -36,6 +37,9 @@ class _CommentsTabPagesState extends State<CommentsTabPages> {
3637 if (message is UpdateCommentFailure ) {
3738 _showSnackBar ('Update comment failure: ${message .error }' );
3839 }
40+ if (message is MinLengthOfCommentIs3 ) {
41+ _showSnackBar ('Min length of comment is 3!' );
42+ }
3943 }, onError: (e, s) => print ('$e $s ' ));
4044 }
4145
@@ -60,40 +64,91 @@ class _CommentsTabPagesState extends State<CommentsTabPages> {
6064
6165 return Container (
6266 color: Colors .white,
63- child: StreamBuilder <CommentsTabState >(
64- stream: bloc.state$,
65- initialData: bloc.state$.value,
66- builder: (context, snapshot) {
67- var state = snapshot.data;
67+ child: Column (
68+ children: < Widget > [
69+ Expanded (
70+ child: StreamBuilder <CommentsTabState >(
71+ stream: bloc.state$,
72+ initialData: bloc.state$.value,
73+ builder: (context, snapshot) {
74+ var state = snapshot.data;
6875
69- if (state.isLoading) {
70- return Center (
71- child: CircularProgressIndicator (),
72- );
73- }
76+ if (state.isLoading) {
77+ return Center (
78+ child: CircularProgressIndicator (),
79+ );
80+ }
7481
75- if (state.error != null ) {
76- return Center (
77- child: Text ('Error ${state .error }' ),
78- );
79- }
82+ if (state.error != null ) {
83+ return Center (
84+ child: Text ('Error ${state .error }' ),
85+ );
86+ }
8087
81- var comments = state.comments;
82- return Scrollbar (
83- child: ListView .separated (
84- physics: const BouncingScrollPhysics (),
85- itemCount: comments.length,
86- itemBuilder: (context, index) => CommentItemWidget (
87- comment: comments[index],
88- deleteCallback: showDeleteDialog,
89- editCallback: showEditDialog,
90- ),
91- separatorBuilder: (context, index) => Divider (
92- color: Theme .of (context).dividerColor.withAlpha (128 ),
93- ),
88+ var comments = state.comments;
89+ return Scrollbar (
90+ child: ListView .separated (
91+ physics: const BouncingScrollPhysics (),
92+ itemCount: comments.length,
93+ itemBuilder: (context, index) => CommentItemWidget (
94+ comment: comments[index],
95+ deleteCallback: showDeleteDialog,
96+ editCallback: showEditDialog,
97+ ),
98+ separatorBuilder: (context, index) => Divider (
99+ color: Theme .of (context).dividerColor.withAlpha (128 ),
100+ ),
101+ ),
102+ );
103+ },
104+ ),
105+ ),
106+ Container (
107+ padding: const EdgeInsets .all (8.0 ),
108+ decoration: BoxDecoration (
109+ color: Colors .white,
110+ boxShadow: [
111+ BoxShadow (
112+ color: Colors .grey,
113+ blurRadius: 4 ,
114+ )
115+ ],
116+ ),
117+ child: Row (
118+ children: < Widget > [
119+ Expanded (
120+ child: TextField (
121+ expands: false ,
122+ focusNode: focusNode,
123+ decoration: InputDecoration (
124+ labelText: 'Comment' ,
125+ border: OutlineInputBorder (
126+ borderRadius: BorderRadius .circular (32 ),
127+ borderSide: const BorderSide (width: 0 ),
128+ ),
129+ filled: true ,
130+ ),
131+ onSubmitted: (_) => bloc.submitAddComment (),
132+ onChanged: bloc.commentChanged,
133+ keyboardType: TextInputType .multiline,
134+ textInputAction: TextInputAction .newline,
135+ maxLines: null ,
136+ ),
137+ ),
138+ const SizedBox (width: 8 ),
139+ FloatingActionButton (
140+ onPressed: () {
141+ focusNode.unfocus ();
142+ bloc.submitAddComment ();
143+ },
144+ child: Icon (
145+ Icons .send,
146+ ),
147+ )
148+ ],
94149 ),
95- );
96- } ,
150+ )
151+ ] ,
97152 ),
98153 );
99154 }
@@ -258,7 +313,7 @@ class CommentItemWidget extends StatelessWidget {
258313 child: Text (
259314 comment.updatedAt != null
260315 ? 'Edited: ${comment .updatedAt }'
261- : comment.createdAt,
316+ : ( comment.createdAt ?? 'Loading...' ) ,
262317 style: Theme .of (context)
263318 .textTheme
264319 .subtitle
0 commit comments