diff --git a/src/pretix/base/models/event.py b/src/pretix/base/models/event.py index b02c343af8..b35893a3dd 100644 --- a/src/pretix/base/models/event.py +++ b/src/pretix/base/models/event.py @@ -1004,6 +1004,11 @@ class Event(EventMixin, LoggedModel): | Q(date_to__gte=now() - timedelta(hours=24)) ) ) # order_by doesn't make sense with I18nField + if ordering in ("date_ascending", "date_descending"): + # if primary order is by date, then order in database + # this allows to limit/slice results + return subevs.order_by(*orderfields) + for f in reversed(orderfields): if f.startswith('-'): subevs = sorted(subevs, key=attrgetter(f[1:]), reverse=True) diff --git a/src/pretix/presale/views/widget.py b/src/pretix/presale/views/widget.py index 03ac67b60c..69ba1c906d 100644 --- a/src/pretix/presale/views/widget.py +++ b/src/pretix/presale/views/widget.py @@ -422,7 +422,10 @@ class WidgetAPIProductList(EventListMixin, View): data['list_type'] = list_type if hasattr(self.request, 'event') and data['list_type'] not in ("calendar", "week"): - if self.request.event.subevents.filter(date_from__gt=now()).count() > 50: + # only allow list-view of more than 50 subevents if ordering is by data as this can be done in the database + # ordering by name is currently not supported in database due to I18NField-JSON + ordering = self.request.event.settings.get('frontpage_subevent_ordering', default='date_ascending', as_type=str) + if ordering not in ("date_ascending", "date_descending") and self.request.event.subevents.filter(date_from__gt=now()).count() > 50: if self.request.event.settings.event_list_type not in ("calendar", "week"): self.request.event.settings.event_list_type = "calendar" data['list_type'] = list_type = 'calendar' @@ -537,10 +540,21 @@ class WidgetAPIProductList(EventListMixin, View): for d in data['days']: d['events'] = self._serialize_events(d['events'] or []) else: + offset = int(self.request.GET.get("offset", 0)) + limit = 50 if hasattr(self.request, 'event'): evs = self.request.event.subevents_sorted( filter_qs_by_attr(self.request.event.subevents_annotated(self.request.sales_channel.identifier), self.request) ) + ordering = self.request.event.settings.get('frontpage_subevent_ordering', default='date_ascending', as_type=str) + data['has_more_events'] = False + if ordering in ("date_ascending", "date_descending"): + # fetch one more result than needed to check if more events exist + evs = list(evs[offset:offset + limit + 1]) + if len(evs) > limit: + data['has_more_events'] = True + evs = evs[:limit] + tz = pytz.timezone(request.event.settings.timezone) if self.request.event.settings.event_list_available_only: evs = [ diff --git a/src/pretix/static/pretixpresale/js/widget/widget.js b/src/pretix/static/pretixpresale/js/widget/widget.js index 5bf266d285..fd15d132a0 100644 --- a/src/pretix/static/pretixpresale/js/widget/widget.js +++ b/src/pretix/static/pretixpresale/js/widget/widget.js @@ -53,6 +53,7 @@ var strings = { 'next_week': django.pgettext('widget', 'Next week'), 'previous_week': django.pgettext('widget', 'Previous week'), 'show_seating': django.pgettext('widget', 'Open seat selection'), + 'load_more': django.pgettext('widget', 'Load more'), 'days': { 'MO': django.gettext('Mo'), 'TU': django.gettext('Tu'), @@ -854,6 +855,8 @@ Vue.component('pretix-widget-event-form', { this.$root.target_url = this.$root.parent_stack.pop(); this.$root.error = null; this.$root.subevent = null; + this.$root.offset = 0; + this.$root.append_events = false; this.$root.trigger_load_callback(); if (this.$root.events !== undefined && this.$root.events !== null) { this.$root.view = "events"; @@ -938,9 +941,12 @@ Vue.component('pretix-widget-event-list', { + '' + '
' + '