forked from OpenNeo/impress
nice page to view current user's outfits
This commit is contained in:
parent
88fbc72a46
commit
1207e84804
14 changed files with 663 additions and 514 deletions
|
@ -1,6 +1,6 @@
|
|||
class OutfitsController < ApplicationController
|
||||
before_filter :find_authorized_outfit, :only => [:update, :destroy]
|
||||
|
||||
|
||||
def create
|
||||
@outfit = Outfit.build_for_user(current_user, params[:outfit])
|
||||
if @outfit.save
|
||||
|
@ -9,12 +9,22 @@ class OutfitsController < ApplicationController
|
|||
render_outfit_errors
|
||||
end
|
||||
end
|
||||
|
||||
def for_current_user
|
||||
@outfits = user_signed_in? ? current_user.outfits : []
|
||||
render :json => @outfits
|
||||
|
||||
def index
|
||||
if user_signed_in?
|
||||
@outfits = current_user.outfits.wardrobe_order
|
||||
respond_to do |format|
|
||||
format.html { render }
|
||||
format.json { render :json => @outfits }
|
||||
end
|
||||
else
|
||||
respond_to do |format|
|
||||
format.html { redirect_to login_path(:return_to => request.fullpath) }
|
||||
format.json { render :json => [] }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def destroy
|
||||
if @outfit.destroy
|
||||
render :json => true
|
||||
|
@ -22,7 +32,7 @@ class OutfitsController < ApplicationController
|
|||
render :json => false, :status => :bad_request
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def new
|
||||
unless fragment_exist?(:action_suffix => 'start_from_scratch_form_content')
|
||||
@colors = Color.all_ordered_by_name
|
||||
|
@ -32,7 +42,7 @@ class OutfitsController < ApplicationController
|
|||
@top_contributors = User.top_contributors.limit(User::PreviewTopContributorsCount)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def show
|
||||
@outfit = Outfit.find(params[:id])
|
||||
respond_to do |format|
|
||||
|
@ -40,7 +50,7 @@ class OutfitsController < ApplicationController
|
|||
format.json { render :json => @outfit }
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def update
|
||||
if @outfit.update_attributes(params[:outfit])
|
||||
render :json => true
|
||||
|
@ -48,15 +58,16 @@ class OutfitsController < ApplicationController
|
|||
render_outfit_errors
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
|
||||
|
||||
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}, :status => :bad_request
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -2,14 +2,34 @@ module OutfitsHelper
|
|||
def destination_tag(value)
|
||||
hidden_field_tag 'destination', value, :id => nil
|
||||
end
|
||||
|
||||
|
||||
def link_to_edit_outfit(content_or_outfit, outfit_or_options, options={})
|
||||
if block_given?
|
||||
content = capture_haml(&Proc.new)
|
||||
outfit = content_or_outfit
|
||||
options = outfit_or_options
|
||||
else
|
||||
content = content_or_outfit
|
||||
outfit = outfit_or_options
|
||||
end
|
||||
query = outfit.to_query
|
||||
query << "&outfit=#{outfit.id}" if outfit.user == current_user
|
||||
link_to content, wardrobe_path(:anchor => query), options
|
||||
end
|
||||
|
||||
def outfit_li_for(outfit)
|
||||
class_name = outfit.starred? ? 'starred' : nil
|
||||
content_tag :li, :class => class_name, &Proc.new
|
||||
end
|
||||
|
||||
def pet_attribute_select(name, collection, value=nil)
|
||||
select_tag name,
|
||||
options_from_collection_for_select(collection, :id, :human_name, value)
|
||||
end
|
||||
|
||||
|
||||
def pet_name_tag(options={})
|
||||
options = {:spellcheck => false, :id => nil}.merge(options)
|
||||
text_field_tag 'name', nil, options
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -5,29 +5,31 @@ class Outfit < ActiveRecord::Base
|
|||
has_many :worn_items, :through => :worn_item_outfit_relationships, :source => :item
|
||||
belongs_to :pet_state
|
||||
belongs_to :user
|
||||
|
||||
|
||||
validates :name, :presence => {:if => :user_id}, :uniqueness => {:scope => :user_id, :if => :user_id}
|
||||
validates :pet_state, :presence => true
|
||||
|
||||
|
||||
attr_accessible :name, :pet_state_id, :starred, :worn_and_unworn_item_ids
|
||||
|
||||
|
||||
scope :wardrobe_order, order('starred DESC', :name)
|
||||
|
||||
def as_json(more_options={})
|
||||
serializable_hash :only => [:id, :name, :pet_state_id, :starred],
|
||||
:methods => [:color_id, :species_id, :worn_and_unworn_item_ids]
|
||||
end
|
||||
|
||||
|
||||
def closet_item_ids
|
||||
item_outfit_relationships.map(&:item_id)
|
||||
end
|
||||
|
||||
|
||||
def color_id
|
||||
pet_state.pet_type.color_id
|
||||
end
|
||||
|
||||
|
||||
def species_id
|
||||
pet_state.pet_type.species_id
|
||||
end
|
||||
|
||||
|
||||
def to_query
|
||||
{
|
||||
:closet => closet_item_ids,
|
||||
|
@ -37,7 +39,7 @@ class Outfit < ActiveRecord::Base
|
|||
:state => pet_state_id
|
||||
}.to_query
|
||||
end
|
||||
|
||||
|
||||
def worn_and_unworn_item_ids
|
||||
{:worn => [], :unworn => []}.tap do |output|
|
||||
item_outfit_relationships.each do |rel|
|
||||
|
@ -46,7 +48,7 @@ class Outfit < ActiveRecord::Base
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def worn_and_unworn_item_ids=(all_item_ids)
|
||||
new_rels = []
|
||||
all_item_ids.each do |key, item_ids|
|
||||
|
@ -62,11 +64,11 @@ class Outfit < ActiveRecord::Base
|
|||
end
|
||||
self.item_outfit_relationships = new_rels
|
||||
end
|
||||
|
||||
|
||||
def worn_item_ids
|
||||
worn_and_unworn_item_ids[:worn]
|
||||
end
|
||||
|
||||
|
||||
def self.build_for_user(user, params)
|
||||
Outfit.new.tap do |outfit|
|
||||
name = params.delete(:name)
|
||||
|
@ -80,3 +82,4 @@ class Outfit < ActiveRecord::Base
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
@import ../shared/jquery.jgrowl
|
||||
|
||||
@import icon
|
||||
@import star
|
||||
|
||||
$object-padding: 6px
|
||||
$nc-icon-size: 16px
|
||||
|
||||
|
@ -16,14 +19,8 @@ $outfit-header-padding: 24px
|
|||
$outfit-content-width: $sidebar-unit-inner-width - $outfit-thumbnail-size - $outfit-thumbnail-margin - 32px
|
||||
$outfit-content-inner-width: $outfit-content-width - $outfit-header-padding
|
||||
|
||||
=icon
|
||||
bottom: -2px
|
||||
height: 16px
|
||||
position: relative
|
||||
width: 16px
|
||||
|
||||
=outfit
|
||||
//+clearfix
|
||||
+outfit-star-shifted
|
||||
padding: .25em 0
|
||||
//.outfit-thumbnail
|
||||
float: left
|
||||
|
@ -38,9 +35,6 @@ $outfit-content-inner-width: $outfit-content-width - $outfit-header-padding
|
|||
position: absolute
|
||||
top: -$outfit-thumbnail-original-size / 4
|
||||
width: $outfit-thumbnail-original-size
|
||||
//> div
|
||||
float: left
|
||||
width: $outfit-content-width
|
||||
.outfit-delete
|
||||
+reset-awesome-button
|
||||
+opacity(.5)
|
||||
|
@ -55,23 +49,6 @@ $outfit-content-inner-width: $outfit-content-width - $outfit-header-padding
|
|||
header
|
||||
display: block
|
||||
padding-left: $outfit-header-padding
|
||||
.outfit-star
|
||||
+icon
|
||||
background:
|
||||
image: image-url("unstarred.png")
|
||||
position: left top
|
||||
repeat: no-repeat
|
||||
cursor: pointer
|
||||
display: block
|
||||
float: left
|
||||
margin-left: -24px
|
||||
/* makes it not take up inline space
|
||||
&.starred .outfit-star
|
||||
background-image: image-url("star.png")
|
||||
&.loading .outfit-star
|
||||
background-image: image-url("loading.gif")
|
||||
&.loading.active .outfit-star
|
||||
background-image: image-url("loading_current_outfit.gif")
|
||||
h4
|
||||
cursor: pointer
|
||||
display: inline
|
||||
|
@ -208,7 +185,7 @@ body.outfits-edit
|
|||
display: block
|
||||
.sidebar-view
|
||||
h2
|
||||
margin:
|
||||
margin:
|
||||
bottom: .25em
|
||||
left: $sidebar-unit-horizontal-padding
|
||||
#preview-closet
|
||||
|
@ -413,24 +390,24 @@ body.outfits-edit
|
|||
margin:
|
||||
right: $sidebar-unit-horizontal-padding
|
||||
top: 1em
|
||||
|
||||
|
||||
#save-success, #save-error, #outfit-not-found
|
||||
+sidebar-view-child
|
||||
display: none
|
||||
margin:
|
||||
top: 1em
|
||||
text-align: center
|
||||
|
||||
|
||||
#save-success
|
||||
+notice
|
||||
|
||||
|
||||
#save-error, #outfit-not-found
|
||||
+error
|
||||
|
||||
|
||||
#userbar-message
|
||||
+opacity(.5)
|
||||
display: none
|
||||
|
||||
|
||||
#new-outfit
|
||||
+outfit
|
||||
+sidebar-view-child
|
||||
|
@ -441,18 +418,18 @@ body.outfits-edit
|
|||
text-decoration: none
|
||||
.outfit-star
|
||||
margin-top: .5em
|
||||
|
||||
|
||||
#new-outfit-name
|
||||
font: inherit
|
||||
line-height: 1
|
||||
|
||||
|
||||
#preview-saving-outfit
|
||||
display: none
|
||||
padding-bottom: 1em
|
||||
|
||||
|
||||
#pet-type-form, #pet-state-form, #preview-swf, #preview-search-form
|
||||
position: relative
|
||||
|
||||
|
||||
.control-overlay
|
||||
height: 100%
|
||||
left: 0
|
||||
|
@ -460,27 +437,27 @@ body.outfits-edit
|
|||
top: 0
|
||||
width: 100%
|
||||
z-index: 5
|
||||
|
||||
|
||||
#preview-sidebar-nav-outfits, #save-outfit-signed-in
|
||||
display: none
|
||||
|
||||
|
||||
form#save-outfit-form
|
||||
+outfit
|
||||
display: none
|
||||
margin-right: 0
|
||||
padding: 0
|
||||
|
||||
|
||||
.outfit-star, input, button
|
||||
+inline-block
|
||||
float: none
|
||||
vertical-align: top
|
||||
|
||||
|
||||
.outfit-star
|
||||
margin-top: .25em
|
||||
|
||||
|
||||
.outfit-url
|
||||
font-size: 75%
|
||||
|
||||
|
||||
&.user-signed-in
|
||||
#preview-sidebar-nav-outfits
|
||||
display: block
|
||||
|
@ -499,10 +476,11 @@ body.outfits-edit
|
|||
display: block
|
||||
#save-outfit, #save-current-outfit, #save-outfit-copy, #current-outfit-permalink
|
||||
display: none
|
||||
|
||||
|
||||
&.user-not-signed-in
|
||||
#share-outfit, #save-outfit-not-signed-in
|
||||
display: inline-block
|
||||
#save-outfit-wrapper.shared-outfit
|
||||
#current-outfit-permalink, #current-outfit-url
|
||||
display: inline-block
|
||||
|
||||
|
|
9
app/stylesheets/outfits/_icon.sass
Normal file
9
app/stylesheets/outfits/_icon.sass
Normal file
|
@ -0,0 +1,9 @@
|
|||
$icon-width: 16px
|
||||
$icon-height: 16px
|
||||
|
||||
=icon
|
||||
bottom: -2px
|
||||
height: $icon-height
|
||||
position: relative
|
||||
width: $icon-width
|
||||
|
16
app/stylesheets/outfits/_index.sass
Normal file
16
app/stylesheets/outfits/_index.sass
Normal file
|
@ -0,0 +1,16 @@
|
|||
@import star
|
||||
|
||||
body.outfits-index
|
||||
#outfits
|
||||
list-style: none
|
||||
|
||||
li
|
||||
+outfit-star
|
||||
|
||||
h4
|
||||
display: inline
|
||||
|
||||
.outfit-edit-link
|
||||
font-size: 85%
|
||||
margin-left: 1em
|
||||
|
27
app/stylesheets/outfits/_star.sass
Normal file
27
app/stylesheets/outfits/_star.sass
Normal file
|
@ -0,0 +1,27 @@
|
|||
@import icon
|
||||
|
||||
=outfit-star
|
||||
.outfit-star
|
||||
+icon
|
||||
background:
|
||||
image: image-url("unstarred.png")
|
||||
position: left top
|
||||
repeat: no-repeat
|
||||
cursor: pointer
|
||||
display: block
|
||||
float: left
|
||||
margin-right: $icon-width / 2
|
||||
&.starred .outfit-star
|
||||
background-image: image-url("star.png")
|
||||
&.loading .outfit-star
|
||||
background-image: image-url("loading.gif")
|
||||
&.loading.active .outfit-star
|
||||
background-image: image-url("loading_current_outfit.gif")
|
||||
|
||||
=outfit-star-shifted
|
||||
+outfit-star
|
||||
|
||||
.outfit-star
|
||||
margin-left: -$icon-width * 1.5
|
||||
margin-right: 0
|
||||
|
|
@ -11,8 +11,10 @@
|
|||
@import items/index
|
||||
@import items/show
|
||||
@import outfits/edit
|
||||
@import outfits/index
|
||||
@import outfits/new
|
||||
@import outfits/show
|
||||
@import pets/bulk
|
||||
@import static/terms
|
||||
@import users/top_contributors
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
= yield(:content)
|
||||
- else
|
||||
= yield
|
||||
|
||||
|
||||
- if home_link?
|
||||
%a#home-link{:href => root_path}
|
||||
%span Dress to Impress
|
||||
|
@ -34,6 +34,7 @@
|
|||
%span
|
||||
== Hey, #{link_to current_user.name, user_contributions_path(current_user)}!
|
||||
== You have #{current_user.points} points.
|
||||
= link_to 'Outfits', current_user_outfits_path
|
||||
= link_to 'Settings', Openneo::Auth.remote_settings_url
|
||||
= link_to 'Log out', logout_path_with_return_to
|
||||
- else
|
||||
|
@ -64,3 +65,4 @@
|
|||
Images © 2000-2010 Neopets, Inc. All Rights Reserved.
|
||||
Used With Permission
|
||||
= yield(:javascripts)
|
||||
|
||||
|
|
5
app/views/outfits/_outfit.html.haml
Normal file
5
app/views/outfits/_outfit.html.haml
Normal file
|
@ -0,0 +1,5 @@
|
|||
= outfit_li_for(outfit) do
|
||||
.outfit-star
|
||||
%h4= link_to outfit.name, outfit
|
||||
= link_to_edit_outfit '(edit)', outfit, :class => 'outfit-edit-link'
|
||||
|
20
app/views/outfits/index.html.haml
Normal file
20
app/views/outfits/index.html.haml
Normal file
|
@ -0,0 +1,20 @@
|
|||
- title 'Your outfits'
|
||||
%p
|
||||
These are the outfits that you've saved to Dress to Impress so far. To save
|
||||
some more, head to the wardrobe and click Save Outfit in the top right
|
||||
corner.
|
||||
%p
|
||||
The link for each outfit is totally public, so please feel free to share the
|
||||
URL with the whole wide world.
|
||||
- unless @outfits.empty?
|
||||
%ul#outfits= render @outfits
|
||||
- else
|
||||
%p
|
||||
You haven't saved any outfits yet.
|
||||
- succeed ',' do
|
||||
= link_to 'Start at the home page', root_path
|
||||
enter a pet name or choose a color combination, create the outfit of your
|
||||
dreams, and click "Save Outfit" in the top right corner.
|
||||
%p
|
||||
It'll be fantastic. Promise.
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
- title(@outfit.name || "Shared outfit")
|
||||
%a.button#outfit-wardrobe-link{:href => wardrobe_path(:anchor => @outfit.to_query)}
|
||||
Edit a copy
|
||||
= link_to_edit_outfit(@outfit, :class => 'button', :id => 'outfit-wardrobe-link') do
|
||||
Edit
|
||||
- unless @outfit.user == current_user
|
||||
a copy
|
||||
- if @outfit.user_id
|
||||
#outfit-user
|
||||
Created by
|
||||
|
@ -15,3 +17,4 @@
|
|||
var INITIAL_OUTFIT_DATA = #{@outfit.to_json};
|
||||
= include_javascript_libraries :jquery, :swfobject
|
||||
= include_javascripts :show_outfit_package
|
||||
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
OpenneoImpressItems::Application.routes.draw do |map|
|
||||
root :to => 'outfits#new'
|
||||
|
||||
|
||||
devise_for :users
|
||||
|
||||
|
||||
match '/item_zone_sets.json' => 'ItemZoneSets#index'
|
||||
|
||||
|
||||
match '/bodies/:body_id/swf_assets.json' => 'swf_assets#index', :as => :body_swf_assets
|
||||
match '/items/:item_id/swf_assets.json' => 'swf_assets#index', :as => :item_swf_assets
|
||||
match '/items/:item_id/bodies/:body_id/swf_assets.json' => 'swf_assets#index', :as => :item_swf_assets_for_body_id
|
||||
match '/pet_types/:pet_type_id/swf_assets.json' => 'swf_assets#index', :as => :pet_type_swf_assets
|
||||
match '/pet_types/:pet_type_id/swf_assets.json' => 'swf_assets#index', :as => :pet_type_swf_assets
|
||||
match '/pet_states/:pet_state_id/swf_assets.json' => 'swf_assets#index', :as => :pet_state_swf_assets
|
||||
match '/species/:species_id/color/:color_id/pet_type.json' => 'pet_types#show'
|
||||
|
||||
|
||||
match '/roulette' => 'roulettes#new', :as => :roulette
|
||||
|
||||
|
||||
resources :contributions, :only => [:index]
|
||||
resources :items, :only => [:index, :show] do
|
||||
collection do
|
||||
|
@ -22,23 +22,24 @@ OpenneoImpressItems::Application.routes.draw do |map|
|
|||
end
|
||||
resources :outfits, :only => [:show, :create, :update, :destroy]
|
||||
resources :pet_attributes, :only => [:index]
|
||||
|
||||
match '/users/current-user/outfits.json' => 'outfits#for_current_user'
|
||||
|
||||
|
||||
match '/users/current-user/outfits' => 'outfits#index', :as => :current_user_outfits
|
||||
|
||||
match '/pets/load' => 'pets#load', :method => :post, :as => :load_pet
|
||||
match '/pets/bulk' => 'pets#bulk', :as => :bulk_pets
|
||||
|
||||
|
||||
match '/login' => 'sessions#new', :as => :login
|
||||
match '/logout' => 'sessions#destroy', :as => :logout
|
||||
match '/users/authorize' => 'sessions#create'
|
||||
|
||||
|
||||
resources :user, :only => [] do
|
||||
resources :contributions, :only => [:index]
|
||||
end
|
||||
match 'users/top-contributors' => 'users#top_contributors', :as => :top_contributors
|
||||
match 'users/top_contributors' => redirect('/users/top-contributors')
|
||||
|
||||
|
||||
match '/wardrobe' => 'outfits#edit', :as => :wardrobe
|
||||
|
||||
|
||||
match '/terms' => 'static#terms', :as => :terms
|
||||
end
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue