| 1 | //! Gallery: toasts. |
| 2 | |
| 3 | use std::time::{Duration, Instant}; |
| 4 | |
| 5 | use ratatui::{buffer::Buffer, layout::Rect}; |
| 6 | |
| 7 | use super::Entry; |
| 8 | use crate::{MotionMode, Paint, State, Theme, Toast, Toasts, Ttl}; |
| 9 | |
| 10 | fn toasts(area: Rect, buf: &mut Buffer, theme: &Theme) { |
| 11 | Toasts::new(vec![ |
| 12 | Toast::new(State::Done, "Theme set to Shoreline"), |
| 13 | Toast::new(State::NeedsYou, "A command is waiting for your approval").opens(), |
| 14 | Toast::new( |
| 15 | State::Failed, |
| 16 | "Could not save: the settings file is read-only", |
| 17 | ) |
| 18 | .opens(), |
| 19 | ]) |
| 20 | .paint(area, buf, theme); |
| 21 | } |
| 22 | |
| 23 | /// Six toasts, three visible: the older three fold into `+3 more`. |
| 24 | fn stacked(area: Rect, buf: &mut Buffer, theme: &Theme) { |
| 25 | Toasts::new(vec![ |
| 26 | Toast::new(State::Done, "Saved summary.md"), |
| 27 | Toast::new(State::Done, "Saved CHANGELOG.md"), |
| 28 | Toast::new(State::Working, "Indexing 1,204 files"), |
| 29 | Toast::new(State::Done, "Theme set to Shoreline"), |
| 30 | Toast::new(State::NeedsYou, "A command is waiting for your approval").opens(), |
| 31 | Toast::new( |
| 32 | State::Failed, |
| 33 | "Could not save: the settings file is read-only", |
| 34 | ), |
| 35 | ]) |
| 36 | .paint(area, buf, theme); |
| 37 | } |
| 38 | |
| 39 | /// A toast mid-fade: the host's clock says 70 ms after it was born, so the |
| 40 | /// sentence is in the second step of ink. The same stack under reduced |
| 41 | /// motion is settled. |
| 42 | fn fading(area: Rect, buf: &mut Buffer, theme: &Theme) { |
| 43 | let base = Instant::now(); |
| 44 | let at = base + Duration::from_millis(70); |
| 45 | let items = || { |
| 46 | vec![ |
| 47 | Toast::new(State::Done, "Theme set to Shoreline").born(base), |
| 48 | Toast::new(State::Done, "Saved summary.md") |
| 49 | .born(base.checked_sub(Duration::from_millis(900)).unwrap_or(base)) |
| 50 | .ttl(Ttl::Seconds(1)), |
| 51 | ] |
| 52 | }; |
| 53 | let half = area.height / 2; |
| 54 | let top = Rect::new(area.x, area.y, area.width, half); |
| 55 | let bottom = Rect::new(area.x, area.y + half, area.width, area.height - half); |
| 56 | Toasts::new(items()).at(at).paint(top, buf, theme); |
| 57 | Toasts::new(items()) |
| 58 | .at(at) |
| 59 | .motion(MotionMode::Reduced) |
| 60 | .paint(bottom, buf, theme); |
| 61 | } |
| 62 | |
| 63 | pub(crate) fn entries() -> Vec<Entry> { |
| 64 | vec![ |
| 65 | Entry { |
| 66 | name: "toasts", |
| 67 | width: 60, |
| 68 | height: 3, |
| 69 | draw: toasts, |
| 70 | }, |
| 71 | Entry { |
| 72 | name: "toasts-stacked", |
| 73 | width: 60, |
| 74 | height: 5, |
| 75 | draw: stacked, |
| 76 | }, |
| 77 | Entry { |
| 78 | name: "toasts-fading", |
| 79 | width: 60, |
| 80 | height: 4, |
| 81 | draw: fading, |
| 82 | }, |
| 83 | ] |
| 84 | } |
| 85 |