Browse Source

Add ui_dialogs in State

async
Manos Pitsidianakis 3 years ago
parent
commit
e3abd458ce
Signed by untrusted user: epilys GPG Key ID: 73627C2F690DF710
  1. 197
      src/state.rs

197
src/state.rs

@ -194,6 +194,7 @@ pub struct State {
pub context: Context,
timer: thread::JoinHandle<()>,
ui_dialogs: Vec<Box<dyn Component>>,
display_messages: SmallVec<[DisplayMessage; 8]>,
display_messages_expiration_start: Option<UnixTimestamp>,
display_messages_active: bool,
@ -493,6 +494,33 @@ impl State {
));
}
}
if !self.ui_dialogs.is_empty() {
let area = center_area(
(
(0, 0),
(self.cols.saturating_sub(1), self.rows.saturating_sub(1)),
),
(
if self.cols / 3 > 30 {
self.cols / 3
} else {
self.cols
},
if self.rows / 5 > 10 {
self.rows / 5
} else {
self.rows
},
),
);
areas.push(area);
let area = create_box(&mut self.overlay_grid, area);
self.ui_dialogs.get_mut(0).unwrap().draw(
&mut self.overlay_grid,
area,
&mut self.context,
);
}
/* Sort by x_start, ie upper_left corner's x coordinate */
areas.sort_by(|a, b| (a.0).0.partial_cmp(&(b.0).0).unwrap());
@ -743,90 +771,77 @@ impl State {
}
/// Convert user commands to actions/method calls.
fn parse_command(&mut self, cmd: &str) {
let result = parse_command(&cmd.as_bytes()).to_full_result();
if let Ok(v) = result {
match v {
SetEnv(key, val) => {
env::set_var(key.as_str(), val.as_str());
}
PrintEnv(key) => {
self.context.replies.push_back(UIEvent::StatusEvent(
StatusEvent::DisplayMessage(
env::var(key.as_str()).unwrap_or_else(|e| e.to_string()),
),
));
}
Folder(account_name, op) => {
if let Some(account) = self
.context
.accounts
.iter_mut()
.find(|a| a.name() == account_name)
{
match account.folder_operation(op) {
Err(err) => {
self.context.replies.push_back(UIEvent::StatusEvent(
StatusEvent::DisplayMessage(err.to_string()),
));
}
Ok(msg) => {
self.context.replies.push_back(UIEvent::StatusEvent(
StatusEvent::DisplayMessage(format!(
"`{}`: {}",
account_name, msg
)),
));
}
}
} else {
self.context.replies.push_back(UIEvent::StatusEvent(
StatusEvent::DisplayMessage(format!(
"Account with name `{}` not found.",
account_name
)),
));
}
}
AccountAction(ref account_name, ReIndex) => {
#[cfg(feature = "sqlite3")]
match crate::sqlite3::index(&mut self.context, account_name) {
Ok(()) => {
self.context.replies.push_back(UIEvent::Notification(
None,
"Message index rebuild started.".to_string(),
Some(NotificationType::INFO),
fn exec_command(&mut self, cmd: Action) {
match cmd {
SetEnv(key, val) => {
env::set_var(key.as_str(), val.as_str());
}
PrintEnv(key) => {
self.context
.replies
.push_back(UIEvent::StatusEvent(StatusEvent::DisplayMessage(
env::var(key.as_str()).unwrap_or_else(|e| e.to_string()),
)));
}
Folder(account_name, op) => {
if let Some(account) = self
.context
.accounts
.iter_mut()
.find(|a| a.name() == account_name)
{
match account.folder_operation(op) {
Err(err) => {
self.context.replies.push_back(UIEvent::StatusEvent(
StatusEvent::DisplayMessage(err.to_string()),
));
}
Err(e) => {
self.context.replies.push_back(UIEvent::Notification(
None,
format!("Message index rebuild failed: {}.", e),
Some(NotificationType::ERROR),
Ok(msg) => {
self.context.replies.push_back(UIEvent::StatusEvent(
StatusEvent::DisplayMessage(format!("`{}`: {}", account_name, msg)),
));
}
}
#[cfg(not(feature = "sqlite3"))]
{
} else {
self.context.replies.push_back(UIEvent::StatusEvent(
StatusEvent::DisplayMessage(format!(
"Account with name `{}` not found.",
account_name
)),
));
}
}
AccountAction(ref account_name, ReIndex) => {
#[cfg(feature = "sqlite3")]
match crate::sqlite3::index(&mut self.context, account_name) {
Ok(()) => {
self.context.replies.push_back(UIEvent::Notification(
None,
"Message index rebuild started.".to_string(),
Some(NotificationType::INFO),
));
}
Err(e) => {
self.context.replies.push_back(UIEvent::Notification(
None,
"Message index rebuild failed: meli is not built with sqlite3 support."
.to_string(),
format!("Message index rebuild failed: {}.", e),
Some(NotificationType::ERROR),
));
}
}
v => {
self.rcv_event(UIEvent::Action(v));
#[cfg(not(feature = "sqlite3"))]
{
self.context.replies.push_back(UIEvent::Notification(
None,
"Message index rebuild failed: meli is not built with sqlite3 support."
.to_string(),
Some(NotificationType::ERROR),
));
}
}
} else {
self.context
.replies
.push_back(UIEvent::StatusEvent(StatusEvent::DisplayMessage(
"invalid command".to_string(),
)));
v => {
self.rcv_event(UIEvent::Action(v));
}
}
}
@ -841,7 +856,33 @@ impl State {
match event {
// Command type is handled only by State.
UIEvent::Command(cmd) => {
self.parse_command(&cmd);
if let Ok(action) = parse_command(&cmd.as_bytes()).to_full_result() {
if action.needs_confirmation() {
let action = std::sync::Arc::new(action);
self.ui_dialogs.push(Box::new(UIConfirmationDialog::new(
"You sure?",
vec![(true, "yes".to_string()), (false, "no".to_string())],
true,
std::sync::Arc::new(move |result: bool| {
if result {
Some(UIEvent::FinishedUIDialog(
ComponentId::nil(),
Box::new(action.clone()),
))
} else {
None
}
}),
&mut self.context,
)));
} else {
self.exec_command(action);
}
} else {
self.context.replies.push_back(UIEvent::StatusEvent(
StatusEvent::DisplayMessage("invalid command".to_string()),
));
}
return;
}
UIEvent::Fork(ForkType::Finished) => {
@ -908,6 +949,18 @@ impl State {
self.display_messages_active = true;
self.display_messages_pos = self.display_messages.len() - 1;
}
UIEvent::FinishedUIDialog(ref id, ref mut results)
if self.ui_dialogs.get(0).map(|c| c.id()) == Some(*id) =>
{
if let Some(ref mut action) = results.downcast_mut::<Action>() {
self.exec_command(std::mem::replace(action, Action::ToggleThreadSnooze));
return;
}
}
UIEvent::GlobalUIDialog(dialog) => {
self.ui_dialogs.push(dialog);
return;
}
_ => {}
}
/* inform each component */

Loading…
Cancel
Save