How to implement 1 deep level comment and reply structure

Viewed 47

I am trying to implement a comment and reply feature under 1 level. Just like every other social media apps with comments and reply. I am having problem in laying out comments reply. I created a listview builder for getting the parent comments of a post. Each comments have its own ID (commentId). I am finding it difficult to show the replies of each comments accordingly under it's parents comment.

What i am trying to do:

I get user comment from api and show it on the UI. under the comment, I want to show the replies of every comment.

This is what i have tried:

Comment page for showing the comment using getx state management

class CommentWidget extends StatelessWidget {
  CommentWidget({Key? key, required this.postId}) : super(key: key);

  final String postId;

  final isShowReply = false.obs;

  @override
  Widget build(BuildContext context) {
    return GetBuilder<CommentPaginationController>(
      init: CommentPaginationController(
        pId: postId,
      ),
      builder: (controller) {
        return controller.isFetchingComment.value
            ? Center(
                child: SizedBox(
                  width: MediaQuery.of(context).size.width - 200,
                  child: LinearProgressIndicator(
                    backgroundColor: AppColors.backgroundColor,
                    valueColor: AlwaysStoppedAnimation<Color?>(
                      AppColors.secondaryColor,
                    ),
                  ),
                ),
              )
            : controller.commentsModel.isNotEmpty
                ? ListView.builder(
                    // reverse: true,
                    controller: controller.scrollController,
                    shrinkWrap: true,
                    itemCount: controller.commentsModel.length + 1,
                    itemBuilder: (context, index) {
                      if (index < controller.commentsModel.length) {
                        final comment = controller.commentsModel[index];
                        return Column(
                          crossAxisAlignment: CrossAxisAlignment.start,
                          children: [
                            // Build comment widget
                            const SizedBox(height: 10.0),
                            CommentHeaderWidget(
                              commentsModel: comment,
                              headerPadding: const EdgeInsets.fromLTRB(
                                  14.0, 0.0, 14.0, 0.0),
                              radius: 26.0,
                              iconSize: 22,
                              headerSize: 14,
                            ),
                            // Build reply widget
                          controller.commentsModel[index].nrComments != 0
                                ? ReplyWidget(commentsModel: comment)
                                : const SizedBox()
                          ],
                        );
                      } else if (controller.isLoadingMore.value == true) {
                        return const Center(
                          child: LoadingAnimation(
                            height: 16.0,
                            width: 16.0,
                          ),
                        );
                      } else {
                        return const SizedBox();
                      }
                    },
                  )
                : Padding(
                    padding: const EdgeInsets.all(8.0),
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      mainAxisAlignment: MainAxisAlignment.center,
                      children: [
                        NoUPdateWidget(
                          title: 'No comments yet',
                          content:
                              'Be the first to add a comment on this post.',
                          action: Icon(
                            FluentIcons.comment_off_24_regular,
                            size: 50.0,
                            color: AppColors.secondaryColor,
                          ),
                        ),
                      ],
                    ),
                  );
      },
    );
  }
}

State management code for getting comment details from api

class CommentPaginationController extends GetxController {
  CommentPaginationController({required this.pId});
  final String pId;

  final _postService = UserPostService();
  final scrollController = ScrollController();

  List<GetCommentsModel> commentsModel = [];
  RxBool isLoadingMore = false.obs;
  RxBool hasMoreItems = true.obs;
  RxBool isFetchingComment = false.obs;
  RxInt offset = 0.obs;
  RxInt maxCount = 12.obs;

  Future<void> loadInitialItem() async {
    isFetchingComment.value = true;
    try {
      final value = await _postService.getComments(
        GetCommentsModel(
          pId: pId,
          offset: offset.value,
          maxCount: maxCount.value,
        ),
      );
      isFetchingComment.value = false;
      if (value.isNotEmpty) {
        offset.value++;
        commentsModel = value;
        isFetchingComment.value = false;
      }
    } catch (e) {
      isFetchingComment.value = false;
    }
    update();
  }

  Future<void> loadMore() async {
    if (hasMoreItems.value == true &&
        isFetchingComment.value == false &&
        isLoadingMore.value == false) {
      isLoadingMore.value = true;
      try {
        final posts = await _postService.getComments(
          GetCommentsModel(
              pId: pId, offset: offset.value, maxCount: maxCount.value),
        );
        if (posts.isNotEmpty) {
          offset.value++;
          commentsModel.addAll(posts);
        } else {
          hasMoreItems.value = false;
        }
      } catch (e) {
        isLoadingMore.value = false;
      }
      isLoadingMore.value = false;
    }
    update();
  }

  @override
  void onInit() {
    loadInitialItem();
    scrollController.addListener(() {
      if (scrollController.position.minScrollExtent ==
          scrollController.offset) {
        loadMore();
      }
    });
    super.onInit();
  }

  @override
  void onClose() {
    scrollController.removeListener(() {});
    super.onClose();
  }
}

I can successfully get the comments and it's details using pagination. I am wondering how to get the reply of the comments and display them under their parent comments.

0 Answers
Related