From adf6e7f78c06cd6c23f0c2627be7f3f18e8446cf Mon Sep 17 00:00:00 2001 From: saviojks Date: Tue, 10 Sep 2024 12:39:33 -0300 Subject: [PATCH] feat: :sparkles: Check a way to limit a asset image size when show it on KleverScan --- package.json | 2 +- .../CreateAsset/BasicInfoSection/index.tsx | 21 +++++----- .../TransactionForms/FormInput/index.tsx | 9 +++- src/utils/imageValidate/index.ts | 42 ++++++++++++++++--- 4 files changed, 57 insertions(+), 17 deletions(-) diff --git a/package.json b/package.json index b1ee8bc3e..05aa274da 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "explorer", - "version": "3.3.8", + "version": "3.3.7", "private": true, "license": "GPL-3.0-only", "scripts": { diff --git a/src/components/TransactionForms/CustomForms/CreateAsset/BasicInfoSection/index.tsx b/src/components/TransactionForms/CustomForms/CreateAsset/BasicInfoSection/index.tsx index ee300334a..db833e8d0 100644 --- a/src/components/TransactionForms/CustomForms/CreateAsset/BasicInfoSection/index.tsx +++ b/src/components/TransactionForms/CustomForms/CreateAsset/BasicInfoSection/index.tsx @@ -18,8 +18,7 @@ export const BasicInfoSection: React.FC> = ({ isFungible, }) => { const [logoError, setLogoError] = useState(null); - const { watch, trigger, setError, clearErrors } = - useFormContext(); + const { watch, trigger } = useFormContext(); const { walletAddress } = useExtension(); const [isEqual, setIsEqual] = useState(false); const [iAgree, setIAgree] = useState(false); @@ -32,7 +31,7 @@ export const BasicInfoSection: React.FC> = ({ useEffect(() => { trigger('initialSupply'); - trigger('maxSupply'); + trigger('logo'); }, [precision, trigger]); const isValidLogo = async () => { @@ -40,10 +39,14 @@ export const BasicInfoSection: React.FC> = ({ 'The logo link is invalid, which could lead to your logo not being displayed.'; try { if (!!logo) { - const isValid = await validateImgUrl(logo, 2000); + const [isValid, erroMessage] = await validateImgUrl(logo, 2000); if (!isValid) { - setLogoError(logoErrorMsg); - return; + if (erroMessage) { + return erroMessage; + } else { + setLogoError(logoErrorMsg); + return false; + } } } setLogoError(null); @@ -56,13 +59,10 @@ export const BasicInfoSection: React.FC> = ({ setIAgree(old => !old); } - useEffect(() => { - isValidLogo(); - }, [logo]); - useEffect(() => { trigger('initialSupply'); }, [iAgree]); + useEffect(() => { if (initialSupply === maxSupply) { setIsEqual(true); @@ -140,6 +140,7 @@ export const BasicInfoSection: React.FC> = ({ span={2} tooltip={tooltip.logo} logoError={logoError} + propsValidate={isValidLogo} /> ); diff --git a/src/components/TransactionForms/FormInput/index.tsx b/src/components/TransactionForms/FormInput/index.tsx index 6f273045a..a49e5c32a 100644 --- a/src/components/TransactionForms/FormInput/index.tsx +++ b/src/components/TransactionForms/FormInput/index.tsx @@ -236,6 +236,12 @@ const FormInput: React.FC< type, customOnChange, ), + validate: (value: any) => { + if (propsValidate) { + return propsValidate?.(); + } + return true; + }, }) : register(name, { valueAsNumber: true, @@ -282,6 +288,7 @@ const FormInput: React.FC< : 'Only integer numbers allowed'; } } + if (propsValidate) { return propsValidate?.(); } @@ -509,7 +516,7 @@ const FormInput: React.FC< type !== 'textarea' && type !== 'object' && type !== 'file' && - type !== 'hidden' && } + type !== 'hidden' && } {error && ( { setTimeout(() => resolve(false), timeout); }); + return Promise.race([imgPromise, timeoutPromise]); }; @@ -59,17 +60,48 @@ export const validateImgRequestHeader = async ( export const validateImgUrl = async ( url: string, timeout: number, -): Promise => { +): Promise<[boolean, string?]> => { + try { + const response = await fetch(url); + const blob = await response.blob(); + const sizeInKB = blob.size / 1024; + let width = 0; + let height = 0; + + if (sizeInKB > 1024 * 3) { + return [false, 'maximum image size should be 3mb']; + } + + const img = new Image(); + img.src = URL.createObjectURL(blob); + + const imgLoaded = new Promise<[number, number]>(resolve => { + img.onload = () => { + width = img.width; + height = img.height; + resolve([width, height]); + }; + }); + + [width, height] = await imgLoaded; + + if (width > 1920 || height > 1080) { + return [false, 'maximum image size should be 1920x1080']; + } + } catch (error) { + return [false]; + } + if (regexImgUrl(url)) { - return true; + return [true]; } if (await validateImgRequestHeader(url, timeout)) { - return true; + return [true]; } if (await isImage(url, timeout)) { - return true; + return [true]; } - return false; + return [false]; };