feat: integrate comment composer and fix post card border control

PostCard enhancements:
- Add showBorder prop to control border independently from showHeader
- Fix duplicate border in post detail by passing showBorder: false

Post detail screen integration:
- Connect comment button to new reply screen
- Add authentication check before opening composer
- Implement comment submission handler (TODO: atProto integration)
- Navigate to reply screen with full post context

Fixes duplicate border issue where post detail showed extra divider
between post content and comments when showHeader: false was used.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>

Changed files
+43 -11
lib
+40 -10
lib/screens/home/post_detail_screen.dart
···
import '../../widgets/loading_error_states.dart';
import '../../widgets/post_action_bar.dart';
import '../../widgets/post_card.dart';
+
import '../compose/reply_screen.dart';
/// Post Detail Screen
///
···
await Share.share('$title\n\n$postUri', subject: title);
}
-
/// Build bottom action bar with comment input and buttons
+
/// Build bottom action bar with vote, save, and comment actions
Widget _buildActionBar() {
return Consumer<VoteProvider>(
builder: (context, voteProvider, child) {
···
return PostActionBar(
post: displayPost,
isVoted: isVoted,
-
onCommentTap: () {
-
// TODO: Open comment composer
-
ScaffoldMessenger.of(context).showSnackBar(
-
const SnackBar(
-
content: Text('Comment composer coming soon!'),
-
behavior: SnackBarBehavior.floating,
-
),
-
);
-
},
+
onCommentTap: _openCommentComposer,
onVoteTap: () async {
// Check authentication
final authProvider = context.read<AuthProvider>();
···
);
}
+
/// Open the reply screen for composing a comment
+
void _openCommentComposer() {
+
// Check authentication
+
final authProvider = context.read<AuthProvider>();
+
if (!authProvider.isAuthenticated) {
+
ScaffoldMessenger.of(context).showSnackBar(
+
const SnackBar(
+
content: Text('Sign in to comment'),
+
behavior: SnackBarBehavior.floating,
+
),
+
);
+
return;
+
}
+
+
// Navigate to reply screen with full post context
+
Navigator.of(context).push(
+
MaterialPageRoute<void>(
+
builder:
+
(context) =>
+
ReplyScreen(post: widget.post, onSubmit: _handleCommentSubmit),
+
),
+
);
+
}
+
+
/// Handle comment submission
+
Future<void> _handleCommentSubmit(String content) async {
+
// TODO: Implement comment creation via atProto
+
ScaffoldMessenger.of(context).showSnackBar(
+
SnackBar(
+
content: Text('Comment submitted: $content'),
+
behavior: SnackBarBehavior.floating,
+
duration: const Duration(seconds: 2),
+
),
+
);
+
}
+
/// Build main content area
Widget _buildContent() {
// Use Consumer to rebuild when comments provider changes
···
disableNavigation: true,
showActions: false,
showHeader: false,
+
showBorder: false,
);
},
);
+3 -1
lib/widgets/post_card.dart
···
this.disableNavigation = false,
this.showActions = true,
this.showHeader = true,
+
this.showBorder = true,
super.key,
});
···
final bool disableNavigation;
final bool showActions;
final bool showHeader;
+
final bool showBorder;
/// Check if this post should be clickable
/// Only text posts (no embeds or non-video/link embeds) are
···
decoration: BoxDecoration(
color: AppColors.background,
border:
-
showHeader
+
showBorder
? const Border(bottom: BorderSide(color: AppColors.border))
: null,
),