Skip to content

Commit 1b60706

Browse files
authored
fix(llc): fix [Flutter Web] TypeError JSArray (#2172)
* fix(llc): fix [Flutter Web] TypeError JSArray * chore: update CHANGELOG.md
1 parent 502f892 commit 1b60706

File tree

3 files changed

+73
-38
lines changed

3 files changed

+73
-38
lines changed

packages/stream_chat/CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,10 @@
1+
## Upcoming
2+
3+
🐞 Fixed
4+
5+
- [[#2171]](https://github.com/GetStream/stream-chat-flutter/issues/2171) Fixed [Flutter Web]
6+
dynamic TypeError
7+
18
## 8.3.0
29

310
✅ Added

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

Lines changed: 20 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -2509,35 +2509,35 @@ class ChannelClientState {
25092509

25102510
/// Update channelState with updated information.
25112511
void updateChannelState(ChannelState updatedState) {
2512-
final _existingStateMessages = [...messages];
2512+
final _existingStateMessages = <Message>[...messages];
25132513
final newMessages = <Message>[
2514-
..._existingStateMessages.merge(updatedState.messages),
2514+
..._existingStateMessages.merge(
2515+
updatedState.messages,
2516+
key: (message) => message.id,
2517+
update: (original, updated) => updated.syncWith(original),
2518+
),
25152519
].sorted(_sortByCreatedAt);
25162520

2517-
final _existingStateWatchers = _channelState.watchers ?? [];
2518-
final _updatedStateWatchers = updatedState.watchers ?? [];
2521+
final _existingStateWatchers = <User>[...?_channelState.watchers];
25192522
final newWatchers = <User>[
2520-
..._updatedStateWatchers,
2521-
..._existingStateWatchers
2522-
.where((w) =>
2523-
!_updatedStateWatchers.any((newWatcher) => newWatcher.id == w.id))
2524-
.toList(),
2525-
];
2526-
2527-
final newMembers = <Member>[
2528-
...updatedState.members ?? [],
2523+
..._existingStateWatchers.merge(
2524+
updatedState.watchers,
2525+
key: (watcher) => watcher.id,
2526+
update: (original, updated) => updated,
2527+
),
25292528
];
25302529

2531-
final _existingStateRead = _channelState.read ?? [];
2532-
final _updatedStateRead = updatedState.read ?? [];
2530+
final _existingStateRead = <Read>[...?_channelState.read];
25332531
final newReads = <Read>[
2534-
..._updatedStateRead,
2535-
..._existingStateRead
2536-
.where((r) =>
2537-
!_updatedStateRead.any((newRead) => newRead.user.id == r.user.id))
2538-
.toList(),
2532+
..._existingStateRead.merge(
2533+
updatedState.read,
2534+
key: (read) => read.user.id,
2535+
update: (original, updated) => updated,
2536+
),
25392537
];
25402538

2539+
final newMembers = <Member>[...?updatedState.members];
2540+
25412541
_checkExpiredAttachmentMessages(updatedState);
25422542

25432543
_channelState = _channelState.copyWith(
@@ -2730,21 +2730,3 @@ bool _pinIsValid(Message message) {
27302730
final now = DateTime.now();
27312731
return message.pinExpires!.isAfter(now);
27322732
}
2733-
2734-
extension on Iterable<Message> {
2735-
Iterable<Message> merge(Iterable<Message>? other) {
2736-
if (other == null) return this;
2737-
2738-
final messageMap = {for (final message in this) message.id: message};
2739-
2740-
for (final message in other) {
2741-
messageMap.update(
2742-
message.id,
2743-
message.syncWith,
2744-
ifAbsent: () => message,
2745-
);
2746-
}
2747-
2748-
return messageMap.values;
2749-
}
2750-
}

packages/stream_chat/lib/src/core/util/extension.dart

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,49 @@ extension StringX on String {
3131
}
3232
}
3333
}
34+
35+
/// Extension providing merge functionality for any iterable.
36+
extension IterableMergeExtension<T extends Object?> on Iterable<T> {
37+
/// Merges this iterable with another iterable of the same type.
38+
///
39+
/// This method allows merging two iterables by identifying items with the
40+
/// same key and using an update function to combine them. Items that exist
41+
/// only in one iterable will be included in the result.
42+
///
43+
/// Example:
44+
/// ```dart
45+
/// final list1 = [User(id: '1', name: 'John'), User(id: '2', name: 'Alice')];
46+
/// final list2 = [User(id: '1', age: 30), User(id: '3', name: 'Bob')];
47+
///
48+
/// final merged = list1.merge(
49+
/// list2,
50+
/// key: (user) => user.id,
51+
/// update: (original, updated) => original.copyWith(age: updated.age),
52+
/// );
53+
///
54+
/// // Result: [
55+
/// // User(id: '1', name: 'John', age: 30),
56+
/// // User(id: '2', name: 'Alice'),
57+
/// // User(id: '3', name: 'Bob'),
58+
/// // ]
59+
/// ```
60+
Iterable<T> merge<K>(
61+
Iterable<T>? other, {
62+
required K Function(T item) key,
63+
required T Function(T original, T updated) update,
64+
}) {
65+
if (other == null) return this;
66+
67+
final itemMap = {for (final item in this) key(item): item};
68+
69+
for (final item in other) {
70+
itemMap.update(
71+
key(item),
72+
(original) => update(original, item),
73+
ifAbsent: () => item,
74+
);
75+
}
76+
77+
return itemMap.values;
78+
}
79+
}

0 commit comments

Comments
 (0)