allow ctrl+v to paste image to editor

This commit is contained in:
Qing 2022-10-08 21:41:26 +08:00
parent 4980675730
commit 3c5781c947
4 changed files with 51 additions and 7 deletions

View File

@ -1,4 +1,4 @@
import React, { useEffect, useMemo } from 'react' import React, { useCallback, useEffect, useMemo, useState } from 'react'
import { useRecoilState } from 'recoil' import { useRecoilState } from 'recoil'
import { nanoid } from 'nanoid' import { nanoid } from 'nanoid'
import useInputImage from './hooks/useInputImage' import useInputImage from './hooks/useInputImage'
@ -26,6 +26,8 @@ function App() {
const [theme, setTheme] = useRecoilState(themeState) const [theme, setTheme] = useRecoilState(themeState)
const [toastVal, setToastState] = useRecoilState(toastState) const [toastVal, setToastState] = useRecoilState(toastState)
const userInputImage = useInputImage() const userInputImage = useInputImage()
const [openPasteImageAlertDialog, setOpenPasteImageAlertDialog] =
useState(false)
// Set Input Image // Set Input Image
useEffect(() => { useEffect(() => {
@ -60,6 +62,7 @@ function App() {
event.preventDefault() event.preventDefault()
event.stopPropagation() event.stopPropagation()
}, []) }, [])
const handleDragIn = React.useCallback(event => { const handleDragIn = React.useCallback(event => {
event.preventDefault() event.preventDefault()
event.stopPropagation() event.stopPropagation()
@ -68,6 +71,7 @@ function App() {
setIsDragging(true) setIsDragging(true)
} }
}, []) }, [])
const handleDragOut = React.useCallback(event => { const handleDragOut = React.useCallback(event => {
event.preventDefault() event.preventDefault()
event.stopPropagation() event.stopPropagation()
@ -75,6 +79,7 @@ function App() {
if (dragCounter.current > 0) return if (dragCounter.current > 0) return
setIsDragging(false) setIsDragging(false)
}, []) }, [])
const handleDrop = React.useCallback(event => { const handleDrop = React.useCallback(event => {
event.preventDefault() event.preventDefault()
event.stopPropagation() event.stopPropagation()
@ -105,21 +110,52 @@ function App() {
} }
}, []) }, [])
const onPaste = useCallback((event: any) => {
// TODO: when sd side panel open, ctrl+v not work
// https://htmldom.dev/paste-an-image-from-the-clipboard/
if (!event.clipboardData) {
return
}
const clipboardItems = event.clipboardData.items
const items: DataTransferItem[] = [].slice
.call(clipboardItems)
.filter((item: DataTransferItem) => {
// Filter the image items only
return item.type.indexOf('image') !== -1
})
if (items.length === 0) {
return
}
event.preventDefault()
event.stopPropagation()
// TODO: add confirm dialog
const item = items[0]
// Get the blob of image
const blob = item.getAsFile()
if (blob) {
setFile(blob)
}
}, [])
React.useEffect(() => { React.useEffect(() => {
window.addEventListener('dragenter', handleDragIn) window.addEventListener('dragenter', handleDragIn)
window.addEventListener('dragleave', handleDragOut) window.addEventListener('dragleave', handleDragOut)
window.addEventListener('dragover', handleDrag) window.addEventListener('dragover', handleDrag)
window.addEventListener('drop', handleDrop) window.addEventListener('drop', handleDrop)
window.addEventListener('paste', onPaste)
return function cleanUp() { return function cleanUp() {
window.removeEventListener('dragenter', handleDragIn) window.removeEventListener('dragenter', handleDragIn)
window.removeEventListener('dragleave', handleDragOut) window.removeEventListener('dragleave', handleDragOut)
window.removeEventListener('dragover', handleDrag) window.removeEventListener('dragover', handleDrag)
window.removeEventListener('drop', handleDrop) window.removeEventListener('drop', handleDrop)
window.removeEventListener('paste', onPaste)
} }
}) })
///
return ( return (
<div className="lama-cleaner"> <div className="lama-cleaner">
<Header /> <Header />

View File

@ -22,12 +22,12 @@ const SidePanel = () => {
className="btn-primary side-panel-trigger" className="btn-primary side-panel-trigger"
onClick={() => toggleOpen()} onClick={() => toggleOpen()}
> >
Stable Diffusion Configurations
</PopoverPrimitive.Trigger> </PopoverPrimitive.Trigger>
<PopoverPrimitive.Portal> <PopoverPrimitive.Portal>
<PopoverPrimitive.Content className="side-panel-content"> <PopoverPrimitive.Content className="side-panel-content">
<SettingBlock <SettingBlock
title="Show Croper" title="Croper"
input={ input={
<Switch <Switch
checked={setting.showCroper} checked={setting.showCroper}

View File

@ -1,10 +1,16 @@
import React, { useEffect } from 'react' import React, { useCallback, useEffect } from 'react'
import { useRecoilState, useRecoilValue } from 'recoil' import { useRecoilState, useRecoilValue } from 'recoil'
import Editor from './Editor/Editor' import Editor from './Editor/Editor'
import ShortcutsModal from './Shortcuts/ShortcutsModal' import ShortcutsModal from './Shortcuts/ShortcutsModal'
import SettingModal from './Settings/SettingsModal' import SettingModal from './Settings/SettingsModal'
import Toast from './shared/Toast' import Toast from './shared/Toast'
import { AIModel, isSDState, settingState, toastState } from '../store/Atoms' import {
AIModel,
fileState,
isSDState,
settingState,
toastState,
} from '../store/Atoms'
import { import {
currentModel, currentModel,
modelDownloaded, modelDownloaded,
@ -13,6 +19,7 @@ import {
import SidePanel from './SidePanel/SidePanel' import SidePanel from './SidePanel/SidePanel'
const Workspace = () => { const Workspace = () => {
const [file, setFile] = useRecoilState(fileState)
const [settings, setSettingState] = useRecoilState(settingState) const [settings, setSettingState] = useRecoilState(settingState)
const [toastVal, setToastState] = useRecoilState(toastState) const [toastVal, setToastState] = useRecoilState(toastState)
const isSD = useRecoilValue(isSDState) const isSD = useRecoilValue(isSDState)

View File

@ -31,6 +31,7 @@ const TextInput = React.forwardRef<
type="text" type="text"
onFocus={handleOnFocus} onFocus={handleOnFocus}
onBlur={handleOnBlur} onBlur={handleOnBlur}
onPaste={evt => evt.stopPropagation()}
onKeyDown={e => { onKeyDown={e => {
if (e.key === 'Escape') { if (e.key === 'Escape') {
e.currentTarget.blur() e.currentTarget.blur()