From 01bc9e20b0bdd7d61c83666b917d4f4333e79980 Mon Sep 17 00:00:00 2001 From: tom Date: Wed, 4 Sep 2024 16:17:07 +0200 Subject: [PATCH] Pass the file path when verifying a multi-part contract Fixes #2207 --- .../fields/ContractVerificationFieldSources.tsx | 7 ++++--- .../methods/ContractVerificationMultiPartFile.tsx | 1 + .../methods/ContractVerificationVyperMultiPartFile.tsx | 1 + ui/shared/forms/DragAndDropArea.tsx | 7 ++++--- ui/shared/forms/utils/files.ts | 10 +++++++--- 5 files changed, 17 insertions(+), 9 deletions(-) diff --git a/ui/contractVerification/fields/ContractVerificationFieldSources.tsx b/ui/contractVerification/fields/ContractVerificationFieldSources.tsx index 17d0f7f016..f8bf351ca5 100644 --- a/ui/contractVerification/fields/ContractVerificationFieldSources.tsx +++ b/ui/contractVerification/fields/ContractVerificationFieldSources.tsx @@ -18,13 +18,14 @@ type FileTypes = '.sol' | '.yul' | '.json' | '.vy' interface Props { name?: 'sources' | 'interfaces'; fileTypes: Array; + fullFilePath?: boolean; multiple?: boolean; required?: boolean; title: string; hint: string | React.ReactNode; } -const ContractVerificationFieldSources = ({ fileTypes, multiple, required, title, hint, name = 'sources' }: Props) => { +const ContractVerificationFieldSources = ({ fileTypes, multiple, required, title, hint, name = 'sources', fullFilePath }: Props) => { const { setValue, getValues, control, formState, clearErrors } = useFormContext(); const error = (() => { @@ -114,7 +115,7 @@ const ContractVerificationFieldSources = ({ fileTypes, multiple, required, title rowGap={ 2 } w="100%" > - + { hasValue ? renderFiles(field.value) : renderUploadButton() } @@ -123,7 +124,7 @@ const ContractVerificationFieldSources = ({ fileTypes, multiple, required, title { errorElement } ); - }, [ fileTypes, multiple, commonError, formState.isSubmitting, renderFiles, renderUploadButton ]); + }, [ fileTypes, multiple, commonError, formState.isSubmitting, renderFiles, renderUploadButton, fullFilePath ]); const validateFileType = React.useCallback(async(value: FieldPathValue): Promise => { if (Array.isArray(value)) { diff --git a/ui/contractVerification/methods/ContractVerificationMultiPartFile.tsx b/ui/contractVerification/methods/ContractVerificationMultiPartFile.tsx index da2967a9e8..8212b3b583 100644 --- a/ui/contractVerification/methods/ContractVerificationMultiPartFile.tsx +++ b/ui/contractVerification/methods/ContractVerificationMultiPartFile.tsx @@ -18,6 +18,7 @@ const ContractVerificationMultiPartFile = () => { { name="interfaces" fileTypes={ INTERFACE_TYPES } multiple + fullFilePath title="Interfaces (.vy or .json)" hint={ interfacesHint } /> diff --git a/ui/shared/forms/DragAndDropArea.tsx b/ui/shared/forms/DragAndDropArea.tsx index 51cab94cec..1b2d573729 100644 --- a/ui/shared/forms/DragAndDropArea.tsx +++ b/ui/shared/forms/DragAndDropArea.tsx @@ -9,9 +9,10 @@ interface Props { onDrop: (files: Array) => void; className?: string; isDisabled?: boolean; + fullFilePath?: boolean; } -const DragAndDropArea = ({ onDrop, children, className, isDisabled }: Props) => { +const DragAndDropArea = ({ onDrop, children, className, isDisabled, fullFilePath }: Props) => { const [ isDragOver, setIsDragOver ] = React.useState(false); const handleDrop = React.useCallback(async(event: DragEvent) => { @@ -22,11 +23,11 @@ const DragAndDropArea = ({ onDrop, children, className, isDisabled }: Props) => } const fileEntries = await getAllFileEntries(event.dataTransfer.items); - const files = await Promise.all(fileEntries.map(convertFileEntryToFile)); + const files = await Promise.all(fileEntries.map((fileEntry) => convertFileEntryToFile(fileEntry, fullFilePath))); onDrop(files); setIsDragOver(false); - }, [ isDisabled, onDrop ]); + }, [ isDisabled, onDrop, fullFilePath ]); const handleDragOver = React.useCallback((event: DragEvent) => { event.preventDefault(); diff --git a/ui/shared/forms/utils/files.ts b/ui/shared/forms/utils/files.ts index 57a52d9800..f5e0327258 100644 --- a/ui/shared/forms/utils/files.ts +++ b/ui/shared/forms/utils/files.ts @@ -1,3 +1,5 @@ +import stripLeadingSlash from 'lib/stripLeadingSlash'; + // Function to get all files in drop directory export async function getAllFileEntries(dataTransferItemList: DataTransferItemList): Promise> { const fileEntries: Array = []; @@ -54,11 +56,13 @@ async function readEntriesPromise(directoryReader: DirectoryReader): Promise { +export function convertFileEntryToFile(entry: FileSystemFileEntry, fullFilePath?: boolean): Promise { return new Promise((resolve) => { entry.file(async(file: File) => { - // const newFile = new File([ file ], entry.fullPath, { lastModified: file.lastModified, type: file.type }); - resolve(file); + const newFile = fullFilePath ? + new File([ file ], stripLeadingSlash(entry.fullPath), { lastModified: file.lastModified, type: file.type }) : + file; + resolve(newFile); }); }); }