message: support 'personal' flag for messages

Add a new flag 'personal' for a message, which means that at least one of the
contact fields is personal.
This commit is contained in:
Dirk-Jan C. Binnema 2022-05-01 11:18:57 +03:00
parent a4f39819ee
commit ee4b3bda2d
5 changed files with 33 additions and 10 deletions

View File

@ -166,7 +166,7 @@ test_flag_info()
{
static_assert(flag_info('D')->flag == Flags::Draft);
static_assert(flag_info('l')->flag == Flags::MailingList);
static_assert(!flag_info('q'));
static_assert(!flag_info('y'));
static_assert(flag_info("trashed")->flag == Flags::Trashed);
static_assert(flag_info("attach")->flag == Flags::HasAttachment);

View File

@ -63,11 +63,12 @@ enum struct Flags {
* other content flags
*/
MailingList = 1 << 11, /**< A mailing-list message */
Personal = 1 << 12, /**< A personal message (i.e., at least one of the
* contact fields contains a personal address) */
/*
* <private>
*/
_final_ = 1 << 12
_final_ = 1 << 13
};
MU_ENABLE_BITOPS(Flags);
@ -90,7 +91,9 @@ enum struct MessageFlagCategory {
struct MessageFlagInfo {
Flags flag; /**< The message flag */
char shortcut; /**< Shortcut character */
char shortcut; /**< Shortcut character;
* tolower(shortcut) must be
* unique for all flags */
std::string_view name; /**< Name of the flag */
MessageFlagCategory category; /**< Flag category */
std::string_view description; /**< Description */
@ -109,7 +112,7 @@ struct MessageFlagInfo {
/**
* Array of all flag information.
*/
constexpr std::array<MessageFlagInfo, 12> AllMessageFlagInfos = {{
constexpr std::array<MessageFlagInfo, 13> AllMessageFlagInfos = {{
MessageFlagInfo{Flags::Draft, 'D', "draft", MessageFlagCategory::Mailfile,
"Draft (in progress)"
},
@ -147,6 +150,9 @@ constexpr std::array<MessageFlagInfo, 12> AllMessageFlagInfos = {{
MessageFlagInfo{Flags::MailingList, 'l', "list", MessageFlagCategory::Content,
"Mailing list message"
},
MessageFlagInfo{Flags::Personal, 'q', "personal", MessageFlagCategory::Content,
"Personal message"
},
}};

View File

@ -221,9 +221,9 @@ ContactsCache::add(Contact&& contact)
void
ContactsCache::add(Contacts&& contacts)
ContactsCache::add(Contacts&& contacts, bool& personal)
{
const auto personal = seq_find_if(contacts,[&](auto&& c){
personal = seq_find_if(contacts,[&](auto&& c){
return is_personal(c.email); }) != contacts.cend();
for (auto&& contact: contacts) {

View File

@ -66,8 +66,15 @@ public:
* any of the senders/recipients are considered "personal"
*
* @param contacts a Contact object sequence
* @param is_personal receives true if any of the contacts was personal;
* false otherwise
*/
void add(Contacts&& contacts);
void add(Contacts&& contacts, bool& is_personal);
void add(Contacts&& contacts) {
bool _ignore;
add(std::move(contacts), _ignore);
}
/**
* Clear all contacts

View File

@ -344,14 +344,24 @@ Store::add_message(Message& msg, bool use_transaction)
if (auto&& res = msg.set_maildir(mdir.value()); !res)
return Err(res.error());
/* add contacts from this message to cache; this cache
* also determines whether those contacts are _personal_, i.e. match
* our personal addresses.
*
* if a message has any personal contacts, mark it as personal; do
* this by updating the message flags.
*/
bool is_personal{};
priv_->contacts_cache_.add(msg.all_contacts(), is_personal);
if (is_personal)
msg.set_flags(msg.flags() | Flags::Personal);
/* now, we're done with all the fields; generate the sexp string for this
* message */
msg.update_cached_sexp();
std::lock_guard guard{priv_->lock_};
priv_->contacts_cache_.add(msg.all_contacts());
const auto docid = xapian_try([&]{
if (use_transaction)