// SPDX-FileCopyrightText: 2019-Present Christian Kußowski // SPDX-FileCopyrightText: 2019-Present Contributors to FluffyChat // // SPDX-License-Identifier: AGPL-3.0-or-later import 'package:tatchat/config/themes.dart'; import 'package:tatchat/l10n/l10n.dart'; import 'package:tatchat/pages/chat/chat.dart'; import 'package:tatchat/utils/platform_infos.dart'; import 'package:material_ui/material_ui.dart'; class ChatAttachmentPicker extends StatelessWidget { final ChatController controller; const ChatAttachmentPicker(this.controller, {super.key}); static const double _itemSpacing = 8; static const double _handleSize = 4; @override Widget build(BuildContext context) { final theme = Theme.of(context); final l10n = L10n.of(context); final mobile = PlatformInfos.isMobile; final items = <(IconData, String, AddPopupMenuActions)>[ if (mobile) ( Icons.gps_fixed_outlined, l10n.shareLocation, AddPopupMenuActions.location, ), (Icons.poll_outlined, l10n.startPoll, AddPopupMenuActions.poll), if (mobile) ( Icons.videocam_outlined, l10n.recordAVideo, AddPopupMenuActions.videoCamera, ), if (mobile) ( Icons.camera_alt_outlined, l10n.takeAPhoto, AddPopupMenuActions.photoCamera, ), (Icons.image_outlined, l10n.openGallery, AddPopupMenuActions.media), (Icons.attachment_outlined, l10n.sendFile, AddPopupMenuActions.file), ]; if (items.isEmpty) return const SizedBox.shrink(); final rows = >[]; for (var i = 0; i < items.length; i += 3) { rows.add(items.sublist(i, i + 3 > items.length ? items.length : i + 3)); } return ClipRRect( borderRadius: const BorderRadius.vertical(top: Radius.circular(20)), child: AnimatedSize( duration: FluffyThemes.animationDuration, curve: FluffyThemes.animationCurve, alignment: Alignment.bottomCenter, child: controller.showAttachmentPicker ? Material( color: theme.colorScheme.surfaceContainer, child: Padding( padding: const EdgeInsets.fromLTRB(12, 6, 12, 12), child: Column( mainAxisSize: .min, children: [ Container( width: 32, height: _handleSize, decoration: BoxDecoration( color: theme.colorScheme.outlineVariant, borderRadius: BorderRadius.circular(_handleSize / 2), ), ), const SizedBox(height: 12), Column( mainAxisSize: .min, children: [ for (final (i, row) in rows.indexed) ...[ if (i > 0) const SizedBox(height: _itemSpacing), Row( children: [ for (final item in row) ...[ if (row.indexOf(item) > 0) const SizedBox(width: _itemSpacing), Expanded( child: AspectRatio( aspectRatio: 1, child: _AttachmentItem( icon: item.$1, label: item.$2, onTap: () { controller.hideAttachmentPicker(); controller .onAddPopupMenuButtonSelected( item.$3, ); }, ), ), ), ], if (row.length < 3) for (var i = 0; i < 3 - row.length; i++) ...[ const SizedBox(width: _itemSpacing), const Expanded(child: SizedBox()), ], ], ), ], ], ), ], ), ), ) : const SizedBox.shrink(), ), ); } } class _AttachmentItem extends StatelessWidget { final IconData icon; final String label; final VoidCallback onTap; const _AttachmentItem({ required this.icon, required this.label, required this.onTap, }); @override Widget build(BuildContext context) { final theme = Theme.of(context); return Material( color: theme.colorScheme.secondaryContainer, borderRadius: BorderRadius.circular(20), clipBehavior: Clip.hardEdge, child: InkWell( onTap: onTap, child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(icon, size: 30, color: theme.colorScheme.onSecondaryContainer), const SizedBox(height: 8), Padding( padding: const EdgeInsets.symmetric(horizontal: 4), child: Text( label, maxLines: 1, overflow: TextOverflow.ellipsis, textAlign: TextAlign.center, style: theme.textTheme.labelMedium?.copyWith( color: theme.colorScheme.onSecondaryContainer, ), ), ), ], ), ), ); } }