Skip to content

Commit

Permalink
feat: support drag-and-drop when importing opml (#2001)
Browse files Browse the repository at this point in the history
  • Loading branch information
lawvs authored Dec 4, 2024
1 parent 564270b commit bad7be9
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 7 deletions.
71 changes: 71 additions & 0 deletions apps/renderer/src/components/ui/drop-zone.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import type { DragEvent, ReactNode } from "react"
import { useCallback, useRef, useState } from "react"

// Ported from https://github.com/react-dropzone/react-dropzone/issues/753#issuecomment-774782919
const useDragAndDrop = ({ callback }: { callback: (file: FileList) => void | Promise<void> }) => {
const [isDragging, setIsDragging] = useState(false)
const dragCounter = useRef(0)

const onDrop = useCallback(
async (event: DragEvent<HTMLLabelElement>) => {
event.preventDefault()
setIsDragging(false)
if (event.dataTransfer && event.dataTransfer.files && event.dataTransfer.files.length > 0) {
dragCounter.current = 0
await callback(event.dataTransfer.files)
event.dataTransfer.clearData()
}
},
[callback],
)

const onDragEnter = useCallback((event: DragEvent) => {
event.preventDefault()
dragCounter.current++
setIsDragging(true)
}, [])

const onDragOver = useCallback((event: DragEvent) => {
event.preventDefault()
}, [])

const onDragLeave = useCallback((event: DragEvent) => {
event.preventDefault()
dragCounter.current--
if (dragCounter.current > 0) return
setIsDragging(false)
}, [])

return {
isDragging,

dragHandlers: {
onDrop,
onDragOver,
onDragEnter,
onDragLeave,
},
}
}

export const DropZone = ({
onDrop,
children,
}: {
onDrop: (file: FileList) => void | Promise<void>
children?: ReactNode
}) => {
const { isDragging, dragHandlers } = useDragAndDrop({ callback: onDrop })

return (
<label
className={`center flex h-[100px] w-full rounded-md border border-dashed ${
isDragging ? "border-blue-500 bg-blue-100" : ""
}`}
htmlFor="upload-file"
{...dragHandlers}
>
{children}
</label>
)
}
10 changes: 3 additions & 7 deletions apps/renderer/src/modules/discover/import.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { useForm } from "react-hook-form"
import { Trans, useTranslation } from "react-i18next"
import { z } from "zod"

import { DropZone } from "~/components/ui/drop-zone"
import { apiFetch } from "~/lib/api-fetch"
import { toastFetchError } from "~/lib/error-parser"
import { Queries } from "~/queries"
Expand Down Expand Up @@ -110,26 +111,21 @@ export function DiscoverImport({ isInit = false }: { isInit?: boolean }) {
{isInit ? t("discover.import.new_import_opml") : t("discover.import.opml")}
</FormLabel>
<FormControl>
<label
className="center flex h-[100px] w-full rounded-md border border-dashed"
htmlFor="upload-file"
>
<DropZone onDrop={(fileList) => onChange(fileList[0])}>
{form.formState.dirtyFields.file ? (
<Fragment>
<i className="i-mgc-file-upload-cute-re size-5" />

<span className="ml-2 text-sm font-semibold opacity-80">{value.name}</span>
</Fragment>
) : (
<Fragment>
<i className="i-mgc-file-upload-cute-re size-5" />

<span className="ml-2 text-sm opacity-80">
{t("discover.import.click_to_upload")}
</span>
</Fragment>
)}
</label>
</DropZone>
</FormControl>
<Input
{...fieldProps}
Expand Down

0 comments on commit bad7be9

Please sign in to comment.