From 40bb495a2b1f7efd40f197ee21d680ae7e3f55ec Mon Sep 17 00:00:00 2001 From: Matchu Date: Mon, 31 May 2010 15:45:03 -0400 Subject: [PATCH] gracefully handles asset not found, preloads to handle it before it even comes up --- app/controllers/pet_types_controller.rb | 1 + app/helpers/items_helper.rb | 9 +- app/stylesheets/items/_show.scss | 22 +++- app/views/items/show.html.haml | 1 + public/javascripts/items/show.js | 151 ++++++++++++++++++------ public/stylesheets/compiled/screen.css | 38 ++++-- 6 files changed, 180 insertions(+), 42 deletions(-) diff --git a/app/controllers/pet_types_controller.rb b/app/controllers/pet_types_controller.rb index 09574d8e..d56f93d2 100644 --- a/app/controllers/pet_types_controller.rb +++ b/app/controllers/pet_types_controller.rb @@ -1,6 +1,7 @@ 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 end end diff --git a/app/helpers/items_helper.rb b/app/helpers/items_helper.rb index 88d64967..fb1c79f9 100644 --- a/app/helpers/items_helper.rb +++ b/app/helpers/items_helper.rb @@ -11,7 +11,14 @@ module ItemsHelper src = sprintf(StandardSpeciesImageFormat, pet_type.image_hash) human_name = species.name.humanize 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 diff --git a/app/stylesheets/items/_show.scss b/app/stylesheets/items/_show.scss index 6693ca54..0c062cd4 100644 --- a/app/stylesheets/items/_show.scss +++ b/app/stylesheets/items/_show.scss @@ -22,8 +22,11 @@ body.show { #item-preview { div { float: left; - width: 50%; } + } + + #item-preview-species { + width: 400px; a, img { height: 50px; @@ -32,13 +35,30 @@ body.show { a { @include inline-block; + &.current { background: $module_background_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 { height: 300px; overflow: hidden; diff --git a/app/views/items/show.html.haml b/app/views/items/show.html.haml index 801ec782..03e40673 100644 --- a/app/views/items/show.html.haml +++ b/app/views/items/show.html.haml @@ -8,6 +8,7 @@ #item-preview #item-preview-species= standard_species_images(@item.supported_species) + #item-preview-error #item-preview-swf{'data-impress-host' => RemoteImpressHost} Javascript and Flash are required to preview wearables. Sorry! diff --git a/public/javascripts/items/show.js b/public/javascripts/items/show.js index 6f58e6d3..4b1659d0 100644 --- a/public/javascripts/items/show.js +++ b/public/javascripts/items/show.js @@ -10,50 +10,119 @@ if(console === undefined || console.log === undefined) { 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) { 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 " + + "submit that pet's name as soon as you " + + "get the chance! Thanks!"; + } +} -PetType.prototype.load = function () { - var url = '/species/' + this.species_id + '/color/' + this.color_id + '/pet_type.json', - pet_type = this; - $.getJSON(url, function (data) { - pet_type.id = data.id; - pet_type.body_id = data.body_id; - Item.current.load(); - $.getJSON('/pet_types/' + data.id + '/swf_assets.json', function (assets) { - log('pet type assets loaded'); - pet_type.assets = assets; - Preview.update(); +function PetType() { + var pet_type = this; + + this.activated = true; + + this.deactivate = function (error, args) { + var msg; + this.activated = false; + if(typeof args == 'undefined') args = {}; + args.color = this.color_name.capitalize(); + 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.current = this; - speciesList.filter('.current').removeClass('current'); - this.link.addClass('current'); - this.load(); -} +PetType.all = []; + +PetType.LOAD_ERROR = new LoadError("$color_article $color $species"); PetType.createFromLink = function (link) { var pet_type = new PetType(); 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_name = link.attr('data-species-name'); pet_type.link = link; + PetType.all.push(pet_type); return pet_type; } function Item() { - this.load = function () { - var url = '/' + this.id + '/swf_assets.json?body_id=' + PetType.current.body_id, + this.load = function (pet_type) { + var url = '/' + this.id + '/swf_assets.json?body_id=' + pet_type.body_id, item = this; $.getJSON(url, function (data) { - log('item assets loaded'); - item.assets = data; - Preview.update(); + if(data.length) { + item.assets = data; + 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 () { var item = new Item(); item.id = parseInt(document.location.pathname.substr(1)); @@ -72,25 +143,19 @@ Preview = new function Preview() { var assets = [], swf_id, swf, updateWhenFlashReady = false; this.setFlashIsReady = function () { - log('flash ready'); swf = document.getElementById(swf_id); if(updateWhenFlashReady) this.update(); } this.update = function (assets) { var assets = []; - log('want to update'); if(swf) { - log('got to update'); - log(assets); $.each([PetType, Item], function () { if(this.current.assets) assets = assets.concat(this.current.assets); }); - log(assets); assets = $.each(assets, function () { this.local_path = this.local_url; }); - log(assets); swf.setAssets(assets); } else { updateWhenFlashReady = true; @@ -110,6 +175,16 @@ Preview = new function Preview() { {'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); @@ -117,10 +192,20 @@ Preview.embed(PREVIEW_SWF_ID); PetType.createFromLink(speciesList.eq(Math.floor(Math.random()*speciesList.length))).setAsCurrent(); Item.createFromLocation().setAsCurrent(); +Item.current.name = $('#item-name').text(); -speciesList.click(function (e) { - e.preventDefault(); - PetType.createFromLink($(this)).setAsCurrent(); +speciesList.each(function () { + var pet_type = PetType.createFromLink($(this)); + $(this).click(function (e) { + e.preventDefault(); + pet_type.setAsCurrent(); + }); }); MainWardrobe = { View: { Outfit: Preview } }; + +setTimeout(function () { + $.each(PetType.all, function () { + this.load(); + }); +}, 5000); diff --git a/public/stylesheets/compiled/screen.css b/public/stylesheets/compiled/screen.css index 130414cd..bc9055b2 100644 --- a/public/stylesheets/compiled/screen.css +++ b/public/stylesheets/compiled/screen.css @@ -612,15 +612,18 @@ body.show #item-name { /* line 23, ../../../app/stylesheets/items/_show.scss */ body.show #item-preview div { float: left; - width: 50%; } /* 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; width: 50px; } -/* line 33, ../../../app/stylesheets/items/_show.scss */ -body.show #item-preview a { +/* line 36, ../../../app/stylesheets/items/_show.scss */ +body.show #item-preview-species a { display: -moz-inline-box; -moz-box-orient: vertical; display: inline-block; @@ -628,12 +631,33 @@ body.show #item-preview a { *display: inline; *vertical-align: auto; } -/* line 35, ../../../app/stylesheets/items/_show.scss */ -body.show #item-preview a.current { +/* line 39, ../../../app/stylesheets/items/_show.scss */ +body.show #item-preview-species a.current { background: #66a3d2; 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 { height: 300px; overflow: hidden;