TF-1679: Hide cursor of bcc when focus to html editor
(cherry picked from commit 588c9b4873ea40b75dd6e6cffbe80af21a4b287c)
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
import 'package:core/utils/app_logger.dart';
|
import 'package:core/utils/app_logger.dart';
|
||||||
import 'package:core/utils/build_utils.dart';
|
import 'package:core/utils/build_utils.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
import 'package:get/get_core/get_core.dart';
|
import 'package:get/get_core/get_core.dart';
|
||||||
import 'package:get/get_instance/get_instance.dart';
|
import 'package:get/get_instance/get_instance.dart';
|
||||||
import 'package:get/get_rx/get_rx.dart';
|
import 'package:get/get_rx/get_rx.dart';
|
||||||
@@ -63,6 +64,7 @@ class IdentityCreatorController extends BaseController {
|
|||||||
TextEditingController? inputNameIdentityController;
|
TextEditingController? inputNameIdentityController;
|
||||||
TextEditingController? inputBccIdentityController;
|
TextEditingController? inputBccIdentityController;
|
||||||
FocusNode? inputNameIdentityFocusNode;
|
FocusNode? inputNameIdentityFocusNode;
|
||||||
|
FocusNode? inputBccIdentityFocusNode;
|
||||||
|
|
||||||
String? _nameIdentity;
|
String? _nameIdentity;
|
||||||
String? _contentHtmlEditor;
|
String? _contentHtmlEditor;
|
||||||
@@ -109,6 +111,7 @@ class IdentityCreatorController extends BaseController {
|
|||||||
inputNameIdentityController = TextEditingController();
|
inputNameIdentityController = TextEditingController();
|
||||||
inputBccIdentityController = TextEditingController();
|
inputBccIdentityController = TextEditingController();
|
||||||
inputNameIdentityFocusNode = FocusNode();
|
inputNameIdentityFocusNode = FocusNode();
|
||||||
|
inputBccIdentityFocusNode = FocusNode();
|
||||||
scrollController = ScrollController();
|
scrollController = ScrollController();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -422,6 +425,7 @@ class IdentityCreatorController extends BaseController {
|
|||||||
if (!BuildUtils.isWeb) {
|
if (!BuildUtils.isWeb) {
|
||||||
keyboardRichTextController.htmlEditorApi?.unfocus();
|
keyboardRichTextController.htmlEditorApi?.unfocus();
|
||||||
}
|
}
|
||||||
|
SystemChannels.textInput.invokeMethod('TextInput.hide');
|
||||||
FocusScope.of(context).unfocus();
|
FocusScope.of(context).unfocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -437,6 +441,8 @@ class IdentityCreatorController extends BaseController {
|
|||||||
keyboardRichTextController.dispose();
|
keyboardRichTextController.dispose();
|
||||||
inputNameIdentityFocusNode?.dispose();
|
inputNameIdentityFocusNode?.dispose();
|
||||||
inputNameIdentityFocusNode = null;
|
inputNameIdentityFocusNode = null;
|
||||||
|
inputBccIdentityFocusNode?.dispose();
|
||||||
|
inputBccIdentityFocusNode = null;
|
||||||
inputNameIdentityController?.dispose();
|
inputNameIdentityController?.dispose();
|
||||||
inputNameIdentityController = null;
|
inputNameIdentityController = null;
|
||||||
inputBccIdentityController?.dispose();
|
inputBccIdentityController?.dispose();
|
||||||
@@ -444,7 +450,19 @@ class IdentityCreatorController extends BaseController {
|
|||||||
scrollController?.dispose();
|
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 (scrollController != null) {
|
||||||
if (htmlKey.currentContext != null) {
|
if (htmlKey.currentContext != null) {
|
||||||
await Scrollable.ensureVisible(htmlKey.currentContext!);
|
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) {
|
if (scrollController != null && scrollController!.position.pixels < scrollController!.position.maxScrollExtent) {
|
||||||
scrollController!.animateTo(
|
scrollController!.animateTo(
|
||||||
scrollController!.position.pixels + 20,
|
scrollController!.position.pixels + 20,
|
||||||
|
|||||||
@@ -237,7 +237,8 @@ class IdentityCreatorView extends GetWidget<IdentityCreatorController> {
|
|||||||
Obx(() => (IdentityInputWithDropListFieldBuilder(
|
Obx(() => (IdentityInputWithDropListFieldBuilder(
|
||||||
AppLocalizations.of(context).bcc_to,
|
AppLocalizations.of(context).bcc_to,
|
||||||
controller.errorBccIdentity.value,
|
controller.errorBccIdentity.value,
|
||||||
controller.inputBccIdentityController)
|
controller.inputBccIdentityController,
|
||||||
|
focusNode: controller.inputBccIdentityFocusNode)
|
||||||
..addOnSelectedSuggestionAction((newEmailAddress) {
|
..addOnSelectedSuggestionAction((newEmailAddress) {
|
||||||
controller.inputBccIdentityController?.text = newEmailAddress?.email ?? '';
|
controller.inputBccIdentityController?.text = newEmailAddress?.email ?? '';
|
||||||
controller.updateBccOfIdentity(newEmailAddress);
|
controller.updateBccOfIdentity(newEmailAddress);
|
||||||
@@ -337,7 +338,9 @@ class IdentityCreatorView extends GetWidget<IdentityCreatorController> {
|
|||||||
),
|
),
|
||||||
]
|
]
|
||||||
),
|
),
|
||||||
)] else ...[
|
),
|
||||||
|
const SizedBox(height: 35),
|
||||||
|
] else ...[
|
||||||
_buildActionBottomDesktop(context)
|
_buildActionBottomDesktop(context)
|
||||||
]
|
]
|
||||||
]),
|
]),
|
||||||
@@ -346,48 +349,57 @@ class IdentityCreatorView extends GetWidget<IdentityCreatorController> {
|
|||||||
|
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: () => controller.clearFocusEditor(context),
|
onTap: () => controller.clearFocusEditor(context),
|
||||||
child: Stack(
|
child: Column(children: [
|
||||||
children: [
|
SizedBox(
|
||||||
Column(children: [
|
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(
|
||||||
padding: const EdgeInsets.only(top: 14),
|
padding: const EdgeInsets.only(top: 14),
|
||||||
|
child: Align(
|
||||||
|
alignment: Alignment.center,
|
||||||
child: Obx(() {
|
child: Obx(() {
|
||||||
return Text(controller.actionType.value == IdentityActionType.create
|
return Text(controller.actionType.value == IdentityActionType.create
|
||||||
? AppLocalizations.of(context).createNewIdentity.inCaps
|
? AppLocalizations.of(context).createNewIdentity.inCaps
|
||||||
: AppLocalizations.of(context).edit_identity.inCaps,
|
: AppLocalizations.of(context).edit_identity.inCaps,
|
||||||
style: const TextStyle(fontWeight: FontWeight.bold, fontSize: 20, color: Colors.black));
|
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,
|
const SizedBox(height: 8),
|
||||||
icon: SvgPicture.asset(
|
Expanded(
|
||||||
_imagePaths.icComposerClose,
|
child: BuildUtils.isWeb
|
||||||
fit: BoxFit.fill,
|
? PointerInterceptor(child: bodyCreatorView)
|
||||||
colorFilter: AppColor.colorDeleteContactIcon.asFilter()
|
: KeyboardRichText(
|
||||||
),
|
keyBroadToolbar: RichTextKeyboardToolBar(
|
||||||
tooltip: AppLocalizations.of(context).close,
|
titleBack: AppLocalizations.of(context).titleFormat,
|
||||||
onTap: () => controller.closeView(context)))
|
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,
|
minHeight: controller.htmlEditorMinHeight,
|
||||||
addDefaultSelectionMenuItems: false,
|
addDefaultSelectionMenuItems: false,
|
||||||
initialContent: initialContent ?? '',
|
initialContent: initialContent ?? '',
|
||||||
onCreated: (editorApi) {
|
onCreated: (editorApi) => controller.initRichTextForMobile(context, editorApi),
|
||||||
controller.keyboardRichTextController.onCreateHTMLEditor(
|
|
||||||
editorApi,
|
|
||||||
onEnterKeyDown: controller.onEnterKeyDownOnMobile,
|
|
||||||
onFocus: controller.onFocusHTMLEditorOnMobile,
|
|
||||||
context: context
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
+12
-7
@@ -14,6 +14,7 @@ class IdentityInputWithDropListFieldBuilder {
|
|||||||
final String _label;
|
final String _label;
|
||||||
final String? _error;
|
final String? _error;
|
||||||
final TextEditingController? editingController;
|
final TextEditingController? editingController;
|
||||||
|
final FocusNode? focusNode;
|
||||||
|
|
||||||
OnSelectedSuggestionAction? _onSelectedSuggestionAction;
|
OnSelectedSuggestionAction? _onSelectedSuggestionAction;
|
||||||
OnSuggestionCallbackAction? _onSuggestionCallbackAction;
|
OnSuggestionCallbackAction? _onSuggestionCallbackAction;
|
||||||
@@ -23,6 +24,9 @@ class IdentityInputWithDropListFieldBuilder {
|
|||||||
this._label,
|
this._label,
|
||||||
this._error,
|
this._error,
|
||||||
this.editingController,
|
this.editingController,
|
||||||
|
{
|
||||||
|
this.focusNode,
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
void addOnSelectedSuggestionAction(OnSelectedSuggestionAction action) {
|
void addOnSelectedSuggestionAction(OnSelectedSuggestionAction action) {
|
||||||
@@ -46,13 +50,14 @@ class IdentityInputWithDropListFieldBuilder {
|
|||||||
const SizedBox(height: 8),
|
const SizedBox(height: 8),
|
||||||
TypeAheadFormField<EmailAddress>(
|
TypeAheadFormField<EmailAddress>(
|
||||||
textFieldConfiguration: TextFieldConfiguration(
|
textFieldConfiguration: TextFieldConfiguration(
|
||||||
controller: editingController,
|
focusNode: focusNode,
|
||||||
textInputAction: TextInputAction.done,
|
controller: editingController,
|
||||||
decoration: (IdentityInputDecorationBuilder()
|
textInputAction: TextInputAction.done,
|
||||||
..setContentPadding(const EdgeInsets.symmetric(
|
decoration: (IdentityInputDecorationBuilder()
|
||||||
vertical: BuildUtils.isWeb ? 16 : 12,
|
..setContentPadding(const EdgeInsets.symmetric(
|
||||||
horizontal: 12))
|
vertical: BuildUtils.isWeb ? 16 : 12,
|
||||||
..setErrorText(_error))
|
horizontal: 12))
|
||||||
|
..setErrorText(_error))
|
||||||
.build()
|
.build()
|
||||||
),
|
),
|
||||||
debounceDuration: const Duration(milliseconds: 500),
|
debounceDuration: const Duration(milliseconds: 500),
|
||||||
|
|||||||
-23
@@ -53,7 +53,6 @@ class IdentitiesController extends BaseController {
|
|||||||
|
|
||||||
final identitySelected = Rxn<Identity>();
|
final identitySelected = Rxn<Identity>();
|
||||||
final signatureSelected = Rxn<String>();
|
final signatureSelected = Rxn<String>();
|
||||||
final _htmlSignature = Rxn<bool>();
|
|
||||||
final listAllIdentities = <Identity>[].obs;
|
final listAllIdentities = <Identity>[].obs;
|
||||||
|
|
||||||
IdentitiesController(
|
IdentitiesController(
|
||||||
@@ -163,15 +162,10 @@ class IdentitiesController extends BaseController {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
_hideHtmlSignature();
|
|
||||||
final newIdentityArguments = await push(
|
final newIdentityArguments = await push(
|
||||||
AppRoutes.identityCreator,
|
AppRoutes.identityCreator,
|
||||||
arguments: arguments);
|
arguments: arguments);
|
||||||
|
|
||||||
if(newIdentityArguments == true) {
|
|
||||||
_showHtmlSignature();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (newIdentityArguments is CreateNewIdentityRequest) {
|
if (newIdentityArguments is CreateNewIdentityRequest) {
|
||||||
_createNewIdentityAction(session, accountId, newIdentityArguments);
|
_createNewIdentityAction(session, accountId, newIdentityArguments);
|
||||||
} else if (newIdentityArguments is EditIdentityRequest) {
|
} else if (newIdentityArguments is EditIdentityRequest) {
|
||||||
@@ -199,7 +193,6 @@ class IdentitiesController extends BaseController {
|
|||||||
currentOverlayContext!,
|
currentOverlayContext!,
|
||||||
AppLocalizations.of(currentContext!).you_have_created_a_new_identity);
|
AppLocalizations.of(currentContext!).you_have_created_a_new_identity);
|
||||||
}
|
}
|
||||||
_showHtmlSignature();
|
|
||||||
|
|
||||||
_refreshAllIdentities();
|
_refreshAllIdentities();
|
||||||
}
|
}
|
||||||
@@ -210,7 +203,6 @@ class IdentitiesController extends BaseController {
|
|||||||
currentOverlayContext!,
|
currentOverlayContext!,
|
||||||
AppLocalizations.of(currentContext!).you_have_created_a_new_default_identity);
|
AppLocalizations.of(currentContext!).you_have_created_a_new_default_identity);
|
||||||
}
|
}
|
||||||
_showHtmlSignature();
|
|
||||||
|
|
||||||
_refreshAllIdentities();
|
_refreshAllIdentities();
|
||||||
}
|
}
|
||||||
@@ -295,15 +287,10 @@ class IdentitiesController extends BaseController {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
_hideHtmlSignature();
|
|
||||||
final newIdentityArguments = await push(
|
final newIdentityArguments = await push(
|
||||||
AppRoutes.identityCreator,
|
AppRoutes.identityCreator,
|
||||||
arguments: arguments);
|
arguments: arguments);
|
||||||
|
|
||||||
if(newIdentityArguments == true) {
|
|
||||||
_showHtmlSignature();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (newIdentityArguments is CreateNewIdentityRequest) {
|
if (newIdentityArguments is CreateNewIdentityRequest) {
|
||||||
_createNewIdentityAction(session, accountId, newIdentityArguments);
|
_createNewIdentityAction(session, accountId, newIdentityArguments);
|
||||||
} else if (newIdentityArguments is EditIdentityRequest) {
|
} else if (newIdentityArguments is EditIdentityRequest) {
|
||||||
@@ -331,7 +318,6 @@ class IdentitiesController extends BaseController {
|
|||||||
currentOverlayContext!,
|
currentOverlayContext!,
|
||||||
AppLocalizations.of(currentContext!).you_are_changed_your_identity_successfully);
|
AppLocalizations.of(currentContext!).you_are_changed_your_identity_successfully);
|
||||||
}
|
}
|
||||||
_showHtmlSignature();
|
|
||||||
|
|
||||||
_refreshAllIdentities();
|
_refreshAllIdentities();
|
||||||
}
|
}
|
||||||
@@ -339,13 +325,4 @@ class IdentitiesController extends BaseController {
|
|||||||
ImagePaths get imagePaths => _imagePaths;
|
ImagePaths get imagePaths => _imagePaths;
|
||||||
|
|
||||||
bool get isSignatureShow => identitySelected.value != null;
|
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;
|
|
||||||
}
|
}
|
||||||
+1
-1
@@ -49,7 +49,7 @@ class IdentitiesRadioListBuilder extends StatelessWidget {
|
|||||||
_buildListIdentityView(context),
|
_buildListIdentityView(context),
|
||||||
Container(height: 1, color: AppColor.attachmentFileBorderColor),
|
Container(height: 1, color: AppColor.attachmentFileBorderColor),
|
||||||
Obx(() {
|
Obx(() {
|
||||||
if (controller.isShowHtmlSignature) {
|
if (controller.isSignatureShow) {
|
||||||
return SignatureBuilder(controller.signatureSelected.value!);
|
return SignatureBuilder(controller.signatureSelected.value!);
|
||||||
} else {
|
} else {
|
||||||
return _buildLoadingView();
|
return _buildLoadingView();
|
||||||
|
|||||||
Reference in New Issue
Block a user