Skip to content

Commit

Permalink
Merge branch 'main' into release-please--branches--main--components--…
Browse files Browse the repository at this point in the history
…core
  • Loading branch information
Peeja authored Sep 3, 2024
2 parents df4f08a + 050c9b8 commit e65442c
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 36 deletions.
2 changes: 1 addition & 1 deletion eslint.packages.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module.exports = {
extends: ['./node_modules/hd-scripts/eslint/ts.js'],
parserOptions: {
project: './tsconfig.json',
project: ['./tsconfig.json', 'packages/*/tsconfig.json'],
ecmaFeatures: {
jsx: true,
},
Expand Down
83 changes: 48 additions & 35 deletions packages/react/src/Uploader.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { As, Component, Props, Options, HTMLProps } from 'ariakit-react-utils'
import type { ChangeEvent } from 'react'
import type { ChangeEvent, FormEventHandler } from 'react'
import type { AnyLink, CARMetadata, ProgressStatus } from '@w3ui/core'

import React, {
Expand Down Expand Up @@ -43,7 +43,7 @@ export interface UploaderContextState {
* A callback that can be passed to an `onSubmit` handler to
* upload `file` to web3.storage via the w3up API.
*/
handleUploadSubmit?: (e: Event) => Promise<void>
handleUploadSubmit?: FormEventHandler<HTMLFormElement>
/**
* The CID of a successful upload
*/
Expand Down Expand Up @@ -158,7 +158,7 @@ export const UploaderRoot: Component<UploaderRootProps> = createComponent(
const [uploadAsCAR, setUploadAsCAR] = useState(defaultUploadAsCAR)
const [dataCID, setDataCID] = useState<AnyLink>()
const [status, setStatus] = useState(UploadStatus.Idle)
const [error, setError] = useState()
const [error, setError] = useState<Error>()
const [storedDAGShards, setStoredDAGShards] = useState<UploaderContextState['storedDAGShards']>([])
const [uploadProgress, setUploadProgress] = useState<UploadProgress>({})

Expand All @@ -167,42 +167,55 @@ export const UploaderRoot: Component<UploaderRootProps> = createComponent(
setStatus(UploadStatus.Idle)
}

const handleUploadSubmit = async (e: Event): Promise<void> => {
const handleUploadSubmit: FormEventHandler<HTMLFormElement> = (e) => {
e.preventDefault()
// file !== undefined should be unecessary but is here to make tsc happy
if ((client !== undefined) && (files !== undefined) && (file !== undefined)) {
try {
setError(undefined)
setStatus(UploadStatus.Uploading)
const storedShards: CARMetadata[] = []
setStoredDAGShards(storedShards)
const uploadOptions = {
onShardStored (meta: CARMetadata) {
storedShards.push(meta)
setStoredDAGShards([...storedShards])
},
onUploadProgress (status: ProgressStatus) {
setUploadProgress(statuses => ({ ...statuses, [status.url ?? '']: status }))
}
}
const cid = files.length > 1
? await client.uploadDirectory(files, uploadOptions)
: (uploadAsCAR
? await client.uploadCAR(file, uploadOptions)
: (wrapInDirectory
? await client.uploadDirectory(files, uploadOptions)
: await client.uploadFile(file, uploadOptions)))
if ((client === undefined)) {
// eslint-disable-next-line no-console
console.error('No client available for upload. Ignoring upload attempt.')
return
}

// The application should only attempt to submit once files are selected.
if ((files === undefined) || (file === undefined)) {
// eslint-disable-next-line no-console
console.error('No no files given to upload. Ignoring upload attempt.')
return
}

setDataCID(cid)
setStatus(UploadStatus.Succeeded)
if (onUploadComplete !== undefined) {
onUploadComplete({ file, files, dataCID: cid })
const doUpload = async (): Promise<void> => {
setError(undefined)
setStatus(UploadStatus.Uploading)
const storedShards: CARMetadata[] = []
setStoredDAGShards(storedShards)
const uploadOptions = {
onShardStored (meta: CARMetadata) {
storedShards.push(meta)
setStoredDAGShards([...storedShards])
},
onUploadProgress (status: ProgressStatus) {
setUploadProgress(statuses => ({ ...statuses, [status.url ?? '']: status }))
}
} catch (error_: any) {
setError(error_)
setStatus(UploadStatus.Failed)
}
const cid = files.length > 1
? await client.uploadDirectory(files, uploadOptions)
: (uploadAsCAR
? await client.uploadCAR(file, uploadOptions)
: (wrapInDirectory
? await client.uploadDirectory(files, uploadOptions)
: await client.uploadFile(file, uploadOptions)))

setDataCID(cid)
setStatus(UploadStatus.Succeeded)
if (onUploadComplete !== undefined) {
onUploadComplete({ file, files, dataCID: cid })
}
}

doUpload().catch((error_: unknown) => {
const error = (error_ instanceof Error) ? error_ : new Error(String(error_))
setError(error)
setStatus(UploadStatus.Failed)
})
}

const uploaderContextValue =
Expand Down Expand Up @@ -307,7 +320,7 @@ export type UploaderFormProps<T extends As = 'form'> = Props<UploaderFormOptions
*/
export const UploaderForm: Component<UploaderFormProps> = createComponent((props) => {
const [{ handleUploadSubmit }] = useContext(UploaderContext)
return createElement('form', { ...props, onSubmit: handleUploadSubmit })
return createElement('form', { ...props, onSubmit: handleUploadSubmit satisfies React.ComponentProps<'form'>['onSubmit'] })
})

/**
Expand Down

0 comments on commit e65442c

Please sign in to comment.