searchEmoji method

Future<List<Emoji>> searchEmoji(
  1. String search,
  2. List<CategoryEmoji> emojiSet, {
  3. bool checkPlatformCompatibility = true,
})

Search for related emoticons based on keywords

Implementation

Future<List<Emoji>> searchEmoji(
  String search,
  List<CategoryEmoji> emojiSet, {
  bool checkPlatformCompatibility = true,
}) async {
  if (search.isEmpty) return [];

  if (_allAvailableEmojiEntities.isEmpty) {
    final emojiPickerInternalUtils = EmojiPickerInternalUtils();

    final data = [...emojiSet]
      ..removeWhere((e) => e.category == Category.RECENT);
    final availableCategoryEmoji = checkPlatformCompatibility
        ? await emojiPickerInternalUtils.filterUnsupported(data)
        : data;

    // Set all the emoji entities
    for (var emojis in availableCategoryEmoji) {
      _allAvailableEmojiEntities.addAll(emojis.emoji);
    }
  }

  // Split the input string into a list of lowercase keywords
  final keywordSet = search
      .split(_whitespaceRegExp)
      .where((e) => e.isNotEmpty)
      .map((e) => e.toLowerCase())
      .toSet();

  if (keywordSet.isEmpty) return [];

  return _allAvailableEmojiEntities.where((emoji) {
    // Perform lowercasing of emoji keywords once
    final emojiKeywordSet = emoji.keywords
        .map((e) => e.toLowerCase())
        .toSet();

    // Check if first keyword is a prefix of any emoji keyword
    final matchFirstKeyword = emojiKeywordSet.any(
      (emojiKeyword) => emojiKeyword.startsWith(keywordSet.first),
    );

    var matchKeywords = false;
    if (matchFirstKeyword) {
      // Check if each search keyword is a prefix of any emoji keyword
      // start from second keyword, returns true if empty (only 1 keyword)
      matchKeywords = keywordSet.skip(1).every((keyword) {
        return emojiKeywordSet.any(
          (emojiKeyword) => emojiKeyword.startsWith(keyword),
        );
      });
    } else {
      matchKeywords = false;
    }

    // Check for an exact match with emoji character
    final matchEmoji = emoji.emoji == search.trim();

    return matchKeywords || matchEmoji;
  }).toList();
}