Browse Source

Small fixes

tags/alpha-0.6.0
parent
commit
3ac2c12e7a
WARNING! Although there is a key with this ID in the database it does not verify this commit! This commit is SUSPICIOUS. GPG Key ID: 73627C2F690DF710
11 changed files with 48 additions and 35 deletions
  1. +7
    -0
      CHANGELOG.md
  2. +1
    -1
      Cargo.toml
  3. +25
    -4
      melib/src/backends/imap.rs
  4. +4
    -19
      melib/src/backends/imap/connection.rs
  5. +2
    -1
      melib/src/backends/imap/operations.rs
  6. +1
    -1
      melib/src/collection.rs
  7. +1
    -0
      melib/src/conf.rs
  8. +0
    -3
      melib/src/smtp.rs
  9. +1
    -1
      src/components/mail/status.rs
  10. +5
    -4
      src/components/mail/view/thread.rs
  11. +1
    -1
      src/components/utilities/widgets.rs

+ 7
- 0
CHANGELOG.md View File

@@ -9,6 +9,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Added

- Add `select` command to select threads that match search query
- Add support for mass copying/deleting/flagging/moving of messages
- IMAP: add support for COMPRESS=DEFLATE and others
Extension use can be configured with individual flags such as `use_deflate`
- Rename EXECUTE mode to COMMAND
- add async IMAP backend
- add in-app SMTP support
- ui: Show decoded source by default when viewing an Envelope's source
- ui: Add search in pagers
- Add managesieve REPL binary for managesieve script management


+ 1
- 1
Cargo.toml View File

@@ -65,7 +65,7 @@ quote = "^1.0"
proc-macro2 = "1.0.18"

[profile.release]
lto = true
lto = "fat"
opt-level = "z"
debug = false



+ 25
- 4
melib/src/backends/imap.rs View File

@@ -306,10 +306,19 @@ impl MailBackend for ImapType {
fn is_online_async(&self) -> ResultFuture<()> {
let connection = self.connection.clone();
Ok(Box::pin(async move {
let mut conn = connection.lock().await;
conn.connect().await?;

Ok(())
match timeout(std::time::Duration::from_secs(3), connection.lock()).await {
Ok(mut conn) => {
debug!("is_online_async");
match debug!(timeout(std::time::Duration::from_secs(3), conn.connect()).await) {
Ok(Ok(())) => Ok(()),
Err(err) | Ok(Err(err)) => {
conn.stream = Err(err.clone());
debug!(conn.connect().await)
}
}
}
Err(err) => Err(err),
}
}))
}

@@ -1627,3 +1636,15 @@ async fn fetch_hlpr(
};
Ok(payload)
}

use futures::future::{self, Either};

async fn timeout<O>(dur: std::time::Duration, f: impl Future<Output = O>) -> Result<O> {
futures::pin_mut!(f);
match future::select(f, smol::Timer::after(dur)).await {
Either::Left((out, _)) => Ok(out),
Either::Right(_) => {
Err(MeliError::new("Timed out.").set_kind(crate::error::ErrorKind::Network))
}
}
}

+ 4
- 19
melib/src/backends/imap/connection.rs View File

@@ -396,9 +396,6 @@ impl ImapStream {
last_line_idx += pos + "\r\n".len();
}
}
Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => {
continue;
}
Err(e) => {
return Err(MeliError::from(e).set_err_kind(crate::error::ErrorKind::Network));
}
@@ -634,6 +631,7 @@ impl ImapConnection {
if let Err(err) =
try_await(async { self.stream.as_mut()?.send_command(command).await }).await
{
self.stream = Err(err.clone());
if err.kind.is_network() {
self.connect().await?;
}
@@ -646,6 +644,7 @@ impl ImapConnection {
pub async fn send_literal(&mut self, data: &[u8]) -> Result<()> {
if let Err(err) = try_await(async { self.stream.as_mut()?.send_literal(data).await }).await
{
self.stream = Err(err.clone());
if err.kind.is_network() {
self.connect().await?;
}
@@ -657,6 +656,7 @@ impl ImapConnection {

pub async fn send_raw(&mut self, raw: &[u8]) -> Result<()> {
if let Err(err) = try_await(async { self.stream.as_mut()?.send_raw(raw).await }).await {
self.stream = Err(err.clone());
if err.kind.is_network() {
self.connect().await?;
}
@@ -862,27 +862,12 @@ async fn read(
}
*prev_failure = None;
}
Err(e)
if e.kind() == std::io::ErrorKind::WouldBlock
|| e.kind() == std::io::ErrorKind::Interrupted =>
{
debug!(&e);
if let Some(prev_failure) = prev_failure.as_ref() {
if Instant::now().duration_since(*prev_failure)
>= std::time::Duration::new(60 * 5, 0)
{
*err = Some(e.to_string());
*break_flag = true;
}
} else {
*prev_failure = Some(Instant::now());
}
}
Err(e) => {
debug!(&conn.stream);
debug!(&e);
*err = Some(e.to_string());
*break_flag = true;
*prev_failure = Some(Instant::now());
}
}
None


+ 2
- 1
melib/src/backends/imap/operations.rs View File

@@ -66,7 +66,8 @@ impl BackendOp for ImapOp {
if !exists_in_cache {
let mut response = String::with_capacity(8 * 1024);
{
let mut conn = connection.lock().await;
let mut conn =
timeout(std::time::Duration::from_secs(3), connection.lock()).await?;
conn.examine_mailbox(mailbox_hash, &mut response, false)
.await?;
conn.send_command(format!("UID FETCH {} (FLAGS RFC822)", uid).as_bytes())


+ 1
- 1
melib/src/collection.rs View File

@@ -155,7 +155,7 @@ impl Collection {
new_hash: EnvelopeHash,
mailbox_hash: MailboxHash,
) -> bool {
if !self.envelopes.write().unwrap().contains_key(&old_hash) {
if !self.envelopes.read().unwrap().contains_key(&old_hash) {
return false;
}
let mut envelope = self.envelopes.write().unwrap().remove(&old_hash).unwrap();


+ 1
- 0
melib/src/conf.rs View File

@@ -75,6 +75,7 @@ impl AccountSettings {
#[serde(default)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct MailboxConf {
#[serde(alias = "rename")]
pub alias: Option<String>,
#[serde(default = "false_val")]
pub autoload: bool,


+ 0
- 3
melib/src/smtp.rs View File

@@ -903,9 +903,6 @@ async fn read_lines<'r>(
Ok(b) => {
ret.push_str(unsafe { std::str::from_utf8_unchecked(&buf[0..b]) });
}
Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => {
panic!("block");
}
Err(e) => {
return Err(MeliError::from(e).set_kind(crate::error::ErrorKind::Network));
}


+ 1
- 1
src/components/mail/status.rs View File

@@ -384,7 +384,7 @@ impl StatusPanel {
.enumerate()
{
write_string_to_grid(
&format!("{}: {}", f.path(), f.special_usage()),
&format!("{}: {}", f.special_usage(), f.path()),
&mut self.content,
self.theme_default.fg,
self.theme_default.bg,


+ 5
- 4
src/components/mail/view/thread.rs View File

@@ -733,12 +733,10 @@ impl ThreadView {
let total_rows = height!(area);

let pager_ratio = context.runtime_settings.pager.pager_ratio;
let bottom_entity_rows = (pager_ratio * total_rows) / 100;
let mut bottom_entity_rows = (pager_ratio * total_rows) / 100;

if bottom_entity_rows > total_rows {
clear_area(grid, area, crate::conf::value(context, "theme_default"));
context.dirty_areas.push_back(area);
return;
bottom_entity_rows = total_rows.saturating_sub(1);
}

let mut mid = get_y(upper_left) + total_rows - bottom_entity_rows;
@@ -952,6 +950,9 @@ impl Component for ThreadView {
self.dirty = false;
return;
}
if !self.is_dirty() {
return;
}

/* If user has selected another mail to view, change to it */
if self.new_expanded_pos != self.expanded_pos {


+ 1
- 1
src/components/utilities/widgets.rs View File

@@ -1063,7 +1063,7 @@ impl fmt::Display for ProgressSpinner {
impl Component for ProgressSpinner {
fn draw(&mut self, grid: &mut CellBuffer, area: Area, context: &mut Context) {
if self.dirty {
let theme_attr = crate::conf::value(context, "theme_default");
let theme_attr = crate::conf::value(context, "status.bar");
clear_area(grid, area, theme_attr);
let stage = self.stage;
self.stage = (self.stage + 1).wrapping_rem(Self::KINDS[self.kind].len());


Loading…
Cancel
Save