TF-1544: Support can TAB another field in composer
(cherry picked from commit 38f24da4295f4e6231eb77af18b2181496ad78f8)
This commit is contained in:
@@ -12,6 +12,7 @@ import 'package:filesize/filesize.dart';
|
|||||||
import 'package:fk_user_agent/fk_user_agent.dart';
|
import 'package:fk_user_agent/fk_user_agent.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:http_parser/http_parser.dart';
|
import 'package:http_parser/http_parser.dart';
|
||||||
@@ -346,7 +347,15 @@ class ComposerController extends BaseController {
|
|||||||
|
|
||||||
void createFocusNodeInput() {
|
void createFocusNodeInput() {
|
||||||
toAddressFocusNode = FocusNode();
|
toAddressFocusNode = FocusNode();
|
||||||
subjectEmailInputFocusNode = FocusNode();
|
subjectEmailInputFocusNode = FocusNode(
|
||||||
|
onKey: (focus, event) {
|
||||||
|
if (event is RawKeyDownEvent && event.logicalKey == LogicalKeyboardKey.tab) {
|
||||||
|
richTextWebController.editorController.setFocus();
|
||||||
|
return KeyEventResult.handled;
|
||||||
|
}
|
||||||
|
return KeyEventResult.ignored;
|
||||||
|
}
|
||||||
|
);
|
||||||
ccAddressFocusNode = FocusNode();
|
ccAddressFocusNode = FocusNode();
|
||||||
bccAddressFocusNode = FocusNode();
|
bccAddressFocusNode = FocusNode();
|
||||||
|
|
||||||
@@ -1198,9 +1207,11 @@ class ComposerController extends BaseController {
|
|||||||
updateListEmailAddress(prefixEmailAddress, <EmailAddress>[]);
|
updateListEmailAddress(prefixEmailAddress, <EmailAddress>[]);
|
||||||
switch(prefixEmailAddress) {
|
switch(prefixEmailAddress) {
|
||||||
case PrefixEmailAddress.cc:
|
case PrefixEmailAddress.cc:
|
||||||
|
ccAddressFocusNode = FocusNode();
|
||||||
ccEmailAddressController.clear();
|
ccEmailAddressController.clear();
|
||||||
break;
|
break;
|
||||||
case PrefixEmailAddress.bcc:
|
case PrefixEmailAddress.bcc:
|
||||||
|
bccAddressFocusNode = FocusNode();
|
||||||
bccEmailAddressController.clear();
|
bccEmailAddressController.clear();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -1632,4 +1643,26 @@ class ComposerController extends BaseController {
|
|||||||
Navigator.maybePop(context);
|
Navigator.maybePop(context);
|
||||||
onEditorFocusChange(true);
|
onEditorFocusChange(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FocusNode? getNextFocusOfToEmailAddress() {
|
||||||
|
if (listEmailAddressType.contains(PrefixEmailAddress.cc) == true) {
|
||||||
|
return ccAddressFocusNode;
|
||||||
|
} else if (listEmailAddressType.contains(PrefixEmailAddress.bcc) == true) {
|
||||||
|
return bccAddressFocusNode;
|
||||||
|
} else {
|
||||||
|
return subjectEmailInputFocusNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FocusNode? getNextFocusOfCcEmailAddress() {
|
||||||
|
if (listEmailAddressType.contains(PrefixEmailAddress.bcc) == true) {
|
||||||
|
return bccAddressFocusNode;
|
||||||
|
} else {
|
||||||
|
return subjectEmailInputFocusNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleFocusNextAddressAction() {
|
||||||
|
_autoCreateEmailTag();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -579,13 +579,15 @@ class ComposerView extends GetWidget<ComposerController>
|
|||||||
focusNode: controller.toAddressFocusNode,
|
focusNode: controller.toAddressFocusNode,
|
||||||
autoDisposeFocusNode: false,
|
autoDisposeFocusNode: false,
|
||||||
isInitial: controller.isInitialRecipient.value,
|
isInitial: controller.isInitialRecipient.value,
|
||||||
keyTagEditor: controller.keyToEmailTagEditor
|
keyTagEditor: controller.keyToEmailTagEditor,
|
||||||
|
nextFocusNode: controller.getNextFocusOfToEmailAddress()
|
||||||
)
|
)
|
||||||
..addOnFocusEmailAddressChangeAction((prefixEmailAddress, focus) => controller.onEmailAddressFocusChange(prefixEmailAddress, focus))
|
..addOnFocusEmailAddressChangeAction((prefixEmailAddress, focus) => controller.onEmailAddressFocusChange(prefixEmailAddress, focus))
|
||||||
..addOnShowFullListEmailAddressAction((prefixEmailAddress) => controller.showFullEmailAddress(prefixEmailAddress))
|
..addOnShowFullListEmailAddressAction((prefixEmailAddress) => controller.showFullEmailAddress(prefixEmailAddress))
|
||||||
..addOnAddEmailAddressTypeAction((prefixEmailAddress) => controller.addEmailAddressType(prefixEmailAddress))
|
..addOnAddEmailAddressTypeAction((prefixEmailAddress) => controller.addEmailAddressType(prefixEmailAddress))
|
||||||
..addOnUpdateListEmailAddressAction((prefixEmailAddress, listEmailAddress) => controller.updateListEmailAddress(prefixEmailAddress, listEmailAddress))
|
..addOnUpdateListEmailAddressAction((prefixEmailAddress, listEmailAddress) => controller.updateListEmailAddress(prefixEmailAddress, listEmailAddress))
|
||||||
..addOnSuggestionEmailAddress(controller.getAutoCompleteSuggestion))
|
..addOnSuggestionEmailAddress(controller.getAutoCompleteSuggestion)
|
||||||
|
..addOnFocusNextAddressAction(controller.handleFocusNextAddressAction))
|
||||||
.build()
|
.build()
|
||||||
)),
|
)),
|
||||||
Obx(() => controller.listEmailAddressType.contains(PrefixEmailAddress.cc) == true
|
Obx(() => controller.listEmailAddressType.contains(PrefixEmailAddress.cc) == true
|
||||||
@@ -604,13 +606,16 @@ class ComposerView extends GetWidget<ComposerController>
|
|||||||
expandMode: controller.ccAddressExpandMode.value,
|
expandMode: controller.ccAddressExpandMode.value,
|
||||||
controller: controller.ccEmailAddressController,
|
controller: controller.ccEmailAddressController,
|
||||||
isInitial: controller.isInitialRecipient.value,
|
isInitial: controller.isInitialRecipient.value,
|
||||||
keyTagEditor: controller.keyCcEmailTagEditor
|
keyTagEditor: controller.keyCcEmailTagEditor,
|
||||||
|
focusNode: controller.ccAddressFocusNode,
|
||||||
|
nextFocusNode: controller.getNextFocusOfCcEmailAddress()
|
||||||
)
|
)
|
||||||
..addOnFocusEmailAddressChangeAction((prefixEmailAddress, focus) => controller.onEmailAddressFocusChange(prefixEmailAddress, focus))
|
..addOnFocusEmailAddressChangeAction((prefixEmailAddress, focus) => controller.onEmailAddressFocusChange(prefixEmailAddress, focus))
|
||||||
..addOnShowFullListEmailAddressAction((prefixEmailAddress) => controller.showFullEmailAddress(prefixEmailAddress))
|
..addOnShowFullListEmailAddressAction((prefixEmailAddress) => controller.showFullEmailAddress(prefixEmailAddress))
|
||||||
..addOnDeleteEmailAddressTypeAction((prefixEmailAddress) => controller.deleteEmailAddressType(prefixEmailAddress))
|
..addOnDeleteEmailAddressTypeAction((prefixEmailAddress) => controller.deleteEmailAddressType(prefixEmailAddress))
|
||||||
..addOnUpdateListEmailAddressAction((prefixEmailAddress, listEmailAddress) => controller.updateListEmailAddress(prefixEmailAddress, listEmailAddress))
|
..addOnUpdateListEmailAddressAction((prefixEmailAddress, listEmailAddress) => controller.updateListEmailAddress(prefixEmailAddress, listEmailAddress))
|
||||||
..addOnSuggestionEmailAddress(controller.getAutoCompleteSuggestion))
|
..addOnSuggestionEmailAddress(controller.getAutoCompleteSuggestion)
|
||||||
|
..addOnFocusNextAddressAction(controller.handleFocusNextAddressAction))
|
||||||
.build())
|
.build())
|
||||||
: const SizedBox.shrink()
|
: const SizedBox.shrink()
|
||||||
),
|
),
|
||||||
@@ -630,13 +635,16 @@ class ComposerView extends GetWidget<ComposerController>
|
|||||||
expandMode: controller.bccAddressExpandMode.value,
|
expandMode: controller.bccAddressExpandMode.value,
|
||||||
controller: controller.bccEmailAddressController,
|
controller: controller.bccEmailAddressController,
|
||||||
isInitial: controller.isInitialRecipient.value,
|
isInitial: controller.isInitialRecipient.value,
|
||||||
keyTagEditor: controller.keyBccEmailTagEditor
|
keyTagEditor: controller.keyBccEmailTagEditor,
|
||||||
|
focusNode: controller.bccAddressFocusNode,
|
||||||
|
nextFocusNode: controller.subjectEmailInputFocusNode
|
||||||
)
|
)
|
||||||
..addOnFocusEmailAddressChangeAction((prefixEmailAddress, focus) => controller.onEmailAddressFocusChange(prefixEmailAddress, focus))
|
..addOnFocusEmailAddressChangeAction((prefixEmailAddress, focus) => controller.onEmailAddressFocusChange(prefixEmailAddress, focus))
|
||||||
..addOnShowFullListEmailAddressAction((prefixEmailAddress) => controller.showFullEmailAddress(prefixEmailAddress))
|
..addOnShowFullListEmailAddressAction((prefixEmailAddress) => controller.showFullEmailAddress(prefixEmailAddress))
|
||||||
..addOnDeleteEmailAddressTypeAction((prefixEmailAddress) => controller.deleteEmailAddressType(prefixEmailAddress))
|
..addOnDeleteEmailAddressTypeAction((prefixEmailAddress) => controller.deleteEmailAddressType(prefixEmailAddress))
|
||||||
..addOnUpdateListEmailAddressAction((prefixEmailAddress, listEmailAddress) => controller.updateListEmailAddress(prefixEmailAddress, listEmailAddress))
|
..addOnUpdateListEmailAddressAction((prefixEmailAddress, listEmailAddress) => controller.updateListEmailAddress(prefixEmailAddress, listEmailAddress))
|
||||||
..addOnSuggestionEmailAddress(controller.getAutoCompleteSuggestion))
|
..addOnSuggestionEmailAddress(controller.getAutoCompleteSuggestion)
|
||||||
|
..addOnFocusNextAddressAction(controller.handleFocusNextAddressAction))
|
||||||
.build())
|
.build())
|
||||||
: const SizedBox.shrink()
|
: const SizedBox.shrink()
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import 'package:collection/collection.dart';
|
|||||||
import 'package:core/core.dart';
|
import 'package:core/core.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
|
import 'package:jmap_dart_client/jmap/mail/email/email_address.dart';
|
||||||
@@ -21,6 +22,7 @@ typedef OnAddEmailAddressTypeAction = void Function(PrefixEmailAddress);
|
|||||||
typedef OnDeleteEmailAddressTypeAction = void Function(PrefixEmailAddress);
|
typedef OnDeleteEmailAddressTypeAction = void Function(PrefixEmailAddress);
|
||||||
typedef OnShowFullListEmailAddressAction = void Function(PrefixEmailAddress);
|
typedef OnShowFullListEmailAddressAction = void Function(PrefixEmailAddress);
|
||||||
typedef OnFocusEmailAddressChangeAction = void Function(PrefixEmailAddress, bool);
|
typedef OnFocusEmailAddressChangeAction = void Function(PrefixEmailAddress, bool);
|
||||||
|
typedef OnFocusNextAddressAction = void Function();
|
||||||
|
|
||||||
class EmailAddressInputBuilder {
|
class EmailAddressInputBuilder {
|
||||||
|
|
||||||
@@ -35,6 +37,7 @@ class EmailAddressInputBuilder {
|
|||||||
final FocusNode? focusNode;
|
final FocusNode? focusNode;
|
||||||
final bool autoDisposeFocusNode;
|
final bool autoDisposeFocusNode;
|
||||||
final GlobalKey? keyTagEditor;
|
final GlobalKey? keyTagEditor;
|
||||||
|
final FocusNode? nextFocusNode;
|
||||||
|
|
||||||
List<EmailAddress> listEmailAddress = <EmailAddress>[];
|
List<EmailAddress> listEmailAddress = <EmailAddress>[];
|
||||||
|
|
||||||
@@ -44,6 +47,7 @@ class EmailAddressInputBuilder {
|
|||||||
OnDeleteEmailAddressTypeAction? _onDeleteEmailAddressTypeAction;
|
OnDeleteEmailAddressTypeAction? _onDeleteEmailAddressTypeAction;
|
||||||
OnShowFullListEmailAddressAction? _onShowFullListEmailAddressAction;
|
OnShowFullListEmailAddressAction? _onShowFullListEmailAddressAction;
|
||||||
OnFocusEmailAddressChangeAction? _onFocusEmailAddressChangeAction;
|
OnFocusEmailAddressChangeAction? _onFocusEmailAddressChangeAction;
|
||||||
|
OnFocusNextAddressAction? _onFocusNextAddressAction;
|
||||||
|
|
||||||
Timer? _gapBetweenTagChangedAndFindSuggestion;
|
Timer? _gapBetweenTagChangedAndFindSuggestion;
|
||||||
bool lastTagFocused = false;
|
bool lastTagFocused = false;
|
||||||
@@ -72,6 +76,10 @@ class EmailAddressInputBuilder {
|
|||||||
_onFocusEmailAddressChangeAction = onFocusEmailAddressChangeAction;
|
_onFocusEmailAddressChangeAction = onFocusEmailAddressChangeAction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void addOnFocusNextAddressAction(OnFocusNextAddressAction onFocusNextAddressAction) {
|
||||||
|
_onFocusNextAddressAction = onFocusNextAddressAction;
|
||||||
|
}
|
||||||
|
|
||||||
EmailAddressInputBuilder(
|
EmailAddressInputBuilder(
|
||||||
this._context,
|
this._context,
|
||||||
this._imagePaths,
|
this._imagePaths,
|
||||||
@@ -85,6 +93,7 @@ class EmailAddressInputBuilder {
|
|||||||
this.autoDisposeFocusNode = true,
|
this.autoDisposeFocusNode = true,
|
||||||
this.expandMode = ExpandMode.EXPAND,
|
this.expandMode = ExpandMode.EXPAND,
|
||||||
this.keyTagEditor,
|
this.keyTagEditor,
|
||||||
|
this.nextFocusNode,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -132,6 +141,14 @@ class EmailAddressInputBuilder {
|
|||||||
final newListEmailAddress = _isCollapse ? listEmailAddress.sublist(0, 1) : listEmailAddress;
|
final newListEmailAddress = _isCollapse ? listEmailAddress.sublist(0, 1) : listEmailAddress;
|
||||||
return FocusScope(child: Focus(
|
return FocusScope(child: Focus(
|
||||||
onFocusChange: (focus) => _onFocusEmailAddressChangeAction?.call(_prefixEmailAddress, focus),
|
onFocusChange: (focus) => _onFocusEmailAddressChangeAction?.call(_prefixEmailAddress, focus),
|
||||||
|
onKey: (focusNode, event) {
|
||||||
|
if (event is RawKeyDownEvent && event.logicalKey == LogicalKeyboardKey.tab) {
|
||||||
|
nextFocusNode?.requestFocus();
|
||||||
|
_onFocusNextAddressAction?.call();
|
||||||
|
return KeyEventResult.handled;
|
||||||
|
}
|
||||||
|
return KeyEventResult.ignored;
|
||||||
|
},
|
||||||
child: TagEditor<SuggestionEmailAddress>(
|
child: TagEditor<SuggestionEmailAddress>(
|
||||||
key: keyTagEditor,
|
key: keyTagEditor,
|
||||||
length: newListEmailAddress.length,
|
length: newListEmailAddress.length,
|
||||||
|
|||||||
Reference in New Issue
Block a user