capture icon indicating copy to clipboard operation
capture copied to clipboard

Any way to know when the screenshot process starts/finishes?

Open daattali opened this issue 1 year ago • 5 comments

Sometimes there's a few seconds delay between pressing the button and when the button becomes disabled. This causes confusion to the end user. I would like to have some sort of signal from {capture} -- whether it's a javascript event that gets triggered or a Shiny input or anything else -- that notifies me when the button is first pressed and when the download begins. That way I could let the user know when they're waiting.

daattali avatar Sep 17 '24 14:09 daattali

I added an argument statusInputId to specify an input ID and retrieve status :

capture(
    selector = "body",
    filename = "all-page",
    icon("camera"), "Input value",
    statusInputId = "loading"
  )

See https://github.com/dreamRs/capture/blob/master/examples/status.R for usage

pvictor avatar Sep 18 '24 12:09 pvictor

Thanks for the quick work, I can verify both loading and statusInputId parameters work.

I do have a few comments, but you can close this issue:

  • When I use the loading parameter to take a screenshot of a leaflet map that has a lot of polygons, I still have the same underlying issue as you can see in this video: https://www.loom.com/share/5e4651ef4091431a8959bb8251841f1d -- the problem is that the UI gets frozen for 5 seconds after pressing the button

  • I didn't test so maybe this already works, but make sure the status id parameter works in shiny modules, when you provide the ID as a namespaced ID

  • The documentation for the loading argument should make it clear that the loading argument takes the result of the loading() function

  • Similarly, the documentation for the loading() function should include an example code so that users can see how to use it. Currenty the only place that has an example usage is the website.

  • The documentation for loading() has a ... argument but it's unclear what you can use that for -- "other arguments" that go where?

  • The documentation for the size argument says "Size (in px)". This makes me think that I should be able to simply specify a number, since the units are assumed to be pixels. However, if I use size = 100 then the javascript breaks. I would make sure that the user is able to provide a number, or maybe clarify if the argument is meant to be a string or an integer, and if it's a string then is the text "px" required?

  • For statusInputId, is the path always started -> error or started -> finished? Or is it possible to get into the error state before getting a started event?

You don't need to answer my questions, it's just things to consider adding to the docs. Nice work :)

daattali avatar Sep 18 '24 16:09 daattali

@daattali Would you want to share code and see if I can help diagnose the issue? I've been using capture() with leaflet in a Shiny app for 2 years and never experienced a UI freeze like that. Are you simplifying those shapes at all? The data transfer may simply be too much for your Shiny server to handle at once if those are unadjusted Census tract shapefiles.

CIOData avatar Sep 20 '24 18:09 CIOData

I am not simplifying the shapes at all, no. I think the issue is more on the browser side than the shiny side, but yes it's almost certainly because the census tract shapefiles are too detailed. I simply don't know enough about spatial to know how to simplify.

daattali avatar Sep 21 '24 03:09 daattali

It's worth a shot to see what happens. I typically use ms_simplify() from the rmapshaper package. When I loaded the shapes for Census tracts in Texas and applied this to them, it reduced the object size by 70%. E.g.

tex = tigris::tracts(state = 'TX')

tex2 = tex |> 
    rmapshaper::ms_simplify(keep = 0.2, keep_shapes = T, drop_null_geometries = F)

object.size(tex2)/object.size(tex)

CIOData avatar Sep 21 '24 07:09 CIOData