Improve design of attachment buttons

This commit is contained in:
Nutcake 2023-05-21 18:43:01 +02:00
parent 2987603b7a
commit 358e8490bc
2 changed files with 129 additions and 141 deletions

View file

@ -21,6 +21,7 @@ class _MessageAttachmentListState extends State<MessageAttachmentList> {
final List<(FileType, File)> _loadedFiles = [];
final ScrollController _scrollController = ScrollController();
bool _showShadow = true;
bool _popupIsOpen = false;
@override
void initState() {
@ -121,146 +122,131 @@ class _MessageAttachmentListState extends State<MessageAttachmentList> {
),
),
),
PopupMenuButton<DocumentType>(
offset: const Offset(0, -64),
constraints: const BoxConstraints.tightFor(width: 48 * 3, height: 64),
shadowColor: Colors.transparent,
position: PopupMenuPosition.over,
color: Colors.transparent,
enableFeedback: true,
padding: EdgeInsets.zero,
surfaceTintColor: Colors.transparent,
iconSize: 24,
itemBuilder: (context) =>
[
PopupMenuItem(
padding: EdgeInsets.zero,
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
IconButton(
iconSize: 24,
style: IconButton.styleFrom(
backgroundColor: Theme
.of(context)
.colorScheme
.surface,
foregroundColor: Theme
.of(context)
.colorScheme
.onSurface,
side: BorderSide(
width: 1,
color: Theme
.of(context)
.colorScheme
.secondary,
)
),
padding: EdgeInsets.zero,
onPressed: () async {
final result = await FilePicker.platform.pickFiles(type: FileType.image, allowMultiple: true);
if (result != null) {
setState(() {
_loadedFiles.addAll(
result.files.map((e) => e.path != null ? (FileType.image, File(e.path!)) : null)
.whereNotNull());
});
}
if (context.mounted) {
Navigator.of(context).pop();
}
},
icon: const Icon(Icons.image,),
),
IconButton(
iconSize: 24,
style: IconButton.styleFrom(
backgroundColor: Theme
.of(context)
.colorScheme
.surface,
foregroundColor: Theme
.of(context)
.colorScheme
.onSurface,
side: BorderSide(
width: 1,
color: Theme
.of(context)
.colorScheme
.secondary,
)
),
padding: EdgeInsets.zero,
onPressed: () async {
final picture = await Navigator.of(context).push(
MaterialPageRoute(builder: (context) => const MessageCameraView())) as File?;
if (picture != null) {
_loadedFiles.add((FileType.image, picture));
await widget.onChange(_loadedFiles);
}
if (context.mounted) {
Navigator.of(context).pop();
}
},
icon: const Icon(Icons.camera,),
),
IconButton(
iconSize: 24,
style: IconButton.styleFrom(
backgroundColor: Theme
.of(context)
.colorScheme
.surface,
foregroundColor: Theme
.of(context)
.colorScheme
.onSurface,
side: BorderSide(
width: 1,
color: Theme
.of(context)
.colorScheme
.secondary,
)
),
padding: EdgeInsets.zero,
onPressed: () async {
final result = await FilePicker.platform.pickFiles(type: FileType.any, allowMultiple: true);
if (result != null) {
setState(() {
_loadedFiles.addAll(
result.files.map((e) => e.path != null ? (FileType.any, File(e.path!)) : null)
.whereNotNull());
});
}
if (context.mounted) {
Navigator.of(context).pop();
}
},
icon: const Icon(Icons.file_present_rounded,),
),
],
),
),
],
icon: Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(64),
border: Border.all(
color: Theme
.of(context)
.colorScheme
.primary,
),
),
child: Icon(
Icons.add,
color: Theme.of(context).colorScheme.onSurface,
AnimatedSwitcher(
duration: const Duration(milliseconds: 200),
switchInCurve: Curves.decelerate,
transitionBuilder: (child, animation) => FadeTransition(
opacity: animation,
child: SizeTransition(
sizeFactor: animation,
axis: Axis.horizontal,
//position: Tween<Offset>(begin: const Offset(1, 0), end: const Offset(0, 0)).animate(animation),
child: child,
),
),
child: _popupIsOpen ? Row(
key: const ValueKey("popup-buttons"),
children: [
IconButton(
iconSize: 24,
style: IconButton.styleFrom(
backgroundColor: Theme
.of(context)
.colorScheme
.surface,
foregroundColor: Theme
.of(context)
.colorScheme
.onSurface,
side: BorderSide(
width: 1,
color: Theme
.of(context)
.colorScheme
.secondary,
)
),
padding: EdgeInsets.zero,
onPressed: () async {
final result = await FilePicker.platform.pickFiles(type: FileType.image, allowMultiple: true);
if (result != null) {
setState(() {
_loadedFiles.addAll(
result.files.map((e) => e.path != null ? (FileType.image, File(e.path!)) : null)
.whereNotNull());
});
}
},
icon: const Icon(Icons.image,),
),
IconButton(
iconSize: 24,
style: IconButton.styleFrom(
backgroundColor: Theme
.of(context)
.colorScheme
.surface,
foregroundColor: Theme
.of(context)
.colorScheme
.onSurface,
side: BorderSide(
width: 1,
color: Theme
.of(context)
.colorScheme
.secondary,
)
),
padding: EdgeInsets.zero,
onPressed: () async {
final picture = await Navigator.of(context).push(
MaterialPageRoute(builder: (context) => const MessageCameraView())) as File?;
if (picture != null) {
_loadedFiles.add((FileType.image, picture));
await widget.onChange(_loadedFiles);
}
},
icon: const Icon(Icons.camera,),
),
IconButton(
iconSize: 24,
style: IconButton.styleFrom(
backgroundColor: Theme
.of(context)
.colorScheme
.surface,
foregroundColor: Theme
.of(context)
.colorScheme
.onSurface,
side: BorderSide(
width: 1,
color: Theme
.of(context)
.colorScheme
.secondary,
)
),
padding: EdgeInsets.zero,
onPressed: () async {
final result = await FilePicker.platform.pickFiles(type: FileType.any, allowMultiple: true);
if (result != null) {
setState(() {
_loadedFiles.addAll(
result.files.map((e) => e.path != null ? (FileType.any, File(e.path!)) : null)
.whereNotNull());
});
}
},
icon: const Icon(Icons.file_present_rounded,),
),
],
) : const SizedBox.shrink(),
),
Container(
color: Theme.of(context).colorScheme.surface,
child: IconButton(onPressed: () {
setState(() {
_popupIsOpen = !_popupIsOpen;
});
}, icon: AnimatedRotation(
duration: const Duration(milliseconds: 200),
turns: _popupIsOpen ? 3/8 : 0,
child: const Icon(Icons.add),
)),
)
],
);
}

View file

@ -270,7 +270,7 @@ class _MessageInputBarState extends State<MessageInputBar> {
});
}
},
icon: const Icon(Icons.camera_alt),
icon: const Icon(Icons.camera),
label: const Text("Camera"),
),
TextButton.icon(
@ -393,11 +393,13 @@ class _MessageInputBarState extends State<MessageInputBar> {
hintText: _isRecording ? "" : "Message ${widget.recipient
.username}...",
hintMaxLines: 1,
contentPadding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12),
fillColor: Colors.black38,
filled: true,
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(24)
),
borderSide: BorderSide.none,
borderRadius: BorderRadius.circular(24),
)
),
),
AnimatedSwitcher(