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)]
|
#[derive(Debug)]
|
||||||
pub struct Listing {
|
pub struct Listing {
|
||||||
component: ListingComponent,
|
component: ListingComponent,
|
||||||
@ -226,6 +260,14 @@ impl Component for Listing {
|
|||||||
}
|
}
|
||||||
let folder_hash =
|
let folder_hash =
|
||||||
context.accounts[self.cursor_pos.0].folders_order[self.cursor_pos.1];
|
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.
|
// Inform State that we changed the current folder view.
|
||||||
context
|
context
|
||||||
.replies
|
.replies
|
||||||
@ -258,6 +300,14 @@ impl Component for Listing {
|
|||||||
}
|
}
|
||||||
let folder_hash =
|
let folder_hash =
|
||||||
context.accounts[self.cursor_pos.0].folders_order[self.cursor_pos.1];
|
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.
|
// Inform State that we changed the current folder view.
|
||||||
context
|
context
|
||||||
.replies
|
.replies
|
||||||
@ -266,30 +316,15 @@ impl Component for Listing {
|
|||||||
}
|
}
|
||||||
UIEvent::Action(ref action) => match action {
|
UIEvent::Action(ref action) => match action {
|
||||||
Action::Listing(ListingAction::SetPlain) => {
|
Action::Listing(ListingAction::SetPlain) => {
|
||||||
if let Plain(_) = self.component {
|
self.component.set_style(IndexStyle::Plain);
|
||||||
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);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
Action::Listing(ListingAction::SetThreaded) => {
|
Action::Listing(ListingAction::SetThreaded) => {
|
||||||
if let Threaded(_) = self.component {
|
self.component.set_style(IndexStyle::Threaded);
|
||||||
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);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
Action::Listing(ListingAction::SetCompact) => {
|
Action::Listing(ListingAction::SetCompact) => {
|
||||||
if let Compact(_) = self.component {
|
self.component.set_style(IndexStyle::Compact);
|
||||||
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);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
@ -437,7 +472,7 @@ impl From<IndexStyle> for ListingComponent {
|
|||||||
impl Listing {
|
impl Listing {
|
||||||
const DESCRIPTION: &'static str = "listing";
|
const DESCRIPTION: &'static str = "listing";
|
||||||
pub fn new(accounts: &[Account]) -> Self {
|
pub fn new(accounts: &[Account]) -> Self {
|
||||||
let accounts = accounts
|
let account_entries = accounts
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(|(i, a)| AccountMenuEntry {
|
.map(|(i, a)| AccountMenuEntry {
|
||||||
@ -445,9 +480,20 @@ impl Listing {
|
|||||||
index: i,
|
index: i,
|
||||||
})
|
})
|
||||||
.collect();
|
.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 {
|
Listing {
|
||||||
component: Compact(Default::default()),
|
component,
|
||||||
accounts,
|
accounts: account_entries,
|
||||||
visible: true,
|
visible: true,
|
||||||
dirty: true,
|
dirty: true,
|
||||||
cursor_pos: (0, 0),
|
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)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct FolderConf {
|
pub struct FolderConf {
|
||||||
rename: Option<String>,
|
pub rename: Option<String>,
|
||||||
#[serde(default = "true_val")]
|
#[serde(default = "true_val")]
|
||||||
autoload: bool,
|
pub autoload: bool,
|
||||||
#[serde(deserialize_with = "toggleflag_de", default)]
|
#[serde(deserialize_with = "toggleflag_de", default)]
|
||||||
subscribe: ToggleFlag,
|
pub subscribe: ToggleFlag,
|
||||||
#[serde(deserialize_with = "toggleflag_de", default)]
|
#[serde(deserialize_with = "toggleflag_de", default)]
|
||||||
ignore: ToggleFlag,
|
pub ignore: ToggleFlag,
|
||||||
#[serde(default = "none")]
|
#[serde(default = "none")]
|
||||||
usage: Option<SpecialUseMailbox>,
|
pub usage: Option<SpecialUseMailbox>,
|
||||||
|
#[serde(flatten)]
|
||||||
|
pub conf_override: MailUIConf,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for FolderConf {
|
impl Default for FolderConf {
|
||||||
@ -108,8 +120,9 @@ impl Default for FolderConf {
|
|||||||
rename: None,
|
rename: None,
|
||||||
autoload: true,
|
autoload: true,
|
||||||
subscribe: ToggleFlag::Unset,
|
subscribe: ToggleFlag::Unset,
|
||||||
ignore: ToggleFlag::False,
|
ignore: ToggleFlag::Unset,
|
||||||
usage: None,
|
usage: None,
|
||||||
|
conf_override: MailUIConf::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -132,7 +145,6 @@ pub struct FileAccount {
|
|||||||
|
|
||||||
#[serde(default = "none")]
|
#[serde(default = "none")]
|
||||||
display_name: Option<String>,
|
display_name: Option<String>,
|
||||||
#[serde(deserialize_with = "index_from_str")]
|
|
||||||
index: IndexStyle,
|
index: IndexStyle,
|
||||||
|
|
||||||
/// A command to pipe html output before displaying it in a pager
|
/// 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() {
|
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") {
|
folder_confs.get_mut(s).unwrap().usage = if name.eq_ignore_ascii_case("inbox") {
|
||||||
Some(SpecialUseMailbox::Inbox)
|
Some(SpecialUseMailbox::Inbox)
|
||||||
} else if name.eq_ignore_ascii_case("archive") {
|
} else if name.eq_ignore_ascii_case("archive") {
|
||||||
@ -265,9 +280,9 @@ struct FileSettings {
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone, Default)]
|
||||||
pub struct AccountConf {
|
pub struct AccountConf {
|
||||||
account: AccountSettings,
|
pub(crate) account: AccountSettings,
|
||||||
conf: FileAccount,
|
pub(crate) conf: FileAccount,
|
||||||
folder_confs: HashMap<String, FolderConf>,
|
pub(crate) folder_confs: HashMap<String, FolderConf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AccountConf {
|
impl AccountConf {
|
||||||
@ -380,7 +395,7 @@ impl Settings {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Debug, Clone, Serialize, Deserialize)]
|
#[derive(Copy, Debug, Clone, Hash, PartialEq)]
|
||||||
pub enum IndexStyle {
|
pub enum IndexStyle {
|
||||||
Plain,
|
Plain,
|
||||||
Threaded,
|
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>
|
fn non_empty_string<'de, D>(deserializer: D) -> std::result::Result<Option<String>, D::Error>
|
||||||
where
|
where
|
||||||
D: Deserializer<'de>,
|
D: Deserializer<'de>,
|
||||||
@ -468,3 +470,31 @@ mod default_vals {
|
|||||||
None
|
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.
|
* Account management from user configuration.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use super::AccountConf;
|
use super::{AccountConf, FolderConf};
|
||||||
use fnv::FnvHashMap;
|
use fnv::FnvHashMap;
|
||||||
use melib::async_workers::{Async, AsyncBuilder, AsyncStatus};
|
use melib::async_workers::{Async, AsyncBuilder, AsyncStatus};
|
||||||
use melib::backends::{
|
use melib::backends::{
|
||||||
@ -116,8 +116,9 @@ impl MailboxEntry {
|
|||||||
pub struct Account {
|
pub struct Account {
|
||||||
name: String,
|
name: String,
|
||||||
pub(crate) folders: FnvHashMap<FolderHash, MailboxEntry>,
|
pub(crate) folders: FnvHashMap<FolderHash, MailboxEntry>,
|
||||||
|
pub(crate) folder_confs: FnvHashMap<FolderHash, FolderConf>,
|
||||||
pub(crate) folders_order: Vec<FolderHash>,
|
pub(crate) folders_order: Vec<FolderHash>,
|
||||||
folder_names: FnvHashMap<FolderHash, String>,
|
pub(crate) folder_names: FnvHashMap<FolderHash, String>,
|
||||||
tree: Vec<FolderNode>,
|
tree: Vec<FolderNode>,
|
||||||
sent_folder: Option<FolderHash>,
|
sent_folder: Option<FolderHash>,
|
||||||
pub(crate) collection: Collection,
|
pub(crate) collection: Collection,
|
||||||
@ -205,6 +206,7 @@ impl Account {
|
|||||||
let mut workers: FnvHashMap<FolderHash, Worker> = FnvHashMap::default();
|
let mut workers: FnvHashMap<FolderHash, Worker> = FnvHashMap::default();
|
||||||
let notify_fn = Arc::new(notify_fn);
|
let notify_fn = Arc::new(notify_fn);
|
||||||
let mut folder_names = FnvHashMap::default();
|
let mut folder_names = FnvHashMap::default();
|
||||||
|
let mut folder_confs = FnvHashMap::default();
|
||||||
|
|
||||||
let mut sent_folder = None;
|
let mut sent_folder = None;
|
||||||
for f in ref_folders.values_mut() {
|
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());
|
folder_names.insert(f.hash(), f.path().to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -300,6 +303,7 @@ impl Account {
|
|||||||
Account {
|
Account {
|
||||||
name,
|
name,
|
||||||
folders,
|
folders,
|
||||||
|
folder_confs,
|
||||||
folders_order,
|
folders_order,
|
||||||
folder_names,
|
folder_names,
|
||||||
tree,
|
tree,
|
||||||
@ -669,6 +673,10 @@ impl Account {
|
|||||||
pub fn folder_operation(&mut self, path: &str, op: FolderOperation) -> Result<()> {
|
pub fn folder_operation(&mut self, path: &str, op: FolderOperation) -> Result<()> {
|
||||||
self.backend.folder_operation(path, op)
|
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 {
|
impl Index<FolderHash> for Account {
|
||||||
|
Loading…
Reference in New Issue
Block a user