Skip to content

Commit

Permalink
feat: directory uploads (#79)
Browse files Browse the repository at this point in the history
Use the new w3ui Uploader's directory upload support to allow users to
upload directories. Also allow them to wrap a single file in a
directory.

I've moved this to a radio group because we are going to add the ability
to upload a CAR file, which will be a third option and will use a
different upload function.
<img width="676" alt="Screenshot 2024-01-10 at 1 33 34 PM"
src="https://github.com/web3-storage/console/assets/1113/c2e785ea-fb1b-4fcc-997e-5a1e21ba61fb">
<img width="673" alt="Screenshot 2024-01-10 at 1 33 42 PM"
src="https://github.com/web3-storage/console/assets/1113/dc2e4019-3df4-4899-8c86-5604eca32a96">
  • Loading branch information
Travis Vachon authored Jan 11, 2024
1 parent a123299 commit 2ded489
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 23 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"@ucanto/core": "^9.0.0",
"@ucanto/interface": "^9.0.0",
"@ucanto/transport": "^9.0.0",
"@w3ui/react": "^1.3.0",
"@w3ui/react": "^2.2.0",
"@web3-storage/content-claims": "^3.2.1",
"@web3-storage/data-segment": "^5.0.0",
"archy": "^1.0.0",
Expand Down
47 changes: 27 additions & 20 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

52 changes: 50 additions & 2 deletions src/components/Uploader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,12 @@ import { ArrowPathIcon } from '@heroicons/react/24/outline'
import {
UploadStatus,
Uploader as W3Uploader,
WrapInDirectoryCheckbox,
useUploader
} from '@w3ui/react'
import { gatewayHost } from '../components/services'
import { ChangeEvent, useCallback, useState } from 'react'
import { RadioGroup } from '@headlessui/react'

function StatusLoader ({ progressStatus }: { progressStatus: ProgressStatus }) {
const { total, loaded, lengthComputable } = progressStatus
Expand Down Expand Up @@ -99,18 +102,62 @@ export const Done = ({ dataCID }: DoneProps): JSX.Element => {
)
}

enum UploadType {
File = 'File',
Directory = 'Directory'
}

function uploadPrompt (uploadType: UploadType) {
switch (uploadType) {
case UploadType.File: {
return 'Drag File or Click to Browse'
}
case UploadType.Directory: {
return 'Drag Directory or Click to Browse'
}
}
}

const UploaderForm = (): JSX.Element => {
const [{ status, file }] = useUploader()
const [allowDirectory, setAllowDirectory] = useState(false)
const [uploadType, setUploadType] = useState(UploadType.File)
function changeUploadType (type: UploadType) {
if (type === UploadType.File) {
setAllowDirectory(false)
} else if (type === UploadType.Directory) {
setAllowDirectory(true)
}
setUploadType(type)
}
const hasFile = file !== undefined
return (
<>
<W3Uploader.Form>
<RadioGroup value={uploadType} onChange={changeUploadType} className='flex flex-row items-center text-center my-2'>
<RadioGroup.Option value={UploadType.File}>
{({ checked }) => (
<div className={`${checked ? 'bg-blue-200' : ''} w-24 border p-2 rounded-l`}>File</div>
)}
</RadioGroup.Option>
<RadioGroup.Option value={UploadType.Directory}>
{({ checked }) => (
<div className={`${checked ? 'bg-blue-200' : ''} w-24 border p-2 rounded-r`}>Directory</div>
)}
</RadioGroup.Option>
</RadioGroup>
{uploadType === UploadType.File && (
<label className='flex flex-row items-center mb-1'>
<WrapInDirectoryCheckbox />
<span className='text-sm ml-1'>Wrap In Directory</span>
</label>
)}
<div className={`relative shadow h-52 p-8 rounded-md bg-white/5 hover:bg-white/20 border-2 border-dotted border-zinc-950 flex flex-col justify-center items-center text-center`}>
{hasFile ? '' : <span className='mb-5'><img src='/icon-tray.svg' /></span>}
<label className={`${hasFile ? 'hidden' : 'block h-px w-px overflow-hidden absolute whitespace-nowrap'}`}>File:</label>
<W3Uploader.Input className={`${hasFile ? 'hidden' : 'block absolute inset-0 cursor-pointer w-full opacity-0'}`} />
<W3Uploader.Input className={`${hasFile ? 'hidden' : 'block absolute inset-0 cursor-pointer w-full opacity-0'}`} allowDirectory={allowDirectory} />
<UploaderContents />
{hasFile ? '' : <span>Drag files or Click to Browse</span>}
{hasFile ? '' : <span>{uploadPrompt(uploadType)}</span>}
</div>
</W3Uploader.Form>
<div className='flex flex-col lg:flex-row space-y-4 lg:space-y-0 lg:space-x-4 mt-4 text-center lg:text-left'>
Expand Down Expand Up @@ -226,6 +273,7 @@ export const Uploader = ({
<W3Uploader
as='div'
onUploadComplete={onUploadComplete}
defaultWrapInDirectory={true}
>
<UploaderForm />
</W3Uploader>
Expand Down

0 comments on commit 2ded489

Please sign in to comment.