Another attempt to fix Mobile Safari not saving photo cards correctly

* Moved photo card right underneath "Save as Photo" button
* Update to latest html-to-image library (1.9.0)
* Added 1px border to photo card
* Hide photo card when camera opened or new file selected
* Rev version to 2.1.5
This commit is contained in:
Ryan Slobojan 2021-10-18 18:25:55 -04:00
parent ddd6e19266
commit 0a91eadb14
5 changed files with 55 additions and 143 deletions

View File

@ -1,9 +1,8 @@
import {saveAs} from 'file-saver'; import {saveAs} from 'file-saver';
import React, {FormEvent, useEffect, useRef, useState, Component} from "react"; import React, {FormEvent, useEffect, useRef, useState} from "react";
import {BrowserQRCodeReader, IScannerControls} from "@zxing/browser"; import {BrowserQRCodeReader, IScannerControls} from "@zxing/browser";
import {Result} from "@zxing/library"; import {Result} from "@zxing/library";
import {useTranslation} from 'next-i18next'; import {useTranslation} from 'next-i18next';
import Link from 'next/link';
import Card from "./Card"; import Card from "./Card";
import Alert from "./Alert"; import Alert from "./Alert";
@ -25,8 +24,7 @@ const options = [
{ label: 'Nova Scotia', value: 'https://novascotia.flow.canimmunize.ca/en/portal'}, { label: 'Nova Scotia', value: 'https://novascotia.flow.canimmunize.ca/en/portal'},
{ label: 'Québec', value: 'https://covid19.quebec.ca/PreuveVaccinale'}, { label: 'Québec', value: 'https://covid19.quebec.ca/PreuveVaccinale'},
{ label: 'Saskatchewan', value: 'https://services.saskatchewan.ca/#/login'}, { label: 'Saskatchewan', value: 'https://services.saskatchewan.ca/#/login'},
{ label: 'Yukon', value: 'https://service.yukon.ca/forms/en/get-covid19-proof-of-vaccination'} { label: 'Yukon', value: 'https://service.yukon.ca/forms/en/get-covid19-proof-of-vaccination'},
] ]
function Form(): JSX.Element { function Form(): JSX.Element {
@ -63,7 +61,6 @@ function Form(): JSX.Element {
// const [warningMessages, _setWarningMessages] = useState<Array<string>>([]); // const [warningMessages, _setWarningMessages] = useState<Array<string>>([]);
const hitcountHost = 'https://stats.vaccine-ontario.ca'; const hitcountHost = 'https://stats.vaccine-ontario.ca';
// Check if there is a translation and replace message accordingly // Check if there is a translation and replace message accordingly
const setAddErrorMessage = (message: string) => { const setAddErrorMessage = (message: string) => {
if (!message) { if (!message) {
@ -83,21 +80,9 @@ function Form(): JSX.Element {
_setFileErrorMessages(Array.from(new Set([...addErrorMessages, translation !== message ? translation : message]))); _setFileErrorMessages(Array.from(new Set([...addErrorMessages, translation !== message ? translation : message])));
}; };
// const setWarningMessage = (message: string) => {
// if (!message) {
// return;
// }
// const translation = t('errors:'.concat(message));
// _setWarningMessages(Array.from(new Set([...warningMessages, translation !== message ? translation : message])));
// }
const deleteAddErrorMessage = (message: string) =>{ const deleteAddErrorMessage = (message: string) =>{
_setAddErrorMessages(addErrorMessages.filter(item => item !== message)) _setAddErrorMessages(addErrorMessages.filter(item => item !== message))
} }
const deleteFileErrorMessage = (message: string) =>{
_setFileErrorMessages(addErrorMessages.filter(item => item !== message))
}
// File Input ref // File Input ref
const inputFile = useRef<HTMLInputElement>(undefined) const inputFile = useRef<HTMLInputElement>(undefined)
@ -172,15 +157,12 @@ function Form(): JSX.Element {
// Clear out any currently-selected files // Clear out any currently-selected files
inputFile.current.value = ''; inputFile.current.value = '';
// Hide our existing pass image
document.getElementById('shc-pass-image').hidden = true;
inputFile.current.click(); inputFile.current.click();
} }
async function gotoOntarioHealth(e) {
e.preventDefault();
// window.open('https://covid19.ontariohealth.ca','_blank'); // this created many extra steps in mobile chrome to return to the grassroots main window... if user has many windows open, they get lost (BACK button on the same window is easier for user to return)
window.location.href = 'https://covid19.ontariohealth.ca';
}
async function goToFAQ(e) { async function goToFAQ(e) {
e.preventDefault(); e.preventDefault();
window.location.href = '/faq'; window.location.href = '/faq';
@ -259,6 +241,9 @@ function Form(): JSX.Element {
) )
); );
// Hide our existing pass image
document.getElementById('shc-pass-image').hidden = true;
setQrCode(undefined); setQrCode(undefined);
setPayloadBody(undefined); setPayloadBody(undefined);
setFile(undefined); setFile(undefined);
@ -407,7 +392,6 @@ function Form(): JSX.Element {
setSaveLoading(false); setSaveLoading(false);
} catch (e) { } catch (e) {
Sentry.captureException(e); Sentry.captureException(e);
setAddErrorMessage(e.message); setAddErrorMessage(e.message);
@ -442,7 +426,6 @@ function Form(): JSX.Element {
if (isMacOs) { if (isMacOs) {
setAddErrorMessage('Reminder: iOS 15+ is needed for the Apple Wallet functionality to work with Smart Health Card') setAddErrorMessage('Reminder: iOS 15+ is needed for the Apple Wallet functionality to work with Smart Health Card')
return; return;
} }
if (isIOS && !isSafari) { if (isIOS && !isSafari) {
@ -450,7 +433,6 @@ function Form(): JSX.Element {
setAddErrorMessage('Sorry, only Safari can be used to add a Wallet Pass on iOS'); setAddErrorMessage('Sorry, only Safari can be used to add a Wallet Pass on iOS');
setIsDisabledAppleWallet(true); setIsDisabledAppleWallet(true);
return; return;
} }
// } else if (!isIOS) { // } else if (!isIOS) {
// setWarningMessage('Only Safari on iOS is officially supported for Wallet import at the moment - ' + // setWarningMessage('Only Safari on iOS is officially supported for Wallet import at the moment - ' +
@ -463,10 +445,6 @@ function Form(): JSX.Element {
window.location.href = option.value; window.location.href = option.value;
} }
function promptTextCreator(value) {
return 'Select province...';
}
return ( return (
<div> <div>
<form className="space-y-5" id="form" onSubmit={addToWallet}> <form className="space-y-5" id="form" onSubmit={addToWallet}>
@ -598,9 +576,48 @@ function Form(): JSX.Element {
{addErrorMessages.map((message, i) => {addErrorMessages.map((message, i) =>
<Alert message={message} key={'error-' + i} type="error" /> <Alert message={message} key={'error-' + i} type="error" />
)} )}
{/* {warningMessages.map((message, i) => <br/>
<Alert message={message} key={'warning-' + i} type="warning" /> <div id="shc-pass-image" style={{backgroundColor: "white", color: "black", fontFamily: 'Arial', fontSize: 10, width: '350px', padding: '10px', border: '1px solid', margin: '0px'}} hidden>
)} */} <table style={{verticalAlign: "middle"}}>
<tbody>
<tr>
<td><img src='shield-black.svg' width='50' height='50' /></td>
<td style={{fontSize: 20, width: 280}}>
<span style={{marginLeft: '11px', whiteSpace: 'nowrap'}}><b>COVID-19 Vaccination Card</b></span><br/>
<span style={{marginLeft: '11px'}}><b id='shc-card-origin'></b></span>
</td>
</tr>
</tbody>
</table>
<br/>
<br/>
<div style={{fontSize:14, textAlign: 'center'}}>
<span id='shc-card-name' ></span>&nbsp;&nbsp;&nbsp;&nbsp;(<span id='shc-card-dob'></span>)
</div>
<br/>
<br/>
<table style={{textAlign: "center", width: "100%"}}>
<tbody>
<tr>
<td id='shc-card-vaccine-name-1'></td>&nbsp;&nbsp;<td id='shc-card-vaccine-name-2'></td>
</tr>
<tr>
<td id='shc-card-vaccine-date-1'></td>&nbsp;&nbsp;<td id='shc-card-vaccine-date-2'></td>
</tr>
<tr id='extraRow1' hidden>
<td id='shc-card-vaccine-name-3'></td>&nbsp;&nbsp;<td id='shc-card-vaccine-name-4'></td>
</tr>
<tr id='extraRow2' hidden>
<td id='shc-card-vaccine-date-3'></td>&nbsp;&nbsp;<td id='shc-card-vaccine-date-4'></td>
</tr>
</tbody>
</table>
<div id='shc-card-vaccine' style={{width:'63%', display:'block', marginLeft: 'auto', marginRight: 'auto'}}></div>
<div id='shc-qrcode' style={{width:'63%', display:'block', marginLeft: 'auto', marginRight: 'auto'}}></div>
<br/>
</div>
</div> </div>
}/> }/>
@ -627,7 +644,6 @@ function Form(): JSX.Element {
</div> </div>
}/> }/>
</form> </form>
<canvas id="canvas" style={{ display: "none" }} />
</div> </div>
) )
} }

View File

@ -34,114 +34,13 @@ function Page(props: PageProps): JSX.Element {
<a href="https://github.com/billylo1/covidpass" className="underline">{t('common:gitHub')}</a> <a href="https://github.com/billylo1/covidpass" className="underline">{t('common:gitHub')}</a>
<a href="https://vaccine-ontario.ca" className="underline">{t('common:returnToMainSite')}</a> <a href="https://vaccine-ontario.ca" className="underline">{t('common:returnToMainSite')}</a>
</nav> </nav>
<div className="flex pt-4 flex-row space-x-4 justify-center text-md flex-wrap">Last updated: 2021-10-18 (v2.1.4)</div> <div className="flex pt-4 flex-row space-x-4 justify-center text-md flex-wrap">Last updated: 2021-10-18 (v2.1.5)</div>
</footer> </footer>
</main> </main>
</div> </div>
<br/> <br/>
<br/> <br/>
<br/> <br/>
<div id="pass-image" style={{backgroundColor: "orangered", color: "white", fontFamily: 'Arial', fontSize: 10, width: '350px', padding: '10px'}} hidden>
<table style={{verticalAlign: "middle"}}>
<tbody>
<tr>
<td><img src='shield4.svg' width='50' height='50' /></td>
<td style={{fontSize: 20, width: 280}}><span style={{marginLeft: '11px'}}><b>Vaccination Receipt</b></span></td>
</tr>
</tbody>
</table>
<br/>
<br/>
<div style={{height:12}}><b>VACCINE</b></div>
<div id='vaccineName' style={{fontSize:28}}></div>
<br/>
<br/>
<table style={{fontSize:12, border: 0 }}>
<tbody>
<tr>
<td style={{width: 220}}><b>AUTHORIZED ORGANIZATION</b></td>
<td><b>VACC. DATE</b></td>
</tr>
<tr>
<td id='organization' style={{width: 220}}></td>
<td id='vaccinationDate' style={{width:120}}></td>
</tr>
<tr id='extraRow2' hidden>
<td id='organization2' style={{width: 220}}></td>
<td id='vaccinationDate2' style={{width:120}}></td>
</tr>
<tr id='extraRow1' hidden>
<td id='organization1' style={{width: 220}}></td>
<td id='vaccinationDate1' style={{width:120}}></td>
</tr>
<tr style={{height: 20}}></tr>
<tr>
<td><b>NAME</b></td>
<td><b>DATE OF BIRTH</b></td>
</tr>
<tr>
<td id='name' style={{fontSize: 12}}></td>
<td id='dob' style={{fontSize: 12}}></td>
</tr>
<tr style={{height: 20}}></tr>
<tr>
<td><b></b></td>
<td><b>QR CODE EXPIRY</b></td>
</tr>
<tr>
<td id='null' style={{fontSize: 12}}></td>
<td id='expiry' style={{fontSize: 12}}>2021-10-22</td>
</tr>
</tbody>
</table>
<br/>
<br/>
<div id='qrcode' style={{width:'63%', display:'block', marginLeft: 'auto', marginRight: 'auto'}}></div>
<br/>
<br/>
</div>
<div id="shc-pass-image" style={{backgroundColor: "white", color: "black", fontFamily: 'Arial', fontSize: 10, width: '350px', padding: '10px'}} hidden>
<table style={{verticalAlign: "middle"}}>
<tbody>
<tr>
<td><img src='shield-black.svg' width='50' height='50' /></td>
<td style={{fontSize: 20, width: 280}}>
<span style={{marginLeft: '11px', whiteSpace: 'nowrap'}}><b>COVID-19 Vaccination Card</b></span><br/>
<span style={{marginLeft: '11px'}}><b id='shc-card-origin'></b></span>
</td>
</tr>
</tbody>
</table>
<br/>
<br/>
<div style={{fontSize:14, textAlign: 'center'}}>
<span id='shc-card-name' ></span>&nbsp;&nbsp;&nbsp;&nbsp;(<span id='shc-card-dob'></span>)
</div>
<br/>
<br/>
<table style={{textAlign: "center", width: "100%"}}>
<tbody>
<tr>
<td id='shc-card-vaccine-name-1'></td>&nbsp;&nbsp;<td id='shc-card-vaccine-name-2'></td>
</tr>
<tr>
<td id='shc-card-vaccine-date-1'></td>&nbsp;&nbsp;<td id='shc-card-vaccine-date-2'></td>
</tr>
<tr id='extraRow1' hidden>
<td id='shc-card-vaccine-name-3'></td>&nbsp;&nbsp;<td id='shc-card-vaccine-name-4'></td>
</tr>
<tr id='extraRow2' hidden>
<td id='shc-card-vaccine-date-3'></td>&nbsp;&nbsp;<td id='shc-card-vaccine-date-4'></td>
</tr>
</tbody>
</table>
<div id='shc-card-vaccine' style={{width:'63%', display:'block', marginLeft: 'auto', marginRight: 'auto'}}></div>
<div id='shc-qrcode' style={{width:'63%', display:'block', marginLeft: 'auto', marginRight: 'auto'}}></div>
<br/>
<br/>
</div>
<canvas id="canvas" style={{display: 'none'}}/> <canvas id="canvas" style={{display: 'none'}}/>
</div> </div>
) )

View File

@ -1,6 +1,6 @@
{ {
"name": "grassroots_covidpass", "name": "grassroots_covidpass",
"version": "2.1.4", "version": "2.1.5",
"author": "Billy Lo <billy@vaccine-ontario.ca>", "author": "Billy Lo <billy@vaccine-ontario.ca>",
"license": "MIT", "license": "MIT",
"private": false, "private": false,
@ -33,7 +33,7 @@
"file-saver": "^2.0.5", "file-saver": "^2.0.5",
"fs-extra": "^10.0.0", "fs-extra": "^10.0.0",
"fs.promises": "^0.1.2", "fs.promises": "^0.1.2",
"html-to-image": "^1.7.0", "html-to-image": "^1.9.0",
"html2canvas": "^1.3.2", "html2canvas": "^1.3.2",
"jpeg-js": "^0.4.3", "jpeg-js": "^0.4.3",
"jsqr": "^1.4.0", "jsqr": "^1.4.0",

View File

@ -219,7 +219,4 @@ function processSHCReceipt(receipt: SHCReceipt, generic: PassDictionary) {
) )
} }
} }

View File

@ -3,7 +3,7 @@ import { Integrations } from '@sentry/tracing';
export const initSentry = () => { export const initSentry = () => {
SentryModule.init({ SentryModule.init({
release: 'grassroots_covidpass@2.1.4', // App version. Needs to be manually updated as we go unless we make the build smarter release: 'grassroots_covidpass@2.1.5', // App version. Needs to be manually updated as we go unless we make the build smarter
dsn: 'https://7120dcf8548c4c5cb148cdde2ed6a778@o1015766.ingest.sentry.io/5981424', dsn: 'https://7120dcf8548c4c5cb148cdde2ed6a778@o1015766.ingest.sentry.io/5981424',
integrations: [ integrations: [
new Integrations.BrowserTracing(), new Integrations.BrowserTracing(),