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:jmap_dart_client/jmap/mail/email/email_address.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_view.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() {
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/main/routes/route_navigation.dart';
typedef OnSelectedContactCallback = Function(EmailAddress emailAddress);
class ContactController extends BaseController {
final textInputSearchController = TextEditingController();
final textInputSearchFocus = FocusNode();
TextEditingController? textInputSearchController;
FocusNode? textInputSearchFocus;
ContactSuggestionSource _contactSuggestionSource = ContactSuggestionSource.tMailContact;
final searchQuery = SearchQuery.initial().obs;
@@ -34,22 +36,28 @@ class ContactController extends BaseController {
late AccountId _accountId;
late Session _session;
ContactArguments? arguments;
EmailAddress? contactSelected;
OnSelectedContactCallback? onSelectedContactCallback;
VoidCallback? onDismissContactView;
@override
void onInit() {
super.onInit();
textInputSearchController = TextEditingController();
textInputSearchFocus = FocusNode();
_initializeDebounceTimeTextSearchChange();
}
@override
void onReady() async {
textInputSearchFocus.requestFocus();
final arguments = Get.arguments;
if (arguments is ContactArguments) {
_accountId = arguments.accountId;
_session = arguments.session;
final listContactSelected = arguments.listContactSelected;
textInputSearchFocus?.requestFocus();
if (arguments != null) {
_accountId = arguments!.accountId;
_session = arguments!.session;
final listContactSelected = arguments!.listContactSelected;
log('ContactController::onReady(): arguments: $arguments');
log('ContactController::onReady(): listContactSelected: $listContactSelected');
if (listContactSelected.isNotEmpty) {
contactSelected = EmailAddress(listContactSelected.first, listContactSelected.first);
}
@@ -65,7 +73,10 @@ class ContactController extends BaseController {
@override
void onClose() {
textInputSearchController.dispose();
textInputSearchController?.dispose();
textInputSearchController = null;
textInputSearchFocus?.dispose();
textInputSearchFocus = null;
_deBouncerTime.cancel();
super.onClose();
}
@@ -85,9 +96,9 @@ class ContactController extends BaseController {
}
void clearAllTextInputSearchForm() {
textInputSearchController.clear();
textInputSearchController?.clear();
searchQuery.value = SearchQuery.initial();
textInputSearchFocus.requestFocus();
textInputSearchFocus?.requestFocus();
}
void _checkContactPermission() async {
@@ -158,13 +169,35 @@ class ContactController extends BaseController {
void selectContact(BuildContext context, EmailAddress emailAddress) {
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) {
clearAllTextInputSearchForm();
FocusScope.of(context).unfocus();
popBack();
if (BuildUtils.isWeb) {
textInputSearchFocus?.dispose();
textInputSearchFocus = null;
textInputSearchController?.dispose();
textInputSearchController = null;
_deBouncerTime.cancel();
onDismissContactView?.call();
} else {
popBack();
}
}
@override
@@ -9,6 +9,7 @@ import 'package:get/get.dart';
import 'package:jmap_dart_client/jmap/mail/email/email_address.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/model/contact_arguments.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/thread/presentation/widgets/search_app_bar_widget.dart';
@@ -19,16 +20,27 @@ class ContactView extends GetWidget<ContactController> {
final _responsiveUtils = Get.find<ResponsiveUtils>();
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
Widget build(BuildContext context) {
if (_responsiveUtils.isWebDesktop(context)) {
WidgetsBinding.instance.addPostFrameCallback((_) {
controller.closeContactView(context);
});
}
return Scaffold(
backgroundColor: Colors.black38,
body: GestureDetector(
@@ -37,7 +37,7 @@ class AppBarContactWidget extends StatelessWidget {
onTap: onCloseContactView),
),
Center(child: Text(
AppLocalizations.of(context).contains,
AppLocalizations.of(context).contact,
style: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
@@ -453,55 +453,89 @@ class SearchEmailController extends BaseController
) async {
if (accountId != null && session != null) {
final listContactSelected = simpleSearchFilter.value.getContactApplied(prefixEmailAddress);
final newContact = await push(
AppRoutes.contact,
arguments: ContactArguments(accountId!, session!, listContactSelected));
final arguments = ContactArguments(accountId!, session!, listContactSelected);
if (newContact is EmailAddress) {
if (listContactSelected.isNotEmpty) {
switch(prefixEmailAddress) {
case PrefixEmailAddress.from:
listContactSelected.first == newContact.email
? simpleSearchFilter.value.from.removeWhere((e) => e == newContact.email!)
: simpleSearchFilter.value.from.add(newContact.email!);
break;
case PrefixEmailAddress.to:
listContactSelected.first == newContact.email
? simpleSearchFilter.value.to.removeWhere((e) => e == newContact.email!)
: 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;
}
if (BuildUtils.isWeb) {
showDialogContactView(
context: context,
arguments: arguments,
onSelectedContact: (newContact) {
_dispatchApplyContactAction(
context,
listContactSelected,
prefixEmailAddress,
newContact);
});
} else {
final newContact = await push(
AppRoutes.contact,
arguments: arguments);
if (newContact is EmailAddress) {
_dispatchApplyContactAction(
context,
listContactSelected,
prefixEmailAddress,
newContact);
}
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({
Set<String>? from,
Set<String>? to,
+5 -5
View File
@@ -47,6 +47,11 @@ class AppPages {
opaque: false,
page: () => DeferredWidget(mailbox_creator.loadLibrary, () => mailbox_creator.MailboxCreatorView()),
binding: MailboxCreatorBindings()),
GetPage(
name: AppRoutes.contact,
opaque: false,
page: () => DeferredWidget(contact_view.loadLibrary, () => contact_view.ContactView()),
binding: ContactBindings()),
];
static final pages = [
@@ -89,11 +94,6 @@ class AppPages {
page: () => DeferredWidget(emails_forward_creator.loadLibrary,
() => emails_forward_creator.EmailsForwardCreatorView()),
binding: EmailsForwardCreatorBindings()),
GetPage(
name: AppRoutes.contact,
opaque: false,
page: () => DeferredWidget(contact_view.loadLibrary, () => contact_view.ContactView()),
binding: ContactBindings()),
if (!BuildUtils.isWeb)
...pagesOnlyOnMobile
];
+1 -1
View File
@@ -8,7 +8,7 @@ abstract class AppRoutes {
static const composer = '/composer';
static const destinationPicker = '/destination_picker';
static const mailboxCreator = '/mailbox_creator';
static const contact = '$dashboard/contact';
static const contact = '/contact';
static const identityCreator = '$settings/identity_creator';
static const rulesFilterCreator = '$settings/rules_filter_creator';
static const emailsForwardCreator = '$settings/emails_forward_creator';