Skip to content

Commit 8f5ce9d

Browse files
committed
Insert room comment
1 parent e645c68 commit 8f5ce9d

File tree

6 files changed

+146
-31
lines changed

6 files changed

+146
-31
lines changed

lib/data/room_comments/room_comments_repository.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import 'package:find_room/models/room_comment_entity.dart';
33
import 'package:meta/meta.dart';
44

55
abstract class RoomCommentsRepository {
6+
Future<void> add({RoomCommentEntity commentEntity});
7+
68
Stream<BuiltList<RoomCommentEntity>> commentsFor({@required String roomId});
79

810
Future<void> deleteCommentBy({@required String id});

lib/data/room_comments/room_comments_repository_impl.dart

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,15 @@ class RoomCommentsRepositoryImpl implements RoomCommentsRepository {
4444
var documentSnapshot = await _firestore.document('comments/$byId').get();
4545
return RoomCommentEntity.fromDocumentSnapshot(documentSnapshot);
4646
}
47+
48+
@override
49+
Future<void> add({RoomCommentEntity commentEntity}) async {
50+
Map<String, dynamic> json = commentEntity.toJson();
51+
json.remove('documentID');
52+
json['created_at'] = FieldValue.serverTimestamp();
53+
json['updated_at'] = null;
54+
print(json);
55+
await _firestore.collection('comments').add(json);
56+
print('done');
57+
}
4758
}

lib/pages/detail/comments/comments_tab_bloc.dart

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ class CommentsTabBloc implements BaseBloc {
1818
final void Function() getComments;
1919
final void Function(CommentItem) deleteComment;
2020
final void Function(CommentItem, String) updateComment;
21+
final void Function(String) commentChanged;
22+
final void Function() submitAddComment;
2123

2224
final ValueStream<CommentsTabState> state$;
2325
final Stream<CommentsTabMessage> message$;
@@ -28,6 +30,8 @@ class CommentsTabBloc implements BaseBloc {
2830
this.getComments,
2931
this.deleteComment,
3032
this.updateComment,
33+
this.commentChanged,
34+
this.submitAddComment,
3135
this.state$,
3236
this.message$,
3337
this._disposeBag,
@@ -43,6 +47,8 @@ class CommentsTabBloc implements BaseBloc {
4347
final getCommentS = PublishSubject<void>();
4448
final deleteCommentS = PublishSubject<CommentItem>();
4549
final updateCommentS = PublishSubject<Tuple2<CommentItem, String>>();
50+
final commentChangedS = PublishSubject<String>();
51+
final submitAddCommentS = PublishSubject<void>();
4652

4753
final initialVS = CommentsTabState.initial();
4854

@@ -58,6 +64,16 @@ class CommentsTabBloc implements BaseBloc {
5864
final stateDistinct$ =
5965
state$.publishValueSeededDistinct(seedValue: initialVS);
6066

67+
final comment$ = submitAddCommentS
68+
.withLatestFrom(commentChangedS, (_, String comment) => comment)
69+
.map((comment) {
70+
if (comment.length < 3) {
71+
return Tuple2(comment, const MinLengthOfCommentIs3());
72+
} else {
73+
return Tuple2(comment, null);
74+
}
75+
}).share();
76+
6177
final ConnectableStream<CommentsTabMessage> message$ = Rx.merge(
6278
[
6379
deleteCommentS.groupBy((comment) => comment.id).flatMap(
@@ -76,13 +92,39 @@ class CommentsTabBloc implements BaseBloc {
7692
);
7793
},
7894
),
95+
comment$
96+
.map((tuple) => tuple.item2)
97+
.where((message) => message != null),
98+
comment$
99+
.where((tuple) => tuple.item2 == null)
100+
.map((tuple) => tuple.item1)
101+
.exhaustMap((comment) async* {
102+
var currentUser = authBloc.currentUser();
103+
if (currentUser == null) {
104+
throw 'Fucking...';
105+
}
106+
await commentsRepository.add(
107+
commentEntity: RoomCommentEntity(
108+
null,
109+
comment,
110+
roomId,
111+
currentUser.uid,
112+
currentUser.avatar,
113+
currentUser.fullName,
114+
null,
115+
null,
116+
),
117+
);
118+
}),
79119
],
80120
).publish();
81121

82122
return CommentsTabBloc._(
83123
() => getCommentS.add(null),
84124
deleteCommentS.add,
85125
(comment, content) => updateCommentS.add(Tuple2(comment, content)),
126+
commentChangedS.add,
127+
() => submitAddCommentS.add(null),
86128
stateDistinct$,
87129
message$,
88130
DisposeBag(

lib/pages/detail/comments/comments_tab_page.dart

Lines changed: 86 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ class CommentsTabPages extends StatefulWidget {
1616

1717
class _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

lib/pages/detail/comments/comments_tab_state.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ class UpdateCommentFailure implements CommentsTabMessage {
3636
UpdateCommentFailure(this.comment, this.error);
3737
}
3838

39+
class MinLengthOfCommentIs3 implements CommentsTabMessage {
40+
const MinLengthOfCommentIs3();
41+
}
42+
3943
///
4044
/// PartialChange
4145
///

lib/pages/detail/room_detail_page.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ class _RoomDetailPageState extends State<RoomDetailPage> {
5353
final bloc = BlocProvider.of<RoomDetailBloc>(context);
5454

5555
return Scaffold(
56+
resizeToAvoidBottomPadding: false,
5657
appBar: AppBar(
5758
title: Text(S.of(context).detail_title),
5859
actions: <Widget>[

0 commit comments

Comments
 (0)