···
1
+
import 'package:flutter/foundation.dart';
2
+
import 'package:flutter/material.dart';
3
+
import 'package:flutter/services.dart';
4
+
import 'package:provider/provider.dart';
6
+
import '../constants/app_colors.dart';
7
+
import '../models/post.dart';
8
+
import '../providers/auth_provider.dart';
9
+
import '../providers/vote_provider.dart';
10
+
import '../utils/date_time_utils.dart';
11
+
import 'icons/animated_heart_icon.dart';
12
+
import 'icons/reply_icon.dart';
13
+
import 'icons/share_icon.dart';
14
+
import 'sign_in_dialog.dart';
16
+
/// Action buttons row for post cards
18
+
/// Displays menu, share, comment, and like buttons with proper
19
+
/// authentication handling and optimistic updates.
20
+
class PostCardActions extends StatelessWidget {
21
+
const PostCardActions({required this.post, super.key});
23
+
final FeedViewPost post;
26
+
Widget build(BuildContext context) {
28
+
mainAxisAlignment: MainAxisAlignment.spaceBetween,
30
+
// Left side: Three dots menu and share
32
+
mainAxisSize: MainAxisSize.min,
34
+
// Three dots menu button
37
+
label: 'Post options menu',
40
+
// TODO: Show post options menu
42
+
debugPrint('Menu button tapped for post');
46
+
padding: const EdgeInsets.symmetric(
53
+
color: AppColors.textPrimary.withValues(alpha: 0.6),
62
+
label: 'Share post',
65
+
// TODO: Handle share interaction with backend
67
+
debugPrint('Share button tapped for post');
71
+
padding: const EdgeInsets.symmetric(
76
+
color: AppColors.textPrimary.withValues(alpha: 0.6),
84
+
// Right side: Comment and heart
86
+
mainAxisSize: MainAxisSize.min,
92
+
'View ${post.post.stats.commentCount} ${post.post.stats.commentCount == 1 ? "comment" : "comments"}',
95
+
// TODO: Navigate to post detail/comments screen
97
+
debugPrint('Comment button tapped for post');
101
+
padding: const EdgeInsets.symmetric(
106
+
mainAxisSize: MainAxisSize.min,
109
+
color: AppColors.textPrimary.withValues(alpha: 0.6),
111
+
const SizedBox(width: 5),
113
+
DateTimeUtils.formatCount(post.post.stats.commentCount),
115
+
color: AppColors.textPrimary.withValues(alpha: 0.6),
124
+
const SizedBox(width: 8),
127
+
Consumer<VoteProvider>(
128
+
builder: (context, voteProvider, child) {
129
+
final isLiked = voteProvider.isLiked(post.post.uri);
130
+
final adjustedScore = voteProvider.getAdjustedScore(
132
+
post.post.stats.score,
139
+
? 'Unlike post, $adjustedScore ${adjustedScore == 1 ? "like" : "likes"}'
140
+
: 'Like post, $adjustedScore ${adjustedScore == 1 ? "like" : "likes"}',
143
+
// Check authentication
144
+
final authProvider = context.read<AuthProvider>();
145
+
if (!authProvider.isAuthenticated) {
146
+
// Show sign-in dialog
147
+
final shouldSignIn = await SignInDialog.show(
149
+
message: 'You need to sign in to like posts.',
152
+
if ((shouldSignIn ?? false) && context.mounted) {
153
+
// TODO: Navigate to sign-in screen
155
+
debugPrint('Navigate to sign-in screen');
161
+
// Light haptic feedback on both like and unlike
162
+
await HapticFeedback.lightImpact();
164
+
// Toggle vote with optimistic update
166
+
await voteProvider.toggleVote(
167
+
postUri: post.post.uri,
168
+
postCid: post.post.cid,
170
+
} on Exception catch (e) {
172
+
debugPrint('Failed to toggle vote: $e');
174
+
// TODO: Show error snackbar
178
+
padding: const EdgeInsets.symmetric(
183
+
mainAxisSize: MainAxisSize.min,
187
+
color: AppColors.textPrimary.withValues(alpha: 0.6),
188
+
likedColor: const Color(0xFFFF0033),
190
+
const SizedBox(width: 5),
192
+
DateTimeUtils.formatCount(adjustedScore),
194
+
color: AppColors.textPrimary.withValues(