Add message listing and message reading states

This commit is contained in:
Sofia 2026-06-04 19:21:00 +03:00
parent 4c0f284b62
commit 11ca5019b5
2 changed files with 99 additions and 16 deletions

View File

@ -720,12 +720,12 @@ pub enum ListSMSMessagesResponse {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct SMSMessageListing { pub struct SMSMessageListing {
index: u32, pub index: u32,
stat: SMSMessageStat, pub stat: SMSMessageStat,
from_addr: String, pub from_addr: String,
to_addr: String, pub to_addr: String,
timestamp: String, pub timestamp: String,
text: String, pub text: String,
} }
impl ATResponse for ListSMSMessagesResponse { impl ATResponse for ListSMSMessagesResponse {
@ -791,8 +791,8 @@ impl ATCommand for ListSMSMessages {
let mut params = parser.params().unwrap(); let mut params = parser.params().unwrap();
let idx = params.read_u32().unwrap(); let idx = params.read_u32().unwrap();
let stat = SMSMessageStat::from(&params.read_string().unwrap()); let stat = SMSMessageStat::from(&params.read_string().unwrap());
let from_addr = params.read_string().unwrap();
let to_addr = params.read_string().unwrap(); let to_addr = params.read_string().unwrap();
let from_addr = params.read_string().unwrap();
let timestamp = params.read_string().unwrap(); let timestamp = params.read_string().unwrap();
let mut message = String::new(); let mut message = String::new();

View File

@ -5,6 +5,7 @@ use alloc::{
boxed::Box, boxed::Box,
format, format,
string::{String, ToString}, string::{String, ToString},
vec::Vec,
}; };
use esp_hal::time::{Duration, Instant}; use esp_hal::time::{Duration, Instant};
@ -12,8 +13,9 @@ use crate::{
async_io::{ATPromise, KeypadButton, NumberInput, TextInput}, async_io::{ATPromise, KeypadButton, NumberInput, TextInput},
at_commands::{ at_commands::{
ATCommand, ATError, ATInformationCommand, CheckPinCommand, CheckPinResult, EnterPinCommand, ATCommand, ATError, ATInformationCommand, CheckPinCommand, CheckPinResult, EnterPinCommand,
EnterPinResult, ListSMSMessages, SMSFormat, SMSMessageStat, SelectSMSFormatCommand, EnterPinResult, ListSMSMessages, ListSMSMessagesResponse, SMSFormat, SMSMessageListing,
SendSMSCommand, SendSMSResponse, SetTECharsetCommand, SimpleATResponse, TECharset, SMSMessageStat, SelectSMSFormatCommand, SendSMSCommand, SendSMSResponse,
SetTECharsetCommand, SimpleATResponse, TECharset,
}, },
display::{Position, Rgb565}, display::{Position, Rgb565},
font::{HorizontalAlignment, VerticalAlignment}, font::{HorizontalAlignment, VerticalAlignment},
@ -339,18 +341,20 @@ impl State for MainMenuState {
MainMenuItem::SendSMS => return Some(Box::new(PhoneNumberState::default())), MainMenuItem::SendSMS => return Some(Box::new(PhoneNumberState::default())),
MainMenuItem::ReadSMS => { MainMenuItem::ReadSMS => {
return Some(Box::new(ATCommandState::with( return Some(Box::new(ATCommandState::with(
"Loading messages".to_owned(), "Loading\nmessages".to_owned(),
ListSMSMessages { ListSMSMessages {
stat: SMSMessageStat::All, stat: SMSMessageStat::All,
}, },
|resp| match resp { |resp| match resp {
Ok(messages) => { Ok(response) => match response {
log::info!("{:?}", messages); ListSMSMessagesResponse::Ok(messages) => {
Box::new(TextState { Box::new(ListSMSMessagesState::from(messages))
text: format!("Messages read"),
after: MainMenuState::default(),
})
} }
ListSMSMessagesResponse::Error(err) => Box::new(TextState {
text: format!("Error:\n{:?}", err),
after: MainMenuState::default(),
}),
},
Err(err) => Box::new(TextState { Err(err) => Box::new(TextState {
text: format!("Error:\n{:?}", err), text: format!("Error:\n{:?}", err),
after: MainMenuState::default(), after: MainMenuState::default(),
@ -369,6 +373,85 @@ impl State for MainMenuState {
} }
} }
#[derive(Clone, Default)]
pub struct MessageListing {
from: String,
text: String,
}
impl MenuItem for MessageListing {
fn as_text(&self) -> String {
format!("{}: {}", self.from, self.text)
}
}
#[derive(Clone, Default)]
pub struct ListSMSMessagesState {
menu: Menu<MessageListing>,
}
impl ListSMSMessagesState {
pub fn from(messages: Vec<SMSMessageListing>) -> ListSMSMessagesState {
let mut menu = Menu::default();
for message in &messages {
menu = menu.with_item(MessageListing {
from: message.from_addr.clone(),
text: message.text.clone(),
})
}
ListSMSMessagesState { menu }
}
}
impl State for ListSMSMessagesState {
fn update(&mut self, data: &mut StateData) -> Option<Box<dyn State>> {
if let Some(listing) = self.menu.poll(&mut data.io) {
return Some(Box::new(ReadMessageState {
message: listing.clone(),
}));
}
if data.io.keypad.get_presses(KeypadButton::KeypadB) > 0 {
Some(Box::new(MainMenuState::default()))
} else {
None
}
}
fn draw(&self, data: &mut StateData) {
self.menu.draw(data);
}
}
#[derive(Clone, Default)]
pub struct ReadMessageState {
message: MessageListing,
}
impl State for ReadMessageState {
fn update(&mut self, data: &mut StateData) -> Option<Box<dyn State>> {
if data.io.keypad.get_presses(KeypadButton::KeypadB) > 0 {
Some(Box::new(MainMenuState::default()))
} else {
None
}
}
fn draw(&self, data: &mut StateData) {
data.clear_screen(Rgb565::black().as_color());
data.draw_text(
self.message.from.clone(),
Position::new(0, 0),
TextSettings::default(),
);
data.draw_text(
self.message.text.clone(),
Position::new(0, 30),
TextSettings::default(),
);
}
}
#[derive(Clone, Default)] #[derive(Clone, Default)]
pub struct PhoneNumberState { pub struct PhoneNumberState {
input: NumberInput, input: NumberInput,