import 'package:async_tools/async_tools.dart'; import 'package:awesome_extensions/awesome_extensions.dart'; import 'package:flutter/material.dart'; import 'package:flutter_translate/flutter_translate.dart'; import 'package:provider/provider.dart'; import '../../chat/chat.dart'; import '../../chat_list/chat_list.dart'; import '../../layout/layout.dart'; import '../../proto/proto.dart' as proto; import '../../theme/theme.dart'; import '../contacts.dart'; const _kDoBackArrow = 'doBackArrow'; class ContactsPage extends StatefulWidget { const ContactsPage({super.key}); @override State createState() => _ContactsPageState(); } class _ContactsPageState extends State { @override void initState() { super.initState(); } @override Widget build(BuildContext context) { final theme = Theme.of(context); final scaleTheme = theme.extension()!; final appBarTheme = scaleTheme.appBarTheme(); final scaleScheme = theme.extension()!; final scale = scaleScheme.scale(ScaleKind.primary); final enableSplit = !isMobileSize(context); final enableLeft = enableSplit || _selectedContact == null; final enableRight = enableSplit || _selectedContact != null; return StyledScaffold( appBar: DefaultAppBar( title: Text( !enableSplit && enableRight ? translate('contacts_dialog.edit_contact') : translate('contacts_dialog.contacts'), ), leading: IconButton( icon: const Icon(Icons.arrow_back), onPressed: () { singleFuture((this, _kDoBackArrow), () async { final confirmed = await _onContactSelected(null); if (!enableSplit && enableRight) { } else { if (confirmed) { if (context.mounted) { Navigator.pop(context); } } } }); }, ), actions: [ if (_selectedContact != null) IconButton( icon: const Icon(Icons.chat_bubble), iconSize: 24, color: appBarTheme.iconColor, tooltip: translate('contacts_dialog.new_chat'), onPressed: () async { await _onChatStarted(_selectedContact!); }).paddingLTRB(8, 0, 8, 0), if (enableSplit && _selectedContact != null) IconButton( icon: const Icon(Icons.close), iconSize: 24, color: appBarTheme.iconColor, tooltip: translate('contacts_dialog.close_contact'), onPressed: () async { await _onContactSelected(null); }).paddingLTRB(8, 0, 8, 0), ]), body: LayoutBuilder(builder: (context, constraint) { final maxWidth = constraint.maxWidth; return ColoredBox( color: scale.appBackground, child: Row(crossAxisAlignment: CrossAxisAlignment.start, children: [ Offstage( offstage: !enableLeft, child: SizedBox( width: enableLeft && !enableRight ? maxWidth : (maxWidth / 3).clamp(200, 500), child: DecoratedBox( decoration: BoxDecoration(color: scale.subtleBackground), child: ContactsBrowser( selectedContactRecordKey: _selectedContact ?.localConversationRecordKey .toVeilid(), onContactSelected: _onContactSelected, onStartChat: _onChatStarted, ).paddingLTRB(4, 0, 4, 8)))), if (enableRight && enableLeft) Container( constraints: const BoxConstraints(minWidth: 1, maxWidth: 1), color: scale.subtleBorder), if (enableRight) if (_selectedContact == null) const NoContactWidget().expanded() else ContactDetailsWidget( contact: _selectedContact!, onModifiedState: _onModifiedState) .paddingLTRB(16, 16, 16, 16) .expanded(), ])); })); } void _onModifiedState(bool isModified) { setState(() { _isModified = isModified; }); } Future _onContactSelected(proto.Contact? contact) async { if (contact != _selectedContact && _isModified) { final ok = await showConfirmModal( context: context, title: translate('confirmation.discard_changes'), text: translate('confirmation.are_you_sure_discard')); if (!ok) { return false; } } setState(() { _selectedContact = contact; _isModified = false; }); return true; } Future _onChatStarted(proto.Contact contact) async { final chatListCubit = context.read(); await chatListCubit.getOrCreateChatSingleContact(contact: contact); if (mounted) { context .read() .setActiveChat(contact.localConversationRecordKey.toVeilid()); Navigator.pop(context); } } proto.Contact? _selectedContact; bool _isModified = false; }