diff --git a/apps/passport-client/components/shared/PCDCard.tsx b/apps/passport-client/components/shared/PCDCard.tsx index 8ccaafce0d..5a5773bd45 100644 --- a/apps/passport-client/components/shared/PCDCard.tsx +++ b/apps/passport-client/components/shared/PCDCard.tsx @@ -8,6 +8,8 @@ import { TicketQR as EddsaTicketQR } from "@pcd/eddsa-ticket-pcd-ui"; import { PCD, PCDUI } from "@pcd/pcd-types"; +import { isPODPCD } from "@pcd/pod-pcd"; +import { PODPCDUI } from "@pcd/pod-pcd-ui"; import { isPODTicketPCD } from "@pcd/pod-ticket-pcd"; import { PODTicketPCDUI, @@ -28,8 +30,6 @@ import { pcdRenderers } from "../../src/pcdRenderers"; import { usePackage } from "../../src/usePackage"; import { Button, H4, Spacer, TextCenter } from "../core"; import { MainIdentityCard } from "./MainIdentityCard"; -import { isPODPCD } from "@pcd/pod-pcd"; -import { PODPCDUI } from "@pcd/pod-pcd-ui"; export const PCDCard = memo(PCDCardImpl); @@ -245,9 +245,8 @@ const TicketWrapper = forwardRef< pcd: EdDSATicketPCD; hidePadding?: boolean; addOns?: AddOnsProps; - showDownloadButton?: boolean; } ->(({ pcd, hidePadding, addOns, showDownloadButton }, ref) => { +>(({ pcd, hidePadding, addOns }, ref) => { const Card = EdDSATicketPCDUI.renderCardBody; const identityPCD = useUserIdentityPCD(); const ticketCategory = pcd.claim.ticket.ticketCategory; @@ -298,7 +297,6 @@ const TicketWrapper = forwardRef< verifyURL={verifyURL} idBasedVerifyURL={idBasedVerifyURL} addOns={addOns} - showDownloadButton={showDownloadButton} /> ) : null; @@ -312,22 +310,11 @@ type CardBodyProps = { isMainIdentity: boolean; hidePadding?: boolean; addOns?: AddOnsProps; - showDownloadButton?: boolean; deletePodPcd?: () => Promise; }; export const CardBody = forwardRef( - ( - { - pcd, - isMainIdentity, - hidePadding, - addOns, - showDownloadButton, - deletePodPcd - }, - ref - ) => { + ({ pcd, isMainIdentity, hidePadding, addOns, deletePodPcd }, ref) => { const pcdCollection = usePCDCollection(); if (isMainIdentity) { @@ -335,14 +322,7 @@ export const CardBody = forwardRef( } if (pcdCollection.hasPackage(pcd.type)) { if (isEdDSATicketPCD(pcd)) { - return ( - - ); + return ; } if (isPODTicketPCD(pcd)) { const Component = PODTicketPCDUI.renderCardBody; @@ -352,7 +332,6 @@ export const CardBody = forwardRef( id={pcd.claim.ticket.eventId + pcd.claim.ticket.attendeeEmail} > { {packs.map((pack) => { return ( 0 diff --git a/packages/ui/eddsa-ticket-pcd-ui/package.json b/packages/ui/eddsa-ticket-pcd-ui/package.json index 6d9a5caff4..5baf64a2fe 100644 --- a/packages/ui/eddsa-ticket-pcd-ui/package.json +++ b/packages/ui/eddsa-ticket-pcd-ui/package.json @@ -30,8 +30,7 @@ "@pcd/eddsa-ticket-pcd": "0.10.0", "@pcd/passport-interface": "^0.15.0", "@pcd/passport-ui": "0.15.0", - "@pcd/pcd-types": "0.15.0", - "html-to-image": "^1.11.11" + "@pcd/pcd-types": "0.15.0" }, "devDependencies": { "@pcd/eslint-config-custom": "0.15.0", diff --git a/packages/ui/eddsa-ticket-pcd-ui/src/CardBody.tsx b/packages/ui/eddsa-ticket-pcd-ui/src/CardBody.tsx index b0fa7dc4d9..5ef831fcd0 100644 --- a/packages/ui/eddsa-ticket-pcd-ui/src/CardBody.tsx +++ b/packages/ui/eddsa-ticket-pcd-ui/src/CardBody.tsx @@ -7,8 +7,7 @@ import { import { ZUCONNECT_23_DAY_PASS_PRODUCT_ID } from "@pcd/passport-interface"; import { styled } from "@pcd/passport-ui"; import { PCDUI } from "@pcd/pcd-types"; -import { toCanvas } from "html-to-image"; -import { useRef, useState } from "react"; +import { useRef } from "react"; import { TicketQR } from "./TicketQR"; type NEW_UI__AddOns = { @@ -29,8 +28,6 @@ export interface EdDSATicketPCDCardProps { hidePadding?: boolean; // when clicked on the the addons sections, if there is any, do something addOns?: NEW_UI__AddOns; - // defined by if the image has QR code displayed and by this flag. - showDownloadButton?: boolean; } export const EdDSATicketPCDUI: PCDUI = @@ -43,14 +40,12 @@ function EdDSATicketPCDCardBody({ pcd, verifyURL, idBasedVerifyURL, - addOns, - showDownloadButton + addOns }: { pcd: EdDSATicketPCD; } & EdDSATicketPCDCardProps): JSX.Element { const ticketImageRef = useRef(null); const ticketData = getEdDSATicketData(pcd); - const [downloading, setDownloading] = useState(false); // If ticket has an `eventStartDate` render the `qrCodeOverrideImageUrl`, if it exists // Else, render the `imageUrl`, if it existss @@ -96,26 +91,6 @@ function EdDSATicketPCDCardBody({
- {!imageToRender && showDownloadButton && ( - { - if (downloading) return; - setDownloading(true); - const ticketElement = ticketImageRef.current; - if (!ticketElement) return; - await shareOrDownloadImage( - ticketElement, - (ticketData?.eventName || "event-ticket-data") + ".jpeg" - ); - setDownloading(false); - }} - > - - Download ticket - - - - )} {addOns && ( {addOns.text} @@ -257,20 +232,6 @@ const ExtraSectionSecondaryText = styled.div` line-height: 135%; /* 16.2px */ `; -const DownloadIcon = (): JSX.Element => ( - - - - -); - const QRIcon = (): JSX.Element => ( ( ); - -const shareOrDownloadImage = async ( - ticketElement: HTMLElement | null, - fileName: string -): Promise => { - if (!ticketElement) return; - - const canvas: HTMLCanvasElement = await toCanvas(ticketElement); - const blob: Blob | null = await new Promise((resolve) => - canvas.toBlob(resolve, "image/jpeg") - ); - if (!blob) return; // Ensure the blob exists before proceeding - - const downloadImage = (blob: Blob, fileName: string): void => { - const url = URL.createObjectURL(blob); - const link = document.createElement("a"); - link.href = url; - link.download = fileName; - link.click(); - URL.revokeObjectURL(url); - }; - const file = new File([blob], fileName, { type: "image/jpeg" }); - if (navigator.share && navigator.canShare({ files: [file] })) { - try { - await navigator.share({ - files: [file] - }); - } catch (e) { - console.error("Error sharing image", e); - // Ignore errors related to the user aborting the share or a share already in progress - if ( - e instanceof Error && - ["AbortError", "InvalidStateError"].includes(e.name) - ) - return; - downloadImage(blob, fileName); - } - } else { - downloadImage(blob, fileName); - } -}; diff --git a/packages/ui/pod-ticket-pcd-ui/package.json b/packages/ui/pod-ticket-pcd-ui/package.json index 30aaf1fc87..3a1fe98cee 100644 --- a/packages/ui/pod-ticket-pcd-ui/package.json +++ b/packages/ui/pod-ticket-pcd-ui/package.json @@ -29,7 +29,6 @@ "@pcd/passport-ui": "0.15.0", "@pcd/pcd-types": "0.15.0", "@pcd/pod-ticket-pcd": "0.5.0", - "html-to-image": "^1.11.11", "url-join": "4.0.1" }, "devDependencies": { diff --git a/packages/ui/pod-ticket-pcd-ui/src/CardBody.tsx b/packages/ui/pod-ticket-pcd-ui/src/CardBody.tsx index df2e708ec2..f2e8a5c8ea 100644 --- a/packages/ui/pod-ticket-pcd-ui/src/CardBody.tsx +++ b/packages/ui/pod-ticket-pcd-ui/src/CardBody.tsx @@ -2,8 +2,7 @@ import { QRDisplayWithRegenerateAndStorage, styled } from "@pcd/passport-ui"; import { PCDUI } from "@pcd/pcd-types"; import { PODTicketPCD } from "@pcd/pod-ticket-pcd"; import { IPODTicketData } from "@pcd/pod-ticket-pcd/src/schema"; -import { toCanvas } from "html-to-image"; -import { useCallback, useRef, useState } from "react"; +import { useCallback, useRef } from "react"; import urlJoin from "url-join"; type NEW_UI__AddOns = { @@ -14,7 +13,6 @@ export interface PODTicketPCDCardProps { ticketData: IPODTicketData; idBasedVerifyURL: string; addOns?: NEW_UI__AddOns; - showDownoladButton?: boolean; } export const PODTicketPCDUI: PCDUI = { @@ -24,17 +22,14 @@ export const PODTicketPCDUI: PCDUI = { function PODTicketCardBody({ pcd, idBasedVerifyURL, - addOns, - showDownoladButton + addOns }: { pcd: PODTicketPCD; idBasedVerifyURL: string; addOns?: NEW_UI__AddOns; - showDownoladButton?: boolean; }): JSX.Element { return ( (null); - const [downloading, setDownloading] = useState(false); - // If ticket has an `eventStartDate` render the `qrCodeOverrideImageUrl`, if it exists // Else, render the `imageUrl`, if it existss const imageToRender = ticketData?.eventStartDate @@ -94,26 +86,6 @@ export function PODTicketCardBodyImpl({
- {showDownoladButton && !imageToRender && ( - { - if (downloading) return; - setDownloading(true); - const ticketElement = ticketImageRef.current; - if (!ticketElement) return; - await shareOrDownloadImage( - ticketElement, - (ticketData?.eventName || "event-ticket-data") + ".jpeg" - ); - setDownloading(false); - }} - > - - Download ticket - - - - )} {addOns && ( {addOns.text} @@ -289,20 +261,6 @@ const ExtraSectionSecondaryText = styled.div` line-height: 135%; /* 16.2px */ `; -const DownloadIcon = (): JSX.Element => ( - - - - -); - const QRIcon = (): JSX.Element => ( ( ); - -const shareOrDownloadImage = async ( - ticketElement: HTMLElement | null, - fileName: string -): Promise => { - if (!ticketElement) return; - - const canvas: HTMLCanvasElement = await toCanvas(ticketElement); - const blob: Blob | null = await new Promise((resolve) => - canvas.toBlob(resolve, "image/jpeg") - ); - if (!blob) return; // Ensure the blob exists before proceeding - - const downloadImage = (blob: Blob, fileName: string): void => { - const url = URL.createObjectURL(blob); - const link = document.createElement("a"); - link.href = url; - link.download = fileName; - link.click(); - URL.revokeObjectURL(url); - }; - const file = new File([blob], fileName, { type: "image/jpeg" }); - if (navigator.share && navigator.canShare({ files: [file] })) { - try { - await navigator.share({ - files: [file] - }); - } catch (e) { - console.error("Error sharing image", e); - // Ignore errors related to the user aborting the share or a share already in progress - if ( - e instanceof Error && - ["AbortError", "InvalidStateError"].includes(e.name) - ) - return; - downloadImage(blob, fileName); - } - } else { - downloadImage(blob, fileName); - } -}; diff --git a/yarn.lock b/yarn.lock index 879b72faf1..66eff3823d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6011,7 +6011,7 @@ "@ethersproject/keccak256" "^5.7.0" "@zk-kit/incremental-merkle-tree" "1.1.0" -"@semaphore-protocol/identity@4.5.0": +"@semaphore-protocol/identity@4.5.0", "semaphore-identity-v4@npm:@semaphore-protocol/identity@^4.0.3": version "4.5.0" resolved "https://registry.yarnpkg.com/@semaphore-protocol/identity/-/identity-4.5.0.tgz#d5c412eb609df2686b7216825ec88670ef73461b" integrity sha512-TIKxF2Lir1LppDQDJU6Z/aJUkocHT03BLpzv5vFEdCo/IT4g/4BhbFp2UQui7HyDE+JgMfUASXfScbFfo/5ULA== @@ -14152,11 +14152,6 @@ html-escaper@^2.0.0: resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== -html-to-image@^1.11.11: - version "1.11.11" - resolved "https://registry.yarnpkg.com/html-to-image/-/html-to-image-1.11.11.tgz#c0f8a34dc9e4b97b93ff7ea286eb8562642ebbea" - integrity sha512-9gux8QhvjRO/erSnDPv28noDZcPZmYE7e1vFsBLKLlRlKDSqNJYebj6Qz1TGd5lsRV+X+xYyjCKjuZdABinWjA== - html-url-attributes@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/html-url-attributes/-/html-url-attributes-3.0.0.tgz#fc4abf0c3fb437e2329c678b80abb3c62cff6f08" @@ -20074,16 +20069,6 @@ seek-bzip@^1.0.5: dependencies: commander "^2.8.1" -"semaphore-identity-v4@npm:@semaphore-protocol/identity@^4.0.3": - version "4.5.0" - resolved "https://registry.yarnpkg.com/@semaphore-protocol/identity/-/identity-4.5.0.tgz#d5c412eb609df2686b7216825ec88670ef73461b" - integrity sha512-TIKxF2Lir1LppDQDJU6Z/aJUkocHT03BLpzv5vFEdCo/IT4g/4BhbFp2UQui7HyDE+JgMfUASXfScbFfo/5ULA== - dependencies: - "@zk-kit/baby-jubjub" "1.0.3" - "@zk-kit/eddsa-poseidon" "1.0.4" - "@zk-kit/utils" "1.2.1" - poseidon-lite "0.3.0" - semver-match@0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/semver-match/-/semver-match-0.1.1.tgz#e7ccb31f83fd4a0e377d66387afd8ca3a329b5fc" @@ -20829,16 +20814,7 @@ string-template@~0.2.1: resolved "https://registry.yarnpkg.com/string-template/-/string-template-0.2.1.tgz#42932e598a352d01fc22ec3367d9d84eec6c9add" integrity sha512-Yptehjogou2xm4UJbxJ4CxgZx12HBfeystp0y3x7s4Dj32ltVVG1Gg8YhKjHZkHicuKpZX/ffilA8505VbUbpw== -"string-width-cjs@npm:string-width@^4.2.0": - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -20971,14 +20947,7 @@ stringify-entities@^4.0.0: character-entities-html4 "^2.0.0" character-entities-legacy "^3.0.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -23493,7 +23462,7 @@ workspace-tools@^0.36.4: js-yaml "^4.1.0" micromatch "^4.0.0" -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -23511,15 +23480,6 @@ wrap-ansi@^6.0.1, wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - wrap-ansi@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"