Synchronization of delivery status
When we send a message to a conversation, the delivery status must be explicit and understandable for the end user. So, Jami must offer the possibility to know if the message was delivered to the other members of a conversation and synchronize this status (sent and displayed) across devices.
How it works (backend)
The status of messages is stored in the conversation layer via the variable messagesStatus (map<string, map<string, string>)
with the following structure:
{uri, {
{"fetch", "commitId"},
{"fetched_ts", "timestamp"},
{"read", "commitId"},
{"read_ts", "timestamp"}
}
}
The fetch
status is the commitId of the last message fetched by the member. The fetched_ts
is the timestamp of the last message fetched by the member. The read
status is the commitId of the last message read by the member. The read_ts
is the timestamp of the last message read by the member.
When a member fetches a message, the fetch
status is updated with the commitId of the message and the fetched_ts
is updated with the timestamp of the message. When a member reads a message, the read
status is updated with the commitId of the message and the read_ts
is updated with the timestamp of the message. This information is synced across devices and other devices will update their internal structure if the timestamp is newer.
This information is stored in conversation_data/xxxxxxxxx/status
.
Client API
The client should get status from the current SwarmMessage structure when loading conversation and update the status via AccountMessageStatusChanged
.
In AccountMessageStatusChanged
the client will have the commitId, peer uri and new status. So, this will correspond to message.status[uri]
.
SwarmMessage's status structure is:
{
{uri, status},
{uri2, status2}
}
Where uri
is the peer uri and status
is the status of the message for this peer (from the MessageStates
enum).
When sending a new message, the status
map can be empty (because no one fetched). By default, if there is no fetch/read information for a message, the message MUST be considered as sending.
The global status of a message is the maximum of the status of all members except ourselves. For example, if Alice sends a message and we have:
status = {alice: displayed, bob: sending, carl: sent}
The global status is sent
.
Notes for client
If the client wants to show which message is the last read message for a member, they must check the index when responding to
AccountMessageStatusChanged
. Because this signal can emit that a previous message is displayed later.The status of a message can be used to create a detailed view of who received/displayed a specific message. However, timestamps of those events are not stored, because this would represent too much data.