vibe/vibe/cli/textual_ui/widgets/status_message.py
Mathias Gesbert 078693fc64 v1.3.0
Co-Authored-By: Quentin Torroba <quentin.torroba@mistral.ai>
Co-Authored-By: Michel Thomazo <michel.thomazo@mistral.ai>
Co-Authored-By: Clément Drouin <clement.drouin@mistral.ai>
Co-Authored-by: Thiago Padilha <thiago@coplane.com>
2025-12-23 19:11:27 +01:00

75 lines
2.5 KiB
Python

from __future__ import annotations
from typing import Any, ClassVar
from textual.app import ComposeResult
from textual.containers import Horizontal
from textual.widgets import Static
from vibe.cli.textual_ui.widgets.messages import NonSelectableStatic
from vibe.cli.textual_ui.widgets.spinner import SpinnerMixin, SpinnerType
class StatusMessage(SpinnerMixin, Static):
SPINNER_TYPE: ClassVar[SpinnerType] = SpinnerType.LINE
def __init__(self, initial_text: str = "", **kwargs: Any) -> None:
self._initial_text = initial_text
self._indicator_widget: Static | None = None
self._text_widget: Static | None = None
self.init_spinner()
super().__init__(**kwargs)
def compose(self) -> ComposeResult:
with Horizontal():
self._indicator_widget = NonSelectableStatic(
self._spinner.current_frame(),
markup=False,
classes="status-indicator-icon",
)
yield self._indicator_widget
self._text_widget = Static(
"", markup=False, classes="status-indicator-text"
)
yield self._text_widget
def on_mount(self) -> None:
self.update_display()
self.start_spinner_timer()
def _update_spinner_frame(self) -> None:
if not self._is_spinning:
return
self.update_display()
def update_display(self) -> None:
if not self._indicator_widget or not self._text_widget:
return
content = self.get_content()
if self._is_spinning:
self._indicator_widget.update(self._spinner.next_frame())
self._indicator_widget.remove_class("success")
self._indicator_widget.remove_class("error")
elif self.success:
self._indicator_widget.update("")
self._indicator_widget.add_class("success")
self._indicator_widget.remove_class("error")
else:
self._indicator_widget.update("")
self._indicator_widget.add_class("error")
self._indicator_widget.remove_class("success")
self._text_widget.update(content)
def get_content(self) -> str:
return self._initial_text
def stop_spinning(self, success: bool = True) -> None:
self._is_spinning = False
self.success = success
if self._spinner_timer:
self._spinner_timer.stop()
self._spinner_timer = None
self.update_display()