[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.

make user clickable on comments (#36)

authored by

Davi Rodrigues and committed by
GitHub
dc1e6b49 544ec55b

+58 -9
+24 -7
lib/widgets/comments/comment_item.dart
··· 1 1 import 'package:cached_network_image/cached_network_image.dart'; 2 2 import 'package:fluentui_system_icons/fluentui_system_icons.dart'; 3 3 import 'package:flutter/material.dart'; 4 - import 'package:sparksocial/widgets/common/user_avatar.dart'; 5 - import 'package:sparksocial/widgets/dialogs/report_dialog.dart'; 6 4 import 'package:provider/provider.dart'; 7 - import 'package:sparksocial/services/mod_service.dart'; 5 + import 'package:sparksocial/services/actions_service.dart'; 8 6 import 'package:sparksocial/services/auth_service.dart'; 7 + import 'package:sparksocial/services/mod_service.dart'; 8 + import 'package:sparksocial/widgets/common/user_avatar.dart'; 9 + import 'package:sparksocial/widgets/dialogs/report_dialog.dart'; 9 10 import 'package:video_player/video_player.dart'; 10 - import 'package:sparksocial/services/actions_service.dart'; 11 11 12 12 import '../../models/comment.dart'; 13 13 import '../../utils/app_colors.dart'; 14 + import '../action_buttons/menu_action_button.dart'; 14 15 import '../image/image_carousel.dart'; 15 16 import 'comment_reply_item.dart'; 16 - import '../action_buttons/menu_action_button.dart'; 17 17 18 18 class CommentItem extends StatefulWidget { 19 19 final String id; ··· 37 37 final bool isLiked; 38 38 final VoidCallback? onLikePressed; 39 39 final VoidCallback? onDeleted; 40 + final Function(String)? onUsernameTap; 40 41 41 42 const CommentItem({ 42 43 super.key, ··· 61 62 this.isLiked = false, 62 63 this.onLikePressed, 63 64 this.onDeleted, 65 + this.onUsernameTap, 64 66 }); 65 67 66 68 @override ··· 276 278 child: Row( 277 279 crossAxisAlignment: CrossAxisAlignment.start, 278 280 children: [ 279 - _buildAvatar(), 281 + GestureDetector( 282 + onTap: () { 283 + if (widget.onUsernameTap != null) { 284 + widget.onUsernameTap!(widget.authorDid); 285 + } 286 + }, 287 + child: _buildAvatar(), 288 + ), 280 289 const SizedBox(width: 12), 281 290 Expanded(child: _buildCommentContent(textColor, secondaryTextColor)), 282 291 ], ··· 313 322 Expanded( 314 323 child: Row( 315 324 children: [ 316 - Text(widget.username, style: TextStyle(fontWeight: FontWeight.bold, color: textColor)), 325 + GestureDetector( 326 + onTap: () { 327 + if (widget.onUsernameTap != null) { 328 + widget.onUsernameTap!(widget.authorDid); 329 + } 330 + }, 331 + child: Text(widget.username, style: TextStyle(fontWeight: FontWeight.bold, color: textColor)), 332 + ), 317 333 const SizedBox(width: 8), 318 334 Text(widget.timeAgo, style: TextStyle(fontSize: 12, color: secondaryTextColor)), 319 335 ], ··· 445 461 isDarkMode: widget.isDarkMode, 446 462 onReply: widget.onReply, 447 463 profileImageUrl: reply.profileImageUrl, 464 + onUsernameTap: widget.onUsernameTap, 448 465 ), 449 466 ), 450 467 ],
+22 -2
lib/widgets/comments/comment_reply_item.dart
··· 14 14 final bool isDarkMode; 15 15 final Function(String, String) onReply; 16 16 final String? profileImageUrl; 17 + final Function(String)? onUsernameTap; 17 18 18 19 const CommentReplyItem({ 19 20 super.key, ··· 26 27 required this.isDarkMode, 27 28 required this.onReply, 28 29 this.profileImageUrl, 30 + this.onUsernameTap, 29 31 }); 30 32 31 33 @override ··· 51 53 child: Row( 52 54 crossAxisAlignment: CrossAxisAlignment.start, 53 55 mainAxisAlignment: MainAxisAlignment.start, 54 - children: [_buildAvatar(), const SizedBox(width: 8), Expanded(child: _buildReplyContent(textColor, secondaryTextColor))], 56 + children: [ 57 + GestureDetector( 58 + onTap: () { 59 + if (widget.onUsernameTap != null) { 60 + widget.onUsernameTap!(widget.userId); 61 + } 62 + }, 63 + child: _buildAvatar(), 64 + ), 65 + const SizedBox(width: 8), 66 + Expanded(child: _buildReplyContent(textColor, secondaryTextColor)), 67 + ], 55 68 ), 56 69 ); 57 70 } ··· 83 96 Row( 84 97 crossAxisAlignment: CrossAxisAlignment.center, 85 98 children: [ 86 - Text(widget.username, style: TextStyle(fontWeight: FontWeight.bold, color: textColor, fontSize: 13)), 99 + GestureDetector( 100 + onTap: () { 101 + if (widget.onUsernameTap != null) { 102 + widget.onUsernameTap!(widget.userId); 103 + } 104 + }, 105 + child: Text(widget.username, style: TextStyle(fontWeight: FontWeight.bold, color: textColor, fontSize: 13)), 106 + ), 87 107 const SizedBox(width: 6), 88 108 Text(widget.timeAgo, style: TextStyle(fontSize: 11, color: secondaryTextColor)), 89 109 ],
+12
lib/widgets/comments/comments_tray.dart
··· 3 3 import 'package:provider/provider.dart'; 4 4 5 5 import '../../models/comment.dart'; 6 + import '../../screens/profile_screen.dart'; 6 7 import '../../services/comments_service.dart'; 7 8 import '../../services/actions_service.dart'; 8 9 import '../../utils/app_colors.dart'; ··· 369 370 } 370 371 } 371 372 373 + void _navigateToUserProfile(String did) { 374 + if (!mounted) return; 375 + 376 + Navigator.push(context, MaterialPageRoute(builder: (_) => ProfileScreen(did: did))).catchError((error) { 377 + if (!mounted) return; 378 + ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text('Could not load profile: ${error.toString()}'))); 379 + return null; 380 + }); 381 + } 382 + 372 383 @override 373 384 Widget build(BuildContext context) { 374 385 final height = MediaQuery.of(context).size.height * 0.75; ··· 535 546 isLiked: comment.isLiked, 536 547 onLikePressed: () => _handleLike(comment), 537 548 onDeleted: () => _handleCommentDeleted(comment.id), 549 + onUsernameTap: _navigateToUserProfile, 538 550 ); 539 551 }, 540 552 );