TF-1074 Handle go to path /contact

This commit is contained in:
dab246
2022-10-25 01:07:39 +07:00
committed by Dat H. Pham
parent 50bba630d5
commit f2ab8136f8
8 changed files with 185 additions and 70 deletions
@@ -1,6 +1,10 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
import 'package:model/mailbox/presentation_mailbox.dart'; import 'package:model/mailbox/presentation_mailbox.dart';
import 'package:tmail_ui_user/features/contact/presentation/contact_bindings.dart';
import 'package:tmail_ui_user/features/contact/presentation/contact_view.dart';
import 'package:tmail_ui_user/features/contact/presentation/model/contact_arguments.dart';
import 'package:tmail_ui_user/features/destination_picker/presentation/destination_picker_bindings.dart'; import 'package:tmail_ui_user/features/destination_picker/presentation/destination_picker_bindings.dart';
import 'package:tmail_ui_user/features/destination_picker/presentation/destination_picker_view.dart'; import 'package:tmail_ui_user/features/destination_picker/presentation/destination_picker_view.dart';
import 'package:tmail_ui_user/features/destination_picker/presentation/model/destination_picker_arguments.dart'; import 'package:tmail_ui_user/features/destination_picker/presentation/model/destination_picker_arguments.dart';
@@ -71,4 +75,32 @@ mixin ViewAsDialogActionMixin {
}); });
}); });
} }
void showDialogContactView({
required BuildContext context,
required ContactArguments arguments,
required Function(EmailAddress) onSelectedContact
}) {
ContactBindings().dependencies();
showGeneralDialog(
context: context,
barrierDismissible: true,
barrierLabel: '',
barrierColor: Colors.black.withAlpha(24),
pageBuilder: (context, animation, secondaryAnimation) {
return ContactView.fromArguments(
arguments,
onDismissCallback: () {
ContactBindings().dispose();
popBack();
},
onSelectedContactCallback: (emailAddress) {
ContactBindings().dispose();
popBack();
onSelectedContact.call(emailAddress);
});
});
}
} }
@@ -8,4 +8,8 @@ class ContactBindings extends Bindings {
void dependencies() { void dependencies() {
Get.lazyPut(() => ContactController()); Get.lazyPut(() => ContactController());
} }
void dispose() {
Get.delete<ContactController>();
}
} }
@@ -18,10 +18,12 @@ import 'package:tmail_ui_user/features/contact/presentation/model/contact_argume
import 'package:tmail_ui_user/features/thread/domain/model/search_query.dart'; import 'package:tmail_ui_user/features/thread/domain/model/search_query.dart';
import 'package:tmail_ui_user/main/routes/route_navigation.dart'; import 'package:tmail_ui_user/main/routes/route_navigation.dart';
typedef OnSelectedContactCallback = Function(EmailAddress emailAddress);
class ContactController extends BaseController { class ContactController extends BaseController {
final textInputSearchController = TextEditingController(); TextEditingController? textInputSearchController;
final textInputSearchFocus = FocusNode(); FocusNode? textInputSearchFocus;
ContactSuggestionSource _contactSuggestionSource = ContactSuggestionSource.tMailContact; ContactSuggestionSource _contactSuggestionSource = ContactSuggestionSource.tMailContact;
final searchQuery = SearchQuery.initial().obs; final searchQuery = SearchQuery.initial().obs;
@@ -34,22 +36,28 @@ class ContactController extends BaseController {
late AccountId _accountId; late AccountId _accountId;
late Session _session; late Session _session;
ContactArguments? arguments;
EmailAddress? contactSelected; EmailAddress? contactSelected;
OnSelectedContactCallback? onSelectedContactCallback;
VoidCallback? onDismissContactView;
@override @override
void onInit() { void onInit() {
super.onInit(); super.onInit();
textInputSearchController = TextEditingController();
textInputSearchFocus = FocusNode();
_initializeDebounceTimeTextSearchChange(); _initializeDebounceTimeTextSearchChange();
} }
@override @override
void onReady() async { void onReady() async {
textInputSearchFocus.requestFocus(); textInputSearchFocus?.requestFocus();
final arguments = Get.arguments; if (arguments != null) {
if (arguments is ContactArguments) { _accountId = arguments!.accountId;
_accountId = arguments.accountId; _session = arguments!.session;
_session = arguments.session; final listContactSelected = arguments!.listContactSelected;
final listContactSelected = arguments.listContactSelected; log('ContactController::onReady(): arguments: $arguments');
log('ContactController::onReady(): listContactSelected: $listContactSelected');
if (listContactSelected.isNotEmpty) { if (listContactSelected.isNotEmpty) {
contactSelected = EmailAddress(listContactSelected.first, listContactSelected.first); contactSelected = EmailAddress(listContactSelected.first, listContactSelected.first);
} }
@@ -65,7 +73,10 @@ class ContactController extends BaseController {
@override @override
void onClose() { void onClose() {
textInputSearchController.dispose(); textInputSearchController?.dispose();
textInputSearchController = null;
textInputSearchFocus?.dispose();
textInputSearchFocus = null;
_deBouncerTime.cancel(); _deBouncerTime.cancel();
super.onClose(); super.onClose();
} }
@@ -85,9 +96,9 @@ class ContactController extends BaseController {
} }
void clearAllTextInputSearchForm() { void clearAllTextInputSearchForm() {
textInputSearchController.clear(); textInputSearchController?.clear();
searchQuery.value = SearchQuery.initial(); searchQuery.value = SearchQuery.initial();
textInputSearchFocus.requestFocus(); textInputSearchFocus?.requestFocus();
} }
void _checkContactPermission() async { void _checkContactPermission() async {
@@ -158,13 +169,35 @@ class ContactController extends BaseController {
void selectContact(BuildContext context, EmailAddress emailAddress) { void selectContact(BuildContext context, EmailAddress emailAddress) {
FocusScope.of(context).unfocus(); FocusScope.of(context).unfocus();
popBack(result: emailAddress);
if (BuildUtils.isWeb) {
textInputSearchFocus?.dispose();
textInputSearchFocus = null;
textInputSearchController?.dispose();
textInputSearchController = null;
_deBouncerTime.cancel();
onSelectedContactCallback?.call(emailAddress);
} else {
popBack(result: emailAddress);
}
} }
void closeContactView(BuildContext context) { void closeContactView(BuildContext context) {
clearAllTextInputSearchForm(); clearAllTextInputSearchForm();
FocusScope.of(context).unfocus(); FocusScope.of(context).unfocus();
popBack();
if (BuildUtils.isWeb) {
textInputSearchFocus?.dispose();
textInputSearchFocus = null;
textInputSearchController?.dispose();
textInputSearchController = null;
_deBouncerTime.cancel();
onDismissContactView?.call();
} else {
popBack();
}
} }
@override @override
@@ -9,6 +9,7 @@ import 'package:get/get.dart';
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart'; import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
import 'package:model/extensions/email_address_extension.dart'; import 'package:model/extensions/email_address_extension.dart';
import 'package:tmail_ui_user/features/contact/presentation/contact_controller.dart'; import 'package:tmail_ui_user/features/contact/presentation/contact_controller.dart';
import 'package:tmail_ui_user/features/contact/presentation/model/contact_arguments.dart';
import 'package:tmail_ui_user/features/contact/presentation/utils/contact_utils.dart'; import 'package:tmail_ui_user/features/contact/presentation/utils/contact_utils.dart';
import 'package:tmail_ui_user/features/contact/presentation/widgets/app_bar_contact_widget.dart'; import 'package:tmail_ui_user/features/contact/presentation/widgets/app_bar_contact_widget.dart';
import 'package:tmail_ui_user/features/thread/presentation/widgets/search_app_bar_widget.dart'; import 'package:tmail_ui_user/features/thread/presentation/widgets/search_app_bar_widget.dart';
@@ -19,16 +20,27 @@ class ContactView extends GetWidget<ContactController> {
final _responsiveUtils = Get.find<ResponsiveUtils>(); final _responsiveUtils = Get.find<ResponsiveUtils>();
final _imagePaths = Get.find<ImagePaths>(); final _imagePaths = Get.find<ImagePaths>();
ContactView({Key? key}) : super(key: key); @override
final controller = Get.find<ContactController>();
ContactView({Key? key}) : super(key: key) {
controller.arguments = Get.arguments;
}
ContactView.fromArguments(
ContactArguments arguments, {
Key? key,
OnSelectedContactCallback? onSelectedContactCallback,
VoidCallback? onDismissCallback
}) : super(key: key) {
controller.arguments = arguments;
controller.onSelectedContactCallback = onSelectedContactCallback;
controller.onDismissContactView = onDismissCallback;
controller.onInit();
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
if (_responsiveUtils.isWebDesktop(context)) {
WidgetsBinding.instance.addPostFrameCallback((_) {
controller.closeContactView(context);
});
}
return Scaffold( return Scaffold(
backgroundColor: Colors.black38, backgroundColor: Colors.black38,
body: GestureDetector( body: GestureDetector(
@@ -37,7 +37,7 @@ class AppBarContactWidget extends StatelessWidget {
onTap: onCloseContactView), onTap: onCloseContactView),
), ),
Center(child: Text( Center(child: Text(
AppLocalizations.of(context).contains, AppLocalizations.of(context).contact,
style: const TextStyle( style: const TextStyle(
fontSize: 20, fontSize: 20,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
@@ -453,55 +453,89 @@ class SearchEmailController extends BaseController
) async { ) async {
if (accountId != null && session != null) { if (accountId != null && session != null) {
final listContactSelected = simpleSearchFilter.value.getContactApplied(prefixEmailAddress); final listContactSelected = simpleSearchFilter.value.getContactApplied(prefixEmailAddress);
final newContact = await push( final arguments = ContactArguments(accountId!, session!, listContactSelected);
AppRoutes.contact,
arguments: ContactArguments(accountId!, session!, listContactSelected));
if (newContact is EmailAddress) { if (BuildUtils.isWeb) {
if (listContactSelected.isNotEmpty) { showDialogContactView(
switch(prefixEmailAddress) { context: context,
case PrefixEmailAddress.from: arguments: arguments,
listContactSelected.first == newContact.email onSelectedContact: (newContact) {
? simpleSearchFilter.value.from.removeWhere((e) => e == newContact.email!) _dispatchApplyContactAction(
: simpleSearchFilter.value.from.add(newContact.email!); context,
break; listContactSelected,
case PrefixEmailAddress.to: prefixEmailAddress,
listContactSelected.first == newContact.email newContact);
? simpleSearchFilter.value.to.removeWhere((e) => e == newContact.email!) });
: simpleSearchFilter.value.to.add(newContact.email!); } else {
break; final newContact = await push(
default: AppRoutes.contact,
break; arguments: arguments);
}
} else { if (newContact is EmailAddress) {
switch(prefixEmailAddress) { _dispatchApplyContactAction(
case PrefixEmailAddress.from: context,
simpleSearchFilter.value.from.add(newContact.email!); listContactSelected,
break; prefixEmailAddress,
case PrefixEmailAddress.to: newContact);
simpleSearchFilter.value.to.add(newContact.email!);
break;
default:
break;
}
} }
switch(prefixEmailAddress) {
case PrefixEmailAddress.from:
_updateSimpleSearchFilter(from: simpleSearchFilter.value.from);
break;
case PrefixEmailAddress.to:
_updateSimpleSearchFilter(to: simpleSearchFilter.value.to);
break;
default:
break;
}
_searchEmailAction(context);
} }
} }
} }
void _dispatchApplyContactAction(
BuildContext context,
Set<String> listContactSelected,
PrefixEmailAddress prefixEmailAddress,
EmailAddress newContact
) {
if (listContactSelected.isNotEmpty) {
switch(prefixEmailAddress) {
case PrefixEmailAddress.from:
if (listContactSelected.first == newContact.email) {
simpleSearchFilter.value.from.clear();
} else {
simpleSearchFilter.value.from.clear();
simpleSearchFilter.value.from.add(newContact.email!);
}
break;
case PrefixEmailAddress.to:
if (listContactSelected.first == newContact.email) {
simpleSearchFilter.value.to.clear();
} else {
simpleSearchFilter.value.to.clear();
simpleSearchFilter.value.to.add(newContact.email!);
}
break;
default:
break;
}
} else {
switch(prefixEmailAddress) {
case PrefixEmailAddress.from:
simpleSearchFilter.value.from.add(newContact.email!);
break;
case PrefixEmailAddress.to:
simpleSearchFilter.value.to.add(newContact.email!);
break;
default:
break;
}
}
switch(prefixEmailAddress) {
case PrefixEmailAddress.from:
_updateSimpleSearchFilter(from: simpleSearchFilter.value.from);
break;
case PrefixEmailAddress.to:
_updateSimpleSearchFilter(to: simpleSearchFilter.value.to);
break;
default:
break;
}
_searchEmailAction(context);
}
void _updateSimpleSearchFilter({ void _updateSimpleSearchFilter({
Set<String>? from, Set<String>? from,
Set<String>? to, Set<String>? to,
+5 -5
View File
@@ -47,6 +47,11 @@ class AppPages {
opaque: false, opaque: false,
page: () => DeferredWidget(mailbox_creator.loadLibrary, () => mailbox_creator.MailboxCreatorView()), page: () => DeferredWidget(mailbox_creator.loadLibrary, () => mailbox_creator.MailboxCreatorView()),
binding: MailboxCreatorBindings()), binding: MailboxCreatorBindings()),
GetPage(
name: AppRoutes.contact,
opaque: false,
page: () => DeferredWidget(contact_view.loadLibrary, () => contact_view.ContactView()),
binding: ContactBindings()),
]; ];
static final pages = [ static final pages = [
@@ -89,11 +94,6 @@ class AppPages {
page: () => DeferredWidget(emails_forward_creator.loadLibrary, page: () => DeferredWidget(emails_forward_creator.loadLibrary,
() => emails_forward_creator.EmailsForwardCreatorView()), () => emails_forward_creator.EmailsForwardCreatorView()),
binding: EmailsForwardCreatorBindings()), binding: EmailsForwardCreatorBindings()),
GetPage(
name: AppRoutes.contact,
opaque: false,
page: () => DeferredWidget(contact_view.loadLibrary, () => contact_view.ContactView()),
binding: ContactBindings()),
if (!BuildUtils.isWeb) if (!BuildUtils.isWeb)
...pagesOnlyOnMobile ...pagesOnlyOnMobile
]; ];
+1 -1
View File
@@ -8,7 +8,7 @@ abstract class AppRoutes {
static const composer = '/composer'; static const composer = '/composer';
static const destinationPicker = '/destination_picker'; static const destinationPicker = '/destination_picker';
static const mailboxCreator = '/mailbox_creator'; static const mailboxCreator = '/mailbox_creator';
static const contact = '$dashboard/contact'; static const contact = '/contact';
static const identityCreator = '$settings/identity_creator'; static const identityCreator = '$settings/identity_creator';
static const rulesFilterCreator = '$settings/rules_filter_creator'; static const rulesFilterCreator = '$settings/rules_filter_creator';
static const emailsForwardCreator = '$settings/emails_forward_creator'; static const emailsForwardCreator = '$settings/emails_forward_creator';