[READ ONLY MIRROR] Open Source TikTok alternative built on AT Protocol github.com/sprksocial/client
flutter atproto video dart
10
fork

Configure Feed

Select the types of activity you want to include in your feed.

fix: non-root replies root field

+65 -37
+65 -37
lib/src/features/comments/ui/pages/replies_page.dart
··· 58 58 } 59 59 } 60 60 61 + /// Extracts the thread root URI and CID from the reply record. 62 + /// Returns null if the thread post is a root post (not a reply). 63 + ({String uri, String cid})? _getThreadRoot(ThreadViewPost thread) { 64 + final post = thread.post; 65 + if (post is ThreadReplyView) { 66 + final record = post.reply.record; 67 + if (record is Map<String, dynamic>) { 68 + final reply = record['reply'] as Map<String, dynamic>?; 69 + if (reply != null) { 70 + final root = reply['root'] as Map<String, dynamic>?; 71 + if (root != null) { 72 + final uri = root['uri'] as String?; 73 + final cid = root['cid'] as String?; 74 + if (uri != null && cid != null) { 75 + return (uri: uri, cid: cid); 76 + } 77 + } 78 + } 79 + } 80 + } 81 + return null; 82 + } 83 + 61 84 @override 62 85 Widget build(BuildContext context) { 63 86 final l10n = AppLocalizations.of(context); ··· 80 103 leading: AppLeadingButton(color: textColor), 81 104 ), 82 105 body: state.when( 83 - data: (data) => SafeArea( 84 - child: Column( 85 - children: [ 86 - if (data.thread.parent is ThreadViewPost) 87 - CommentItem( 88 - key: ValueKey( 89 - 'comment-' 90 - '${(data.thread.parent! as ThreadViewPost).post.uri}', 106 + data: (data) { 107 + final threadRoot = _getThreadRoot(data.thread); 108 + return SafeArea( 109 + child: Column( 110 + children: [ 111 + if (data.thread.parent is ThreadViewPost) 112 + CommentItem( 113 + key: ValueKey( 114 + 'comment-' 115 + '${(data.thread.parent! as ThreadViewPost).post.uri}', 116 + ), 117 + thread: data.thread.parent! as ThreadViewPost, 118 + mainPostUri: AtUri.parse(widget.postUri), 91 119 ), 92 - thread: data.thread.parent! as ThreadViewPost, 93 - mainPostUri: AtUri.parse(widget.postUri), 94 - ), 95 - Expanded( 96 - child: ListView.builder( 97 - controller: _scrollController, 98 - padding: EdgeInsets.only( 99 - bottom: 16 + (keyboardHeight > 0 ? 0 : 80), 120 + Expanded( 121 + child: ListView.builder( 122 + controller: _scrollController, 123 + padding: EdgeInsets.only( 124 + bottom: 16 + (keyboardHeight > 0 ? 0 : 80), 125 + ), 126 + itemCount: data.thread.replies?.length ?? 0, 127 + itemBuilder: (context, index) { 128 + final comment = 129 + data.thread.replies![index] as ThreadViewPost; 130 + return CommentItem( 131 + key: ValueKey('comment-${comment.post.cid}'), 132 + thread: comment, 133 + mainPostUri: AtUri.parse(widget.postUri), 134 + ); 135 + }, 100 136 ), 101 - itemCount: data.thread.replies?.length ?? 0, 102 - itemBuilder: (context, index) { 103 - final comment = 104 - data.thread.replies![index] as ThreadViewPost; 105 - return CommentItem( 106 - key: ValueKey('comment-${comment.post.cid}'), 107 - thread: comment, 108 - mainPostUri: AtUri.parse(widget.postUri), 109 - ); 110 - }, 137 + ), 138 + CommentInputWidget( 139 + videoId: widget.postUri, 140 + postUri: widget.postUri, 141 + isSprk: data.thread.post.isSprk, 142 + focusNode: _focusNode, 143 + postCid: data.thread.post.cid, 144 + rootUri: threadRoot?.uri, 145 + rootCid: threadRoot?.cid, 111 146 ), 112 - ), 113 - CommentInputWidget( 114 - videoId: widget.postUri, 115 - postUri: widget.postUri, 116 - isSprk: data.thread.post.isSprk, 117 - focusNode: _focusNode, 118 - postCid: data.thread.post.cid, 119 - ), 120 - ], 121 - ), 122 - ), 147 + ], 148 + ), 149 + ); 150 + }, 123 151 error: (error, stackTrace) => 124 152 Center(child: Text(l10n.errorWithDetail(error.toString()))), 125 153 loading: () => const Center(child: CircularProgressIndicator()),