show owned/wanted icons and search filters
This commit is contained in:
parent
b1670b1595
commit
6d155ecaf1
8 changed files with 101 additions and 40 deletions
|
@ -48,15 +48,26 @@ module ItemsHelper
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def closeted_icon_for(item)
|
def closeted_icons_for(item)
|
||||||
if item.closeted?
|
content = ''.html_safe
|
||||||
image_tag(
|
|
||||||
'closeted.png',
|
if item.owned?
|
||||||
|
content << image_tag(
|
||||||
|
'owned.png',
|
||||||
:title => 'You own this',
|
:title => 'You own this',
|
||||||
:alt => 'Closet',
|
:alt => 'Own'
|
||||||
:class => 'closeted-icon'
|
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if item.wanted?
|
||||||
|
content << image_tag(
|
||||||
|
'wanted.png',
|
||||||
|
:title => 'You want this',
|
||||||
|
:alt => 'Want'
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
content_tag :div, content, :class => 'closeted-icons'
|
||||||
end
|
end
|
||||||
|
|
||||||
def list_zones(zones, method=:label)
|
def list_zones(zones, method=:label)
|
||||||
|
|
|
@ -10,7 +10,7 @@ class Item < ActiveRecord::Base
|
||||||
has_many :swf_assets, :through => :parent_swf_asset_relationships, :source => :object_asset,
|
has_many :swf_assets, :through => :parent_swf_asset_relationships, :source => :object_asset,
|
||||||
:conditions => {:type => SwfAssetType}
|
:conditions => {:type => SwfAssetType}
|
||||||
|
|
||||||
attr_writer :closeted, :current_body_id
|
attr_writer :current_body_id, :owned, :wanted
|
||||||
|
|
||||||
NCRarities = [0, 500]
|
NCRarities = [0, 500]
|
||||||
PAINTBRUSH_SET_DESCRIPTION = 'This item is part of a deluxe paint brush set!'
|
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)
|
scope :with_closet_hangers, joins(:closet_hangers)
|
||||||
|
|
||||||
def closeted?
|
def closeted?
|
||||||
!!@closeted
|
@owned || @wanted
|
||||||
end
|
end
|
||||||
|
|
||||||
def nc?
|
def nc?
|
||||||
NCRarities.include?(rarity_index)
|
NCRarities.include?(rarity_index)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def owned?
|
||||||
|
@owned
|
||||||
|
end
|
||||||
|
|
||||||
|
def wanted?
|
||||||
|
@wanted
|
||||||
|
end
|
||||||
|
|
||||||
def restricted_zones
|
def restricted_zones
|
||||||
unless @restricted_zones
|
unless @restricted_zones
|
||||||
@restricted_zones = []
|
@restricted_zones = []
|
||||||
|
@ -639,7 +647,10 @@ class Item < ActiveRecord::Base
|
||||||
def self.search_filter_block(options, positive, &block)
|
def self.search_filter_block(options, positive, &block)
|
||||||
Proc.new { |str, user, scope|
|
Proc.new { |str, user, scope|
|
||||||
condition = block.arity == 1 ? block.call(str) : block.call(str, user)
|
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 = scope.send(options[:scope]) if options[:scope]
|
||||||
scope.where(condition)
|
scope.where(condition)
|
||||||
}
|
}
|
||||||
|
@ -667,25 +678,45 @@ class Item < ActiveRecord::Base
|
||||||
filter
|
filter
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.validate_user_condition(adjective, user)
|
USER_ADJECTIVES = {
|
||||||
unless adjective == "owns"
|
'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}. " +
|
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
|
end
|
||||||
|
|
||||||
unless user
|
unless user
|
||||||
raise SearchError, "It looks like you're not logged in, so you don't own any items."
|
raise SearchError, "It looks like you're not logged in, so you don't own any items."
|
||||||
end
|
end
|
||||||
|
|
||||||
|
USER_ADJECTIVES[adjective]
|
||||||
end
|
end
|
||||||
|
|
||||||
single_search_filter :user, :full => lambda { |adjective, user, scope|
|
search_filter :user do |adjective, user|
|
||||||
validate_user_condition(adjective, user)
|
# Though joins may seem more efficient here for the positive case, we need
|
||||||
scope.joins(:closet_hangers).where(ClosetHanger.arel_table[:user_id].eq(user.id))
|
# 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|
|
owned_value = parse_user_adjective(adjective, user)
|
||||||
validate_user_condition(adjective, user)
|
hangers = ClosetHanger.arel_table
|
||||||
arel_table[:id].not_in(user.closeted_items.map(&:id))
|
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
|
end
|
||||||
|
|
||||||
search_filter :only do |species_name|
|
search_filter :only do |species_name|
|
||||||
|
|
|
@ -49,8 +49,14 @@ class User < ActiveRecord::Base
|
||||||
# versa, and everything stays a lovely O(n)
|
# versa, and everything stays a lovely O(n)
|
||||||
items_by_id = {}
|
items_by_id = {}
|
||||||
items.each { |item| items_by_id[item.id] = item }
|
items.each { |item| items_by_id[item.id] = item }
|
||||||
closeted_item_ids = closeted_items.where(:id => items_by_id.keys).map(&:id)
|
closet_hangers.where(:item_id => items_by_id.keys).each do |hanger|
|
||||||
closeted_item_ids.each { |id| items_by_id[id].closeted = true }
|
item = items_by_id[hanger.item_id]
|
||||||
|
if hanger.owned?
|
||||||
|
item.owned = true
|
||||||
|
else
|
||||||
|
item.wanted = true
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.find_or_create_from_remote_auth_data(user_data)
|
def self.find_or_create_from_remote_auth_data(user_data)
|
||||||
|
|
|
@ -178,19 +178,25 @@ ul.buttons
|
||||||
// (quantity form in user items)
|
// (quantity form in user items)
|
||||||
+opacity(1)
|
+opacity(1)
|
||||||
|
|
||||||
.nc-icon, .closeted-icon
|
.nc-icon, .closeted-icons
|
||||||
+opacity(1)
|
+opacity(1)
|
||||||
height: $nc-icon-size
|
background: rgba(255, 255, 255, 0.75)
|
||||||
|
line-height: 1
|
||||||
position: absolute
|
position: absolute
|
||||||
top: $object-img-size - $nc-icon-size
|
top: $object-img-size - $nc-icon-size
|
||||||
width: $nc-icon-size
|
|
||||||
&:hover
|
&:hover
|
||||||
+opacity(0.5)
|
+opacity(0.5)
|
||||||
|
background: transparent
|
||||||
|
|
||||||
|
.nc-icon, .closeted-icons img
|
||||||
|
display: inline
|
||||||
|
height: $nc-icon-size
|
||||||
|
width: $nc-icon-size
|
||||||
|
|
||||||
.nc-icon
|
.nc-icon
|
||||||
right: ($object-width - $object-img-size) / 2 + $object-padding
|
right: ($object-width - $object-img-size) / 2 + $object-padding
|
||||||
|
|
||||||
.closeted-icon
|
.closeted-icons
|
||||||
left: ($object-width - $object-img-size) / 2 + $object-padding
|
left: ($object-width - $object-img-size) / 2 + $object-padding
|
||||||
|
|
||||||
dt
|
dt
|
||||||
|
|
|
@ -2,5 +2,5 @@
|
||||||
= image_tag item.thumbnail_url, :alt => item.description, :title => item.description
|
= image_tag item.thumbnail_url, :alt => item.description, :title => item.description
|
||||||
= item.name
|
= item.name
|
||||||
= nc_icon_for(item)
|
= nc_icon_for(item)
|
||||||
= closeted_icon_for(item)
|
= closeted_icons_for(item)
|
||||||
|
|
||||||
|
|
Before Width: | Height: | Size: 537 B After Width: | Height: | Size: 537 B |
BIN
public/images/wanted.png
Normal file
BIN
public/images/wanted.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 671 B |
|
@ -304,43 +304,50 @@ ul.buttons li, ul.buttons li form {
|
||||||
-khtml-opacity: 1;
|
-khtml-opacity: 1;
|
||||||
}
|
}
|
||||||
/* line 181, ../../../app/stylesheets/_layout.sass */
|
/* line 181, ../../../app/stylesheets/_layout.sass */
|
||||||
.object .nc-icon, .object .closeted-icon {
|
.object .nc-icon, .object .closeted-icons {
|
||||||
-moz-opacity: 1;
|
-moz-opacity: 1;
|
||||||
-webkit-opacity: 1;
|
-webkit-opacity: 1;
|
||||||
-o-opacity: 1;
|
-o-opacity: 1;
|
||||||
-khtml-opacity: 1;
|
-khtml-opacity: 1;
|
||||||
height: 16px;
|
background: rgba(255, 255, 255, 0.75);
|
||||||
|
line-height: 1;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 64px;
|
top: 64px;
|
||||||
width: 16px;
|
|
||||||
}
|
}
|
||||||
/* line 187, ../../../app/stylesheets/_layout.sass */
|
/* line 187, ../../../app/stylesheets/_layout.sass */
|
||||||
.object .nc-icon:hover, .object .closeted-icon:hover {
|
.object .nc-icon:hover, .object .closeted-icons:hover {
|
||||||
-moz-opacity: 0.5;
|
-moz-opacity: 0.5;
|
||||||
-webkit-opacity: 0.5;
|
-webkit-opacity: 0.5;
|
||||||
-o-opacity: 0.5;
|
-o-opacity: 0.5;
|
||||||
-khtml-opacity: 0.5;
|
-khtml-opacity: 0.5;
|
||||||
|
background: transparent;
|
||||||
}
|
}
|
||||||
/* line 190, ../../../app/stylesheets/_layout.sass */
|
/* line 191, ../../../app/stylesheets/_layout.sass */
|
||||||
|
.object .nc-icon, .object .closeted-icons img {
|
||||||
|
display: inline;
|
||||||
|
height: 16px;
|
||||||
|
width: 16px;
|
||||||
|
}
|
||||||
|
/* line 196, ../../../app/stylesheets/_layout.sass */
|
||||||
.object .nc-icon {
|
.object .nc-icon {
|
||||||
right: 18px;
|
right: 18px;
|
||||||
}
|
}
|
||||||
/* line 193, ../../../app/stylesheets/_layout.sass */
|
/* line 199, ../../../app/stylesheets/_layout.sass */
|
||||||
.object .closeted-icon {
|
.object .closeted-icons {
|
||||||
left: 18px;
|
left: 18px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* line 196, ../../../app/stylesheets/_layout.sass */
|
/* line 202, ../../../app/stylesheets/_layout.sass */
|
||||||
dt {
|
dt {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* line 199, ../../../app/stylesheets/_layout.sass */
|
/* line 205, ../../../app/stylesheets/_layout.sass */
|
||||||
dd {
|
dd {
|
||||||
margin: 0 0 1.5em 1em;
|
margin: 0 0 1.5em 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* line 202, ../../../app/stylesheets/_layout.sass */
|
/* line 208, ../../../app/stylesheets/_layout.sass */
|
||||||
#home-link {
|
#home-link {
|
||||||
font-family: Delicious, Helvetica, Arial, Verdana, sans-serif;
|
font-family: Delicious, Helvetica, Arial, Verdana, sans-serif;
|
||||||
font-size: 175%;
|
font-size: 175%;
|
||||||
|
@ -351,21 +358,21 @@ dd {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
}
|
}
|
||||||
/* line 212, ../../../app/stylesheets/_layout.sass */
|
/* line 218, ../../../app/stylesheets/_layout.sass */
|
||||||
#home-link:hover {
|
#home-link:hover {
|
||||||
background: #eeffee;
|
background: #eeffee;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
/* line 215, ../../../app/stylesheets/_layout.sass */
|
/* line 221, ../../../app/stylesheets/_layout.sass */
|
||||||
#home-link span:before {
|
#home-link span:before {
|
||||||
content: "<< ";
|
content: "<< ";
|
||||||
}
|
}
|
||||||
|
|
||||||
/* line 219, ../../../app/stylesheets/_layout.sass */
|
/* line 225, ../../../app/stylesheets/_layout.sass */
|
||||||
.pagination a, .pagination span {
|
.pagination a, .pagination span {
|
||||||
margin: 0 0.5em;
|
margin: 0 0.5em;
|
||||||
}
|
}
|
||||||
/* line 221, ../../../app/stylesheets/_layout.sass */
|
/* line 227, ../../../app/stylesheets/_layout.sass */
|
||||||
.pagination .current {
|
.pagination .current {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue