allow ctrl+v to paste image to editor
This commit is contained in:
parent
4980675730
commit
3c5781c947
@ -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 />
|
||||||
|
@ -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}
|
||||||
|
@ -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)
|
||||||
|
@ -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()
|
||||||
|
Loading…
Reference in New Issue
Block a user