
How we taught Mail.Ru Mail to glue letters in threads
Threads, or chains of letters, have always been one of the most desirable features in Mail.Ru Mail, provided that the survey “What functionality are you missing?” Was conducted among an advanced audience (for example, among programmers or habrayuzers). The second most popular feature among geeks is, perhaps, two-factor authentication, but about it in a separate post .
However, all our usability tests showed that for a less advanced audience, threads are a rather complicated and not always convenient feature. Many were horrified by "losing" their letters in the Inbox, they could not understand how to respond to a specific message in the chain, and much more.
Nevertheless, to ourselves (the Mail.Ru Mail team), as people belonging to the first group (geeks, productivity buffs and programmers), the idea of threads was close and clear. Therefore, we decided to meet the wishes of the advanced community and implement the threads in the optional mode (you can enable them in the "View" menu in the upper right corner above the list of letters).

However, it is easy to solve, but not so easy to do. At the stage of thinking through logic, a lot of nuances were revealed. Although the threads were already implemented in other mail services, we still had to develop our own algorithm. Firstly, some foreign solutions seemed erroneous to us, and we decided to fix them, and secondly, the logic of some basic functionality of our mail is different from the work of similar functionality of others, so it’s impossible to simply “take over experience” as is.
In this post we want to talk about what difficulties awaited us and how we managed to overcome them.
1.1 Understanding In-Reply-To
Each letter has meta-information (service headers). The In-Reply-To header indicates the response to which message is the message you opened (In-Reply-To), and the References contains, among other things, information about the letter that was the first in the correspondence. It is logical that if there are such service headers, then it makes sense to group letters by these headers. However, there are two nuances that we had to consider.
First: what to do with redirected letters? In the case when the incoming message is redirected, in fact another message appears with the In-Reply-To service header. This header indicates a forwarded email. At the same time, the prefix FW or FWD appears in the subject. That is, in fact, the forward is another answer. Guided by this logic, Gmail, for example, “sticks” redirected messages to the same thread.
We interviewed users inside Mail.Ru and outside and found that, as a rule, they send a letter not to connect a person to the correspondence, but to discuss the topic of correspondence separately with him. So - they want to start a new "conversation", and not stay in the old one. Therefore, we decided that in such cases we will start a new chain.

Second: sometimes people can reply to the letter by changing its subject manually. Then in the service heading of the letter formally will remain marked In-Reply-To, but the subject of the letter will change. Focusing on the results of our research, we realized that if people consciously change the subject of a letter, then this is a new chain for them, and decided that in such cases we will also create a separate thread, even despite the presence of In-Reply-To in the service header .
Based on these two nuances, the grouping algorithm should be like this:
1.2 We think over a grouping for automatic mailings.
If there are no headings, this does not mean that there is nothing to group. There are many letters that just ask in one group: notifications from social networks, promotional letters from online stores, letters from the task tracker, finally. As a rule, in all these cases, letters have one subject and one sender. Therefore, we decided to group letters without headers according to the criterion “subject + sender” in order to cover automatic mailings.

1.3 Separate the "basket"
A separate problem when implementing threads is created by the Mail folder structure. We decided that letters from different folders, including “Sent Items”, could fall into the same chain, so that in one place you could see the letters that arrived and the answers to them. There, in theory, letters from the "Basket" folder should also have been included. Initially, we were guided by this logic, but the first beta testers gave us feedback that it was inconvenient and that they did not want to see deleted messages, even if they could be grouped by letter in the Inbox folder.
1.4 Determining the readings of counters
As we have already said, when grouping letters from the same chain, they can be scattered in different folders (the simplest case is “Inbox” and “Sent”). In this regard, a lot of questions arise, for example:
We get three options. Let's look at them.
First: the counter works with conversations, and an unread conversation is marked in all folders in which it is displayed. Say, in two folders - “Inbox” and “Sent” - there is one unread letter that has just arrived in the mailbox. In the list of folders we will see one in each of these two folders. But what to show in the general counter at the box? In theory, there you need to display the amount for all folders, and in our case it is two. But in fact, in the box there is one unread chain!
The second option: a thread in a folder is considered unread only if there are unread messages from this thread in the folder. But suppose there are two unread letters in the thread. The folder counter displays one: one thread has not been read. The user opens the thread and reads the top letter, after which he returns to the list of letters. One letter has been read, but the counter still shows one: after all, there is another unread letter in the thread, which means that the whole thread has not been read. It turns out that the user took an action, and the readings of the counters have not changed.
The third option, which we chose: in the counters we take into account letters, not threads. In this case, the counter for each folder displays the correct data, because the letter cannot be in several folders. The total counter also always displays the correct number. The interface in this case responds to reading any letter by changing the counter.

We summarize:
2.1 Three levels or two?
Basically in the market there are two types of displaying threads:
First, when you click on a thread in the list of threads, another list opens, this time letters, where to get to reading a particular letter, you must click again. For convenience, we called it "three-level." By the way, it is used a lot where - from some versions of Outlook to a large number of mobile email clients.
The second (aka “two-level”) - when a user clicks from the list of threads, the user immediately goes to the “bodies” of letters, i.e. has the ability to quickly get to the actual contents of the correspondence.
We decided not to stand in the way of the user to his content and not to force him to make two clicks every time he wants to read a newly arrived letter. As you might have guessed, the "two-tier" option was chosen. Although he both technically and ideologically foreshadowed much more problems, but about them a little further.
2.2 Read and unread letters inside the thread
Here we decided not to philosophize mischievously - it is obvious that the user is interested in first of all familiarizing himself with the contents of those letters that he has not yet seen. And therefore, they need to focus on his attention. Therefore, inside the thread, we decided to expand all unread letters, and leave all read letters folded.
If there are no unread letters in the thread, we leave the latest one expanded (why - more on that later).

2.3 Read and unread threads in the thread list
The first question to be solved was whether to mark the thread unread in the list of letters (now in the list of threads), if there is at least one unread letter there? Suppose we decide to mark the thread unread. But if the letters of the same thread are in different folders (for example, part in the Inbox and part in the Important), we have two problems at once. The first - marking the thread read in one folder, we change the counter of unread messages in two folders at once. The second - it is not clear what to do with the general counter of unread letters. Indeed, if the user goes into the mailbox, sees that there are two unread letters at once, opens the thread in the first folder and reads it, and both counters are reset to zero, then he will think that the second unread letter was simply lost.
We dismissed this option as unsuccessful and decided to try differently: mark the thread unread only in the folder where the user has unread messages. For example, thread letters are dispersed between Inbox and Important, with the only unread letter in Important. That is, if the user is in the Inbox (where there are no unread emails), all threads are marked as read.
However, another small problem arose here - when a user opens a thread from Inbox, already inside he sees that there is a detailed unread message in it (the same one that lies in "Important"). It turns out a little illogical.
We decided to fix this problem as follows: letters from other folders in the thread will also be collapsed to the state of the header, even if they are not read. So, getting into the thread, the user sees expanded only unread messages from this folder. Thus, we do not have unnecessary information and there are no “accidental” readings of what should have been reminiscent of ourselves (it was not for nothing that sorting into a separate folder was set up).
However, in fairness, I must say that the situation when letters from the same thread are in different folders (not counting the Sent ones, of course) is quite rare. And this is good!
2.4 deleting threads
At the same time, we had to find an answer to one more question. Imagine a situation: we are in the Inbox folder and we open a thread in which one letter is from the Inbox folder and the second is from the Sent Items folder. If you click "Delete thread", what will happen to the letter from the "Sent"? Interviewing users, we found out: they expect the message to remain in the Sent Items folder. Therefore, we have all the actions with the thread - deleting, moving, etc. - apply only to letters from the folder that the user has opened.
2.5 Position of new letters in the thread
Another important question that needed to be solved: show the latest letters at the top or bottom of the chain? We decided to preserve the principle by which classical email works, that is, show the latest letters on the top of the thread (unlike, for example, Gmail, where new letters are displayed at the bottom of the thread).
In addition, our research has shown that many users begin to read the thread from the last letter in order to understand whether to read the rest of the letters in the chain. This was another argument in favor of displaying new letters on top.
2.6 Toolbar Functionality
It was also necessary to decide how the toolbar with the “Reply” button will work, relating to the entire thread. We chose between two options: hang up the answer and forwarding it in relation to the last letter in the thread, or to the letter that is currently on the screen of the user. As a result, we settled on the first option, since the option with the letter currently on the screen introduced too much uncertainty, for example, what to do if there are two or even three short letters on the screen at once? Or how to intuitively tell the user which letter he will answer now?
By the way, that is why the last letter in the thread is always deployed, regardless of whether it is read or not. In case the user has a desire to respond to any other letter, we made a small additional toolbar inside the thread, allowing you to do this.

We summarize:
***
Implementation of threads in the mail is a rather difficult task, for the solution of which we spent a lot of time and effort. Now threads can be enabled in all Mail.Ru Mailboxes.
I would be very grateful if in the comments you tell us how convenient it is for you to use the updated interface and whether the decisions that we have chosen seem logical to you.
However, all our usability tests showed that for a less advanced audience, threads are a rather complicated and not always convenient feature. Many were horrified by "losing" their letters in the Inbox, they could not understand how to respond to a specific message in the chain, and much more.
Nevertheless, to ourselves (the Mail.Ru Mail team), as people belonging to the first group (geeks, productivity buffs and programmers), the idea of threads was close and clear. Therefore, we decided to meet the wishes of the advanced community and implement the threads in the optional mode (you can enable them in the "View" menu in the upper right corner above the list of letters).

However, it is easy to solve, but not so easy to do. At the stage of thinking through logic, a lot of nuances were revealed. Although the threads were already implemented in other mail services, we still had to develop our own algorithm. Firstly, some foreign solutions seemed erroneous to us, and we decided to fix them, and secondly, the logic of some basic functionality of our mail is different from the work of similar functionality of others, so it’s impossible to simply “take over experience” as is.
In this post we want to talk about what difficulties awaited us and how we managed to overcome them.
1. How to "glue" threads
1.1 Understanding In-Reply-To
Each letter has meta-information (service headers). The In-Reply-To header indicates the response to which message is the message you opened (In-Reply-To), and the References contains, among other things, information about the letter that was the first in the correspondence. It is logical that if there are such service headers, then it makes sense to group letters by these headers. However, there are two nuances that we had to consider.
First: what to do with redirected letters? In the case when the incoming message is redirected, in fact another message appears with the In-Reply-To service header. This header indicates a forwarded email. At the same time, the prefix FW or FWD appears in the subject. That is, in fact, the forward is another answer. Guided by this logic, Gmail, for example, “sticks” redirected messages to the same thread.
We interviewed users inside Mail.Ru and outside and found that, as a rule, they send a letter not to connect a person to the correspondence, but to discuss the topic of correspondence separately with him. So - they want to start a new "conversation", and not stay in the old one. Therefore, we decided that in such cases we will start a new chain.

Second: sometimes people can reply to the letter by changing its subject manually. Then in the service heading of the letter formally will remain marked In-Reply-To, but the subject of the letter will change. Focusing on the results of our research, we realized that if people consciously change the subject of a letter, then this is a new chain for them, and decided that in such cases we will also create a separate thread, even despite the presence of In-Reply-To in the service header .
Based on these two nuances, the grouping algorithm should be like this:
- normalize the topic, for example, throw out all the prefixes “Re”, but leave “FWD”
- group letters related to headers and one normalized subject
1.2 We think over a grouping for automatic mailings.
If there are no headings, this does not mean that there is nothing to group. There are many letters that just ask in one group: notifications from social networks, promotional letters from online stores, letters from the task tracker, finally. As a rule, in all these cases, letters have one subject and one sender. Therefore, we decided to group letters without headers according to the criterion “subject + sender” in order to cover automatic mailings.

1.3 Separate the "basket"
A separate problem when implementing threads is created by the Mail folder structure. We decided that letters from different folders, including “Sent Items”, could fall into the same chain, so that in one place you could see the letters that arrived and the answers to them. There, in theory, letters from the "Basket" folder should also have been included. Initially, we were guided by this logic, but the first beta testers gave us feedback that it was inconvenient and that they did not want to see deleted messages, even if they could be grouped by letter in the Inbox folder.
1.4 Determining the readings of counters
As we have already said, when grouping letters from the same chain, they can be scattered in different folders (the simplest case is “Inbox” and “Sent”). In this regard, a lot of questions arise, for example:
- If the conversation is not read, does it remain unread in all folders?
- If there are several unread messages in the conversation, what should the counter show - the number of unread messages or one unread conversation?
We get three options. Let's look at them.
First: the counter works with conversations, and an unread conversation is marked in all folders in which it is displayed. Say, in two folders - “Inbox” and “Sent” - there is one unread letter that has just arrived in the mailbox. In the list of folders we will see one in each of these two folders. But what to show in the general counter at the box? In theory, there you need to display the amount for all folders, and in our case it is two. But in fact, in the box there is one unread chain!
The second option: a thread in a folder is considered unread only if there are unread messages from this thread in the folder. But suppose there are two unread letters in the thread. The folder counter displays one: one thread has not been read. The user opens the thread and reads the top letter, after which he returns to the list of letters. One letter has been read, but the counter still shows one: after all, there is another unread letter in the thread, which means that the whole thread has not been read. It turns out that the user took an action, and the readings of the counters have not changed.
The third option, which we chose: in the counters we take into account letters, not threads. In this case, the counter for each folder displays the correct data, because the letter cannot be in several folders. The total counter also always displays the correct number. The interface in this case responds to reading any letter by changing the counter.

We summarize:
- we glue threads by headers and subject or by sender and subject
- the forwarded letter starts a new thread
- the thread includes letters from all folders except the "Recycle Bin"
- in the folder counters we display the number of unread letters, not threads
2. Appearance of the thread and actions with it
2.1 Three levels or two?
Basically in the market there are two types of displaying threads:
First, when you click on a thread in the list of threads, another list opens, this time letters, where to get to reading a particular letter, you must click again. For convenience, we called it "three-level." By the way, it is used a lot where - from some versions of Outlook to a large number of mobile email clients.
The second (aka “two-level”) - when a user clicks from the list of threads, the user immediately goes to the “bodies” of letters, i.e. has the ability to quickly get to the actual contents of the correspondence.
We decided not to stand in the way of the user to his content and not to force him to make two clicks every time he wants to read a newly arrived letter. As you might have guessed, the "two-tier" option was chosen. Although he both technically and ideologically foreshadowed much more problems, but about them a little further.
2.2 Read and unread letters inside the thread
Here we decided not to philosophize mischievously - it is obvious that the user is interested in first of all familiarizing himself with the contents of those letters that he has not yet seen. And therefore, they need to focus on his attention. Therefore, inside the thread, we decided to expand all unread letters, and leave all read letters folded.
If there are no unread letters in the thread, we leave the latest one expanded (why - more on that later).

2.3 Read and unread threads in the thread list
The first question to be solved was whether to mark the thread unread in the list of letters (now in the list of threads), if there is at least one unread letter there? Suppose we decide to mark the thread unread. But if the letters of the same thread are in different folders (for example, part in the Inbox and part in the Important), we have two problems at once. The first - marking the thread read in one folder, we change the counter of unread messages in two folders at once. The second - it is not clear what to do with the general counter of unread letters. Indeed, if the user goes into the mailbox, sees that there are two unread letters at once, opens the thread in the first folder and reads it, and both counters are reset to zero, then he will think that the second unread letter was simply lost.
We dismissed this option as unsuccessful and decided to try differently: mark the thread unread only in the folder where the user has unread messages. For example, thread letters are dispersed between Inbox and Important, with the only unread letter in Important. That is, if the user is in the Inbox (where there are no unread emails), all threads are marked as read.
However, another small problem arose here - when a user opens a thread from Inbox, already inside he sees that there is a detailed unread message in it (the same one that lies in "Important"). It turns out a little illogical.
We decided to fix this problem as follows: letters from other folders in the thread will also be collapsed to the state of the header, even if they are not read. So, getting into the thread, the user sees expanded only unread messages from this folder. Thus, we do not have unnecessary information and there are no “accidental” readings of what should have been reminiscent of ourselves (it was not for nothing that sorting into a separate folder was set up).
However, in fairness, I must say that the situation when letters from the same thread are in different folders (not counting the Sent ones, of course) is quite rare. And this is good!
2.4 deleting threads
At the same time, we had to find an answer to one more question. Imagine a situation: we are in the Inbox folder and we open a thread in which one letter is from the Inbox folder and the second is from the Sent Items folder. If you click "Delete thread", what will happen to the letter from the "Sent"? Interviewing users, we found out: they expect the message to remain in the Sent Items folder. Therefore, we have all the actions with the thread - deleting, moving, etc. - apply only to letters from the folder that the user has opened.
2.5 Position of new letters in the thread
Another important question that needed to be solved: show the latest letters at the top or bottom of the chain? We decided to preserve the principle by which classical email works, that is, show the latest letters on the top of the thread (unlike, for example, Gmail, where new letters are displayed at the bottom of the thread).
In addition, our research has shown that many users begin to read the thread from the last letter in order to understand whether to read the rest of the letters in the chain. This was another argument in favor of displaying new letters on top.
2.6 Toolbar Functionality
It was also necessary to decide how the toolbar with the “Reply” button will work, relating to the entire thread. We chose between two options: hang up the answer and forwarding it in relation to the last letter in the thread, or to the letter that is currently on the screen of the user. As a result, we settled on the first option, since the option with the letter currently on the screen introduced too much uncertainty, for example, what to do if there are two or even three short letters on the screen at once? Or how to intuitively tell the user which letter he will answer now?
By the way, that is why the last letter in the thread is always deployed, regardless of whether it is read or not. In case the user has a desire to respond to any other letter, we made a small additional toolbar inside the thread, allowing you to do this.

We summarize:
- the most current letter from the current folder is always expanded
- letters from other folders are minimized regardless of status
- letters from the current folder are minimized only if read
- when deleting a thread, we delete only letters from the current folder
- display the latest letters on top
- the buttons on the upper tablar in the thread work with the upper letter
***
Implementation of threads in the mail is a rather difficult task, for the solution of which we spent a lot of time and effort. Now threads can be enabled in all Mail.Ru Mailboxes.
I would be very grateful if in the comments you tell us how convenient it is for you to use the updated interface and whether the decisions that we have chosen seem logical to you.