TF-1074 Handle go to path /contact
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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
|
||||
];
|
||||
|
||||
@@ -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';
|
||||
|
||||
Reference in New Issue
Block a user