diff --git a/app/models/outfit.rb b/app/models/outfit.rb index edad2a0b..828b7e80 100644 --- a/app/models/outfit.rb +++ b/app/models/outfit.rb @@ -6,7 +6,7 @@ class Outfit < ActiveRecord::Base validates :name, :presence => true, :uniqueness => {:scope => :user_id} validates :pet_state, :presence => true - attr_accessible :name, :pet_state_id, :starred, :unworn_item_ids, :worn_item_ids + attr_accessible :name, :pet_state_id, :starred, :worn_and_unworn_item_ids def as_json(more_options={}) serializable_hash :only => [:id, :name, :pet_state_id, :starred], @@ -30,20 +30,17 @@ class Outfit < ActiveRecord::Base 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 + def worn_and_unworn_item_ids=(all_item_ids) + new_rels = [] + all_item_ids.each do |key, item_ids| + worn = key == 'worn' + item_ids.each do |item_id| + rel = ItemOutfitRelationship.new + rel.item_id = item_id + rel.is_worn = worn + new_rels << rel + end end + self.item_outfit_relationships = new_rels end end diff --git a/app/stylesheets/outfits/_edit.sass b/app/stylesheets/outfits/_edit.sass index 2c5516a9..d151d1b4 100644 --- a/app/stylesheets/outfits/_edit.sass +++ b/app/stylesheets/outfits/_edit.sass @@ -422,6 +422,11 @@ body.outfits-edit display: block #save-outfit display: inline-block + #save-outfit-wrapper.active-outfit + #save-outfit + display: none + #save-current-outfit, #save-outfit-copy + display: inline-block &.user-not-signed-in #save-outfit-not-signed-in diff --git a/app/views/outfits/edit.html.haml b/app/views/outfits/edit.html.haml index 95fa685e..36fb89e2 100644 --- a/app/views/outfits/edit.html.haml +++ b/app/views/outfits/edit.html.haml @@ -16,6 +16,8 @@ #save-outfit-wrapper %button#save-outfit Save outfit %button#save-outfit-not-signed-in Log in to save outfit + %button#save-current-outfit Save "current outfit" + %button#save-outfit-copy Save a copy #preview #preview-swf #preview-swf-container diff --git a/public/javascripts/outfits/edit.js b/public/javascripts/outfits/edit.js index 72251a9a..a2f880b0 100644 --- a/public/javascripts/outfits/edit.js +++ b/public/javascripts/outfits/edit.js @@ -428,14 +428,20 @@ View.Hash = function (wardrobe) { } View.Outfits = function (wardrobe) { - var outfits_el = $('#preview-outfits'), sidebar_el = $('#preview-sidebar'), - 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'), + var controls = $('#pet-type-form, #pet-state-form, #preview-swf, #preview-search-form'), + new_outfit_el = $('#new-outfit'), + new_outfit_form_el = $('#new-outfit-form'), new_outfit_name_el = $('#new-outfit-name'), + outfits_el = $('#preview-outfits'), outfits_list_el = outfits_el.children('ul'), outfit_not_found_el = $('#outfit-not-found'), + save_current_outfit_el = $('#save-current-outfit'), + save_current_outfit_name_el = save_current_outfit_el.children('span'), + save_outfit_wrapper_el = $('#save-outfit-wrapper'), + save_success_el = $('#save-success'), + save_error_el = $('#save-error'), stars = $('#preview-outfits div.outfit-star'), + sidebar_el = $('#preview-sidebar'), signed_in, previously_viewing = ''; @@ -490,7 +496,7 @@ View.Outfits = function (wardrobe) { sidebar_el.attr('class', previously_viewing); }); - $('#save-outfit').click(function () { + $('#save-outfit, #save-outfit-copy').click(function () { new_outfit_name_el.val(''); new_outfit_el.removeClass('starred').show(); showSavingOutfit(); @@ -528,7 +534,7 @@ View.Outfits = function (wardrobe) { }); $('#preview-outfits h4').live('click', function () { - wardrobe.outfit.load($(this).tmplItem().data.clone()); + wardrobe.outfit.load($(this).tmplItem().data.id); }); $('input.outfit-url').live('mouseover', function () { @@ -566,7 +572,9 @@ View.Outfits = function (wardrobe) { outfits_list_el.find('li.active').removeClass('active'); if(outfit.id) { $('li.outfit-' + outfit.id).addClass('active'); + save_current_outfit_name_el.text(outfit.name); } + save_outfit_wrapper_el.toggleClass('active-outfit', outfit.id ? true : false); } function updateActiveOutfit() { @@ -578,9 +586,13 @@ View.Outfits = function (wardrobe) { /* Saving */ + save_current_outfit_el.click(function () { + wardrobe.outfit.update(); + }); + new_outfit_form_el.submit(function (e) { e.preventDefault(); - wardrobe.outfit.save(new_outfit_el.hasClass('starred'), new_outfit_name_el.val()); + wardrobe.outfit.create({starred: new_outfit_el.hasClass('starred'), name: new_outfit_name_el.val()}); }); new_outfit_el.find('div.outfit-star').click(function () { @@ -599,11 +611,18 @@ View.Outfits = function (wardrobe) { } wardrobe.outfit.bind('saveSuccess', function (outfit) { - wardrobe.user.addOutfit(outfit); save_success_el.notify(); + }); + + wardrobe.outfit.bind('createSuccess', function (outfit) { + wardrobe.user.addOutfit(outfit); showOutfits(); }); + wardrobe.outfit.bind('updateSuccess', function (outfit) { + wardrobe.user.updateOutfit(outfit); + }); + wardrobe.outfit.bind('saveFailure', function (response) { var errors = response.errors; if(typeof errors == 'undefined') { diff --git a/public/javascripts/wardrobe.js b/public/javascripts/wardrobe.js index 1d27c2f1..ffe1ba77 100644 --- a/public/javascripts/wardrobe.js +++ b/public/javascripts/wardrobe.js @@ -220,7 +220,7 @@ function Wardrobe() { function Outfit(data) { var outfit = this, previous_pet_type, worn_item_ids = [], - new_record = true; + closet_item_ids = [], new_record = true; this.setWornAndUnwornItemIds = function (new_ids) { this.worn_and_unworn_item_ids = new_ids; @@ -250,6 +250,15 @@ function Wardrobe() { return closet_item_ids; } + function getAttributes() { + var outfit_data = {}; + outfit_data.name = outfit.name; + outfit_data.starred = outfit.starred; + outfit_data.worn_and_unworn_item_ids = outfit.getWornAndUnwornItemIds(); + if(outfit.pet_state) outfit_data.pet_state_id = outfit.pet_state.id; + return outfit_data; + } + function getRestrictedZones() { // note: may contain duplicates - loop through assets, not these, for // best performance @@ -316,6 +325,19 @@ function Wardrobe() { } } + function sendUpdate(outfit_data, success, failure) { + $.ajax({ + url: '/outfits/' + outfit.id, + type: 'post', + data: {'_method': 'put', outfit: outfit_data}, + success: function () { + Outfit.cache[outfit.id] = outfit; + success(outfit); + }, + error: function () { if(typeof failure !== 'undefined') failure(outfit) } + }); + } + this.closetItem = function (item, updateClosetItemsCallback) { if(!hasItemInCloset(item)) { this.closet_items.push(item); @@ -413,6 +435,10 @@ function Wardrobe() { } } + this.update = function (success, failure) { + sendUpdate(getAttributes(), success, failure); + } + this.wearItem = function (item, updateWornItemsCallback, updateClosetItemsCallback, updateItemAssetsCallback) { if(!isWearingItem(item)) { this.worn_items.push(item); @@ -426,16 +452,14 @@ function Wardrobe() { } this.getWornAndUnwornItemIds = function () { - if(typeof outfit.worn_and_unworn_item_ids === 'undefined') { - var unworn_item_ids = [], id; - for(var i = 0; i < closet_item_ids.length; i++) { - id = closet_item_ids[i]; - if($.inArray(id, worn_item_ids) === -1) { - unworn_item_ids.push(id); - } + var unworn_item_ids = [], id; + for(var i = 0; i < closet_item_ids.length; i++) { + id = closet_item_ids[i]; + if($.inArray(id, worn_item_ids) === -1) { + unworn_item_ids.push(id); } - outfit.worn_and_unworn_item_ids = {worn: worn_item_ids, unworn: unworn_item_ids}; } + outfit.worn_and_unworn_item_ids = {worn: worn_item_ids, unworn: unworn_item_ids}; return outfit.worn_and_unworn_item_ids; } @@ -473,16 +497,10 @@ function Wardrobe() { } this.create = function (success, error) { - var outfit_data = {}, sorted = outfit.getWornAndUnwornItemIds(); - outfit_data.name = outfit.name; - outfit_data.starred = outfit.starred; - outfit_data.worn_item_ids = sorted.worn; - outfit_data.unworn_item_ids = sorted.unworn; - if(outfit.pet_state) outfit_data.pet_state_id = outfit.pet_state.id; $.ajax({ url: '/outfits', type: 'post', - data: {outfit: outfit_data}, + data: {outfit: getAttributes()}, success: function (data) { new_record = false; outfit.id = data; @@ -502,12 +520,7 @@ function Wardrobe() { outfit_data[key] = outfit[key] = attributes[key]; } } - $.ajax({ - url: '/outfits/' + outfit.id, - type: 'post', - data: {'_method': 'put', outfit: outfit_data}, - success: function () { success(outfit) } - }); + sendUpdate(outfit_data, success); } } @@ -758,24 +771,29 @@ function Wardrobe() { return outfit.worn_items; } - this.load = function (new_outfit) { - outfit = new_outfit; - this.in_transaction = true; - controller.setPetTypeByColorAndSpecies(outfit.color_id, outfit.species_id); - controller.setPetStateById(outfit.pet_state_id); - controller.setClosetItemsByIds(outfit.getClosetItemIds()); - controller.setWornItemsByIds(outfit.getWornItemIds()); - controller.events.trigger('setOutfit', outfit); - this.in_transaction = false; - controller.events.trigger('loadOutfit', outfit); + this.load = function (new_outfit_id) { + Outfit.find(new_outfit_id, function (new_outfit) { + outfit = new_outfit.clone(); + controller.in_transaction = true; + controller.setPetTypeByColorAndSpecies(outfit.color_id, outfit.species_id); + controller.setPetStateById(outfit.pet_state_id); + controller.setClosetItemsByIds(outfit.getClosetItemIds()); + controller.setWornItemsByIds(outfit.getWornItemIds()); + controller.events.trigger('setOutfit', outfit); + controller.in_transaction = false; + controller.events.trigger('loadOutfit', outfit); + }); } - this.save = function (starred, name) { - outfit.starred = starred; - outfit.name = name; + this.create = function (attributes) { + if(attributes) { + outfit.starred = attributes.starred; + outfit.name = attributes.name; + } outfit.create( function (outfit) { controller.events.trigger('saveSuccess', outfit); + controller.events.trigger('createSuccess', outfit); controller.events.trigger('setOutfit', outfit); }, controller.event('saveFailure') @@ -843,6 +861,16 @@ function Wardrobe() { outfit.unwearItem(item, controller.event('updateWornItems')); } + this.update = function () { + outfit.update( + function (outfit) { + controller.events.trigger('saveSuccess', outfit), + controller.events.trigger('updateSuccess', outfit) + }, + controller.event('saveFailure') + ); + } + this.wearItem = function (item) { outfit.wearItem( item, @@ -988,6 +1016,15 @@ function Wardrobe() { controller.events.trigger('outfitStarToggled', outfit); }); } + + this.updateOutfit = function (outfit) { + for(var i = 0; i < outfits.length; i++) { + if(outfits[i].id == outfit.id) { + outfits[i] = outfit.clone(); + break; + } + } + } } var underscored_name; diff --git a/public/stylesheets/compiled/screen.css b/public/stylesheets/compiled/screen.css index 457a28ae..149b8179 100644 --- a/public/stylesheets/compiled/screen.css +++ b/public/stylesheets/compiled/screen.css @@ -1621,7 +1621,15 @@ body.outfits-edit.user-signed-in #preview-sidebar-nav-outfits { body.outfits-edit.user-signed-in #save-outfit { display: inline-block; } -/* line 427, ../../../app/stylesheets/outfits/_edit.sass */ +/* line 426, ../../../app/stylesheets/outfits/_edit.sass */ +body.outfits-edit.user-signed-in #save-outfit-wrapper.active-outfit #save-outfit { + display: none; +} +/* line 428, ../../../app/stylesheets/outfits/_edit.sass */ +body.outfits-edit.user-signed-in #save-outfit-wrapper.active-outfit #save-current-outfit, body.outfits-edit.user-signed-in #save-outfit-wrapper.active-outfit #save-outfit-copy { + display: inline-block; +} +/* line 432, ../../../app/stylesheets/outfits/_edit.sass */ body.outfits-edit.user-not-signed-in #save-outfit-not-signed-in { display: inline-block; }