queryChannels method

Stream<List<Channel>> queryChannels (
  1. {Map<String, dynamic> filter,
  2. List<SortOption> sort,
  3. Map<String, dynamic> options,
  4. PaginationParams paginationParams,
  5. int messageLimit,
  6. bool onlyOffline: false}
)

Requests channels with a given query.

Implementation

Stream<List<Channel>> queryChannels({
  Map<String, dynamic> filter,
  List<SortOption> sort,
  Map<String, dynamic> options,
  PaginationParams paginationParams,
  int messageLimit,
  bool onlyOffline = false,
}) async* {
  logger.info('Query channel start');
  final defaultOptions = {
    'state': true,
    'watch': true,
    'presence': false,
  };

  var payload = <String, dynamic>{
    'filter_conditions': filter,
    'sort': sort,
    'user_details': state.user,
  };

  if (messageLimit != null) {
    payload['message_limit'] = messageLimit;
  }

  payload.addAll(defaultOptions);

  if (options != null) {
    payload.addAll(options);
  }

  if (paginationParams != null) {
    payload.addAll(paginationParams.toJson());
  }

  final offlineChannels = await _offlineStorage?.getChannelStates(
        filter: filter,
        sort: sort,
        paginationParams: paginationParams,
      ) ??
      [];
  var newChannels = Map<String, Channel>.from(state.channels ?? {});
  logger.info('Got ${offlineChannels.length} channels from storage');
  var channels = offlineChannels.map((channelState) {
    final channel = newChannels[channelState.channel.cid];
    if (channel != null) {
      channel.state?.updateChannelState(channelState);
      return channel;
    } else {
      final newChannel = Channel.fromState(this, channelState);
      _offlineStorage?.updateChannelState(newChannel.state.channelState);
      newChannels[newChannel.cid] = newChannel;
      return newChannel;
    }
  }).toList();

  if (channels.isNotEmpty) {
    yield channels;

    state.channels = newChannels;
  }

  if (onlyOffline) {
    return;
  }

  final response = await get(
    '/channels',
    queryParameters: {
      'payload': jsonEncode(payload),
    },
  );

  final res = decode<QueryChannelsResponse>(
    response.data,
    QueryChannelsResponse.fromJson,
  );

  final users = res.channels
      ?.expand((channel) => channel.members.map((member) => member.user))
      ?.toList();

  if (users != null) {
    state._updateUsers(users);
  }

  logger.info('Got ${res.channels?.length} channels from api');

  newChannels = Map<String, Channel>.from(state.channels ?? {});
  channels.clear();

  if (res.channels != null) {
    for (final channelState in res.channels) {
      final channel = newChannels[channelState.channel.cid];
      if (channel != null) {
        channel.state?.updateChannelState(channelState);
        channels.add(channel);
      } else {
        final newChannel = Channel.fromState(this, channelState);
        await _offlineStorage
            ?.updateChannelState(newChannel.state.channelState);
        newChannel.state?.updateChannelState(channelState);
        newChannels[newChannel.cid] = newChannel;
        channels.add(newChannel);
      }
    }
  }

  yield channels;

  state.channels = newChannels;

  await _offlineStorage?.updateChannelQueries(
    filter,
    res.channels.map((c) => c.channel.cid).toList(),
    paginationParams?.offset == null || paginationParams.offset == 0,
  );
}