The-Agency/lib/ui/widgets/chat/attachment_preview.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;
}
}
}