74 lines
2.3 KiB
TypeScript
74 lines
2.3 KiB
TypeScript
import { useEffect, useCallback } from 'react'
|
|
import { useTabStore } from '../stores/tabStore'
|
|
import { isAllowedFile } from '../lib/fileUtils'
|
|
import { MAX_FILE_SIZE } from '../lib/constants'
|
|
import { logError } from '../lib/errorHandler'
|
|
|
|
export function useDragDrop(showToast: (msg: string) => void) {
|
|
const createTab = useTabStore(s => s.createTab)
|
|
|
|
const handleDrop = useCallback(async (e: DragEvent) => {
|
|
e.preventDefault()
|
|
e.stopPropagation()
|
|
|
|
const files = e.dataTransfer?.files
|
|
if (!files) return
|
|
|
|
let rejected = 0
|
|
for (const file of Array.from(files)) {
|
|
// Electron adds a `path` property to File objects
|
|
const electronFile = file as File & { path?: string }
|
|
const filePath: string = electronFile.path || file.name
|
|
if (!isAllowedFile(filePath)) {
|
|
rejected++
|
|
continue
|
|
}
|
|
if (file.size > MAX_FILE_SIZE) {
|
|
showToast(`"${file.name}" 过大,暂不支持超过 20MB 的文件`)
|
|
continue
|
|
}
|
|
|
|
if (window.electronAPI) {
|
|
try {
|
|
const result = await window.electronAPI.readFile(filePath)
|
|
if (result.success && result.content !== undefined) {
|
|
createTab(filePath, result.content)
|
|
}
|
|
} catch (error) {
|
|
logError('拖拽读取文件失败', error)
|
|
}
|
|
} else {
|
|
const reader = new FileReader()
|
|
reader.onload = (ev: ProgressEvent<FileReader>) => {
|
|
const content = ev.target?.result as string
|
|
createTab(file.name, content)
|
|
}
|
|
reader.readAsText(file)
|
|
}
|
|
}
|
|
|
|
if (rejected > 0) {
|
|
showToast(`仅支持 .md / .markdown / .txt 文件,已忽略 ${rejected} 个文件`)
|
|
}
|
|
}, [createTab, showToast])
|
|
|
|
useEffect(() => {
|
|
const prevent = (e: DragEvent) => {
|
|
e.preventDefault()
|
|
e.stopPropagation()
|
|
}
|
|
|
|
document.addEventListener('dragenter', prevent)
|
|
document.addEventListener('dragleave', prevent)
|
|
document.addEventListener('dragover', prevent)
|
|
document.addEventListener('drop', handleDrop)
|
|
|
|
return () => {
|
|
document.removeEventListener('dragenter', prevent)
|
|
document.removeEventListener('dragleave', prevent)
|
|
document.removeEventListener('dragover', prevent)
|
|
document.removeEventListener('drop', handleDrop)
|
|
}
|
|
}, [handleDrop])
|
|
}
|