From b10dd88ab21d86157a58448265797417065d6218 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Blin?=
 <sebastien.blin@savoirfairelinux.com>
Date: Thu, 22 Jul 2021 12:13:04 -0400
Subject: [PATCH] Create 2.6 Displayed status

---
 2.6-Displayed-status.md | 73 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 73 insertions(+)
 create mode 100644 2.6-Displayed-status.md

diff --git a/2.6-Displayed-status.md b/2.6-Displayed-status.md
new file mode 100644
index 00000000..f30e3969
--- /dev/null
+++ b/2.6-Displayed-status.md
@@ -0,0 +1,73 @@
+Every client generally must be able to show what peer read what message and get how many unread messages there is.
+
+For this, the daemon provides some APIs:
+
+# Set a message displayed
+
+The Configuration manager provides:
+
+```
+<method name="setMessageDisplayed" tp:name-for-bindings="setMessageDisplayed">
+    <tp:added version="8.1.0"/>
+    <tp:docstring>
+        <p>Informs that a message have been read</p>
+    </tp:docstring>
+    <arg type="s" name="accountId" direction="in">
+        <tp:docstring>
+        The account ID
+        </tp:docstring>
+    </arg>
+    <arg type="s" name="conversationUri" direction="in">
+        <tp:docstring>
+        A conversation uri (swarm:xxxx or jami:xxxx)
+        </tp:docstring>
+    </arg>
+    <arg type="s" name="messageId" direction="in">
+        <tp:docstring>
+        The message ID
+        </tp:docstring>
+    </arg>
+    <arg type="i" name="status" direction="in">
+        <tp:docstring>
+        The message status, 3 for displayed
+        </tp:docstring>
+    </arg>
+    <arg type="b" name="success" direction="out">
+        <tp:docstring>
+        True if the message status was set, false if account, contact or message is unknown.
+        </tp:docstring>
+    </arg>
+</method>
+```
+
+to set a message as displayed. Should be done when the interaction is shown and the conversation selected.
+
+This sends a SIP messages to connected peers with the following format:
+
+```cpp
+std::string
+getDisplayed(const std::string& conversationId, const std::string& messageId)
+{
+    // implementing https://tools.ietf.org/rfc/rfc5438.txt
+    return fmt::format(
+        "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
+        "<imdn><message-id>{}</message-id>\n"
+        "{}"
+        "<display-notification><status><displayed/></status></display-notification>\n"
+        "</imdn>",
+        messageId,
+        conversationId.empty() ? "" : "<conversation>" + conversationId + "</conversation>");
+}
+```
+
+Then the peer will know this via `onMessageDisplayed` and emit a signal to the client (`DRing::ConfigurationSignal::AccountMessageStatusChanged` with status 3 (`DRing::Account::MessageStates::DISPLAYED`))
+
+# Get unread messages
+
+By knowing the lastDisplayedMessage for our account, we can use this informations and `ConfigrationManager::countInteractionsSince` which count interaction since last message to a given message (typically last displayed interaction)
+
+To get last displayed message for a member, in `Configuration::getConversationMembers` each member will have the last displayed interaction available via `memberInfo["lastDisplayed"]`
+
+# How this information is stored
+
+In `src/jamidht/conversation.cpp` each conversation store the last displayed messages in a map<string, string> (uri, interactionId) and this structure is serialized in `fileutils::get_data_dir()/getAccountID()/conversation_data/repository_->id()/lastDisplayed`
\ No newline at end of file
-- 
GitLab