fetchImages method

  1. @override
Future<List<NetworkToFileImage>> fetchImages(
  1. {required AppModel appModel,
  2. required BuildContext context,
  3. String? searchTerm}
)
override

Given a search term, generate a list of images.

Implementation

@override
Future<List<NetworkToFileImage>> fetchImages({
  required AppModel appModel,
  required BuildContext context,
  String? searchTerm,
}) async {
  if (_bingCache[searchTerm!] != null) {
    return _bingCache[searchTerm]!;
  }

  List<NetworkToFileImage> images = [];

  bool webViewBusy = true;

  HeadlessInAppWebView webView = HeadlessInAppWebView(
      initialUrlRequest: URLRequest(
        url: Uri.parse(
          "https://www.bing.com/images/search?q=$searchTerm')",
        ),
      ),
      initialOptions: InAppWebViewGroupOptions(
        android: AndroidInAppWebViewOptions(
          blockNetworkImage: true,
        ),
      ),
      onLoadStop: (controller, uri) async {
        Directory appDirDoc = await getApplicationSupportDirectory();
        String bingImagesPath = '${appDirDoc.path}/bingImages';
        Directory bingImagesDir = Directory(bingImagesPath);
        if (bingImagesDir.existsSync()) {
          if (_bingCache.isEmpty) {
            bingImagesDir.deleteSync(recursive: true);
          }
        }
        bingImagesDir.createSync();

        await Future.delayed(const Duration(milliseconds: 1000), () {});

        dom.Document document = parser.parse(await controller.getHtml());

        List<dom.Element> imgElements =
            document.getElementsByClassName('iusc');

        String timestamp =
            DateFormat('yyyyMMddTkkmmss').format(DateTime.now());
        Directory imageDir = Directory('$bingImagesPath/$timestamp');
        imageDir.createSync();
        for (int i = 0; i < imgElements.length; i++) {
          Map<dynamic, dynamic> imgMap =
              jsonDecode(imgElements[i].attributes['m']!);
          String imageURL = imgMap['turl'];

          String imagePath = '${imageDir.path}/$i';
          File imageFile = File(imagePath);

          /// Instant export requires a file to already be written to the
          /// file system.
          if (i == 0) {
            File networkFile =
                await DefaultCacheManager().getSingleFile(imageURL);
            networkFile.copySync(imagePath);
          }
          NetworkToFileImage image = NetworkToFileImage(
            url: imageURL,
            file: imageFile,
          );

          images.add(image);
        }

        webViewBusy = false;
      });

  await webView.run();

  while (webViewBusy) {
    await Future.delayed(const Duration(milliseconds: 100), () {});
  }

  if (images.isNotEmpty) {
    _bingCache[searchTerm] = images;
  }

  return images;
}