mirror of
https://github.com/ankitects/anki.git
synced 2025-11-15 17:17:11 -05:00
add replay buttons to reviewing screen
This commit is contained in:
parent
4fb227ca4c
commit
7b3d701ad5
4 changed files with 50 additions and 3 deletions
|
|
@ -14,10 +14,11 @@ import aqt
|
||||||
from anki import hooks
|
from anki import hooks
|
||||||
from anki.cards import Card
|
from anki.cards import Card
|
||||||
from anki.lang import _, ngettext
|
from anki.lang import _, ngettext
|
||||||
|
from anki.sound import AVTag
|
||||||
from anki.utils import bodyClass, stripHTML
|
from anki.utils import bodyClass, stripHTML
|
||||||
from aqt import AnkiQt, gui_hooks
|
from aqt import AnkiQt, gui_hooks
|
||||||
from aqt.qt import *
|
from aqt.qt import *
|
||||||
from aqt.sound import av_player, getAudio
|
from aqt.sound import av_player, getAudio, process_av_tags
|
||||||
from aqt.utils import (
|
from aqt.utils import (
|
||||||
askUserDialog,
|
askUserDialog,
|
||||||
downArrow,
|
downArrow,
|
||||||
|
|
@ -38,6 +39,7 @@ class Reviewer:
|
||||||
self.hadCardQueue = False
|
self.hadCardQueue = False
|
||||||
self._answeredIds: List[int] = []
|
self._answeredIds: List[int] = []
|
||||||
self._recordedAudio = None
|
self._recordedAudio = None
|
||||||
|
self._current_side_audio: Optional[List[AVTag]] = None
|
||||||
self.typeCorrect = None # web init happens before this is set
|
self.typeCorrect = None # web init happens before this is set
|
||||||
self.state: Optional[str] = None
|
self.state: Optional[str] = None
|
||||||
self.bottom = aqt.toolbar.BottomBar(mw, mw.bottomWeb)
|
self.bottom = aqt.toolbar.BottomBar(mw, mw.bottomWeb)
|
||||||
|
|
@ -122,6 +124,14 @@ class Reviewer:
|
||||||
txt += c.a()
|
txt += c.a()
|
||||||
av_player.play_from_text(self.mw.col, txt)
|
av_player.play_from_text(self.mw.col, txt)
|
||||||
|
|
||||||
|
def on_play_button(self, idx: int):
|
||||||
|
try:
|
||||||
|
tag = self._current_side_audio[idx]
|
||||||
|
except IndexError:
|
||||||
|
return
|
||||||
|
|
||||||
|
av_player.play_tags([tag])
|
||||||
|
|
||||||
# Initializing the webview
|
# Initializing the webview
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
|
|
@ -181,8 +191,11 @@ The front of this card is empty. Please run Tools>Empty Cards."""
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
q = c.q()
|
q = c.q()
|
||||||
|
|
||||||
|
q, self._current_side_audio = process_av_tags(self.mw.col, q)
|
||||||
if self.autoplay(c):
|
if self.autoplay(c):
|
||||||
av_player.play_from_text(self.mw.col, q)
|
av_player.play_tags(self._current_side_audio)
|
||||||
|
|
||||||
# render & update bottom
|
# render & update bottom
|
||||||
q = self._mungeQA(q)
|
q = self._mungeQA(q)
|
||||||
q = gui_hooks.card_will_show(q, c, "reviewQuestion")
|
q = gui_hooks.card_will_show(q, c, "reviewQuestion")
|
||||||
|
|
@ -223,8 +236,9 @@ The front of this card is empty. Please run Tools>Empty Cards."""
|
||||||
c = self.card
|
c = self.card
|
||||||
a = c.a()
|
a = c.a()
|
||||||
# play audio?
|
# play audio?
|
||||||
|
a, self._current_side_audio = process_av_tags(self.mw.col, a)
|
||||||
if self.autoplay(c):
|
if self.autoplay(c):
|
||||||
av_player.play_from_text(self.mw.col, a)
|
av_player.play_tags(self._current_side_audio)
|
||||||
a = self._mungeQA(a)
|
a = self._mungeQA(a)
|
||||||
a = gui_hooks.card_will_show(a, c, "reviewAnswer")
|
a = gui_hooks.card_will_show(a, c, "reviewAnswer")
|
||||||
# render and update bottom
|
# render and update bottom
|
||||||
|
|
@ -304,6 +318,8 @@ The front of this card is empty. Please run Tools>Empty Cards."""
|
||||||
self.mw.onEditCurrent()
|
self.mw.onEditCurrent()
|
||||||
elif url == "more":
|
elif url == "more":
|
||||||
self.showContextMenu()
|
self.showContextMenu()
|
||||||
|
elif url.startswith("play:"):
|
||||||
|
self.on_play_button(int(url.split(":")[1]))
|
||||||
else:
|
else:
|
||||||
print("unrecognized anki link:", url)
|
print("unrecognized anki link:", url)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@
|
||||||
|
|
||||||
import atexit
|
import atexit
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
import threading
|
import threading
|
||||||
|
|
@ -580,6 +581,33 @@ _exports = [i for i in locals().items() if not i[0].startswith("__")]
|
||||||
for (k, v) in _exports:
|
for (k, v) in _exports:
|
||||||
sys.modules["anki.sound"].__dict__[k] = v
|
sys.modules["anki.sound"].__dict__[k] = v
|
||||||
|
|
||||||
|
# Tag handling
|
||||||
|
##########################################################################
|
||||||
|
|
||||||
|
|
||||||
|
def process_av_tags(
|
||||||
|
col: anki.storage._Collection, text: str
|
||||||
|
) -> Tuple[str, List[AVTag]]:
|
||||||
|
"Return card text with play buttons added, and the extracted AV tags."
|
||||||
|
return (
|
||||||
|
av_flags_to_html(col.backend.flag_av_tags(text)),
|
||||||
|
col.backend.get_av_tags(text),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
AV_FLAG_RE = re.compile(r"\[anki:play\](\d+)\[/anki:play]")
|
||||||
|
|
||||||
|
|
||||||
|
def av_flags_to_html(text: str) -> str:
|
||||||
|
def repl(match: re.Match) -> str:
|
||||||
|
return f"""
|
||||||
|
<a class=soundLink href=# onclick="pycmd('play:{match.group(1)}'); return false;">
|
||||||
|
<img class=playImage src='/_anki/imgs/play.png'>
|
||||||
|
</a>"""
|
||||||
|
|
||||||
|
return AV_FLAG_RE.sub(repl, text)
|
||||||
|
|
||||||
|
|
||||||
# Init defaults
|
# Init defaults
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
|
|
|
||||||
BIN
qt/aqt_data/web/imgs/play.png
Normal file
BIN
qt/aqt_data/web/imgs/play.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6 KiB |
|
|
@ -56,3 +56,6 @@ img {
|
||||||
.typeMissed {
|
.typeMissed {
|
||||||
background: #ccc;
|
background: #ccc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.playImage { zoom: 50% }
|
||||||
|
.soundLink { text-decoration: none; }
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue