Commit graph

199 commits

Author SHA1 Message Date
8ab5af1aca Remove unused logic for whether a zone is "sometimes" occupied
I'm about to reimplement the more-robust version of what this used to
be: how the item page used to say "sometimes" after certain zones in
the occupied list.

Now, we're going to do parity with 2020, and list the actual species!

I like that this takes away the weird `#sometimes` method on the `Zone`
class, which was always an odd hack for just this small thing.
2024-08-31 13:16:47 -07:00
bd62476722 Add basic zone info to simpler item previews
We're missing the feature where we enumerate the exact species in
ambiguous cases, though!
2024-08-31 13:11:50 -07:00
ac002f3151 Track preferred color/species for new item page previews
Also adapted from the Impress 2020 logic!

Note that I refactored `compatible_pet_type` to a series of scopes on
`PetType`. I think this is a simpler, clearer, and more flexible API!
2024-07-01 17:38:31 -07:00
fe6035d438 Default to compatible pet types in new item page preview
Just adapted from Impress 2020 logic again, easy peasy!
2024-07-01 17:20:38 -07:00
3f38fbd1b0 Support zone restriction in new item preview
Adapted from wardrobe-2020's `getVisibleLayers`! Thanks past-Matchu for
all the comments lol!
2024-07-01 16:54:39 -07:00
74748acaaf Refactor more of item outfit preview into the Outfit class
This is a cute thing that I think sets us up for other stuff down the
line: move more of the outfit appearance logic into the `Outfit` class!
Now, we set up the item page with a temporary instance of `Outfit`,
then ask for its `visible_layers`.

Still missing restricted-zones logic and such, that's next!
2024-07-01 16:07:25 -07:00
ea17e76c39 [WIP] Start replacing item page preview with simpler HTML-based version
Just stripping out the big React component, and having Rails output it!

There's a lot of work rn in extracting the Impress 2020 dependency from
the `wardrobe-2020` React app, and I'm just curious to see if we can
simplify it at all by pulling this stuff *way* back to basics, and
deleting the item page part of `wardrobe-2020` altogether.

In this draft, we regress a lot of functionality: it just shows the
item on a Blue Acara, with no ability to change it! I'm gonna play with
putting more of that back in.

I also haven't actually removed any of the item page React code; I just
stopped calling it. That can be a cleanup for another time, once we're
confident in this experiment!
2024-07-01 15:35:58 -07:00
a70b70be7d Merge remote-tracking branch 'origin/main' 2024-07-01 14:56:08 -07:00
5401ea984a Merge remote-tracking branch 'origin/main' 2024-06-22 18:47:10 -07:00
97abd6e438 Add probabilities to Dyeworks items in Item Getting Guide
I'm gonna better explain the gacha nature, I'm doing this part first!
2024-06-20 12:54:39 -07:00
1d250f3148 Remove unused Item.with_closet_hangers scope
Idk why we thought this made sense way back when? But it evidently has
no call sites now so. Goodbye!
2024-06-19 17:49:18 -07:00
015010345a Extract Dyeworks methods into Item::Dyeworks module
There's just starting to be a lot going on, so I pulled them out into
here!

I also considered a like, `Item::DyeworksStatus` class, and then you'd
go like, `item.dyeworks.buyable?`. But idk, I think it's nice that the
current API is simple for callers, and being able to do things like
`items.filter(&:dyeworks_buyable?)` is pretty darn convenient.

This solution lets us keep the increasing number of Dyeworks methods
from polluting the main `item.rb`, while still keeping the API
identical!
2024-06-18 15:21:43 -07:00
26dfe13b0e Parse "Limited Dyeworks" items from Owls
Yay thank you Owls team! I might also try to parse the dates too, the
format seems to be "Owls: Limited Dyeworks - Dyeable Thru July 15"
2024-06-18 14:59:09 -07:00
bbd1849e19 Oops, fix crash for Dyeworks without Owls info in Item Getting Guide
Silly mistake, right, we might not have a trade value listed! This is
relevant for the new Dyeworks items that just came out like a few hours
ago, which Owls doesn't have info for yet.
2024-06-17 13:07:03 -07:00
9f536f81b3 Refactor to use a new Item#source method for where an item is from
I'm doing this in preparation for maybe trying to load some of this
info into the outfit editor, too!
2024-06-16 12:37:53 -07:00
b22ccbc2a3 Use Owls to check for Permanent Dyeworks items
Previously, I added a Dyeworks section that was incorrect: the base
item being available in the NC Mall does *not* mean you can necessarily
dye it with a potion!

In this change, we lean on Owls to tell us more about Dyeworks status,
and only group items in this section that Owls has marked as "Permanent
Dyeworks".

We don't have support for limited-time Dyeworks items yet—I've sent out
a message asking the Owls team for more info on what they do for those
items!
2024-06-09 14:46:24 -07:00
5de9e2a27b Add Dyeworks section to Item Getting Guide (but it's currently wrong!)
I started writing this up, then sent a preview to a friend, and he was
like "oh cool, but also this is not correct?"

I didn't realize Dyeworks has limited-time support to be *able* to dye
certain items. Hey, glad we're writing this guide for people like me,
then! lol

I wonder if we can lean on Owls for this. It seems like they already
list "Permanent Dyeworks" for some items, I wonder if they say
something special for active limited-edition Dyeworks items!
2024-06-09 13:25:59 -07:00
857cb547ed Add Item#dyeworks_base_item database field, and populate it
In this change, instead of *always* inferring the Dyeworks base item
from the item name at runtime, we now have a database field that tracks
it, and auto-populates whenever an item *seems* to need a Dyeworks base
item but doesn't have one yet.

This will enable us to set the base item manually in cases where it
can't be inferred, and load Dyeworks base items for the Item Getting
Guide in one query with `includes(:dyeworks_base_item)`.

This migration does a bit more of the fix-em-up scripting work *in* the
migration itself than I usually do, mainly because there's so much in
this one that I think being extra-explicit is useful. We make sure to
do it gracefully though!
2024-06-07 20:10:06 -07:00
68cb44d159 Add logic to infer the base for Dyeworks items
This works for most of the current 1,094 Dyeworks items! But there are
a few exceptions, for cases where the base item name is not quite the
same (e.g. the Dyeworks version is more concise). Maybe we'll add a
database field to override this?

- Dyeworks Baby Blue: Baby Valentine Jumper
- Dyeworks Baby Pink: Baby Valentine Jumper
- Dyeworks Black: Field of Flowers
- Dyeworks Black: Games Master Challenge 2010 Lulu Shirt
- Dyeworks Blue: Field of Flowers
- Dyeworks Blue: Stars and Glitter Facepaint
- Dyeworks Brown: Hanging Winter Candles Garland
- Dyeworks Green: Stars and Glitter Facepaint
- Dyeworks Magenta: Lovely Berry Blush
- Dyeworks Orange & Pink: Winter Lights Effects
- Dyeworks Orange: Games Master Challenge 2010 Lulu Shirt
- Dyeworks Peach: Lovely Berry Blush
- Dyeworks Purple: Baby Valentine Jumper
- Dyeworks Purple: Games Master Challenge 2010 Lulu Shirt
- Dyeworks Purple: Hanging Winter Candles Garland
- Dyeworks Purple: Stars and Glitter Facepaint
- Dyeworks Red & Green: Winter Lights Effects
- Dyeworks Silver: Hanging Winter Candles Garland
- Dyeworks Soft Pink: Lovely Berry Blush
- Dyeworks Yellow & Magenta: Winter Lights Effects
- Dyeworks Yellow: Field of Flowers
2024-06-07 19:35:43 -07:00
31c281390d Add explanations for why Item#pb_{species,color} would return nil 2024-06-05 19:46:12 -07:00
193b1fa5e3 Improve performance for occupies:X searches
I noticed in the app that these queries were slowwww! I was able to
track it down to a bad query plan, as we explain in the comment.

I searched online for "mysql query performance filter on one join table
sort by another", and was surprised to find this answer suggest a
subquery, which I've often been told to expect to be slower compared to
joins? But it certainly worked in this case!

https://stackoverflow.com/questions/35679693/mysql-optimize-join-with-filter-and-order-on-different-tables
2024-06-03 11:45:51 -07:00
758b62e7d5 Improve performance of Owls values in Item Getting Guide
Now we preload them all concurrently, instead of in sequence when the
template gets around to asking for them!
2024-05-27 16:21:22 -07:00
d34bebc336 Use a pet face when there's no paint brush, in Item Getting Guide
Now, for colors like Mutant or Magma where there's no paint brush
image to show, we use a sample pet image instead, to help it have equal
visual weight and clarity as the cases with the paint brushes.

We do some cleverness in here to make sure to always show the relevant
species, if possible!
2024-05-22 17:53:52 -07:00
1b03c2caed Add more PB item info and links to Item Getting Guide
I add some infrastructural support for inferring an item's paintbrush
color (if any), and a field to the database to manually track an item's
paint brush item name! This is both useful for tracking which colors
are even *available* via paint brush, and also for working with colors
with unusual paint brush names, like the "Get Off My Lawn Paint Brush"
(for Elderly pets).

Here's the script I ran to backfill this for current colors and their
paint brushes!

```rb
Color.find_by_name("Baby").update!(pb_item_name: "Baby Paint Brush")
Color.find_by_name("Biscuit").update!(pb_item_name: "Biscuit Paint Brush")
Color.find_by_name("Blue").update!(pb_item_name: "Blue Paint Brush")
Color.find_by_name("Brown").update!(pb_item_name: "Brown Paint Brush")
Color.find_by_name("Camouflage").update!(pb_item_name: "Camouflage Paint Brush")
Color.find_by_name("Candy").update!(pb_item_name: "Candy Paint Brush")
Color.find_by_name("Checkered").update!(pb_item_name: "Checkered Paint Brush")
Color.find_by_name("Christmas").update!(pb_item_name: "Christmas Paint Brush")
Color.find_by_name("Cloud").update!(pb_item_name: "Cloud Paint Brush")
Color.find_by_name("Darigan").update!(pb_item_name: "Darigan Paint Brush")
Color.find_by_name("Dimensional").update!(pb_item_name: "Dimensional Paint Brush")
Color.find_by_name("Disco").update!(pb_item_name: "Disco Fever Paint Brush")
Color.find_by_name("Electric").update!(pb_item_name: "Electric Blue Paint Brush")
Color.find_by_name("Eventide").update!(pb_item_name: "Eventide Paint Brush")
Color.find_by_name("Faerie").update!(pb_item_name: "Faerie Paint Brush")
Color.find_by_name("Fire").update!(pb_item_name: "Fire, Fire, Your Pants On Fire Paint Brush")
Color.find_by_name("Elderlyboy").update!(pb_item_name: "Get Off My Lawn Paint Brush")
Color.find_by_name("Elderlygirl").update!(pb_item_name: "Get Off My Lawn Paint Brush")
Color.find_by_name("Ghost").update!(pb_item_name: "Ghost Paint Brush")
Color.find_by_name("Glowing").update!(pb_item_name: "Glowing Paint Brush")
Color.find_by_name("Gold").update!(pb_item_name: "Golden Paint Brush")
Color.find_by_name("Green").update!(pb_item_name: "Green Paint Brush")
Color.find_by_name("Grey").update!(pb_item_name: "Grey Paint Brush")
Color.find_by_name("Halloween").update!(pb_item_name: "Halloween Paint Brush")
Color.find_by_name("Invisible").update!(pb_item_name: "Invisible Paint Brush")
Color.find_by_name("Desert").update!(pb_item_name: "Lost Desert Paint Brush")
Color.find_by_name("Maractite").update!(pb_item_name: "Maractite Paint Brush")
Color.find_by_name("Maraquan").update!(pb_item_name: "Maraquan Paint Brush")
Color.find_by_name("Marble").update!(pb_item_name: "Marble Paint Brush")
Color.find_by_name("Island").update!(pb_item_name: "Mystery Island Paint Brush")
Color.find_by_name("Oil Paint").update!(pb_item_name: "Oil Paint Brush")
Color.find_by_name("Orange").update!(pb_item_name: "Orange Paint Brush")
Color.find_by_name("Origami").update!(pb_item_name: "Origami Paint Brush")
Color.find_by_name("Pastel").update!(pb_item_name: "Pastel Paint Brush")
Color.find_by_name("Pink").update!(pb_item_name: "Pink Paint Brush")
Color.find_by_name("Pirate").update!(pb_item_name: "Pirate Paint Brush")
Color.find_by_name("Plushie").update!(pb_item_name: "Plushie Paint Brush")
Color.find_by_name("Polka Dot").update!(pb_item_name: "Polka Dot Paint Brush")
Color.find_by_name("Purple").update!(pb_item_name: "Purple Paint Brush")
Color.find_by_name("Rainbow").update!(pb_item_name: "Rainbow Paint Brush")
Color.find_by_name("Red").update!(pb_item_name: "Red Paint Brush")
Color.find_by_name("Relic").update!(pb_item_name: "Relic Paint Brush")
Color.find_by_name("Royalboy").update!(pb_item_name: "Royal Paint Brush")
Color.find_by_name("Royalgirl").update!(pb_item_name: "Royal Paint Brush")
Color.find_by_name("Sketch").update!(pb_item_name: "Scritchy Sketchy Paint Brush")
Color.find_by_name("Shadow").update!(pb_item_name: "Shadow Paint Brush")
Color.find_by_name("Silver").update!(pb_item_name: "Silver Paint Brush")
Color.find_by_name("Skunk").update!(pb_item_name: "Skunk Paint Brush")
Color.find_by_name("Snow").update!(pb_item_name: "Snow Paint Brush")
Color.find_by_name("Speckled").update!(pb_item_name: "Speckled Paint Brush")
Color.find_by_name("Split").update!(pb_item_name: "Split Paint Brush")
Color.find_by_name("Spotted").update!(pb_item_name: "Spotted Paint Brush")
Color.find_by_name("Starry").update!(pb_item_name: "Starry Paint Brush")
Color.find_by_name("Stealthy").update!(pb_item_name: "Stealth Paint Brush")
Color.find_by_name("Steampunk").update!(pb_item_name: "Steampunk Paint Brush")
Color.find_by_name("Strawberry").update!(pb_item_name: "Strawberry Fields Forever Paint Brush")
Color.find_by_name("Striped").update!(pb_item_name: "Striped Paint Brush")
Color.find_by_name("Swamp Gas").update!(pb_item_name: "Swamp Gas Paint Brush")
Color.find_by_name("Toy").update!(pb_item_name: "Toy Paint Brush")
Color.find_by_name("Transparent").update!(pb_item_name: "Transparent Paint Brush")
Color.find_by_name("Tyrannian").update!(pb_item_name: "Tyrannian Paint Brush")
Color.find_by_name("Usuki Boy").update!(pb_item_name: "Usuki Paint Brush")
Color.find_by_name("Usuki Girl").update!(pb_item_name: "Usuki Paint Brush")
Color.find_by_name("Valentine").update!(pb_item_name: "Valentine Paint Brush")
Color.find_by_name("Water").update!(pb_item_name: "Water Paint Brush")
Color.find_by_name("White").update!(pb_item_name: "White Paint Brush")
Color.find_by_name("Woodland").update!(pb_item_name: "Woodland Paint Brush")
Color.find_by_name("Wraith").update!(pb_item_name: "Wraith Paint Brush")
Color.find_by_name("Yellow").update!(pb_item_name: "Yellow Paint Brush")
Color.find_by_name("Zombie").update!(pb_item_name: "Zombie Paint Brush")

```
2024-05-22 16:09:49 -07:00
23ad52a8db Oops, don't crash calling current_nc_price on non-NC-Mall items
If `nc_mall_record` is `nil`, return `nil`! (This is the nil method
chaining operator!)
2024-05-21 17:24:55 -07:00
d8b577aab1 Add more info to NC Mall section of Item Getting Guide
NC prices, some CSS, and also a new application-level helper that adds
a feature I've long wanted and been working around for Turbo: the
ability to specific that a stylesheet is specific to the current page,
and should be unloaded when removed!

I use this to write `sources.sass` without the usual
`body.items-sources` scoping that we've historically used to control
what pages a stylesheet applies to. (In the long past, this was because
a lot of stylesheets were—and still are–routed through the
`application.sass` stylesheet! But even for more recent standalone page
stylesheets, I've done the scoping, to avoid issues with styles leaking
beyond the page they're meant for when Turbo does a navigation.)
2024-05-14 16:04:40 -07:00
d3b3a3060c Split Item Getting Guide between NC Mall items and Other NC items
This'll affect the recommended acquisition method by a lot!

NC Mall info like current price isn't surfaced anywhere else in the app
right now. It'd probably be good to add to the item page, and maybe
some other places too!
2024-05-14 00:09:27 -07:00
9733ceae25 Add bare-bones Item Getting Guide page
TNT requested that we figure out ways to connect the dots between
people's intentions on DTI to their purchases in the NC Mall.

But rather than just slam ad links everywhere, our plan is to design an
actually useful feature about it: the "Item Getting Guide". It'll break
down items by how you can actually get them (NP economy, NC Mall,
retired NC, Dyeworks, etc), and we're planning some cute actions you
can take, like shortcuts for getting them onto trade wishlists or into
your NC Mall cart.

This is just a little demo version of the page, just breaking down
items specified in the URL into NC/NP/PB! Later we'll do more granular
breakdown than this, with more info and actions—and we'll also like,
link to it at all, which isn't the case yet! (The main way we expect
people to get here is by a "Get these items" button we'll add to the
outfit editor, but there might be other paths, too.)
2024-05-06 20:37:59 -07:00
0943e2dbba Fix broken default value in schema for item description
Idk how we got into this state, or if it's environment-dependent or
MySQL-version-dependent or what, but setting up the dev environment on
my macOS machine is complaining that `TEXT` columns can't have default
values.

Well, in that case, let's just have it be a non-nullable field, and add
a note to our code that missing fields *can* cause item saving to fail!
(This was always true, but I'm just extra-noting it because it's
becoming *more* true.)
2024-05-02 13:00:10 -07:00
87782767f8 Filter search in wardrobe-2020 by alt styles!
Yay, we finally added it, the part where we include the appearance data
for the items based on both the species/color and the alt style! Now,
switching to Faerie Acara correctly filters the search only to items
that would fit (I think literally just only body_id=0 items right now,
but we're not banking on that!)
2024-02-27 16:11:06 -08:00
183cb40e74 Oops, don't return body_id=0 items for "-fits:blue-acara"
Right, fitting isn't just body_id = this one, it's also body_id=0!

Anyway, doing this query on its own is still deathly slow, I wonder if
the idea I had about left joins (back when I was still working in a
Rails version that didn't support it lol) could help! Might poke at
that a smidge.
2024-02-27 14:07:20 -08:00
2e5b1c7350 Remove unused Item.per_page attribute
I feel like this was part of `will_paginate` back before the Rails
community had itself figured out about what belongs in a model?

But yeah, a default per-page value for search results does not belong
here. And I don't think anything references it anymore, because we pass
`per_page` to the `paginate` call in `ItemsController` explicitly! So,
goodbye!
2024-02-25 16:16:43 -08:00
e5bf6d6ba1 Oops, fix remaining references to locale in item search
This is both unnecessary now, but also caused a bug in the new search
stuff where searching by zone would pass an extra `locale` argument to
a filter that doesn't need it!
2024-02-25 15:00:22 -08:00
61a4dcad02 Oops, "fits:blue-acara" search should return non-body-specific items
Idk when this regressed exactly, but probably people didn't super
notice because I don't think it's a very common thing to type directly
into the Infinite Closet search box! (It used to be crucial to the old
wardrobe app.)

But I'm using it in the wardrobe app again now, so, fixed!
2024-02-25 14:47:37 -08:00
52e81557c2 Update search filters to consider NP and PB mutually exclusive
`is:np` now means "is not NC and is not PB".

Note that it might be good to make NC and PB explicitly mutually
exclusive too? It would complicate queries though, and not matter in
most cases… the Burlap Usul Bow is the only item that we currently
return for `is:pb is:nc`, which is probably because of a rarity issue?
2024-02-25 12:57:04 -08:00
a3dcaa0f0e Add useItemSearch for wardrobe app, but don't use it yet!
Adding new functionality to the item search JSON endpoint, and adding
an adapter layer to match the GQL format!

Hopefully this will be pretty drop-in-able, we'll see!
2024-02-25 12:06:32 -08:00
cd095eefcb Oops, fix crashing bug when loading item appearances endpoint
I missed this because it's only for backgrounds and stuff! But yeah I
added a prefix to the `Body` struct, and forgot to apply it everywhere,
oops!
2024-02-24 16:14:30 -08:00
3f449310d6 Refactor item search JSON, add appearances
Preparing to finally move wardrobe-2020's item search to use the main
app's API endpoints instead!

One blocker I forgot about here: Impress 2020 has actual support for
knowing an item's true appearance, like by reading the manifest and
stuff, that we haven't really ported over. I feel like maybe I should
pause and work on the changes to manifest-archiving that I'd been
planning anyway? I'll think about it.
2024-02-23 10:44:50 -08:00
1e6ff4cefc Remove the Item::Translation model entirely
Okay, Impress 2020 is migrated off translations too, so we can start to
wrap this up!
2024-02-20 16:57:45 -08:00
3ac9e7ce69 Migrate item search away from item translations
Lightning fast for simple name queries now, gotta say!!
2024-02-20 16:04:41 -08:00
5ee3b472ec Migrate away from item translations in modeling
This one is important, I didn't notice that this is a way of setting
attributes that won't be written to both tables! `name` will only be
written to the translation table (which crashes the save), and the
other fields would only be written to the main table. Fixed! (I don't
like the super-dynamic this code was written before, anyway.)
2024-02-20 15:52:03 -08:00
0e8f457aa1 Oops, fix bug on item page now that translations aren't available
Missed this at first - now that the `name` field is just a normal field
and is always English, it's now an error to provide the locale to it as
a parameter, like we used to for the translated version of the field!
2024-02-20 15:37:07 -08:00
a1066d9c8a Add translated item fields directly to the Item model
Like with Species, Color, and Zone, we're moving the translation data
directly onto the model, and just using English. This will simplify
some of our queries a lot (way fewer joins!), and it's what Neopets
does now anyway, and I have a secret hope that removing the complexity
along the codepath for `item.name` might help speed up large item lists
if we're lucky?? 🤞

Anyway, this is the first step, performing the migration to copy the
data onto the `items` table, making sure to keep them in sync for the
2020 app for now!
2024-02-20 15:25:03 -08:00
1b22258576 Update special_color logic for Banana Chia Wings case
Tbh I'm not sure `special_color` is actually used anywhere? It used to
be how we decide what to show in the previewer on the item page, but
that's been replaced with the 2020 logic, so idk…

But in any case, I noticed that the description doesn't match the
pattern we have, so here's the fix!
2024-02-17 12:50:35 -08:00
73af9d4d77 Start migrating off globalize gem for zones
Like in 0dca538, this is preliminary work for being able to drop the
`zone_translations` table! We're copying the field over first, to be
able to migrate DTI 2020 safely before dropping anything.
2024-01-23 05:43:00 -08:00
ce64f12cc3 Remove references to species/color translations at call sites
We wisely did preloading in some places. Now, we don't need to!
Hopefully this'll even be a free speed boost on some pages!
2024-01-23 05:23:57 -08:00
b1c1bea7be Remove unused data in items#show controller
Oh right, this was for the old pet previewer. Goodbye!
2024-01-20 23:53:30 -08:00
c725a11920 Remove unused NC Mall spider code & fields
We haven't used the mall spider in this app in forever (I guess we even
deleted the code at some point?), but there was some vestigial stuff
left. Goodbye!
2023-11-11 15:45:38 -08:00
a31039c4c8 Load item page restricted zones data from Rails app, not impress-2020
Just moving more stuff over! I modernized Item's `as_json` method while
I was here. (Note that I removed the NC/own/want fields, because I
think the only other place this method is still called from is the
quick-add feature on the closet lists page, and I think it doesn't use
these fields to do anything: updating the page is basically a full-page
reload, done sneakily.)
2023-11-11 08:49:19 -08:00
c6cb61ef38 Remove no-op item.thumbnail.secure_url
There was a time when I used an old proxy server to try to fix mixed
content issues, and I eventually removed it but never took the tendrils
out from the code.

We probably _should_ figure out how to secure these URLs! But until
then, we may as well simplify the code.
2023-11-11 08:24:08 -08:00