import 'package:flutter/material.dart'; import 'dart:io'; import 'package:emoji_picker_flutter/emoji_picker_flutter.dart'; import '../models/message.dart'; import 'package:flutter/foundation.dart' as foundation; import '../../../core/theme/app_colors.dart'; import 'reply_bar.dart'; class MessageInputWidget extends StatelessWidget { final TextEditingController messageController; final FocusNode focusNode; final bool isUploading; final File? selectedImage; final bool showEmojiKeyboard; final bool isReplying; final Message? replyToMessage; final VoidCallback onSend; final VoidCallback onImageOptions; final VoidCallback onEmojiToggle; final VoidCallback onClearImage; final VoidCallback onCancelReply; final Color themeColor; const MessageInputWidget({ Key? key, required this.messageController, required this.focusNode, required this.isUploading, required this.selectedImage, required this.showEmojiKeyboard, required this.isReplying, required this.replyToMessage, required this.onSend, required this.onImageOptions, required this.onEmojiToggle, required this.onClearImage, required this.onCancelReply, required this.themeColor, }) : super(key: key); @override Widget build(BuildContext context) { // Wrap everything in a Column to contain emoji keyboard return Column( mainAxisSize: MainAxisSize.min, children: [ // Selected image preview if (selectedImage != null) _buildImagePreview(), // Reply bar if (isReplying) _buildReplyBar(), // Input bar Container( padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 6.0), decoration: BoxDecoration( color: Colors.white, boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.05), blurRadius: 3, offset: Offset(0, -1), ), ], ), child: SafeArea( top: false, child: Row( crossAxisAlignment: CrossAxisAlignment.end, children: [ // Emoji button IconButton( icon: Icon( showEmojiKeyboard ? Icons.keyboard : Icons.emoji_emotions_outlined, color: themeColor, ), onPressed: onEmojiToggle, padding: EdgeInsets.zero, constraints: BoxConstraints( minWidth: 36, minHeight: 36, ), ), // Text field Expanded( child: ConstrainedBox( constraints: BoxConstraints( maxHeight: 120.0, // Limit max height ), child: TextField( controller: messageController, focusNode: focusNode, minLines: 1, maxLines: 5, // Allow multiple lines but not too many textCapitalization: TextCapitalization.sentences, decoration: InputDecoration( hintText: 'Ketik pesan...', border: InputBorder.none, contentPadding: EdgeInsets.symmetric(horizontal: 8.0, vertical: 10.0), ), ), ), ), // Attachment button IconButton( icon: Icon( Icons.attach_file, color: themeColor, ), onPressed: onImageOptions, padding: EdgeInsets.zero, constraints: BoxConstraints( minWidth: 36, minHeight: 36, ), ), // Send button _buildSendButton(), ], ), ), ), // Emoji keyboard - Wrap in AnimatedContainer for smooth transitions AnimatedContainer( duration: Duration(milliseconds: 200), height: showEmojiKeyboard ? _getEmojiKeyboardHeight(context) : 0, child: showEmojiKeyboard ? _buildEmojiPicker(context) : SizedBox(), ), ], ); } Widget _buildImagePreview() { return Container( width: double.infinity, padding: EdgeInsets.all(8.0), color: Colors.grey[200], child: Stack( alignment: Alignment.center, children: [ // Image preview with fixed height Container( height: 150, width: double.infinity, decoration: BoxDecoration( borderRadius: BorderRadius.circular(8), color: Colors.black, ), child: ClipRRect( borderRadius: BorderRadius.circular(8), child: Image.file( selectedImage!, fit: BoxFit.cover, ), ), ), // Loading indicator if (isUploading) Container( height: 150, width: double.infinity, color: Colors.black54, child: Center( child: CircularProgressIndicator( valueColor: AlwaysStoppedAnimation(Colors.white), ), ), ), // Close button Positioned( top: 0, right: 0, child: Material( color: Colors.transparent, child: InkWell( borderRadius: BorderRadius.circular(20), onTap: onClearImage, child: Container( padding: EdgeInsets.all(4), decoration: BoxDecoration( color: Colors.black54, shape: BoxShape.circle, ), child: Icon( Icons.close, color: Colors.white, size: 20, ), ), ), ), ), ], ), ); } Widget _buildReplyBar() { if (replyToMessage == null) return SizedBox.shrink(); return ReplyBar( message: replyToMessage!, onCancel: onCancelReply, ); } Widget _buildSendButton() { final bool canSend = messageController.text.trim().isNotEmpty || selectedImage != null; return GestureDetector( onTap: canSend ? onSend : null, child: Container( width: 36, height: 36, margin: EdgeInsets.only(left: 4, right: 4), decoration: BoxDecoration( color: canSend ? themeColor : Colors.grey, shape: BoxShape.circle, ), child: Icon( Icons.send, color: Colors.white, size: 18, ), ), ); } Widget _buildEmojiPicker(BuildContext context) { return EmojiPicker( onEmojiSelected: (category, emoji) { messageController.text = messageController.text + emoji.emoji; }, textEditingController: messageController, config: Config( checkPlatformCompatibility: true, ), ); } // Calculate emoji keyboard height based on screen size and keyboard visibility double _getEmojiKeyboardHeight(BuildContext context) { final screenHeight = MediaQuery.of(context).size.height; final keyboardVisible = MediaQuery.of(context).viewInsets.bottom > 0; // Calculate safe height for emoji picker final double baseHeight = keyboardVisible ? screenHeight * 0.25 // 25% when keyboard visible : screenHeight * 0.35; // 35% when keyboard hidden // Ensure we don't exceed available space final availableHeight = screenHeight - MediaQuery.of(context).viewInsets.bottom - kToolbarHeight - 100; return baseHeight.clamp(100.0, availableHeight); } }