Skip to content

Commit

Permalink
feature/add-comment-screen (#12)(#13)
Browse files Browse the repository at this point in the history
  • Loading branch information
codewithJosh committed Nov 27, 2022
2 parents c603a33 + f20a464 commit 0e00d30
Show file tree
Hide file tree
Showing 11 changed files with 389 additions and 116 deletions.
74 changes: 74 additions & 0 deletions lib/adapters/comment_adapter.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:news_expose_2k21/functions.dart';

class Comment extends StatefulWidget {
final String commentContent;
final Timestamp commentTimestamp;
final String userBio;
final String userImage;
final String userName;

const Comment(
{Key? key,
required this.commentContent,
required this.commentTimestamp,
required this.userBio,
required this.userImage,
required this.userName})
: super(key: key);

factory Comment.fromDocument(final documentSnapshot) => Comment(
commentContent: documentSnapshot['comment_content'],
commentTimestamp: documentSnapshot['comment_timestamp'],
userBio: documentSnapshot['user_bio'],
userImage: documentSnapshot['user_image'],
userName: documentSnapshot['user_name'],
);

@override
State<Comment> createState() => _CommentState();
}

class _CommentState extends State<Comment> {
late final String _commentContent = widget.commentContent;
late final Timestamp _commentTimestamp = widget.commentTimestamp;
late final String _userBio = widget.userBio;
late final String _userImage = widget.userImage;
late final String _userName = widget.userName;

@override
Widget build(BuildContext context) => ListTile(
leading: _userImage.isNotEmpty
? CircleAvatar(
radius: 23.0,
backgroundImage: CachedNetworkImageProvider(_userImage),
backgroundColor: colorEerieBlack,
)
: CircleAvatar(
child: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(22.0),
gradient: linearProfile,
),
),
),
title: Column(
children: <Widget>[
Container(
alignment: Alignment.topLeft,
child: initTitle2(_userBio,
size: 17.0, fontWeight: FontWeight.bold, fontFamily: ''),
),
Container(
alignment: Alignment.topLeft,
child: initTitle2(
'${initTimestamp(_commentTimestamp)} · $_userName'),
),
],
),
subtitle: Container(
alignment: Alignment.topLeft, child: initTitle2(_commentContent)),
);
}
68 changes: 37 additions & 31 deletions lib/adapters/update_adapter.dart
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class Update extends StatefulWidget {
updateContent: documentSnapshot['update_content'],
updateTimestamp: documentSnapshot['update_timestamp'],
userId: documentSnapshot['user_id'],
seen: documentSnapshot['Seen'],
seen: documentSnapshot['seen'],
);

seenCount(final seen) {
Expand Down Expand Up @@ -71,12 +71,16 @@ class _UpdateState extends State<Update> {
}

final user = User.fromDocument(dataSnapshot.data);

final userBio = user.userBio!;
final userImage = user.userImage!;
final userName = user.userName!;

return ListTile(
leading: user.userImage!.isNotEmpty
leading: userImage.isNotEmpty
? CircleAvatar(
radius: 25.0,
backgroundImage:
CachedNetworkImageProvider(user.userImage!),
backgroundImage: CachedNetworkImageProvider(userImage),
backgroundColor: colorEerieBlack,
)
: CircleAvatar(
Expand All @@ -87,10 +91,10 @@ class _UpdateState extends State<Update> {
),
),
),
title: initTitle2(user.userBio,
title: initTitle2(userBio,
size: 17.0, fontWeight: FontWeight.bold, fontFamily: ''),
subtitle: initTitle2(
'${initUpdateTimestamp(_updateTimestamp)} · ${user.userName}'),
subtitle:
initTitle2('${initTimestamp(_updateTimestamp)} · $userName'),
);
},
),
Expand Down Expand Up @@ -160,18 +164,20 @@ class _UpdateState extends State<Update> {
);

_onSeen() {
updatesRef.doc(_updateId).update({'Seen.$userId': !_isSeen});
updatesRef.doc(_updateId).update({'seen.$userId': !_isSeen});

setState(() {
_seenCount += _isSeen ? -1 : 1;
_isSeen = !_isSeen;
});
}

_onComment(final context, final updateId) =>
Navigator.push(context, MaterialPageRoute(builder: (context) => CommentScreen(
updateId: updateId,
)));
_onComment(final context, final updateId) => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => CommentScreen(
updateId: updateId,
)));

@override
void initState() {
Expand All @@ -181,24 +187,24 @@ class _UpdateState extends State<Update> {

@override
Widget build(BuildContext context) => Container(
margin: const EdgeInsets.all(18.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(25.0),
color: colorEerieBlack,
),
child: Column(
children: <Widget>[
_initHead(),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 18.0),
child: Column(
children: <Widget>[
_initBody(),
_initFoot(context),
],
margin: const EdgeInsets.all(18.0),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(25.0),
color: colorEerieBlack,
),
child: Column(
children: <Widget>[
_initHead(),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 18.0),
child: Column(
children: <Widget>[
_initBody(),
_initFoot(context),
],
),
),
),
],
),
);
],
),
);
}
192 changes: 190 additions & 2 deletions lib/comment_screen.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
import 'package:cached_network_image/cached_network_image.dart';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:news_expose_2k21/adapters/comment_adapter.dart';
import 'package:news_expose_2k21/functions.dart';
import 'package:news_expose_2k21/models/user_model.dart';

class CommentScreen extends StatefulWidget {
final String updateId;
Expand All @@ -10,8 +17,189 @@ class CommentScreen extends StatefulWidget {
}

class _CommentScreenState extends State<CommentScreen> {
late final String _updateId = widget.updateId;
final _commentContentController = TextEditingController();
bool _isLoading = false;
List<Comment> _comments = [];

_initAppBar() => AppBar(
systemOverlayStyle: SystemUiOverlayStyle.light,
backgroundColor: colorChineseBlack,
toolbarHeight: 55.0,
flexibleSpace: SafeArea(
child: Container(
decoration: const BoxDecoration(
gradient: linearAppBar,
),
child: Container(
alignment: Alignment.centerLeft,
margin: const EdgeInsets.only(left: 60.0),
child: initTitle2('Comments', size: 23.0),
),
),
),
);

_onComment(final context, final userBio, final userImage, final userName,
final commentContent) {
onFocusLost(context);

if (commentContent.isEmpty) {
buildFlutterToast('Comment cannot be empty!', colorKUCrimson);
} else {
addComment() =>
updatesRef.doc(_updateId).collection('Comments').doc().set({
'comment_content': commentContent,
'comment_timestamp': Timestamp.now(),
'user_bio': userBio,
'user_image': userImage,
'user_name': userName,
});

addComment().then((value) {
setState(() {
_commentContentController.clear();
_onLoadComments();
});
});
}
}

_loadComments() => _isLoading
? buildCircularProgress()
: SingleChildScrollView(
physics: const BouncingScrollPhysics(),
child: Column(
children: _comments,
),
);

_onLoadComments() async {
setState(() {
_isLoading = true;
});

final querySnapshot =
await updatesRef.doc(_updateId).collection('Comments').get();

setState(() {
_isLoading = false;
_comments = querySnapshot.docs
.map((documentSnapshot) => Comment.fromDocument(documentSnapshot))
.toList();
});
}

@override
Widget build(BuildContext context) {
return Container();
void initState() {
super.initState();
_onLoadComments();
}

@override
Widget build(BuildContext context) => GestureDetector(
onTap: () => onFocusLost(context),
child: Scaffold(
appBar: _initAppBar(),
body: Stack(
children: <Widget>[
Container(
decoration: const BoxDecoration(
image: DecorationImage(
image: AssetImage('res/images/img_background_2.png'),
fit: BoxFit.cover,
),
),
),
Column(
children: <Widget>[
Expanded(
child: _loadComments(),
),
Container(
alignment: Alignment.bottomCenter,
height: 55.0,
decoration: const BoxDecoration(
gradient: linearAppBar,
),
child: Row(
children: <Widget>[
Expanded(
child: FutureBuilder(
future: usersRef.doc(userId).get(),
builder: (context, dataSnapshot) {
if (!dataSnapshot.hasData) {
return buildCircularProgress();
}

final user = User.fromDocument(dataSnapshot.data);

final userBio = user.userBio!;
final userImage = user.userImage!;
final userName = user.userName!;

return ListTile(
leading: userImage.isNotEmpty
? CircleAvatar(
radius: 20.0,
backgroundImage:
CachedNetworkImageProvider(
userImage),
backgroundColor: colorEerieBlack,
)
: CircleAvatar(
child: Container(
decoration: BoxDecoration(
borderRadius:
BorderRadius.circular(22.0),
gradient: linearProfile,
),
),
),

title: TextField(
controller: _commentContentController,
inputFormatters: [
LengthLimitingTextInputFormatter(1024),
],
style: const TextStyle(color: colorFulvous),
decoration: const InputDecoration(
border: InputBorder.none,
hintText: 'Add a comment...',
hintStyle: TextStyle(
fontFamily: 'Tahoma',
fontSize: 15.0,
color: colorBrightGray,
),
),
textInputAction: TextInputAction.done,
),

trailing: GestureDetector(
onTap: () => _onComment(
context,
userBio,
userImage,
userName,
_commentContentController.text.trim()),
child: SvgPicture.string(
createSendUIButton,
allowDrawingOutsideViewBox: true,
),
),

//
);
},
),
),
],
),
),
],
),
],
),
),
);
}
Loading

0 comments on commit 0e00d30

Please sign in to comment.