143 lines
3.8 KiB
Dart
143 lines
3.8 KiB
Dart
import "package:shadcn_flutter/shadcn_flutter.dart";
|
|
import '../../models/attachment.dart';
|
|
import '../common/button.dart';
|
|
|
|
class AttachmentPreview extends StatelessWidget {
|
|
final List<Attachment> 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;
|
|
}
|
|
}
|
|
}
|