Merge branch 'develop' into ISSUE-1456/SendingMessageIndicatorFix

This commit is contained in:
Sahil Kumar
2023-04-07 06:06:28 +05:30
committed by GitHub
4 changed files with 57 additions and 21 deletions
@@ -10,6 +10,7 @@
- Now it is possible to customize the max lines of the title of a url attachment. Before it was always 1 line.
- Added `attachmentActionsModalBuilder` parameter to `StreamMessageWidget` that allows to customize `AttachmentActionsModal`.
- Added `StreamMessageInput.sendMessageKeyPredicate` and `StreamMessageInput.clearQuotedMessageKeyPredicate` to customize the keys used to send and clear the quoted message.
🔄 Changed
@@ -1,4 +1,4 @@
import 'package:flutter/material.dart' show Theme;
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
/// A generic widget builder function.
@@ -30,7 +30,7 @@ abstract class PlatformWidgetBase<M extends Widget, D extends Widget,
@override
Widget build(BuildContext context) {
final platform = Theme.of(context).platform;
final platform = defaultTargetPlatform;
if (platform == TargetPlatform.android || platform == TargetPlatform.iOS) {
return createMobileWidget(context);
} else if (platform == TargetPlatform.macOS ||
@@ -7,6 +7,7 @@ import 'package:cached_network_image/cached_network_image.dart'
hide ErrorListener;
import 'package:desktop_drop/desktop_drop.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:photo_manager/photo_manager.dart';
import 'package:shimmer/shimmer.dart';
@@ -110,8 +111,17 @@ class StreamMessageInput extends StatefulWidget {
this.enableMentionsOverlay = true,
this.onQuotedMessageCleared,
this.enableActionAnimation = true,
this.sendMessageKeyPredicate = _defaultSendMessageKeyPredicate,
this.clearQuotedMessageKeyPredicate =
_defaultClearQuotedMessageKeyPredicate,
});
/// The predicate used to send a message on desktop/web
final KeyEventPredicate sendMessageKeyPredicate;
/// The predicate used to clear the quoted message on desktop/web
final KeyEventPredicate clearQuotedMessageKeyPredicate;
/// If true the message input will animate the actions while you type
final bool enableActionAnimation;
@@ -252,6 +262,22 @@ class StreamMessageInput extends StatefulWidget {
static bool _defaultValidator(Message message) =>
message.text?.isNotEmpty == true || message.attachments.isNotEmpty;
static bool _defaultSendMessageKeyPredicate(
FocusNode node,
KeyEvent event,
) {
// On desktop/web, send the message when the user presses the enter key.
return event is KeyUpEvent && event.logicalKey == LogicalKeyboardKey.enter;
}
static bool _defaultClearQuotedMessageKeyPredicate(
FocusNode node,
KeyEvent event,
) {
// On desktop/web, clear the quoted message when the user presses the escape key.
return event is KeyUpEvent && event.logicalKey == LogicalKeyboardKey.escape;
}
@override
StreamMessageInputState createState() => StreamMessageInputState();
}
@@ -509,9 +535,6 @@ class StreamMessageInputState extends State<StreamMessageInput>
: CrossFadeState.showSecond,
),
),
// PlatformWidgetBuilder(
// mobile: (context, child) => _buildFilePickerSection(),
// ),
],
),
),
@@ -753,24 +776,12 @@ class StreamMessageInputState extends State<StreamMessageInput>
LimitedBox(
maxHeight: widget.maxHeight,
child: PlatformWidgetBuilder(
web: (context, child) => KeyboardShortcutRunner(
onEnterKeypress: sendMessage,
onEscapeKeypress: () {
if (_hasQuotedMessage &&
_effectiveController.text.isEmpty) {
widget.onQuotedMessageCleared?.call();
}
},
web: (context, child) => Focus(
onKeyEvent: _handleKeyPressed,
child: child!,
),
desktop: (context, child) => KeyboardShortcutRunner(
onEnterKeypress: sendMessage,
onEscapeKeypress: () {
if (_hasQuotedMessage &&
_effectiveController.text.isEmpty) {
widget.onQuotedMessageCleared?.call();
}
},
desktop: (context, child) => Focus(
onKeyEvent: _handleKeyPressed,
child: child!,
),
mobile: (context, child) => child,
@@ -801,6 +812,25 @@ class StreamMessageInputState extends State<StreamMessageInput>
);
}
KeyEventResult _handleKeyPressed(FocusNode node, KeyEvent event) {
// Check for send message key.
if (widget.sendMessageKeyPredicate(node, event)) {
sendMessage();
return KeyEventResult.handled;
}
// Check for clear quoted message key.
if (widget.clearQuotedMessageKeyPredicate(node, event)) {
if (_hasQuotedMessage && _effectiveController.text.isEmpty) {
widget.onQuotedMessageCleared?.call();
}
return KeyEventResult.handled;
}
// Return ignored to allow other key events to be handled.
return KeyEventResult.ignored;
}
InputDecoration _getInputDecoration(BuildContext context) {
final passedDecoration = _messageInputTheme.inputDecoration;
return InputDecoration(
@@ -340,6 +340,11 @@ typedef DownloadedPathCallback = void Function(String? path);
/// {@endtemplate}
typedef UserTapCallback = void Function(User, Widget?);
/// {@template rawKeyEventPredicate}
/// Callback called to react to a key event
/// {@endtemplate}
typedef KeyEventPredicate = bool Function(FocusNode, KeyEvent);
/// {@template userItemBuilder}
/// Builder used to create a custom [ListUserItem] from a [User]
/// {@endtemplate}