Spaces:
Sleeping
Sleeping
Julian Bilcke
commited on
Commit
·
f309083
1
Parent(s):
8e2433b
better captions
Browse files- package-lock.json +35 -0
- package.json +2 -0
- src/app/interface/panel/bubble/index.tsx +104 -0
- src/app/interface/panel/{bubble.tsx → bubble/legacy.tsx} +1 -1
- src/app/interface/panel/index.tsx +45 -62
- src/app/queries/getStory.ts +2 -2
- src/app/store/index.ts +9 -0
package-lock.json
CHANGED
|
@@ -49,7 +49,9 @@
|
|
| 49 |
"postcss": "8.4.26",
|
| 50 |
"react": "18.2.0",
|
| 51 |
"react-circular-progressbar": "^2.1.0",
|
|
|
|
| 52 |
"react-dom": "18.2.0",
|
|
|
|
| 53 |
"react-icons": "^4.11.0",
|
| 54 |
"react-konva": "^18.2.10",
|
| 55 |
"react-virtualized-auto-sizer": "^1.0.20",
|
|
@@ -5947,6 +5949,18 @@
|
|
| 5947 |
"react": "^0.14.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0"
|
| 5948 |
}
|
| 5949 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5950 |
"node_modules/react-dom": {
|
| 5951 |
"version": "18.2.0",
|
| 5952 |
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
|
|
@@ -5967,6 +5981,27 @@
|
|
| 5967 |
"loose-envify": "^1.1.0"
|
| 5968 |
}
|
| 5969 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 5970 |
"node_modules/react-icons": {
|
| 5971 |
"version": "4.11.0",
|
| 5972 |
"resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.11.0.tgz",
|
|
|
|
| 49 |
"postcss": "8.4.26",
|
| 50 |
"react": "18.2.0",
|
| 51 |
"react-circular-progressbar": "^2.1.0",
|
| 52 |
+
"react-contenteditable": "^3.3.7",
|
| 53 |
"react-dom": "18.2.0",
|
| 54 |
+
"react-draggable": "^4.4.6",
|
| 55 |
"react-icons": "^4.11.0",
|
| 56 |
"react-konva": "^18.2.10",
|
| 57 |
"react-virtualized-auto-sizer": "^1.0.20",
|
|
|
|
| 5949 |
"react": "^0.14.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0"
|
| 5950 |
}
|
| 5951 |
},
|
| 5952 |
+
"node_modules/react-contenteditable": {
|
| 5953 |
+
"version": "3.3.7",
|
| 5954 |
+
"resolved": "https://registry.npmjs.org/react-contenteditable/-/react-contenteditable-3.3.7.tgz",
|
| 5955 |
+
"integrity": "sha512-GA9NbC0DkDdpN3iGvib/OMHWTJzDX2cfkgy5Tt98JJAbA3kLnyrNbBIpsSpPpq7T8d3scD39DHP+j8mAM7BIfQ==",
|
| 5956 |
+
"dependencies": {
|
| 5957 |
+
"fast-deep-equal": "^3.1.3",
|
| 5958 |
+
"prop-types": "^15.7.1"
|
| 5959 |
+
},
|
| 5960 |
+
"peerDependencies": {
|
| 5961 |
+
"react": ">=16.3"
|
| 5962 |
+
}
|
| 5963 |
+
},
|
| 5964 |
"node_modules/react-dom": {
|
| 5965 |
"version": "18.2.0",
|
| 5966 |
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
|
|
|
|
| 5981 |
"loose-envify": "^1.1.0"
|
| 5982 |
}
|
| 5983 |
},
|
| 5984 |
+
"node_modules/react-draggable": {
|
| 5985 |
+
"version": "4.4.6",
|
| 5986 |
+
"resolved": "https://registry.npmjs.org/react-draggable/-/react-draggable-4.4.6.tgz",
|
| 5987 |
+
"integrity": "sha512-LtY5Xw1zTPqHkVmtM3X8MUOxNDOUhv/khTgBgrUvwaS064bwVvxT+q5El0uUFNx5IEPKXuRejr7UqLwBIg5pdw==",
|
| 5988 |
+
"dependencies": {
|
| 5989 |
+
"clsx": "^1.1.1",
|
| 5990 |
+
"prop-types": "^15.8.1"
|
| 5991 |
+
},
|
| 5992 |
+
"peerDependencies": {
|
| 5993 |
+
"react": ">= 16.3.0",
|
| 5994 |
+
"react-dom": ">= 16.3.0"
|
| 5995 |
+
}
|
| 5996 |
+
},
|
| 5997 |
+
"node_modules/react-draggable/node_modules/clsx": {
|
| 5998 |
+
"version": "1.2.1",
|
| 5999 |
+
"resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz",
|
| 6000 |
+
"integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==",
|
| 6001 |
+
"engines": {
|
| 6002 |
+
"node": ">=6"
|
| 6003 |
+
}
|
| 6004 |
+
},
|
| 6005 |
"node_modules/react-icons": {
|
| 6006 |
"version": "4.11.0",
|
| 6007 |
"resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.11.0.tgz",
|
package.json
CHANGED
|
@@ -50,7 +50,9 @@
|
|
| 50 |
"postcss": "8.4.26",
|
| 51 |
"react": "18.2.0",
|
| 52 |
"react-circular-progressbar": "^2.1.0",
|
|
|
|
| 53 |
"react-dom": "18.2.0",
|
|
|
|
| 54 |
"react-icons": "^4.11.0",
|
| 55 |
"react-konva": "^18.2.10",
|
| 56 |
"react-virtualized-auto-sizer": "^1.0.20",
|
|
|
|
| 50 |
"postcss": "8.4.26",
|
| 51 |
"react": "18.2.0",
|
| 52 |
"react-circular-progressbar": "^2.1.0",
|
| 53 |
+
"react-contenteditable": "^3.3.7",
|
| 54 |
"react-dom": "18.2.0",
|
| 55 |
+
"react-draggable": "^4.4.6",
|
| 56 |
"react-icons": "^4.11.0",
|
| 57 |
"react-konva": "^18.2.10",
|
| 58 |
"react-virtualized-auto-sizer": "^1.0.20",
|
src/app/interface/panel/bubble/index.tsx
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"use client"
|
| 2 |
+
|
| 3 |
+
import { ReactNode, useRef } from "react"
|
| 4 |
+
|
| 5 |
+
// import Draggable from "react-draggable"
|
| 6 |
+
import ContentEditable, { ContentEditableEvent } from "react-contenteditable"
|
| 7 |
+
|
| 8 |
+
import { useStore } from "@/app/store"
|
| 9 |
+
import { cn } from "@/lib/utils"
|
| 10 |
+
|
| 11 |
+
export function Bubble({ children, onChange }: {
|
| 12 |
+
children: ReactNode;
|
| 13 |
+
onChange: (newCaption: string) => void
|
| 14 |
+
}) {
|
| 15 |
+
|
| 16 |
+
const ref = useRef<HTMLDivElement>(null)
|
| 17 |
+
const zoomLevel = useStore(state => state.zoomLevel)
|
| 18 |
+
const showCaptions = useStore(state => state.showCaptions)
|
| 19 |
+
|
| 20 |
+
const text = useRef(`${children || ''}`)
|
| 21 |
+
|
| 22 |
+
const handleChange = (evt: ContentEditableEvent) => {
|
| 23 |
+
// hmm no, this returns us some rich HTML - but it's too early for that
|
| 24 |
+
// text.current = evt.target.value
|
| 25 |
+
|
| 26 |
+
text.current = `${ref.current?.innerText || ''}`
|
| 27 |
+
};
|
| 28 |
+
|
| 29 |
+
const handleBlur = () => {
|
| 30 |
+
onChange(text.current)
|
| 31 |
+
};
|
| 32 |
+
|
| 33 |
+
// we can wrap this bubble in a <Draggable>
|
| 34 |
+
// but the zoom will break it, so we will need to figure out something
|
| 35 |
+
return (
|
| 36 |
+
<div className={cn(
|
| 37 |
+
`bottom-0`,
|
| 38 |
+
// `cursor-grab`,
|
| 39 |
+
`absolute flex w-full items-center justify-center`,
|
| 40 |
+
zoomLevel > 200 ? `p-4 md:p-8` :
|
| 41 |
+
zoomLevel > 180 ? `p-[14px] md:p-8` :
|
| 42 |
+
zoomLevel > 160 ? `p-[12px] md:p-[28px]` :
|
| 43 |
+
zoomLevel > 140 ? `p-[10px] md:p-[26px]` :
|
| 44 |
+
zoomLevel > 120 ? `p-2 md:p-6` :
|
| 45 |
+
zoomLevel > 100 ? `p-1.5 md:p-[20px]` :
|
| 46 |
+
zoomLevel > 90 ? `p-1.5 md:p-4` :
|
| 47 |
+
zoomLevel > 40 ? `p-1 md:p-2` :
|
| 48 |
+
`p-0.5 md:p-2`,
|
| 49 |
+
)}>
|
| 50 |
+
<div
|
| 51 |
+
ref={ref}
|
| 52 |
+
className={cn(
|
| 53 |
+
`bg-stone-50`,
|
| 54 |
+
`border-stone-800`,
|
| 55 |
+
`transition-all duration-200 ease-in-out`,
|
| 56 |
+
zoomLevel > 140 ? `border-[1.5px] md:border-[2px]` :
|
| 57 |
+
zoomLevel > 120 ? `border-[1px] md:border-[1.5px]` :
|
| 58 |
+
zoomLevel > 90 ? `border-[0.5px] md:border-[1px]` :
|
| 59 |
+
zoomLevel > 40 ? `border-transparent md:border-[0.5px]` :
|
| 60 |
+
`border-transparent md:border-transparent`,
|
| 61 |
+
`print:border-[1px]`,
|
| 62 |
+
|
| 63 |
+
zoomLevel > 200 ? `p-4 md:p-8` :
|
| 64 |
+
zoomLevel > 180 ? `p-[14px] md:p-6` :
|
| 65 |
+
zoomLevel > 160 ? `p-3 md:p-5` :
|
| 66 |
+
zoomLevel > 140 ? `p-[10px] md:p-4` :
|
| 67 |
+
zoomLevel > 120 ? `p-2 md:p-3` :
|
| 68 |
+
zoomLevel > 100 ? `p-1.5 md:p-2` :
|
| 69 |
+
zoomLevel > 90 ? `p-1 md:p-1` :
|
| 70 |
+
zoomLevel > 40 ? `p-0.5 md:p-0.5` :
|
| 71 |
+
`p-0.5 md:p-0.5]`,
|
| 72 |
+
|
| 73 |
+
zoomLevel > 220 ? `text-base md:text-lg` :
|
| 74 |
+
zoomLevel > 200 ? `text-sm md:text-md` :
|
| 75 |
+
zoomLevel > 180 ? `text-xs md:text-base` :
|
| 76 |
+
zoomLevel > 140 ? `text-2xs md:text-sm` :
|
| 77 |
+
zoomLevel > 120 ? `text-3xs md:text-xs` :
|
| 78 |
+
zoomLevel > 100 ? `text-4xs md:text-2xs` :
|
| 79 |
+
zoomLevel > 90 ? `text-5xs md:text-3xs` :
|
| 80 |
+
zoomLevel > 40 ? `text-6xs md:text-4xs`
|
| 81 |
+
: `text-7xs md:text-5xs`,
|
| 82 |
+
|
| 83 |
+
zoomLevel > 140 ? `rounded-lg md:rounded-xl` :
|
| 84 |
+
zoomLevel > 120 ? `rounded-md md:rounded-lg` :
|
| 85 |
+
zoomLevel > 90 ? `rounded-sm md:rounded-md` :
|
| 86 |
+
zoomLevel > 40 ? `rounded-xs md:rounded-sm` :
|
| 87 |
+
`rounded-none md:rounded-none`,
|
| 88 |
+
|
| 89 |
+
showCaptions ? (
|
| 90 |
+
zoomLevel > 90 ? `block` : `hidden md:block`
|
| 91 |
+
) : `hidden`,
|
| 92 |
+
|
| 93 |
+
`text-center`
|
| 94 |
+
)}>
|
| 95 |
+
<ContentEditable
|
| 96 |
+
html={text.current}
|
| 97 |
+
className="line-clamp-3"
|
| 98 |
+
onBlur={handleBlur}
|
| 99 |
+
onChange={handleChange}
|
| 100 |
+
/>
|
| 101 |
+
</div>
|
| 102 |
+
</div>
|
| 103 |
+
)
|
| 104 |
+
}
|
src/app/interface/panel/{bubble.tsx → bubble/legacy.tsx}
RENAMED
|
@@ -2,7 +2,7 @@ import { ReactNode } from "react"
|
|
| 2 |
|
| 3 |
import { cn } from "@/lib/utils"
|
| 4 |
|
| 5 |
-
export function
|
| 6 |
children,
|
| 7 |
className
|
| 8 |
}: {
|
|
|
|
| 2 |
|
| 3 |
import { cn } from "@/lib/utils"
|
| 4 |
|
| 5 |
+
export function BubbleLegacy({
|
| 6 |
children,
|
| 7 |
className
|
| 8 |
}: {
|
src/app/interface/panel/index.tsx
CHANGED
|
@@ -12,6 +12,7 @@ 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,
|
|
@@ -59,9 +60,9 @@ export function Panel({
|
|
| 59 |
|
| 60 |
const captions = useStore(state => state.captions)
|
| 61 |
const caption = captions[panelIndex] || ""
|
| 62 |
-
|
|
|
|
| 63 |
const zoomLevel = useStore(state => state.zoomLevel)
|
| 64 |
-
const showCaptions = useStore(state => state.showCaptions)
|
| 65 |
|
| 66 |
const addToUpscaleQueue = useStore(state => state.addToUpscaleQueue)
|
| 67 |
|
|
@@ -251,6 +252,7 @@ export function Panel({
|
|
| 251 |
|
| 252 |
const frameClassName = cn(
|
| 253 |
//`flex`,
|
|
|
|
| 254 |
`w-full h-full`,
|
| 255 |
`border-stone-800`,
|
| 256 |
`transition-all duration-200 ease-in-out`,
|
|
@@ -275,6 +277,10 @@ export function Panel({
|
|
| 275 |
setPanelPrompt(newPrompt, panelIndex)
|
| 276 |
}
|
| 277 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 278 |
if (prompt && !rendered.assetUrl) {
|
| 279 |
return (
|
| 280 |
<div className={cn(
|
|
@@ -296,61 +302,16 @@ export function Panel({
|
|
| 296 |
onMouseEnter={() => setMouseOver(true)}
|
| 297 |
onMouseLeave={() => setMouseOver(false)}
|
| 298 |
>
|
| 299 |
-
|
| 300 |
-
|
| 301 |
-
|
| 302 |
-
|
| 303 |
-
zoomLevel > 140 ? `border-b-[2px] md:border-b-[4px]` :
|
| 304 |
-
zoomLevel > 120 ? `border-b-[1.5px] md:border-b-[3px]` :
|
| 305 |
-
zoomLevel > 90 ? `border-b-[1px] md:border-b-[2px]` :
|
| 306 |
-
zoomLevel > 40 ? `border-b-[0.5px] md:border-b-[1px]` :
|
| 307 |
-
`border-transparent md:border-b-[0.5px]`,
|
| 308 |
-
`print:border-b-[1.5px]`,
|
| 309 |
-
`truncate`,
|
| 310 |
-
|
| 311 |
-
zoomLevel > 200 ? `p-4 md:p-8` :
|
| 312 |
-
zoomLevel > 180 ? `p-[14px] md:p-8` :
|
| 313 |
-
zoomLevel > 160 ? `p-[12px] md:p-[28px]` :
|
| 314 |
-
zoomLevel > 140 ? `p-[10px] md:p-[26px]` :
|
| 315 |
-
zoomLevel > 120 ? `p-2 md:p-6` :
|
| 316 |
-
zoomLevel > 100 ? `p-1.5 md:p-[20px]` :
|
| 317 |
-
zoomLevel > 90 ? `p-1.5 md:p-4` :
|
| 318 |
-
zoomLevel > 40 ? `p-1 md:p-2` :
|
| 319 |
-
`p-0.5 md:p-2`,
|
| 320 |
-
|
| 321 |
-
zoomLevel > 220 ? `text-xl md:text-4xl` :
|
| 322 |
-
zoomLevel > 200 ? `text-lg md:text-3xl` :
|
| 323 |
-
zoomLevel > 180 ? `text-md md:text-2xl` :
|
| 324 |
-
zoomLevel > 140 ? `text-2xs md:text-2xl` :
|
| 325 |
-
zoomLevel > 120 ? `text-3xs md:text-xl` :
|
| 326 |
-
zoomLevel > 100 ? `text-4xs md:text-lg` :
|
| 327 |
-
zoomLevel > 90 ? `text-5xs md:text-sm` :
|
| 328 |
-
zoomLevel > 40 ? `md:text-xs` : `md:text-2xs`,
|
| 329 |
-
|
| 330 |
-
showCaptions ? (
|
| 331 |
-
zoomLevel > 90 ? `block` : `hidden md:block`
|
| 332 |
-
) : `hidden`,
|
| 333 |
-
)}
|
| 334 |
-
>{caption || ""}
|
| 335 |
-
</div>
|
| 336 |
-
{rendered.assetUrl &&
|
| 337 |
-
<img
|
| 338 |
-
ref={ref}
|
| 339 |
-
src={rendered.assetUrl}
|
| 340 |
-
width={width}
|
| 341 |
-
height={height}
|
| 342 |
-
alt={rendered.alt}
|
| 343 |
className={cn(
|
| 344 |
-
`
|
| 345 |
-
|
| 346 |
-
|
| 347 |
-
|
| 348 |
-
|
| 349 |
-
// there is an issue, this env check doesn't work..
|
| 350 |
-
// process.env.NEXT_PUBLIC_CAN_REDRAW === "true" ?
|
| 351 |
-
<div
|
| 352 |
-
className={cn(`relative -mt-8 ml-2 md:-mt-12md:ml-3 lg:-mt-14 lg:ml-4`,)}>
|
| 353 |
-
<div className="flex flex-row space-x-2">
|
| 354 |
<div
|
| 355 |
onClick={rendered.status === "completed" ? handleReload : undefined}
|
| 356 |
className={cn(
|
|
@@ -364,7 +325,13 @@ export function Panel({
|
|
| 364 |
<RxReload
|
| 365 |
className="w-3 h-3 md:w-4 md:h-4 lg:w-5 lg:h-5"
|
| 366 |
/>
|
| 367 |
-
<span className=
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 368 |
</div>
|
| 369 |
<EditModal
|
| 370 |
isEnabled={rendered.status === "completed"}
|
|
@@ -383,14 +350,30 @@ export function Panel({
|
|
| 383 |
<RxPencil2
|
| 384 |
className="w-3 h-3 md:w-4 md:h-4 lg:w-5 lg:h-5"
|
| 385 |
/>
|
| 386 |
-
<span className=
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 387 |
</div>
|
| 388 |
|
| 389 |
</EditModal>
|
| 390 |
-
|
| 391 |
-
|
| 392 |
-
|
| 393 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 394 |
</div>
|
| 395 |
)
|
| 396 |
}
|
|
|
|
| 12 |
import { getInitialRenderedScene } from "@/lib/getInitialRenderedScene"
|
| 13 |
import { Progress } from "@/app/interface/progress"
|
| 14 |
import { EditModal } from "../edit-modal"
|
| 15 |
+
import { Bubble } from "./bubble"
|
| 16 |
|
| 17 |
export function Panel({
|
| 18 |
page,
|
|
|
|
| 60 |
|
| 61 |
const captions = useStore(state => state.captions)
|
| 62 |
const caption = captions[panelIndex] || ""
|
| 63 |
+
const setPanelCaption = useStore(state => state.setPanelCaption)
|
| 64 |
+
|
| 65 |
const zoomLevel = useStore(state => state.zoomLevel)
|
|
|
|
| 66 |
|
| 67 |
const addToUpscaleQueue = useStore(state => state.addToUpscaleQueue)
|
| 68 |
|
|
|
|
| 252 |
|
| 253 |
const frameClassName = cn(
|
| 254 |
//`flex`,
|
| 255 |
+
`relative`,
|
| 256 |
`w-full h-full`,
|
| 257 |
`border-stone-800`,
|
| 258 |
`transition-all duration-200 ease-in-out`,
|
|
|
|
| 277 |
setPanelPrompt(newPrompt, panelIndex)
|
| 278 |
}
|
| 279 |
|
| 280 |
+
const handleSaveCaption = (newCaption: string) => {
|
| 281 |
+
console.log(`Asked to save a new caption: ${newCaption}`)
|
| 282 |
+
setPanelCaption(newCaption, panelIndex)
|
| 283 |
+
}
|
| 284 |
if (prompt && !rendered.assetUrl) {
|
| 285 |
return (
|
| 286 |
<div className={cn(
|
|
|
|
| 302 |
onMouseEnter={() => setMouseOver(true)}
|
| 303 |
onMouseLeave={() => setMouseOver(false)}
|
| 304 |
>
|
| 305 |
+
{(prompt && rendered.assetUrl && caption)
|
| 306 |
+
? <Bubble onChange={handleSaveCaption}>{caption}</Bubble>
|
| 307 |
+
: null}
|
| 308 |
+
<div
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 309 |
className={cn(
|
| 310 |
+
`absolute`,
|
| 311 |
+
`top-0 w-full`,
|
| 312 |
+
`flex justify-between`,
|
| 313 |
+
`p-2 space-x-2`
|
| 314 |
+
)}>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 315 |
<div
|
| 316 |
onClick={rendered.status === "completed" ? handleReload : undefined}
|
| 317 |
className={cn(
|
|
|
|
| 325 |
<RxReload
|
| 326 |
className="w-3 h-3 md:w-4 md:h-4 lg:w-5 lg:h-5"
|
| 327 |
/>
|
| 328 |
+
<span className={cn(
|
| 329 |
+
zoomLevel > 80
|
| 330 |
+
? `text-xs md:text-sm lg:text-base` :
|
| 331 |
+
zoomLevel > 40
|
| 332 |
+
? `text-2xs md:text-xs lg:text-sm` :
|
| 333 |
+
`text-3xs md:text-2xs lg:text-xs`
|
| 334 |
+
)}>Redraw</span>
|
| 335 |
</div>
|
| 336 |
<EditModal
|
| 337 |
isEnabled={rendered.status === "completed"}
|
|
|
|
| 350 |
<RxPencil2
|
| 351 |
className="w-3 h-3 md:w-4 md:h-4 lg:w-5 lg:h-5"
|
| 352 |
/>
|
| 353 |
+
<span className={cn(
|
| 354 |
+
zoomLevel > 80
|
| 355 |
+
? `text-xs md:text-sm lg:text-base` :
|
| 356 |
+
zoomLevel > 40
|
| 357 |
+
? `text-2xs md:text-xs lg:text-sm` :
|
| 358 |
+
`text-3xs md:text-2xs lg:text-xs`
|
| 359 |
+
)}>Edit</span>
|
| 360 |
</div>
|
| 361 |
|
| 362 |
</EditModal>
|
| 363 |
+
</div>
|
| 364 |
+
|
| 365 |
+
{rendered.assetUrl &&
|
| 366 |
+
<img
|
| 367 |
+
ref={ref}
|
| 368 |
+
src={rendered.assetUrl}
|
| 369 |
+
width={width}
|
| 370 |
+
height={height}
|
| 371 |
+
alt={rendered.alt}
|
| 372 |
+
className={cn(
|
| 373 |
+
`comic-panel w-full h-full object-cover max-w-max`,
|
| 374 |
+
// showCaptions ? `-mt-11` : ''
|
| 375 |
+
)}
|
| 376 |
+
/>}
|
| 377 |
</div>
|
| 378 |
)
|
| 379 |
}
|
src/app/queries/getStory.ts
CHANGED
|
@@ -27,10 +27,10 @@ export const getStory = async ({
|
|
| 27 |
role: "system",
|
| 28 |
content: [
|
| 29 |
`You are a writer specialized in ${preset.llmPrompt}`,
|
| 30 |
-
`Please write detailed drawing instructions and a
|
| 31 |
`Give your response as a VALID JSON array like this: \`Array<{ panel: number; instructions: string; caption: string}>\`.`,
|
| 32 |
// `Give your response as Markdown bullet points.`,
|
| 33 |
-
`Be brief in your ${nbTotalPanels} instructions and captions, don't add your own comments. Be straight to the point, and never reply things like "Sure, I can.." etc. Reply using valid JSON.`
|
| 34 |
].filter(item => item).join("\n")
|
| 35 |
},
|
| 36 |
{
|
|
|
|
| 27 |
role: "system",
|
| 28 |
content: [
|
| 29 |
`You are a writer specialized in ${preset.llmPrompt}`,
|
| 30 |
+
`Please write detailed drawing instructions and a short (1 or 2 sentences long) speech caption for the ${nbTotalPanels} panels of a new story. Please make sure each of the ${nbTotalPanels} panels include info about character gender, age, origin, clothes, colors, location, lights, etc.`,
|
| 31 |
`Give your response as a VALID JSON array like this: \`Array<{ panel: number; instructions: string; caption: string}>\`.`,
|
| 32 |
// `Give your response as Markdown bullet points.`,
|
| 33 |
+
`Be brief in your ${nbTotalPanels} instructions and narrative captions, don't add your own comments. Be straight to the point, and never reply things like "Sure, I can.." etc. Reply using valid JSON.`
|
| 34 |
].filter(item => item).join("\n")
|
| 35 |
},
|
| 36 |
{
|
src/app/store/index.ts
CHANGED
|
@@ -40,6 +40,7 @@ export const useStore = create<{
|
|
| 40 |
setLayout: (layout: LayoutName) => void
|
| 41 |
setLayouts: (layouts: LayoutName[]) => void
|
| 42 |
setCaptions: (captions: string[]) => void
|
|
|
|
| 43 |
setZoomLevel: (zoomLevel: number) => void
|
| 44 |
setPage: (page: HTMLDivElement) => void
|
| 45 |
setGeneratingStory: (isGeneratingStory: boolean) => void
|
|
@@ -135,6 +136,14 @@ export const useStore = create<{
|
|
| 135 |
showCaptions,
|
| 136 |
})
|
| 137 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 138 |
setLayout: (layoutName: LayoutName) => {
|
| 139 |
|
| 140 |
const { nbPages } = get()
|
|
|
|
| 40 |
setLayout: (layout: LayoutName) => void
|
| 41 |
setLayouts: (layouts: LayoutName[]) => void
|
| 42 |
setCaptions: (captions: string[]) => void
|
| 43 |
+
setPanelCaption: (newCaption: string, index: number) => void
|
| 44 |
setZoomLevel: (zoomLevel: number) => void
|
| 45 |
setPage: (page: HTMLDivElement) => void
|
| 46 |
setGeneratingStory: (isGeneratingStory: boolean) => void
|
|
|
|
| 136 |
showCaptions,
|
| 137 |
})
|
| 138 |
},
|
| 139 |
+
setPanelCaption: (newCaption, index) => {
|
| 140 |
+
const { captions } = get()
|
| 141 |
+
set({
|
| 142 |
+
captions: captions.map((c, i) => (
|
| 143 |
+
index === i ? newCaption : c
|
| 144 |
+
))
|
| 145 |
+
})
|
| 146 |
+
},
|
| 147 |
setLayout: (layoutName: LayoutName) => {
|
| 148 |
|
| 149 |
const { nbPages } = get()
|