Server: Use overlay buttons as next/prev on boo details page

See #1845417 ([Enhancement] Book details on calibre-server)
This commit is contained in:
Kovid Goyal 2019-09-26 11:55:23 +05:30
parent ff162a2b8f
commit 0641384bc7
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
4 changed files with 55 additions and 34 deletions

View File

@ -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)

View File

@ -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]

View File

@ -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

View File

@ -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()