forked from OpenNeo/impress
lovely interface for saving outfits. still no reading them yet
This commit is contained in:
parent
1fd98fb191
commit
1dd2ccb00b
21 changed files with 1286 additions and 612 deletions
|
@ -1,4 +1,18 @@
|
||||||
class OutfitsController < ApplicationController
|
class OutfitsController < ApplicationController
|
||||||
|
def create
|
||||||
|
if user_signed_in?
|
||||||
|
outfit = Outfit.new params[:outfit]
|
||||||
|
outfit.user = current_user
|
||||||
|
if outfit.save
|
||||||
|
render :json => true
|
||||||
|
else
|
||||||
|
render :json => {:errors => outfit.errors}, :status => :bad_request
|
||||||
|
end
|
||||||
|
else
|
||||||
|
render :json => {:errors => {:user => ['not logged in']}}, :status => :forbidden
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def new
|
def new
|
||||||
@colors = Color.all
|
@colors = Color.all
|
||||||
@species = Species.all
|
@species = Species.all
|
||||||
|
|
|
@ -18,7 +18,7 @@ class SessionsController < ApplicationController
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
warden.logout
|
warden.logout
|
||||||
redirect_to root_path
|
redirect_to (params[:return_to] || root_path)
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
|
@ -29,7 +29,7 @@ module ApplicationHelper
|
||||||
:addthis => 'http://s7.addthis.com/js/250/addthis_widget.js#username=openneo',
|
:addthis => 'http://s7.addthis.com/js/250/addthis_widget.js#username=openneo',
|
||||||
:bitly => 'http://bit.ly/javascript-api.js?version=latest&login=openneo&apiKey=R_4d0438829b7a99860de1d3edf55d8dc8',
|
:bitly => 'http://bit.ly/javascript-api.js?version=latest&login=openneo&apiKey=R_4d0438829b7a99860de1d3edf55d8dc8',
|
||||||
:html5 => 'http://html5shim.googlecode.com/svn/trunk/html5.js',
|
:html5 => 'http://html5shim.googlecode.com/svn/trunk/html5.js',
|
||||||
:jquery => 'http://ajax.googleapis.com/ajax/libs/jquery/1.4.0/jquery.min.js',
|
:jquery => 'http://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js',
|
||||||
:swfobject => 'http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js'
|
:swfobject => 'http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,7 +40,11 @@ module ApplicationHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
def login_path_with_return_to
|
def login_path_with_return_to
|
||||||
login_path :return_to => request.request_uri
|
login_path :return_to => request.fullpath
|
||||||
|
end
|
||||||
|
|
||||||
|
def logout_path_with_return_to
|
||||||
|
logout_path :return_to => request.fullpath
|
||||||
end
|
end
|
||||||
|
|
||||||
def origin_tag(value)
|
def origin_tag(value)
|
||||||
|
|
6
app/models/item_outfit_relationship.rb
Normal file
6
app/models/item_outfit_relationship.rb
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
class ItemOutfitRelationship < ActiveRecord::Base
|
||||||
|
belongs_to :item
|
||||||
|
belongs_to :outfit
|
||||||
|
|
||||||
|
validates_presence_of :item
|
||||||
|
end
|
36
app/models/outfit.rb
Normal file
36
app/models/outfit.rb
Normal file
|
@ -0,0 +1,36 @@
|
||||||
|
class Outfit < ActiveRecord::Base
|
||||||
|
has_many :item_outfit_relationships
|
||||||
|
belongs_to :pet_state
|
||||||
|
belongs_to :user
|
||||||
|
|
||||||
|
validates :name, :presence => true
|
||||||
|
validates :pet_state, :presence => true
|
||||||
|
|
||||||
|
attr_accessible :name, :pet_state_id, :starred, :unworn_item_ids, :worn_item_ids
|
||||||
|
|
||||||
|
def worn_and_unworn_items
|
||||||
|
{:worn => [], :unworn => []}.tap do |output|
|
||||||
|
item_outfit_relationships.all(:include => :item).each do |rel|
|
||||||
|
key = rel.is_worn? ? :worn : :unworn
|
||||||
|
output[key] << rel.item
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def worn_item_ids=(item_ids)
|
||||||
|
add_relationships(item_ids, true)
|
||||||
|
end
|
||||||
|
|
||||||
|
def unworn_item_ids=(item_ids)
|
||||||
|
add_relationships(item_ids, false)
|
||||||
|
end
|
||||||
|
|
||||||
|
def add_relationships(item_ids, worn)
|
||||||
|
item_ids.each do |item_id|
|
||||||
|
rel = ItemOutfitRelationship.new
|
||||||
|
rel.item_id = item_id
|
||||||
|
rel.is_worn = worn
|
||||||
|
item_outfit_relationships << rel
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -118,19 +118,13 @@ ul.buttons
|
||||||
text-align: center
|
text-align: center
|
||||||
|
|
||||||
.success
|
.success
|
||||||
background: $notice-bg-color
|
+notice
|
||||||
border: 1px solid $notice-border-color
|
|
||||||
color: $notice-color
|
|
||||||
|
|
||||||
.alert
|
.alert
|
||||||
background: $error-bg-color
|
+error
|
||||||
border: 1px solid $error-border-color
|
|
||||||
color: $error-color
|
|
||||||
|
|
||||||
.warning
|
.warning
|
||||||
background: $warning-bg-color
|
+warning
|
||||||
border: 1px solid $warning-border-color
|
|
||||||
color: $warning-color
|
|
||||||
|
|
||||||
#userbar
|
#userbar
|
||||||
+header-text
|
+header-text
|
||||||
|
|
|
@ -9,12 +9,98 @@ $sidebar-width: 400px
|
||||||
$sidebar-unit-horizontal-padding: 24px
|
$sidebar-unit-horizontal-padding: 24px
|
||||||
$sidebar-unit-inner-width: $sidebar-width - $sidebar-unit-horizontal-padding * 2
|
$sidebar-unit-inner-width: $sidebar-width - $sidebar-unit-horizontal-padding * 2
|
||||||
|
|
||||||
|
$outfit-thumbnail-size: 0
|
||||||
|
$outfit-thumbnail-original-size: 100px
|
||||||
|
$outfit-thumbnail-margin: 12px
|
||||||
|
$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
|
||||||
|
|
||||||
|
=outfit
|
||||||
|
//+clearfix
|
||||||
|
margin-bottom: .5em
|
||||||
|
//.outfit-thumbnail
|
||||||
|
float: left
|
||||||
|
height: $outfit-thumbnail-size
|
||||||
|
margin-right: $outfit-thumbnail-margin
|
||||||
|
overflow: hidden
|
||||||
|
position: relative
|
||||||
|
width: $outfit-thumbnail-size
|
||||||
|
img
|
||||||
|
height: $outfit-thumbnail-original-size
|
||||||
|
left: -$outfit-thumbnail-original-size / 4
|
||||||
|
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)
|
||||||
|
font-size: 150%
|
||||||
|
float: right
|
||||||
|
line-height: 1
|
||||||
|
margin-top: -.125em
|
||||||
|
padding: .125em .25em
|
||||||
|
&:hover
|
||||||
|
+opacity(1)
|
||||||
|
background: $module-bg-color
|
||||||
|
header
|
||||||
|
display: block
|
||||||
|
padding-left: $outfit-header-padding
|
||||||
|
.outfit-star
|
||||||
|
background:
|
||||||
|
image: url(/images/unstarred.png)
|
||||||
|
position: left top
|
||||||
|
repeat: no-repeat
|
||||||
|
bottom: -2px
|
||||||
|
/* margin-bottom doesn't work here
|
||||||
|
cursor: pointer
|
||||||
|
display: block
|
||||||
|
float: left
|
||||||
|
height: 16px
|
||||||
|
margin-left: -24px
|
||||||
|
/* makes it not take up inline space
|
||||||
|
position: relative
|
||||||
|
width: 16px
|
||||||
|
h4
|
||||||
|
cursor: pointer
|
||||||
|
font-size: 115%
|
||||||
|
&:hover
|
||||||
|
text-decoration: underline
|
||||||
|
.outfit-url
|
||||||
|
+opacity(.5)
|
||||||
|
border-color: $background-color
|
||||||
|
font-size: 75%
|
||||||
|
width: $outfit-content-inner-width
|
||||||
|
&:hover
|
||||||
|
+opacity(1)
|
||||||
|
border-color: $input-border-color
|
||||||
|
.outfit-delete-confirmation
|
||||||
|
display: none
|
||||||
|
font-size: 75%
|
||||||
|
span
|
||||||
|
color: red
|
||||||
|
a
|
||||||
|
margin: 0 .25em
|
||||||
|
&.confirming-deletion
|
||||||
|
.outfit-delete
|
||||||
|
visibility: hidden
|
||||||
|
.outfit-url
|
||||||
|
display: none
|
||||||
|
.outfit-delete-confirmation
|
||||||
|
display: block
|
||||||
|
&.starred
|
||||||
|
.outfit-star
|
||||||
|
background-image: url(/images/star.png)
|
||||||
|
|
||||||
body.outfits-edit
|
body.outfits-edit
|
||||||
#preview-toolbar
|
#preview-toolbar
|
||||||
margin-bottom: .5em
|
margin-bottom: .5em
|
||||||
text-align: left
|
text-align: left
|
||||||
form
|
form
|
||||||
display: inline
|
+inline-block
|
||||||
margin-right: 2em
|
margin-right: 2em
|
||||||
#pet-info form
|
#pet-info form
|
||||||
display: inline
|
display: inline
|
||||||
|
@ -30,27 +116,12 @@ body.outfits-edit
|
||||||
margin: 0 .25em
|
margin: 0 .25em
|
||||||
li.selected label
|
li.selected label
|
||||||
+awesome-button-color($marked_button_color)
|
+awesome-button-color($marked_button_color)
|
||||||
#sharing
|
&.hidden
|
||||||
|
visibility: hidden
|
||||||
|
#save-outfit-wrapper
|
||||||
float: right
|
float: right
|
||||||
position: relative
|
button
|
||||||
#short-url-response
|
+loud-awesome-button-color
|
||||||
font-size: 87.5%
|
|
||||||
display: none
|
|
||||||
position: absolute
|
|
||||||
right: 0
|
|
||||||
top: -2em
|
|
||||||
width: 20em
|
|
||||||
#share-button-wrapper
|
|
||||||
display: inline
|
|
||||||
#share-button
|
|
||||||
img
|
|
||||||
margin:
|
|
||||||
bottom: -0.25em
|
|
||||||
right: .25em
|
|
||||||
height: 16px
|
|
||||||
width: 16px
|
|
||||||
&:active
|
|
||||||
top: 1px
|
|
||||||
#preview
|
#preview
|
||||||
clear: both
|
clear: both
|
||||||
#preview-swf
|
#preview-swf
|
||||||
|
@ -78,6 +149,13 @@ body.outfits-edit
|
||||||
display: none
|
display: none
|
||||||
#preview-outfits
|
#preview-outfits
|
||||||
display: block
|
display: block
|
||||||
|
&.viewing-saving-outfit
|
||||||
|
height: auto
|
||||||
|
max-height: 100%
|
||||||
|
#preview-closet
|
||||||
|
display: none
|
||||||
|
#preview-saving-outfit
|
||||||
|
display: block
|
||||||
#preview-closet
|
#preview-closet
|
||||||
h2
|
h2
|
||||||
margin: 0
|
margin: 0
|
||||||
|
@ -180,9 +258,14 @@ body.outfits-edit
|
||||||
position: relative
|
position: relative
|
||||||
width: $sidebar-width
|
width: $sidebar-width
|
||||||
> div
|
> div
|
||||||
padding:
|
margin:
|
||||||
left: $sidebar-unit-horizontal-padding
|
left: $sidebar-unit-horizontal-padding
|
||||||
right: $sidebar-unit-horizontal-padding
|
right: $sidebar-unit-horizontal-padding
|
||||||
|
h2
|
||||||
|
margin-bottom: .25em
|
||||||
|
&.viewing-saving-outfit
|
||||||
|
height: auto
|
||||||
|
max-height: 100%
|
||||||
#preview-search-form
|
#preview-search-form
|
||||||
bottom: 1em
|
bottom: 1em
|
||||||
left: 0
|
left: 0
|
||||||
|
@ -259,18 +342,9 @@ body.outfits-edit
|
||||||
&:hover
|
&:hover
|
||||||
+opacity(1)
|
+opacity(1)
|
||||||
|
|
||||||
$outfit-thumbnail-size: 50px
|
|
||||||
$outfit-thumbnail-original-size: 100px
|
|
||||||
$outfit-thumbnail-margin: 12px
|
|
||||||
$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
|
|
||||||
|
|
||||||
#preview-outfits
|
#preview-outfits
|
||||||
display: none
|
display: none
|
||||||
text-align: left
|
text-align: left
|
||||||
h2
|
|
||||||
margin-bottom: .25em
|
|
||||||
h3
|
h3
|
||||||
margin-bottom: .5em
|
margin-bottom: .5em
|
||||||
> ul
|
> ul
|
||||||
|
@ -279,84 +353,53 @@ body.outfits-edit
|
||||||
list-style: none
|
list-style: none
|
||||||
margin-bottom: 1em
|
margin-bottom: 1em
|
||||||
> li
|
> li
|
||||||
+clearfix
|
+outfit
|
||||||
font-size: 75%
|
|
||||||
margin-bottom: .5em
|
|
||||||
.outfit-thumbnail
|
|
||||||
float: left
|
|
||||||
height: $outfit-thumbnail-size
|
|
||||||
margin-right: $outfit-thumbnail-margin
|
|
||||||
overflow: hidden
|
|
||||||
position: relative
|
|
||||||
width: $outfit-thumbnail-size
|
|
||||||
img
|
|
||||||
height: $outfit-thumbnail-original-size
|
|
||||||
left: -$outfit-thumbnail-original-size / 4
|
|
||||||
position: absolute
|
|
||||||
top: -$outfit-thumbnail-original-size / 4
|
|
||||||
width: $outfit-thumbnail-original-size
|
|
||||||
> div
|
|
||||||
float: left
|
|
||||||
width: $outfit-content-width
|
|
||||||
button
|
|
||||||
+reset-awesome-button
|
|
||||||
+opacity(.5)
|
|
||||||
font-size: 150%
|
|
||||||
float: right
|
|
||||||
line-height: 1
|
|
||||||
margin-top: -.125em
|
|
||||||
padding: .125em .25em
|
|
||||||
&:hover
|
|
||||||
+opacity(1)
|
|
||||||
background: $module-bg-color
|
|
||||||
header
|
|
||||||
display: block
|
|
||||||
padding-left: $outfit-header-padding
|
|
||||||
.outfit-star
|
|
||||||
background:
|
|
||||||
image: url(/images/unstarred.png)
|
|
||||||
position: left top
|
|
||||||
repeat: no-repeat
|
|
||||||
bottom: -2px
|
|
||||||
/* margin-bottom doesn't work here
|
|
||||||
cursor: pointer
|
|
||||||
display: block
|
|
||||||
float: left
|
|
||||||
height: 16px
|
|
||||||
margin-left: -24px
|
|
||||||
/* makes it not take up inline space
|
|
||||||
position: relative
|
|
||||||
width: 16px
|
|
||||||
h4
|
|
||||||
cursor: pointer
|
|
||||||
font-size: 150%
|
|
||||||
&:hover
|
|
||||||
text-decoration: underline
|
|
||||||
input
|
|
||||||
+opacity(.5)
|
|
||||||
border-color: $background-color
|
|
||||||
width: $outfit-content-inner-width
|
|
||||||
&:hover
|
|
||||||
+opacity(1)
|
|
||||||
border-color: $input-border-color
|
|
||||||
.outfit-delete-confirmation
|
|
||||||
display: none
|
|
||||||
span
|
|
||||||
color: red
|
|
||||||
a
|
|
||||||
margin: 0 .25em
|
|
||||||
&.confirming-deletion
|
|
||||||
.outfit-delete
|
|
||||||
visibility: hidden
|
|
||||||
.outfit-url
|
|
||||||
display: none
|
|
||||||
.outfit-delete-confirmation
|
|
||||||
display: block
|
|
||||||
&.starred
|
|
||||||
.outfit-star
|
|
||||||
background-image: url(/images/star.png)
|
|
||||||
|
|
||||||
.preview-sidebar-nav
|
.preview-sidebar-nav
|
||||||
float: right
|
float: right
|
||||||
font-size: 85%
|
font-size: 85%
|
||||||
margin-top: 1em
|
margin-top: 1em
|
||||||
|
|
||||||
|
#save-success, #save-error
|
||||||
|
display: none
|
||||||
|
margin-top: 1em
|
||||||
|
text-align: center
|
||||||
|
|
||||||
|
#save-success
|
||||||
|
+notice
|
||||||
|
|
||||||
|
#save-error
|
||||||
|
+error
|
||||||
|
|
||||||
|
#userbar-message
|
||||||
|
+opacity(.5)
|
||||||
|
display: none
|
||||||
|
|
||||||
|
#new-outfit
|
||||||
|
+outfit
|
||||||
|
display: none
|
||||||
|
h4
|
||||||
|
display: inline
|
||||||
|
&:hover
|
||||||
|
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
|
||||||
|
position: absolute
|
||||||
|
top: 0
|
||||||
|
width: 100%
|
||||||
|
z-index: 5
|
||||||
|
|
|
@ -91,3 +91,18 @@
|
||||||
background: $module-bg-color
|
background: $module-bg-color
|
||||||
border: 1px solid $module-border-color
|
border: 1px solid $module-border-color
|
||||||
padding: 1em
|
padding: 1em
|
||||||
|
|
||||||
|
=notice
|
||||||
|
background: $notice-bg-color
|
||||||
|
border: 1px solid $notice-border-color
|
||||||
|
color: $notice-color
|
||||||
|
|
||||||
|
=error
|
||||||
|
background: $error-bg-color
|
||||||
|
border: 1px solid $error-border-color
|
||||||
|
color: $error-color
|
||||||
|
|
||||||
|
=warning
|
||||||
|
background: $warning-bg-color
|
||||||
|
border: 1px solid $warning-border-color
|
||||||
|
color: $warning-color
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
|
|
||||||
@import layout
|
@import layout
|
||||||
|
|
||||||
|
@import partials/jquery.jgrowl
|
||||||
|
|
||||||
@import contributions/index
|
@import contributions/index
|
||||||
@import items
|
@import items
|
||||||
@import items/index
|
@import items/index
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
= yield :title
|
= yield :title
|
||||||
= stylesheet_link_tag "compiled/screen"
|
= stylesheet_link_tag "compiled/screen"
|
||||||
= javascript_include_tag "http://#{RemoteImpressHost}/assets/js/analytics.js"
|
= javascript_include_tag "http://#{RemoteImpressHost}/assets/js/analytics.js"
|
||||||
|
= csrf_meta_tag
|
||||||
%body{:class => body_class}
|
%body{:class => body_class}
|
||||||
#container
|
#container
|
||||||
- if content_for? :title
|
- if content_for? :title
|
||||||
|
@ -31,7 +32,7 @@
|
||||||
%span
|
%span
|
||||||
== Hey, #{link_to current_user.name, user_contributions_path(current_user)}!
|
== Hey, #{link_to current_user.name, user_contributions_path(current_user)}!
|
||||||
== You have #{current_user.points} points.
|
== You have #{current_user.points} points.
|
||||||
= link_to 'Log out', logout_path
|
= link_to 'Log out', logout_path_with_return_to
|
||||||
- else
|
- else
|
||||||
= link_to login_path_with_return_to, :id => 'userbar-log-in' do
|
= link_to login_path_with_return_to, :id => 'userbar-log-in' do
|
||||||
= image_tag auth_server_icon_url
|
= image_tag auth_server_icon_url
|
||||||
|
|
|
@ -13,21 +13,16 @@
|
||||||
%form#pet-state-form
|
%form#pet-state-form
|
||||||
Gender/Emotions:
|
Gender/Emotions:
|
||||||
%ul
|
%ul
|
||||||
#sharing
|
#save-outfit-wrapper
|
||||||
%input#short-url-response{:type => "text", :value => "http://www.example.com/"}/
|
%button#save-outfit Save outfit
|
||||||
%button#short-url-button
|
|
||||||
Short URL
|
|
||||||
#share-button-wrapper
|
|
||||||
%button#share-button.addthis_button
|
|
||||||
%img{:src => "http://s7.addthis.com/static/t00/logo1414.gif"}/
|
|
||||||
Share
|
|
||||||
#preview
|
#preview
|
||||||
#preview-swf
|
#preview-swf
|
||||||
#preview-swf-container
|
#preview-swf-container
|
||||||
%p Flash and Javascript (but not Java!) are required to preview outfits.
|
%p Flash and Javascript (but not Java!) are required to preview outfits.
|
||||||
%p If this message stays after the page is done loading, check those first.
|
%p If this message stays after the page is done loading, check those first.
|
||||||
#preview-swf-overlay
|
|
||||||
#preview-sidebar
|
#preview-sidebar
|
||||||
|
#save-success Outfit successfully saved
|
||||||
|
#save-error
|
||||||
#preview-closet
|
#preview-closet
|
||||||
%a#preview-sidebar-nav-outfits.preview-sidebar-nav{:href => '#'} Your outfits
|
%a#preview-sidebar-nav-outfits.preview-sidebar-nav{:href => '#'} Your outfits
|
||||||
%h2 Closet
|
%h2 Closet
|
||||||
|
@ -40,61 +35,63 @@
|
||||||
%h2 Your outfits
|
%h2 Your outfits
|
||||||
%ul
|
%ul
|
||||||
%li.starred
|
%li.starred
|
||||||
%span.outfit-thumbnail
|
|
||||||
%img{:src => "http://pets.neopets.com/cp/qw2l4ocw/1/2.png"}/
|
|
||||||
%div
|
%div
|
||||||
%header
|
%header
|
||||||
%button.outfit-delete ×
|
%button.outfit-delete ×
|
||||||
.outfit-star
|
.outfit-star
|
||||||
%h4 Pretty in Pink
|
%h4 Pretty in Pink
|
||||||
%input.outfit-url{:type => 'text', :value => 'http://impress.openneo.net/outfits/qW2l4o'}
|
%input.outfit-url{:type => 'text', :value => 'http://impress.openneo.net/outfits/qW2l4o'}
|
||||||
.outfit-delete-confirmation
|
.outfit-delete-confirmation
|
||||||
%span Delete forever?
|
%span Delete forever?
|
||||||
%a.outfit-delete-confirmation-yes{:href => '#'} yes
|
%a.outfit-delete-confirmation-yes{:href => '#'} yes
|
||||||
\/
|
\/
|
||||||
%a.outfit-delete-confirmation-no{:href => '#'} no, thanks
|
%a.outfit-delete-confirmation-no{:href => '#'} no, thanks
|
||||||
%li.starred
|
%li.starred
|
||||||
%span.outfit-thumbnail
|
|
||||||
%img{:src => "http://pets.neopets.com/cp/wgvw75n8/1/2.png"}/
|
|
||||||
%div
|
%div
|
||||||
%header
|
%header
|
||||||
%button.outfit-delete ×
|
%button.outfit-delete ×
|
||||||
.outfit-star
|
.outfit-star
|
||||||
%h4 The Little Mermaid
|
%h4 The Little Mermaid
|
||||||
%input.outfit-url{:type => 'text', :value => 'http://impress.openneo.net/outfits/qW2l4o'}
|
%input.outfit-url{:type => 'text', :value => 'http://impress.openneo.net/outfits/qW2l4o'}
|
||||||
.outfit-delete-confirmation
|
.outfit-delete-confirmation
|
||||||
%span Delete forever?
|
%span Delete forever?
|
||||||
%a.outfit-delete-confirmation-yes{:href => '#'} yes
|
%a.outfit-delete-confirmation-yes{:href => '#'} yes
|
||||||
\/
|
\/
|
||||||
%a.outfit-delete-confirmation-no{:href => '#'} no, thanks
|
%a.outfit-delete-confirmation-no{:href => '#'} no, thanks
|
||||||
%li
|
%li
|
||||||
%span.outfit-thumbnail
|
|
||||||
%img{:src => "http://pets.neopets.com/cp/qb98jrng/1/2.png"}/
|
|
||||||
%div
|
%div
|
||||||
%header
|
%header
|
||||||
%button.outfit-delete ×
|
%button.outfit-delete ×
|
||||||
.outfit-star
|
.outfit-star
|
||||||
%h4 Autumn is Here
|
%h4 Autumn is Here
|
||||||
%input.outfit-url{:type => 'text', :value => 'http://impress.openneo.net/outfits/qW2l4o'}
|
%input.outfit-url{:type => 'text', :value => 'http://impress.openneo.net/outfits/qW2l4o'}
|
||||||
.outfit-delete-confirmation
|
.outfit-delete-confirmation
|
||||||
%span Delete forever?
|
%span Delete forever?
|
||||||
%a.outfit-delete-confirmation-yes{:href => '#'} yes
|
%a.outfit-delete-confirmation-yes{:href => '#'} yes
|
||||||
\/
|
\/
|
||||||
%a.outfit-delete-confirmation-no{:href => '#'} no, thanks
|
%a.outfit-delete-confirmation-no{:href => '#'} no, thanks
|
||||||
%li
|
%li
|
||||||
%span.outfit-thumbnail
|
|
||||||
%img{:src => "http://pets.neopets.com/cp/84l7xx9t/1/2.png"}/
|
|
||||||
%div
|
%div
|
||||||
%header
|
%header
|
||||||
%button.outfit-delete ×
|
%button.outfit-delete ×
|
||||||
.outfit-star
|
.outfit-star
|
||||||
%h4 Super Mysterious Secret Agent
|
%h4 Super Mysterious Secret Agent
|
||||||
%input.outfit-url{:type => 'text', :value => 'http://impress.openneo.net/outfits/qW2l4o'}
|
%input.outfit-url{:type => 'text', :value => 'http://impress.openneo.net/outfits/qW2l4o'}
|
||||||
.outfit-delete-confirmation
|
.outfit-delete-confirmation
|
||||||
%span Delete forever?
|
%span Delete forever?
|
||||||
%a.outfit-delete-confirmation-yes{:href => '#'} yes
|
%a.outfit-delete-confirmation-yes{:href => '#'} yes
|
||||||
\/
|
\/
|
||||||
%a.outfit-delete-confirmation-no{:href => '#'} no, thanks
|
%a.outfit-delete-confirmation-no{:href => '#'} no, thanks
|
||||||
|
#preview-saving-outfit
|
||||||
|
%a#preview-sidebar-nav-cancel-save.preview-sidebar-nav{:href => '#'} ← Cancel
|
||||||
|
%h2 Saving new outfit
|
||||||
|
#new-outfit
|
||||||
|
%form#new-outfit-form
|
||||||
|
%header
|
||||||
|
.outfit-star
|
||||||
|
%h4
|
||||||
|
%input#new-outfit-name{:type => 'text', :placeholder => 'Outfit name'}
|
||||||
|
%button{:type => 'submit'} Save
|
||||||
%form#preview-search-form
|
%form#preview-search-form
|
||||||
%header
|
%header
|
||||||
%h2 Add an item
|
%h2 Add an item
|
||||||
|
@ -139,5 +136,5 @@
|
||||||
- content_for :javascripts do
|
- content_for :javascripts do
|
||||||
/[if IE]
|
/[if IE]
|
||||||
= include_javascript_libraries :html5
|
= include_javascript_libraries :html5
|
||||||
= include_javascript_libraries :jquery, :swfobject, :bitly, :addthis
|
= include_javascript_libraries :jquery, :swfobject
|
||||||
= include_javascripts :edit_outfit_package
|
= include_javascripts :edit_outfit_package
|
||||||
|
|
|
@ -20,6 +20,7 @@ OpenneoImpressItems::Application.routes.draw do |map|
|
||||||
get :needed
|
get :needed
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
resources :outfits, :only => [:create]
|
||||||
resources :pet_attributes, :only => [:index]
|
resources :pet_attributes, :only => [:index]
|
||||||
|
|
||||||
match '/pets/load' => 'pets#load', :method => :post, :as => :load_pet
|
match '/pets/load' => 'pets#load', :method => :post, :as => :load_pet
|
||||||
|
|
14
db/migrate/20101109021049_create_outfits.rb
Normal file
14
db/migrate/20101109021049_create_outfits.rb
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
class CreateOutfits < ActiveRecord::Migration
|
||||||
|
def self.up
|
||||||
|
create_table :outfits do |t|
|
||||||
|
t.integer :pet_state_id
|
||||||
|
t.integer :user_id
|
||||||
|
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.down
|
||||||
|
drop_table :outfits
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,15 @@
|
||||||
|
class CreateItemOutfitRelationships < ActiveRecord::Migration
|
||||||
|
def self.up
|
||||||
|
create_table :item_outfit_relationships do |t|
|
||||||
|
t.integer :item_id
|
||||||
|
t.integer :outfit_id
|
||||||
|
t.boolean :is_worn
|
||||||
|
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.down
|
||||||
|
drop_table :item_outfit_relationships
|
||||||
|
end
|
||||||
|
end
|
11
db/migrate/20101110213044_add_name_and_starred_to_outfits.rb
Normal file
11
db/migrate/20101110213044_add_name_and_starred_to_outfits.rb
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
class AddNameAndStarredToOutfits < ActiveRecord::Migration
|
||||||
|
def self.up
|
||||||
|
add_column :outfits, :name, :string, :null => false
|
||||||
|
add_column :outfits, :starred, :boolean, :default => false, :null => false
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.down
|
||||||
|
remove_column :outfits, :starred
|
||||||
|
remove_column :outfits, :name
|
||||||
|
end
|
||||||
|
end
|
85
db/schema.rb
85
db/schema.rb
|
@ -10,7 +10,7 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended to check this file into your version control system.
|
# It's strongly recommended to check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(:version => 0) do
|
ActiveRecord::Schema.define(:version => 20101110213044) do
|
||||||
|
|
||||||
create_table "auth_servers", :force => true do |t|
|
create_table "auth_servers", :force => true do |t|
|
||||||
t.string "short_name", :limit => 10, :null => false
|
t.string "short_name", :limit => 10, :null => false
|
||||||
|
@ -21,10 +21,18 @@ ActiveRecord::Schema.define(:version => 0) do
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "contributions", :force => true do |t|
|
create_table "contributions", :force => true do |t|
|
||||||
t.string "contributed_type", :limit => 8, :null => false
|
t.string "contributed_type", :limit => 8, :null => false
|
||||||
t.integer "contributed_id", :null => false
|
t.integer "contributed_id", :null => false
|
||||||
t.integer "user_id", :null => false
|
t.integer "user_id", :null => false
|
||||||
t.timestamp "created_at", :null => false
|
t.datetime "created_at", :null => false
|
||||||
|
end
|
||||||
|
|
||||||
|
create_table "item_outfit_relationships", :force => true do |t|
|
||||||
|
t.integer "item_id"
|
||||||
|
t.integer "outfit_id"
|
||||||
|
t.boolean "is_worn"
|
||||||
|
t.datetime "created_at"
|
||||||
|
t.datetime "updated_at"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "login_cookies", :force => true do |t|
|
create_table "login_cookies", :force => true do |t|
|
||||||
|
@ -37,38 +45,47 @@ ActiveRecord::Schema.define(:version => 0) do
|
||||||
add_index "login_cookies", ["user_id"], :name => "login_cookies_user_id"
|
add_index "login_cookies", ["user_id"], :name => "login_cookies_user_id"
|
||||||
|
|
||||||
create_table "objects", :force => true do |t|
|
create_table "objects", :force => true do |t|
|
||||||
t.text "zones_restrict", :limit => 255, :null => false
|
t.text "zones_restrict", :limit => 255, :null => false
|
||||||
t.text "thumbnail_url", :null => false
|
t.text "thumbnail_url", :null => false
|
||||||
t.string "name", :limit => 100, :null => false
|
t.string "name", :limit => 100, :null => false
|
||||||
t.text "description", :null => false
|
t.text "description", :null => false
|
||||||
t.string "category", :limit => 50, :null => false
|
t.string "category", :limit => 50, :null => false
|
||||||
t.string "type", :limit => 50, :null => false
|
t.string "type", :limit => 50, :null => false
|
||||||
t.string "rarity", :limit => 25, :null => false
|
t.string "rarity", :limit => 25, :null => false
|
||||||
t.integer "rarity_index", :limit => 2, :null => false
|
t.integer "rarity_index", :limit => 2, :null => false
|
||||||
t.integer "price", :limit => 3, :null => false
|
t.integer "price", :limit => 3, :null => false
|
||||||
t.integer "weight_lbs", :limit => 2, :null => false
|
t.integer "weight_lbs", :limit => 2, :null => false
|
||||||
t.text "species_support_ids"
|
t.text "species_support_ids"
|
||||||
t.integer "sold_in_mall", :limit => 1, :null => false
|
t.integer "sold_in_mall", :limit => 1, :null => false
|
||||||
t.timestamp "last_spidered"
|
t.datetime "last_spidered"
|
||||||
end
|
end
|
||||||
|
|
||||||
add_index "objects", ["last_spidered"], :name => "objects_last_spidered"
|
add_index "objects", ["last_spidered"], :name => "objects_last_spidered"
|
||||||
add_index "objects", ["name"], :name => "name"
|
add_index "objects", ["name"], :name => "name"
|
||||||
|
|
||||||
|
create_table "outfits", :force => true do |t|
|
||||||
|
t.integer "pet_state_id"
|
||||||
|
t.integer "user_id"
|
||||||
|
t.datetime "created_at"
|
||||||
|
t.datetime "updated_at"
|
||||||
|
t.string "name", :null => false
|
||||||
|
t.boolean "starred", :default => false, :null => false
|
||||||
|
end
|
||||||
|
|
||||||
create_table "parents_swf_assets", :id => false, :force => true do |t|
|
create_table "parents_swf_assets", :id => false, :force => true do |t|
|
||||||
t.integer "parent_id", :limit => 3, :null => false
|
t.integer "parent_id", :limit => 3, :null => false
|
||||||
t.integer "swf_asset_id", :limit => 3, :null => false
|
t.integer "swf_asset_id", :limit => 3, :null => false
|
||||||
t.string "swf_asset_type", :limit => 7, :null => false
|
t.string "swf_asset_type", :limit => 7, :null => false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
add_index "parents_swf_assets", ["parent_id", "swf_asset_id", "swf_asset_type"], :name => "unique_parents_swf_assets", :unique => true
|
||||||
add_index "parents_swf_assets", ["parent_id"], :name => "parent_swf_assets_parent_id"
|
add_index "parents_swf_assets", ["parent_id"], :name => "parent_swf_assets_parent_id"
|
||||||
add_index "parents_swf_assets", ["swf_asset_id"], :name => "parents_swf_assets_swf_asset_id"
|
add_index "parents_swf_assets", ["swf_asset_id"], :name => "parents_swf_assets_swf_asset_id"
|
||||||
add_index "parents_swf_assets", ["parent_id", "swf_asset_id", "swf_asset_type"], :name => "unique_parents_swf_assets", :unique => true
|
|
||||||
|
|
||||||
create_table "pet_loads", :force => true do |t|
|
create_table "pet_loads", :force => true do |t|
|
||||||
t.string "pet_name", :limit => 20, :null => false
|
t.string "pet_name", :limit => 20, :null => false
|
||||||
t.text "amf", :null => false
|
t.text "amf", :null => false
|
||||||
t.timestamp "created_at", :null => false
|
t.datetime "created_at", :null => false
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "pet_states", :force => true do |t|
|
create_table "pet_states", :force => true do |t|
|
||||||
|
@ -79,11 +96,11 @@ ActiveRecord::Schema.define(:version => 0) do
|
||||||
add_index "pet_states", ["pet_type_id"], :name => "pet_states_pet_type_id"
|
add_index "pet_states", ["pet_type_id"], :name => "pet_states_pet_type_id"
|
||||||
|
|
||||||
create_table "pet_types", :force => true do |t|
|
create_table "pet_types", :force => true do |t|
|
||||||
t.integer "color_id", :limit => 1, :null => false
|
t.integer "color_id", :limit => 1, :null => false
|
||||||
t.integer "species_id", :limit => 1, :null => false
|
t.integer "species_id", :limit => 1, :null => false
|
||||||
t.timestamp "created_at", :null => false
|
t.datetime "created_at", :null => false
|
||||||
t.integer "body_id", :limit => 2, :null => false
|
t.integer "body_id", :limit => 2, :null => false
|
||||||
t.string "image_hash", :limit => 8
|
t.string "image_hash", :limit => 8
|
||||||
end
|
end
|
||||||
|
|
||||||
add_index "pet_types", ["species_id", "color_id"], :name => "pet_types_species_color", :unique => true
|
add_index "pet_types", ["species_id", "color_id"], :name => "pet_types_species_color", :unique => true
|
||||||
|
@ -101,13 +118,13 @@ ActiveRecord::Schema.define(:version => 0) do
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "swf_assets", :id => false, :force => true do |t|
|
create_table "swf_assets", :id => false, :force => true do |t|
|
||||||
t.string "type", :limit => 7, :null => false
|
t.string "type", :limit => 7, :null => false
|
||||||
t.integer "id", :limit => 3, :null => false
|
t.integer "id", :limit => 3, :null => false
|
||||||
t.text "url", :null => false
|
t.text "url", :null => false
|
||||||
t.integer "zone_id", :limit => 1, :null => false
|
t.integer "zone_id", :limit => 1, :null => false
|
||||||
t.text "zones_restrict", :limit => 255, :null => false
|
t.text "zones_restrict", :limit => 255, :null => false
|
||||||
t.timestamp "created_at", :null => false
|
t.datetime "created_at", :null => false
|
||||||
t.integer "body_id", :limit => 2, :null => false
|
t.integer "body_id", :limit => 2, :null => false
|
||||||
end
|
end
|
||||||
|
|
||||||
add_index "swf_assets", ["body_id"], :name => "swf_assets_body_id_and_object_id"
|
add_index "swf_assets", ["body_id"], :name => "swf_assets_body_id_and_object_id"
|
||||||
|
|
|
@ -1,4 +1,28 @@
|
||||||
// TODO: remove code associated with Short URL, Share
|
// TODO: replace updateItems triggers, move references to wardrobe.closet to outfit controller
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
var csrf_param = $('meta[name=csrf-param]').attr('content'),
|
||||||
|
csrf_token = $('meta[name=csrf-token]').attr('content');
|
||||||
|
$.ajaxSetup({
|
||||||
|
data: {csrf_param: csrf_token}
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
|
||||||
|
(function () {
|
||||||
|
var controlOverlay = $('<div/>', {'class': 'control-overlay'});
|
||||||
|
|
||||||
|
$.fn.disableControl = function () {
|
||||||
|
this.prepend(controlOverlay.clone()).stop().fadeTo('slow', .35);
|
||||||
|
}
|
||||||
|
|
||||||
|
$.fn.enableControl = function () {
|
||||||
|
this.stop().fadeTo('fast', 1).children('div.control-overlay').remove();
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
|
||||||
|
$.fn.notify = function () {
|
||||||
|
this.show('slow').delay(5000).hide('fast');
|
||||||
|
}
|
||||||
|
|
||||||
var Partial = {}, main_wardrobe,
|
var Partial = {}, main_wardrobe,
|
||||||
View = Wardrobe.getStandardView({
|
View = Wardrobe.getStandardView({
|
||||||
|
@ -43,7 +67,7 @@ Partial.ItemSet = function ItemSet(wardrobe, selector) {
|
||||||
var item, no_assets, li, no_assets_message;
|
var item, no_assets, li, no_assets_message;
|
||||||
for(var i = 0, l = specific_items.length; i < l; i++) {
|
for(var i = 0, l = specific_items.length; i < l; i++) {
|
||||||
item = specific_items[i];
|
item = specific_items[i];
|
||||||
no_assets = item.couldNotLoadAssetsFitting(wardrobe.outfit.pet_type);
|
no_assets = item.couldNotLoadAssetsFitting(wardrobe.outfit.getPetType());
|
||||||
li = $('li.object-' + item.id).toggleClass('no-assets', no_assets);
|
li = $('li.object-' + item.id).toggleClass('no-assets', no_assets);
|
||||||
(function (li) {
|
(function (li) {
|
||||||
no_assets_message = li.find('span.no-assets-message');
|
no_assets_message = li.find('span.no-assets-message');
|
||||||
|
@ -82,8 +106,8 @@ Partial.ItemSet = function ItemSet(wardrobe, selector) {
|
||||||
}
|
}
|
||||||
li.append(img).append(controls).append(info_link).append(item.name).appendTo(ul);
|
li.append(img).append(controls).append(info_link).append(item.name).appendTo(ul);
|
||||||
}
|
}
|
||||||
setClosetItems(wardrobe.closet.items);
|
setClosetItems(wardrobe.outfit.getClosetItems());
|
||||||
setOutfitItems(wardrobe.outfit.items);
|
setOutfitItems(wardrobe.outfit.getWornItems());
|
||||||
}
|
}
|
||||||
|
|
||||||
$('span.no-assets-message').live('mouseover', function () {
|
$('span.no-assets-message').live('mouseover', function () {
|
||||||
|
@ -96,9 +120,9 @@ Partial.ItemSet = function ItemSet(wardrobe, selector) {
|
||||||
no_assets_full_message.removeAttr('style');
|
no_assets_full_message.removeAttr('style');
|
||||||
});
|
});
|
||||||
|
|
||||||
wardrobe.outfit.bind('updateItemAssets', function () { setHasAssets(wardrobe.outfit.items) });
|
wardrobe.outfit.bind('updateItemAssets', function () { setHasAssets(wardrobe.outfit.getWornItems()) });
|
||||||
wardrobe.outfit.bind('updateItems', setOutfitItems);
|
wardrobe.outfit.bind('updateWornItems', setOutfitItems);
|
||||||
wardrobe.closet.bind('updateItems', setClosetItems);
|
wardrobe.outfit.bind('updateClosetItems', setClosetItems);
|
||||||
}
|
}
|
||||||
|
|
||||||
Partial.ItemSet.CONTROL_SETS = {};
|
Partial.ItemSet.CONTROL_SETS = {};
|
||||||
|
@ -130,12 +154,12 @@ Partial.ItemSet.setWardrobe = function (wardrobe) {
|
||||||
}
|
}
|
||||||
|
|
||||||
toggle_fn.closeted = {};
|
toggle_fn.closeted = {};
|
||||||
toggle_fn.closeted[true] = $.proxy(wardrobe.closet, 'addItem');
|
toggle_fn.closeted[true] = $.proxy(wardrobe.outfit, 'closetItem');
|
||||||
toggle_fn.closeted[false] = function (item) { wardrobe.outfit.removeItem(item); wardrobe.closet.removeItem(item); }
|
toggle_fn.closeted[false] = $.proxy(wardrobe.outfit, 'unclosetItem');
|
||||||
|
|
||||||
toggle_fn.worn = {};
|
toggle_fn.worn = {};
|
||||||
toggle_fn.worn[true] = function (item) { wardrobe.closet.addItem(item); wardrobe.outfit.addItem(item); }
|
toggle_fn.worn[true] = $.proxy(wardrobe.outfit, 'wearItem');
|
||||||
toggle_fn.worn[false] = $.proxy(wardrobe.outfit, 'removeItem');
|
toggle_fn.worn[false] = $.proxy(wardrobe.outfit, 'unwearItem');
|
||||||
|
|
||||||
Partial.ItemSet.setWardrobe = $.noop;
|
Partial.ItemSet.setWardrobe = $.noop;
|
||||||
}
|
}
|
||||||
|
@ -143,7 +167,7 @@ Partial.ItemSet.setWardrobe = function (wardrobe) {
|
||||||
View.Closet = function (wardrobe) {
|
View.Closet = function (wardrobe) {
|
||||||
var item_set = new Partial.ItemSet(wardrobe, '#preview-closet ul');
|
var item_set = new Partial.ItemSet(wardrobe, '#preview-closet ul');
|
||||||
|
|
||||||
wardrobe.closet.bind('updateItems', $.proxy(item_set, 'setItems'));
|
wardrobe.outfit.bind('updateClosetItems', $.proxy(item_set, 'setItems'));
|
||||||
}
|
}
|
||||||
|
|
||||||
View.Fullscreen = function (wardrobe) {
|
View.Fullscreen = function (wardrobe) {
|
||||||
|
@ -214,7 +238,7 @@ View.Hash = function (wardrobe) {
|
||||||
search_offset: TYPES.INTEGER,
|
search_offset: TYPES.INTEGER,
|
||||||
species: TYPES.INTEGER,
|
species: TYPES.INTEGER,
|
||||||
state: TYPES.INTEGER
|
state: TYPES.INTEGER
|
||||||
}, onUpdateQuery;
|
}, links_with_return_to = $('a[href*=return_to]');
|
||||||
|
|
||||||
function checkQuery() {
|
function checkQuery() {
|
||||||
var query = (document.location.hash || document.location.search).substr(1);
|
var query = (document.location.hash || document.location.search).substr(1);
|
||||||
|
@ -251,13 +275,13 @@ View.Hash = function (wardrobe) {
|
||||||
}
|
}
|
||||||
if(new_data.closet) {
|
if(new_data.closet) {
|
||||||
if(!arraysMatch(new_data.closet, data.closet)) {
|
if(!arraysMatch(new_data.closet, data.closet)) {
|
||||||
wardrobe.closet.setItemsByIds(new_data.closet.slice(0));
|
wardrobe.outfit.setClosetItemsByIds(new_data.closet.slice(0));
|
||||||
}
|
}
|
||||||
} else if(!arraysMatch(new_data.objects, data.closet)) {
|
} else if(!arraysMatch(new_data.objects, data.closet)) {
|
||||||
wardrobe.closet.setItemsByIds(new_data.objects.slice(0));
|
wardrobe.outfit.setClosetItemsByIds(new_data.objects.slice(0));
|
||||||
}
|
}
|
||||||
if(!arraysMatch(new_data.objects, data.objects)) {
|
if(!arraysMatch(new_data.objects, data.objects)) {
|
||||||
wardrobe.outfit.setItemsByIds(new_data.objects.slice(0));
|
wardrobe.outfit.setWornItemsByIds(new_data.objects.slice(0));
|
||||||
}
|
}
|
||||||
if(new_data.name != data.name && new_data.name) {
|
if(new_data.name != data.name && new_data.name) {
|
||||||
wardrobe.base_pet.setName(new_data.name);
|
wardrobe.base_pet.setName(new_data.name);
|
||||||
|
@ -270,6 +294,7 @@ View.Hash = function (wardrobe) {
|
||||||
}
|
}
|
||||||
data = new_data;
|
data = new_data;
|
||||||
parse_in_progress = false;
|
parse_in_progress = false;
|
||||||
|
updateLinksWithReturnTo();
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeQuery(changes) {
|
function changeQuery(changes) {
|
||||||
|
@ -294,23 +319,33 @@ View.Hash = function (wardrobe) {
|
||||||
new_query = $.param(data).replace(/%5B%5D/g, '[]');
|
new_query = $.param(data).replace(/%5B%5D/g, '[]');
|
||||||
previous_query = new_query;
|
previous_query = new_query;
|
||||||
document.location.hash = '#' + new_query;
|
document.location.hash = '#' + new_query;
|
||||||
onUpdateQuery();
|
updateLinksWithReturnTo();
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateLinksWithReturnTo() {
|
||||||
|
links_with_return_to.each(function () {
|
||||||
|
var new_return_to = 'return_to=' + encodeURIComponent(
|
||||||
|
document.location.pathname +
|
||||||
|
document.location.search +
|
||||||
|
document.location.hash
|
||||||
|
);
|
||||||
|
this.href = this.href.replace(/return_to=[^&]+/, new_return_to);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
this.initialize = function () {
|
this.initialize = function () {
|
||||||
checkQuery();
|
checkQuery();
|
||||||
setInterval(checkQuery, 100);
|
setInterval(checkQuery, 100);
|
||||||
onUpdateQuery();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
wardrobe.closet.bind('updateItems', function (items) {
|
wardrobe.outfit.bind('updateClosetItems', function (items) {
|
||||||
var item_ids = items.map('id');
|
var item_ids = items.map('id');
|
||||||
if(!arraysMatch(item_ids, data.closet)) {
|
if(!arraysMatch(item_ids, data.closet)) {
|
||||||
changeQuery({closet: item_ids});
|
changeQuery({closet: item_ids});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
wardrobe.outfit.bind('updateItems', function (items) {
|
wardrobe.outfit.bind('updateWornItems', function (items) {
|
||||||
var item_ids = items.map('id'), changes = {};
|
var item_ids = items.map('id'), changes = {};
|
||||||
if(!arraysMatch(item_ids, data.objects)) {
|
if(!arraysMatch(item_ids, data.objects)) {
|
||||||
changes.objects = item_ids;
|
changes.objects = item_ids;
|
||||||
|
@ -318,7 +353,7 @@ View.Hash = function (wardrobe) {
|
||||||
if(arraysMatch(item_ids, data.closet) || arraysMatch(item_ids, data.objects)) {
|
if(arraysMatch(item_ids, data.closet) || arraysMatch(item_ids, data.objects)) {
|
||||||
changes.closet = undefined;
|
changes.closet = undefined;
|
||||||
} else {
|
} else {
|
||||||
changes.closet = wardrobe.closet.items.map('id');
|
changes.closet = wardrobe.outfit.getClosetItems().map('id');
|
||||||
}
|
}
|
||||||
if(changes.objects || changes.closet) changeQuery(changes);
|
if(changes.objects || changes.closet) changeQuery(changes);
|
||||||
});
|
});
|
||||||
|
@ -338,7 +373,7 @@ View.Hash = function (wardrobe) {
|
||||||
});
|
});
|
||||||
|
|
||||||
wardrobe.outfit.bind('updatePetState', function (pet_state) {
|
wardrobe.outfit.bind('updatePetState', function (pet_state) {
|
||||||
var pet_type = wardrobe.outfit.pet_type;
|
var pet_type = wardrobe.outfit.getPetType();
|
||||||
if(pet_state.id != data.state && pet_type && (data.state || pet_state.id != pet_type.pet_state_ids[0])) {
|
if(pet_state.id != data.state && pet_type && (data.state || pet_state.id != pet_type.pet_state_ids[0])) {
|
||||||
changeQuery({state: pet_state.id});
|
changeQuery({state: pet_state.id});
|
||||||
}
|
}
|
||||||
|
@ -352,67 +387,65 @@ View.Hash = function (wardrobe) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
(function Share() {
|
|
||||||
var CALLBACK_NAME = 'shortenResponse',
|
|
||||||
button_id = '#share-button',
|
|
||||||
button = $(button_id),
|
|
||||||
wrapper = button.parent(),
|
|
||||||
shorten_el = $('#short-url-button'),
|
|
||||||
response_el = $('#short-url-response'),
|
|
||||||
current_url,
|
|
||||||
shortening = false,
|
|
||||||
shortened = false;
|
|
||||||
|
|
||||||
onUpdateQuery = function () {
|
|
||||||
var l = window.location, hash = l.hash;
|
|
||||||
if(!hash) hash = '#' + l.search.substr(1);
|
|
||||||
current_url = l.protocol + '//' + l.host + l.pathname + hash;
|
|
||||||
setURL(current_url);
|
|
||||||
response_el.hide();
|
|
||||||
shortened = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
function setURL(url) {
|
|
||||||
if(typeof addthis_share != 'undefined') {
|
|
||||||
addthis_share.url = url;
|
|
||||||
button.replaceWith(button.clone());
|
|
||||||
addthis.button(button_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
BitlyCB[CALLBACK_NAME] = function (data) {
|
|
||||||
var url, key;
|
|
||||||
for(key in data.results) {
|
|
||||||
url = SHORT_URL_HOST + data.results[key].hash;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
setURL(url);
|
|
||||||
response_el.val(url).show();
|
|
||||||
shortening = false;
|
|
||||||
shortened = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
function startShorten() {
|
|
||||||
if(!shortening && !shortened) {
|
|
||||||
shortening = true;
|
|
||||||
BitlyClient.shorten(current_url, 'BitlyCB.' + CALLBACK_NAME);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
shorten_el.click(startShorten);
|
|
||||||
wrapper.mouseover(startShorten);
|
|
||||||
button.focus(startShorten);
|
|
||||||
|
|
||||||
response_el.mouseover(function () {
|
|
||||||
response_el.focus().select();
|
|
||||||
});
|
|
||||||
})();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
View.Outfits = function (wardrobe) {
|
View.Outfits = function (wardrobe) {
|
||||||
var outfits_el = $('#preview-outfits'), sidebar_el = $('#preview-sidebar'),
|
var outfits_el = $('#preview-outfits'), sidebar_el = $('#preview-sidebar'),
|
||||||
overlay_el = $('#preview-swf-overlay');
|
controls = $('#pet-type-form, #pet-state-form, #preview-swf, #preview-search-form'),
|
||||||
|
save_success_el = $('#save-success'), save_error_el = $('#save-error'),
|
||||||
|
new_outfit_el = $('#new-outfit'), new_outfit_form_el = $('#new-outfit-form'),
|
||||||
|
new_outfit_name_el = $('#new-outfit-name'),
|
||||||
|
outfits_list_el = outfits_el.children('ul'),
|
||||||
|
stars = $('div.outfit-star'),
|
||||||
|
previously_viewing = '';
|
||||||
|
|
||||||
|
function navLinkTo(callback) {
|
||||||
|
return function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function navigateTo(will_be_viewing) {
|
||||||
|
var currently_viewing = sidebar_el.attr('class');
|
||||||
|
if(currently_viewing != will_be_viewing) previously_viewing = currently_viewing;
|
||||||
|
sidebar_el.attr('class', will_be_viewing);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Nav */
|
||||||
|
|
||||||
|
function showCloset() {
|
||||||
|
controls.enableControl('fast');
|
||||||
|
navigateTo('');
|
||||||
|
}
|
||||||
|
|
||||||
|
function showOutfits() {
|
||||||
|
controls.enableControl('fast');
|
||||||
|
navigateTo('viewing-outfits');
|
||||||
|
}
|
||||||
|
|
||||||
|
function showSavingOutfit() {
|
||||||
|
controls.disableControl('slow');
|
||||||
|
navigateTo('viewing-saving-outfit');
|
||||||
|
new_outfit_name_el.focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#preview-sidebar-nav-outfits').click(navLinkTo(showOutfits));
|
||||||
|
|
||||||
|
$('#preview-sidebar-nav-closet').click(navLinkTo(showCloset));
|
||||||
|
|
||||||
|
$('#preview-sidebar-nav-cancel-save').click(function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
controls.enableControl('fast');
|
||||||
|
sidebar_el.attr('class', previously_viewing);
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#save-outfit').click(function () {
|
||||||
|
new_outfit_el.show().children('input').text('').removeClass('starred');
|
||||||
|
showSavingOutfit();
|
||||||
|
});
|
||||||
|
|
||||||
|
/* Individual outfits */
|
||||||
|
|
||||||
$('input.outfit-url').live('mouseover', function () {
|
$('input.outfit-url').live('mouseover', function () {
|
||||||
this.focus();
|
this.focus();
|
||||||
|
@ -430,16 +463,45 @@ View.Outfits = function (wardrobe) {
|
||||||
$(this).closest('li').removeClass('confirming-deletion');
|
$(this).closest('li').removeClass('confirming-deletion');
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#preview-sidebar-nav-outfits').click(function (e) {
|
stars.live('click', function () {
|
||||||
e.preventDefault();
|
$(this).closest('#new-outfit, li').toggleClass('starred');
|
||||||
sidebar_el.addClass('viewing-outfits');
|
|
||||||
overlay_el.fadeTo('slow', .75)
|
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#preview-sidebar-nav-closet').click(function (e) {
|
/* Saving */
|
||||||
|
|
||||||
|
new_outfit_form_el.submit(function (e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
sidebar_el.removeClass('viewing-outfits');
|
wardrobe.outfit.save(new_outfit_el.hasClass('starred'), new_outfit_name_el.val());
|
||||||
overlay_el.fadeTo('fast', 0);
|
});
|
||||||
|
|
||||||
|
var SAVE_ERRORS = {
|
||||||
|
'item_outfit_relationships': "Item not found. How odd. Pull some items out of your closet and try again.",
|
||||||
|
'pet_state': "Pet state not found. How odd. Try picking a new Gender/Emotion.",
|
||||||
|
'name': "Outfits must have a name",
|
||||||
|
'user': "You must be logged in to save outfits"
|
||||||
|
};
|
||||||
|
|
||||||
|
function saveErrorMessage(text) {
|
||||||
|
save_error_el.text(text).notify();
|
||||||
|
}
|
||||||
|
|
||||||
|
wardrobe.outfit.bind('saveSuccess', function () {
|
||||||
|
save_success_el.notify();
|
||||||
|
showOutfits();
|
||||||
|
});
|
||||||
|
|
||||||
|
wardrobe.outfit.bind('saveFailure', function (response) {
|
||||||
|
var errors = response.errors;
|
||||||
|
if(typeof errors == 'undefined') {
|
||||||
|
saveErrorMessage("Whoops! The save failed, but the server didn't say why. Please try again.");
|
||||||
|
} else {
|
||||||
|
for(var key in SAVE_ERRORS) {
|
||||||
|
if(SAVE_ERRORS.hasOwnProperty(key) && typeof errors[key] != 'undefined') {
|
||||||
|
saveErrorMessage(SAVE_ERRORS[key]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -464,9 +526,9 @@ View.PetStateForm = function (wardrobe) {
|
||||||
var ids = pet_type.pet_state_ids, i, id, li, radio, label;
|
var ids = pet_type.pet_state_ids, i, id, li, radio, label;
|
||||||
ul.children().remove();
|
ul.children().remove();
|
||||||
if(ids.length == 1) {
|
if(ids.length == 1) {
|
||||||
form.hide();
|
form.addClass('hidden');
|
||||||
} else {
|
} else {
|
||||||
form.show();
|
form.removeClass('hidden');
|
||||||
for(var i = 0; i < ids.length; i++) {
|
for(var i = 0; i < ids.length; i++) {
|
||||||
id = 'pet-state-radio-' + i;
|
id = 'pet-state-radio-' + i;
|
||||||
li = $('<li/>');
|
li = $('<li/>');
|
||||||
|
@ -527,7 +589,7 @@ View.PetTypeForm = function (wardrobe) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
loaded = true;
|
loaded = true;
|
||||||
updatePetType(wardrobe.outfit.pet_type);
|
updatePetType(wardrobe.outfit.getPetType());
|
||||||
});
|
});
|
||||||
|
|
||||||
wardrobe.outfit.bind('updatePetType', updatePetType);
|
wardrobe.outfit.bind('updatePetType', updatePetType);
|
||||||
|
@ -757,6 +819,19 @@ View.Title = function (wardrobe) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var userbar_sessions_link = $('#userbar a:last'),
|
||||||
|
userbar_message_verb = userbar_sessions_link.text() == 'Log out' ? 'logged out' : 'sent to the login page',
|
||||||
|
userbar_message_el = $('<span/>', {
|
||||||
|
id: 'userbar-message',
|
||||||
|
text: "You will be " + userbar_message_verb + ", then brought back to this exact outfit you've made."
|
||||||
|
}).prependTo('#userbar');
|
||||||
|
|
||||||
|
userbar_sessions_link.hover(function () {
|
||||||
|
userbar_message_el.stop().fadeTo('normal', .5);
|
||||||
|
}, function () {
|
||||||
|
userbar_message_el.stop().fadeOut('fast');
|
||||||
|
});
|
||||||
|
|
||||||
$.ajaxSetup({
|
$.ajaxSetup({
|
||||||
error: function (xhr) {
|
error: function (xhr) {
|
||||||
$.jGrowl("There was an error loading that last resource. Oops. Please try again!");
|
$.jGrowl("There was an error loading that last resource. Oops. Please try again!");
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
var SHORT_URL_HOST = 'http://bit.ly/';
|
|
||||||
|
|
||||||
window.log = window.SWFLog = $.noop;
|
window.log = window.SWFLog = $.noop;
|
||||||
|
|
||||||
function arraysMatch(array1, array2) {
|
function arraysMatch(array1, array2) {
|
||||||
|
@ -220,6 +218,201 @@ function Wardrobe() {
|
||||||
|
|
||||||
ItemZoneSet.all = [];
|
ItemZoneSet.all = [];
|
||||||
|
|
||||||
|
function Outfit() {
|
||||||
|
var outfit = this, previous_pet_type, worn_item_ids = [];
|
||||||
|
|
||||||
|
this.closet_items = [];
|
||||||
|
this.worn_items = [];
|
||||||
|
|
||||||
|
function getRestrictedZones() {
|
||||||
|
// note: may contain duplicates - loop through assets, not these, for
|
||||||
|
// best performance
|
||||||
|
var restricted_zones = [],
|
||||||
|
restrictors = outfit.worn_items.concat(outfit.pet_state.assets);
|
||||||
|
$.each(restrictors, function () {
|
||||||
|
restricted_zones = restricted_zones.concat(this.restricted_zones);
|
||||||
|
});
|
||||||
|
return restricted_zones;
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasItemInCloset(item) {
|
||||||
|
return $.inArray(item, outfit.closet_items) != -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isWearingItem(item) {
|
||||||
|
return $.inArray(item, outfit.worn_items) != -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
function itemAssetsOnLoad(added_item, updateItemsCallback, updateItemAssetsCallback) {
|
||||||
|
var item_zones, item_zones_length, existing_item, existing_item_zones, passed,
|
||||||
|
new_items = [], new_worn_item_ids = [];
|
||||||
|
if(added_item) {
|
||||||
|
// now that we've loaded, check for conflicts on the added item
|
||||||
|
item_zones = added_item.getAssetsFitting(outfit.pet_type).map('zone_id');
|
||||||
|
item_zones_length = item_zones.length;
|
||||||
|
for(var i = 0; i < outfit.worn_items.length; i++) {
|
||||||
|
existing_item = outfit.worn_items[i];
|
||||||
|
existing_item_zones = existing_item.getAssetsFitting(outfit.pet_type).map('zone_id');
|
||||||
|
passed = true;
|
||||||
|
if(existing_item != added_item) {
|
||||||
|
for(var j = 0; j < item_zones_length; j++) {
|
||||||
|
if($.inArray(item_zones[j], existing_item_zones) != -1) {
|
||||||
|
passed = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(passed) {
|
||||||
|
new_items.push(existing_item);
|
||||||
|
new_worn_item_ids.push(existing_item.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
outfit.worn_items = new_items;
|
||||||
|
worn_item_ids = new_worn_item_ids;
|
||||||
|
updateItemsCallback(outfit.worn_items);
|
||||||
|
}
|
||||||
|
updateItemAssetsCallback();
|
||||||
|
}
|
||||||
|
|
||||||
|
function petTypeOnLoad(pet_type, petTypeLoadedCallback, updatePetStateCallback, updateItemsCallback, updateItemAssetsCallback) {
|
||||||
|
if(!outfit.pet_state || !pet_type.ownsPetState(outfit.pet_state)) {
|
||||||
|
outfit.setPetStateById(null, updatePetStateCallback);
|
||||||
|
}
|
||||||
|
petTypeLoadedCallback(pet_type);
|
||||||
|
updateItemAssets(null, updateItemsCallback, updateItemAssetsCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateItemAssets(added_item, updateItemsCallback, updateItemAssetsCallback) {
|
||||||
|
if(outfit.pet_type && outfit.pet_type.loaded && worn_item_ids.length) {
|
||||||
|
outfit.pet_type.loadItemAssets(worn_item_ids, function () {
|
||||||
|
itemAssetsOnLoad(added_item, updateItemsCallback, updateItemAssetsCallback)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.closetItem = function (item, updateClosetItemsCallback) {
|
||||||
|
if(!hasItemInCloset(item)) {
|
||||||
|
this.closet_items.push(item);
|
||||||
|
closet_item_ids.push(item.id);
|
||||||
|
updateClosetItemsCallback(this.closet_items);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.getVisibleAssets = function () {
|
||||||
|
var assets = this.pet_state.assets, restricted_zones = getRestrictedZones(),
|
||||||
|
visible_assets = [];
|
||||||
|
for(var i = 0; i < outfit.worn_items.length; i++) {
|
||||||
|
assets = assets.concat(outfit.worn_items[i].getAssetsFitting(outfit.pet_type));
|
||||||
|
}
|
||||||
|
$.each(assets, function () {
|
||||||
|
if($.inArray(this.zone_id, restricted_zones) == -1) {
|
||||||
|
visible_assets.push(this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return visible_assets;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setClosetItemsByIds = function (ids, updateItemsCallback) {
|
||||||
|
if(ids) closet_item_ids = ids;
|
||||||
|
if(ids && ids.length) {
|
||||||
|
this.closet_items = Item.loadByIds(ids, updateItemsCallback);
|
||||||
|
} else {
|
||||||
|
this.closet_items = [];
|
||||||
|
updateItemsCallback(this.closet_items);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setPetStateById = function (id, petStateOnLoad) {
|
||||||
|
if(!id && this.pet_type) {
|
||||||
|
id = this.pet_type.pet_state_ids[0];
|
||||||
|
}
|
||||||
|
if(id) {
|
||||||
|
this.pet_state = PetState.find(id);
|
||||||
|
this.pet_state.loadAssets(petStateOnLoad);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setPetTypeByColorAndSpecies = function (color_id, species_id, updatePetTypeCallback, petTypeLoadedCallback, petTypeNotFoundCallback, updatePetStateCallback, updateItemsCallback, updateItemAssetsCallback) {
|
||||||
|
this.pet_type = PetType.findOrCreateByColorAndSpecies(color_id, species_id);
|
||||||
|
updatePetTypeCallback(this.pet_type);
|
||||||
|
this.pet_type.load(function (pet_type) { petTypeOnLoad(pet_type, petTypeLoadedCallback, updatePetStateCallback, updateItemsCallback, updateItemAssetsCallback) }, petTypeNotFoundCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setWornItemsByIds = function (ids, updateItemsCallback, updateItemAssetsCallback) {
|
||||||
|
if(ids) worn_item_ids = ids;
|
||||||
|
if(ids && ids.length) {
|
||||||
|
this.worn_items = Item.loadByIds(ids, updateItemsCallback);
|
||||||
|
} else {
|
||||||
|
this.worn_items = [];
|
||||||
|
updateItemsCallback(this.worn_items);
|
||||||
|
}
|
||||||
|
updateItemAssets(null, updateItemsCallback, updateItemAssetsCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.unclosetItem = function (item, updateClosetItemsCallback, updateWornItemsCallback) {
|
||||||
|
var i = $.inArray(item, this.closet_items), id_i;
|
||||||
|
if(i != -1) {
|
||||||
|
this.closet_items.splice(i, 1);
|
||||||
|
id_i = $.inArray(item.id, closet_item_ids);
|
||||||
|
closet_item_ids.splice(id_i, 1);
|
||||||
|
updateClosetItemsCallback(this.closet_items);
|
||||||
|
this.unwearItem(item, updateWornItemsCallback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.unwearItem = function (item, updateWornItemsCallback) {
|
||||||
|
var i = $.inArray(item, this.worn_items), id_i;
|
||||||
|
if(i != -1) {
|
||||||
|
this.worn_items.splice(i, 1);
|
||||||
|
id_i = $.inArray(item.id, worn_item_ids);
|
||||||
|
worn_item_ids.splice(id_i, 1);
|
||||||
|
updateWornItemsCallback(this.worn_items);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.wearItem = function (item, updateWornItemsCallback, updateClosetItemsCallback, updateItemAssetsCallback) {
|
||||||
|
if(!isWearingItem(item)) {
|
||||||
|
this.worn_items.push(item);
|
||||||
|
worn_item_ids.push(item.id);
|
||||||
|
this.closetItem(item, updateClosetItemsCallback);
|
||||||
|
if(updateItemAssetsCallback) {
|
||||||
|
updateItemAssets(item, updateWornItemsCallback, updateItemAssetsCallback);
|
||||||
|
}
|
||||||
|
updateWornItemsCallback(this.worn_items);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function sortWornUnworn() {
|
||||||
|
var unworn_item_ids = [], id;
|
||||||
|
for(var i in outfit.closet_items) {
|
||||||
|
id = outfit.closet_items[i].id;
|
||||||
|
if(outfit.closet_items.hasOwnProperty(i)) {
|
||||||
|
if($.inArray(id, worn_item_ids) === -1) {
|
||||||
|
unworn_item_ids.push(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {worn_item_ids: worn_item_ids, unworn_item_ids: unworn_item_ids};
|
||||||
|
}
|
||||||
|
|
||||||
|
this.save = function (starred, name, success, error) {
|
||||||
|
// TODO: put starred and name on the actual objects, for updating
|
||||||
|
var outfit_data = sortWornUnworn();
|
||||||
|
outfit_data.name = name;
|
||||||
|
outfit_data.starred = starred;
|
||||||
|
outfit_data.pet_state_id = outfit.pet_state.id;
|
||||||
|
$.ajax({
|
||||||
|
url: '/outfits',
|
||||||
|
type: 'post',
|
||||||
|
data: {outfit: outfit_data},
|
||||||
|
success: success,
|
||||||
|
error: function (xhr) {
|
||||||
|
error($.parseJSON(xhr.responseText));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function PetAttribute() {}
|
function PetAttribute() {}
|
||||||
|
|
||||||
PetAttribute.loadAll = function (success) {
|
PetAttribute.loadAll = function (success) {
|
||||||
|
@ -373,199 +566,110 @@ function Wardrobe() {
|
||||||
this.events[event].push(callback);
|
this.events[event].push(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.events.trigger = function (event) {
|
this.event = function (event_name) {
|
||||||
var subarguments;
|
return function () {
|
||||||
if(controller.events[event]) {
|
var subarguments = arguments;
|
||||||
subarguments = Array.prototype.slice.apply(arguments, [1]);
|
$.each(controller.events[event_name], function () {
|
||||||
$.each(controller.events[event], function () {
|
|
||||||
this.apply(controller, subarguments);
|
this.apply(controller, subarguments);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.events.trigger = function (event_name) {
|
||||||
|
var subarguments, event;
|
||||||
|
if(controller.events[event_name]) {
|
||||||
|
subarguments = Array.prototype.slice.apply(arguments, [1]);
|
||||||
|
controller.event(event_name).apply(controller, subarguments);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Controller.all = {};
|
Controller.all = {};
|
||||||
|
|
||||||
Controller.all.Outfit = function OutfitController() {
|
Controller.all.Outfit = function OutfitController() {
|
||||||
var outfit = this, previous_pet_type, item_ids = [];
|
var controller = this, outfit = new Outfit;
|
||||||
|
|
||||||
this.items = [];
|
this.closetItem = function (item) {
|
||||||
|
outfit.closetItem(
|
||||||
function getRestrictedZones() {
|
item,
|
||||||
// note: may contain duplicates - loop through assets, not these, for
|
controller.event('updateClosetItems')
|
||||||
// best performance
|
);
|
||||||
var restricted_zones = [],
|
|
||||||
restrictors = outfit.items.concat(outfit.pet_state.assets);
|
|
||||||
$.each(restrictors, function () {
|
|
||||||
restricted_zones = restricted_zones.concat(this.restricted_zones);
|
|
||||||
});
|
|
||||||
return restricted_zones;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasItem(item) {
|
this.getClosetItems = function () {
|
||||||
return $.inArray(item, outfit.items) != -1;
|
return outfit.closet_items;
|
||||||
}
|
}
|
||||||
|
|
||||||
function itemAssetsOnLoad(added_item) {
|
this.getPetType = function () {
|
||||||
var item_zones, item_zones_length, existing_item, existing_item_zones, passed,
|
return outfit.pet_type;
|
||||||
new_items = [], new_item_ids = [];
|
|
||||||
if(added_item) {
|
|
||||||
// now that we've loaded, check for conflicts on the added item
|
|
||||||
item_zones = added_item.getAssetsFitting(outfit.pet_type).map('zone_id');
|
|
||||||
item_zones_length = item_zones.length;
|
|
||||||
for(var i = 0; i < outfit.items.length; i++) {
|
|
||||||
existing_item = outfit.items[i];
|
|
||||||
existing_item_zones = existing_item.getAssetsFitting(outfit.pet_type).map('zone_id');
|
|
||||||
passed = true;
|
|
||||||
if(existing_item != added_item) {
|
|
||||||
for(var j = 0; j < item_zones_length; j++) {
|
|
||||||
if($.inArray(item_zones[j], existing_item_zones) != -1) {
|
|
||||||
passed = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(passed) {
|
|
||||||
new_items.push(existing_item);
|
|
||||||
new_item_ids.push(existing_item.id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
outfit.items = new_items;
|
|
||||||
item_ids = new_item_ids;
|
|
||||||
outfit.events.trigger('updateItems', outfit.items);
|
|
||||||
}
|
|
||||||
outfit.events.trigger('updateItemAssets');
|
|
||||||
}
|
|
||||||
|
|
||||||
function itemsOnLoad(items) {
|
|
||||||
outfit.events.trigger('updateItems', items);
|
|
||||||
}
|
|
||||||
|
|
||||||
function petStateOnLoad(pet_state) {
|
|
||||||
outfit.events.trigger('updatePetState', pet_state);
|
|
||||||
}
|
|
||||||
|
|
||||||
function petTypeOnLoad(pet_type) {
|
|
||||||
if(!outfit.pet_state || !pet_type.ownsPetState(outfit.pet_state)) {
|
|
||||||
outfit.setPetStateById();
|
|
||||||
}
|
|
||||||
outfit.events.trigger('petTypeLoaded', pet_type);
|
|
||||||
updateItemAssets();
|
|
||||||
}
|
|
||||||
|
|
||||||
function petTypeOnError(pet_type) {
|
|
||||||
outfit.events.trigger('petTypeNotFound', pet_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
function updateItemAssets(added_item) {
|
|
||||||
if(outfit.pet_type && outfit.pet_type.loaded && item_ids.length) {
|
|
||||||
outfit.pet_type.loadItemAssets(item_ids, function () {
|
|
||||||
itemAssetsOnLoad(added_item)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.addItem = function (item) {
|
|
||||||
if(!hasItem(item)) {
|
|
||||||
this.items.push(item);
|
|
||||||
item_ids.push(item.id);
|
|
||||||
updateItemAssets(item);
|
|
||||||
outfit.events.trigger('updateItems', this.items);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.getVisibleAssets = function () {
|
this.getVisibleAssets = function () {
|
||||||
var assets = this.pet_state.assets, restricted_zones = getRestrictedZones(),
|
return outfit.getVisibleAssets();
|
||||||
visible_assets = [];
|
|
||||||
for(var i = 0; i < outfit.items.length; i++) {
|
|
||||||
assets = assets.concat(outfit.items[i].getAssetsFitting(outfit.pet_type));
|
|
||||||
}
|
|
||||||
$.each(assets, function () {
|
|
||||||
if($.inArray(this.zone_id, restricted_zones) == -1) {
|
|
||||||
visible_assets.push(this);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return visible_assets;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.removeItem = function (item) {
|
this.getWornItems = function () {
|
||||||
var i = $.inArray(item, this.items), id_i;
|
return outfit.worn_items;
|
||||||
if(i != -1) {
|
|
||||||
this.items.splice(i, 1);
|
|
||||||
id_i = $.inArray(item.id, item_ids);
|
|
||||||
item_ids.splice(id_i, 1);
|
|
||||||
outfit.events.trigger('updateItems', this.items);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setPetStateById = function (id) {
|
this.save = function (starred, name) {
|
||||||
if(!id && this.pet_type) {
|
outfit.save(
|
||||||
id = this.pet_type.pet_state_ids[0];
|
starred,
|
||||||
}
|
name,
|
||||||
if(id) {
|
controller.event('saveSuccess'),
|
||||||
this.pet_state = PetState.find(id);
|
controller.event('saveFailure')
|
||||||
this.pet_state.loadAssets(petStateOnLoad);
|
);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setPetTypeByColorAndSpecies = function (color_id, species_id) {
|
this.setClosetItemsByIds = function (item_ids) {
|
||||||
this.pet_type = PetType.findOrCreateByColorAndSpecies(color_id, species_id);
|
outfit.setClosetItemsByIds(
|
||||||
outfit.events.trigger('updatePetType', this.pet_type);
|
item_ids,
|
||||||
this.pet_type.load(petTypeOnLoad, petTypeOnError);
|
controller.event('updateClosetItems')
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setItemsByIds = function (ids) {
|
this.setPetStateById = function (pet_state_id) {
|
||||||
if(ids) item_ids = ids;
|
outfit.setPetStateById(pet_state_id, controller.event('updatePetState'));
|
||||||
if(ids && ids.length) {
|
|
||||||
this.items = Item.loadByIds(ids, itemsOnLoad);
|
|
||||||
} else {
|
|
||||||
this.items = [];
|
|
||||||
itemsOnLoad(this.items);
|
|
||||||
}
|
|
||||||
updateItemAssets();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Controller.all.Closet = function ClosetController() {
|
|
||||||
// FIXME: a lot of duplication from outfit controller
|
|
||||||
var closet = this, item_ids = [];
|
|
||||||
this.items = [];
|
|
||||||
|
|
||||||
function hasItem(item) {
|
|
||||||
return $.inArray(item, closet.items) != -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function itemsOnLoad(items) {
|
this.setPetTypeByColorAndSpecies = function(color_id, species_id) {
|
||||||
closet.events.trigger('updateItems', items);
|
outfit.setPetTypeByColorAndSpecies(color_id, species_id,
|
||||||
|
controller.event('updatePetType'),
|
||||||
|
controller.event('petTypeLoaded'),
|
||||||
|
controller.event('petTypeNotFound'),
|
||||||
|
controller.event('updatePetState'),
|
||||||
|
controller.event('updateWornItems'),
|
||||||
|
controller.event('updateItemAssets')
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.addItem = function (item) {
|
this.setWornItemsByIds = function (item_ids) {
|
||||||
if(!hasItem(item)) {
|
outfit.setWornItemsByIds(
|
||||||
this.items.push(item);
|
item_ids,
|
||||||
item_ids.push(item.id);
|
controller.event('updateWornItems'),
|
||||||
closet.events.trigger('updateItems', this.items);
|
controller.event('updateItemAssets')
|
||||||
}
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.removeItem = function (item) {
|
this.unclosetItem = function (item) {
|
||||||
var i = $.inArray(item, this.items), id_i;
|
outfit.unclosetItem(
|
||||||
if(i != -1) {
|
item,
|
||||||
this.items.splice(i, 1);
|
controller.event('updateClosetItems'),
|
||||||
id_i = $.inArray(item.id, item_ids);
|
controller.event('updateWornItems')
|
||||||
item_ids.splice(id_i, 1);
|
);
|
||||||
closet.events.trigger('updateItems', this.items);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setItemsByIds = function (ids) {
|
this.unwearItem = function (item) {
|
||||||
if(ids && ids.length) {
|
outfit.unwearItem(item, controller.event('updateWornItems'));
|
||||||
item_ids = ids;
|
}
|
||||||
this.items = Item.loadByIds(ids, itemsOnLoad);
|
|
||||||
} else {
|
this.wearItem = function (item) {
|
||||||
item_ids = ids;
|
outfit.wearItem(
|
||||||
this.items = [];
|
item,
|
||||||
itemsOnLoad(this.items);
|
controller.event('updateWornItems'),
|
||||||
}
|
controller.event('updateClosetItems'),
|
||||||
|
controller.event('updateItemAssets')
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -703,7 +807,7 @@ Wardrobe.getStandardView = function (options) {
|
||||||
log('Welcome to the Wardrobe!');
|
log('Welcome to the Wardrobe!');
|
||||||
}
|
}
|
||||||
|
|
||||||
var outfit_events = ['updateItems', 'updateItemAssets', 'updatePetType', 'updatePetState'];
|
var outfit_events = ['updateWornItems', 'updateClosetItems', 'updateItemAssets', 'updatePetType', 'updatePetState'];
|
||||||
for(var i = 0; i < outfit_events.length; i++) {
|
for(var i = 0; i < outfit_events.length; i++) {
|
||||||
(function (event) {
|
(function (event) {
|
||||||
wardrobe.outfit.bind(event, function (obj) {
|
wardrobe.outfit.bind(event, function (obj) {
|
||||||
|
@ -737,7 +841,6 @@ Wardrobe.getStandardView = function (options) {
|
||||||
);
|
);
|
||||||
|
|
||||||
Wardrobe.StandardPreview.views_by_swf_id[preview_swf_id] = this;
|
Wardrobe.StandardPreview.views_by_swf_id[preview_swf_id] = this;
|
||||||
console.log(Wardrobe.StandardPreview.views_by_swf_id);
|
|
||||||
|
|
||||||
this.previewSWFIsReady = function () {
|
this.previewSWFIsReady = function () {
|
||||||
preview_swf = document.getElementById(preview_swf_id);
|
preview_swf = document.getElementById(preview_swf_id);
|
||||||
|
@ -758,7 +861,7 @@ Wardrobe.getStandardView = function (options) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wardrobe.outfit.bind('updateItems', updateAssets);
|
wardrobe.outfit.bind('updateWornItems', updateAssets);
|
||||||
wardrobe.outfit.bind('updateItemAssets', updateAssets);
|
wardrobe.outfit.bind('updateItemAssets', updateAssets);
|
||||||
wardrobe.outfit.bind('updatePetState', updateAssets);
|
wardrobe.outfit.bind('updatePetState', updateAssets);
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
5
spec/models/item_outfit_relationship_spec.rb
Normal file
5
spec/models/item_outfit_relationship_spec.rb
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe ItemOutfitRelationship do
|
||||||
|
pending "add some examples to (or delete) #{__FILE__}"
|
||||||
|
end
|
5
spec/models/outfit_spec.rb
Normal file
5
spec/models/outfit_spec.rb
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe Outfit do
|
||||||
|
pending "add some examples to (or delete) #{__FILE__}"
|
||||||
|
end
|
Loading…
Reference in a new issue