mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Various cleanups
Use theme based background colors. Dont use ids for components. Change the tolltip of the play/pause button dynamically
This commit is contained in:
parent
8aa13dd2e7
commit
264bb9917c
@ -104,11 +104,18 @@ def create_keyframes(animation_name, *frames):
|
|||||||
ans.push('}')
|
ans.push('}')
|
||||||
return ans.join('\n') + '\n'
|
return ans.join('\n') + '\n'
|
||||||
|
|
||||||
def change_icon_image(icon_element, new_name):
|
def change_icon_image(icon_element, new_name, tooltip):
|
||||||
if new_name:
|
if new_name:
|
||||||
icon_element.firstChild.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', '#icon-' + new_name)
|
icon_element.firstChild.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', '#icon-' + new_name)
|
||||||
else:
|
else:
|
||||||
icon_element.firstChild.removeAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href')
|
icon_element.firstChild.removeAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href')
|
||||||
|
if tooltip?:
|
||||||
|
x = icon_element.getElementsByTagNameNS('http://www.w3.org/2000/svg', 'title')
|
||||||
|
if not x.length:
|
||||||
|
tt = document.createElementNS('http://www.w3.org/2000/svg', 'title')
|
||||||
|
icon_element.appendChild(tt)
|
||||||
|
x = v'[tt]'
|
||||||
|
x[0].textContent = tooltip
|
||||||
|
|
||||||
def svgicon(name, height, width, tooltip):
|
def svgicon(name, height, width, tooltip):
|
||||||
ans = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
|
ans = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
|
||||||
|
@ -12,7 +12,8 @@ from __python__ import bound_methods, hash_literals
|
|||||||
|
|
||||||
from elementmaker import E
|
from elementmaker import E
|
||||||
|
|
||||||
from dom import change_icon_image, svgicon, unique_id
|
from book_list.theme import get_color
|
||||||
|
from dom import change_icon_image, svgicon
|
||||||
from gettext import gettext as _
|
from gettext import gettext as _
|
||||||
from modals import error_dialog
|
from modals import error_dialog
|
||||||
from read_book.globals import ui_operations
|
from read_book.globals import ui_operations
|
||||||
@ -26,6 +27,13 @@ from read_book.smil import (
|
|||||||
HIDDEN, PLAYING, PAUSED = 'HIDDEN', 'PLAYING', 'PAUSED'
|
HIDDEN, PLAYING, PAUSED = 'HIDDEN', 'PLAYING', 'PAUSED'
|
||||||
|
|
||||||
|
|
||||||
|
def seconds_to_ms(seconds):
|
||||||
|
minutes = Math.floor(seconds / 60)
|
||||||
|
remaining_seconds = int(seconds % 60)
|
||||||
|
return str(minutes) + ':' + (str(remaining_seconds).zfill(2))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class ReadAudioEbook:
|
class ReadAudioEbook:
|
||||||
|
|
||||||
dont_hide_on_content_loaded = True
|
dont_hide_on_content_loaded = True
|
||||||
@ -40,22 +48,21 @@ class ReadAudioEbook:
|
|||||||
if self.initialized:
|
if self.initialized:
|
||||||
return
|
return
|
||||||
self.initialized = True
|
self.initialized = True
|
||||||
self.bar_id = unique_id("bar")
|
|
||||||
|
|
||||||
container = self.container
|
container = self.container
|
||||||
container.style.transition = "height 0.5s ease-in-out"
|
container.style.transition = "height 0.5s ease-in-out"
|
||||||
container.style.backgroundColor = "rgba(127, 127, 127, 0.05)"
|
container.style.backgroundColor = "rgba(127, 127, 127, 0.05)"
|
||||||
container.setAttribute("tabindex", "0")
|
container.setAttribute("tabindex", "0")
|
||||||
|
bg = get_color("window-background")
|
||||||
container.appendChild(E.div(
|
container.appendChild(E.div(
|
||||||
id=self.bar_id,
|
data_component='bar',
|
||||||
style="position: absolute; bottom: 0; width: 90%; height: 2em; border-radius: 1em; padding:0.5em; display: flex; justify-content: center; align-items: center; background-color: rgba(127, 127, 127, 0.3); "
|
style=f'position: absolute; bottom: 0; width: 90%; height: 2em; border-radius: 1em; padding:0.5em; display: flex; justify-content: center; align-items: center; background-color: {bg};'
|
||||||
))
|
))
|
||||||
|
bar_container = container.lastChild
|
||||||
container.addEventListener("keydown", self.on_keydown, {"passive": False})
|
container.addEventListener("keydown", self.on_keydown, {"passive": False})
|
||||||
container.addEventListener("click", self.on_container_clicked, {"passive": False})
|
container.addEventListener("click", self.on_container_clicked, {"passive": False})
|
||||||
container.addEventListener("contextmenu", self.toggle, {"passive": False})
|
container.addEventListener("contextmenu", self.toggle, {"passive": False})
|
||||||
|
|
||||||
bar_container = self.bar = document.getElementById(self.bar_id)
|
|
||||||
|
|
||||||
def create_button(name, icon, text):
|
def create_button(name, icon, text):
|
||||||
ans = svgicon(icon, ICON_SIZE, ICON_SIZE, text)
|
ans = svgicon(icon, ICON_SIZE, ICON_SIZE, text)
|
||||||
if name:
|
if name:
|
||||||
@ -71,37 +78,29 @@ class ReadAudioEbook:
|
|||||||
|
|
||||||
for x in [
|
for x in [
|
||||||
E.div (
|
E.div (
|
||||||
id="audioButtons",
|
|
||||||
style='height: 3ex; display: flex; align-items: center; justify-content: center',
|
style='height: 3ex; display: flex; align-items: center; justify-content: center',
|
||||||
create_button("toggle", "pause", _("Toggle pause & play")),
|
create_button("toggle", "pause", _('Pause audio')),
|
||||||
),
|
),
|
||||||
E.div(
|
E.div(
|
||||||
id="timeDisplay",
|
data_component="time_display", E.text("")
|
||||||
E.text("")
|
|
||||||
),
|
),
|
||||||
E.div(
|
E.div(
|
||||||
id="progressBar",
|
data_component="progress_bar",
|
||||||
style="height:1.5em; display:block; background-color:rgba(255, 255, 255, 0.7); width:70%; margin:1em",
|
style=f'height:1.5em; display:block; background-color:{get_color("window-background2")}; width:70%; margin:1em',
|
||||||
E.div(
|
E.div(style=f'display:block; background-color:{get_color("window-foreground")}; height:100%'),
|
||||||
style="display:block; background-color:rgba(0, 0, 0, 0.3); height:100%")
|
|
||||||
),
|
),
|
||||||
E.div(
|
E.div(
|
||||||
style='height: 3ex; display: flex; align-items: center; justify-content: center',
|
style='height: 3ex; display: flex; align-items: center; justify-content: center',
|
||||||
create_button("slower", "slower", _("Slow down audio")),
|
create_button("slower", "slower", _("Slow down audio")),
|
||||||
create_button("faster", "faster", _("Speed up audio")),
|
create_button("faster", "faster", _("Speed up audio")),
|
||||||
create_button("hide", "off", _("Close Read Audio-Ebook"))
|
create_button("hide", "off", _("Close Read aloud"))
|
||||||
)
|
)
|
||||||
|
|
||||||
]:
|
]:
|
||||||
bar_container.appendChild(x)
|
bar_container.appendChild(x)
|
||||||
|
|
||||||
self.audio_buttons = document.getElementById("audioButtons")
|
self.container.appendChild(E.audio(data_component='audio', style="display:none"))
|
||||||
self.progress_bar = document.getElementById("progressBar")
|
|
||||||
self.time_display = document.getElementById("timeDisplay")
|
|
||||||
|
|
||||||
self.container.appendChild(E.audio(id=unique_id('audio'), style="display:none"))
|
|
||||||
ap = self.container.lastChild
|
ap = self.container.lastChild
|
||||||
self.audio_player_id = ap.id
|
|
||||||
|
|
||||||
ap.addEventListener("timeupdate", def():
|
ap.addEventListener("timeupdate", def():
|
||||||
if self.state is not HIDDEN:
|
if self.state is not HIDDEN:
|
||||||
@ -110,7 +109,7 @@ class ReadAudioEbook:
|
|||||||
audio_current_time = ap.currentTime
|
audio_current_time = ap.currentTime
|
||||||
progress = (audio_current_time / ap.duration) * 100
|
progress = (audio_current_time / ap.duration) * 100
|
||||||
self.progress_bar.firstChild.style.width = progress + "%"
|
self.progress_bar.firstChild.style.width = progress + "%"
|
||||||
self.time_display.textContent = f"{self.seconds_to_ms(audio_current_time)}/{self.seconds_to_ms(ap.duration)}"
|
self.time_display.textContent = f'{seconds_to_ms(audio_current_time)}/{seconds_to_ms(ap.duration)}'
|
||||||
self.mark_for_timeupdate(audio_current_time)
|
self.mark_for_timeupdate(audio_current_time)
|
||||||
else:
|
else:
|
||||||
self.time_display.textContent = "00:00"
|
self.time_display.textContent = "00:00"
|
||||||
@ -132,6 +131,18 @@ class ReadAudioEbook:
|
|||||||
ap.currentTime = skip_time
|
ap.currentTime = skip_time
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def bar(self):
|
||||||
|
return self.container.querySelector('[data-component=bar]')
|
||||||
|
|
||||||
|
@property
|
||||||
|
def time_display(self):
|
||||||
|
return self.container.querySelector('[data-component=time_display]')
|
||||||
|
|
||||||
|
@property
|
||||||
|
def progress_bar(self):
|
||||||
|
return self.container.querySelector('[data-component=progress_bar]')
|
||||||
|
|
||||||
def mark_for_timeupdate(self, audio_time):
|
def mark_for_timeupdate(self, audio_time):
|
||||||
sam = self.view.currently_showing.smil_audio_map
|
sam = self.view.currently_showing.smil_audio_map
|
||||||
if sam:
|
if sam:
|
||||||
@ -207,7 +218,7 @@ class ReadAudioEbook:
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def audio_player(self):
|
def audio_player(self):
|
||||||
return document.getElementById(self.audio_player_id)
|
return self.container.querySelector('[data-component=audio]')
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_visible(self):
|
def is_visible(self):
|
||||||
@ -245,7 +256,7 @@ class ReadAudioEbook:
|
|||||||
if self.state is HIDDEN:
|
if self.state is HIDDEN:
|
||||||
self.initialize()
|
self.initialize()
|
||||||
self.state = PLAYING
|
self.state = PLAYING
|
||||||
change_icon_image(self.play_pause_button, "pause")
|
change_icon_image(self.play_pause_button, "pause", _('Pause audio'))
|
||||||
self.start_playback()
|
self.start_playback()
|
||||||
self.container.style.display = "block"
|
self.container.style.display = "block"
|
||||||
self.focus()
|
self.focus()
|
||||||
@ -263,14 +274,14 @@ class ReadAudioEbook:
|
|||||||
|
|
||||||
def play(self):
|
def play(self):
|
||||||
self.state = PLAYING
|
self.state = PLAYING
|
||||||
change_icon_image(self.play_pause_button, "pause")
|
change_icon_image(self.play_pause_button, "pause", _('Pause audio'))
|
||||||
ap = self.audio_player
|
ap = self.audio_player
|
||||||
if ap.getAttribute("src"):
|
if ap.getAttribute("src"):
|
||||||
ap.play()
|
ap.play()
|
||||||
|
|
||||||
def pause(self):
|
def pause(self):
|
||||||
self.state = PAUSED
|
self.state = PAUSED
|
||||||
change_icon_image(self.play_pause_button, "play")
|
change_icon_image(self.play_pause_button, "play", _('Play audio'))
|
||||||
ap = self.audio_player
|
ap = self.audio_player
|
||||||
if ap.getAttribute("src"):
|
if ap.getAttribute("src"):
|
||||||
ap.pause()
|
ap.pause()
|
||||||
@ -314,11 +325,6 @@ class ReadAudioEbook:
|
|||||||
elif sc_name in ("up", "down", "pageup", "pagedown", "left", "right"):
|
elif sc_name in ("up", "down", "pageup", "pagedown", "left", "right"):
|
||||||
self.send_message("trigger_shortcut", name=sc_name)
|
self.send_message("trigger_shortcut", name=sc_name)
|
||||||
|
|
||||||
def seconds_to_ms(self, seconds):
|
|
||||||
minutes = Math.floor(seconds / 60)
|
|
||||||
remaining_seconds = int(seconds % 60)
|
|
||||||
return str(minutes) + ':' + (str(remaining_seconds).zfill(2))
|
|
||||||
|
|
||||||
def send_message(self, message_type, **kw):
|
def send_message(self, message_type, **kw):
|
||||||
self.view.iframe_wrapper.send_message("audio-ebook", type=message_type, **kw)
|
self.view.iframe_wrapper.send_message("audio-ebook", type=message_type, **kw)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user