chore: merge latest changes
Signed-off-by: xsahil03x <[email protected]>
This commit is contained in:
@@ -876,6 +876,23 @@ class Channel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Retry the operation on the message based on the failed state.
|
||||||
|
///
|
||||||
|
/// For example, if the message failed to send, it will retry sending the
|
||||||
|
/// message and vice-versa.
|
||||||
|
Future<Object> retryMessage(Message message) async {
|
||||||
|
assert(message.state.isFailed, 'Message state is not failed');
|
||||||
|
|
||||||
|
return message.state.maybeWhen(
|
||||||
|
failed: (state, _) => state.when(
|
||||||
|
sendingFailed: () => sendMessage(message),
|
||||||
|
updatingFailed: () => updateMessage(message),
|
||||||
|
deletingFailed: (hard) => deleteMessage(message, hard: hard),
|
||||||
|
),
|
||||||
|
orElse: () => throw StateError('Message state is not failed'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/// Pins provided message
|
/// Pins provided message
|
||||||
Future<UpdateMessageResponse> pinMessage(
|
Future<UpdateMessageResponse> pinMessage(
|
||||||
Message message, {
|
Message message, {
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ class RetryQueue {
|
|||||||
final retryPolicy = _retryPolicy;
|
final retryPolicy = _retryPolicy;
|
||||||
try {
|
try {
|
||||||
await backOff(
|
await backOff(
|
||||||
() => _retryMessage(message),
|
() => channel.retryMessage(message),
|
||||||
delayFactor: retryPolicy.delayFactor,
|
delayFactor: retryPolicy.delayFactor,
|
||||||
randomizationFactor: retryPolicy.randomizationFactor,
|
randomizationFactor: retryPolicy.randomizationFactor,
|
||||||
maxDelay: retryPolicy.maxDelay,
|
maxDelay: retryPolicy.maxDelay,
|
||||||
@@ -113,17 +113,6 @@ class RetryQueue {
|
|||||||
_isProcessing = false;
|
_isProcessing = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Object> _retryMessage(Message message) async {
|
|
||||||
return message.state.maybeWhen(
|
|
||||||
failed: (state, _) => state.when(
|
|
||||||
sendingFailed: () => channel.sendMessage(message),
|
|
||||||
updatingFailed: () => channel.updateMessage(message),
|
|
||||||
deletingFailed: (hard) => channel.deleteMessage(message, hard: hard),
|
|
||||||
),
|
|
||||||
orElse: () => throw StateError('Message state is not failed'),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Whether our [_messageQueue] has messages or not.
|
/// Whether our [_messageQueue] has messages or not.
|
||||||
bool get hasMessages => _messageQueue.isNotEmpty;
|
bool get hasMessages => _messageQueue.isNotEmpty;
|
||||||
|
|
||||||
|
|||||||
+10
-1
@@ -19,6 +19,7 @@ class MessageActionsModal extends StatefulWidget {
|
|||||||
this.showDeleteMessage = true,
|
this.showDeleteMessage = true,
|
||||||
this.showEditMessage = true,
|
this.showEditMessage = true,
|
||||||
this.onReplyTap,
|
this.onReplyTap,
|
||||||
|
this.onConfirmDeleteTap,
|
||||||
this.onThreadReplyTap,
|
this.onThreadReplyTap,
|
||||||
this.showCopyMessage = true,
|
this.showCopyMessage = true,
|
||||||
this.showReplyMessage = true,
|
this.showReplyMessage = true,
|
||||||
@@ -44,6 +45,9 @@ class MessageActionsModal extends StatefulWidget {
|
|||||||
/// The action to perform when "reply" is tapped
|
/// The action to perform when "reply" is tapped
|
||||||
final OnMessageTap? onReplyTap;
|
final OnMessageTap? onReplyTap;
|
||||||
|
|
||||||
|
/// The action to perform when delete confirmation button is tapped.
|
||||||
|
final Future<void> Function(Message)? onConfirmDeleteTap;
|
||||||
|
|
||||||
/// Message in focus for actions
|
/// Message in focus for actions
|
||||||
final Message message;
|
final Message message;
|
||||||
|
|
||||||
@@ -359,7 +363,12 @@ class _MessageActionsModalState extends State<MessageActionsModal> {
|
|||||||
if (answer == true) {
|
if (answer == true) {
|
||||||
try {
|
try {
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
await StreamChannel.of(context).channel.deleteMessage(widget.message);
|
final onConfirmDeleteTap = widget.onConfirmDeleteTap;
|
||||||
|
if (onConfirmDeleteTap != null) {
|
||||||
|
await onConfirmDeleteTap(widget.message);
|
||||||
|
} else {
|
||||||
|
await StreamChannel.of(context).channel.deleteMessage(widget.message);
|
||||||
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
_showErrorAlertBottomSheet();
|
_showErrorAlertBottomSheet();
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-6
@@ -27,12 +27,7 @@ class ResendMessageButton extends StatelessWidget {
|
|||||||
return InkWell(
|
return InkWell(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
message.state.whenOrNull(failed: (state, error) {
|
channel.retryMessage(message);
|
||||||
state.whenOrNull(
|
|
||||||
sendingFailed: () => channel.sendMessage(message),
|
|
||||||
updatingFailed: () => channel.updateMessage(message),
|
|
||||||
);
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 11, horizontal: 16),
|
padding: const EdgeInsets.symmetric(vertical: 11, horizontal: 16),
|
||||||
|
|||||||
@@ -129,6 +129,7 @@ class StreamMessageInput extends StatefulWidget {
|
|||||||
this.customAutocompleteTriggers = const [],
|
this.customAutocompleteTriggers = const [],
|
||||||
this.mentionAllAppUsers = false,
|
this.mentionAllAppUsers = false,
|
||||||
this.sendButtonBuilder,
|
this.sendButtonBuilder,
|
||||||
|
this.quotedMessageBuilder,
|
||||||
this.shouldKeepFocusAfterMessage,
|
this.shouldKeepFocusAfterMessage,
|
||||||
this.validator = _defaultValidator,
|
this.validator = _defaultValidator,
|
||||||
this.restorationId,
|
this.restorationId,
|
||||||
@@ -266,6 +267,9 @@ class StreamMessageInput extends StatefulWidget {
|
|||||||
/// Builder for creating send button
|
/// Builder for creating send button
|
||||||
final MessageRelatedBuilder? sendButtonBuilder;
|
final MessageRelatedBuilder? sendButtonBuilder;
|
||||||
|
|
||||||
|
/// Builder for building quoted message
|
||||||
|
final Widget Function(BuildContext, Message)? quotedMessageBuilder;
|
||||||
|
|
||||||
/// Defines if the [StreamMessageInput] loses focuses after a message is sent.
|
/// Defines if the [StreamMessageInput] loses focuses after a message is sent.
|
||||||
/// The default behaviour keeps focus until a command is enabled.
|
/// The default behaviour keeps focus until a command is enabled.
|
||||||
final bool? shouldKeepFocusAfterMessage;
|
final bool? shouldKeepFocusAfterMessage;
|
||||||
@@ -781,7 +785,6 @@ class StreamMessageInputState extends State<StreamMessageInput>
|
|||||||
Future<void> _onAttachmentButtonPressed() async {
|
Future<void> _onAttachmentButtonPressed() async {
|
||||||
final attachments = await showStreamAttachmentPickerModalBottomSheet(
|
final attachments = await showStreamAttachmentPickerModalBottomSheet(
|
||||||
context: context,
|
context: context,
|
||||||
useRootNavigator: true,
|
|
||||||
allowedTypes: widget.allowedAttachmentPickerTypes,
|
allowedTypes: widget.allowedAttachmentPickerTypes,
|
||||||
initialAttachments: _effectiveController.attachments,
|
initialAttachments: _effectiveController.attachments,
|
||||||
);
|
);
|
||||||
@@ -1131,14 +1134,20 @@ class StreamMessageInputState extends State<StreamMessageInput>
|
|||||||
if (!_hasQuotedMessage) return const Offstage();
|
if (!_hasQuotedMessage) return const Offstage();
|
||||||
final containsUrl = _effectiveController.message.quotedMessage!.attachments
|
final containsUrl = _effectiveController.message.quotedMessage!.attachments
|
||||||
.any((element) => element.titleLink != null);
|
.any((element) => element.titleLink != null);
|
||||||
return StreamQuotedMessageWidget(
|
|
||||||
reverse: true,
|
return widget.quotedMessageBuilder?.call(
|
||||||
showBorder: !containsUrl,
|
context,
|
||||||
message: _effectiveController.message.quotedMessage!,
|
_effectiveController.message.quotedMessage!,
|
||||||
messageTheme: _streamChatTheme.otherMessageTheme,
|
) ??
|
||||||
padding: const EdgeInsets.fromLTRB(8, 8, 8, 0),
|
StreamQuotedMessageWidget(
|
||||||
onQuotedMessageClear: widget.onQuotedMessageCleared,
|
reverse: true,
|
||||||
);
|
showBorder: !containsUrl,
|
||||||
|
message: _effectiveController.message.quotedMessage!,
|
||||||
|
messageTheme: _streamChatTheme.otherMessageTheme,
|
||||||
|
padding: const EdgeInsets.fromLTRB(8, 8, 8, 0),
|
||||||
|
onQuotedMessageClear: widget.onQuotedMessageCleared,
|
||||||
|
attachmentThumbnailBuilders: widget.attachmentThumbnailBuilders,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildAttachments() {
|
Widget _buildAttachments() {
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ class StreamMessageWidget extends StatefulWidget {
|
|||||||
this.showInChannelIndicator = false,
|
this.showInChannelIndicator = false,
|
||||||
this.onReplyTap,
|
this.onReplyTap,
|
||||||
this.onThreadTap,
|
this.onThreadTap,
|
||||||
|
this.onConfirmDeleteTap,
|
||||||
this.showUsername = true,
|
this.showUsername = true,
|
||||||
this.showTimestamp = true,
|
this.showTimestamp = true,
|
||||||
this.showReactions = true,
|
this.showReactions = true,
|
||||||
@@ -78,6 +79,7 @@ class StreamMessageWidget extends StatefulWidget {
|
|||||||
this.onMessageActions,
|
this.onMessageActions,
|
||||||
this.onShowMessage,
|
this.onShowMessage,
|
||||||
this.userAvatarBuilder,
|
this.userAvatarBuilder,
|
||||||
|
this.quotedMessageBuilder,
|
||||||
this.editMessageInputBuilder,
|
this.editMessageInputBuilder,
|
||||||
this.textBuilder,
|
this.textBuilder,
|
||||||
@Deprecated('''
|
@Deprecated('''
|
||||||
@@ -307,6 +309,11 @@ class StreamMessageWidget extends StatefulWidget {
|
|||||||
/// {@endtemplate}
|
/// {@endtemplate}
|
||||||
final void Function(Message)? onReplyTap;
|
final void Function(Message)? onReplyTap;
|
||||||
|
|
||||||
|
/// {@template onDeleteTap}
|
||||||
|
/// The function called when delete confirmation button is tapped.
|
||||||
|
/// {@endtemplate}
|
||||||
|
final Future<void> Function(Message)? onConfirmDeleteTap;
|
||||||
|
|
||||||
/// {@template editMessageInputBuilder}
|
/// {@template editMessageInputBuilder}
|
||||||
/// Widget builder for edit message layout
|
/// Widget builder for edit message layout
|
||||||
/// {@endtemplate}
|
/// {@endtemplate}
|
||||||
@@ -348,6 +355,11 @@ class StreamMessageWidget extends StatefulWidget {
|
|||||||
/// {@endtemplate}
|
/// {@endtemplate}
|
||||||
final Widget Function(BuildContext, User)? userAvatarBuilder;
|
final Widget Function(BuildContext, User)? userAvatarBuilder;
|
||||||
|
|
||||||
|
/// {@template quotedMessageBuilder}
|
||||||
|
/// Widget builder for building quoted message
|
||||||
|
/// {@endtemplate}
|
||||||
|
final Widget Function(BuildContext, Message)? quotedMessageBuilder;
|
||||||
|
|
||||||
/// {@template message}
|
/// {@template message}
|
||||||
/// The message to display.
|
/// The message to display.
|
||||||
/// {@endtemplate}
|
/// {@endtemplate}
|
||||||
@@ -568,8 +580,10 @@ class StreamMessageWidget extends StatefulWidget {
|
|||||||
void Function(User)? onMentionTap,
|
void Function(User)? onMentionTap,
|
||||||
void Function(Message)? onThreadTap,
|
void Function(Message)? onThreadTap,
|
||||||
void Function(Message)? onReplyTap,
|
void Function(Message)? onReplyTap,
|
||||||
|
Future<void> Function(Message)? onConfirmDeleteTap,
|
||||||
Widget Function(BuildContext, Message)? editMessageInputBuilder,
|
Widget Function(BuildContext, Message)? editMessageInputBuilder,
|
||||||
Widget Function(BuildContext, Message)? textBuilder,
|
Widget Function(BuildContext, Message)? textBuilder,
|
||||||
|
Widget Function(BuildContext, Message)? quotedMessageBuilder,
|
||||||
@Deprecated('''
|
@Deprecated('''
|
||||||
Use [bottomRowBuilderWithDefaultWidget] instead.
|
Use [bottomRowBuilderWithDefaultWidget] instead.
|
||||||
Will be removed in the next major version.
|
Will be removed in the next major version.
|
||||||
@@ -659,9 +673,11 @@ class StreamMessageWidget extends StatefulWidget {
|
|||||||
onMentionTap: onMentionTap ?? this.onMentionTap,
|
onMentionTap: onMentionTap ?? this.onMentionTap,
|
||||||
onThreadTap: onThreadTap ?? this.onThreadTap,
|
onThreadTap: onThreadTap ?? this.onThreadTap,
|
||||||
onReplyTap: onReplyTap ?? this.onReplyTap,
|
onReplyTap: onReplyTap ?? this.onReplyTap,
|
||||||
|
onConfirmDeleteTap: onConfirmDeleteTap ?? this.onConfirmDeleteTap,
|
||||||
editMessageInputBuilder:
|
editMessageInputBuilder:
|
||||||
editMessageInputBuilder ?? this.editMessageInputBuilder,
|
editMessageInputBuilder ?? this.editMessageInputBuilder,
|
||||||
textBuilder: textBuilder ?? this.textBuilder,
|
textBuilder: textBuilder ?? this.textBuilder,
|
||||||
|
quotedMessageBuilder: quotedMessageBuilder ?? this.quotedMessageBuilder,
|
||||||
bottomRowBuilderWithDefaultWidget: _bottomRowBuilderWithDefaultWidget,
|
bottomRowBuilderWithDefaultWidget: _bottomRowBuilderWithDefaultWidget,
|
||||||
onMessageActions: onMessageActions ?? this.onMessageActions,
|
onMessageActions: onMessageActions ?? this.onMessageActions,
|
||||||
message: message ?? this.message,
|
message: message ?? this.message,
|
||||||
@@ -955,6 +971,7 @@ class _StreamMessageWidgetState extends State<StreamMessageWidget>
|
|||||||
borderSide: widget.borderSide,
|
borderSide: widget.borderSide,
|
||||||
borderRadiusGeometry: widget.borderRadiusGeometry,
|
borderRadiusGeometry: widget.borderRadiusGeometry,
|
||||||
textBuilder: widget.textBuilder,
|
textBuilder: widget.textBuilder,
|
||||||
|
quotedMessageBuilder: widget.quotedMessageBuilder,
|
||||||
onLinkTap: widget.onLinkTap,
|
onLinkTap: widget.onLinkTap,
|
||||||
onMentionTap: widget.onMentionTap,
|
onMentionTap: widget.onMentionTap,
|
||||||
onQuotedMessageTap: widget.onQuotedMessageTap,
|
onQuotedMessageTap: widget.onQuotedMessageTap,
|
||||||
@@ -1094,16 +1111,21 @@ class _StreamMessageWidgetState extends State<StreamMessageWidget>
|
|||||||
),
|
),
|
||||||
onClick: () async {
|
onClick: () async {
|
||||||
Navigator.of(context, rootNavigator: true).pop();
|
Navigator.of(context, rootNavigator: true).pop();
|
||||||
final deleted = await showDialog(
|
final deleted = await showDialog<bool?>(
|
||||||
context: context,
|
context: context,
|
||||||
barrierDismissible: false,
|
barrierDismissible: false,
|
||||||
builder: (_) => const DeleteMessageDialog(),
|
builder: (_) => const DeleteMessageDialog(),
|
||||||
);
|
);
|
||||||
if (deleted) {
|
if (deleted == true) {
|
||||||
try {
|
try {
|
||||||
await StreamChannel.of(context)
|
final onConfirmDeleteTap = widget.onConfirmDeleteTap;
|
||||||
.channel
|
if (onConfirmDeleteTap != null) {
|
||||||
.deleteMessage(widget.message);
|
await onConfirmDeleteTap(widget.message);
|
||||||
|
} else {
|
||||||
|
await StreamChannel.of(context)
|
||||||
|
.channel
|
||||||
|
.deleteMessage(widget.message);
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
showDialog(
|
showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
@@ -1175,6 +1197,7 @@ class _StreamMessageWidgetState extends State<StreamMessageWidget>
|
|||||||
messageTheme: widget.messageTheme,
|
messageTheme: widget.messageTheme,
|
||||||
reverse: widget.reverse,
|
reverse: widget.reverse,
|
||||||
showDeleteMessage: shouldShowDeleteAction,
|
showDeleteMessage: shouldShowDeleteAction,
|
||||||
|
onConfirmDeleteTap: widget.onConfirmDeleteTap,
|
||||||
message: widget.message,
|
message: widget.message,
|
||||||
editMessageInputBuilder: widget.editMessageInputBuilder,
|
editMessageInputBuilder: widget.editMessageInputBuilder,
|
||||||
onReplyTap: widget.onReplyTap,
|
onReplyTap: widget.onReplyTap,
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ class MessageWidgetContent extends StatelessWidget {
|
|||||||
this.onMentionTap,
|
this.onMentionTap,
|
||||||
this.onLinkTap,
|
this.onLinkTap,
|
||||||
this.textBuilder,
|
this.textBuilder,
|
||||||
|
this.quotedMessageBuilder,
|
||||||
@Deprecated('''
|
@Deprecated('''
|
||||||
Use [bottomRowBuilderWithDefaultWidget] instead.
|
Use [bottomRowBuilderWithDefaultWidget] instead.
|
||||||
Will be removed in the next major version.
|
Will be removed in the next major version.
|
||||||
@@ -170,6 +171,9 @@ class MessageWidgetContent extends StatelessWidget {
|
|||||||
/// {@macro textBuilder}
|
/// {@macro textBuilder}
|
||||||
final Widget Function(BuildContext, Message)? textBuilder;
|
final Widget Function(BuildContext, Message)? textBuilder;
|
||||||
|
|
||||||
|
/// {@macro quotedMessageBuilder}
|
||||||
|
final Widget Function(BuildContext, Message)? quotedMessageBuilder;
|
||||||
|
|
||||||
/// {@macro showReactionPickerIndicator}
|
/// {@macro showReactionPickerIndicator}
|
||||||
final bool showReactionPickerIndicator;
|
final bool showReactionPickerIndicator;
|
||||||
|
|
||||||
@@ -351,6 +355,8 @@ class MessageWidgetContent extends StatelessWidget {
|
|||||||
onMentionTap: onMentionTap,
|
onMentionTap: onMentionTap,
|
||||||
onLinkTap: onLinkTap,
|
onLinkTap: onLinkTap,
|
||||||
textBuilder: textBuilder,
|
textBuilder: textBuilder,
|
||||||
|
quotedMessageBuilder:
|
||||||
|
quotedMessageBuilder,
|
||||||
borderRadiusGeometry:
|
borderRadiusGeometry:
|
||||||
borderRadiusGeometry,
|
borderRadiusGeometry,
|
||||||
borderSide: borderSide,
|
borderSide: borderSide,
|
||||||
|
|||||||
Reference in New Issue
Block a user