lazy-load discovery promo modules for real (bug 719305)

This commit is contained in:
Chris Van 2012-01-27 16:53:00 -08:00
Родитель 5608d36713
Коммит 07d3e1f817
10 изменённых файлов: 140 добавлений и 87 удалений

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

@ -386,14 +386,11 @@ def home(request):
def homepage_promos(request):
from discovery.views import get_modules
platform = amo.PLATFORM_DICT.get(request.GET.get('platform'),
amo.PLATFORM_ALL)
version = request.GET.get('version')
modules = get_modules(request, platform.api_name, version)
module_context = request.GET.get('context', 'home')
return jingo.render(request, 'addons/impala/homepage_promos.html',
{'modules': modules, 'module_context': module_context})
from discovery.views import promos
version, platform = request.GET.get('version'), request.GET.get('platform')
if not (platform or version):
raise http.Http404
return promos(request, 'home', version, platform)
class CollectionPromoBox(object):
@ -672,7 +669,8 @@ def contribute(request, addon):
amount = {
'suggested': addon.suggested_amount,
'onetime': request.POST.get('onetime-amount', '')}.get(contrib_type, '')
'onetime': request.POST.get('onetime-amount', '')
}.get(contrib_type, '')
if not amount:
amount = settings.DEFAULT_SUGGESTED_CONTRIBUTION

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

@ -6,6 +6,8 @@
{% block bodyclass %}pane no-recs{% endblock %}
{% block bodyattrs %}
data-version="{{ version }}"
data-platform="{{ platform }}"
data-services-url="{{ settings.SERVICES_URL }}"
data-recs-url="{{ services_url('discovery.recs', version, platform) }}"
data-account-url="{{ services_url('discovery.pane.account') }}"
@ -38,25 +40,22 @@ data-upandcoming-url="{{ services_url('discovery.pane.more_addons', 'up-and-comi
<section id="main">
{% if modules %}
{# TODO: Lazy-load promo modules. #}
<section id="promos">
<section id="promos" data-promo-url="{{ services_url('discovery.pane.promos', version, platform) }}">
<ul id="nav-features">
<li class="nav-prev"><a href="#" class="prev">{{ _('Previous') }}</a></li>
<li class="nav-next"><a href="#" class="next">{{ _('Next') }}</a></li>
</ul>
<ul class="slider">
{% for module in modules %}{{ module.render() }}{% endfor %}
</ul>
<ul class="slider"></ul>
</section>
{% endif %}
{% if featured_addons %}
<section id="featured-addons">
<h2 class="translate" data-trans="featured">{{ _('Featured Add-ons') }}</h2>
<div class="addons">
{{ addon_list(featured_addons, limit=6) }}
</div>
</section>
{% endif %}
<section id="recs">
<div class="header">

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

@ -1,7 +1,6 @@
import json
from django import test
from django.conf import settings
from django.core.cache import cache
import mock
@ -177,7 +176,6 @@ class TestRecs(amo.tests.TestCase):
eq_(one['token2'], two['token2'])
# assert one['recommendations'] != two['recommendations']
assert one['addons'] != two['addons']
eq_(CollectionToken.objects.count(), 1)
eq_(len(Collection.objects.filter(type=amo.COLLECTION_SYNCHRONIZED)),
2)
@ -255,17 +253,44 @@ class TestUrls(amo.tests.TestCase):
class TestPromos(amo.tests.TestCase):
fixtures = ['discovery/discoverymodules']
def setUp(self):
self.url = reverse('discovery.pane', args=['3.7a1pre', 'Darwin'])
def get_disco_url(self, platform, version):
return reverse('discovery.pane.promos', args=[platform, version])
def test_promos_visible(self):
r = self.client.get(self.url)
eq_(pq(r.content)('#promos').length, 1)
def get_home_url(self):
return reverse('addons.homepage_promos')
def test_promos_hidden(self):
def test_no_params(self):
r = self.client.get(self.get_home_url())
eq_(r.status_code, 404)
def test_mac(self):
# Ensure that we get the same thing for the homepage promos.
r_mac = self.client.get(self.get_home_url(),
{'version': '10.0', 'platform': 'mac'})
r_darwin = self.client.get(self.get_disco_url('10.0', 'Darwin'))
eq_(r_mac.status_code, 200)
eq_(r_darwin.status_code, 200)
eq_(r_mac.content, r_darwin.content)
panels = pq(r_mac.content)('.panel')
eq_(panels.length, 1)
eq_(panels.find('.ryff').length, 1)
def test_win(self):
r_win = self.client.get(self.get_home_url(),
{'version': '10.0', 'platform': 'win'})
r_winnt = self.client.get(self.get_disco_url('10.0', 'WINNT'))
eq_(r_win.status_code, 200)
eq_(r_winnt.status_code, 200)
eq_(r_win.content, r_winnt.content)
panels = pq(r_win.content)('.panel')
eq_(panels.length, 1)
eq_(panels.find('.ryff').length, 1)
def test_hidden(self):
DiscoveryModule.objects.all().delete()
r = self.client.get(self.url)
eq_(pq(r.content)('#promos').length, 0)
r = self.client.get(self.get_disco_url('10.0', 'Darwin'))
eq_(r.status_code, 200)
eq_(r.content, '')
class TestPane(amo.tests.TestCase):
@ -466,7 +491,9 @@ class TestMonthlyPick(amo.tests.TestCase):
fixtures = ['base/apps', 'base/addon_3615', 'discovery/discoverymodules']
def setUp(self):
self.url = reverse('discovery.pane', args=['3.7a1pre', 'Darwin'])
self.url = reverse('addons.homepage_promos')
self.vars = {'version': '5.0', 'platform': 'mac',
'context': 'discovery'}
self.addon = Addon.objects.get(id=3615)
DiscoveryModule.objects.create(
app=Application.objects.get(id=amo.FIREFOX.id), ordering=4,
@ -475,10 +502,11 @@ class TestMonthlyPick(amo.tests.TestCase):
def test_monthlypick(self):
mp = MonthlyPick.objects.create(addon=self.addon, blurb='BOOP',
image='http://mozilla.com')
r = self.client.get(self.url)
r = self.client.get(self.url, self.vars)
eq_(pq(r.content)('#monthly').length, 0)
mp.update(locale='')
r = self.client.get(self.url)
r = self.client.get(self.url, self.vars)
pick = pq(r.content)('#monthly')
eq_(pick.length, 1)
a = pick.find('h3 a')
@ -493,22 +521,22 @@ class TestMonthlyPick(amo.tests.TestCase):
.endswith('?src=discovery-promo'), True)
def test_monthlypick_no_image(self):
mp = MonthlyPick.objects.create(addon=self.addon, blurb='BOOP',
locale='', image='')
MonthlyPick.objects.create(addon=self.addon, blurb='BOOP', locale='',
image='')
# Tests for no image when screenshot not set.
r = self.client.get(self.url)
r = self.client.get(self.url, self.vars)
pick = pq(r.content)('#monthly')
eq_(pick.length, 1)
eq_(pick.find('img').length, 0)
# Tests for screenshot image when set.
p = Preview.objects.create(addon=self.addon)
r = self.client.get(self.url)
Preview.objects.create(addon=self.addon)
r = self.client.get(self.url, self.vars)
pick = pq(r.content)('#monthly')
eq_(pick.length, 1)
eq_(pick.find('img').attr('src'), self.addon.all_previews[0].image_url)
def test_no_monthlypick(self):
r = self.client.get(self.url)
r = self.client.get(self.url, self.vars)
eq_(pq(r.content)('#monthly').length, 0)

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

@ -39,6 +39,8 @@ urlpatterns = patterns('',
url('^%s$' % (browser_re + compat_mode_re), pane_redirect),
url('^pane/%s$' % (browser_re + compat_mode_re), views.pane,
name='discovery.pane'),
url('^pane/promos/%s$' % (browser_re + compat_mode_re), views.pane_promos,
name='discovery.pane.promos'),
url('^modules$', views.module_admin, name='discovery.module_admin'),
url('^what-the-rec$', views.recs_debug, name='discovery.recs.debug'),
)

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

@ -48,8 +48,7 @@ def pane(request, version, platform, compat_mode='strict'):
promovideo = PromoVideoCollection().get_items()
return jingo.render(request, 'discovery/pane.html',
{'modules': get_modules(request, platform, version),
'up_and_coming': from_api('hotness'),
{'up_and_coming': from_api('hotness'),
'featured_addons': from_api('featured'),
'featured_personas': get_featured_personas(request),
'version': version, 'platform': platform,
@ -67,6 +66,17 @@ def pane_account(request):
{'addon_downloads': addon_downloads})
def promos(request, context, version, platform, compat_mode='strict'):
platform = amo.PLATFORM_DICT.get(version.lower(), amo.PLATFORM_ALL)
modules = get_modules(request, platform.api_name, version)
return jingo.render(request, 'addons/impala/homepage_promos.html',
{'modules': modules, 'module_context': context})
def pane_promos(request, version, platform, compat_mode='strict'):
return promos(request, 'discovery', version, platform, compat_mode)
def pane_more_addons(request, section, version, platform):
def from_api(list_type):

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

@ -346,7 +346,7 @@ header:after,
}
#main #featured-addons {
margin-top: 283px;
margin-top: 293px;
}
#main #promos.js + #featured-addons {
margin-top: 0;

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

@ -1,46 +1,24 @@
(function () {
$('.toplist .name').truncate({showTitle: true});
initPromos();
})();
function initPromos($context) {
if (typeof $context === 'undefined') {
$context = $(document.body);
}
var $promos = $('#promos[data-promo-url]', $context);
if (!$promos.length) {
return;
}
var promos_base = $promos.attr('data-promo-url'),
promos_url = format('{0}?version={1}&platform={2}',
promos_base, z.browserVersion, z.platform);
if (z.badBrowser) {
promos_url = format('{0}?version={1}&platform={2}',
promos_base, '5.0', 'mac');
}
$.get(promos_url, function(resp) {
$('ul', $promos).append($(resp));
$(document).bind('promos_shown', function(e, $promos) {
hideHomePromo();
$promos.append('<a href="#" class="control prev">&laquo;</a>\
$promos.slideDown('slow')
.append('<a href="#" class="control prev">&laquo;</a>\
<a href="#" class="control next">&raquo;</a>');
var $panels = $('.panel', $promos);
if ($panels.length) {
// Show promo module only if we have at least panel.
$promos.show();
$('div', $promos).zCarousel({
circular: true,
btnPrev: $('.prev', $promos),
btnNext: $('.next', $promos)
});
}
$('div', $promos).zCarousel({
circular: true,
btnPrev: $('.prev', $promos),
btnNext: $('.next', $promos)
});
$('.addons h3', $promos).truncate({dir: 'h'});
$('.addons .desc', $promos).truncate({dir: 'v'});
$('.install', $promos).installButton();
$('#monthly .blurb > p').lineclamp(4);
$('h2', $promos).linefit();
});
$('.toplist .name').truncate({showTitle: true});
}
})();
function hideHomePromo($context) {

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

@ -0,0 +1,34 @@
function initPromos($context, module_context, version, platform) {
if (!$context) {
$context = $(document.body);
}
var $promos = $('#promos[data-promo-url]', $context);
if (!$promos.length) {
return;
}
var promo_url = $promos.attr('data-promo-url');
if (!version) {
version = z.browserVersion;
}
if (!platform) {
platform = z.platform;
}
if (z.badBrowser && !version && !platform) {
version = '5.0';
platform = 'mac';
}
var data = {};
if (module_context != 'discovery') {
// The version + platform are passed in the `promo_url` for the
// discopane promos because when we serve static assets the
// `?build=<BUILD_ID>` cachebustage kills our querystring.
data = {version: version, platform: platform};
}
$.get(promo_url, data, function(resp) {
$('.slider', $promos).append($(resp));
if ($('.panel', $promos).length) {
// Show promo module only if we have at least panel.
$promos.trigger('promos_shown', [$promos]);
}
});
}

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

@ -16,30 +16,30 @@ z.discoStorage = z.Storage("discopane");
$(document).ready(function(){
if ($(".pane").length) {
initSidebar();
if (!$('.pane').length) {
return;
}
// Store the pane URL so we can link back from the add-on detail pages.
z.discoStorage.set("url", location);
initSidebar();
// Store the pane URL so we can link back from the add-on detail pages.
z.discoStorage.set('url', location);
hideInstalled();
initRecs();
hideInstalled();
// Show "Starter Pack" panel only if user has fewer than three extensions.
initPromos(null, 'discovery');
$(this).bind('promos_shown', function(e, $promos) {
// Show "Starter Pack" panel only if user has fewer than 3 extensions.
if (z.has_addons) {
$("#starter").closest(".panel").remove();
$('#starter').closest('.panel').remove();
}
initRecs();
// Set up the promo carousel.
$("#promos").fadeIn("slow").addClass("js").zCarousel({
btnNext: "#promos .nav-next a",
btnPrev: "#promos .nav-prev a",
$promos.fadeIn('slow').addClass('js').zCarousel({
btnNext: '#promos .nav-next a',
btnPrev: '#promos .nav-prev a',
circular: true
});
initTrunc();
}
});
});

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

@ -593,6 +593,7 @@ MINIFY_BUNDLES = {
'js/zamboni/debouncer.js',
# Homepage
'js/impala/promos.js',
'js/zamboni/homepage.js',
# Add-ons details page
@ -676,6 +677,7 @@ MINIFY_BUNDLES = {
'js/impala/forms.js',
# Homepage
'js/impala/promos.js',
'js/impala/homepage.js',
# Add-ons details page
@ -744,6 +746,8 @@ MINIFY_BUNDLES = {
'js/zamboni/debouncer.js',
'js/zamboni/truncation.js',
'js/impala/promos.js',
'js/zamboni/discovery_addons.js',
'js/zamboni/discovery_pane.js',
),