onufitness_mobile/lib/screens/echoboard/widget/comment_bottomsheet.dart
2026-01-13 11:36:24 +05:30

1155 lines
40 KiB
Dart

// import 'package:flutter/material.dart';
// import 'package:flutter_screenutil/flutter_screenutil.dart';
// import 'package:get/get.dart';
// import 'package:onufitness/constants/color_constant.dart';
// import 'package:onufitness/constants/text_constant.dart';
// import 'package:onufitness/screens/echoboard/controllers/like_comment_controller.dart';
// import 'package:onufitness/screens/echoboard/models/parent_comments_response_model.dart';
// import 'package:shimmer/shimmer.dart';
// import 'package:timeago/timeago.dart' as timeago;
// class CommentBottomSheet extends StatefulWidget {
// final String postId;
// final LikeCommentController controller;
// const CommentBottomSheet({
// super.key,
// required this.postId,
// required this.controller,
// });
// @override
// State<CommentBottomSheet> createState() => _CommentBottomSheetState();
// }
// class _CommentBottomSheetState extends State<CommentBottomSheet> {
// final TextEditingController commentController = TextEditingController();
// final ScrollController scrollController = ScrollController();
// @override
// void initState() {
// super.initState();
// widget.controller.postId.value = widget.postId;
// widget.controller.resetReplyState();
// _loadComments();
// scrollController.addListener(() {
// if (scrollController.position.pixels >=
// scrollController.position.maxScrollExtent - 200) {
// _loadMoreComments();
// }
// });
// }
// Future<void> _loadComments() async {
// await widget.controller.fetchcomments(refresh: true);
// }
// Future<void> _loadMoreComments() async {
// if (!widget.controller.isCommentPaginationLoading.value &&
// widget.controller.hasMoreComments.value) {
// await widget.controller.fetchcomments();
// }
// }
// Future<void> _loadSubComments(int parentCommentId) async {
// await widget.controller.fetchSubComments(parentCommentId);
// }
// void _submitComment() async {
// if (commentController.text.trim().isEmpty) return;
// final String commentText = commentController.text.trim();
// int? parentId;
// if (widget.controller.replyingTo.value != null &&
// widget.controller.parentOfReply.value != null) {
// parentId = widget.controller.parentOfReply.value!.commentId;
// } else if (widget.controller.replyingTo.value != null) {
// parentId = widget.controller.replyingTo.value!.commentId;
// }
// commentController.clear();
// widget.controller.resetReplyState();
// await widget.controller.submitComment(
// postId: widget.postId,
// commentText: commentText,
// parentCommentId: parentId,
// );
// }
// void _startReply(CommentItem comment, {CommentItem? parentComment}) {
// widget.controller.startReply(comment, parentComment);
// commentController.clear();
// FocusScope.of(context).unfocus();
// Future.delayed(const Duration(milliseconds: 100), () {
// if (!mounted) return;
// FocusScope.of(context).requestFocus(FocusNode());
// });
// }
// @override
// Widget build(BuildContext context) {
// return Container(
// decoration: BoxDecoration(
// color: Theme.of(context).scaffoldBackgroundColor,
// borderRadius: const BorderRadius.only(
// topLeft: Radius.circular(20),
// topRight: Radius.circular(20),
// ),
// ),
// child: Column(
// children: [
// _buildHeader(),
// Expanded(
// child: Obx(
// () =>
// widget.controller.isCommentsFetchLoading.value
// ? _buildLoadingShimmer()
// : _buildCommentsList(),
// ),
// ),
// Obx(() => _buildReplyBar()),
// _buildCommentInput(),
// ],
// ),
// );
// }
// Widget _buildHeader() {
// return Container(
// padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
// decoration: BoxDecoration(
// color: Theme.of(context).cardColor,
// borderRadius: const BorderRadius.only(
// topLeft: Radius.circular(20),
// topRight: Radius.circular(20),
// ),
// ),
// child: Row(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
// children: [
// const Text(
// 'Comments',
// style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
// ),
// IconButton(
// icon: const Icon(Icons.close),
// onPressed: () => Navigator.pop(context),
// ),
// ],
// ),
// );
// }
// Widget _buildLoadingShimmer() {
// return ListView.builder(
// padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
// itemCount: 5,
// itemBuilder: (context, index) {
// return Shimmer.fromColors(
// baseColor: Colors.grey[300]!,
// highlightColor: Colors.grey[100]!,
// child: Padding(
// padding: const EdgeInsets.only(bottom: 16),
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// Row(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// Container(
// width: 36,
// height: 36,
// decoration: const BoxDecoration(
// color: Colors.white,
// shape: BoxShape.circle,
// ),
// ),
// const SizedBox(width: 12),
// Expanded(
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// Container(
// width: 120,
// height: 14,
// decoration: BoxDecoration(
// color: Colors.white,
// borderRadius: BorderRadius.circular(2),
// ),
// ),
// const SizedBox(height: 8),
// Container(
// width: double.infinity,
// height: 12,
// decoration: BoxDecoration(
// color: Colors.white,
// borderRadius: BorderRadius.circular(2),
// ),
// ),
// const SizedBox(height: 4),
// Container(
// width: MediaQuery.of(context).size.width * 0.6,
// height: 12,
// decoration: BoxDecoration(
// color: Colors.white,
// borderRadius: BorderRadius.circular(2),
// ),
// ),
// const SizedBox(height: 8),
// Container(
// width: 40,
// height: 10,
// decoration: BoxDecoration(
// color: Colors.white,
// borderRadius: BorderRadius.circular(2),
// ),
// ),
// ],
// ),
// ),
// ],
// ),
// const SizedBox(height: 16),
// const Divider(),
// ],
// ),
// ),
// );
// },
// );
// }
// Widget _buildCommentsList() {
// return Obx(() {
// final comments =
// widget.controller.commentsResponseModel.value.data?.items ?? [];
// if (comments.isEmpty) {
// return const Center(
// child: Text('No comments yet. Be the first to comment!'),
// );
// }
// return ListView.builder(
// controller: scrollController,
// padding: const EdgeInsets.only(bottom: 80),
// itemCount: comments.length + 1,
// itemBuilder: (context, index) {
// if (index == comments.length) {
// if (widget.controller.hasMoreComments.value) {
// return Padding(
// padding: const EdgeInsets.symmetric(vertical: 12),
// child: Center(
// child: ElevatedButton(
// onPressed: _loadMoreComments,
// style: ElevatedButton.styleFrom(
// padding: const EdgeInsets.symmetric(
// horizontal: 16,
// vertical: 8,
// ),
// ),
// child: Obx(
// () =>
// widget.controller.isCommentPaginationLoading.value
// ? const SizedBox(
// height: 20,
// width: 20,
// child: CircularProgressIndicator(
// color: Colors.black,
// ),
// )
// : const Text('See more'),
// ),
// ),
// ),
// );
// } else {
// return const SizedBox.shrink();
// }
// }
// final comment = comments[index];
// return Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// _buildCommentItem(comment, isSubComment: false),
// if ((comment.subComments?.isNotEmpty ?? false) ||
// (comment.totalSubCommentCount ?? 0) > 0)
// Padding(
// padding: const EdgeInsets.only(left: 40),
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// if (comment.subComments != null)
// ...comment.subComments!.map(
// (subComment) => _buildCommentItem(
// subComment,
// isSubComment: true,
// parentComment: comment,
// ),
// ),
// if ((comment.totalSubCommentCount ?? 0) >
// (comment.subComments?.length ?? 0))
// InkWell(
// onTap: () => _loadSubComments(comment.commentId!),
// child: Padding(
// padding: const EdgeInsets.symmetric(vertical: 8),
// child: Row(
// children: [
// Obx(
// () =>
// widget.controller.loadingSubCommentIds
// .contains(comment.commentId)
// ? const SizedBox(
// width: 16,
// height: 16,
// child: CircularProgressIndicator(
// strokeWidth: 2,
// valueColor:
// AlwaysStoppedAnimation<Color>(
// Colors.grey,
// ),
// ),
// )
// : const Icon(
// Icons.forum_outlined,
// size: 14,
// color: Colors.grey,
// ),
// ),
// const SizedBox(width: 4),
// Text(
// 'View ${(comment.totalSubCommentCount ?? 0) - (comment.subComments?.length ?? 0)} more ${((comment.totalSubCommentCount ?? 0) - (comment.subComments?.length ?? 0)) == 1 ? 'reply' : 'replies'}',
// style: TextStyle(
// fontSize: verySmallSizeText,
// color: Color(primaryColor),
// ),
// ),
// ],
// ),
// ),
// ),
// ],
// ),
// ),
// const Divider(),
// ],
// );
// },
// );
// });
// }
// Widget _buildCommentItem(
// CommentItem comment, {
// required bool isSubComment,
// CommentItem? parentComment,
// }) {
// return Padding(
// padding: EdgeInsets.only(
// left: isSubComment ? 16 : 8,
// right: 8,
// top: 8,
// bottom: 4,
// ),
// child: Row(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// if (isSubComment)
// const Padding(
// padding: EdgeInsets.only(right: 8),
// child: Icon(
// Icons.subdirectory_arrow_right,
// size: 16,
// color: Colors.grey,
// ),
// ),
// CircleAvatar(
// radius: 18,
// backgroundColor: Colors.grey.shade300,
// child:
// (comment.profilePicture != null &&
// comment.profilePicture!.isNotEmpty)
// ? ClipOval(
// child: Image.network(
// comment.profilePicture!,
// fit: BoxFit.cover,
// width: 36,
// height: 36,
// errorBuilder: (context, error, stackTrace) {
// return const Icon(Icons.person, color: Colors.white);
// },
// ),
// )
// : const Icon(Icons.person, color: Colors.white),
// ),
// const SizedBox(width: 12),
// Expanded(
// child: Column(
// crossAxisAlignment: CrossAxisAlignment.start,
// children: [
// Row(
// children: [
// Text(
// comment.fullName ?? 'Unknown User',
// style: const TextStyle(
// fontWeight: FontWeight.bold,
// fontSize: 14,
// ),
// ),
// const SizedBox(width: 8),
// Text(
// comment.createdAt != null
// ? timeago.format(comment.createdAt!)
// : '',
// style: TextStyle(fontSize: 12, color: Colors.grey[600]),
// ),
// ],
// ),
// const SizedBox(height: 4),
// Text(
// comment.commentText ?? '',
// style: const TextStyle(fontSize: 14),
// ),
// const SizedBox(height: 4),
// GestureDetector(
// onTap:
// () => _startReply(comment, parentComment: parentComment),
// child: Text(
// 'Reply',
// style: TextStyle(
// fontSize: 12.sp,
// fontWeight: FontWeight.w500,
// color: Theme.of(context).primaryColor,
// ),
// ),
// ),
// ],
// ),
// ),
// ],
// ),
// );
// }
// Widget _buildReplyBar() {
// if (widget.controller.replyingTo.value == null) {
// return const SizedBox.shrink();
// }
// return Container(
// padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
// color: Colors.grey.shade200,
// child: Row(
// children: [
// const Icon(Icons.reply, size: 16),
// const SizedBox(width: 8),
// Expanded(
// child: Text(
// 'Replying to ${widget.controller.replyingTo.value!.fullName}',
// style: const TextStyle(fontWeight: FontWeight.w500),
// maxLines: 1,
// overflow: TextOverflow.ellipsis,
// ),
// ),
// IconButton(
// icon: const Icon(Icons.close, size: 16),
// onPressed: () => widget.controller.resetReplyState(),
// padding: EdgeInsets.zero,
// constraints: const BoxConstraints(),
// ),
// ],
// ),
// );
// }
// Widget _buildCommentInput() {
// return Padding(
// padding: EdgeInsets.only(
// left: 16,
// right: 16,
// bottom: 12 + MediaQuery.of(context).viewInsets.bottom,
// ),
// child: Container(
// height: 56,
// decoration: BoxDecoration(
// color: Colors.white,
// borderRadius: BorderRadius.circular(30),
// border: Border.all(color: Colors.grey.shade300),
// ),
// child: Row(
// children: [
// const SizedBox(width: 16),
// Expanded(
// child: TextField(
// controller: commentController,
// maxLines: 3,
// minLines: 1,
// decoration: const InputDecoration(
// hintText: 'Add a comment...',
// border: InputBorder.none,
// ),
// style: const TextStyle(fontSize: 16),
// textCapitalization: TextCapitalization.sentences,
// ),
// ),
// Container(
// width: 1,
// height: 28,
// color: Colors.grey.shade300,
// margin: const EdgeInsets.symmetric(horizontal: 10),
// ),
// Container(
// margin: const EdgeInsets.only(right: 10),
// width: 40,
// height: 40,
// decoration: BoxDecoration(
// color: yellowColor,
// shape: BoxShape.circle,
// ),
// child: IconButton(
// icon: const Icon(Icons.send, size: 20, color: Colors.black),
// onPressed: _submitComment,
// splashRadius: 22,
// ),
// ),
// ],
// ),
// ),
// );
// }
// @override
// void dispose() {
// commentController.dispose();
// scrollController.dispose();
// super.dispose();
// }
// }
// void showCommentsBottomSheet(
// BuildContext context,
// String postId,
// LikeCommentController controller,
// ) {
// showModalBottomSheet(
// context: context,
// isScrollControlled: true,
// backgroundColor: Colors.transparent,
// builder:
// (context) => SafeArea(
// bottom: true,
// child: DraggableScrollableSheet(
// initialChildSize: 0.9,
// minChildSize: 0.5,
// maxChildSize: 0.95,
// builder:
// (context, scrollController) =>
// CommentBottomSheet(postId: postId, controller: controller),
// ),
// ),
// );
// }
//......................................................................................................................................................
//.. Above one is with sub comments "Reply" button...........................................................................
//......................................................................................................................................................
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:onufitness/constants/color_constant.dart';
import 'package:onufitness/constants/text_constant.dart';
import 'package:onufitness/screens/echoboard/controllers/like_comment_controller.dart';
import 'package:onufitness/screens/echoboard/models/parent_comments_response_model.dart';
import 'package:shimmer/shimmer.dart';
import 'package:timeago/timeago.dart' as timeago;
class CommentBottomSheet extends StatefulWidget {
final String postId;
final LikeCommentController controller;
const CommentBottomSheet({
super.key,
required this.postId,
required this.controller,
});
@override
State<CommentBottomSheet> createState() => _CommentBottomSheetState();
}
class _CommentBottomSheetState extends State<CommentBottomSheet> {
final TextEditingController commentController = TextEditingController();
final ScrollController scrollController = ScrollController();
@override
void initState() {
super.initState();
widget.controller.postId.value = widget.postId;
widget.controller.resetReplyState();
_loadComments();
scrollController.addListener(() {
if (scrollController.position.pixels >=
scrollController.position.maxScrollExtent - 200) {
_loadMoreComments();
}
});
}
Future<void> _loadComments() async {
await widget.controller.fetchcomments(refresh: true);
}
Future<void> _loadMoreComments() async {
if (!widget.controller.isCommentPaginationLoading.value &&
widget.controller.hasMoreComments.value) {
await widget.controller.fetchcomments();
}
}
Future<void> _loadSubComments(int parentCommentId) async {
await widget.controller.fetchSubComments(parentCommentId);
}
void _submitComment() async {
if (commentController.text.trim().isEmpty) return;
final String commentText = commentController.text.trim();
int? parentId;
if (widget.controller.replyingTo.value != null &&
widget.controller.parentOfReply.value != null) {
parentId = widget.controller.parentOfReply.value!.commentId;
} else if (widget.controller.replyingTo.value != null) {
parentId = widget.controller.replyingTo.value!.commentId;
}
commentController.clear();
widget.controller.resetReplyState();
await widget.controller.submitComment(
postId: widget.postId,
commentText: commentText,
parentCommentId: parentId,
);
}
void _startReply(CommentItem comment, {CommentItem? parentComment}) {
widget.controller.startReply(comment, parentComment);
commentController.clear();
FocusScope.of(context).unfocus();
Future.delayed(const Duration(milliseconds: 100), () {
if (!mounted) return;
FocusScope.of(context).requestFocus(FocusNode());
});
}
@override
Widget build(BuildContext context) {
return Container(
decoration: BoxDecoration(
color: Theme.of(context).scaffoldBackgroundColor,
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(20),
topRight: Radius.circular(20),
),
),
child: Column(
children: [
_buildHeader(),
Expanded(
child: Obx(
() =>
widget.controller.isCommentsFetchLoading.value
? _buildLoadingShimmer()
: _buildCommentsList(),
),
),
Obx(() => _buildReplyBar()),
_buildCommentInput(),
Container(
padding: EdgeInsetsDirectional.only(
bottom: MediaQuery.of(context).viewPadding.bottom,
),
color: Colors.white,
),
],
),
);
}
Widget _buildHeader() {
return Container(
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
decoration: BoxDecoration(
color: Theme.of(context).cardColor,
borderRadius: const BorderRadius.only(
topLeft: Radius.circular(20),
topRight: Radius.circular(20),
),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text(
'Comments',
style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
),
IconButton(
icon: const Icon(Icons.close),
onPressed: () => Navigator.pop(context),
),
],
),
);
}
Widget _buildLoadingShimmer() {
return ListView.builder(
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
itemCount: 5,
itemBuilder: (context, index) {
return Shimmer.fromColors(
baseColor: Colors.grey[300]!,
highlightColor: Colors.grey[100]!,
child: Padding(
padding: const EdgeInsets.only(bottom: 16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: 36,
height: 36,
decoration: const BoxDecoration(
color: Colors.white,
shape: BoxShape.circle,
),
),
const SizedBox(width: 12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: 120,
height: 14,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(2),
),
),
const SizedBox(height: 8),
Container(
width: double.infinity,
height: 12,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(2),
),
),
const SizedBox(height: 4),
Container(
width: MediaQuery.of(context).size.width * 0.6,
height: 12,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(2),
),
),
const SizedBox(height: 8),
Container(
width: 40,
height: 10,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(2),
),
),
],
),
),
],
),
const SizedBox(height: 16),
Divider(),
],
),
),
);
},
);
}
Widget _buildCommentsList() {
return Obx(() {
final comments =
widget.controller.commentsResponseModel.value.data?.items ?? [];
if (comments.isEmpty) {
return const Center(
child: Text('No comments yet. Be the first to comment!'),
);
}
return ListView.builder(
controller: scrollController,
padding: const EdgeInsets.only(bottom: 80),
itemCount: comments.length + 1,
itemBuilder: (context, index) {
if (index == comments.length) {
if (widget.controller.hasMoreComments.value) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 12),
child: Center(
child: ElevatedButton(
onPressed: _loadMoreComments,
style: ElevatedButton.styleFrom(
padding: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 8,
),
),
child: Obx(
() =>
widget.controller.isCommentPaginationLoading.value
? const SizedBox(
height: 20,
width: 20,
child: CircularProgressIndicator(
color: Colors.black,
),
)
: const Text('See more'),
),
),
),
);
} else {
return const SizedBox.shrink();
}
}
final comment = comments[index];
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_buildCommentItem(comment, isSubComment: false),
if ((comment.subComments?.isNotEmpty ?? false) ||
(comment.totalSubCommentCount ?? 0) > 0)
Padding(
padding: const EdgeInsets.only(left: 40),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (comment.subComments != null)
...comment.subComments!.map(
(subComment) => _buildCommentItem(
subComment,
isSubComment: true,
parentComment: comment,
),
),
if ((comment.totalSubCommentCount ?? 0) >
(comment.subComments?.length ?? 0))
InkWell(
onTap: () => _loadSubComments(comment.commentId!),
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 8),
child: Row(
children: [
Obx(
() =>
widget.controller.loadingSubCommentIds
.contains(comment.commentId)
? const SizedBox(
width: 16,
height: 16,
child: CircularProgressIndicator(
strokeWidth: 2,
valueColor:
AlwaysStoppedAnimation<Color>(
Colors.grey,
),
),
)
: const Icon(
Icons.forum_outlined,
size: 14,
color: Colors.grey,
),
),
const SizedBox(width: 4),
Text(
'View ${(comment.totalSubCommentCount ?? 0) - (comment.subComments?.length ?? 0)} more ${((comment.totalSubCommentCount ?? 0) - (comment.subComments?.length ?? 0)) == 1 ? 'reply' : 'replies'}',
style: TextStyle(
fontSize: verySmallSizeText,
color: Color(primaryColor),
),
),
],
),
),
),
],
),
),
const Divider(),
],
);
},
);
});
}
Widget _buildCommentItem(
CommentItem comment, {
required bool isSubComment,
CommentItem? parentComment,
}) {
return Padding(
padding: EdgeInsets.only(
left: isSubComment ? 16 : 8,
right: 8,
top: 8,
bottom: 4,
),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (isSubComment)
const Padding(
padding: EdgeInsets.only(right: 8),
child: Icon(
Icons.subdirectory_arrow_right,
size: 16,
color: Colors.grey,
),
),
CircleAvatar(
radius: 18,
backgroundColor: Colors.grey.shade300,
child:
(comment.profilePicture != null &&
comment.profilePicture!.isNotEmpty)
? ClipOval(
child: Image.network(
comment.profilePicture!,
fit: BoxFit.cover,
width: 36,
height: 36,
errorBuilder: (context, error, stackTrace) {
return const Icon(Icons.person, color: Colors.white);
},
),
)
: const Icon(Icons.person, color: Colors.white),
),
const SizedBox(width: 12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
Text(
comment.fullName ?? 'Unknown User',
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 14,
),
),
const SizedBox(width: 8),
Text(
comment.createdAt != null
? timeago.format(comment.createdAt!)
: '',
style: TextStyle(fontSize: 12, color: Colors.grey[600]),
),
],
),
const SizedBox(height: 4),
Text(
comment.commentText ?? '',
style: const TextStyle(fontSize: 14),
),
const SizedBox(height: 4),
// Only show Reply button for parent comments (not sub-comments)
if (!isSubComment)
GestureDetector(
onTap:
() =>
_startReply(comment, parentComment: parentComment),
child: Text(
'Reply',
style: TextStyle(
fontSize: 12.sp,
fontWeight: FontWeight.w500,
color: Theme.of(context).primaryColor,
),
),
),
],
),
),
],
),
);
}
Widget _buildReplyBar() {
if (widget.controller.replyingTo.value == null) {
return const SizedBox.shrink();
}
return Container(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
color: Colors.grey.shade200,
child: Row(
children: [
const Icon(Icons.reply, size: 16),
const SizedBox(width: 8),
Expanded(
child: Text(
'Replying to ${widget.controller.replyingTo.value!.fullName}',
style: const TextStyle(fontWeight: FontWeight.w500),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
),
IconButton(
icon: const Icon(Icons.close, size: 16),
onPressed: () => widget.controller.resetReplyState(),
padding: EdgeInsets.zero,
constraints: const BoxConstraints(),
),
],
),
);
}
Widget _buildCommentInput() {
return Padding(
padding: EdgeInsets.only(
left: 16,
right: 16,
bottom: 12 + MediaQuery.of(context).viewInsets.bottom,
),
child: Container(
height: 56,
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(30),
border: Border.all(color: Colors.grey.shade300),
),
child: Row(
children: [
const SizedBox(width: 16),
Expanded(
child: TextField(
controller: commentController,
maxLines: 3,
minLines: 1,
decoration: const InputDecoration(
hintText: 'Add a comment...',
border: InputBorder.none,
),
style: const TextStyle(fontSize: 16),
textCapitalization: TextCapitalization.sentences,
),
),
Container(
width: 1,
height: 28,
color: Colors.grey.shade300,
margin: const EdgeInsets.symmetric(horizontal: 10),
),
Container(
margin: const EdgeInsets.only(right: 10),
width: 40,
height: 40,
decoration: BoxDecoration(
color: yellowColor,
shape: BoxShape.circle,
),
child: IconButton(
icon: const Icon(Icons.send, size: 20, color: Colors.black),
onPressed: _submitComment,
splashRadius: 22,
),
),
],
),
),
);
}
@override
void dispose() {
commentController.dispose();
scrollController.dispose();
super.dispose();
}
}
void showCommentsBottomSheet(
BuildContext context,
String postId,
LikeCommentController controller,
) {
SystemChrome.setSystemUIOverlayStyle(
const SystemUiOverlayStyle(
systemNavigationBarColor: Color(0xFFF4F6F8), // your color
systemNavigationBarIconBrightness: Brightness.dark,
),
);
showModalBottomSheet(
context: context,
isScrollControlled: true,
backgroundColor: Colors.transparent,
builder:
(context) => Container(
decoration: BoxDecoration(
color: Colors.transparent,
borderRadius: BorderRadius.vertical(top: Radius.circular(20)),
),
child: DraggableScrollableSheet(
initialChildSize: 0.9,
minChildSize: 0.5,
maxChildSize: 0.95,
builder:
(context, scrollController) =>
CommentBottomSheet(postId: postId, controller: controller),
),
),
);
}