More work on the content server tag browser

This commit is contained in:
Kovid Goyal 2016-01-29 12:29:50 +05:30
parent 0056aa177b
commit 7dda0e0e41
3 changed files with 42 additions and 3 deletions

View File

@ -123,6 +123,7 @@ def interface_data(ctx, rd):
key=lambda (field, name):sort_key(name)) key=lambda (field, name):sort_key(name))
ans['field_metadata'] = db.field_metadata.all_metadata() ans['field_metadata'] = db.field_metadata.all_metadata()
ans['icon_map'] = icon_map() ans['icon_map'] = icon_map()
ans['icon_path'] = ctx.url_for('/icon', which='')
mdata = ans['metadata'] = {} mdata = ans['metadata'] = {}
try: try:
extra_books = set(int(x) for x in rd.query.get('extra_books', '').split(',')) extra_books = set(int(x) for x in rd.query.get('extra_books', '').split(','))

View File

@ -10,6 +10,7 @@ from collections import namedtuple
from datetime import datetime, time from datetime import datetime, time
from functools import partial from functools import partial
from threading import Lock from threading import Lock
from urllib import quote
from calibre.constants import config_dir from calibre.constants import config_dir
from calibre.db.categories import Tag from calibre.db.categories import Tag
@ -140,7 +141,7 @@ def icon_map():
custom_icons = JSONConfig('gui').get('tags_browser_category_icons', {}) custom_icons = JSONConfig('gui').get('tags_browser_category_icons', {})
for k, v in custom_icons.iteritems(): for k, v in custom_icons.iteritems():
if os.access(os.path.join(config_dir, 'tb_icons', v), os.R_OK): if os.access(os.path.join(config_dir, 'tb_icons', v), os.R_OK):
_icon_map[k] = '_' + v _icon_map[k] = '_' + quote(v)
_icon_map['file_type_icons'] = { _icon_map['file_type_icons'] = {
k:'mimetypes/%s.png' % v for k, v in EXT_MAP.iteritems() k:'mimetypes/%s.png' % v for k, v in EXT_MAP.iteritems()
} }

View File

@ -2,7 +2,7 @@
# License: GPL v3 Copyright: 2015, Kovid Goyal <kovid at kovidgoyal.net> # License: GPL v3 Copyright: 2015, Kovid Goyal <kovid at kovidgoyal.net>
from ajax import ajax from ajax import ajax
from dom import clear from dom import clear, set_css
from elementmaker import E from elementmaker import E
from gettext import gettext as _ from gettext import gettext as _
from widgets import create_button, BUTTON_VPADDING, create_spinner from widgets import create_button, BUTTON_VPADDING, create_spinner
@ -17,6 +17,7 @@ class SearchPanel:
sp_counter += 1 sp_counter += 1
self.container_id = 'search-panel-' + sp_counter self.container_id = 'search-panel-' + sp_counter
self.interface_data = interface_data self.interface_data = interface_data
self.tag_path = []
style = '' style = ''
div = E.div( div = E.div(
id=self.container_id, style='display:none', id=self.container_id, style='display:none',
@ -99,10 +100,46 @@ class SearchPanel:
self.tag_browser_data = JSON.parse(xhr.responseText) self.tag_browser_data = JSON.parse(xhr.responseText)
except Exception as err: except Exception as err:
show_error(err + '') show_error(err + '')
container.innerHTML = 'Loaded' return
self.render_tag_browser(container, clear_path=True)
else: else:
show_error(xhr.error_html) show_error(xhr.error_html)
def render_tag_browser(self, container, clear_path=False):
if clear_path:
self.tag_path = []
clear(container)
set_css(container, padding='1rem', display='flex', flex_wrap='wrap')
parent = self.tag_browser_data.root
detailed_child = None
for child_index, state in self.tag_path:
q = parent.children and parent.children[child_index]
if not q:
break
parent, detailed_child = q, state
if detailed_child is not None and parent.children[detailed_child]:
self.render_child_menu(container, parent.children[detailed_child])
else:
self.render_children(container, parent.children)
def icon_for_node(self, node):
ans = self.interface_data.icon_map[node.category] or 'column.png'
return self.interface_data.icon_path + '/' + ans
def render_children(self, container, children):
item_map = self.tag_browser_data.item_map
for child in children:
node = item_map[child.id]
div = E.div(
E.div(
E.img(src=self.icon_for_node(node), style='vertical-align:middle; display:inline-block; max-height:4ex'),
'\xa0' + node.name)
)
set_css(div, max_width='45vw', border='solid 1px currentColor', border_radius='20px', margin='0.5rem', padding='1ex', cursor='pointer')
set_css(div.firstChild, position='relative', top='50%', transform='translateY(-50%)', margin_left='0.5rem')
container.appendChild(div)
@property @property
def container(self): def container(self):
return document.getElementById(self.container_id) return document.getElementById(self.container_id)