From bca33370cc59ef4efbdd2331707d168bbaec69e3 Mon Sep 17 00:00:00 2001 From: Manos Pitsidianakis Date: Sun, 1 Dec 2019 12:05:14 +0200 Subject: [PATCH] Add tag settings in UI config module --- melib/src/conf.rs | 20 +----- ui/src/components/mail/listing/compact.rs | 14 +++- .../components/mail/listing/conversations.rs | 14 +++- ui/src/components/mail/listing/plain.rs | 16 ----- ui/src/conf.rs | 7 ++ ui/src/conf/shortcuts.rs | 22 +++++- ui/src/conf/tags.rs | 69 +++++++++++++++++++ 7 files changed, 124 insertions(+), 38 deletions(-) create mode 100644 ui/src/conf/tags.rs diff --git a/melib/src/conf.rs b/melib/src/conf.rs index a6a2d643..d5199213 100644 --- a/melib/src/conf.rs +++ b/melib/src/conf.rs @@ -20,8 +20,7 @@ */ use crate::backends::SpecialUseMailbox; use serde::{Deserialize, Deserializer, Serialize, Serializer}; -use std::collections::{hash_map::DefaultHasher, HashMap, HashSet}; -use std::hash::Hasher; +use std::collections::HashMap; #[derive(Debug, Serialize, Default, Clone)] pub struct AccountSettings { @@ -83,8 +82,6 @@ pub struct FolderConf { pub ignore: ToggleFlag, #[serde(default = "none")] pub usage: Option, - #[serde(default, deserialize_with = "tag_set_de")] - pub ignore_tags: HashSet, #[serde(flatten)] pub extra: HashMap, } @@ -97,7 +94,6 @@ impl Default for FolderConf { subscribe: ToggleFlag::Unset, ignore: ToggleFlag::Unset, usage: None, - ignore_tags: HashSet::default(), extra: HashMap::default(), } } @@ -184,17 +180,3 @@ impl Serialize for ToggleFlag { } } } - -pub fn tag_set_de<'de, D>(deserializer: D) -> std::result::Result, D::Error> -where - D: Deserializer<'de>, -{ - Ok(>::deserialize(deserializer)? - .into_iter() - .map(|tag| { - let mut hasher = DefaultHasher::new(); - hasher.write(tag.as_bytes()); - hasher.finish() - }) - .collect()) -} diff --git a/ui/src/components/mail/listing/compact.rs b/ui/src/components/mail/listing/compact.rs index 6ce6ae6f..72b89000 100644 --- a/ui/src/components/mail/listing/compact.rs +++ b/ui/src/components/mail/listing/compact.rs @@ -505,16 +505,28 @@ impl CompactListing { .hash(); let folder = &context.accounts[self.cursor_pos.0].folder_confs[&folder_hash]; let mut tags = String::new(); + let mut colors = StackVec::new(); let backend_lck = context.accounts[self.cursor_pos.0].backend.read().unwrap(); if let Some(t) = backend_lck.tags() { let tags_lck = t.read().unwrap(); for t in e.labels().iter() { - if folder.folder_conf.ignore_tags.contains(t) { + if folder + .conf_override + .tags + .as_ref() + .map(|s| s.ignore_tags.contains(t)) + .unwrap_or(false) + { continue; } tags.push(' '); tags.push_str(tags_lck.get(t).as_ref().unwrap()); tags.push(' '); + if let Some(&c) = context.settings.tags.colors.get(t) { + colors.push(c); + } else { + colors.push(8); + } } if !tags.is_empty() { tags.pop(); diff --git a/ui/src/components/mail/listing/conversations.rs b/ui/src/components/mail/listing/conversations.rs index dfc40b5b..3b8011d3 100644 --- a/ui/src/components/mail/listing/conversations.rs +++ b/ui/src/components/mail/listing/conversations.rs @@ -483,16 +483,28 @@ impl ConversationsListing { .hash(); let folder = &context.accounts[self.cursor_pos.0].folder_confs[&folder_hash]; let mut tags = String::new(); + let mut colors = StackVec::new(); let backend_lck = context.accounts[self.cursor_pos.0].backend.read().unwrap(); if let Some(t) = backend_lck.tags() { let tags_lck = t.read().unwrap(); for t in e.labels().iter() { - if folder.folder_conf.ignore_tags.contains(t) { + if folder + .conf_override + .tags + .as_ref() + .map(|s| s.ignore_tags.contains(t)) + .unwrap_or(false) + { continue; } tags.push(' '); tags.push_str(tags_lck.get(t).as_ref().unwrap()); tags.push(' '); + if let Some(&c) = context.settings.tags.colors.get(t) { + colors.push(c); + } else { + colors.push(8); + } } if !tags.is_empty() { tags.pop(); diff --git a/ui/src/components/mail/listing/plain.rs b/ui/src/components/mail/listing/plain.rs index 06b89a50..6c99efba 100644 --- a/ui/src/components/mail/listing/plain.rs +++ b/ui/src/components/mail/listing/plain.rs @@ -603,22 +603,6 @@ impl PlainListing { } let envelope: EnvelopeRef = context.accounts[self.cursor_pos.0].collection.get_env(i); let mut tags = String::new(); - let backend_lck = context.accounts[self.cursor_pos.0].backend.read().unwrap(); - if let Some(t) = backend_lck.tags() { - let tags_lck = t.read().unwrap(); - for t in envelope.labels().iter() { - if folder.folder_conf.ignore_tags.contains(t) { - continue; - } - tags.push(' '); - tags.push_str(tags_lck.get(t).as_ref().unwrap()); - tags.push(' '); - } - if !tags.is_empty() { - tags.pop(); - } - } - drop(backend_lck); let entry_strings = PlainListing::make_entry_string(envelope, tags); min_width.1 = cmp::max(min_width.1, entry_strings.date.grapheme_width()); /* date */ diff --git a/ui/src/conf.rs b/ui/src/conf.rs index 84e27ef9..00d01d2e 100644 --- a/ui/src/conf.rs +++ b/ui/src/conf.rs @@ -28,6 +28,7 @@ pub mod composing; pub mod notifications; pub mod pager; pub mod pgp; +pub mod tags; #[macro_use] pub mod shortcuts; pub mod terminal; @@ -37,6 +38,7 @@ pub use self::accounts::Account; pub use self::composing::*; pub use self::pgp::*; pub use self::shortcuts::*; +pub use self::tags::*; use self::default_vals::*; use self::notifications::NotificationsSettings; @@ -70,6 +72,7 @@ pub struct MailUIConf { pub composing: Option, pub identity: Option, pub index_style: Option, + pub tags: Option, } #[serde(default)] @@ -230,6 +233,8 @@ pub struct FileSettings { shortcuts: Shortcuts, composing: ComposingSettings, #[serde(default)] + tags: TagsSettings, + #[serde(default)] pgp: PGPSettings, #[serde(default)] terminal: TerminalSettings, @@ -260,6 +265,7 @@ pub struct Settings { pub pager: PagerSettings, pub notifications: NotificationsSettings, pub shortcuts: Shortcuts, + pub tags: TagsSettings, pub composing: ComposingSettings, pub pgp: PGPSettings, pub terminal: TerminalSettings, @@ -376,6 +382,7 @@ impl Settings { pager: fs.pager, notifications: fs.notifications, shortcuts: fs.shortcuts, + tags: fs.tags, composing: fs.composing, pgp: fs.pgp, terminal: fs.terminal, diff --git a/ui/src/conf/shortcuts.rs b/ui/src/conf/shortcuts.rs index 33843849..45bbd729 100644 --- a/ui/src/conf/shortcuts.rs +++ b/ui/src/conf/shortcuts.rs @@ -1,5 +1,25 @@ +/* + * meli - configuration module. + * + * Copyright 2019 Manos Pitsidianakis + * + * This file is part of meli. + * + * meli is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * meli is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with meli. If not, see . + */ + use crate::terminal::Key; -//use std::any::TypeId; use fnv::FnvHashMap; #[macro_export] diff --git a/ui/src/conf/tags.rs b/ui/src/conf/tags.rs new file mode 100644 index 00000000..8429a5f2 --- /dev/null +++ b/ui/src/conf/tags.rs @@ -0,0 +1,69 @@ +/* + * meli - configuration module. + * + * Copyright 2019 Manos Pitsidianakis + * + * This file is part of meli. + * + * meli is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * meli is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with meli. If not, see . + */ + +use serde::{Deserialize, Deserializer}; +use std::collections::{hash_map::DefaultHasher, HashMap, HashSet}; +use std::hash::Hasher; + +#[derive(Debug, Deserialize, Clone, Serialize)] +pub struct TagsSettings { + #[serde(default, deserialize_with = "tag_color_de")] + pub colors: HashMap, + #[serde(default, deserialize_with = "tag_set_de")] + pub ignore_tags: HashSet, +} + +impl Default for TagsSettings { + fn default() -> Self { + TagsSettings { + colors: Default::default(), + ignore_tags: Default::default(), + } + } +} + +pub fn tag_set_de<'de, D>(deserializer: D) -> std::result::Result, D::Error> +where + D: Deserializer<'de>, +{ + Ok(>::deserialize(deserializer)? + .into_iter() + .map(|tag| { + let mut hasher = DefaultHasher::new(); + hasher.write(tag.as_bytes()); + hasher.finish() + }) + .collect()) +} + +pub fn tag_color_de<'de, D>(deserializer: D) -> std::result::Result, D::Error> +where + D: Deserializer<'de>, +{ + Ok(>::deserialize(deserializer)? + .into_iter() + .map(|(tag, color)| { + let mut hasher = DefaultHasher::new(); + hasher.write(tag.as_bytes()); + (hasher.finish(), color) + }) + .collect()) +}