Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(llc): channel.query not initializing state. #1703

Merged
merged 2 commits into from
Aug 11, 2023
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
4 changes: 4 additions & 0 deletions packages/stream_chat/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
## Upcoming

🐞 Fixed

- Fixed `Channel.query` not initializing `ChannelState`.

✅ Added

- Added support for `channel.countUnreadMentions()` to get the count of unread messages mentioning the current user on a
Expand Down
108 changes: 63 additions & 45 deletions packages/stream_chat/lib/src/client/channel.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1339,26 +1339,6 @@ class Channel {
return _client.markChannelRead(id!, type, messageId: messageId);
}

/// Loads the initial channel state and watches for changes.
Future<ChannelState> watch({bool presence = false}) async {
ChannelState response;

try {
response = await query(watch: true, presence: presence);
} catch (error, stackTrace) {
if (!_initializedCompleter.isCompleted) {
_initializedCompleter.completeError(error, stackTrace);
}
rethrow;
}

if (state == null) {
_initState(response);
}

return response;
}

void _initState(ChannelState channelState) {
state = ChannelClientState(this, channelState);

Expand All @@ -1370,6 +1350,22 @@ class Channel {
}
}

/// Loads the initial channel state and watches for changes.
Future<ChannelState> watch({
bool presence = false,
PaginationParams? messagesPagination,
PaginationParams? membersPagination,
PaginationParams? watchersPagination,
}) {
return query(
watch: true,
presence: presence,
messagesPagination: messagesPagination,
membersPagination: membersPagination,
watchersPagination: watchersPagination,
);
}

/// Stop watching the channel.
Future<EmptyResponse> stopWatching() async {
_checkInitialized();
Expand Down Expand Up @@ -1435,7 +1431,7 @@ class Channel {
);

/// Creates a new channel.
Future<ChannelState> create() async => query(state: false);
Future<ChannelState> create() => query(state: false);

/// Query the API, get messages, members or other channel fields.
///
Expand All @@ -1450,23 +1446,28 @@ class Channel {
PaginationParams? watchersPagination,
bool preferOffline = false,
}) async {
if (preferOffline && cid != null) {
final updatedState = await _client.chatPersistenceClient
?.getChannelStateByCid(cid!, messagePagination: messagesPagination);
if (updatedState != null &&
updatedState.messages != null &&
updatedState.messages!.isNotEmpty) {
if (this.state == null) {
_initState(updatedState);
} else {
this.state?.updateChannelState(updatedState);
ChannelState? channelState;

try {
// If we prefer offline, we first try to get the channel state from the
// offline storage.
if (preferOffline && !watch && cid != null) {
final persistenceClient = _client.chatPersistenceClient;
if (persistenceClient != null) {
final cachedState = await persistenceClient.getChannelStateByCid(
cid!,
messagePagination: messagesPagination,
);

// If the cached state contains messages, we can use it.
if (cachedState.messages?.isNotEmpty == true) {
channelState = cachedState;
}
}
return updatedState;
}
}

try {
final updatedState = await _client.queryChannel(
// If we still don't have the channelState, we try to get it from the API.
channelState ??= await _client.queryChannel(
type,
channelId: id,
channelData: _extraData,
Expand All @@ -1479,18 +1480,35 @@ class Channel {
);

if (_id == null) {
_id = updatedState.channel!.id;
_cid = updatedState.channel!.cid;
_id = channelState.channel!.id;
_cid = channelState.channel!.cid;
}

this.state?.updateChannelState(updatedState);
return updatedState;
} catch (e) {
if (_client.persistenceEnabled) {
return _client.chatPersistenceClient!.getChannelStateByCid(
cid!,
messagePagination: messagesPagination,
);
// Initialize the channel state if it's not initialized yet.
if (this.state == null) {
_initState(channelState);
} else {
// Otherwise, update the channel state.
this.state?.updateChannelState(channelState);
}

return channelState;
} catch (e, stk) {
// If we failed to get the channel state from the API and we were not
// supposed to watch the channel, we will try to get the channel state
// from the offline storage.
if (watch == false) {
if (_client.persistenceEnabled) {
return _client.chatPersistenceClient!.getChannelStateByCid(
cid!,
messagePagination: messagesPagination,
);
}
}

// Otherwise, we will just rethrow the error.
if (!_initializedCompleter.isCompleted) {
_initializedCompleter.completeError(e, stk);
}

rethrow;
Expand Down
Loading