captureScreenshot method

Future<Image> captureScreenshot(
  1. BuildContext context,
  2. GlobalKey<State<StatefulWidget>> key,
  3. String pageName,
  4. String pageTag,
)

Implementation

Future<ui.Image> captureScreenshot(BuildContext context, GlobalKey key,
    String pageName, String pageTag) async {
  print("screenShot started");
  Completer<ui.Image> completer = Completer();

  OverlayEntry? overlayEntry;

  OverlayEntry createOverlayEntry(
    BuildContext context,
    GlobalKey key,
  ) {
    RenderBox renderBox = key.currentContext!.findRenderObject() as RenderBox;
    var size = renderBox.size;
    var offset = renderBox.localToGlobal(Offset.zero);

    return OverlayEntry(
      builder: (context) => Positioned(
        left: offset.dx,
        top: offset.dy + size.height + 5.0,
        child: const Material(
          elevation: 4.0,
          child: Padding(
            padding: EdgeInsets.all(8.0),
            child: Text('Hello, I am a custom tooltip!'),
          ),
        ),
      ),
    );
  }

  void _showCustomTooltip(BuildContext context) {
    if (overlayEntry != null) {
      // Hide tooltip if it's already shown
      overlayEntry!.remove();
      overlayEntry = null;
    } else {
      // Create and show the tooltip

      overlayEntry = createOverlayEntry(context, key);
      Overlay.of(context).insert(overlayEntry!);
    }
  }

  // Schedule the screenshot after the current frame
  WidgetsBinding.instance.addPostFrameCallback((_) async {
    print("screenShot started 2");
    try {
      RenderRepaintBoundary? boundary =
          key.currentContext?.findRenderObject() as RenderRepaintBoundary?;

      if (boundary != null) {
        await Future.delayed(
          const Duration(seconds: 1),
        ); //TODO: think of a better way to do this
        ui.Image image = await boundary.toImage(pixelRatio: 2.0);

        final data = await image.toByteData(
          format: ui.ImageByteFormat.png,
        );

        final x = image.width;
        final y = image.height;
        final bytes = data?.buffer.asUint8List().toList();

        RenderBox renderBox =
            key.currentContext!.findRenderObject() as RenderBox;

        var componentWidth = renderBox.size.width;
        var componentHeight = renderBox.size.height;

        num xFactor = x / componentWidth;
        num yFactor = y / componentHeight;

        List<Map<String, dynamic>> components =
            NudgeWidgetTracker.getAllWidgetDetails(xFactor, yFactor);
        print("test 1");
        await sendDataToBackend(
            x, y, bytes, components, image, pageName, pageTag);

        print("test 2");
        completer.complete(image);
        print("test 3");
      } else {
        completer.completeError(
            Exception('RenderRepaintBoundary is null or needs paint'));
      }
    } catch (e, st) {
      print(e);
      print(st);

      completer.completeError(e);
    }
  });

  return completer.future;
}