diff --git a/lib/presentation_layer/components/comments_section.dart b/lib/presentation_layer/components/comments_section.dart index 62195c80..6d182f96 100644 --- a/lib/presentation_layer/components/comments_section.dart +++ b/lib/presentation_layer/components/comments_section.dart @@ -8,72 +8,143 @@ import '../../domain_layer/entities/tree_node.dart'; import '../atoms/rounded_corner_painer.dart'; import 'note_card/note_card.dart'; -class CommentSection extends StatelessWidget { +class CommentSection extends StatefulWidget { final TreeNode commentTree; const CommentSection({super.key, required this.commentTree}); + @override + State createState() => _CommentSectionState(); +} + +class _CommentSectionState extends State { + final repliesExpanded = {}; + @override Widget build(BuildContext context) { return SingleChildScrollView( - child: _buildCommentTree(commentTree, 0), + child: _buildCommentTree(widget.commentTree, 0, []), ); } - Widget _buildCommentTree(TreeNode node, int depth) { + Widget _buildCommentTree( + TreeNode node, + int depth, + List ancestorHasSibling, + ) { + final Color lineColor = Palette.darkGray; + + List childAncestorHasSibling = List.from(ancestorHasSibling); + childAncestorHasSibling.add(node.hasSiblings); + return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Padding( - padding: EdgeInsets.only(left: depth * 36.0), - child: Stack( - clipBehavior: Clip.none, - children: [ - // Rounded corner connecting horizontal and vertical lines - if (node.hasParent) + Stack( + clipBehavior: Clip.none, + children: [ + // for loop + for (int i = 0; i < depth; i++) + if (ancestorHasSibling[i]) Positioned( - left: -25.0, - top: 0.0, - child: Column( - children: [ - Container( - width: 2.0, - height: 60.0, - color: Palette.gray, - ), - Padding( - padding: EdgeInsets.only(left: 15.0), - child: CustomPaint( - size: Size(15.0, 15.0), - painter: RoundedCornerPainter( - color: Palette.gray, - ), - ), - ), - ], - ), - ), - - if (node.hasChildren) - Positioned( - left: 25.0, - top: 50, + left: 1.0 * i, + top: 0, bottom: 0, child: Container( width: 2.0, - height: 120, - color: Palette.gray, + height: 60, + color: Palette.purple, ), ), - NoteCardContainer( - key: ValueKey(node.value.id), - note: node.value, + Padding( + padding: EdgeInsets.only(left: depth * 16.0), + child: Stack( + clipBehavior: Clip.none, + children: [ + // Rounded corner connecting horizontal and vertical lines + if (node.hasParent) + Positioned( + left: -15.0, + top: 0.0, + child: Column( + children: [ + Container( + width: 2.0, + height: 60.0, + color: lineColor, + ), + Padding( + padding: EdgeInsets.only(left: 10.0), + child: CustomPaint( + size: Size(10.0, 10.0), + painter: RoundedCornerPainter( + color: lineColor, + ), + ), + ), + ], + ), + ), + + if (node.hasChildren) + Positioned( + left: 10.0, + top: 60, + bottom: 0, + child: Container( + width: 2.0, + height: 60, + color: lineColor, + ), + ), + + NoteCardContainer( + key: ValueKey(node.value.id), + note: node.value, + ), + if (node.hasChildren) + // expand replies + Positioned( + left: 0.0, + //top: 60, + bottom: 20, + child: GestureDetector( + onTap: () { + setState(() { + repliesExpanded[node.value.id] = + !(repliesExpanded[node.value.id] ?? false); + }); + }, + child: Container( + padding: const EdgeInsets.all(4.0), + decoration: BoxDecoration( + color: Palette.purple, + borderRadius: BorderRadius.circular(4.0), + ), + child: Text( + repliesExpanded[node.value.id] ?? false + ? "Collapse" + : "Expand", + style: TextStyle( + color: Palette.white, + fontSize: 12.0, + ), + ), + ), + ), + ), + ], ), - ], - ), + ), + ], ), - ...node.children.map((child) => _buildCommentTree(child, depth + 1)), + if (repliesExpanded[node.value.id] ?? false) + ...node.children.map((child) => _buildCommentTree( + child, + depth + 1, + childAncestorHasSibling, + )), ], ); } diff --git a/lib/presentation_layer/components/note_card/note_card_container.dart b/lib/presentation_layer/components/note_card/note_card_container.dart index b697b7f4..37e5e098 100644 --- a/lib/presentation_layer/components/note_card/note_card_container.dart +++ b/lib/presentation_layer/components/note_card/note_card_container.dart @@ -81,30 +81,30 @@ class _NoteCardContainerState extends ConsumerState { @override Widget build(BuildContext context) { final note = widget.note; - return Container( - padding: const EdgeInsets.only(top: 10), - child: Column( - children: [ - // check if reply - if (note.getTagEvents.isNotEmpty) - // for myNote.getTagPubkeys - InReplyTo( + return Column( + children: [ + // check if reply + if (note.getTagEvents.isNotEmpty) + // for myNote.getTagPubkeys + Padding( + padding: const EdgeInsets.only(left: 15.0), + child: InReplyTo( key: ValueKey('in-reply-to-${note.id}'), myNote: note, ), + ), - GestureDetector( - onTap: () { - _onNoteTab(context, note); - }, - child: NoteCard( - note: note, - myMetadata: myUserNoteMetadata, - key: ValueKey('note-${note.id}'), - ), + GestureDetector( + onTap: () { + _onNoteTab(context, note); + }, + child: NoteCard( + note: note, + myMetadata: myUserNoteMetadata, + key: ValueKey('note-${note.id}'), ), - ], - ), + ), + ], ); } }