Main coves client
1import 'package:flutter/material.dart';
2
3import '../constants/app_colors.dart';
4import '../models/post.dart';
5import '../utils/date_time_utils.dart';
6import 'icons/animated_heart_icon.dart';
7
8/// Post Action Bar
9///
10/// Bottom bar with comment input and action buttons (vote, save,
11/// comment count).
12/// Displays:
13/// - Comment input field (opens composer when tapped)
14/// - Heart icon with vote count
15/// - Star icon with save count
16/// - Comment bubble icon with comment count (scrolls to comments when tapped)
17class PostActionBar extends StatelessWidget {
18 const PostActionBar({
19 required this.post,
20 this.onCommentTap,
21 this.onCommentInputTap,
22 this.onCommentCountTap,
23 this.onVoteTap,
24 this.onSaveTap,
25 this.isVoted = false,
26 this.isSaved = false,
27 super.key,
28 });
29
30 final FeedViewPost post;
31
32 /// Deprecated: Use onCommentInputTap and onCommentCountTap instead
33 final VoidCallback? onCommentTap;
34
35 /// Callback when comment input field is tapped (typically opens composer)
36 final VoidCallback? onCommentInputTap;
37
38 /// Callback when comment count button is tapped (typically scrolls to
39 /// comments)
40 final VoidCallback? onCommentCountTap;
41
42 final VoidCallback? onVoteTap;
43 final VoidCallback? onSaveTap;
44 final bool isVoted;
45 final bool isSaved;
46
47 @override
48 Widget build(BuildContext context) {
49 return Container(
50 decoration: const BoxDecoration(
51 color: AppColors.background,
52 border: Border(top: BorderSide(color: AppColors.backgroundSecondary)),
53 ),
54 padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
55 child: SafeArea(
56 top: false,
57 child: Row(
58 children: [
59 // Comment input field
60 Expanded(
61 child: GestureDetector(
62 onTap: onCommentInputTap ?? onCommentTap,
63 child: Container(
64 height: 40,
65 padding: const EdgeInsets.symmetric(horizontal: 12),
66 decoration: const BoxDecoration(
67 color: AppColors.backgroundSecondary,
68 borderRadius: BorderRadius.all(Radius.circular(20)),
69 ),
70 child: Row(
71 children: [
72 Icon(
73 Icons.edit_outlined,
74 size: 16,
75 color: AppColors.textPrimary.withValues(alpha: 0.5),
76 ),
77 const SizedBox(width: 8),
78 Text(
79 'Comment',
80 style: TextStyle(
81 color: AppColors.textPrimary.withValues(alpha: 0.5),
82 fontSize: 14,
83 ),
84 ),
85 ],
86 ),
87 ),
88 ),
89 ),
90 const SizedBox(width: 16),
91
92 // Vote button with animated heart icon
93 GestureDetector(
94 onTap: onVoteTap,
95 child: Row(
96 mainAxisSize: MainAxisSize.min,
97 children: [
98 AnimatedHeartIcon(
99 isLiked: isVoted,
100 color: AppColors.textPrimary.withValues(alpha: 0.7),
101 likedColor: const Color(0xFFFF0033),
102 size: 24,
103 ),
104 const SizedBox(width: 4),
105 Text(
106 DateTimeUtils.formatCount(post.post.stats.score),
107 style: TextStyle(
108 color:
109 isVoted
110 ? const Color(0xFFFF0033)
111 : AppColors.textPrimary.withValues(alpha: 0.7),
112 fontSize: 13,
113 fontWeight: FontWeight.w500,
114 ),
115 ),
116 ],
117 ),
118 ),
119 const SizedBox(width: 16),
120
121 // Save button with count (placeholder for now)
122 _ActionButton(
123 icon: isSaved ? Icons.bookmark : Icons.bookmark_border,
124 count: 0, // TODO: Add save count when backend supports it
125 color: isSaved ? AppColors.primary : null,
126 onTap: onSaveTap,
127 ),
128 const SizedBox(width: 16),
129
130 // Comment count button
131 _ActionButton(
132 icon: Icons.chat_bubble_outline,
133 count: post.post.stats.commentCount,
134 onTap: onCommentCountTap ?? onCommentTap,
135 ),
136 ],
137 ),
138 ),
139 );
140 }
141}
142
143/// Action button with icon and count
144class _ActionButton extends StatelessWidget {
145 const _ActionButton({
146 required this.icon,
147 required this.count,
148 this.color,
149 this.onTap,
150 });
151
152 final IconData icon;
153 final int count;
154 final Color? color;
155 final VoidCallback? onTap;
156
157 @override
158 Widget build(BuildContext context) {
159 final effectiveColor =
160 color ?? AppColors.textPrimary.withValues(alpha: 0.7);
161
162 return GestureDetector(
163 onTap: onTap,
164 child: Row(
165 mainAxisSize: MainAxisSize.min,
166 children: [
167 Icon(icon, size: 24, color: effectiveColor),
168 const SizedBox(width: 4),
169 Text(
170 DateTimeUtils.formatCount(count),
171 style: TextStyle(
172 color: effectiveColor,
173 fontSize: 13,
174 fontWeight: FontWeight.w500,
175 ),
176 ),
177 ],
178 ),
179 );
180 }
181}