Unify animations (#3729)
Unify the animation in a single code and add the CTRL + . in the onboarding
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
use crate::frames::ALL_VARIANTS as FRAME_VARIANTS;
|
||||
use crate::frames::FRAME_TICK_DEFAULT;
|
||||
use crate::ascii_animation::AsciiAnimation;
|
||||
use crate::tui::FrameRequester;
|
||||
use crate::tui::Tui;
|
||||
use crate::tui::TuiEvent;
|
||||
@@ -7,7 +6,6 @@ use color_eyre::eyre::Result;
|
||||
use crossterm::event::KeyCode;
|
||||
use crossterm::event::KeyEvent;
|
||||
use crossterm::event::KeyModifiers;
|
||||
use rand::Rng as _;
|
||||
use ratatui::buffer::Buffer;
|
||||
use ratatui::layout::Rect;
|
||||
use ratatui::prelude::Widget;
|
||||
@@ -17,10 +15,8 @@ use ratatui::widgets::Clear;
|
||||
use ratatui::widgets::Paragraph;
|
||||
use ratatui::widgets::WidgetRef;
|
||||
use ratatui::widgets::Wrap;
|
||||
use std::time::Duration;
|
||||
use tokio_stream::StreamExt;
|
||||
|
||||
const FRAME_TICK: Duration = FRAME_TICK_DEFAULT;
|
||||
const MIN_ANIMATION_HEIGHT: u16 = 24;
|
||||
const MIN_ANIMATION_WIDTH: u16 = 60;
|
||||
|
||||
@@ -39,9 +35,7 @@ enum ModelUpgradeOption {
|
||||
struct ModelUpgradePopup {
|
||||
highlighted: ModelUpgradeOption,
|
||||
decision: Option<ModelUpgradeDecision>,
|
||||
request_frame: FrameRequester,
|
||||
frame_idx: usize,
|
||||
variant_idx: usize,
|
||||
animation: AsciiAnimation,
|
||||
}
|
||||
|
||||
impl ModelUpgradePopup {
|
||||
@@ -49,9 +43,7 @@ impl ModelUpgradePopup {
|
||||
Self {
|
||||
highlighted: ModelUpgradeOption::TryNewModel,
|
||||
decision: None,
|
||||
request_frame,
|
||||
frame_idx: 0,
|
||||
variant_idx: 0,
|
||||
animation: AsciiAnimation::new(request_frame),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,7 +57,7 @@ impl ModelUpgradePopup {
|
||||
KeyCode::Esc => self.select(ModelUpgradeOption::KeepCurrent),
|
||||
KeyCode::Char('.') => {
|
||||
if key_event.modifiers.contains(KeyModifiers::CONTROL) {
|
||||
self.pick_random_variant();
|
||||
let _ = self.animation.pick_random_variant();
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
@@ -75,37 +67,13 @@ impl ModelUpgradePopup {
|
||||
fn highlight(&mut self, option: ModelUpgradeOption) {
|
||||
if self.highlighted != option {
|
||||
self.highlighted = option;
|
||||
self.request_frame.schedule_frame();
|
||||
self.animation.request_frame();
|
||||
}
|
||||
}
|
||||
|
||||
fn select(&mut self, option: ModelUpgradeOption) {
|
||||
self.decision = Some(option.into());
|
||||
self.request_frame.schedule_frame();
|
||||
}
|
||||
|
||||
fn advance_animation(&mut self) {
|
||||
let len = self.frames().len();
|
||||
self.frame_idx = (self.frame_idx + 1) % len;
|
||||
self.request_frame.schedule_frame_in(FRAME_TICK);
|
||||
}
|
||||
|
||||
fn frames(&self) -> &'static [&'static str] {
|
||||
FRAME_VARIANTS[self.variant_idx]
|
||||
}
|
||||
|
||||
fn pick_random_variant(&mut self) {
|
||||
let total = FRAME_VARIANTS.len();
|
||||
if total <= 1 {
|
||||
return;
|
||||
}
|
||||
let mut rng = rand::rng();
|
||||
let mut next = self.variant_idx;
|
||||
while next == self.variant_idx {
|
||||
next = rng.random_range(0..total);
|
||||
}
|
||||
self.variant_idx = next;
|
||||
self.request_frame.schedule_frame();
|
||||
self.animation.request_frame();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,6 +89,7 @@ impl From<ModelUpgradeOption> for ModelUpgradeDecision {
|
||||
impl WidgetRef for &ModelUpgradePopup {
|
||||
fn render_ref(&self, area: Rect, buf: &mut Buffer) {
|
||||
Clear.render(area, buf);
|
||||
self.animation.schedule_next_frame();
|
||||
|
||||
// Skip the animation entirely when the viewport is too small so we don't clip frames.
|
||||
let show_animation =
|
||||
@@ -128,7 +97,7 @@ impl WidgetRef for &ModelUpgradePopup {
|
||||
|
||||
let mut lines: Vec<Line> = Vec::new();
|
||||
if show_animation {
|
||||
let frame = self.frames()[self.frame_idx];
|
||||
let frame = self.animation.current_frame();
|
||||
lines.extend(frame.lines().map(|l| l.into()));
|
||||
// Spacer between animation and text content.
|
||||
lines.push("".into());
|
||||
@@ -188,8 +157,6 @@ pub(crate) async fn run_model_upgrade_popup(tui: &mut Tui) -> Result<ModelUpgrad
|
||||
frame.render_widget_ref(&popup, frame.area());
|
||||
})?;
|
||||
|
||||
popup.advance_animation();
|
||||
|
||||
let events = tui.event_stream();
|
||||
tokio::pin!(events);
|
||||
while popup.decision.is_none() {
|
||||
@@ -197,7 +164,6 @@ pub(crate) async fn run_model_upgrade_popup(tui: &mut Tui) -> Result<ModelUpgrad
|
||||
match event {
|
||||
TuiEvent::Key(key_event) => popup.handle_key_event(key_event),
|
||||
TuiEvent::Draw => {
|
||||
popup.advance_animation();
|
||||
let _ = tui.draw(u16::MAX, |frame| {
|
||||
frame.render_widget_ref(&popup, frame.area());
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user