Infinite scroll enhancements.

see #585
This commit is contained in:
Antoine Nguyen
2014-10-15 11:06:35 +02:00
parent a5210de1e6
commit e102ac0292
11 changed files with 70 additions and 58 deletions
+1 -1
View File
@@ -143,7 +143,7 @@ def logs_page(request, tplname="core/logs_page.html"):
else:
context = {
"rows": render_to_string(tplname, {"logs": page.object_list}),
"page": page.number
"pages": [page.number]
}
return render_to_json_response(context)
+1 -1
View File
@@ -71,7 +71,7 @@ def _domains(request):
'domains': page.object_list,
}
)
context["page"] = page.number
context["pages"] = [page.number]
return render_to_json_response(context)
+1 -1
View File
@@ -60,7 +60,7 @@ def _identities(request):
"identities": page.object_list
}
)
context["page"] = page.number
context["pages"] = [page.number]
return render_to_json_response(context)
@@ -83,7 +83,6 @@ Quarantine.prototype = {
$(this.options.scroll_container).scrollTop(10);
} else {
this.update_listing(data, false);
$(this.options.scroll_container).infinite_scroll("pause");
}
},
+30 -24
View File
@@ -27,15 +27,15 @@ from .sql_connector import get_connector
from .sql_listing import SQLemail
def empty_quarantine(request):
def empty_quarantine():
"""Shortcut to use when no content can be displayed."""
content = "<div class='alert alert-info'>%s</div>" % _("Empty quarantine")
ctx = getctx("ok", level=2, listing=content)
return render_to_json_response(ctx)
def get_listing_page(request, connector):
"""."""
def get_listing_pages(request, connector):
"""Return listing pages."""
paginator = Paginator(
connector.messages_count(),
int(parameters.get_user(request.user, "MESSAGES_PER_PAGE"))
@@ -44,7 +44,13 @@ def get_listing_page(request, connector):
page = paginator.getpage(page_id)
if not page:
return None
return page
pages = [page]
if not page.has_next and page.has_previous and page.items < 40:
pages = [paginator.getpage(page_id - 1)] + pages
email_list = []
for page in pages:
email_list += connector.fetch(page.id_start, page.id_stop)
return {"pages": [page.number for page in pages], "rows": email_list}
@login_required
@@ -55,42 +61,42 @@ def listing_page(request):
navparams.store()
connector = get_connector(user=request.user, navparams=navparams)
page = get_listing_page(request, connector)
if page is None:
context = get_listing_pages(request, connector)
if context is None:
context = {"length": 0}
navparams["page"] = previous_page_id
else:
context = {
"rows": _render_to_string(request, "amavis/emails_page.html", {
"email_list": connector.fetch(page.id_start, page.id_stop)
}),
"page": page.number
}
context["rows"] = _render_to_string(
request, "amavis/emails_page.html", {"email_list": context["rows"]}
)
return render_to_json_response(context)
@login_required
def _listing(request):
"""Listing initial view.
Called the first time the listing page is displayed.
"""
if not request.user.is_superuser and request.user.group != 'SimpleUsers':
if not Domain.objects.get_for_admin(request.user).count():
return empty_quarantine(request)
return empty_quarantine()
navparams = QuarantineNavigationParameters(request)
navparams.store()
connector = get_connector(user=request.user, navparams=navparams)
page = get_listing_page(request, connector)
if page is None:
return empty_quarantine(request)
content = _render_to_string(request, "amavis/email_list.html", {
"email_list": connector.fetch(page.id_start, page.id_stop),
})
ctx = getctx("ok", listing=content, page=page.number)
context = get_listing_pages(request, connector)
if context is None:
return empty_quarantine()
context["listing"] = _render_to_string(
request, "amavis/email_list.html", {"email_list": context["rows"]}
)
del context["rows"]
if request.session.get('location', 'listing') != 'listing':
ctx['menu'] = quar_menu()
request.session['location'] = 'listing'
return render_to_json_response(ctx)
context["menu"] = quar_menu()
request.session["location"] = "listingx"
return render_to_json_response(context)
@login_required
+4 -2
View File
@@ -664,7 +664,7 @@ class IMAPconnector(object):
attdef = bs.find_attachment(partnum)
return attdef, data[int(uid)]["BODY[%s]" % partnum]
def fetch(self, start, stop=None, mbox=None, **kwargs):
def fetch(self, start, stop=None, mbox=None):
"""Retrieve information about messages from the server
Issue a FETCH command to retrieve information about one or
@@ -685,7 +685,9 @@ class IMAPconnector(object):
data = self._cmd("FETCH", range, query)
result = []
for uid in submessages:
msg = email.message_from_string(data[int(uid)]['BODY[HEADER.FIELDS (DATE FROM TO CC SUBJECT)]'])
msg = email.message_from_string(
data[int(uid)]['BODY[HEADER.FIELDS (DATE FROM TO CC SUBJECT)]']
)
msg['imapid'] = uid
if not r'\Seen' in data[int(uid)]['FLAGS']:
msg['style'] = 'unseen'
@@ -172,15 +172,16 @@ Webmail.prototype = {
var that = this;
if ($container.data("infinite-scroll") !== undefined) {
$container.scrollTop(10);
$container.infinite_scroll(
"reset_loaded_pages", parseInt(data.page));
if (data.pages && data.pages[0] != 1) {
$container.scrollTop(10);
}
$container.infinite_scroll("reset_loaded_pages", data.pages);
$container.infinite_scroll("resume");
return;
}
$container.infinite_scroll({
initial_page: parseInt(data.page),
initial_pages: data.pages,
url: this.options.listing_url,
calculate_bottom: function($element) {
return $("#emails").height() - $element.height();
+8 -9
View File
@@ -127,7 +127,7 @@ def empty(request):
get_imapconnector(request).empty(name)
content = "<div class='alert alert-info'>%s</div>" % _("Empty mailbox")
return render_to_json_response({
'listing': content, 'mailbox': name
'listing': content, 'mailbox': name, 'pages': [1]
})
@@ -357,11 +357,9 @@ def listmailbox(request, defmailbox="INBOX", update_session=True):
int(parameters.get_user(request.user, "MESSAGES_PER_PAGE"))
)
page = paginator.getpage(page_id)
content = ""
if page is not None:
email_list = mbc.fetch(
page.id_start, page.id_stop, mbox, nbelems=page.items
)
email_list = mbc.fetch(page.id_start, page.id_stop, mbox)
content = _render_to_string(request, "webmail/email_list.html", {
"email_list": email_list,
"page": page_id,
@@ -369,12 +367,13 @@ def listmailbox(request, defmailbox="INBOX", update_session=True):
})
length = len(content)
else:
content = "<div class='alert alert-info'>{}</div>".format(
_("Empty mailbox")
)
if page_id == 1:
content = "<div class='alert alert-info'>{}</div>".format(
_("Empty mailbox")
)
length = 0
navparams["page"] = previous_page_id
return {"listing": content, "length": length, "page": page_id}
return {"listing": content, "length": length, "pages": [page_id]}
def render_compose(request, form, posturl, email=None, insert_signature=False):
+4 -4
View File
@@ -25,8 +25,8 @@ class Page(object):
@property
def items(self):
"""The total number of items. (shortcut)"""
return self.paginator.total
"""The number of items in this page."""
return self.id_stop - self.id_start
@property
def has_previous(self):
@@ -61,10 +61,10 @@ class Page(object):
@property
def last_page(self):
"""Retrieve the id of the last page."""
lid = self.items / self.items_per_page
lid = self.paginator.total / self.items_per_page
if not lid:
return 1
if self.items % self.items_per_page:
if self.paginator.total % self.items_per_page:
lid += 1
return lid
+13 -9
View File
@@ -20,10 +20,14 @@
this.$options = options;
this.executing = false;
this.end_of_results = false;
this.current_page = (isNaN(this.$options.initial_page)) ?
1 : this.$options.initial_page;
this.loaded_pages = [this.current_page];
if (this.$options.initial_pages !== undefined &&
this.$options.initial_pages.length > 0) {
this.current_page = this.$options.initial_pages[0];
this.loaded_pages = this.$options.initial_pages;
} else {
this.current_page = 1;
this.loaded_pages = [this.current_page];
}
this.resume();
};
@@ -38,7 +42,7 @@
on_scroll: function() {
var bottom = this.$options.calculate_bottom(this.$element);
if (bottom === undefined) {
if (bottom === undefined || bottom < 0) {
return;
}
if (this.$element.scrollTop() >= bottom) {
@@ -128,11 +132,11 @@
* Reset the loaded pages cache.
*
* @this InfiniteScroll
* @param {Array} current_page - the new current_page
* @param {Array} new_pages - the new loaded pages
*/
reset_loaded_pages: function(current_page) {
this.current_page = current_page;
this.loaded_pages = [this.current_page];
reset_loaded_pages: function(new_pages) {
this.current_page = new_pages[0];
this.loaded_pages = new_pages;
this.end_of_results = false;
},
+3 -2
View File
@@ -136,7 +136,7 @@ Listing.prototype = {
*/
end_of_list_reached: function(element) {
$("#" + this.options.main_table_id).after(
$("<div class='alert alert-info'>{0}</div>".format(
$("<div class='alert alert-info text-center'>{0}</div>".format(
this.options.eor_message
))
);
@@ -156,10 +156,11 @@ Listing.prototype = {
$scroll_container.scrollTop(0);
if (with_infinite_scroll || with_infinite_scroll === undefined) {
if ($scroll_container.data("infinite-scroll") !== undefined) {
$scroll_container.infinite_scroll("reset_loaded_pages", data.page);
$scroll_container.infinite_scroll("reset_loaded_pages", data.pages);
$scroll_container.infinite_scroll("resume");
} else {
$scroll_container.infinite_scroll({
initial_pages: data.pages,
url: this.options.load_page_url,
get_args: $.proxy(this.get_load_page_args, this),
calculate_bottom: $.proxy(this.calculate_bottom, this),