mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Cover grid view for the new server
This commit is contained in:
parent
eae610e465
commit
12d1d5c8c2
@ -573,6 +573,7 @@ def interface_data(ctx, rd, library_id):
|
||||
session = rd.session
|
||||
ans = {'session_data': {k:session[k] for k in defaults.iterkeys()}}
|
||||
ans['library_map'], ans['default_library'] = ctx.library_map
|
||||
ans['library_id'] = library_id or ans['default_library']
|
||||
sorts, orders = [], []
|
||||
for x in ans['session_data']['sort'].split(','):
|
||||
s, o = x.partition(':')[::2]
|
||||
|
@ -3,8 +3,10 @@
|
||||
|
||||
from book_list.theme import get_color
|
||||
from book_list.top_bar import TopBar
|
||||
from book_list.views import BooksView
|
||||
from dom import set_css
|
||||
from gettext import gettext as _
|
||||
from utils import debounce
|
||||
|
||||
class BarState:
|
||||
|
||||
@ -27,4 +29,9 @@ class BookList:
|
||||
self.states.append(ibs)
|
||||
self.top_bar = TopBar()
|
||||
self.top_bar.apply_state(ibs.left_state, ibs.buttons)
|
||||
self.books_view = BooksView(interface_data)
|
||||
ibs.left_state.run_animation = False
|
||||
window.addEventListener('resize', debounce(bind(self.on_resize, self), 250))
|
||||
|
||||
def on_resize(self):
|
||||
self.books_view.on_resize()
|
||||
|
102
src/pyj/book_list/views.pyj
Normal file
102
src/pyj/book_list/views.pyj
Normal file
@ -0,0 +1,102 @@
|
||||
# vim:fileencoding=utf-8
|
||||
# License: GPL v3 Copyright: 2015, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
from dom import set_css
|
||||
from elementmaker import E
|
||||
|
||||
bv_counter = 0
|
||||
THUMBNAIL_MAX_WIDTH = 300
|
||||
THUMBNAIL_MAX_HEIGHT = 400
|
||||
|
||||
class BooksView:
|
||||
|
||||
def __init__(self, interface_data):
|
||||
nonlocal bv_counter
|
||||
bv_counter += 1
|
||||
self.interface_data = interface_data
|
||||
self.search_result = interface_data['search_result']
|
||||
self.metadata_map = interface_data['metadata']
|
||||
self.container_id = 'books-view-' + bv_counter
|
||||
div = E.div(
|
||||
id=self.container_id, style='display:none',
|
||||
E.style(),
|
||||
E.div(),
|
||||
E.div(id='get-more-books')
|
||||
)
|
||||
document.body.appendChild(div)
|
||||
self.render_book = bind(self.cover_grid_item, self)
|
||||
self.init_grid = bind(self.init_cover_grid, self)
|
||||
self.resize_grid = bind(self.resize_cover_grid, self)
|
||||
self.mode = 'cover_grid'
|
||||
self.init_grid()
|
||||
self.render_ids()
|
||||
self.resize_grid()
|
||||
self.is_visible = True
|
||||
|
||||
@property
|
||||
def container(self):
|
||||
return document.getElementById(self.container_id)
|
||||
|
||||
@property
|
||||
def grid(self):
|
||||
return self.container.lastChild.previousSibling
|
||||
|
||||
@property
|
||||
def is_visible(self):
|
||||
self.container.style.display == 'block'
|
||||
|
||||
@is_visible.setter
|
||||
def is_visible(self, val):
|
||||
self.container.style.display = 'block' if val else 'none'
|
||||
|
||||
def clear(self):
|
||||
# We replace the div entirely so that any styles associated with it are
|
||||
# also removed
|
||||
c = self.container
|
||||
c.removeChild(self.grid)
|
||||
c.insertBefore(E.div(), c.lastChild)
|
||||
self.init_grid()
|
||||
|
||||
def init_cover_grid(self):
|
||||
div = self.grid
|
||||
set_css(div, display='flex', flex_wrap='wrap', justify_content='flex-start', align_items='flex-end', align_content='flex-start')
|
||||
self.cover_grid_width = self.cover_grid_height = -1
|
||||
|
||||
def resize_cover_grid(self):
|
||||
w, h = window.innerWidth, window.innerHeight
|
||||
if w <= h:
|
||||
# Portrait
|
||||
MAX_WIDTH, MIN_WIDTH = THUMBNAIL_MAX_WIDTH, THUMBNAIL_MAX_WIDTH // 2
|
||||
no_wider_than = (w - 50) // 2
|
||||
width = min(no_wider_than, MAX_WIDTH)
|
||||
width = max(width, MIN_WIDTH)
|
||||
height = int((4 / 3) * width)
|
||||
else:
|
||||
# Landscape
|
||||
MAX_HEIGHT, MIN_HEIGHT = THUMBNAIL_MAX_HEIGHT, THUMBNAIL_MAX_HEIGHT // 2
|
||||
no_taller_than = (h - 75) // 2
|
||||
height = min(no_taller_than, MAX_HEIGHT)
|
||||
height = max(height, MIN_HEIGHT)
|
||||
width = int((3 / 4) * height)
|
||||
width, height = width + 'px', height + 'px'
|
||||
for child in self.grid.childNodes:
|
||||
set_css(child, width=width, height=height)
|
||||
|
||||
def cover_grid_item(self, book_id):
|
||||
cover_url = str.format('get/thumb/{}/{}?sz={}x{}', book_id, self.interface_data['library_id'], THUMBNAIL_MAX_WIDTH, THUMBNAIL_MAX_HEIGHT)
|
||||
return E.div(
|
||||
style='margin: 10px; display: flex; align-content: flex-end; align-items: flex-end; justify-content: space-around',
|
||||
data_book_id=str(book_id),
|
||||
E.img(src=cover_url, style='max-width: 100%; max-height: 100%; display: block; cursor: pointer; width:auto; height:auto')
|
||||
)
|
||||
|
||||
def render_ids(self, book_ids=None):
|
||||
if book_ids is None:
|
||||
book_ids = self.search_result['book_ids']
|
||||
div = self.grid
|
||||
for book_id in book_ids:
|
||||
div.appendChild(self.render_book(book_id))
|
||||
|
||||
def on_resize(self):
|
||||
if self.resize_grid:
|
||||
self.resize_grid()
|
22
src/pyj/utils.pyj
Normal file
22
src/pyj/utils.pyj
Normal file
@ -0,0 +1,22 @@
|
||||
# vim:fileencoding=utf-8
|
||||
# License: GPL v3 Copyright: 2015, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
def debounce(func, wait, immediate=False):
|
||||
# Returns a function, that, as long as it continues to be invoked, will not
|
||||
# be triggered. The function will be called after it stops being called for
|
||||
# N milliseconds. If `immediate` is True, trigger the function on the
|
||||
# leading edge, instead of the trailing.
|
||||
timeout = None
|
||||
return def debounce_inner(): # noqa: unused-local
|
||||
nonlocal timeout
|
||||
context, args = this, arguments
|
||||
def later():
|
||||
nonlocal timeout
|
||||
timeout = None
|
||||
if not immediate:
|
||||
func.apply(context, args)
|
||||
call_now = immediate and not timeout
|
||||
window.clearTimeout(timeout)
|
||||
timeout = window.setTimeout(later, wait)
|
||||
if call_now:
|
||||
func.apply(context, args)
|
Loading…
x
Reference in New Issue
Block a user