Compare commits

..

1 Commits

Author SHA1 Message Date
WofWca
5265dc635b fix: hide connectivity HTML quota if not supported
This also solves the problem with the fact that
it's not clear from the resulting HTML
that this error message is referring to quota and not something else.
See https://github.com/chatmail/core/pull/8130.
2026-05-15 12:07:46 +04:00
5 changed files with 76 additions and 75 deletions

View File

@@ -7056,11 +7056,6 @@ void dc_event_unref(dc_event_t* event);
/// `%1$s` will be replaced by a possibly more detailed, typically english, error description.
#define DC_STR_ERROR 112
/// "Not supported by your provider."
///
/// Used in the connectivity view.
#define DC_STR_NOT_SUPPORTED_BY_PROVIDER 113
/// "Messages"
///
/// Used as a subtitle in quota context; can be plural always.

View File

@@ -3,13 +3,13 @@
use std::collections::BTreeMap;
use std::time::Duration;
use anyhow::{Context as _, Result, anyhow};
use anyhow::{Context as _, Result};
use async_imap::types::{Quota, QuotaResource};
use crate::EventType;
use crate::context::Context;
use crate::imap::session::Session as ImapSession;
use crate::tools::{self, time_elapsed};
use crate::{EventType, stock_str};
/// quota icon in connectivity is "yellow".
pub const QUOTA_WARN_THRESHOLD_PERCENTAGE: u64 = 80;
@@ -17,13 +17,25 @@ pub const QUOTA_WARN_THRESHOLD_PERCENTAGE: u64 = 80;
/// quota icon in connectivity is "red".
pub const QUOTA_ERROR_THRESHOLD_PERCENTAGE: u64 = 95;
/// [QuotaInfo] error.
#[derive(Debug, thiserror::Error)]
pub enum Error {
/// Quota info not supported by the provider
#[error("Quota info not supported by the provider")]
NotSupportedByProvider,
/// Any other error: network, parsing, etc.
#[error("{0:#}")]
Other(#[from] anyhow::Error),
}
/// Server quota information with an update timestamp.
#[derive(Debug)]
pub struct QuotaInfo {
/// Recently loaded quota information.
/// set to `Err()` if the provider does not support quota or on other errors,
/// set to `Ok()` for valid quota information.
pub(crate) recent: Result<BTreeMap<String, Vec<QuotaResource>>>,
pub(crate) recent: Result<BTreeMap<String, Vec<QuotaResource>>, Error>,
/// When the structure was modified.
pub(crate) modified: tools::Time,
@@ -76,9 +88,11 @@ impl Context {
info!(self, "Transport {transport_id}: Updating quota.");
let quota = if session.can_check_quota() {
get_unique_quota_roots_and_usage(session, folder).await
get_unique_quota_roots_and_usage(session, folder)
.await
.map_err(Error::Other)
} else {
Err(anyhow!(stock_str::not_supported_by_provider(self)))
Err(Error::NotSupportedByProvider)
};
self.quota.write().await.insert(

View File

@@ -2352,75 +2352,71 @@ async fn handle_edit_delete(
from_id: ContactId,
) -> Result<()> {
if let Some(rfc724_mid) = mime_parser.get_header(HeaderDef::ChatEdit) {
let Some(original_msg_id) = rfc724_mid_exists(context, rfc724_mid).await? else {
if let Some(original_msg_id) = rfc724_mid_exists(context, rfc724_mid).await? {
if let Some(mut original_msg) =
Message::load_from_db_optional(context, original_msg_id).await?
{
if original_msg.from_id == from_id {
if let Some(part) = mime_parser.parts.first() {
let edit_msg_showpadlock = part
.param
.get_bool(Param::GuaranteeE2ee)
.unwrap_or_default();
if edit_msg_showpadlock || !original_msg.get_showpadlock() {
let new_text =
part.msg.strip_prefix(EDITED_PREFIX).unwrap_or(&part.msg);
chat::save_text_edit_to_db(context, &mut original_msg, new_text)
.await?;
} else {
warn!(context, "Edit message: Not encrypted.");
}
}
} else {
warn!(context, "Edit message: Bad sender.");
}
} else {
warn!(context, "Edit message: Database entry does not exist.");
}
} else {
warn!(
context,
"Edit message: rfc724_mid {rfc724_mid:?} not found."
);
return Ok(());
};
let Some(mut original_msg) =
Message::load_from_db_optional(context, original_msg_id).await?
else {
warn!(context, "Edit message: Database entry does not exist.");
return Ok(());
};
if original_msg.from_id != from_id {
warn!(context, "Edit message: Bad sender.");
return Ok(());
}
let Some(part) = mime_parser.parts.first() else {
return Ok(());
};
let edit_msg_showpadlock = part
.param
.get_bool(Param::GuaranteeE2ee)
.unwrap_or_default();
if !edit_msg_showpadlock && original_msg.get_showpadlock() {
warn!(context, "Edit message: Not encrypted.");
return Ok(());
}
let new_text = part.msg.strip_prefix(EDITED_PREFIX).unwrap_or(&part.msg);
chat::save_text_edit_to_db(context, &mut original_msg, new_text).await?;
} else if let Some(rfc724_mid_list) = mime_parser.get_header(HeaderDef::ChatDelete)
&& let Some(part) = mime_parser.parts.first()
{
// See `message::delete_msgs_ex()`, unlike edit requests, DC doesn't send unencrypted
// deletion requests, so there's no need to support them.
if part.param.get_bool(Param::GuaranteeE2ee) != Some(true) {
warn!(context, "Delete message: Not encrypted.");
return Ok(());
}
if part.param.get_bool(Param::GuaranteeE2ee).unwrap_or(false) {
let mut modified_chat_ids = BTreeSet::new();
let mut msg_ids = Vec::new();
let mut modified_chat_ids = BTreeSet::new();
let mut msg_ids = Vec::new();
let rfc724_mid_vec: Vec<&str> = rfc724_mid_list.split_whitespace().collect();
for rfc724_mid in rfc724_mid_vec {
let rfc724_mid = rfc724_mid.trim_start_matches('<').trim_end_matches('>');
let Some(msg_id) = message::rfc724_mid_exists(context, rfc724_mid).await? else {
warn!(context, "Delete message: {rfc724_mid:?} not found.");
// Insert a tombstone so that the message will be ignored if it arrives later within a period specified in prune_tombstones().
insert_tombstone(context, rfc724_mid).await?;
continue;
};
let Some(msg) = Message::load_from_db_optional(context, msg_id).await? else {
warn!(context, "Delete message: Database entry does not exist.");
continue;
};
if msg.from_id != from_id {
warn!(context, "Delete message: Bad sender.");
continue;
let rfc724_mid_vec: Vec<&str> = rfc724_mid_list.split_whitespace().collect();
for rfc724_mid in rfc724_mid_vec {
let rfc724_mid = rfc724_mid.trim_start_matches('<').trim_end_matches('>');
if let Some(msg_id) = message::rfc724_mid_exists(context, rfc724_mid).await? {
if let Some(msg) = Message::load_from_db_optional(context, msg_id).await? {
if msg.from_id == from_id {
message::delete_msg_locally(context, &msg).await?;
msg_ids.push(msg.id);
modified_chat_ids.insert(msg.chat_id);
} else {
warn!(context, "Delete message: Bad sender.");
}
} else {
warn!(context, "Delete message: Database entry does not exist.");
}
} else {
warn!(context, "Delete message: {rfc724_mid:?} not found.");
// Insert a tombstone so that the message will be ignored if it arrives later within a period specified in prune_tombstones().
insert_tombstone(context, rfc724_mid).await?;
}
}
message::delete_msg_locally(context, &msg).await?;
msg_ids.push(msg.id);
modified_chat_ids.insert(msg.chat_id);
message::delete_msgs_locally_done(context, &msg_ids, modified_chat_ids).await?;
} else {
warn!(context, "Delete message: Not encrypted.");
}
message::delete_msgs_locally_done(context, &msg_ids, modified_chat_ids).await?;
}
Ok(())
}

View File

@@ -418,7 +418,11 @@ impl Context {
};
match &quota.recent {
Err(e) => {
ret += &escaper::encode_minimal(&e.to_string());
// If not supported by the provider,
// just skip the "quota" section.
if !matches!(e, crate::quota::Error::NotSupportedByProvider) {
ret += &escaper::encode_minimal(&e.to_string());
}
}
Ok(quota) => {
if quota.is_empty() {

View File

@@ -189,9 +189,6 @@ pub enum StockMessage {
#[strum(props(fallback = "Error: %1$s"))]
Error = 112,
#[strum(props(fallback = "Not supported by your provider."))]
NotSupportedByProvider = 113,
#[strum(props(fallback = "Messages"))]
Messages = 114,
@@ -1137,11 +1134,6 @@ pub(crate) fn error(context: &Context, error: &str) -> String {
translated(context, StockMessage::Error).replace1(error)
}
/// Stock string: `Not supported by your provider.`.
pub(crate) fn not_supported_by_provider(context: &Context) -> String {
translated(context, StockMessage::NotSupportedByProvider)
}
/// Stock string: `Messages`.
/// Used as a subtitle in quota context; can be plural always.
pub(crate) fn messages(context: &Context) -> String {