mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Server: Use overlay buttons as next/prev on boo details page
See #1845417 ([Enhancement] Book details on calibre-server)
This commit is contained in:
parent
ff162a2b8f
commit
0641384bc7
@ -16,7 +16,7 @@ from book_list.library_data import (
|
|||||||
set_book_metadata
|
set_book_metadata
|
||||||
)
|
)
|
||||||
from book_list.router import back, home, open_book, report_a_load_failure
|
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.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.ui import query_as_href, set_panel_handler, show_panel
|
||||||
from book_list.views import search_query_for
|
from book_list.views import search_query_for
|
||||||
@ -382,6 +382,7 @@ def basic_table_rules(sel):
|
|||||||
add_extra_css(def():
|
add_extra_css(def():
|
||||||
sel = '.' + CLASS_NAME + ' '
|
sel = '.' + CLASS_NAME + ' '
|
||||||
style = basic_table_rules(sel)
|
style = basic_table_rules(sel)
|
||||||
|
style += build_rule(sel + ' .next-book-button:hover', transform='scale(1.5)')
|
||||||
|
|
||||||
sel = '.' + SEARCH_INTERNET_CLASS
|
sel = '.' + SEARCH_INTERNET_CLASS
|
||||||
style += build_rule(sel, margin='1ex 1em')
|
style += build_rule(sel, margin='1ex 1em')
|
||||||
@ -440,15 +441,40 @@ def render_book(container_id, book_id):
|
|||||||
set_title(c, metadata.title)
|
set_title(c, metadata.title)
|
||||||
authors = metadata.authors.join(' & ') if metadata.authors else _('Unknown')
|
authors = metadata.authors.join(' & ') if metadata.authors else _('Unknown')
|
||||||
alt = _('{} by {}\nClick to read').format(metadata.title, authors)
|
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(
|
E.img(
|
||||||
alt=alt, title=alt, data_title=metadata.title, data_authors=authors,
|
alt=alt, title=alt, data_title=metadata.title, data_authors=authors,
|
||||||
onclick=read_book.bind(None, book_id),
|
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
|
img = imgdiv.getElementsByTagName('img')[0]
|
||||||
imgdiv.firstChild.src = cover_url(book_id)
|
img.onerror = on_img_err
|
||||||
|
img.src = cover_url(book_id)
|
||||||
c = c.lastChild
|
c = c.lastChild
|
||||||
c.appendChild(E.div(
|
c.appendChild(E.div(
|
||||||
style='display:flex; padding: 1ex 1em; align-items: flex-start; justify-content: flex-start; flex-wrap: wrap',
|
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)
|
container.appendChild(md)
|
||||||
md.appendChild(table)
|
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)
|
render_metadata(metadata, table, book_id)
|
||||||
|
|
||||||
|
|
||||||
|
@ -50,9 +50,30 @@ DEFAULT_FONTS = {
|
|||||||
'main': 'sans-serif'
|
'main': 'sans-serif'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def get_color(name):
|
def get_color(name):
|
||||||
return DEFAULT_COLORS[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):
|
def get_font_size(name):
|
||||||
return DEFAULT_SIZES[name]
|
return DEFAULT_SIZES[name]
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ from gettext import gettext as _
|
|||||||
import read_book.iframe # noqa
|
import read_book.iframe # noqa
|
||||||
from ajax import ajax_send
|
from ajax import ajax_send
|
||||||
from book_list.globals import get_session_data
|
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 dom import add_extra_css, build_rule, set_css, svgicon, unique_id
|
||||||
from iframe_comm import IframeWrapper
|
from iframe_comm import IframeWrapper
|
||||||
from modals import error_dialog, warning_dialog
|
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 read_book.touch import set_left_margin_handler, set_right_margin_handler
|
||||||
from session import get_device_uuid, get_interface_data
|
from session import get_device_uuid, get_interface_data
|
||||||
from utils import (
|
from utils import (
|
||||||
color_to_rgba, html_escape, is_ios, parse_url_params, safe_set_inner_html,
|
html_escape, is_ios, parse_url_params, safe_set_inner_html, username_key
|
||||||
username_key
|
|
||||||
)
|
)
|
||||||
from viewer.constants import READER_BACKGROUND_URL
|
from viewer.constants import READER_BACKGROUND_URL
|
||||||
|
|
||||||
|
@ -242,17 +242,6 @@ def sandboxed_html(html, style, sandbox):
|
|||||||
return ans
|
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__':
|
if __name__ is '__main__':
|
||||||
from pythonize import strings
|
from pythonize import strings
|
||||||
strings()
|
strings()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user