getArtistAlbums method

Future<List> getArtistAlbums(
  1. String channelId,
  2. String params, {
  3. int? limit = 100,
  4. ArtistOrderType? order,
})

Get the full list of an artist's albums, singles or shows.

  • channelId browseId of the artist as returned by getArtist.
  • params Params obtained by getArtist.
  • limit Number of albums to return. null retrieves them all. (Default: 100).
  • order Order of albums to return. (Default: default order).

Returns List of albums in the format of getLibraryAlbums, except artists key is missing. // TODO getLibraryAlbums is currently missing

Implementation

Future<List> getArtistAlbums(
  String channelId,
  String params, {
  int? limit = 100,
  ArtistOrderType? order,
}) async {
  const endpoint = 'browse';
  final body = <String, dynamic>{'browseId': channelId, 'params': params};
  var response = await sendRequest(endpoint, body);

  Future<JsonMap> requestFunc(String additionalParams) =>
      sendRequest(endpoint, body, additionalParams: additionalParams);

  List parseFunc(List<JsonMap> contents) => parseAlbums(contents);

  JsonMap results;
  if (order != null) {
    // pick the correct continuation from response depending on the order chosen
    final sortOptions =
        nav(response, [
              ...SINGLE_COLUMN_TAB,
              ...SECTION,
              ...HEADER_SIDE,
              'endItems',
              0,
              'musicSortFilterButtonRenderer',
              'menu',
              'musicMultiSelectMenuRenderer',
              'options',
            ])
            as List;
    final continuation =
        sortOptions
                .where(
                  (option) =>
                      (nav(option, [...MULTI_SELECT, ...TITLE_TEXT])
                              as String)
                          .toLowerCase() ==
                      order.value.toLowerCase(),
                )
                .map(
                  (option) => nav(option, [
                    ...MULTI_SELECT,
                    'selectedCommand',
                    'commandExecutorCommand',
                    'commands',
                    -1,
                    'browseSectionListReloadEndpoint',
                  ]),
                )
                .cast<dynamic>()
                .firstWhere((result) => result != null, orElse: () => null)
            as JsonMap?;
    // if a valid order was provided, request continuation and replace original response
    if (continuation != null) {
      final additionalParams = getReloadableContinuationParams({
        'continuations': [continuation['continuation']],
      });
      response = await requestFunc(additionalParams);

      results =
          nav(response, [...SECTION_LIST_CONTINUATION, ...CONTENT])
              as JsonMap;
    } else {
      throw Exception('Invalid order parameter $order');
    }
  } else {
    // just use the results from the first request
    results =
        nav(response, [...SINGLE_COLUMN_TAB, ...SECTION_LIST_ITEM])
            as JsonMap;
  }

  final contents =
      nav(results, GRID_ITEMS, nullIfAbsent: true) ??
      nav(results, CAROUSEL_CONTENTS);
  final albums = parseAlbums(List<JsonMap>.from(contents as List));

  final remainingResults = nav(results, GRID, nullIfAbsent: true) as JsonMap;
  if (remainingResults.containsKey('continuations')) {
    final remainingLimit = limit == null ? null : limit - albums.length;
    albums.addAll(
      await getContinuations(
        remainingResults,
        'gridContinuation',
        remainingLimit,
        requestFunc,
        parseFunc,
      ),
    );
  }

  return albums;
}