privacy for unlisted hangers

This commit is contained in:
Emi Matchu 2011-07-30 19:45:28 -04:00
parent 9a7b13dc5d
commit 75961abc17
9 changed files with 235 additions and 62 deletions

View file

@ -16,9 +16,16 @@ class ClosetHangersController < ApplicationController
@user = User.find params[:user_id]
@closet_lists_by_owned = @user.closet_lists.alphabetical.
includes(:hangers => :item).group_by(&:hangers_owned)
@unlisted_closet_hangers_by_owned = @user.closet_hangers.unlisted.
owned_before_wanted.alphabetical_by_item_name.includes(:item).
group_by(&:owned)
visible_groups = @user.closet_hangers_groups_visible_to(current_user)
unless visible_groups.empty?
@unlisted_closet_hangers_by_owned = @user.closet_hangers.unlisted.
owned_before_wanted.alphabetical_by_item_name.includes(:item).
where(:owned => [visible_groups]).group_by(&:owned)
else
@unlisted_closet_hangers_by_owned = {}
end
@public_perspective = params.has_key?(:public) || !user_is?(@user)
end

View file

@ -13,6 +13,16 @@ module ClosetHangersHelper
public_perspective? ? @user.name : :you
end
def hangers_group_visibility_field_name(owned)
owned ? :owned_closet_hangers_visibility : :wanted_closet_hangers_visibility
end
def hangers_group_visibility_choices(owned)
ClosetVisibility.levels.map do |level|
[level.description("these items"), level.id]
end
end
# Do we have either unlisted hangers that are owned/wanted, or non-empty
# owned/wanted lists?
def has_hangers?(owned)
@ -55,16 +65,9 @@ module ClosetHangersHelper
end
def render_unlisted_closet_hangers(owned)
if @unlisted_closet_hangers_by_owned[owned]
hangers_content = render :partial => 'closet_hanger',
:collection => @unlisted_closet_hangers_by_owned[owned],
:locals => {:show_controls => !public_perspective?}
content = content_tag(:div, hangers_content, :class => 'closet-list-hangers')
if has_lists?(owned)
content = content_tag(:header, content_tag(:h4, '(Not in a list)')) + content
end
content_tag(:div, content, :class => 'closet-list unlisted')
end
hangers_content = render :partial => 'closet_hanger',
:collection => @unlisted_closet_hangers_by_owned[owned],
:locals => {:show_controls => !public_perspective?}
end
end

View file

@ -0,0 +1,54 @@
module ClosetVisibility
class Level
attr_accessor :id, :name
attr_writer :description
def initialize(data)
data.each do |key, value|
send("#{key}=", value)
end
end
def description(subject=nil)
if subject
@description.sub('$SUBJECT', subject).capitalize
else
@description
end
end
end
LEVELS = [
Level.new(
:id => 0,
:name => :private,
:description => "Only you can see $SUBJECT"
),
Level.new(
:id => 1,
:name => :public,
:description => "Anyone who visits this page can see $SUBJECT"
),
Level.new(
:id => 2,
:name => :advertised,
:description => "$SUBJECT will be publicly listed for trades"
)
]
LEVELS_BY_NAME = {}.tap do |levels_by_name|
LEVELS.each do |level|
levels_by_name[level.id] = level
levels_by_name[level.name] = level
end
end
def self.[](id)
LEVELS_BY_NAME[id]
end
def self.levels
LEVELS
end
end

View file

@ -14,7 +14,8 @@ class User < ActiveRecord::Base
devise :rememberable
attr_accessible :neopets_username
attr_accessible :neopets_username, :owned_closet_hangers_visibility,
:wanted_closet_hangers_visibility
def contribute!(pet)
new_contributions = []
@ -62,6 +63,14 @@ class User < ActiveRecord::Base
end
end
def closet_hangers_groups_visible_to(user)
return [true, false] if user == self
[].tap do |groups|
groups << true if owned_closet_hangers_visibility >= ClosetVisibility[:public].id
groups << false if wanted_closet_hangers_visibility >= ClosetVisibility[:public].id
end
end
def self.find_or_create_from_remote_auth_data(user_data)
user = find_or_initialize_by_remote_id_and_auth_server_id(
user_data['id'],

View file

@ -141,6 +141,30 @@ body.closet_hangers-index
.closet-list
border-bottom: 1px solid $soft-border-color
padding: .5em 0
position: relative
.visibility-form
+inline-block
margin: 0 auto
position: relative
input, select
font-size: 85%
margin:
bottom: 0
top: 0
select
border-color: $background-color
input[type=submit]
left: 100%
position: absolute
top: 0
visibility: hidden
&:active
top: 1px
header
display: block
@ -149,6 +173,7 @@ body.closet_hangers-index
h4
+header-text
font-size: 150%
line-height: 1
margin: 0 auto
.empty-list
@ -168,12 +193,21 @@ body.closet_hangers-index
&.unlisted
h4
font-style: italic
font:
size: 125%
style: italic
&:hover
.closet-list-controls
display: block
.visibility-form
input[type=submit]
visibility: visible
select
border-color: $soft-border-color
&:last-child
border-bottom: 0

View file

@ -67,7 +67,16 @@
= link_to_add_closet_list 'Add new list', :owned => owned, :class => 'add-closet-list'
.closet-hangers-group-content
= render_closet_lists(@closet_lists_by_owned[owned])
= render_unlisted_closet_hangers(owned)
- if @unlisted_closet_hangers_by_owned[owned]
.closet-list.unlisted
- if has_lists?(owned)
%header
%h4 (Not in a list)
= form_for @user, :html => {:class => 'visibility-form'} do |f|
= f.select hangers_group_visibility_field_name(owned),
hangers_group_visibility_choices(owned)
= f.submit "Save"
.closet-list-hangers= render_unlisted_closet_hangers(owned)
- if public_perspective?
- unless has_hangers?(owned)
%p #{@user.name} doesn't seem to #{closet_hanger_verb(owned, false)} anything.

View file

@ -0,0 +1,12 @@
class AddClosetHangersVisibilityToUsers < ActiveRecord::Migration
def self.up
add_column :users, :owned_closet_hangers_visibility, :integer, :null => false, :default => 1
add_column :users, :wanted_closet_hangers_visibility, :integer, :null => false, :default => 1
end
def self.down
remove_column :users, :wanted_closet_hangers_visibility
remove_column :users, :owned_closet_hangers_visibility
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 => 20110726231143) do
ActiveRecord::Schema.define(:version => 20110730174148) do
create_table "auth_servers", :force => true do |t|
t.string "short_name", :limit => 10, :null => false
@ -178,18 +178,20 @@ ActiveRecord::Schema.define(:version => 20110726231143) do
end
create_table "users", :force => true do |t|
t.string "name", :limit => 20, :null => false
t.integer "auth_server_id", :limit => 1, :null => false
t.integer "remote_id", :null => false
t.integer "points", :default => 0, :null => false
t.boolean "beta", :default => false, :null => false
t.string "name", :limit => 20, :null => false
t.integer "auth_server_id", :limit => 1, :null => false
t.integer "remote_id", :null => false
t.integer "points", :default => 0, :null => false
t.boolean "beta", :default => false, :null => false
t.string "remember_token"
t.datetime "remember_created_at"
t.boolean "forum_admin", :default => false, :null => false
t.boolean "forum_admin", :default => false, :null => false
t.boolean "forum_moderator"
t.boolean "image_mode_tester", :default => false, :null => false
t.text "closet_description", :null => false
t.boolean "image_mode_tester", :default => false, :null => false
t.text "closet_description", :null => false
t.string "neopets_username"
t.integer "owned_closet_hangers_visibility", :default => 1, :null => false
t.integer "wanted_closet_hangers_visibility", :default => 1, :null => false
end
create_table "zones", :force => true do |t|

View file

@ -791,30 +791,64 @@ body.closet_hangers-index .closet-hangers-group > header span.show:hover, body.c
body.closet_hangers-index .closet-list {
border-bottom: 1px solid #aaddaa;
padding: 0.5em 0;
position: relative;
}
/* line 145, ../../../app/stylesheets/closet_hangers/_index.sass */
/* line 146, ../../../app/stylesheets/closet_hangers/_index.sass */
body.closet_hangers-index .closet-list .visibility-form {
display: -moz-inline-box;
-moz-box-orient: vertical;
display: inline-block;
vertical-align: middle;
*display: inline;
*vertical-align: auto;
margin: 0 auto;
position: relative;
}
/* line 151, ../../../app/stylesheets/closet_hangers/_index.sass */
body.closet_hangers-index .closet-list .visibility-form input, body.closet_hangers-index .closet-list .visibility-form select {
font-size: 85%;
margin-bottom: 0;
margin-top: 0;
}
/* line 157, ../../../app/stylesheets/closet_hangers/_index.sass */
body.closet_hangers-index .closet-list .visibility-form select {
border-color: white;
}
/* line 160, ../../../app/stylesheets/closet_hangers/_index.sass */
body.closet_hangers-index .closet-list .visibility-form input[type=submit] {
left: 100%;
position: absolute;
top: 0;
visibility: hidden;
}
/* line 166, ../../../app/stylesheets/closet_hangers/_index.sass */
body.closet_hangers-index .closet-list .visibility-form input[type=submit]:active {
top: 1px;
}
/* line 169, ../../../app/stylesheets/closet_hangers/_index.sass */
body.closet_hangers-index .closet-list header {
display: block;
position: relative;
}
/* line 149, ../../../app/stylesheets/closet_hangers/_index.sass */
/* line 173, ../../../app/stylesheets/closet_hangers/_index.sass */
body.closet_hangers-index .closet-list h4 {
font-family: Delicious, Helvetica, Arial, Verdana, sans-serif;
font-size: 150%;
line-height: 1;
margin: 0 auto;
}
/* line 154, ../../../app/stylesheets/closet_hangers/_index.sass */
/* line 179, ../../../app/stylesheets/closet_hangers/_index.sass */
body.closet_hangers-index .closet-list .empty-list {
font-style: italic;
}
/* line 157, ../../../app/stylesheets/closet_hangers/_index.sass */
/* line 182, ../../../app/stylesheets/closet_hangers/_index.sass */
body.closet_hangers-index .closet-list .closet-list-controls {
display: none;
position: absolute;
right: 1em;
top: 0;
}
/* line 163, ../../../app/stylesheets/closet_hangers/_index.sass */
/* line 188, ../../../app/stylesheets/closet_hangers/_index.sass */
body.closet_hangers-index .closet-list .closet-list-controls a, body.closet_hangers-index .closet-list .closet-list-controls input[type=submit] {
/* http://www.zurb.com/blog_uploads/0000/0617/buttons-03.html */
-moz-border-radius: 5px;
@ -855,23 +889,32 @@ body.closet_hangers-index .closet-list .closet-list-controls a:active, body.clos
body.closet_hangers-index .closet-list .closet-list-controls a:hover, body.closet_hangers-index .closet-list .closet-list-controls input[type=submit]:hover {
background-color: #999999;
}
/* line 166, ../../../app/stylesheets/closet_hangers/_index.sass */
/* line 191, ../../../app/stylesheets/closet_hangers/_index.sass */
body.closet_hangers-index .closet-list .closet-list-controls form {
display: inline;
}
/* line 170, ../../../app/stylesheets/closet_hangers/_index.sass */
/* line 195, ../../../app/stylesheets/closet_hangers/_index.sass */
body.closet_hangers-index .closet-list.unlisted h4 {
font-size: 125%;
font-style: italic;
}
/* line 174, ../../../app/stylesheets/closet_hangers/_index.sass */
/* line 201, ../../../app/stylesheets/closet_hangers/_index.sass */
body.closet_hangers-index .closet-list:hover .closet-list-controls {
display: block;
}
/* line 177, ../../../app/stylesheets/closet_hangers/_index.sass */
/* line 205, ../../../app/stylesheets/closet_hangers/_index.sass */
body.closet_hangers-index .closet-list:hover .visibility-form input[type=submit] {
visibility: visible;
}
/* line 208, ../../../app/stylesheets/closet_hangers/_index.sass */
body.closet_hangers-index .closet-list:hover .visibility-form select {
border-color: #aaddaa;
}
/* line 211, ../../../app/stylesheets/closet_hangers/_index.sass */
body.closet_hangers-index .closet-list:last-child {
border-bottom: 0;
}
/* line 180, ../../../app/stylesheets/closet_hangers/_index.sass */
/* line 214, ../../../app/stylesheets/closet_hangers/_index.sass */
body.closet_hangers-index .closet-list.droppable-active {
-moz-border-radius: 1em;
-webkit-border-radius: 1em;
@ -882,49 +925,49 @@ body.closet_hangers-index .closet-list.droppable-active {
border-style: dotted;
margin: 1em 0;
}
/* line 187, ../../../app/stylesheets/closet_hangers/_index.sass */
/* line 221, ../../../app/stylesheets/closet_hangers/_index.sass */
body.closet_hangers-index .closet-list.droppable-active .object {
-moz-opacity: 0.25;
-webkit-opacity: 0.25;
-o-opacity: 0.25;
-khtml-opacity: 0.25;
}
/* line 191, ../../../app/stylesheets/closet_hangers/_index.sass */
/* line 225, ../../../app/stylesheets/closet_hangers/_index.sass */
body.closet_hangers-index .closet-list.droppable-active .object.ui-draggable-dragging {
-moz-opacity: 1;
-webkit-opacity: 1;
-o-opacity: 1;
-khtml-opacity: 1;
}
/* line 194, ../../../app/stylesheets/closet_hangers/_index.sass */
/* line 228, ../../../app/stylesheets/closet_hangers/_index.sass */
body.closet_hangers-index .closet-list.droppable-active .closet-list-controls {
display: none;
}
/* line 197, ../../../app/stylesheets/closet_hangers/_index.sass */
/* line 231, ../../../app/stylesheets/closet_hangers/_index.sass */
body.closet_hangers-index .closet-list.droppable-active .closet-list-hangers {
overflow: hidden;
}
/* line 201, ../../../app/stylesheets/closet_hangers/_index.sass */
/* line 235, ../../../app/stylesheets/closet_hangers/_index.sass */
body.closet_hangers-index .closet-hangers-group-autocomplete-item span, body.closet_hangers-index .closet-list-autocomplete-item span {
font-style: italic;
padding: 0.2em 0.4em;
}
/* line 206, ../../../app/stylesheets/closet_hangers/_index.sass */
/* line 240, ../../../app/stylesheets/closet_hangers/_index.sass */
body.closet_hangers-index .closet-list-autocomplete-item a, body.closet_hangers-index .closet-list-autocomplete-item span {
font-size: 85%;
padding-left: 2em;
}
/* line 213, ../../../app/stylesheets/closet_hangers/_index.sass */
/* line 247, ../../../app/stylesheets/closet_hangers/_index.sass */
body.closet_hangers-index.current-user #closet-hangers .object:hover form {
display: inline;
}
/* line 216, ../../../app/stylesheets/closet_hangers/_index.sass */
/* line 250, ../../../app/stylesheets/closet_hangers/_index.sass */
body.closet_hangers-index.current-user #closet-hangers .object:hover .closet-hanger-destroy {
position: absolute;
right: 18px;
top: 0;
}
/* line 221, ../../../app/stylesheets/closet_hangers/_index.sass */
/* line 255, ../../../app/stylesheets/closet_hangers/_index.sass */
body.closet_hangers-index.current-user #closet-hangers .object:hover .closet-hanger-destroy input {
/* http://www.zurb.com/blog_uploads/0000/0617/buttons-03.html */
-moz-border-radius: 5px;
@ -965,7 +1008,7 @@ body.closet_hangers-index.current-user #closet-hangers .object:hover .closet-han
body.closet_hangers-index.current-user #closet-hangers .object:hover .closet-hanger-destroy input:hover {
background-color: #999999;
}
/* line 224, ../../../app/stylesheets/closet_hangers/_index.sass */
/* line 258, ../../../app/stylesheets/closet_hangers/_index.sass */
body.closet_hangers-index.current-user #closet-hangers .object:hover .quantity {
-moz-opacity: 1;
-webkit-opacity: 1;
@ -975,73 +1018,73 @@ body.closet_hangers-index.current-user #closet-hangers .object:hover .quantity {
top: 56px;
padding: 0;
}
/* line 230, ../../../app/stylesheets/closet_hangers/_index.sass */
/* line 264, ../../../app/stylesheets/closet_hangers/_index.sass */
body.closet_hangers-index.current-user #closet-hangers .object:hover .quantity span {
display: none;
}
/* line 233, ../../../app/stylesheets/closet_hangers/_index.sass */
/* line 267, ../../../app/stylesheets/closet_hangers/_index.sass */
body.closet_hangers-index.current-user #closet-hangers .object:hover .quantity input[type=number] {
padding: 2px;
width: 2em;
}
/* line 237, ../../../app/stylesheets/closet_hangers/_index.sass */
/* line 271, ../../../app/stylesheets/closet_hangers/_index.sass */
body.closet_hangers-index.current-user #closet-hangers .object:hover .quantity input[type=submit] {
font-size: 85%;
}
/* line 242, ../../../app/stylesheets/closet_hangers/_index.sass */
/* line 276, ../../../app/stylesheets/closet_hangers/_index.sass */
body.closet_hangers-index.current-user.js #closet-hangers .object:hover .quantity {
display: block;
}
/* line 245, ../../../app/stylesheets/closet_hangers/_index.sass */
/* line 279, ../../../app/stylesheets/closet_hangers/_index.sass */
body.closet_hangers-index.current-user.js #closet-hangers .object:hover .quantity input[type=number] {
width: 2.5em;
}
/* line 248, ../../../app/stylesheets/closet_hangers/_index.sass */
/* line 282, ../../../app/stylesheets/closet_hangers/_index.sass */
body.closet_hangers-index.current-user.js #closet-hangers .object:hover .quantity input[type=submit] {
display: none;
}
/* line 251, ../../../app/stylesheets/closet_hangers/_index.sass */
/* line 285, ../../../app/stylesheets/closet_hangers/_index.sass */
body.closet_hangers-index.current-user.js #closet-hangers .object.loading {
background: #eeffee;
outline: 1px solid #006600;
}
/* line 255, ../../../app/stylesheets/closet_hangers/_index.sass */
/* line 289, ../../../app/stylesheets/closet_hangers/_index.sass */
body.closet_hangers-index.current-user.js #closet-hangers .object.loading .quantity {
display: block;
}
/* line 258, ../../../app/stylesheets/closet_hangers/_index.sass */
/* line 292, ../../../app/stylesheets/closet_hangers/_index.sass */
body.closet_hangers-index.current-user.js #closet-hangers .object.loading .quantity span:after {
content: "…";
}
/* line 262, ../../../app/stylesheets/closet_hangers/_index.sass */
/* line 296, ../../../app/stylesheets/closet_hangers/_index.sass */
body.closet_hangers-index.current-user.js #closet-hangers-contact form {
display: none;
}
/* line 265, ../../../app/stylesheets/closet_hangers/_index.sass */
/* line 299, ../../../app/stylesheets/closet_hangers/_index.sass */
body.closet_hangers-index.current-user.js #closet-hangers-contact .edit-contact-link, body.closet_hangers-index.current-user.js #closet-hangers-contact #cancel-contact-link {
display: inline;
}
/* line 269, ../../../app/stylesheets/closet_hangers/_index.sass */
/* line 303, ../../../app/stylesheets/closet_hangers/_index.sass */
body.closet_hangers-index.current-user.js #closet-hangers-contact.editing form {
display: block;
}
/* line 272, ../../../app/stylesheets/closet_hangers/_index.sass */
/* line 306, ../../../app/stylesheets/closet_hangers/_index.sass */
body.closet_hangers-index.current-user.js #closet-hangers-contact.editing .edit-contact-link {
display: none;
}
/* line 277, ../../../app/stylesheets/closet_hangers/_index.sass */
/* line 311, ../../../app/stylesheets/closet_hangers/_index.sass */
body.closet_hangers-index.current-user.js .closet-hangers-group header .show, body.closet_hangers-index.current-user.js .closet-hangers-group header .hide {
cursor: pointer;
}
/* line 280, ../../../app/stylesheets/closet_hangers/_index.sass */
/* line 314, ../../../app/stylesheets/closet_hangers/_index.sass */
body.closet_hangers-index.current-user.js .closet-hangers-group header .hide {
display: block;
}
/* line 284, ../../../app/stylesheets/closet_hangers/_index.sass */
/* line 318, ../../../app/stylesheets/closet_hangers/_index.sass */
body.closet_hangers-index.current-user.js .closet-hangers-group.hidden header .hide, body.closet_hangers-index.current-user.js .closet-hangers-group.hidden .closet-hangers-group-content {
display: none;
}
/* line 287, ../../../app/stylesheets/closet_hangers/_index.sass */
/* line 321, ../../../app/stylesheets/closet_hangers/_index.sass */
body.closet_hangers-index.current-user.js .closet-hangers-group.hidden header .show {
display: block;
}