Implementing labeling emails

Now that the new MAIL:label attribute has been made available in nightly images, I’m looking into implementing assigning a label to an email in the Mail app. See also https://discuss.haiku-os.org/t/introducing-a-new-indexed-attribute-meta-tag

I have two questions:


1. Assigning statuses
The new label attribute was introduced to do away with abusing MAIL:status, which should be reserved for actual email status like New, Seen, Read, Replied, Answered, Pending, Sent.
We should still keep a menu around to allow the user to switch between the status New and Read. But all other statuses won’t be available, that’s what the new labels are for. Right?

Now, do we have to come up with a sort of migration from old custom statuses to new labels?
If so, would a script that moves all emails’ custom MAIL:status to MAIL:label be enough? How can we make sure the script is run once? Or is it OK to point to the script in the next release notes and maybe the User guide?


2. Implementing labels
I originally thought to implement labels 1:1 to how statuses are managed in Mail, but after having a look, I’m not so sure. This is how it works now:

The Mail app queries the boot partition for all files with the indexed attribute “_status” and generates a list from the result to present to the user in a menu. User-created statuses are saved with a “_status” attribute in ~/config/settings/Mail/status.

Isn’t that quite a bit complicated? Do people create their own statuses, assign a “_status” attribute and save them somewhere else on the boot partition?
(In the future those statuses aren’t needed, we can simply hard-code the two options a user has to switch between New and Read.)

For the new labels though, shouldn’t we simply save the user labels into ~/config/settings/Mail/labels and just iterate over the file names there to put in the menu?


I hope I didn’t bite off more than I can chew here, put I’m willing to give that label implementation a stab… :slight_smile:

1 Like

As you say, the previous status was “abused” for this. I would not introduce any migration, the new labels don’t do the same thing. Do you want to label an e-mail as unread in addition to the status beeing unread?

Since your intention here was to make “status” respect whatever imap thinks I agree that there is no need for custom statuses.

What would this file contain? Just a BMessage? And what is it for?

Do you want a fixed set of labels, or can they change at runtime?
If they can change at runtime I would expect this to kinda work like People files: The system checks with a querry which attributes i actually used.

As an example I’ve tagged some e-mails with “important” , “work” etc.
I would expect the Mail app to querry the system to find these, and then present me with them in the menu so i can use labels i’ve used before again.

If your config file is a cache so you don’t have to do this every time for example or to overwrite something (don’t show a label for old-work anymore for example) I think that is fine, but caching here is an optimization and it may be easier to first implement the querry based way.

1 Like

No, only the custom statuses. Like for the mails you’ve set the MAIL:status to “Important”, we copy to MAIL:label.

It’s a simple generic file, one file per label. The file name is the label the user has created in the Mail app.
Those files are used to populate a menu “Label as…” where the user can choose one label to set for the currently open email in the Mail app.

I suppose we could update the menu with the available labels via MenusBeginning().

I don’t think a query is necessary. Just like really only the user-created statuses that were saved in ~/config/settings/Mail/status were shown to the user before, the same could be done with labels.

Did people set statuses before manually, i.e. by not using the “Mark as…” Tracker add-on or from within Tracker, but by manually enter some text in the “Status” column? Probably not, and why would they: they need to e.g. query for a specific status, so entering arbitrary, changing strings doesn’t make sense. And if so, what’s the worst scenario: They have to create the new label via the Mail app or by creating a file in ~/config/settings/Mail/status.

But isn’t that needlessly costly? Once you have thousands of labeled mails, you need to go through each and every one of them to collect every label they might contain. All for no gain, because the users themselves have set those labels by choosing them from a list of labels they themselves have created before. It’s not like labels arrive with some emails with labels from another user and new labels pop up unexpectedly.

Having a fixed list of labels the user curates appears to be the most sensible and simplest solution IMO.

Side note on IMAP standards - assuming we’re talking about the “system” flags that are specified by the standard. There are really only a couple that likely belong here: Seen and Answered. There’s also Flaggedand Draft, if anyone uses those.

Deleted is an important system flag, if your client shows it to you, as I imagine most do not. Recent is a transient flag, cleared by the server after the first session. Seen is set by the server on first access to the message.

Answered, Flagged and Draft are up to the client to set. It isn’t obvious to me that it’s important to preserve any other system flags from IMAP, on message content disk files. From IMAP, they convey the state of the IMAP store. From a file attribute, they don’t.

An IMAP server may add its own flag options. Mine supports $Forwarded and NonJunk, so a client that is aware of this can set those flags on the server so other clients can see them.

Side-note appreciated, but that’s exactly not what this is about. :slight_smile:
Those you mention are/can/will be handled with the MAIL:status attribute.

The new MAIL:label attribute is stricly for local, user-defined content. Before, those were mixed in with the mail_daemon set status.

Personally I constantly create new imap folders to categorize emails, these labels can carry a similar function, but are more flexible.

In my mind you can easily create a new mail status just in the mail UI, and as for it beeing expensive, I don’t know.

In any case, as a user having to remember file locations to drop files in specific formats so e-mails work is quite complicated, it would be much easier to just label an e-mail and the system picks it up. Again like people files. I don’t have a config folder for people files, the system just picks them up.
Is that too performance intensive? That’s why i suggested your thing work like a cache. You update it only sometimes. Or with IMAPfs, once we get around to that, you could make the querry only run on that special filesystem instead of the whole one.

Anyhow, I wouldn’t try to pre-optimize performance here :slight_smile:

Maybe for your use case, sticking to IMAP folders would be the better solution.

That’s not at all what I propose. The Mail app saves the labels a user creates in ~/config/settings/Mail/labels, just like before it saved the custom statuses in ~/config/settings/Mail/status.
The user sets their label from within the Mail app, or the “Mark as…” Tracker addon, just like they did before with the custom statuses.

I don’t understand why we should change that.
I’d only change that the Mail app doesn’t use a query for a special indexed “_label” attribute (as it does for “_status” for the custom statuses currently), and instead directly read in the labels, which are saved in one location on disk, just like those customed statuses before.