Commit graph

1229 commits

Author SHA1 Message Date
e56c5d9a9c Use stale-while-revalidate for /api/validPetPoses
Idk I was surprised to notice that /api/validPetPoses wasn't cached by the Vercel CDN… but I guess that makes sense, because it's only allowed to be an hour old, and client caches hold onto it, so I suppose it makes sense for the CDN cache to not bother.

But in practice, that means users loading the site are pretty _likely_ to see /api/validPetPoses taking its full load time, which can be up to 500ms.

So, I'm offering this additional cache hint, to be willing to serve /api/validPetPose responses up to a week old while reloading the latest data. My hope is that the cache algorithm is much more excited about holding onto that, and that it makes the 500ms delay very _rare_ in practice!
2021-05-13 01:05:34 -07:00
c8feb9a7e0 Fix infinite loop when searching for Markings
Oops, we did an in-place sort on the search variables we passed to Apollo! This meant that Apollo's first read of the variables wouldn't match later reads, so it would always decide the variables had changed, causing an infinite re-render loop.

Remember to copy existing arrays before sorting! 😅

Incidentally, this only happened for Markings, by coincidence: it's the only (I think) searchable zone label with multiple zone IDs, that don't sort alphabetically the same as they sort numerically. This `.sort()` sorts them alphabetically, whereas they come in numerical order in `allZones`, because that's the order the GQL server returns them in `build-cached-data.js`.
2021-05-13 00:28:06 -07:00
b521f79a13 Don't auto-select the first item search filter
There have been usability problems with this search filter UI, and I think they mostly come down to people accidentally selecting filters when they don't mean to—sometimes pressing Enter to indicate that they're done typing, but accidentally selecting something.

Here, we remove that behavior, and additionally add a new behavior to clear the suggestions on pressing Enter.
2021-05-12 23:08:54 -07:00
9ea8245208 Serve pet name as id too in GQL 2021-05-12 22:52:58 -07:00
92a4fd4808 Use Fastly to cache our PNG assets from S3
We've been serving images directly from `impress-asset-images.s3.amazonaws.com` for a long time. While they serve with long-lasting HTTP cache headers, and the app requests them with the `updated_at` timestamp in the query string; each GET request still executes a full S3 ReadObject operation to get the latest version.

In the past, this was only relevant to users on Image Mode, not Flash Mode. But now that everyone's on Image Mode, this matters a lot more!

Now, we've configured a Fastly host at `impress-asset-images.openneo.net`, to sit in front of our S3 bucket. This should dramatically reduce the GET requests to S3 itself, as our cache warms up and gains copies of the most common asset PNGs.

That said, I'm not sure how much actual cost impact this change will have. Our AWS console isn't configured to differentiate cost by bucket yet—I've started this process, but it might take a few days to propagate. All I know is that our current costs are $35/mo data transfer + $20/mo storage, and that outfit images are responsible for most of the storage cost. I hypothesize that `impress-asset-images` is responsible for most of the reads and data transfers, but I'm not sure!

In the future, I think we'll be able to bring our AWS costs to near-zero, by:
- Obsolete `impress-asset-images`, by using the official Neopets PNGs instead, after the HTML5 conversion completes.
- Obsolete `impress-outfit-images`, by using a Node endpoint to generate the images, fronted by a CDN cache. (Transfer the actual data to a long-term storage backup, and replace the S3 objects with redirects, so that old S3 URLs will still work.)

I hope this will be a big slice of the costs though! 🤞

(Note: I'll be deploying this on a bit of a delay, because I want to see the DNS propagate across the globe before flipping to a new domain!)
2021-05-12 22:49:59 -07:00
7ec4bfcf64 Announce outfit saving on homepage 2021-05-05 00:23:41 -07:00
65af7ef64c Add general error message for wardrobe crashes
Boom, pulled some stuff out into util! Now we also have error boundaries in both panels of the wardrobe page.

You can test this one by visiting `/outfits/new?send-test-error-for-sentry`, just like on the home page! Util component for fake errors owo
2021-05-05 00:22:28 -07:00
6dc6ad2578 Add general error message when page crashes
Previously, we would tear down to a blank white page. Now, for errors within most page content, we show a cute error message with a grundo programmer!

To test, visit `/?send-test-error-for-sentry`, which will trigger an intentional render error on the home page.

Note that this does _not_ cover pages that don't use PageLayout, namely the wardrobe page! I'll want to add other boundaries there…
2021-05-05 00:09:09 -07:00
aa0a66fe6d Oops, fix a crasher on item search page
Crashes on clearing the search box. I really thought I fixed this when I refactored `forceReset` to be a function, but I guess I missed it when I went back-and-forth deciding whether to actually do the refactor!
2021-05-04 18:56:00 -07:00
8da664227f Add a pre-commit lint hook
I've got it in my IDE too, but I want more safeguards lol, I'm tired of goofing up the pushes :p

I don't allow warnings here, but still have them as warnings not errors; because I don't want them to block build, but I _do_ want them to block commit.
2021-05-04 18:50:47 -07:00
e63c4ea68f Stop adding extras to Your Outfits after save 2021-05-04 18:38:14 -07:00
e7ad4dc39e Avoid extra rename action logs 2021-05-04 16:32:01 -07:00
76aca48b43 Warn user of unsaved outfit changes 2021-05-04 16:31:48 -07:00
a69bc8184a Upgrade Cypress
I was hoping it would fix a bug I'm having in a new test, and it didn't. But it didn't seem to break anything either so!
2021-05-04 16:07:00 -07:00
7d9e83a0c1 Switch console.log to a lint warning, not error
Didn't realize lint errors blocked compilation lol

I just want it to be annoyed enough at me to draw my attention back to it lol
2021-05-04 14:26:44 -07:00
19c3b50c97 Add attribution for Cypress window size hack 2021-05-04 13:49:53 -07:00
8e18262db0 Fix making changes while outfit is saving
Before this, if you made a change while the outfit was auto-saving, it would reset your changes back and forth in an infinite loop, oops!

This was because the response from the save would reset the outfit state to match, but the _debounced_ outfit state would still show the user's changes, so we'd trigger another save. And then the same thing would happen in reverse, and back and forth again!
2021-05-04 13:43:32 -07:00
3088b97ad2 Enable auto-saving while searching for items
This means hoisting `useOutfitSaving` up to the top of the page! We had it down lower for iteration convenience to start :)
2021-05-04 13:28:29 -07:00
93bc960221 Cypress hint to ensure minimum window size
Lol this is mostly to stop me from accidentally launching it too small 😅

also there seemed to be subtle pixel shifts from some of this? idk still flakier than I want I guess, but hopefully it sticks a bit better now with the new window size hints…
2021-05-04 13:15:27 -07:00
8bd64f7aae Add outfit auto-save Cypress tests 2021-05-04 12:38:55 -07:00
03acbb9757 Add Cypress env to eslint 2021-05-04 12:33:13 -07:00
b6274193d5 Hide outfit thumbnail in wardrobe after loading
Oops, it was possible after saving an outfit to get into a state where we would show the `<OutfitThumbnailIfCached />` behind the outfit even after it was saved, and then removing items would look weird until auto-saving caught up.

We had used the `backdrop` property because we wanted smoother partial load-ins, but for now I'm just fixing this by switching it to `placeholder`, which already has the right loading-only behavior.

This was also the only call site for `backdrop`, so I've removed it!
2021-05-04 12:33:13 -07:00
995a2b8a3a Fix infinite loop bug on initial outfit save
Oops, the sequence here was:
1) Save a new outfit
2) The debounced outfit state still contains id=null, which doesn't match the saved outfit, which triggers an auto-save
3) And now again, the debounced outfit state contains the _previous_ saved outfit ID, but the saved outfit has a _new_ ID, so we save the _previous_ outfit again

and back and forth forever.

Right, ok, simple change: if the saved outfit ID changes, reset the debounced state immediately, so it can't even be out of sync in the first place! (I also considered checking it in the condition, but I didn't really understand what the timing properties of being out of sync due to debouncing would be, and it seemed to not represent the reality I want.)
2021-05-04 12:33:13 -07:00
1d97988383 Finish outfit auto-saving!
Hope it actually work-works lol

Did some refactors in useOutfitState to support the new reset action we do after auto-saving, in case the server tweaked things like the name.
2021-05-04 12:33:13 -07:00
217aa8dcc1 [WIP] Outfit-saving UI
The auto-saving frontend! It seems to trigger saves at the right times, but they fail, because the backend doesn't support updates yet!
2021-05-04 12:33:13 -07:00
18a3ddfbad Fix Cypress outfit snapshot positioning (a hack!) 2021-05-04 12:31:54 -07:00
56e1ce595c Fix misc lint errors
I ran `yarn eslint src`, and fixed everything I saw!
2021-05-03 15:06:07 -07:00
ec3aa1747d Lint against console.log
and replace `console.log` instances in the codebase with better alternatives!
2021-05-03 15:01:49 -07:00
71a6dbdad7 Oh right, stop leaving console.log lying around 2021-05-03 14:57:10 -07:00
c508d49272 Add glitch message for Faerie Uni
Note that we implemented the actual horn behavior described in the message, simply by marking the yellow horn appearance glitched for Fem, but not for Masc! Also, we don't have a yellow-horn Sick Masc model, so it's blue too.
2021-05-03 14:52:50 -07:00
f3e9df2d91 Fix PosePicker support modal
It wouldn't open, because I'd set `isLazy` on the popover, so opening the modal would close and UNMOUNT the popover, which unmounted the modal!

Now, we use the new `lazyBehavior` prop to keep it mounted _after_ the first time it opens. This is why I needed to upgrade Chakra!
2021-04-30 12:48:49 -07:00
ee0185a846 Upgrade Chakra to 1.6.0
Need this for an upcoming bug fix!
2021-04-30 12:48:03 -07:00
e735b9b0f6 Disambiguate some UC conflict glitch message cases 2021-04-29 12:59:33 -07:00
cb104954af More aggressive zone filtering for UCs 2021-04-29 12:38:31 -07:00
d373a7a54f Add restricted zones to pet appearance support UI 2021-04-29 11:52:25 -07:00
cb2a5bc912 Don't add ?state until opening Support pose picker
Oops, I made a recent change to automatically add `appearanceId` to the outfit state when you open the Support pose picker, to avoid navigation issues.

But I didn't realize this happened _silently_ when you open the page as a Support user, because the Popover preloads!

Now, the Popover doesn't preload its content. This is probably better for normal users too, the PosePicker UI is a bit heavier with 6 previews than I really want!
2021-04-28 15:00:34 -07:00
f3173db7b3 Fix bug unwearing/removing search results
Oops, our "items to reconsider" feature was preventing unwearing/removing items you're already wearing!

This feature helps you try stuff in Search, without disrupting your outfit. e.g. if you try on a new Background, then change your mind and unwear it, then we reapply whatever old Background you had on the outfit before.

But this made it impossible to remove your _current_ background from the search page if you went back and searched for it again, because we would remove it and then reconsider and reapply it 😅

Now we, um, stop that!
2021-04-26 07:21:47 -07:00
6517087568 Improve search result click performance
Huh, dunno when I regressed this! Or maybe I never did it for search results, just the main items page? But we're needlessly re-rendering the entire search results list when you wear/unwear something, because `onRemove` always changes, and that breaks the `React.useMemo` on `Item`.

Now, we cache the `onRemove` callback with `React.useCallback`, so perf is much happier!
2021-04-26 07:14:29 -07:00
571b064fb5 Oops, fix crash for empty manifests!
Lol whoops I goofed up what happens when there's no manifest! Ooops
2021-04-26 06:48:33 -07:00
d98a533dce Update asset manifests after 3 days of staleness 2021-04-26 06:40:05 -07:00
6918b3cefa Fix bulk-add layers tool
Oops, we extracted Support fields out from the default `appearanceLayerFragment`!

This was causing the page to silently fail to show any changes, because `layer.remoteId` was evaluating to `undefined` rather than one of the ID numbers in the range.

Here, I've added both `remoteId` explictly because we use it directly, and also the support fields because that's what the layer support UI needs!
2021-04-26 06:07:52 -07:00
3a4e5d7e13 Whoops, fix lint 2021-04-26 05:52:43 -07:00
de27c4297d Stop reverting PosePickerSupport with cache data
Oops, making changes in PosePickerSupport would sometimes trigger a re-fetch in PosePicker.

Specifically, PosePicker needs some fields that PosePickerSupport doesn't, so changing the canonical poses causes PosePicker to ask for stuff again—which will probably serve a SWR'd cached version that doesn't reflect the Support changes!

Here, we update the PosePickerSupport query to prefetch all the fields the PosePicker _would_ want for any of these poses. That way, if we swap in a new one as the canonical appearance for a pose, there's no refetch needed, and therefore no risk of hitting a stale cache.
2021-04-23 16:05:52 -07:00
e955817acf Don't navigate away after updating a pose 2021-04-23 15:58:47 -07:00
f223424cfa Add total count to /support/petAppearances 2021-04-23 15:37:52 -07:00
61636a0067 Better focus/hover UI on /support/petAppearances 2021-04-23 15:34:16 -07:00
72e4fa0ad0 More precise data for /support/petAppearances
We move to an actual GQL query, instead of approximating with /api/validPetPoses.

Notable changes are omitting glitched states from UNKNOWN, so we don't prompt Support users to fill in missing states with bad states; and omitting glitched states from standard, so that we _do_ prompt Support users to check UNKNOWN states for new _non-glitched_ versions we can start to use.
2021-04-23 15:31:10 -07:00
a0107aaf7b Add createdAt and updatedAt to Outfit GQL
Not used in-app yet, but Dice wanted it for the Discord Neobot!
2021-04-23 13:02:18 -07:00
fc6cb2dfdd Fix Honeycomb trace labels for API endpoints
I'm learning that top-level traces should use operation_name as well as name, because name is the low-level thing that every trace gets (including child traces like db queries and net requests)!

Also there was an incorrect label in one of these, and validPetPoses was missing it altogether
2021-04-23 12:31:50 -07:00
14ec4585d7 Oops, fix stale-while-revalidate for modeling data
Huh, I used max-age=1, which suggests to me that I _meant_ to put SWR in here too but just forgot! Oh well lol, fixed now!
2021-04-23 12:12:15 -07:00