chore: merge latest changes

Signed-off-by: xsahil03x <[email protected]>
This commit is contained in:
Sahil Kumar
2023-06-20 15:28:05 +05:30
committed by xsahil03x
parent ffeef9fc3e
commit 6c8c4b54fa
7 changed files with 81 additions and 33 deletions
@@ -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;
@@ -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();
} }
@@ -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,