import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_speed_dial/flutter_speed_dial.dart'; import 'package:get_it/get_it.dart'; import 'package:moxxyv2/ui/bloc/conversation_bloc.dart'; import 'package:moxxyv2/ui/bloc/conversations_bloc.dart'; import 'package:moxxyv2/ui/bloc/profile_bloc.dart' as profile; import 'package:moxxyv2/ui/constants.dart'; import 'package:moxxyv2/ui/helpers.dart'; import 'package:moxxyv2/ui/widgets/avatar.dart'; import 'package:moxxyv2/ui/widgets/conversation.dart'; import 'package:moxxyv2/ui/widgets/topbar.dart'; import 'package:moxxyv2/xmpp/xeps/xep_0085.dart'; enum ConversationsOptions { settings } class ConversationsPage extends StatelessWidget { const ConversationsPage({ Key? key }) : super(key: key); static MaterialPageRoute get route => MaterialPageRoute( builder: (context) => const ConversationsPage(), settings: const RouteSettings( name: conversationsRoute, ), ); Widget _listWrapper(BuildContext context, ConversationsState state) { final maxTextWidth = MediaQuery.of(context).size.width * 0.6; if (state.conversations.isNotEmpty) { return ListView.builder( itemCount: state.conversations.length, itemBuilder: (_context, index) { final item = state.conversations[index]; return Dismissible( key: ValueKey('conversation;$item'), onDismissed: (direction) => context.read().add( ConversationClosedEvent(item.jid), ), background: ColoredBox( color: Colors.red, child: Padding( padding: const EdgeInsets.all(16), child: Row( children: const [ Icon(Icons.delete), Spacer(), Icon(Icons.delete) ], ), ), ), child: InkWell( onTap: () => GetIt.I.get().add( RequestedConversationEvent(item.jid, item.title, item.avatarUrl), ), child: ConversationsListRow( item.avatarUrl, item.title, item.lastMessageBody, item.unreadCounter, maxTextWidth, item.lastChangeTimestamp, true, typingIndicator: item.chatState == ChatState.composing, key: ValueKey('conversationRow;${item.jid}'), ), ), ); }, ); } return Padding( padding: const EdgeInsets.symmetric(horizontal: paddingVeryLarge), child: Column( children: [ Padding( padding: const EdgeInsets.only(top: 8), // TODO(Unknown): Maybe somehow render the svg child: Image.asset('assets/images/begin_chat.png'), ), const Padding( padding: EdgeInsets.only(top: 8), child: Text('You have no open chats'), ), TextButton( child: const Text('Start a chat'), onPressed: () => Navigator.pushNamed(context, newConversationRoute), ) ], ), ); } @override Widget build(BuildContext context) { return BlocBuilder( builder: (BuildContext context, ConversationsState state) => Scaffold( appBar: BorderlessTopbar.avatarAndName( TopbarAvatarAndName( TopbarTitleText(state.displayName), Hero( tag: 'self_profile_picture', child: Material( color: const Color.fromRGBO(0, 0, 0, 0), child: AvatarWrapper( radius: 20, avatarUrl: state.avatarUrl, altIcon: Icons.person, ), ), ), () => GetIt.I.get().add( profile.ProfilePageRequestedEvent( true, jid: state.jid, avatarUrl: state.avatarUrl, displayName: state.displayName, ), ), showBackButton: false, extra: [ PopupMenuButton( onSelected: (ConversationsOptions result) { switch (result) { case ConversationsOptions.settings: Navigator.pushNamed(context, settingsRoute); break; } }, icon: const Icon(Icons.more_vert), itemBuilder: (BuildContext context) => [ const PopupMenuItem( value: ConversationsOptions.settings, child: Text('Settings'), ) ], ) ], ), ), body: _listWrapper(context, state), floatingActionButton: SpeedDial( icon: Icons.chat, curve: Curves.bounceInOut, backgroundColor: primaryColor, // TODO(Unknown): Theme dependent? foregroundColor: Colors.white, children: [ SpeedDialChild( child: const Icon(Icons.group), onTap: () => showNotImplementedDialog('groupchat', context), backgroundColor: primaryColor, // TODO(Unknown): Theme dependent? foregroundColor: Colors.white, label: 'Join groupchat', ), SpeedDialChild( child: const Icon(Icons.person_add), onTap: () => Navigator.pushNamed(context, newConversationRoute), backgroundColor: primaryColor, // TODO(Unknown): Theme dependent? foregroundColor: Colors.white, label: 'New chat', ) ], ), ), ); } }