Bug 585201, add-on directory buttons

This commit is contained in:
Matt Claypotch 2010-08-20 11:35:10 -07:00
Родитель fef968049e
Коммит 03bcb7e352
10 изменённых файлов: 219 добавлений и 74 удалений

Просмотреть файл

@ -1,29 +1,35 @@
<div class="collection-add"
<div class="collection-add{{ ' condensed' if condensed else '' }}"
data-listurl="{{ url('collections.ajax_list') }}"
data-addurl="{{ url('collections.ajax_add') }}"
data-removeurl="{{ url('collections.ajax_remove') }}"
data-newurl="{{ url('collections.ajax_new') }}"
data-addonid="{{ addon.id }}"
>
<span><a href="#">Add to collection</a></span>
</div>
<div class="collection-add-dropdown install-note">
{% if user.is_anonymous() %}
<div class="collection-add-login">
<p>
{% trans %}
To create your own collections, you must have an add-ons
account.
{% endtrans %}
</p>
<p class="register-button">
<a class="button" href="{{ remora_url('users/register') }}">{{ _('Create an Add-ons Account') }}</a>
</p>
<p>
{% trans login=login_link() %}
or <a href="{{ login }}">log in to your current account</a>
{% endtrans %}
</p>
{% if condensed %}
<a href="#"><span></span></a>
{% else %}
<span><a href="#">Add to collection</a></span>
{% endif %}
<div class="popup-shim">
<div class="collection-add-dropdown popup{{ ' left' if condensed else '' }}">
{% if user.is_anonymous() %}
<div class="collection-add-login">
<p>
{% trans %}
To create your own collections, you must have an add-ons
account.
{% endtrans %}
</p>
<p class="register-button">
<a class="button" href="{{ remora_url('users/register') }}">{{ _('Create an Add-ons Account') }}</a>
</p>
<p>
{% trans login=login_link() %}
or <a href="{{ login }}">log in to your current account</a>
{% endtrans %}
</p>
</div>
{% endif %}
</div>
</div>
{% endif %}
</div>
</div>

Просмотреть файл

@ -7,6 +7,10 @@
<div class="item-info">
{{ install_button(addon, collection=collection) }}
{{ item_info(addon, amo, show_added_date) }}
<div class="collection_widgets">
{{ favorites_widget(addon, condensed=True) }}
{{ collection_add_widget(addon, condensed=True) }}
</div>
</div>
<blockquote>
{% if addon.is_persona() %}

Просмотреть файл

@ -104,9 +104,19 @@ def barometer(context, collection):
return c
@register.inclusion_tag('addons/includes/collection_add_widget.html')
@register.function
@jinja2.contextfunction
def favorites_widget(context, addon):
def collection_add_widget(context, addon, condensed=False):
"""Displays 'Add to Collection' widget"""
c = dict(context.items())
c.update(locals())
return c
@register.function
@jinja2.contextfunction
def favorites_widget(context, addon, condensed=False):
"""Displays 'Add to Favorites' widget"""
c = dict(context.items())
request = c['request']
@ -114,6 +124,9 @@ def favorites_widget(context, addon):
is_favorite = bool(addon.id in request.amo_user.favorite_addons)
faved_class = 'faved' if is_favorite else ''
unfaved_text = '' if condensed else _('Add to favorites')
faved_text = 'Favorite' if condensed else _('Remove from favorites')
add_url = reverse('collections.alter',
args=[request.amo_user.username, 'favorites', 'add'])
remove_url = reverse('collections.alter',

Просмотреть файл

@ -3,7 +3,7 @@
{% for collection in collections %}
<li {{ collection.has_addon|class_selected(True) }}
data-id="{{ collection.id }}">
<span class="collectionitem">{{ collection.name }}</span>
<span class="collectionitem">{{ collection.name }}</span><a title="{{ _('View this collection') }}" class="outlink" href="{{ collection.get_url_path() }}"></a>
</li>
{% endfor %}
</ul>

Просмотреть файл

@ -1,13 +1,25 @@
<div class="addon-favorite {{ faved_class }}"
<div class="addon-favorite {{ faved_class }}{{ ' condensed' if condensed else '' }}"
data-addonid="{{ addon.id }}"
data-addurl="{{ add_url }}"
data-removeurl="{{ remove_url }}"
data-favedtext="{{ faved_text }}"
data-unfavedtext="{{ unfaved_text }}"
>
<span><a href="#">
{% if is_favorite %}
{{ _('Remove from favorites') }}
{% else %}
{{ _('Add to favorites') }}
{% endif %}
</a></span>
{% if condensed %}
<span class="msg">
{% if is_favorite %}
{{ faved_text }}
{% else %}
{{ unfaved_text }}
{% endif %}
</span>
{% else %}
<span><a class="msg" href="#">
{% if is_favorite %}
{{ faved_text }}
{% else %}
{{ unfaved_text }}
{% endif %}
</a></span>
{% endif %}
</div>

Просмотреть файл

@ -4,7 +4,7 @@
<h3>{{ _('Collection Description') }}</h3>
</div>
<fieldset>
{{ field(form.name, form.name.label) }}
{{ field(form.name, _('Name:')) }}
{% if not (collection and
collection.type in amo.COLLECTION_SPECIAL_SLUGS.keys()) %}
<p id="collection-form-slug">

Просмотреть файл

@ -328,11 +328,11 @@ class TestCRUD(test_utils.TestCase):
r = self.client.get(url)
eq_(r.status_code, 403)
def test_edit_addons(self):
def test_edit_addons_get(self):
self.create_collection()
url = reverse('collections.edit_addons', args=['admin', 'pornstar'])
r = self.client.get(url, follow=True)
eq_(r.status_code, 200)
eq_(r.status_code, 405)
def test_edit_addons_post(self):
self.create_collection()
@ -356,7 +356,7 @@ class TestCRUD(test_utils.TestCase):
@patch('access.acl.action_allowed')
def test_admin(self, f):
self.create_collection()
url = reverse('collections.edit_contributors',
url = reverse('collections.edit',
args=['admin', 'pornstar'])
r = self.client.get(url, follow=True)
doc = pq(r.content)
@ -372,7 +372,7 @@ class TestCRUD(test_utils.TestCase):
url = reverse('collections.edit_contributors',
args=['admin', 'pornstar'])
self.client.post(url, {'contributor': 999}, follow=True)
url = reverse('collections.edit_addons', args=['admin', 'pornstar'])
url = reverse('collections.edit', args=['admin', 'pornstar'])
r = self.client.get(url)
doc = pq(r.content)

Просмотреть файл

@ -2537,7 +2537,7 @@ html[xmlns] .clearfix {
padding: 4px;
}
.addon-collections li .collectionitem, .collection-add span {
.addon-collections li .collectionitem, .collection-add > span {
padding-left: 20px;
background-image: url(../../img/amo2009/icons/icons.png);
background-repeat: no-repeat;

Просмотреть файл

@ -610,6 +610,14 @@ th, td {
padding: 2px 3px 3px;
}
.popup-shim {
position: relative;
}
.popup p:last-child {
margin-bottom: 0;
}
.install-note .msg,
.popup .msg {
background-repeat: no-repeat;
@ -639,8 +647,7 @@ th, td {
margin-top: 5px;
z-index: 999;
background: #fff;
width: 300px;
padding: 10px 10px 0;
padding: 10px;
border: 3px solid #2e5186;
-moz-border-radius: 8px;
-webkit-border-radius: 8px;
@ -649,6 +656,9 @@ th, td {
-webkit-box-shadow: 0 1px 3px rgba(0,0,0,0.35);
box-shadow: 0 1px 3px rgba(0,0,0,0.35);
}
.install-note {
width: 300px;
}
/* append the left class if the bubble is to the far right */
.install-note.left,
.popup.left {
@ -2461,9 +2471,15 @@ h6.author, .author a {
.collection-add-dropdown a {
color: #0055EE;
}
.collection-add-dropdown form {
margin-bottom: 0;
}
.collection-add-dropdown.new-collection {
width: 410px;
}
.collection-add-dropdown.new-collection #id_description {
height: 6em;
}
#collection-form-slug {
font-size: .9em;
@ -2597,6 +2613,9 @@ table#addons-list, table#contributors-list {
float: left;
margin: 2px 1em 0 0;
}
#details-edit #id_name {
display: block;
}
.ui-autocomplete {
background-color: #fff;
border: 1px solid black;
@ -2671,13 +2690,25 @@ table#addons-list, table#contributors-list {
}
.addon-favorite span {
.collection_widgets {
margin-top: .5em;
}
.addon-favorite {
cursor: pointer;
}
.addon-favorite span,
.collection-add.condensed a span {
background-repeat: no-repeat;
background-image: url(../../img/zamboni/icons/collections.png);
white-space: nowrap;
background-position: 0 -500px;
padding-left: 20px;
}
.addon-favorite span.msg {
font-weight: bold;
}
.addon-favorite:hover span {
background-position: 0 -450px;
}
@ -2688,3 +2719,58 @@ table#addons-list, table#contributors-list {
background-image: url(../../img/zamboni/loading-white.gif);
background-position: left bottom;
}
a.outlink {
margin-left: 4px;
background-repeat: no-repeat;
background-image: url(../../img/zamboni/icons/collections.png);
white-space: nowrap;
padding-left: 16px;
background-position: 0 -850px;
}
a.outlink:hover {
background-position: 0 -900px;
}
.collection-add.condensed a span {
background-position: 0 -151px;
}
.collection-add.condensed:hover a span {
background-position: 0 -101px;
}
.collection-add.condensed .collection-add-dropdown {
left: -140px;
top: 4px;
}
.collection-add.condensed .collection-add-dropdown.new-collection {
left: -350px;
top: 4px;
}
.share-this.condensed {
margin-right: 4px;
width: 16px;
float: none;
}
.share-this.condensed > a {
background-image: url(../../img/zamboni/icons/collections.png);
background-repeat: no-repeat;
white-space: nowrap;
background-position: 0 -600px;
}
.share-this.condensed > a:hover {
background-position: 0 -550px;
}
.condensed .share-frame {
left: -186px;
}
.collection_widgets .condensed {
margin-right: 4px;
display: inline-block;
}

Просмотреть файл

@ -527,26 +527,26 @@ $(document).ready(function () {
/* Add to collection initialization */
var btn = $('div.collection-add');
var dropdown = $('.collection-add-dropdown');
if (!btn.length) return;
btn.show();
var list_url = btn.attr('data-listurl');
var remove_url = btn.attr('data-removeurl');
var add_url = btn.attr('data-addurl');
var form_url = btn.attr('data-newurl');
var addon_id = $('#addon, #persona').attr('data-id');
function handleToggle(e) {
e.preventDefault();
var tgt = $(this);
var dropdown = tgt.closest(".popup");
var addon_id = tgt.closest(".collection-add").attr('data-addonid');
var data = {'addon_id': addon_id,
'id': this.getAttribute('data-id')};
'id': tgt.attr('data-id')};
var url = this.className == "selected" ? remove_url
: add_url;
$(this).addClass('ajax-loading');
e.preventDefault();
$.post(url, data, function(data) {
dropdown.removeClass('new-collection');
dropdown.html(data);
@ -554,6 +554,9 @@ $(document).ready(function () {
}
var handleSubmit = function(e) {
var tgt = $(this);
var dropdown = tgt.parents(".popup");
var addon_id = tgt.parents(".collection-add").attr('data-addonid');
e.preventDefault();
form_data = $('#collections-new form').serialize();
$.post(form_url + '?addon_id=' + addon_id, form_data, function(d) {
@ -562,6 +565,9 @@ $(document).ready(function () {
};
var handleNew = function(e) {
var tgt = $(this);
var dropdown = tgt.parents('.collection-add-dropdown');
var addon_id = tgt.parents(".collection-add").attr('data-addonid');
e.preventDefault();
$.get(form_url, {'addon_id': addon_id}, function(d) {
dropdown.addClass('new-collection');
@ -571,50 +577,68 @@ $(document).ready(function () {
};
var handleClick = function(e) {
$('.collection-add-dropdown').hide();
var dropdown = $('.collection-add-dropdown', $(this));
dropdown.removeClass("new-collection");
var addon_id = $(this).attr('data-addonid');
// If anonymous, show login overlay.
dropdown.show();
// Make a call to /collections/ajax/list with addon_id
if (!z.anonymous) {
if (z.anonymous) {
dropdown.show();
} else {
// Make a call to /collections/ajax/list with addon_id
$.get(list_url, {'addon_id': addon_id}, function(data) {
dropdown.show();
dropdown.html(data);
dropdown.removeClass('new-collection');
$("a.outlink", dropdown).click(stopPropagation);
}, 'html');
}
e.preventDefault();
console.log("click");
dropdown.unbind('click.popup', stopPropagation);
dropdown.bind('click.popup', stopPropagation);
dropdown.delegate('#ajax_collections_list li', 'click', handleToggle)
.delegate('#collections-new form', 'submit', handleSubmit)
.delegate('#ajax_new_collection', 'click', handleNew)
.delegate('#collections-new-cancel', 'click', handleClick);
// Clear popup when we click outside it.
setTimeout(function(){
$(document.body).bind('click newPopup', cb);
$(document.body).bind('click newPopup', cb(dropdown));
}, 0);
};
btn.click(handleClick);
$(document.body).delegate("div.collection-add", 'click', handleClick);
dropdown.delegate('#ajax_collections_list li', 'click', handleToggle)
.delegate('#collections-new form', 'submit', handleSubmit)
.delegate('#ajax_new_collection', 'click', handleNew)
.delegate('#collections-new-cancel', 'click', handleClick);
var cb = function(e) {
_root = dropdown.get(0);
// Bail if the click was somewhere on the popup.
if (e.type == 'click' &&
_root == e.target ||
_.indexOf($(e.target).parents(), _root) != -1) {
return;
}
dropdown.hide();
$(document.body).unbind('click newPopup', cb);
function cb(el) {
var hider = function function(e) {
_root = el.get(0);
// Bail if the click was somewhere on the popup.
if (e.type == 'click' &&
_root == e.target ||
_.indexOf($(e.target).parents(), _root) != -1) {
return;
}
el.hide();
el.unbind();
el.undelegate();
$(document.body).unbind('click newPopup', hider);
};
return hider;
}
function stopPropagation(e) {
e.stopPropagation();
}
});
// Add to favorites functionality
$(document).ready(function () {
$(".addon-favorite a").click(function(e) {
$(".addon-favorite").click(function(e) {
e.preventDefault();
var tgt = $(this);
var widget = $(this).parents(".addon-favorite");
var msg = $(".msg", this);
var widget = $(this);
var data = {'addon_id': widget.attr('data-addonid')};
var faved = widget.hasClass("faved");
var url = faved ? widget.attr('data-removeurl') : widget.attr('data-addurl');
@ -630,10 +654,10 @@ $(document).ready(function () {
widget.removeClass('ajax-loading');
if (faved) {
widget.removeClass("faved");
tgt.text(gettext("Add to favorites"));
msg.text(widget.attr('data-unfavedtext'));
} else {
widget.addClass("faved");
tgt.text(gettext("Remove from favorites"));
msg.text(widget.attr('data-favedtext'));
}
},
error: function(xhr) {