Skip to content
Merged
13 changes: 13 additions & 0 deletions packages/stream_chat/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
## Upcoming

✅ Added

- Added `reactionGroups` to the `Message` model. This field is a map of reaction types to their
respective counts and scores and additional metadata such as the first and last reaction
timestamps.

🔄 Changed

- Deprecated `message.reactionCounts`, `message.reactionScores` in favor of
`message.reactionGroups`.

## 9.10.0

🐞 Fixed
Expand Down
92 changes: 23 additions & 69 deletions packages/stream_chat/lib/src/client/channel.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// ignore_for_file: avoid_redundant_argument_values

import 'dart:async';
import 'dart:math';
import 'dart:math' as math;

import 'package:collection/collection.dart';
import 'package:rxdart/rxdart.dart';
Expand Down Expand Up @@ -303,7 +303,7 @@
final currentTime = DateTime.timestamp();
final elapsedTime = currentTime.difference(userLastMessageAt).inSeconds;

return max(0, cooldownDuration - elapsedTime);
return math.max(0, cooldownDuration - elapsedTime);

Check warning on line 306 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#L306

Added line #L306 was not covered by tests
}

/// Stores time at which cooldown was started
Expand Down Expand Up @@ -1303,59 +1303,37 @@
bool enforceUnique = false,
}) async {
_checkInitialized();
final messageId = message.id;
final now = DateTime.now();
final user = _client.state.currentUser;

var latestReactions = [...message.latestReactions ?? <Reaction>[]];
if (enforceUnique) {
latestReactions.removeWhere((it) => it.userId == user!.id);
final currentUser = _client.state.currentUser;
if (currentUser == null) {
throw StateError(

Check warning on line 1308 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#L1308

Added line #L1308 was not covered by tests
'Cannot send reaction: current user is not available. '
'Ensure the client is connected and a user is set.',
);
}

final newReaction = Reaction(
messageId: messageId,
createdAt: now,
final messageId = message.id;
final reaction = Reaction(
type: type,
user: user,
messageId: messageId,
user: currentUser,
score: score,
createdAt: DateTime.timestamp(),
extraData: extraData,
);

latestReactions = (latestReactions
// Inserting at the 0th index as it's the latest reaction
..insert(0, newReaction))
.take(10)
.toList();
final ownReactions = enforceUnique
? <Reaction>[newReaction]
: <Reaction>[
...message.ownReactions ?? [],
newReaction,
];

final newMessage = message.copyWith(
reactionCounts: {...message.reactionCounts ?? <String, int>{}}
..update(type, (value) {
if (enforceUnique) return value;
return value + 1;
}, ifAbsent: () => 1), // ignore: prefer-trailing-comma
reactionScores: {...message.reactionScores ?? <String, int>{}}
..update(type, (value) {
if (enforceUnique) return value;
return value + 1;
}, ifAbsent: () => 1), // ignore: prefer-trailing-comma
latestReactions: latestReactions,
ownReactions: ownReactions,
final updatedMessage = message.addMyReaction(
reaction,
enforceUnique: enforceUnique,
);

state?.updateMessage(newMessage);
state?.updateMessage(updatedMessage);

try {
final reactionResp = await _client.sendReaction(
messageId,
type,
score: score,
extraData: extraData,
reaction.type,
score: reaction.score,
extraData: reaction.extraData,
enforceUnique: enforceUnique,
);
return reactionResp;
Expand All @@ -1371,35 +1349,11 @@
Message message,
Reaction reaction,
) async {
final type = reaction.type;

final reactionCounts = {...?message.reactionCounts};
if (reactionCounts.containsKey(type)) {
reactionCounts.update(type, (value) => value - 1);
}
final reactionScores = {...?message.reactionScores};
if (reactionScores.containsKey(type)) {
reactionScores.update(type, (value) => value - 1);
}

final latestReactions = [...?message.latestReactions]..removeWhere((r) =>
r.userId == reaction.userId &&
r.type == reaction.type &&
r.messageId == reaction.messageId);

final ownReactions = [...?message.ownReactions]..removeWhere((r) =>
r.userId == reaction.userId &&
r.type == reaction.type &&
r.messageId == reaction.messageId);

final newMessage = message.copyWith(
reactionCounts: reactionCounts..removeWhere((_, value) => value == 0),
reactionScores: reactionScores..removeWhere((_, value) => value == 0),
latestReactions: latestReactions,
ownReactions: ownReactions,
final updatedMessage = message.deleteMyReaction(
reactionType: reaction.type,
);

state?.updateMessage(newMessage);
state?.updateMessage(updatedMessage);

try {
final deleteResponse = await _client.deleteReaction(
Expand Down
Loading