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(
53 top: BorderSide(color: AppColors.backgroundSecondary),
54 ),
55 ),
56 padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
57 child: SafeArea(
58 top: false,
59 child: Row(
60 children: [
61 // Comment input field
62 Expanded(
63 child: GestureDetector(
64 onTap: onCommentInputTap ?? onCommentTap,
65 child: Container(
66 height: 40,
67 padding: const EdgeInsets.symmetric(horizontal: 12),
68 decoration: const BoxDecoration(
69 color: AppColors.backgroundSecondary,
70 borderRadius: BorderRadius.all(Radius.circular(20)),
71 ),
72 child: Row(
73 children: [
74 Icon(
75 Icons.edit_outlined,
76 size: 16,
77 color: AppColors.textPrimary.withValues(alpha: 0.5),
78 ),
79 const SizedBox(width: 8),
80 Text(
81 'Comment',
82 style: TextStyle(
83 color: AppColors.textPrimary.withValues(alpha: 0.5),
84 fontSize: 14,
85 ),
86 ),
87 ],
88 ),
89 ),
90 ),
91 ),
92 const SizedBox(width: 16),
93
94 // Vote button with animated heart icon
95 GestureDetector(
96 onTap: onVoteTap,
97 child: Row(
98 mainAxisSize: MainAxisSize.min,
99 children: [
100 AnimatedHeartIcon(
101 isLiked: isVoted,
102 color: AppColors.textPrimary.withValues(alpha: 0.7),
103 likedColor: const Color(0xFFFF0033),
104 size: 24,
105 ),
106 const SizedBox(width: 4),
107 Text(
108 DateTimeUtils.formatCount(post.post.stats.score),
109 style: TextStyle(
110 color:
111 isVoted
112 ? const Color(0xFFFF0033)
113 : AppColors.textPrimary.withValues(alpha: 0.7),
114 fontSize: 13,
115 fontWeight: FontWeight.w500,
116 ),
117 ),
118 ],
119 ),
120 ),
121 const SizedBox(width: 16),
122
123 // Save button with count (placeholder for now)
124 _ActionButton(
125 icon: isSaved ? Icons.bookmark : Icons.bookmark_border,
126 count: 0, // TODO: Add save count when backend supports it
127 color: isSaved ? AppColors.primary : null,
128 onTap: onSaveTap,
129 ),
130 const SizedBox(width: 16),
131
132 // Comment count button
133 _ActionButton(
134 icon: Icons.chat_bubble_outline,
135 count: post.post.stats.commentCount,
136 onTap: onCommentCountTap ?? onCommentTap,
137 ),
138 ],
139 ),
140 ),
141 );
142 }
143}
144
145/// Action button with icon and count
146class _ActionButton extends StatelessWidget {
147 const _ActionButton({
148 required this.icon,
149 required this.count,
150 this.color,
151 this.onTap,
152 });
153
154 final IconData icon;
155 final int count;
156 final Color? color;
157 final VoidCallback? onTap;
158
159 @override
160 Widget build(BuildContext context) {
161 final effectiveColor =
162 color ?? AppColors.textPrimary.withValues(alpha: 0.7);
163
164 return GestureDetector(
165 onTap: onTap,
166 child: Row(
167 mainAxisSize: MainAxisSize.min,
168 children: [
169 Icon(icon, size: 24, color: effectiveColor),
170 const SizedBox(width: 4),
171 Text(
172 DateTimeUtils.formatCount(count),
173 style: TextStyle(
174 color: effectiveColor,
175 fontSize: 13,
176 fontWeight: FontWeight.w500,
177 ),
178 ),
179 ],
180 ),
181 );
182 }
183}