import "package:shadcn_flutter/shadcn_flutter.dart"; import '../../models/attachment.dart'; import '../common/button.dart'; class AttachmentPreview extends StatelessWidget { final List attachments; final Function(int) onRemove; const AttachmentPreview({ required this.attachments, required this.onRemove, }); @override Widget build(BuildContext context) { if (attachments.isEmpty) { return SizedBox.shrink(); } return MouseRegion( cursor: SystemMouseCursors.basic, child: Padding( padding: const EdgeInsets.only(bottom: 8), child: SingleChildScrollView( scrollDirection: Axis.horizontal, child: Row( children: [ for (int i = 0; i < attachments.length; i++) Padding( padding: EdgeInsets.only(right: 8), child: AttachmentItem( attachment: attachments[i], onRemove: () => onRemove(i), ), ), ], ), ), ), ); } } class AttachmentItem extends StatelessWidget { final Attachment attachment; final VoidCallback onRemove; const AttachmentItem({ required this.attachment, required this.onRemove, }); @override Widget build(BuildContext context) { String sanitisedName = attachment.displayName; String type = attachment.mimeType.split("/").last.toUpperCase(); return OutlinedContainer( height: 52, borderRadius: Theme.of(context).borderRadiusSm, padding: EdgeInsets.all(8), borderColor: Theme.of(context).colorScheme.border, child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ OutlinedContainer( borderRadius: BorderRadius.circular( Theme.of(context).radiusSm - 4 ), child: AspectRatio( aspectRatio: 1, child: ClipRRect( borderRadius: BorderRadius.zero, child: _buildPreview(context), ), ), ), Gap(8), Column( crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [ Text( sanitisedName, maxLines: 1, overflow: TextOverflow.ellipsis, ).small.semiBold, Gap(2), Text( type, maxLines: 1, overflow: TextOverflow.ellipsis, ).extraLight.small, ], ), Gap(8), SizedBox( child: ClipRRect( borderRadius: BorderRadius.circular( Theme.of(context).radiusSm - 4 ), child: AspectRatio( aspectRatio: 1, child: AgcGhostButton( onPressed: onRemove, child: Icon(LucideIcons.x, size: 14), ), ), ), ) ], ), ); } Widget _buildPreview(BuildContext context) { if (attachment.isImage) { return Image.memory( attachment.data, fit: BoxFit.cover, ); } final icon = _getIconForMimeType(attachment.mimeType); return Container( color: Theme.of(context).colorScheme.muted, child: Icon(icon).iconMedium, ); } IconData _getIconForMimeType(String mimeType) { if (mimeType == 'application/pdf') { return LucideIcons.book; } else if (mimeType.startsWith('text/') || mimeType == 'application/json') { return LucideIcons.fileText; } else if (mimeType.startsWith('image/')) { return LucideIcons.image; } else { return LucideIcons.file; } } }