Skip to content
Merged
66 changes: 44 additions & 22 deletions packages/stream_chat/lib/src/client/channel.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2608,15 +2608,7 @@
final draft = event.draft;
if (draft == null) return;

if (draft.parentId case final parentId?) {
for (final message in messages) {
if (message.id == parentId) {
return updateMessage(message.copyWith(draft: draft));
}
}
}

updateChannelState(channelState.copyWith(draft: draft));
return updateDraft(draft);
}),
);
}
Expand All @@ -2627,19 +2619,7 @@
final draft = event.draft;
if (draft == null) return;

if (draft.parentId case final parentId?) {
for (final message in messages) {
if (message.id == parentId) {
return updateMessage(
message.copyWith(draft: null),
);
}
}
}

updateChannelState(
channelState.copyWith(draft: null),
);
return deleteDraft(draft);
}),
);
}
Expand Down Expand Up @@ -2781,6 +2761,48 @@
);
}

/// Updates the [draft] in the channel state or the message if it exists.
void updateDraft(Draft draft) {
if (draft.parentId case final parentId?) {
for (final message in messages) {
if (message.id == parentId) {
return updateMessage(message.copyWith(draft: draft));
}
}
}

updateChannelState(
channelState.copyWith(
draft: draft,
),
);
}

/// Deletes the [draft] from the state if it exists.
void deleteDraft(Draft draft) async {
// Delete the draft from the persistence client.
await _channel._client.chatPersistenceClient?.deleteDraftMessageByCid(
draft.channelCid,
parentId: draft.parentId,

Check warning on line 2786 in packages/stream_chat/lib/src/client/channel.dart

View check run for this annotation

Codecov / codecov/patch

packages/stream_chat/lib/src/client/channel.dart#L2785-L2786

Added lines #L2785 - L2786 were not covered by tests
);

if (draft.parentId case final parentId?) {
for (final message in messages) {
if (message.id == parentId) {
return updateMessage(
message.copyWith(draft: null),
);
}
}
}

updateChannelState(
channelState.copyWith(
draft: null,
),
);
}

/// Updates the [message] in the state if it exists. Adds it otherwise.
void updateMessage(Message message) {
// Determine if the message should be displayed in the channel view.
Expand Down
20 changes: 7 additions & 13 deletions packages/stream_chat/lib/src/db/chat_persistence_client.dart
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,9 @@ abstract class ChatPersistenceClient {
PaginationParams? messagePagination,
});

/// Get stored [Draft] message by providing channel [cid].
Future<Draft?> getDraftMessageByCid(String cid);

/// Get stored [Draft] message by providing parent message [id].
Future<Draft?> getDraftMessageByParentId(String parentId);
/// Get stored [Draft] message by providing channel [cid] and a optional
/// [parentId] for thread messages.
Future<Draft?> getDraftMessageByCid(String cid, {String? parentId});

/// Get [ChannelState] data by providing channel [cid]
Future<ChannelState> getChannelStateByCid(
Expand Down Expand Up @@ -166,8 +164,9 @@ abstract class ChatPersistenceClient {
/// Remove a channel by [channelId]
Future<void> deleteChannels(List<String> cids);

/// Removes all the draft messages by draft [messageIds]
Future<void> deleteDraftMessagesByIds(List<String> messageIds);
/// Removes the draft message by matching [DraftMessages.channelCid] and
/// [DraftMessages.parentId].
Future<void> deleteDraftMessageByCid(String cid, {String? parentId});

/// Updates the message data of a particular channel [cid] with
/// the new [messages] data
Expand Down Expand Up @@ -278,6 +277,7 @@ abstract class ChatPersistenceClient {
final channelWithPinnedMessages = <String, List<Message>?>{};
final channelWithReads = <String, List<Read>?>{};
final channelWithMembers = <String, List<Member>?>{};
final drafts = <Draft>[];

final users = <User>[];
final reactions = <Reaction>[];
Expand All @@ -287,9 +287,6 @@ abstract class ChatPersistenceClient {
final pollVotes = <PollVote>[];
final pollVotesToDelete = <String>[];

final drafts = <Draft>[];
final draftsToDelete = <String>[];

for (final state in channelStates) {
final channel = state.channel;
// Continue if channel is not available.
Expand Down Expand Up @@ -339,8 +336,6 @@ abstract class ChatPersistenceClient {
...?pinnedMessages?.map((it) => it.draft),
].nonNulls);

draftsToDelete.addAll(drafts.map((it) => it.message.id));

users.addAll([
channel.createdBy,
...?messages?.map((it) => it.user),
Expand All @@ -361,7 +356,6 @@ abstract class ChatPersistenceClient {
deleteReactionsByMessageId(reactionsToDelete),
deletePinnedMessageReactionsByMessageId(pinnedReactionsToDelete),
deletePollVotesByPollIds(pollVotesToDelete),
deleteDraftMessagesByIds(draftsToDelete),
]);

// Updating first as does not depend on any other table.
Expand Down
24 changes: 11 additions & 13 deletions packages/stream_chat/test/src/db/chat_persistence_client_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ class TestPersistenceClient extends ChatPersistenceClient {
Future<void> deletePollVotesByPollIds(List<String> pollIds) => Future.value();

@override
Future<void> deleteDraftMessagesByIds(List<String> messageIds) =>
Future<void> deleteDraftMessageByCid(String cid, {String? parentId}) =>
Future.value();

@override
Expand Down Expand Up @@ -105,17 +105,14 @@ class TestPersistenceClient extends ChatPersistenceClient {
Future<List<Read>> getReadsByCid(String cid) async => [];

@override
Future<Draft?> getDraftMessageByCid(String cid) async => Draft(
Future<Draft?> getDraftMessageByCid(
String cid, {
String? parentId,
}) async =>
Draft(
channelCid: cid,
createdAt: DateTime.now(),
message: DraftMessage(id: 'message-id', text: 'message-text'),
);

@override
Future<Draft?> getDraftMessageByParentId(String parentId) async => Draft(
channelCid: 'test:cid',
createdAt: DateTime.now(),
parentId: parentId,
createdAt: DateTime.now(),
message: DraftMessage(id: 'message-id', text: 'message-text'),
);

Expand Down Expand Up @@ -218,9 +215,10 @@ void main() {
persistenceClient.updatePolls([poll]);
});

test('deleteDraftMessagesByIds', () {
const messageIds = ['message-id'];
persistenceClient.deleteDraftMessagesByIds(messageIds);
test('deleteDraftMessageByCid', () {
const cid = 'test:cid';
const parentId = 'parent-id';
persistenceClient.deleteDraftMessageByCid(cid, parentId: parentId);
});

test('updateDraftMessages', () async {
Expand Down
7 changes: 7 additions & 0 deletions packages/stream_chat_flutter/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
## Upcoming

✅ Added

- Added support for Draft messages preview.
- Added a new `StreamDraftListView` for displaying draft messages.

## 9.8.0

🐞 Fixed
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import 'package:flutter/material.dart';
import 'package:stream_chat_flutter/stream_chat_flutter.dart';

/// A widget that renders a preview of the draft message text.
class StreamDraftMessagePreviewText extends StatelessWidget {
/// Creates a new instance of [StreamDraftMessagePreviewText].
const StreamDraftMessagePreviewText({
super.key,
required this.draftMessage,
this.textStyle,
});

/// The draft message to display.
final DraftMessage draftMessage;

/// The style to use for the text.
final TextStyle? textStyle;

@override
Widget build(BuildContext context) {
final theme = StreamChatTheme.of(context);
final colorTheme = theme.colorTheme;

final previewTextSpan = TextSpan(
text: '${context.translations.draftLabel}: ',
style: textStyle?.copyWith(
fontWeight: FontWeight.bold,
color: colorTheme.accentPrimary,
),
children: [
TextSpan(text: draftMessage.text, style: textStyle),
],
);

return Text.rich(
maxLines: 1,
previewTextSpan,
overflow: TextOverflow.ellipsis,
textAlign: TextAlign.start,
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,9 @@ abstract class Translations {

/// The text for poll when someone created
String pollSomeoneCreatedText(String username);

/// The label for draft message
String get draftLabel;
}

/// Default implementation of Translation strings for the stream chat widgets
Expand Down Expand Up @@ -1198,4 +1201,7 @@ Attachment limit exceeded: it's not possible to add more than $limit attachments

@override
String pollSomeoneCreatedText(String username) => '$username created';

@override
String get draftLabel => 'Draft';
}
Loading