Spaces:
Sleeping
Sleeping
Julian Bilcke
commited on
Commit
·
f658021
1
Parent(s):
5dd2af5
up
Browse files
src/app/interface/bottom-bar/index.tsx
CHANGED
|
@@ -65,7 +65,7 @@ export function BottomBar() {
|
|
| 65 |
let uploadUrl = ""
|
| 66 |
try {
|
| 67 |
uploadUrl = await uploadToHuggingFace(fileToUpload)
|
| 68 |
-
console.log("uploadUrl:", uploadUrl)
|
| 69 |
} catch (err) {
|
| 70 |
console.error("Failed to upload the image to Hugging Face")
|
| 71 |
}
|
|
|
|
| 65 |
let uploadUrl = ""
|
| 66 |
try {
|
| 67 |
uploadUrl = await uploadToHuggingFace(fileToUpload)
|
| 68 |
+
// console.log("uploadUrl:", uploadUrl)
|
| 69 |
} catch (err) {
|
| 70 |
console.error("Failed to upload the image to Hugging Face")
|
| 71 |
}
|
src/app/interface/edit-modal/index.tsx
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import { ReactNode, useState } from "react"
|
| 2 |
+
import { RxReload, RxPencil2 } from "react-icons/rx"
|
| 3 |
+
|
| 4 |
+
import { Button } from "@/components/ui/button"
|
| 5 |
+
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog"
|
| 6 |
+
import { Input } from "@/components/ui/input"
|
| 7 |
+
import { cn } from "@/lib/utils"
|
| 8 |
+
|
| 9 |
+
|
| 10 |
+
export function EditModal({
|
| 11 |
+
existingPrompt,
|
| 12 |
+
isEnabled,
|
| 13 |
+
className,
|
| 14 |
+
children,
|
| 15 |
+
onSave,
|
| 16 |
+
}: {
|
| 17 |
+
existingPrompt: string;
|
| 18 |
+
isEnabled: boolean;
|
| 19 |
+
className?: string;
|
| 20 |
+
children?: ReactNode;
|
| 21 |
+
onSave: (newPrompt: string) => void;
|
| 22 |
+
}) {
|
| 23 |
+
const [draftPrompt, setDraftPrompt] = useState(existingPrompt)
|
| 24 |
+
const [isOpen, setOpen] = useState(false)
|
| 25 |
+
|
| 26 |
+
const handleSubmit = () => {
|
| 27 |
+
if (draftPrompt) {
|
| 28 |
+
onSave(draftPrompt)
|
| 29 |
+
setOpen(false)
|
| 30 |
+
}
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
return (
|
| 34 |
+
<Dialog open={isOpen} onOpenChange={() => isEnabled ? setOpen(true) : undefined}>
|
| 35 |
+
<DialogTrigger asChild>
|
| 36 |
+
<Button variant="outline">
|
| 37 |
+
{children}
|
| 38 |
+
</Button>
|
| 39 |
+
</DialogTrigger>
|
| 40 |
+
<DialogContent className="sm:max-w-[425px]">
|
| 41 |
+
<DialogHeader>
|
| 42 |
+
<DialogTitle>Edit Prompt</DialogTitle>
|
| 43 |
+
<DialogDescription className="w-full text-center text-lg font-bold text-stone-800">
|
| 44 |
+
Edit Prompt
|
| 45 |
+
</DialogDescription>
|
| 46 |
+
</DialogHeader>
|
| 47 |
+
<div className="flex flex-row flex-grow w-full">
|
| 48 |
+
<Input
|
| 49 |
+
placeholder="Story"
|
| 50 |
+
className="w-full bg-neutral-300 text-neutral-800 dark:bg-neutral-300 dark:text-neutral-800 rounded-r-none"
|
| 51 |
+
// disabled={atLeastOnePanelIsBusy}
|
| 52 |
+
onChange={(e) => {
|
| 53 |
+
setDraftPrompt(e.target.value)
|
| 54 |
+
}}
|
| 55 |
+
onKeyDown={({ key }) => {
|
| 56 |
+
if (key === 'Enter') {
|
| 57 |
+
handleSubmit()
|
| 58 |
+
}
|
| 59 |
+
}}
|
| 60 |
+
value={draftPrompt}
|
| 61 |
+
/>
|
| 62 |
+
</div>
|
| 63 |
+
<DialogFooter>
|
| 64 |
+
<Button
|
| 65 |
+
type="submit"
|
| 66 |
+
onClick={() => handleSubmit()}
|
| 67 |
+
disabled={!draftPrompt.length}
|
| 68 |
+
>Save</Button>
|
| 69 |
+
</DialogFooter>
|
| 70 |
+
</DialogContent>
|
| 71 |
+
</Dialog>
|
| 72 |
+
)
|
| 73 |
+
}
|
src/app/interface/panel/index.tsx
CHANGED
|
@@ -1,7 +1,7 @@
|
|
| 1 |
"use client"
|
| 2 |
|
| 3 |
import { useEffect, useRef, useState, useTransition } from "react"
|
| 4 |
-
import { RxReload } from "react-icons/rx"
|
| 5 |
|
| 6 |
import { RenderedScene } from "@/types"
|
| 7 |
|
|
@@ -11,6 +11,7 @@ import { useStore } from "@/app/store"
|
|
| 11 |
import { cn } from "@/lib/utils"
|
| 12 |
import { getInitialRenderedScene } from "@/lib/getInitialRenderedScene"
|
| 13 |
import { Progress } from "@/app/interface/progress"
|
|
|
|
| 14 |
|
| 15 |
export function Panel({
|
| 16 |
page,
|
|
@@ -54,6 +55,8 @@ export function Panel({
|
|
| 54 |
const panels = useStore(state => state.panels)
|
| 55 |
const prompt = panels[panelIndex] || ""
|
| 56 |
|
|
|
|
|
|
|
| 57 |
const captions = useStore(state => state.captions)
|
| 58 |
const caption = captions[panelIndex] || ""
|
| 59 |
|
|
@@ -266,6 +269,12 @@ export function Panel({
|
|
| 266 |
setRevision(revision + 1)
|
| 267 |
}
|
| 268 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 269 |
if (prompt && !rendered.assetUrl) {
|
| 270 |
return (
|
| 271 |
<div className={cn(
|
|
@@ -341,7 +350,7 @@ export function Panel({
|
|
| 341 |
// process.env.NEXT_PUBLIC_CAN_REDRAW === "true" ?
|
| 342 |
<div
|
| 343 |
className={cn(`relative -mt-14 ml-4`,)}>
|
| 344 |
-
<div className="flex flex-row">
|
| 345 |
<div
|
| 346 |
onClick={rendered.status === "completed" ? handleReload : undefined}
|
| 347 |
className={cn(
|
|
@@ -355,8 +364,29 @@ export function Panel({
|
|
| 355 |
<RxReload
|
| 356 |
className="w-5 h-5"
|
| 357 |
/>
|
| 358 |
-
<span className="text-
|
| 359 |
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 360 |
</div>
|
| 361 |
</div>
|
| 362 |
//: null
|
|
|
|
| 1 |
"use client"
|
| 2 |
|
| 3 |
import { useEffect, useRef, useState, useTransition } from "react"
|
| 4 |
+
import { RxReload, RxPencil2 } from "react-icons/rx"
|
| 5 |
|
| 6 |
import { RenderedScene } from "@/types"
|
| 7 |
|
|
|
|
| 11 |
import { cn } from "@/lib/utils"
|
| 12 |
import { getInitialRenderedScene } from "@/lib/getInitialRenderedScene"
|
| 13 |
import { Progress } from "@/app/interface/progress"
|
| 14 |
+
import { EditModal } from "../edit-modal"
|
| 15 |
|
| 16 |
export function Panel({
|
| 17 |
page,
|
|
|
|
| 55 |
const panels = useStore(state => state.panels)
|
| 56 |
const prompt = panels[panelIndex] || ""
|
| 57 |
|
| 58 |
+
const setPanelPrompt = useStore(state => state.setPanelPrompt)
|
| 59 |
+
|
| 60 |
const captions = useStore(state => state.captions)
|
| 61 |
const caption = captions[panelIndex] || ""
|
| 62 |
|
|
|
|
| 269 |
setRevision(revision + 1)
|
| 270 |
}
|
| 271 |
|
| 272 |
+
|
| 273 |
+
const handleSavePrompt = (newPrompt: string) => {
|
| 274 |
+
console.log(`Asked to save a new prompt: ${newPrompt}`)
|
| 275 |
+
setPanelPrompt(newPrompt, panelIndex)
|
| 276 |
+
}
|
| 277 |
+
|
| 278 |
if (prompt && !rendered.assetUrl) {
|
| 279 |
return (
|
| 280 |
<div className={cn(
|
|
|
|
| 350 |
// process.env.NEXT_PUBLIC_CAN_REDRAW === "true" ?
|
| 351 |
<div
|
| 352 |
className={cn(`relative -mt-14 ml-4`,)}>
|
| 353 |
+
<div className="flex flex-row space-x-2">
|
| 354 |
<div
|
| 355 |
onClick={rendered.status === "completed" ? handleReload : undefined}
|
| 356 |
className={cn(
|
|
|
|
| 364 |
<RxReload
|
| 365 |
className="w-5 h-5"
|
| 366 |
/>
|
| 367 |
+
<span className="text-sm">Redraw</span>
|
| 368 |
</div>
|
| 369 |
+
<EditModal
|
| 370 |
+
isEnabled={rendered.status === "completed"}
|
| 371 |
+
existingPrompt={prompt}
|
| 372 |
+
onSave={handleSavePrompt}
|
| 373 |
+
>
|
| 374 |
+
<div
|
| 375 |
+
className={cn(
|
| 376 |
+
`bg-stone-100 rounded-lg`,
|
| 377 |
+
`flex flex-row space-x-2 items-center`,
|
| 378 |
+
`py-2 px-3 cursor-pointer`,
|
| 379 |
+
`transition-all duration-200 ease-in-out`,
|
| 380 |
+
rendered.status === "completed" ? "opacity-95" : "opacity-50",
|
| 381 |
+
mouseOver && rendered.assetUrl ? `scale-95 hover:scale-100 hover:opacity-100`: `scale-0`
|
| 382 |
+
)}>
|
| 383 |
+
<RxPencil2
|
| 384 |
+
className="w-5 h-5"
|
| 385 |
+
/>
|
| 386 |
+
<span className="text-sm">Edit</span>
|
| 387 |
+
</div>
|
| 388 |
+
|
| 389 |
+
</EditModal>
|
| 390 |
</div>
|
| 391 |
</div>
|
| 392 |
//: null
|
src/app/store/index.ts
CHANGED
|
@@ -35,6 +35,7 @@ export const useStore = create<{
|
|
| 35 |
setFont: (font: FontName) => void
|
| 36 |
setPreset: (preset: Preset) => void
|
| 37 |
setPanels: (panels: string[]) => void
|
|
|
|
| 38 |
setShowCaptions: (showCaptions: boolean) => void
|
| 39 |
setLayout: (layout: LayoutName) => void
|
| 40 |
setLayouts: (layouts: LayoutName[]) => void
|
|
@@ -116,6 +117,14 @@ export const useStore = create<{
|
|
| 116 |
})
|
| 117 |
},
|
| 118 |
setPanels: (panels: string[]) => set({ panels }),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 119 |
setCaptions: (captions: string[]) => {
|
| 120 |
set({
|
| 121 |
captions,
|
|
|
|
| 35 |
setFont: (font: FontName) => void
|
| 36 |
setPreset: (preset: Preset) => void
|
| 37 |
setPanels: (panels: string[]) => void
|
| 38 |
+
setPanelPrompt: (newPrompt: string, index: number) => void
|
| 39 |
setShowCaptions: (showCaptions: boolean) => void
|
| 40 |
setLayout: (layout: LayoutName) => void
|
| 41 |
setLayouts: (layouts: LayoutName[]) => void
|
|
|
|
| 117 |
})
|
| 118 |
},
|
| 119 |
setPanels: (panels: string[]) => set({ panels }),
|
| 120 |
+
setPanelPrompt: (newPrompt, index) => {
|
| 121 |
+
const { panels } = get()
|
| 122 |
+
set({
|
| 123 |
+
panels: panels.map((p, i) => (
|
| 124 |
+
index === i ? newPrompt : p
|
| 125 |
+
))
|
| 126 |
+
})
|
| 127 |
+
},
|
| 128 |
setCaptions: (captions: string[]) => {
|
| 129 |
set({
|
| 130 |
captions,
|