import { useEffect, useState } from 'react'; import { View, Canvas } from '@tarojs/components'; import Taro from '@tarojs/taro'; import { REDEEM_QR_DISPLAY_SIZE, buildRedeemQrDataUrl, drawRedeemQrOnCanvas, } from '../lib/redeem-qr'; const CANVAS_ID = 'redeem-qr-canvas'; type RedeemQrCodeProps = { token: string; }; function drawOnWeappCanvas(token: string) { const page = Taro.getCurrentInstance().page; const query = page ? Taro.createSelectorQuery().in(page) : Taro.createSelectorQuery(); query .select(`#${CANVAS_ID}`) .fields({ node: true, size: true }) .exec((res) => { const item = res[0] as { node?: WechatMiniprogram.Canvas; width?: number; height?: number } | undefined; const canvas = item?.node; if (!canvas) return; const layoutW = item.width || REDEEM_QR_DISPLAY_SIZE; const layoutH = item.height || REDEEM_QR_DISPLAY_SIZE; const drawSize = Math.min(layoutW, layoutH); const ctx = canvas.getContext('2d') as CanvasRenderingContext2D; const dpr = Taro.getSystemInfoSync().pixelRatio || 2; canvas.width = layoutW * dpr; canvas.height = layoutH * dpr; ctx.scale(dpr, dpr); drawRedeemQrOnCanvas(ctx, token, drawSize); }); } export default function RedeemQrCode({ token }: RedeemQrCodeProps) { const [imgSrc, setImgSrc] = useState(''); const isWeapp = process.env.TARO_ENV === 'weapp'; useEffect(() => { if (!token) { setImgSrc(''); return; } if (isWeapp) { const timer = setTimeout(() => drawOnWeappCanvas(token), 120); return () => clearTimeout(timer); } let cancelled = false; void buildRedeemQrDataUrl(token).then((url) => { if (!cancelled) setImgSrc(url); }); return () => { cancelled = true; }; }, [token, isWeapp]); return ( {isWeapp ? ( ) : imgSrc ? ( ) : null} ); }