mirror of
https://github.com/soywod/himalaya.git
synced 2024-07-08 18:45:13 +00:00
improve choice after editing msg
This commit is contained in:
parent
0dd73e693e
commit
64019fa5ec
|
@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- IDLE support [#29]
|
- IDLE support [#29]
|
||||||
|
- Improve choice after editing msg [#30]
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
|
@ -80,6 +81,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
[#22]: https://github.com/soywod/himalaya/issues/22
|
[#22]: https://github.com/soywod/himalaya/issues/22
|
||||||
[#25]: https://github.com/soywod/himalaya/issues/25
|
[#25]: https://github.com/soywod/himalaya/issues/25
|
||||||
[#29]: https://github.com/soywod/himalaya/issues/29
|
[#29]: https://github.com/soywod/himalaya/issues/29
|
||||||
|
[#30]: https://github.com/soywod/himalaya/issues/30
|
||||||
[#32]: https://github.com/soywod/himalaya/issues/32
|
[#32]: https://github.com/soywod/himalaya/issues/32
|
||||||
[#38]: https://github.com/soywod/himalaya/issues/38
|
[#38]: https://github.com/soywod/himalaya/issues/38
|
||||||
[#39]: https://github.com/soywod/himalaya/issues/39
|
[#39]: https://github.com/soywod/himalaya/issues/39
|
||||||
|
|
101
src/app.rs
101
src/app.rs
|
@ -1,6 +1,6 @@
|
||||||
use clap::{self, Arg, SubCommand};
|
use clap::{self, Arg, SubCommand};
|
||||||
use error_chain::error_chain;
|
use error_chain::error_chain;
|
||||||
use std::fs;
|
use std::{env, fs};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
config::{self, Config},
|
config::{self, Config},
|
||||||
|
@ -332,14 +332,33 @@ impl<'a> App<'a> {
|
||||||
let mut imap_conn = ImapConnector::new(&account)?;
|
let mut imap_conn = ImapConnector::new(&account)?;
|
||||||
let tpl = Msg::build_new_tpl(&config, &account)?;
|
let tpl = Msg::build_new_tpl(&config, &account)?;
|
||||||
let content = input::open_editor_with_tpl(tpl.to_string().as_bytes())?;
|
let content = input::open_editor_with_tpl(tpl.to_string().as_bytes())?;
|
||||||
let msg = Msg::from(content);
|
let mut msg = Msg::from(content);
|
||||||
|
|
||||||
input::ask_for_confirmation("Send the message?")?;
|
loop {
|
||||||
|
match input::post_edit_choice() {
|
||||||
println!("Sending…");
|
Ok(choice) => match choice {
|
||||||
smtp::send(&account, &msg.to_sendable_msg()?)?;
|
input::Choice::Send => {
|
||||||
imap_conn.append_msg("Sent", &msg.to_vec()?)?;
|
println!("Sending…");
|
||||||
println!("Done!");
|
smtp::send(&account, &msg.to_sendable_msg()?)?;
|
||||||
|
imap_conn.append_msg("Sent", &msg.to_vec()?)?;
|
||||||
|
println!("Done!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
input::Choice::Draft => {
|
||||||
|
println!("Saving to draft…");
|
||||||
|
imap_conn.append_msg("Drafts", &msg.to_vec()?)?;
|
||||||
|
println!("Done!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
input::Choice::Edit => {
|
||||||
|
let content = input::open_editor_with_draft()?;
|
||||||
|
msg = Msg::from(content);
|
||||||
|
}
|
||||||
|
input::Choice::Quit => break,
|
||||||
|
},
|
||||||
|
Err(err) => eprintln!("{}", err),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
imap_conn.logout();
|
imap_conn.logout();
|
||||||
}
|
}
|
||||||
|
@ -395,14 +414,33 @@ impl<'a> App<'a> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let content = input::open_editor_with_tpl(&tpl.to_string().as_bytes())?;
|
let content = input::open_editor_with_tpl(&tpl.to_string().as_bytes())?;
|
||||||
let msg = Msg::from(content);
|
let mut msg = Msg::from(content);
|
||||||
|
|
||||||
input::ask_for_confirmation("Send the message?")?;
|
loop {
|
||||||
|
match input::post_edit_choice() {
|
||||||
println!("Sending…");
|
Ok(choice) => match choice {
|
||||||
smtp::send(&account, &msg.to_sendable_msg()?)?;
|
input::Choice::Send => {
|
||||||
imap_conn.append_msg("Sent", &msg.to_vec()?)?;
|
println!("Sending…");
|
||||||
println!("Done!");
|
smtp::send(&account, &msg.to_sendable_msg()?)?;
|
||||||
|
imap_conn.append_msg("Sent", &msg.to_vec()?)?;
|
||||||
|
println!("Done!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
input::Choice::Draft => {
|
||||||
|
println!("Saving to draft…");
|
||||||
|
imap_conn.append_msg("Drafts", &msg.to_vec()?)?;
|
||||||
|
println!("Done!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
input::Choice::Edit => {
|
||||||
|
let content = input::open_editor_with_draft()?;
|
||||||
|
msg = Msg::from(content);
|
||||||
|
}
|
||||||
|
input::Choice::Quit => break,
|
||||||
|
},
|
||||||
|
Err(err) => eprintln!("{}", err),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
imap_conn.logout();
|
imap_conn.logout();
|
||||||
}
|
}
|
||||||
|
@ -418,14 +456,33 @@ impl<'a> App<'a> {
|
||||||
let msg = Msg::from(imap_conn.read_msg(&mbox, &uid)?);
|
let msg = Msg::from(imap_conn.read_msg(&mbox, &uid)?);
|
||||||
let tpl = msg.build_forward_tpl(&config, &account)?;
|
let tpl = msg.build_forward_tpl(&config, &account)?;
|
||||||
let content = input::open_editor_with_tpl(&tpl.to_string().as_bytes())?;
|
let content = input::open_editor_with_tpl(&tpl.to_string().as_bytes())?;
|
||||||
let msg = Msg::from(content);
|
let mut msg = Msg::from(content);
|
||||||
|
|
||||||
input::ask_for_confirmation("Send the message?")?;
|
loop {
|
||||||
|
match input::post_edit_choice() {
|
||||||
println!("Sending…");
|
Ok(choice) => match choice {
|
||||||
smtp::send(&account, &msg.to_sendable_msg()?)?;
|
input::Choice::Send => {
|
||||||
imap_conn.append_msg("Sent", &msg.to_vec()?)?;
|
println!("Sending…");
|
||||||
println!("Done!");
|
smtp::send(&account, &msg.to_sendable_msg()?)?;
|
||||||
|
imap_conn.append_msg("Sent", &msg.to_vec()?)?;
|
||||||
|
println!("Done!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
input::Choice::Draft => {
|
||||||
|
println!("Saving to draft…");
|
||||||
|
imap_conn.append_msg("Drafts", &msg.to_vec()?)?;
|
||||||
|
println!("Done!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
input::Choice::Edit => {
|
||||||
|
let content = input::open_editor_with_draft()?;
|
||||||
|
msg = Msg::from(content);
|
||||||
|
}
|
||||||
|
input::Choice::Quit => break,
|
||||||
|
},
|
||||||
|
Err(err) => eprintln!("{}", err),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
imap_conn.logout();
|
imap_conn.logout();
|
||||||
}
|
}
|
||||||
|
|
53
src/input.rs
53
src/input.rs
|
@ -1,7 +1,7 @@
|
||||||
use error_chain::error_chain;
|
use error_chain::error_chain;
|
||||||
use std::{
|
use std::{
|
||||||
env,
|
env,
|
||||||
fs::{remove_file, File},
|
fs::File,
|
||||||
io::{self, Read, Write},
|
io::{self, Read, Write},
|
||||||
process::Command,
|
process::Command,
|
||||||
};
|
};
|
||||||
|
@ -29,23 +29,52 @@ pub fn open_editor_with_tpl(tpl: &[u8]) -> Result<String> {
|
||||||
.chain_err(|| format!("Cannot open file `{}`", draft_path.to_string_lossy()))?
|
.chain_err(|| format!("Cannot open file `{}`", draft_path.to_string_lossy()))?
|
||||||
.read_to_string(&mut draft)
|
.read_to_string(&mut draft)
|
||||||
.chain_err(|| format!("Cannot read file `{}`", draft_path.to_string_lossy()))?;
|
.chain_err(|| format!("Cannot read file `{}`", draft_path.to_string_lossy()))?;
|
||||||
remove_file(&draft_path)
|
|
||||||
.chain_err(|| format!("Cannot remove file `{}`", draft_path.to_string_lossy()))?;
|
|
||||||
|
|
||||||
Ok(draft)
|
Ok(draft)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ask_for_confirmation(prompt: &str) -> Result<()> {
|
pub fn open_editor_with_draft() -> Result<String> {
|
||||||
print!("{} (y/n) ", prompt);
|
// Creates draft file
|
||||||
|
let mut draft_path = env::temp_dir();
|
||||||
|
draft_path.push("himalaya-draft.mail");
|
||||||
|
|
||||||
|
// Opens editor and saves user input to draft file
|
||||||
|
Command::new(env::var("EDITOR").chain_err(|| "Cannot find `EDITOR` env var")?)
|
||||||
|
.arg(&draft_path)
|
||||||
|
.status()
|
||||||
|
.chain_err(|| "Cannot start editor")?;
|
||||||
|
|
||||||
|
// Extracts draft file content
|
||||||
|
let mut draft = String::new();
|
||||||
|
File::open(&draft_path)
|
||||||
|
.chain_err(|| format!("Cannot open file `{}`", draft_path.to_string_lossy()))?
|
||||||
|
.read_to_string(&mut draft)
|
||||||
|
.chain_err(|| format!("Cannot read file `{}`", draft_path.to_string_lossy()))?;
|
||||||
|
|
||||||
|
Ok(draft)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub enum Choice {
|
||||||
|
Send,
|
||||||
|
Draft,
|
||||||
|
Edit,
|
||||||
|
Quit,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn post_edit_choice() -> Result<Choice> {
|
||||||
|
print!("(s)end, (d)raft, (e)dit or (q)uit? ");
|
||||||
io::stdout().flush().chain_err(|| "Cannot flush stdout")?;
|
io::stdout().flush().chain_err(|| "Cannot flush stdout")?;
|
||||||
|
|
||||||
match io::stdin()
|
let mut buf = String::new();
|
||||||
.bytes()
|
io::stdin()
|
||||||
.next()
|
.read_line(&mut buf)
|
||||||
.and_then(|res| res.ok())
|
.chain_err(|| "Cannot read stdin")?;
|
||||||
.map(|bytes| bytes as char)
|
|
||||||
{
|
match buf.bytes().next().map(|bytes| bytes as char) {
|
||||||
Some('y') | Some('Y') => Ok(()),
|
Some('s') => Ok(Choice::Send),
|
||||||
|
Some('d') => Ok(Choice::Draft),
|
||||||
|
Some('e') => Ok(Choice::Edit),
|
||||||
|
Some('q') => Ok(Choice::Quit),
|
||||||
Some(choice) => Err(format!("Invalid choice `{}`", choice).into()),
|
Some(choice) => Err(format!("Invalid choice `{}`", choice).into()),
|
||||||
None => Err("Empty choice".into()),
|
None => Err("Empty choice".into()),
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue