Commit graph

1343 commits

Author SHA1 Message Date
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
341869fb17 Oops, say "these items" plural for basic colors in Item Getting Guide
We could do a whole thing about like, checking singular vs plural, but
I'd rather just keep it simpler; I think it's clear from context that
we're talking about a category, so plural is fine even if it's not
actually more than one.
2024-06-05 19:51:11 -07:00
31c281390d Add explanations for why Item#pb_{species,color} would return nil 2024-06-05 19:46:12 -07:00
a3bd841bb8 Fix handling of basic PB items in Item Getting Guide
Okay so, like 30 minutes ago I added fallback behavior for cases where
we can't correctly infer the color from a PB item's name… and then I
pulled it up in the color and found that, oh, right, there are already
3 PB items that *correctly* return `nil` for `Item#pb_color`: Aisha
Collar, Elephante Hat, and Ixi Collar.

This is because they're common items that apply to many colors, like
the basics, but also many other less-special or older color variants.
They are the most likely case where we'll return `nil`.

So, I've updated our fallback UI to, instead of talk vaguely about
missing data, just assume that we're dealing with basic items. In the
rare window of time where a new color is released, and we have PB items
for it but no manual color data yet, this can just incorrectly say
"Basic Colors" and that's fine.
2024-06-05 19:45:39 -07:00
bd6b6450d9 Handle newly-released species in Item Getting Guide
This is less likely than the newly-released color case for PB items,
but I figure let's be resilient anyway, especially since it's so easy
to—and also I figure this is less likely to be triggered by an *actual*
new species, and more likely to be triggered by a surprise in an item's
naming conventions.

But yeah, if `Item#pb_species` returns `nil` upstream, it'll be passed
to `Color#example_pet_type`, which will crash trying to read its ID. So
in this change, we update `Color#example_pet_type` to accept a `nil`
value, and fall back to the first Species (Acara) in that case.

This means that, if you e.g. take the Mutant Aisha Collar and delete
the word "Aisha" from the name, then load it in the Item Getting Guide,
you'll see a thumbnail of a Mutant Acara. Good enough!
2024-06-05 19:27:38 -07:00
3dab235335 Handle newly-released PB items in Item Getting Guide
Oh right, it's possible for `Item#pb?` to return true, but
`Item#pb_color` to return `nil`, if the item has the paintbrush item
description but we can't find a color whose name matches the item name.
This would be expected if a new color were added to Neopets, and PB
items for it were modeled by the community, but we hadn't manually
added the color to the database yet.

Previously, the Item Getting Guide would crash in this scenario. Now,
it correctly handles the possibility of a `nil` value for `pb_color`,
and shows some placeholder info.

To test this, I temporarily edited some item names to not contain the
color name anymore (e.g. "P-rate Elephante Shirt and Vest"), then
loaded the guide and made changes until it no longer crashed.
2024-06-05 19:23:57 -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
63abfa51f7 Redesign "Get these items!" button to use a cart icon instead
This helps it fit in the kinda crunchy horizontal space a lot better!
2024-05-31 17:38:25 -07:00
1e99376449 Remove hundreds of unnecessary queries from /alt-styles page!
I think the Rails query cache handled these anyway? But `SwfAsset` has
a `before_save` hook that checks its zone's info, and
`SwfAsset.preload_manifests` saves all the assets, on the assumption
that saving is a no-op when the record didn't change anyway. And it
basically is!

But I figure that, now that I'm realizing hooks exist, simply not
attempting to save unchanged records is probably a better
representation of what we intend to do. So I'm fixing it like that!

Another potential fix would be to preload the zones for these assets,
but I think that confuses the intent too much; the method itself isn't
using the zones, it's just a weird incidental thing that a save hook
happens to use. (Would probably be better to refactor this old save
hook into a different situation altogether, but that's for another
time!)
2024-05-29 18:52:36 -07:00
244bb7627a Remove outdated info from Alt Styles page
Apparently I correctly updated the first paragraph, but not the third
one, oops lol!
2024-05-29 18:47:06 -07:00
285cf233f0 Assume new alt styles are "Nostalgic" until the end of 2024 2024-05-29 18:46:17 -07:00
b06e8a25c0 Validate presence of body ID when saving AltStyle
This is a minor nbd change, I just noticed when playing around in the
console that, unlike most other errors for this model, the `body_id`
being required is _only_ enforced in the database schema, so it isn't
returned with the usual errors. Not a big deal! Just feels like this is
clearer to work with, and more correct to what we *intend*.
2024-05-29 18:42:41 -07:00
c78d51ab01 Don't hardcode the series name in AltStyle thumbnail_url
This is just a bit of future-proofing! We also add a default thumbnail
URL of the cute "Neopets Circle Background", for cases where the series
name isn't known yet.
2024-05-29 18:36:30 -07:00
72c739ca0f Improve layout for "Get these items!" and "Save" buttons in editor
Make them the same size, add spacing between them, and also put the
"Get these items!" on the right, because the list is right-aligned and
the Save button has dynamic width (the save vs saving vs saved states),
so this makes things a lot more consistent and stable!
2024-05-28 17:32:18 -07:00
bb0d219508 Don't let action buttons wrap onto multiple lines in Item Getting Guide
A funny table-layout bug, where the item "Portal to the Unknown" had a
very long Owls listing ("Owls listing: Buyable - Magic Lens + Blank
Grey Tome (NP)"), and so the table layout tried to give it more room by
decreasing the width of the action cell and wrapping the "NC Trades"
action button text onto multiple lines.

The fix: don't allow that! The table layout will figure out how to
handle this being disallowed, and give the actions cell an appropriate
minimum width.
2024-05-28 17:16:41 -07:00
f84e340899 Add link to Item Getting Guide from outfit editor (behind secret link)
You can now go to `/outfits/new?features=get-these-items` to start
seeing the "Get These Items!" button in the outfit editor!

I haven't tested it a ton yet, but yeah here it is!
2024-05-28 17:06:23 -07:00
671e0becb6 Oops, fix recent bug in Item Getting Guide for most item types
Oh oops, I added an optional `subtitle` argument for the item table
list row template, but didn't realize that it would crash in cases when
not provided! Now, we add an initializer to set it to `nil` if
undefined.
2024-05-28 17:05:28 -07:00
3eb40b2a4f Preload SWF asset manifests during wardrobe item search
This doesn't matter a ton in production, where we already have most of
our manifests loaded! But it matters a lot on my relatively-fresh
development instance, at times like now when images.neopets.com is slow
to respond. A single item search was taking minutes before this change
(5 seconds of timeout per asset for 30 items!), but now takes a few
seconds the first time, as it should!
2024-05-28 17:05:04 -07:00
d3d3297a28 Oops, fix recent bug in Owls value widget on item page
Oh right, I was briefly planning to change the syntax for this stuff,
then changed my mind, but forgot to change it back on this page!
2024-05-28 16:21:03 -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
551e8941f3 Add OWLS values to non-NC-Mall NC items in Item Getting Guide
Note that there's a known performance issue here: we should try to
fetch all the OWLS values at once, instead of doing them in sequence
while rendering the page!
2024-05-27 15:53:08 -07:00
c49cf52939 Remove CSS reset that removes focus outline from all elements by default
Oh jeez, idk why this was ever in here, but yeah no, I want to be using
default browser focus outlines unless specifically overridden otherwise.
Will help keyboard navigation a lot! Yikes!!
2024-05-27 15:49:12 -07:00
b2615eaf00 Use table layout for other NC items in Item Getting Guide
To start, we just link to DTI's own NC trades. I also want to add OWLS
values in here too!
2024-05-27 14:25:12 -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
4e11ee4da7 Add paint brush images to Item Getting Guide
In the previous change, we started grouping PB items by color. But I
wanted to better express that the grouping itself *is* an item, and the
items below it are secondary!

The main change we make here is to leverage DTI's existing design
language that "thumbnail image means item", and record thumbnail URLs
as well as paint brush names now, too!

We're still not leveraging the full Item system here, just fields on
Color. Keeping it simple for now!

Here's the script I ran to add the paint brush images to all the
existing colors!

```rb
Color.find_by_name("Baby").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/babypaintbrush.gif")
Color.find_by_name("Biscuit").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/paintbrush_biscuit.gif")
Color.find_by_name("Blue").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/bluepntbrsh.gif")
Color.find_by_name("Brown").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/brownpntbrush.gif")
Color.find_by_name("Camouflage").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/paintbrush_camo.gif")
Color.find_by_name("Candy").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/paintbrush_candy.gif")
Color.find_by_name("Checkered").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/checkeredpntbrush.gif")
Color.find_by_name("Christmas").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/xmaspaintbrush.gif")
Color.find_by_name("Cloud").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/cloudpntbrush.gif")
Color.find_by_name("Darigan").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/pb_darigan.gif")
Color.find_by_name("Dimensional").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/paintbrush_dimensional.gif")
Color.find_by_name("Disco").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/discopntbrush.gif")
Color.find_by_name("Electric").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/electricbluepntbrush.gif")
Color.find_by_name("Eventide").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/eventidepaintbrush.gif")
Color.find_by_name("Faerie").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/faeriepntbrush.gif")
Color.find_by_name("Fire").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/firepntbrush.gif")
Color.find_by_name("Elderlyboy").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/pb_elderly.gif")
Color.find_by_name("Elderlygirl").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/pb_elderly.gif")
Color.find_by_name("Ghost").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/ghostpntbrush.gif")
Color.find_by_name("Glowing").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/glowingpntbrsh.gif")
Color.find_by_name("Gold").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/gold_pntbrush.gif")
Color.find_by_name("Green").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/greenpntbrsh.gif")
Color.find_by_name("Grey").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/greypntbrush.gif")
Color.find_by_name("Halloween").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/halloweenpntbrsh.gif")
Color.find_by_name("Invisible").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/invisiblepntbrsh.gif")
Color.find_by_name("Desert").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/desertpaintbrush.gif")
Color.find_by_name("Maractite").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/maractitepaintbrush.gif")
Color.find_by_name("Maraquan").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/maraquanpntbrush.gif")
Color.find_by_name("Marble").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/paintbrush_marble.gif")
Color.find_by_name("Island").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/islandpntbrush.gif")
Color.find_by_name("Oil Paint").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/oilpaintingpntbrsh.gif")
Color.find_by_name("Orange").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/orange_paint_brush.gif")
Color.find_by_name("Origami").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/paintbrush_origami.gif")
Color.find_by_name("Pastel").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/paintbrush_pastel.gif")
Color.find_by_name("Pink").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/pink_paint_brush.gif")
Color.find_by_name("Pirate").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/piratepntbrush.gif")
Color.find_by_name("Plushie").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/plushiepaintbrush.gif")
Color.find_by_name("Polka Dot").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/paintbrush_polkadot.gif")
Color.find_by_name("Purple").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/purplepntbrsh.gif")
Color.find_by_name("Rainbow").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/rainbowpntbrsh.gif")
Color.find_by_name("Red").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/redpntbrsh.gif")
Color.find_by_name("Relic").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/relic_pntbrush.gif")
Color.find_by_name("Royalboy").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/paintbrush_royal.gif")
Color.find_by_name("Royalgirl").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/paintbrush_royal.gif")
Color.find_by_name("Sketch").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/sketchpntbrush.gif")
Color.find_by_name("Shadow").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/shadowpntbrsh.gif")
Color.find_by_name("Silver").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/silverpntbrsh.gif")
Color.find_by_name("Skunk").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/skunkpntbrush.gif")
Color.find_by_name("Snow").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/paintbrush_snowman.gif")
Color.find_by_name("Speckled").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/greenwhitedotspntbrush.gif")
Color.find_by_name("Split").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/halfandhalfpntbrsh.gif")
Color.find_by_name("Spotted").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/spottedpntbrush.gif")
Color.find_by_name("Starry").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/starspntbrush.gif")
Color.find_by_name("Stealthy").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/pb_stealthy.gif")
Color.find_by_name("Steampunk").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/paintbrush_steampunk.gif")
Color.find_by_name("Strawberry").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/strawberrypntbrush.gif")
Color.find_by_name("Striped").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/stripedpntbrsh.gif")
Color.find_by_name("Swamp Gas").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/newpbsg2011color.gif")
Color.find_by_name("Toy").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/paintbrush_toy.gif")
Color.find_by_name("Transparent").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/transparentpaintbrush.gif")
Color.find_by_name("Tyrannian").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/tyrannianpntbrush.gif")
Color.find_by_name("Usuki Boy").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/usukipaintbrush.gif")
Color.find_by_name("Usuki Girl").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/usukipaintbrush.gif")
Color.find_by_name("Valentine").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/paintbrush_valentine.gif")
Color.find_by_name("Water").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/paintbrush_water.gif")
Color.find_by_name("White").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/whitepntbrsh.gif")
Color.find_by_name("Woodland").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/paintbrush_woodland.gif")
Color.find_by_name("Wraith").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/paintbrush_wraith.gif")
Color.find_by_name("Yellow").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/yellowpntbrsh.gif")
Color.find_by_name("Zombie").update!(pb_item_thumbnail_url: "https://images.neopets.com/items/paintbrush_zombie.gif")
```
2024-05-22 16:59:36 -07:00
1a76923ce6 Group PB items by color in Item Getting Guide
Ohh yeah, this helps communicate the process much better, especially
for what the Shops/Trades links mean.

I think I'm gonna also go get the paint brush thumbnail images and add
them to the database too, to help better communicate that this is a
paint brush item situation.
2024-05-22 16:34:48 -07:00
a8648fc9c1 Add a limit to the number of items for the Item Getting Guide
Just to make it harder to willfully overload the server or whatever!
2024-05-22 16:09:49 -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
1bd5598b64 Improve row focus and keyboard nav in Item Getting Guide
Clearer focus states, row changes bg color on hover/focus to help you
track where you are, remove the redundant image thumbnail link from the
tab order (it's the same as the item name link!)
2024-05-22 14:58:02 -07:00
189cb6a132 Set fixed table width for Item Getting Guide tables
We'll need to dig into this more for mobile, but here's my initial
attempt at getting the tables to be consistently-sized and such!
2024-05-22 14:47:43 -07:00
ecde507b60 Add item page links to Item Getting Guide table rows
Just a simple one! Clicking the item image or name takes you to the DTI
item page for it now!
2024-05-21 18:57:32 -07:00
39c05b8dac Refactor Item Getting Guide table rows to use a shared template
I'm gonna add more stuff like linking to the item page and stuff, and
that's starting to get complex enough to not want to repeat myself!
2024-05-21 18:48:29 -07:00
8440a28898 Add cart icon to Item Getting Guide's "Buy" buttons for NC Mall 2024-05-21 18:14:14 -07:00
4a74e5e1a7 Use table layout for Item Getting Guide's NP items section
As part of this, I added a new `search_icon` helper, and a new
`button_link_to` helper, which both styles the link as a button and
accepts an `icon` parameter to make it easier to pass in an icon!
2024-05-21 18:03:00 -07:00
18076badcd Oops, fix Shop Wizard URL!
I'm not sure when TNT changed this, but the Shop Wizard has a new
canonical URL now! The previous one redirects, but it does *not* pass
along query string parameters, so these buttons would correctly go to
the Shop Wizard but not auto-fill the name!

Now, we go directly to the new canonical URL, with query params in hand!
2024-05-21 18:00:01 -07:00
73a49c1fec Update item URL helpers (like Shop Wiz) to use URL templates
This is just a tech update: instead of using hand-built URLs with
`CGI::escape`, I use `Addressable::Template`, which is a more reliable
way to build URLs in general.

The motivation here is that I noticed the Shop Wizard link is actually
broken! And I wanted to fix this while I was here, but I figured let's
split that into a separate commit than this refactor. See next!
2024-05-21 17:54:12 -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
283a5b0479 Refactor and simplify Item Getting Guide item list CSS a bit
Notably, we're renaming `.add-to-cart-cell` to `.actions-cell`, in
preparation for other potential actions in other categories!
2024-05-20 16:15:46 -07:00
19470f74d4 Use table layout for Item Getting Guide item list
This helps us be more efficient with our use of space, keep the CTAs well
aligned, show a clear total, and set up how we might do CTAs for more complex
cases like all the potential Neopoint CTAs like Wiz/Trades/Auction/etc!
2024-05-20 15:23:34 -07:00
41532bd019 Write more and better descriptions for Item Getting Guide
Not sure if these are final, but they certainly help communicate what
the heck we're doing here!
2024-05-14 17:41:05 -07:00
8117d976a6 Update some stylesheets to use new page_stylesheet_link_tag helper
Now that we have this helper, we no longer need these stylesheets to
include a `body.controller-action` wrapper to scope all the styles!

Someday we should convert more of our stylesheets to this format,
instead of slamming them all into `application.sass` like we do now.
Ah, well!
2024-05-14 16:10:09 -07:00
e30e25a3f5 Remove unused stylesheet
Huh, guess this got auto-generated long ago! Goodbye!
2024-05-14 16:08:51 -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
46d3325144 Load *all* NC Mall pages in nc_mall:sync
Ta da! Now I can run this and pull 481 records into our database, and
then turn around and run it again and have them all correctly say
"skipped"!
2024-05-10 17:39:40 -07:00
b6e18e10a5 Add bare-bones rails nc_mall:sync task, incl. NCMallRecord model
Currently we only load the homepage, so there's only actually one
wearable item to sync up! But here's the task to do it!

To do this, we also created the backing model NCMallRecord, where we'll
save the current NC Mall state!
2024-05-07 17:40:14 -07:00
1f157b49da Load additional pages via NC Mall scraper service
This is for URLs like this! https://ncmall.neopets.com/mall/ajax/load_page.phtml?type=browse&cat=43&lang=en
2024-05-07 17:38:48 -07:00