1# vim:fileencoding=utf-8
2# License: GPL v3 Copyright: 2016, Kovid Goyal <kovid at kovidgoyal.net>
3from __python__ import hash_literals, bound_methods
4
5from dom import clear, set_css, build_rule
6from elementmaker import E
7from gettext import gettext as _
8
9
10COVER_GRID_CLASS = 'book-list-cover-grid'
11THUMBNAIL_MAX_WIDTH = 3 * 100
12THUMBNAIL_MAX_HEIGHT = 4 * 100
13THUMBNAIL_MIN_WIDTH = 3 * 35
14THUMBNAIL_MIN_HEIGHT = 4 * 35
15BORDER_RADIUS = 10
16
17
18def description():
19    return _('A grid of book covers')
20
21
22def cover_grid_css():
23    sel = '.' + COVER_GRID_CLASS
24    margin, margin_unit = 10, 'px'
25    ans = build_rule(sel, display='flex', flex_wrap='wrap', justify_content='space-around', align_items='flex-end',
26                     align_content='flex-start', user_select='none', overflow='hidden', margin_top=f'{margin / 2}{margin_unit}')
27
28    # Container for an individual cover
29    sel += ' > a'
30    ans += build_rule(
31        sel, margin=f'{margin}{margin_unit}', display='flex', align_content='flex-end', align_items='center', justify_content='space-around',
32        max_width=THUMBNAIL_MAX_WIDTH+'px', max_height=THUMBNAIL_MAX_HEIGHT+'px', cursor='pointer',
33        min_width=THUMBNAIL_MIN_WIDTH+'px', min_height=THUMBNAIL_MIN_HEIGHT + 'px')
34    mq =  '@media all and (orientation: {orient}) {{ {sel} {{ width: 21{dim}; height: 28{dim} }} }}\n'
35    for dim in 'vw', 'vh':
36        ans += mq.format(sel=sel, dim=dim, orient='portrait' if dim is 'vw' else 'landscape')
37    ans += build_rule(f'{sel}:hover', transform='scale(1.2)')
38    ans += build_rule(f'{sel}:active', transform='scale(2)')
39    ans += build_rule(sel + '.cover-grid-filler', height='0', max_height='0', min_height='0')
40
41    # Container for cover failed to load message
42    ans += build_rule(sel + ' > div', position='relative', top='-50%', transform='translateY(50%)', margin='0')
43
44    # The actual cover
45    sel += ' > img'
46    ans += build_rule(sel, max_width='100%', max_height='100%', display='block', width='auto', height='auto', border_radius=BORDER_RADIUS+'px')
47    return ans
48
49def init(container):
50    clear(container)
51    container.appendChild(E.div(class_=COVER_GRID_CLASS))
52    for i in range(12):
53        container.lastChild.appendChild(E.div(class_='cover-grid-filler'))
54
55def on_img_load(img, load_type):
56    div = img.parentNode
57    if not div:
58        return
59    if load_type is not 'load':
60        clear(div)
61        div.appendChild(E.div(
62            E.h2(img.dataset.title, style='text-align:center; font-size:larger; font-weight: bold'),
63            E.div(_('by'), style='text-align: center'),
64            E.h2(img.dataset.authors, style='text-align:center; font-size:larger; font-weight: bold')
65        ))
66        set_css(div, border='dashed 1px currentColor', border_radius=BORDER_RADIUS+'px')
67
68def create_item(book_id, metadata, create_image, show_book_details, href):
69    authors = metadata.authors.join(' & ') if metadata.authors else _('Unknown')
70    img = create_image(book_id, THUMBNAIL_MAX_WIDTH, THUMBNAIL_MAX_HEIGHT, on_img_load)
71    tooltip = _('{} by {}').format(metadata.title, authors)
72    img.setAttribute('alt', tooltip)
73    img.dataset.title, img.dataset.authors = metadata.title, authors
74    ans = E.a(img, onclick=show_book_details, title=tooltip, href=href)
75    return ans
76
77def append_item(container, item):
78    first_filler = container.lastChild.querySelector('.cover-grid-filler')
79    container.lastChild.insertBefore(item, first_filler)
80