gracefully handles asset not found, preloads to handle it before it even comes up

This commit is contained in:
Emi Matchu 2010-05-31 15:45:03 -04:00
parent 6cdde0b2ed
commit 40bb495a2b
6 changed files with 180 additions and 42 deletions

View file

@ -1,6 +1,7 @@
class PetTypesController < ApplicationController class PetTypesController < ApplicationController
def show def show
pet_type = PetType.find_by_color_id_and_species_id(params[:color_id], params[:species_id]) 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 render :json => pet_type
end end
end end

View file

@ -11,7 +11,14 @@ module ItemsHelper
src = sprintf(StandardSpeciesImageFormat, pet_type.image_hash) src = sprintf(StandardSpeciesImageFormat, pet_type.image_hash)
human_name = species.name.humanize human_name = species.name.humanize
image = image_tag(src, :alt => human_name, :title => human_name) image = image_tag(src, :alt => human_name, :title => human_name)
html + link_to(image, '#', 'data-color-id' => color.id, 'data-species-id' => species.id, 'data-species-name' => species.name) html + link_to(
image,
'#',
'data-color-id' => color.id,
'data-color-name' => color.name,
'data-species-id' => species.id,
'data-species-name' => species.name
)
end) end)
end end
end end

View file

@ -22,8 +22,11 @@ body.show {
#item-preview { #item-preview {
div { div {
float: left; float: left;
width: 50%;
} }
}
#item-preview-species {
width: 400px;
a, img { a, img {
height: 50px; height: 50px;
@ -32,13 +35,30 @@ body.show {
a { a {
@include inline-block; @include inline-block;
&.current { &.current {
background: $module_background_color; background: $module_background_color;
outline: 1px solid $module_border_color; outline: 1px solid $module_border_color;
} }
&.deactivated {
@include opacity(.5);
background: $error_bg_color;
//background: #fff;
//background: rgba(255, 255, 255, .5);
&.current {
outline-color: $error_border_color;
}
}
} }
} }
#item-preview-error {
display: none;
padding: 20px 10px 0;
width: 380px;
}
#item-preview-swf { #item-preview-swf {
height: 300px; height: 300px;
overflow: hidden; overflow: hidden;

View file

@ -8,6 +8,7 @@
#item-preview #item-preview
#item-preview-species= standard_species_images(@item.supported_species) #item-preview-species= standard_species_images(@item.supported_species)
#item-preview-error
#item-preview-swf{'data-impress-host' => RemoteImpressHost} #item-preview-swf{'data-impress-host' => RemoteImpressHost}
Javascript and Flash are required to preview wearables. Sorry! Javascript and Flash are required to preview wearables. Sorry!

View file

@ -10,50 +10,119 @@ if(console === undefined || console.log === undefined) {
log = $.proxy(console, 'log'); log = $.proxy(console, 'log');
} }
String.prototype.capitalize = function () {
return this.charAt(0).toUpperCase() + this.substr(1);
}
String.prototype.article = function () {
return 'aeiou'.indexOf(this.charAt(0).toLowerCase()) == -1 ? 'a' : 'an'
}
function impressUrl(path) { function impressUrl(path) {
return 'http://' + IMPRESS_HOST + path; return 'http://' + IMPRESS_HOST + path;
} }
function PetType() {} function LoadError(base_msg) {
this.render = function (args) {
var msg = base_msg, token, article_token;
for(var i in args) {
token = "$" + i;
article_token = token + "_article";
if(msg.indexOf(article_token) != -1) {
msg = msg.replace(article_token, args[i].article());
}
msg = msg.replace(token, args[i]);
}
return "Whoops - we've never seen " + msg + " before! If you have, please " +
"<a href='http://" + IMPRESS_HOST + "'>submit that pet's name</a> as soon as you " +
"get the chance! Thanks!";
}
}
PetType.prototype.load = function () { function PetType() {
var url = '/species/' + this.species_id + '/color/' + this.color_id + '/pet_type.json', var pet_type = this;
pet_type = this;
$.getJSON(url, function (data) { this.activated = true;
pet_type.id = data.id;
pet_type.body_id = data.body_id; this.deactivate = function (error, args) {
Item.current.load(); var msg;
$.getJSON('/pet_types/' + data.id + '/swf_assets.json', function (assets) { this.activated = false;
log('pet type assets loaded'); if(typeof args == 'undefined') args = {};
pet_type.assets = assets; args.color = this.color_name.capitalize();
Preview.update(); args.species = this.species_name.capitalize();
this.deactivation_msg = error.render(args);
if(this == PetType.current) showDeactivationMsg();
var img = this.link.children('img').get(0);
this.link.addClass('deactivated');
img.src = img.src.replace('/1/', '/2/');
}
this.load = function () {
var url = '/species/' + this.species_id + '/color/' + this.color_id + '/pet_type.json',
pet_type = this;
$.ajax({
url: url,
dataType: 'json',
success: function (data) {
pet_type.id = data.id;
pet_type.body_id = data.body_id;
Item.current.load(pet_type);
$.getJSON('/pet_types/' + data.id + '/swf_assets.json', function (assets) {
pet_type.assets = assets;
Preview.update();
});
},
error: function () {
pet_type.deactivate(PetType.LOAD_ERROR);
}
}); });
}); }
this.setAsCurrent = function () {
PetType.current = this;
speciesList.filter('.current').removeClass('current');
this.link.addClass('current');
if(this.activated) {
Preview.enable();
this.load();
} else {
showDeactivationMsg();
}
}
function showDeactivationMsg() {
Preview.disable(pet_type.deactivation_msg);
}
} }
PetType.prototype.setAsCurrent = function () { PetType.all = [];
PetType.current = this;
speciesList.filter('.current').removeClass('current'); PetType.LOAD_ERROR = new LoadError("$color_article $color $species");
this.link.addClass('current');
this.load();
}
PetType.createFromLink = function (link) { PetType.createFromLink = function (link) {
var pet_type = new PetType(); var pet_type = new PetType();
pet_type.color_id = link.attr('data-color-id'); pet_type.color_id = link.attr('data-color-id');
pet_type.color_name = link.attr('data-color-name');
pet_type.species_id = link.attr('data-species-id'); pet_type.species_id = link.attr('data-species-id');
pet_type.species_name = link.attr('data-species-name');
pet_type.link = link; pet_type.link = link;
PetType.all.push(pet_type);
return pet_type; return pet_type;
} }
function Item() { function Item() {
this.load = function () { this.load = function (pet_type) {
var url = '/' + this.id + '/swf_assets.json?body_id=' + PetType.current.body_id, var url = '/' + this.id + '/swf_assets.json?body_id=' + pet_type.body_id,
item = this; item = this;
$.getJSON(url, function (data) { $.getJSON(url, function (data) {
log('item assets loaded'); if(data.length) {
item.assets = data; item.assets = data;
Preview.update(); Preview.update();
} else {
pet_type.deactivate(Item.LOAD_ERROR, {
item: item.name
});
}
}) })
} }
@ -62,6 +131,8 @@ function Item() {
} }
} }
Item.LOAD_ERROR = new LoadError("$species_article $species wear a $item");
Item.createFromLocation = function () { Item.createFromLocation = function () {
var item = new Item(); var item = new Item();
item.id = parseInt(document.location.pathname.substr(1)); item.id = parseInt(document.location.pathname.substr(1));
@ -72,25 +143,19 @@ Preview = new function Preview() {
var assets = [], swf_id, swf, updateWhenFlashReady = false; var assets = [], swf_id, swf, updateWhenFlashReady = false;
this.setFlashIsReady = function () { this.setFlashIsReady = function () {
log('flash ready');
swf = document.getElementById(swf_id); swf = document.getElementById(swf_id);
if(updateWhenFlashReady) this.update(); if(updateWhenFlashReady) this.update();
} }
this.update = function (assets) { this.update = function (assets) {
var assets = []; var assets = [];
log('want to update');
if(swf) { if(swf) {
log('got to update');
log(assets);
$.each([PetType, Item], function () { $.each([PetType, Item], function () {
if(this.current.assets) assets = assets.concat(this.current.assets); if(this.current.assets) assets = assets.concat(this.current.assets);
}); });
log(assets);
assets = $.each(assets, function () { assets = $.each(assets, function () {
this.local_path = this.local_url; this.local_path = this.local_url;
}); });
log(assets);
swf.setAssets(assets); swf.setAssets(assets);
} else { } else {
updateWhenFlashReady = true; updateWhenFlashReady = true;
@ -110,6 +175,16 @@ Preview = new function Preview() {
{'wmode': 'transparent', 'allowscriptaccess': 'always'} // params {'wmode': 'transparent', 'allowscriptaccess': 'always'} // params
); );
} }
this.disable = function (msg) {
$('#' + swf_id).hide();
$('#item-preview-error').html(msg).show();
}
this.enable = function () {
$('#item-preview-error').hide();
$('#' + swf_id).show();
}
} }
Preview.embed(PREVIEW_SWF_ID); Preview.embed(PREVIEW_SWF_ID);
@ -117,10 +192,20 @@ Preview.embed(PREVIEW_SWF_ID);
PetType.createFromLink(speciesList.eq(Math.floor(Math.random()*speciesList.length))).setAsCurrent(); PetType.createFromLink(speciesList.eq(Math.floor(Math.random()*speciesList.length))).setAsCurrent();
Item.createFromLocation().setAsCurrent(); Item.createFromLocation().setAsCurrent();
Item.current.name = $('#item-name').text();
speciesList.click(function (e) { speciesList.each(function () {
e.preventDefault(); var pet_type = PetType.createFromLink($(this));
PetType.createFromLink($(this)).setAsCurrent(); $(this).click(function (e) {
e.preventDefault();
pet_type.setAsCurrent();
});
}); });
MainWardrobe = { View: { Outfit: Preview } }; MainWardrobe = { View: { Outfit: Preview } };
setTimeout(function () {
$.each(PetType.all, function () {
this.load();
});
}, 5000);

View file

@ -612,15 +612,18 @@ body.show #item-name {
/* line 23, ../../../app/stylesheets/items/_show.scss */ /* line 23, ../../../app/stylesheets/items/_show.scss */
body.show #item-preview div { body.show #item-preview div {
float: left; float: left;
width: 50%;
} }
/* line 28, ../../../app/stylesheets/items/_show.scss */ /* line 28, ../../../app/stylesheets/items/_show.scss */
body.show #item-preview a, body.show #item-preview img { body.show #item-preview-species {
width: 400px;
}
/* line 31, ../../../app/stylesheets/items/_show.scss */
body.show #item-preview-species a, body.show #item-preview-species img {
height: 50px; height: 50px;
width: 50px; width: 50px;
} }
/* line 33, ../../../app/stylesheets/items/_show.scss */ /* line 36, ../../../app/stylesheets/items/_show.scss */
body.show #item-preview a { body.show #item-preview-species a {
display: -moz-inline-box; display: -moz-inline-box;
-moz-box-orient: vertical; -moz-box-orient: vertical;
display: inline-block; display: inline-block;
@ -628,12 +631,33 @@ body.show #item-preview a {
*display: inline; *display: inline;
*vertical-align: auto; *vertical-align: auto;
} }
/* line 35, ../../../app/stylesheets/items/_show.scss */ /* line 39, ../../../app/stylesheets/items/_show.scss */
body.show #item-preview a.current { body.show #item-preview-species a.current {
background: #66a3d2; background: #66a3d2;
outline: 1px solid #033e6b; outline: 1px solid #033e6b;
} }
/* line 42, ../../../app/stylesheets/items/_show.scss */ /* line 44, ../../../app/stylesheets/items/_show.scss */
body.show #item-preview-species a.deactivated {
-moz-opacity: 0.5;
-webkit-opacity: 0.5;
-o-opacity: 0.5;
-khtml-opacity: 0.5;
opacity: 0.5;
-ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=50);
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=50);
background: #e14f1c;
}
/* line 49, ../../../app/stylesheets/items/_show.scss */
body.show #item-preview-species a.deactivated.current {
outline-color: #cd0a0a;
}
/* line 56, ../../../app/stylesheets/items/_show.scss */
body.show #item-preview-error {
display: none;
padding: 20px 10px 0;
width: 380px;
}
/* line 62, ../../../app/stylesheets/items/_show.scss */
body.show #item-preview-swf { body.show #item-preview-swf {
height: 300px; height: 300px;
overflow: hidden; overflow: hidden;