Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions packages/stream_chat/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
## Upcoming

🐞 Fixed

- Fixed cached messages are cleared from channels with unread messages when accessed
offline. [[#2083]](https://github.com/GetStream/stream-chat-flutter/issues/2083)

🔄 Changed

- Deprecated `SortOption.new` constructor in favor of `SortOption.desc` and `SortOption.asc`.
Expand Down
13 changes: 12 additions & 1 deletion packages/stream_chat/lib/src/client/channel.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1776,7 +1776,18 @@ class Channel {
if (this.state == null) {
_initState(channelState);
} else {
// Otherwise, update the channel state.
// Otherwise, we update the existing state with the new channel state.
//
// But, before updating the state, we check if we are querying around a
// message, If we are, we have to truncate the state to avoid potential
// gaps in the message sequence.
final isQueryingAround = switch (messagesPagination) {
PaginationParams(idAround: _?) => true,
PaginationParams(createdAtAround: _?) => true,
_ => false,
};

if (isQueryingAround) this.state?.truncate();
this.state?.updateChannelState(channelState);
}

Expand Down
5 changes: 5 additions & 0 deletions packages/stream_chat/lib/src/core/api/requests.dart
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,11 @@ class PaginationParams extends Equatable {
greaterThanOrEqual,
lessThan,
lessThanOrEqual,
createdAtAfterOrEqual,
createdAtAfter,
createdAtBeforeOrEqual,
createdAtBefore,
createdAtAround,
];
}

Expand Down
115 changes: 115 additions & 0 deletions packages/stream_chat/test/src/client/channel_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2749,6 +2749,121 @@ void main() {
),
).called(1);
});

test('should truncate state when querying around message id', () async {
final initialMessages = [
Message(id: 'msg1', text: 'Hello 1'),
Message(id: 'msg2', text: 'Hello 2'),
Message(id: 'msg3', text: 'Hello 3'),
];

final stateWithMessages = _generateChannelState(
channelId,
channelType,
).copyWith(messages: initialMessages);

channel.state!.updateChannelState(stateWithMessages);
expect(channel.state!.messages, hasLength(3));

final newState = _generateChannelState(
channelId,
channelType,
).copyWith(messages: [
Message(id: 'msg-before-1', text: 'Message before 1'),
Message(id: 'msg-before-2', text: 'Message before 2'),
Message(id: 'target-message-id', text: 'Target message'),
Message(id: 'msg-after-1', text: 'Message after 1'),
Message(id: 'msg-after-2', text: 'Message after 2'),
]);

when(
() => client.queryChannel(
channelType,
channelId: channelId,
channelData: any(named: 'channelData'),
messagesPagination: any(named: 'messagesPagination'),
membersPagination: any(named: 'membersPagination'),
watchersPagination: any(named: 'watchersPagination'),
),
).thenAnswer((_) async => newState);

const pagination = PaginationParams(idAround: 'target-message-id');

final res = await channel.query(messagesPagination: pagination);

expect(res, isNotNull);
expect(channel.state!.messages, hasLength(5));
expect(channel.state!.messages[2].id, 'target-message-id');

verify(
() => client.queryChannel(
channelType,
channelId: channelId,
channelData: any(named: 'channelData'),
messagesPagination: pagination,
membersPagination: any(named: 'membersPagination'),
watchersPagination: any(named: 'watchersPagination'),
),
).called(1);
});

test('should truncate state when querying around created date', () async {
final initialMessages = [
Message(id: 'msg1', text: 'Hello 1'),
Message(id: 'msg2', text: 'Hello 2'),
Message(id: 'msg3', text: 'Hello 3'),
];

final stateWithMessages = _generateChannelState(
channelId,
channelType,
).copyWith(messages: initialMessages);

channel.state!.updateChannelState(stateWithMessages);
expect(channel.state!.messages, hasLength(3));

final targetDate = DateTime.now();
final newState = _generateChannelState(
channelId,
channelType,
).copyWith(messages: [
Message(id: 'msg-before-1', text: 'Message before 1'),
Message(id: 'msg-before-2', text: 'Message before 2'),
Message(id: 'target-message', text: 'Target message'),
Message(id: 'msg-after-1', text: 'Message after 1'),
Message(id: 'msg-after-2', text: 'Message after 2'),
]);

when(
() => client.queryChannel(
channelType,
channelId: channelId,
channelData: any(named: 'channelData'),
messagesPagination: any(named: 'messagesPagination'),
membersPagination: any(named: 'membersPagination'),
watchersPagination: any(named: 'watchersPagination'),
),
).thenAnswer((_) async => newState);

final pagination = PaginationParams(createdAtAround: targetDate);

final res = await channel.query(messagesPagination: pagination);

expect(res, isNotNull);
expect(channel.state!.messages, hasLength(5));
expect(channel.state!.messages[2].id, 'target-message');

verify(
() => client.queryChannel(
channelType,
channelId: channelId,
channelData: any(named: 'channelData'),
messagesPagination: pagination,
membersPagination: any(named: 'membersPagination'),
watchersPagination: any(named: 'watchersPagination'),
),
).called(1);
});
});

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

🐞 Fixed

- Fixed cached messages are cleared from channels with unread messages when accessed
offline. [[#2083]](https://github.com/GetStream/stream-chat-flutter/issues/2083)

## 9.13.0

🐞 Fixed
Expand Down
2 changes: 0 additions & 2 deletions packages/stream_chat_flutter_core/lib/src/stream_channel.dart
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,6 @@ class StreamChannelState extends State<StreamChannel> {
}) async {
if (channel.state == null) return null;
channel.state?.isUpToDate = false;
channel.state?.truncate();

final pagination = PaginationParams(
limit: limit,
Expand Down Expand Up @@ -461,7 +460,6 @@ class StreamChannelState extends State<StreamChannel> {
}) async {
if (channel.state == null) return null;
channel.state?.isUpToDate = false;
channel.state?.truncate();

final pagination = PaginationParams(
limit: limit,
Expand Down