diff --git a/src/pyj/book_list/book_details.pyj b/src/pyj/book_list/book_details.pyj index 31cfba1fea..2c217c5628 100644 --- a/src/pyj/book_list/book_details.pyj +++ b/src/pyj/book_list/book_details.pyj @@ -16,7 +16,7 @@ from book_list.library_data import ( set_book_metadata ) from book_list.router import back, home, open_book, report_a_load_failure -from book_list.theme import get_color, get_font_size +from book_list.theme import get_color, get_color_as_rgba, get_font_size from book_list.top_bar import add_button, clear_buttons, create_top_bar, set_title from book_list.ui import query_as_href, set_panel_handler, show_panel from book_list.views import search_query_for @@ -382,6 +382,7 @@ def basic_table_rules(sel): add_extra_css(def(): sel = '.' + CLASS_NAME + ' ' style = basic_table_rules(sel) + style += build_rule(sel + ' .next-book-button:hover', transform='scale(1.5)') sel = '.' + SEARCH_INTERNET_CLASS style += build_rule(sel, margin='1ex 1em') @@ -440,15 +441,40 @@ def render_book(container_id, book_id): set_title(c, metadata.title) authors = metadata.authors.join(' & ') if metadata.authors else _('Unknown') alt = _('{} by {}\nClick to read').format(metadata.title, authors) - imgdiv = E.div( + bsrgb = get_color_as_rgba('button-start') + + def next_book(delta): + next_book_id = book_after(book_id, delta) + if next_book_id: + q = parse_url_params() + q.book_id = next_book_id + '' + show_panel('book_details', query=q, replace=True) + + def prev_next_button(is_prev): + return E.div( + style=f'border-radius: {border_radius//5}px; background-color:rgba({bsrgb[0]}, {bsrgb[1]}, {bsrgb[2]}, 0.75);', + title=_('Previous book') if is_prev else _('Next book'), + class_='simple-link next-book-button', + svgicon('chevron-left' if is_prev else 'chevron-right'), + onclick=next_book.bind(None, (-1 if is_prev else 1)) + ) + + border_radius = 20 + imgdiv = E.div(style='position: relative', E.img( alt=alt, title=alt, data_title=metadata.title, data_authors=authors, onclick=read_book.bind(None, book_id), - style='cursor: pointer; border-radius: 20px; max-width: calc(100vw - 2em); max-height: calc(100vh - 4ex - {}); display: block; width:auto; height:auto; border-radius: 20px'.format(get_font_size('title') - )) + style='cursor: pointer; border-radius: 20px; max-width: calc(100vw - 2em); max-height: calc(100vh - 4ex - {}); display: block; width:auto; height:auto; border-radius: {}px'.format(get_font_size('title'), border_radius + )), + E.div( + style=f'position: absolute; top:0; width: 100%; padding: {border_radius//2}px; box-sizing: border-box; font-size: 2rem; display: flex; justify-content: space-between; color: {get_color("button-text")}', + prev_next_button(True), + prev_next_button(), + ), ) - imgdiv.firstChild.onerror = on_img_err - imgdiv.firstChild.src = cover_url(book_id) + img = imgdiv.getElementsByTagName('img')[0] + img.onerror = on_img_err + img.src = cover_url(book_id) c = c.lastChild c.appendChild(E.div( style='display:flex; padding: 1ex 1em; align-items: flex-start; justify-content: flex-start; flex-wrap: wrap', @@ -470,20 +496,6 @@ def render_book(container_id, book_id): container.appendChild(md) md.appendChild(table) - def next_book(delta): - next_book_id = book_after(book_id, delta) - if next_book_id: - q = parse_url_params() - q.book_id = next_book_id + '' - show_panel('book_details', query=q, replace=True) - - md.appendChild(E.div( - style='margin-top: 1.5ex', - create_button(_('Previous'), 'arrow-left', next_book.bind(None, -1)), - '\xa0\xa0\xa0', - create_button(_('Next'), 'arrow-right', next_book.bind(None, 1)), - )) - render_metadata(metadata, table, book_id) diff --git a/src/pyj/book_list/theme.pyj b/src/pyj/book_list/theme.pyj index 394ae3ceac..ddd4d7da54 100644 --- a/src/pyj/book_list/theme.pyj +++ b/src/pyj/book_list/theme.pyj @@ -50,9 +50,30 @@ DEFAULT_FONTS = { 'main': 'sans-serif' } + def get_color(name): return DEFAULT_COLORS[name] + +def color_to_rgba(color): + # take an arbitrary color spec and return it as [r, g, b, a] + cvs = document.createElement('canvas') + cvs.height = 1 + cvs.width = 1 + ctx = cvs.getContext('2d') + ctx.fillStyle = color + ctx.fillRect(0, 0, 1, 1) + return ctx.getImageData(0, 0, 1, 1).data + + +def get_color_as_rgba(name): + cache = get_color_as_rgba.cache + if not cache[name]: + cache[name] = color_to_rgba(get_color(name)) + return cache[name] +get_color_as_rgba.cache = {} + + def get_font_size(name): return DEFAULT_SIZES[name] diff --git a/src/pyj/read_book/view.pyj b/src/pyj/read_book/view.pyj index cf55baa25d..993265e027 100644 --- a/src/pyj/read_book/view.pyj +++ b/src/pyj/read_book/view.pyj @@ -8,7 +8,7 @@ from gettext import gettext as _ import read_book.iframe # noqa from ajax import ajax_send from book_list.globals import get_session_data -from book_list.theme import get_color +from book_list.theme import color_to_rgba, get_color from dom import add_extra_css, build_rule, set_css, svgicon, unique_id from iframe_comm import IframeWrapper from modals import error_dialog, warning_dialog @@ -30,8 +30,7 @@ from read_book.toc import get_current_toc_nodes, update_visible_toc_nodes from read_book.touch import set_left_margin_handler, set_right_margin_handler from session import get_device_uuid, get_interface_data from utils import ( - color_to_rgba, html_escape, is_ios, parse_url_params, safe_set_inner_html, - username_key + html_escape, is_ios, parse_url_params, safe_set_inner_html, username_key ) from viewer.constants import READER_BACKGROUND_URL diff --git a/src/pyj/utils.pyj b/src/pyj/utils.pyj index cde25310a0..9903fd9d26 100644 --- a/src/pyj/utils.pyj +++ b/src/pyj/utils.pyj @@ -242,17 +242,6 @@ def sandboxed_html(html, style, sandbox): return ans -def color_to_rgba(color): - # take an arbitrary color spec and return it as [r, g, b, a] - cvs = document.createElement('canvas') - cvs.height = 1 - cvs.width = 1 - ctx = cvs.getContext('2d') - ctx.fillStyle = color - ctx.fillRect(0, 0, 1, 1) - return ctx.getImageData(0, 0, 1, 1).data - - if __name__ is '__main__': from pythonize import strings strings()