mirror of
https://github.com/pretix/pretix.git
synced 2026-05-17 17:14:04 +00:00
extend cart without full page reload
This commit is contained in:
@@ -1655,7 +1655,7 @@ def clear_cart(self, event: Event, cart_id: str=None, locale='en', sales_channel
|
|||||||
|
|
||||||
|
|
||||||
@app.task(base=ProfiledEventTask, bind=True, max_retries=5, default_retry_delay=1, throws=(CartError,))
|
@app.task(base=ProfiledEventTask, bind=True, max_retries=5, default_retry_delay=1, throws=(CartError,))
|
||||||
def extend_cart_reservation(self, event: Event, cart_id: str=None, locale='en', sales_channel='web', override_now_dt: datetime=None) -> None:
|
def extend_cart_reservation(self, event: Event, cart_id: str=None, locale='en', sales_channel='web', override_now_dt: datetime=None) -> dict:
|
||||||
"""
|
"""
|
||||||
Resets the expiry time of a cart to the configured reservation time of this event.
|
Resets the expiry time of a cart to the configured reservation time of this event.
|
||||||
Limited to 11x the reservation time.
|
Limited to 11x the reservation time.
|
||||||
@@ -1672,7 +1672,7 @@ def extend_cart_reservation(self, event: Event, cart_id: str=None, locale='en',
|
|||||||
try:
|
try:
|
||||||
cm = CartManager(event=event, cart_id=cart_id, sales_channel=sales_channel)
|
cm = CartManager(event=event, cart_id=cart_id, sales_channel=sales_channel)
|
||||||
cm.commit()
|
cm.commit()
|
||||||
return cm.num_extended_positions
|
return {"success": cm.num_extended_positions, "expiry": cm._expiry, "max_expiry_extend": cm._max_expiry_extend}
|
||||||
except LockTimeoutException:
|
except LockTimeoutException:
|
||||||
self.retry()
|
self.retry()
|
||||||
except (MaxRetriesExceededError, LockTimeoutException):
|
except (MaxRetriesExceededError, LockTimeoutException):
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ class AsyncMixin:
|
|||||||
def get_check_url(self, task_id, ajax):
|
def get_check_url(self, task_id, ajax):
|
||||||
return self.request.path + '?async_id=%s' % task_id + ('&ajax=1' if ajax else '')
|
return self.request.path + '?async_id=%s' % task_id + ('&ajax=1' if ajax else '')
|
||||||
|
|
||||||
def _ajax_response_data(self):
|
def _ajax_response_data(self, value):
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
def _return_ajax_result(self, res, timeout=.5):
|
def _return_ajax_result(self, res, timeout=.5):
|
||||||
@@ -85,7 +85,7 @@ class AsyncMixin:
|
|||||||
logger.warning('Ignored ResponseError in AsyncResult.get()')
|
logger.warning('Ignored ResponseError in AsyncResult.get()')
|
||||||
except ConnectionError:
|
except ConnectionError:
|
||||||
# Redis probably just restarted, let's just report not ready and retry next time
|
# Redis probably just restarted, let's just report not ready and retry next time
|
||||||
data = self._ajax_response_data()
|
data = self._ajax_response_data(None)
|
||||||
data.update({
|
data.update({
|
||||||
'async_id': res.id,
|
'async_id': res.id,
|
||||||
'ready': False
|
'ready': False
|
||||||
@@ -93,7 +93,7 @@ class AsyncMixin:
|
|||||||
return data
|
return data
|
||||||
|
|
||||||
state, info = res.state, res.info
|
state, info = res.state, res.info
|
||||||
data = self._ajax_response_data()
|
data = self._ajax_response_data(info)
|
||||||
data.update({
|
data.update({
|
||||||
'async_id': res.id,
|
'async_id': res.id,
|
||||||
'ready': ready,
|
'ready': ready,
|
||||||
|
|||||||
@@ -11,31 +11,31 @@
|
|||||||
<h2>{% trans "Review order" %}</h2>
|
<h2>{% trans "Review order" %}</h2>
|
||||||
{% include "pretixpresale/event/fragment_checkoutflow.html" %}
|
{% include "pretixpresale/event/fragment_checkoutflow.html" %}
|
||||||
<p>{% trans "Please review the details below and confirm your order." %}</p>
|
<p>{% trans "Please review the details below and confirm your order." %}</p>
|
||||||
|
<div class="panel panel-primary cart">
|
||||||
|
<div class="panel-heading panel-heading-flex">
|
||||||
|
<h3 class="panel-title">
|
||||||
|
<i class="fa fa-shopping-cart" aria-hidden="true"></i>
|
||||||
|
{% trans "Your cart" %}
|
||||||
|
<a href="{% eventurl request.event "presale:event.index" cart_namespace=cart_namespace|default_if_none:"" %}" class="h6">
|
||||||
|
<span class="fa fa-edit" aria-hidden="true"></span>{% trans "Add or remove tickets" %}
|
||||||
|
</a>
|
||||||
|
</h3>
|
||||||
|
<span class="panel-heading-flex-gap"></span>
|
||||||
|
<strong class="helper-display-block" id="cart-deadline-short" data-expires="{{ cart.first_expiry|date:"Y-m-d H:i:sO" }}">
|
||||||
|
{% if cart.minutes_left > 0 or cart.seconds_left > 0 %}
|
||||||
|
{{ cart.minutes_left|stringformat:"02d" }}:{{ cart.seconds_left|stringformat:"02d" }}
|
||||||
|
{% else %}
|
||||||
|
{% trans "Cart expired" %}
|
||||||
|
{% endif %}
|
||||||
|
</strong>
|
||||||
|
</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
{% include "pretixpresale/event/fragment_cart.html" with cart=cart event=request.event editable=False %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<form method="post" data-asynctask
|
<form method="post" data-asynctask
|
||||||
data-asynctask-headline="{% trans "Please hang tight, we're finalizing your order!" %}">
|
data-asynctask-headline="{% trans "Please hang tight, we're finalizing your order!" %}">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<div class="panel panel-primary cart">
|
|
||||||
<div class="panel-heading panel-heading-flex">
|
|
||||||
<h3 class="panel-title">
|
|
||||||
<i class="fa fa-shopping-cart" aria-hidden="true"></i>
|
|
||||||
{% trans "Your cart" %}
|
|
||||||
<a href="{% eventurl request.event "presale:event.index" cart_namespace=cart_namespace|default_if_none:"" %}" class="h6">
|
|
||||||
<span class="fa fa-edit" aria-hidden="true"></span>{% trans "Add or remove tickets" %}
|
|
||||||
</a>
|
|
||||||
</h3>
|
|
||||||
<span class="panel-heading-flex-gap"></span>
|
|
||||||
<strong class="helper-display-block" id="cart-deadline-short" data-expires="{{ cart.first_expiry|date:"Y-m-d H:i:sO" }}">
|
|
||||||
{% if cart.minutes_left > 0 or cart.seconds_left > 0 %}
|
|
||||||
{{ cart.minutes_left|stringformat:"02d" }}:{{ cart.seconds_left|stringformat:"02d" }}
|
|
||||||
{% else %}
|
|
||||||
{% trans "Cart expired" %}
|
|
||||||
{% endif %}
|
|
||||||
</strong>
|
|
||||||
</div>
|
|
||||||
<div class="panel-body">
|
|
||||||
{% include "pretixpresale/event/fragment_cart.html" with cart=cart event=request.event editable=False %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% if payments %}
|
{% if payments %}
|
||||||
<div class="panel panel-default">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
|
|||||||
@@ -492,10 +492,10 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
{% if not cart.is_ordered %}
|
{% if not cart.is_ordered %}
|
||||||
<form class="text-muted"
|
<form class="text-muted" id="cart-extend-form" data-asynctask data-asynctask-no-redirect
|
||||||
method="post" data-asynctask action="{% eventurl request.event "presale:event.cart.extend" cart_namespace=cart_namespace %}">
|
method="post" action="{% eventurl request.event "presale:event.cart.extend" cart_namespace=cart_namespace %}">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<span id="cart-deadline" data-expires="{{ cart.first_expiry|date:"Y-m-d H:i:sO" }}">
|
<span id="cart-deadline" data-expires="{{ cart.first_expiry|date:"Y-m-d H:i:sO" }}" data-max-expiry-extend="{{ cart.max_expiry_extend|date:"Y-m-d H:i:sO" }}">
|
||||||
{% if cart.minutes_left > 0 or cart.seconds_left > 0 %}
|
{% if cart.minutes_left > 0 or cart.seconds_left > 0 %}
|
||||||
{% blocktrans trimmed with minutes=cart.minutes_left %}
|
{% blocktrans trimmed with minutes=cart.minutes_left %}
|
||||||
The items in your cart are reserved for you for {{ minutes }} minutes.
|
The items in your cart are reserved for you for {{ minutes }} minutes.
|
||||||
|
|||||||
@@ -229,11 +229,13 @@ class CartMixin:
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
first_expiry = min(p.expires for p in positions) if positions else now()
|
first_expiry = min(p.expires for p in positions) if positions else now()
|
||||||
|
max_expiry_extend = min(p.max_extend for p in positions) if positions else now()
|
||||||
total_seconds_left = max(first_expiry - now(), timedelta()).total_seconds()
|
total_seconds_left = max(first_expiry - now(), timedelta()).total_seconds()
|
||||||
minutes_left = int(total_seconds_left // 60)
|
minutes_left = int(total_seconds_left // 60)
|
||||||
seconds_left = int(total_seconds_left % 60)
|
seconds_left = int(total_seconds_left % 60)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
first_expiry = None
|
first_expiry = None
|
||||||
|
max_expiry_extend = None
|
||||||
minutes_left = None
|
minutes_left = None
|
||||||
seconds_left = None
|
seconds_left = None
|
||||||
|
|
||||||
@@ -250,6 +252,7 @@ class CartMixin:
|
|||||||
'minutes_left': minutes_left,
|
'minutes_left': minutes_left,
|
||||||
'seconds_left': seconds_left,
|
'seconds_left': seconds_left,
|
||||||
'first_expiry': first_expiry,
|
'first_expiry': first_expiry,
|
||||||
|
'max_expiry_extend': max_expiry_extend,
|
||||||
'is_ordered': bool(order),
|
'is_ordered': bool(order),
|
||||||
'itemcount': sum(c.count for c in positions if not c.addon_to),
|
'itemcount': sum(c.count for c in positions if not c.addon_to),
|
||||||
'current_selected_payments': [p for p in self.current_selected_payments(total) if p.get('multi_use_supported')]
|
'current_selected_payments': [p for p in self.current_selected_payments(total) if p.get('multi_use_supported')]
|
||||||
|
|||||||
@@ -542,8 +542,11 @@ class CartExtendReservation(EventViewMixin, CartActionMixin, AsyncAction, View):
|
|||||||
task = extend_cart_reservation
|
task = extend_cart_reservation
|
||||||
known_errortypes = ['CartError']
|
known_errortypes = ['CartError']
|
||||||
|
|
||||||
|
def _ajax_response_data(self, value):
|
||||||
|
return value
|
||||||
|
|
||||||
def get_success_message(self, value):
|
def get_success_message(self, value):
|
||||||
if value > 0:
|
if value['success'] > 0:
|
||||||
return _('Your cart timeout was extended.')
|
return _('Your cart timeout was extended.')
|
||||||
|
|
||||||
def post(self, request, *args, **kwargs):
|
def post(self, request, *args, **kwargs):
|
||||||
@@ -561,7 +564,7 @@ class CartAdd(EventViewMixin, CartActionMixin, AsyncAction, View):
|
|||||||
def get_success_message(self, value):
|
def get_success_message(self, value):
|
||||||
return _('The products have been successfully added to your cart.')
|
return _('The products have been successfully added to your cart.')
|
||||||
|
|
||||||
def _ajax_response_data(self):
|
def _ajax_response_data(self, value):
|
||||||
cart_id = get_or_create_cart_id(self.request)
|
cart_id = get_or_create_cart_id(self.request)
|
||||||
return {
|
return {
|
||||||
'cart_id': cart_id,
|
'cart_id': cart_id,
|
||||||
|
|||||||
@@ -5,36 +5,58 @@ var async_task_check_url = null;
|
|||||||
var async_task_old_url = null;
|
var async_task_old_url = null;
|
||||||
var async_task_is_download = false;
|
var async_task_is_download = false;
|
||||||
var async_task_is_long = false;
|
var async_task_is_long = false;
|
||||||
|
var async_task_dont_redirect = false;
|
||||||
|
|
||||||
function async_task_check() {
|
|
||||||
|
var async_task_status_messages = {
|
||||||
|
long_task_started: gettext(
|
||||||
|
'Your request is currently being processed. Depending on the size of your event, this might take up to ' +
|
||||||
|
'a few minutes.'
|
||||||
|
),
|
||||||
|
long_task_pending: gettext(
|
||||||
|
'Your request has been queued on the server and will soon be ' +
|
||||||
|
'processed.'
|
||||||
|
),
|
||||||
|
short_task: gettext(
|
||||||
|
'Your request arrived on the server but we still wait for it to be ' +
|
||||||
|
'processed. If this takes longer than two minutes, please contact us or go ' +
|
||||||
|
'back in your browser and try again.'
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
function async_task_schedule_check(context, timeout) {
|
||||||
"use strict";
|
"use strict";
|
||||||
$.ajax(
|
async_task_timeout = window.setTimeout(function() {
|
||||||
{
|
$.ajax(
|
||||||
'type': 'GET',
|
{
|
||||||
'url': async_task_check_url,
|
'type': 'GET',
|
||||||
'success': async_task_check_callback,
|
'url': async_task_check_url,
|
||||||
'error': async_task_check_error,
|
'success': async_task_check_callback,
|
||||||
'context': this,
|
'error': async_task_check_error,
|
||||||
'dataType': 'json'
|
'context': context,
|
||||||
}
|
'dataType': 'json'
|
||||||
);
|
}
|
||||||
|
);
|
||||||
|
}, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
function async_task_on_success(data) {
|
function async_task_on_success(data) {
|
||||||
"use strict";
|
"use strict";
|
||||||
if (async_task_is_download && data.success) {
|
if ((async_task_is_download || async_task_dont_redirect) && data.success) {
|
||||||
waitingDialog.hide();
|
waitingDialog.hide();
|
||||||
if (location.href.indexOf("async_id") !== -1) {
|
if (location.href.indexOf("async_id") !== -1) {
|
||||||
history.replaceState({}, "pretix", async_task_old_url);
|
history.replaceState({}, "pretix", async_task_old_url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
location.href = data.redirect;
|
if (!async_task_dont_redirect)
|
||||||
|
location.href = data.redirect;
|
||||||
|
$(this).trigger('pretix:async-task-success', data);
|
||||||
}
|
}
|
||||||
|
|
||||||
function async_task_check_callback(data, textStatus, jqXHR) {
|
function async_task_check_callback(data, textStatus, jqXHR) {
|
||||||
"use strict";
|
"use strict";
|
||||||
if (data.ready && data.redirect) {
|
if (data.ready && data.redirect) {
|
||||||
async_task_on_success(data);
|
async_task_on_success.call(this, data);
|
||||||
return;
|
return;
|
||||||
} else if (typeof data.percentage === "number") {
|
} else if (typeof data.percentage === "number") {
|
||||||
$("#loadingmodal .progress").show();
|
$("#loadingmodal .progress").show();
|
||||||
@@ -55,7 +77,7 @@ function async_task_check_callback(data, textStatus, jqXHR) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
async_task_timeout = window.setTimeout(async_task_check, 250);
|
async_task_schedule_check(this, 250);
|
||||||
|
|
||||||
if (async_task_is_long) {
|
if (async_task_is_long) {
|
||||||
if (data.started) {
|
if (data.started) {
|
||||||
@@ -117,7 +139,7 @@ function async_task_check_error(jqXHR, textStatus, errorThrown) {
|
|||||||
// 500 can be an application error or overload in some cases :(
|
// 500 can be an application error or overload in some cases :(
|
||||||
$("#loadingmodal p.status").text(gettext('We currently cannot reach the server, but we keep trying.' +
|
$("#loadingmodal p.status").text(gettext('We currently cannot reach the server, but we keep trying.' +
|
||||||
' Last error code: {code}').replace(/\{code\}/, jqXHR.status));
|
' Last error code: {code}').replace(/\{code\}/, jqXHR.status));
|
||||||
async_task_timeout = window.setTimeout(async_task_check, 5000);
|
async_task_schedule_check(this, 5000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -126,12 +148,12 @@ function async_task_callback(data, jqXHR, status) {
|
|||||||
"use strict";
|
"use strict";
|
||||||
$("body").data('ajaxing', false);
|
$("body").data('ajaxing', false);
|
||||||
if (data.redirect) {
|
if (data.redirect) {
|
||||||
async_task_on_success(data);
|
async_task_on_success.call(this, data);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
async_task_id = data.async_id;
|
async_task_id = data.async_id;
|
||||||
async_task_check_url = data.check_url;
|
async_task_check_url = data.check_url;
|
||||||
async_task_timeout = window.setTimeout(async_task_check, 100);
|
async_task_schedule_check(this, 100);
|
||||||
|
|
||||||
if (async_task_is_long) {
|
if (async_task_is_long) {
|
||||||
if (data.started) {
|
if (data.started) {
|
||||||
@@ -160,9 +182,9 @@ function async_task_callback(data, jqXHR, status) {
|
|||||||
function async_task_error(jqXHR, textStatus, errorThrown) {
|
function async_task_error(jqXHR, textStatus, errorThrown) {
|
||||||
"use strict";
|
"use strict";
|
||||||
$("body").data('ajaxing', false);
|
$("body").data('ajaxing', false);
|
||||||
|
waitingDialog.hide();
|
||||||
if (textStatus === "timeout") {
|
if (textStatus === "timeout") {
|
||||||
alert(gettext("The request took too long. Please try again."));
|
alert(gettext("The request took too long. Please try again."));
|
||||||
waitingDialog.hide();
|
|
||||||
} else if (jqXHR.responseText.indexOf('<html') > 0) {
|
} else if (jqXHR.responseText.indexOf('<html') > 0) {
|
||||||
var respdom = $(jqXHR.responseText);
|
var respdom = $(jqXHR.responseText);
|
||||||
var c = respdom.filter('.container');
|
var c = respdom.filter('.container');
|
||||||
@@ -180,18 +202,14 @@ function async_task_error(jqXHR, textStatus, errorThrown) {
|
|||||||
|
|
||||||
} else if (c.length > 0) {
|
} else if (c.length > 0) {
|
||||||
// This is some kind of 500/404/403 page, show it in an overlay
|
// This is some kind of 500/404/403 page, show it in an overlay
|
||||||
waitingDialog.hide();
|
|
||||||
ajaxErrDialog.show(c.first().html());
|
ajaxErrDialog.show(c.first().html());
|
||||||
} else {
|
} else {
|
||||||
waitingDialog.hide();
|
|
||||||
alert(gettext('An error of type {code} occurred.').replace(/\{code\}/, jqXHR.status));
|
alert(gettext('An error of type {code} occurred.').replace(/\{code\}/, jqXHR.status));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (jqXHR.status >= 400 && jqXHR.status < 500) {
|
if (jqXHR.status >= 400 && jqXHR.status < 500) {
|
||||||
waitingDialog.hide();
|
|
||||||
alert(gettext('An error of type {code} occurred.').replace(/\{code\}/, jqXHR.status));
|
alert(gettext('An error of type {code} occurred.').replace(/\{code\}/, jqXHR.status));
|
||||||
} else {
|
} else {
|
||||||
waitingDialog.hide();
|
|
||||||
alert(gettext('We currently cannot reach the server. Please try again. ' +
|
alert(gettext('We currently cannot reach the server. Please try again. ' +
|
||||||
'Error code: {code}').replace(/\{code\}/, jqXHR.status));
|
'Error code: {code}').replace(/\{code\}/, jqXHR.status));
|
||||||
}
|
}
|
||||||
@@ -215,6 +233,7 @@ $(function () {
|
|||||||
}
|
}
|
||||||
async_task_id = null;
|
async_task_id = null;
|
||||||
async_task_is_download = $(this).is("[data-asynctask-download]");
|
async_task_is_download = $(this).is("[data-asynctask-download]");
|
||||||
|
async_task_dont_redirect = $(this).is("[data-asynctask-no-redirect]");
|
||||||
async_task_is_long = $(this).is("[data-asynctask-long]");
|
async_task_is_long = $(this).is("[data-asynctask-long]");
|
||||||
async_task_old_url = location.href;
|
async_task_old_url = location.href;
|
||||||
$("body").data('ajaxing', true);
|
$("body").data('ajaxing', true);
|
||||||
|
|||||||
@@ -33,8 +33,9 @@ var cart = {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var now = cart._get_now();
|
var now = cart._get_now();
|
||||||
var diff_minutes = Math.floor(cart._deadline.diff(now) / 1000 / 60);
|
var diff_total_seconds = cart._deadline.diff(now) / 1000;
|
||||||
var diff_seconds = Math.floor(cart._deadline.diff(now) / 1000 % 60);
|
var diff_minutes = Math.floor(diff_total_seconds / 60);
|
||||||
|
var diff_seconds = Math.floor(diff_total_seconds % 60);
|
||||||
|
|
||||||
if (diff_minutes < 2 || diff_minutes == 5) $("#cart-deadline").get(0).setAttribute("aria-live", "polite");
|
if (diff_minutes < 2 || diff_minutes == 5) $("#cart-deadline").get(0).setAttribute("aria-live", "polite");
|
||||||
else $("#cart-deadline").get(0).removeAttribute("aria-live");
|
else $("#cart-deadline").get(0).removeAttribute("aria-live");
|
||||||
@@ -45,6 +46,7 @@ var cart = {
|
|||||||
gettext("Cart expired")
|
gettext("Cart expired")
|
||||||
);
|
);
|
||||||
window.clearInterval(cart._deadline_interval);
|
window.clearInterval(cart._deadline_interval);
|
||||||
|
cart._deadline_interval = null;
|
||||||
} else {
|
} else {
|
||||||
$("#cart-deadline").text(ngettext(
|
$("#cart-deadline").text(ngettext(
|
||||||
"The items in your cart are reserved for you for one minute.",
|
"The items in your cart are reserved for you for one minute.",
|
||||||
@@ -56,13 +58,26 @@ var cart = {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
$("#cart-extend-button").toggle(diff_minutes < 3);
|
$("#cart-extend-button").toggle(diff_minutes < 3);
|
||||||
|
var can_extend_cart = diff_minutes < 3 && (diff_total_seconds < 0 || cart._deadline < cart._max_extend);
|
||||||
|
$("#cart-extend-button").toggle(can_extend_cart);
|
||||||
},
|
},
|
||||||
|
|
||||||
init: function () {
|
init: function () {
|
||||||
"use strict";
|
"use strict";
|
||||||
cart._deadline = moment($("#cart-deadline").attr("data-expires"));
|
|
||||||
cart._deadline_interval = window.setInterval(cart.draw_deadline, 500);
|
|
||||||
cart._calc_offset();
|
cart._calc_offset();
|
||||||
|
cart.set_deadline(
|
||||||
|
$("#cart-deadline").attr("data-expires"),
|
||||||
|
$("#cart-deadline").attr("data-max-expiry-extend")
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
set_deadline: function (expiry, max_extend) {
|
||||||
|
"use strict";
|
||||||
|
cart._expiry_notified = false;
|
||||||
|
cart._deadline = moment(expiry);
|
||||||
|
cart._max_extend = moment(max_extend);
|
||||||
|
if (!cart._deadline_interval)
|
||||||
|
cart._deadline_interval = window.setInterval(cart.draw_deadline, 500);
|
||||||
cart.draw_deadline();
|
cart.draw_deadline();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -74,6 +89,10 @@ $(function () {
|
|||||||
cart.init();
|
cart.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$("#cart-extend-form").on("pretix:async-task-success", function(e, data, x, y, z) {
|
||||||
|
cart.set_deadline(data.expiry, data.max_expiry_extend);
|
||||||
|
});
|
||||||
|
|
||||||
$(".toggle-container").each(function() {
|
$(".toggle-container").each(function() {
|
||||||
var summary = $(".toggle-summary", this);
|
var summary = $(".toggle-summary", this);
|
||||||
var content = $("> :not(.toggle-summary)", this);
|
var content = $("> :not(.toggle-summary)", this);
|
||||||
|
|||||||
Reference in New Issue
Block a user