Add ui_dialogs in State
parent
a806571322
commit
e3abd458ce
201
src/state.rs
201
src/state.rs
|
@ -194,6 +194,7 @@ pub struct State {
|
||||||
pub context: Context,
|
pub context: Context,
|
||||||
timer: thread::JoinHandle<()>,
|
timer: thread::JoinHandle<()>,
|
||||||
|
|
||||||
|
ui_dialogs: Vec<Box<dyn Component>>,
|
||||||
display_messages: SmallVec<[DisplayMessage; 8]>,
|
display_messages: SmallVec<[DisplayMessage; 8]>,
|
||||||
display_messages_expiration_start: Option<UnixTimestamp>,
|
display_messages_expiration_start: Option<UnixTimestamp>,
|
||||||
display_messages_active: bool,
|
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 */
|
/* 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());
|
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.
|
/// Convert user commands to actions/method calls.
|
||||||
fn parse_command(&mut self, cmd: &str) {
|
fn exec_command(&mut self, cmd: Action) {
|
||||||
let result = parse_command(&cmd.as_bytes()).to_full_result();
|
match cmd {
|
||||||
|
SetEnv(key, val) => {
|
||||||
if let Ok(v) = result {
|
env::set_var(key.as_str(), val.as_str());
|
||||||
match v {
|
}
|
||||||
SetEnv(key, val) => {
|
PrintEnv(key) => {
|
||||||
env::set_var(key.as_str(), val.as_str());
|
self.context
|
||||||
}
|
.replies
|
||||||
PrintEnv(key) => {
|
.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(
|
self.context.replies.push_back(UIEvent::StatusEvent(
|
||||||
StatusEvent::DisplayMessage(
|
StatusEvent::DisplayMessage(format!(
|
||||||
env::var(key.as_str()).unwrap_or_else(|e| e.to_string()),
|
"Account with name `{}` not found.",
|
||||||
),
|
account_name
|
||||||
|
)),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
Folder(account_name, op) => {
|
}
|
||||||
if let Some(account) = self
|
AccountAction(ref account_name, ReIndex) => {
|
||||||
.context
|
#[cfg(feature = "sqlite3")]
|
||||||
.accounts
|
match crate::sqlite3::index(&mut self.context, account_name) {
|
||||||
.iter_mut()
|
Ok(()) => {
|
||||||
.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),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
Err(e) => {
|
|
||||||
self.context.replies.push_back(UIEvent::Notification(
|
|
||||||
None,
|
|
||||||
format!("Message index rebuild failed: {}.", e),
|
|
||||||
Some(NotificationType::ERROR),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#[cfg(not(feature = "sqlite3"))]
|
|
||||||
{
|
|
||||||
self.context.replies.push_back(UIEvent::Notification(
|
self.context.replies.push_back(UIEvent::Notification(
|
||||||
None,
|
None,
|
||||||
"Message index rebuild failed: meli is not built with sqlite3 support."
|
"Message index rebuild started.".to_string(),
|
||||||
.to_string(),
|
Some(NotificationType::INFO),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
self.context.replies.push_back(UIEvent::Notification(
|
||||||
|
None,
|
||||||
|
format!("Message index rebuild failed: {}.", e),
|
||||||
Some(NotificationType::ERROR),
|
Some(NotificationType::ERROR),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
v => {
|
#[cfg(not(feature = "sqlite3"))]
|
||||||
self.rcv_event(UIEvent::Action(v));
|
{
|
||||||
|
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 {
|
v => {
|
||||||
self.context
|
self.rcv_event(UIEvent::Action(v));
|
||||||
.replies
|
}
|
||||||
.push_back(UIEvent::StatusEvent(StatusEvent::DisplayMessage(
|
|
||||||
"invalid command".to_string(),
|
|
||||||
)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -841,7 +856,33 @@ impl State {
|
||||||
match event {
|
match event {
|
||||||
// Command type is handled only by State.
|
// Command type is handled only by State.
|
||||||
UIEvent::Command(cmd) => {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
UIEvent::Fork(ForkType::Finished) => {
|
UIEvent::Fork(ForkType::Finished) => {
|
||||||
|
@ -908,6 +949,18 @@ impl State {
|
||||||
self.display_messages_active = true;
|
self.display_messages_active = true;
|
||||||
self.display_messages_pos = self.display_messages.len() - 1;
|
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 */
|
/* inform each component */
|
||||||
|
|
Loading…
Reference in New Issue