Skip to content

Commit af41c5b

Browse files
authored
Merge pull request #4 from alamgu/dn-prompt-queing-fixes
Misc fixes to prompt queue
2 parents 75cefe6 + 718b9ab commit af41c5b

File tree

1 file changed

+59
-42
lines changed

1 file changed

+59
-42
lines changed

src/prompts.rs

Lines changed: 59 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,31 @@
11
use crate::*;
22
use arrayvec::ArrayString;
33
use core::fmt::{Arguments, Error, Write};
4+
use core::str::from_utf8;
45

56
use nanos_sdk::buttons::*;
67
use nanos_ui::bagls::*;
8+
use nanos_ui::layout::*;
9+
use nanos_ui::ui::clear_screen;
710

811
#[derive(Clone, Debug)]
912
pub struct PromptQueue {
1013
io: HostIO,
1114
prev: SHA256Sum,
1215
}
1316

17+
const HASH_LENGTH: usize = 32;
18+
19+
const PROMPT_TITLE_LENGTH: usize = 17;
20+
1421
#[cfg(target_os = "nanos")]
1522
const PROMPT_CHUNK_LENGTH: usize = 16;
1623

1724
#[cfg(not(target_os = "nanos"))]
18-
const PROMPT_CHUNK_LENGTH: usize = 64;
25+
const PROMPT_CHUNK_LENGTH: usize = 48;
1926

20-
type PromptBuffer = ArrayVec<u8, { 32 + 19 + PROMPT_CHUNK_LENGTH }>;
27+
// The two bytes are to store the actual "length" of title and chunk, respectively
28+
type PromptBuffer = ArrayVec<u8, { HASH_LENGTH + 2 + PROMPT_TITLE_LENGTH + PROMPT_CHUNK_LENGTH }>;
2129

2230
#[derive(Debug, PartialEq)]
2331
pub struct PromptingError;
@@ -45,22 +53,32 @@ impl From<ChunkNotFound> for PromptingError {
4553

4654
impl PromptQueue {
4755
pub fn new(io: HostIO) -> PromptQueue {
48-
PromptQueue { io, prev: [0; 32] }
56+
PromptQueue {
57+
io,
58+
prev: [0; HASH_LENGTH],
59+
}
4960
}
5061

5162
async fn pop(
5263
&mut self,
53-
) -> Result<Option<(ArrayString<16>, ArrayString<PROMPT_CHUNK_LENGTH>)>, PromptingError> {
54-
if self.prev == [0; 32] {
64+
) -> Result<
65+
Option<(
66+
ArrayString<PROMPT_TITLE_LENGTH>,
67+
ArrayString<PROMPT_CHUNK_LENGTH>,
68+
)>,
69+
PromptingError,
70+
> {
71+
if self.prev == [0; HASH_LENGTH] {
5572
return Ok(None);
5673
}
5774
let chunk = PromptBuffer::try_from(self.io.get_chunk(self.prev).await?.as_ref())?;
58-
self.prev[0..32].copy_from_slice(&chunk[0..32]);
59-
let title =
60-
ArrayString::try_from(core::str::from_utf8(&chunk[34..34 + chunk[32] as usize])?)?;
61-
let body = ArrayString::try_from(core::str::from_utf8(
62-
&chunk[34 + chunk[32] as usize..(34 + chunk[32] + chunk[33]) as usize],
63-
)?)?;
75+
self.prev[0..HASH_LENGTH].copy_from_slice(&chunk[0..HASH_LENGTH]);
76+
let title_len = chunk[32] as usize;
77+
let title_end = 34 + title_len;
78+
let body_len = chunk[33] as usize;
79+
let body_end = title_end + body_len;
80+
let title = ArrayString::try_from(core::str::from_utf8(&chunk[34..title_end])?)?;
81+
let body = ArrayString::try_from(core::str::from_utf8(&chunk[title_end..body_end])?)?;
6482
Ok(Some((title, body)))
6583
}
6684

@@ -82,7 +100,7 @@ impl PromptQueue {
82100
}
83101

84102
pub async fn show(&mut self) -> Result<bool, PromptingError> {
85-
if self.prev == [0; 32] {
103+
if self.prev == [0; HASH_LENGTH] {
86104
return Err(PromptingError);
87105
} // No showing empty PromptQueues.
88106

@@ -100,47 +118,44 @@ impl PromptQueue {
100118
let mut buttons = Default::default();
101119

102120
loop {
121+
clear_screen();
103122
// Display
104123
let (current_title, current_body) = title_and_body;
105124
match state {
106125
PromptingState::Prompts => {
107-
Bagl::LABELLINE(LabelLine::new().pos(0, 10).text(current_title.as_str()))
108-
.display();
126+
current_title.as_str().place(Location::Top, Layout::Centered, false);
109127
#[cfg(target_os = "nanos")]
110128
{
111-
Bagl::LABELLINE(LabelLine::new().pos(0, 25).text(current_body.as_str()))
112-
.paint();
129+
current_body.as_str().place(Location::Custom(15), Layout::Centered, false);
113130
}
114131
#[cfg(not(target_os = "nanos"))]
115132
{
116-
current_body.as_str().get(0..16).map(|body| {
117-
Bagl::LABELLINE(LabelLine::new().pos(0, 25).text(body)).paint()
118-
});
119-
current_body.as_str().get(16..32).map(|body| {
120-
Bagl::LABELLINE(LabelLine::new().pos(0, 37).text(body)).paint()
121-
});
122-
current_body.as_str().get(32..48).map(|body| {
123-
Bagl::LABELLINE(LabelLine::new().pos(0, 49).text(body)).paint()
124-
});
125-
current_body.as_str().get(48..64).map(|body| {
126-
Bagl::LABELLINE(LabelLine::new().pos(0, 61).text(body)).paint()
127-
});
133+
let mut iter = current_body.as_bytes().chunks(16);
134+
if let Some(body) = iter.next().map(|s| from_utf8(s).ok()).flatten() {
135+
body.place(Location::Custom(16), Layout::Centered, false);
136+
};
137+
if let Some(body) = iter.next().map(|s| from_utf8(s).ok()).flatten() {
138+
body.place(Location::Custom(31), Layout::Centered, false);
139+
};
140+
if let Some(body) = iter.next().map(|s| from_utf8(s).ok()).flatten() {
141+
body.place(Location::Custom(46), Layout::Centered, false);
142+
};
128143
}
129-
if backward.prev != [0; 32] {
130-
LEFT_ARROW.paint();
144+
if backward.prev != [0; HASH_LENGTH] {
145+
LEFT_ARROW.instant_display();
131146
}
132-
RIGHT_ARROW.paint();
147+
RIGHT_ARROW.instant_display();
133148
}
134149
PromptingState::Confirm => {
135-
Bagl::ICON(Icon::new(Icons::CheckBadge).pos(18, 12)).display();
136-
Bagl::LABELLINE(LabelLine::new().text("Confirm").pos(0, 20)).paint();
137-
LEFT_ARROW.paint();
138-
RIGHT_ARROW.paint();
150+
CHECKMARK_ICON.set_x(18).display();
151+
"Confirm".place(Location::Middle, Layout::Centered, false);
152+
LEFT_ARROW.instant_display();
153+
RIGHT_ARROW.instant_display();
139154
}
140155
PromptingState::Cancel => {
141-
Bagl::ICON(Icon::new(Icons::CrossBadge).pos(18, 12)).display();
142-
Bagl::LABELLINE(LabelLine::new().text("Cancel").pos(0, 20)).paint();
143-
LEFT_ARROW.paint();
156+
CROSS_ICON.set_x(18).display();
157+
"Reject".place(Location::Middle, Layout::Centered, false);
158+
LEFT_ARROW.instant_display();
144159
}
145160
}
146161
// Handle buttons
@@ -155,15 +170,15 @@ impl PromptQueue {
155170
// {
156171
match (state.clone(), buttons_evt) {
157172
(PromptingState::Prompts, ButtonEvent::LeftButtonRelease) => {
158-
if backward.prev != [0; 32] {
173+
if backward.prev != [0; HASH_LENGTH] {
159174
forward
160175
.add_prompt_chunk(&current_title, &current_body)
161176
.await?;
162177
title_and_body = backward.pop().await?.unwrap();
163178
}
164179
}
165180
(PromptingState::Prompts, ButtonEvent::RightButtonRelease) => {
166-
if forward.prev != [0; 32] {
181+
if forward.prev != [0; HASH_LENGTH] {
167182
backward
168183
.add_prompt_chunk(&current_title, &current_body)
169184
.await?;
@@ -187,7 +202,9 @@ impl PromptQueue {
187202
(PromptingState::Cancel, ButtonEvent::LeftButtonRelease) => {
188203
state = PromptingState::Confirm;
189204
}
190-
_ => {}
205+
_ => {
206+
continue;
207+
}
191208
}
192209
break;
193210
} else {
@@ -197,7 +214,7 @@ impl PromptQueue {
197214
}
198215

199216
async fn add_prompt_chunk(&mut self, title: &str, segment: &str) -> Result<(), PromptingError> {
200-
if title.len() > 17 {
217+
if title.len() > PROMPT_TITLE_LENGTH {
201218
return Err(PromptingError);
202219
}
203220
if segment.len() > PROMPT_CHUNK_LENGTH {

0 commit comments

Comments
 (0)