From 1bf33c14dbaebe5393c00352e38e54030e6548a5 Mon Sep 17 00:00:00 2001 From: Matt Dunn-Rankin Date: Sun, 3 May 2020 01:52:39 -0700 Subject: [PATCH] use compressed validPetPoses to save network it also has valid emotion/gp data in there too, which we'll use later! --- package.json | 3 +- src/app/SpeciesColorPicker.js | 61 +++++++++--------- .../getValidPetPoses.test.js.snap | Bin 6335 -> 6284 bytes src/server/getValidPetPoses.js | 9 ++- src/server/index.js | 3 +- src/server/util.js | 14 ++-- yarn.lock | 24 +++++++ 7 files changed, 70 insertions(+), 44 deletions(-) diff --git a/package.json b/package.json index 2168b32..6d519c6 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,8 @@ "react-dom": "^16.13.1", "react-helmet": "^6.0.0", "react-scripts": "3.4.1", - "react-transition-group": "^4.3.0" + "react-transition-group": "^4.3.0", + "use-http": "^1.0.10" }, "scripts": { "start": "react-scripts start", diff --git a/src/app/SpeciesColorPicker.js b/src/app/SpeciesColorPicker.js index 79f41de..8844533 100644 --- a/src/app/SpeciesColorPicker.js +++ b/src/app/SpeciesColorPicker.js @@ -1,5 +1,6 @@ import React from "react"; import gql from "graphql-tag"; +import useFetch from "use-http"; import { useQuery } from "@apollo/react-hooks"; import { Box, Flex, Select, Text, useToast } from "@chakra-ui/core"; @@ -13,7 +14,7 @@ import { Delay } from "./util"; */ function SpeciesColorPicker({ outfitState, dispatchToOutfit }) { const toast = useToast(); - const { loading, error, data } = useQuery(gql` + const { loading: loadingMeta, error: errorMeta, data: meta } = useQuery(gql` query { allSpecies { id @@ -24,35 +25,24 @@ function SpeciesColorPicker({ outfitState, dispatchToOutfit }) { id name } - - allValidSpeciesColorPairs { - species { - id - } - color { - id - } - } } `); - - const allColors = (data && [...data.allColors]) || []; - allColors.sort((a, b) => a.name.localeCompare(b.name)); - const allSpecies = (data && [...data.allSpecies]) || []; - allSpecies.sort((a, b) => a.name.localeCompare(b.name)); - - // Build a large Set where we can quickly look up species/color pairs! - const allValidSpeciesColorPairs = React.useMemo( - () => - new Set( - ((data && data.allValidSpeciesColorPairs) || []).map( - (p) => `${p.species.id},${p.color.id}` - ) - ), - [data] + const { + loading: loadingValids, + error: errorValids, + data: validsBuffer, + } = useFetch("/api/validPetPoses", { responseType: "arrayBuffer" }, []); + const valids = React.useMemo( + () => validsBuffer && new DataView(validsBuffer), + [validsBuffer] ); - if (loading) { + const allColors = (meta && [...meta.allColors]) || []; + allColors.sort((a, b) => a.name.localeCompare(b.name)); + const allSpecies = (meta && [...meta.allSpecies]) || []; + allSpecies.sort((a, b) => a.name.localeCompare(b.name)); + + if (loadingMeta || loadingValids) { return ( @@ -62,7 +52,7 @@ function SpeciesColorPicker({ outfitState, dispatchToOutfit }) { ); } - if (error) { + if (errorMeta || errorValids) { return ( Error loading species/color data. @@ -75,8 +65,7 @@ function SpeciesColorPicker({ outfitState, dispatchToOutfit }) { const onChangeColor = (e) => { const speciesId = outfitState.speciesId; const colorId = e.target.value; - const pair = `${speciesId},${colorId}`; - if (allValidSpeciesColorPairs.has(pair)) { + if (pairIsValid(valids, meta, speciesId, colorId)) { dispatchToOutfit({ type: "changeColor", colorId: e.target.value }); } else { const species = allSpecies.find((s) => s.id === speciesId); @@ -93,14 +82,14 @@ function SpeciesColorPicker({ outfitState, dispatchToOutfit }) { const onChangeSpecies = (e) => { const colorId = outfitState.colorId; const speciesId = e.target.value; - const pair = `${speciesId},${colorId}`; - if (allValidSpeciesColorPairs.has(pair)) { + if (pairIsValid(valids, meta, speciesId, colorId)) { dispatchToOutfit({ type: "changeSpecies", speciesId: e.target.value }); } else { const species = allSpecies.find((s) => s.id === speciesId); const color = allColors.find((c) => c.id === colorId); toast({ title: `We haven't seen a ${color.name} ${species.name} before! 😓`, + status: "warning", }); } }; @@ -144,4 +133,14 @@ function SpeciesColorPicker({ outfitState, dispatchToOutfit }) { ); } +function pairIsValid(valids, meta, speciesId, colorId) { + // Reading a bit table, owo! + const speciesIndex = speciesId - 1; + const colorIndex = colorId - 1; + const numColors = meta.allColors.length; + const pairByteIndex = speciesIndex * numColors + colorIndex; + const pairByte = valids.getUint8(pairByteIndex); + return pairByte !== 0; +} + export default SpeciesColorPicker; diff --git a/src/server/__snapshots__/getValidPetPoses.test.js.snap b/src/server/__snapshots__/getValidPetPoses.test.js.snap index 67045aeec450192acc8e5173101e1dab542bfeb6..4028d806617b5c4504c6f5b717ada672278d306f 100644 GIT binary patch literal 6284 zcmZ{o|7#rA6~%{86fngtA#H!_4vs2ANF$p{Gp3T}(O*k`a47VbreKH2b|8(6wQcj~ z=X}n&GdsJhJk7j!-@WJFbKlq9)%kh<_uKnz|BoMEzrTNXx9$J;{EPnGcKiPRujl7) z@9w^Q`@{L0Z~yl7S1%tuy8Y?>-G}Y{zh1q)-Tw3S58r?H@^<_3?*8_^m*T$PzPtTT z|N6)8`u~6Uek-N>+q?dC|LuR@yt)0*KY#V_{-%HRq@%R4b$Xg4S4~a52ozA==TpJE z32bZAAFy2@@qmdZ0^)dmZkMGhJp_IPBm|XT_paKAw`BVTs@~=r?5?c&Htn-cgHRG< z$QMdSA{Nhse2VxWU%UDkGL4NwSe}HjOR30qUCg31!Z+H34#P^MeZHytGJ$0z`_=}{ zaMNrre5M$t8`0pqU(BP*z5=k8=3AnIM`=F=Mk15n2)lsGib*&H>Dt+~tae&gZE!3+ zvBE_drJRnIK*bmfky`ucqD|8`-#qbzn%_~KLZq>~5VPf_B2Oa7Yp~R@%1ImrhMA0R zic)l9vM^j1qfy5qgUg>haSI=U;9>!p^(YtA*eIaDP{w&iU)+q#jFP0SfO(kFQdz&M z3SyT~B!!s|{}rElUY=!d#$WElPp5T*J)&B1A(C2>c9Lwnc_ZM?S_VZ!L??hnF!u&I zI0vi*X`dH0DI6@J`4Xh~2*@j7YnOUWQ!UMEe18tm#01YU@u#P9$c7#t%&Cy;Eur}8 zMl)KL{@N$LFq<&gGl9$)QZvsLEX1Er;33~e3NuzSWe{4wnokW^G;2Nu`&2H+V@sUy zY2WFu(shWrqjQAqV0^_VrW}flhiomWl7sfmVQHs^m`zZhIFAvQN*fg5nJ|5Dw&XrGiWn~Y^au3xkkWCytd$8=rhs~SVYJi5;6>vC2tUw0Z*#njL zrwP&WP!>hIX8qK!A`@0GOClXI+21VkW0UXmIXDr)t@-i^asA>c1aSDguDnUgKGcW1 zCP~iw^Y`gGZ$crkQPgI?XyS+_l2Lpfn`Q=JxTQm&3@<(|DgD%m=^%@TX&eJp-Cr-Z^%WbMnTLWWiQ+4 z>`Y^#`s54~4i8XPNCH2|haJb6FH&oN%;$qwL6`(jqbvDwcj_xn7s+~XL=r|1XDWQm zhL5mqRzAcxY1IUk$)8X&ANU?xg8F@!4_5v{pANn9!D2@>_5BQJ3O0aXErD#qp!q%^ zLvNP2wC+v2}d`M3z*981HXU^d?{?YC=H;~ zvtRiXBJT>>OvCaWT<4hN@iLz#OW`Sw0biYn@vIGJo&@cnnor_$lh5$$BuRfR@Z~|$ zePtRN1S(6Bts-dBVHpfrf?yI}VSJl+r#SBwpdJq`f#~Y>^h1ch3Sye@E#G*B25+FH z>YbN^-F6kw8IKcky*ojhfL|dhHW`*1R9HK#_+XZjY4>@t->M3qYA0D-+Id9PSQ__( zG5E+_;}elTbnSqvtq!A(W>f*buy(I9K+90yKwm6;WXx8Rg0gFJ1TNbNwkpg0LTaG( zcl_-oahy9e{Hah$)V~-IB-#I}&coDYQ?{pk1J%yfIK(Dd@#6{dcw-Vq1*m3-V}R4l z=Z!~a11B~b34B-?#`-~|E)STPx@V?qCsEmLR{@<}5~xC?qi_Leq3dm$EAxaZd}OG;eu#2$+X5CAnu)EY-gy03Ha~Ep)2VaA2Ies6e_F@I zzi{IjKIFVRfu!T?8HCR#6QY1k6bI^4i?AJX1}`%)2^6k2|0fU&UT&~kVtj(;^G_PA zNukClT^9Usgh1=r<8uTV&+JDydotB@e3{volZy~<8ajMyIHYnPeb7c!Fe#OueHv_pF1=Qr&*+5 OF#Uo$ZckoaJ^C4trTqo~ literal 6335 zcmeIuy9&ZU6og^xJjIY&T+%8Qwqg+xY(&@%IlBqOY{)rY9^YW?Bg}O3m!ESuiW)9s zn6%4=SG7iGHtE*6l=CJHE;fhrsV)lnOnElF`6PA?L*Le7byiU