Skip to content

Commit

Permalink
Imgck (#7)
Browse files Browse the repository at this point in the history
* add swr, backend fxns

* post

* gitignore

* progress...

* randomize colors

* cant get stdout to upload...binary to buffer no, binery to base64 no...

* need to add promise.all

* successful get layer images

* can i return multiple colors in same job? doing too much....

* success send of awaited object... need to now send one obj per color choice... another promise.all??

* success send of awaited object... need to now send one obj per color choice... another promise.all??

* no errors, have to check if everything is working right with new shape...

* success... might be duplicating same color in varieties though somehow... i.e. if requesting 3 varieties, they may be all the same for each image, not randomizing color on each iteration?

* better... more tings need to happen inside variety loop

* fixed error in gen, pass orig ids, create folders for each artworkid, with varieties inside

* adding coalesce and flatten

* rename some thangs and trycatch for better error handling on vercels server....methinks i cant download (curl) files from mocknstock storage
  • Loading branch information
Kiel-H-Byrne authored Jun 20, 2022
1 parent 9aac510 commit c86acab
Show file tree
Hide file tree
Showing 13 changed files with 606 additions and 128 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,5 @@ yarn-debug.log*
yarn-error.log*

/.idea
.next
.next
.tsbuildinfo
224 changes: 154 additions & 70 deletions components/App.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import {
Box,
SimpleGrid,
Image,
Center,
Button,
Expand All @@ -13,10 +12,13 @@ import {
GridItem,
FormHelperText,
Progress,
Divider,
Text,
} from "@chakra-ui/react"
import { nanoid } from "nanoid"
import { BaseSyntheticEvent, useState } from "react"
import { artworkSet, storeImage } from "./db/firebase"
import { updateArtworkSet, storeImage } from "./db/firebase"
import { ILayerData, IUploadedImage, IVarietyLeaf } from "./types"

//get length
const BASE_PATH = `/gallery/`
Expand All @@ -28,36 +30,30 @@ for (let index = 0; index < IMAGES.length; index++) {
}

function App() {
const [userImage, setUserImage] = useState(null)
const [userArtwork, setUserArtwork] = useState(null)
// const [imageURI, setImageURI] = useState("")
const [previewURI, setPreviewURI] = useState("")
const [errorMsg, setErrorMsg] = useState("")
const [projectId, setProjectId] = useState("")
const [uploadStatus, setUploadStatus] = useState("")
const [layerImages, setLayerImages] = useState([])
const [artworkLayers, setArtworkLayers] = useState([])
const [varietyMetadata, setVarietyMetadata] = useState([] as IVarietyLeaf[][])
const [metadata, setMetaData] = useState({} as Partial<ILayerData>)
const [fuzzNum, setFuzzNum] = useState(0)
const [colorsNum, setColorsNum] = useState(0)

type IUploadSettings = {
awid: string
imageUrl: string | undefined
fuzz: string
numDominantColorsToExtract: number
}

const onClickUpload = async () => {
setUploadStatus("STORING IMAGE...")
if (userImage) {
const imageUrl = await storeImage(userImage)
if (userArtwork) {
const imageUrl = await storeImage(userArtwork)
setUploadStatus("UPLOADING DOCUMENT....")
const awid = await artworkSet({ sourceImageUri: imageUrl })
const metadata = {
awid,
const _id = await updateArtworkSet({ imageUrl })
const metadata: Partial<IUploadedImage> = {
_id,
imageUrl,
fuzz: `${fuzzNum}%`,
numDominantColorsToExtract: colorsNum,
numDominantColorsToExtract: 6,
}
setProjectId(awid)
setProjectId(_id)
setUploadStatus("GETTING LAYERS....")
// uri && setImageURI(uri)
imageUrl && getLayers(metadata)
Expand All @@ -68,9 +64,9 @@ function App() {

const onFileInputChange = (e: BaseSyntheticEvent) => {
setPreviewURI("")
setUserImage(null)
setUserArtwork(null)
const file = e.target.files[0]
setUserImage(file)
setUserArtwork(file)
const reader = new FileReader()
reader.onload = (ev) =>
ev.target?.result && setPreviewURI(ev.target.result as string)
Expand All @@ -81,17 +77,17 @@ function App() {
}

const getLayers = async ({
awid,
_id, // original artwork/source id
imageUrl,
fuzz,
numDominantColorsToExtract,
}: IUploadSettings) => {
}: Partial<IUploadedImage>) => {
// post image to url, get response back,
// response is array of images and metadata
// Example POST method implementation:
// Default options are marked with *
setLayerImages([])
const data = {
setArtworkLayers([])
const data: Partial<IUploadedImage> = {
imageUrl,
fuzz,
numDominantColorsToExtract,
Expand All @@ -111,72 +107,114 @@ function App() {
// referrerPolicy: "no-referrer", // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
body: JSON.stringify(data), // body data type must match "Content-Type" header
})
.then((response) => {
if (!response.ok) {
return response
.text()
.then((result) => Promise.reject(new Error(result)))
.then((resp) => {
if (!resp.ok) {
return resp.text().then((result) => Promise.reject(new Error(result)))
}
setUploadStatus("DISPLAYING LAYERS....")
return response.json()
setUploadStatus("FETCHING LAYERS....")
return resp.json()
})
.then((data) => data)
.catch((err) => {
setErrorMsg("Error Fetching Layers: " + err.message)
console.error("error", err)
})
console.log(response)
setLayerImages(response.urls) // parses JSON response into native JavaScript objects
const layerData = response.urls.map((url: string, i: number) => ({
[response.dominantColors[i].hexCode]: {
depthNumber: 1,
imageUri: url,
rarity: "normal",

console.info("::-LAYERS RESPONSE-::")
console.info(response)
// setLayerImages(response.urls) // parses JSON response into native JavaScript objects

// const layerData: ILayerData = response.urls.map(
// (url: string, i: number) => ({
// hexCode: response.dominantColors[i].hexCode,
// _id: nanoid(),
// depthNumber: i,
// imageUri: url,
// rarity: "normal",
// colorVariety: 0,
// }),
// )
/**
* object with layer information.
* can change shape to array here
*/
const layerData: Partial<ILayerData> = response.urls.reduce(
(obj: any, url: string, i: number) => {
obj[response.dominantColors[i].hexCode] = {
_id: nanoid(),
_ogid: response.id,
_rid: _id,
depthNumber: i,
imageUri: url,
rarity: "normal",
colorVariety: 0,
varieties: {
// "rgba255_255_255_1": {}
},
}
return obj
},
}))
const ref = await artworkSet({ awid, layers: layerData })
setUploadStatus("")
{},
)
setArtworkLayers(response.urls)
setMetaData(layerData)
projectId && (await updateArtworkSet({ _id: projectId, layers: layerData })) // use swr here
}
const assembleImages = async () => {
// get urls of each layer, save to fs in certain way, then run generate script
const response = await fetch("./api/gen", {
/**
* sends an array of layer urls to server, receives and returns an array of objects containing metadata about each iteration, the source layer, etc.
* after randomizing layers, the next step is to randomly assemble each layer to create new images of N size.
*/
const randomizeLayers = async () => {
console.log("::-SENDING TO SERVER-::")
console.log(metadata)
//convert images but ideally recieve downloadURLs when finished...
console.log("projectId", projectId && projectId)
const response = (await fetch(`/api/gen`, {
method: "POST", // *GET, POST, PUT, DELETE, etc.
mode: "same-origin", // no-cors, *cors, same-origin
mode: "cors", // no-cors, *cors, same-origin
// cache: "no-cache", // *default, no-cache, reload, force-cache, only-if-cached
// credentials: "same-origin", // include, *same-origin, omit
headers: {
"Content-Type": "application/json",
},
// redirect: "follow", // manual, *follow, error
// referrerPolicy: "no-referrer", // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
body: JSON.stringify(layerImages), // body data type must match "Content-Type" header
body: JSON.stringify(metadata), // body data type must match "Content-Type" header
})
.then((response) => {
if (!response.ok) {
return response
.text()
.then((result) => Promise.reject(new Error(result)))
.then((resp) => {
if (!resp.ok) {
return resp.text().then((result) => Promise.reject(new Error(result)))
}
setUploadStatus("DISPLAYING LAYERS....")
return response.json()
setUploadStatus("RANDOMIZING LAYERS....")
return resp.json()
})
.then((data) => data)
.catch((err) => {
setErrorMsg("Error Fetching Layers: " + err.message)
setErrorMsg("Error Creating Layers: " + err.message)
console.error("error", err)
})
})) as IVarietyLeaf[][]

console.info("::-RANDOMIZATION RESPONSE-::")
console.log(response)
response?.length > 0 && setVarietyMetadata(response)
//response is an array or array of varieties, each with an array of varieties per layer
response?.forEach((layer) => {
const colorIndex = layer[0].origColorCode
metadata[colorIndex]!.varieties = {
[layer[0].newColorCode]: layer,
}
})
//can i upload new stuff to layers and have it merge, or willi t overwrite layers:
updateArtworkSet({ _id: projectId, layers: metadata }) // use swr here

//check status and get URLs for randomized images, then upload to db, display results in view?
// then generate random images from layerImages
}
return (
<Box className="App">
<Center marginBlock="10">
<Box>
<FormControl isInvalid={!!errorMsg} isRequired>
{previewURI && (
<Box>
<Img src={previewURI} border={"1px solid red"} p={9} />
</Box>
)}
<FormLabel width={"50%"} htmlFor="imgUpload">
Upload File:
</FormLabel>
Expand All @@ -188,51 +226,97 @@ function App() {
/>
{previewURI && (
<Box>
<FormLabel width={"50%"}>Amount of Fuzz (0-100%)</FormLabel>
<Img src={previewURI} border={"1px solid red"} p={9} />
<Divider w={"80%"} />
<FormLabel width={"50%"} htmlFor="fuzzNum">
Amount of Fuzz (0-100%)
</FormLabel>
<Input
id="fuzzNum"
type="number"
min={0}
max={100}
step={10}
onChange={(ev) => setFuzzNum(Number(ev.target.value))}
/>
<FormLabel width={"50%"}>Amount of Colors (layers)</FormLabel>
<br />
{/* <FormLabel width={"50%"}>Amount of Colors (layers)</FormLabel>
<Input
id="colorsNum"
type="number"
min={2}
max={20}
onChange={(ev) => setColorsNum(Number(ev.target.value))}
/>
/> */}
<Button onClick={onClickUpload}>Get Layers</Button>
<FormHelperText>{uploadStatus}</FormHelperText>
{uploadStatus && <Progress size="xs" isIndeterminate />}
</Box>
)}
{projectId && <Text>Project ID: {projectId}</Text>}
{layerImages?.length > 0 && (
{artworkLayers?.length > 0 && (
<Grid
templateColumns="repeat(3, 1fr)"
gap={5}
overflowX="scroll"
width="100vw"
>
{layerImages.map((url) => (
{artworkLayers?.map((url) => (
<GridItem key={url}>
<Image src={url} alt="Layer Image" />
</GridItem>
))}
</Grid>
)}
{layerImages && (
<Button onClick={() => assembleImages()}>Assemble Images</Button>
{artworkLayers.length > 0 && (
<Box>
<FormLabel># of Colors</FormLabel>
<Input
type="number"
min={1}
onChange={(e) => {
const newMeta = metadata
Object.entries(newMeta).forEach((iteration) => {
newMeta[iteration[0]]!.colorVariety = Number(
e.currentTarget.value,
)
})
setMetaData(newMeta)
}}
/>
<Button
onClick={() => {
randomizeLayers()
}}
>
Randomize Colors
</Button>
</Box>
)}
{varietyMetadata?.length > 0 && (
<Grid
templateColumns="repeat(3, 1fr)"
gap={5}
overflowX="scroll"
width="100vw"
>
{varietyMetadata?.map((layer: any) =>
layer.map((variety: any) => (
<GridItem
key={`${variety.imageUri}_${variety.origColorCode}_${variety.newColorCode}`}
>
<Image src={variety.imageUri} alt="Layer Image" />
</GridItem>
)),
)}
</Grid>
)}

{errorMsg && <FormErrorMessage>{errorMsg}</FormErrorMessage>}
</FormControl>
</Box>
</Center>
<SimpleGrid columns={2}>
{/* <SimpleGrid columns={2}>
{IMAGES.map((path) => (
<Center key={path}>
<Box
Expand All @@ -254,7 +338,7 @@ function App() {
</Box>
</Center>
))}
</SimpleGrid>
</SimpleGrid> */}
</Box>
)
}
Expand Down
Loading

1 comment on commit c86acab

@vercel
Copy link

@vercel vercel bot commented on c86acab Jun 20, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.