Server and Viewer: Add support for dark themes in the UI

UI now uses dark colors when either the browser is in dark mode or the
viewer color theme is dark
This commit is contained in:
Kovid Goyal 2020-08-05 10:41:26 +05:30
parent 9283e58359
commit 57c0517508
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
2 changed files with 44 additions and 22 deletions

View File

@ -6,38 +6,46 @@ DARK = '#39322B'
LIGHT = '#F6F3E9'
LIGHT_DARKER = '#b6b3a8'
LIGHT_GRADIENT = 'linear-gradient(to bottom, {}, {})'.format(LIGHT, LIGHT_DARKER)
DT_DARK = '#2d2d2d'
DT_DARK_LIGHTER = '#777'
DT_LIGHT = '#ddd'
DARK_GRADIENT = 'linear-gradient(to bottom, {}, {})'.format(DT_DARK_LIGHTER, DT_DARK)
def c(light, dark):
return {'light': light, 'dark': dark or light}
DEFAULT_COLORS = {
# General colors
'window-background': LIGHT,
'window-background2': LIGHT_DARKER,
'window-foreground': DARK,
'window-error-foreground': 'red',
'window-hover-foreground': 'red',
'link-foreground': 'blue',
'window-background': c(LIGHT, DT_DARK),
'window-background2': c(LIGHT_DARKER, DT_DARK_LIGHTER),
'window-foreground': c(DARK, DT_LIGHT),
'window-error-foreground': c('red'),
'window-hover-foreground': c('red'),
'link-foreground': c('blue', '#6cb4ee'),
# Top bar specific colors
'bar-background': DARK,
'bar-foreground': LIGHT,
'bar-highlight': 'yellow',
'heart': '#B92111',
'bar-background': c(DARK, DT_DARK_LIGHTER),
'bar-foreground': c(LIGHT, DT_DARK),
'bar-highlight': c('yellow'),
'heart': c('#B92111'),
# Item list colors
'list-hover-background': DARK,
'list-hover-foreground': LIGHT,
'list-hover-background': c(DARK, DT_DARK_LIGHTER),
'list-hover-foreground': c(LIGHT, DT_DARK),
# Tree colors
'tree-highlight-item': LIGHT_DARKER,
'tree-highlight-item': c(LIGHT_DARKER, DT_DARK_LIGHTER),
# Button colors
'button-start': DARK,
'button-end': '#49423B',
'button-text': LIGHT,
'button-start': c(DARK, DT_LIGHT),
'button-end': c('#49423B', '#666'),
'button-text': c(LIGHT, DT_DARK),
# Dialog colors
'dialog-background': LIGHT,
'dialog-background-image': LIGHT_GRADIENT,
'dialog-foreground': DARK,
'dialog-background': c(LIGHT, DT_DARK),
'dialog-background-image': c(LIGHT_GRADIENT, DARK_GRADIENT),
'dialog-foreground': c(DARK, DT_LIGHT),
}
DEFAULT_SIZES = {
@ -50,10 +58,21 @@ DEFAULT_FONTS = {
'main': 'sans-serif'
}
def set_ui_colors(is_dark_theme):
attr = 'dark' if is_dark_theme else 'light'
s = document.documentElement.style
for k in DEFAULT_COLORS:
val = DEFAULT_COLORS[k][attr]
s.setProperty('--calibre-color-' + k, val)
def css_for_variables():
is_dark_theme = window.matchMedia('(prefers-color-scheme: dark)').matches
attr = 'dark' if is_dark_theme else 'light'
ans = v'[]'
for k in DEFAULT_COLORS:
val = DEFAULT_COLORS[k]
val = DEFAULT_COLORS[k][attr]
ans.push(f'--calibre-color-{k}: {val};')
return ':root { ' + ans.join('\n') + '}'

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 cached_color_to_rgba, get_color
from book_list.theme import cached_color_to_rgba, get_color, set_ui_colors
from dom import add_extra_css, build_rule, clear, set_css, svgicon, unique_id
from iframe_comm import IframeWrapper
from modals import error_dialog, warning_dialog
@ -295,9 +295,10 @@ class View:
,
}
entry_point = None if runtime.is_standalone_viewer else 'read_book.iframe'
self.current_color_scheme = resolve_color_scheme()
if runtime.is_standalone_viewer:
document.documentElement.addEventListener('keydown', self.handle_keypress, {'passive': False})
self.current_color_scheme = resolve_color_scheme()
set_ui_colors(self.current_color_scheme.is_dark_theme)
self.iframe_wrapper = IframeWrapper(
handlers, document.getElementById(iframe_id), entry_point, _('Bootstrapping book reader...'),
f'{runtime.FAKE_PROTOCOL}://{runtime.SANDBOX_HOST}/book/__index__')
@ -718,6 +719,8 @@ class View:
def apply_color_scheme(self):
self.current_color_scheme = ans = resolve_color_scheme()
if runtime.is_standalone_viewer:
set_ui_colors(self.current_color_scheme.is_dark_theme)
for which in 'left top right bottom'.split(' '):
m = document.getElementById('book-{}-margin'.format(which))
s = m.style