[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(comments): like/unlike logic

+13 -37
+2 -25
lib/src/features/comments/providers/comment_provider.dart
··· 32 32 final wasLiked = state.isLiked; 33 33 final currentLikeCount = state.thread.post.likeCount ?? 0; 34 34 final postUri = state.thread.post.uri.toString(); 35 + final originalState = state; 35 36 36 37 try { 37 38 if (wasLiked) { 38 - // Capture the like reference before optimistic update 39 39 final likeUri = state.thread.post.viewer!.like!; 40 40 41 - // Optimistically update UI for unlike 42 41 final updatedPost = switch (state.thread.post) { 43 42 ThreadPostView(:final post) => ThreadPostView( 44 43 post: post.copyWith( ··· 57 56 thread: state.thread.copyWith(post: updatedPost), 58 57 ); 59 58 60 - // Perform the actual unlike using the captured reference 61 59 await _feedRepository.unlikePost(likeUri); 62 - 63 - // Trigger UI updates 64 60 ref.read(postUpdateProvider(postUri).notifier).state++; 65 61 } else { 66 - // Optimistically update UI for like 67 62 final response = await _feedRepository.likePost(state.thread.post.cid, state.thread.post.uri); 68 63 69 64 final updatedPost = switch (state.thread.post) { ··· 84 79 thread: state.thread.copyWith(post: updatedPost), 85 80 ); 86 81 87 - // Trigger UI updates 88 82 ref.read(postUpdateProvider(postUri).notifier).state++; 89 83 } 90 84 } catch (e) { 91 - // Revert optimistic update on error 92 - final revertedPost = switch (state.thread.post) { 93 - ThreadPostView(:final post) => ThreadPostView( 94 - post: post.copyWith( 95 - viewer: wasLiked ? post.viewer?.copyWith(like: post.viewer?.like) : post.viewer?.copyWith(like: null), 96 - likeCount: currentLikeCount, 97 - ), 98 - ), 99 - ThreadReplyView(:final reply) => ThreadReplyView( 100 - reply: reply.copyWith( 101 - viewer: wasLiked ? reply.viewer?.copyWith(like: reply.viewer?.like) : reply.viewer?.copyWith(like: null), 102 - likeCount: currentLikeCount, 103 - ), 104 - ), 105 - }; 106 - state = state.copyWith( 107 - thread: state.thread.copyWith(post: revertedPost), 108 - ); 85 + state = originalState; 109 86 rethrow; 110 87 } 111 88 }
+9 -11
lib/src/features/comments/ui/pages/comments_page.dart
··· 48 48 builder: (context, child) { 49 49 return Transform.translate(offset: Offset(0, height * (1 - _animation.value)), child: child); 50 50 }, 51 - child: SafeArea( 52 - child: Container( 53 - height: height, 54 - decoration: BoxDecoration( 55 - color: backgroundColor, 56 - borderRadius: const BorderRadius.only(topLeft: Radius.circular(12), topRight: Radius.circular(12)), 57 - ), 58 - child: const ClipRRect( 59 - borderRadius: BorderRadius.only(topLeft: Radius.circular(12), topRight: Radius.circular(12)), 60 - child: AutoRouter(), 61 - ), 51 + child: Container( 52 + height: height, 53 + decoration: BoxDecoration( 54 + color: backgroundColor, 55 + borderRadius: const BorderRadius.only(topLeft: Radius.circular(12), topRight: Radius.circular(12)), 56 + ), 57 + child: const ClipRRect( 58 + borderRadius: BorderRadius.only(topLeft: Radius.circular(12), topRight: Radius.circular(12)), 59 + child: SafeArea(child: AutoRouter()), 62 60 ), 63 61 ), 64 62 );
+2 -1
lib/src/features/comments/ui/widgets/comment_item.dart
··· 268 268 269 269 @override 270 270 Widget build(BuildContext context) { 271 - final notifier = ref.read(commentProvider(commentState.thread).notifier); 271 + final notifier = ref.read(commentProvider(widget.thread).notifier); 272 272 return Row( 273 273 children: [ 274 274 TextButton( ··· 276 276 padding: EdgeInsets.zero, 277 277 minimumSize: Size.zero, 278 278 tapTargetSize: MaterialTapTargetSize.shrinkWrap, 279 + splashFactory: NoSplash.splashFactory, 279 280 ), 280 281 onPressed: notifier.toggleLike, 281 282 child: Row(