Skip to content

Commit 74f46ab

Browse files
committed
Merge remote-tracking branch 'origin/master' into v10.0.0
# Conflicts: # melos.yaml # packages/stream_chat/CHANGELOG.md # packages/stream_chat/example/pubspec.yaml # packages/stream_chat/lib/src/client/channel.dart # packages/stream_chat/lib/src/event_type.dart # packages/stream_chat/lib/version.dart # packages/stream_chat/pubspec.yaml # packages/stream_chat/test/src/client/channel_test.dart # packages/stream_chat_flutter/CHANGELOG.md # packages/stream_chat_flutter/example/pubspec.yaml # packages/stream_chat_flutter/pubspec.yaml # packages/stream_chat_flutter/test/src/poll/goldens/ci/stream_poll_options_dialog_dark.png # packages/stream_chat_flutter/test/src/poll/goldens/ci/stream_poll_options_dialog_light.png # packages/stream_chat_flutter/test/src/poll/goldens/ci/stream_poll_results_dialog_dark.png # packages/stream_chat_flutter/test/src/poll/goldens/ci/stream_poll_results_dialog_light.png # packages/stream_chat_flutter/test/src/poll/goldens/ci/stream_poll_results_dialog_with_show_all_dark.png # packages/stream_chat_flutter/test/src/poll/goldens/ci/stream_poll_results_dialog_with_show_all_light.png # packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/stream_poll_interactor_closed_dark.png # packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/stream_poll_interactor_closed_light.png # packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/stream_poll_interactor_dark.png # packages/stream_chat_flutter/test/src/poll/interactor/goldens/ci/stream_poll_interactor_light.png # packages/stream_chat_flutter/test/src/scroll_view/thread_scroll_view/goldens/ci/stream_thread_list_tile_dark.png # packages/stream_chat_flutter/test/src/scroll_view/thread_scroll_view/goldens/ci/stream_thread_list_tile_light.png # packages/stream_chat_flutter_core/CHANGELOG.md # packages/stream_chat_flutter_core/example/pubspec.yaml # packages/stream_chat_flutter_core/pubspec.yaml # packages/stream_chat_localizations/CHANGELOG.md # packages/stream_chat_localizations/example/pubspec.yaml # packages/stream_chat_localizations/pubspec.yaml # packages/stream_chat_persistence/CHANGELOG.md # packages/stream_chat_persistence/example/pubspec.yaml # packages/stream_chat_persistence/pubspec.yaml # sample_app/pubspec.yaml
2 parents c7c1dd3 + 008bece commit 74f46ab

File tree

50 files changed

+1527
-291
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+1527
-291
lines changed

melos.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ command:
102102
dev_dependencies:
103103
alchemist: ">=0.11.0 <0.13.0"
104104
build_runner: ^2.4.9
105+
connectivity_plus_platform_interface: ^2.0.0
105106
drift_dev: ^2.22.1
106107
fake_async: ^1.3.1
107108
faker_dart: ^0.2.1

packages/stream_chat/CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,12 @@
1+
## 9.17.0
2+
3+
🐞 Fixed
4+
5+
- Fixed `currentUser.pushPreferences` not updating immediately after calling `setPushPreferences`.
6+
- Fixed `Channel.sendMessage` to prevent sending empty messages when all attachments are cancelled
7+
during upload.
8+
- Fixed `toDraftMessage` to only include successfully uploaded attachments in draft messages.
9+
110
## 10.0.0-beta.5
211

312
- Included the changes from version [`9.16.0`](https://pub.dev/packages/stream_chat/changelog).

packages/stream_chat/lib/src/client/channel.dart

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -649,6 +649,15 @@ class Channel {
649649
});
650650
}
651651

652+
bool _isMessageValidForUpload(Message message) {
653+
final hasText = message.text?.trim().isNotEmpty == true;
654+
final hasAttachments = message.attachments.isNotEmpty;
655+
final hasQuotedMessage = message.quotedMessageId != null;
656+
final hasPoll = message.pollId != null;
657+
658+
return hasText || hasAttachments || hasQuotedMessage || hasPoll;
659+
}
660+
652661
final _sendMessageLock = Lock();
653662

654663
/// Send a [message] to this channel.
@@ -707,6 +716,15 @@ class Channel {
707716
message = await attachmentsUploadCompleter.future;
708717
}
709718

719+
// Validate the final message before sending it to the server.
720+
if (_isMessageValidForUpload(message) == false) {
721+
client.logger.warning('Message is not valid for sending, removing it');
722+
723+
// Remove the message from state as it is invalid.
724+
state!.deleteMessage(message, hardDelete: true);
725+
throw const StreamChatError('Message is not valid for sending');
726+
}
727+
710728
// Wait for the previous sendMessage call to finish. Otherwise, the order
711729
// of messages will not be maintained.
712730
final response = await _sendMessageLock.synchronized(
@@ -2262,6 +2280,8 @@ class ChannelClientState {
22622280

22632281
_startCleaningExpiredLocations();
22642282

2283+
_listenChannelPushPreferenceUpdated();
2284+
22652285
_channel._client.chatPersistenceClient
22662286
?.getChannelThreads(_channel.cid!)
22672287
.then((threads) {
@@ -3824,6 +3844,24 @@ class ChannelClientState {
38243844
);
38253845
}
38263846

3847+
// Listens to channel push preference update events and updates the state
3848+
void _listenChannelPushPreferenceUpdated() {
3849+
_subscriptions.add(
3850+
_channel.on(EventType.channelPushPreferenceUpdated).listen(
3851+
(event) {
3852+
final pushPreferences = event.channelPushPreference;
3853+
if (pushPreferences == null) return;
3854+
3855+
updateChannelState(
3856+
channelState.copyWith(
3857+
pushPreferences: pushPreferences,
3858+
),
3859+
);
3860+
},
3861+
),
3862+
);
3863+
}
3864+
38273865
/// Call this method to dispose this object.
38283866
void dispose() {
38293867
_debouncedUpdatePersistenceChannelState.cancel();

packages/stream_chat/lib/src/client/client.dart

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1017,8 +1017,39 @@ class StreamChatClient {
10171017
/// ```
10181018
Future<UpsertPushPreferencesResponse> setPushPreferences(
10191019
List<PushPreferenceInput> preferences,
1020-
) {
1021-
return _chatApi.device.setPushPreferences(preferences);
1020+
) async {
1021+
final res = await _chatApi.device.setPushPreferences(preferences);
1022+
1023+
final currentUser = state.currentUser;
1024+
final currentUserId = currentUser?.id;
1025+
if (currentUserId == null) return res;
1026+
1027+
// Emit events for updated preferences
1028+
final updatedPushPreference = res.userPreferences[currentUserId];
1029+
if (updatedPushPreference != null) {
1030+
final pushPreferenceUpdatedEvent = Event(
1031+
type: EventType.pushPreferenceUpdated,
1032+
pushPreference: updatedPushPreference,
1033+
);
1034+
1035+
handleEvent(pushPreferenceUpdatedEvent);
1036+
}
1037+
1038+
// Emit events for updated channel-specific preferences
1039+
final channelPushPreferences = res.userChannelPreferences[currentUserId];
1040+
if (channelPushPreferences != null) {
1041+
for (final MapEntry(:key, :value) in channelPushPreferences.entries) {
1042+
final pushPreferenceUpdatedEvent = Event(
1043+
type: EventType.channelPushPreferenceUpdated,
1044+
cid: key,
1045+
channelPushPreference: value,
1046+
);
1047+
1048+
handleEvent(pushPreferenceUpdatedEvent);
1049+
}
1050+
}
1051+
1052+
return res;
10221053
}
10231054

10241055
/// Get a development token
@@ -2150,6 +2181,11 @@ class ClientState {
21502181
if (event.unreadThreads case final count?) {
21512182
currentUser = currentUser?.copyWith(unreadThreads: count);
21522183
}
2184+
2185+
// Update the push preferences.
2186+
if (event.pushPreference case final preferences?) {
2187+
currentUser = currentUser?.copyWith(pushPreferences: preferences);
2188+
}
21532189
}),
21542190
);
21552191

packages/stream_chat/lib/src/core/models/draft_message.dart

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,11 +189,16 @@ extension MessageToDraftMessage on Message {
189189
/// This is useful when you want to convert a message to a draft message
190190
/// before sending it to the server.
191191
DraftMessage toDraftMessage() {
192+
// Only include attachments that have been successfully uploaded.
193+
final uploadedAttachments = attachments.where((it) {
194+
return it.uploadState.isSuccess;
195+
}).toList();
196+
192197
return DraftMessage(
193198
id: id,
194199
text: text,
195200
type: type,
196-
attachments: attachments,
201+
attachments: uploadedAttachments,
197202
parentId: parentId,
198203
showInChannel: showInChannel,
199204
mentionedUsers: mentionedUsers,

packages/stream_chat/lib/src/core/models/event.dart

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ class Event {
4141
this.lastReadMessageId,
4242
this.draft,
4343
this.reminder,
44+
this.pushPreference,
45+
this.channelPushPreference,
4446
this.extraData = const {},
4547
this.isLocal = true,
4648
}) : createdAt = createdAt?.toUtc() ?? DateTime.now().toUtc();
@@ -154,6 +156,12 @@ class Event {
154156
/// The message reminder sent with the event.
155157
final MessageReminder? reminder;
156158

159+
/// Push notification preferences for the current user.
160+
final PushPreference? pushPreference;
161+
162+
/// Push notification preferences for the current user for this channel.
163+
final ChannelPushPreference? channelPushPreference;
164+
157165
/// Map of custom channel extraData
158166
final Map<String, Object?> extraData;
159167

@@ -193,6 +201,8 @@ class Event {
193201
'last_read_message_id',
194202
'draft',
195203
'reminder',
204+
'push_preference',
205+
'channel_push_preference',
196206
];
197207

198208
/// Serialize to json
@@ -234,6 +244,8 @@ class Event {
234244
String? lastReadMessageId,
235245
Draft? draft,
236246
MessageReminder? reminder,
247+
PushPreference? pushPreference,
248+
ChannelPushPreference? channelPushPreference,
237249
Map<String, Object?>? extraData,
238250
}) =>
239251
Event(
@@ -269,6 +281,9 @@ class Event {
269281
lastReadMessageId: lastReadMessageId ?? this.lastReadMessageId,
270282
draft: draft ?? this.draft,
271283
reminder: reminder ?? this.reminder,
284+
pushPreference: pushPreference ?? this.pushPreference,
285+
channelPushPreference:
286+
channelPushPreference ?? this.channelPushPreference,
272287
isLocal: isLocal,
273288
extraData: extraData ?? this.extraData,
274289
);

packages/stream_chat/lib/src/core/models/event.g.dart

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/stream_chat/lib/src/event_type.dart

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,4 +182,11 @@ class EventType {
182182

183183
/// Event sent when a live shared location is expired.
184184
static const String locationExpired = 'location.expired';
185+
186+
/// Local event sent when push notification preference is updated.
187+
static const String pushPreferenceUpdated = 'push_preference.updated';
188+
189+
/// Local event sent when channel push notification preference is updated.
190+
static const String channelPushPreferenceUpdated =
191+
'channel.push_preference.updated';
185192
}

0 commit comments

Comments
 (0)