Skip to content

Commit

Permalink
feat: one click to copy exist prompt
Browse files Browse the repository at this point in the history
  • Loading branch information
LeafYeeXYZ committed Dec 7, 2024
1 parent eb3ee07 commit e85e429
Show file tree
Hide file tree
Showing 5 changed files with 32 additions and 8 deletions.
10 changes: 8 additions & 2 deletions app/components/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import Painting from './Painting'
import Prompt from './Prompt'
import { useState, useEffect } from 'react'
import { ConfigProvider, type ThemeConfig } from 'antd'
import { ConfigProvider, type ThemeConfig, message } from 'antd'
import { ANTD_THEME_DARK, ANTD_THEME_LIGHT } from '../lib/config'
import { getStaredImages } from '../lib/utils'
import { useZustand } from '../lib/useZustand'
Expand All @@ -21,14 +21,19 @@ export default function App() {
return () => window.matchMedia('(prefers-color-scheme: dark)').removeEventListener('change', subTheme)
}, [])
// 初始化图片
const { tasks, setTasks, setImages, hasImage } = useZustand()
const { tasks, setTasks, setImages, hasImage, setMessageApi } = useZustand()
useEffect(() => {
getStaredImages().then((images) => setImages(() => images))
}, [setImages])
// 处理任务
useEffect(() => {
handleTasks(tasks, setTasks, setImages, hasImage)
}, [tasks, setTasks, setImages, hasImage])
// 消息提示
const [messageApi, contextHolder] = message.useMessage()
useEffect(() => {
setMessageApi(messageApi)
}, [messageApi, setMessageApi])

return (
<ConfigProvider theme={config}>
Expand All @@ -44,6 +49,7 @@ export default function App() {
</div>
</section>
</main>
{contextHolder}
</ConfigProvider>
)
}
6 changes: 3 additions & 3 deletions app/components/Prompt.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ type FormValues = {

export default function Prompt() {

const { setTasks } = useZustand()
const { setTasks, messageApi } = useZustand()
const [disabled, setDisabled] = useState(false)
const handleFinish = (value: FormValues) => {
flushSync(() => setDisabled(true))
Expand Down Expand Up @@ -90,7 +90,7 @@ export default function Prompt() {
try {
flushSync(() => setDisabled(true))
if (file.size > MAX_SIZE_MB * 1024 * 1024) {
alert(`Image size should be less than ${MAX_SIZE_MB}MB`)
messageApi?.error(`Image size should be less than ${MAX_SIZE_MB} MB`)
return false
}
const uint8array = new Uint8Array(await file.arrayBuffer())
Expand All @@ -107,7 +107,7 @@ export default function Prompt() {
})
}
if (!res.ok) {
alert(`Failed to generate prompt, error: ${res.status}`)
messageApi?.error(`Failed to generate prompt, error: ${res.status}`)
return false
}
const data = await res.json()
Expand Down
7 changes: 6 additions & 1 deletion app/lib/useZustand.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { create } from 'zustand'
import type { Task, Image } from './types'
import type { MessageInstance } from 'antd/es/message/interface'

export type SetAction<T> = (prev: T) => T

Expand All @@ -9,6 +10,8 @@ export type States = {
setTasks: (action: SetAction<Task[]>) => void
setImages: (action: SetAction<Image[]>) => void
hasImage: (hash: string) => boolean
messageApi: MessageInstance | null
setMessageApi: (messageApi: MessageInstance | null) => void
}

export const useZustand = create<States>()((set, get) => ({
Expand All @@ -18,5 +21,7 @@ export const useZustand = create<States>()((set, get) => ({
setImages: (action) => set((state) => ({ images: action(state.images) })),
hasImage: (hash) => {
return get().images.some((image) => image.hash === hash)
}
},
messageApi: null,
setMessageApi: (messageApi) => set({ messageApi })
}))
15 changes: 14 additions & 1 deletion app/widgets/Images.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { DeleteOutlined, StarOutlined, StarFilled, InfoCircleOutlined } from '@a

export default function Images({ containerID }: { containerID: string }) {

const { images, setImages } = useZustand()
const { images, setImages, messageApi } = useZustand()
const imageSize = useImageSize(containerID)
return (
<section className='w-full h-full flex justify-center items-center'>
Expand All @@ -39,6 +39,19 @@ export default function Images({ containerID }: { containerID: string }) {
content={(
<p>
{image.prompt}
<Tag
className='m-0 ml-2 cursor-pointer'
onClick={async () => {
try {
messageApi?.success('Copied to clipboard', 1)
await navigator.clipboard.writeText(image.prompt)
} catch {
messageApi?.error('Filed to copy, please copy manually')
}
}}
>
Click to Copy
</Tag>
<br />
<Tag className='m-0 mt-2'>{image.model}</Tag>
</p>
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"dev": "next dev --turbopack",
"build": "next build",
"start": "next start",
"lint": "next lint"
Expand Down

0 comments on commit e85e429

Please sign in to comment.