TF-1513 Fix rich text toolbar lost on mobile
This commit is contained in:
@@ -314,6 +314,17 @@ class ComposerController extends BaseController {
|
|||||||
void createFocusNodeInput() {
|
void createFocusNodeInput() {
|
||||||
toAddressFocusNode = FocusNode();
|
toAddressFocusNode = FocusNode();
|
||||||
subjectEmailInputFocusNode = FocusNode();
|
subjectEmailInputFocusNode = FocusNode();
|
||||||
|
|
||||||
|
subjectEmailInputFocusNode?.addListener(() {
|
||||||
|
log('ComposerController::createFocusNodeInput():subjectEmailInputFocusNode: ${subjectEmailInputFocusNode?.hasFocus}');
|
||||||
|
if (subjectEmailInputFocusNode?.hasFocus == true) {
|
||||||
|
if (!BuildUtils.isWeb) {
|
||||||
|
htmlEditorApi?.unfocus();
|
||||||
|
}
|
||||||
|
_collapseAllRecipient();
|
||||||
|
_autoCreateEmailTag();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void initRichTextForMobile(BuildContext context, HtmlEditorApi editorApi) {
|
void initRichTextForMobile(BuildContext context, HtmlEditorApi editorApi) {
|
||||||
@@ -322,14 +333,8 @@ class ComposerController extends BaseController {
|
|||||||
editorApi,
|
editorApi,
|
||||||
onEnterKeyDown: _onEnterKeyDown,
|
onEnterKeyDown: _onEnterKeyDown,
|
||||||
context: context,
|
context: context,
|
||||||
|
onFocus: _onEditorFocusOnMobile
|
||||||
);
|
);
|
||||||
|
|
||||||
richTextMobileTabletController.htmlEditorApi?.onFocus = () {
|
|
||||||
FocusManager.instance.primaryFocus?.unfocus();
|
|
||||||
|
|
||||||
_collapseAllRecipient();
|
|
||||||
_autoCreateEmailTag();
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _initEmail() {
|
void _initEmail() {
|
||||||
@@ -1170,15 +1175,6 @@ class ComposerController extends BaseController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void onSubjectEmailFocusChange(bool isFocus) {
|
|
||||||
log('ComposerController::onSubjectEmailFocusChange(): Focus: $isFocus');
|
|
||||||
if (isFocus) {
|
|
||||||
_collapseAllRecipient();
|
|
||||||
htmlEditorApi?.unfocus();
|
|
||||||
_autoCreateEmailTag();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void onEditorFocusChange(bool isFocus) {
|
void onEditorFocusChange(bool isFocus) {
|
||||||
log('ComposerController::onEditorFocusChange(): Focus: $isFocus');
|
log('ComposerController::onEditorFocusChange(): Focus: $isFocus');
|
||||||
if (isFocus) {
|
if (isFocus) {
|
||||||
@@ -1312,6 +1308,9 @@ class ComposerController extends BaseController {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
_closeSuggestionBox();
|
_closeSuggestionBox();
|
||||||
|
if (!BuildUtils.isWeb) {
|
||||||
|
htmlEditorApi?.unfocus();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (!BuildUtils.isWeb) {
|
if (!BuildUtils.isWeb) {
|
||||||
_collapseAllRecipient();
|
_collapseAllRecipient();
|
||||||
@@ -1507,6 +1506,13 @@ class ComposerController extends BaseController {
|
|||||||
popBack();
|
popBack();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _onEditorFocusOnMobile() {
|
||||||
|
if (Platform.isAndroid) {
|
||||||
|
_collapseAllRecipient();
|
||||||
|
_autoCreateEmailTag();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void _onEnterKeyDown() {
|
void _onEnterKeyDown() {
|
||||||
if(scrollController.position.pixels < scrollController.position.maxScrollExtent) {
|
if(scrollController.position.pixels < scrollController.position.maxScrollExtent) {
|
||||||
scrollController.animateTo(
|
scrollController.animateTo(
|
||||||
|
|||||||
@@ -337,115 +337,100 @@ class ComposerView extends GetWidget<ComposerController>
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildEmailAddress(BuildContext context) {
|
Widget _buildEmailAddress(BuildContext context) {
|
||||||
return Focus(
|
return Column(
|
||||||
onFocusChange: (focus) {
|
children: [
|
||||||
if(focus) {
|
Obx(() => Padding(
|
||||||
controller.htmlEditorApi?.unfocus();
|
padding: EdgeInsets.only(left: responsiveUtils.isMobile(context) ? 16 : 0),
|
||||||
controller.keyboardRichTextController.hideRichTextView();
|
child: (EmailAddressInputBuilder(context, imagePaths,
|
||||||
}
|
PrefixEmailAddress.to,
|
||||||
},
|
controller.listToEmailAddress,
|
||||||
child: Column(
|
controller.listEmailAddressType,
|
||||||
children: [
|
expandMode: controller.toAddressExpandMode.value,
|
||||||
Obx(() => Padding(
|
controller: controller.toEmailAddressController,
|
||||||
padding: EdgeInsets.only(left: responsiveUtils.isMobile(context) ? 16 : 0),
|
focusNode: controller.toAddressFocusNode,
|
||||||
child: (EmailAddressInputBuilder(context, imagePaths,
|
autoDisposeFocusNode: false,
|
||||||
PrefixEmailAddress.to,
|
keyTagEditor: controller.keyToEmailTagEditor,
|
||||||
controller.listToEmailAddress,
|
isInitial: controller.isInitialRecipient.value)
|
||||||
controller.listEmailAddressType,
|
..addOnFocusEmailAddressChangeAction((prefixEmailAddress, focus) => controller.onEmailAddressFocusChange(prefixEmailAddress, focus))
|
||||||
expandMode: controller.toAddressExpandMode.value,
|
..addOnShowFullListEmailAddressAction((prefixEmailAddress) => controller.showFullEmailAddress(prefixEmailAddress))
|
||||||
controller: controller.toEmailAddressController,
|
..addOnAddEmailAddressTypeAction((prefixEmailAddress) => controller.addEmailAddressType(prefixEmailAddress))
|
||||||
focusNode: controller.toAddressFocusNode,
|
..addOnUpdateListEmailAddressAction((prefixEmailAddress, listEmailAddress) => controller.updateListEmailAddress(prefixEmailAddress, listEmailAddress))
|
||||||
autoDisposeFocusNode: false,
|
..addOnSuggestionEmailAddress((word) => controller.getAutoCompleteSuggestion(word)))
|
||||||
keyTagEditor: controller.keyToEmailTagEditor,
|
.build()
|
||||||
isInitial: controller.isInitialRecipient.value)
|
)),
|
||||||
..addOnFocusEmailAddressChangeAction((prefixEmailAddress, focus) => controller.onEmailAddressFocusChange(prefixEmailAddress, focus))
|
Obx(() => controller.listEmailAddressType.contains(PrefixEmailAddress.cc) == true
|
||||||
..addOnShowFullListEmailAddressAction((prefixEmailAddress) => controller.showFullEmailAddress(prefixEmailAddress))
|
? const Divider(color: AppColor.colorDividerComposer, height: 1)
|
||||||
..addOnAddEmailAddressTypeAction((prefixEmailAddress) => controller.addEmailAddressType(prefixEmailAddress))
|
: const SizedBox.shrink()),
|
||||||
..addOnUpdateListEmailAddressAction((prefixEmailAddress, listEmailAddress) => controller.updateListEmailAddress(prefixEmailAddress, listEmailAddress))
|
Obx(() => controller.listEmailAddressType.contains(PrefixEmailAddress.cc) == true
|
||||||
..addOnSuggestionEmailAddress((word) => controller.getAutoCompleteSuggestion(word)))
|
? Padding(
|
||||||
.build()
|
padding: EdgeInsets.only(left: responsiveUtils.isMobile(context) ? 16 : 0),
|
||||||
)),
|
child: (EmailAddressInputBuilder(context, imagePaths,
|
||||||
Obx(() => controller.listEmailAddressType.contains(PrefixEmailAddress.cc) == true
|
PrefixEmailAddress.cc,
|
||||||
? const Divider(color: AppColor.colorDividerComposer, height: 1)
|
controller.listCcEmailAddress,
|
||||||
: const SizedBox.shrink()),
|
controller.listEmailAddressType,
|
||||||
Obx(() => controller.listEmailAddressType.contains(PrefixEmailAddress.cc) == true
|
expandMode: controller.ccAddressExpandMode.value,
|
||||||
? Padding(
|
controller: controller.ccEmailAddressController,
|
||||||
padding: EdgeInsets.only(left: responsiveUtils.isMobile(context) ? 16 : 0),
|
keyTagEditor: controller.keyCcEmailTagEditor,
|
||||||
child: (EmailAddressInputBuilder(context, imagePaths,
|
isInitial: controller.isInitialRecipient.value,)
|
||||||
PrefixEmailAddress.cc,
|
..addOnFocusEmailAddressChangeAction((prefixEmailAddress, focus) => controller.onEmailAddressFocusChange(prefixEmailAddress, focus))
|
||||||
controller.listCcEmailAddress,
|
..addOnShowFullListEmailAddressAction((prefixEmailAddress) => controller.showFullEmailAddress(prefixEmailAddress))
|
||||||
controller.listEmailAddressType,
|
..addOnDeleteEmailAddressTypeAction((prefixEmailAddress) => controller.deleteEmailAddressType(prefixEmailAddress))
|
||||||
expandMode: controller.ccAddressExpandMode.value,
|
..addOnUpdateListEmailAddressAction((prefixEmailAddress, listEmailAddress) => controller.updateListEmailAddress(prefixEmailAddress, listEmailAddress))
|
||||||
controller: controller.ccEmailAddressController,
|
..addOnSuggestionEmailAddress((word) => controller.getAutoCompleteSuggestion(word)))
|
||||||
keyTagEditor: controller.keyCcEmailTagEditor,
|
.build())
|
||||||
isInitial: controller.isInitialRecipient.value,)
|
: const SizedBox.shrink()
|
||||||
..addOnFocusEmailAddressChangeAction((prefixEmailAddress, focus) => controller.onEmailAddressFocusChange(prefixEmailAddress, focus))
|
),
|
||||||
..addOnShowFullListEmailAddressAction((prefixEmailAddress) => controller.showFullEmailAddress(prefixEmailAddress))
|
Obx(() => controller.listEmailAddressType.contains(PrefixEmailAddress.bcc) == true
|
||||||
..addOnDeleteEmailAddressTypeAction((prefixEmailAddress) => controller.deleteEmailAddressType(prefixEmailAddress))
|
? const Divider(color: AppColor.colorDividerComposer, height: 1)
|
||||||
..addOnUpdateListEmailAddressAction((prefixEmailAddress, listEmailAddress) => controller.updateListEmailAddress(prefixEmailAddress, listEmailAddress))
|
: const SizedBox.shrink()),
|
||||||
..addOnSuggestionEmailAddress((word) => controller.getAutoCompleteSuggestion(word)))
|
Obx(() => controller.listEmailAddressType.contains(PrefixEmailAddress.bcc) == true
|
||||||
.build())
|
? Padding(
|
||||||
: const SizedBox.shrink()
|
padding: EdgeInsets.only(left: responsiveUtils.isMobile(context) ? 16 : 0),
|
||||||
),
|
child: (EmailAddressInputBuilder(context, imagePaths,
|
||||||
Obx(() => controller.listEmailAddressType.contains(PrefixEmailAddress.bcc) == true
|
PrefixEmailAddress.bcc,
|
||||||
? const Divider(color: AppColor.colorDividerComposer, height: 1)
|
controller.listBccEmailAddress,
|
||||||
: const SizedBox.shrink()),
|
controller.listEmailAddressType,
|
||||||
Obx(() => controller.listEmailAddressType.contains(PrefixEmailAddress.bcc) == true
|
expandMode: controller.bccAddressExpandMode.value,
|
||||||
? Padding(
|
controller: controller.bccEmailAddressController,
|
||||||
padding: EdgeInsets.only(left: responsiveUtils.isMobile(context) ? 16 : 0),
|
keyTagEditor: controller.keyBccEmailTagEditor,
|
||||||
child: (EmailAddressInputBuilder(context, imagePaths,
|
isInitial: controller.isInitialRecipient.value,)
|
||||||
PrefixEmailAddress.bcc,
|
..addOnFocusEmailAddressChangeAction((prefixEmailAddress, focus) => controller.onEmailAddressFocusChange(prefixEmailAddress, focus))
|
||||||
controller.listBccEmailAddress,
|
..addOnShowFullListEmailAddressAction((prefixEmailAddress) => controller.showFullEmailAddress(prefixEmailAddress))
|
||||||
controller.listEmailAddressType,
|
..addOnDeleteEmailAddressTypeAction((prefixEmailAddress) => controller.deleteEmailAddressType(prefixEmailAddress))
|
||||||
expandMode: controller.bccAddressExpandMode.value,
|
..addOnUpdateListEmailAddressAction((prefixEmailAddress, listEmailAddress) => controller.updateListEmailAddress(prefixEmailAddress, listEmailAddress))
|
||||||
controller: controller.bccEmailAddressController,
|
..addOnSuggestionEmailAddress((word) => controller.getAutoCompleteSuggestion(word)))
|
||||||
keyTagEditor: controller.keyBccEmailTagEditor,
|
.build())
|
||||||
isInitial: controller.isInitialRecipient.value,)
|
: const SizedBox.shrink()
|
||||||
..addOnFocusEmailAddressChangeAction((prefixEmailAddress, focus) => controller.onEmailAddressFocusChange(prefixEmailAddress, focus))
|
),
|
||||||
..addOnShowFullListEmailAddressAction((prefixEmailAddress) => controller.showFullEmailAddress(prefixEmailAddress))
|
],
|
||||||
..addOnDeleteEmailAddressTypeAction((prefixEmailAddress) => controller.deleteEmailAddressType(prefixEmailAddress))
|
|
||||||
..addOnUpdateListEmailAddressAction((prefixEmailAddress, listEmailAddress) => controller.updateListEmailAddress(prefixEmailAddress, listEmailAddress))
|
|
||||||
..addOnSuggestionEmailAddress((word) => controller.getAutoCompleteSuggestion(word)))
|
|
||||||
.build())
|
|
||||||
: const SizedBox.shrink()
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildSubjectEmail(BuildContext context) {
|
Widget _buildSubjectEmail(BuildContext context) {
|
||||||
return Focus(
|
log('ComposerView::_buildSubjectEmail(): ');
|
||||||
onFocusChange: (focus) {
|
return Row(
|
||||||
if(focus) {
|
children: [
|
||||||
controller.htmlEditorApi?.unfocus();
|
Padding(
|
||||||
controller.keyboardRichTextController.hideRichTextView();
|
padding: const EdgeInsets.only(right: 8),
|
||||||
}
|
child: Text(
|
||||||
},
|
'${AppLocalizations.of(context).subject_email}:',
|
||||||
child: Row(
|
style: const TextStyle(
|
||||||
children: [
|
fontSize: 15,
|
||||||
Padding(
|
color: AppColor.colorHintEmailAddressInput
|
||||||
padding: const EdgeInsets.only(right: 8),
|
|
||||||
child: Text(
|
|
||||||
'${AppLocalizations.of(context).subject_email}:',
|
|
||||||
style: const TextStyle(fontSize: 15, color: AppColor.colorHintEmailAddressInput))),
|
|
||||||
Expanded(
|
|
||||||
child: FocusScope(child: Focus(
|
|
||||||
onFocusChange: (focus) => controller.onSubjectEmailFocusChange(focus),
|
|
||||||
child: (TextFieldBuilder()
|
|
||||||
..key(const Key('subject_email_input'))
|
|
||||||
..cursorColor(AppColor.colorTextButton)
|
|
||||||
..maxLines(responsiveUtils.isMobile(context) ? null : 1)
|
|
||||||
..addFocusNode(controller.subjectEmailInputFocusNode)
|
|
||||||
..onChange((value) => controller.setSubjectEmail(value))
|
|
||||||
..textStyle(const TextStyle(color: Colors.black, fontSize: 15, fontWeight: FontWeight.normal))
|
|
||||||
..textDecoration(const InputDecoration(contentPadding: EdgeInsets.zero, border: InputBorder.none))
|
|
||||||
..addController(controller.subjectEmailInputController))
|
|
||||||
.build(),
|
|
||||||
))
|
|
||||||
)
|
)
|
||||||
]
|
)
|
||||||
),
|
),
|
||||||
|
Expanded(child: (TextFieldBuilder()
|
||||||
|
..key(const Key('subject_email_input'))
|
||||||
|
..cursorColor(AppColor.colorTextButton)
|
||||||
|
..maxLines(responsiveUtils.isMobile(context) ? null : 1)
|
||||||
|
..addFocusNode(controller.subjectEmailInputFocusNode)
|
||||||
|
..onChange((value) => controller.setSubjectEmail(value))
|
||||||
|
..textStyle(const TextStyle(color: Colors.black, fontSize: 15, fontWeight: FontWeight.normal))
|
||||||
|
..textDecoration(const InputDecoration(contentPadding: EdgeInsets.zero, border: InputBorder.none))
|
||||||
|
..addController(controller.subjectEmailInputController))
|
||||||
|
.build())
|
||||||
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -544,28 +544,29 @@ class ComposerView extends GetWidget<ComposerController>
|
|||||||
|
|
||||||
Widget _buildSubjectEmail(BuildContext context) {
|
Widget _buildSubjectEmail(BuildContext context) {
|
||||||
return Row(
|
return Row(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
children: [
|
children: [
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.only(right: 8, top: 16),
|
padding: const EdgeInsets.only(right: 8, top: 16),
|
||||||
child: Text(
|
child: Text(
|
||||||
'${AppLocalizations.of(context).subject_email}:',
|
'${AppLocalizations.of(context).subject_email}:',
|
||||||
style: const TextStyle(fontSize: 15, color: AppColor.colorHintEmailAddressInput))),
|
style: const TextStyle(
|
||||||
Expanded(
|
fontSize: 15,
|
||||||
child: FocusScope(child: Focus(
|
color: AppColor.colorHintEmailAddressInput
|
||||||
onFocusChange: (focus) => controller.onSubjectEmailFocusChange(focus),
|
)
|
||||||
child: (TextFieldBuilder()
|
|
||||||
..key(const Key('subject_email_input'))
|
|
||||||
..cursorColor(AppColor.colorTextButton)
|
|
||||||
..addFocusNode(controller.subjectEmailInputFocusNode)
|
|
||||||
..onChange((value) => controller.setSubjectEmail(value))
|
|
||||||
..textStyle(const TextStyle(color: Colors.black, fontSize: 15, fontWeight: FontWeight.normal))
|
|
||||||
..textDecoration(const InputDecoration(contentPadding: EdgeInsets.zero, border: InputBorder.none))
|
|
||||||
..addController(controller.subjectEmailInputController))
|
|
||||||
.build(),
|
|
||||||
))
|
|
||||||
)
|
)
|
||||||
]
|
),
|
||||||
|
Expanded(child: (TextFieldBuilder()
|
||||||
|
..key(const Key('subject_email_input'))
|
||||||
|
..cursorColor(AppColor.colorTextButton)
|
||||||
|
..addFocusNode(controller.subjectEmailInputFocusNode)
|
||||||
|
..onChange((value) => controller.setSubjectEmail(value))
|
||||||
|
..textStyle(const TextStyle(color: Colors.black, fontSize: 15, fontWeight: FontWeight.normal))
|
||||||
|
..textDecoration(const InputDecoration(contentPadding: EdgeInsets.zero, border: InputBorder.none))
|
||||||
|
..addController(controller.subjectEmailInputController))
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user