Skip to content

Commit

Permalink
fleanup dropbox upload
Browse files Browse the repository at this point in the history
  • Loading branch information
mbret committed Jan 19, 2025
1 parent a025651 commit ca92ec4
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 49 deletions.
86 changes: 37 additions & 49 deletions packages/web/src/plugins/dropbox/UploadBook.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,71 +2,59 @@
* @see https://www.dropbox.com/developers/chooser
* @see https://www.dropbox.com/lp/developers/reference/oauth-guide
*/
import { FC, memo, useEffect, useRef } from "react"
import { Report } from "../../debug/report.shared"
import { FC, memo } from "react"
import { BlockingScreen } from "../../common/BlockingBackdrop"
import { useAddBook } from "../../books/helpers"
import { useDataSourceHelpers } from "../../dataSources/helpers"
import { UNIQUE_RESOURCE_IDENTIFIER } from "./constants"
import { useIsMounted } from "./lib/useIsMounted"
import { READER_ACCEPTED_EXTENSIONS } from "@oboku/shared"
import { useDropboxChoose } from "./lib/useDropboxChoose"
import { useMutation$ } from "reactjrx"
import { defaultIfEmpty, from } from "rxjs"
import { useMountOnce } from "../../common/useMountOnce"

export const UploadBook: FC<{
onClose: () => void
}> = memo(({ onClose }) => {
const [addBook] = useAddBook()
const isMounted = useIsMounted()
const isOpened = useRef(false)
const { generateResourceId } = useDataSourceHelpers(
UNIQUE_RESOURCE_IDENTIFIER
)

useEffect(() => {
if (isOpened.current) return
const { mutateAsync: addBooks } = useMutation$({
mutationFn: (files: readonly Dropbox.ChooserFile[]) => {
const promises = files.map((doc) =>
addBook({
book: {
metadata: [
{
type: "link",
title: doc.name
}
]
},
link: {
book: null,
data: null,
resourceId: generateResourceId(doc.id),
type: `dropbox`,
createdAt: new Date().toISOString(),
modifiedAt: null
}
})
)

if (window.Dropbox) {
isOpened.current = true

window.Dropbox.choose({
multiselect: true,
extensions: READER_ACCEPTED_EXTENSIONS,
linkType: "direct",
cancel: function () {
if (!isMounted()) return
return from(Promise.all(promises)).pipe(defaultIfEmpty(null))
}
})

onClose()
},
success: (files) => {
if (!isMounted()) return
const { choose } = useDropboxChoose({
onSettled: onClose,
onSuccess: addBooks
})

Promise.all(
files.map((doc) =>
addBook({
book: {
metadata: [
{
type: "link",
title: doc.name
}
]
},
link: {
book: null,
data: null,
resourceId: generateResourceId(doc.id),
type: `dropbox`,
createdAt: new Date().toISOString(),
modifiedAt: null
}
}).catch(Report.error)
)
).then(() => {
onClose()
})
}
})
}
}, [onClose, generateResourceId, addBook, isOpened, isMounted])
useMountOnce(() => {
choose()
})

return (
<>
Expand Down
37 changes: 37 additions & 0 deletions packages/web/src/plugins/dropbox/lib/useDropboxChoose.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { READER_ACCEPTED_EXTENSIONS } from "@oboku/shared"
import { useCallback } from "react"
import { useLiveRef } from "reactjrx"

export const useDropboxChoose = (options: {
onCancel?: () => void
onSuccess: (files: readonly Dropbox.ChooserFile[]) => Promise<unknown>
onSettled: () => void
}) => {
const optionsRef = useLiveRef(options)

const choose = useCallback(() => {
if (!window.Dropbox) {
throw new Error("Dropbox is not available")
}

window.Dropbox.choose({
multiselect: true,
extensions: READER_ACCEPTED_EXTENSIONS,
linkType: "direct",
cancel: () => {
optionsRef.current?.onCancel?.()
optionsRef.current?.onSettled?.()
},
success: (files) => {
const promise =
optionsRef.current?.onSuccess(files) ?? Promise.resolve(null)

promise.finally(() => {
optionsRef.current?.onSettled?.()
})
}
})
}, [optionsRef])

return { choose }
}

0 comments on commit ca92ec4

Please sign in to comment.