File size: 4,614 Bytes
dbc8f44 ec121fd f5d8038 b724e18 6cc7c15 11d758a dbc8f44 b6caea7 dbc8f44 b6caea7 dbc8f44 a40bf40 f5d8038 61bb967 f5d8038 61bb967 f5d8038 61bb967 a40bf40 6cc7c15 dbc8f44 a40bf40 ec121fd dbc8f44 719ed9c dbc8f44 ec121fd 719ed9c ec121fd b724e18 ec121fd 719ed9c ec121fd 11d758a f5d8038 11d758a 5dd2af5 ec121fd f5d8038 ec121fd f5d8038 ec121fd 5dd2af5 6cc7c15 5dd2af5 6cc7c15 b6caea7 dbc8f44 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
import { useStore } from "@/app/store"
import { Button } from "@/components/ui/button"
import { cn } from "@/lib/utils"
import { About } from "../about"
import { startTransition, useState } from "react"
import { upscaleImage } from "@/app/engine/render"
import { sleep } from "@/lib/sleep"
import { AIClipFactory } from "../ai-clip-factory"
import { Share } from "../share"
import { SettingsDialog } from "../settings-dialog"
export function BottomBar() {
const download = useStore(state => state.download)
const isGeneratingStory = useStore(state => state.isGeneratingStory)
const prompt = useStore(state => state.prompt)
const panelGenerationStatus = useStore(state => state.panelGenerationStatus)
const page = useStore(state => state.page)
const preset = useStore(state => state.preset)
const pageToImage = useStore(state => state.pageToImage)
const allStatus = Object.values(panelGenerationStatus)
const remainingImages = allStatus.reduce((acc, s) => (acc + (s ? 1 : 0)), 0)
const upscaleQueue = useStore(state => state.upscaleQueue)
const renderedScenes = useStore(state => state.renderedScenes)
const removeFromUpscaleQueue = useStore(state => state.removeFromUpscaleQueue)
const setRendered = useStore(state => state.setRendered)
const [isUpscaling, setUpscaling] = useState(false)
const handleUpscale = () => {
setUpscaling(true)
startTransition(() => {
const fn = async () => {
for (let [panelId, renderedScene] of Object.entries(upscaleQueue)) {
try {
console.log(`upscaling panel ${panelId} (${renderedScene.renderId})`)
const result = await upscaleImage(renderedScene.assetUrl)
await sleep(1000)
if (result.assetUrl) {
console.log(`upscale successful, removing ${panelId} (${renderedScene.renderId}) from upscale queue`)
setRendered(panelId, {
...renderedScene,
assetUrl: result.assetUrl
})
removeFromUpscaleQueue(panelId)
}
} catch (err) {
console.error(`failed to upscale: ${err}`)
}
}
setUpscaling(false)
}
fn()
})
}
const handlePrint = () => {
window.print()
}
return (
<div className={cn(
`print:hidden`,
`fixed bottom-2 md:bottom-4 left-2 right-0 md:left-3 md:right-1`,
`flex flex-row`,
`justify-between`,
`pointer-events-none`
)}>
<div className={cn(
`flex flex-row`,
`items-end`,
`pointer-events-auto`,
`animation-all duration-300 ease-in-out`,
isGeneratingStory ? `scale-0 opacity-0` : ``,
`space-x-3`,
`scale-[0.9]`
)}>
<About />
<AIClipFactory />
</div>
<div className={cn(
`flex flex-row`,
`pointer-events-auto`,
`animation-all duration-300 ease-in-out`,
isGeneratingStory ? `scale-0 opacity-0` : ``,
`space-x-3`,
`scale-[0.9]`
)}>
<SettingsDialog />
<Button
onClick={handleUpscale}
disabled={!prompt?.length || remainingImages > 0 || isUpscaling || !Object.values(upscaleQueue).length}
>
{isUpscaling
? `${allStatus.length - Object.values(upscaleQueue).length}/${allStatus.length} ⌛`
: "Upscale"}
</Button>
{/*
<div>
<Button
onClick={handlePrint}
disabled={!prompt?.length}
>
Print
</Button>
</div>
<div>
<Button
onClick={download}
disabled={!prompt?.length}
>
<span className="hidden md:inline">{
remainingImages ? `${allStatus.length - remainingImages}/${allStatus.length} panels ⌛` : `Save`
}</span>
<span className="inline md:hidden">{
remainingImages ? `${allStatus.length - remainingImages}/${allStatus.length} ⌛` : `Save`
}</span>
</Button>
</div>
*/}
<Button
onClick={handlePrint}
disabled={!prompt?.length}
>
<span className="hidden md:inline">{
remainingImages ? `${allStatus.length - remainingImages}/${allStatus.length} panels ⌛` : `Save PDF`
}</span>
<span className="inline md:hidden">{
remainingImages ? `${allStatus.length - remainingImages}/${allStatus.length} ⌛` : `Save`
}</span>
</Button>
<Share />
</div>
</div>
)
} |