getodk / central-frontend

Vue.js based frontend for ODK Central
https://docs.getodk.org/central-intro/
Apache License 2.0
32 stars 57 forks source link

Add white margin to QR code image #938

Closed ktuite closed 7 months ago

ktuite commented 7 months ago

Added 15 px white border to QR code image and added -15px margin to image to account for it. Also switched this component to the composition API.

Screenshot 2024-02-05 at 11 43 49 AM

What has been done to verify that this works as intended?

Trying it.

Why is this the best possible solution? Were any other approaches considered?

Maybe there are better ways to remove the extra padding.... maybe 15px is too large.

I would LOVE to do some html5 canvas tricks to render some other info into the QR code image, but the bootstrap popover that this QR code is shown in was interacting really poorly with any canvas tags I tried to add.

How does this change affect users? Describe intentional changes to behavior and behavior that could have accidentally been affected by code changes. In other words, what are the regression risks?

Does this change require updates to user documentation? If so, please file an issue here and include the link below.

Before submitting this PR, please make sure you have:

ktuite commented 7 months ago

Here's roughly how I was trying to insert a <canvas> into the template so that I would be able to draw the QR code and anything else into it. (Ignore the styling, I was just trying to be able to see it!)

...

<canvas ref="myCanvas" width="300" height="300" style="border:1px solid blue;"></canvas>

...

const myCanvas = ref(null);

...

onMounted(() => {
  const myContext = myCanvas.value.getContext('2d');

  const code = qrcode(0, props.errorCorrectionLevel);
  const json = JSON.stringify(props.settings);
  code.addData(btoa(pako.deflate(json, { to: 'string' })));
  code.make();
  code.renderTo2dContext(myContext, props.cellSize);
});

This appeared to work when I made a new QR code and it appeared in a modal, but the <canvas> would be totally gone from the DOM when it was in a popover, even though it appeared to be finding it in onMounted()

matthew-white commented 7 months ago

Ah interesting. The popover component is definitely pretty limited right now. The content of the popover is actually rendered twice: once in the Popover element (which is hidden with display: none;), then once in a new element that Bootstrap creates (which I think it inserts as a child of <body>). Bootstrap is only passed HTML, so anything not in the HTML won't appear in the duplicate element that Bootstrap creates. That includes event listeners. Maybe it also includes what you're trying to do with the canvas?

The current approach with Popover has a number of limitations, and I've been waiting for the right moment to improve it. If v2024.2 includes a number of popups, that might be the right time. We'll want to implement popups so that they aren't two different elements: we'll just correctly position the one element. I think what you're trying would work if we did it that way.

matthew-white commented 7 months ago

Related forum post: https://forum.getodk.org/t/odk-central-qr-code-should-include-a-white-border-and-be-on-screen-on-mobile/34599