parent
865d3a7442
commit
00bab2a5bf
|
@ -69,10 +69,13 @@ function Form(): JSX.Element {
|
|||
// Currently selected QR Code / File. Only one of them is set.
|
||||
const [qrCode, setQrCode] = useState<Result>(undefined);
|
||||
const [file, setFile] = useState<File>(undefined);
|
||||
const [file2, setFile2] = useState<File>(undefined);
|
||||
|
||||
const [payloadBody, setPayloadBody] = useState<PayloadBody>(undefined);
|
||||
|
||||
const [saveLoading, setSaveLoading] = useState<boolean>(false);
|
||||
const [fileLoading, setFileLoading] = useState<boolean>(false);
|
||||
const [file2Loading, setFile2Loading] = useState<boolean>(false);
|
||||
|
||||
const [generated, setGenerated] = useState<boolean>(false); // this flag represents the file has been used to generate a pass
|
||||
|
||||
|
@ -112,8 +115,14 @@ function Form(): JSX.Element {
|
|||
// File Input ref
|
||||
const inputFile = useRef<HTMLInputElement>(undefined)
|
||||
|
||||
const inputFile2 = useRef<HTMLInputElement>(undefined)
|
||||
|
||||
|
||||
// Add event listener to listen for file change events
|
||||
useEffect(() => {
|
||||
|
||||
let payloadBody;
|
||||
|
||||
if (inputFile && inputFile.current) {
|
||||
inputFile.current.addEventListener('change', async () => {
|
||||
let selectedFile = inputFile.current.files[0];
|
||||
|
@ -127,19 +136,28 @@ function Form(): JSX.Element {
|
|||
deleteAddErrorMessage(t('errors:'.concat('noFileOrQrCode')));
|
||||
_setFileErrorMessages([]);
|
||||
checkBrowserType();
|
||||
const payloadBody = await getPayload(selectedFile);
|
||||
|
||||
//TODO: feature flagging
|
||||
|
||||
await createDataUrlForDisplay(selectedFile);
|
||||
payloadBody = await getPayload(selectedFile);
|
||||
await storeFileToLocalStorageBase64('receipt', selectedFile);
|
||||
await renderPhoto(payloadBody);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (inputFile2 && inputFile2.current) {
|
||||
inputFile2.current.addEventListener('change', async () => {
|
||||
let selectedFile2 = inputFile2.current.files[0];
|
||||
if (selectedFile2) {
|
||||
setFile2Loading(true);
|
||||
setFile2(selectedFile2);
|
||||
await storeFileToLocalStorageBase64('extra', selectedFile2);
|
||||
payloadBody.extraUrl = 'extra';
|
||||
setFile2Loading(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
checkBrowserType();
|
||||
}, [inputFile])
|
||||
}, [inputFile, inputFile2])
|
||||
|
||||
async function createDataUrlForDisplay(file: File) {
|
||||
async function storeFileToLocalStorageBase64(key: string, file: File) {
|
||||
|
||||
if (window.localStorage) {
|
||||
|
||||
|
@ -147,36 +165,21 @@ function Form(): JSX.Element {
|
|||
|
||||
const buffer = Buffer.from(await new Response(file).arrayBuffer());
|
||||
let dataUrl = `data:${file.type};base64,${buffer.toString("base64")}`;
|
||||
localStorage.setItem('pdfDataUrl', dataUrl);
|
||||
localStorage.setItem(key, dataUrl);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
async function showPDF() {
|
||||
let dataUrl = localStorage.getItem('pdfDataUrl');
|
||||
// console.log(dataUrl)
|
||||
let script = `function debugBase64(base64URL){
|
||||
var win = window.open();
|
||||
win.document.write('<iframe src="' + base64URL + '" frameborder="0" style="border:0; top:0px; left:0px; bottom:0px; right:0px; width:100%; height:100%;" allowfullscreen></iframe>');
|
||||
}
|
||||
debugBase64('${dataUrl}');
|
||||
`;
|
||||
|
||||
let hrefValue = `javascript:${script};`
|
||||
document.getElementById('mylink').setAttribute('href', hrefValue);
|
||||
|
||||
}
|
||||
|
||||
async function getPayload(file) : Promise<PayloadBody> {
|
||||
try {
|
||||
const payload = await getPayloadBodyFromFile(file);
|
||||
|
||||
//TODO: feature flagging
|
||||
|
||||
// const buffer = Buffer.from(await new Response(file).arrayBuffer());
|
||||
// let dataUrl = `data:${file.type};base64,${buffer.toString("base64")}`;
|
||||
payload.dataUrl = "receipt";
|
||||
console.log(file2);
|
||||
|
||||
// payload.dataUrl = dataUrl;
|
||||
if (file2) {
|
||||
payload.extraUrl = file2.name;
|
||||
}
|
||||
|
||||
setPayloadBody(payload);
|
||||
setFileLoading(false);
|
||||
|
@ -229,6 +232,11 @@ function Form(): JSX.Element {
|
|||
inputFile.current.click();
|
||||
}
|
||||
|
||||
async function showFile2Dialog() {
|
||||
inputFile2.current.click();
|
||||
|
||||
}
|
||||
|
||||
async function goToFAQ(e : any) {
|
||||
e.preventDefault();
|
||||
window.location.href = '/faq';
|
||||
|
@ -487,7 +495,7 @@ function Form(): JSX.Element {
|
|||
// setAddErrorMessage('Sorry. Apple Wallet pass can be added using Safari or Chrome only.');
|
||||
// setIsDisabledAppleWallet(true);
|
||||
// }
|
||||
|
||||
|
||||
const uaIsiOS15 = getUA.includes('15_');
|
||||
if (isIOS && ((!osVersion.startsWith('15')) && !uaIsiOS15)) {
|
||||
const message = `Not iOS15 error: osVersion=${osVersion} UA=${getUA}`;
|
||||
|
@ -592,6 +600,52 @@ function Form(): JSX.Element {
|
|||
</div>
|
||||
}/>
|
||||
|
||||
<Card step="3" heading='(Optional) Link a picture to your wallet pass for fast access' content={
|
||||
<div className="space-y-5">
|
||||
<p>The picture will be saved in your browser (in local storage, private). You can view it as extra info on your Wallet Pass' details pane.</p>
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-5 items-center justify-start">
|
||||
<button
|
||||
type="button"
|
||||
onClick={showFile2Dialog}
|
||||
className="h-20 bg-green-600 hover:bg-gray-700 text-white font-semibold rounded-md">
|
||||
{t('index:openFile')}
|
||||
</button>
|
||||
<div id="spin2" className={fileLoading ? undefined : "hidden"}>
|
||||
<svg className="animate-spin h-5 w-5 ml-4" viewBox="0 0 24 24">
|
||||
<circle className="opacity-0" cx="12" cy="12" r="10" stroke="currentColor"
|
||||
strokeWidth="4"/>
|
||||
<path className="opacity-75" fill="currentColor"
|
||||
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<input type='file'
|
||||
id='file2'
|
||||
accept="application/pdf,.png,.jpg,.jpeg,.gif,.webp"
|
||||
ref={inputFile2}
|
||||
style={{display: 'none'}}
|
||||
/>
|
||||
|
||||
{(file2) &&
|
||||
<div className="flex items-center space-x-1">
|
||||
<svg className="h-4 w-4 text-green-600" fill="none" viewBox="0 0 24 24"
|
||||
stroke="currentColor">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M9 5l7 7-7 7"/>
|
||||
</svg>
|
||||
<span className="w-full truncate">
|
||||
{
|
||||
file2 && file2.name
|
||||
}
|
||||
</span>
|
||||
</div>
|
||||
}
|
||||
{fileErrorMessages.map((message, i) =>
|
||||
<Alert message={message} key={'error-' + i} type="error" />
|
||||
)}
|
||||
</div>
|
||||
}/>
|
||||
|
||||
{showDoseOption && <Card step="3" heading={'Choose dose number'} content={
|
||||
<div className="space-y-5">
|
||||
<p>
|
||||
|
@ -615,7 +669,7 @@ function Form(): JSX.Element {
|
|||
</div>
|
||||
} />}
|
||||
|
||||
<Card step={showDoseOption ? '4' : '3'} heading={t('index:addToWalletHeader')} content={
|
||||
<Card step={showDoseOption ? '5' : '4'} heading={t('index:addToWalletHeader')} content={
|
||||
<div className="space-y-5">
|
||||
<div>
|
||||
<ul className="list-none">
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
<script>
|
||||
function loadItem() {
|
||||
|
||||
if (navigator.userAgent.indexOf('Safari') < 0) {
|
||||
document.getElementById('msg').textContent = 'Sorry. For fastlink to work, your iPhone needs to be using Safari as default browser. To change it, you can go to Settings - Chrome/Firefox';
|
||||
return;
|
||||
}
|
||||
|
||||
const itemKey = location.href.split('=')[1];
|
||||
console.log(itemKey);
|
||||
let dataUrl = localStorage.getItem(itemKey);
|
||||
if (dataUrl) {
|
||||
const imageElement = document.getElementById('image');
|
||||
imageElement.setAttribute('src', dataUrl);
|
||||
document.getElementById('clearButton').hidden = false;
|
||||
} else {
|
||||
document.getElementById('msg').innerHTML = `Sorry, ${itemKey} not found in local storage.<p />Creating your wallet pass again would likely fix this issue.`;
|
||||
}
|
||||
}
|
||||
|
||||
function clearLocalStorage() {
|
||||
localStorage.clear();
|
||||
document.getElementById('msg').innerHTML = 'Local storage cleared.';
|
||||
document.getElementById('clearButton').hidden = true;
|
||||
}
|
||||
|
||||
</script>
|
||||
<style>
|
||||
|
||||
body {
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
.center {
|
||||
margin: 0;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
-ms-transform: translate(-50%, -50%);
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.big-text {
|
||||
font-size: 48;
|
||||
}
|
||||
</style>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<img id='image' width="100%" />
|
||||
<br />
|
||||
<input id='clearButton' type="button" hidden value='Clear Local Storage' onclick="clearLocalStorage()"></input>
|
||||
<div id='msg' class='center big-text' width="100%" />
|
||||
|
||||
<script>
|
||||
loadItem();
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -44,6 +44,7 @@ export interface PayloadBody {
|
|||
receipts: HashTable<Receipt>;
|
||||
shcReceipt: SHCReceipt;
|
||||
dataUrl?: string;
|
||||
extraUrl?: string;
|
||||
}
|
||||
|
||||
export class Payload {
|
||||
|
@ -52,6 +53,7 @@ export class Payload {
|
|||
shcReceipt: SHCReceipt;
|
||||
rawData: string;
|
||||
dataUrl?: string;
|
||||
extraUrl?: string;
|
||||
backgroundColor: string;
|
||||
labelColor: string;
|
||||
foregroundColor: string;
|
||||
|
@ -67,6 +69,8 @@ export class Payload {
|
|||
this.shcReceipt = body.shcReceipt;
|
||||
this.rawData = body.rawData;
|
||||
this.dataUrl = body.dataUrl;
|
||||
this.extraUrl = body.extraUrl;
|
||||
|
||||
this.generic = {
|
||||
headerFields: [],
|
||||
primaryFields: [],
|
||||
|
@ -83,19 +87,27 @@ export class Payload {
|
|||
this.img1x = Constants.img1xBlack;
|
||||
this.img2x = Constants.img2xBlack;
|
||||
|
||||
let displayLocallyStoredPDFUrl = window.location.href + "displayLocallyStoredPDF.html";
|
||||
console.log(displayLocallyStoredPDFUrl)
|
||||
const attributedValue = `<a href="${displayLocallyStoredPDFUrl}">View</a>`;
|
||||
console.log('*** attributedValue ***');
|
||||
console.log(attributedValue);
|
||||
if (this.dataUrl) {
|
||||
let displayLocallyStoredPDFUrl = window.location.href + "displayLocallyStoredItem.html?item=receipt" ;
|
||||
const attributedValue = `<a href="${displayLocallyStoredPDFUrl}">View Receipt</a>`;
|
||||
|
||||
this.generic.backFields.push({
|
||||
key: "original",
|
||||
label: "Original receipt (saved locally in Safari)",
|
||||
attributedValue: attributedValue
|
||||
});
|
||||
}
|
||||
|
||||
if (this.extraUrl) {
|
||||
let extraUrl = window.location.href + "displayLocallyStoredItem.html?item=extra" ;
|
||||
const attributedValue = `<a href="${extraUrl}">View Extra Info</a>`;
|
||||
this.generic.backFields.push({
|
||||
key: "extra",
|
||||
label: "Extra image",
|
||||
attributedValue: attributedValue
|
||||
});
|
||||
}
|
||||
|
||||
//TODO: feature flagging
|
||||
|
||||
this.generic.backFields.push({
|
||||
key: "original",
|
||||
label: "Original receipt (saved locally in Safari)",
|
||||
attributedValue: attributedValue
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,12 +6,15 @@ import * as Decode from './decode';
|
|||
import {getScannedJWS, verifyJWS, decodeJWS} from "./shc";
|
||||
|
||||
import { PDFPageProxy } from 'pdfjs-dist/types/src/display/api';
|
||||
import pdfjsWorker from "pdfjs-dist/build/pdf.worker.entry";
|
||||
|
||||
// import {PNG} from 'pngjs'
|
||||
// import {decodeData} from "./decode";
|
||||
// import {Result} from "@zxing/library";
|
||||
|
||||
PdfJS.GlobalWorkerOptions.workerSrc = `https://cdnjs.cloudflare.com/ajax/libs/pdf.js/${PdfJS.version}/pdf.worker.js`
|
||||
PdfJS.GlobalWorkerOptions.workerSrc = pdfjsWorker;
|
||||
|
||||
// PdfJS.GlobalWorkerOptions.workerSrc = `https://cdnjs.cloudflare.com/ajax/libs/pdf.js/${PdfJS.version}/pdf.worker.js`
|
||||
|
||||
export async function getPayloadBodyFromFile(file: File): Promise<PayloadBody> {
|
||||
// Read file
|
||||
|
|
Loading…
Reference in New Issue