1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
use blaeck::prelude::*;
const ITEMS: usize = 8;
fn make_lines(count: usize) -> Vec<LogLine> {
let mut lines = Vec::new();
for i in 1..=count.min(ITEMS) {
lines.push(LogLine::new(format!("Processing item {}...", i)).color(Color::DarkGray));
}
if count > ITEMS {
lines.push(LogLine::success("Done!"));
}
if count > ITEMS + 1 {
lines.push(LogLine::success("✓ Command completed successfully"));
}
lines
}
/// Animated preview — lines stream in with blinking dot, then completed state.
pub fn build_ui_with_timer(timer: &AnimationTimer) -> Element {
let elapsed = timer.elapsed_ms() as usize;
// Phase 1: streaming (300ms per item, 8 items + "Done!" = 2700ms)
// Phase 2: completed state held for 3000ms
// Cycle = 5700ms
let cycle_ms = 5700;
let phase_time = elapsed % cycle_ms;
if phase_time < 2700 {
// Streaming phase with blinking dot
let line_count = (phase_time / 300 + 1).min(ITEMS);
let lines = make_lines(line_count);
Element::node::<Box>(
BoxProps {
flex_direction: FlexDirection::Column,
padding: 1.0,
border_style: BorderStyle::Round,
..Default::default()
},
vec![
Element::node::<Box>(
BoxProps {
flex_direction: FlexDirection::Row,
..Default::default()
},
vec![
blinking_dot(timer, 500, Color::DarkGray),
Element::node::<Text>(
TextProps {
content: " Running command".into(),
bold: true,
..Default::default()
},
vec![],
),
],
),
Element::node::<LogBox>(
LogBoxProps::with_lines(lines)
.max_lines(5)
.tree_style(TreeStyle::Unicode)
.indent(1),
vec![],
),
],
)
} else {
// Completed state
build_completed_ui()
}
}
/// Completed state — command finished with green indicator.
pub fn build_completed_ui() -> Element {
let lines = make_lines(ITEMS + 2); // all items + Done! + success
Element::node::<Box>(
BoxProps {
flex_direction: FlexDirection::Column,
padding: 1.0,
border_style: BorderStyle::Round,
border_color: Some(Color::Green),
..Default::default()
},
vec![
Element::node::<Box>(
BoxProps {
flex_direction: FlexDirection::Row,
..Default::default()
},
vec![
Element::node::<Text>(
TextProps {
content: "●".into(),
color: Some(Color::Green),
..Default::default()
},
vec![],
),
Element::node::<Text>(
TextProps {
content: " Command finished".into(),
bold: true,
..Default::default()
},
vec![],
),
],
),
Element::node::<LogBox>(
LogBoxProps::with_lines(lines)
.max_lines(5)
.tree_style(TreeStyle::Unicode)
.indent(1),
vec![],
),
],
)
}