diff --git a/src/api/conversation.h b/src/api/conversation.h
index 9bddff558d911025b9184b54cabaf890d6705475..fe828bf5f2029407c370245bab1886b71e596d65 100644
--- a/src/api/conversation.h
+++ b/src/api/conversation.h
@@ -37,18 +37,18 @@ static inline Mode
 to_mode(const int intMode)
 {
     switch (intMode) {
-        case 0:
-            return Mode::ONE_TO_ONE;
-        case 1:
-            return Mode::ADMIN_INVITES_ONLY;
-        case 2:
-            return Mode::INVITES_ONLY;
-        case 3:
-            return Mode::PUBLIC;
-        case 4:
-            return Mode::NON_SWARM;
-        default:
-            return Mode::ONE_TO_ONE;
+    case 0:
+        return Mode::ONE_TO_ONE;
+    case 1:
+        return Mode::ADMIN_INVITES_ONLY;
+    case 2:
+        return Mode::INVITES_ONLY;
+    case 3:
+        return Mode::PUBLIC;
+    case 4:
+        return Mode::NON_SWARM;
+    default:
+        return Mode::ONE_TO_ONE;
     }
 }
 
@@ -75,6 +75,7 @@ struct Info
     QString getCallId() { return confId.isEmpty() ? callId : confId; }
 
     Mode mode = Mode::NON_SWARM;
+    bool needsSyncing = false;
     bool isRequest = false;
 };
 
diff --git a/src/chatview.cpp b/src/chatview.cpp
index b673233f2211ffbdad9b30af9d688eca2e4ae5ca..57f3d5abe07f13093bc7ef7bb683c32526e076e9 100644
--- a/src/chatview.cpp
+++ b/src/chatview.cpp
@@ -49,6 +49,10 @@ getTranslatedStrings(bool qwebview)
          QObject::tr("has sent you a conversation request.")},
         {"Hello, do you want to join the conversation?",
          QObject::tr("Hello, do you want to join the conversation?")},
+        {"You have accepted the conversation request.",
+         QObject::tr("You have accepted the conversation request.")},
+        {"We are waiting for another device to synchronize the conversation.",
+         QObject::tr("We are waiting for another device to synchronize the conversation.")},
         {"Note: you can automatically accept this invitation by sending a message.",
          QObject::tr("Note: you can automatically accept this invitation by sending a message.")},
         {"%d days ago", qwebview ? QObject::tr("{0} days ago") : QObject::tr("%d days ago")},
diff --git a/src/contactmodel.cpp b/src/contactmodel.cpp
index 2b2ffb1a48e0ed5c9e6f42300135550e69fb855c..341dfb6f0e96fa06a3a1f0feb12dc40dcb7df700 100644
--- a/src/contactmodel.cpp
+++ b/src/contactmodel.cpp
@@ -84,11 +84,13 @@ public:
      * @param type
      * @param displayName
      * @param banned whether contact is banned or not
+     * @param conversationId linked swarm if one
      */
     void addToContacts(const QString& contactId,
                        const profile::Type& type,
                        const QString& displayName = "",
-                       bool banned = false);
+                       bool banned = false,
+                       const QString& conversationId = "");
     /**
      * Helpers for searchContact. Search for a given classic or SIP contact.
      */
@@ -662,7 +664,11 @@ ContactModelPimpl::fillWithJamiContacts()
     for (auto contact_info : contacts_vector) {
         std::lock_guard<std::mutex> lk(contactsMtx_);
         bool banned = contact_info["banned"] == "true" ? true : false;
-        addToContacts(contact_info["id"], linked.owner.profileInfo.type, "", banned);
+        addToContacts(contact_info["id"],
+                      linked.owner.profileInfo.type,
+                      "",
+                      banned,
+                      contact_info["conversationId"]);
     }
 
     // Add pending contacts
@@ -692,6 +698,7 @@ ContactModelPimpl::fillWithJamiContacts()
             contactInfo.profileInfo.avatar = photo.constData();
         contactInfo.registeredName = "";
         contactInfo.isBanned = false;
+        contactInfo.conversationId = tr_info[DRing::Account::TrustRequest::CONVERSATIONID];
 
         {
             std::lock_guard<std::mutex> lk(contactsMtx_);
@@ -792,7 +799,13 @@ ContactModelPimpl::slotContactAdded(const QString& accountId,
                 bannedContacts.erase(it);
             }
 
-            addToContacts(contactUri, linked.owner.profileInfo.type, "", false);
+            MapStringString details = ConfigurationManager::instance()
+                                          .getContactDetails(linked.owner.id, contactUri);
+            addToContacts(contactUri,
+                          linked.owner.profileInfo.type,
+                          "",
+                          false,
+                          details["conversationId"]);
         }
     }
     if (isBanned) {
@@ -864,7 +877,8 @@ void
 ContactModelPimpl::addToContacts(const QString& contactUri,
                                  const profile::Type& type,
                                  const QString& displayName,
-                                 bool banned)
+                                 bool banned,
+                                 const QString& conversationId)
 {
     // create a vcard if necessary
     profile::Info profileInfo {contactUri, {}, displayName, linked.owner.profileInfo.type};
@@ -872,6 +886,7 @@ ContactModelPimpl::addToContacts(const QString& contactUri,
 
     auto contactInfo = storage::buildContactFromProfile(linked.owner.id, contactUri, type);
     contactInfo.isBanned = banned;
+    contactInfo.conversationId = conversationId;
 
     // lookup address in case of RING contact
     if (type == profile::Type::JAMI) {
diff --git a/src/conversationmodel.cpp b/src/conversationmodel.cpp
index b9a0070da869f29e3295bdf204d69fa356655f9d..0738adeb5cb3d0bb341014498ccd596f149b6844 100644
--- a/src/conversationmodel.cpp
+++ b/src/conversationmodel.cpp
@@ -1485,6 +1485,9 @@ ConversationModel::acceptConversationRequest(const QString& conversationId)
     default:
         break;
     }
+    conversation.needsSyncing = true;
+    pimpl_->invalidateModel();
+    emit modelChanged();
     ConfigurationManager::instance().acceptConversationRequest(owner.id, conversationId);
 }
 
@@ -1843,6 +1846,16 @@ ConversationModelPimpl::initConversations()
             conv.push_back(storage::beginConversationWithPeer(db, c.second.profileInfo.uri));
         }
         addConversationWith(conv[0], c.first);
+        if (!c.second.conversationId.isEmpty()) {
+            // it is a swarm conversation.
+            try {
+                auto& conversation = getConversationForUid(conv[0]).get();
+                conversation.mode = conversation::Mode::ONE_TO_ONE;
+                conversation.needsSyncing = true;
+            } catch (...) {
+                continue;
+            }
+        }
 
         auto convIdx = indexOf(conv[0]);
 
@@ -2278,6 +2291,7 @@ ConversationModelPimpl::slotConversationReady(const QString& accountId,
                                              .conversationInfos(accountId, conversationId);
         conversation.mode = conversation::to_mode(details["mode"].toInt());
         conversation.isRequest = false;
+        conversation.needsSyncing = false;
         auto id = ConfigurationManager::instance().loadConversationMessages(linked.owner.id,
                                                                             conversationId,
                                                                             "",
@@ -2402,6 +2416,13 @@ ConversationModelPimpl::slotContactAdded(const QString& contactUri)
         auto& conversation = getConversationForPeerUri(contactUri).get();
         // swarm conversation we update when receive conversation ready signal.
         if (conversation.mode != conversation::Mode::NON_SWARM) {
+            QStringList swarms = ConfigurationManager::instance().getConversations(linked.owner.id);
+            bool needsSyncing = swarms.indexOf(conversation.uid) == -1;
+            if (conversation.needsSyncing != needsSyncing) {
+                conversation.needsSyncing = needsSyncing;
+                invalidateModel();
+                emit linked.modelChanged();
+            }
             return;
         }
         if (conv.empty()) {
@@ -2623,6 +2644,7 @@ ConversationModelPimpl::addSwarmConversation(const QString& convId)
         } catch (...) {
         }
     }
+    conversation.needsSyncing = false;
     conversations.emplace_back(std::move(conversation));
     auto id = ConfigurationManager::instance().loadConversationMessages(linked.owner.id,
                                                                         convId,
@@ -2638,6 +2660,7 @@ ConversationModelPimpl::addConversationWith(const QString& convId, const QString
     conversation.accountId = linked.owner.id;
     conversation.participants = {contactUri};
     conversation.mode = conversation::Mode::NON_SWARM;
+    conversation.needsSyncing = false;
     try {
         conversation.confId = linked.owner.callModel->getConferenceFromURI(contactUri).id;
     } catch (...) {
diff --git a/src/web-chatview/chatview.css b/src/web-chatview/chatview.css
index e362134e6e16b06ed1e0803e481b2e7d06f03c11..13fadb78fe35da63703fff5eea511ba889c1710a 100644
--- a/src/web-chatview/chatview.css
+++ b/src/web-chatview/chatview.css
@@ -1139,7 +1139,11 @@ video {
   }
 
   #join_text {
-      font-size: 18px;
+      font-size: 1.1em;
+  }
+
+  #note_text {
+      font-size: .8em;
   }
 }
 
@@ -1164,7 +1168,11 @@ video {
   }
 
   #join_text {
-      font-size: 16px;
+      font-size: 1em;
+  }
+
+  #note_text {
+      font-size: .8em;
   }
 }
 
diff --git a/src/web-chatview/chatview.html b/src/web-chatview/chatview.html
index ed277b7cc74037074959741b958f0cfdd43570a8..1d89434d85c5acb31c6a90da536668a0a8cf27ec 100644
--- a/src/web-chatview/chatview.html
+++ b/src/web-chatview/chatview.html
@@ -121,7 +121,8 @@
         <div id="typing_indicator_container"></div>
 
         <div id="back_to_bottom_button_container">
-            <div id="back_to_bottom_button" onclick="back_to_bottom()">Jump to latest &#9660;</div>
+            <div id="back_to_bottom_button" onclick="back_to_bottom()">Jump to latest &#9660;
+</div>
         </div>
         <div id="send_inteface_container" onresize="updateBackToBottomContainer()">
             <div id="sendMessage">
diff --git a/src/web-chatview/chatview.js b/src/web-chatview/chatview.js
index 34d74a45766bd9da05f6f0cc1d507c8263ed5ec3..311d50a79b58494adb6132dd1dff507a52b80e13 100644
--- a/src/web-chatview/chatview.js
+++ b/src/web-chatview/chatview.js
@@ -64,6 +64,7 @@ const navbar = document.getElementById("navbar")
 const emojiBtn = document.getElementById('emojiButton');
 const invitationText = document.getElementById("invitation_text")
 const joinText = document.getElementById("join_text")
+const noteText = document.getElementById("note_text")
 const invitationNoteText = document.getElementById("invitation_note")
 
 var   messages = document.getElementById("messages")
@@ -379,9 +380,11 @@ function update_chatview_frame(accountEnabled, banned, temporary, alias, bestid)
  *
  * @param contactAlias
  * @param contactId
+ * @param isSwarm
+ * @param isSyncing
  */
 /* exported showInvitation */
-function showInvitation(contactAlias, contactId, isSwarm) {
+function showInvitation(contactAlias, contactId, isSwarm, isSyncing) {
     if (!contactAlias) {
         if (hasInvitation) {
             hasInvitation = false
@@ -408,9 +411,17 @@ function showInvitation(contactAlias, contactId, isSwarm) {
             i18n.sprintf(i18n.gettext("%s has sent you a conversation request."), contactAlias))
             + "<br/>"
 
+        var joinTextValue = (isSyncing ?
+            "You have accepted the conversation request." :
+            "Hello, do you want to join the conversation?")
         joinText.innerHTML = (use_qt ?
-            i18nStringData["Hello, do you want to join the conversation?"] :
-            i18n.gettext("Hello, do you want to join the conversation?"))
+            i18nStringData[joinTextValue] :
+            i18n.gettext(joinTextValue))
+            + "<br/>"
+
+        noteText.innerHTML = (use_qt ?
+            i18nStringData["We are waiting for another device to synchronize the conversation."] :
+            i18n.gettext("We are waiting for another device to synchronize the conversation."))
             + "<br/>"
 
         invitationNoteText.innerHTML = (use_qt ?
@@ -428,7 +439,7 @@ function showInvitation(contactAlias, contactId, isSwarm) {
             invitationNoteText.style.visibility = "visible"
             messageBar.style.visibility = "visible"
         }
-
+        
         invitation.style.display = "flex"
         invitation.style.visibility = "visible"
 
@@ -1022,14 +1033,7 @@ function fileInteraction(message_id, message_direction) {
 
     const internal_mes_wrapper = document.createElement("div")
     internal_mes_wrapper.setAttribute("class", "internal_mes_wrapper")
-   // if(use_qt) {
-   //     var tbl = buildMsgTable(message_direction)
-   //     var msg_cell = tbl.querySelector(".msg_cell")
-   //     msg_cell.appendChild(message_wrapper)
-   //     internal_mes_wrapper.appendChild(tbl)
-   // } else {
-        internal_mes_wrapper.appendChild(message_wrapper)
-   // }
+    internal_mes_wrapper.appendChild(message_wrapper)
 
     return internal_mes_wrapper
 }