Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DropZone always returns error when glb/gltf file triggers dragenter event #6644

Open
tawago opened this issue Jul 15, 2022 · 12 comments · May be fixed by #12135
Open

DropZone always returns error when glb/gltf file triggers dragenter event #6644

tawago opened this issue Jul 15, 2022 · 12 comments · May be fixed by #12135
Assignees
Labels
Bug Something is broken and not working as intended in the system. Component Engineering Good first issue

Comments

@tawago
Copy link

tawago commented Jul 15, 2022

DropZone

  • The validation error dragErrorOverlay for dragenter event relies on accept property or customValidator function property of <DropZone>

    const getValidatedFiles = useCallback(
    (files: File[] | DataTransferItem[]) => {
    const acceptedFiles: File[] = [];
    const rejectedFiles: File[] = [];
    Array.from(files as File[]).forEach((file: File) => {
    !fileAccepted(file, accept) ||
    (customValidator && !customValidator(file))
    ? rejectedFiles.push(file)
    : acceptedFiles.push(file);
    });
    if (!allowMultiple) {
    acceptedFiles.splice(1, acceptedFiles.length);
    rejectedFiles.push(...acceptedFiles.slice(1));
    }
    return {files, acceptedFiles, rejectedFiles};
    },
    [accept, allowMultiple, customValidator],
    );

  • When accept property is present and its !fileAccepted returns true, customValidator never gets evaluated.

  • fileAccepted always returns false for glb/gltf file because:

    1. When a file is dragentered, it is not a File instance but DataTransferItem instance and DataTransferItem only has kind and type properties. When a glb/gltf dragentered, however,DataTransferItem's type has an empty string; thus an-always validation error. This part is related to a situation when accept property is a mimeType string like model/gltf+json,model/gltf-binary instead of a dot string like .glb. The validation works for files like video/mp4 because DataTransferItem has a proper type.

    2. When accept property is a dot string like .glb,.mp4,.wav, fileAccepted always returns false because DataTransferItem does not have name property.

      const fileName = file.name || '';
      This is a bug that should be fixed separately. all file types not working.

    3. Additionally, File instance of drop event has type property but it is an empty string. name gets correct information tho. file.name validation would work only when accept is a dot string.

  • To avoid dragErrorOverlay showing up for dragenter event, a file validation needs to rely on customValidator and omit accept property

  • This compromises "click and select files" user interaction of System UI outside of browsers because to filter file types on System, it relies on accept property of <input type="file"> tag.

Examples

dragErrorOverlay showing up even tho DropZone actually accepts glb

const [files, setFiles] = useState<File[]>()
const handleDrop = (acceptedFiles: File[]) => setFiles(acceptedFiles)
const fileUpload = !files.length && <DropZone.FileUpload />
const uploadedFiles = files.length > 0 && (
    <Stack vertical>
      {files.map((file, index) => (
        <Stack alignment="center" key={index}>
          <Thumbnail
            size="small"
            alt={file.name}
            source={window.URL.createObjectURL(file)}
          />
          <div>
            {file.name} <Caption>{file.size} bytes</Caption>
          </div>
        </Stack>
      ))}
    </Stack>
);
...
      <DropZone accept="model/gltf-binary" type="file" onDropAccepted={handleDrop}>
        {uploadedFiles}
        {fileUpload}
      </DropZone>

Best practices

The DropZone component should either:

  • skip fileAccepted validation for dragenter event when DataTransferItem.type has an empty string. (with a better documentation otherwise coders implicitly have to use a dot string for accept prop)
  • prioritize customValidator over fileAccepted and give coders a better control. If customValidator is present, just skip fileAccepted. (This is because I would rather have a mimetype <=> a dot string extension conversion in the customValidator and check both file.name and file.type with a specified filetypes as accept prop)

-ps
I would like to create a PR but I wanted to make sure that we have a consensus on which solution would be better.

@ghost
Copy link

ghost commented Jul 15, 2022

👋 Thanks for opening your first issue. A contributor should give feedback soon. If you haven’t already, please check out the contributing guidelines.

@yurm04 yurm04 added the Bug Something is broken and not working as intended in the system. label Jul 19, 2022
@chloerice
Copy link
Member

Hey @tawago 👋🏽 Thanks for flagging and investigating this bug! I think solution B is the way to go, the customValidator method should be prioritized, especially since it's a required prop 🧐 If you run into any blockers or questions raise them here and we'll figure it out together, and feel free to ping me for review in your PR 😁 🙏🏽

@laurkim
Copy link
Contributor

laurkim commented Aug 15, 2022

Hey @tawago, just doing some backlog cleanup and noticed you mentioned opening a PR and @chloerice gave feedback on which solution would be preferable. Going to add you as an assignee to this issue 😃

@alex-page alex-page removed the group 2 label Aug 19, 2022
@github-actions
Copy link
Contributor

Hi! We noticed there hasn’t been activity on this issue in a while. After 30 days, it will close automatically.

If it’s still relevant, or you have updates, comment and let us know. And don’t worry, you can always re-open later if needed.

@shoenseiwaso
Copy link

Hi! We noticed there hasn’t been activity on this issue in a while. After 30 days, it will close automatically.

If it’s still relevant, or you have updates, comment and let us know. And don’t worry, you can always re-open later if needed.

Still relevant, thanks!

Copy link
Contributor

github-actions bot commented Dec 3, 2023

Hi! We noticed there hasn’t been activity on this issue in a while. After 30 days, it will close automatically.

If it’s still relevant, or you have updates, comment and let us know. And don’t worry, you can always re-open later if needed.

@shoenseiwaso
Copy link

Hi! We noticed there hasn’t been activity on this issue in a while. After 30 days, it will close automatically.

If it’s still relevant, or you have updates, comment and let us know. And don’t worry, you can always re-open later if needed.

Yes, still a problem.

@shoenseiwaso
Copy link

Coming up on the two year anniversary of this - yes, it's still relevant!

@genevieveluyt
Copy link
Contributor

genevieveluyt commented May 21, 2024

@chloerice I could give this a go, though I'd like to propose an alternate solution (similar to the first proposed solution):

The System OS file picker works with both mime types and file extensions, so if I wanted my dropzone to accept say images and GLB files, I could pass an accept prop of image/jpeg,.glb. It would be great if the drag and drop validation could respect this as well, rather than requiring me to write custom logic in customValidator.

If there is a value in the accept prop that starts with '.' I think it's safe to assume that the user intends to validate against the file extension. We also know that during the dragenter and dragover events, the file name is not known:

Note: The files property of DataTransfer objects can only be accessed from within the drop event. For all other events, the files property will be empty — because its underlying data store will be in a protected mode.
Ref

So it is not possible for us to validate by file extension on these events. So only in this case (if the accept prop contains a file extension), we could skip validation on dragenter and dragover events because we are missing information to validate properly, and only validate on drop events at which point the filename is known.

I think it would be worth some docs to recommend using mime types if possible (eg. if they are common mime types), else use file extension but note that on-drag validation is not supported in that case.

@shoenseiwaso
Copy link

@genevieveluyt @chloerice thanks for addressing this! Has the fix been merged and/or released yet?

@genevieveluyt
Copy link
Contributor

Sorry closed it by accident! PR is here: #12135

@genevieveluyt genevieveluyt reopened this May 29, 2024
@shoenseiwaso
Copy link

Sorry closed it by accident! PR is here: #12135

All good, thanks for picking this up!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Something is broken and not working as intended in the system. Component Engineering Good first issue
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants