getForvoResults method

Future<List<ForvoResult>> getForvoResults(
  1. {required AppModel appModel,
  2. required String searchTerm}
)

Return a list of pronunciations from a search term.

Implementation

Future<List<ForvoResult>> getForvoResults(
    {required AppModel appModel, required String searchTerm}) async {
  Codec<String, String> stringToBase64Url = utf8.fuse(base64Url);
  Language language = appModel.targetLanguage;
  String cacheKey = '${language.languageCode}/$searchTerm';

  List<ForvoResult> results = [];
  if (_forvoCache[cacheKey] != null) {
    results = _forvoCache[cacheKey]!;
  } else {
    http.Response response =
        await _client.get(Uri.parse('https://forvo.com/word/$searchTerm/'));
    var document = parser.parse(response.body);

    try {
      String className = '';

      // Language Customizable
      if (appModel.targetLanguage is JapaneseLanguage) {
        className = 'pronunciations-list-ja';
      } else if (appModel.targetLanguage is EnglishLanguage) {
        className = 'pronunciations-list-en_usa';
      }

      List<dom.Element> liElements = document
          .getElementsByClassName(className)
          .first
          .children
          .where((element) =>
              element.localName == 'li' &&
              element.children.first.id.startsWith('play_'))
          .toList();

      results = liElements.map((element) {
        String onClick = element.children[0].attributes['onclick']!;
        String? contributor = element.children[1].attributes['data-p2'];

        if (contributor == null) {
          element.children
              .where((child) =>
                  child.className == 'more' || child.className == 'from')
              .toList()
              .forEach((child) => child.remove());

          contributor = element.text
              .replaceAll(
                  RegExp(r'[\s\S]*?(?=Pronunciation by)Pronunciation by'), '')
              .trim();
        }

        String onClickCut = onClick.substring(onClick.indexOf(',') + 2);
        String base64 = onClickCut.substring(0, onClickCut.indexOf("'"));

        String fileUrl = stringToBase64Url.decode(base64);

        String audioUrl = 'https://audio.forvo.com/mp3/$fileUrl';

        return ForvoResult(
          audioUrl: audioUrl,
          contributor: contributor,
        );
      }).toList();

      _forvoCache[cacheKey] = results;
    } catch (error) {
      debugPrint('$error');
    }
  }

  return results;
}