Commit graph

765 commits

Author SHA1 Message Date
f29a269b94 Use prettier focus outline for HTML5Badge 2021-02-09 21:47:12 -08:00
828fb65cf4 Refactor HTML5Badge
let's de-dupe that stuff, baby!
2021-02-09 21:45:29 -08:00
3599c78a85 Add to home page updates section 2021-02-09 21:41:08 -08:00
b8744037d1 Add HTML5 indicator to item preview page 2021-02-09 21:39:29 -08:00
193273f00f Share appearance data via useOutfitPreview
Here, we offer a second syntax for `<OutfitPreview />`: a hook that offers the same UI as `preview`, but _also_ shares the `appearance` data.

This makes it easier to have UI that depends on the outfit appearance, without having to commit to all the `useOutfitAppearance` stuff in the parent. Same easy syntax! :3

I've refactored the item page to use this for compatibility testing, instead of using the Apollo cache (which was also cute and same perf impact, but more overhead!)
2021-02-09 20:28:03 -08:00
8694729b38 Fix placeholder URLs in safeImageUrl
Oops, I got distracted partway through typing the domain, lol! They point to a real place now, lol! (not a very helpful place, but at least the real one I intended! :p)
2021-02-09 16:16:46 -08:00
10aa4f9905 Also log the non-HTTPS URL case in safeImageUrl
When I added this new error case in the last change, I made it log to Sentry, because I don't think this should be possible under our data set, so if it happens I want to hear about it. Same is true for this error case, so let's log it too!
2021-02-09 16:13:18 -08:00
330e4ee12e Fix URL parsing for Jetsam Lunch Lady items
A crasher, fixed! :) I made Jetsam Lunch Lady Gloves no longer crash the page, lol - its thumbnail URL is "/items/clo_jetsam_lunchladygloves.gif", with no host specified. The shoes are the same!

I also added a fallback, to return a placeholder error URL instead of just letting the URL through as-is—and I updated the other error case to behave the same. I'd rather have a specific isolated feature get crashy, than have the mixed content warning pop up, or let through some mystery unparseable URL that, idk, might be part of an attack?? Seems better to fail hard-but-small than easy-but-potentially-leakily.
2021-02-09 16:11:32 -08:00
fe5eab5763 Fix stray null error in SearchToolbar
Oops, we don't provide this in the item search page, so check for that!
2021-02-09 16:05:21 -08:00
e6200df49d Speed up dev server by skipping persisted queries 2021-02-07 00:18:01 -08:00
2115bd64a7 Add ?offset parameter to item search page
No links to it yet, but it's respected as a way to request other pages!
2021-02-06 22:02:32 -08:00
2d0601cfeb Add total item count to search results
This will help us set up pagination!
2021-02-06 21:50:52 -08:00
6738f07e64 Add expand-on-hover effect to "Customize more" 2021-02-06 15:52:47 -08:00
7620d3f315 Fix alignment bug on ItemPage 2021-02-06 15:21:57 -08:00
922e150020 Extend itemSearch, deprecate itemSearchToFit
I'm gonna extend `itemSearch` to also look up the total number of results, and the fragmentation between `itemSearch` and `itemSearchToFit` finally caught up with me :p

I've deprecated `itemSearchToFit`, and moved the fit parameters into a new optional `fitsPet` parameter for `itemSearch`.

I'm going to keep `itemSearchToFit` around for now, because old JS builds still use it, and I'd like to avoid disrupting folks. But I'm not going to add the new total results field to the results object it returns, and that's gonna be okay!
2021-02-04 23:34:43 -08:00
b9aac7d8d2 Add "Search all items" placeholder to item search
I was starting to write a Cypress test, and noticed there was no placeholder to use for searching, and I don't know how that escaped my notice for so long! I guess I commented it out for some reason, but I forget why, and this seems fine now! (Looks like we removed it when we added zone suggestions? Idk!)
2021-02-04 22:23:34 -08:00
927d783a96 Delete GQL query tests
I haven't been keeping these up to date, so at this point they're more overhead than they're worth.

Helpful in the early days when we were iterating fast and making more mistakes, but now we're more solid (and I learned how to just resend queries from devtools :p)
2021-02-04 21:24:53 -08:00
580fd79b8c Fix loading state after each species face click 2021-02-03 16:14:08 -08:00
c3cb923b58 Increase preview size on item page 2021-02-03 16:08:02 -08:00
f3e19158d0 Fix crash when using old tab to load item page
Oops, the new `canonicalAppearance` arguments couldn't handle being omitted rather than being null, due to a low-level SQL call site that cares about the difference.

This meant that loading an item page in an old tab, with an old copy of our JS, could cause a crash.

Now, the backend will be okay with queries from old pages, and respond the same as before!

This isn't a huge deal, because once everyone is on the new JS we won't send queries without this parameter anyway… but I like my optional arguments to actually BE optional, without surprises lurking >.>
2021-02-03 15:51:49 -08:00
8970b6af26 Remove stray console lines 2021-02-03 15:45:19 -08:00
958d9c16b8 Change "Not modeled yet" -> "Item needs models" 2021-02-03 15:44:53 -08:00
be151ab400 Save user's preferred color for item previews 2021-02-03 15:33:23 -08:00
787dc7da87 Save user's preferred species for item previews 2021-02-03 14:27:02 -08:00
13a5a0a7aa Update "New updates" section on home page 2021-02-03 02:20:03 -08:00
75fccf1adf Load best available pose in SpeciesFacesPicker
Oh right, I left in a hack to just always pick HAPPY_MASC or HAPPY_FEM, back when it was just the basic colors. Now that we're all the colors, we need to be able to handle fallbacks for missing or unlabeled poses, too!!
2021-02-03 02:10:52 -08:00
082af11b5b Don't say "(Can't be this color)" while loading 2021-02-03 01:53:09 -08:00
4431c43663 Enable free color/species input on ItemPage
Previously, I kept this constrained to valid species/color pairs only, because we didn't have a great error state. But at this point, it feels worse to throw people out of the color they're looking at, and to make it harder for them to pick the color in the first place!
2021-02-03 01:51:51 -08:00
6a4be0390a Show a fallback face for valid face options
Sometimes we just don't have the image! Don't let that stop people from clicking it tho!
2021-02-03 01:47:39 -08:00
a293dc56b5 Disable faces that can't be the chosen color 2021-02-03 01:41:03 -08:00
8de85fbc63 Pulse effect while SpeciesFacesPicker is loading
like the Skeleton elements!
2021-02-03 01:27:16 -08:00
27d4bed172 Cross-fade images in SpeciesFacesPicker
Wowie, this was hard to get right, but I'm very pleased with where it ended up!! React `key` stuff was a total brainwave, and even though it depends on kinda obscure knowledge, it made this whole thing WAAAY easier, omg
2021-02-03 01:24:13 -08:00
a42e696955 Show selected color faces for SpeciesFacesPicker 2021-02-02 23:29:06 -08:00
19482be2b8 Use ES module syntax in backend instead of require
Ok cool, so apparently another win we get from using `ts-node` is that I can finally easily use some non-native-Node features like ES module import syntax, for consistency with what I'm doing in the main app source! That was getting on my nerves tbh. Ooh I bet I can finally use `?.` too, I've had to rewrite that a bunch…
2021-02-02 22:26:55 -08:00
4483df2040 Run Prettier on my TS file
VS Code wasn't running it automatically; now we've got it set up!
2021-02-02 21:40:43 -08:00
b58db4a629 Finally finish TS setup, build works!
`yarn build` was crashing on my `build-cached-data` script, because we were trying to run the Typescript file uncompiled!

Now, we run it with `ts-node`, which transparently compiles Typescript files before execution. Phew!

`react-scripts build` made some automated changes to `tsconfig.json` for compatibility with `create-react-app`, and I also added a `ts-node` section to override one of them so we can compile to CommonJS for `ts-node` script execution!
2021-02-02 21:38:57 -08:00
d7028bc2cc One more TS fix, adding a tsconfig.json 2021-02-02 19:29:58 -08:00
cb87fd8a9a more TS fixes 2021-02-02 19:22:47 -08:00
cee5e128cb fix TypeScript build errors
That's what I get for forking a TS file, not knowing TS, and ignoring the errors lol :p
2021-02-02 19:20:02 -08:00
d3b9f72e67 Add stale-while-revalidate cache headers
Oh yay, I'm pleased with this! I hope it works out well!

stale-while-revalidate is an HTTP caching feature that gives us the ability to still serve relatively static content like item pages ASAP, while also making sure users generally see updates quickly.

The trick is that we declare a period of time where, you can still serve the data from the cache, but you should _then_ go re-fetch the latest data in the background for next time. This works on end users and on the CDN!

I've scanned the basic wardrobe and homepage stuff and brought them up-to-date, and gave particular attention to the item page, which I hope can be very very snappy now! :3

Note to self: Vercel says we can manually clear out a stale-while-revalidate resource by requesting it with `Pragma: no-cache`. I'm not sure it will listen to us for _fresh_ resources, though, so I'm not sure we can actually use that to flush things out in the way I had been hoping until writing this sentence lol :p
2021-02-02 19:07:48 -08:00
c00df62bdc More cache hint tags for Item etc
Trying to get that Item page fast!

I don't really want to ship this as-is, because I'd really like to get stale-while-revalidate working before shipping a 1-week cache timer… will be tricky though!
2021-02-02 17:51:54 -08:00
f0b3047112 Defer tooltip renders in SpeciesFacesPicker 2021-02-02 17:08:39 -08:00
bccb36dda2 Improve SpeciesFacesPicker render performance
The Tooltip elements seem to still be taking a bit, I don't really know a great workaround for that… could maybe split it out into a separate box and defer the rendering on it, so it doesn't block the first pageload?
2021-02-02 16:56:26 -08:00
6549bba756 Remove stray console.log 2021-02-02 16:48:08 -08:00
6d05fb8680 Fix bug in SpeciesColorPicker loading state
Oops, I made a fix to the color picker, but not the species picker! Updated them both to match.
2021-02-02 16:46:07 -08:00
f699d867e5 Disable species picker for species-specific items 2021-02-02 16:45:28 -08:00
6c84baca03 Hide alt text while species faces are loading
and some nicer typography when it fails!
2021-02-02 16:35:54 -08:00
adecb4167b Remove extra focus outline for SpeciesFacesPicker
Before the tooltips, I thought the focus state wasn't clear enough at a glance, so I added an extra focus outline to the species faces picker area. Now, I think it's clear enough with the species name tooltip popping up!
2021-02-02 16:31:55 -08:00
e788040315 Guess when item is species-specific, for UI hints 2021-02-02 16:29:20 -08:00
6f19ef8c88 Fade out incompatible pets, too 2021-02-02 16:06:33 -08:00
382c1c9da3 Fix tooltip hover flicker in SpeciesFacesPicker 2021-02-02 16:01:46 -08:00
28f457e21f Always show species face tooltip in keyboard nav 2021-02-02 15:43:36 -08:00
cdff51dfef Hook up compatibility data for SpeciesFacesPicker
It looks really nice!! :3
2021-02-02 15:22:08 -08:00
93c00c5e79 [WIP] Species face compatibility UI
Now, when a species isn't compatible with an item, we gray out and sadden the pet, like on Classic DTI!

For now, I've hardcoded only the Zafara body ID to match. Let's do server connection next!
2021-02-02 14:47:17 -08:00
b0a8b41c80 Add focus state to species faces picker 2021-02-02 14:19:11 -08:00
d16bfd9781 Use higher-res pet faces on higher-res devices
Didn't realize there was a convenient 150x150 face thumbnail we could use, so hey! Nice!

At one point I was considering generating our own thumbnails, but this is making me increasingly interested in just scraping the Rainbow Pool or something :p
2021-02-02 13:15:42 -08:00
33353e5328 Fix uncaught promise error in search results
Sentry issue IMPRESS-2020-20 doesn't have a clear backtrace, but it looks like the usual thing where we trigger an Apollo query directly, and forget to catch a potential error in the returned promise. I noticed that the last thing the user did was type in the search bar, and got a _caught_ error for the initial search!

Scanning the SearchPanel file, I think it's likely that this was a failure in `fetchMore` for the infinite pagination.

I'm a bit worried as to _why_ we were doing infinite scrolling stuff when there were no results? I wasn't able to repro a scroll event on the empty results list, but it's plausible that it could happen. I've added a gate to not send this request when there's an error!
2021-02-01 19:08:20 -08:00
05282f4b7b Handle memory issues in OutfitMovieLayer
I think what's happening in Sentry error IMPRESS-2020-1F is that mobile devices are running out of memory, so `canvas.getContext("2d")` returns null.

Now, we have a UI affordance to let you know when this is probably what's happening!

Also, when researching this, I learned about a Safari bug where you need to manually garbage-collect your own canvas data. It's possible that Safari users have been having particular trouble with memory leaks over long sessions? I'm not sure, but it seems like a good idea to add this small garbage-collection code!
2021-02-01 18:55:05 -08:00
5d827bc78d Disable species/color picker while item page loads
Ok I think I've finally narrowed this bug down! We had one more loading case: the items page needs time to figure out which species/color to default the fields to, and passes null into the component while this loads. Now, we wait for that!
2021-02-01 18:05:29 -08:00
be7401d62a Recover from missing pose data
Previously, if you typed a pet name on the homepage, but its pose wasn't labeled in our database, you'd get a black empty screen. Now, we redirect to the UNKNOWN pose, or whatever exists for us to use!
2021-01-28 10:37:04 -08:00
71ec5ddc58 Group poses by emotion first, in PosePickerSupport
I think it's confusing that the poses in the dropdown start with the emotion word, but are grouped by the gender presentation word! It's also different than the precedence order! I've reordered them.
2021-01-28 10:34:09 -08:00
0d14fde318 Add "Customize more" button to item page preview 2021-01-26 15:09:41 -08:00
10e09e266c Add debug logging for species/color picker bug
We're occasionally getting errors on the homepage, of the new message I added: `Error loading valid poses for species=, color=108: byteOffset cannot be negative`.

So ok, now we know it's a species undefined bug, coming from `onChangeSpecies`! That suggests we're not finding by ID correctly?

So I'm adding some new logging to help me understand the sequence of actions leading up to this point, and the species data state when the error itself happens!
2021-01-26 14:08:09 -08:00
f74fc05112 Fix remaining chunk error noise
I've been getting more Sentry errors about JS chunk errors after deploys, and finally looked into it!

Turns out that, our try/catch handling was working great, and the page was reloading correctly for users as expected. But in these scenarios we would _also_ throw and log two uncaught errors!

The first is that, because we're a single-page app, unrecognized routes fall back to the index.html by default (to power our custom client-side routes, like /outfits/123 etc). So this meant that missing JS files, which _should_ be returning a 404, were instead returning 200 OK and an HTML file, which failed to parse. (And running the script isn't included in the catchable part of the `import` promise!)

Now, in our `vercel.json` config, we catch those paths specifically and 404 them. (The exact choice of path is important: on dev, all these routes run _before_ the dev server, which is responsible for serving the static files - but dev doesn't include hashes in the JS file names, so this 404 route only matches built prod JS files, not local dev JS files.)

The second is that we failed to return anything to `@loadable/component` in the error case, so it would try to render `undefined` as if it were a component class. Now, we return a trivial component class that returns null!
2021-01-26 11:43:27 -08:00
03a3f7ede4 oops, remove unused import 2021-01-25 10:59:10 -08:00
f50de9b11e Add species-face picker to item page previews
Note that it doesn't do any compatibility checking, graying out, hiding unneeded faces, etc. They just exist now is all!
2021-01-25 10:24:39 -08:00
7092d86b76 Better error logging for movie clip errors
I'm getting some vague errors in Sentry about `canvas.getContext` returning null? Weird. (IMPRESS-2020-1F)

I'm not sure what that's about, so I don't want to stop sending it to Sentry. But I do want to make sure we handle this kind of error gracefully! (I'm thinking about how, while I don't think this one was, in the future this _could_ be caused by errors in Neopets movie clip JS, and I don't want our app to start messing up because of it!)

Here, we make sure to log the error to the console with more detail (the library URL), and show feedback to the user, and only log the error once per clip (so that animated ones don't like, send a bunch).
2021-01-23 12:43:17 -08:00
7ac9571ce4 Add error wrapper for potential title bug source 2021-01-22 14:47:18 -08:00
8f8c60d91b Fix crash when user items page not found
Huh, I'm not sure why Apollo is returning `data: undefined`, when the server is definitely returning the correct no-user-found data in the shape I expect... suspicious :/ well, let's at least stop crashing!
2021-01-22 14:38:37 -08:00
38969e8658 Use loading state while loading /api/validPetPoses
Oops, we were getting errors when people tried to change the species/color picker before the valid pose data was ready!

This was only happening on the homepage and item page, because on the wardrobe page we wait for the valids to load before showing the picker at all (`showPlaceholders` is false).

To fix this, we add the valid poses loading state to our existing `isLoading` state on the selects, which disables the element and adds a loading spinner cursor. This prevents interactions we're not ready for!
2021-01-22 14:27:23 -08:00
88fd4698d0 Better handling for getPairByte errors
I'm not sure why, but people are seeing errors when reading from the /api/validPetPoses binary blob. I think it's the picker not handling loading states well?

In this change, we start by just giving it graceful handling, and improving the logging. I'll also try to fix the cause in the next change!
2021-01-22 14:23:05 -08:00
fca3ccf0a0 Don't remove word from query in Advanced Search
Oops, we were removing the last word of the search query if you picked a suggestion from Advanced Search! That behavior is meant for the case where you're _typing_ a filter name 😅
2021-01-22 14:14:31 -08:00
a527d44e12 Handle removing last word of empty text
Sooo, I added this more graceful regex and error logging… then realized that this shouldn't be happening in the first place, because we should only be removing the last word of the query if you picked the filter via typing, not advanced search!

I'm glad to have the assertion error and the new handler, but I'll fix the cause too in the next change :p
2021-01-22 14:12:07 -08:00
4c0afae38e Fix bug that caused filter text "NC you own" 2021-01-21 17:35:03 -08:00
539a6bd740 Oops, fix bug where suggestion didn't remove word 2021-01-21 17:32:37 -08:00
2a08aa5ce9 Mention "items you own" filter on homepage 2021-01-21 17:28:06 -08:00
add7fc0cb6 Add Advanced Search toggle button
It shows all of the suggestion options!

I feel like the state stuff on this isn't super robust, I hope it works okay!
2021-01-21 17:23:34 -08:00
5799c725ff Use plural zone names and "Zone:" prefix in search
We were getting away with singular stuff like "Hat" in the filter text for a while, but once it became "Hat you own" it got too weird imo!

Now, we say "Hats" and "Hats you own" in the filter text. We keep the singular in the search suggestion, but with the "Zone:" prefix, which is something I've been wanting anyway. (It should help with the show all suggestions UI coming soon, too.)
2021-01-21 16:46:23 -08:00
82c1eefb13 Add a no results message to the item search page 2021-01-21 16:39:43 -08:00
d0f133acda Stop showing clear on item search page when empty
Oops, the old condition depending on `queryFilterText` to implicitly check for filter presence. But now that we always show "Items" as prefix text for the filters on this page, the reset button was always showing!

Use our new util function instead.
2021-01-21 16:38:08 -08:00
11fae604be Fix flash of content when emptying search field
1. Search for something
2. Clear the search bar
3. Quickly start typing something new

Before this change, the results would clear on #2, but then the old results would show up again during #3, before the loading state for the new query.

This matches the logic, right? We hid the results when both the current and debounced query were empty, and, during that time, neither is empty.

Instead, here we update the `useDebounce` hook to have a `forceReset` option, to immediately clear out the value instead of waiting.
2021-01-21 16:03:14 -08:00
701eb33391 Add "Items you own" and "Items you want" filters 2021-01-21 15:58:24 -08:00
2164f06021 Add --resync-existing to cache-asset-manifests
Wowie, looks like all the SVG asset manifests changed format lol! Running this now to update them all. There's a lot of them!
2021-01-21 15:14:23 -08:00
81117218a3 Only wait for auth on queries that need it
I switched from my `_NoAuthRequired` opname hack, to a more robust `context` argument, and it's opt-in!

This should make queries without user data faster by default. We'll need to remember to specify this in order to get user data, but it shouldn't be something we'd like, ship without remembering—the feature just won't work until we do!
2021-01-21 14:57:21 -08:00
7f777ed5b3 Add page-reload recovery to *all* code splitting
Still getting some chunk load errors in my Sentry reporting! My hunch is these are the culprit. I hooope that after this the errors are pretty much gone! If not, then I'm missing something about what causes these failures…
2021-01-21 14:34:55 -08:00
ffc697b241 Move our loadable wrapper into util
I wanna use it for other loadables, too!
2021-01-21 14:27:05 -08:00
353f90dcac Fix /conversion styles on mobile 2021-01-20 10:56:09 -08:00
f40ccf0b21 Fix bug where we weren't recognizing new SVGs
So, we've been behind the latest conversion data for a while anyway, because I don't run the sync very often. But I ran the sync today and noticed that the newly converted SVGs weren't showing up in DTI!

This is because TNT changed the asset manifest structure they use for SVG-only assets. Now, we support both!

To test, I checked the Blue Acara (old-style SVG manifest), the Blue Chia (new-style SVG manifest), and the Floating Negg Faerie Doll (animated clip).
2021-01-20 10:44:32 -08:00
275d1d62ab Add secret HTML5 conversion page at /conversion
A lil page for us to keep track of Neopets's HTML5 conversion progress!
2021-01-20 10:44:29 -08:00
ccd4885aad Add "New updates" / "Coming soon" to homepage
Not really sure how to scale these over time, I feel like some amount of history + blog cuteness could be fun? And like, the ability to catch up if you come back after a couple weeks could be nice. But this seems like a really useful at-a-glancer for folks!
2021-01-19 15:46:21 -08:00
61d60170f3 Fix console error in SearchToolbar on add filter 2021-01-19 14:34:30 -08:00
0333b47c05 Leave search suggestions open on blur
Someone wrote in how, when your search query ends with a string that creates Advanced Search suggestions, clicking on items in the list requires two clicks: one to blur and dismiss the suggestions, and one to actually click the item.

Here, I'm experimenting with just leaving the suggestions open. It doesn't feel _great_, but it definitely feels _better_ than before on this edge case, and I thiiink this only affects this edge case in practice? We'll see if it feels goofy in some cases I forgot tho!
2021-01-19 14:27:55 -08:00
94efb80e65 Handle bugs in neopets username data
Huh, looks like it's possible for a user's NeopetsConnection record to be missing, despite having the ID on their User record!

Here, we handle that case.
2021-01-19 13:55:25 -08:00
8aa644a031 Stop sending client-side nav transaction to Sentry
Oops, we hit our Sentry transaction limit after 3 days!

This is in part because we selected a 100% sample rate to start, but also because our app has a lot of client-side navs that don't represent real navigation, and are just to update the state in the URL.

I'm not using most of Sentry's performance tracing features, though! I don't have logging that helps us understand once the page is really done, and I'm only really able to use Web Vitals right now - which only applies to first-time pageload events, anyway. So, that's now all we track!
2021-01-18 16:31:02 -08:00
b39914976b Add an /items/search page, and search box on Home
Woo, it's looking pretty good, I think!

I didn't bother with pagination yet, since I feel like that'll be a bit of a design and eng lift unto itself... but I figured people would appreciate the ability to look up individual items, even if the rest isn't ready yet 😅
2021-01-18 15:56:24 -08:00
9e5dfd1c84 Move "Log out" button into the nav menu
When actually using mobile, I was like "oh, it's maybe not great that the menu button is tiny and the Log out button is huge". Awkward click targets!
2021-01-18 13:51:52 -08:00
6e33132881 Load homepage faster for logged-in users
When building the code to await auth before sending _any_ GraphQL queries, I didn't realize that auth might be kinda slow. So, I've added a hack to let me mark queries with no user-specific data to skip auth, and applied that to the main queries on the homepage.

I think this is a hint that we might want to change our strategy - e.g. to flip it to hackily mark that auth _is_ required, or to create wrappers or option-builder helpers for logged-in queries, etc.

I also notice that SSR would have resolved this particular case...
2021-01-18 07:15:00 -08:00
154046695f Avoid alt text flash of content for item thumbnail 2021-01-18 06:51:23 -08:00
b78cede939 Add brief delay before Latest Items loading state
This UI generally loads very fast, thanks to the CDN cache, so the flash of skeleton content is more distracting than anything else! We still show it quickly after 300ms, but good network connections should reliably get it loaded before then.
2021-01-18 06:46:18 -08:00
f3633f5ab6 Privacy policy copy tweak 2021-01-18 06:44:07 -08:00