searchVideos method Null safety

  1. @override
Future<VideoFullList> searchVideos(
  1. {SearchSort searchSort = SearchSort.newest,
  2. List<Language>? languages,
  3. List<SearchTarget>? searchTargets,
  4. List<String>? conditions,
  5. List<String>? topics,
  6. List<String>? vch,
  7. List<Organization>? organizations,
  8. bool paginated = true,
  9. int offset = 0,
  10. int limit = 25}
)

Flexible endpoint to search for videos fufilling multiple conditions.

Descriptions with "any" implies an OR condition, and "all" implies a AND condition.

Searching for topics and clips is not supported, because clips do not contain topics

Arguments

  • searchSort Sort by newest or oldest
  • languages If set, will filter clips to only show clips with these languages + all vtuber streams (provided searchTargets is not set to filter out streams)
  • searchTargets Target types of videos
  • conditions Match all of the items. > For each item: Text to look for text in video title or description
  • topics Return videos that match one of the provided topics
  • vch Videos with all of the specified channel ids. If two or more channel IDs are specified, will only return their collabs, or if one channel is a clipper, it will only show clips of the other vtubers made by this clipper.
  • organizations Videos of channels in any of the specified organizations, or clips that involve a channel in the specified organization.
  • paginated If paginated is set to true, returns VideoFullList with total, otherwise returns VideoFullList without the total.
  • offset Offset results
  • limit Result limit

Implementation

@override
Future<VideoFullList> searchVideos({
  SearchSort searchSort = SearchSort.newest,
  List<Language>? languages,
  List<SearchTarget>? searchTargets,
  List<String>? conditions,
  List<String>? topics,
  List<String>? vch,
  List<Organization>? organizations,
  bool paginated = true,
  int offset = 0,
  int limit = 25,
}) async {
  final Map<String, dynamic> data = {};

  data.addAll({
    'sort': EnumUtil.convertSearchSortToString(searchSort),
    'paginated': paginated,
    'offset': offset,
    'limit': limit,
    // 'comment': [],
  });

  if (languages != null && languages.isNotEmpty) {
    data.addAll({
      'lang': languages.map((l) => EnumUtil.convertLanguageToString(l)).toList(),
    });
  }

  if (searchTargets != null && searchTargets.isNotEmpty) {
    data.addAll({
      'target': searchTargets.map((s) => EnumUtil.convertSearchTargetToString(s)).toList(),
    });
  }

  if (conditions != null && conditions.isNotEmpty) {
    data.addAll({
      'conditions': conditions,
    });
  }

  if (topics != null && topics.isNotEmpty) {
    data.addAll({
      'topic': topics,
    });
  }

  if (vch != null && vch.isNotEmpty) {
    data.addAll({
      'vch': vch,
    });
  }

  final response = await post(path: _Constants.videoSearch, data: data);

  if (paginated) {
    // Grab total and return with it
    final videoList = VideoFullList.fromJson(response.body);
    return videoList.copyWith(paginated: true);
  }

  final List list = jsonDecode(response.body);
  return VideoFullList(videos: list.map((video) => VideoFull.fromMap(video)).toList());
}