import 'dart:io'; import 'package:Capsule/views/main/conversation/message.dart'; import 'package:flutter/material.dart'; import 'package:image_picker/image_picker.dart'; import '/components/custom_title_bar.dart'; import '/components/file_picker.dart'; import '/models/conversations.dart'; import '/models/messages.dart'; import '/models/my_profile.dart'; import '/utils/storage/messages.dart'; import '/views/main/conversation/settings.dart'; class ConversationDetail extends StatefulWidget{ final Conversation conversation; const ConversationDetail({ Key? key, required this.conversation, }) : super(key: key); @override _ConversationDetailState createState() => _ConversationDetailState(); } class _ConversationDetailState extends State { List messages = []; MyProfile profile = MyProfile( id: '', username: '', messageExpiryDefault: 'no_expiry', ); TextEditingController msgController = TextEditingController(); bool showFilePicker = false; List selectedImages = []; @override Widget build(BuildContext context) { return Scaffold( appBar: CustomTitleBar( title: Text( widget.conversation.name, style: TextStyle( fontSize: 16, fontWeight: FontWeight.w600, color: Theme.of(context).appBarTheme.toolbarTextStyle?.color ), ), showBack: true, rightHandButton: IconButton( onPressed: (){ Navigator.of(context).push( MaterialPageRoute(builder: (context) => ConversationSettings( conversation: widget.conversation )), ); }, icon: Icon( Icons.settings, color: Theme.of(context).appBarTheme.iconTheme?.color, ), ), ), body: Stack( children: [ messagesView(), newMessageContent(), ], ), ); } Future fetchMessages() async { profile = await MyProfile.getProfile(); messages = await getMessagesForThread(widget.conversation); setState(() {}); } @override void initState() { super.initState(); fetchMessages(); } Widget messagesView() { if (messages.isEmpty) { return const Center( child: Text('No Messages'), ); } return ListView.builder( itemCount: messages.length, shrinkWrap: true, padding: EdgeInsets.only( top: 10, bottom: selectedImages.isEmpty ? 90 : 160, ), reverse: true, itemBuilder: (context, index) { return ConversationMessage( message: messages[index], profile: profile, index: index, ); }, ); } Widget showSelectedImages() { if (selectedImages.isEmpty) { return const SizedBox.shrink(); } return SizedBox( height: 80, width: double.infinity, child: ListView.builder( itemCount: selectedImages.length, shrinkWrap: true, scrollDirection: Axis.horizontal, padding: const EdgeInsets.all(5), itemBuilder: (context, i) { return Stack( children: [ Column( children: [ const SizedBox(height: 5), Container( alignment: Alignment.center, height: 65, width: 65, child: Image.file( selectedImages[i], fit: BoxFit.fill, ), ), ], ), SizedBox( height: 60, width: 70, child: Align( alignment: Alignment.topRight, child: GestureDetector( onTap: () { setState(() { selectedImages.removeAt(i); }); }, child: Container( height: 20, width: 20, decoration: BoxDecoration( color: Theme.of(context).colorScheme.onPrimary, borderRadius: BorderRadius.circular(30), ), child: Icon( Icons.cancel, color: Theme.of(context).primaryColor, size: 20 ), ), ), ), ), ], ); }, ) ); } Widget newMessageContent() { return Align( alignment: Alignment.bottomLeft, child: ConstrainedBox( constraints: BoxConstraints( maxHeight: selectedImages.isEmpty ? 200.0 : 270.0, ), child: Container( padding: const EdgeInsets.only(left: 10,bottom: 10,top: 10), width: double.infinity, color: Theme.of(context).backgroundColor, child: Column( mainAxisSize: MainAxisSize.min, children: [ showSelectedImages(), Row( children: [ GestureDetector( onTap: (){ setState(() { showFilePicker = !showFilePicker; }); }, child: Container( height: 30, width: 30, decoration: BoxDecoration( color: Theme.of(context).primaryColor, borderRadius: BorderRadius.circular(30), ), child: Icon( Icons.add, color: Theme.of(context).colorScheme.onPrimary, size: 20 ), ), ), const SizedBox(width: 15,), Expanded( child: TextField( decoration: InputDecoration( hintText: 'Write message...', hintStyle: TextStyle( color: Theme.of(context).hintColor, ), border: InputBorder.none, ), maxLines: null, controller: msgController, ), ), const SizedBox(width: 15), SizedBox( width: 45, height: 45, child: FittedBox( child: FloatingActionButton( onPressed: () async { if (msgController.text == '' && selectedImages.isEmpty) { return; } await sendMessage( widget.conversation, data: msgController.text != '' ? msgController.text : null, files: selectedImages, ); messages = await getMessagesForThread(widget.conversation); setState(() { msgController.text = ''; selectedImages = []; }); }, child: Icon( Icons.send, color: Theme.of(context).colorScheme.onPrimary, size: 22 ), backgroundColor: Theme.of(context).primaryColor, ), ), ), const SizedBox(width: 10), ], ), showFilePicker ? FilePicker( cameraHandle: (XFile image) {}, galleryHandleMultiple: (List images) async { for (var img in images) { selectedImages.add(File(img.path)); } setState(() { showFilePicker = false; }); }, fileHandle: () {}, ) : const SizedBox.shrink(), ], ), ), ), ); } }