Compare commits

...

3 commits

Author SHA1 Message Date
5e6c2c3c3f Put the new item preview in a Turbo frame
Nice, gotta say, this is a pretty neat way of making things feel more
app-y! There's some missing pieces here about like, loading state etc,
but the vibes are pretty good, and the implementation was dead-easy!
2024-07-01 13:48:20 -07:00
a8b4f9be65 [WIP] Add species/color picker for simplified item page preview
Still a lot missing here, like choosing the right default for Baby etc
items, and saving the user's preferences. But it's a start!
2024-06-30 23:34:27 -07:00
7733e9a8c4 [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-06-30 23:09:28 -07:00
6 changed files with 111 additions and 16 deletions

View file

@ -37,3 +37,34 @@ body.items-show
.nc-icon
height: 16px
width: 16px
outfit-viewer
position: relative
display: block
width: 300px
height: 300px
border: 1px solid $module-border-color
border-radius: 1em
overflow: hidden
margin: 0 auto .75em
outfit-layer
display: block
position: absolute
inset: 0
img
width: 100%
height: 100%
.species-color-picker
.error-icon
cursor: help
margin-right: .25em
&[data-is-valid="false"]
select
border-color: $error-border-color
color: $error-color

View file

@ -82,6 +82,17 @@ class ItemsController < ApplicationController
group_by_owned
@current_user_quantities = current_user.item_quantities_for(@item)
end
@selected_preview_pet_type = load_selected_preview_pet_type
@preview_pet_type = load_preview_pet_type
@item_layers = @item.appearance_for(
@preview_pet_type, swf_asset_includes: [:zone]
).swf_assets
@pet_layers = @preview_pet_type.canonical_pet_state.swf_assets.
includes(:zone)
@preview_error = validate_preview
end
format.gif do
@ -188,6 +199,38 @@ class ItemsController < ApplicationController
SwfAsset.preload_manifests(swf_assets)
end
end
def load_selected_preview_pet_type
color_id = params.dig(:preview, :color_id)
species_id = params.dig(:preview, :species_id)
return load_default_preview_pet_type if color_id.nil? || species_id.nil?
PetType.find_or_initialize_by(color_id:, species_id:)
end
def load_preview_pet_type
if @selected_preview_pet_type.persisted?
@selected_preview_pet_type
else
load_default_preview_pet_type
end
end
def load_default_preview_pet_type
PetType.find_by_color_id_and_species_id(
Color.find_by_name("Blue"),
Species.find_by_name("Acara"),
)
end
def validate_preview
if @selected_preview_pet_type.new_record?
:pet_type_does_not_exist
elsif @item_layers.empty?
:no_item_data
end
end
def search_error(e)
@items = []

View file

@ -260,5 +260,15 @@ module ItemsHelper
def item_header_user_lists_form_state
cookies.fetch("DTIItemPageUserListsFormState", "closed")
end
def outfit_viewer_layers(swf_assets)
swf_assets.map { |a| outfit_viewer_layer(a) }.join("\n").html_safe
end
def outfit_viewer_layer(swf_asset)
content_tag "outfit-layer", style: "z-index: #{swf_asset.zone.depth}" do
image_tag swf_asset.image_url, alt: ""
end
end
end

View file

@ -1,15 +1,2 @@
import React from "react";
import ReactDOM from "react-dom";
import { AppProvider, ItemPageOutfitPreview } from "./wardrobe-2020";
const rootNode = document.querySelector("#outfit-preview-root");
const itemId = rootNode.getAttribute("data-item-id");
// TODO: Use the new React 18 APIs instead!
// eslint-disable-next-line react/no-deprecated
ReactDOM.render(
<AppProvider>
<ItemPageOutfitPreview itemId={itemId} />
</AppProvider>,
rootNode,
);
// eslint-disable-next-line no-console
console.log("OwO!");

View file

@ -593,6 +593,10 @@ class Item < ApplicationRecord
end
end
def appearance_for(target, ...)
Item.appearances_for([id], target, ...)[id]
end
# Given a list of item IDs, return how they look on the given target (either
# a pet type or an alt style).
def self.appearances_for(item_ids, target, swf_asset_includes: [])

View file

@ -13,7 +13,27 @@
how we handle zones. Until then, these items will be <em>very</em> buggy,
sorry!
#outfit-preview-root{'data-item-id': @item.id}
= turbo_frame_tag "item-preview" do
%outfit-viewer
%outfit-pet-appearance
= outfit_viewer_layers @pet_layers
%outfit-item-appearance
= outfit_viewer_layers @item_layers
= form_for item_path(@item), method: :get, class: "species-color-picker",
data: {"is-valid": @preview_error.nil?} do |f|
- if @preview_error == :pet_type_does_not_exist
%span.error-icon{title: "We haven't seen this kind of pet before."} ⚠️
- elsif @preview_error == :no_item_data
%span.error-icon{title: "We haven't seen this item on this pet before."} ⚠️
= select_tag "preview[color_id]",
options_from_collection_for_select(Color.funny.alphabetical,
"id", "human_name", @selected_preview_pet_type.color_id)
= select_tag "preview[species_id]",
options_from_collection_for_select(Species.alphabetical,
"id", "human_name", @selected_preview_pet_type.species_id)
= submit_tag "Go", name: nil
- unless @contributors_with_counts.empty?
#item-contributors