search method

Stream<Iterable<SearchResult>> search(
  1. String query, {
  2. SearchFilter searchFilter = SearchFilter.none,
  3. int offset = defaultOffset,
  4. int limit = defaultLimit,
})

Searches for the provided query with the specified searchFilter.

Search results are offset by the specified offset, with each batch containing limit results.

Implementation

Stream<Iterable<SearchResult>> search(
  String query, {
  SearchFilter searchFilter = SearchFilter.none,
  int offset = defaultOffset,
  int limit = defaultLimit
}) async* {
  throwIfNegative(offset, 'offset');
  throwIfNegative(limit, 'limit');

  var continuationOffset = offset;

  final filter = switch (searchFilter) {
    SearchFilter.tracks => '/tracks',
    SearchFilter.playlists => '/playlists',
    SearchFilter.playlistsWithoutAlbums => '/playlists_without_albums',
    SearchFilter.albums => '/albums',
    SearchFilter.users => '/users',
    _ => ''
  };

  final clientId = await _controller.getClientId();

  while (true) {
    final uri = Uri.https(
      'api-v2.soundcloud.com',
      '/search$filter', {
        'q': query,
        'client_id': clientId,
        'limit': '$limit',
        'offset': '$continuationOffset',
      }
    );

    final response = await _http.get(uri);
    response.ensureSuccessStatusCode();
    final json = jsonDecode(response.body);
    final collection = json['collection'] as List;

    if (collection.isEmpty) return;

    yield collection.map((result) {
      final permalinkUri = Uri.parse(result['permalink_url']);

      return switch (permalinkUri.pathSegments.length) {
        1 => UserSearchResult.fromJson(result),
        2 => TrackSearchResult.fromJson(result),
        3 => PlaylistSearchResult.fromJson(result),
        _ => throw SearchResultException.cannotResolve()
      };
    });

    continuationOffset += collection.length;
  }
}