From dd7e1a02bee2df3a58b3ef4569d55a0a19b1a1b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20DOUIN?= Date: Sun, 4 Feb 2024 12:13:14 +0100 Subject: [PATCH] improve pre and post edit choices interaction --- CHANGELOG.md | 2 + Cargo.lock | 2 +- Cargo.toml | 2 +- src/ui/choice.rs | 130 +++++++++++++++++++++-------------------------- 4 files changed, 62 insertions(+), 74 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c8b62bc..c21d293 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed +- Improved pre and post edit choices interaction. [sourcehut#58] - Changed `envelope.watch.{event}.{hook}`: hooks can now be cumulated. For example it is possible to send a system notification and execute a shell command when receiving a new envelope: ```toml @@ -907,6 +908,7 @@ Few major concepts changed: [sourcehut#41]: https://todo.sr.ht/~soywod/pimalaya/41 [sourcehut#43]: https://todo.sr.ht/~soywod/pimalaya/43 [sourcehut#54]: https://todo.sr.ht/~soywod/pimalaya/54 +[sourcehut#58]: https://todo.sr.ht/~soywod/pimalaya/58 [sourcehut#59]: https://todo.sr.ht/~soywod/pimalaya/59 [sourcehut#60]: https://todo.sr.ht/~soywod/pimalaya/60 [sourcehut#95]: https://todo.sr.ht/~soywod/pimalaya/95 diff --git a/Cargo.lock b/Cargo.lock index 60ee8c2..5966de5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1840,7 +1840,7 @@ dependencies = [ [[package]] name = "himalaya" -version = "1.0.0-beta.2" +version = "1.0.0-beta.3" dependencies = [ "anyhow", "async-trait", diff --git a/Cargo.toml b/Cargo.toml index ed87d40..571350f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "himalaya" description = "CLI to manage emails" -version = "1.0.0-beta.2" +version = "1.0.0-beta.3" authors = ["soywod "] edition = "2021" license = "MIT" diff --git a/src/ui/choice.rs b/src/ui/choice.rs index ad0ce67..6ea62be 100644 --- a/src/ui/choice.rs +++ b/src/ui/choice.rs @@ -1,47 +1,42 @@ -use anyhow::{anyhow, bail, Context, Result}; -use log::{debug, error}; -use std::io::{self, Write}; +use anyhow::Result; +use dialoguer::Select; +use super::THEME; + +#[derive(Clone, Debug)] pub enum PreEditChoice { Edit, Discard, Quit, } -pub fn pre_edit() -> Result { - println!("A draft was found:"); - print!("(e)dit, (d)iscard or (q)uit? "); - io::stdout().flush().context("cannot flush stdout")?; - - let mut buf = String::new(); - io::stdin() - .read_line(&mut buf) - .context("cannot read stdin")?; - - match buf.bytes().next().map(|bytes| bytes as char) { - Some('e') => { - debug!("edit choice matched"); - Ok(PreEditChoice::Edit) - } - Some('d') => { - debug!("discard choice matched"); - Ok(PreEditChoice::Discard) - } - Some('q') => { - debug!("quit choice matched"); - Ok(PreEditChoice::Quit) - } - Some(choice) => { - error!(r#"invalid choice "{}""#, choice); - Err(anyhow!(r#"invalid choice "{}""#, choice)) - } - None => { - error!("empty choice"); - Err(anyhow!("empty choice")) +impl ToString for PreEditChoice { + fn to_string(&self) -> String { + match self { + Self::Edit => "Edit it".into(), + Self::Discard => "Discard it".into(), + Self::Quit => "Quit".into(), } } } +pub fn pre_edit() -> Result { + let choices = [ + PreEditChoice::Edit, + PreEditChoice::Discard, + PreEditChoice::Quit, + ]; + + let choice_idx = Select::with_theme(&*THEME) + .with_prompt("A draft was found, what would you like to do with it?") + .items(&choices) + .default(0) + .interact()?; + + Ok(choices[choice_idx].clone()) +} + +#[derive(Clone, Debug, Eq, PartialEq)] pub enum PostEditChoice { #[cfg(feature = "message-send")] Send, @@ -52,45 +47,36 @@ pub enum PostEditChoice { Discard, } -pub fn post_edit() -> Result { - print!("(s)end, (e)dit, (l)ocal/(r)emote draft or (d)iscard? "); - io::stdout().flush().context("cannot flush stdout")?; - - let mut buf = String::new(); - io::stdin() - .read_line(&mut buf) - .context("cannot read stdin")?; - - match buf.bytes().next().map(|bytes| bytes as char) { - #[cfg(feature = "message-send")] - Some('s') => { - debug!("send choice matched"); - Ok(PostEditChoice::Send) - } - Some('l') => { - debug!("save local draft choice matched"); - Ok(PostEditChoice::LocalDraft) - } - #[cfg(feature = "message-add")] - Some('r') => { - debug!("save remote draft matched"); - Ok(PostEditChoice::RemoteDraft) - } - Some('e') => { - debug!("edit choice matched"); - Ok(PostEditChoice::Edit) - } - Some('d') => { - debug!("discard choice matched"); - Ok(PostEditChoice::Discard) - } - Some(choice) => { - error!(r#"invalid choice "{}""#, choice); - bail!("invalid choice {choice}"); - } - None => { - error!("empty choice"); - bail!("empty choice"); +impl ToString for PostEditChoice { + fn to_string(&self) -> String { + match self { + #[cfg(feature = "message-send")] + Self::Send => "Send it".into(), + Self::Edit => "Edit it again".into(), + Self::LocalDraft => "Save it as local draft".into(), + #[cfg(feature = "message-add")] + Self::RemoteDraft => "Save it as remote draft".into(), + Self::Discard => "Discard it".into(), } } } + +pub fn post_edit() -> Result { + let choices = [ + #[cfg(feature = "message-send")] + PostEditChoice::Send, + PostEditChoice::Edit, + PostEditChoice::LocalDraft, + #[cfg(feature = "message-add")] + PostEditChoice::RemoteDraft, + PostEditChoice::Discard, + ]; + + let choice_idx = Select::with_theme(&*THEME) + .with_prompt("What would you like to do with this message?") + .items(&choices) + .default(0) + .interact()?; + + Ok(choices[choice_idx].clone()) +}