sojorn/sojorn_app/lib/widgets/post_item.dart
2026-02-01 16:06:12 -06:00

140 lines
3.5 KiB
Dart

import 'package:flutter/material.dart';
import '../models/post.dart';
import '../theme/app_theme.dart';
import 'sojorn_post_card.dart';
import 'post/post_view_mode.dart';
/// UnifiedPostTile - Backward-compatible wrapper around sojornPostCard.
///
/// This class is now DEPRECATED in favor of sojornPostCard.
/// It exists only for backward compatibility with existing code.
///
/// ## New Usage
/// ```dart
/// sojornPostCard(
/// post: post,
/// mode: PostViewMode.feed,
/// onTap: () {},
/// )
/// ```
///
/// ## Migration Guide
/// Replace `UnifiedPostTile(...)` with `sojornPostCard(...)`
class UnifiedPostTile extends StatelessWidget {
final Post post;
final VoidCallback? onTap;
final VoidCallback? onChain;
final bool showDivider;
final bool isDetailView;
final bool showThreadSpine;
final double? avatarSize;
final bool isThreadView;
const UnifiedPostTile({
super.key,
required this.post,
this.onTap,
this.onChain,
this.showDivider = true,
this.isDetailView = false,
this.showThreadSpine = false,
this.avatarSize,
this.isThreadView = false,
});
/// Convert legacy parameters to PostViewMode
PostViewMode get _viewMode {
if (isDetailView) return PostViewMode.detail;
if (avatarSize != null && avatarSize! < 32) return PostViewMode.compact;
return PostViewMode.feed;
}
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Thread spine line (if enabled in threaded view)
if (showThreadSpine) _buildThreadSpine(context),
// Backward compatibility: wrap in divider if needed
if (showDivider)
Column(
children: [
_buildPostContent(context),
_buildStrictDivider(),
],
)
else
_buildPostContent(context),
],
);
}
Widget _buildPostContent(BuildContext context) {
return sojornPostCard(
post: post,
mode: _viewMode,
onTap: onTap,
onChain: onChain,
isThreadView: isThreadView,
);
}
/// STRICT SEPARATION: Full-width Divider at bottom of every post
Widget _buildStrictDivider() {
return Container(
height: 1.0,
width: double.infinity,
color: AppTheme.egyptianBlue.withOpacity(0.15),
margin: EdgeInsets.zero,
);
}
/// Thread spine: vertical line connecting parent to child in threaded view
Widget _buildThreadSpine(BuildContext context) {
return CustomPaint(
size: const Size(2, AppTheme.spacingMd),
painter: ThreadSpinePainter(
color: AppTheme.egyptianBlue.withOpacity(0.3),
width: 2,
),
);
}
}
/// Thread Spine Painter - draws vertical line for threaded views
class ThreadSpinePainter extends CustomPainter {
final Color color;
final double width;
ThreadSpinePainter({required this.color, required this.width});
@override
void paint(Canvas canvas, Size size) {
final paint = Paint()
..color = color
..strokeWidth = width
..style = PaintingStyle.fill;
// Draw vertical line from center-top to center-bottom
canvas.drawRect(
Rect.fromLTWH(
size.width / 2 - width / 2,
0,
width,
size.height,
),
paint,
);
}
@override
bool shouldRepaint(ThreadSpinePainter oldDelegate) {
return oldDelegate.color != color || oldDelegate.width != width;
}
}
/// Backward-compatible alias for UnifiedPostTile
typedef PostItem = UnifiedPostTile;