impress/app/controllers/outfits_controller.rb

226 lines
6.5 KiB
Ruby

class OutfitsController < ApplicationController
before_action :find_authorized_outfit, :only => [:update, :destroy]
def create
@outfit = Outfit.new(outfit_params)
@outfit.user = current_user
if @outfit.save
render :json => @outfit
else
render_outfit_errors
end
end
def edit
render "outfits/edit", layout: false
end
def index
if user_signed_in?
@outfits = current_user.outfits.
includes(:item_outfit_relationships, {:pet_state => :pet_type}).
wardrobe_order
respond_to do |format|
format.html { render }
format.json { render :json => @outfits }
end
else
respond_to do |format|
format.html { redirect_to new_auth_user_session_path(:return_to => request.fullpath) }
format.json { render :json => [] }
end
end
end
def destroy
@outfit.destroy
respond_to do |format|
format.html {
flash[:notice] = t('outfits.destroy.success',
:outfit_name => @outfit.name)
redirect_to current_user_outfits_path
}
format.json { render :json => true }
end
end
def new
@colors = Color.alphabetical
@species = Species.alphabetical
newest_items = Item.newest.limit(18)
@newest_modeled_items, @newest_unmodeled_items =
newest_items.partition(&:predicted_fully_modeled?)
@newest_unmodeled_items_predicted_missing_species_by_color = {}
@newest_unmodeled_items_predicted_modeled_ratio = {}
@newest_unmodeled_items.each do |item|
h = item.predicted_missing_nonstandard_body_ids_by_species_by_color
standard_body_ids_by_species = item.
predicted_missing_standard_body_ids_by_species
if standard_body_ids_by_species.present?
h[:standard] = standard_body_ids_by_species
end
@newest_unmodeled_items_predicted_missing_species_by_color[item] = h
@newest_unmodeled_items_predicted_modeled_ratio[item] = item.predicted_modeled_ratio
end
@species_count = Species.count
@latest_contribution = Contribution.recent.first
Contribution.preload_contributeds_and_parents([@latest_contribution].compact)
@neopets_usernames = user_signed_in? ? current_user.neopets_usernames : []
@campaign = Fundraising::Campaign.current rescue nil
end
def new_v2
# Get selected species and color from params, or default to Blue Acara
@selected_species = params[:species] ? Species.find_by_id(params[:species]) : Species.find_by_name("Acara")
@selected_color = params[:color] ? Color.find_by_id(params[:color]) : Color.find_by_name("Blue")
# Load valid colors for the selected species (colors that have existing pet types)
@species = Species.alphabetical
@colors = @selected_species.compatible_colors
# Find the best pet type for this species+color combo
# If the exact combo doesn't exist, this will fall back to a simple color
@pet_type = PetType.for_species_and_color(
species_id: @selected_species.id,
color_id: @selected_color.id
)
# Use the pet type's actual color as the selected color
# (might differ from requested color if we fell back to a simple color)
@selected_color = @pet_type&.color
# Load items from the objects[] parameter
item_ids = params[:objects] || []
items = Item.where(id: item_ids)
# Build the outfit
@outfit = Outfit.new(
pet_state: @pet_type&.canonical_pet_state,
worn_items: items,
)
# Preload the manifests for all visible layers, so they load efficiently
# in parallel rather than sequentially when rendering
SwfAsset.preload_manifests(@outfit.visible_layers)
# Handle search mode
@search_mode = params[:q].present?
if @search_mode
search_filters = build_search_filters(params[:q], @outfit)
query_params = ActionController::Parameters.new(
search_filters.each_with_index.map { |filter, i| [i.to_s, filter] }.to_h
)
@query = Item::Search::Query.from_params(query_params, current_user)
@search_results = @query.results.paginate(page: params.dig(:q, :page), per_page: 30)
end
render layout: false
end
def show
@outfit = Outfit.find(params[:id])
respond_to do |format|
format.html { render "outfits/edit", layout: false }
format.json { render json: @outfit }
end
end
def start
# Start URLs are always in English, so let's make sure we search in
# English.
I18n.locale = I18n.default_locale
@species = Species.find_by_name params[:species_name]
@color = Color.find_by_name params[:color_name]
if @species && @color
redirect_to wardrobe_path(:species => @species.id, :color => @color.id)
else
not_found('species/color')
end
end
def update
if @outfit.update(outfit_params)
render :json => @outfit
else
render_outfit_errors
end
end
private
def outfit_params
params.require(:outfit).permit(
:name, :starred, :alt_style_id, item_ids: {worn: [], closeted: []},
biology: [:species_id, :color_id, :pose, :pet_state_id])
end
def find_authorized_outfit
raise ActiveRecord::RecordNotFound unless user_signed_in?
@outfit = current_user.outfits.find(params[:id])
end
def render_outfit_errors
render :json => {:errors => @outfit.errors,
:full_error_messages => @outfit.errors.full_messages},
:status => :bad_request
end
def build_search_filters(query_params, outfit)
filters = []
# Add name filter if present
if query_params[:name].present?
filters << { key: "name", value: query_params[:name] }
end
# Add item kind filter if present
if query_params[:item_kind].present?
case query_params[:item_kind]
when "nc"
filters << { key: "is_nc", value: "true" }
when "np"
filters << { key: "is_np", value: "true" }
when "pb"
filters << { key: "is_pb", value: "true" }
end
end
# Add zone filter if present
if query_params[:zone].present?
filters << { key: "occupied_zone_set_name", value: query_params[:zone] }
end
# Always add auto-filter for items that fit the current pet
pet_type = outfit.pet_type
if pet_type
fit_filter = {
key: "fits",
value: {
species_id: pet_type.species_id.to_s,
color_id: pet_type.color_id.to_s
}
}
# Include alt_style_id if present
if outfit.alt_style_id.present?
fit_filter[:value][:alt_style_id] = outfit.alt_style_id.to_s
end
filters << fit_filter
end
filters
end
end