Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add reviewer_will_play_question_sounds and reviewer_will_play_answer_sounds hooks #719

Merged
merged 4 commits into from Jul 31, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
78 changes: 78 additions & 0 deletions qt/aqt/gui_hooks.py
Expand Up @@ -2112,6 +2112,84 @@ def __call__(self) -> None:
reviewer_will_end = _ReviewerWillEndHook()


class _ReviewerWillPlayAnswerSoundsHook:
"""Called before showing the answer/back side.

`tags` can be used to inspect and manipulate the sounds
that will be played (if any).

This won't be called when the user manually plays sounds
using `Replay Audio`.

Note that this hook is called even when the `Automatically play audio`
option is unchecked; This is so as to allow playing custom
sounds regardless of that option."""

_hooks: List[Callable[[Card, "List[anki.sound.AVTag]"], None]] = []

def append(self, cb: Callable[[Card, "List[anki.sound.AVTag]"], None]) -> None:
"""(card: Card, tags: List[anki.sound.AVTag])"""
self._hooks.append(cb)

def remove(self, cb: Callable[[Card, "List[anki.sound.AVTag]"], None]) -> None:
if cb in self._hooks:
self._hooks.remove(cb)

def count(self) -> int:
return len(self._hooks)

def __call__(self, card: Card, tags: List[anki.sound.AVTag]) -> None:
for hook in self._hooks:
try:
hook(card, tags)
except:
# if the hook fails, remove it
self._hooks.remove(hook)
raise


reviewer_will_play_answer_sounds = _ReviewerWillPlayAnswerSoundsHook()


class _ReviewerWillPlayQuestionSoundsHook:
"""Called before showing the question/front side.

`tags` can be used to inspect and manipulate the sounds
that will be played (if any).

This won't be called when the user manually plays sounds
using `Replay Audio`.

Note that this hook is called even when the `Automatically play audio`
option is unchecked; This is so as to allow playing custom
sounds regardless of that option."""

_hooks: List[Callable[[Card, "List[anki.sound.AVTag]"], None]] = []

def append(self, cb: Callable[[Card, "List[anki.sound.AVTag]"], None]) -> None:
"""(card: Card, tags: List[anki.sound.AVTag])"""
self._hooks.append(cb)

def remove(self, cb: Callable[[Card, "List[anki.sound.AVTag]"], None]) -> None:
if cb in self._hooks:
self._hooks.remove(cb)

def count(self) -> int:
return len(self._hooks)

def __call__(self, card: Card, tags: List[anki.sound.AVTag]) -> None:
for hook in self._hooks:
try:
hook(card, tags)
except:
# if the hook fails, remove it
self._hooks.remove(hook)
raise


reviewer_will_play_question_sounds = _ReviewerWillPlayQuestionSoundsHook()


class _ReviewerWillShowContextMenuHook:
_hooks: List[Callable[["aqt.reviewer.Reviewer", QMenu], None]] = []

Expand Down
16 changes: 12 additions & 4 deletions qt/aqt/reviewer.py
Expand Up @@ -183,10 +183,14 @@ def _showQuestion(self) -> None:
q = c.q()
# play audio?
if c.autoplay():
av_player.play_tags(c.question_av_tags())
sounds = c.question_av_tags()
gui_hooks.reviewer_will_play_question_sounds(c, sounds)
av_player.play_tags(sounds)
else:
av_player.clear_queue_and_maybe_interrupt()

sounds = []
gui_hooks.reviewer_will_play_question_sounds(c, sounds)
av_player.play_tags(sounds)
# render & update bottom
q = self._mungeQA(q)
q = gui_hooks.card_will_show(q, c, "reviewQuestion")
Expand Down Expand Up @@ -225,10 +229,14 @@ def _showAnswer(self) -> None:
a = c.a()
# play audio?
if c.autoplay():
av_player.play_tags(c.answer_av_tags())
sounds = c.answer_av_tags()
gui_hooks.reviewer_will_play_answer_sounds(c, sounds)
av_player.play_tags(sounds)
else:
av_player.clear_queue_and_maybe_interrupt()

sounds = []
gui_hooks.reviewer_will_play_answer_sounds(c, sounds)
av_player.play_tags(sounds)
a = self._mungeQA(a)
a = gui_hooks.card_will_show(a, c, "reviewAnswer")
# render and update bottom
Expand Down
30 changes: 30 additions & 0 deletions qt/tools/genhooks_gui.py
Expand Up @@ -90,6 +90,36 @@ def on_overview_will_render_content(overview, content):
legacy_hook="reviewCleanup",
doc="Called before Anki transitions from the review screen to another screen.",
),
Hook(
name="reviewer_will_play_question_sounds",
args=["card: Card", "tags: List[anki.sound.AVTag]"],
doc="""Called before showing the question/front side.

`tags` can be used to inspect and manipulate the sounds
that will be played (if any).

This won't be called when the user manually plays sounds
using `Replay Audio`.

Note that this hook is called even when the `Automatically play audio`
option is unchecked; This is so as to allow playing custom
sounds regardless of that option.""",
),
Hook(
name="reviewer_will_play_answer_sounds",
args=["card: Card", "tags: List[anki.sound.AVTag]"],
doc="""Called before showing the answer/back side.

`tags` can be used to inspect and manipulate the sounds
that will be played (if any).

This won't be called when the user manually plays sounds
using `Replay Audio`.

Note that this hook is called even when the `Automatically play audio`
option is unchecked; This is so as to allow playing custom
sounds regardless of that option.""",
),
# Debug
###################
Hook(
Expand Down