Compare commits
2 commits
56fe5e4889
...
cd28c26ae7
Author | SHA1 | Date | |
---|---|---|---|
cd28c26ae7 | |||
36452a4704 |
7 changed files with 154 additions and 82 deletions
|
@ -58,9 +58,33 @@
|
||||||
.thumbnail-cell img
|
.thumbnail-cell img
|
||||||
outline: 1px solid $soft-border-color
|
outline: 1px solid $soft-border-color
|
||||||
|
|
||||||
.actions-cell button
|
.actions-cell
|
||||||
/* Bootstrap's Purple 600 */
|
button, a.button
|
||||||
+awesome-button-color(#59359a)
|
/* Bootstrap's Purple 600 */
|
||||||
|
+awesome-button-color(#59359a)
|
||||||
|
|
||||||
|
tr[data-item-owned]
|
||||||
|
color: #aaa
|
||||||
|
|
||||||
|
a:not(.button)
|
||||||
|
color: inherit
|
||||||
|
|
||||||
|
.thumbnail-cell
|
||||||
|
filter: grayscale(1)
|
||||||
|
opacity: .75
|
||||||
|
|
||||||
|
.item-name
|
||||||
|
font-style: italic
|
||||||
|
text-decoration: line-through
|
||||||
|
text-decoration-color: rgba($text-color, 0.35)
|
||||||
|
|
||||||
|
.owned-explanation
|
||||||
|
font-style: italic
|
||||||
|
font-size: 85%
|
||||||
|
|
||||||
|
.actions-cell
|
||||||
|
button, a.button
|
||||||
|
+awesome-button-color(#999)
|
||||||
|
|
||||||
.price-breakdown
|
.price-breakdown
|
||||||
text-decoration-line: underline
|
text-decoration-line: underline
|
||||||
|
@ -100,3 +124,8 @@
|
||||||
|
|
||||||
tr:hover .thumbnail-cell
|
tr:hover .thumbnail-cell
|
||||||
opacity: 0.85
|
opacity: 0.85
|
||||||
|
|
||||||
|
&[data-group-owned]
|
||||||
|
thead
|
||||||
|
button, a.button
|
||||||
|
+awesome-button-color(#999)
|
||||||
|
|
|
@ -116,6 +116,7 @@ class ItemsController < ApplicationController
|
||||||
item_ids = params[:ids].split(",")
|
item_ids = params[:ids].split(",")
|
||||||
@items = Item.where(id: item_ids).includes(:nc_mall_record).
|
@items = Item.where(id: item_ids).includes(:nc_mall_record).
|
||||||
includes(:dyeworks_base_item).order(:name).limit(50)
|
includes(:dyeworks_base_item).order(:name).limit(50)
|
||||||
|
assign_closeted!
|
||||||
|
|
||||||
if @items.empty?
|
if @items.empty?
|
||||||
render file: "public/404.html", status: :not_found, layout: nil
|
render file: "public/404.html", status: :not_found, layout: nil
|
||||||
|
@ -155,6 +156,16 @@ class ItemsController < ApplicationController
|
||||||
[color, color.example_pet_type(preferred_species: species)]
|
[color, color.example_pet_type(preferred_species: species)]
|
||||||
end.to_h
|
end.to_h
|
||||||
|
|
||||||
|
# Create a second value that only include the items the user *needs*: that
|
||||||
|
# is, that they don't already own.
|
||||||
|
@nc_mall_items_needed = @nc_mall_items.reject(&:owned?)
|
||||||
|
@buyable_dyeworks_items_needed = @buyable_dyeworks_items.reject(&:owned?)
|
||||||
|
@np_items_needed = @np_items.reject(&:owned?)
|
||||||
|
@pb_items_needed = @pb_items.reject(&:owned?)
|
||||||
|
@other_nc_items_needed = @other_nc_items.reject(&:owned?)
|
||||||
|
@pb_items_needed_by_color =
|
||||||
|
@pb_items_by_color.transform_values { |items| items.reject(&:owned?) }
|
||||||
|
|
||||||
# Finish loading the NC trade values.
|
# Finish loading the NC trade values.
|
||||||
trade_values_task.wait
|
trade_values_task.wait
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ class AltStyle < ApplicationRecord
|
||||||
validates :body_id, presence: true
|
validates :body_id, presence: true
|
||||||
|
|
||||||
before_create :infer_series_name
|
before_create :infer_series_name
|
||||||
|
before_create :infer_thumbnail_url
|
||||||
|
|
||||||
scope :matching_name, ->(series_name, color_name, species_name) {
|
scope :matching_name, ->(series_name, color_name, species_name) {
|
||||||
color = Color.find_by_name!(color_name)
|
color = Color.find_by_name!(color_name)
|
||||||
|
@ -41,22 +42,6 @@ class AltStyle < ApplicationRecord
|
||||||
"#{series_name} #{color.human_name}"
|
"#{series_name} #{color.human_name}"
|
||||||
end
|
end
|
||||||
|
|
||||||
THUMBNAIL_URL_TEMPLATE = Addressable::Template.new(
|
|
||||||
"https://images.neopets.com/items/{series}_{color}_{species}.gif"
|
|
||||||
)
|
|
||||||
DEFAULT_THUMBNAIL_URL = "https://images.neopets.com/items/mall_bg_circle.gif"
|
|
||||||
def thumbnail_url
|
|
||||||
return DEFAULT_THUMBNAIL_URL unless has_real_series_name?
|
|
||||||
|
|
||||||
# HACK: We're assuming this is the format long-term! But if it changes, we
|
|
||||||
# may need to add it as a database field instead.
|
|
||||||
THUMBNAIL_URL_TEMPLATE.expand(
|
|
||||||
series: series_name.gsub(/\s+/, '').downcase,
|
|
||||||
color: color.name.gsub(/\s+/, '').downcase,
|
|
||||||
species: species.name.gsub(/\s+/, '').downcase,
|
|
||||||
).to_s
|
|
||||||
end
|
|
||||||
|
|
||||||
def preview_image_url
|
def preview_image_url
|
||||||
swf_asset = swf_assets.first
|
swf_asset = swf_assets.first
|
||||||
return nil if swf_asset.nil?
|
return nil if swf_asset.nil?
|
||||||
|
@ -91,6 +76,26 @@ class AltStyle < ApplicationRecord
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# At time of writing, most batches of Alt Styles thumbnails used a simple
|
||||||
|
# pattern for the item thumbnail URL, but that's not always the case anymore.
|
||||||
|
# For now, let's keep using this format as the default value when creating a
|
||||||
|
# new Alt Style, but the database field can be manually overridden as needed!
|
||||||
|
THUMBNAIL_URL_TEMPLATE = Addressable::Template.new(
|
||||||
|
"https://images.neopets.com/items/{series}_{color}_{species}.gif"
|
||||||
|
)
|
||||||
|
DEFAULT_THUMBNAIL_URL = "https://images.neopets.com/items/mall_bg_circle.gif"
|
||||||
|
def infer_thumbnail_url
|
||||||
|
if has_real_series_name?
|
||||||
|
self.thumbnail_url = THUMBNAIL_URL_TEMPLATE.expand(
|
||||||
|
series: series_name.gsub(/\s+/, '').downcase,
|
||||||
|
color: color.name.gsub(/\s+/, '').downcase,
|
||||||
|
species: species.name.gsub(/\s+/, '').downcase,
|
||||||
|
).to_s
|
||||||
|
else
|
||||||
|
self.thumbnail_url = DEFAULT_THUMBNAIL_URL
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# For convenience in the console!
|
# For convenience in the console!
|
||||||
def self.find_by_name(color_name, species_name)
|
def self.find_by_name(color_name, species_name)
|
||||||
color = Color.find_by_name(color_name)
|
color = Color.find_by_name(color_name)
|
||||||
|
|
|
@ -4,12 +4,15 @@
|
||||||
- content = yield
|
- content = yield
|
||||||
- subtitle = yield :subtitle
|
- subtitle = yield :subtitle
|
||||||
|
|
||||||
%tr
|
%tr{"data-item-owned": item.owned?}
|
||||||
%td.thumbnail-cell
|
%td.thumbnail-cell
|
||||||
= link_to item_thumbnail_for(item), item, target: "_blank",
|
= link_to item_thumbnail_for(item), item, target: "_blank",
|
||||||
tabindex: "-1"
|
tabindex: "-1"
|
||||||
%td.name-cell
|
%td.name-cell
|
||||||
= link_to item.name, item, target: "_blank"
|
= link_to item.name, item, target: "_blank", class: "item-name"
|
||||||
|
- if item.owned?
|
||||||
|
%span.owned-explanation
|
||||||
|
(You own this)
|
||||||
- if subtitle.present?
|
- if subtitle.present?
|
||||||
.subtitle= subtitle
|
.subtitle= subtitle
|
||||||
%td.actions-cell= content
|
%td.actions-cell= content
|
||||||
|
|
|
@ -16,13 +16,14 @@
|
||||||
%tr
|
%tr
|
||||||
%td
|
%td
|
||||||
%th
|
%th
|
||||||
Total: #{nc_total_for @nc_mall_items} NC
|
Total: #{nc_total_for @nc_mall_items_needed} NC
|
||||||
(#{pluralize @nc_mall_items.size, "item"})
|
(#{pluralize @nc_mall_items_needed.size, "item"})
|
||||||
|
|
||||||
%td.actions-cell
|
%td.actions-cell
|
||||||
%button{onclick: "alert('Todo!')"}
|
- if @nc_mall_items_needed.present?
|
||||||
= cart_icon alt: ""
|
%button{onclick: "alert('Todo!')"}
|
||||||
Buy all in NC Mall
|
= cart_icon alt: ""
|
||||||
|
Buy all in NC Mall
|
||||||
%tbody
|
%tbody
|
||||||
- @nc_mall_items.each do |item|
|
- @nc_mall_items.each do |item|
|
||||||
= render "item_list_row", item: do
|
= render "item_list_row", item: do
|
||||||
|
@ -42,25 +43,27 @@
|
||||||
|
|
||||||
%table.item-list
|
%table.item-list
|
||||||
%thead
|
%thead
|
||||||
%td.thumbnail-cell
|
%tr
|
||||||
= image_tag "https://images.neopets.com/items/mall_80x80_cleaning.gif",
|
%td.thumbnail-cell
|
||||||
alt: "Dyeworks Hue Brew Potion"
|
= image_tag "https://images.neopets.com/items/mall_80x80_cleaning.gif",
|
||||||
%th
|
alt: "Dyeworks Hue Brew Potion"
|
||||||
Total: #{dyeworks_nc_total_for @buyable_dyeworks_items} NC
|
%th
|
||||||
= surround "(", ")" do
|
Total: #{dyeworks_nc_total_for @buyable_dyeworks_items_needed} NC
|
||||||
%span.price-breakdown{
|
= surround "(", ")" do
|
||||||
title: "#{dyeworks_items_nc_total_for(@buyable_dyeworks_items)} NC"
|
%span.price-breakdown{
|
||||||
}<
|
title: "#{dyeworks_items_nc_total_for(@buyable_dyeworks_items_needed)} NC"
|
||||||
#{pluralize @buyable_dyeworks_items.size, "item"}
|
}<
|
||||||
+
|
#{pluralize @buyable_dyeworks_items_needed.size, "item"}
|
||||||
%span.price-breakdown{
|
+
|
||||||
title: dyeworks_potions_nc_summary(@buyable_dyeworks_items.size)
|
%span.price-breakdown{
|
||||||
}<
|
title: dyeworks_potions_nc_summary(@buyable_dyeworks_items_needed.size)
|
||||||
#{pluralize @buyable_dyeworks_items.size, "potion"}
|
}<
|
||||||
%td.actions-cell
|
#{pluralize @buyable_dyeworks_items_needed.size, "potion"}
|
||||||
%button{onclick: "alert('Todo!')"}
|
%td.actions-cell
|
||||||
= cart_icon alt: ""
|
- if @buyable_dyeworks_items_needed.present?
|
||||||
Buy all in NC Mall
|
%button{onclick: "alert('Todo!')"}
|
||||||
|
= cart_icon alt: ""
|
||||||
|
Buy all in NC Mall
|
||||||
%tbody
|
%tbody
|
||||||
- @buyable_dyeworks_items.each do |item|
|
- @buyable_dyeworks_items.each do |item|
|
||||||
= render "item_list_row", item: do
|
= render "item_list_row", item: do
|
||||||
|
@ -96,9 +99,10 @@
|
||||||
|
|
||||||
%table.item-list
|
%table.item-list
|
||||||
%thead
|
%thead
|
||||||
%td
|
%tr
|
||||||
%th{colspan: 2}
|
%td
|
||||||
Total: #{pluralize @np_items.size, "item"}
|
%th{colspan: 2}
|
||||||
|
Total: #{pluralize @np_items_needed.size, "item"}
|
||||||
%tbody
|
%tbody
|
||||||
- @np_items.each do |item|
|
- @np_items.each do |item|
|
||||||
= render "item_list_row", item: do
|
= render "item_list_row", item: do
|
||||||
|
@ -116,39 +120,44 @@
|
||||||
"cross-paint" outfits.
|
"cross-paint" outfits.
|
||||||
|
|
||||||
- @pb_items_by_color.each do |color, items|
|
- @pb_items_by_color.each do |color, items|
|
||||||
%table.item-list{"data-group-type": "bundle"}
|
- items_needed = @pb_items_needed_by_color[color]
|
||||||
|
%table.item-list{
|
||||||
|
"data-group-type": "bundle",
|
||||||
|
"data-group-owned": items.all?(&:owned?),
|
||||||
|
}
|
||||||
%thead
|
%thead
|
||||||
%td.thumbnail-cell
|
%tr
|
||||||
- if color&.pb_item_thumbnail_url?
|
%td.thumbnail-cell
|
||||||
= image_tag color.pb_item_thumbnail_url,
|
- if color&.pb_item_thumbnail_url?
|
||||||
alt: "Item thumbnail for #{color.pb_item_name}"
|
= image_tag color.pb_item_thumbnail_url,
|
||||||
- elsif color
|
alt: "Item thumbnail for #{color.pb_item_name}"
|
||||||
= image_tag pet_type_image_url(@pb_color_pet_types[color], size: :face),
|
- elsif color
|
||||||
srcset: ["#{pet_type_image_url(@pb_color_pet_types[color], size: :face_2x)} 2x"],
|
= image_tag pet_type_image_url(@pb_color_pet_types[color], size: :face),
|
||||||
alt: @pb_color_pet_types[color].human_name
|
srcset: ["#{pet_type_image_url(@pb_color_pet_types[color], size: :face_2x)} 2x"],
|
||||||
- else
|
alt: @pb_color_pet_types[color].human_name
|
||||||
= image_tag "https://images.neopets.com/items/starter_red_pb.gif",
|
- else
|
||||||
alt: "Item thumbnail for Starter Red Paint Brush"
|
= image_tag "https://images.neopets.com/items/starter_red_pb.gif",
|
||||||
%th
|
alt: "Item thumbnail for Starter Red Paint Brush"
|
||||||
- if color
|
%th
|
||||||
#{color.pb_item_name || color.name.humanize}
|
- if color
|
||||||
- else
|
#{color.pb_item_name || color.name.humanize}
|
||||||
Basic colors
|
- else
|
||||||
(#{pluralize items.size, "item"})
|
Basic colors
|
||||||
%td.actions-cell
|
(#{pluralize items_needed.size, "item"})
|
||||||
- if color&.pb_item_name?
|
%td.actions-cell
|
||||||
= button_link_to "Shops",
|
- if color&.pb_item_name?
|
||||||
shop_wizard_url_for(color.pb_item_name),
|
= button_link_to "Shops",
|
||||||
target: "_blank", icon: search_icon
|
shop_wizard_url_for(color.pb_item_name),
|
||||||
= button_link_to "Trades",
|
target: "_blank", icon: search_icon
|
||||||
trading_post_url_for(color.pb_item_name),
|
= button_link_to "Trades",
|
||||||
target: "_blank", icon: search_icon
|
trading_post_url_for(color.pb_item_name),
|
||||||
- elsif color
|
target: "_blank", icon: search_icon
|
||||||
.special-color-explanation
|
- elsif color
|
||||||
Get via Lab Ray, morphing potions, etc.
|
.special-color-explanation
|
||||||
- else
|
Get via Lab Ray, morphing potions, etc.
|
||||||
.special-color-explanation
|
- else
|
||||||
Many colors, like Red, will grant these items.
|
.special-color-explanation
|
||||||
|
Many colors, like Red, will grant these items.
|
||||||
%tbody
|
%tbody
|
||||||
- items.each do |item|
|
- items.each do |item|
|
||||||
= render "item_list_row", item:
|
= render "item_list_row", item:
|
||||||
|
@ -175,7 +184,7 @@
|
||||||
%thead
|
%thead
|
||||||
%td
|
%td
|
||||||
%th{colspan: 2}
|
%th{colspan: 2}
|
||||||
Total: #{pluralize @other_nc_items.size, "item"}
|
Total: #{pluralize @other_nc_items_needed.size, "item"}
|
||||||
%tbody
|
%tbody
|
||||||
- @other_nc_items.each do |item|
|
- @other_nc_items.each do |item|
|
||||||
= render "item_list_row", item: do
|
= render "item_list_row", item: do
|
||||||
|
|
14
db/migrate/20240616001002_add_thumbnail_url_to_alt_styles.rb
Normal file
14
db/migrate/20240616001002_add_thumbnail_url_to_alt_styles.rb
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
class AddThumbnailUrlToAltStyles < ActiveRecord::Migration[7.1]
|
||||||
|
def change
|
||||||
|
add_column :alt_styles, :thumbnail_url, :string, null: false
|
||||||
|
|
||||||
|
reversible do |direction|
|
||||||
|
direction.up do
|
||||||
|
AltStyle.find_each do |alt_style|
|
||||||
|
alt_style.infer_thumbnail_url
|
||||||
|
alt_style.save!
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -10,7 +10,7 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema[7.1].define(version: 2024_06_08_022149) do
|
ActiveRecord::Schema[7.1].define(version: 2024_06_16_001002) do
|
||||||
create_table "alt_styles", charset: "utf8mb4", collation: "utf8mb4_unicode_520_ci", force: :cascade do |t|
|
create_table "alt_styles", charset: "utf8mb4", collation: "utf8mb4_unicode_520_ci", force: :cascade do |t|
|
||||||
t.integer "species_id", null: false
|
t.integer "species_id", null: false
|
||||||
t.integer "color_id", null: false
|
t.integer "color_id", null: false
|
||||||
|
@ -18,6 +18,7 @@ ActiveRecord::Schema[7.1].define(version: 2024_06_08_022149) do
|
||||||
t.datetime "created_at", precision: nil, null: false
|
t.datetime "created_at", precision: nil, null: false
|
||||||
t.datetime "updated_at", precision: nil, null: false
|
t.datetime "updated_at", precision: nil, null: false
|
||||||
t.string "series_name"
|
t.string "series_name"
|
||||||
|
t.string "thumbnail_url", null: false
|
||||||
t.index ["color_id"], name: "index_alt_styles_on_color_id"
|
t.index ["color_id"], name: "index_alt_styles_on_color_id"
|
||||||
t.index ["species_id"], name: "index_alt_styles_on_species_id"
|
t.index ["species_id"], name: "index_alt_styles_on_species_id"
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue