diff --git a/src/pyj/book_list/views.pyj b/src/pyj/book_list/views.pyj index f45809546a..3b67b652e8 100644 --- a/src/pyj/book_list/views.pyj +++ b/src/pyj/book_list/views.pyj @@ -2,11 +2,16 @@ # License: GPL v3 Copyright: 2015, Kovid Goyal from __python__ import hash_literals -from dom import add_extra_css, clear, ensure_id +import traceback + +from ajax import ajax_send +from dom import add_extra_css, clear, ensure_id, set_css from elementmaker import E from gettext import gettext as _ +from modals import error_dialog from utils import conditional_timeout from session import get_interface_data +from widgets import create_button, create_spinner from book_list.globals import get_session_data from book_list.cover_grid import cover_grid_css, create_item as create_cover_grid_item, init as init_cover_grid, append_item as cover_grid_append_item @@ -24,7 +29,7 @@ add_extra_css(def(): ) book_list_data = { - 'container_id': None, 'shown_book_ids': set(), 'is_fetching': False, 'mode': None, + 'container_id': None, 'shown_book_ids': set(), 'mode': None, 'fetching_more_books': None, } @@ -71,14 +76,81 @@ def apply_view_mode(mode=DEFAULT_MODE): render_ids() +def update_fetching_status(): + more = document.getElementById(book_list_data.container_id).lastChild + if book_list_data.fetching_more_books: + more.firstChild.style.display = 'none' + more.lastChild.style.display = 'block' + elif library_data.search_result.total_num > book_list_data.shown_book_ids.length: + more.firstChild.style.display = 'block' + more.lastChild.style.display = 'none' + else: + more.firstChild.style.display = 'none' + more.lastChild.style.display = 'none' + + +def abort_get_more_books(no_update): + if book_list_data.fetching_more_books: + book_list_data.fetching_more_books.abort() + book_list_data.fetching_more_books = None + if not no_update: + update_fetching_status() + + +def got_more_books(end_type, xhr, event): + if book_list_data.fetching_more_books is not xhr: + return # Fetching was aborted + book_list_data.fetching_more_books = None + update_fetching_status() + if end_type is 'load': + try: + data = JSON.parse(xhr.responseText) + for key in data.metadata: + library_data.metadata[key] = data.metadata[key] + if not data.search_result.book_ids: + raise Exception('No books ids object in search result from server') + library_data.search_result = data.search_result + render_ids(data.search_result.book_ids) + except Exception: + error_dialog(_('Could not get more books'), _('Server returned an invalid response'), traceback.format_exc()) + elif end_type is not 'abort': + error_dialog(_('Could not get more books'), xhr.error_html) + + +def get_more_books(): + data = {'offset':book_list_data.shown_book_ids.length} + for key in 'query', 'sort', 'sort_order': + data[key] = library_data.search_result[key] + book_list_data.fetching_more_books = ajax_send( + 'interface-data/more-books', data, got_more_books, + query={'library_id':current_library_id()} + ) + update_fetching_status() + + +def create_more_button(more): + more.appendChild(create_button( + _('Show more books'), 'cloud-download', get_more_books + )) + more.lastChild.setAttribute('rel', 'next') + set_css(more.firstChild, display='block', margin_left='auto', margin_right='auto') + set_css(more, font_size='1.5rem', padding_top='1.5rem', margin_bottom='1.5rem', text_align='center', display='flex') + more.appendChild(E.div( + create_spinner(), '\xa0' + _('Fetching metadata for more books, please wait') + '…', + style='margin-left:auto; margin-right:auto; display:none') + ) + update_fetching_status() + + def create_books_list(container): book_list_data.container_id = ensure_id(container) book_list_data.shown_book_ids = set() - book_list_data.is_fetching = False book_list_data.mode = None + abort_get_more_books(True) container.appendChild(E.div(style='display:none')) container.appendChild(E.div()), container.appendChild(E.div()) apply_view_mode(get_session_data().get('view_mode')) + create_more_button(container.lastChild) def check_for_books_loaded():