Merge pull request #1674 from GetStream/release/6.7.0
This commit is contained in:
@@ -1,3 +1,10 @@
|
|||||||
|
## 6.6.0
|
||||||
|
|
||||||
|
🔄 Changed
|
||||||
|
|
||||||
|
- Deprecated `Message.status` in favor of `Message.state`.
|
||||||
|
- Deprecated `RetryPolicy.retryTimeout` in favor of `RetryPolicy.delayFactor`.
|
||||||
|
|
||||||
## 6.5.0
|
## 6.5.0
|
||||||
|
|
||||||
🔄 Changed
|
🔄 Changed
|
||||||
|
|||||||
@@ -582,7 +582,7 @@ class Channel {
|
|||||||
// Eg. Updating the message while the previous call is in progress.
|
// Eg. Updating the message while the previous call is in progress.
|
||||||
_messageAttachmentsUploadCompleter
|
_messageAttachmentsUploadCompleter
|
||||||
.remove(message.id)
|
.remove(message.id)
|
||||||
?.completeError('Message Cancelled');
|
?.completeError(const StreamChatError('Message cancelled'));
|
||||||
|
|
||||||
final quotedMessage = state!.messages.firstWhereOrNull(
|
final quotedMessage = state!.messages.firstWhereOrNull(
|
||||||
(m) => m.id == message.quotedMessageId,
|
(m) => m.id == message.quotedMessageId,
|
||||||
@@ -592,7 +592,7 @@ class Channel {
|
|||||||
localCreatedAt: DateTime.now(),
|
localCreatedAt: DateTime.now(),
|
||||||
user: _client.state.currentUser,
|
user: _client.state.currentUser,
|
||||||
quotedMessage: quotedMessage,
|
quotedMessage: quotedMessage,
|
||||||
status: MessageSendingStatus.sending,
|
state: MessageState.sending,
|
||||||
attachments: message.attachments.map(
|
attachments: message.attachments.map(
|
||||||
(it) {
|
(it) {
|
||||||
if (it.uploadState.isSuccess) return it;
|
if (it.uploadState.isSuccess) return it;
|
||||||
@@ -630,15 +630,24 @@ class Channel {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
final sentMessage = response.message.syncWith(message);
|
final sentMessage = response.message.syncWith(message).copyWith(
|
||||||
|
// Update the message state to sent.
|
||||||
|
state: MessageState.sent,
|
||||||
|
);
|
||||||
|
|
||||||
state!.updateMessage(sentMessage);
|
state!.updateMessage(sentMessage);
|
||||||
if (cooldown > 0) cooldownStartedAt = DateTime.now();
|
if (cooldown > 0) cooldownStartedAt = DateTime.now();
|
||||||
return response;
|
return response;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e is StreamChatNetworkError && e.isRetriable) {
|
if (e is StreamChatNetworkError && e.isRetriable) {
|
||||||
state!._retryQueue.add([message]);
|
state!._retryQueue.add([
|
||||||
|
message.copyWith(
|
||||||
|
// Update the message state to failed.
|
||||||
|
state: MessageState.sendingFailed,
|
||||||
|
),
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -653,17 +662,18 @@ class Channel {
|
|||||||
Message message, {
|
Message message, {
|
||||||
bool skipEnrichUrl = false,
|
bool skipEnrichUrl = false,
|
||||||
}) async {
|
}) async {
|
||||||
|
_checkInitialized();
|
||||||
final originalMessage = message;
|
final originalMessage = message;
|
||||||
|
|
||||||
// Cancelling previous completer in case it's called again in the process
|
// Cancelling previous completer in case it's called again in the process
|
||||||
// Eg. Updating the message while the previous call is in progress.
|
// Eg. Updating the message while the previous call is in progress.
|
||||||
_messageAttachmentsUploadCompleter
|
_messageAttachmentsUploadCompleter
|
||||||
.remove(message.id)
|
.remove(message.id)
|
||||||
?.completeError('Message Cancelled');
|
?.completeError(const StreamChatError('Message cancelled'));
|
||||||
|
|
||||||
// ignore: parameter_assignments
|
// ignore: parameter_assignments
|
||||||
message = message.copyWith(
|
message = message.copyWith(
|
||||||
status: MessageSendingStatus.updating,
|
state: MessageState.updating,
|
||||||
localUpdatedAt: DateTime.now(),
|
localUpdatedAt: DateTime.now(),
|
||||||
attachments: message.attachments.map(
|
attachments: message.attachments.map(
|
||||||
(it) {
|
(it) {
|
||||||
@@ -699,19 +709,30 @@ class Channel {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
final updatedMessage = response.message
|
final updateMessage = response.message.syncWith(message).copyWith(
|
||||||
.syncWith(message)
|
// Update the message state to updated.
|
||||||
.copyWith(ownReactions: message.ownReactions);
|
state: MessageState.updated,
|
||||||
|
ownReactions: message.ownReactions,
|
||||||
|
);
|
||||||
|
|
||||||
state?.updateMessage(updatedMessage);
|
state?.updateMessage(updateMessage);
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e is StreamChatNetworkError) {
|
if (e is StreamChatNetworkError) {
|
||||||
if (e.isRetriable) {
|
if (e.isRetriable) {
|
||||||
state!._retryQueue.add([message]);
|
state!._retryQueue.add([
|
||||||
|
message.copyWith(
|
||||||
|
// Update the message state to failed.
|
||||||
|
state: MessageState.updatingFailed,
|
||||||
|
),
|
||||||
|
]);
|
||||||
} else {
|
} else {
|
||||||
state?.updateMessage(originalMessage);
|
// Reset the message to original state if the update fails and is not
|
||||||
|
// retriable.
|
||||||
|
state?.updateMessage(originalMessage.copyWith(
|
||||||
|
state: MessageState.updatingFailed,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rethrow;
|
rethrow;
|
||||||
@@ -729,6 +750,23 @@ class Channel {
|
|||||||
List<String>? unset,
|
List<String>? unset,
|
||||||
bool skipEnrichUrl = false,
|
bool skipEnrichUrl = false,
|
||||||
}) async {
|
}) async {
|
||||||
|
_checkInitialized();
|
||||||
|
final originalMessage = message;
|
||||||
|
|
||||||
|
// Cancelling previous completer in case it's called again in the process
|
||||||
|
// Eg. Updating the message while the previous call is in progress.
|
||||||
|
_messageAttachmentsUploadCompleter
|
||||||
|
.remove(message.id)
|
||||||
|
?.completeError(const StreamChatError('Message cancelled'));
|
||||||
|
|
||||||
|
// ignore: parameter_assignments
|
||||||
|
message = message.copyWith(
|
||||||
|
state: MessageState.updating,
|
||||||
|
localUpdatedAt: DateTime.now(),
|
||||||
|
);
|
||||||
|
|
||||||
|
state?.updateMessage(message);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Wait for the previous update call to finish. Otherwise, the order of
|
// Wait for the previous update call to finish. Otherwise, the order of
|
||||||
// messages will not be maintained.
|
// messages will not be maintained.
|
||||||
@@ -741,17 +779,33 @@ class Channel {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
final updatedMessage = response.message
|
final updatedMessage = response.message.syncWith(message).copyWith(
|
||||||
.syncWith(message)
|
// Update the message state to updated.
|
||||||
.copyWith(ownReactions: message.ownReactions);
|
state: MessageState.updated,
|
||||||
|
ownReactions: message.ownReactions,
|
||||||
|
);
|
||||||
|
|
||||||
state?.updateMessage(updatedMessage);
|
state?.updateMessage(updatedMessage);
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e is StreamChatNetworkError && e.isRetriable) {
|
if (e is StreamChatNetworkError) {
|
||||||
state!._retryQueue.add([message]);
|
if (e.isRetriable) {
|
||||||
|
state!._retryQueue.add([
|
||||||
|
message.copyWith(
|
||||||
|
// Update the message state to failed.
|
||||||
|
state: MessageState.updatingFailed,
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
} else {
|
||||||
|
// Reset the message to original state if the update fails and is not
|
||||||
|
// retriable.
|
||||||
|
state?.updateMessage(originalMessage.copyWith(
|
||||||
|
state: MessageState.updatingFailed,
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -759,39 +813,43 @@ class Channel {
|
|||||||
final _deleteMessageLock = Lock();
|
final _deleteMessageLock = Lock();
|
||||||
|
|
||||||
/// Deletes the [message] from the channel.
|
/// Deletes the [message] from the channel.
|
||||||
Future<EmptyResponse> deleteMessage(Message message, {bool? hard}) async {
|
Future<EmptyResponse> deleteMessage(
|
||||||
final hardDelete = hard ?? false;
|
Message message, {
|
||||||
|
bool hard = false,
|
||||||
|
}) async {
|
||||||
|
_checkInitialized();
|
||||||
|
|
||||||
// Directly deleting the local messages which are not yet sent to server
|
// Directly deleting the local messages which are not yet sent to server.
|
||||||
if (message.status == MessageSendingStatus.sending ||
|
if (message.remoteCreatedAt == null) {
|
||||||
message.status == MessageSendingStatus.failed) {
|
|
||||||
state!.deleteMessage(
|
state!.deleteMessage(
|
||||||
message.copyWith(
|
message.copyWith(
|
||||||
type: 'deleted',
|
type: 'deleted',
|
||||||
localDeletedAt: DateTime.now(),
|
localDeletedAt: DateTime.now(),
|
||||||
status: MessageSendingStatus.sent,
|
state: MessageState.deleted(hard: hard),
|
||||||
),
|
),
|
||||||
hardDelete: hardDelete,
|
hardDelete: hard,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Removing the attachments upload completer to stop the `sendMessage`
|
// Removing the attachments upload completer to stop the `sendMessage`
|
||||||
// waiting for attachments to complete.
|
// waiting for attachments to complete.
|
||||||
_messageAttachmentsUploadCompleter
|
_messageAttachmentsUploadCompleter
|
||||||
.remove(message.id)
|
.remove(message.id)
|
||||||
?.completeError(Exception('Message deleted'));
|
?.completeError(const StreamChatError('Message deleted'));
|
||||||
|
|
||||||
|
// Returning empty response to mark the api call as success.
|
||||||
return EmptyResponse();
|
return EmptyResponse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ignore: parameter_assignments
|
||||||
|
message = message.copyWith(
|
||||||
|
type: 'deleted',
|
||||||
|
deletedAt: DateTime.now(),
|
||||||
|
state: MessageState.deleting(hard: hard),
|
||||||
|
);
|
||||||
|
|
||||||
|
state?.deleteMessage(message, hardDelete: hard);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// ignore: parameter_assignments
|
|
||||||
message = message.copyWith(
|
|
||||||
type: 'deleted',
|
|
||||||
status: MessageSendingStatus.deleting,
|
|
||||||
deletedAt: message.deletedAt ?? DateTime.now(),
|
|
||||||
);
|
|
||||||
|
|
||||||
state?.deleteMessage(message, hardDelete: hardDelete);
|
|
||||||
|
|
||||||
// Wait for the previous delete call to finish. Otherwise, the order of
|
// Wait for the previous delete call to finish. Otherwise, the order of
|
||||||
// messages will not be maintained.
|
// messages will not be maintained.
|
||||||
final response = await _deleteMessageLock.synchronized(
|
final response = await _deleteMessageLock.synchronized(
|
||||||
@@ -799,20 +857,42 @@ class Channel {
|
|||||||
);
|
);
|
||||||
|
|
||||||
final deletedMessage = message.copyWith(
|
final deletedMessage = message.copyWith(
|
||||||
status: MessageSendingStatus.sent,
|
state: MessageState.deleted(hard: hard),
|
||||||
);
|
);
|
||||||
|
|
||||||
state?.deleteMessage(deletedMessage, hardDelete: hardDelete);
|
state?.deleteMessage(deletedMessage, hardDelete: hard);
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e is StreamChatNetworkError && e.isRetriable) {
|
if (e is StreamChatNetworkError && e.isRetriable) {
|
||||||
state!._retryQueue.add([message]);
|
state!._retryQueue.add([
|
||||||
|
message.copyWith(
|
||||||
|
// Update the message state to failed.
|
||||||
|
state: MessageState.deletingFailed(hard: hard),
|
||||||
|
),
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
rethrow;
|
rethrow;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// 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, {
|
||||||
@@ -1895,15 +1975,7 @@ class ChannelClientState {
|
|||||||
/// Retry failed message.
|
/// Retry failed message.
|
||||||
Future<void> retryFailedMessages() async {
|
Future<void> retryFailedMessages() async {
|
||||||
final failedMessages = [...messages, ...threads.values.expand((v) => v)]
|
final failedMessages = [...messages, ...threads.values.expand((v) => v)]
|
||||||
.where(
|
.where((it) => it.state.isFailed);
|
||||||
(message) =>
|
|
||||||
message.status != MessageSendingStatus.sent &&
|
|
||||||
message.createdAt.isBefore(
|
|
||||||
DateTime.now().subtract(const Duration(seconds: 5)),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.toList();
|
|
||||||
|
|
||||||
_retryQueue.add(failedMessages);
|
_retryQueue.add(failedMessages);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -109,8 +109,9 @@ class StreamChatClient {
|
|||||||
|
|
||||||
_retryPolicy = retryPolicy ??
|
_retryPolicy = retryPolicy ??
|
||||||
RetryPolicy(
|
RetryPolicy(
|
||||||
shouldRetry: (_, attempt, __) => attempt < 5,
|
shouldRetry: (_, __, error) {
|
||||||
retryTimeout: (_, attempt, __) => Duration(seconds: attempt),
|
return error is StreamChatNetworkError && error.isRetriable;
|
||||||
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
state = ClientState(this);
|
state = ClientState(this);
|
||||||
@@ -1397,12 +1398,19 @@ class StreamChatClient {
|
|||||||
);
|
);
|
||||||
|
|
||||||
/// Deletes the given message
|
/// Deletes the given message
|
||||||
Future<EmptyResponse> deleteMessage(String messageId, {bool? hard}) async {
|
Future<EmptyResponse> deleteMessage(
|
||||||
final response =
|
String messageId, {
|
||||||
await _chatApi.message.deleteMessage(messageId, hard: hard);
|
bool hard = false,
|
||||||
if (hard == true) {
|
}) async {
|
||||||
|
final response = await _chatApi.message.deleteMessage(
|
||||||
|
messageId,
|
||||||
|
hard: hard,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (hard) {
|
||||||
await chatPersistenceClient?.deleteMessageById(messageId);
|
await chatPersistenceClient?.deleteMessageById(messageId);
|
||||||
}
|
}
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,27 +1,54 @@
|
|||||||
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:stream_chat/src/client/client.dart';
|
import 'package:stream_chat/src/client/client.dart';
|
||||||
import 'package:stream_chat/src/core/error/error.dart';
|
import 'package:stream_chat/src/core/error/error.dart';
|
||||||
|
|
||||||
/// The retry options
|
/// The retry policy associated to a client.
|
||||||
/// When sending/updating/deleting a message any temporary error will trigger the retry policy
|
|
||||||
/// The retry policy exposes 2 methods
|
|
||||||
/// - shouldRetry: returns a boolean if the request should be retried
|
|
||||||
/// - retryTimeout: How many milliseconds to wait till the next attempt
|
|
||||||
///
|
///
|
||||||
/// maxRetryAttempts is a hard limit on maximum retry attempts before giving up
|
/// This policy is used to determine if a request should be retried and when.
|
||||||
|
///
|
||||||
|
/// also see:
|
||||||
|
/// - [RetryQueue]
|
||||||
class RetryPolicy {
|
class RetryPolicy {
|
||||||
/// Instantiate a new RetryPolicy
|
/// Instantiate a new RetryPolicy
|
||||||
RetryPolicy({
|
RetryPolicy({
|
||||||
required this.shouldRetry,
|
required this.shouldRetry,
|
||||||
required this.retryTimeout,
|
@Deprecated("Use 'delayFactor' instead.") this.retryTimeout,
|
||||||
this.maxRetryAttempts = 6,
|
this.maxRetryAttempts = 6,
|
||||||
|
this.delayFactor = const Duration(milliseconds: 200),
|
||||||
|
this.randomizationFactor = 0.25,
|
||||||
|
this.maxDelay = const Duration(seconds: 30),
|
||||||
});
|
});
|
||||||
|
|
||||||
/// Hard limit on maximum retry attempts before giving up, defaults to 6
|
/// Delay factor to double after every attempt.
|
||||||
/// Resets once connection recovers.
|
///
|
||||||
|
/// Defaults to 200 ms, which results in the following delays:
|
||||||
|
///
|
||||||
|
/// 1. 400 ms
|
||||||
|
/// 2. 800 ms
|
||||||
|
/// 3. 1600 ms
|
||||||
|
/// 4. 3200 ms
|
||||||
|
/// 5. 6400 ms
|
||||||
|
/// 6. 12800 ms
|
||||||
|
///
|
||||||
|
/// Before application of [randomizationFactor].
|
||||||
|
final Duration delayFactor;
|
||||||
|
|
||||||
|
/// Percentage the delay should be randomized, given as fraction between
|
||||||
|
/// 0 and 1.
|
||||||
|
///
|
||||||
|
/// If [randomizationFactor] is `0.25` (default) this indicates 25 % of the
|
||||||
|
/// delay should be increased or decreased by 25 %.
|
||||||
|
final double randomizationFactor;
|
||||||
|
|
||||||
|
/// Maximum delay between retries, defaults to 30 seconds.
|
||||||
|
final Duration maxDelay;
|
||||||
|
|
||||||
|
/// Maximum number of attempts before giving up, defaults to 6.
|
||||||
final int maxRetryAttempts;
|
final int maxRetryAttempts;
|
||||||
|
|
||||||
/// This function evaluates if we should retry the failure
|
/// Function to determine if a retry should be attempted.
|
||||||
final bool Function(
|
final FutureOr<bool> Function(
|
||||||
StreamChatClient client,
|
StreamChatClient client,
|
||||||
int attempt,
|
int attempt,
|
||||||
StreamChatError? error,
|
StreamChatError? error,
|
||||||
@@ -29,9 +56,10 @@ class RetryPolicy {
|
|||||||
|
|
||||||
/// In the case that we want to retry a failed request the retryTimeout
|
/// In the case that we want to retry a failed request the retryTimeout
|
||||||
/// method is called to determine the timeout
|
/// method is called to determine the timeout
|
||||||
|
@Deprecated("Use 'delayFactor' instead.")
|
||||||
final Duration Function(
|
final Duration Function(
|
||||||
StreamChatClient client,
|
StreamChatClient client,
|
||||||
int attempt,
|
int attempt,
|
||||||
StreamChatError? error,
|
StreamChatError? error,
|
||||||
) retryTimeout;
|
)? retryTimeout;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class RetryQueue {
|
|||||||
}) : client = channel.client {
|
}) : client = channel.client {
|
||||||
_retryPolicy = client.retryPolicy;
|
_retryPolicy = client.retryPolicy;
|
||||||
_listenConnectionRecovered();
|
_listenConnectionRecovered();
|
||||||
_listenFailedEvents();
|
_listenMessageEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The channel of this queue.
|
/// The channel of this queue.
|
||||||
@@ -31,153 +31,94 @@ class RetryQueue {
|
|||||||
final _compositeSubscription = CompositeSubscription();
|
final _compositeSubscription = CompositeSubscription();
|
||||||
|
|
||||||
final _messageQueue = HeapPriorityQueue(_byDate);
|
final _messageQueue = HeapPriorityQueue(_byDate);
|
||||||
bool _isRetrying = false;
|
|
||||||
|
|
||||||
void _listenConnectionRecovered() {
|
void _listenConnectionRecovered() {
|
||||||
client.on(EventType.connectionRecovered).listen((event) {
|
client.on(EventType.connectionRecovered).distinct().listen((event) {
|
||||||
if (event.online == true) {
|
if (event.online == true) {
|
||||||
_startRetrying();
|
logger?.info('Connection recovered, retrying failed messages');
|
||||||
|
channel.state?.retryFailedMessages();
|
||||||
}
|
}
|
||||||
}).addTo(_compositeSubscription);
|
}).addTo(_compositeSubscription);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _listenFailedEvents() {
|
void _listenMessageEvents() {
|
||||||
channel.on().where((event) => event.message != null).listen((event) {
|
channel.on().where((event) => event.message != null).listen((event) {
|
||||||
final message = event.message!;
|
final message = event.message!;
|
||||||
final containsMessage = _messageQueue.containsMessage(message);
|
final containsMessage = _messageQueue.containsMessage(message);
|
||||||
if (!containsMessage) return;
|
if (!containsMessage) return;
|
||||||
if (message.status == MessageSendingStatus.sent) {
|
|
||||||
|
if (message.state.isCompleted) {
|
||||||
logger?.info('Removing sent message from queue : ${message.id}');
|
logger?.info('Removing sent message from queue : ${message.id}');
|
||||||
_messageQueue.removeMessage(message);
|
return _messageQueue.removeMessage(message);
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
if ([
|
|
||||||
MessageSendingStatus.failed_update,
|
|
||||||
MessageSendingStatus.failed,
|
|
||||||
MessageSendingStatus.failed_delete,
|
|
||||||
].contains(message.status)) {
|
|
||||||
logger?.info('Adding failed message from event : ${event.type}');
|
|
||||||
add([message]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}).addTo(_compositeSubscription);
|
}).addTo(_compositeSubscription);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Add a list of messages.
|
/// Add a list of messages.
|
||||||
void add(List<Message> messages) {
|
void add(Iterable<Message> messages) {
|
||||||
if (messages.isEmpty) return;
|
assert(
|
||||||
if (!_messageQueue.containsAllMessage(messages)) {
|
messages.every((it) => it.state.isFailed),
|
||||||
logger?.info('Adding ${messages.length} messages');
|
'Only failed messages can be added to the queue',
|
||||||
final messageList = _messageQueue.toList();
|
);
|
||||||
// we should not add message if already available in the queue
|
|
||||||
_messageQueue.addAll(messages.where(
|
|
||||||
(it) => !messageList.any((m) => m.id == it.id),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
_startRetrying();
|
// Filter out messages that are already in the queue.
|
||||||
|
final messagesToAdd = messages.where((it) {
|
||||||
|
return !_messageQueue.containsMessage(it);
|
||||||
|
});
|
||||||
|
|
||||||
|
// If there are no messages to add, return.
|
||||||
|
if (messagesToAdd.isEmpty) return;
|
||||||
|
|
||||||
|
logger?.info('Adding ${messagesToAdd.length} messages to the queue');
|
||||||
|
_messageQueue.addAll(messagesToAdd);
|
||||||
|
|
||||||
|
_processQueue();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _startRetrying() async {
|
bool _isProcessing = false;
|
||||||
if (_isRetrying) return;
|
|
||||||
_isRetrying = true;
|
Future<void> _processQueue() async {
|
||||||
|
if (_isProcessing) return;
|
||||||
|
_isProcessing = true;
|
||||||
|
|
||||||
logger?.info('Started retrying failed messages');
|
logger?.info('Started retrying failed messages');
|
||||||
while (_messageQueue.isNotEmpty) {
|
while (_messageQueue.isNotEmpty) {
|
||||||
logger?.info('${_messageQueue.length} messages remaining in the queue');
|
logger?.info('${_messageQueue.length} messages remaining in the queue');
|
||||||
|
|
||||||
final message = _messageQueue.first;
|
final message = _messageQueue.first;
|
||||||
final succeeded = await _runAndRetry(message);
|
final retryPolicy = _retryPolicy;
|
||||||
if (!succeeded) {
|
|
||||||
_messageQueue.toList().forEach(_sendFailedEvent);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_isRetrying = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<bool> _runAndRetry(Message message) async {
|
|
||||||
var attempt = 1;
|
|
||||||
|
|
||||||
final maxAttempt = _retryPolicy.maxRetryAttempts;
|
|
||||||
// early return in case maxAttempt is less than 0
|
|
||||||
if (attempt > maxAttempt) return false;
|
|
||||||
|
|
||||||
// ignore: literal_only_boolean_expressions
|
|
||||||
while (true) {
|
|
||||||
try {
|
try {
|
||||||
logger?.info('Message (${message.id}) retry attempt $attempt');
|
await backOff(
|
||||||
await _retryMessage(message);
|
() => channel.retryMessage(message),
|
||||||
logger?.info('Message (${message.id}) sent successfully');
|
delayFactor: retryPolicy.delayFactor,
|
||||||
_messageQueue.removeMessage(message);
|
randomizationFactor: retryPolicy.randomizationFactor,
|
||||||
return true;
|
maxDelay: retryPolicy.maxDelay,
|
||||||
} catch (e) {
|
maxAttempts: retryPolicy.maxRetryAttempts,
|
||||||
if (e is! StreamChatNetworkError || !e.isRetriable) {
|
retryIf: (error, attempt) {
|
||||||
_messageQueue.removeMessage(message);
|
if (error is! StreamChatError) return false;
|
||||||
_sendFailedEvent(message);
|
return retryPolicy.shouldRetry(client, attempt, error);
|
||||||
return true;
|
},
|
||||||
}
|
);
|
||||||
// retry logic
|
} catch (error) {
|
||||||
final maxAttempt = _retryPolicy.maxRetryAttempts;
|
logger?.severe('Error while retrying message ${message.id}', error);
|
||||||
if (attempt < maxAttempt) {
|
// If we are unable to successfully retry the message, update the state
|
||||||
final shouldRetry = _retryPolicy.shouldRetry(client, attempt, e);
|
// with the failed state.
|
||||||
if (shouldRetry) {
|
channel.state?.updateMessage(message);
|
||||||
final timeout = _retryPolicy.retryTimeout(client, attempt, e);
|
} finally {
|
||||||
// temporary failure, continue
|
// remove the message from the queue after it's handled.
|
||||||
logger?.info(
|
_messageQueue.removeFirst();
|
||||||
'API call failed (attempt $attempt), '
|
|
||||||
'retrying in ${timeout.inSeconds} seconds. Error was $e',
|
|
||||||
);
|
|
||||||
await Future.delayed(timeout);
|
|
||||||
attempt += 1;
|
|
||||||
} else {
|
|
||||||
logger?.info(
|
|
||||||
'API call failed (attempt $attempt). '
|
|
||||||
'Giving up for now, will retry when connection recovers. '
|
|
||||||
'Error was $e',
|
|
||||||
);
|
|
||||||
_sendFailedEvent(message);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
logger?.info(
|
|
||||||
'API call failed (attempt $attempt). '
|
|
||||||
'Exceeds maxRetryAttempt : $maxAttempt '
|
|
||||||
'Giving up for now, will retry when connection recovers. '
|
|
||||||
'Error was $e',
|
|
||||||
);
|
|
||||||
_sendFailedEvent(message);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _sendFailedEvent(Message message) {
|
_isProcessing = false;
|
||||||
final newStatus = message.status == MessageSendingStatus.sending
|
|
||||||
? MessageSendingStatus.failed
|
|
||||||
: message.status == MessageSendingStatus.updating
|
|
||||||
? MessageSendingStatus.failed_update
|
|
||||||
: MessageSendingStatus.failed_delete;
|
|
||||||
channel.state?.updateMessage(message.copyWith(status: newStatus));
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> _retryMessage(Message message) async {
|
|
||||||
if (message.status == MessageSendingStatus.failed_update ||
|
|
||||||
message.status == MessageSendingStatus.updating) {
|
|
||||||
await channel.updateMessage(message);
|
|
||||||
} else if (message.status == MessageSendingStatus.failed ||
|
|
||||||
message.status == MessageSendingStatus.sending) {
|
|
||||||
await channel.sendMessage(message);
|
|
||||||
} else if (message.status == MessageSendingStatus.failed_delete ||
|
|
||||||
message.status == MessageSendingStatus.deleting) {
|
|
||||||
await channel.deleteMessage(message);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Whether our [_messageQueue] has messages or not.
|
/// Whether our [_messageQueue] has messages or not.
|
||||||
bool get hasMessages => _messageQueue.isNotEmpty;
|
bool get hasMessages => _messageQueue.isNotEmpty;
|
||||||
|
|
||||||
|
/// Returns true if the queue contains the given [message].
|
||||||
|
bool contains(Message message) => _messageQueue.containsMessage(message);
|
||||||
|
|
||||||
/// Call this method to dispose this object.
|
/// Call this method to dispose this object.
|
||||||
void dispose() {
|
void dispose() {
|
||||||
_messageQueue.clear();
|
_messageQueue.clear();
|
||||||
@@ -188,33 +129,25 @@ class RetryQueue {
|
|||||||
final date1 = _getMessageDate(m1);
|
final date1 = _getMessageDate(m1);
|
||||||
final date2 = _getMessageDate(m2);
|
final date2 = _getMessageDate(m2);
|
||||||
|
|
||||||
if (date1 == null || date2 == null) {
|
if (date1 == null && date2 == null) return 0;
|
||||||
return 0;
|
if (date1 == null) return -1;
|
||||||
}
|
if (date2 == null) return 1;
|
||||||
|
|
||||||
return date1.compareTo(date2);
|
return date1.compareTo(date2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static DateTime? _getMessageDate(Message m1) {
|
static DateTime? _getMessageDate(Message message) {
|
||||||
switch (m1.status) {
|
return message.state.maybeWhen(
|
||||||
case MessageSendingStatus.failed_delete:
|
failed: (state, _) => state.when(
|
||||||
case MessageSendingStatus.deleting:
|
sendingFailed: () => message.createdAt,
|
||||||
return m1.deletedAt;
|
updatingFailed: () => message.updatedAt,
|
||||||
|
deletingFailed: (_) => message.deletedAt,
|
||||||
case MessageSendingStatus.failed:
|
),
|
||||||
case MessageSendingStatus.sending:
|
orElse: () => null,
|
||||||
return m1.createdAt;
|
);
|
||||||
|
|
||||||
case MessageSendingStatus.failed_update:
|
|
||||||
case MessageSendingStatus.updating:
|
|
||||||
return m1.updatedAt;
|
|
||||||
default:
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension _MessageHeapPriorityQueue on HeapPriorityQueue<Message> {
|
extension on HeapPriorityQueue<Message> {
|
||||||
void removeMessage(Message message) {
|
void removeMessage(Message message) {
|
||||||
final list = toUnorderedList();
|
final list = toUnorderedList();
|
||||||
final index = list.indexWhere((it) => it.id == message.id);
|
final index = list.indexWhere((it) => it.id == message.id);
|
||||||
@@ -229,11 +162,4 @@ extension _MessageHeapPriorityQueue on HeapPriorityQueue<Message> {
|
|||||||
if (index == -1) return false;
|
if (index == -1) return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool containsAllMessage(List<Message> messages) {
|
|
||||||
if (isEmpty) return false;
|
|
||||||
final list = toUnorderedList();
|
|
||||||
final messageIds = messages.map((it) => it.id);
|
|
||||||
return list.every((it) => messageIds.contains(it.id));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
import 'package:json_annotation/json_annotation.dart';
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
import 'package:stream_chat/src/core/models/attachment.dart';
|
import 'package:stream_chat/src/core/models/attachment.dart';
|
||||||
|
import 'package:stream_chat/src/core/models/message_state.dart';
|
||||||
import 'package:stream_chat/src/core/models/reaction.dart';
|
import 'package:stream_chat/src/core/models/reaction.dart';
|
||||||
import 'package:stream_chat/src/core/models/user.dart';
|
import 'package:stream_chat/src/core/models/user.dart';
|
||||||
import 'package:stream_chat/src/core/util/serializer.dart';
|
import 'package:stream_chat/src/core/util/serializer.dart';
|
||||||
@@ -37,7 +38,45 @@ enum MessageSendingStatus {
|
|||||||
failed_delete,
|
failed_delete,
|
||||||
|
|
||||||
/// Message correctly sent
|
/// Message correctly sent
|
||||||
sent,
|
sent;
|
||||||
|
|
||||||
|
/// Returns a [MessageState] from a [MessageSendingStatus]
|
||||||
|
MessageState toMessageState() {
|
||||||
|
switch (this) {
|
||||||
|
case MessageSendingStatus.sending:
|
||||||
|
return MessageState.sending;
|
||||||
|
case MessageSendingStatus.updating:
|
||||||
|
return MessageState.updating;
|
||||||
|
case MessageSendingStatus.deleting:
|
||||||
|
return MessageState.softDeleting;
|
||||||
|
case MessageSendingStatus.failed:
|
||||||
|
return MessageState.sendingFailed;
|
||||||
|
case MessageSendingStatus.failed_update:
|
||||||
|
return MessageState.updatingFailed;
|
||||||
|
case MessageSendingStatus.failed_delete:
|
||||||
|
return MessageState.softDeletingFailed;
|
||||||
|
case MessageSendingStatus.sent:
|
||||||
|
return MessageState.sent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a [MessageSendingStatus] from a [MessageState].
|
||||||
|
static MessageSendingStatus fromMessageState(MessageState state) {
|
||||||
|
return state.when(
|
||||||
|
initial: () => MessageSendingStatus.sending,
|
||||||
|
outgoing: (it) => it.when(
|
||||||
|
sending: () => MessageSendingStatus.sending,
|
||||||
|
updating: () => MessageSendingStatus.updating,
|
||||||
|
deleting: (_) => MessageSendingStatus.deleting,
|
||||||
|
),
|
||||||
|
completed: (_) => MessageSendingStatus.sent,
|
||||||
|
failed: (it, __) => it.when(
|
||||||
|
sendingFailed: () => MessageSendingStatus.failed,
|
||||||
|
updatingFailed: () => MessageSendingStatus.failed_update,
|
||||||
|
deletingFailed: (_) => MessageSendingStatus.failed_delete,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The class that contains the information about a message.
|
/// The class that contains the information about a message.
|
||||||
@@ -75,21 +114,39 @@ class Message extends Equatable {
|
|||||||
DateTime? pinExpires,
|
DateTime? pinExpires,
|
||||||
this.pinnedBy,
|
this.pinnedBy,
|
||||||
this.extraData = const {},
|
this.extraData = const {},
|
||||||
this.status = MessageSendingStatus.sending,
|
@Deprecated('Use `state` instead') MessageSendingStatus? status,
|
||||||
|
MessageState? state,
|
||||||
this.i18n,
|
this.i18n,
|
||||||
}) : id = id ?? const Uuid().v4(),
|
}) : id = id ?? const Uuid().v4(),
|
||||||
pinExpires = pinExpires?.toUtc(),
|
pinExpires = pinExpires?.toUtc(),
|
||||||
remoteCreatedAt = createdAt,
|
remoteCreatedAt = createdAt,
|
||||||
remoteUpdatedAt = updatedAt,
|
remoteUpdatedAt = updatedAt,
|
||||||
remoteDeletedAt = deletedAt,
|
remoteDeletedAt = deletedAt,
|
||||||
_quotedMessageId = quotedMessageId;
|
_quotedMessageId = quotedMessageId {
|
||||||
|
var messageState = state ?? const MessageState.initial();
|
||||||
|
// Backward compatibility. TODO: Remove in the next major version
|
||||||
|
if (status != null) {
|
||||||
|
messageState = status.toMessageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.state = messageState;
|
||||||
|
}
|
||||||
|
|
||||||
/// Create a new instance from JSON.
|
/// Create a new instance from JSON.
|
||||||
factory Message.fromJson(Map<String, dynamic> json) => _$MessageFromJson(
|
factory Message.fromJson(Map<String, dynamic> json) {
|
||||||
Serializer.moveToExtraDataFromRoot(json, topLevelFields),
|
final message = _$MessageFromJson(
|
||||||
).copyWith(
|
Serializer.moveToExtraDataFromRoot(json, topLevelFields),
|
||||||
status: MessageSendingStatus.sent,
|
);
|
||||||
);
|
|
||||||
|
var state = MessageState.sent;
|
||||||
|
if (message.deletedAt != null) {
|
||||||
|
state = MessageState.softDeleted;
|
||||||
|
} else if (message.updatedAt.isAfter(message.createdAt)) {
|
||||||
|
state = MessageState.updated;
|
||||||
|
}
|
||||||
|
|
||||||
|
return message.copyWith(state: state);
|
||||||
|
}
|
||||||
|
|
||||||
/// The message ID. This is either created by Stream or set client side when
|
/// The message ID. This is either created by Stream or set client side when
|
||||||
/// the message is added.
|
/// the message is added.
|
||||||
@@ -99,8 +156,16 @@ class Message extends Equatable {
|
|||||||
final String? text;
|
final String? text;
|
||||||
|
|
||||||
/// The status of a sending message.
|
/// The status of a sending message.
|
||||||
|
@Deprecated('Use `state` instead')
|
||||||
@JsonKey(includeFromJson: false, includeToJson: false)
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
final MessageSendingStatus status;
|
MessageSendingStatus get status {
|
||||||
|
return MessageSendingStatus.fromMessageState(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Remove late modifier in the next major version.
|
||||||
|
/// The current state of the message.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
late final MessageState state;
|
||||||
|
|
||||||
/// The message type.
|
/// The message type.
|
||||||
@JsonKey(includeToJson: false)
|
@JsonKey(includeToJson: false)
|
||||||
@@ -316,7 +381,8 @@ class Message extends Equatable {
|
|||||||
Object? pinExpires = _nullConst,
|
Object? pinExpires = _nullConst,
|
||||||
User? pinnedBy,
|
User? pinnedBy,
|
||||||
Map<String, Object?>? extraData,
|
Map<String, Object?>? extraData,
|
||||||
MessageSendingStatus? status,
|
@Deprecated('Use `state` instead') MessageSendingStatus? status,
|
||||||
|
MessageState? state,
|
||||||
Map<String, String>? i18n,
|
Map<String, String>? i18n,
|
||||||
}) {
|
}) {
|
||||||
assert(() {
|
assert(() {
|
||||||
@@ -350,6 +416,8 @@ class Message extends Equatable {
|
|||||||
return true;
|
return true;
|
||||||
}(), 'Validate type for quotedMessage');
|
}(), 'Validate type for quotedMessage');
|
||||||
|
|
||||||
|
final messageState = state ?? status?.toMessageState();
|
||||||
|
|
||||||
return Message(
|
return Message(
|
||||||
id: id ?? this.id,
|
id: id ?? this.id,
|
||||||
text: text ?? this.text,
|
text: text ?? this.text,
|
||||||
@@ -386,47 +454,49 @@ class Message extends Equatable {
|
|||||||
pinExpires == _nullConst ? this.pinExpires : pinExpires as DateTime?,
|
pinExpires == _nullConst ? this.pinExpires : pinExpires as DateTime?,
|
||||||
pinnedBy: pinnedBy ?? this.pinnedBy,
|
pinnedBy: pinnedBy ?? this.pinnedBy,
|
||||||
extraData: extraData ?? this.extraData,
|
extraData: extraData ?? this.extraData,
|
||||||
status: status ?? this.status,
|
state: messageState ?? this.state,
|
||||||
i18n: i18n ?? this.i18n,
|
i18n: i18n ?? this.i18n,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns a new [Message] that is a combination of this message and the
|
/// Returns a new [Message] that is a combination of this message and the
|
||||||
/// given [other] message.
|
/// given [other] message.
|
||||||
Message merge(Message other) => copyWith(
|
Message merge(Message other) {
|
||||||
id: other.id,
|
return copyWith(
|
||||||
text: other.text,
|
id: other.id,
|
||||||
type: other.type,
|
text: other.text,
|
||||||
attachments: other.attachments,
|
type: other.type,
|
||||||
mentionedUsers: other.mentionedUsers,
|
attachments: other.attachments,
|
||||||
silent: other.silent,
|
mentionedUsers: other.mentionedUsers,
|
||||||
shadowed: other.shadowed,
|
silent: other.silent,
|
||||||
reactionCounts: other.reactionCounts,
|
shadowed: other.shadowed,
|
||||||
reactionScores: other.reactionScores,
|
reactionCounts: other.reactionCounts,
|
||||||
latestReactions: other.latestReactions,
|
reactionScores: other.reactionScores,
|
||||||
ownReactions: other.ownReactions,
|
latestReactions: other.latestReactions,
|
||||||
parentId: other.parentId,
|
ownReactions: other.ownReactions,
|
||||||
quotedMessage: other.quotedMessage,
|
parentId: other.parentId,
|
||||||
quotedMessageId: other.quotedMessageId,
|
quotedMessage: other.quotedMessage,
|
||||||
replyCount: other.replyCount,
|
quotedMessageId: other.quotedMessageId,
|
||||||
threadParticipants: other.threadParticipants,
|
replyCount: other.replyCount,
|
||||||
showInChannel: other.showInChannel,
|
threadParticipants: other.threadParticipants,
|
||||||
command: other.command,
|
showInChannel: other.showInChannel,
|
||||||
createdAt: other.remoteCreatedAt,
|
command: other.command,
|
||||||
localCreatedAt: other.localCreatedAt,
|
createdAt: other.remoteCreatedAt,
|
||||||
updatedAt: other.remoteUpdatedAt,
|
localCreatedAt: other.localCreatedAt,
|
||||||
localUpdatedAt: other.localUpdatedAt,
|
updatedAt: other.remoteUpdatedAt,
|
||||||
deletedAt: other.remoteDeletedAt,
|
localUpdatedAt: other.localUpdatedAt,
|
||||||
localDeletedAt: other.localDeletedAt,
|
deletedAt: other.remoteDeletedAt,
|
||||||
user: other.user,
|
localDeletedAt: other.localDeletedAt,
|
||||||
pinned: other.pinned,
|
user: other.user,
|
||||||
pinnedAt: other.pinnedAt,
|
pinned: other.pinned,
|
||||||
pinExpires: other.pinExpires,
|
pinnedAt: other.pinnedAt,
|
||||||
pinnedBy: other.pinnedBy,
|
pinExpires: other.pinExpires,
|
||||||
extraData: other.extraData,
|
pinnedBy: other.pinnedBy,
|
||||||
status: other.status,
|
extraData: other.extraData,
|
||||||
i18n: other.i18n,
|
state: other.state,
|
||||||
);
|
i18n: other.i18n,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns a new [Message] that is [other] with local changes applied to it.
|
/// Returns a new [Message] that is [other] with local changes applied to it.
|
||||||
///
|
///
|
||||||
@@ -482,7 +552,7 @@ class Message extends Equatable {
|
|||||||
pinExpires,
|
pinExpires,
|
||||||
pinnedBy,
|
pinnedBy,
|
||||||
extraData,
|
extraData,
|
||||||
status,
|
state,
|
||||||
i18n,
|
i18n,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,299 @@
|
|||||||
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
|
||||||
|
part 'message_state.freezed.dart';
|
||||||
|
|
||||||
|
part 'message_state.g.dart';
|
||||||
|
|
||||||
|
/// Helper extension for [MessageState].
|
||||||
|
extension MessageStateX on MessageState {
|
||||||
|
/// Returns true if the message is in initial state.
|
||||||
|
bool get isInitial => this is MessageInitial;
|
||||||
|
|
||||||
|
/// Returns true if the message is in outgoing state.
|
||||||
|
bool get isOutgoing => this is MessageOutgoing;
|
||||||
|
|
||||||
|
/// Returns true if the message is in completed state.
|
||||||
|
bool get isCompleted => this is MessageCompleted;
|
||||||
|
|
||||||
|
/// Returns true if the message is in failed state.
|
||||||
|
bool get isFailed => this is MessageFailed;
|
||||||
|
|
||||||
|
/// Returns true if the message is in outgoing sending state.
|
||||||
|
bool get isSending {
|
||||||
|
final messageState = this;
|
||||||
|
return messageState is MessageOutgoing && messageState.state is Sending;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns true if the message is in outgoing updating state.
|
||||||
|
bool get isUpdating {
|
||||||
|
final messageState = this;
|
||||||
|
return messageState is MessageOutgoing && messageState.state is Updating;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns true if the message is in outgoing deleting state.
|
||||||
|
bool get isDeleting => isSoftDeleting || isHardDeleting;
|
||||||
|
|
||||||
|
/// Returns true if the message is in outgoing soft deleting state.
|
||||||
|
bool get isSoftDeleting {
|
||||||
|
final messageState = this;
|
||||||
|
if (messageState is! MessageOutgoing) return false;
|
||||||
|
|
||||||
|
final outgoingState = messageState.state;
|
||||||
|
if (outgoingState is! Deleting) return false;
|
||||||
|
|
||||||
|
return !outgoingState.hard;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns true if the message is in outgoing hard deleting state.
|
||||||
|
bool get isHardDeleting {
|
||||||
|
final messageState = this;
|
||||||
|
if (messageState is! MessageOutgoing) return false;
|
||||||
|
|
||||||
|
final outgoingState = messageState.state;
|
||||||
|
if (outgoingState is! Deleting) return false;
|
||||||
|
|
||||||
|
return outgoingState.hard;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns true if the message is in completed sent state.
|
||||||
|
bool get isSent {
|
||||||
|
final messageState = this;
|
||||||
|
return messageState is MessageCompleted && messageState.state is Sent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns true if the message is in completed updated state.
|
||||||
|
bool get isUpdated {
|
||||||
|
final messageState = this;
|
||||||
|
return messageState is MessageCompleted && messageState.state is Updated;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns true if the message is in completed deleted state.
|
||||||
|
bool get isDeleted => isSoftDeleted || isHardDeleted;
|
||||||
|
|
||||||
|
/// Returns true if the message is in completed soft deleted state.
|
||||||
|
bool get isSoftDeleted {
|
||||||
|
final messageState = this;
|
||||||
|
if (messageState is! MessageCompleted) return false;
|
||||||
|
|
||||||
|
final completedState = messageState.state;
|
||||||
|
if (completedState is! Deleted) return false;
|
||||||
|
|
||||||
|
return !completedState.hard;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns true if the message is in completed hard deleted state.
|
||||||
|
bool get isHardDeleted {
|
||||||
|
final messageState = this;
|
||||||
|
if (messageState is! MessageCompleted) return false;
|
||||||
|
|
||||||
|
final completedState = messageState.state;
|
||||||
|
if (completedState is! Deleted) return false;
|
||||||
|
|
||||||
|
return completedState.hard;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns true if the message is in failed sending state.
|
||||||
|
bool get isSendingFailed {
|
||||||
|
final messageState = this;
|
||||||
|
if (messageState is! MessageFailed) return false;
|
||||||
|
return messageState.state is SendingFailed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns true if the message is in failed updating state.
|
||||||
|
bool get isUpdatingFailed {
|
||||||
|
final messageState = this;
|
||||||
|
if (messageState is! MessageFailed) return false;
|
||||||
|
return messageState.state is UpdatingFailed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns true if the message is in failed deleting state.
|
||||||
|
bool get isDeletingFailed => isSoftDeletingFailed || isHardDeletingFailed;
|
||||||
|
|
||||||
|
/// Returns true if the message is in failed soft deleting state.
|
||||||
|
bool get isSoftDeletingFailed {
|
||||||
|
final messageState = this;
|
||||||
|
if (messageState is! MessageFailed) return false;
|
||||||
|
|
||||||
|
final failedState = messageState.state;
|
||||||
|
if (failedState is! DeletingFailed) return false;
|
||||||
|
|
||||||
|
return !failedState.hard;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns true if the message is in failed hard deleting state.
|
||||||
|
bool get isHardDeletingFailed {
|
||||||
|
final messageState = this;
|
||||||
|
if (messageState is! MessageFailed) return false;
|
||||||
|
|
||||||
|
final failedState = messageState.state;
|
||||||
|
if (failedState is! DeletingFailed) return false;
|
||||||
|
|
||||||
|
return failedState.hard;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Represents the various states a message can be in.
|
||||||
|
@freezed
|
||||||
|
class MessageState with _$MessageState {
|
||||||
|
/// Initial state when the message is created.
|
||||||
|
const factory MessageState.initial() = MessageInitial;
|
||||||
|
|
||||||
|
/// Outgoing state when the message is being sent, updated, or deleted.
|
||||||
|
const factory MessageState.outgoing({
|
||||||
|
required OutgoingState state,
|
||||||
|
}) = MessageOutgoing;
|
||||||
|
|
||||||
|
/// Completed state when the message has been successfully sent, updated, or
|
||||||
|
/// deleted.
|
||||||
|
const factory MessageState.completed({
|
||||||
|
required CompletedState state,
|
||||||
|
}) = MessageCompleted;
|
||||||
|
|
||||||
|
/// Failed state when the message fails to be sent, updated, or deleted.
|
||||||
|
const factory MessageState.failed({
|
||||||
|
required FailedState state,
|
||||||
|
Object? reason,
|
||||||
|
}) = MessageFailed;
|
||||||
|
|
||||||
|
/// Creates a new instance from a json
|
||||||
|
factory MessageState.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$MessageStateFromJson(json);
|
||||||
|
|
||||||
|
/// Deleting state when the message is being deleted.
|
||||||
|
factory MessageState.deleting({required bool hard}) {
|
||||||
|
return MessageState.outgoing(
|
||||||
|
state: OutgoingState.deleting(hard: hard),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Deleting state when the message has been successfully deleted.
|
||||||
|
factory MessageState.deleted({required bool hard}) {
|
||||||
|
return MessageState.completed(
|
||||||
|
state: CompletedState.deleted(hard: hard),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Deleting failed state when the message fails to be deleted.
|
||||||
|
factory MessageState.deletingFailed({required bool hard}) {
|
||||||
|
return MessageState.failed(
|
||||||
|
state: FailedState.deletingFailed(hard: hard),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Sending state when the message is being sent.
|
||||||
|
static const sending = MessageState.outgoing(
|
||||||
|
state: OutgoingState.sending(),
|
||||||
|
);
|
||||||
|
|
||||||
|
/// Updating state when the message is being updated.
|
||||||
|
static const updating = MessageState.outgoing(
|
||||||
|
state: OutgoingState.updating(),
|
||||||
|
);
|
||||||
|
|
||||||
|
/// Deleting state when the message is being soft deleted.
|
||||||
|
static const softDeleting = MessageState.outgoing(
|
||||||
|
state: OutgoingState.deleting(),
|
||||||
|
);
|
||||||
|
|
||||||
|
/// Hard deleting state when the message is being hard deleted.
|
||||||
|
static const hardDeleting = MessageState.outgoing(
|
||||||
|
state: OutgoingState.deleting(hard: true),
|
||||||
|
);
|
||||||
|
|
||||||
|
/// Sent state when the message has been successfully sent.
|
||||||
|
static const sent = MessageState.completed(
|
||||||
|
state: CompletedState.sent(),
|
||||||
|
);
|
||||||
|
|
||||||
|
/// Updated state when the message has been successfully updated.
|
||||||
|
static const updated = MessageState.completed(
|
||||||
|
state: CompletedState.updated(),
|
||||||
|
);
|
||||||
|
|
||||||
|
/// Deleted state when the message has been successfully soft deleted.
|
||||||
|
static const softDeleted = MessageState.completed(
|
||||||
|
state: CompletedState.deleted(),
|
||||||
|
);
|
||||||
|
|
||||||
|
/// Hard deleted state when the message has been successfully hard deleted.
|
||||||
|
static const hardDeleted = MessageState.completed(
|
||||||
|
state: CompletedState.deleted(hard: true),
|
||||||
|
);
|
||||||
|
|
||||||
|
/// Sending failed state when the message fails to be sent.
|
||||||
|
static const sendingFailed = MessageState.failed(
|
||||||
|
state: FailedState.sendingFailed(),
|
||||||
|
);
|
||||||
|
|
||||||
|
/// Updating failed state when the message fails to be updated.
|
||||||
|
static const updatingFailed = MessageState.failed(
|
||||||
|
state: FailedState.updatingFailed(),
|
||||||
|
);
|
||||||
|
|
||||||
|
/// Deleting failed state when the message fails to be soft deleted.
|
||||||
|
static const softDeletingFailed = MessageState.failed(
|
||||||
|
state: FailedState.deletingFailed(),
|
||||||
|
);
|
||||||
|
|
||||||
|
/// Hard deleting failed state when the message fails to be hard deleted.
|
||||||
|
static const hardDeletingFailed = MessageState.failed(
|
||||||
|
state: FailedState.deletingFailed(hard: true),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Represents the state of an outgoing message.
|
||||||
|
@freezed
|
||||||
|
class OutgoingState with _$OutgoingState {
|
||||||
|
/// Sending state when the message is being sent.
|
||||||
|
const factory OutgoingState.sending() = Sending;
|
||||||
|
|
||||||
|
/// Updating state when the message is being updated.
|
||||||
|
const factory OutgoingState.updating() = Updating;
|
||||||
|
|
||||||
|
/// Deleting state when the message is being deleted.
|
||||||
|
const factory OutgoingState.deleting({
|
||||||
|
@Default(false) bool hard,
|
||||||
|
}) = Deleting;
|
||||||
|
|
||||||
|
/// Creates a new instance from a json
|
||||||
|
factory OutgoingState.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$OutgoingStateFromJson(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Represents the completed state of a message.
|
||||||
|
@freezed
|
||||||
|
class CompletedState with _$CompletedState {
|
||||||
|
/// Sent state when the message has been successfully sent.
|
||||||
|
const factory CompletedState.sent() = Sent;
|
||||||
|
|
||||||
|
/// Updated state when the message has been successfully updated.
|
||||||
|
const factory CompletedState.updated() = Updated;
|
||||||
|
|
||||||
|
/// Deleted state when the message has been successfully deleted.
|
||||||
|
const factory CompletedState.deleted({
|
||||||
|
@Default(false) bool hard,
|
||||||
|
}) = Deleted;
|
||||||
|
|
||||||
|
/// Creates a new instance from a json
|
||||||
|
factory CompletedState.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$CompletedStateFromJson(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Represents the failed state of a message.
|
||||||
|
@freezed
|
||||||
|
class FailedState with _$FailedState {
|
||||||
|
/// Sending failed state when the message fails to be sent.
|
||||||
|
const factory FailedState.sendingFailed() = SendingFailed;
|
||||||
|
|
||||||
|
/// Updating failed state when the message fails to be updated.
|
||||||
|
const factory FailedState.updatingFailed() = UpdatingFailed;
|
||||||
|
|
||||||
|
/// Deleting failed state when the message fails to be deleted.
|
||||||
|
const factory FailedState.deletingFailed({
|
||||||
|
@Default(false) bool hard,
|
||||||
|
}) = DeletingFailed;
|
||||||
|
|
||||||
|
/// Creates a new instance from a json
|
||||||
|
factory FailedState.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$FailedStateFromJson(json);
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,141 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
|
part of 'message_state.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// JsonSerializableGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
_$MessageInitial _$$MessageInitialFromJson(Map<String, dynamic> json) =>
|
||||||
|
_$MessageInitial(
|
||||||
|
$type: json['runtimeType'] as String?,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$$MessageInitialToJson(_$MessageInitial instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'runtimeType': instance.$type,
|
||||||
|
};
|
||||||
|
|
||||||
|
_$MessageOutgoing _$$MessageOutgoingFromJson(Map<String, dynamic> json) =>
|
||||||
|
_$MessageOutgoing(
|
||||||
|
state: OutgoingState.fromJson(json['state'] as Map<String, dynamic>),
|
||||||
|
$type: json['runtimeType'] as String?,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$$MessageOutgoingToJson(_$MessageOutgoing instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'state': instance.state.toJson(),
|
||||||
|
'runtimeType': instance.$type,
|
||||||
|
};
|
||||||
|
|
||||||
|
_$MessageCompleted _$$MessageCompletedFromJson(Map<String, dynamic> json) =>
|
||||||
|
_$MessageCompleted(
|
||||||
|
state: CompletedState.fromJson(json['state'] as Map<String, dynamic>),
|
||||||
|
$type: json['runtimeType'] as String?,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$$MessageCompletedToJson(_$MessageCompleted instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'state': instance.state.toJson(),
|
||||||
|
'runtimeType': instance.$type,
|
||||||
|
};
|
||||||
|
|
||||||
|
_$MessageFailed _$$MessageFailedFromJson(Map<String, dynamic> json) =>
|
||||||
|
_$MessageFailed(
|
||||||
|
state: FailedState.fromJson(json['state'] as Map<String, dynamic>),
|
||||||
|
reason: json['reason'],
|
||||||
|
$type: json['runtimeType'] as String?,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$$MessageFailedToJson(_$MessageFailed instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'state': instance.state.toJson(),
|
||||||
|
'reason': instance.reason,
|
||||||
|
'runtimeType': instance.$type,
|
||||||
|
};
|
||||||
|
|
||||||
|
_$Sending _$$SendingFromJson(Map<String, dynamic> json) => _$Sending(
|
||||||
|
$type: json['runtimeType'] as String?,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$$SendingToJson(_$Sending instance) => <String, dynamic>{
|
||||||
|
'runtimeType': instance.$type,
|
||||||
|
};
|
||||||
|
|
||||||
|
_$Updating _$$UpdatingFromJson(Map<String, dynamic> json) => _$Updating(
|
||||||
|
$type: json['runtimeType'] as String?,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$$UpdatingToJson(_$Updating instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'runtimeType': instance.$type,
|
||||||
|
};
|
||||||
|
|
||||||
|
_$Deleting _$$DeletingFromJson(Map<String, dynamic> json) => _$Deleting(
|
||||||
|
hard: json['hard'] as bool? ?? false,
|
||||||
|
$type: json['runtimeType'] as String?,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$$DeletingToJson(_$Deleting instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'hard': instance.hard,
|
||||||
|
'runtimeType': instance.$type,
|
||||||
|
};
|
||||||
|
|
||||||
|
_$Sent _$$SentFromJson(Map<String, dynamic> json) => _$Sent(
|
||||||
|
$type: json['runtimeType'] as String?,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$$SentToJson(_$Sent instance) => <String, dynamic>{
|
||||||
|
'runtimeType': instance.$type,
|
||||||
|
};
|
||||||
|
|
||||||
|
_$Updated _$$UpdatedFromJson(Map<String, dynamic> json) => _$Updated(
|
||||||
|
$type: json['runtimeType'] as String?,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$$UpdatedToJson(_$Updated instance) => <String, dynamic>{
|
||||||
|
'runtimeType': instance.$type,
|
||||||
|
};
|
||||||
|
|
||||||
|
_$Deleted _$$DeletedFromJson(Map<String, dynamic> json) => _$Deleted(
|
||||||
|
hard: json['hard'] as bool? ?? false,
|
||||||
|
$type: json['runtimeType'] as String?,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$$DeletedToJson(_$Deleted instance) => <String, dynamic>{
|
||||||
|
'hard': instance.hard,
|
||||||
|
'runtimeType': instance.$type,
|
||||||
|
};
|
||||||
|
|
||||||
|
_$SendingFailed _$$SendingFailedFromJson(Map<String, dynamic> json) =>
|
||||||
|
_$SendingFailed(
|
||||||
|
$type: json['runtimeType'] as String?,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$$SendingFailedToJson(_$SendingFailed instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'runtimeType': instance.$type,
|
||||||
|
};
|
||||||
|
|
||||||
|
_$UpdatingFailed _$$UpdatingFailedFromJson(Map<String, dynamic> json) =>
|
||||||
|
_$UpdatingFailed(
|
||||||
|
$type: json['runtimeType'] as String?,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$$UpdatingFailedToJson(_$UpdatingFailed instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'runtimeType': instance.$type,
|
||||||
|
};
|
||||||
|
|
||||||
|
_$DeletingFailed _$$DeletingFailedFromJson(Map<String, dynamic> json) =>
|
||||||
|
_$DeletingFailed(
|
||||||
|
hard: json['hard'] as bool? ?? false,
|
||||||
|
$type: json['runtimeType'] as String?,
|
||||||
|
);
|
||||||
|
|
||||||
|
Map<String, dynamic> _$$DeletingFailedToJson(_$DeletingFailed instance) =>
|
||||||
|
<String, dynamic>{
|
||||||
|
'hard': instance.hard,
|
||||||
|
'runtimeType': instance.$type,
|
||||||
|
};
|
||||||
@@ -38,6 +38,7 @@ export 'src/core/models/event.dart';
|
|||||||
export 'src/core/models/filter.dart' show Filter;
|
export 'src/core/models/filter.dart' show Filter;
|
||||||
export 'src/core/models/member.dart';
|
export 'src/core/models/member.dart';
|
||||||
export 'src/core/models/message.dart';
|
export 'src/core/models/message.dart';
|
||||||
|
export 'src/core/models/message_state.dart';
|
||||||
export 'src/core/models/mute.dart';
|
export 'src/core/models/mute.dart';
|
||||||
export 'src/core/models/own_user.dart';
|
export 'src/core/models/own_user.dart';
|
||||||
export 'src/core/models/reaction.dart';
|
export 'src/core/models/reaction.dart';
|
||||||
|
|||||||
@@ -3,4 +3,4 @@ import 'package:stream_chat/src/client/client.dart';
|
|||||||
/// Current package version
|
/// Current package version
|
||||||
/// Used in [StreamChatClient] to build the `x-stream-client` header
|
/// Used in [StreamChatClient] to build the `x-stream-client` header
|
||||||
// ignore: constant_identifier_names
|
// ignore: constant_identifier_names
|
||||||
const PACKAGE_VERSION = '6.5.0';
|
const PACKAGE_VERSION = '6.6.0';
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
name: stream_chat
|
name: stream_chat
|
||||||
homepage: https://getstream.io/
|
homepage: https://getstream.io/
|
||||||
description: The official Dart client for Stream Chat, a service for building chat applications.
|
description: The official Dart client for Stream Chat, a service for building chat applications.
|
||||||
version: 6.5.0
|
version: 6.6.0
|
||||||
repository: https://github.com/GetStream/stream-chat-flutter
|
repository: https://github.com/GetStream/stream-chat-flutter
|
||||||
issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues
|
issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues
|
||||||
|
|
||||||
|
|||||||
@@ -133,7 +133,7 @@ void main() {
|
|||||||
|
|
||||||
final retryPolicy = RetryPolicy(
|
final retryPolicy = RetryPolicy(
|
||||||
shouldRetry: (_, __, ___) => false,
|
shouldRetry: (_, __, ___) => false,
|
||||||
retryTimeout: (_, __, ___) => Duration.zero,
|
delayFactor: Duration.zero,
|
||||||
);
|
);
|
||||||
when(() => client.retryPolicy).thenReturn(retryPolicy);
|
when(() => client.retryPolicy).thenReturn(retryPolicy);
|
||||||
|
|
||||||
@@ -191,7 +191,7 @@ void main() {
|
|||||||
|
|
||||||
final retryPolicy = RetryPolicy(
|
final retryPolicy = RetryPolicy(
|
||||||
shouldRetry: (_, __, ___) => false,
|
shouldRetry: (_, __, ___) => false,
|
||||||
retryTimeout: (_, __, ___) => Duration.zero,
|
delayFactor: Duration.zero,
|
||||||
);
|
);
|
||||||
when(() => client.retryPolicy).thenReturn(retryPolicy);
|
when(() => client.retryPolicy).thenReturn(retryPolicy);
|
||||||
|
|
||||||
@@ -253,7 +253,7 @@ void main() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
final sendMessageResponse = SendMessageResponse()
|
final sendMessageResponse = SendMessageResponse()
|
||||||
..message = message.copyWith(status: MessageSendingStatus.sent);
|
..message = message.copyWith(state: MessageState.sent);
|
||||||
|
|
||||||
when(() => client.sendMessage(
|
when(() => client.sendMessage(
|
||||||
any(that: isSameMessageAs(message)),
|
any(that: isSameMessageAs(message)),
|
||||||
@@ -267,14 +267,14 @@ void main() {
|
|||||||
emitsInOrder([
|
emitsInOrder([
|
||||||
[
|
[
|
||||||
isSameMessageAs(
|
isSameMessageAs(
|
||||||
message.copyWith(status: MessageSendingStatus.sending),
|
message.copyWith(state: MessageState.sending),
|
||||||
matchSendingStatus: true,
|
matchMessageState: true,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
isSameMessageAs(
|
isSameMessageAs(
|
||||||
message.copyWith(status: MessageSendingStatus.sent),
|
message.copyWith(state: MessageState.sent),
|
||||||
matchSendingStatus: true,
|
matchMessageState: true,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
]),
|
]),
|
||||||
@@ -338,7 +338,7 @@ void main() {
|
|||||||
.map((it) =>
|
.map((it) =>
|
||||||
it.copyWith(uploadState: const UploadState.success()))
|
it.copyWith(uploadState: const UploadState.success()))
|
||||||
.toList(growable: false),
|
.toList(growable: false),
|
||||||
status: MessageSendingStatus.sent,
|
state: MessageState.sent,
|
||||||
));
|
));
|
||||||
|
|
||||||
expectLater(
|
expectLater(
|
||||||
@@ -350,13 +350,13 @@ void main() {
|
|||||||
[
|
[
|
||||||
isSameMessageAs(
|
isSameMessageAs(
|
||||||
message.copyWith(
|
message.copyWith(
|
||||||
status: MessageSendingStatus.sending,
|
state: MessageState.sending,
|
||||||
attachments: [
|
attachments: [
|
||||||
...attachments.map((it) => it.copyWith(
|
...attachments.map((it) => it.copyWith(
|
||||||
uploadState: const UploadState.preparing()))
|
uploadState: const UploadState.preparing()))
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
matchSendingStatus: true,
|
matchMessageState: true,
|
||||||
matchAttachments: true,
|
matchAttachments: true,
|
||||||
matchAttachmentsUploadState: true,
|
matchAttachmentsUploadState: true,
|
||||||
),
|
),
|
||||||
@@ -365,13 +365,13 @@ void main() {
|
|||||||
[
|
[
|
||||||
isSameMessageAs(
|
isSameMessageAs(
|
||||||
message.copyWith(
|
message.copyWith(
|
||||||
status: MessageSendingStatus.sending,
|
state: MessageState.sending,
|
||||||
attachments: [...attachments]..[0] =
|
attachments: [...attachments]..[0] =
|
||||||
attachments[0].copyWith(
|
attachments[0].copyWith(
|
||||||
uploadState: const UploadState.success(),
|
uploadState: const UploadState.success(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
matchSendingStatus: true,
|
matchMessageState: true,
|
||||||
matchAttachments: true,
|
matchAttachments: true,
|
||||||
matchAttachmentsUploadState: true,
|
matchAttachmentsUploadState: true,
|
||||||
),
|
),
|
||||||
@@ -380,7 +380,7 @@ void main() {
|
|||||||
[
|
[
|
||||||
isSameMessageAs(
|
isSameMessageAs(
|
||||||
message.copyWith(
|
message.copyWith(
|
||||||
status: MessageSendingStatus.sending,
|
state: MessageState.sending,
|
||||||
attachments: [...attachments]
|
attachments: [...attachments]
|
||||||
..[0] = attachments[0].copyWith(
|
..[0] = attachments[0].copyWith(
|
||||||
uploadState: const UploadState.success(),
|
uploadState: const UploadState.success(),
|
||||||
@@ -389,7 +389,7 @@ void main() {
|
|||||||
uploadState: const UploadState.success(),
|
uploadState: const UploadState.success(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
matchSendingStatus: true,
|
matchMessageState: true,
|
||||||
matchAttachments: true,
|
matchAttachments: true,
|
||||||
matchAttachmentsUploadState: true,
|
matchAttachmentsUploadState: true,
|
||||||
),
|
),
|
||||||
@@ -398,13 +398,13 @@ void main() {
|
|||||||
[
|
[
|
||||||
isSameMessageAs(
|
isSameMessageAs(
|
||||||
message.copyWith(
|
message.copyWith(
|
||||||
status: MessageSendingStatus.sending,
|
state: MessageState.sending,
|
||||||
attachments: [
|
attachments: [
|
||||||
...attachments.map((it) =>
|
...attachments.map((it) =>
|
||||||
it.copyWith(uploadState: const UploadState.success()))
|
it.copyWith(uploadState: const UploadState.success()))
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
matchSendingStatus: true,
|
matchMessageState: true,
|
||||||
matchAttachments: true,
|
matchAttachments: true,
|
||||||
matchAttachmentsUploadState: true,
|
matchAttachmentsUploadState: true,
|
||||||
),
|
),
|
||||||
@@ -412,13 +412,13 @@ void main() {
|
|||||||
[
|
[
|
||||||
isSameMessageAs(
|
isSameMessageAs(
|
||||||
message.copyWith(
|
message.copyWith(
|
||||||
status: MessageSendingStatus.sent,
|
state: MessageState.sent,
|
||||||
attachments: [
|
attachments: [
|
||||||
...attachments.map((it) =>
|
...attachments.map((it) =>
|
||||||
it.copyWith(uploadState: const UploadState.success()))
|
it.copyWith(uploadState: const UploadState.success()))
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
matchSendingStatus: true,
|
matchMessageState: true,
|
||||||
matchAttachments: true,
|
matchAttachments: true,
|
||||||
matchAttachmentsUploadState: true,
|
matchAttachmentsUploadState: true,
|
||||||
),
|
),
|
||||||
@@ -469,7 +469,7 @@ void main() {
|
|||||||
test('should work fine', () async {
|
test('should work fine', () async {
|
||||||
final message = Message(
|
final message = Message(
|
||||||
id: 'test-message-id',
|
id: 'test-message-id',
|
||||||
status: MessageSendingStatus.sent,
|
state: MessageState.sent,
|
||||||
);
|
);
|
||||||
|
|
||||||
final updateMessageResponse = UpdateMessageResponse()
|
final updateMessageResponse = UpdateMessageResponse()
|
||||||
@@ -484,14 +484,14 @@ void main() {
|
|||||||
emitsInOrder([
|
emitsInOrder([
|
||||||
[
|
[
|
||||||
isSameMessageAs(
|
isSameMessageAs(
|
||||||
message.copyWith(status: MessageSendingStatus.updating),
|
message.copyWith(state: MessageState.updating),
|
||||||
matchSendingStatus: true,
|
matchMessageState: true,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
isSameMessageAs(
|
isSameMessageAs(
|
||||||
message.copyWith(status: MessageSendingStatus.sent),
|
message.copyWith(state: MessageState.updated),
|
||||||
matchSendingStatus: true,
|
matchMessageState: true,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
]),
|
]),
|
||||||
@@ -547,7 +547,7 @@ void main() {
|
|||||||
any(that: isSameMessageAs(message)),
|
any(that: isSameMessageAs(message)),
|
||||||
)).thenAnswer((_) async => UpdateMessageResponse()
|
)).thenAnswer((_) async => UpdateMessageResponse()
|
||||||
..message = message.copyWith(
|
..message = message.copyWith(
|
||||||
status: MessageSendingStatus.sent,
|
state: MessageState.sent,
|
||||||
attachments: attachments
|
attachments: attachments
|
||||||
.map((it) =>
|
.map((it) =>
|
||||||
it.copyWith(uploadState: const UploadState.success()))
|
it.copyWith(uploadState: const UploadState.success()))
|
||||||
@@ -563,13 +563,13 @@ void main() {
|
|||||||
[
|
[
|
||||||
isSameMessageAs(
|
isSameMessageAs(
|
||||||
message.copyWith(
|
message.copyWith(
|
||||||
status: MessageSendingStatus.updating,
|
state: MessageState.updating,
|
||||||
attachments: [
|
attachments: [
|
||||||
...attachments.map((it) => it.copyWith(
|
...attachments.map((it) => it.copyWith(
|
||||||
uploadState: const UploadState.preparing()))
|
uploadState: const UploadState.preparing()))
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
matchSendingStatus: true,
|
matchMessageState: true,
|
||||||
matchAttachments: true,
|
matchAttachments: true,
|
||||||
matchAttachmentsUploadState: true,
|
matchAttachmentsUploadState: true,
|
||||||
),
|
),
|
||||||
@@ -578,13 +578,13 @@ void main() {
|
|||||||
[
|
[
|
||||||
isSameMessageAs(
|
isSameMessageAs(
|
||||||
message.copyWith(
|
message.copyWith(
|
||||||
status: MessageSendingStatus.updating,
|
state: MessageState.updating,
|
||||||
attachments: [...attachments]..[0] =
|
attachments: [...attachments]..[0] =
|
||||||
attachments[0].copyWith(
|
attachments[0].copyWith(
|
||||||
uploadState: const UploadState.success(),
|
uploadState: const UploadState.success(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
matchSendingStatus: true,
|
matchMessageState: true,
|
||||||
matchAttachments: true,
|
matchAttachments: true,
|
||||||
matchAttachmentsUploadState: true,
|
matchAttachmentsUploadState: true,
|
||||||
),
|
),
|
||||||
@@ -593,7 +593,7 @@ void main() {
|
|||||||
[
|
[
|
||||||
isSameMessageAs(
|
isSameMessageAs(
|
||||||
message.copyWith(
|
message.copyWith(
|
||||||
status: MessageSendingStatus.updating,
|
state: MessageState.updating,
|
||||||
attachments: [...attachments]
|
attachments: [...attachments]
|
||||||
..[0] = attachments[0].copyWith(
|
..[0] = attachments[0].copyWith(
|
||||||
uploadState: const UploadState.success(),
|
uploadState: const UploadState.success(),
|
||||||
@@ -602,7 +602,7 @@ void main() {
|
|||||||
uploadState: const UploadState.success(),
|
uploadState: const UploadState.success(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
matchSendingStatus: true,
|
matchMessageState: true,
|
||||||
matchAttachments: true,
|
matchAttachments: true,
|
||||||
matchAttachmentsUploadState: true,
|
matchAttachmentsUploadState: true,
|
||||||
),
|
),
|
||||||
@@ -611,13 +611,13 @@ void main() {
|
|||||||
[
|
[
|
||||||
isSameMessageAs(
|
isSameMessageAs(
|
||||||
message.copyWith(
|
message.copyWith(
|
||||||
status: MessageSendingStatus.updating,
|
state: MessageState.updating,
|
||||||
attachments: [
|
attachments: [
|
||||||
...attachments.map((it) =>
|
...attachments.map((it) =>
|
||||||
it.copyWith(uploadState: const UploadState.success()))
|
it.copyWith(uploadState: const UploadState.success()))
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
matchSendingStatus: true,
|
matchMessageState: true,
|
||||||
matchAttachments: true,
|
matchAttachments: true,
|
||||||
matchAttachmentsUploadState: true,
|
matchAttachmentsUploadState: true,
|
||||||
),
|
),
|
||||||
@@ -625,13 +625,13 @@ void main() {
|
|||||||
[
|
[
|
||||||
isSameMessageAs(
|
isSameMessageAs(
|
||||||
message.copyWith(
|
message.copyWith(
|
||||||
status: MessageSendingStatus.sent,
|
state: MessageState.updated,
|
||||||
attachments: [
|
attachments: [
|
||||||
...attachments.map((it) =>
|
...attachments.map((it) =>
|
||||||
it.copyWith(uploadState: const UploadState.success()))
|
it.copyWith(uploadState: const UploadState.success()))
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
matchSendingStatus: true,
|
matchMessageState: true,
|
||||||
matchAttachments: true,
|
matchAttachments: true,
|
||||||
matchAttachmentsUploadState: true,
|
matchAttachmentsUploadState: true,
|
||||||
),
|
),
|
||||||
@@ -677,7 +677,10 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('`.partialUpdateMessage`', () async {
|
test('`.partialUpdateMessage`', () async {
|
||||||
final message = Message(id: 'test-message-id');
|
final message = Message(
|
||||||
|
id: 'test-message-id',
|
||||||
|
state: MessageState.sent,
|
||||||
|
);
|
||||||
|
|
||||||
const set = {'text': 'Update Message text'};
|
const set = {'text': 'Update Message text'};
|
||||||
const unset = ['pinExpires'];
|
const unset = ['pinExpires'];
|
||||||
@@ -689,19 +692,26 @@ void main() {
|
|||||||
() => client.partialUpdateMessage(message.id, set: set, unset: unset),
|
() => client.partialUpdateMessage(message.id, set: set, unset: unset),
|
||||||
).thenAnswer((_) async => updateMessageResponse);
|
).thenAnswer((_) async => updateMessageResponse);
|
||||||
|
|
||||||
channel.state?.messagesStream.skip(1).listen(print);
|
|
||||||
|
|
||||||
expectLater(
|
expectLater(
|
||||||
// skipping first seed message list -> [] messages
|
// skipping first seed message list -> [] messages
|
||||||
channel.state?.messagesStream.skip(1),
|
channel.state?.messagesStream.skip(1),
|
||||||
emitsInOrder([
|
emitsInOrder([
|
||||||
[
|
[
|
||||||
isSameMessageAs(
|
isSameMessageAs(
|
||||||
updateMessageResponse.message.copyWith(
|
message.copyWith(
|
||||||
status: MessageSendingStatus.sending,
|
state: MessageState.updating,
|
||||||
),
|
),
|
||||||
matchText: true,
|
matchText: true,
|
||||||
matchSendingStatus: true,
|
matchMessageState: true,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
isSameMessageAs(
|
||||||
|
updateMessageResponse.message.copyWith(
|
||||||
|
state: MessageState.updated,
|
||||||
|
),
|
||||||
|
matchText: true,
|
||||||
|
matchMessageState: true,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
]),
|
]),
|
||||||
@@ -729,7 +739,8 @@ void main() {
|
|||||||
const messageId = 'test-message-id';
|
const messageId = 'test-message-id';
|
||||||
final message = Message(
|
final message = Message(
|
||||||
id: messageId,
|
id: messageId,
|
||||||
status: MessageSendingStatus.sent,
|
createdAt: DateTime.now(),
|
||||||
|
state: MessageState.sent,
|
||||||
);
|
);
|
||||||
|
|
||||||
when(() => client.deleteMessage(messageId))
|
when(() => client.deleteMessage(messageId))
|
||||||
@@ -741,14 +752,14 @@ void main() {
|
|||||||
emitsInOrder([
|
emitsInOrder([
|
||||||
[
|
[
|
||||||
isSameMessageAs(
|
isSameMessageAs(
|
||||||
message.copyWith(status: MessageSendingStatus.deleting),
|
message.copyWith(state: MessageState.softDeleting),
|
||||||
matchSendingStatus: true,
|
matchMessageState: true,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
isSameMessageAs(
|
isSameMessageAs(
|
||||||
message.copyWith(status: MessageSendingStatus.sent),
|
message.copyWith(state: MessageState.softDeleted),
|
||||||
matchSendingStatus: true,
|
matchMessageState: true,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
]),
|
]),
|
||||||
@@ -775,8 +786,8 @@ void main() {
|
|||||||
emitsInOrder([
|
emitsInOrder([
|
||||||
[
|
[
|
||||||
isSameMessageAs(
|
isSameMessageAs(
|
||||||
message.copyWith(status: MessageSendingStatus.sent),
|
message.copyWith(state: MessageState.softDeleted),
|
||||||
matchSendingStatus: true,
|
matchMessageState: true,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
]),
|
]),
|
||||||
@@ -785,6 +796,7 @@ void main() {
|
|||||||
final res = await channel.deleteMessage(message);
|
final res = await channel.deleteMessage(message);
|
||||||
|
|
||||||
expect(res, isNotNull);
|
expect(res, isNotNull);
|
||||||
|
verifyNever(() => client.deleteMessage(messageId));
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@@ -802,7 +814,6 @@ void main() {
|
|||||||
..message = message.copyWith(
|
..message = message.copyWith(
|
||||||
pinned: true,
|
pinned: true,
|
||||||
pinExpires: null,
|
pinExpires: null,
|
||||||
status: MessageSendingStatus.sent,
|
|
||||||
));
|
));
|
||||||
|
|
||||||
expectLater(
|
expectLater(
|
||||||
@@ -811,8 +822,14 @@ void main() {
|
|||||||
emitsInOrder([
|
emitsInOrder([
|
||||||
[
|
[
|
||||||
isSameMessageAs(
|
isSameMessageAs(
|
||||||
message.copyWith(status: MessageSendingStatus.sent),
|
message.copyWith(state: MessageState.updating),
|
||||||
matchSendingStatus: true,
|
matchMessageState: true,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
isSameMessageAs(
|
||||||
|
message.copyWith(state: MessageState.updated),
|
||||||
|
matchMessageState: true,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
]),
|
]),
|
||||||
@@ -847,7 +864,6 @@ void main() {
|
|||||||
pinExpires: DateTime.now().add(
|
pinExpires: DateTime.now().add(
|
||||||
const Duration(seconds: timeoutOrExpirationDate),
|
const Duration(seconds: timeoutOrExpirationDate),
|
||||||
),
|
),
|
||||||
status: MessageSendingStatus.sent,
|
|
||||||
));
|
));
|
||||||
|
|
||||||
expectLater(
|
expectLater(
|
||||||
@@ -856,8 +872,14 @@ void main() {
|
|||||||
emitsInOrder([
|
emitsInOrder([
|
||||||
[
|
[
|
||||||
isSameMessageAs(
|
isSameMessageAs(
|
||||||
message.copyWith(status: MessageSendingStatus.sent),
|
message.copyWith(state: MessageState.updating),
|
||||||
matchSendingStatus: true,
|
matchMessageState: true,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
isSameMessageAs(
|
||||||
|
message.copyWith(state: MessageState.updated),
|
||||||
|
matchMessageState: true,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
]),
|
]),
|
||||||
@@ -895,7 +917,6 @@ void main() {
|
|||||||
..message = message.copyWith(
|
..message = message.copyWith(
|
||||||
pinned: true,
|
pinned: true,
|
||||||
pinExpires: timeoutOrExpirationDate,
|
pinExpires: timeoutOrExpirationDate,
|
||||||
status: MessageSendingStatus.sent,
|
|
||||||
));
|
));
|
||||||
|
|
||||||
expectLater(
|
expectLater(
|
||||||
@@ -904,8 +925,14 @@ void main() {
|
|||||||
emitsInOrder([
|
emitsInOrder([
|
||||||
[
|
[
|
||||||
isSameMessageAs(
|
isSameMessageAs(
|
||||||
message.copyWith(status: MessageSendingStatus.sent),
|
message.copyWith(state: MessageState.updating),
|
||||||
matchSendingStatus: true,
|
matchMessageState: true,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
isSameMessageAs(
|
||||||
|
message.copyWith(state: MessageState.updated),
|
||||||
|
matchMessageState: true,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
]),
|
]),
|
||||||
@@ -954,10 +981,7 @@ void main() {
|
|||||||
message.id,
|
message.id,
|
||||||
set: {'pinned': false},
|
set: {'pinned': false},
|
||||||
)).thenAnswer((_) async => UpdateMessageResponse()
|
)).thenAnswer((_) async => UpdateMessageResponse()
|
||||||
..message = message.copyWith(
|
..message = message.copyWith(pinned: false));
|
||||||
pinned: false,
|
|
||||||
status: MessageSendingStatus.sent,
|
|
||||||
));
|
|
||||||
|
|
||||||
expectLater(
|
expectLater(
|
||||||
// skipping first seed message list -> [] messages
|
// skipping first seed message list -> [] messages
|
||||||
@@ -965,8 +989,14 @@ void main() {
|
|||||||
emitsInOrder([
|
emitsInOrder([
|
||||||
[
|
[
|
||||||
isSameMessageAs(
|
isSameMessageAs(
|
||||||
message.copyWith(status: MessageSendingStatus.sent),
|
message.copyWith(state: MessageState.updating),
|
||||||
matchSendingStatus: true,
|
matchMessageState: true,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
[
|
||||||
|
isSameMessageAs(
|
||||||
|
message.copyWith(state: MessageState.updated),
|
||||||
|
matchMessageState: true,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
]),
|
]),
|
||||||
@@ -1101,7 +1131,7 @@ void main() {
|
|||||||
const type = 'test-reaction-type';
|
const type = 'test-reaction-type';
|
||||||
final message = Message(
|
final message = Message(
|
||||||
id: 'test-message-id',
|
id: 'test-message-id',
|
||||||
status: MessageSendingStatus.sent,
|
state: MessageState.sent,
|
||||||
);
|
);
|
||||||
|
|
||||||
final reaction = Reaction(type: type, messageId: message.id);
|
final reaction = Reaction(type: type, messageId: message.id);
|
||||||
@@ -1119,14 +1149,14 @@ void main() {
|
|||||||
[
|
[
|
||||||
isSameMessageAs(
|
isSameMessageAs(
|
||||||
message.copyWith(
|
message.copyWith(
|
||||||
status: MessageSendingStatus.sent,
|
state: MessageState.sent,
|
||||||
reactionCounts: {type: 1},
|
reactionCounts: {type: 1},
|
||||||
reactionScores: {type: 1},
|
reactionScores: {type: 1},
|
||||||
latestReactions: [reaction],
|
latestReactions: [reaction],
|
||||||
ownReactions: [reaction],
|
ownReactions: [reaction],
|
||||||
),
|
),
|
||||||
matchReactions: true,
|
matchReactions: true,
|
||||||
matchSendingStatus: true,
|
matchMessageState: true,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
]),
|
]),
|
||||||
@@ -1145,7 +1175,7 @@ void main() {
|
|||||||
const type = 'test-reaction-type';
|
const type = 'test-reaction-type';
|
||||||
final message = Message(
|
final message = Message(
|
||||||
id: 'test-message-id',
|
id: 'test-message-id',
|
||||||
status: MessageSendingStatus.sent,
|
state: MessageState.sent,
|
||||||
);
|
);
|
||||||
|
|
||||||
const score = 5;
|
const score = 5;
|
||||||
@@ -1172,14 +1202,14 @@ void main() {
|
|||||||
[
|
[
|
||||||
isSameMessageAs(
|
isSameMessageAs(
|
||||||
message.copyWith(
|
message.copyWith(
|
||||||
status: MessageSendingStatus.sent,
|
state: MessageState.sent,
|
||||||
reactionCounts: {type: 1},
|
reactionCounts: {type: 1},
|
||||||
reactionScores: {type: score},
|
reactionScores: {type: score},
|
||||||
latestReactions: [reaction],
|
latestReactions: [reaction],
|
||||||
ownReactions: [reaction],
|
ownReactions: [reaction],
|
||||||
),
|
),
|
||||||
matchReactions: true,
|
matchReactions: true,
|
||||||
matchSendingStatus: true,
|
matchMessageState: true,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
]),
|
]),
|
||||||
@@ -1208,7 +1238,7 @@ void main() {
|
|||||||
const type = 'test-reaction-type';
|
const type = 'test-reaction-type';
|
||||||
final message = Message(
|
final message = Message(
|
||||||
id: 'test-message-id',
|
id: 'test-message-id',
|
||||||
status: MessageSendingStatus.sent,
|
state: MessageState.sent,
|
||||||
);
|
);
|
||||||
|
|
||||||
const score = 5;
|
const score = 5;
|
||||||
@@ -1240,14 +1270,14 @@ void main() {
|
|||||||
[
|
[
|
||||||
isSameMessageAs(
|
isSameMessageAs(
|
||||||
message.copyWith(
|
message.copyWith(
|
||||||
status: MessageSendingStatus.sent,
|
state: MessageState.sent,
|
||||||
reactionCounts: {type: 1},
|
reactionCounts: {type: 1},
|
||||||
reactionScores: {type: extraDataScore},
|
reactionScores: {type: extraDataScore},
|
||||||
latestReactions: [reaction],
|
latestReactions: [reaction],
|
||||||
ownReactions: [reaction],
|
ownReactions: [reaction],
|
||||||
),
|
),
|
||||||
matchReactions: true,
|
matchReactions: true,
|
||||||
matchSendingStatus: true,
|
matchMessageState: true,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
]),
|
]),
|
||||||
@@ -1282,7 +1312,7 @@ void main() {
|
|||||||
const type = 'test-reaction-type';
|
const type = 'test-reaction-type';
|
||||||
final message = Message(
|
final message = Message(
|
||||||
id: 'test-message-id',
|
id: 'test-message-id',
|
||||||
status: MessageSendingStatus.sent,
|
state: MessageState.sent,
|
||||||
);
|
);
|
||||||
|
|
||||||
final reaction = Reaction(type: type, messageId: message.id);
|
final reaction = Reaction(type: type, messageId: message.id);
|
||||||
@@ -1297,21 +1327,21 @@ void main() {
|
|||||||
[
|
[
|
||||||
isSameMessageAs(
|
isSameMessageAs(
|
||||||
message.copyWith(
|
message.copyWith(
|
||||||
status: MessageSendingStatus.sent,
|
state: MessageState.sent,
|
||||||
reactionCounts: {type: 1},
|
reactionCounts: {type: 1},
|
||||||
reactionScores: {type: 1},
|
reactionScores: {type: 1},
|
||||||
latestReactions: [reaction],
|
latestReactions: [reaction],
|
||||||
ownReactions: [reaction],
|
ownReactions: [reaction],
|
||||||
),
|
),
|
||||||
matchReactions: true,
|
matchReactions: true,
|
||||||
matchSendingStatus: true,
|
matchMessageState: true,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
isSameMessageAs(
|
isSameMessageAs(
|
||||||
message,
|
message,
|
||||||
matchReactions: true,
|
matchReactions: true,
|
||||||
matchSendingStatus: true,
|
matchMessageState: true,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
]),
|
]),
|
||||||
@@ -1344,7 +1374,7 @@ void main() {
|
|||||||
latestReactions: [prevReaction],
|
latestReactions: [prevReaction],
|
||||||
reactionScores: const {prevType: 1},
|
reactionScores: const {prevType: 1},
|
||||||
reactionCounts: const {prevType: 1},
|
reactionCounts: const {prevType: 1},
|
||||||
status: MessageSendingStatus.sent,
|
state: MessageState.sent,
|
||||||
);
|
);
|
||||||
|
|
||||||
const type = 'test-reaction-type-2';
|
const type = 'test-reaction-type-2';
|
||||||
@@ -1378,7 +1408,7 @@ void main() {
|
|||||||
isSameMessageAs(
|
isSameMessageAs(
|
||||||
newMessage,
|
newMessage,
|
||||||
matchReactions: true,
|
matchReactions: true,
|
||||||
matchSendingStatus: true,
|
matchMessageState: true,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
]),
|
]),
|
||||||
@@ -1409,7 +1439,7 @@ void main() {
|
|||||||
final message = Message(
|
final message = Message(
|
||||||
id: 'test-message-id',
|
id: 'test-message-id',
|
||||||
parentId: 'test-parent-id', // is thread message
|
parentId: 'test-parent-id', // is thread message
|
||||||
status: MessageSendingStatus.sent,
|
state: MessageState.sent,
|
||||||
);
|
);
|
||||||
|
|
||||||
final reaction = Reaction(type: type, messageId: message.id);
|
final reaction = Reaction(type: type, messageId: message.id);
|
||||||
@@ -1429,14 +1459,14 @@ void main() {
|
|||||||
[
|
[
|
||||||
isSameMessageAs(
|
isSameMessageAs(
|
||||||
message.copyWith(
|
message.copyWith(
|
||||||
status: MessageSendingStatus.sent,
|
state: MessageState.sent,
|
||||||
reactionCounts: {type: 1},
|
reactionCounts: {type: 1},
|
||||||
reactionScores: {type: 1},
|
reactionScores: {type: 1},
|
||||||
latestReactions: [reaction],
|
latestReactions: [reaction],
|
||||||
ownReactions: [reaction],
|
ownReactions: [reaction],
|
||||||
),
|
),
|
||||||
matchReactions: true,
|
matchReactions: true,
|
||||||
matchSendingStatus: true,
|
matchMessageState: true,
|
||||||
matchParentId: true,
|
matchParentId: true,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -1459,7 +1489,7 @@ void main() {
|
|||||||
final message = Message(
|
final message = Message(
|
||||||
id: 'test-message-id',
|
id: 'test-message-id',
|
||||||
parentId: 'test-parent-id', // is thread message
|
parentId: 'test-parent-id', // is thread message
|
||||||
status: MessageSendingStatus.sent,
|
state: MessageState.sent,
|
||||||
);
|
);
|
||||||
|
|
||||||
final reaction = Reaction(type: type, messageId: message.id);
|
final reaction = Reaction(type: type, messageId: message.id);
|
||||||
@@ -1476,14 +1506,14 @@ void main() {
|
|||||||
[
|
[
|
||||||
isSameMessageAs(
|
isSameMessageAs(
|
||||||
message.copyWith(
|
message.copyWith(
|
||||||
status: MessageSendingStatus.sent,
|
state: MessageState.sent,
|
||||||
reactionCounts: {type: 1},
|
reactionCounts: {type: 1},
|
||||||
reactionScores: {type: 1},
|
reactionScores: {type: 1},
|
||||||
latestReactions: [reaction],
|
latestReactions: [reaction],
|
||||||
ownReactions: [reaction],
|
ownReactions: [reaction],
|
||||||
),
|
),
|
||||||
matchReactions: true,
|
matchReactions: true,
|
||||||
matchSendingStatus: true,
|
matchMessageState: true,
|
||||||
matchParentId: true,
|
matchParentId: true,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -1491,7 +1521,7 @@ void main() {
|
|||||||
isSameMessageAs(
|
isSameMessageAs(
|
||||||
message,
|
message,
|
||||||
matchReactions: true,
|
matchReactions: true,
|
||||||
matchSendingStatus: true,
|
matchMessageState: true,
|
||||||
matchParentId: true,
|
matchParentId: true,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -1527,7 +1557,7 @@ void main() {
|
|||||||
latestReactions: [prevReaction],
|
latestReactions: [prevReaction],
|
||||||
reactionScores: const {prevType: 1},
|
reactionScores: const {prevType: 1},
|
||||||
reactionCounts: const {prevType: 1},
|
reactionCounts: const {prevType: 1},
|
||||||
status: MessageSendingStatus.sent,
|
state: MessageState.sent,
|
||||||
);
|
);
|
||||||
|
|
||||||
const type = 'test-reaction-type-2';
|
const type = 'test-reaction-type-2';
|
||||||
@@ -1561,9 +1591,9 @@ void main() {
|
|||||||
emitsInOrder([
|
emitsInOrder([
|
||||||
[
|
[
|
||||||
isSameMessageAs(
|
isSameMessageAs(
|
||||||
newMessage.copyWith(status: MessageSendingStatus.sent),
|
newMessage.copyWith(state: MessageState.sent),
|
||||||
matchReactions: true,
|
matchReactions: true,
|
||||||
matchSendingStatus: true,
|
matchMessageState: true,
|
||||||
matchParentId: true,
|
matchParentId: true,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -1605,7 +1635,7 @@ void main() {
|
|||||||
latestReactions: [reaction],
|
latestReactions: [reaction],
|
||||||
reactionScores: const {type: 1},
|
reactionScores: const {type: 1},
|
||||||
reactionCounts: const {type: 1},
|
reactionCounts: const {type: 1},
|
||||||
status: MessageSendingStatus.sent,
|
state: MessageState.sent,
|
||||||
);
|
);
|
||||||
|
|
||||||
when(() => client.deleteReaction(messageId, type))
|
when(() => client.deleteReaction(messageId, type))
|
||||||
@@ -1618,12 +1648,12 @@ void main() {
|
|||||||
[
|
[
|
||||||
isSameMessageAs(
|
isSameMessageAs(
|
||||||
message.copyWith(
|
message.copyWith(
|
||||||
status: MessageSendingStatus.sent,
|
state: MessageState.sent,
|
||||||
latestReactions: [],
|
latestReactions: [],
|
||||||
ownReactions: [],
|
ownReactions: [],
|
||||||
),
|
),
|
||||||
matchReactions: true,
|
matchReactions: true,
|
||||||
matchSendingStatus: true,
|
matchMessageState: true,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
]),
|
]),
|
||||||
@@ -1653,7 +1683,7 @@ void main() {
|
|||||||
latestReactions: [reaction],
|
latestReactions: [reaction],
|
||||||
reactionScores: const {type: 1},
|
reactionScores: const {type: 1},
|
||||||
reactionCounts: const {type: 1},
|
reactionCounts: const {type: 1},
|
||||||
status: MessageSendingStatus.sent,
|
state: MessageState.sent,
|
||||||
);
|
);
|
||||||
|
|
||||||
when(() => client.deleteReaction(messageId, type))
|
when(() => client.deleteReaction(messageId, type))
|
||||||
@@ -1666,19 +1696,19 @@ void main() {
|
|||||||
[
|
[
|
||||||
isSameMessageAs(
|
isSameMessageAs(
|
||||||
message.copyWith(
|
message.copyWith(
|
||||||
status: MessageSendingStatus.sent,
|
state: MessageState.sent,
|
||||||
latestReactions: [],
|
latestReactions: [],
|
||||||
ownReactions: [],
|
ownReactions: [],
|
||||||
),
|
),
|
||||||
matchReactions: true,
|
matchReactions: true,
|
||||||
matchSendingStatus: true,
|
matchMessageState: true,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
isSameMessageAs(
|
isSameMessageAs(
|
||||||
message,
|
message,
|
||||||
matchReactions: true,
|
matchReactions: true,
|
||||||
matchSendingStatus: true,
|
matchMessageState: true,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
]),
|
]),
|
||||||
@@ -1714,7 +1744,7 @@ void main() {
|
|||||||
latestReactions: [reaction],
|
latestReactions: [reaction],
|
||||||
reactionScores: const {type: 1},
|
reactionScores: const {type: 1},
|
||||||
reactionCounts: const {type: 1},
|
reactionCounts: const {type: 1},
|
||||||
status: MessageSendingStatus.sent,
|
state: MessageState.sent,
|
||||||
);
|
);
|
||||||
|
|
||||||
when(() => client.deleteReaction(messageId, type))
|
when(() => client.deleteReaction(messageId, type))
|
||||||
@@ -1729,12 +1759,12 @@ void main() {
|
|||||||
[
|
[
|
||||||
isSameMessageAs(
|
isSameMessageAs(
|
||||||
message.copyWith(
|
message.copyWith(
|
||||||
status: MessageSendingStatus.sent,
|
state: MessageState.sent,
|
||||||
latestReactions: [],
|
latestReactions: [],
|
||||||
ownReactions: [],
|
ownReactions: [],
|
||||||
),
|
),
|
||||||
matchReactions: true,
|
matchReactions: true,
|
||||||
matchSendingStatus: true,
|
matchMessageState: true,
|
||||||
matchParentId: true,
|
matchParentId: true,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -1767,7 +1797,7 @@ void main() {
|
|||||||
latestReactions: [reaction],
|
latestReactions: [reaction],
|
||||||
reactionScores: const {type: 1},
|
reactionScores: const {type: 1},
|
||||||
reactionCounts: const {type: 1},
|
reactionCounts: const {type: 1},
|
||||||
status: MessageSendingStatus.sent,
|
state: MessageState.sent,
|
||||||
);
|
);
|
||||||
|
|
||||||
when(() => client.deleteReaction(messageId, type))
|
when(() => client.deleteReaction(messageId, type))
|
||||||
@@ -1782,12 +1812,12 @@ void main() {
|
|||||||
[
|
[
|
||||||
isSameMessageAs(
|
isSameMessageAs(
|
||||||
message.copyWith(
|
message.copyWith(
|
||||||
status: MessageSendingStatus.sent,
|
state: MessageState.sent,
|
||||||
latestReactions: [],
|
latestReactions: [],
|
||||||
ownReactions: [],
|
ownReactions: [],
|
||||||
),
|
),
|
||||||
matchReactions: true,
|
matchReactions: true,
|
||||||
matchSendingStatus: true,
|
matchMessageState: true,
|
||||||
matchParentId: true,
|
matchParentId: true,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -1795,7 +1825,7 @@ void main() {
|
|||||||
isSameMessageAs(
|
isSameMessageAs(
|
||||||
message,
|
message,
|
||||||
matchReactions: true,
|
matchReactions: true,
|
||||||
matchSendingStatus: true,
|
matchMessageState: true,
|
||||||
matchParentId: true,
|
matchParentId: true,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -2144,7 +2174,7 @@ void main() {
|
|||||||
[
|
[
|
||||||
isSameMessageAs(
|
isSameMessageAs(
|
||||||
message,
|
message,
|
||||||
matchSendingStatus: true,
|
matchMessageState: true,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
]),
|
]),
|
||||||
|
|||||||
@@ -2236,13 +2236,13 @@ void main() {
|
|||||||
test('`.deleteMessage`', () async {
|
test('`.deleteMessage`', () async {
|
||||||
const messageId = 'test-message-id';
|
const messageId = 'test-message-id';
|
||||||
|
|
||||||
when(() => api.message.deleteMessage(messageId))
|
when(() => api.message.deleteMessage(messageId, hard: false))
|
||||||
.thenAnswer((_) async => EmptyResponse());
|
.thenAnswer((_) async => EmptyResponse());
|
||||||
|
|
||||||
final res = await client.deleteMessage(messageId);
|
final res = await client.deleteMessage(messageId);
|
||||||
expect(res, isNotNull);
|
expect(res, isNotNull);
|
||||||
|
|
||||||
verify(() => api.message.deleteMessage(messageId)).called(1);
|
verify(() => api.message.deleteMessage(messageId, hard: false)).called(1);
|
||||||
verifyNoMoreInteractions(api.message);
|
verifyNoMoreInteractions(api.message);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -2359,7 +2359,7 @@ void main() {
|
|||||||
..message = message.copyWith(
|
..message = message.copyWith(
|
||||||
pinned: true,
|
pinned: true,
|
||||||
pinExpires: null,
|
pinExpires: null,
|
||||||
status: MessageSendingStatus.sent,
|
state: MessageState.sent,
|
||||||
));
|
));
|
||||||
|
|
||||||
final res = await client.pinMessage(messageId);
|
final res = await client.pinMessage(messageId);
|
||||||
@@ -2393,7 +2393,7 @@ void main() {
|
|||||||
pinExpires: DateTime.now().add(
|
pinExpires: DateTime.now().add(
|
||||||
const Duration(seconds: timeoutOrExpirationDate),
|
const Duration(seconds: timeoutOrExpirationDate),
|
||||||
),
|
),
|
||||||
status: MessageSendingStatus.sent,
|
state: MessageState.sent,
|
||||||
));
|
));
|
||||||
|
|
||||||
final res = await client.pinMessage(
|
final res = await client.pinMessage(
|
||||||
@@ -2430,7 +2430,7 @@ void main() {
|
|||||||
..message = message.copyWith(
|
..message = message.copyWith(
|
||||||
pinned: true,
|
pinned: true,
|
||||||
pinExpires: timeoutOrExpirationDate,
|
pinExpires: timeoutOrExpirationDate,
|
||||||
status: MessageSendingStatus.sent,
|
state: MessageState.sent,
|
||||||
));
|
));
|
||||||
|
|
||||||
final res = await client.pinMessage(
|
final res = await client.pinMessage(
|
||||||
@@ -2480,7 +2480,7 @@ void main() {
|
|||||||
)).thenAnswer((_) async => UpdateMessageResponse()
|
)).thenAnswer((_) async => UpdateMessageResponse()
|
||||||
..message = message.copyWith(
|
..message = message.copyWith(
|
||||||
pinned: false,
|
pinned: false,
|
||||||
status: MessageSendingStatus.sent,
|
state: MessageState.sent,
|
||||||
));
|
));
|
||||||
|
|
||||||
final res = await client.unpinMessage(messageId);
|
final res = await client.unpinMessage(messageId);
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
import 'package:mocktail/mocktail.dart';
|
import 'package:mocktail/mocktail.dart';
|
||||||
import 'package:stream_chat/src/client/retry_policy.dart';
|
import 'package:stream_chat/src/client/retry_policy.dart';
|
||||||
import 'package:stream_chat/src/client/retry_queue.dart';
|
import 'package:stream_chat/src/client/retry_queue.dart';
|
||||||
import 'package:stream_chat/src/core/models/event.dart';
|
import 'package:stream_chat/stream_chat.dart';
|
||||||
import 'package:stream_chat/src/core/models/message.dart';
|
|
||||||
import 'package:stream_chat/src/event_type.dart';
|
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
import '../mocks.dart';
|
import '../mocks.dart';
|
||||||
@@ -15,8 +13,9 @@ void main() {
|
|||||||
|
|
||||||
setUpAll(() {
|
setUpAll(() {
|
||||||
final retryPolicy = RetryPolicy(
|
final retryPolicy = RetryPolicy(
|
||||||
shouldRetry: (_, attempt, __) => attempt < 5,
|
shouldRetry: (_, __, error) {
|
||||||
retryTimeout: (_, attempt, __) => Duration(seconds: attempt),
|
return error is StreamChatNetworkError && error.isRetriable;
|
||||||
|
},
|
||||||
);
|
);
|
||||||
when(() => channel.client.retryPolicy).thenReturn(retryPolicy);
|
when(() => channel.client.retryPolicy).thenReturn(retryPolicy);
|
||||||
|
|
||||||
@@ -48,21 +47,32 @@ void main() {
|
|||||||
verifyNever(() => logger.info(any()));
|
verifyNever(() => logger.info(any()));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('should throw if message state is not failed', () {
|
||||||
|
final message = Message(
|
||||||
|
id: 'test-message-id',
|
||||||
|
text: 'Sample message test',
|
||||||
|
state: MessageState.sent,
|
||||||
|
);
|
||||||
|
expect(() => retryQueue.add([message]), throwsA(isA<AssertionError>()));
|
||||||
|
});
|
||||||
|
|
||||||
test('should return if queue already contains the message', () {
|
test('should return if queue already contains the message', () {
|
||||||
final message = Message(
|
final message = Message(
|
||||||
id: 'test-message-id',
|
id: 'test-message-id',
|
||||||
text: 'Sample message test',
|
text: 'Sample message test',
|
||||||
|
state: MessageState.sendingFailed,
|
||||||
);
|
);
|
||||||
retryQueue.add([message]);
|
retryQueue.add([message]);
|
||||||
expect(() => retryQueue.add([message]), returnsNormally);
|
expect(() => retryQueue.add([message]), returnsNormally);
|
||||||
// Called only for the first message
|
// Called only for the first message
|
||||||
verify(() => logger.info('Adding 1 messages')).called(1);
|
verify(() => logger.info('Adding 1 messages to the queue')).called(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('`.add` should add failed request to the queue', () async {
|
test('`.add` should add failed request to the queue', () async {
|
||||||
final message = Message(
|
final message = Message(
|
||||||
id: 'test-message-id',
|
id: 'test-message-id',
|
||||||
text: 'Sample message test',
|
text: 'Sample message test',
|
||||||
|
state: MessageState.sendingFailed,
|
||||||
);
|
);
|
||||||
retryQueue.add([message]);
|
retryQueue.add([message]);
|
||||||
expect(retryQueue.hasMessages, isTrue);
|
expect(retryQueue.hasMessages, isTrue);
|
||||||
|
|||||||
@@ -0,0 +1,308 @@
|
|||||||
|
// ignore_for_file: use_named_constants, lines_longer_than_80_chars
|
||||||
|
|
||||||
|
import 'package:stream_chat/src/core/models/message_state.dart';
|
||||||
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
group(
|
||||||
|
'Message State Extensions',
|
||||||
|
() {
|
||||||
|
test(
|
||||||
|
'isInitial should return true if the message state is MessageInitial',
|
||||||
|
() {
|
||||||
|
const messageState = MessageState.initial();
|
||||||
|
expect(messageState.isInitial, true);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
'isOutgoing should return true if the message state is MessageOutgoing',
|
||||||
|
() {
|
||||||
|
const messageState = MessageState.outgoing(
|
||||||
|
state: OutgoingState.sending(),
|
||||||
|
);
|
||||||
|
expect(messageState.isOutgoing, true);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
'isCompleted should return true if the message state is MessageCompleted',
|
||||||
|
() {
|
||||||
|
const messageState = MessageState.completed(
|
||||||
|
state: CompletedState.sent(),
|
||||||
|
);
|
||||||
|
expect(messageState.isCompleted, true);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
'isFailed should return true if the message state is MessageFailed',
|
||||||
|
() {
|
||||||
|
const messageState = MessageState.failed(
|
||||||
|
state: FailedState.sendingFailed(),
|
||||||
|
);
|
||||||
|
expect(messageState.isFailed, true);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
'isSending should return true if the message state is MessageOutgoing with Sending state',
|
||||||
|
() {
|
||||||
|
const messageState = MessageState.outgoing(
|
||||||
|
state: OutgoingState.sending(),
|
||||||
|
);
|
||||||
|
expect(messageState.isSending, true);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
'isUpdating should return true if the message state is MessageOutgoing with Updating state',
|
||||||
|
() {
|
||||||
|
const messageState = MessageState.outgoing(
|
||||||
|
state: OutgoingState.updating(),
|
||||||
|
);
|
||||||
|
expect(messageState.isUpdating, true);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
'isDeleting should return true if the message state is either isSoftDeleting or isHardDeleting',
|
||||||
|
() {
|
||||||
|
const messageState = MessageState.softDeleting;
|
||||||
|
expect(messageState.isDeleting, true);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
'isSoftDeleting should return true if the message state is MessageOutgoing with Deleting state and not hard deleting',
|
||||||
|
() {
|
||||||
|
const messageState = MessageState.outgoing(
|
||||||
|
state: OutgoingState.deleting(),
|
||||||
|
);
|
||||||
|
expect(messageState.isSoftDeleting, true);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
'isHardDeleting should return true if the message state is MessageOutgoing with Deleting state and hard deleting',
|
||||||
|
() {
|
||||||
|
const messageState = MessageState.outgoing(
|
||||||
|
state: OutgoingState.deleting(hard: true),
|
||||||
|
);
|
||||||
|
expect(messageState.isHardDeleting, true);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
'isSent should return true if the message state is MessageCompleted with Sent state',
|
||||||
|
() {
|
||||||
|
const messageState =
|
||||||
|
MessageState.completed(state: CompletedState.sent());
|
||||||
|
expect(messageState.isSent, true);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
'isUpdated should return true if the message state is MessageCompleted with Updated state',
|
||||||
|
() {
|
||||||
|
const messageState = MessageState.completed(
|
||||||
|
state: CompletedState.updated(),
|
||||||
|
);
|
||||||
|
expect(messageState.isUpdated, true);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
'isDeleted should return true if the message state is either isSoftDeleted or isHardDeleted',
|
||||||
|
() {
|
||||||
|
const messageState = MessageState.softDeleted;
|
||||||
|
expect(messageState.isDeleted, true);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
'isSoftDeleted should return true if the message state is MessageCompleted with Deleted state and not hard deleting',
|
||||||
|
() {
|
||||||
|
const messageState = MessageState.completed(
|
||||||
|
state: CompletedState.deleted(),
|
||||||
|
);
|
||||||
|
expect(messageState.isSoftDeleted, true);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
'isHardDeleted should return true if the message state is MessageCompleted with Deleted state and hard deleting',
|
||||||
|
() {
|
||||||
|
const messageState = MessageState.completed(
|
||||||
|
state: CompletedState.deleted(hard: true),
|
||||||
|
);
|
||||||
|
expect(messageState.isHardDeleted, true);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
'isSendingFailed should return true if the message state is MessageFailed with SendingFailed state',
|
||||||
|
() {
|
||||||
|
const messageState = MessageState.failed(
|
||||||
|
state: FailedState.sendingFailed(),
|
||||||
|
);
|
||||||
|
expect(messageState.isSendingFailed, true);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
'isUpdatingFailed should return true if the message state is MessageFailed with UpdatingFailed state',
|
||||||
|
() {
|
||||||
|
const messageState = MessageState.failed(
|
||||||
|
state: FailedState.updatingFailed(),
|
||||||
|
);
|
||||||
|
expect(messageState.isUpdatingFailed, true);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
'isDeletingFailed should return true if the message state is either isSoftDeletingFailed or isHardDeletingFailed',
|
||||||
|
() {
|
||||||
|
const messageState = MessageState.softDeletingFailed;
|
||||||
|
expect(messageState.isDeletingFailed, true);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
'isSoftDeletingFailed should return true if the message state is MessageFailed with DeletingFailed state and not hard deleting',
|
||||||
|
() {
|
||||||
|
const messageState = MessageState.failed(
|
||||||
|
state: FailedState.deletingFailed(),
|
||||||
|
);
|
||||||
|
expect(messageState.isSoftDeletingFailed, true);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
'isHardDeletingFailed should return true if the message state is MessageFailed with DeletingFailed state and hard deleting',
|
||||||
|
() {
|
||||||
|
const messageState = MessageState.failed(
|
||||||
|
state: FailedState.deletingFailed(hard: true),
|
||||||
|
);
|
||||||
|
expect(messageState.isHardDeletingFailed, true);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
group('Message State Classes', () {
|
||||||
|
test(
|
||||||
|
'MessageState.sending should create a MessageOutgoing instance with Sending state',
|
||||||
|
() {
|
||||||
|
const messageState = MessageState.sending;
|
||||||
|
expect(messageState, isA<MessageOutgoing>());
|
||||||
|
expect((messageState as MessageOutgoing).state, isA<Sending>());
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
'MessageState.updating should create a MessageOutgoing instance with Updating state',
|
||||||
|
() {
|
||||||
|
const messageState = MessageState.updating;
|
||||||
|
expect(messageState, isA<MessageOutgoing>());
|
||||||
|
expect((messageState as MessageOutgoing).state, isA<Updating>());
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
'MessageState.softDeleting should create a MessageOutgoing instance with Deleting state and not hard deleting',
|
||||||
|
() {
|
||||||
|
const messageState = MessageState.softDeleting;
|
||||||
|
expect(messageState, isA<MessageOutgoing>());
|
||||||
|
expect((messageState as MessageOutgoing).state, isA<Deleting>());
|
||||||
|
expect((messageState.state as Deleting).hard, false);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
'MessageState.hardDeleting should create a MessageOutgoing instance with Deleting state and hard deleting',
|
||||||
|
() {
|
||||||
|
const messageState = MessageState.hardDeleting;
|
||||||
|
expect(messageState, isA<MessageOutgoing>());
|
||||||
|
expect((messageState as MessageOutgoing).state, isA<Deleting>());
|
||||||
|
expect((messageState.state as Deleting).hard, true);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
'MessageState.sent should create a MessageCompleted instance with Sent state',
|
||||||
|
() {
|
||||||
|
const messageState = MessageState.sent;
|
||||||
|
expect(messageState, isA<MessageCompleted>());
|
||||||
|
expect((messageState as MessageCompleted).state, isA<Sent>());
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
'MessageState.updated should create a MessageCompleted instance with Updated state',
|
||||||
|
() {
|
||||||
|
const messageState = MessageState.updated;
|
||||||
|
expect(messageState, isA<MessageCompleted>());
|
||||||
|
expect((messageState as MessageCompleted).state, isA<Updated>());
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
'MessageState.softDeleted should create a MessageCompleted instance with Deleted state and not hard deleting',
|
||||||
|
() {
|
||||||
|
const messageState = MessageState.softDeleted;
|
||||||
|
expect(messageState, isA<MessageCompleted>());
|
||||||
|
expect((messageState as MessageCompleted).state, isA<Deleted>());
|
||||||
|
expect((messageState.state as Deleted).hard, false);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
'MessageState.hardDeleted should create a MessageCompleted instance with Deleted state and hard deleting',
|
||||||
|
() {
|
||||||
|
const messageState = MessageState.hardDeleted;
|
||||||
|
expect(messageState, isA<MessageCompleted>());
|
||||||
|
expect((messageState as MessageCompleted).state, isA<Deleted>());
|
||||||
|
expect((messageState.state as Deleted).hard, true);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
'MessageState.sendingFailed should create a MessageFailed instance with SendingFailed state',
|
||||||
|
() {
|
||||||
|
const messageState = MessageState.sendingFailed;
|
||||||
|
expect(messageState, isA<MessageFailed>());
|
||||||
|
expect((messageState as MessageFailed).state, isA<SendingFailed>());
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
'MessageState.updatingFailed should create a MessageFailed instance with UpdatingFailed state',
|
||||||
|
() {
|
||||||
|
const messageState = MessageState.updatingFailed;
|
||||||
|
expect(messageState, isA<MessageFailed>());
|
||||||
|
expect((messageState as MessageFailed).state, isA<UpdatingFailed>());
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
'MessageState.softDeletingFailed should create a MessageFailed instance with DeletingFailed state and not hard deleting',
|
||||||
|
() {
|
||||||
|
const messageState = MessageState.softDeletingFailed;
|
||||||
|
expect(messageState, isA<MessageFailed>());
|
||||||
|
expect((messageState as MessageFailed).state, isA<DeletingFailed>());
|
||||||
|
expect((messageState.state as DeletingFailed).hard, false);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
'MessageState.hardDeletingFailed should create a MessageFailed instance with DeletingFailed state and hard deleting',
|
||||||
|
() {
|
||||||
|
const messageState = MessageState.hardDeletingFailed;
|
||||||
|
expect(messageState, isA<MessageFailed>());
|
||||||
|
expect((messageState as MessageFailed).state, isA<DeletingFailed>());
|
||||||
|
expect((messageState.state as DeletingFailed).hard, true);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -46,7 +46,7 @@ Matcher isSameMessageAs(
|
|||||||
Message targetMessage, {
|
Message targetMessage, {
|
||||||
bool matchText = false,
|
bool matchText = false,
|
||||||
bool matchReactions = false,
|
bool matchReactions = false,
|
||||||
bool matchSendingStatus = false,
|
bool matchMessageState = false,
|
||||||
bool matchAttachments = false,
|
bool matchAttachments = false,
|
||||||
bool matchAttachmentsUploadState = false,
|
bool matchAttachmentsUploadState = false,
|
||||||
bool matchParentId = false,
|
bool matchParentId = false,
|
||||||
@@ -55,7 +55,7 @@ Matcher isSameMessageAs(
|
|||||||
targetMessage: targetMessage,
|
targetMessage: targetMessage,
|
||||||
matchText: matchText,
|
matchText: matchText,
|
||||||
matchReactions: matchReactions,
|
matchReactions: matchReactions,
|
||||||
matchSendingStatus: matchSendingStatus,
|
matchMessageState: matchMessageState,
|
||||||
matchAttachments: matchAttachments,
|
matchAttachments: matchAttachments,
|
||||||
matchAttachmentsUploadState: matchAttachmentsUploadState,
|
matchAttachmentsUploadState: matchAttachmentsUploadState,
|
||||||
matchParentId: matchParentId,
|
matchParentId: matchParentId,
|
||||||
@@ -66,7 +66,7 @@ class _IsSameMessageAs extends Matcher {
|
|||||||
required this.targetMessage,
|
required this.targetMessage,
|
||||||
this.matchText = false,
|
this.matchText = false,
|
||||||
this.matchReactions = false,
|
this.matchReactions = false,
|
||||||
this.matchSendingStatus = false,
|
this.matchMessageState = false,
|
||||||
this.matchAttachments = false,
|
this.matchAttachments = false,
|
||||||
this.matchAttachmentsUploadState = false,
|
this.matchAttachmentsUploadState = false,
|
||||||
this.matchParentId = false,
|
this.matchParentId = false,
|
||||||
@@ -75,7 +75,7 @@ class _IsSameMessageAs extends Matcher {
|
|||||||
final Message targetMessage;
|
final Message targetMessage;
|
||||||
final bool matchText;
|
final bool matchText;
|
||||||
final bool matchReactions;
|
final bool matchReactions;
|
||||||
final bool matchSendingStatus;
|
final bool matchMessageState;
|
||||||
final bool matchAttachments;
|
final bool matchAttachments;
|
||||||
final bool matchAttachmentsUploadState;
|
final bool matchAttachmentsUploadState;
|
||||||
final bool matchParentId;
|
final bool matchParentId;
|
||||||
@@ -90,8 +90,8 @@ class _IsSameMessageAs extends Matcher {
|
|||||||
if (matchText) {
|
if (matchText) {
|
||||||
matches &= message.text == targetMessage.text;
|
matches &= message.text == targetMessage.text;
|
||||||
}
|
}
|
||||||
if (matchSendingStatus) {
|
if (matchMessageState) {
|
||||||
matches &= message.status == targetMessage.status;
|
matches &= message.state == targetMessage.state;
|
||||||
}
|
}
|
||||||
if (matchReactions) {
|
if (matchReactions) {
|
||||||
matches &= const ListEquality().equals(
|
matches &= const ListEquality().equals(
|
||||||
|
|||||||
@@ -1,3 +1,10 @@
|
|||||||
|
## 6.7.0
|
||||||
|
|
||||||
|
🔄 Changed
|
||||||
|
|
||||||
|
- Updated `stream_chat_flutter_core` dependency
|
||||||
|
to [`6.6.0`](https://pub.dev/packages/stream_chat_flutter_core/changelog).
|
||||||
|
|
||||||
## 6.6.0
|
## 6.6.0
|
||||||
|
|
||||||
🔄 Changed
|
🔄 Changed
|
||||||
|
|||||||
+1
-1
@@ -36,7 +36,7 @@ class StreamAttachmentUploadStateBuilder extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
if (message.status == MessageSendingStatus.sent) {
|
if (message.state.isCompleted) {
|
||||||
return const Offstage();
|
return const Offstage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -236,7 +236,7 @@ class _Trailing extends StatelessWidget {
|
|||||||
final channel = StreamChannel.of(context).channel;
|
final channel = StreamChannel.of(context).channel;
|
||||||
final attachmentId = attachment.id;
|
final attachmentId = attachment.id;
|
||||||
|
|
||||||
if (message.status == MessageSendingStatus.sent) {
|
if (message.state.isCompleted) {
|
||||||
return IconButton(
|
return IconButton(
|
||||||
icon: StreamSvgIcon.cloudDownload(
|
icon: StreamSvgIcon.cloudDownload(
|
||||||
color: theme.colorTheme.textHighEmphasis,
|
color: theme.colorTheme.textHighEmphasis,
|
||||||
|
|||||||
@@ -30,14 +30,13 @@ class StreamSendingIndicator extends StatelessWidget {
|
|||||||
color: StreamChatTheme.of(context).colorTheme.accentPrimary,
|
color: StreamChatTheme.of(context).colorTheme.accentPrimary,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (message.status == MessageSendingStatus.sent) {
|
if (message.state.isCompleted) {
|
||||||
return StreamSvgIcon.check(
|
return StreamSvgIcon.check(
|
||||||
size: size,
|
size: size,
|
||||||
color: StreamChatTheme.of(context).colorTheme.textLowEmphasis,
|
color: StreamChatTheme.of(context).colorTheme.textLowEmphasis,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (message.status == MessageSendingStatus.sending ||
|
if (message.state.isOutgoing) {
|
||||||
message.status == MessageSendingStatus.updating) {
|
|
||||||
return Icon(
|
return Icon(
|
||||||
Icons.access_time,
|
Icons.access_time,
|
||||||
size: size,
|
size: size,
|
||||||
|
|||||||
+5
-8
@@ -98,9 +98,7 @@ class _MessageActionsModalState extends State<MessageActionsModal> {
|
|||||||
bool _showActions = true;
|
bool _showActions = true;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) => _showMessageOptionsModal();
|
Widget build(BuildContext context) {
|
||||||
|
|
||||||
Widget _showMessageOptionsModal() {
|
|
||||||
final mediaQueryData = MediaQuery.of(context);
|
final mediaQueryData = MediaQuery.of(context);
|
||||||
final user = StreamChat.of(context).currentUser;
|
final user = StreamChat.of(context).currentUser;
|
||||||
final orientation = mediaQueryData.orientation;
|
final orientation = mediaQueryData.orientation;
|
||||||
@@ -163,7 +161,7 @@ class _MessageActionsModalState extends State<MessageActionsModal> {
|
|||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
children: [
|
children: [
|
||||||
if (widget.showReplyMessage &&
|
if (widget.showReplyMessage &&
|
||||||
widget.message.status == MessageSendingStatus.sent)
|
widget.message.state.isCompleted)
|
||||||
ReplyButton(
|
ReplyButton(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
@@ -173,8 +171,7 @@ class _MessageActionsModalState extends State<MessageActionsModal> {
|
|||||||
},
|
},
|
||||||
),
|
),
|
||||||
if (widget.showThreadReplyMessage &&
|
if (widget.showThreadReplyMessage &&
|
||||||
(widget.message.status ==
|
(widget.message.state.isCompleted) &&
|
||||||
MessageSendingStatus.sent) &&
|
|
||||||
widget.message.parentId == null)
|
widget.message.parentId == null)
|
||||||
ThreadReplyButton(
|
ThreadReplyButton(
|
||||||
message: widget.message,
|
message: widget.message,
|
||||||
@@ -210,8 +207,8 @@ class _MessageActionsModalState extends State<MessageActionsModal> {
|
|||||||
),
|
),
|
||||||
if (widget.showDeleteMessage)
|
if (widget.showDeleteMessage)
|
||||||
DeleteMessageButton(
|
DeleteMessageButton(
|
||||||
isDeleteFailed: widget.message.status ==
|
isDeleteFailed:
|
||||||
MessageSendingStatus.failed_delete,
|
widget.message.state.isDeletingFailed,
|
||||||
onTap: _showDeleteBottomSheet,
|
onTap: _showDeleteBottomSheet,
|
||||||
),
|
),
|
||||||
...widget.customActions
|
...widget.customActions
|
||||||
|
|||||||
+2
-6
@@ -22,16 +22,12 @@ class ResendMessageButton extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final isUpdateFailed = message.status == MessageSendingStatus.failed_update;
|
final isUpdateFailed = message.state.isUpdatingFailed;
|
||||||
final streamChatThemeData = StreamChatTheme.of(context);
|
final streamChatThemeData = StreamChatTheme.of(context);
|
||||||
return InkWell(
|
return InkWell(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
if (isUpdateFailed) {
|
channel.retryMessage(message);
|
||||||
channel.updateMessage(message);
|
|
||||||
} else {
|
|
||||||
channel.sendMessage(message);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
child: Padding(
|
child: Padding(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 11, horizontal: 16),
|
padding: const EdgeInsets.symmetric(vertical: 11, horizontal: 16),
|
||||||
|
|||||||
@@ -400,8 +400,7 @@ class StreamMessageInputState extends State<StreamMessageInput>
|
|||||||
bool get _hasQuotedMessage =>
|
bool get _hasQuotedMessage =>
|
||||||
_effectiveController.message.quotedMessage != null;
|
_effectiveController.message.quotedMessage != null;
|
||||||
|
|
||||||
bool get _isEditing =>
|
bool get _isEditing => !_effectiveController.message.state.isInitial;
|
||||||
_effectiveController.message.status != MessageSendingStatus.sending;
|
|
||||||
|
|
||||||
BoxBorder? _draggingBorder;
|
BoxBorder? _draggingBorder;
|
||||||
|
|
||||||
@@ -587,7 +586,7 @@ class StreamMessageInputState extends State<StreamMessageInput>
|
|||||||
child: Column(
|
child: Column(
|
||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
if (_hasQuotedMessage)
|
if (_hasQuotedMessage && !_isEditing)
|
||||||
// Ensure this doesn't show on web & desktop
|
// Ensure this doesn't show on web & desktop
|
||||||
PlatformWidgetBuilder(
|
PlatformWidgetBuilder(
|
||||||
mobile: (context, child) => child,
|
mobile: (context, child) => child,
|
||||||
@@ -1386,10 +1385,12 @@ class StreamMessageInputState extends State<StreamMessageInput>
|
|||||||
skipEnrichUrl: skipEnrichUrl,
|
skipEnrichUrl: skipEnrichUrl,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (shouldKeepFocus) {
|
if (mounted) {
|
||||||
FocusScope.of(context).requestFocus(_effectiveFocusNode);
|
if (shouldKeepFocus) {
|
||||||
} else {
|
FocusScope.of(context).requestFocus(_effectiveFocusNode);
|
||||||
FocusScope.of(context).unfocus();
|
} else {
|
||||||
|
FocusScope.of(context).unfocus();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -783,13 +783,11 @@ class _StreamMessageWidgetState extends State<StreamMessageWidget>
|
|||||||
/// {@endtemplate}
|
/// {@endtemplate}
|
||||||
bool get hasQuotedMessage => widget.message.quotedMessage != null;
|
bool get hasQuotedMessage => widget.message.quotedMessage != null;
|
||||||
|
|
||||||
bool get isSendFailed => widget.message.status == MessageSendingStatus.failed;
|
bool get isSendFailed => widget.message.state.isSendingFailed;
|
||||||
|
|
||||||
bool get isUpdateFailed =>
|
bool get isUpdateFailed => widget.message.state.isUpdatingFailed;
|
||||||
widget.message.status == MessageSendingStatus.failed_update;
|
|
||||||
|
|
||||||
bool get isDeleteFailed =>
|
bool get isDeleteFailed => widget.message.state.isDeletingFailed;
|
||||||
widget.message.status == MessageSendingStatus.failed_delete;
|
|
||||||
|
|
||||||
/// {@template isFailedState}
|
/// {@template isFailedState}
|
||||||
/// Whether the message has failed to be sent, updated, or deleted.
|
/// Whether the message has failed to be sent, updated, or deleted.
|
||||||
@@ -905,7 +903,7 @@ class _StreamMessageWidgetState extends State<StreamMessageWidget>
|
|||||||
|
|
||||||
return ConditionalParentBuilder(
|
return ConditionalParentBuilder(
|
||||||
builder: (context, child) {
|
builder: (context, child) {
|
||||||
if (!widget.message.isDeleted) {
|
if (!widget.message.state.isDeleted) {
|
||||||
return ContextMenuArea(
|
return ContextMenuArea(
|
||||||
verticalPadding: 0,
|
verticalPadding: 0,
|
||||||
builder: (_) => _buildContextMenu(),
|
builder: (_) => _buildContextMenu(),
|
||||||
@@ -927,7 +925,7 @@ class _StreamMessageWidgetState extends State<StreamMessageWidget>
|
|||||||
mobile: (context, child) {
|
mobile: (context, child) {
|
||||||
return InkWell(
|
return InkWell(
|
||||||
onTap: () => widget.onMessageTap!(widget.message),
|
onTap: () => widget.onMessageTap!(widget.message),
|
||||||
onLongPress: widget.message.isDeleted && !isFailedState
|
onLongPress: widget.message.state.isDeleted
|
||||||
? null
|
? null
|
||||||
: () => onLongPress(context),
|
: () => onLongPress(context),
|
||||||
child: child,
|
child: child,
|
||||||
@@ -1114,14 +1112,12 @@ class _StreamMessageWidgetState extends State<StreamMessageWidget>
|
|||||||
leading: StreamSvgIcon.iconSendMessage(),
|
leading: StreamSvgIcon.iconSendMessage(),
|
||||||
title: Text(
|
title: Text(
|
||||||
context.translations.toggleResendOrResendEditedMessage(
|
context.translations.toggleResendOrResendEditedMessage(
|
||||||
isUpdateFailed:
|
isUpdateFailed: widget.message.state.isUpdatingFailed,
|
||||||
widget.message.status == MessageSendingStatus.failed,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
onClick: () {
|
onClick: () {
|
||||||
Navigator.of(context, rootNavigator: true).pop();
|
Navigator.of(context, rootNavigator: true).pop();
|
||||||
final isUpdateFailed =
|
final isUpdateFailed = widget.message.state.isUpdatingFailed;
|
||||||
widget.message.status == MessageSendingStatus.failed_update;
|
|
||||||
final channel = StreamChannel.of(context).channel;
|
final channel = StreamChannel.of(context).channel;
|
||||||
if (isUpdateFailed) {
|
if (isUpdateFailed) {
|
||||||
channel.updateMessage(widget.message);
|
channel.updateMessage(widget.message);
|
||||||
@@ -1216,8 +1212,7 @@ class _StreamMessageWidgetState extends State<StreamMessageWidget>
|
|||||||
}
|
}
|
||||||
|
|
||||||
void onLongPress(BuildContext context) {
|
void onLongPress(BuildContext context) {
|
||||||
if (widget.message.isEphemeral ||
|
if (widget.message.isEphemeral || widget.message.state.isOutgoing) {
|
||||||
widget.message.status == MessageSendingStatus.sending) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+12
-16
@@ -42,25 +42,21 @@ class SendingIndicatorBuilder extends StatelessWidget {
|
|||||||
final channel = this.channel ?? StreamChannel.of(context).channel;
|
final channel = this.channel ?? StreamChannel.of(context).channel;
|
||||||
final memberCount = channel.memberCount ?? 0;
|
final memberCount = channel.memberCount ?? 0;
|
||||||
|
|
||||||
if (hasNonUrlAttachments &&
|
if (hasNonUrlAttachments && message.state.isOutgoing) {
|
||||||
(message.status == MessageSendingStatus.sending ||
|
|
||||||
message.status == MessageSendingStatus.updating)) {
|
|
||||||
final totalAttachments = message.attachments.length;
|
final totalAttachments = message.attachments.length;
|
||||||
final uploadRemaining =
|
final attachmentsToUpload = message.attachments.where((it) {
|
||||||
message.attachments.where((it) => !it.uploadState.isSuccess).length;
|
return !it.uploadState.isSuccess;
|
||||||
if (uploadRemaining == 0) {
|
});
|
||||||
return StreamSvgIcon.check(
|
|
||||||
size: style!.fontSize,
|
if (attachmentsToUpload.isNotEmpty) {
|
||||||
color: IconTheme.of(context).color!.withOpacity(0.5),
|
return Text(
|
||||||
|
context.translations.attachmentsUploadProgressText(
|
||||||
|
remaining: attachmentsToUpload.length,
|
||||||
|
total: totalAttachments,
|
||||||
|
),
|
||||||
|
style: style,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return Text(
|
|
||||||
context.translations.attachmentsUploadProgressText(
|
|
||||||
remaining: uploadRemaining,
|
|
||||||
total: totalAttachments,
|
|
||||||
),
|
|
||||||
style: style,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return BetterStreamBuilder<List<Read>>(
|
return BetterStreamBuilder<List<Read>>(
|
||||||
|
|||||||
+1
-1
@@ -91,7 +91,7 @@ class StreamChannelListTile extends StatelessWidget {
|
|||||||
/// The widget builder for the sending indicator.
|
/// The widget builder for the sending indicator.
|
||||||
///
|
///
|
||||||
/// `Message` is the last message in the channel, Use it to determine the
|
/// `Message` is the last message in the channel, Use it to determine the
|
||||||
/// status using [Message.status].
|
/// status using [Message.state].
|
||||||
final Widget Function(BuildContext, Message)? sendingIndicatorBuilder;
|
final Widget Function(BuildContext, Message)? sendingIndicatorBuilder;
|
||||||
|
|
||||||
/// True if the tile is in a selected state.
|
/// True if the tile is in a selected state.
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
name: stream_chat_flutter
|
name: stream_chat_flutter
|
||||||
homepage: https://github.com/GetStream/stream-chat-flutter
|
homepage: https://github.com/GetStream/stream-chat-flutter
|
||||||
description: Stream Chat official Flutter SDK. Build your own chat experience using Dart and Flutter.
|
description: Stream Chat official Flutter SDK. Build your own chat experience using Dart and Flutter.
|
||||||
version: 6.6.0
|
version: 6.7.0
|
||||||
repository: https://github.com/GetStream/stream-chat-flutter
|
repository: https://github.com/GetStream/stream-chat-flutter
|
||||||
issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues
|
issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues
|
||||||
|
|
||||||
@@ -38,7 +38,7 @@ dependencies:
|
|||||||
rxdart: ^0.27.7
|
rxdart: ^0.27.7
|
||||||
share_plus: ^7.0.2
|
share_plus: ^7.0.2
|
||||||
shimmer: ^3.0.0
|
shimmer: ^3.0.0
|
||||||
stream_chat_flutter_core: ^6.5.0
|
stream_chat_flutter_core: ^6.6.0
|
||||||
synchronized: ^3.1.0
|
synchronized: ^3.1.0
|
||||||
thumblr: ^0.0.4
|
thumblr: ^0.0.4
|
||||||
url_launcher: ^6.1.11
|
url_launcher: ^6.1.11
|
||||||
|
|||||||
@@ -4,24 +4,51 @@ import 'package:golden_toolkit/golden_toolkit.dart';
|
|||||||
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
|
import 'package:stream_chat_flutter/stream_chat_flutter.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
testWidgets('StreamSendingIndicator shows an Icon', (tester) async {
|
testWidgets(
|
||||||
await tester.pumpWidget(
|
'StreamSendingIndicator shows sizedBox if messsage state is initial',
|
||||||
MaterialApp(
|
(tester) async {
|
||||||
home: StreamChatTheme(
|
await tester.pumpWidget(
|
||||||
data: StreamChatThemeData.light(),
|
MaterialApp(
|
||||||
child: Scaffold(
|
home: StreamChatTheme(
|
||||||
body: Center(
|
data: StreamChatThemeData.light(),
|
||||||
child: StreamSendingIndicator(
|
child: Scaffold(
|
||||||
message: Message(),
|
body: Center(
|
||||||
|
child: StreamSendingIndicator(
|
||||||
|
message: Message(),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
);
|
||||||
);
|
|
||||||
|
|
||||||
expect(find.byType(Icon), findsOneWidget);
|
expect(find.byType(SizedBox), findsOneWidget);
|
||||||
});
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
testWidgets(
|
||||||
|
'StreamSendingIndicator shows an Icon if message state is sending',
|
||||||
|
(tester) async {
|
||||||
|
await tester.pumpWidget(
|
||||||
|
MaterialApp(
|
||||||
|
home: StreamChatTheme(
|
||||||
|
data: StreamChatThemeData.light(),
|
||||||
|
child: Scaffold(
|
||||||
|
body: Center(
|
||||||
|
child: StreamSendingIndicator(
|
||||||
|
message: Message(
|
||||||
|
state: MessageState.sending,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(find.byType(Icon), findsOneWidget);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
testGoldens(
|
testGoldens(
|
||||||
'golden test for StreamSendingIndicator with StreamSvgIcon.checkAll',
|
'golden test for StreamSendingIndicator with StreamSvgIcon.checkAll',
|
||||||
|
|||||||
+15
-63
@@ -40,7 +40,7 @@ void main() {
|
|||||||
user: User(
|
user: User(
|
||||||
id: 'user-id',
|
id: 'user-id',
|
||||||
),
|
),
|
||||||
status: MessageSendingStatus.sent,
|
state: MessageState.sent,
|
||||||
),
|
),
|
||||||
messageWidget: const Text(
|
messageWidget: const Text(
|
||||||
'test',
|
'test',
|
||||||
@@ -211,7 +211,7 @@ void main() {
|
|||||||
user: User(
|
user: User(
|
||||||
id: 'user-id',
|
id: 'user-id',
|
||||||
),
|
),
|
||||||
status: MessageSendingStatus.sent,
|
state: MessageState.sent,
|
||||||
),
|
),
|
||||||
messageTheme: streamTheme.ownMessageTheme,
|
messageTheme: streamTheme.ownMessageTheme,
|
||||||
),
|
),
|
||||||
@@ -262,7 +262,7 @@ void main() {
|
|||||||
user: User(
|
user: User(
|
||||||
id: 'user-id',
|
id: 'user-id',
|
||||||
),
|
),
|
||||||
status: MessageSendingStatus.sent,
|
state: MessageState.sent,
|
||||||
),
|
),
|
||||||
messageTheme: streamTheme.ownMessageTheme,
|
messageTheme: streamTheme.ownMessageTheme,
|
||||||
),
|
),
|
||||||
@@ -431,15 +431,23 @@ void main() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
testWidgets(
|
testWidgets(
|
||||||
'tapping on resend should call send message',
|
'tapping on resend should call retry message',
|
||||||
(WidgetTester tester) async {
|
(WidgetTester tester) async {
|
||||||
final client = MockClient();
|
final client = MockClient();
|
||||||
final clientState = MockClientState();
|
final clientState = MockClientState();
|
||||||
final channel = MockChannel();
|
final channel = MockChannel();
|
||||||
|
|
||||||
|
final message = Message(
|
||||||
|
state: MessageState.sendingFailed,
|
||||||
|
text: 'test',
|
||||||
|
user: User(
|
||||||
|
id: 'user-id',
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
when(() => client.state).thenReturn(clientState);
|
when(() => client.state).thenReturn(clientState);
|
||||||
when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
|
when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
|
||||||
when(() => channel.sendMessage(any()))
|
when(() => channel.retryMessage(message))
|
||||||
.thenAnswer((_) async => SendMessageResponse());
|
.thenAnswer((_) async => SendMessageResponse());
|
||||||
|
|
||||||
final themeData = ThemeData();
|
final themeData = ThemeData();
|
||||||
@@ -459,13 +467,7 @@ void main() {
|
|||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
child: MessageActionsModal(
|
child: MessageActionsModal(
|
||||||
messageWidget: const Text('test'),
|
messageWidget: const Text('test'),
|
||||||
message: Message(
|
message: message,
|
||||||
status: MessageSendingStatus.failed,
|
|
||||||
text: 'test',
|
|
||||||
user: User(
|
|
||||||
id: 'user-id',
|
|
||||||
),
|
|
||||||
),
|
|
||||||
messageTheme: streamTheme.ownMessageTheme,
|
messageTheme: streamTheme.ownMessageTheme,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@@ -476,57 +478,7 @@ void main() {
|
|||||||
|
|
||||||
await tester.tap(find.text('Resend'));
|
await tester.tap(find.text('Resend'));
|
||||||
|
|
||||||
verify(() => channel.sendMessage(any())).called(1);
|
verify(() => channel.retryMessage(message)).called(1);
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
testWidgets(
|
|
||||||
'tapping on resend should call update message if editing the message',
|
|
||||||
(WidgetTester tester) async {
|
|
||||||
final client = MockClient();
|
|
||||||
final clientState = MockClientState();
|
|
||||||
final channel = MockChannel();
|
|
||||||
|
|
||||||
when(() => client.state).thenReturn(clientState);
|
|
||||||
when(() => clientState.currentUser).thenReturn(OwnUser(id: 'user-id'));
|
|
||||||
when(() => channel.updateMessage(any()))
|
|
||||||
.thenAnswer((_) async => UpdateMessageResponse());
|
|
||||||
|
|
||||||
final themeData = ThemeData();
|
|
||||||
final streamTheme = StreamChatThemeData.fromTheme(themeData);
|
|
||||||
|
|
||||||
await tester.pumpWidget(
|
|
||||||
MaterialApp(
|
|
||||||
builder: (context, child) => StreamChat(
|
|
||||||
client: client,
|
|
||||||
streamChatThemeData: streamTheme,
|
|
||||||
child: child,
|
|
||||||
),
|
|
||||||
theme: themeData,
|
|
||||||
home: StreamChannel(
|
|
||||||
showLoading: false,
|
|
||||||
channel: channel,
|
|
||||||
child: SizedBox(
|
|
||||||
child: MessageActionsModal(
|
|
||||||
messageWidget: const Text('test'),
|
|
||||||
message: Message(
|
|
||||||
status: MessageSendingStatus.failed_update,
|
|
||||||
text: 'test',
|
|
||||||
user: User(
|
|
||||||
id: 'user-id',
|
|
||||||
),
|
|
||||||
),
|
|
||||||
messageTheme: streamTheme.ownMessageTheme,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
await tester.pumpAndSettle();
|
|
||||||
|
|
||||||
await tester.tap(find.text('Resend Edited Message'));
|
|
||||||
|
|
||||||
verify(() => channel.updateMessage(any())).called(1);
|
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,11 @@
|
|||||||
|
## 6.6.0
|
||||||
|
|
||||||
|
- Updated `stream_chat` dependency to [`6.6.0`](https://pub.dev/packages/stream_chat/changelog).
|
||||||
|
|
||||||
## 6.5.0
|
## 6.5.0
|
||||||
|
|
||||||
- Updated minimum supported `SDK` version to Flutter 3.7/Dart 2.19
|
- Updated minimum supported `SDK` version to Flutter 3.7/Dart 2.19
|
||||||
|
- Updated `stream_chat` dependency to [`6.5.0`](https://pub.dev/packages/stream_chat/changelog).
|
||||||
|
|
||||||
## 6.4.0
|
## 6.4.0
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
name: stream_chat_flutter_core
|
name: stream_chat_flutter_core
|
||||||
homepage: https://github.com/GetStream/stream-chat-flutter
|
homepage: https://github.com/GetStream/stream-chat-flutter
|
||||||
description: Stream Chat official Flutter SDK Core. Build your own chat experience using Dart and Flutter.
|
description: Stream Chat official Flutter SDK Core. Build your own chat experience using Dart and Flutter.
|
||||||
version: 6.5.0
|
version: 6.6.0
|
||||||
repository: https://github.com/GetStream/stream-chat-flutter
|
repository: https://github.com/GetStream/stream-chat-flutter
|
||||||
issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues
|
issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues
|
||||||
|
|
||||||
@@ -17,7 +17,7 @@ dependencies:
|
|||||||
freezed_annotation: ^2.2.0
|
freezed_annotation: ^2.2.0
|
||||||
meta: ^1.8.0
|
meta: ^1.8.0
|
||||||
rxdart: ^0.27.7
|
rxdart: ^0.27.7
|
||||||
stream_chat: ^6.5.0
|
stream_chat: ^6.6.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
build_runner: ^2.3.3
|
build_runner: ^2.3.3
|
||||||
|
|||||||
@@ -1,6 +1,11 @@
|
|||||||
|
## 5.7.0
|
||||||
|
|
||||||
|
* Updated `stream_chat_flutter` dependency to [`6.7.0`](https://pub.dev/packages/stream_chat_flutter/changelog).
|
||||||
|
|
||||||
## 5.6.0
|
## 5.6.0
|
||||||
|
|
||||||
- Updated minimum supported `SDK` version to Flutter 3.7/Dart 2.19
|
* Updated minimum supported `SDK` version to Flutter 3.7/Dart 2.19
|
||||||
|
* Updated `stream_chat_flutter` dependency to [`6.6.0`](https://pub.dev/packages/stream_chat_flutter/changelog).
|
||||||
|
|
||||||
## 5.5.0
|
## 5.5.0
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
name: stream_chat_localizations
|
name: stream_chat_localizations
|
||||||
description: The Official localizations for Stream Chat Flutter, a service for building chat applications
|
description: The Official localizations for Stream Chat Flutter, a service for building chat applications
|
||||||
version: 5.6.0
|
version: 5.7.0
|
||||||
homepage: https://github.com/GetStream/stream-chat-flutter
|
homepage: https://github.com/GetStream/stream-chat-flutter
|
||||||
repository: https://github.com/GetStream/stream-chat-flutter
|
repository: https://github.com/GetStream/stream-chat-flutter
|
||||||
issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues
|
issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues
|
||||||
@@ -14,7 +14,7 @@ dependencies:
|
|||||||
sdk: flutter
|
sdk: flutter
|
||||||
flutter_localizations:
|
flutter_localizations:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
stream_chat_flutter: ^6.6.0
|
stream_chat_flutter: ^6.7.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
## 6.6.0
|
||||||
|
|
||||||
|
- Updated `stream_chat` dependency to [`6.6.0`](https://pub.dev/packages/stream_chat/changelog).
|
||||||
|
|
||||||
## 6.5.0
|
## 6.5.0
|
||||||
|
|
||||||
- Updated minimum supported `SDK` version to Flutter 3.7/Dart 2.19
|
- Updated minimum supported `SDK` version to Flutter 3.7/Dart 2.19
|
||||||
|
|||||||
@@ -1,3 +1,2 @@
|
|||||||
export 'list_converter.dart';
|
export 'list_converter.dart';
|
||||||
export 'map_converter.dart';
|
export 'map_converter.dart';
|
||||||
export 'message_sending_status_converter.dart';
|
|
||||||
|
|||||||
-48
@@ -1,48 +0,0 @@
|
|||||||
import 'package:drift/drift.dart';
|
|
||||||
import 'package:stream_chat/stream_chat.dart';
|
|
||||||
|
|
||||||
/// Maps a [MessageSendingStatus] into a [int] understood
|
|
||||||
/// by the sqlite backend.
|
|
||||||
class MessageSendingStatusConverter
|
|
||||||
extends TypeConverter<MessageSendingStatus, int> {
|
|
||||||
@override
|
|
||||||
MessageSendingStatus fromSql(int fromDb) {
|
|
||||||
switch (fromDb) {
|
|
||||||
case 0:
|
|
||||||
return MessageSendingStatus.sending;
|
|
||||||
case 1:
|
|
||||||
return MessageSendingStatus.sent;
|
|
||||||
case 2:
|
|
||||||
return MessageSendingStatus.failed;
|
|
||||||
case 3:
|
|
||||||
return MessageSendingStatus.updating;
|
|
||||||
case 4:
|
|
||||||
return MessageSendingStatus.failed_update;
|
|
||||||
case 5:
|
|
||||||
return MessageSendingStatus.deleting;
|
|
||||||
case 6:
|
|
||||||
return MessageSendingStatus.failed_delete;
|
|
||||||
}
|
|
||||||
return MessageSendingStatus.sending;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
int toSql(MessageSendingStatus value) {
|
|
||||||
switch (value) {
|
|
||||||
case MessageSendingStatus.sending:
|
|
||||||
return 0;
|
|
||||||
case MessageSendingStatus.sent:
|
|
||||||
return 1;
|
|
||||||
case MessageSendingStatus.failed:
|
|
||||||
return 2;
|
|
||||||
case MessageSendingStatus.updating:
|
|
||||||
return 3;
|
|
||||||
case MessageSendingStatus.failed_update:
|
|
||||||
return 4;
|
|
||||||
case MessageSendingStatus.deleting:
|
|
||||||
return 5;
|
|
||||||
case MessageSendingStatus.failed_delete:
|
|
||||||
return 6;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
import 'package:drift/drift.dart';
|
import 'package:drift/drift.dart';
|
||||||
import 'package:stream_chat/stream_chat.dart';
|
|
||||||
import 'package:stream_chat_persistence/src/converter/converter.dart';
|
import 'package:stream_chat_persistence/src/converter/converter.dart';
|
||||||
import 'package:stream_chat_persistence/src/dao/dao.dart';
|
import 'package:stream_chat_persistence/src/dao/dao.dart';
|
||||||
import 'package:stream_chat_persistence/src/entity/entity.dart';
|
import 'package:stream_chat_persistence/src/entity/entity.dart';
|
||||||
|
|||||||
@@ -667,14 +667,11 @@ class $MessagesTable extends Messages
|
|||||||
attachments = GeneratedColumn<String>('attachments', aliasedName, false,
|
attachments = GeneratedColumn<String>('attachments', aliasedName, false,
|
||||||
type: DriftSqlType.string, requiredDuringInsert: true)
|
type: DriftSqlType.string, requiredDuringInsert: true)
|
||||||
.withConverter<List<String>>($MessagesTable.$converterattachments);
|
.withConverter<List<String>>($MessagesTable.$converterattachments);
|
||||||
static const VerificationMeta _statusMeta = const VerificationMeta('status');
|
static const VerificationMeta _stateMeta = const VerificationMeta('state');
|
||||||
@override
|
@override
|
||||||
late final GeneratedColumnWithTypeConverter<MessageSendingStatus, int>
|
late final GeneratedColumn<String> state = GeneratedColumn<String>(
|
||||||
status = GeneratedColumn<int>('status', aliasedName, false,
|
'state', aliasedName, false,
|
||||||
type: DriftSqlType.int,
|
type: DriftSqlType.string, requiredDuringInsert: true);
|
||||||
requiredDuringInsert: false,
|
|
||||||
defaultValue: const Constant(1))
|
|
||||||
.withConverter<MessageSendingStatus>($MessagesTable.$converterstatus);
|
|
||||||
static const VerificationMeta _typeMeta = const VerificationMeta('type');
|
static const VerificationMeta _typeMeta = const VerificationMeta('type');
|
||||||
@override
|
@override
|
||||||
late final GeneratedColumn<String> type = GeneratedColumn<String>(
|
late final GeneratedColumn<String> type = GeneratedColumn<String>(
|
||||||
@@ -856,7 +853,7 @@ class $MessagesTable extends Messages
|
|||||||
id,
|
id,
|
||||||
messageText,
|
messageText,
|
||||||
attachments,
|
attachments,
|
||||||
status,
|
state,
|
||||||
type,
|
type,
|
||||||
mentionedUsers,
|
mentionedUsers,
|
||||||
reactionCounts,
|
reactionCounts,
|
||||||
@@ -903,7 +900,12 @@ class $MessagesTable extends Messages
|
|||||||
data['message_text']!, _messageTextMeta));
|
data['message_text']!, _messageTextMeta));
|
||||||
}
|
}
|
||||||
context.handle(_attachmentsMeta, const VerificationResult.success());
|
context.handle(_attachmentsMeta, const VerificationResult.success());
|
||||||
context.handle(_statusMeta, const VerificationResult.success());
|
if (data.containsKey('state')) {
|
||||||
|
context.handle(
|
||||||
|
_stateMeta, state.isAcceptableOrUnknown(data['state']!, _stateMeta));
|
||||||
|
} else if (isInserting) {
|
||||||
|
context.missing(_stateMeta);
|
||||||
|
}
|
||||||
if (data.containsKey('type')) {
|
if (data.containsKey('type')) {
|
||||||
context.handle(
|
context.handle(
|
||||||
_typeMeta, type.isAcceptableOrUnknown(data['type']!, _typeMeta));
|
_typeMeta, type.isAcceptableOrUnknown(data['type']!, _typeMeta));
|
||||||
@@ -1027,9 +1029,8 @@ class $MessagesTable extends Messages
|
|||||||
attachments: $MessagesTable.$converterattachments.fromSql(attachedDatabase
|
attachments: $MessagesTable.$converterattachments.fromSql(attachedDatabase
|
||||||
.typeMapping
|
.typeMapping
|
||||||
.read(DriftSqlType.string, data['${effectivePrefix}attachments'])!),
|
.read(DriftSqlType.string, data['${effectivePrefix}attachments'])!),
|
||||||
status: $MessagesTable.$converterstatus.fromSql(attachedDatabase
|
state: attachedDatabase.typeMapping
|
||||||
.typeMapping
|
.read(DriftSqlType.string, data['${effectivePrefix}state'])!,
|
||||||
.read(DriftSqlType.int, data['${effectivePrefix}status'])!),
|
|
||||||
type: attachedDatabase.typeMapping
|
type: attachedDatabase.typeMapping
|
||||||
.read(DriftSqlType.string, data['${effectivePrefix}type'])!,
|
.read(DriftSqlType.string, data['${effectivePrefix}type'])!,
|
||||||
mentionedUsers: $MessagesTable.$convertermentionedUsers.fromSql(
|
mentionedUsers: $MessagesTable.$convertermentionedUsers.fromSql(
|
||||||
@@ -1092,8 +1093,6 @@ class $MessagesTable extends Messages
|
|||||||
|
|
||||||
static TypeConverter<List<String>, String> $converterattachments =
|
static TypeConverter<List<String>, String> $converterattachments =
|
||||||
ListConverter();
|
ListConverter();
|
||||||
static TypeConverter<MessageSendingStatus, int> $converterstatus =
|
|
||||||
MessageSendingStatusConverter();
|
|
||||||
static TypeConverter<List<String>, String> $convertermentionedUsers =
|
static TypeConverter<List<String>, String> $convertermentionedUsers =
|
||||||
ListConverter();
|
ListConverter();
|
||||||
static TypeConverter<Map<String, int>, String> $converterreactionCounts =
|
static TypeConverter<Map<String, int>, String> $converterreactionCounts =
|
||||||
@@ -1123,8 +1122,8 @@ class MessageEntity extends DataClass implements Insertable<MessageEntity> {
|
|||||||
/// or generated from a command or as a result of URL scraping.
|
/// or generated from a command or as a result of URL scraping.
|
||||||
final List<String> attachments;
|
final List<String> attachments;
|
||||||
|
|
||||||
/// The status of a sending message
|
/// The current state of the message.
|
||||||
final MessageSendingStatus status;
|
final String state;
|
||||||
|
|
||||||
/// The message type
|
/// The message type
|
||||||
final String type;
|
final String type;
|
||||||
@@ -1201,7 +1200,7 @@ class MessageEntity extends DataClass implements Insertable<MessageEntity> {
|
|||||||
{required this.id,
|
{required this.id,
|
||||||
this.messageText,
|
this.messageText,
|
||||||
required this.attachments,
|
required this.attachments,
|
||||||
required this.status,
|
required this.state,
|
||||||
required this.type,
|
required this.type,
|
||||||
required this.mentionedUsers,
|
required this.mentionedUsers,
|
||||||
this.reactionCounts,
|
this.reactionCounts,
|
||||||
@@ -1237,10 +1236,7 @@ class MessageEntity extends DataClass implements Insertable<MessageEntity> {
|
|||||||
final converter = $MessagesTable.$converterattachments;
|
final converter = $MessagesTable.$converterattachments;
|
||||||
map['attachments'] = Variable<String>(converter.toSql(attachments));
|
map['attachments'] = Variable<String>(converter.toSql(attachments));
|
||||||
}
|
}
|
||||||
{
|
map['state'] = Variable<String>(state);
|
||||||
final converter = $MessagesTable.$converterstatus;
|
|
||||||
map['status'] = Variable<int>(converter.toSql(status));
|
|
||||||
}
|
|
||||||
map['type'] = Variable<String>(type);
|
map['type'] = Variable<String>(type);
|
||||||
{
|
{
|
||||||
final converter = $MessagesTable.$convertermentionedUsers;
|
final converter = $MessagesTable.$convertermentionedUsers;
|
||||||
@@ -1323,7 +1319,7 @@ class MessageEntity extends DataClass implements Insertable<MessageEntity> {
|
|||||||
id: serializer.fromJson<String>(json['id']),
|
id: serializer.fromJson<String>(json['id']),
|
||||||
messageText: serializer.fromJson<String?>(json['messageText']),
|
messageText: serializer.fromJson<String?>(json['messageText']),
|
||||||
attachments: serializer.fromJson<List<String>>(json['attachments']),
|
attachments: serializer.fromJson<List<String>>(json['attachments']),
|
||||||
status: serializer.fromJson<MessageSendingStatus>(json['status']),
|
state: serializer.fromJson<String>(json['state']),
|
||||||
type: serializer.fromJson<String>(json['type']),
|
type: serializer.fromJson<String>(json['type']),
|
||||||
mentionedUsers: serializer.fromJson<List<String>>(json['mentionedUsers']),
|
mentionedUsers: serializer.fromJson<List<String>>(json['mentionedUsers']),
|
||||||
reactionCounts:
|
reactionCounts:
|
||||||
@@ -1359,7 +1355,7 @@ class MessageEntity extends DataClass implements Insertable<MessageEntity> {
|
|||||||
'id': serializer.toJson<String>(id),
|
'id': serializer.toJson<String>(id),
|
||||||
'messageText': serializer.toJson<String?>(messageText),
|
'messageText': serializer.toJson<String?>(messageText),
|
||||||
'attachments': serializer.toJson<List<String>>(attachments),
|
'attachments': serializer.toJson<List<String>>(attachments),
|
||||||
'status': serializer.toJson<MessageSendingStatus>(status),
|
'state': serializer.toJson<String>(state),
|
||||||
'type': serializer.toJson<String>(type),
|
'type': serializer.toJson<String>(type),
|
||||||
'mentionedUsers': serializer.toJson<List<String>>(mentionedUsers),
|
'mentionedUsers': serializer.toJson<List<String>>(mentionedUsers),
|
||||||
'reactionCounts': serializer.toJson<Map<String, int>?>(reactionCounts),
|
'reactionCounts': serializer.toJson<Map<String, int>?>(reactionCounts),
|
||||||
@@ -1391,7 +1387,7 @@ class MessageEntity extends DataClass implements Insertable<MessageEntity> {
|
|||||||
{String? id,
|
{String? id,
|
||||||
Value<String?> messageText = const Value.absent(),
|
Value<String?> messageText = const Value.absent(),
|
||||||
List<String>? attachments,
|
List<String>? attachments,
|
||||||
MessageSendingStatus? status,
|
String? state,
|
||||||
String? type,
|
String? type,
|
||||||
List<String>? mentionedUsers,
|
List<String>? mentionedUsers,
|
||||||
Value<Map<String, int>?> reactionCounts = const Value.absent(),
|
Value<Map<String, int>?> reactionCounts = const Value.absent(),
|
||||||
@@ -1420,7 +1416,7 @@ class MessageEntity extends DataClass implements Insertable<MessageEntity> {
|
|||||||
id: id ?? this.id,
|
id: id ?? this.id,
|
||||||
messageText: messageText.present ? messageText.value : this.messageText,
|
messageText: messageText.present ? messageText.value : this.messageText,
|
||||||
attachments: attachments ?? this.attachments,
|
attachments: attachments ?? this.attachments,
|
||||||
status: status ?? this.status,
|
state: state ?? this.state,
|
||||||
type: type ?? this.type,
|
type: type ?? this.type,
|
||||||
mentionedUsers: mentionedUsers ?? this.mentionedUsers,
|
mentionedUsers: mentionedUsers ?? this.mentionedUsers,
|
||||||
reactionCounts:
|
reactionCounts:
|
||||||
@@ -1467,7 +1463,7 @@ class MessageEntity extends DataClass implements Insertable<MessageEntity> {
|
|||||||
..write('id: $id, ')
|
..write('id: $id, ')
|
||||||
..write('messageText: $messageText, ')
|
..write('messageText: $messageText, ')
|
||||||
..write('attachments: $attachments, ')
|
..write('attachments: $attachments, ')
|
||||||
..write('status: $status, ')
|
..write('state: $state, ')
|
||||||
..write('type: $type, ')
|
..write('type: $type, ')
|
||||||
..write('mentionedUsers: $mentionedUsers, ')
|
..write('mentionedUsers: $mentionedUsers, ')
|
||||||
..write('reactionCounts: $reactionCounts, ')
|
..write('reactionCounts: $reactionCounts, ')
|
||||||
@@ -1501,7 +1497,7 @@ class MessageEntity extends DataClass implements Insertable<MessageEntity> {
|
|||||||
id,
|
id,
|
||||||
messageText,
|
messageText,
|
||||||
attachments,
|
attachments,
|
||||||
status,
|
state,
|
||||||
type,
|
type,
|
||||||
mentionedUsers,
|
mentionedUsers,
|
||||||
reactionCounts,
|
reactionCounts,
|
||||||
@@ -1534,7 +1530,7 @@ class MessageEntity extends DataClass implements Insertable<MessageEntity> {
|
|||||||
other.id == this.id &&
|
other.id == this.id &&
|
||||||
other.messageText == this.messageText &&
|
other.messageText == this.messageText &&
|
||||||
other.attachments == this.attachments &&
|
other.attachments == this.attachments &&
|
||||||
other.status == this.status &&
|
other.state == this.state &&
|
||||||
other.type == this.type &&
|
other.type == this.type &&
|
||||||
other.mentionedUsers == this.mentionedUsers &&
|
other.mentionedUsers == this.mentionedUsers &&
|
||||||
other.reactionCounts == this.reactionCounts &&
|
other.reactionCounts == this.reactionCounts &&
|
||||||
@@ -1565,7 +1561,7 @@ class MessagesCompanion extends UpdateCompanion<MessageEntity> {
|
|||||||
final Value<String> id;
|
final Value<String> id;
|
||||||
final Value<String?> messageText;
|
final Value<String?> messageText;
|
||||||
final Value<List<String>> attachments;
|
final Value<List<String>> attachments;
|
||||||
final Value<MessageSendingStatus> status;
|
final Value<String> state;
|
||||||
final Value<String> type;
|
final Value<String> type;
|
||||||
final Value<List<String>> mentionedUsers;
|
final Value<List<String>> mentionedUsers;
|
||||||
final Value<Map<String, int>?> reactionCounts;
|
final Value<Map<String, int>?> reactionCounts;
|
||||||
@@ -1595,7 +1591,7 @@ class MessagesCompanion extends UpdateCompanion<MessageEntity> {
|
|||||||
this.id = const Value.absent(),
|
this.id = const Value.absent(),
|
||||||
this.messageText = const Value.absent(),
|
this.messageText = const Value.absent(),
|
||||||
this.attachments = const Value.absent(),
|
this.attachments = const Value.absent(),
|
||||||
this.status = const Value.absent(),
|
this.state = const Value.absent(),
|
||||||
this.type = const Value.absent(),
|
this.type = const Value.absent(),
|
||||||
this.mentionedUsers = const Value.absent(),
|
this.mentionedUsers = const Value.absent(),
|
||||||
this.reactionCounts = const Value.absent(),
|
this.reactionCounts = const Value.absent(),
|
||||||
@@ -1626,7 +1622,7 @@ class MessagesCompanion extends UpdateCompanion<MessageEntity> {
|
|||||||
required String id,
|
required String id,
|
||||||
this.messageText = const Value.absent(),
|
this.messageText = const Value.absent(),
|
||||||
required List<String> attachments,
|
required List<String> attachments,
|
||||||
this.status = const Value.absent(),
|
required String state,
|
||||||
this.type = const Value.absent(),
|
this.type = const Value.absent(),
|
||||||
required List<String> mentionedUsers,
|
required List<String> mentionedUsers,
|
||||||
this.reactionCounts = const Value.absent(),
|
this.reactionCounts = const Value.absent(),
|
||||||
@@ -1654,13 +1650,14 @@ class MessagesCompanion extends UpdateCompanion<MessageEntity> {
|
|||||||
this.rowid = const Value.absent(),
|
this.rowid = const Value.absent(),
|
||||||
}) : id = Value(id),
|
}) : id = Value(id),
|
||||||
attachments = Value(attachments),
|
attachments = Value(attachments),
|
||||||
|
state = Value(state),
|
||||||
mentionedUsers = Value(mentionedUsers),
|
mentionedUsers = Value(mentionedUsers),
|
||||||
channelCid = Value(channelCid);
|
channelCid = Value(channelCid);
|
||||||
static Insertable<MessageEntity> custom({
|
static Insertable<MessageEntity> custom({
|
||||||
Expression<String>? id,
|
Expression<String>? id,
|
||||||
Expression<String>? messageText,
|
Expression<String>? messageText,
|
||||||
Expression<String>? attachments,
|
Expression<String>? attachments,
|
||||||
Expression<int>? status,
|
Expression<String>? state,
|
||||||
Expression<String>? type,
|
Expression<String>? type,
|
||||||
Expression<String>? mentionedUsers,
|
Expression<String>? mentionedUsers,
|
||||||
Expression<String>? reactionCounts,
|
Expression<String>? reactionCounts,
|
||||||
@@ -1691,7 +1688,7 @@ class MessagesCompanion extends UpdateCompanion<MessageEntity> {
|
|||||||
if (id != null) 'id': id,
|
if (id != null) 'id': id,
|
||||||
if (messageText != null) 'message_text': messageText,
|
if (messageText != null) 'message_text': messageText,
|
||||||
if (attachments != null) 'attachments': attachments,
|
if (attachments != null) 'attachments': attachments,
|
||||||
if (status != null) 'status': status,
|
if (state != null) 'state': state,
|
||||||
if (type != null) 'type': type,
|
if (type != null) 'type': type,
|
||||||
if (mentionedUsers != null) 'mentioned_users': mentionedUsers,
|
if (mentionedUsers != null) 'mentioned_users': mentionedUsers,
|
||||||
if (reactionCounts != null) 'reaction_counts': reactionCounts,
|
if (reactionCounts != null) 'reaction_counts': reactionCounts,
|
||||||
@@ -1724,7 +1721,7 @@ class MessagesCompanion extends UpdateCompanion<MessageEntity> {
|
|||||||
{Value<String>? id,
|
{Value<String>? id,
|
||||||
Value<String?>? messageText,
|
Value<String?>? messageText,
|
||||||
Value<List<String>>? attachments,
|
Value<List<String>>? attachments,
|
||||||
Value<MessageSendingStatus>? status,
|
Value<String>? state,
|
||||||
Value<String>? type,
|
Value<String>? type,
|
||||||
Value<List<String>>? mentionedUsers,
|
Value<List<String>>? mentionedUsers,
|
||||||
Value<Map<String, int>?>? reactionCounts,
|
Value<Map<String, int>?>? reactionCounts,
|
||||||
@@ -1754,7 +1751,7 @@ class MessagesCompanion extends UpdateCompanion<MessageEntity> {
|
|||||||
id: id ?? this.id,
|
id: id ?? this.id,
|
||||||
messageText: messageText ?? this.messageText,
|
messageText: messageText ?? this.messageText,
|
||||||
attachments: attachments ?? this.attachments,
|
attachments: attachments ?? this.attachments,
|
||||||
status: status ?? this.status,
|
state: state ?? this.state,
|
||||||
type: type ?? this.type,
|
type: type ?? this.type,
|
||||||
mentionedUsers: mentionedUsers ?? this.mentionedUsers,
|
mentionedUsers: mentionedUsers ?? this.mentionedUsers,
|
||||||
reactionCounts: reactionCounts ?? this.reactionCounts,
|
reactionCounts: reactionCounts ?? this.reactionCounts,
|
||||||
@@ -1796,9 +1793,8 @@ class MessagesCompanion extends UpdateCompanion<MessageEntity> {
|
|||||||
final converter = $MessagesTable.$converterattachments;
|
final converter = $MessagesTable.$converterattachments;
|
||||||
map['attachments'] = Variable<String>(converter.toSql(attachments.value));
|
map['attachments'] = Variable<String>(converter.toSql(attachments.value));
|
||||||
}
|
}
|
||||||
if (status.present) {
|
if (state.present) {
|
||||||
final converter = $MessagesTable.$converterstatus;
|
map['state'] = Variable<String>(state.value);
|
||||||
map['status'] = Variable<int>(converter.toSql(status.value));
|
|
||||||
}
|
}
|
||||||
if (type.present) {
|
if (type.present) {
|
||||||
map['type'] = Variable<String>(type.value);
|
map['type'] = Variable<String>(type.value);
|
||||||
@@ -1892,7 +1888,7 @@ class MessagesCompanion extends UpdateCompanion<MessageEntity> {
|
|||||||
..write('id: $id, ')
|
..write('id: $id, ')
|
||||||
..write('messageText: $messageText, ')
|
..write('messageText: $messageText, ')
|
||||||
..write('attachments: $attachments, ')
|
..write('attachments: $attachments, ')
|
||||||
..write('status: $status, ')
|
..write('state: $state, ')
|
||||||
..write('type: $type, ')
|
..write('type: $type, ')
|
||||||
..write('mentionedUsers: $mentionedUsers, ')
|
..write('mentionedUsers: $mentionedUsers, ')
|
||||||
..write('reactionCounts: $reactionCounts, ')
|
..write('reactionCounts: $reactionCounts, ')
|
||||||
@@ -1948,15 +1944,11 @@ class $PinnedMessagesTable extends PinnedMessages
|
|||||||
type: DriftSqlType.string, requiredDuringInsert: true)
|
type: DriftSqlType.string, requiredDuringInsert: true)
|
||||||
.withConverter<List<String>>(
|
.withConverter<List<String>>(
|
||||||
$PinnedMessagesTable.$converterattachments);
|
$PinnedMessagesTable.$converterattachments);
|
||||||
static const VerificationMeta _statusMeta = const VerificationMeta('status');
|
static const VerificationMeta _stateMeta = const VerificationMeta('state');
|
||||||
@override
|
@override
|
||||||
late final GeneratedColumnWithTypeConverter<MessageSendingStatus, int>
|
late final GeneratedColumn<String> state = GeneratedColumn<String>(
|
||||||
status = GeneratedColumn<int>('status', aliasedName, false,
|
'state', aliasedName, false,
|
||||||
type: DriftSqlType.int,
|
type: DriftSqlType.string, requiredDuringInsert: true);
|
||||||
requiredDuringInsert: false,
|
|
||||||
defaultValue: const Constant(1))
|
|
||||||
.withConverter<MessageSendingStatus>(
|
|
||||||
$PinnedMessagesTable.$converterstatus);
|
|
||||||
static const VerificationMeta _typeMeta = const VerificationMeta('type');
|
static const VerificationMeta _typeMeta = const VerificationMeta('type');
|
||||||
@override
|
@override
|
||||||
late final GeneratedColumn<String> type = GeneratedColumn<String>(
|
late final GeneratedColumn<String> type = GeneratedColumn<String>(
|
||||||
@@ -2140,7 +2132,7 @@ class $PinnedMessagesTable extends PinnedMessages
|
|||||||
id,
|
id,
|
||||||
messageText,
|
messageText,
|
||||||
attachments,
|
attachments,
|
||||||
status,
|
state,
|
||||||
type,
|
type,
|
||||||
mentionedUsers,
|
mentionedUsers,
|
||||||
reactionCounts,
|
reactionCounts,
|
||||||
@@ -2188,7 +2180,12 @@ class $PinnedMessagesTable extends PinnedMessages
|
|||||||
data['message_text']!, _messageTextMeta));
|
data['message_text']!, _messageTextMeta));
|
||||||
}
|
}
|
||||||
context.handle(_attachmentsMeta, const VerificationResult.success());
|
context.handle(_attachmentsMeta, const VerificationResult.success());
|
||||||
context.handle(_statusMeta, const VerificationResult.success());
|
if (data.containsKey('state')) {
|
||||||
|
context.handle(
|
||||||
|
_stateMeta, state.isAcceptableOrUnknown(data['state']!, _stateMeta));
|
||||||
|
} else if (isInserting) {
|
||||||
|
context.missing(_stateMeta);
|
||||||
|
}
|
||||||
if (data.containsKey('type')) {
|
if (data.containsKey('type')) {
|
||||||
context.handle(
|
context.handle(
|
||||||
_typeMeta, type.isAcceptableOrUnknown(data['type']!, _typeMeta));
|
_typeMeta, type.isAcceptableOrUnknown(data['type']!, _typeMeta));
|
||||||
@@ -2312,9 +2309,8 @@ class $PinnedMessagesTable extends PinnedMessages
|
|||||||
attachments: $PinnedMessagesTable.$converterattachments.fromSql(
|
attachments: $PinnedMessagesTable.$converterattachments.fromSql(
|
||||||
attachedDatabase.typeMapping.read(
|
attachedDatabase.typeMapping.read(
|
||||||
DriftSqlType.string, data['${effectivePrefix}attachments'])!),
|
DriftSqlType.string, data['${effectivePrefix}attachments'])!),
|
||||||
status: $PinnedMessagesTable.$converterstatus.fromSql(attachedDatabase
|
state: attachedDatabase.typeMapping
|
||||||
.typeMapping
|
.read(DriftSqlType.string, data['${effectivePrefix}state'])!,
|
||||||
.read(DriftSqlType.int, data['${effectivePrefix}status'])!),
|
|
||||||
type: attachedDatabase.typeMapping
|
type: attachedDatabase.typeMapping
|
||||||
.read(DriftSqlType.string, data['${effectivePrefix}type'])!,
|
.read(DriftSqlType.string, data['${effectivePrefix}type'])!,
|
||||||
mentionedUsers: $PinnedMessagesTable.$convertermentionedUsers.fromSql(
|
mentionedUsers: $PinnedMessagesTable.$convertermentionedUsers.fromSql(
|
||||||
@@ -2378,8 +2374,6 @@ class $PinnedMessagesTable extends PinnedMessages
|
|||||||
|
|
||||||
static TypeConverter<List<String>, String> $converterattachments =
|
static TypeConverter<List<String>, String> $converterattachments =
|
||||||
ListConverter();
|
ListConverter();
|
||||||
static TypeConverter<MessageSendingStatus, int> $converterstatus =
|
|
||||||
MessageSendingStatusConverter();
|
|
||||||
static TypeConverter<List<String>, String> $convertermentionedUsers =
|
static TypeConverter<List<String>, String> $convertermentionedUsers =
|
||||||
ListConverter();
|
ListConverter();
|
||||||
static TypeConverter<Map<String, int>, String> $converterreactionCounts =
|
static TypeConverter<Map<String, int>, String> $converterreactionCounts =
|
||||||
@@ -2410,8 +2404,8 @@ class PinnedMessageEntity extends DataClass
|
|||||||
/// or generated from a command or as a result of URL scraping.
|
/// or generated from a command or as a result of URL scraping.
|
||||||
final List<String> attachments;
|
final List<String> attachments;
|
||||||
|
|
||||||
/// The status of a sending message
|
/// The current state of the message.
|
||||||
final MessageSendingStatus status;
|
final String state;
|
||||||
|
|
||||||
/// The message type
|
/// The message type
|
||||||
final String type;
|
final String type;
|
||||||
@@ -2488,7 +2482,7 @@ class PinnedMessageEntity extends DataClass
|
|||||||
{required this.id,
|
{required this.id,
|
||||||
this.messageText,
|
this.messageText,
|
||||||
required this.attachments,
|
required this.attachments,
|
||||||
required this.status,
|
required this.state,
|
||||||
required this.type,
|
required this.type,
|
||||||
required this.mentionedUsers,
|
required this.mentionedUsers,
|
||||||
this.reactionCounts,
|
this.reactionCounts,
|
||||||
@@ -2524,10 +2518,7 @@ class PinnedMessageEntity extends DataClass
|
|||||||
final converter = $PinnedMessagesTable.$converterattachments;
|
final converter = $PinnedMessagesTable.$converterattachments;
|
||||||
map['attachments'] = Variable<String>(converter.toSql(attachments));
|
map['attachments'] = Variable<String>(converter.toSql(attachments));
|
||||||
}
|
}
|
||||||
{
|
map['state'] = Variable<String>(state);
|
||||||
final converter = $PinnedMessagesTable.$converterstatus;
|
|
||||||
map['status'] = Variable<int>(converter.toSql(status));
|
|
||||||
}
|
|
||||||
map['type'] = Variable<String>(type);
|
map['type'] = Variable<String>(type);
|
||||||
{
|
{
|
||||||
final converter = $PinnedMessagesTable.$convertermentionedUsers;
|
final converter = $PinnedMessagesTable.$convertermentionedUsers;
|
||||||
@@ -2610,7 +2601,7 @@ class PinnedMessageEntity extends DataClass
|
|||||||
id: serializer.fromJson<String>(json['id']),
|
id: serializer.fromJson<String>(json['id']),
|
||||||
messageText: serializer.fromJson<String?>(json['messageText']),
|
messageText: serializer.fromJson<String?>(json['messageText']),
|
||||||
attachments: serializer.fromJson<List<String>>(json['attachments']),
|
attachments: serializer.fromJson<List<String>>(json['attachments']),
|
||||||
status: serializer.fromJson<MessageSendingStatus>(json['status']),
|
state: serializer.fromJson<String>(json['state']),
|
||||||
type: serializer.fromJson<String>(json['type']),
|
type: serializer.fromJson<String>(json['type']),
|
||||||
mentionedUsers: serializer.fromJson<List<String>>(json['mentionedUsers']),
|
mentionedUsers: serializer.fromJson<List<String>>(json['mentionedUsers']),
|
||||||
reactionCounts:
|
reactionCounts:
|
||||||
@@ -2646,7 +2637,7 @@ class PinnedMessageEntity extends DataClass
|
|||||||
'id': serializer.toJson<String>(id),
|
'id': serializer.toJson<String>(id),
|
||||||
'messageText': serializer.toJson<String?>(messageText),
|
'messageText': serializer.toJson<String?>(messageText),
|
||||||
'attachments': serializer.toJson<List<String>>(attachments),
|
'attachments': serializer.toJson<List<String>>(attachments),
|
||||||
'status': serializer.toJson<MessageSendingStatus>(status),
|
'state': serializer.toJson<String>(state),
|
||||||
'type': serializer.toJson<String>(type),
|
'type': serializer.toJson<String>(type),
|
||||||
'mentionedUsers': serializer.toJson<List<String>>(mentionedUsers),
|
'mentionedUsers': serializer.toJson<List<String>>(mentionedUsers),
|
||||||
'reactionCounts': serializer.toJson<Map<String, int>?>(reactionCounts),
|
'reactionCounts': serializer.toJson<Map<String, int>?>(reactionCounts),
|
||||||
@@ -2678,7 +2669,7 @@ class PinnedMessageEntity extends DataClass
|
|||||||
{String? id,
|
{String? id,
|
||||||
Value<String?> messageText = const Value.absent(),
|
Value<String?> messageText = const Value.absent(),
|
||||||
List<String>? attachments,
|
List<String>? attachments,
|
||||||
MessageSendingStatus? status,
|
String? state,
|
||||||
String? type,
|
String? type,
|
||||||
List<String>? mentionedUsers,
|
List<String>? mentionedUsers,
|
||||||
Value<Map<String, int>?> reactionCounts = const Value.absent(),
|
Value<Map<String, int>?> reactionCounts = const Value.absent(),
|
||||||
@@ -2707,7 +2698,7 @@ class PinnedMessageEntity extends DataClass
|
|||||||
id: id ?? this.id,
|
id: id ?? this.id,
|
||||||
messageText: messageText.present ? messageText.value : this.messageText,
|
messageText: messageText.present ? messageText.value : this.messageText,
|
||||||
attachments: attachments ?? this.attachments,
|
attachments: attachments ?? this.attachments,
|
||||||
status: status ?? this.status,
|
state: state ?? this.state,
|
||||||
type: type ?? this.type,
|
type: type ?? this.type,
|
||||||
mentionedUsers: mentionedUsers ?? this.mentionedUsers,
|
mentionedUsers: mentionedUsers ?? this.mentionedUsers,
|
||||||
reactionCounts:
|
reactionCounts:
|
||||||
@@ -2754,7 +2745,7 @@ class PinnedMessageEntity extends DataClass
|
|||||||
..write('id: $id, ')
|
..write('id: $id, ')
|
||||||
..write('messageText: $messageText, ')
|
..write('messageText: $messageText, ')
|
||||||
..write('attachments: $attachments, ')
|
..write('attachments: $attachments, ')
|
||||||
..write('status: $status, ')
|
..write('state: $state, ')
|
||||||
..write('type: $type, ')
|
..write('type: $type, ')
|
||||||
..write('mentionedUsers: $mentionedUsers, ')
|
..write('mentionedUsers: $mentionedUsers, ')
|
||||||
..write('reactionCounts: $reactionCounts, ')
|
..write('reactionCounts: $reactionCounts, ')
|
||||||
@@ -2788,7 +2779,7 @@ class PinnedMessageEntity extends DataClass
|
|||||||
id,
|
id,
|
||||||
messageText,
|
messageText,
|
||||||
attachments,
|
attachments,
|
||||||
status,
|
state,
|
||||||
type,
|
type,
|
||||||
mentionedUsers,
|
mentionedUsers,
|
||||||
reactionCounts,
|
reactionCounts,
|
||||||
@@ -2821,7 +2812,7 @@ class PinnedMessageEntity extends DataClass
|
|||||||
other.id == this.id &&
|
other.id == this.id &&
|
||||||
other.messageText == this.messageText &&
|
other.messageText == this.messageText &&
|
||||||
other.attachments == this.attachments &&
|
other.attachments == this.attachments &&
|
||||||
other.status == this.status &&
|
other.state == this.state &&
|
||||||
other.type == this.type &&
|
other.type == this.type &&
|
||||||
other.mentionedUsers == this.mentionedUsers &&
|
other.mentionedUsers == this.mentionedUsers &&
|
||||||
other.reactionCounts == this.reactionCounts &&
|
other.reactionCounts == this.reactionCounts &&
|
||||||
@@ -2852,7 +2843,7 @@ class PinnedMessagesCompanion extends UpdateCompanion<PinnedMessageEntity> {
|
|||||||
final Value<String> id;
|
final Value<String> id;
|
||||||
final Value<String?> messageText;
|
final Value<String?> messageText;
|
||||||
final Value<List<String>> attachments;
|
final Value<List<String>> attachments;
|
||||||
final Value<MessageSendingStatus> status;
|
final Value<String> state;
|
||||||
final Value<String> type;
|
final Value<String> type;
|
||||||
final Value<List<String>> mentionedUsers;
|
final Value<List<String>> mentionedUsers;
|
||||||
final Value<Map<String, int>?> reactionCounts;
|
final Value<Map<String, int>?> reactionCounts;
|
||||||
@@ -2882,7 +2873,7 @@ class PinnedMessagesCompanion extends UpdateCompanion<PinnedMessageEntity> {
|
|||||||
this.id = const Value.absent(),
|
this.id = const Value.absent(),
|
||||||
this.messageText = const Value.absent(),
|
this.messageText = const Value.absent(),
|
||||||
this.attachments = const Value.absent(),
|
this.attachments = const Value.absent(),
|
||||||
this.status = const Value.absent(),
|
this.state = const Value.absent(),
|
||||||
this.type = const Value.absent(),
|
this.type = const Value.absent(),
|
||||||
this.mentionedUsers = const Value.absent(),
|
this.mentionedUsers = const Value.absent(),
|
||||||
this.reactionCounts = const Value.absent(),
|
this.reactionCounts = const Value.absent(),
|
||||||
@@ -2913,7 +2904,7 @@ class PinnedMessagesCompanion extends UpdateCompanion<PinnedMessageEntity> {
|
|||||||
required String id,
|
required String id,
|
||||||
this.messageText = const Value.absent(),
|
this.messageText = const Value.absent(),
|
||||||
required List<String> attachments,
|
required List<String> attachments,
|
||||||
this.status = const Value.absent(),
|
required String state,
|
||||||
this.type = const Value.absent(),
|
this.type = const Value.absent(),
|
||||||
required List<String> mentionedUsers,
|
required List<String> mentionedUsers,
|
||||||
this.reactionCounts = const Value.absent(),
|
this.reactionCounts = const Value.absent(),
|
||||||
@@ -2941,13 +2932,14 @@ class PinnedMessagesCompanion extends UpdateCompanion<PinnedMessageEntity> {
|
|||||||
this.rowid = const Value.absent(),
|
this.rowid = const Value.absent(),
|
||||||
}) : id = Value(id),
|
}) : id = Value(id),
|
||||||
attachments = Value(attachments),
|
attachments = Value(attachments),
|
||||||
|
state = Value(state),
|
||||||
mentionedUsers = Value(mentionedUsers),
|
mentionedUsers = Value(mentionedUsers),
|
||||||
channelCid = Value(channelCid);
|
channelCid = Value(channelCid);
|
||||||
static Insertable<PinnedMessageEntity> custom({
|
static Insertable<PinnedMessageEntity> custom({
|
||||||
Expression<String>? id,
|
Expression<String>? id,
|
||||||
Expression<String>? messageText,
|
Expression<String>? messageText,
|
||||||
Expression<String>? attachments,
|
Expression<String>? attachments,
|
||||||
Expression<int>? status,
|
Expression<String>? state,
|
||||||
Expression<String>? type,
|
Expression<String>? type,
|
||||||
Expression<String>? mentionedUsers,
|
Expression<String>? mentionedUsers,
|
||||||
Expression<String>? reactionCounts,
|
Expression<String>? reactionCounts,
|
||||||
@@ -2978,7 +2970,7 @@ class PinnedMessagesCompanion extends UpdateCompanion<PinnedMessageEntity> {
|
|||||||
if (id != null) 'id': id,
|
if (id != null) 'id': id,
|
||||||
if (messageText != null) 'message_text': messageText,
|
if (messageText != null) 'message_text': messageText,
|
||||||
if (attachments != null) 'attachments': attachments,
|
if (attachments != null) 'attachments': attachments,
|
||||||
if (status != null) 'status': status,
|
if (state != null) 'state': state,
|
||||||
if (type != null) 'type': type,
|
if (type != null) 'type': type,
|
||||||
if (mentionedUsers != null) 'mentioned_users': mentionedUsers,
|
if (mentionedUsers != null) 'mentioned_users': mentionedUsers,
|
||||||
if (reactionCounts != null) 'reaction_counts': reactionCounts,
|
if (reactionCounts != null) 'reaction_counts': reactionCounts,
|
||||||
@@ -3011,7 +3003,7 @@ class PinnedMessagesCompanion extends UpdateCompanion<PinnedMessageEntity> {
|
|||||||
{Value<String>? id,
|
{Value<String>? id,
|
||||||
Value<String?>? messageText,
|
Value<String?>? messageText,
|
||||||
Value<List<String>>? attachments,
|
Value<List<String>>? attachments,
|
||||||
Value<MessageSendingStatus>? status,
|
Value<String>? state,
|
||||||
Value<String>? type,
|
Value<String>? type,
|
||||||
Value<List<String>>? mentionedUsers,
|
Value<List<String>>? mentionedUsers,
|
||||||
Value<Map<String, int>?>? reactionCounts,
|
Value<Map<String, int>?>? reactionCounts,
|
||||||
@@ -3041,7 +3033,7 @@ class PinnedMessagesCompanion extends UpdateCompanion<PinnedMessageEntity> {
|
|||||||
id: id ?? this.id,
|
id: id ?? this.id,
|
||||||
messageText: messageText ?? this.messageText,
|
messageText: messageText ?? this.messageText,
|
||||||
attachments: attachments ?? this.attachments,
|
attachments: attachments ?? this.attachments,
|
||||||
status: status ?? this.status,
|
state: state ?? this.state,
|
||||||
type: type ?? this.type,
|
type: type ?? this.type,
|
||||||
mentionedUsers: mentionedUsers ?? this.mentionedUsers,
|
mentionedUsers: mentionedUsers ?? this.mentionedUsers,
|
||||||
reactionCounts: reactionCounts ?? this.reactionCounts,
|
reactionCounts: reactionCounts ?? this.reactionCounts,
|
||||||
@@ -3083,9 +3075,8 @@ class PinnedMessagesCompanion extends UpdateCompanion<PinnedMessageEntity> {
|
|||||||
final converter = $PinnedMessagesTable.$converterattachments;
|
final converter = $PinnedMessagesTable.$converterattachments;
|
||||||
map['attachments'] = Variable<String>(converter.toSql(attachments.value));
|
map['attachments'] = Variable<String>(converter.toSql(attachments.value));
|
||||||
}
|
}
|
||||||
if (status.present) {
|
if (state.present) {
|
||||||
final converter = $PinnedMessagesTable.$converterstatus;
|
map['state'] = Variable<String>(state.value);
|
||||||
map['status'] = Variable<int>(converter.toSql(status.value));
|
|
||||||
}
|
}
|
||||||
if (type.present) {
|
if (type.present) {
|
||||||
map['type'] = Variable<String>(type.value);
|
map['type'] = Variable<String>(type.value);
|
||||||
@@ -3179,7 +3170,7 @@ class PinnedMessagesCompanion extends UpdateCompanion<PinnedMessageEntity> {
|
|||||||
..write('id: $id, ')
|
..write('id: $id, ')
|
||||||
..write('messageText: $messageText, ')
|
..write('messageText: $messageText, ')
|
||||||
..write('attachments: $attachments, ')
|
..write('attachments: $attachments, ')
|
||||||
..write('status: $status, ')
|
..write('state: $state, ')
|
||||||
..write('type: $type, ')
|
..write('type: $type, ')
|
||||||
..write('mentionedUsers: $mentionedUsers, ')
|
..write('mentionedUsers: $mentionedUsers, ')
|
||||||
..write('reactionCounts: $reactionCounts, ')
|
..write('reactionCounts: $reactionCounts, ')
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
import 'package:drift/drift.dart';
|
import 'package:drift/drift.dart';
|
||||||
import 'package:stream_chat_persistence/src/converter/list_converter.dart';
|
import 'package:stream_chat_persistence/src/converter/list_converter.dart';
|
||||||
import 'package:stream_chat_persistence/src/converter/map_converter.dart';
|
import 'package:stream_chat_persistence/src/converter/map_converter.dart';
|
||||||
import 'package:stream_chat_persistence/src/converter/message_sending_status_converter.dart';
|
|
||||||
import 'package:stream_chat_persistence/src/entity/channels.dart';
|
import 'package:stream_chat_persistence/src/entity/channels.dart';
|
||||||
|
|
||||||
/// Represents a [Messages] table in [MoorChatDatabase].
|
/// Represents a [Messages] table in [MoorChatDatabase].
|
||||||
@@ -18,10 +17,8 @@ class Messages extends Table {
|
|||||||
/// or generated from a command or as a result of URL scraping.
|
/// or generated from a command or as a result of URL scraping.
|
||||||
TextColumn get attachments => text().map(ListConverter<String>())();
|
TextColumn get attachments => text().map(ListConverter<String>())();
|
||||||
|
|
||||||
/// The status of a sending message
|
/// The current state of the message.
|
||||||
IntColumn get status => integer()
|
TextColumn get state => text()();
|
||||||
.withDefault(const Constant(1))
|
|
||||||
.map(MessageSendingStatusConverter())();
|
|
||||||
|
|
||||||
/// The message type
|
/// The message type
|
||||||
TextColumn get type => text().withDefault(const Constant('regular'))();
|
TextColumn get type => text().withDefault(const Constant('regular'))();
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ extension MessageEntityX on MessageEntity {
|
|||||||
localDeletedAt: localDeletedAt,
|
localDeletedAt: localDeletedAt,
|
||||||
id: id,
|
id: id,
|
||||||
type: type,
|
type: type,
|
||||||
status: status,
|
state: MessageState.fromJson(jsonDecode(state)),
|
||||||
command: command,
|
command: command,
|
||||||
parentId: parentId,
|
parentId: parentId,
|
||||||
quotedMessageId: quotedMessageId,
|
quotedMessageId: quotedMessageId,
|
||||||
@@ -70,7 +70,7 @@ extension MessageX on Message {
|
|||||||
reactionScores: reactionScores,
|
reactionScores: reactionScores,
|
||||||
reactionCounts: reactionCounts,
|
reactionCounts: reactionCounts,
|
||||||
mentionedUsers: mentionedUsers.map(jsonEncode).toList(),
|
mentionedUsers: mentionedUsers.map(jsonEncode).toList(),
|
||||||
status: status,
|
state: jsonEncode(state),
|
||||||
remoteUpdatedAt: remoteUpdatedAt,
|
remoteUpdatedAt: remoteUpdatedAt,
|
||||||
localUpdatedAt: localUpdatedAt,
|
localUpdatedAt: localUpdatedAt,
|
||||||
extraData: extraData,
|
extraData: extraData,
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ extension PinnedMessageEntityX on PinnedMessageEntity {
|
|||||||
localDeletedAt: localDeletedAt,
|
localDeletedAt: localDeletedAt,
|
||||||
id: id,
|
id: id,
|
||||||
type: type,
|
type: type,
|
||||||
status: status,
|
state: MessageState.fromJson(jsonDecode(state)),
|
||||||
command: command,
|
command: command,
|
||||||
parentId: parentId,
|
parentId: parentId,
|
||||||
quotedMessageId: quotedMessageId,
|
quotedMessageId: quotedMessageId,
|
||||||
@@ -71,7 +71,7 @@ extension PMessageX on Message {
|
|||||||
reactionScores: reactionScores,
|
reactionScores: reactionScores,
|
||||||
reactionCounts: reactionCounts,
|
reactionCounts: reactionCounts,
|
||||||
mentionedUsers: mentionedUsers.map(jsonEncode).toList(),
|
mentionedUsers: mentionedUsers.map(jsonEncode).toList(),
|
||||||
status: status,
|
state: jsonEncode(state),
|
||||||
remoteUpdatedAt: remoteUpdatedAt,
|
remoteUpdatedAt: remoteUpdatedAt,
|
||||||
localUpdatedAt: localUpdatedAt,
|
localUpdatedAt: localUpdatedAt,
|
||||||
extraData: extraData,
|
extraData: extraData,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
name: stream_chat_persistence
|
name: stream_chat_persistence
|
||||||
homepage: https://github.com/GetStream/stream-chat-flutter
|
homepage: https://github.com/GetStream/stream-chat-flutter
|
||||||
description: Official Stream Chat Persistence library. Build your own chat experience using Dart and Flutter.
|
description: Official Stream Chat Persistence library. Build your own chat experience using Dart and Flutter.
|
||||||
version: 6.5.0
|
version: 6.6.0
|
||||||
repository: https://github.com/GetStream/stream-chat-flutter
|
repository: https://github.com/GetStream/stream-chat-flutter
|
||||||
issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues
|
issue_tracker: https://github.com/GetStream/stream-chat-flutter/issues
|
||||||
|
|
||||||
@@ -18,7 +18,7 @@ dependencies:
|
|||||||
path: ^1.8.2
|
path: ^1.8.2
|
||||||
path_provider: ^2.0.15
|
path_provider: ^2.0.15
|
||||||
sqlite3_flutter_libs: ^0.5.15
|
sqlite3_flutter_libs: ^0.5.15
|
||||||
stream_chat: ^6.5.0
|
stream_chat: ^6.6.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
build_runner: ^2.3.3
|
build_runner: ^2.3.3
|
||||||
|
|||||||
-23
@@ -1,23 +0,0 @@
|
|||||||
import 'package:flutter_test/flutter_test.dart';
|
|
||||||
import 'package:stream_chat/stream_chat.dart';
|
|
||||||
import 'package:stream_chat_persistence/src/converter/message_sending_status_converter.dart';
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
group('fromSql', () {
|
|
||||||
final statusConverter = MessageSendingStatusConverter();
|
|
||||||
|
|
||||||
test('should return expected status if status code is provided', () {
|
|
||||||
final res = statusConverter.fromSql(6);
|
|
||||||
expect(res, MessageSendingStatus.failed_delete);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
group('toSql', () {
|
|
||||||
final statusConverter = MessageSendingStatusConverter();
|
|
||||||
|
|
||||||
test('should return expected code if the status is provided', () {
|
|
||||||
final res = statusConverter.toSql(MessageSendingStatus.failed_delete);
|
|
||||||
expect(res, 6);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@@ -52,7 +52,7 @@ void main() {
|
|||||||
mentionedUsers: [
|
mentionedUsers: [
|
||||||
jsonEncode(User(id: 'testuser')),
|
jsonEncode(User(id: 'testuser')),
|
||||||
],
|
],
|
||||||
status: MessageSendingStatus.sent,
|
state: jsonEncode(MessageState.sent),
|
||||||
localUpdatedAt: DateTime.now(),
|
localUpdatedAt: DateTime.now(),
|
||||||
remoteUpdatedAt: DateTime.now().add(const Duration(seconds: 1)),
|
remoteUpdatedAt: DateTime.now().add(const Duration(seconds: 1)),
|
||||||
extraData: {'extra_test_data': 'extraData'},
|
extraData: {'extra_test_data': 'extraData'},
|
||||||
@@ -96,7 +96,7 @@ void main() {
|
|||||||
expect(message.replyCount, entity.replyCount);
|
expect(message.replyCount, entity.replyCount);
|
||||||
expect(message.reactionScores, entity.reactionScores);
|
expect(message.reactionScores, entity.reactionScores);
|
||||||
expect(message.reactionCounts, entity.reactionCounts);
|
expect(message.reactionCounts, entity.reactionCounts);
|
||||||
expect(message.status, entity.status);
|
expect(message.state, MessageState.fromJson(jsonDecode(entity.state)));
|
||||||
expect(message.localUpdatedAt, isSameDateAs(entity.localUpdatedAt));
|
expect(message.localUpdatedAt, isSameDateAs(entity.localUpdatedAt));
|
||||||
expect(message.remoteUpdatedAt, isSameDateAs(entity.remoteUpdatedAt));
|
expect(message.remoteUpdatedAt, isSameDateAs(entity.remoteUpdatedAt));
|
||||||
expect(message.extraData, entity.extraData);
|
expect(message.extraData, entity.extraData);
|
||||||
@@ -197,7 +197,7 @@ void main() {
|
|||||||
entity.mentionedUsers, message.mentionedUsers.map(jsonEncode).toList());
|
entity.mentionedUsers, message.mentionedUsers.map(jsonEncode).toList());
|
||||||
expect(entity.reactionScores, message.reactionScores);
|
expect(entity.reactionScores, message.reactionScores);
|
||||||
expect(entity.reactionCounts, message.reactionCounts);
|
expect(entity.reactionCounts, message.reactionCounts);
|
||||||
expect(entity.status, message.status);
|
expect(entity.state, jsonEncode(message.state));
|
||||||
expect(entity.localUpdatedAt, isSameDateAs(message.localUpdatedAt));
|
expect(entity.localUpdatedAt, isSameDateAs(message.localUpdatedAt));
|
||||||
expect(entity.remoteUpdatedAt, isSameDateAs(message.remoteUpdatedAt));
|
expect(entity.remoteUpdatedAt, isSameDateAs(message.remoteUpdatedAt));
|
||||||
expect(entity.extraData, message.extraData);
|
expect(entity.extraData, message.extraData);
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ void main() {
|
|||||||
mentionedUsers: [
|
mentionedUsers: [
|
||||||
jsonEncode(User(id: 'testuser')),
|
jsonEncode(User(id: 'testuser')),
|
||||||
],
|
],
|
||||||
status: MessageSendingStatus.sent,
|
state: jsonEncode(MessageState.sent),
|
||||||
localUpdatedAt: DateTime.now(),
|
localUpdatedAt: DateTime.now(),
|
||||||
remoteUpdatedAt: DateTime.now().add(const Duration(seconds: 1)),
|
remoteUpdatedAt: DateTime.now().add(const Duration(seconds: 1)),
|
||||||
extraData: {'extra_test_data': 'extraData'},
|
extraData: {'extra_test_data': 'extraData'},
|
||||||
@@ -96,7 +96,7 @@ void main() {
|
|||||||
expect(message.replyCount, entity.replyCount);
|
expect(message.replyCount, entity.replyCount);
|
||||||
expect(message.reactionScores, entity.reactionScores);
|
expect(message.reactionScores, entity.reactionScores);
|
||||||
expect(message.reactionCounts, entity.reactionCounts);
|
expect(message.reactionCounts, entity.reactionCounts);
|
||||||
expect(message.status, entity.status);
|
expect(message.state, MessageState.fromJson(jsonDecode(entity.state)));
|
||||||
expect(message.localUpdatedAt, isSameDateAs(entity.localUpdatedAt));
|
expect(message.localUpdatedAt, isSameDateAs(entity.localUpdatedAt));
|
||||||
expect(message.remoteUpdatedAt, isSameDateAs(entity.remoteUpdatedAt));
|
expect(message.remoteUpdatedAt, isSameDateAs(entity.remoteUpdatedAt));
|
||||||
expect(message.extraData, entity.extraData);
|
expect(message.extraData, entity.extraData);
|
||||||
@@ -197,7 +197,7 @@ void main() {
|
|||||||
entity.mentionedUsers, message.mentionedUsers.map(jsonEncode).toList());
|
entity.mentionedUsers, message.mentionedUsers.map(jsonEncode).toList());
|
||||||
expect(entity.reactionScores, message.reactionScores);
|
expect(entity.reactionScores, message.reactionScores);
|
||||||
expect(entity.reactionCounts, message.reactionCounts);
|
expect(entity.reactionCounts, message.reactionCounts);
|
||||||
expect(entity.status, message.status);
|
expect(entity.state, jsonEncode(message.state));
|
||||||
expect(entity.localUpdatedAt, isSameDateAs(message.localUpdatedAt));
|
expect(entity.localUpdatedAt, isSameDateAs(message.localUpdatedAt));
|
||||||
expect(entity.remoteUpdatedAt, isSameDateAs(message.remoteUpdatedAt));
|
expect(entity.remoteUpdatedAt, isSameDateAs(message.remoteUpdatedAt));
|
||||||
expect(entity.extraData, message.extraData);
|
expect(entity.extraData, message.extraData);
|
||||||
|
|||||||
Reference in New Issue
Block a user