add read-only option in accounts
parent
14f1527e61
commit
a62f1d6c01
|
@ -24,7 +24,7 @@ pub mod mbox;
|
|||
|
||||
use crate::async_workers::*;
|
||||
use crate::conf::AccountSettings;
|
||||
use crate::error::Result;
|
||||
use crate::error::{MeliError, Result};
|
||||
//use mailbox::backends::imap::ImapType;
|
||||
//use mailbox::backends::mbox::MboxType;
|
||||
use self::maildir::MaildirType;
|
||||
|
@ -210,6 +210,39 @@ pub trait BackendOp: ::std::fmt::Debug + ::std::marker::Send {
|
|||
fn set_flag(&mut self, envelope: &mut Envelope, flag: Flag) -> Result<()>;
|
||||
}
|
||||
|
||||
/// Wrapper for BackendOps that are to be set read-only.
|
||||
///
|
||||
/// Warning: Backend implementations may still cause side-effects (for example IMAP can set the
|
||||
/// Seen flag when fetching an envelope)
|
||||
#[derive(Debug)]
|
||||
pub struct ReadOnlyOp {
|
||||
op: Box<BackendOp>,
|
||||
}
|
||||
|
||||
impl ReadOnlyOp {
|
||||
pub fn new(op: Box<BackendOp>) -> Box<BackendOp> {
|
||||
Box::new(ReadOnlyOp { op })
|
||||
}
|
||||
}
|
||||
|
||||
impl BackendOp for ReadOnlyOp {
|
||||
fn description(&self) -> String {
|
||||
format!("read-only: {}", self.op.description())
|
||||
}
|
||||
fn as_bytes(&mut self) -> Result<&[u8]> {
|
||||
self.op.as_bytes()
|
||||
}
|
||||
fn fetch_headers(&mut self) -> Result<&[u8]> {
|
||||
self.op.fetch_headers()
|
||||
}
|
||||
fn fetch_body(&mut self) -> Result<&[u8]> {
|
||||
self.op.fetch_body()
|
||||
}
|
||||
fn fetch_flags(&self) -> Flag {
|
||||
self.op.fetch_flags()
|
||||
}
|
||||
fn set_flag(&mut self, _envelope: &mut Envelope, _flag: Flag) -> Result<()> {
|
||||
Err(MeliError::new("read-only set."))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ pub struct AccountSettings {
|
|||
pub format: String,
|
||||
pub sent_folder: String,
|
||||
pub identity: String,
|
||||
pub read_only: bool,
|
||||
pub display_name: Option<String>,
|
||||
}
|
||||
|
||||
|
@ -45,6 +46,9 @@ impl AccountSettings {
|
|||
pub fn identity(&self) -> &str {
|
||||
&self.identity
|
||||
}
|
||||
pub fn read_only(&self) -> bool {
|
||||
self.read_only
|
||||
}
|
||||
pub fn display_name(&self) -> Option<&String> {
|
||||
self.display_name.as_ref()
|
||||
}
|
||||
|
|
|
@ -1229,14 +1229,22 @@ impl Component for CompactListing {
|
|||
let hash = account.get_env(&i).hash();
|
||||
let op = account.operation(hash);
|
||||
let envelope: &mut Envelope = &mut account.get_env_mut(&i);
|
||||
envelope.set_seen(op).unwrap();
|
||||
if let Err(e) = envelope.set_seen(op) {
|
||||
context.replies.push_back(UIEvent::StatusEvent(
|
||||
StatusEvent::DisplayMessage(e.to_string()),
|
||||
));
|
||||
}
|
||||
self.row_updates.push(i);
|
||||
}
|
||||
SetUnread => {
|
||||
let hash = account.get_env(&i).hash();
|
||||
let op = account.operation(hash);
|
||||
let envelope: &mut Envelope = &mut account.get_env_mut(&i);
|
||||
envelope.set_unseen(op).unwrap();
|
||||
if let Err(e) = envelope.set_unseen(op) {
|
||||
context.replies.push_back(UIEvent::StatusEvent(
|
||||
StatusEvent::DisplayMessage(e.to_string()),
|
||||
));
|
||||
}
|
||||
self.row_updates.push(i);
|
||||
}
|
||||
Delete => { /* do nothing */ }
|
||||
|
|
|
@ -472,20 +472,14 @@ impl Component for ThreadListing {
|
|||
&account.get_env(&self.locations[self.cursor_pos.2]);
|
||||
(envelope.hash(), envelope.is_seen())
|
||||
};
|
||||
if !is_seen {
|
||||
let op = account.operation(hash);
|
||||
let envelope: &mut Envelope =
|
||||
account.get_env_mut(&self.locations[self.cursor_pos.2]);
|
||||
envelope.set_seen(op).unwrap();
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
is_seen
|
||||
}
|
||||
};
|
||||
|
||||
if must_highlight {
|
||||
self.highlight_line_self(idx, context);
|
||||
}
|
||||
|
||||
let mid = get_y(upper_left) + total_rows - bottom_entity_rows;
|
||||
self.draw_list(
|
||||
grid,
|
||||
|
|
|
@ -298,7 +298,14 @@ impl Component for MailView {
|
|||
if !is_seen {
|
||||
let op = account.operation(hash);
|
||||
let envelope: &mut Envelope = &mut account.get_env_mut(&self.coordinates.2);
|
||||
envelope.set_seen(op).unwrap();
|
||||
if let Err(e) = envelope.set_seen(op) {
|
||||
context
|
||||
.replies
|
||||
.push_back(UIEvent::StatusEvent(StatusEvent::DisplayMessage(format!(
|
||||
"Could not set message as seen: {}",
|
||||
e
|
||||
))));
|
||||
}
|
||||
}
|
||||
let envelope: &Envelope = &account.get_env(&self.coordinates.2);
|
||||
|
||||
|
|
|
@ -131,6 +131,8 @@ pub struct FileAccount {
|
|||
#[serde(default = "none", deserialize_with = "non_empty_string")]
|
||||
html_filter: Option<String>,
|
||||
|
||||
#[serde(default = "false_val")]
|
||||
read_only: bool,
|
||||
folders: Option<HashMap<String, FolderConf>>,
|
||||
}
|
||||
|
||||
|
@ -148,6 +150,7 @@ impl From<FileAccount> for AccountConf {
|
|||
format,
|
||||
sent_folder,
|
||||
identity,
|
||||
read_only: x.read_only,
|
||||
display_name,
|
||||
};
|
||||
|
||||
|
@ -366,7 +369,7 @@ where
|
|||
|
||||
mod default_vals {
|
||||
pub(in crate::conf) fn false_val() -> bool {
|
||||
true
|
||||
false
|
||||
}
|
||||
|
||||
pub(in crate::conf) fn true_val() -> bool {
|
||||
|
|
|
@ -28,10 +28,10 @@ use super::ToggleFlag;
|
|||
use fnv::FnvHashMap;
|
||||
use melib::async_workers::{Async, AsyncBuilder, AsyncStatus};
|
||||
use melib::backends::{
|
||||
BackendOp, Backends, Folder, FolderHash, MailBackend, NotifyFn, RefreshEvent,
|
||||
BackendOp, Backends, Folder, FolderHash, MailBackend, NotifyFn, ReadOnlyOp, RefreshEvent,
|
||||
RefreshEventConsumer, RefreshEventKind,
|
||||
};
|
||||
use melib::error::Result;
|
||||
use melib::error::{MeliError, Result};
|
||||
use melib::mailbox::*;
|
||||
use melib::thread::ThreadHash;
|
||||
use melib::AddressBook;
|
||||
|
@ -458,11 +458,23 @@ impl Account {
|
|||
}
|
||||
|
||||
pub fn save_draft(&self, draft: Draft) -> Result<()> {
|
||||
if self.settings.account.read_only() {
|
||||
return Err(MeliError::new(format!(
|
||||
"Account {} is read-only.",
|
||||
self.name.as_str()
|
||||
)));
|
||||
}
|
||||
let finalize = draft.finalise()?;
|
||||
self.backend
|
||||
.save(&finalize.as_bytes(), &self.settings.conf.draft_folder)
|
||||
}
|
||||
pub fn save(&self, bytes: &[u8], folder: &str) -> Result<()> {
|
||||
if self.settings.account.read_only() {
|
||||
return Err(MeliError::new(format!(
|
||||
"Account {} is read-only.",
|
||||
self.name.as_str()
|
||||
)));
|
||||
}
|
||||
self.backend.save(bytes, folder)
|
||||
}
|
||||
pub fn iter_mailboxes(&self) -> MailboxIterator {
|
||||
|
@ -486,7 +498,12 @@ impl Account {
|
|||
for mailbox in self.folders.values() {
|
||||
if let Some(Ok(m)) = mailbox {
|
||||
if m.envelopes.contains(&h) {
|
||||
return self.backend.operation(h, m.folder.hash());
|
||||
let operation = self.backend.operation(h, m.folder.hash());
|
||||
if self.settings.account.read_only() {
|
||||
return ReadOnlyOp::new(operation);
|
||||
} else {
|
||||
return operation;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue