TF-1679: Hide cursor of bcc when focus to html editor

(cherry picked from commit 588c9b4873ea40b75dd6e6cffbe80af21a4b287c)
This commit is contained in:
HuyNguyen
2023-04-05 02:20:43 +07:00
committed by Dat Vu
parent b19a85ac36
commit 28347bb7c1
5 changed files with 85 additions and 80 deletions
@@ -2,6 +2,7 @@
import 'package:core/utils/app_logger.dart';
import 'package:core/utils/build_utils.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/services.dart';
import 'package:get/get_core/get_core.dart';
import 'package:get/get_instance/get_instance.dart';
import 'package:get/get_rx/get_rx.dart';
@@ -63,6 +64,7 @@ class IdentityCreatorController extends BaseController {
TextEditingController? inputNameIdentityController;
TextEditingController? inputBccIdentityController;
FocusNode? inputNameIdentityFocusNode;
FocusNode? inputBccIdentityFocusNode;
String? _nameIdentity;
String? _contentHtmlEditor;
@@ -109,6 +111,7 @@ class IdentityCreatorController extends BaseController {
inputNameIdentityController = TextEditingController();
inputBccIdentityController = TextEditingController();
inputNameIdentityFocusNode = FocusNode();
inputBccIdentityFocusNode = FocusNode();
scrollController = ScrollController();
}
@@ -422,6 +425,7 @@ class IdentityCreatorController extends BaseController {
if (!BuildUtils.isWeb) {
keyboardRichTextController.htmlEditorApi?.unfocus();
}
SystemChannels.textInput.invokeMethod('TextInput.hide');
FocusScope.of(context).unfocus();
}
@@ -437,6 +441,8 @@ class IdentityCreatorController extends BaseController {
keyboardRichTextController.dispose();
inputNameIdentityFocusNode?.dispose();
inputNameIdentityFocusNode = null;
inputBccIdentityFocusNode?.dispose();
inputBccIdentityFocusNode = null;
inputNameIdentityController?.dispose();
inputNameIdentityController = null;
inputBccIdentityController?.dispose();
@@ -444,7 +450,19 @@ class IdentityCreatorController extends BaseController {
scrollController?.dispose();
}
void onFocusHTMLEditorOnMobile() async {
void initRichTextForMobile(BuildContext context, HtmlEditorApi editorApi) {
keyboardRichTextController.htmlEditorApi = editorApi;
keyboardRichTextController.onCreateHTMLEditor(
editorApi,
onEnterKeyDown: _onEnterKeyDownOnMobile,
onFocus: _onFocusHTMLEditorOnMobile,
context: context
);
}
void _onFocusHTMLEditorOnMobile() async {
inputBccIdentityFocusNode?.unfocus();
inputNameIdentityFocusNode?.unfocus();
if (scrollController != null) {
if (htmlKey.currentContext != null) {
await Scrollable.ensureVisible(htmlKey.currentContext!);
@@ -462,7 +480,7 @@ class IdentityCreatorController extends BaseController {
}
}
void onEnterKeyDownOnMobile() {
void _onEnterKeyDownOnMobile() {
if (scrollController != null && scrollController!.position.pixels < scrollController!.position.maxScrollExtent) {
scrollController!.animateTo(
scrollController!.position.pixels + 20,
@@ -237,7 +237,8 @@ class IdentityCreatorView extends GetWidget<IdentityCreatorController> {
Obx(() => (IdentityInputWithDropListFieldBuilder(
AppLocalizations.of(context).bcc_to,
controller.errorBccIdentity.value,
controller.inputBccIdentityController)
controller.inputBccIdentityController,
focusNode: controller.inputBccIdentityFocusNode)
..addOnSelectedSuggestionAction((newEmailAddress) {
controller.inputBccIdentityController?.text = newEmailAddress?.email ?? '';
controller.updateBccOfIdentity(newEmailAddress);
@@ -337,7 +338,9 @@ class IdentityCreatorView extends GetWidget<IdentityCreatorController> {
),
]
),
)] else ...[
),
const SizedBox(height: 35),
] else ...[
_buildActionBottomDesktop(context)
]
]),
@@ -346,48 +349,57 @@ class IdentityCreatorView extends GetWidget<IdentityCreatorController> {
return GestureDetector(
onTap: () => controller.clearFocusEditor(context),
child: Stack(
children: [
Column(children: [
child: Column(children: [
SizedBox(
width: double.infinity,
child: Stack(
children: [
Positioned(right: 8, top: 2,
child: buildIconWeb(
iconSize: 24,
icon: SvgPicture.asset(
_imagePaths.icComposerClose,
fit: BoxFit.fill,
colorFilter: AppColor.colorDeleteContactIcon.asFilter()
),
tooltip: AppLocalizations.of(context).close,
onTap: () => controller.closeView(context)),
),
Padding(
padding: const EdgeInsets.only(top: 14),
padding: const EdgeInsets.only(top: 14),
child: Align(
alignment: Alignment.center,
child: Obx(() {
return Text(controller.actionType.value == IdentityActionType.create
? AppLocalizations.of(context).createNewIdentity.inCaps
: AppLocalizations.of(context).edit_identity.inCaps,
? AppLocalizations.of(context).createNewIdentity.inCaps
: AppLocalizations.of(context).edit_identity.inCaps,
style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 20, color: Colors.black));
})),
const SizedBox(height: 8),
Expanded(
child: BuildUtils.isWeb
? PointerInterceptor(child: bodyCreatorView)
: KeyboardRichText(
keyBroadToolbar: RichTextKeyboardToolBar(
titleBack: AppLocalizations.of(context).titleFormat,
backgroundKeyboardToolBarColor: AppColor.colorBackgroundKeyboard,
isLandScapeMode: _responsiveUtils.isLandscapeMobile(context),
richTextController: controller.keyboardRichTextController,
titleQuickStyleBottomSheet: AppLocalizations.of(context).titleQuickStyles,
titleBackgroundBottomSheet: AppLocalizations.of(context).titleBackground,
titleForegroundBottomSheet: AppLocalizations.of(context).titleForeground,
titleFormatBottomSheet: AppLocalizations.of(context).titleFormat,
),
richTextController: controller.keyboardRichTextController,
child: bodyCreatorView),
}),
),
),
]),
Positioned(top: 2, right: 8,
child: buildIconWeb(
iconSize: 24,
icon: SvgPicture.asset(
_imagePaths.icComposerClose,
fit: BoxFit.fill,
colorFilter: AppColor.colorDeleteContactIcon.asFilter()
),
tooltip: AppLocalizations.of(context).close,
onTap: () => controller.closeView(context)))
]
),
],
),
),
const SizedBox(height: 8),
Expanded(
child: BuildUtils.isWeb
? PointerInterceptor(child: bodyCreatorView)
: KeyboardRichText(
keyBroadToolbar: RichTextKeyboardToolBar(
titleBack: AppLocalizations.of(context).titleFormat,
backgroundKeyboardToolBarColor: AppColor.colorBackgroundKeyboard,
isLandScapeMode: _responsiveUtils.isLandscapeMobile(context),
richTextController: controller.keyboardRichTextController,
titleQuickStyleBottomSheet: AppLocalizations.of(context).titleQuickStyles,
titleBackgroundBottomSheet: AppLocalizations.of(context).titleBackground,
titleForegroundBottomSheet: AppLocalizations.of(context).titleForeground,
titleFormatBottomSheet: AppLocalizations.of(context).titleFormat,
),
richTextController: controller.keyboardRichTextController,
paddingChild: EdgeInsets.zero,
child: bodyCreatorView),
),
]),
);
}
@@ -458,14 +470,7 @@ class IdentityCreatorView extends GetWidget<IdentityCreatorController> {
minHeight: controller.htmlEditorMinHeight,
addDefaultSelectionMenuItems: false,
initialContent: initialContent ?? '',
onCreated: (editorApi) {
controller.keyboardRichTextController.onCreateHTMLEditor(
editorApi,
onEnterKeyDown: controller.onEnterKeyDownOnMobile,
onFocus: controller.onFocusHTMLEditorOnMobile,
context: context
);
},
onCreated: (editorApi) => controller.initRichTextForMobile(context, editorApi),
),
);
}
@@ -14,6 +14,7 @@ class IdentityInputWithDropListFieldBuilder {
final String _label;
final String? _error;
final TextEditingController? editingController;
final FocusNode? focusNode;
OnSelectedSuggestionAction? _onSelectedSuggestionAction;
OnSuggestionCallbackAction? _onSuggestionCallbackAction;
@@ -23,6 +24,9 @@ class IdentityInputWithDropListFieldBuilder {
this._label,
this._error,
this.editingController,
{
this.focusNode,
}
);
void addOnSelectedSuggestionAction(OnSelectedSuggestionAction action) {
@@ -46,13 +50,14 @@ class IdentityInputWithDropListFieldBuilder {
const SizedBox(height: 8),
TypeAheadFormField<EmailAddress>(
textFieldConfiguration: TextFieldConfiguration(
controller: editingController,
textInputAction: TextInputAction.done,
decoration: (IdentityInputDecorationBuilder()
..setContentPadding(const EdgeInsets.symmetric(
vertical: BuildUtils.isWeb ? 16 : 12,
horizontal: 12))
..setErrorText(_error))
focusNode: focusNode,
controller: editingController,
textInputAction: TextInputAction.done,
decoration: (IdentityInputDecorationBuilder()
..setContentPadding(const EdgeInsets.symmetric(
vertical: BuildUtils.isWeb ? 16 : 12,
horizontal: 12))
..setErrorText(_error))
.build()
),
debounceDuration: const Duration(milliseconds: 500),
@@ -53,7 +53,6 @@ class IdentitiesController extends BaseController {
final identitySelected = Rxn<Identity>();
final signatureSelected = Rxn<String>();
final _htmlSignature = Rxn<bool>();
final listAllIdentities = <Identity>[].obs;
IdentitiesController(
@@ -163,15 +162,10 @@ class IdentitiesController extends BaseController {
}
});
} else {
_hideHtmlSignature();
final newIdentityArguments = await push(
AppRoutes.identityCreator,
arguments: arguments);
if(newIdentityArguments == true) {
_showHtmlSignature();
}
if (newIdentityArguments is CreateNewIdentityRequest) {
_createNewIdentityAction(session, accountId, newIdentityArguments);
} else if (newIdentityArguments is EditIdentityRequest) {
@@ -199,7 +193,6 @@ class IdentitiesController extends BaseController {
currentOverlayContext!,
AppLocalizations.of(currentContext!).you_have_created_a_new_identity);
}
_showHtmlSignature();
_refreshAllIdentities();
}
@@ -210,7 +203,6 @@ class IdentitiesController extends BaseController {
currentOverlayContext!,
AppLocalizations.of(currentContext!).you_have_created_a_new_default_identity);
}
_showHtmlSignature();
_refreshAllIdentities();
}
@@ -295,15 +287,10 @@ class IdentitiesController extends BaseController {
}
});
} else {
_hideHtmlSignature();
final newIdentityArguments = await push(
AppRoutes.identityCreator,
arguments: arguments);
if(newIdentityArguments == true) {
_showHtmlSignature();
}
if (newIdentityArguments is CreateNewIdentityRequest) {
_createNewIdentityAction(session, accountId, newIdentityArguments);
} else if (newIdentityArguments is EditIdentityRequest) {
@@ -331,7 +318,6 @@ class IdentitiesController extends BaseController {
currentOverlayContext!,
AppLocalizations.of(currentContext!).you_are_changed_your_identity_successfully);
}
_showHtmlSignature();
_refreshAllIdentities();
}
@@ -339,13 +325,4 @@ class IdentitiesController extends BaseController {
ImagePaths get imagePaths => _imagePaths;
bool get isSignatureShow => identitySelected.value != null;
bool get isShowHtmlSignature => _htmlSignature.value ?? true;
void _hideHtmlSignature() async {
await Future.delayed(const Duration(milliseconds: 100));
_htmlSignature.value = false;
}
void _showHtmlSignature() => _htmlSignature.value = true;
}
@@ -49,7 +49,7 @@ class IdentitiesRadioListBuilder extends StatelessWidget {
_buildListIdentityView(context),
Container(height: 1, color: AppColor.attachmentFileBorderColor),
Obx(() {
if (controller.isShowHtmlSignature) {
if (controller.isSignatureShow) {
return SignatureBuilder(controller.signatureSelected.value!);
} else {
return _buildLoadingView();