From 2300d59a49603c9c52775a961b50205aaf46c20b Mon Sep 17 00:00:00 2001 From: Qing Date: Sun, 25 Sep 2022 21:56:35 +0800 Subject: [PATCH] add full page drag and drop --- lama_cleaner/app/src/App.tsx | 80 +++++++++++++++++++++++++++++++++++- 1 file changed, 79 insertions(+), 1 deletion(-) diff --git a/lama_cleaner/app/src/App.tsx b/lama_cleaner/app/src/App.tsx index 7df91a1..198f689 100644 --- a/lama_cleaner/app/src/App.tsx +++ b/lama_cleaner/app/src/App.tsx @@ -5,17 +5,26 @@ import useInputImage from './hooks/useInputImage' import LandingPage from './components/LandingPage/LandingPage' import { themeState } from './components/Header/ThemeChanger' import Workspace from './components/Workspace' -import { fileState } from './store/Atoms' +import { fileState, toastState } from './store/Atoms' import { keepGUIAlive } from './utils' import Header from './components/Header/Header' import useHotKey from './hooks/useHotkey' +const SUPPORTED_FILE_TYPE = [ + 'image/jpeg', + 'image/png', + 'image/webp', + 'image/bmp', + 'image/tiff', +] + // Keeping GUI Window Open keepGUIAlive() function App() { const [file, setFile] = useRecoilState(fileState) const [theme, setTheme] = useRecoilState(themeState) + const [toastVal, setToastState] = useRecoilState(toastState) const userInputImage = useInputImage() // Set Input Image @@ -42,6 +51,75 @@ function App() { return nanoid() }, [file]) + /// + + const [isDragging, setIsDragging] = React.useState(false) + const dragCounter = React.useRef(0) + + const handleDrag = React.useCallback(event => { + event.preventDefault() + event.stopPropagation() + }, []) + const handleDragIn = React.useCallback(event => { + event.preventDefault() + event.stopPropagation() + dragCounter.current += 1 + if (event.dataTransfer.items && event.dataTransfer.items.length > 0) { + setIsDragging(true) + } + }, []) + const handleDragOut = React.useCallback(event => { + event.preventDefault() + event.stopPropagation() + dragCounter.current -= 1 + if (dragCounter.current > 0) return + setIsDragging(false) + }, []) + const handleDrop = React.useCallback(event => { + event.preventDefault() + event.stopPropagation() + setIsDragging(false) + if (event.dataTransfer.files && event.dataTransfer.files.length > 0) { + if (event.dataTransfer.files.length > 1) { + setToastState({ + open: true, + desc: 'Please drag and drop only one file', + state: 'error', + duration: 3000, + }) + } else { + const dragFile = event.dataTransfer.files[0] + const fileType = dragFile.type + if (SUPPORTED_FILE_TYPE.includes(fileType)) { + setFile(dragFile) + } else { + setToastState({ + open: true, + desc: 'Please drag and drop an image file', + state: 'error', + duration: 3000, + }) + } + } + event.dataTransfer.clearData() + } + }, []) + + React.useEffect(() => { + window.addEventListener('dragenter', handleDragIn) + window.addEventListener('dragleave', handleDragOut) + window.addEventListener('dragover', handleDrag) + window.addEventListener('drop', handleDrop) + return function cleanUp() { + window.removeEventListener('dragenter', handleDragIn) + window.removeEventListener('dragleave', handleDragOut) + window.removeEventListener('dragover', handleDrag) + window.removeEventListener('drop', handleDrop) + } + }) + + /// + return (