Desktop boost 2
This commit is contained in:
Родитель
87cb005e91
Коммит
3bfd7ec5ce
|
@ -1,5 +1,5 @@
|
|||
<div id="popup">
|
||||
<div id="boost">
|
||||
<div id="boost" data-status="{{ boost_status }}">
|
||||
<h3>{{ _('Boost your Spark') }}</h3>
|
||||
<p class="legend">
|
||||
{{ _('Wanna share a few more details?') }}<br>
|
||||
|
@ -55,8 +55,8 @@
|
|||
</div>
|
||||
<div class="buttons-wrapper">
|
||||
{# L10n: Space is limited here, the translation should be no longer than ~15 latin characters #}
|
||||
<a class="button left-button close">{{ _('Cancel') }}</a>
|
||||
<a class="button right-button">{{ _('Next step') }}</a>
|
||||
<a class="button left-button">{{ _('Cancel') }}</a>
|
||||
<a class="button right-button">{{ _('Confirm') }}</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -77,16 +77,15 @@
|
|||
<h3>{{ _('Boost your Spark') }}</h3>
|
||||
<h4>{{ _('Step 1 of 2') }}</h4>
|
||||
|
||||
<!-- Choose your location manually -->
|
||||
<p class="legend">
|
||||
{{ _("Select your location manually") }}
|
||||
</p>
|
||||
<form id="select-location-form" method="post">
|
||||
<form action="{{ url('mobile.yourlocation')|secure_url }}" id="select-location-form" method="post">
|
||||
{{ csrf() }}
|
||||
<fieldset>
|
||||
<select tabindex="1" name="chosen_city" id="citylist">
|
||||
<option value="">{{ _("Your location") }}</option>
|
||||
</select>
|
||||
<select tabindex="1" name="city" id="select-location-form-citylist">
|
||||
<option value="0">{{ _("Your location") }}</option>
|
||||
</select>
|
||||
</fieldset>
|
||||
<div class="buttons-wrapper">
|
||||
{# L10n: Space is limited here, the translation should be no longer than ~15 latin characters #}
|
||||
|
@ -108,16 +107,16 @@
|
|||
{% endtrans %}
|
||||
</p>
|
||||
|
||||
<form method="post" accept-charset="utf-8">
|
||||
<form id="boost2-form" action="{{ url('mobile.boost2')|secure_url }}" method="post" accept-charset="utf-8">
|
||||
{{ csrf() }}
|
||||
<fieldset id="identifier" class="section">
|
||||
<div class="input-wrapper">
|
||||
<input tabindex="1" type="text" name="identifier" value="" placeholder="{{ _('Username/email address') }}">
|
||||
<div id="boost2-form-identifier" class="input-wrapper">
|
||||
<input tabindex="1" type="text" name="identifier" value="" placeholder="{{ _('Username/email address') }}" required>
|
||||
</div>
|
||||
<p class="disclaimer sans">
|
||||
{% trans policy_url='http://www.mozilla.com/m/privacy.html' %}
|
||||
Email address is only used to connect to you. See our <a href="{{ policy_url }}">Privacy Policy.</a>
|
||||
{% endtrans %}
|
||||
{% trans %}
|
||||
Your friend's email address is only used to connect the two of you.
|
||||
{% endtrans %}
|
||||
</p>
|
||||
</fieldset>
|
||||
<hr>
|
||||
|
@ -131,41 +130,38 @@
|
|||
<div class="buttons-wrapper">
|
||||
{# L10n: Space is limited here. The translation should be no longer than the English version, leave only "Later" if needed #}
|
||||
<a class="button left-button close">{{ _('Maybe later') }}</a>
|
||||
<a tabindex="3" class="button right-button" type="submit">{{ _('Find') }}</a>
|
||||
<button tabindex="3" class="right-button" type="submit">{{ _('Find') }}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<form id="boost2-form" action="{{ url('mobile.boost2_confirm')|secure_url }}" method="post" accept-charset="utf-8">
|
||||
{{ csrf() }}
|
||||
<input type="hidden" name="no_parent" value="">
|
||||
<input type="hidden" name="parent" value="">
|
||||
</form>
|
||||
|
||||
<div id="boost2-confirm">
|
||||
<div id="boost2-result">
|
||||
<h3>{{ _('Boost your Spark') }}</h3>
|
||||
<h4>{{ _('Step 2 of 2') }}</h4>
|
||||
|
||||
<div id="boost2-result-solo">
|
||||
<div id="checkmark"></div>
|
||||
<span>
|
||||
{{ _('Congrats! You started a new Spark.') }}
|
||||
</span>
|
||||
</div>
|
||||
<div id="boost2-result">
|
||||
<div id="boost2-result-parent">
|
||||
<div id="checkmark"></div>
|
||||
<span>
|
||||
{{ _('Your Spark was started by:') }}
|
||||
<span></span>
|
||||
<span id="parent-name"></span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<form action="{{ url('mobile.boost2_confirm') }}" method="POST">
|
||||
<form id="boost2-confirm-form" action="{{ url('mobile.boost2_confirm')|secure_url }}" method="POST" accept-charset="utf-8">
|
||||
{{ csrf() }}
|
||||
<input id="no-parent" type="hidden" name="no_parent" value="1">
|
||||
<input id="no-parent" type="hidden" name="no_parent" value="">
|
||||
<input id="has-parent" type="hidden" name="parent" value="">
|
||||
|
||||
<div class="buttons-wrapper">
|
||||
<a class="button left-button close">{{ _('Cancel') }}</a>
|
||||
<a class="button left-button">{{ _('Cancel') }}</a>
|
||||
{# L10n: Action verb on a form submit button. #}
|
||||
<a class="button right-button" type="submit">{{ _('Complete') }}</a>
|
||||
<button tabindex="1" class="right-button" type="submit">{{ _('Complete') }}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
|
|
@ -10,13 +10,15 @@
|
|||
{# L10n: City and country of the logged-in user. #}
|
||||
<span id="user-location">{{ _('Home location: <span>{location}</span>')|fe(location=profile.get_home_location(LANG)) }}</span>
|
||||
{% else %}
|
||||
<a id="user-location" class="popup-trigger">{{ _('Tell us your home location >') }}</a>
|
||||
<span id="user-location"></span>
|
||||
<a id="user-location-link" class="popup-trigger">{{ _('Tell us your home location >') }}</a>
|
||||
{% endif %}
|
||||
{% if profile.boost2_completed %}
|
||||
{# L10n: Name of the parent user who shared Spark with you via a link/QR code. #}
|
||||
<span id="parent-user">{{ _('Spark started with: <span>{parent}</span>')|fe(parent=profile.spark_started_with) }}</span>
|
||||
{% else %}
|
||||
<a id="parent-user" class="popup-trigger">{{ _('Tell us where you got your Spark >') }}</a>
|
||||
<span id="parent-user"></span>
|
||||
<a id="parent-user-link" class="popup-trigger">{{ _('Tell us where you got your Spark >') }}</a>
|
||||
{% endif %}
|
||||
<span id="edit-account">{{ _('Edit <a href="#">your account ></a>')|safe }}</span>
|
||||
</div>
|
||||
|
|
|
@ -9,5 +9,7 @@ urlpatterns = patterns('',
|
|||
url(r'^user/(?P<username>[\w.+-]+)$', views.user, name='desktop.user'),
|
||||
url(r'^global$', views.visualization, name='desktop.visualization'),
|
||||
url(r'^close$', views.close, name='desktop.close_popup'),
|
||||
url(r'^cities$', views.cities, name='desktop.cities')
|
||||
url(r'^cities$', views.cities, name='desktop.cities'),
|
||||
url(r'^location_info$', views.home_location_info, name='desktop.location_info'),
|
||||
url(r'^parent_info$', views.parent_user_info, name='desktop.parent_info')
|
||||
)
|
|
@ -25,6 +25,7 @@ from users.models import User, Profile
|
|||
|
||||
from stats.utils import get_global_stats
|
||||
|
||||
from tower import ugettext as _
|
||||
import jingo
|
||||
|
||||
|
||||
|
@ -34,6 +35,11 @@ def home(request):
|
|||
if request.user.is_authenticated():
|
||||
profile = request.user.profile
|
||||
delta = datetime.datetime.now() - profile.user.date_joined
|
||||
boost_status = 0
|
||||
if profile.boost2_completed:
|
||||
boost_status = 2
|
||||
elif profile.boost1_completed:
|
||||
boost_status = 1
|
||||
return jingo.render(request, 'desktop/dashboard.html',
|
||||
{'username': profile.user.username,
|
||||
'profile': profile,
|
||||
|
@ -49,7 +55,8 @@ def home(request):
|
|||
'facebook_title': urlquote(unicode(FACEBOOK_SPARK_TITLE)),
|
||||
'facebook_spark_msg': urlquote(unicode(FACEBOOK_SPARK_MSG)),
|
||||
'abs_url': profile.generic_sharing_url,
|
||||
'stats': get_global_stats()})
|
||||
'stats': get_global_stats(),
|
||||
'boost_status': boost_status})
|
||||
else:
|
||||
data = {'is_homepage': True,
|
||||
'twitter_url': urlquote(absolute_url(django_reverse('desktop.home'))),
|
||||
|
@ -131,6 +138,18 @@ def cities(request):
|
|||
return citylist
|
||||
|
||||
|
||||
@login_required
|
||||
def home_location_info(request):
|
||||
profile = request.user.profile
|
||||
return HttpResponse(_(u'Home location: <span>{location}</span>').format(location=profile.get_home_location(request.locale)))
|
||||
|
||||
|
||||
@login_required
|
||||
def parent_user_info(request):
|
||||
profile = request.user.profile
|
||||
return HttpResponse(_(u'Spark started with: <span>{parent}</span>').format(parent=profile.spark_started_with))
|
||||
|
||||
|
||||
def _total_seconds(td):
|
||||
"""Returns the total number of seconds in a given timedelta."""
|
||||
return (td.microseconds + (td.seconds + td.days * 24 * 3600) * 10**6) / 10**6
|
||||
|
|
|
@ -9,7 +9,8 @@ from spark.models import City
|
|||
from spark.urlresolvers import reverse, absolute_url
|
||||
from spark.decorators import post_required, json_view
|
||||
from spark.utils import (get_city_fullname, is_supported_non_firefox, is_iphone,
|
||||
is_firefox_mobile, is_android, get_ua, approximate_major_city)
|
||||
is_firefox_mobile, is_android, get_ua, approximate_major_city,
|
||||
get_country_name)
|
||||
|
||||
from users.models import User, UserNode
|
||||
from users.utils import create_relationship
|
||||
|
@ -30,7 +31,7 @@ from stats.utils import get_global_stats
|
|||
from .forms import BoostStep1Form, BoostStep2Form
|
||||
from .decorators import login_required, logout_required
|
||||
|
||||
from tower import ugettext_lazy as _lazy
|
||||
from tower import ugettext as _, ugettext_lazy as _lazy
|
||||
|
||||
|
||||
|
||||
|
@ -113,7 +114,9 @@ def boost1_complete(request):
|
|||
|
||||
|
||||
@login_required
|
||||
@json_view
|
||||
def geolocation_fallback(request):
|
||||
ajax = request.is_ajax()
|
||||
profile = request.user.profile
|
||||
if not profile.boost1_completed:
|
||||
|
||||
|
@ -135,11 +138,18 @@ def geolocation_fallback(request):
|
|||
update_completed_challenges.delay(profile.user.id)
|
||||
|
||||
profile.add_city_shares_for_children()
|
||||
|
||||
return HttpResponseRedirect(reverse('mobile.boost1_complete'))
|
||||
|
||||
if ajax:
|
||||
return {'status': 'success',
|
||||
'data': {'cityName': profile.city_name,
|
||||
'countryName': get_country_name(profile.country_code, request.locale)}}
|
||||
else:
|
||||
return HttpResponseRedirect(reverse('mobile.boost1_complete'))
|
||||
except City.DoesNotExist:
|
||||
# Wrong city in the POST data, ignore it and display the city list again.
|
||||
pass
|
||||
# Wrong city in the POST data
|
||||
if ajax:
|
||||
return {'status': 'error',
|
||||
'errors': {'citylist': [_('Select your location manually')]}}
|
||||
|
||||
cities = City.objects.order_by('city_name')
|
||||
citylist = [(city.id, get_city_fullname(city.city_name, city.country_code, request.locale)) for city in cities]
|
||||
|
@ -151,10 +161,12 @@ def geolocation_fallback(request):
|
|||
|
||||
|
||||
@login_required
|
||||
@json_view
|
||||
def boost2(request):
|
||||
""" Boost your Spark step 2/2 :
|
||||
Allows a Spark user to find a parent user by username or email address."""
|
||||
profile = request.user.profile
|
||||
ajax = request.is_ajax()
|
||||
|
||||
if profile.boost2_completed:
|
||||
return HttpResponseRedirect(reverse('mobile.home'))
|
||||
|
@ -168,7 +180,14 @@ def boost2(request):
|
|||
else: # User just checked the 'I started a new Spark on my own' box
|
||||
data.update({'no_parent': True})
|
||||
|
||||
return jingo.render(request, 'mobile/boost_step2_found.html', data)
|
||||
if ajax:
|
||||
return {'status': 'success', 'data': data}
|
||||
else:
|
||||
return jingo.render(request, 'mobile/boost_step2_found.html', data)
|
||||
else:
|
||||
if ajax:
|
||||
return {'status': 'error',
|
||||
'errors': dict([(k, [unicode(e) for e in v]) for k,v in form.errors.items()])}
|
||||
else:
|
||||
form = BoostStep2Form(request.user)
|
||||
|
||||
|
@ -177,11 +196,14 @@ def boost2(request):
|
|||
|
||||
@login_required
|
||||
@post_required
|
||||
@json_view
|
||||
def boost2_confirm(request):
|
||||
""" Boost your Spark step 2/2 confirmation.
|
||||
This view saves the parent-child relationship in the user tree.
|
||||
"""
|
||||
profile = request.user.profile
|
||||
ajax = request.is_ajax()
|
||||
|
||||
if profile.boost2_completed:
|
||||
return HttpResponseRedirect(reverse('mobile.home'))
|
||||
|
||||
|
@ -225,7 +247,13 @@ def boost2_confirm(request):
|
|||
# This requires to award badges synchronously for this particular step.
|
||||
update_completed_challenges(profile.user.id)
|
||||
|
||||
return HttpResponseRedirect(reverse('mobile.home'))
|
||||
if ajax:
|
||||
return {'status': 'success', 'url': reverse('desktop.parent_info')}
|
||||
else:
|
||||
return HttpResponseRedirect(reverse('mobile.home'))
|
||||
else:
|
||||
if ajax:
|
||||
return {'status': 'error'}
|
||||
|
||||
return jingo.render(request, 'spark/handlers/mobile/400.html', status=400)
|
||||
|
||||
|
|
|
@ -50,18 +50,26 @@ def approximate_major_city(profile, radius):
|
|||
profile.save()
|
||||
|
||||
|
||||
def get_city_fullname(city_name, country_code, locale):
|
||||
def get_country_name(country_code, locale):
|
||||
from geo.countries import countries
|
||||
|
||||
if locale not in countries:
|
||||
locale = 'en-US'
|
||||
|
||||
cc = country_code.lower()
|
||||
if cc in countries[locale]:
|
||||
country_name = countries[locale][cc]
|
||||
else:
|
||||
country_name = '?'
|
||||
|
||||
return country_name
|
||||
|
||||
|
||||
def get_city_fullname(city_name, country_code, locale):
|
||||
from geo.countries import countries
|
||||
|
||||
if locale not in countries:
|
||||
locale = 'en-US'
|
||||
|
||||
country_name = get_country_name(country_code, locale)
|
||||
|
||||
return '%s, %s' % (city_name, country_name)
|
||||
|
||||
|
||||
|
|
|
@ -1600,7 +1600,7 @@ div.level.locked:hover {
|
|||
color:#fff;
|
||||
}
|
||||
|
||||
#citylist {
|
||||
#select-location-form-citylist {
|
||||
width:100%;
|
||||
border-radius:2px;
|
||||
-moz-border-radius:2px;
|
||||
|
@ -1615,7 +1615,7 @@ div.level.locked:hover {
|
|||
height:34px;
|
||||
}
|
||||
|
||||
#citylist option {
|
||||
#select-location-form-citylist option {
|
||||
padding:5px 10px;
|
||||
}
|
||||
|
||||
|
|
|
@ -91,12 +91,6 @@ $(document).ready(function() {
|
|||
$('#your-account').show();
|
||||
showPopup();
|
||||
});
|
||||
|
||||
// displays the boost popups
|
||||
$('#user-details .popup-trigger').click(function() {
|
||||
$('#boost').show();
|
||||
showPopup();
|
||||
});
|
||||
|
||||
// hides the sign-in modal popup (and resets it to sign-in state)
|
||||
$mask.click(function() {
|
||||
|
|
|
@ -1,5 +1,16 @@
|
|||
var initBoost = function() {
|
||||
// Let's boost
|
||||
// Open the correct Boost popup
|
||||
$('#user-details .popup-trigger').click(function() {
|
||||
var status = parseInt($('#boost').data('status'));
|
||||
if(status === 0) {
|
||||
$('#boost').show();
|
||||
} else if(status === 1) {
|
||||
$('#boost2').show();
|
||||
}
|
||||
showPopup();
|
||||
});
|
||||
|
||||
// Let's boost button
|
||||
$('#boost .right-button').click(function() {
|
||||
swap('#boost', '#boost1');
|
||||
});
|
||||
|
@ -9,16 +20,18 @@ var initBoost = function() {
|
|||
swap('#boost1-confirm', '#boost1');
|
||||
});
|
||||
|
||||
|
||||
popupForm('#select-location-form', null, function($form, data) {
|
||||
refreshYourLocation(data.cityName, data.countryName);
|
||||
// Manual geolocation form
|
||||
popupForm('#select-location-form', null, function($form, resp) {
|
||||
refreshYourLocation(resp.data.cityName, resp.data.countryName);
|
||||
swap('#select-location', '#boost1-confirm');
|
||||
$('#location-error').hide();
|
||||
$('#location-result').show();
|
||||
});
|
||||
|
||||
// Select your location manually
|
||||
$('#location-error .cta a').click(function(e) {
|
||||
$.get($(this).attr('href'), function(cities) {
|
||||
var citylist = $("#citylist");
|
||||
var citylist = $("#select-location-form-citylist");
|
||||
|
||||
//¨Populate city drop-down
|
||||
$.each(cities, function(index, city) {
|
||||
|
@ -30,12 +43,61 @@ var initBoost = function() {
|
|||
e.preventDefault();
|
||||
return false;
|
||||
});
|
||||
|
||||
// Next step (boost 1 confirm)
|
||||
$('#boost1-confirm .right-button').click(function() {
|
||||
swap('#boost1-confirm', '#boost2');
|
||||
|
||||
// Boost 1 Confirm
|
||||
popupForm('#boost1-confirm-form', null, function($form, resp) {
|
||||
if(resp.status === 'success') {
|
||||
$.get(resp.url, function(html) {
|
||||
$('#user-location').html(html);
|
||||
$('#user-location-link').hide();
|
||||
});
|
||||
swap('#boost1-confirm', '#boost2');
|
||||
}
|
||||
});
|
||||
|
||||
// Boost 1 Confirm - Cancel button
|
||||
$('#location-result .left-button').click(function(e) {
|
||||
$('#select-location-form-citylist').val('0');
|
||||
swap('#boost1-confirm', '#select-location');
|
||||
});
|
||||
|
||||
// Boost 2 form
|
||||
popupForm('#boost2-form', null, function($form, resp) {
|
||||
if(resp.data.parent) {
|
||||
$('#parent-name').html(resp.data.parent);
|
||||
$('#has-parent').val(resp.data.parent);
|
||||
$('#boost2-result-parent').show();
|
||||
$('#boost2-result-solo').hide();
|
||||
} else {
|
||||
$('#no-parent').val('1');
|
||||
$('#boost2-result-parent').hide();
|
||||
$('#boost2-result-solo').show();
|
||||
}
|
||||
|
||||
swap('#boost2', '#boost2-confirm');
|
||||
});
|
||||
|
||||
// Boost 2 - Maybe Later button
|
||||
$('#boost2 .left-button').click(function(e) {
|
||||
resetForm('#boost2-form');
|
||||
});
|
||||
|
||||
// Boost 2 Complete form
|
||||
popupForm('#boost2-confirm-form', null, function($form, resp) {
|
||||
if(resp.status === 'success') {
|
||||
$.get(resp.url, function(html) {
|
||||
$('#parent-user').html(html);
|
||||
$('#parent-user-link').hide();
|
||||
});
|
||||
hidePopup();
|
||||
}
|
||||
});
|
||||
|
||||
// Boost 2 Complete - Cancel button
|
||||
$('#boost2-confirm-form .left-button').click(function(e) {
|
||||
resetForm('#boost2-form');
|
||||
swap('#boost2-confirm', '#boost2');
|
||||
});
|
||||
|
||||
/*
|
||||
var boost1Error = function() {
|
||||
|
|
Загрузка…
Ссылка в новой задаче