From f9f8cdc553d3d3c35ce37a12f2e177dde8be7873 Mon Sep 17 00:00:00 2001 From: Matchu Date: Tue, 25 May 2021 05:28:02 -0700 Subject: [PATCH] Wire up the bulk outfit image converter Heck yeah, it's looking great!! Good error handling too :) you can test the partial error case by changing some image URLs to have invalid IDs. --- src/app/OutfitUrlsPage.js | 278 ++++++++++++++++++++++++++++++++----- src/server/types/Outfit.js | 6 + 2 files changed, 253 insertions(+), 31 deletions(-) diff --git a/src/app/OutfitUrlsPage.js b/src/app/OutfitUrlsPage.js index f5caaba..b339450 100644 --- a/src/app/OutfitUrlsPage.js +++ b/src/app/OutfitUrlsPage.js @@ -13,6 +13,12 @@ import { Input, InputGroup, InputRightElement, + Popover, + PopoverArrow, + PopoverBody, + PopoverContent, + PopoverTrigger, + Spinner, Tab, TabList, TabPanel, @@ -25,9 +31,10 @@ import { VStack, } from "@chakra-ui/react"; -import { Delay, Heading1, Heading2 } from "./util"; +import { Delay, ErrorMessage, Heading1, Heading2 } from "./util"; import HangerSpinner from "./components/HangerSpinner"; import { gql, useQuery } from "@apollo/client"; +import { CheckIcon, WarningIcon } from "@chakra-ui/icons"; function OutfitUrlsPage() { return ( @@ -253,9 +260,44 @@ function SingleImageConverter() { function BulkImageConverter() { const [inputHtml, setInputHtml] = React.useState(""); - const outputHtml = inputHtml - ? "\n" + inputHtml - : ""; + const parsedUrls = parseManyS3OutfitUrlsFromHtml(inputHtml); + const outfitIds = parsedUrls.map((pu) => pu.outfitId); + + // TODO: Do this query in batches for large pages? + const { loading, error, data } = useQuery( + gql` + query OutfitUrlsBulkImageConverter($outfitIds: [ID!]!) { + outfits(ids: $outfitIds) { + id + # Rather than send requests for different sizes separately, I'm just + # requesting them all and having the client choose, to simplify the + # query. gzip should compress it very efficiently! + imageUrl600: imageUrl(size: SIZE_600) + imageUrl300: imageUrl(size: SIZE_300) + imageUrl150: imageUrl(size: SIZE_150) + } + } + `, + { + variables: { outfitIds }, + skip: outfitIds.length === 0, + onError: (e) => console.error(e), + } + ); + + const { outputHtml, numReplacements, replacementErrors } = React.useMemo( + () => + inputHtml && data?.outfits + ? replaceS3OutfitUrlsInHtml(inputHtml, data.outfits) + : { outputHtml: "", numReplacements: 0, replacementErrors: [] }, + [inputHtml, data?.outfits] + ); + + React.useEffect(() => { + for (const replacementError of replacementErrors) { + console.error("Error replacing outfit URLs in HTML:", replacementError); + } + }, [replacementErrors]); const { onCopy, hasCopied } = useClipboard(outputHtml); @@ -283,42 +325,164 @@ function BulkImageConverter() { /> - - - Then, use this new HTML for your page instead: - - - {outputHtml && ( - - )} - -