forked from OpenNeo/impress
a functioning wardrobe
This commit is contained in:
parent
792d2ff1f2
commit
e40d4601d8
25 changed files with 1735 additions and 35 deletions
2
Gemfile
2
Gemfile
|
@ -25,6 +25,8 @@ gem 'rdiscount', '~> 1.6.5'
|
|||
gem 'RocketAMF', '~> 0.2.1'
|
||||
gem 'will_paginate', '~> 3.0.pre2'
|
||||
|
||||
gem 'jammit', '~> 0.5.3'
|
||||
|
||||
group :test do
|
||||
gem 'factory_girl_rails', '~> 1.0'
|
||||
gem 'rspec-rails', '~> 2.0.0.beta.22'
|
||||
|
|
|
@ -67,6 +67,7 @@ GEM
|
|||
arel (1.0.1)
|
||||
activesupport (~> 3.0.0)
|
||||
builder (2.1.2)
|
||||
closure-compiler (0.3.3)
|
||||
compass (0.10.5)
|
||||
haml (>= 3.0.4)
|
||||
diff-lcs (1.1.2)
|
||||
|
@ -78,6 +79,9 @@ GEM
|
|||
rails (>= 3.0.0.beta4)
|
||||
haml (3.0.21)
|
||||
i18n (0.4.1)
|
||||
jammit (0.5.3)
|
||||
closure-compiler (>= 0.1.0)
|
||||
yui-compressor (>= 0.9.1)
|
||||
mail (2.2.6.1)
|
||||
activesupport (>= 2.3.6)
|
||||
mime-types
|
||||
|
@ -122,6 +126,7 @@ GEM
|
|||
polyglot (>= 0.3.1)
|
||||
tzinfo (0.3.23)
|
||||
will_paginate (3.0.pre2)
|
||||
yui-compressor (0.9.1)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
@ -136,6 +141,7 @@ DEPENDENCIES
|
|||
eventmachine!
|
||||
factory_girl_rails (~> 1.0)
|
||||
haml (~> 3.0.18)
|
||||
jammit (~> 0.5.3)
|
||||
mysqlplus!
|
||||
rack-fiber_pool
|
||||
rails (= 3.0.0)
|
||||
|
|
|
@ -10,10 +10,10 @@ class ItemsController < ApplicationController
|
|||
else
|
||||
per_page = nil
|
||||
end
|
||||
@results = Item.search(@query).alphabetize.paginate :page => params[:page], :per_page => per_page
|
||||
@items = Item.search(@query).alphabetize.paginate :page => params[:page], :per_page => per_page
|
||||
respond_to do |format|
|
||||
format.html { render }
|
||||
format.js { render :json => {:items => @results, :total_pages => @results.total_pages}, :callback => params[:callback] }
|
||||
format.js { render :json => {:items => @items, :total_pages => @items.total_pages}, :callback => params[:callback] }
|
||||
end
|
||||
rescue
|
||||
respond_to do |format|
|
||||
|
@ -21,6 +21,11 @@ class ItemsController < ApplicationController
|
|||
format.js { render :json => {:error => $!.message}, :callback => params[:callback] }
|
||||
end
|
||||
end
|
||||
elsif params.has_key?(:ids) && params[:ids].is_a?(Array)
|
||||
@items = Item.find(params[:ids])
|
||||
respond_to do |format|
|
||||
format.json { render :json => @items }
|
||||
end
|
||||
else
|
||||
respond_to do |format|
|
||||
format.html { render }
|
||||
|
|
5
app/controllers/outfits_controller.rb
Normal file
5
app/controllers/outfits_controller.rb
Normal file
|
@ -0,0 +1,5 @@
|
|||
class OutfitsController < ApplicationController
|
||||
def edit
|
||||
render :layout => false
|
||||
end
|
||||
end
|
8
app/controllers/pet_attributes_controller.rb
Normal file
8
app/controllers/pet_attributes_controller.rb
Normal file
|
@ -0,0 +1,8 @@
|
|||
class PetAttributesController < ApplicationController
|
||||
def index
|
||||
render :json => {
|
||||
:color => Color.all,
|
||||
:species => Species.all
|
||||
}
|
||||
end
|
||||
end
|
|
@ -1,7 +1,10 @@
|
|||
class PetTypesController < ApplicationController
|
||||
def show
|
||||
pet_type = PetType.find_by_color_id_and_species_id(params[:color_id], params[:species_id])
|
||||
raise ActiveRecord::RecordNotFound unless pet_type
|
||||
render :json => pet_type
|
||||
if pet_type
|
||||
render :json => pet_type.as_json(:for => params[:for])
|
||||
else
|
||||
render :json => nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
class PetsController < ActionController::Base
|
||||
class PetsController < ApplicationController
|
||||
def show
|
||||
@pet = Pet.load(params[:id])
|
||||
@pet.save
|
||||
redirect_to @pet.wardrobe_url
|
||||
redirect_to wardrobe_path(:anchor => @pet.wardrobe_query)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -10,6 +10,18 @@ class SwfAssetsController < ApplicationController
|
|||
@swf_assets = @swf_assets.fitting_standard_body_ids
|
||||
json = @swf_assets.all.group_by(&:body_id)
|
||||
end
|
||||
elsif params[:body_id]
|
||||
swf_assets = SwfAsset.arel_table
|
||||
rels = ParentSwfAssetRelationship.arel_table
|
||||
@swf_assets = SwfAsset.select('swf_assets.*, parents_swf_assets.parent_id').
|
||||
fitting_body_id(params[:body_id]).
|
||||
joins(:object_asset_relationships).
|
||||
where(rels[:parent_id].in(params[:item_ids]))
|
||||
json = @swf_assets.map { |a| a.as_json(:parent_id => a.parent_id.to_i, :for => 'wardrobe') }
|
||||
elsif params[:pet_state_id]
|
||||
@swf_assets = PetState.find(params[:pet_state_id]).swf_assets.all
|
||||
pet_state_id = params[:pet_state_id].to_i
|
||||
json = @swf_assets.map { |a| a.as_json(:parent_id => pet_state_id, :for => 'wardrobe') }
|
||||
elsif params[:pet_type_id]
|
||||
@swf_assets = PetType.find(params[:pet_type_id]).pet_states.first.swf_assets
|
||||
end
|
||||
|
|
|
@ -3,7 +3,7 @@ class Item < ActiveRecord::Base
|
|||
|
||||
has_many :parent_swf_asset_relationships, :foreign_key => 'parent_id',
|
||||
:conditions => {:swf_asset_type => SwfAssetType}
|
||||
has_many :swf_assets, :through => :parent_swf_asset_relationships
|
||||
has_many :swf_assets, :through => :parent_swf_asset_relationships, :source => :object_asset
|
||||
|
||||
attr_writer :current_body_id
|
||||
|
||||
|
@ -118,7 +118,7 @@ class Item < ActiveRecord::Base
|
|||
swf_assets = SwfAsset.arel_table
|
||||
ids_to_delete = self.parent_swf_asset_relationships.
|
||||
select(:id).
|
||||
joins(:swf_asset).
|
||||
joins(:object_asset).
|
||||
where(rels[:swf_asset_id].in(new_swf_asset_ids).not).
|
||||
where(swf_assets[:body_id].in([@current_body_id, 0])).
|
||||
map(&:id)
|
||||
|
@ -208,7 +208,7 @@ class Item < ActiveRecord::Base
|
|||
relationship.swf_asset_type = SwfAssetType
|
||||
relationship.swf_asset_id = swf_asset.id
|
||||
end
|
||||
relationship.swf_asset = swf_asset
|
||||
relationship.object_asset = swf_asset
|
||||
relationships_by_item_id[item_id] ||= []
|
||||
relationships_by_item_id[item_id] << relationship
|
||||
end
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
class ParentSwfAssetRelationship < ActiveRecord::Base
|
||||
set_table_name 'parents_swf_assets'
|
||||
|
||||
belongs_to :swf_asset
|
||||
belongs_to :biology_asset, :class_name => 'SwfAsset', :foreign_key => 'swf_asset_id', :conditions => {:type => 'biology'}
|
||||
belongs_to :object_asset, :class_name => 'SwfAsset', :foreign_key => 'swf_asset_id', :conditions => {:type => 'object'}
|
||||
|
||||
def swf_asset
|
||||
self.swf_asset_type == 'biology' ? self.biology_asset : self.object_asset
|
||||
end
|
||||
|
||||
def item
|
||||
parent
|
||||
|
|
|
@ -35,19 +35,14 @@ class Pet < ActiveRecord::Base
|
|||
true
|
||||
end
|
||||
|
||||
def wardrobe_url
|
||||
uri = URI::HTTP.build({
|
||||
:host => RemoteImpressHost,
|
||||
:path => WARDROBE_PATH,
|
||||
:fragment => {
|
||||
:name => self.name,
|
||||
:color => self.pet_type.color.id,
|
||||
:species => self.pet_type.species.id,
|
||||
:state => self.pet_state.id,
|
||||
:objects => self.items.map(&:id)
|
||||
}.to_query
|
||||
})
|
||||
uri.to_s
|
||||
def wardrobe_query
|
||||
{
|
||||
:name => self.name,
|
||||
:color => self.pet_type.color.id,
|
||||
:species => self.pet_type.species.id,
|
||||
:state => self.pet_state.id,
|
||||
:objects => self.items.map(&:id)
|
||||
}.to_query
|
||||
end
|
||||
|
||||
before_save do
|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
class PetAttribute < StaticResource
|
||||
def as_json(options={})
|
||||
{
|
||||
:id => self.id,
|
||||
:name => self.name.capitalize
|
||||
}
|
||||
end
|
||||
|
||||
def self.find_by_name(name)
|
||||
@objects_by_name[name.downcase]
|
||||
end
|
||||
|
|
|
@ -3,7 +3,7 @@ class PetState < ActiveRecord::Base
|
|||
|
||||
has_many :parent_swf_asset_relationships, :foreign_key => 'parent_id',
|
||||
:conditions => {:swf_asset_type => SwfAssetType}
|
||||
has_many :swf_assets, :through => :parent_swf_asset_relationships
|
||||
has_many :swf_assets, :through => :parent_swf_asset_relationships, :source => :biology_asset
|
||||
|
||||
belongs_to :pet_type
|
||||
|
||||
|
@ -63,7 +63,7 @@ class PetState < ActiveRecord::Base
|
|||
relationship.swf_asset_type = SwfAssetType
|
||||
relationship.swf_asset_id = swf_asset.id
|
||||
end
|
||||
relationship.swf_asset = swf_asset
|
||||
relationship.biology_asset = swf_asset
|
||||
relationships << relationship
|
||||
end
|
||||
end
|
||||
|
|
|
@ -25,7 +25,9 @@ class PetType < ActiveRecord::Base
|
|||
}
|
||||
|
||||
def as_json(options={})
|
||||
{:id => id, :body_id => body_id}
|
||||
json = {:id => id, :body_id => body_id}
|
||||
json[:pet_state_ids] = self.pet_state_ids if options[:for] == 'wardrobe'
|
||||
json
|
||||
end
|
||||
|
||||
def color_id=(new_color_id)
|
||||
|
|
|
@ -3,6 +3,9 @@ class SwfAsset < ActiveRecord::Base
|
|||
LOCAL_ASSET_DIR = Rails.root.join('public', PUBLIC_ASSET_DIR)
|
||||
set_inheritance_column 'inheritance_type'
|
||||
|
||||
has_many :object_asset_relationships, :class_name => 'ParentSwfAssetRelationship',
|
||||
:conditions => {:swf_asset_type => 'object'}
|
||||
|
||||
delegate :depth, :to => :zone
|
||||
|
||||
scope :fitting_body_id, lambda { |body_id|
|
||||
|
@ -19,13 +22,21 @@ class SwfAsset < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def as_json(options={})
|
||||
{
|
||||
json = {
|
||||
:id => id,
|
||||
:depth => depth,
|
||||
:local_url => local_url,
|
||||
:body_id => body_id,
|
||||
:zone_id => zone_id
|
||||
:zone_id => zone_id,
|
||||
:zones_restrict => zones_restrict,
|
||||
:is_body_specific => body_specific?
|
||||
}
|
||||
if options[:for] == 'wardrobe'
|
||||
json[:local_path] = local_url
|
||||
else
|
||||
json[:local_url] = local_url
|
||||
end
|
||||
json[:parent_id] = options[:parent_id] if options[:parent_id]
|
||||
json
|
||||
end
|
||||
|
||||
def body_specific?
|
||||
|
@ -78,7 +89,7 @@ class SwfAsset < ActiveRecord::Base
|
|||
before_save do
|
||||
# If an asset body ID changes, that means more than one body ID has been
|
||||
# linked to it, meaning that it's probably wearable by all bodies.
|
||||
self.body_id = 0 if self.body_id_changed? || !self.body_specific?
|
||||
self.body_id = 0 if !self.body_specific? || (!self.new_record? && self.body_id_changed?)
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
- if @results
|
||||
- if @results.empty?
|
||||
- if @items
|
||||
- if @items.empty?
|
||||
:markdown
|
||||
We couldn't find any wearables that matched **#{@query}**. Sorry!
|
||||
|
||||
|
@ -8,9 +8,9 @@
|
|||
|
||||
[1]: http://impress.openneo.net/
|
||||
- else
|
||||
= will_paginate @results
|
||||
= render @results
|
||||
= will_paginate @results
|
||||
= will_paginate @items
|
||||
= render @items
|
||||
= will_paginate @items
|
||||
- else
|
||||
#search-help
|
||||
%h2 Find what you're looking for
|
||||
|
|
120
app/views/outfits/edit.html.haml
Normal file
120
app/views/outfits/edit.html.haml
Normal file
|
@ -0,0 +1,120 @@
|
|||
!!!
|
||||
%html
|
||||
%head
|
||||
%title Dress to Impress - Planning an outfit
|
||||
/[if lt IE 9]
|
||||
= javascript_include_tag "http://html5shiv.googlecode.com/svn/trunk/html5.js"
|
||||
= stylesheet_link_tag "http://#{RemoteImpressHost}/assets/css/clean.css"
|
||||
%body.standard.outfits-edit.fullscreen
|
||||
#container
|
||||
%a#home-link{:href => "/"}
|
||||
%span Dress to Impress
|
||||
%h1#title Planning an outfit
|
||||
#pet-type-not-found.possible-error
|
||||
We haven't seen that combination before. Have you?
|
||||
Submit the pet's name if you have!
|
||||
#preview-toolbar
|
||||
%form#pet-type-form
|
||||
%select{:name => "color"}
|
||||
%select{:name => "species"}
|
||||
%input{:type => "submit", :value => "Go"}/
|
||||
%form#pet-state-form
|
||||
Gender/Emotions:
|
||||
%ul
|
||||
#sharing
|
||||
%input#short-url-response{:type => "text", :value => "http://www.example.com/"}/
|
||||
%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-swf
|
||||
%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.
|
||||
#preview-sidebar
|
||||
#preview-closet
|
||||
%h2 Closet
|
||||
%ul
|
||||
%p#fullscreen-copyright
|
||||
Images © 2000-2010 Neopets, Inc. All Rights Reserved.
|
||||
Used With Permission
|
||||
%form#preview-search-form
|
||||
%header
|
||||
%h2 Add an item
|
||||
%input{:name => "query", :placeholder => "Search items...", :type => "search"}/
|
||||
%input{:type => "submit", :value => "Go"}/
|
||||
#preview-search-form-pagination
|
||||
%a#preview-search-form-clear{:href => "#"} clear
|
||||
%dl#preview-search-form-help
|
||||
%div
|
||||
%dt kreludor "altador cup" -background
|
||||
%dd
|
||||
returns any item with the word "kreludor" and the phrase "altador cup"
|
||||
in it, but not the word "background"
|
||||
%div
|
||||
%dt collar -is:nc -is:pb
|
||||
%dd
|
||||
returns any item with the word "collar" in it, but is not from the NC
|
||||
mall, and is not from a deluxe paint brush set
|
||||
%div
|
||||
%dt
|
||||
%span species:
|
||||
%span.search-helper{"data-search-filter" => "species"} Acara
|
||||
%dd
|
||||
returns any item a
|
||||
%span.search-helper{"data-search-filter" => "species"} Acara
|
||||
can wear
|
||||
%div
|
||||
%dt
|
||||
%span type:
|
||||
%span.search-helper{"data-search-filter" => "type"} background
|
||||
%dd
|
||||
returns any item that fills a
|
||||
%span.search-helper{"data-search-filter" => "type"} background
|
||||
zone
|
||||
#preview-search-form-loading Loading...
|
||||
#preview-search-form-error.possible-error
|
||||
#preview-search-form-no-results
|
||||
No results for "<span></span>"
|
||||
%ul
|
||||
#no-assets-full-message
|
||||
We haven't seen this item on this body type before. Have you? Submit its name on the home page if you have!
|
||||
/[if IE]
|
||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||
%script{:src => "http://ajax.googleapis.com/ajax/libs/jquery/1.4.0/jquery.min.js", :type => "text/javascript"}
|
||||
%script{:src => "http://ajax.googleapis.com/ajax/libs/swfobject/2.2/swfobject.js", :type => "text/javascript"}
|
||||
%script{:src => "http://bit.ly/javascript-api.js?version=latest&login=openneo&apiKey=R_4d0438829b7a99860de1d3edf55d8dc8", :type => "text/javascript"}
|
||||
%script{:src => "http://s7.addthis.com/js/250/addthis_widget.js#username=openneo", :type => "text/javascript"}
|
||||
%script{:src => "http://#{RemoteImpressHost}/assets/timestamped/js/jquery.jgrowl-v1278204174.js", :type => "text/javascript"}
|
||||
= include_javascripts :edit_outfit_package
|
||||
#userbar
|
||||
#userbar-login-with Login with:
|
||||
%ul#userbar-auth-servers
|
||||
%li
|
||||
%a{:href => "http://id.openneo.net/?app=impress&path=%2Fwardrobe&session_id=a9ddeffb83a923447e2f40a2fe8387dc"}
|
||||
%img{:src => "http://id.openneo.net/favicon.png"}/
|
||||
%span OpenNeo ID
|
||||
#footer
|
||||
%ul
|
||||
%li
|
||||
%a{:href => "http://openneo.net/", :target => "_blank"} OpenNeo
|
||||
%li
|
||||
%a{:href => "http://blog.openneo.net/", :target => "_blank"} Blog
|
||||
%li
|
||||
%a{:href => "http://forum.openneo.net/", :target => "_blank"} Forum
|
||||
%li
|
||||
%a{:href => "http://github.com/matchu/openneo-impress"} The Source Code
|
||||
%li
|
||||
%a{:href => "/terms.html"} Terms of Use
|
||||
%div
|
||||
Contact:
|
||||
%ul
|
||||
%li
|
||||
%a{:href => "http://openneo.uservoice.com/forums/40720-dress-to-impress"} Feedback
|
||||
%li
|
||||
%a{:href => "mailto:webmaster@openneo.net"} Questions, comments, bug reports
|
||||
%p
|
||||
Images © 2000-2010 Neopets, Inc. All Rights Reserved.
|
||||
Used With Permission
|
6
config/assets.yml
Normal file
6
config/assets.yml
Normal file
|
@ -0,0 +1,6 @@
|
|||
embed_assets: on
|
||||
|
||||
javascripts:
|
||||
edit_outfit_package:
|
||||
- public/javascripts/wardrobe.js
|
||||
- public/javascripts/outfits/edit.js
|
|
@ -1,15 +1,21 @@
|
|||
OpenneoImpressItems::Application.routes.draw do |map|
|
||||
match '/' => 'items#index', :as => :items
|
||||
match '/index.js' => 'items#index', :format => :js
|
||||
match '/items.json' => 'items#index', :format => :json
|
||||
|
||||
match '/item_zone_sets.js' => '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_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'
|
||||
|
||||
resources :items, :only => [:index]
|
||||
resources :pet_attributes, :only => [:index]
|
||||
resources :pets, :only => [:show]
|
||||
|
||||
match '/wardrobe' => 'outfits#edit', :as => :wardrobe
|
||||
match '/:id' => 'items#show', :as => :item
|
||||
end
|
||||
|
|
733
public/javascripts/outfits/edit.js
Normal file
733
public/javascripts/outfits/edit.js
Normal file
|
@ -0,0 +1,733 @@
|
|||
var Partial = {}, main_wardrobe,
|
||||
View = Wardrobe.getStandardView({
|
||||
Preview: {
|
||||
swf_url: '/swfs/preview.swf?v=0.12',
|
||||
wrapper: $('#preview'),
|
||||
placeholder: $('#preview-swf')
|
||||
}
|
||||
});
|
||||
|
||||
Partial.ItemSet = function ItemSet(wardrobe, selector) {
|
||||
var item_set = this, ul = $(selector), items = [], setClosetItems,
|
||||
setOutfitItems, setOutfitItemsControls, no_assets_full_message = $('#no-assets-full-message'),
|
||||
container = $('#container');
|
||||
|
||||
Partial.ItemSet.setWardrobe(wardrobe);
|
||||
|
||||
function prepSetSpecificItems(type) {
|
||||
return function (specific_items) {
|
||||
var item, worn, li;
|
||||
for(var i = 0; i < items.length; i++) {
|
||||
item = items[i];
|
||||
in_set = $.inArray(item, specific_items) != -1;
|
||||
li = $('li.object-' + item.id).toggleClass(type, in_set).
|
||||
data('item', item).data(type, in_set).children('ul').
|
||||
children('li.control-set-for-' + type).remove().end()
|
||||
[type == 'worn' ? 'prepend' : 'append']
|
||||
(Partial.ItemSet.CONTROL_SETS[type][in_set].clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setClosetItems = prepSetSpecificItems('closeted');
|
||||
|
||||
setOutfitItemsControls = prepSetSpecificItems('worn');
|
||||
setOutfitItems = function (specific_items) {
|
||||
setOutfitItemsControls(specific_items);
|
||||
setHasAssets(specific_items);
|
||||
}
|
||||
|
||||
function setHasAssets(specific_items) {
|
||||
var item, no_assets, li, no_assets_message;
|
||||
for(var i = 0, l = specific_items.length; i < l; i++) {
|
||||
item = specific_items[i];
|
||||
no_assets = item.couldNotLoadAssetsFitting(wardrobe.outfit.pet_type);
|
||||
li = $('li.object-' + item.id).toggleClass('no-assets', no_assets);
|
||||
(function (li) {
|
||||
no_assets_message = li.find('span.no-assets-message');
|
||||
no_assets_message.remove();
|
||||
if(no_assets) {
|
||||
$('<span/>', {'class': 'no-assets-message', text: 'No data yet'}).appendTo(li);
|
||||
}
|
||||
})(li);
|
||||
}
|
||||
}
|
||||
|
||||
this.setItems = function (new_items) {
|
||||
var item, li, controls, info_link;
|
||||
items = new_items;
|
||||
ul.children().remove();
|
||||
for(var i = 0; i < items.length; i++) {
|
||||
item = items[i];
|
||||
li = $('<li/>', {'class': 'object object-' + item.id});
|
||||
img = $('<img/>', {
|
||||
'src': item.thumbnail_url,
|
||||
'alt': item.description,
|
||||
'title': item.description
|
||||
});
|
||||
controls = $('<ul/>');
|
||||
info_link = $('<a/>', {
|
||||
'class': 'object-info',
|
||||
html: '<span>i</span>',
|
||||
href: ITEMS_SERVER + '/' + item.id,
|
||||
target: '_blank'
|
||||
});
|
||||
if(
|
||||
typeof item.rarity_index != 'undefined' &&
|
||||
(item.rarity_index == 500 || item.rarity_index == 0)
|
||||
) {
|
||||
$('<div/>', {'class': 'nc-icon', text: 'NC', title: 'NC'}).appendTo(li);
|
||||
}
|
||||
li.append(img).append(controls).append(info_link).append(item.name).appendTo(ul);
|
||||
}
|
||||
setClosetItems(wardrobe.closet.items);
|
||||
setOutfitItems(wardrobe.outfit.items);
|
||||
}
|
||||
|
||||
$('span.no-assets-message').live('mouseover', function () {
|
||||
var el = $(this), o = el.offset();
|
||||
no_assets_full_message.css({
|
||||
left: o.left + (el.width() / 2) - (no_assets_full_message.width() / 2) - container.offset().left,
|
||||
top: o.top + el.height() + 10
|
||||
});
|
||||
}).live('mouseout', function () {
|
||||
no_assets_full_message.removeAttr('style');
|
||||
});
|
||||
|
||||
wardrobe.outfit.bind('updateItemAssets', function () { setHasAssets(wardrobe.outfit.items) });
|
||||
wardrobe.outfit.bind('updateItems', setOutfitItems);
|
||||
wardrobe.closet.bind('updateItems', setClosetItems);
|
||||
}
|
||||
|
||||
Partial.ItemSet.CONTROL_SETS = {};
|
||||
|
||||
Partial.ItemSet.setWardrobe = function (wardrobe) {
|
||||
var type, verb_set, toggle, live_class, full_class, toggle_fn = {};
|
||||
for(var i = 0; i < 2; i++) {
|
||||
type = i == 0 ? 'worn' : 'closeted';
|
||||
verb_set = i == 0 ? ['Unwear', 'Wear'] : ['Uncloset', 'Closet'];
|
||||
Partial.ItemSet.CONTROL_SETS[type] = {};
|
||||
for(var j = 0; j < 2; j++) {
|
||||
toggle = j == 0;
|
||||
full_class = 'control-set control-set-for-' + type;
|
||||
live_class = 'control-set-' + (toggle ? '' : 'not-') + type;
|
||||
full_class += ' ' + live_class;
|
||||
Partial.ItemSet.CONTROL_SETS[type][toggle] = $('<a/>', {
|
||||
href: '#',
|
||||
text: verb_set[toggle ? 0 : 1]
|
||||
}).wrap('<li/>').parent().attr('class', full_class);
|
||||
|
||||
(function (type, toggle) {
|
||||
$('li.' + live_class + ' a').live('click', function (e) {
|
||||
var el = $(this), item = el.closest('.object').data('item');
|
||||
toggle_fn[type][!toggle](item);
|
||||
e.preventDefault();
|
||||
});
|
||||
})(type, toggle);
|
||||
}
|
||||
}
|
||||
|
||||
toggle_fn.closeted = {};
|
||||
toggle_fn.closeted[true] = $.proxy(wardrobe.closet, 'addItem');
|
||||
toggle_fn.closeted[false] = function (item) { wardrobe.outfit.removeItem(item); wardrobe.closet.removeItem(item); }
|
||||
|
||||
toggle_fn.worn = {};
|
||||
toggle_fn.worn[true] = function (item) { wardrobe.closet.addItem(item); wardrobe.outfit.addItem(item); }
|
||||
toggle_fn.worn[false] = $.proxy(wardrobe.outfit, 'removeItem');
|
||||
|
||||
Partial.ItemSet.setWardrobe = $.noop;
|
||||
}
|
||||
|
||||
View.Closet = function (wardrobe) {
|
||||
var item_set = new Partial.ItemSet(wardrobe, '#preview-closet ul');
|
||||
|
||||
wardrobe.closet.bind('updateItems', $.proxy(item_set, 'setItems'));
|
||||
}
|
||||
|
||||
View.Fullscreen = function (wardrobe) {
|
||||
var full = $(document.body).hasClass('fullscreen'), win = $(window),
|
||||
preview_el = $('#preview'), search_el = $('#preview-search-form'),
|
||||
preview_swf = $('#preview-swf'), closet_el = $('#preview-closet'),
|
||||
footer = $('#footer');
|
||||
|
||||
function fit() {
|
||||
if(full) {
|
||||
preview_swf = $('#preview-swf'); // swf replaced
|
||||
var available = {
|
||||
height: search_el.offset().top - preview_el.offset().top,
|
||||
width: preview_el.innerWidth() - closet_el.outerWidth() - 12 // 12px margin
|
||||
}, dim = {}, margin = {}, size = {
|
||||
old: {height: preview_swf.height(), width: preview_swf.width()},
|
||||
next: {}
|
||||
}, offset;
|
||||
if(available.height > available.width) {
|
||||
dim.larger = 'height';
|
||||
dim.smaller = 'width';
|
||||
margin.active = 'marginTop';
|
||||
margin.inactive = 'marginLeft';
|
||||
} else {
|
||||
dim.larger = 'width';
|
||||
dim.smaller = 'height';
|
||||
margin.active = 'marginLeft';
|
||||
margin.inactive = 'marginTop';
|
||||
}
|
||||
size.next[dim.smaller] = available[dim.smaller];
|
||||
size.next[dim.larger] = available[dim.smaller];
|
||||
size.next[margin.active] = (available[dim.larger] - size.next[dim.larger]) / 2;
|
||||
size.next[margin.inactive] = 0;
|
||||
preview_swf.css(size.next);
|
||||
|
||||
preview_el.height(available.height);
|
||||
}
|
||||
}
|
||||
$('#preview').data('fit', fit);
|
||||
|
||||
win.resize(fit).load(fit);
|
||||
fit();
|
||||
|
||||
var Konami=function(){var a={addEvent:function(b,c,d,e){if(b.addEventListener)b.addEventListener(c,d,false);else if(b.attachEvent){b["e"+c+d]=d;b[c+d]=function(){b["e"+c+d](window.event,e)};b.attachEvent("on"+c,b[c+d])}},input:"",pattern:"3838404037393739666513",load:function(b){this.addEvent(document,"keydown",function(c,d){if(d)a=d;a.input+=c?c.keyCode:event.keyCode;if(a.input.indexOf(a.pattern)!=-1){a.code(b);a.input=""}},this);this.iphone.load(b)},code:function(b){window.location=b},iphone:{start_x:0,start_y:0,stop_x:0,stop_y:0,tap:false,capture:false,keys:["UP","UP","DOWN","DOWN","LEFT","RIGHT","LEFT","RIGHT","TAP","TAP","TAP"],code:function(b){a.code(b)},load:function(b){a.addEvent(document,"touchmove",function(c){if(c.touches.length==1&&a.iphone.capture==true){c=c.touches[0];a.iphone.stop_x=c.pageX;a.iphone.stop_y=c.pageY;a.iphone.tap=false;a.iphone.capture=false;a.iphone.check_direction()}});a.addEvent(document,"touchend",function(){a.iphone.tap==true&&a.iphone.check_direction(b)},false);a.addEvent(document,"touchstart",function(c){a.iphone.start_x=c.changedTouches[0].pageX;a.iphone.start_y=c.changedTouches[0].pageY;a.iphone.tap=true;a.iphone.capture=true})},check_direction:function(b){x_magnitude=Math.abs(this.start_x-this.stop_x);y_magnitude=Math.abs(this.start_y-this.stop_y);x=this.start_x-this.stop_x<0?"RIGHT":"LEFT";y=this.start_y-this.stop_y<0?"DOWN":"UP";result=x_magnitude>y_magnitude?x:y;result=this.tap==true?"TAP":result;if(result==this.keys[0])this.keys=this.keys.slice(1,this.keys.length);this.keys.length==0&&this.code(b)}}};return a};
|
||||
konami = new Konami();
|
||||
konami.code = function () {
|
||||
$(document.body).removeClass('fullscreen');
|
||||
preview_swf.removeAttr('style').css('visibility', 'visible');
|
||||
preview_el.removeAttr('style');
|
||||
wardrobe.search.setPerPage(21);
|
||||
wardrobe.search.setItemsByQuery(wardrobe.search.request.query, {offset: wardrobe.search.request.offset});
|
||||
full = false;
|
||||
}
|
||||
konami.load();
|
||||
}
|
||||
|
||||
View.Hash = function (wardrobe) {
|
||||
var data = {}, proposed_data = {}, previous_query, parse_in_progress = false, TYPES = {
|
||||
INTEGER: 1,
|
||||
STRING: 2,
|
||||
INTEGER_ARRAY: 3
|
||||
}, KEYS = {
|
||||
closet: TYPES.INTEGER_ARRAY,
|
||||
color: TYPES.INTEGER,
|
||||
name: TYPES.STRING,
|
||||
objects: TYPES.INTEGER_ARRAY,
|
||||
search: TYPES.STRING,
|
||||
search_offset: TYPES.INTEGER,
|
||||
species: TYPES.INTEGER,
|
||||
state: TYPES.INTEGER
|
||||
}, onUpdateQuery;
|
||||
|
||||
function checkQuery() {
|
||||
var query = (document.location.hash || document.location.search).substr(1);
|
||||
if(query != previous_query) {
|
||||
parseQuery(query);
|
||||
previous_query = query;
|
||||
}
|
||||
}
|
||||
|
||||
function parseQuery(query) {
|
||||
var new_data = {}, pairs = query.split('&');
|
||||
parse_in_progress = true;
|
||||
for(var i = 0; i < pairs.length; i++) {
|
||||
var pair = pairs[i].split('='),
|
||||
key = decodeURIComponent(pair[0]),
|
||||
value = decodeURIComponent(pair[1]);
|
||||
if(value) {
|
||||
if(KEYS[key] == TYPES.INTEGER) {
|
||||
new_data[key] = +value;
|
||||
} else if(KEYS[key] == TYPES.STRING) {
|
||||
new_data[key] = decodeURIComponent(value).replace(/\+/g, ' ');
|
||||
} else if(key.substr(key.length-2) == '[]') {
|
||||
key = key.substr(0, key.length-2);
|
||||
if(KEYS[key] == TYPES.INTEGER_ARRAY) {
|
||||
if(typeof new_data[key] == 'undefined') new_data[key] = [];
|
||||
new_data[key].push(+value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(new_data.color !== data.color || new_data.species !== data.species) {
|
||||
wardrobe.outfit.setPetTypeByColorAndSpecies(new_data.color, new_data.species);
|
||||
}
|
||||
if(new_data.closet) {
|
||||
if(!arraysMatch(new_data.closet, data.closet)) {
|
||||
wardrobe.closet.setItemsByIds(new_data.closet.slice(0));
|
||||
}
|
||||
} else if(!arraysMatch(new_data.objects, data.closet)) {
|
||||
wardrobe.closet.setItemsByIds(new_data.objects.slice(0));
|
||||
}
|
||||
if(!arraysMatch(new_data.objects, data.objects)) {
|
||||
wardrobe.outfit.setItemsByIds(new_data.objects.slice(0));
|
||||
}
|
||||
if(new_data.name != data.name && new_data.name) {
|
||||
wardrobe.base_pet.setName(new_data.name);
|
||||
}
|
||||
if(new_data.state != data.state) {
|
||||
wardrobe.outfit.setPetStateById(new_data.state);
|
||||
}
|
||||
if(new_data.search != data.search || new_data.search_offset != data.search_offset) {
|
||||
wardrobe.search.setItemsByQuery(new_data.search, {offset: new_data.search_offset});
|
||||
}
|
||||
data = new_data;
|
||||
parse_in_progress = false;
|
||||
}
|
||||
|
||||
function changeQuery(changes) {
|
||||
var value;
|
||||
if(!parse_in_progress) {
|
||||
for(var key in changes) {
|
||||
if(changes.hasOwnProperty(key)) {
|
||||
value = changes[key];
|
||||
if(value === undefined) {
|
||||
delete data[key];
|
||||
} else {
|
||||
data[key] = changes[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
updateQuery();
|
||||
}
|
||||
}
|
||||
|
||||
function updateQuery() {
|
||||
var new_query;
|
||||
new_query = $.param(data).replace(/%5B%5D/g, '[]');
|
||||
previous_query = new_query;
|
||||
document.location.hash = '#' + new_query;
|
||||
onUpdateQuery();
|
||||
}
|
||||
|
||||
this.initialize = function () {
|
||||
checkQuery();
|
||||
setInterval(checkQuery, 100);
|
||||
onUpdateQuery();
|
||||
}
|
||||
|
||||
wardrobe.closet.bind('updateItems', function (items) {
|
||||
var item_ids = items.map('id');
|
||||
if(!arraysMatch(item_ids, data.closet)) {
|
||||
changeQuery({closet: item_ids});
|
||||
}
|
||||
});
|
||||
|
||||
wardrobe.outfit.bind('updateItems', function (items) {
|
||||
var item_ids = items.map('id'), changes = {};
|
||||
if(!arraysMatch(item_ids, data.objects)) {
|
||||
changes.objects = item_ids;
|
||||
}
|
||||
if(arraysMatch(item_ids, data.closet) || arraysMatch(item_ids, data.objects)) {
|
||||
changes.closet = undefined;
|
||||
} else {
|
||||
changes.closet = wardrobe.closet.items.map('id');
|
||||
}
|
||||
if(changes.objects || changes.closet) changeQuery(changes);
|
||||
});
|
||||
|
||||
wardrobe.outfit.bind('updatePetType', function (pet_type) {
|
||||
if(pet_type.color_id != data.color || pet_type.species_id != data.species) {
|
||||
changeQuery({
|
||||
color: pet_type.color_id,
|
||||
species: pet_type.species_id,
|
||||
state: undefined
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
wardrobe.outfit.bind('petTypeNotFound', function () {
|
||||
window.history.back();
|
||||
});
|
||||
|
||||
wardrobe.outfit.bind('updatePetState', function (pet_state) {
|
||||
var pet_type = wardrobe.outfit.pet_type;
|
||||
if(pet_state.id != data.state && pet_type && (data.state || pet_state.id != pet_type.pet_state_ids[0])) {
|
||||
changeQuery({state: pet_state.id});
|
||||
}
|
||||
});
|
||||
|
||||
wardrobe.search.bind('updateRequest', function (request) {
|
||||
if(request.offset != data.search_offset || request.query != data.search) {
|
||||
changeQuery({
|
||||
search_offset: request.offset,
|
||||
search: request.query
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
(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.PetStateForm = function (wardrobe) {
|
||||
var INPUT_NAME = 'pet_state_id', form_query = '#pet-state-form',
|
||||
form = $(form_query),
|
||||
ul = form.children('ul'),
|
||||
radio_query = form_query + ' input[name=' + INPUT_NAME + ']';
|
||||
$(radio_query).live('click', function () {
|
||||
wardrobe.outfit.setPetStateById(+this.value);
|
||||
});
|
||||
|
||||
function updatePetState(pet_state) {
|
||||
if(pet_state) {
|
||||
ul.children('li.selected').removeClass('selected');
|
||||
$(radio_query + '[value=' + pet_state.id + ']')
|
||||
.attr('checked', 'checked').parent().addClass('selected');
|
||||
}
|
||||
}
|
||||
|
||||
wardrobe.outfit.bind('petTypeLoaded', function (pet_type) {
|
||||
var ids = pet_type.pet_state_ids, i, id, li, radio, label;
|
||||
ul.children().remove();
|
||||
if(ids.length == 1) {
|
||||
form.hide();
|
||||
} else {
|
||||
form.show();
|
||||
for(var i = 0; i < ids.length; i++) {
|
||||
id = 'pet-state-radio-' + i;
|
||||
li = $('<li/>');
|
||||
radio = $('<input/>', {
|
||||
id: id,
|
||||
name: INPUT_NAME,
|
||||
type: 'radio',
|
||||
value: ids[i]
|
||||
});
|
||||
label = $('<label/>', {
|
||||
'for': id,
|
||||
text: i + 1
|
||||
});
|
||||
if(i == 0) radio.attr('checked', 'checked');
|
||||
radio.appendTo(li);
|
||||
label.appendTo(li);
|
||||
li.appendTo(ul);
|
||||
}
|
||||
updatePetState(wardrobe.outfit.pet_state);
|
||||
}
|
||||
});
|
||||
|
||||
wardrobe.outfit.bind('updatePetState', updatePetState);
|
||||
}
|
||||
|
||||
View.PetTypeForm = function (wardrobe) {
|
||||
var form = $('#pet-type-form'), dropdowns = {}, loaded = false;
|
||||
form.submit(function (e) {
|
||||
e.preventDefault();
|
||||
wardrobe.outfit.setPetTypeByColorAndSpecies(
|
||||
+dropdowns.color.val(), +dropdowns.species.val()
|
||||
);
|
||||
}).children('select').each(function () {
|
||||
dropdowns[this.name] = $(this);
|
||||
});
|
||||
|
||||
this.initialize = function () {
|
||||
wardrobe.pet_attributes.load();
|
||||
}
|
||||
|
||||
function updatePetType(pet_type) {
|
||||
if(loaded && pet_type) {
|
||||
$.each(dropdowns, function (name) {
|
||||
dropdowns[name].val(pet_type[name + '_id']);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
wardrobe.pet_attributes.bind('update', function (attributes) {
|
||||
$.each(attributes, function (type) {
|
||||
var dropdown = dropdowns[type];
|
||||
$.each(this, function () {
|
||||
var option = $('<option/>', {
|
||||
text: this.name,
|
||||
value: this.id
|
||||
});
|
||||
option.appendTo(dropdown);
|
||||
});
|
||||
});
|
||||
loaded = true;
|
||||
updatePetType(wardrobe.outfit.pet_type);
|
||||
});
|
||||
|
||||
wardrobe.outfit.bind('updatePetType', updatePetType);
|
||||
|
||||
wardrobe.outfit.bind('petTypeNotFound', function () {
|
||||
$('#pet-type-not-found').show('normal').delay(3000).hide('fast');
|
||||
});
|
||||
}
|
||||
|
||||
View.Search = function (wardrobe) {
|
||||
var form_selector = '#preview-search-form', form = $(form_selector),
|
||||
item_set = new Partial.ItemSet(wardrobe, form_selector + ' ul'),
|
||||
input_el = form.find('input[name=query]'),
|
||||
clear_el = $('#preview-search-form-clear'),
|
||||
error_el = $('#preview-search-form-error'),
|
||||
help_el = $('#preview-search-form-help'),
|
||||
loading_el = $('#preview-search-form-loading'),
|
||||
no_results_el = $('#preview-search-form-no-results'),
|
||||
no_results_span = no_results_el.children('span'),
|
||||
PAGINATION = {
|
||||
INNER_WINDOW: 4,
|
||||
OUTER_WINDOW: 1,
|
||||
GAP_TEXT: '…',
|
||||
PREV_TEXT: '← Previous',
|
||||
NEXT_TEXT: 'Next →',
|
||||
PAGE_EL: $('<a/>', {href: '#'}),
|
||||
CURRENT_EL: $('<span/>', {'class': 'current'}),
|
||||
EL_ID: '#preview-search-form-pagination',
|
||||
PER_PAGE: 21
|
||||
}, object_width = 112, last_request;
|
||||
|
||||
PAGINATION.EL = $(PAGINATION.EL_ID);
|
||||
PAGINATION.GAP_EL = $('<span/>', {'class': 'gap', html: PAGINATION.GAP_TEXT})
|
||||
PAGINATION.PREV_EL = $('<a/>', {href: '#', rel: 'prev', html: PAGINATION.PREV_TEXT});
|
||||
PAGINATION.NEXT_EL = $('<a/>', {href: '#', rel: 'next', html: PAGINATION.NEXT_TEXT});
|
||||
|
||||
$(PAGINATION.EL_ID + ' a').live('click', function (e) {
|
||||
e.preventDefault();
|
||||
loadPage($(this).data('page'));
|
||||
});
|
||||
|
||||
this.initialize = $.proxy(wardrobe.item_zone_sets, 'load');
|
||||
|
||||
wardrobe.search.setPerPage(PAGINATION.PER_PAGE);
|
||||
|
||||
function updatePerPage() {
|
||||
var new_per_page = Math.floor(form.width() / object_width),
|
||||
offset, new_page;
|
||||
if(new_per_page != PAGINATION.PER_PAGE) {
|
||||
PAGINATION.PER_PAGE = new_per_page;
|
||||
wardrobe.search.setPerPage(PAGINATION.PER_PAGE);
|
||||
if(last_request) {
|
||||
loadOffset(last_request.offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
$(window).resize(updatePerPage).load(updatePerPage);
|
||||
updatePerPage();
|
||||
|
||||
function loadOffset(offset) {
|
||||
wardrobe.search.setItemsByQuery(input_el.val(), {offset: offset});
|
||||
}
|
||||
|
||||
function loadPage(page) {
|
||||
wardrobe.search.setItemsByQuery(input_el.val(), {page: page});
|
||||
}
|
||||
|
||||
function stopLoading() {
|
||||
loading_el.stop(true, true).hide();
|
||||
}
|
||||
|
||||
form.submit(function (e) {
|
||||
e.preventDefault();
|
||||
loadPage(1);
|
||||
});
|
||||
|
||||
clear_el.click(function (e) {
|
||||
e.preventDefault();
|
||||
input_el.val('');
|
||||
form.submit();
|
||||
});
|
||||
|
||||
wardrobe.search.bind('startRequest', function () {
|
||||
loading_el.delay(1000).show('slow');
|
||||
});
|
||||
|
||||
wardrobe.search.bind('updateItems', function (items) {
|
||||
var fit = $('#preview').data('fit') || $.noop;
|
||||
stopLoading();
|
||||
item_set.setItems(items);
|
||||
if(wardrobe.search.request.query) {
|
||||
if(!items.length) {
|
||||
no_results_el.show();
|
||||
}
|
||||
} else {
|
||||
help_el.show();
|
||||
}
|
||||
form.toggleClass('has-results', items.length > 0);
|
||||
fit();
|
||||
});
|
||||
|
||||
wardrobe.search.bind('updateRequest', function (request) {
|
||||
last_request = request;
|
||||
error_el.hide('fast');
|
||||
help_el.hide();
|
||||
no_results_el.hide();
|
||||
input_el.val(request.query || '');
|
||||
no_results_span.text(request.query);
|
||||
clear_el.toggle(!!request.query);
|
||||
});
|
||||
|
||||
wardrobe.search.bind('updatePagination', function (current_page, total_pages) {
|
||||
// ported from http://github.com/mislav/will_paginate/blob/master/lib/will_paginate/view_helpers.rb#L274
|
||||
var window_from = current_page - PAGINATION.INNER_WINDOW,
|
||||
window_to = current_page + PAGINATION.INNER_WINDOW,
|
||||
visible = [], left_gap, right_gap, subtract_left, subtract_right,
|
||||
i = 1;
|
||||
|
||||
if(window_to > total_pages) {
|
||||
window_from -= window_to - total_pages;
|
||||
window_to = total_pages;
|
||||
}
|
||||
|
||||
if(window_from < 1) {
|
||||
window_to += 1 - window_from;
|
||||
window_from = 1;
|
||||
if(window_to > total_pages) window_to = total_pages;
|
||||
}
|
||||
|
||||
left_gap = [2 + PAGINATION.OUTER_WINDOW, window_from];
|
||||
right_gap = [window_to + 1, total_pages - PAGINATION.OUTER_WINDOW];
|
||||
|
||||
subtract_left = (left_gap[1] - left_gap[0]) > 1;
|
||||
subtract_right = (right_gap[1] - right_gap[0]) > 1;
|
||||
|
||||
PAGINATION.EL.children().remove();
|
||||
|
||||
if(current_page > 1) {
|
||||
PAGINATION.PREV_EL.clone().data('page', current_page - 1).appendTo(PAGINATION.EL);
|
||||
}
|
||||
|
||||
while(i <= total_pages) {
|
||||
if(subtract_left && i >= left_gap[0] && i < left_gap[1]) {
|
||||
PAGINATION.GAP_EL.clone().appendTo(PAGINATION.EL);
|
||||
i = left_gap[1];
|
||||
} else if(subtract_right && i >= right_gap[0] && i < right_gap[1]) {
|
||||
PAGINATION.GAP_EL.clone().appendTo(PAGINATION.EL);
|
||||
i = right_gap[1];
|
||||
} else {
|
||||
if(i == current_page) {
|
||||
PAGINATION.CURRENT_EL.clone().text(i).appendTo(PAGINATION.EL);
|
||||
} else {
|
||||
PAGINATION.PAGE_EL.clone().text(i).data('page', i).appendTo(PAGINATION.EL);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
if(current_page < total_pages) {
|
||||
PAGINATION.NEXT_EL.clone().data('page', current_page + 1).appendTo(PAGINATION.EL);
|
||||
}
|
||||
});
|
||||
|
||||
wardrobe.search.bind('error', function (error) {
|
||||
stopLoading();
|
||||
error_el.text(error).show('normal');
|
||||
});
|
||||
|
||||
help_el.find('dt').each(function () {
|
||||
var el = $(this);
|
||||
if(!el.children().length) {
|
||||
el.wrapInner($('<a/>', {href: '#'}));
|
||||
}
|
||||
}).children('span:not(.search-helper)').each(function () {
|
||||
var el = $(this);
|
||||
el.replaceWith($('<a/>', {href: '#', text: el.text()}));
|
||||
});
|
||||
|
||||
help_el.find('dt a').live('click', function (e) {
|
||||
var el = $(this), siblings = el.parent().children(), query;
|
||||
e.preventDefault();
|
||||
if(siblings.length > 1) {
|
||||
query = siblings.map(function () {
|
||||
var el = $(this);
|
||||
return el[el.is('select') ? 'val' : 'text']();
|
||||
}).get().join('');
|
||||
} else {
|
||||
query = el.text();
|
||||
}
|
||||
input_el.val(query);
|
||||
form.submit();
|
||||
});
|
||||
|
||||
$('select.search-helper').live('change', function () {
|
||||
var el = $(this), filter = el.attr('data-search-filter');
|
||||
$('select.search-helper[data-search-filter=' + filter + ']').val(el.val());
|
||||
});
|
||||
|
||||
function prepBuildHelper(type, getSet) {
|
||||
return function (objs) {
|
||||
var select = $('<select/>',
|
||||
{'class': 'search-helper', 'data-search-filter': type}),
|
||||
span = $('span.search-helper[data-search-filter=' + type + ']');
|
||||
objs = getSet(objs);
|
||||
for(var i = 0, l = objs.length; i < l; i++) {
|
||||
$('<option/>', {text: objs[i].name}).appendTo(select);
|
||||
}
|
||||
span.replaceWith(function () {
|
||||
return select.clone().fadeIn('fast');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function getSpecies(x) { return x.species }
|
||||
|
||||
wardrobe.item_zone_sets.bind('update', prepBuildHelper('type', function (x) {
|
||||
return x;
|
||||
}));
|
||||
|
||||
wardrobe.pet_attributes.bind('update', prepBuildHelper('species', getSpecies));
|
||||
//wardrobe.pet_attributes.bind('update', prepBuildHelper('only', getSpecies));
|
||||
}
|
||||
|
||||
View.Title = function (wardrobe) {
|
||||
wardrobe.base_pet.bind('updateName', function (name) {
|
||||
$('#title').text("Planning " + name + "'s outfit");
|
||||
});
|
||||
}
|
||||
|
||||
$.ajaxSetup({
|
||||
error: function (xhr) {
|
||||
$.jGrowl("There was an error loading that last resource. Oops. Please try again!");
|
||||
}
|
||||
});
|
||||
|
||||
main_wardrobe = new Wardrobe();
|
||||
main_wardrobe.registerViews(View);
|
||||
main_wardrobe.initialize();
|
774
public/javascripts/wardrobe.js
Normal file
774
public/javascripts/wardrobe.js
Normal file
|
@ -0,0 +1,774 @@
|
|||
var ITEMS_SERVER = '',
|
||||
SHORT_URL_HOST = 'http://bit.ly/';
|
||||
|
||||
window.log = window.SWFLog = $.noop;
|
||||
|
||||
function arraysMatch(array1, array2) {
|
||||
// http://www.breakingpar.com/bkp/home.nsf/0/87256B280015193F87256BFB0077DFFD
|
||||
var temp;
|
||||
if(!$.isArray(array1)|| !$.isArray(array2)) {
|
||||
return array1 == array2;
|
||||
}
|
||||
temp = [];
|
||||
if ( (!array1[0]) || (!array2[0]) ) {
|
||||
return false;
|
||||
}
|
||||
if (array1.length != array2.length) {
|
||||
return false;
|
||||
}
|
||||
for (var i=0; i<array1.length; i++) {
|
||||
key = (typeof array1[i]) + "~" + array1[i];
|
||||
if (temp[key]) { temp[key]++; } else { temp[key] = 1; }
|
||||
}
|
||||
for (var i=0; i<array2.length; i++) {
|
||||
key = (typeof array2[i]) + "~" + array2[i];
|
||||
if (temp[key]) {
|
||||
if (temp[key] == 0) { return false; } else { temp[key]--; }
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Array.prototype.map = function (property) {
|
||||
return $.map(this, function (element) {
|
||||
return element[property];
|
||||
});
|
||||
}
|
||||
|
||||
function DeepObject() {}
|
||||
|
||||
DeepObject.prototype.deepGet = function () {
|
||||
var scope = this, i;
|
||||
$.each(arguments, function () {
|
||||
scope = scope[this];
|
||||
if(typeof scope == 'undefined') return false;
|
||||
});
|
||||
return scope;
|
||||
}
|
||||
|
||||
DeepObject.prototype.deepSet = function () {
|
||||
var pop = $.proxy(Array.prototype.pop, 'apply'),
|
||||
value = pop(arguments),
|
||||
final_key = pop(arguments),
|
||||
scope = this;
|
||||
$.each(arguments, function () {
|
||||
if(typeof scope[this] == 'undefined') {
|
||||
scope[this] = {};
|
||||
}
|
||||
scope = scope[this];
|
||||
});
|
||||
scope[final_key] = value;
|
||||
}
|
||||
|
||||
function Wardrobe() {
|
||||
var wardrobe = this, BiologyAsset, ItemAsset;
|
||||
|
||||
/*
|
||||
*
|
||||
* Models
|
||||
*
|
||||
*/
|
||||
|
||||
function determineRestrictedZones() {
|
||||
var i, zone;
|
||||
this.restricted_zones = [];
|
||||
while((zone = this.zones_restrict.indexOf(1, zone) + 1) != 0) {
|
||||
this.restricted_zones.push(zone);
|
||||
}
|
||||
}
|
||||
|
||||
function Asset(data) {
|
||||
var asset = this;
|
||||
for(var key in data) {
|
||||
if(data.hasOwnProperty(key)) {
|
||||
asset[key] = data[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function BiologyAsset(data) {
|
||||
Asset.apply(this, [data]);
|
||||
determineRestrictedZones.apply(this);
|
||||
}
|
||||
|
||||
function ItemAsset(data) {
|
||||
Asset.apply(this, [data]);
|
||||
}
|
||||
|
||||
function Item(id) {
|
||||
var item = this;
|
||||
this.id = id;
|
||||
this.assets_by_body_id = {};
|
||||
this.load_started = false;
|
||||
this.loaded = false;
|
||||
|
||||
this.getAssetsFitting = function (pet_type) {
|
||||
return this.assets_by_body_id[pet_type.body_id] || [];
|
||||
}
|
||||
|
||||
this.hasAssetsFitting = function (pet_type) {
|
||||
return typeof item.assets_by_body_id[pet_type.body_id] != 'undefined' &&
|
||||
item.assets_by_body_id[pet_type.body_id].length > 0;
|
||||
}
|
||||
|
||||
this.couldNotLoadAssetsFitting = function (pet_type) {
|
||||
return typeof item.assets_by_body_id[pet_type.body_id] != 'undefined' &&
|
||||
item.assets_by_body_id[pet_type.body_id].length == 0;
|
||||
}
|
||||
|
||||
this.update = function (data) {
|
||||
for(var key in data) {
|
||||
if(data.hasOwnProperty(key) && key != 'id') { // do not replace ID with string
|
||||
item[key] = data[key];
|
||||
}
|
||||
}
|
||||
determineRestrictedZones.apply(this);
|
||||
this.loaded = true;
|
||||
}
|
||||
|
||||
Item.cache[id] = this;
|
||||
}
|
||||
|
||||
Item.find = function (id) {
|
||||
var item = Item.cache[id];
|
||||
if(!item) {
|
||||
item = new Item(id);
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
var item_load_callbacks = [];
|
||||
|
||||
Item.loadByIds = function (ids, success) {
|
||||
var ids_to_load = [], ids_not_loaded = [], items = $.map(ids, function (id) {
|
||||
var item = Item.find(id);
|
||||
if(!item.load_started) {
|
||||
ids_to_load.push(id);
|
||||
item.load_started = true;
|
||||
}
|
||||
if(!item.loaded) {
|
||||
ids_not_loaded.push(id);
|
||||
}
|
||||
return item;
|
||||
});
|
||||
if(ids_to_load.length) {
|
||||
$.getJSON('/items.json', {ids: ids_to_load}, function (data) {
|
||||
var set, set_items, set_ids, set_callback, run_callback, ids_from_data = [];
|
||||
$.each(data, function () {
|
||||
ids_from_data.push(+this.id);
|
||||
Item.find(this.id).update(this);
|
||||
});
|
||||
for(var i = 0; i < item_load_callbacks.length; i++) {
|
||||
set = item_load_callbacks[i];
|
||||
set_items = set[0];
|
||||
set_ids = set[1];
|
||||
set_callback = set[2];
|
||||
run_callback = true;
|
||||
for(var j = 0; j < set_ids.length; j++) {
|
||||
if($.inArray(set_ids[j], ids_from_data) == -1) {
|
||||
run_callback = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(run_callback) set_callback(set_items);
|
||||
}
|
||||
success(items);
|
||||
});
|
||||
} else if(ids_not_loaded.length) {
|
||||
item_load_callbacks.push([items, ids_not_loaded, success]);
|
||||
} else {
|
||||
success(items);
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
var ITEMS_URL = ITEMS_SERVER + '/index.js?callback=?';
|
||||
|
||||
Item.PER_PAGE = 21;
|
||||
|
||||
Item.loadByQuery = function (query, offset, success, error) {
|
||||
var page = Math.round(offset / Item.PER_PAGE) + 1;
|
||||
$.getJSON(ITEMS_URL, {q: query, per_page: Item.PER_PAGE, page: page}, function (data) {
|
||||
var items = [], item, item_data;
|
||||
if(data.items) {
|
||||
for(var i = 0; i < data.items.length; i++) {
|
||||
item_data = data.items[i];
|
||||
item = Item.find(item_data.id);
|
||||
item.update(item_data);
|
||||
items.push(item);
|
||||
}
|
||||
success(items, data.total_pages, page);
|
||||
} else if(data.error) {
|
||||
error(data.error);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Item.cache = {};
|
||||
|
||||
function ItemZoneSet(name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
ItemZoneSet.loadAll = function (success) {
|
||||
$.getJSON(ITEMS_SERVER + '/item_zone_sets.js?callback=?', function (data) {
|
||||
for(var i = 0, l = data.length; i < l; i++) {
|
||||
ItemZoneSet.all.push(new ItemZoneSet(data[i]));
|
||||
}
|
||||
success(ItemZoneSet.all);
|
||||
});
|
||||
}
|
||||
|
||||
ItemZoneSet.all = [];
|
||||
|
||||
function PetAttribute() {}
|
||||
|
||||
PetAttribute.loadAll = function (success) {
|
||||
$.getJSON('/pet_attributes.json', function (data) {
|
||||
success(data);
|
||||
});
|
||||
}
|
||||
|
||||
function PetState(id) {
|
||||
var pet_state = this, loaded = false;
|
||||
|
||||
this.id = id;
|
||||
this.assets = [];
|
||||
|
||||
this.loadAssets = function (success) {
|
||||
var params;
|
||||
if(loaded) {
|
||||
success(pet_state);
|
||||
} else {
|
||||
$.getJSON('/pet_states/' + pet_state.id + '/swf_assets.json',
|
||||
function (data) {
|
||||
pet_state.assets = $.map(data, function (obj) { return new BiologyAsset(obj) });
|
||||
loaded = true;
|
||||
success(pet_state);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
PetState.cache[id] = this;
|
||||
}
|
||||
|
||||
PetState.find = function (id) {
|
||||
var pet_state = PetState.cache[id];
|
||||
if(!pet_state) {
|
||||
pet_state = new PetState(id);
|
||||
}
|
||||
return pet_state;
|
||||
}
|
||||
|
||||
PetState.cache = {};
|
||||
|
||||
function PetType() {
|
||||
var pet_type = this;
|
||||
|
||||
this.loaded = false;
|
||||
this.pet_states = [];
|
||||
|
||||
this.load = function (success, error) {
|
||||
if(pet_type.loaded) {
|
||||
success(pet_type);
|
||||
} else {
|
||||
$.getJSON('/species/' + pet_type.species_id + '/color/' + pet_type.color_id + '/pet_type.json', {
|
||||
'for': 'wardrobe'
|
||||
}, function (data) {
|
||||
if(data) {
|
||||
for(var key in data) {
|
||||
if(data.hasOwnProperty(key)) {
|
||||
pet_type[key] = data[key];
|
||||
}
|
||||
}
|
||||
for(var i = 0; i < pet_type.pet_state_ids.length; i++) {
|
||||
pet_type.pet_states.push(PetState.find(pet_type.pet_state_ids[i]));
|
||||
}
|
||||
PetType.cache_by_color_and_species.deepSet(
|
||||
pet_type.color_id,
|
||||
pet_type.species_id,
|
||||
pet_type
|
||||
);
|
||||
pet_type.loaded = true;
|
||||
success(pet_type);
|
||||
} else {
|
||||
error(pet_type);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
this.loadItemAssets = function (item_ids, success) {
|
||||
var item_ids_needed = [];
|
||||
for(var i = 0; i < item_ids.length; i++) {
|
||||
var id = item_ids[i], item = Item.find(id);
|
||||
if(!item.hasAssetsFitting(pet_type)) item_ids_needed.push(id);
|
||||
}
|
||||
if(item_ids_needed.length) {
|
||||
$.getJSON('/bodies/' + pet_type.body_id + '/swf_assets.json', {
|
||||
item_ids: item_ids_needed
|
||||
}, function (data) {
|
||||
var item;
|
||||
$.each(data, function () {
|
||||
var item = Item.find(this.parent_id),
|
||||
asset = new ItemAsset(this);
|
||||
if(typeof item.assets_by_body_id[pet_type.body_id] == 'undefined') {
|
||||
item.assets_by_body_id[pet_type.body_id] = [];
|
||||
}
|
||||
item.assets_by_body_id[pet_type.body_id].push(asset);
|
||||
});
|
||||
for(var i = 0, l = item_ids.length; i < l; i++) {
|
||||
item = Item.find(item_ids[i]);
|
||||
if(!item.hasAssetsFitting(pet_type)) {
|
||||
item.assets_by_body_id[pet_type.body_id] = [];
|
||||
}
|
||||
}
|
||||
success();
|
||||
});
|
||||
} else {
|
||||
success();
|
||||
}
|
||||
}
|
||||
|
||||
this.toString = function () {
|
||||
return 'PetType{color_id: ' + this.color_id + ', species_id: ' +
|
||||
this.species_id + '}';
|
||||
}
|
||||
|
||||
this.ownsPetState = function (pet_state) {
|
||||
for(var i = 0; i < this.pet_states.length; i++) {
|
||||
if(this.pet_states[i] == pet_state) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
PetType.cache_by_color_and_species = new DeepObject();
|
||||
|
||||
PetType.findOrCreateByColorAndSpecies = function (color_id, species_id) {
|
||||
var pet_type = PetType.cache_by_color_and_species.deepGet(color_id, species_id);
|
||||
if(!pet_type) {
|
||||
pet_type = new PetType();
|
||||
pet_type.color_id = color_id;
|
||||
pet_type.species_id = species_id;
|
||||
}
|
||||
return pet_type;
|
||||
}
|
||||
|
||||
function SwfAsset() {}
|
||||
|
||||
/*
|
||||
*
|
||||
* Controllers
|
||||
*
|
||||
*/
|
||||
|
||||
function Controller() {
|
||||
var controller = this;
|
||||
this.events = {};
|
||||
|
||||
this.bind = function (event, callback) {
|
||||
if(typeof this.events[event] == 'undefined') {
|
||||
this.events[event] = [];
|
||||
}
|
||||
this.events[event].push(callback);
|
||||
}
|
||||
|
||||
this.events.trigger = function (event) {
|
||||
var subarguments;
|
||||
if(controller.events[event]) {
|
||||
subarguments = Array.prototype.slice.apply(arguments, [1]);
|
||||
$.each(controller.events[event], function () {
|
||||
this.apply(controller, subarguments);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Controller.all = {};
|
||||
|
||||
Controller.all.Outfit = function OutfitController() {
|
||||
var outfit = this, previous_pet_type, item_ids = [];
|
||||
|
||||
this.items = [];
|
||||
|
||||
function getRestrictedZones() {
|
||||
// note: may contain duplicates - loop through assets, not these, for
|
||||
// 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) {
|
||||
return $.inArray(item, outfit.items) != -1;
|
||||
}
|
||||
|
||||
function itemAssetsOnLoad(added_item) {
|
||||
var item_zones, item_zones_length, existing_item, existing_item_zones, passed,
|
||||
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 () {
|
||||
var assets = this.pet_state.assets, restricted_zones = getRestrictedZones(),
|
||||
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) {
|
||||
var i = $.inArray(item, this.items), id_i;
|
||||
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) {
|
||||
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) {
|
||||
this.pet_type = PetType.findOrCreateByColorAndSpecies(color_id, species_id);
|
||||
outfit.events.trigger('updatePetType', this.pet_type);
|
||||
this.pet_type.load(petTypeOnLoad, petTypeOnError);
|
||||
}
|
||||
|
||||
this.setItemsByIds = function (ids) {
|
||||
if(ids) item_ids = ids;
|
||||
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) {
|
||||
closet.events.trigger('updateItems', items);
|
||||
}
|
||||
|
||||
this.addItem = function (item) {
|
||||
if(!hasItem(item)) {
|
||||
this.items.push(item);
|
||||
item_ids.push(item.id);
|
||||
closet.events.trigger('updateItems', this.items);
|
||||
}
|
||||
}
|
||||
|
||||
this.removeItem = function (item) {
|
||||
var i = $.inArray(item, this.items), id_i;
|
||||
if(i != -1) {
|
||||
this.items.splice(i, 1);
|
||||
id_i = $.inArray(item.id, item_ids);
|
||||
item_ids.splice(id_i, 1);
|
||||
closet.events.trigger('updateItems', this.items);
|
||||
}
|
||||
}
|
||||
|
||||
this.setItemsByIds = function (ids) {
|
||||
if(ids && ids.length) {
|
||||
item_ids = ids;
|
||||
this.items = Item.loadByIds(ids, itemsOnLoad);
|
||||
} else {
|
||||
item_ids = ids;
|
||||
this.items = [];
|
||||
itemsOnLoad(this.items);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Controller.all.BasePet = function BasePetController() {
|
||||
var base_pet = this;
|
||||
|
||||
this.setName = function (name) {
|
||||
base_pet.name = name;
|
||||
base_pet.events.trigger('updateName', name);
|
||||
}
|
||||
}
|
||||
|
||||
Controller.all.PetAttributes = function PetAttributesController() {
|
||||
var pet_attributes = this;
|
||||
|
||||
function onLoad(attributes) {
|
||||
pet_attributes.events.trigger('update', attributes);
|
||||
}
|
||||
|
||||
this.load = function () {
|
||||
PetAttribute.loadAll(onLoad);
|
||||
}
|
||||
}
|
||||
|
||||
Controller.all.ItemZoneSets = function ItemZoneSetsController() {
|
||||
var item_zone_sets = this;
|
||||
|
||||
function onLoad(sets) {
|
||||
item_zone_sets.events.trigger('update', sets);
|
||||
}
|
||||
|
||||
this.load = function () {
|
||||
ItemZoneSet.loadAll(onLoad);
|
||||
}
|
||||
}
|
||||
|
||||
Controller.all.Search = function SearchController() {
|
||||
var search = this;
|
||||
|
||||
this.request = {};
|
||||
|
||||
function itemsOnLoad(items, total_pages, page) {
|
||||
search.events.trigger('updateItems', items);
|
||||
search.events.trigger('updatePagination', page, total_pages);
|
||||
}
|
||||
|
||||
function itemsOnError(error) {
|
||||
search.events.trigger('error', error);
|
||||
}
|
||||
|
||||
this.setItemsByQuery = function (query, where) {
|
||||
var offset = (typeof where.offset != 'undefined') ? where.offset : (Item.PER_PAGE * (where.page - 1));
|
||||
search.request = {
|
||||
query: query,
|
||||
offset: offset
|
||||
};
|
||||
search.events.trigger('updateRequest', search.request);
|
||||
if(query) {
|
||||
Item.loadByQuery(query, offset, itemsOnLoad, itemsOnError);
|
||||
search.events.trigger('startRequest');
|
||||
} else {
|
||||
search.events.trigger('updateItems', []);
|
||||
search.events.trigger('updatePagination', 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
this.setPerPage = function (per_page) {
|
||||
Item.PER_PAGE = per_page;
|
||||
}
|
||||
}
|
||||
|
||||
var underscored_name;
|
||||
|
||||
for(var name in Controller.all) {
|
||||
if(Controller.all.hasOwnProperty(name)) {
|
||||
// underscoring translated from
|
||||
// http://api.rubyonrails.org/classes/ActiveSupport/Inflector.html#M000710
|
||||
underscored_name = name.replace(/([A-Z]+)([A-Z][a-z])/g, '$1_$2').
|
||||
replace(/([a-z\d])([A-Z])/g,'$1_$2').toLowerCase();
|
||||
wardrobe[underscored_name] = new Controller.all[name];
|
||||
Controller.apply(wardrobe[underscored_name]);
|
||||
}
|
||||
}
|
||||
|
||||
this.initialize = function () {
|
||||
var view;
|
||||
for(var name in wardrobe.views) {
|
||||
if(wardrobe.views.hasOwnProperty(name)) {
|
||||
view = wardrobe.views[name];
|
||||
if(typeof view.initialize == 'function') {
|
||||
view.initialize();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.registerViews = function (views) {
|
||||
wardrobe.views = {};
|
||||
$.each(views, function (name) {
|
||||
wardrobe.views[name] = new this(wardrobe);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Wardrobe.StandardPreview = {
|
||||
views_by_swf_id: {}
|
||||
};
|
||||
|
||||
Wardrobe.getStandardView = function (options) {
|
||||
var StandardView = {};
|
||||
|
||||
function requireKeys() {
|
||||
var key, key_stack = [], scope = options;
|
||||
for(var i = 0; i < arguments.length; i++) {
|
||||
key = arguments[i];
|
||||
key_stack.push(key);
|
||||
scope = scope[key];
|
||||
if(typeof scope == "undefined") {
|
||||
throw "Options for Wardrobe.getStandardView must include " + key_stack.join(".");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
requireKeys('Preview', 'swf_url');
|
||||
requireKeys('Preview', 'wrapper');
|
||||
requireKeys('Preview', 'placeholder');
|
||||
|
||||
if(document.location.search.substr(0, 6) == '?debug') {
|
||||
StandardView.Console = function (wardrobe) {
|
||||
if(typeof console != 'undefined' && typeof console.log == 'function') {
|
||||
window.log = $.proxy(console, 'log');
|
||||
}
|
||||
|
||||
this.initialize = function () {
|
||||
log('Welcome to the Wardrobe!');
|
||||
}
|
||||
|
||||
var outfit_events = ['updateItems', 'updateItemAssets', 'updatePetType', 'updatePetState'];
|
||||
for(var i = 0; i < outfit_events.length; i++) {
|
||||
(function (event) {
|
||||
wardrobe.outfit.bind(event, function (obj) {
|
||||
log(event, obj);
|
||||
});
|
||||
})(outfit_events[i]);
|
||||
}
|
||||
|
||||
wardrobe.outfit.bind('petTypeNotFound', function (pet_type) {
|
||||
log(pet_type.toString() + ' not found');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
StandardView.Preview = function (wardrobe) {
|
||||
var preview_el = $(options.Preview.wrapper),
|
||||
preview_swf_placeholder = $(options.Preview.placeholder),
|
||||
preview_swf_id = preview_swf_placeholder.attr('id'),
|
||||
preview_swf,
|
||||
update_pending_flash = false;
|
||||
|
||||
swfobject.embedSWF(
|
||||
options.Preview.swf_url,
|
||||
preview_swf_id,
|
||||
'100%',
|
||||
'100%',
|
||||
'9',
|
||||
'/assets/js/swfobject/expressInstall.swf',
|
||||
{'id': preview_swf_id},
|
||||
{'wmode': 'transparent'}
|
||||
);
|
||||
|
||||
Wardrobe.StandardPreview.views_by_swf_id[preview_swf_id] = this;
|
||||
console.log(Wardrobe.StandardPreview.views_by_swf_id);
|
||||
|
||||
this.previewSWFIsReady = function () {
|
||||
preview_swf = document.getElementById(preview_swf_id);
|
||||
if(update_pending_flash) {
|
||||
update_pending_flash = false;
|
||||
updateAssets();
|
||||
}
|
||||
}
|
||||
|
||||
function updateAssets() {
|
||||
var assets, assets_for_swf;
|
||||
if(update_pending_flash) return false;
|
||||
if(preview_swf && preview_swf.setAssets) {
|
||||
assets = wardrobe.outfit.getVisibleAssets();
|
||||
preview_swf.setAssets(assets);
|
||||
} else {
|
||||
update_pending_flash = true;
|
||||
}
|
||||
}
|
||||
|
||||
wardrobe.outfit.bind('updateItems', updateAssets);
|
||||
wardrobe.outfit.bind('updateItemAssets', updateAssets);
|
||||
wardrobe.outfit.bind('updatePetState', updateAssets);
|
||||
}
|
||||
|
||||
window.previewSWFIsReady = function (id) {
|
||||
Wardrobe.StandardPreview.views_by_swf_id[id].previewSWFIsReady();
|
||||
}
|
||||
|
||||
return StandardView;
|
||||
}
|
Binary file not shown.
BIN
vendor/cache/closure-compiler-0.3.3.gem
vendored
Normal file
BIN
vendor/cache/closure-compiler-0.3.3.gem
vendored
Normal file
Binary file not shown.
BIN
vendor/cache/jammit-0.5.3.gem
vendored
Normal file
BIN
vendor/cache/jammit-0.5.3.gem
vendored
Normal file
Binary file not shown.
BIN
vendor/cache/yui-compressor-0.9.1.gem
vendored
Normal file
BIN
vendor/cache/yui-compressor-0.9.1.gem
vendored
Normal file
Binary file not shown.
Loading…
Reference in a new issue