Co-authored-by: Clément Drouin <clement.drouin@mistral.ai> Co-authored-by: Clément Sirieix <clement.sirieix@mistral.ai> Co-authored-by: Gauthier Guinet <43207538+Gguinet@users.noreply.github.com> Co-authored-by: Kim-Adeline Miguel <kimadeline.miguel@mistral.ai> Co-authored-by: Michel Thomazo <51709227+michelTho@users.noreply.github.com> Co-authored-by: Quentin <torroba.q@gmail.com> Co-authored-by: Simon <80467011+sorgfresser@users.noreply.github.com> Co-authored-by: Simon Van de Kerckhove <simon.vandekerckhove@mistral.ai> Co-authored-by: Vincent G <10739306+VinceOPS@users.noreply.github.com> Co-authored-by: angelapopopo <angele.lenglemetz@mistral.ai> Co-authored-by: Mistral Vibe <vibe@mistral.ai>
56 lines
1.7 KiB
Python
56 lines
1.7 KiB
Python
from __future__ import annotations
|
|
|
|
from enum import StrEnum, auto
|
|
from typing import Any
|
|
|
|
from textual.reactive import reactive
|
|
from textual.timer import Timer
|
|
from textual.widgets import Static
|
|
|
|
SHRINK_FRAMES = "█▇▆▅▄▃▂▁"
|
|
BAR_FRAMES = ["▂▅▇", "▃▆▅", "▅▃▇", "▇▂▅", "▅▇▃", "▃▅▆"]
|
|
ANIMATION_INTERVAL = 0.15
|
|
|
|
|
|
class NarratorState(StrEnum):
|
|
IDLE = auto()
|
|
SUMMARIZING = auto()
|
|
SPEAKING = auto()
|
|
|
|
|
|
class NarratorStatus(Static):
|
|
state = reactive(NarratorState.IDLE)
|
|
|
|
def __init__(self, **kwargs: Any) -> None:
|
|
super().__init__("", **kwargs)
|
|
self._timer: Timer | None = None
|
|
self._frame: int = 0
|
|
|
|
def watch_state(self, new_state: NarratorState) -> None:
|
|
self._stop_timer()
|
|
match new_state:
|
|
case NarratorState.IDLE:
|
|
self.update("")
|
|
case NarratorState.SUMMARIZING | NarratorState.SPEAKING:
|
|
self._frame = 0
|
|
self._tick()
|
|
self._timer = self.set_interval(ANIMATION_INTERVAL, self._tick)
|
|
|
|
def _tick(self) -> None:
|
|
match self.state:
|
|
case NarratorState.SUMMARIZING:
|
|
char = SHRINK_FRAMES[self._frame % len(SHRINK_FRAMES)]
|
|
self.update(
|
|
f"[bold orange]{char}[/bold orange] summarizing [dim]esc to stop[/dim]"
|
|
)
|
|
case NarratorState.SPEAKING:
|
|
bars = BAR_FRAMES[self._frame % len(BAR_FRAMES)]
|
|
self.update(
|
|
f"[bold orange]{bars}[/bold orange] speaking [dim]esc to stop[/dim]"
|
|
)
|
|
self._frame += 1
|
|
|
|
def _stop_timer(self) -> None:
|
|
if self._timer is not None:
|
|
self._timer.stop()
|
|
self._timer = None
|