accounts: add default_mailbox setting
Add a default mailbox setting: > The mailbox that is the default to open / view for this account. Must be > a valid mailbox name. > > If not specified, the default is [`Self::root_mailbox`]. Closes: #350 Signed-off-by: Manos Pitsidianakis <manos@pitsidianak.is>pull/370/head
parent
742f038f74
commit
4e941a9e8b
|
@ -217,6 +217,11 @@ Default values are shown in parentheses.
|
|||
The backend-specific path of the root_mailbox, usually
|
||||
.Sy INBOX Ns
|
||||
\&.
|
||||
.It Ic default_mailbox Ar String
|
||||
.Pq Em optional
|
||||
The mailbox that is the default to open or view for this account.
|
||||
Must be a valid mailbox path.
|
||||
If not specified, the default will be the root mailbox.
|
||||
.It Ic format Ar String Op maildir mbox imap notmuch jmap
|
||||
The format of the mail backend.
|
||||
.It Ic subscribed_mailboxes Ar [String,]
|
||||
|
|
|
@ -350,9 +350,19 @@ impl Account {
|
|||
.keys()
|
||||
.cloned()
|
||||
.collect::<HashSet<String>>();
|
||||
let mut default_mailbox = self
|
||||
.settings
|
||||
.conf
|
||||
.default_mailbox
|
||||
.clone()
|
||||
.into_iter()
|
||||
.collect::<HashSet<String>>();
|
||||
for f in ref_mailboxes.values_mut() {
|
||||
if let Some(conf) = self.settings.mailbox_confs.get_mut(f.path()) {
|
||||
mailbox_conf_hash_set.remove(f.path());
|
||||
if default_mailbox.remove(f.path()) {
|
||||
self.settings.default_mailbox = Some(f.hash());
|
||||
}
|
||||
conf.mailbox_conf.usage = if f.special_usage() != SpecialUsageMailbox::Normal {
|
||||
Some(f.special_usage())
|
||||
} else {
|
||||
|
@ -447,6 +457,23 @@ impl Account {
|
|||
)));
|
||||
}
|
||||
|
||||
match self.settings.conf.default_mailbox {
|
||||
Some(ref v) if !default_mailbox.is_empty() => {
|
||||
let err = Error::new(format!(
|
||||
"Account `{}` has default mailbox set as `{}` but it doesn't exist.",
|
||||
&self.name, v
|
||||
))
|
||||
.set_kind(ErrorKind::Configuration);
|
||||
self.is_online.set_err(err.clone());
|
||||
self.main_loop_handler
|
||||
.send(ThreadEvent::UIEvent(UIEvent::AccountStatusChange(
|
||||
self.hash, None,
|
||||
)));
|
||||
return Err(err);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let mut tree: Vec<MailboxNode> = Vec::new();
|
||||
for (h, f) in ref_mailboxes.iter() {
|
||||
if !f.is_subscribed() {
|
||||
|
@ -1394,6 +1421,12 @@ impl Account {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn default_mailbox(&self) -> Option<MailboxHash> {
|
||||
self.settings
|
||||
.default_mailbox
|
||||
.or_else(|| Some(*self.mailboxes_order.first()?))
|
||||
}
|
||||
|
||||
pub fn mailbox_by_path(&self, path: &str) -> Result<MailboxHash> {
|
||||
if let Some((mailbox_hash, _)) = self
|
||||
.mailbox_entries
|
||||
|
|
|
@ -165,6 +165,12 @@ use crate::conf::deserializers::extra_settings;
|
|||
#[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
||||
pub struct FileAccount {
|
||||
pub root_mailbox: String,
|
||||
/// The mailbox that is the default to open / view for this account. Must be
|
||||
/// a valid mailbox path.
|
||||
///
|
||||
/// If not specified, the default is [`Self::root_mailbox`].
|
||||
#[serde(default = "none", skip_serializing_if = "Option::is_none")]
|
||||
pub default_mailbox: Option<String>,
|
||||
pub format: String,
|
||||
pub identity: String,
|
||||
#[serde(default)]
|
||||
|
@ -234,6 +240,7 @@ pub struct FileSettings {
|
|||
#[derive(Clone, Debug, Default, Serialize)]
|
||||
pub struct AccountConf {
|
||||
pub account: AccountSettings,
|
||||
pub default_mailbox: Option<MailboxHash>,
|
||||
pub sent_mailbox: Option<MailboxHash>,
|
||||
pub conf: FileAccount,
|
||||
pub conf_override: MailUIConf,
|
||||
|
@ -286,6 +293,7 @@ impl From<FileAccount> for AccountConf {
|
|||
let mailbox_confs = x.mailboxes.clone();
|
||||
Self {
|
||||
account: acc,
|
||||
default_mailbox: None,
|
||||
sent_mailbox: None,
|
||||
conf_override: x.conf_override.clone(),
|
||||
conf: x,
|
||||
|
@ -538,6 +546,7 @@ This is required so that you don't accidentally start meli and find out later th
|
|||
mailboxes,
|
||||
extra,
|
||||
manual_refresh,
|
||||
default_mailbox: _,
|
||||
refresh_command: _,
|
||||
search_backend: _,
|
||||
conf_override: _,
|
||||
|
|
|
@ -475,6 +475,18 @@ struct AccountMenuEntry {
|
|||
entries: SmallVec<[MailboxMenuEntry; 16]>,
|
||||
}
|
||||
|
||||
impl AccountMenuEntry {
|
||||
fn entry_by_hash(&self, needle: MailboxHash) -> Option<usize> {
|
||||
self.entries.iter().enumerate().find_map(|(i, e)| {
|
||||
if e.mailbox_hash == needle {
|
||||
Some(i)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub trait MailListingTrait: ListingTrait {
|
||||
fn as_component(&self) -> &dyn Component
|
||||
where
|
||||
|
@ -1568,7 +1580,15 @@ impl Component for Listing {
|
|||
k if shortcut!(k == shortcuts[Shortcuts::LISTING]["next_account"]) => {
|
||||
if self.cursor_pos.account + amount < self.accounts.len() {
|
||||
self.cursor_pos.account += amount;
|
||||
self.cursor_pos.menu = MenuEntryCursor::Mailbox(0);
|
||||
let _new_val = self.cursor_pos.account;
|
||||
self.cursor_pos.menu = if let Some(idx) = context.accounts[_new_val]
|
||||
.default_mailbox()
|
||||
.and_then(|h| self.accounts[_new_val].entry_by_hash(h))
|
||||
{
|
||||
MenuEntryCursor::Mailbox(idx)
|
||||
} else {
|
||||
MenuEntryCursor::Status
|
||||
};
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
|
@ -1576,7 +1596,15 @@ impl Component for Listing {
|
|||
k if shortcut!(k == shortcuts[Shortcuts::LISTING]["prev_account"]) => {
|
||||
if self.cursor_pos.account >= amount {
|
||||
self.cursor_pos.account -= amount;
|
||||
self.cursor_pos.menu = MenuEntryCursor::Mailbox(0);
|
||||
let _new_val = self.cursor_pos.account;
|
||||
self.cursor_pos.menu = if let Some(idx) = context.accounts[_new_val]
|
||||
.default_mailbox()
|
||||
.and_then(|h| self.accounts[_new_val].entry_by_hash(h))
|
||||
{
|
||||
MenuEntryCursor::Mailbox(idx)
|
||||
} else {
|
||||
MenuEntryCursor::Status
|
||||
};
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
|
@ -2076,9 +2104,17 @@ impl Component for Listing {
|
|||
} => {
|
||||
if *account > 0 {
|
||||
*account -= 1;
|
||||
self.menu_cursor_pos.menu = MenuEntryCursor::Mailbox(
|
||||
self.accounts[*account].entries.len().saturating_sub(1),
|
||||
);
|
||||
self.menu_cursor_pos.menu =
|
||||
if self.accounts[*account].entries.is_empty() {
|
||||
MenuEntryCursor::Status
|
||||
} else {
|
||||
MenuEntryCursor::Mailbox(
|
||||
self.accounts[*account]
|
||||
.entries
|
||||
.len()
|
||||
.saturating_sub(1),
|
||||
)
|
||||
};
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
|
@ -2111,7 +2147,12 @@ impl Component for Listing {
|
|||
} if !self.accounts[*account].entries.is_empty()
|
||||
&& *menu == MenuEntryCursor::Status =>
|
||||
{
|
||||
*menu = MenuEntryCursor::Mailbox(0);
|
||||
if let Some(idx) = context.accounts[*account]
|
||||
.default_mailbox()
|
||||
.and_then(|h| self.accounts[*account].entry_by_hash(h))
|
||||
{
|
||||
*menu = MenuEntryCursor::Mailbox(idx);
|
||||
}
|
||||
}
|
||||
// If current account has no mailboxes, go to next account
|
||||
CursorPos {
|
||||
|
@ -2250,15 +2291,32 @@ impl Component for Listing {
|
|||
{
|
||||
if self.menu_cursor_pos.account + amount >= self.accounts.len() {
|
||||
// Go to last mailbox.
|
||||
self.menu_cursor_pos.menu = MenuEntryCursor::Mailbox(
|
||||
self.accounts[self.menu_cursor_pos.account]
|
||||
.entries
|
||||
.len()
|
||||
.saturating_sub(1),
|
||||
);
|
||||
self.menu_cursor_pos.menu = if self.accounts
|
||||
[self.menu_cursor_pos.account]
|
||||
.entries
|
||||
.is_empty()
|
||||
{
|
||||
MenuEntryCursor::Status
|
||||
} else {
|
||||
MenuEntryCursor::Mailbox(
|
||||
self.accounts[self.menu_cursor_pos.account]
|
||||
.entries
|
||||
.len()
|
||||
.saturating_sub(1),
|
||||
)
|
||||
};
|
||||
} else if self.menu_cursor_pos.account + amount < self.accounts.len() {
|
||||
self.menu_cursor_pos.account += amount;
|
||||
self.menu_cursor_pos.menu = MenuEntryCursor::Mailbox(0);
|
||||
let _new_val = self.menu_cursor_pos.account;
|
||||
self.menu_cursor_pos.menu = if let Some(idx) = context.accounts
|
||||
[_new_val]
|
||||
.default_mailbox()
|
||||
.and_then(|h| self.accounts[_new_val].entry_by_hash(h))
|
||||
{
|
||||
MenuEntryCursor::Mailbox(idx)
|
||||
} else {
|
||||
MenuEntryCursor::Status
|
||||
};
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
|
@ -2268,7 +2326,16 @@ impl Component for Listing {
|
|||
{
|
||||
if self.menu_cursor_pos.account >= amount {
|
||||
self.menu_cursor_pos.account -= amount;
|
||||
self.menu_cursor_pos.menu = MenuEntryCursor::Mailbox(0);
|
||||
let _new_val = self.menu_cursor_pos.account;
|
||||
self.menu_cursor_pos.menu = if let Some(idx) = context.accounts
|
||||
[_new_val]
|
||||
.default_mailbox()
|
||||
.and_then(|h| self.accounts[_new_val].entry_by_hash(h))
|
||||
{
|
||||
MenuEntryCursor::Mailbox(idx)
|
||||
} else {
|
||||
MenuEntryCursor::Status
|
||||
};
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
|
@ -2294,12 +2361,24 @@ impl Component for Listing {
|
|||
menu: MenuEntryCursor::Mailbox(0)
|
||||
}
|
||||
) {
|
||||
// Can't go anywhere upwards, we're on top already.
|
||||
return true;
|
||||
}
|
||||
if self.menu_cursor_pos.menu == MenuEntryCursor::Mailbox(0) {
|
||||
self.menu_cursor_pos.account = 0;
|
||||
} else {
|
||||
self.menu_cursor_pos.menu = MenuEntryCursor::Mailbox(0);
|
||||
match (
|
||||
self.menu_cursor_pos.menu,
|
||||
context.accounts[self.menu_cursor_pos.account]
|
||||
.default_mailbox()
|
||||
.and_then(|h| {
|
||||
self.accounts[self.menu_cursor_pos.account].entry_by_hash(h)
|
||||
}),
|
||||
) {
|
||||
(MenuEntryCursor::Mailbox(0), _) => {
|
||||
self.menu_cursor_pos.account = 0;
|
||||
}
|
||||
(MenuEntryCursor::Mailbox(_), Some(v)) => {
|
||||
self.menu_cursor_pos.menu = MenuEntryCursor::Mailbox(v);
|
||||
}
|
||||
_ => return true,
|
||||
}
|
||||
if self.show_menu_scrollbar != ShowMenuScrollbar::Never {
|
||||
self.menu_scrollbar_show_timer.rearm();
|
||||
|
@ -2337,11 +2416,20 @@ impl Component for Listing {
|
|||
self.accounts[*account].entries.len().saturating_sub(1)
|
||||
) {
|
||||
*account = self.accounts.len().saturating_sub(1);
|
||||
*menu = MenuEntryCursor::Mailbox(0);
|
||||
} else {
|
||||
*menu = if let Some(idx) = context.accounts[*account]
|
||||
.default_mailbox()
|
||||
.and_then(|h| self.accounts[*account].entry_by_hash(h))
|
||||
{
|
||||
MenuEntryCursor::Mailbox(idx)
|
||||
} else {
|
||||
MenuEntryCursor::Status
|
||||
};
|
||||
} else if !self.accounts[*account].entries.is_empty() {
|
||||
*menu = MenuEntryCursor::Mailbox(
|
||||
self.accounts[*account].entries.len().saturating_sub(1),
|
||||
);
|
||||
} else {
|
||||
*menu = MenuEntryCursor::Status;
|
||||
}
|
||||
if self.show_menu_scrollbar != ShowMenuScrollbar::Never {
|
||||
self.menu_scrollbar_show_timer.rearm();
|
||||
|
|
Loading…
Reference in New Issue