fix(ui): use a predicate instead of a key
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
✅ Added
|
✅ Added
|
||||||
|
|
||||||
- Added `StreamMessageInput.sendMessageKey` and `StreamMessageInput.clearQuotedMessageKey` to customize the keys used to send and clear the quoted message.
|
- Added `StreamMessageInput.sendMessageKeyPredicate` and `StreamMessageInput.clearQuotedMessageKeyPredicate` to customize the keys used to send and clear the quoted message.
|
||||||
|
|
||||||
## 5.1.0
|
## 5.1.0
|
||||||
|
|
||||||
|
|||||||
@@ -111,15 +111,16 @@ class StreamMessageInput extends StatefulWidget {
|
|||||||
this.enableMentionsOverlay = true,
|
this.enableMentionsOverlay = true,
|
||||||
this.onQuotedMessageCleared,
|
this.onQuotedMessageCleared,
|
||||||
this.enableActionAnimation = true,
|
this.enableActionAnimation = true,
|
||||||
this.sendMessageKey = PhysicalKeyboardKey.enter,
|
this.sendMessageKeyPredicate = _defaultSendMessageKeyPredicate,
|
||||||
this.clearQuotedMessageKey = PhysicalKeyboardKey.escape,
|
this.clearQuotedMessageKeyPredicate =
|
||||||
|
_defaultClearQuotedMessageKeyPredicate,
|
||||||
});
|
});
|
||||||
|
|
||||||
/// The key used to send a message on web/desktop
|
/// The predicate used to send a message on desktop/web
|
||||||
final PhysicalKeyboardKey? sendMessageKey;
|
final RawKeyEventPredicate? sendMessageKeyPredicate;
|
||||||
|
|
||||||
/// The key used to send a message on web/desktop
|
/// The predicate used to clear the quoted message on desktop/web
|
||||||
final PhysicalKeyboardKey? clearQuotedMessageKey;
|
final RawKeyEventPredicate? clearQuotedMessageKeyPredicate;
|
||||||
|
|
||||||
/// If true the message input will animate the actions while you type
|
/// If true the message input will animate the actions while you type
|
||||||
final bool enableActionAnimation;
|
final bool enableActionAnimation;
|
||||||
@@ -261,6 +262,18 @@ class StreamMessageInput extends StatefulWidget {
|
|||||||
static bool _defaultValidator(Message message) =>
|
static bool _defaultValidator(Message message) =>
|
||||||
message.text?.isNotEmpty == true || message.attachments.isNotEmpty;
|
message.text?.isNotEmpty == true || message.attachments.isNotEmpty;
|
||||||
|
|
||||||
|
static bool _defaultSendMessageKeyPredicate(
|
||||||
|
FocusNode node,
|
||||||
|
RawKeyEvent event,
|
||||||
|
) =>
|
||||||
|
event.logicalKey == LogicalKeyboardKey.enter;
|
||||||
|
|
||||||
|
static bool _defaultClearQuotedMessageKeyPredicate(
|
||||||
|
FocusNode node,
|
||||||
|
RawKeyEvent event,
|
||||||
|
) =>
|
||||||
|
event.logicalKey == LogicalKeyboardKey.escape;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
StreamMessageInputState createState() => StreamMessageInputState();
|
StreamMessageInputState createState() => StreamMessageInputState();
|
||||||
}
|
}
|
||||||
@@ -760,44 +773,12 @@ class StreamMessageInputState extends State<StreamMessageInput>
|
|||||||
maxHeight: widget.maxHeight,
|
maxHeight: widget.maxHeight,
|
||||||
child: PlatformWidgetBuilder(
|
child: PlatformWidgetBuilder(
|
||||||
web: (context, child) => Focus(
|
web: (context, child) => Focus(
|
||||||
|
onKey: _handleKeyPressed,
|
||||||
child: child!,
|
child: child!,
|
||||||
onKeyEvent: (node, event) {
|
|
||||||
if (widget.sendMessageKey != null &&
|
|
||||||
event.physicalKey == widget.sendMessageKey) {
|
|
||||||
sendMessage();
|
|
||||||
return KeyEventResult.handled;
|
|
||||||
} else if (widget.clearQuotedMessageKey != null &&
|
|
||||||
event.physicalKey ==
|
|
||||||
widget.clearQuotedMessageKey) {
|
|
||||||
if (_hasQuotedMessage &&
|
|
||||||
_effectiveController.text.isEmpty) {
|
|
||||||
widget.onQuotedMessageCleared?.call();
|
|
||||||
}
|
|
||||||
return KeyEventResult.handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
return KeyEventResult.ignored;
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
desktop: (context, child) => Focus(
|
desktop: (context, child) => Focus(
|
||||||
|
onKey: _handleKeyPressed,
|
||||||
child: child!,
|
child: child!,
|
||||||
onKeyEvent: (node, event) {
|
|
||||||
if (widget.sendMessageKey != null &&
|
|
||||||
event.physicalKey == widget.sendMessageKey) {
|
|
||||||
sendMessage();
|
|
||||||
return KeyEventResult.handled;
|
|
||||||
} else if (widget.clearQuotedMessageKey != null &&
|
|
||||||
event.physicalKey ==
|
|
||||||
widget.clearQuotedMessageKey) {
|
|
||||||
if (_hasQuotedMessage &&
|
|
||||||
_effectiveController.text.isEmpty) {
|
|
||||||
widget.onQuotedMessageCleared?.call();
|
|
||||||
}
|
|
||||||
return KeyEventResult.handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
return KeyEventResult.ignored;
|
|
||||||
},
|
|
||||||
),
|
),
|
||||||
mobile: (context, child) => child,
|
mobile: (context, child) => child,
|
||||||
child: StreamMessageTextField(
|
child: StreamMessageTextField(
|
||||||
@@ -827,6 +808,25 @@ class StreamMessageInputState extends State<StreamMessageInput>
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
KeyEventResult _handleKeyPressed(
|
||||||
|
FocusNode node,
|
||||||
|
RawKeyEvent event,
|
||||||
|
) {
|
||||||
|
if (widget.sendMessageKeyPredicate != null &&
|
||||||
|
widget.sendMessageKeyPredicate!(node, event)) {
|
||||||
|
sendMessage();
|
||||||
|
return KeyEventResult.handled;
|
||||||
|
} else if (widget.clearQuotedMessageKeyPredicate != null &&
|
||||||
|
widget.clearQuotedMessageKeyPredicate!(node, event)) {
|
||||||
|
if (_hasQuotedMessage && _effectiveController.text.isEmpty) {
|
||||||
|
widget.onQuotedMessageCleared?.call();
|
||||||
|
}
|
||||||
|
return KeyEventResult.handled;
|
||||||
|
}
|
||||||
|
|
||||||
|
return KeyEventResult.ignored;
|
||||||
|
}
|
||||||
|
|
||||||
InputDecoration _getInputDecoration(BuildContext context) {
|
InputDecoration _getInputDecoration(BuildContext context) {
|
||||||
final passedDecoration = _messageInputTheme.inputDecoration;
|
final passedDecoration = _messageInputTheme.inputDecoration;
|
||||||
return InputDecoration(
|
return InputDecoration(
|
||||||
|
|||||||
@@ -340,6 +340,11 @@ typedef DownloadedPathCallback = void Function(String? path);
|
|||||||
/// {@endtemplate}
|
/// {@endtemplate}
|
||||||
typedef UserTapCallback = void Function(User, Widget?);
|
typedef UserTapCallback = void Function(User, Widget?);
|
||||||
|
|
||||||
|
/// {@template rawKeyEventPredicate}
|
||||||
|
/// Callback called to react to a raw key event
|
||||||
|
/// {@endtemplate}
|
||||||
|
typedef RawKeyEventPredicate = bool Function(FocusNode, RawKeyEvent);
|
||||||
|
|
||||||
/// {@template userItemBuilder}
|
/// {@template userItemBuilder}
|
||||||
/// Builder used to create a custom [ListUserItem] from a [User]
|
/// Builder used to create a custom [ListUserItem] from a [User]
|
||||||
/// {@endtemplate}
|
/// {@endtemplate}
|
||||||
|
|||||||
Reference in New Issue
Block a user