Sharing now fully supports saved outfits, not just shared ones

This commit is contained in:
Emi Matchu 2012-07-26 23:47:22 -04:00
parent b02c95c2d9
commit 374c7e6147
9 changed files with 456 additions and 317 deletions

View file

@ -75,7 +75,7 @@ class OutfitsController < ApplicationController
def update
if @outfit.update_attributes(params[:outfit])
render :json => true
render :json => @outfit
else
render_outfit_errors
end

View file

@ -15,12 +15,13 @@ class Outfit < ActiveRecord::Base
mount_uploader :image, OutfitImageUploader
before_save :update_enqueued_image
after_commit :enqueue_image!
def as_json(more_options={})
serializable_hash :only => [:id, :name, :pet_state_id, :starred],
:methods => [:color_id, :species_id, :worn_and_unworn_item_ids,
:image_versions]
:image_versions, :image_enqueued, :image_layers_hash]
end
def image_versions
@ -94,6 +95,7 @@ class Outfit < ActiveRecord::Base
create_image! image
self.image_layers_hash = generate_image_layers_hash
self.image = image
self.image_enqueued = false
save!
end
end
@ -104,7 +106,12 @@ class Outfit < ActiveRecord::Base
# Enqueue an image write iff the new image would be different than the
# current one.
def enqueue_image!
Resque.enqueue(OutfitImageUpdate, id) if image_layers_dirty?
Resque.enqueue(OutfitImageUpdate, id)
end
def update_enqueued_image
self.image_enqueued = (image_layers_dirty?)
true
end
def s3_key(size)

View file

@ -573,11 +573,14 @@ body.outfits-edit
display: block
height: 150px
margin: 1em auto 0
position: relative
width: 150px
#preview-sharing-thumbnail-loading
height: 100%
position: relative
left: 0
position: absolute
top: 0
width: 100%
span
@ -606,6 +609,13 @@ body.outfits-edit
#preview-sharing-thumbnail
display: block
&.urls-loaded.thumbnail-available
#preview-sharing-thumbnail-loading
+opacity(0.85)
#preview-sharing-thumbnail
display: block
.preview-sidebar-nav
float: right
font-size: 85%

View file

@ -0,0 +1,9 @@
class AddImageEnqueuedToOutfits < ActiveRecord::Migration
def self.up
add_column :outfits, :image_enqueued, :boolean, :null => false, :default => false
end
def self.down
remove_column :outfits, :image_enqueued
end
end

View file

@ -10,7 +10,7 @@
#
# It's strongly recommended to check this file into your version control system.
ActiveRecord::Schema.define(:version => 20120716193946) do
ActiveRecord::Schema.define(:version => 20120725232903) do
create_table "auth_servers", :force => true do |t|
t.string "short_name", :limit => 10, :null => false
@ -119,6 +119,7 @@ ActiveRecord::Schema.define(:version => 20120716193946) do
t.boolean "starred", :default => false, :null => false
t.string "image"
t.string "image_layers_hash"
t.boolean "image_enqueued", :default => false, :null => false
end
add_index "outfits", ["pet_state_id"], :name => "index_outfits_on_pet_state_id"

View file

@ -57,7 +57,7 @@ Partial.ItemSet = function ItemSet(wardrobe, selector) {
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.getPetType());
no_assets = item.couldNotLoadAssetsFitting(wardrobe.outfits.getPetType());
li = $('li.object-' + item.id).toggleClass('no-assets', no_assets);
(function (li) {
no_assets_message = li.find('span.no-assets-message');
@ -103,8 +103,8 @@ Partial.ItemSet = function ItemSet(wardrobe, selector) {
}
li.append(img).append(controls).append(info_link).append(item.name).appendTo(ul);
}
setClosetItems(wardrobe.outfit.getClosetItems());
setOutfitItems(wardrobe.outfit.getWornItems());
setClosetItems(wardrobe.outfits.getClosetItems());
setOutfitItems(wardrobe.outfits.getWornItems());
}
$('span.no-assets-message').live('mouseover', function () {
@ -117,9 +117,9 @@ Partial.ItemSet = function ItemSet(wardrobe, selector) {
no_assets_full_message.removeAttr('style');
});
wardrobe.outfit.bind('updateItemAssets', function () { setHasAssets(wardrobe.outfit.getWornItems()) });
wardrobe.outfit.bind('updateWornItems', setOutfitItems);
wardrobe.outfit.bind('updateClosetItems', setClosetItems);
wardrobe.outfits.bind('updateItemAssets', function () { setHasAssets(wardrobe.outfits.getWornItems()) });
wardrobe.outfits.bind('updateWornItems', setOutfitItems);
wardrobe.outfits.bind('updateClosetItems', setClosetItems);
}
Partial.ItemSet.CONTROL_SETS = {};
@ -151,12 +151,12 @@ Partial.ItemSet.setWardrobe = function (wardrobe) {
}
toggle_fn.closeted = {};
toggle_fn.closeted[true] = $.proxy(wardrobe.outfit, 'closetItem');
toggle_fn.closeted[false] = $.proxy(wardrobe.outfit, 'unclosetItem');
toggle_fn.closeted[true] = $.proxy(wardrobe.outfits, 'closetItem');
toggle_fn.closeted[false] = $.proxy(wardrobe.outfits, 'unclosetItem');
toggle_fn.worn = {};
toggle_fn.worn[true] = $.proxy(wardrobe.outfit, 'wearItem');
toggle_fn.worn[false] = $.proxy(wardrobe.outfit, 'unwearItem');
toggle_fn.worn[true] = $.proxy(wardrobe.outfits, 'wearItem');
toggle_fn.worn[false] = $.proxy(wardrobe.outfits, 'unwearItem');
Partial.ItemSet.setWardrobe = $.noop;
}
@ -164,7 +164,7 @@ Partial.ItemSet.setWardrobe = function (wardrobe) {
View.Closet = function (wardrobe) {
var item_set = new Partial.ItemSet(wardrobe, '#preview-closet ul');
wardrobe.outfit.bind('updateClosetItems', $.proxy(item_set, 'setItems'));
wardrobe.outfits.bind('updateClosetItems', $.proxy(item_set, 'setItems'));
}
View.Fullscreen = function (wardrobe) {
@ -281,32 +281,32 @@ View.Hash = function (wardrobe) {
}
if(new_data.color !== data.color || new_data.species !== data.species) {
wardrobe.outfit.setPetTypeByColorAndSpecies(new_data.color, new_data.species);
wardrobe.outfits.setPetTypeByColorAndSpecies(new_data.color, new_data.species);
}
if(new_data.closet) {
if(!arraysMatch(new_data.closet, data.closet)) {
wardrobe.outfit.setClosetItemsByIds(new_data.closet.slice(0));
wardrobe.outfits.setClosetItemsByIds(new_data.closet.slice(0));
}
} else if(new_data.objects && !arraysMatch(new_data.objects, data.closet)) {
wardrobe.outfit.setClosetItemsByIds(new_data.objects.slice(0));
wardrobe.outfits.setClosetItemsByIds(new_data.objects.slice(0));
} else {
wardrobe.outfit.setClosetItemsByIds([]);
wardrobe.outfits.setClosetItemsByIds([]);
}
if(new_data.objects) {
if(!arraysMatch(new_data.objects, data.objects)) {
wardrobe.outfit.setWornItemsByIds(new_data.objects.slice(0));
wardrobe.outfits.setWornItemsByIds(new_data.objects.slice(0));
}
} else {
wardrobe.outfit.setWornItemsByIds([]);
wardrobe.outfits.setWornItemsByIds([]);
}
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);
wardrobe.outfits.setPetStateById(new_data.state);
}
if(new_data.outfit != data.outfit) {
wardrobe.outfit.setId(new_data.outfit);
wardrobe.outfits.setId(new_data.outfit);
}
if(new_data.search != data.search || new_data.search_offset != data.search_offset) {
wardrobe.search.setItemsByQuery(new_data.search, {offset: new_data.search_offset});
@ -358,8 +358,8 @@ View.Hash = function (wardrobe) {
}
function singleOutfitResponse(event_name, response) {
wardrobe.outfit.bind(event_name, function () {
if(!wardrobe.outfit.in_transaction) response.apply(this, arguments);
wardrobe.outfits.bind(event_name, function () {
if(!wardrobe.outfits.in_transaction) response.apply(this, arguments);
});
}
@ -378,7 +378,7 @@ View.Hash = function (wardrobe) {
if(arraysMatch(item_ids, data.closet) || arraysMatch(item_ids, data.objects)) {
changes.closet = undefined;
} else {
changes.closet = wardrobe.outfit.getClosetItems().mapProperty('id');
changes.closet = wardrobe.outfits.getClosetItems().mapProperty('id');
}
if(changes.objects || changes.closet) changeQuery(changes);
});
@ -398,7 +398,7 @@ View.Hash = function (wardrobe) {
});
singleOutfitResponse('updatePetState', function (pet_state) {
var pet_type = wardrobe.outfit.getPetType();
var pet_type = wardrobe.outfits.getPetType();
if(pet_state.id != data.state && pet_type && (data.state || pet_state.id != pet_type.pet_state_ids[0])) {
changeQuery({state: pet_state.id});
}
@ -410,7 +410,7 @@ View.Hash = function (wardrobe) {
}
});
wardrobe.outfit.bind('loadOutfit', function (outfit) {
wardrobe.outfits.bind('loadOutfit', function (outfit) {
changeQuery({
closet: outfit.getClosetItemIds(),
color: outfit.pet_type.color_id,
@ -421,7 +421,7 @@ View.Hash = function (wardrobe) {
});
});
wardrobe.outfit.bind('outfitNotFound', function (outfit) {
wardrobe.outfits.bind('outfitNotFound', function (outfit) {
var new_id = outfit ? outfit.id : undefined;
changeQuery({outfit: new_id});
});
@ -475,15 +475,18 @@ View.Outfits = function (wardrobe) {
/* Nav */
function showCloset() {
sharing.onHide();
navigateTo('');
}
function showOutfits() {
wardrobe.user.loadOutfits();
sharing.onHide();
wardrobe.outfits.loadOutfits();
navigateTo('viewing-outfits');
}
function showSharing() {
sharing.onShow();
navigateTo('sharing');
}
@ -501,7 +504,7 @@ View.Outfits = function (wardrobe) {
$('#preview-sidebar-navbar-closet').click(showCloset);
$('#preview-sidebar-navbar-sharing').click(function () {
sharing.startLoading();
wardrobe.outfit.share();
wardrobe.outfits.share();
showSharing();
});
$('#preview-sidebar-navbar-outfits').click(showOutfits);
@ -518,13 +521,13 @@ View.Outfits = function (wardrobe) {
$('#outfit-template').template('outfitTemplate');
wardrobe.user.bind('outfitsLoaded', function (outfits) {
wardrobe.outfits.bind('outfitsLoaded', function (outfits) {
var outfit_els = $.tmpl('outfitTemplate', outfits);
outfits_list_el.html('').append(outfit_els).addClass('loaded');
updateActiveOutfit();
});
wardrobe.user.bind('addOutfit', function (outfit, i) {
wardrobe.outfits.bind('addOutfit', function (outfit, i) {
var next_child = outfits_list_el.children().not('.hiding').eq(i),
outfit_el = $.tmpl('outfitTemplate', outfit);
if(next_child.length) {
@ -536,13 +539,13 @@ View.Outfits = function (wardrobe) {
outfit_el.hide().show('normal');
});
wardrobe.user.bind('removeOutfit', function (outfit, i) {
wardrobe.outfits.bind('removeOutfit', function (outfit, i) {
var outfit_el = outfits_list_el.children().not('.hiding').eq(i);
outfit_el.addClass('hiding').stop(true).hide('normal', function () { outfit_el.remove() });
});
$('#preview-outfits h4').live('click', function () {
wardrobe.outfit.load($(this).tmplItem().data.id);
wardrobe.outfits.load($(this).tmplItem().data.id);
});
$('a.outfit-rename-button').live('click', function (e) {
@ -557,7 +560,7 @@ View.Outfits = function (wardrobe) {
li = el.closest('li').removeClass('renaming');
if(new_name != outfit.name) {
li.startLoading();
wardrobe.user.renameOutfit(outfit, new_name);
wardrobe.outfits.renameOutfit(outfit, new_name);
}
}
@ -583,9 +586,9 @@ View.Outfits = function (wardrobe) {
$('a.outfit-delete-confirmation-yes').live('click', function (e) {
var outfit = $(this).tmplItem().data;
e.preventDefault();
wardrobe.user.destroyOutfit(outfit);
if(wardrobe.outfit.getOutfit().id == outfit.id) {
wardrobe.outfit.setId(null);
wardrobe.outfits.destroyOutfit(outfit);
if(wardrobe.outfits.getOutfit().id == outfit.id) {
wardrobe.outfits.setId(null);
}
});
@ -597,7 +600,7 @@ View.Outfits = function (wardrobe) {
stars.live('click', function () {
var el = $(this);
el.closest('li').startLoading();
wardrobe.user.toggleOutfitStar(el.tmplItem().data);
wardrobe.outfits.toggleOutfitStar(el.tmplItem().data);
});
function pathToUrl(path) {
@ -631,14 +634,14 @@ View.Outfits = function (wardrobe) {
}
function updateActiveOutfit() {
setActiveOutfit(wardrobe.outfit.getOutfit());
setActiveOutfit(wardrobe.outfits.getOutfit());
}
wardrobe.outfit.bind('setOutfit', setActiveOutfit);
wardrobe.outfit.bind('outfitNotFound', setActiveOutfit);
wardrobe.outfits.bind('setOutfit', setActiveOutfit);
wardrobe.outfits.bind('outfitNotFound', setActiveOutfit);
wardrobe.user.bind('outfitRenamed', function (outfit) {
if(outfit.id == wardrobe.outfit.getId()) {
wardrobe.outfits.bind('outfitRenamed', function (outfit) {
if(outfit.id == wardrobe.outfits.getId()) {
save_current_outfit_name_el.text(outfit.name);
}
});
@ -654,6 +657,7 @@ View.Outfits = function (wardrobe) {
small_image: $('#preview-sharing-small-image-url'),
};
var format_selector_els = $('#preview-sharing-url-formats li');
var thumbnail_el = $('#preview-sharing-thumbnail');
var formats = {
plain: {
@ -691,13 +695,51 @@ View.Outfits = function (wardrobe) {
formatUrls();
});
var image_subscription = null;
function unsubscribeFromImage() {
if(image_subscription !== null) {
wardrobe.image_subscriptions.unsubscribe(image_subscription);
image_subscription = null;
}
}
function subscribeToImage(outfit) {
image_subscription = wardrobe.image_subscriptions.subscribe(outfit);
}
function subscribeToImageIfVisible() {
if(current_shared_outfit && sidebar_el.hasClass('sharing')) {
subscribeToImage(current_shared_outfit);
}
}
var current_shared_outfit = {id: null};
this.setOutfit = function (outfit) {
urls.permalink = generateOutfitPermalink(outfit);
urls.small_image = pathToUrl(outfit.image_versions.small);
urls.medium_image = pathToUrl(outfit.image_versions.medium);
urls.large_image = pathToUrl(outfit.image_versions.large);
thumbnail.setUrl(urls.small_image);
formatUrls();
// If outfit has no ID but we're already on the Sharing tab (e.g. user is
// on Sharing but goes back in history to a no-ID outfit), we can't
// exactly do anything with it but submit it for sharing.
if(!outfit.id) {
sharing.startLoading();
wardrobe.outfits.share(outfit);
return false;
}
// But if the outfit does have a valid ID, we're good to go. If it's the
// same as the currently shared outfit ID, then don't even change
// anything. If it's new, then change everything.
if(outfit.id != current_shared_outfit.id) {
// The current shared outfit needs to be a clone, or else modifications
// to the active outfit will show up here, too, and then our comparison
// to discover if this is a new outfit ID or not fails.
current_shared_outfit = outfit.clone();
urls.permalink = generateOutfitPermalink(outfit);
urls.small_image = pathToUrl(outfit.image_versions.small);
urls.medium_image = pathToUrl(outfit.image_versions.medium);
urls.large_image = pathToUrl(outfit.image_versions.large);
formatUrls();
WRAPPER.removeClass('thumbnail-available');
subscribeToImageIfVisible();
}
WRAPPER.addClass('urls-loaded');
}
@ -705,6 +747,14 @@ View.Outfits = function (wardrobe) {
WRAPPER.removeClass('urls-loaded');
}
this.onHide = function () {
unsubscribeFromImage();
}
this.onShow = function () {
subscribeToImageIfVisible();
}
function formatUrls() {
formatImageUrl('small_image');
formatImageUrl('medium_image');
@ -724,68 +774,44 @@ View.Outfits = function (wardrobe) {
sharing_url_els[key].val(url);
}
var thumbnail = new function SharingThumbnail() {
var IMAGE = $('#preview-sharing-thumbnail');
var RETRY_DELAY = 2000; // 2 seconds
var url = null;
var xhr = null;
wardrobe.image_subscriptions.bind('imageEnqueued', function (outfit) {
log("Sharing thumbnail enqueued for outfit", outfit);
function abort() {
if(xhr && xhr.readystate != 4) {
log("Aborting sharing thumbnail XHR");
xhr.abort();
}
}
WRAPPER.removeClass('thumbnail-loaded');
});
function hide() {
WRAPPER.removeClass('thumbnail-loaded');
}
wardrobe.image_subscriptions.bind('imageReady', function (outfit) {
log("Sharing thumbnail ready for outfit", outfit);
function load() {
log("Loading sharing thumbnail", url);
xhr = $.ajax({
type: 'HEAD',
cache: false, // in case some browser tries to cache a 404
url: url,
success: show,
error: retry
});
}
var src = outfit.image_versions.small + '?' + outfit.image_layers_hash;
thumbnail_el.attr('src', src);
WRAPPER.addClass('thumbnail-loaded');
WRAPPER.addClass('thumbnail-available');
image_subscription = null;
});
function retry() {
log("Sharing thumbnail not found, retry in", RETRY_DELAY);
setTimeout(load, RETRY_DELAY);
wardrobe.outfits.bind('updateSuccess', function (outfit) {
if(sidebar_el.hasClass('sharing')) {
subscribeToImage(outfit);
}
});
function show() {
log("Sharing thumbnail found");
IMAGE.attr('src', url);
WRAPPER.addClass('thumbnail-loaded');
}
this.setUrl = function (newUrl) {
if(newUrl != url) {
abort();
hide();
url = newUrl;
load();
} else {
log("Sharing thumbnail URLs are identical; no change.");
}
}
}
wardrobe.outfits.bind('setOutfit', function (outfit) {
log("Sharing sees the setOutfit signal, and will set", outfit);
sharing.setOutfit(outfit);
});
}
/* Saving */
save_current_outfit_el.click(function () {
wardrobe.outfit.update();
wardrobe.outfits.update();
});
new_outfit_form_el.submit(function (e) {
e.preventDefault();
new_outfit_form_el.startLoading();
wardrobe.outfit.create({starred: new_outfit_form_el.hasClass('starred'), name: new_outfit_name_el.val()});
wardrobe.outfits.create({starred: new_outfit_form_el.hasClass('starred'), name: new_outfit_name_el.val()});
});
new_outfit_form_el.find('div.outfit-star').click(function () {
@ -803,37 +829,31 @@ View.Outfits = function (wardrobe) {
save_error_el.text(text).notify();
}
wardrobe.outfit.bind('saveSuccess', function (outfit) {
wardrobe.outfits.bind('saveSuccess', function (outfit) {
save_success_el.notify();
sharing.setOutfit(outfit);
});
wardrobe.outfit.bind('createSuccess', function (outfit) {
wardrobe.user.addOutfit(outfit);
wardrobe.outfits.bind('createSuccess', function (outfit) {
showOutfits();
hideNewOutfitForm();
});
wardrobe.outfit.bind('updateSuccess', function (outfit) {
wardrobe.user.updateOutfit(outfit);
});
function shareComplete(outfit) {
save_outfit_wrapper_el.stopLoading().addClass('shared-outfit');
sharing.setOutfit(outfit);
showSharing();
}
wardrobe.outfit.bind('shareSuccess', shareComplete);
wardrobe.outfit.bind('shareSkipped', shareComplete);
wardrobe.outfits.bind('shareSuccess', shareComplete);
wardrobe.outfits.bind('shareSkipped', shareComplete);
function clearSharedOutfit() {
save_outfit_wrapper_el.removeClass('shared-outfit');
}
wardrobe.outfit.bind('updateClosetItems', clearSharedOutfit);
wardrobe.outfit.bind('updateWornItems', clearSharedOutfit);
wardrobe.outfit.bind('updatePetState', clearSharedOutfit);
wardrobe.outfits.bind('updateClosetItems', clearSharedOutfit);
wardrobe.outfits.bind('updateWornItems', clearSharedOutfit);
wardrobe.outfits.bind('updatePetState', clearSharedOutfit);
function saveFailure(outfit, response) {
var errors = response.errors;
@ -856,16 +876,16 @@ View.Outfits = function (wardrobe) {
liForOutfit(outfit).stopLoading();
}
wardrobe.outfit.bind('saveFailure', saveFailure);
wardrobe.user.bind('saveFailure', saveFailure)
wardrobe.outfit.bind('shareFailure', function (outfit, response) {
wardrobe.outfits.bind('saveFailure', saveFailure);
wardrobe.outfits.bind('saveFailure', saveFailure)
wardrobe.outfits.bind('shareFailure', function (outfit, response) {
save_outfit_wrapper_el.stopLoading();
saveFailure(outfit, response);
});
/* Error */
wardrobe.outfit.bind('outfitNotFound', function () {
wardrobe.outfits.bind('outfitNotFound', function () {
outfit_not_found_el.notify();
});
}
@ -877,7 +897,7 @@ View.PetStateForm = function (wardrobe) {
button_query = form_query + ' button';
$(button_query).live('click', function (e) {
e.preventDefault();
wardrobe.outfit.setPetStateById(+$(this).data('value'));
wardrobe.outfits.setPetStateById(+$(this).data('value'));
});
function updatePetState(pet_state) {
@ -887,7 +907,7 @@ View.PetStateForm = function (wardrobe) {
}
}
wardrobe.outfit.bind('petTypeLoaded', function (pet_type) {
wardrobe.outfits.bind('petTypeLoaded', function (pet_type) {
var ids = pet_type.pet_state_ids, i, id, li, button, label;
ul.children().remove();
if(ids.length == 1) {
@ -905,18 +925,18 @@ View.PetStateForm = function (wardrobe) {
button.appendTo(li);
li.appendTo(ul);
}
updatePetState(wardrobe.outfit.getPetState());
updatePetState(wardrobe.outfits.getPetState());
}
});
wardrobe.outfit.bind('updatePetState', updatePetState);
wardrobe.outfits.bind('updatePetState', updatePetState);
}
View.PetTypeForm = function (wardrobe) {
var form = $('#pet-type-form'), dropdowns = {}, loaded = false;
form.submit(function (e) {
e.preventDefault();
wardrobe.outfit.setPetTypeByColorAndSpecies(
wardrobe.outfits.setPetTypeByColorAndSpecies(
+dropdowns.color.val(), +dropdowns.species.val()
);
}).children('select').each(function () {
@ -947,12 +967,12 @@ View.PetTypeForm = function (wardrobe) {
});
});
loaded = true;
updatePetType(wardrobe.outfit.getPetType());
updatePetType(wardrobe.outfits.getPetType());
});
wardrobe.outfit.bind('updatePetType', updatePetType);
wardrobe.outfits.bind('updatePetType', updatePetType);
wardrobe.outfit.bind('petTypeNotFound', function () {
wardrobe.outfits.bind('petTypeNotFound', function () {
$('#pet-type-not-found').show('normal').delay(3000).hide('fast');
});
}
@ -1009,7 +1029,7 @@ View.ReportBrokenImage = function (wardrobe) {
var baseURL = link.attr('data-base-url');
function updateLink() {
var assets = wardrobe.outfit.getVisibleAssets();
var assets = wardrobe.outfits.getVisibleAssets();
var url = baseURL + "?";
for(var i = 0; i < assets.length; i++) {
@ -1020,9 +1040,9 @@ View.ReportBrokenImage = function (wardrobe) {
link.attr('href', url);
}
wardrobe.outfit.bind('updateWornItems', updateLink);
wardrobe.outfit.bind('updateItemAssets', updateLink);
wardrobe.outfit.bind('updatePetState', updateLink);
wardrobe.outfits.bind('updateWornItems', updateLink);
wardrobe.outfits.bind('updateItemAssets', updateLink);
wardrobe.outfits.bind('updatePetState', updateLink);
}
View.Search = function (wardrobe) {

View file

@ -7,4 +7,4 @@ var main_wardrobe = new Wardrobe(), View = Wardrobe.getStandardView({
});
main_wardrobe.registerViews(View);
main_wardrobe.initialize();
main_wardrobe.outfit.loadData(INITIAL_OUTFIT_DATA);
main_wardrobe.outfits.loadData(INITIAL_OUTFIT_DATA);

View file

@ -276,18 +276,24 @@ function Wardrobe() {
closet_item_ids = new_ids.unworn.concat(new_ids.worn);
}
if(typeof data != 'undefined') {
this.color_id = data.color_id;
this.id = data.id;
this.name = data.name;
this.pet_state_id = data.pet_state_id;
this.starred = data.starred;
this.species_id = data.species_id;
this.image_versions = data.image_versions;
this.setWornAndUnwornItemIds(data.worn_and_unworn_item_ids);
function loadAttributes(data) {
outfit.color_id = data.color_id;
outfit.id = data.id;
outfit.name = data.name;
outfit.pet_state_id = data.pet_state_id;
outfit.starred = data.starred;
outfit.species_id = data.species_id;
outfit.image_versions = data.image_versions;
outfit.image_enqueued = data.image_enqueued;
outfit.image_layers_hash = data.image_layers_hash;
outfit.setWornAndUnwornItemIds(data.worn_and_unworn_item_ids);
new_record = false;
}
if(typeof data != 'undefined') {
loadAttributes(data);
}
this.closet_items = [];
this.worn_items = [];
@ -378,23 +384,6 @@ 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 (xhr) {
if(typeof failure !== 'undefined') {
failure(outfit, $.parseJSON(xhr.responseText));
}
}
});
}
this.closetItem = function (item, updateClosetItemsCallback) {
if(!hasItemInCloset(item)) {
this.closet_items.push(item);
@ -539,6 +528,9 @@ function Wardrobe() {
new_outfit.id = outfit.id;
new_outfit.name = outfit.name;
new_outfit.starred = outfit.starred;
new_outfit.image_enqueued = outfit.image_enqueued;
new_outfit.image_versions = outfit.image_versions;
new_outfit.image_layers_hash = outfit.image_layers_hash;
return new_outfit;
}
@ -557,6 +549,13 @@ function Wardrobe() {
outfit.setWornAndUnwornItemIds(new_ids);
}
function updateFromSaveResponse(data) {
outfit.id = data.id;
outfit.image_versions = data.image_versions;
outfit.image_enqueued = data.image_enqueued;
outfit.image_layers_hash = data.image_layers_hash;
}
this.destroy = function (success) {
$.ajax({
url: '/outfits/' + outfit.id + '.json',
@ -574,8 +573,7 @@ function Wardrobe() {
dataType: 'json',
success: function (data) {
new_record = false;
outfit.id = data.id;
outfit.image_versions = data.image_versions;
updateFromSaveResponse(data);
Outfit.cache[outfit.id] = outfit;
success(outfit);
},
@ -585,6 +583,32 @@ function Wardrobe() {
});
}
this.reload = function (success) {
Outfit.load(this.id, function (new_outfit) {
loadAttributes(new_outfit);
success(outfit);
});
}
function sendUpdate(outfit_data, success, failure) {
$.ajax({
url: '/outfits/' + outfit.id,
type: 'post',
data: {'_method': 'put', outfit: outfit_data},
dataType: 'json',
success: function (data) {
updateFromSaveResponse(data);
Outfit.cache[outfit.id] = outfit;
success(outfit);
},
error: function (xhr) {
if(typeof failure !== 'undefined') {
failure(outfit, $.parseJSON(xhr.responseText));
}
}
});
}
this.updateAttributes = function (attributes, success, failure) {
var outfit_data = {};
for(var key in attributes) {
@ -602,20 +626,24 @@ function Wardrobe() {
if(typeof Outfit.cache[id] !== 'undefined') {
callback(Outfit.cache[id]);
} else {
$.ajax({
url: '/outfits/' + id + '.json',
success: function (data) {
var outfit = new Outfit(data);
Outfit.cache[id] = outfit;
callback(outfit);
},
error: function () {
callback(null);
}
});
Outfit.load(id, callback);
}
}
Outfit.load = function (id, callback) {
$.ajax({
url: '/outfits/' + id + '.json',
success: function (data) {
var outfit = new Outfit(data);
Outfit.cache[id] = outfit;
callback(outfit);
},
error: function () {
callback(null);
}
});
}
Outfit.loadForCurrentUser = function (success) {
var outfits = [];
$.getJSON('/users/current-user/outfits.json', function (data) {
@ -807,7 +835,12 @@ function Wardrobe() {
Controller.all = {};
Controller.all.Outfit = function OutfitController() {
Controller.all.Outfits = function OutfitsController() {
// TODO: clean up the merge of outfits and user controller. Some is already
// done, but I'm sure there's tons of redundant code still lying around.
/* Current outfit management */
var controller = this, outfit = new Outfit, last_shared_outfit = null;
this.in_transaction = false;
@ -881,6 +914,7 @@ function Wardrobe() {
}
outfit.create(
function (outfit) {
insertOutfit(outfit);
controller.events.trigger('saveSuccess', outfit);
controller.events.trigger('createSuccess', outfit);
controller.events.trigger('setOutfit', outfit);
@ -974,6 +1008,7 @@ function Wardrobe() {
this.update = function () {
outfit.update(
function (outfit) {
updateUserOutfit(outfit);
controller.events.trigger('saveSuccess', outfit),
controller.events.trigger('updateSuccess', outfit)
},
@ -989,6 +1024,139 @@ function Wardrobe() {
controller.event('updateItemAssets')
);
}
/* User outfits management */
var outfits = [], outfits_loaded = false;
function compareOutfits(a, b) {
if(a.starred) {
if(!b.starred) return -1;
} else if(b.starred) {
return 1;
}
if(a.name < b.name) return -1;
else if(a.name == b.name) return 0;
else return 1;
}
function insertOutfit(outfit) {
for(var i = 0; i < outfits.length; i++) {
if(compareOutfits(outfit, outfits[i]) < 0) {
outfits.splice(i, 0, outfit);
controller.events.trigger('addOutfit', outfit, i);
return;
}
}
controller.events.trigger('addOutfit', outfit, outfits.length);
outfits.push(outfit);
}
function sortOutfits(outfits) {
outfits.sort(compareOutfits);
}
function yankOutfit(outfit) {
var i;
for(i = 0; i < outfits.length; i++) {
if(outfit.id == outfits[i].id) {
outfits.splice(i, 1);
break;
}
}
controller.events.trigger('removeOutfit', outfit, i);
}
this.destroyOutfit = function (outfit) {
outfit.destroy(function () {
yankOutfit(outfit);
});
}
this.loadOutfits = function () {
if(!outfits_loaded) {
Outfit.loadForCurrentUser(function (new_outfits) {
outfits = new_outfits;
outfits_loaded = true;
sortOutfits(outfits);
controller.events.trigger('outfitsLoaded', outfits);
});
}
}
this.renameOutfit = function (outfit, new_name) {
var old_name = outfit.name;
outfit.rename(new_name, function () {
yankOutfit(outfit);
insertOutfit(outfit);
controller.events.trigger('outfitRenamed', outfit);
}, function (outfit_copy, response) {
outfit.name = old_name;
controller.events.trigger('saveFailure', outfit_copy, response);
});
}
this.toggleOutfitStar = function (outfit) {
outfit.toggleStar(function () {
yankOutfit(outfit);
insertOutfit(outfit);
controller.events.trigger('outfitStarToggled', outfit);
});
}
function updateUserOutfit(outfit) {
for(var i = 0; i < outfits.length; i++) {
if(outfits[i].id == outfit.id) {
outfits[i] = outfit.clone();
break;
}
}
}
}
Controller.all.ImageSubscriptions = function ImagesSubscriptionsController() {
var outfitSubscriptionTotals = {};
var DELAY = 5000;
var controller = this;
function checkSubscription(outfit) {
outfit.reload(function () {
if(outfitSubscriptionTotals[outfit.id] > 0) {
if(outfit.image_enqueued) {
log("Outfit image still enqueued; will try again soon", outfit);
setTimeout(function () { checkSubscription(outfit) }, DELAY);
} else {
controller.unsubscribe(outfit);
controller.events.trigger('imageReady', outfit);
}
} else {
log("Outfit was unsubscribed", outfit);
delete outfitSubscriptionTotals[outfit.id];
}
});
}
this.subscribe = function (outfit) {
if(!(outfit.id in outfitSubscriptionTotals)) {
outfitSubscriptionTotals[outfit.id] = 0;
}
outfitSubscriptionTotals[outfit.id] += 1;
if(outfit.image_enqueued) {
// If the image is enqueued, trigger that event and start checking.
controller.events.trigger('imageEnqueued', outfit);
checkSubscription(outfit);
return outfit;
} else {
// Otherwise, never bother checking: skip straight to the ready phase.
controller.events.trigger('imageReady', outfit);
return null;
}
}
this.unsubscribe = function (outfit) {
outfitSubscriptionTotals[outfit.id] -= 1;
}
}
Controller.all.BasePet = function BasePetController() {
@ -1059,96 +1227,6 @@ function Wardrobe() {
}
}
Controller.all.User = function UserController() {
var controller = this, outfits = [], outfits_loaded = false;
function compareOutfits(a, b) {
if(a.starred) {
if(!b.starred) return -1;
} else if(b.starred) {
return 1;
}
if(a.name < b.name) return -1;
else if(a.name == b.name) return 0;
else return 1;
}
function insertOutfit(outfit) {
for(var i = 0; i < outfits.length; i++) {
if(compareOutfits(outfit, outfits[i]) < 0) {
outfits.splice(i, 0, outfit);
controller.events.trigger('addOutfit', outfit, i);
return;
}
}
controller.events.trigger('addOutfit', outfit, outfits.length);
outfits.push(outfit);
}
function sortOutfits(outfits) {
outfits.sort(compareOutfits);
}
function yankOutfit(outfit) {
var i;
for(i = 0; i < outfits.length; i++) {
if(outfit.id == outfits[i].id) {
outfits.splice(i, 1);
break;
}
}
controller.events.trigger('removeOutfit', outfit, i);
}
this.addOutfit = insertOutfit;
this.destroyOutfit = function (outfit) {
outfit.destroy(function () {
yankOutfit(outfit);
});
}
this.loadOutfits = function () {
if(!outfits_loaded) {
Outfit.loadForCurrentUser(function (new_outfits) {
outfits = new_outfits;
outfits_loaded = true;
sortOutfits(outfits);
controller.events.trigger('outfitsLoaded', outfits);
});
}
}
this.renameOutfit = function (outfit, new_name) {
var old_name = outfit.name;
outfit.rename(new_name, function () {
yankOutfit(outfit);
insertOutfit(outfit);
controller.events.trigger('outfitRenamed', outfit);
}, function (outfit_copy, response) {
outfit.name = old_name;
controller.events.trigger('saveFailure', outfit_copy, response);
});
}
this.toggleOutfitStar = function (outfit) {
outfit.toggleStar(function () {
yankOutfit(outfit);
insertOutfit(outfit);
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;
for(var name in Controller.all) {
@ -1227,13 +1305,13 @@ Wardrobe.getStandardView = function (options) {
var outfit_events = ['updateWornItems', 'updateClosetItems', 'updateItemAssets', 'updatePetType', 'updatePetState'];
for(var i = 0; i < outfit_events.length; i++) {
(function (event) {
wardrobe.outfit.bind(event, function (obj) {
wardrobe.outfits.bind(event, function (obj) {
log(event, obj);
});
})(outfit_events[i]);
}
wardrobe.outfit.bind('petTypeNotFound', function (pet_type) {
wardrobe.outfits.bind('petTypeNotFound', function (pet_type) {
log(pet_type.toString() + ' not found');
});
}
@ -1277,7 +1355,7 @@ Wardrobe.getStandardView = function (options) {
var assets, assets_for_swf;
if(update_pending_flash) return false;
if(preview_swf && preview_swf.setAssets) {
assets = wardrobe.outfit.getVisibleAssets();
assets = wardrobe.outfits.getVisibleAssets();
preview_swf.setAssets(assets);
} else {
update_pending_flash = true;
@ -1334,7 +1412,7 @@ Wardrobe.getStandardView = function (options) {
// Get a copy of the visible assets, then sort them in ascending zone
// order.
var assets = wardrobe.outfit.getVisibleAssets().slice(0);
var assets = wardrobe.outfits.getVisibleAssets().slice(0);
assets.sort(function (a, b) {
return a.depth - b.depth;
});
@ -1348,7 +1426,7 @@ Wardrobe.getStandardView = function (options) {
}
this.updateAssets = function () {
var assets = wardrobe.outfit.getVisibleAssets(), asset,
var assets = wardrobe.outfits.getVisibleAssets(), asset,
availableAssets = [];
pendingAssets = {};
pendingAssetsCount = 0;
@ -1507,9 +1585,9 @@ Wardrobe.getStandardView = function (options) {
preview.adapter.updateAssets();
}
wardrobe.outfit.bind('updateWornItems', updateAssets);
wardrobe.outfit.bind('updateItemAssets', updateAssets);
wardrobe.outfit.bind('updatePetState', updateAssets);
wardrobe.outfits.bind('updateWornItems', updateAssets);
wardrobe.outfits.bind('updateItemAssets', updateAssets);
wardrobe.outfits.bind('updatePetState', updateAssets);
function useAdapter(name) {
preview.adapter = new Adapter[name]();

View file

@ -3085,15 +3085,18 @@ body.outfits-edit #preview-sharing #preview-sharing-thumbnail-wrapper {
display: block;
height: 150px;
margin: 1em auto 0;
position: relative;
width: 150px;
}
/* line 578, ../../../app/stylesheets/outfits/_edit.sass */
/* line 579, ../../../app/stylesheets/outfits/_edit.sass */
body.outfits-edit #preview-sharing #preview-sharing-thumbnail-loading {
height: 100%;
position: relative;
left: 0;
position: absolute;
top: 0;
width: 100%;
}
/* line 583, ../../../app/stylesheets/outfits/_edit.sass */
/* line 586, ../../../app/stylesheets/outfits/_edit.sass */
body.outfits-edit #preview-sharing #preview-sharing-thumbnail-loading span {
color: #448844;
font-size: 85%;
@ -3103,52 +3106,63 @@ body.outfits-edit #preview-sharing #preview-sharing-thumbnail-loading span {
top: 50%;
width: 100%;
}
/* line 592, ../../../app/stylesheets/outfits/_edit.sass */
/* line 595, ../../../app/stylesheets/outfits/_edit.sass */
body.outfits-edit #preview-sharing #preview-sharing-thumbnail, body.outfits-edit #preview-sharing #preview-sharing-thumbnail-generating {
display: none;
}
/* line 596, ../../../app/stylesheets/outfits/_edit.sass */
/* line 599, ../../../app/stylesheets/outfits/_edit.sass */
body.outfits-edit #preview-sharing.urls-loaded #preview-sharing-thumbnail-saving {
display: none;
}
/* line 599, ../../../app/stylesheets/outfits/_edit.sass */
/* line 602, ../../../app/stylesheets/outfits/_edit.sass */
body.outfits-edit #preview-sharing.urls-loaded #preview-sharing-urls, body.outfits-edit #preview-sharing.urls-loaded #preview-sharing-url-formats, body.outfits-edit #preview-sharing.urls-loaded #preview-sharing-thumbnail-generating {
display: block;
}
/* line 603, ../../../app/stylesheets/outfits/_edit.sass */
/* line 606, ../../../app/stylesheets/outfits/_edit.sass */
body.outfits-edit #preview-sharing.urls-loaded.thumbnail-loaded #preview-sharing-thumbnail-loading {
display: none;
}
/* line 606, ../../../app/stylesheets/outfits/_edit.sass */
/* line 609, ../../../app/stylesheets/outfits/_edit.sass */
body.outfits-edit #preview-sharing.urls-loaded.thumbnail-loaded #preview-sharing-thumbnail {
display: block;
}
/* line 609, ../../../app/stylesheets/outfits/_edit.sass */
/* line 613, ../../../app/stylesheets/outfits/_edit.sass */
body.outfits-edit #preview-sharing.urls-loaded.thumbnail-available #preview-sharing-thumbnail-loading {
-moz-opacity: 0.85;
-webkit-opacity: 0.85;
-o-opacity: 0.85;
-khtml-opacity: 0.85;
}
/* line 616, ../../../app/stylesheets/outfits/_edit.sass */
body.outfits-edit #preview-sharing.urls-loaded.thumbnail-available #preview-sharing-thumbnail {
display: block;
}
/* line 619, ../../../app/stylesheets/outfits/_edit.sass */
body.outfits-edit .preview-sidebar-nav {
float: right;
font-size: 85%;
margin-right: 24px;
margin-top: 1em;
}
/* line 621, ../../../app/stylesheets/outfits/_edit.sass */
/* line 631, ../../../app/stylesheets/outfits/_edit.sass */
body.outfits-edit #preview-sidebar #preview-sidebar-navbar-closet {
background: white;
border-bottom-color: white;
font-weight: bold;
}
/* line 625, ../../../app/stylesheets/outfits/_edit.sass */
/* line 635, ../../../app/stylesheets/outfits/_edit.sass */
body.outfits-edit #preview-sidebar.viewing-outfits #preview-sidebar-navbar-closet, body.outfits-edit #preview-sidebar.sharing #preview-sidebar-navbar-closet {
background: transparent;
border-bottom: 1px solid #aaddaa;
font-weight: normal;
}
/* line 628, ../../../app/stylesheets/outfits/_edit.sass */
/* line 638, ../../../app/stylesheets/outfits/_edit.sass */
body.outfits-edit #preview-sidebar.viewing-outfits #preview-sidebar-navbar-outfits, body.outfits-edit #preview-sidebar.sharing #preview-sidebar-navbar-sharing {
background: white;
border-bottom-color: white;
font-weight: bold;
}
/* line 631, ../../../app/stylesheets/outfits/_edit.sass */
/* line 641, ../../../app/stylesheets/outfits/_edit.sass */
body.outfits-edit #preview-sidebar-navbar {
-moz-border-radius: 10px 10px 0 0;
-webkit-border-radius: 10px 10px 0 0;
@ -3168,7 +3182,7 @@ body.outfits-edit #preview-sidebar-navbar {
body.outfits-edit #preview-sidebar-navbar {
display: block;
}
/* line 640, ../../../app/stylesheets/outfits/_edit.sass */
/* line 650, ../../../app/stylesheets/outfits/_edit.sass */
body.outfits-edit #preview-sidebar-navbar > div {
background: transparent;
border-bottom: 1px solid #aaddaa;
@ -3180,11 +3194,11 @@ body.outfits-edit #preview-sidebar-navbar > div {
text-align: center;
width: 132px;
}
/* line 649, ../../../app/stylesheets/outfits/_edit.sass */
/* line 659, ../../../app/stylesheets/outfits/_edit.sass */
body.outfits-edit #preview-sidebar-navbar > div:first-child {
border-left: 0;
}
/* line 652, ../../../app/stylesheets/outfits/_edit.sass */
/* line 662, ../../../app/stylesheets/outfits/_edit.sass */
body.outfits-edit #preview-sidebar-content {
-moz-border-radius: 0 0 10px 10px;
-webkit-border-radius: 0 0 10px 10px;
@ -3196,7 +3210,7 @@ body.outfits-edit #preview-sidebar-content {
border-top: 0;
overflow: auto;
}
/* line 658, ../../../app/stylesheets/outfits/_edit.sass */
/* line 668, ../../../app/stylesheets/outfits/_edit.sass */
body.outfits-edit #save-success, body.outfits-edit #save-error, body.outfits-edit #outfit-not-found, body.outfits-edit #preview-sidebar-donation-request {
margin-left: 24px;
margin-right: 24px;
@ -3204,7 +3218,7 @@ body.outfits-edit #save-success, body.outfits-edit #save-error, body.outfits-edi
margin-top: 1em;
text-align: center;
}
/* line 665, ../../../app/stylesheets/outfits/_edit.sass */
/* line 675, ../../../app/stylesheets/outfits/_edit.sass */
body.outfits-edit #preview-sidebar-donation-request {
background: #e6efc2;
border: 1px solid #c6d880;
@ -3212,23 +3226,23 @@ body.outfits-edit #preview-sidebar-donation-request {
font-size: 85%;
padding: 1em;
}
/* line 670, ../../../app/stylesheets/outfits/_edit.sass */
/* line 680, ../../../app/stylesheets/outfits/_edit.sass */
body.outfits-edit #preview-sidebar-donation-request-no-thanks {
margin-left: 1em;
}
/* line 673, ../../../app/stylesheets/outfits/_edit.sass */
/* line 683, ../../../app/stylesheets/outfits/_edit.sass */
body.outfits-edit #save-success {
background: #e6efc2;
border: 1px solid #c6d880;
color: #264409;
}
/* line 676, ../../../app/stylesheets/outfits/_edit.sass */
/* line 686, ../../../app/stylesheets/outfits/_edit.sass */
body.outfits-edit #save-error, body.outfits-edit #outfit-not-found {
background: #fbe3e4;
border: 1px solid #fbc2c4;
color: #8a1f11;
}
/* line 679, ../../../app/stylesheets/outfits/_edit.sass */
/* line 689, ../../../app/stylesheets/outfits/_edit.sass */
body.outfits-edit #userbar-message {
-moz-opacity: 0.5;
-webkit-opacity: 0.5;
@ -3236,7 +3250,7 @@ body.outfits-edit #userbar-message {
-khtml-opacity: 0.5;
display: none;
}
/* line 683, ../../../app/stylesheets/outfits/_edit.sass */
/* line 693, ../../../app/stylesheets/outfits/_edit.sass */
body.outfits-edit #new-outfit {
padding: 0.25em 0;
margin-left: 24px;
@ -3422,28 +3436,28 @@ body.outfits-edit #new-outfit.renaming:hover .outfit-rename-button {
body.outfits-edit #new-outfit:hover .outfit-rename-button {
display: inline;
}
/* line 687, ../../../app/stylesheets/outfits/_edit.sass */
/* line 697, ../../../app/stylesheets/outfits/_edit.sass */
body.outfits-edit #new-outfit h4 {
display: inline;
}
/* line 689, ../../../app/stylesheets/outfits/_edit.sass */
/* line 699, ../../../app/stylesheets/outfits/_edit.sass */
body.outfits-edit #new-outfit h4:hover {
text-decoration: none;
}
/* line 691, ../../../app/stylesheets/outfits/_edit.sass */
/* line 701, ../../../app/stylesheets/outfits/_edit.sass */
body.outfits-edit #new-outfit .outfit-star {
margin-top: 0.5em;
}
/* line 694, ../../../app/stylesheets/outfits/_edit.sass */
/* line 704, ../../../app/stylesheets/outfits/_edit.sass */
body.outfits-edit #new-outfit-name {
font: inherit;
line-height: 1;
}
/* line 698, ../../../app/stylesheets/outfits/_edit.sass */
/* line 708, ../../../app/stylesheets/outfits/_edit.sass */
body.outfits-edit #pet-type-form, body.outfits-edit #pet-state-form, body.outfits-edit #preview-swf, body.outfits-edit #preview-search-form {
position: relative;
}
/* line 701, ../../../app/stylesheets/outfits/_edit.sass */
/* line 711, ../../../app/stylesheets/outfits/_edit.sass */
body.outfits-edit .control-overlay {
height: 100%;
left: 0;
@ -3452,11 +3466,11 @@ body.outfits-edit .control-overlay {
width: 100%;
z-index: 5;
}
/* line 709, ../../../app/stylesheets/outfits/_edit.sass */
/* line 719, ../../../app/stylesheets/outfits/_edit.sass */
body.outfits-edit #preview-sidebar-nav-outfits, body.outfits-edit #save-outfit-signed-in {
display: none;
}
/* line 712, ../../../app/stylesheets/outfits/_edit.sass */
/* line 722, ../../../app/stylesheets/outfits/_edit.sass */
body.outfits-edit form#save-outfit-form {
padding: 0.25em 0;
display: none;
@ -3642,7 +3656,7 @@ body.outfits-edit form#save-outfit-form.renaming:hover .outfit-rename-button {
body.outfits-edit form#save-outfit-form:hover .outfit-rename-button {
display: inline;
}
/* line 718, ../../../app/stylesheets/outfits/_edit.sass */
/* line 728, ../../../app/stylesheets/outfits/_edit.sass */
body.outfits-edit form#save-outfit-form .outfit-star, body.outfits-edit form#save-outfit-form input, body.outfits-edit form#save-outfit-form button {
display: -moz-inline-box;
-moz-box-orient: vertical;
@ -3656,46 +3670,46 @@ body.outfits-edit form#save-outfit-form .outfit-star, body.outfits-edit form#sav
body.outfits-edit form#save-outfit-form .outfit-star, body.outfits-edit form#save-outfit-form input, body.outfits-edit form#save-outfit-form button {
*display: inline;
}
/* line 723, ../../../app/stylesheets/outfits/_edit.sass */
/* line 733, ../../../app/stylesheets/outfits/_edit.sass */
body.outfits-edit form#save-outfit-form .outfit-star {
margin-top: 0.25em;
}
/* line 726, ../../../app/stylesheets/outfits/_edit.sass */
/* line 736, ../../../app/stylesheets/outfits/_edit.sass */
body.outfits-edit .outfit-url {
font-size: 75%;
}
/* line 729, ../../../app/stylesheets/outfits/_edit.sass */
/* line 739, ../../../app/stylesheets/outfits/_edit.sass */
body.outfits-edit #preview-search-form-error {
background: #fbe3e4;
border: 1px solid #fbc2c4;
color: #8a1f11;
padding: 0.25em 0.5em;
}
/* line 734, ../../../app/stylesheets/outfits/_edit.sass */
/* line 744, ../../../app/stylesheets/outfits/_edit.sass */
body.outfits-edit.user-signed-in #preview-sidebar-nav-outfits {
display: block;
}
/* line 736, ../../../app/stylesheets/outfits/_edit.sass */
/* line 746, ../../../app/stylesheets/outfits/_edit.sass */
body.outfits-edit.user-signed-in #save-outfit {
display: inline-block;
}
/* line 740, ../../../app/stylesheets/outfits/_edit.sass */
/* line 750, ../../../app/stylesheets/outfits/_edit.sass */
body.outfits-edit.user-signed-in #save-outfit-wrapper.active-outfit #save-outfit {
display: none;
}
/* line 742, ../../../app/stylesheets/outfits/_edit.sass */
/* line 752, ../../../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 750, ../../../app/stylesheets/outfits/_edit.sass */
/* line 760, ../../../app/stylesheets/outfits/_edit.sass */
body.outfits-edit.user-signed-in #save-outfit-wrapper.saving-outfit #save-outfit-form {
display: block;
}
/* line 752, ../../../app/stylesheets/outfits/_edit.sass */
/* line 762, ../../../app/stylesheets/outfits/_edit.sass */
body.outfits-edit.user-signed-in #save-outfit-wrapper.saving-outfit #save-outfit, body.outfits-edit.user-signed-in #save-outfit-wrapper.saving-outfit #save-current-outfit, body.outfits-edit.user-signed-in #save-outfit-wrapper.saving-outfit #save-outfit-copy, body.outfits-edit.user-signed-in #save-outfit-wrapper.saving-outfit #current-outfit-permalink, body.outfits-edit.user-signed-in #save-outfit-wrapper.saving-outfit #shared-outfit-permalink, body.outfits-edit.user-signed-in #save-outfit-wrapper.saving-outfit #share-outfit, body.outfits-edit.user-signed-in #save-outfit-wrapper.saving-outfit #shared-outfit-url {
display: none;
}
/* line 754, ../../../app/stylesheets/outfits/_edit.sass */
/* line 764, ../../../app/stylesheets/outfits/_edit.sass */
body.outfits-edit.user-signed-in .preview-search-form-your-items {
display: -moz-inline-box;
-moz-box-orient: vertical;
@ -3707,23 +3721,23 @@ body.outfits-edit.user-signed-in .preview-search-form-your-items {
body.outfits-edit.user-signed-in .preview-search-form-your-items {
*display: inline;
}
/* line 756, ../../../app/stylesheets/outfits/_edit.sass */
/* line 766, ../../../app/stylesheets/outfits/_edit.sass */
body.outfits-edit.user-signed-in #preview-outfits-not-logged-in {
display: none;
}
/* line 758, ../../../app/stylesheets/outfits/_edit.sass */
/* line 768, ../../../app/stylesheets/outfits/_edit.sass */
body.outfits-edit.user-signed-in #preview-outfits-list {
display: block;
}
/* line 762, ../../../app/stylesheets/outfits/_edit.sass */
/* line 772, ../../../app/stylesheets/outfits/_edit.sass */
body.outfits-edit.user-not-signed-in #save-outfit-not-signed-in {
display: inline-block;
}
/* line 766, ../../../app/stylesheets/outfits/_edit.sass */
/* line 776, ../../../app/stylesheets/outfits/_edit.sass */
body.outfits-edit #save-outfit-wrapper.shared-outfit #shared-outfit-permalink, body.outfits-edit #save-outfit-wrapper.shared-outfit #shared-outfit-url {
display: inline-block;
}
/* line 768, ../../../app/stylesheets/outfits/_edit.sass */
/* line 778, ../../../app/stylesheets/outfits/_edit.sass */
body.outfits-edit #save-outfit-wrapper.shared-outfit #current-outfit-permalink {
display: none !important;
}