Emi Matchu
b22ccbc2a3
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!
208 lines
6.3 KiB
Ruby
208 lines
6.3 KiB
Ruby
class ItemsController < ApplicationController
|
|
before_action :set_query
|
|
rescue_from Item::Search::Error, :with => :search_error
|
|
|
|
def index
|
|
if @query
|
|
if params[:per_page]
|
|
per_page = params[:per_page].to_i
|
|
per_page = 50 if per_page && per_page > 50
|
|
else
|
|
per_page = 30
|
|
end
|
|
|
|
@items = @query.results.paginate(
|
|
page: params[:page], per_page: per_page)
|
|
assign_closeted!
|
|
|
|
respond_to do |format|
|
|
format.html {
|
|
@campaign = Fundraising::Campaign.current rescue nil
|
|
if @items.count == 1
|
|
redirect_to @items.first
|
|
else
|
|
render
|
|
end
|
|
}
|
|
format.json {
|
|
render json: {
|
|
items: @items.as_json(
|
|
methods: [:nc?, :pb?, :owned?, :wanted?],
|
|
),
|
|
appearances: load_appearances.as_json(
|
|
include: {
|
|
swf_assets: {
|
|
only: [:id, :remote_id, :body_id],
|
|
include: {
|
|
zone: {
|
|
only: [:id, :depth, :label],
|
|
methods: [:is_commonly_used_by_items],
|
|
},
|
|
restricted_zones: {
|
|
only: [:id, :depth, :label],
|
|
methods: [:is_commonly_used_by_items],
|
|
},
|
|
},
|
|
methods: [:urls, :known_glitches],
|
|
},
|
|
}
|
|
),
|
|
total_pages: @items.total_pages,
|
|
query: @query.to_s,
|
|
}
|
|
}
|
|
end
|
|
elsif params.has_key?(:ids) && params[:ids].is_a?(Array)
|
|
@items = Item.find(params[:ids])
|
|
assign_closeted!
|
|
respond_to do |format|
|
|
format.json { render json: @items }
|
|
end
|
|
else
|
|
respond_to do |format|
|
|
format.html {
|
|
@campaign = Fundraising::Campaign.current rescue nil
|
|
@newest_items = Item.newest.limit(18)
|
|
}
|
|
end
|
|
end
|
|
end
|
|
|
|
def show
|
|
@item = Item.find params[:id]
|
|
|
|
respond_to do |format|
|
|
format.html do
|
|
@trades = @item.closet_hangers.trading.user_is_active.to_trades
|
|
|
|
@contributors_with_counts = @item.contributors_with_counts
|
|
|
|
if user_signed_in?
|
|
@current_user_lists = current_user.closet_lists.alphabetical.
|
|
group_by_owned
|
|
@current_user_quantities = current_user.item_quantities_for(@item)
|
|
end
|
|
end
|
|
|
|
format.gif do
|
|
expires_in 1.month
|
|
redirect_to @item.thumbnail_url, allow_other_host: true
|
|
end
|
|
end
|
|
end
|
|
|
|
def needed
|
|
if params[:color] && params[:species]
|
|
@pet_type = PetType.find_by_color_id_and_species_id(
|
|
params[:color],
|
|
params[:species]
|
|
)
|
|
end
|
|
|
|
unless @pet_type
|
|
raise ActiveRecord::RecordNotFound, 'Pet type not found'
|
|
end
|
|
|
|
@items = @pet_type.needed_items.order(:name)
|
|
assign_closeted!
|
|
|
|
respond_to do |format|
|
|
format.html { @pet_name = params[:name] ; render :layout => 'application' }
|
|
format.json { render :json => @items }
|
|
end
|
|
end
|
|
|
|
def sources
|
|
item_ids = params[:ids].split(",")
|
|
@items = Item.where(id: item_ids).includes(:nc_mall_record).
|
|
includes(:dyeworks_base_item).order(:name).limit(50)
|
|
|
|
if @items.empty?
|
|
render file: "public/404.html", status: :not_found, layout: nil
|
|
return
|
|
end
|
|
|
|
# For Dyeworks items whose base is currently in the NC Mall, preload their
|
|
# trade values. We'll use this to determine which ones are fully buyable rn
|
|
# (because Owls tracks this data and we don't).
|
|
Item.preload_nc_trade_values(@items.select(&:dyeworks_base_buyable?))
|
|
|
|
# Group the items by category!
|
|
@nc_mall_items = @items.select(&:currently_in_mall?).
|
|
reject(&:dyeworks_buyable?)
|
|
@buyable_dyeworks_items = @items.select(&:dyeworks_buyable?)
|
|
@np_items = @items.select(&:np?)
|
|
@pb_items = @items.select(&:pb?)
|
|
@other_nc_items = @items.select(&:nc?).reject(&:currently_in_mall?).
|
|
reject(&:dyeworks_buyable?)
|
|
|
|
# Start loading the NC trade values for the non-Mall NC items.
|
|
trade_values_task = Async { Item.preload_nc_trade_values(@other_nc_items) }
|
|
|
|
# Also, PB items have some special handling: we group them by color, then
|
|
# load example pet types for the colors that don't have paint brushes.
|
|
@pb_items_by_color = @pb_items.group_by(&:pb_color).
|
|
sort_by { |color, items| color&.name }.to_h
|
|
|
|
colors_without_thumbnails = @pb_items_by_color.keys.
|
|
select(&:present?).reject(&:pb_item_thumbnail_url?)
|
|
|
|
@pb_color_pet_types = colors_without_thumbnails.map do |color|
|
|
# Infer the ideal species from the first item we can, then try to find a
|
|
# matching pet type to use as the thumbnail, if needed.
|
|
species = @pb_items_by_color[color].map(&:pb_species).select(&:present?)
|
|
.first
|
|
[color, color.example_pet_type(preferred_species: species)]
|
|
end.to_h
|
|
|
|
# Finish loading the NC trade values.
|
|
trade_values_task.wait
|
|
|
|
render layout: "application"
|
|
end
|
|
|
|
protected
|
|
|
|
def assign_closeted!
|
|
current_user.assign_closeted_to_items!(@items) if user_signed_in?
|
|
end
|
|
|
|
def load_appearances
|
|
appearance_params = params[:with_appearances_for]
|
|
return {} if appearance_params.blank?
|
|
|
|
if appearance_params[:alt_style_id].present?
|
|
target = Item::Search::Query.load_alt_style_by_id(
|
|
appearance_params[:alt_style_id])
|
|
else
|
|
target = Item::Search::Query.load_pet_type_by_color_and_species(
|
|
appearance_params[:color_id], appearance_params[:species_id])
|
|
end
|
|
|
|
target.appearances_for(@items.map(&:id), swf_asset_includes: [:zone]).
|
|
tap do |appearances|
|
|
# Preload the manifests for these SWF assets concurrently, rather than
|
|
# loading them in sequence when we generate the JSON.
|
|
swf_assets = appearances.values.map(&:swf_assets).flatten
|
|
SwfAsset.preload_manifests(swf_assets)
|
|
end
|
|
end
|
|
|
|
def search_error(e)
|
|
@items = []
|
|
@query = params[:q]
|
|
respond_to do |format|
|
|
format.html { flash.now[:alert] = e.message; render }
|
|
format.json { render :json => {error: e.message} }
|
|
end
|
|
end
|
|
|
|
def set_query
|
|
q = params[:q]
|
|
if q.is_a?(String)
|
|
@query = Item::Search::Query.from_text(q, current_user)
|
|
elsif q.is_a?(ActionController::Parameters)
|
|
@query = Item::Search::Query.from_params(q, current_user)
|
|
end
|
|
end
|
|
end
|