From 6d155ecaf1dff13aee1b8211958365ef45f5c1a6 Mon Sep 17 00:00:00 2001 From: Matchu Date: Fri, 22 Jul 2011 16:18:15 -0400 Subject: [PATCH] show owned/wanted icons and search filters --- app/helpers/items_helper.rb | 23 ++++++--- app/models/item.rb | 57 +++++++++++++++++----- app/models/user.rb | 10 +++- app/stylesheets/_layout.sass | 14 ++++-- app/views/items/_item_link.html.haml | 2 +- public/images/{closeted.png => owned.png} | Bin public/images/wanted.png | Bin 0 -> 671 bytes public/stylesheets/compiled/screen.css | 35 +++++++------ 8 files changed, 101 insertions(+), 40 deletions(-) rename public/images/{closeted.png => owned.png} (100%) create mode 100644 public/images/wanted.png diff --git a/app/helpers/items_helper.rb b/app/helpers/items_helper.rb index 5bc3a23c..f01fb43b 100644 --- a/app/helpers/items_helper.rb +++ b/app/helpers/items_helper.rb @@ -48,15 +48,26 @@ module ItemsHelper end end - def closeted_icon_for(item) - if item.closeted? - image_tag( - 'closeted.png', + def closeted_icons_for(item) + content = ''.html_safe + + if item.owned? + content << image_tag( + 'owned.png', :title => 'You own this', - :alt => 'Closet', - :class => 'closeted-icon' + :alt => 'Own' ) end + + if item.wanted? + content << image_tag( + 'wanted.png', + :title => 'You want this', + :alt => 'Want' + ) + end + + content_tag :div, content, :class => 'closeted-icons' end def list_zones(zones, method=:label) diff --git a/app/models/item.rb b/app/models/item.rb index 608f8109..6db699cb 100644 --- a/app/models/item.rb +++ b/app/models/item.rb @@ -10,7 +10,7 @@ class Item < ActiveRecord::Base has_many :swf_assets, :through => :parent_swf_asset_relationships, :source => :object_asset, :conditions => {:type => SwfAssetType} - attr_writer :closeted, :current_body_id + attr_writer :current_body_id, :owned, :wanted NCRarities = [0, 500] PAINTBRUSH_SET_DESCRIPTION = 'This item is part of a deluxe paint brush set!' @@ -46,13 +46,21 @@ class Item < ActiveRecord::Base scope :with_closet_hangers, joins(:closet_hangers) def closeted? - !!@closeted + @owned || @wanted end def nc? NCRarities.include?(rarity_index) end + def owned? + @owned + end + + def wanted? + @wanted + end + def restricted_zones unless @restricted_zones @restricted_zones = [] @@ -639,7 +647,10 @@ class Item < ActiveRecord::Base def self.search_filter_block(options, positive, &block) Proc.new { |str, user, scope| condition = block.arity == 1 ? block.call(str) : block.call(str, user) - condition = "!(#{condition.to_sql})" unless positive + unless positive + condition = condition.to_sql if condition.respond_to?(:to_sql) + condition = "!(#{condition})" + end scope = scope.send(options[:scope]) if options[:scope] scope.where(condition) } @@ -667,25 +678,45 @@ class Item < ActiveRecord::Base filter end - def self.validate_user_condition(adjective, user) - unless adjective == "owns" + USER_ADJECTIVES = { + 'own' => true, + 'owns' => true, + 'owned' => true, + 'want' => false, + 'wants' => false, + 'wanted' => false, + 'all' => nil, + 'items' => nil + } + def self.parse_user_adjective(adjective, user) + unless USER_ADJECTIVES.has_key?(adjective) raise SearchError, "We don't understand user:#{adjective}. " + - "Did you mean user:owns?" + "Find items you own with user:owns, items you want with user:wants, or " + + "both with user:all" end unless user raise SearchError, "It looks like you're not logged in, so you don't own any items." end + + USER_ADJECTIVES[adjective] end - single_search_filter :user, :full => lambda { |adjective, user, scope| - validate_user_condition(adjective, user) - scope.joins(:closet_hangers).where(ClosetHanger.arel_table[:user_id].eq(user.id)) - } + search_filter :user do |adjective, user| + # Though joins may seem more efficient here for the positive case, we need + # to be able to handle cases like "user:owns user:wants", which breaks on + # the JOIN approach. Just have to look up the IDs in advance. - single_search_filter :not_user do |adjective, user| - validate_user_condition(adjective, user) - arel_table[:id].not_in(user.closeted_items.map(&:id)) + owned_value = parse_user_adjective(adjective, user) + hangers = ClosetHanger.arel_table + items = user.closeted_items + items = items.where(ClosetHanger.arel_table[:owned].eq(owned_value)) unless owned_value.nil? + item_ids = items.map(&:id) + # Though it's best to do arel_table[:id].in(item_ids), it breaks in this + # version of Arel, and other conditions will overwrite this one. Since IDs + # are guaranteed to be integers, let's just build our own string condition + # and be done with it. + "id IN (#{item_ids.join(',')})" end search_filter :only do |species_name| diff --git a/app/models/user.rb b/app/models/user.rb index a2ab633f..20f027b4 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -49,8 +49,14 @@ class User < ActiveRecord::Base # versa, and everything stays a lovely O(n) items_by_id = {} items.each { |item| items_by_id[item.id] = item } - closeted_item_ids = closeted_items.where(:id => items_by_id.keys).map(&:id) - closeted_item_ids.each { |id| items_by_id[id].closeted = true } + closet_hangers.where(:item_id => items_by_id.keys).each do |hanger| + item = items_by_id[hanger.item_id] + if hanger.owned? + item.owned = true + else + item.wanted = true + end + end end def self.find_or_create_from_remote_auth_data(user_data) diff --git a/app/stylesheets/_layout.sass b/app/stylesheets/_layout.sass index 9a3eaaf7..81cb2731 100644 --- a/app/stylesheets/_layout.sass +++ b/app/stylesheets/_layout.sass @@ -178,19 +178,25 @@ ul.buttons // (quantity form in user items) +opacity(1) - .nc-icon, .closeted-icon + .nc-icon, .closeted-icons +opacity(1) - height: $nc-icon-size + background: rgba(255, 255, 255, 0.75) + line-height: 1 position: absolute top: $object-img-size - $nc-icon-size - width: $nc-icon-size &:hover +opacity(0.5) + background: transparent + + .nc-icon, .closeted-icons img + display: inline + height: $nc-icon-size + width: $nc-icon-size .nc-icon right: ($object-width - $object-img-size) / 2 + $object-padding - .closeted-icon + .closeted-icons left: ($object-width - $object-img-size) / 2 + $object-padding dt diff --git a/app/views/items/_item_link.html.haml b/app/views/items/_item_link.html.haml index 107b7ed9..ed1fd79f 100644 --- a/app/views/items/_item_link.html.haml +++ b/app/views/items/_item_link.html.haml @@ -2,5 +2,5 @@ = image_tag item.thumbnail_url, :alt => item.description, :title => item.description = item.name = nc_icon_for(item) - = closeted_icon_for(item) + = closeted_icons_for(item) diff --git a/public/images/closeted.png b/public/images/owned.png similarity index 100% rename from public/images/closeted.png rename to public/images/owned.png diff --git a/public/images/wanted.png b/public/images/wanted.png new file mode 100644 index 0000000000000000000000000000000000000000..003924f5eaf9d04277db6731c060eea3f91afbe0 GIT binary patch literal 671 zcmV;Q0$}}#P))~3#~Ygh$29>KGa1bdH!g|-+n z%l(K(260cnR7PZA*&f5ViJWk2f?gO&<^&{{2pC@~psYOx{~+*b81ROHwh-W{t3t5R zfUAcy8L&$R7VqU%llVxB*$-TP4VVK!!+YQ{1?q!9``6#^&vyc*d<{N4Fv7TFIs?*V zVE#eNEVW7OU_j1YAe-u>mqKrV*3ZC0Dhr{9JVTgBH3a zw-MOd1e_w^+FNRU0B}<`6@-^H`-eRI8uYrge*@EsyqvK^`lfvjY@_h@W`KJMSbKop zAHe;7z(u1Nuh*cfdJEdlt!IEw0o1wyC*2TZt#4=mjuUi~!k&*bMpx`-Zr%6cESDIq zaoS|ycJT@Z=oCP8Ci0}*C*evrP)&0?`y^