mirror of
https://git.meli.delivery/meli/meli
synced 2024-11-10 19:10:57 +00:00
override configuration with per-folder configs
This commit is contained in:
parent
81a55abc7c
commit
fd38dbed48
@ -96,6 +96,40 @@ impl ListingTrait for ListingComponent {
|
||||
}
|
||||
}
|
||||
|
||||
impl ListingComponent {
|
||||
fn set_style(&mut self, new_style: IndexStyle) {
|
||||
match new_style {
|
||||
IndexStyle::Plain => {
|
||||
if let Plain(_) = self {
|
||||
return;
|
||||
}
|
||||
let mut new_l = PlainListing::default();
|
||||
let coors = self.coordinates();
|
||||
new_l.set_coordinates((coors.0, coors.1, None));
|
||||
*self = Plain(new_l);
|
||||
}
|
||||
IndexStyle::Threaded => {
|
||||
if let Threaded(_) = self {
|
||||
return;
|
||||
}
|
||||
let mut new_l = ThreadListing::default();
|
||||
let coors = self.coordinates();
|
||||
new_l.set_coordinates((coors.0, coors.1, None));
|
||||
*self = Threaded(new_l);
|
||||
}
|
||||
IndexStyle::Compact => {
|
||||
if let Compact(_) = self {
|
||||
return;
|
||||
}
|
||||
let mut new_l = CompactListing::default();
|
||||
let coors = self.coordinates();
|
||||
new_l.set_coordinates((coors.0, coors.1, None));
|
||||
*self = Compact(new_l);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Listing {
|
||||
component: ListingComponent,
|
||||
@ -226,6 +260,14 @@ impl Component for Listing {
|
||||
}
|
||||
let folder_hash =
|
||||
context.accounts[self.cursor_pos.0].folders_order[self.cursor_pos.1];
|
||||
/* Check if per-folder configuration overrides general configuration */
|
||||
if let Some(index_style) = context
|
||||
.accounts
|
||||
.get(self.cursor_pos.0)
|
||||
.and_then(|account| account.folder_confs(folder_hash).conf_override.index)
|
||||
{
|
||||
self.component.set_style(index_style);
|
||||
};
|
||||
// Inform State that we changed the current folder view.
|
||||
context
|
||||
.replies
|
||||
@ -258,6 +300,14 @@ impl Component for Listing {
|
||||
}
|
||||
let folder_hash =
|
||||
context.accounts[self.cursor_pos.0].folders_order[self.cursor_pos.1];
|
||||
/* Check if per-folder configuration overrides general configuration */
|
||||
if let Some(index_style) = context
|
||||
.accounts
|
||||
.get(self.cursor_pos.0)
|
||||
.and_then(|account| account.folder_confs(folder_hash).conf_override.index)
|
||||
{
|
||||
self.component.set_style(index_style);
|
||||
};
|
||||
// Inform State that we changed the current folder view.
|
||||
context
|
||||
.replies
|
||||
@ -266,30 +316,15 @@ impl Component for Listing {
|
||||
}
|
||||
UIEvent::Action(ref action) => match action {
|
||||
Action::Listing(ListingAction::SetPlain) => {
|
||||
if let Plain(_) = self.component {
|
||||
return true;
|
||||
}
|
||||
let mut new_l = PlainListing::default();
|
||||
new_l.set_coordinates((self.cursor_pos.0, self.cursor_pos.1, None));
|
||||
self.component = Plain(new_l);
|
||||
self.component.set_style(IndexStyle::Plain);
|
||||
return true;
|
||||
}
|
||||
Action::Listing(ListingAction::SetThreaded) => {
|
||||
if let Threaded(_) = self.component {
|
||||
return true;
|
||||
}
|
||||
let mut new_l = ThreadListing::default();
|
||||
new_l.set_coordinates((self.cursor_pos.0, self.cursor_pos.1, None));
|
||||
self.component = Threaded(new_l);
|
||||
self.component.set_style(IndexStyle::Threaded);
|
||||
return true;
|
||||
}
|
||||
Action::Listing(ListingAction::SetCompact) => {
|
||||
if let Compact(_) = self.component {
|
||||
return true;
|
||||
}
|
||||
let mut new_l = CompactListing::default();
|
||||
new_l.set_coordinates((self.cursor_pos.0, self.cursor_pos.1, None));
|
||||
self.component = Compact(new_l);
|
||||
self.component.set_style(IndexStyle::Compact);
|
||||
return true;
|
||||
}
|
||||
_ => {}
|
||||
@ -437,7 +472,7 @@ impl From<IndexStyle> for ListingComponent {
|
||||
impl Listing {
|
||||
const DESCRIPTION: &'static str = "listing";
|
||||
pub fn new(accounts: &[Account]) -> Self {
|
||||
let accounts = accounts
|
||||
let account_entries = accounts
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, a)| AccountMenuEntry {
|
||||
@ -445,9 +480,20 @@ impl Listing {
|
||||
index: i,
|
||||
})
|
||||
.collect();
|
||||
/* Check if per-folder configuration overrides general configuration */
|
||||
let component = if let Some(index_style) = accounts.get(0).and_then(|account| {
|
||||
account
|
||||
.folders_order
|
||||
.get(0)
|
||||
.and_then(|folder_hash| account.folder_confs(*folder_hash).conf_override.index)
|
||||
}) {
|
||||
ListingComponent::from(index_style)
|
||||
} else {
|
||||
Compact(Default::default())
|
||||
};
|
||||
Listing {
|
||||
component: Compact(Default::default()),
|
||||
accounts,
|
||||
component,
|
||||
accounts: account_entries,
|
||||
visible: true,
|
||||
dirty: true,
|
||||
cursor_pos: (0, 0),
|
||||
|
@ -89,17 +89,29 @@ impl ToggleFlag {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct MailUIConf {
|
||||
pub pager: Option<PagerSettings>,
|
||||
pub notifications: Option<NotificationsSettings>,
|
||||
pub shortcuts: Option<Shortcuts>,
|
||||
pub mailer: Option<MailerSettings>,
|
||||
pub identity: Option<String>,
|
||||
pub index: Option<IndexStyle>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct FolderConf {
|
||||
rename: Option<String>,
|
||||
pub rename: Option<String>,
|
||||
#[serde(default = "true_val")]
|
||||
autoload: bool,
|
||||
pub autoload: bool,
|
||||
#[serde(deserialize_with = "toggleflag_de", default)]
|
||||
subscribe: ToggleFlag,
|
||||
pub subscribe: ToggleFlag,
|
||||
#[serde(deserialize_with = "toggleflag_de", default)]
|
||||
ignore: ToggleFlag,
|
||||
pub ignore: ToggleFlag,
|
||||
#[serde(default = "none")]
|
||||
usage: Option<SpecialUseMailbox>,
|
||||
pub usage: Option<SpecialUseMailbox>,
|
||||
#[serde(flatten)]
|
||||
pub conf_override: MailUIConf,
|
||||
}
|
||||
|
||||
impl Default for FolderConf {
|
||||
@ -108,8 +120,9 @@ impl Default for FolderConf {
|
||||
rename: None,
|
||||
autoload: true,
|
||||
subscribe: ToggleFlag::Unset,
|
||||
ignore: ToggleFlag::False,
|
||||
ignore: ToggleFlag::Unset,
|
||||
usage: None,
|
||||
conf_override: MailUIConf::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -132,7 +145,6 @@ pub struct FileAccount {
|
||||
|
||||
#[serde(default = "none")]
|
||||
display_name: Option<String>,
|
||||
#[serde(deserialize_with = "index_from_str")]
|
||||
index: IndexStyle,
|
||||
|
||||
/// A command to pipe html output before displaying it in a pager
|
||||
@ -197,7 +209,10 @@ impl From<FileAccount> for AccountConf {
|
||||
}
|
||||
|
||||
if folder_confs[s].usage.is_none() {
|
||||
let name = s.split('/').last().unwrap_or("");
|
||||
let name = s
|
||||
.split(if s.contains('/') { '/' } else { '.' })
|
||||
.last()
|
||||
.unwrap_or("");
|
||||
folder_confs.get_mut(s).unwrap().usage = if name.eq_ignore_ascii_case("inbox") {
|
||||
Some(SpecialUseMailbox::Inbox)
|
||||
} else if name.eq_ignore_ascii_case("archive") {
|
||||
@ -265,9 +280,9 @@ struct FileSettings {
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
pub struct AccountConf {
|
||||
account: AccountSettings,
|
||||
conf: FileAccount,
|
||||
folder_confs: HashMap<String, FolderConf>,
|
||||
pub(crate) account: AccountSettings,
|
||||
pub(crate) conf: FileAccount,
|
||||
pub(crate) folder_confs: HashMap<String, FolderConf>,
|
||||
}
|
||||
|
||||
impl AccountConf {
|
||||
@ -380,7 +395,7 @@ impl Settings {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Debug, Clone, Serialize, Deserialize)]
|
||||
#[derive(Copy, Debug, Clone, Hash, PartialEq)]
|
||||
pub enum IndexStyle {
|
||||
Plain,
|
||||
Threaded,
|
||||
@ -393,19 +408,6 @@ impl Default for IndexStyle {
|
||||
}
|
||||
}
|
||||
|
||||
fn index_from_str<'de, D>(deserializer: D) -> std::result::Result<IndexStyle, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let s = <String>::deserialize(deserializer)?;
|
||||
match s.as_str() {
|
||||
"Plain" | "plain" => Ok(IndexStyle::Plain),
|
||||
"Threaded" | "threaded" => Ok(IndexStyle::Threaded),
|
||||
"Compact" | "compact" => Ok(IndexStyle::Compact),
|
||||
_ => Err(de::Error::custom("invalid `index` value")),
|
||||
}
|
||||
}
|
||||
|
||||
fn non_empty_string<'de, D>(deserializer: D) -> std::result::Result<Option<String>, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
@ -468,3 +470,31 @@ mod default_vals {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for IndexStyle {
|
||||
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let s = <String>::deserialize(deserializer)?;
|
||||
match s.as_str() {
|
||||
"Plain" | "plain" => Ok(IndexStyle::Plain),
|
||||
"Threaded" | "threaded" => Ok(IndexStyle::Threaded),
|
||||
"Compact" | "compact" => Ok(IndexStyle::Compact),
|
||||
_ => Err(de::Error::custom("invalid `index` value")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for IndexStyle {
|
||||
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
match self {
|
||||
IndexStyle::Plain => serializer.serialize_str("plain"),
|
||||
IndexStyle::Threaded => serializer.serialize_str("threaded"),
|
||||
IndexStyle::Compact => serializer.serialize_str("compact"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,7 @@
|
||||
* Account management from user configuration.
|
||||
*/
|
||||
|
||||
use super::AccountConf;
|
||||
use super::{AccountConf, FolderConf};
|
||||
use fnv::FnvHashMap;
|
||||
use melib::async_workers::{Async, AsyncBuilder, AsyncStatus};
|
||||
use melib::backends::{
|
||||
@ -116,8 +116,9 @@ impl MailboxEntry {
|
||||
pub struct Account {
|
||||
name: String,
|
||||
pub(crate) folders: FnvHashMap<FolderHash, MailboxEntry>,
|
||||
pub(crate) folder_confs: FnvHashMap<FolderHash, FolderConf>,
|
||||
pub(crate) folders_order: Vec<FolderHash>,
|
||||
folder_names: FnvHashMap<FolderHash, String>,
|
||||
pub(crate) folder_names: FnvHashMap<FolderHash, String>,
|
||||
tree: Vec<FolderNode>,
|
||||
sent_folder: Option<FolderHash>,
|
||||
pub(crate) collection: Collection,
|
||||
@ -205,6 +206,7 @@ impl Account {
|
||||
let mut workers: FnvHashMap<FolderHash, Worker> = FnvHashMap::default();
|
||||
let notify_fn = Arc::new(notify_fn);
|
||||
let mut folder_names = FnvHashMap::default();
|
||||
let mut folder_confs = FnvHashMap::default();
|
||||
|
||||
let mut sent_folder = None;
|
||||
for f in ref_folders.values_mut() {
|
||||
@ -221,6 +223,7 @@ impl Account {
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
folder_confs.insert(f.hash(), settings.folder_confs[f.path()].clone());
|
||||
folder_names.insert(f.hash(), f.path().to_string());
|
||||
}
|
||||
|
||||
@ -300,6 +303,7 @@ impl Account {
|
||||
Account {
|
||||
name,
|
||||
folders,
|
||||
folder_confs,
|
||||
folders_order,
|
||||
folder_names,
|
||||
tree,
|
||||
@ -669,6 +673,10 @@ impl Account {
|
||||
pub fn folder_operation(&mut self, path: &str, op: FolderOperation) -> Result<()> {
|
||||
self.backend.folder_operation(path, op)
|
||||
}
|
||||
|
||||
pub fn folder_confs(&self, folder_hash: FolderHash) -> &FolderConf {
|
||||
&self.folder_confs[&folder_hash]
|
||||
}
|
||||
}
|
||||
|
||||
impl Index<FolderHash> for Account {
|
||||
|
Loading…
Reference in New Issue
Block a user