diff --git a/src/conversationsadapter.cpp b/src/conversationsadapter.cpp
index 74e2567f166944474f57eece1e70845c5aa5427b..186731001e6080c39210238f44732669b6bab7a1 100644
--- a/src/conversationsadapter.cpp
+++ b/src/conversationsadapter.cpp
@@ -276,12 +276,6 @@ ConversationsAdapter::onProfileUpdated(const QString& contactUri)
 void
 ConversationsAdapter::onConversationUpdated(const QString& convId)
 {
-    // this could be the result of a member event
-    auto& convInfo = lrcInstance_->getConversationFromConvUid(convId);
-    if (convInfo.uid.isEmpty())
-        return;
-    set_currentConvIsReadOnly(convInfo.readOnly);
-
     updateConversationFilterData();
 }
 
@@ -335,12 +329,6 @@ ConversationsAdapter::onConversationReady(const QString& convId)
     updateConversation(convId);
 }
 
-void
-ConversationsAdapter::onNeedsSyncingSet(const QString& convId)
-{
-    updateConversation(convId);
-}
-
 void
 ConversationsAdapter::onBannedStatusChanged(const QString& uri, bool banned)
 {
@@ -499,12 +487,6 @@ ConversationsAdapter::connectConversationModel()
                      &ConversationsAdapter::onConversationReady,
                      Qt::UniqueConnection);
 
-    QObject::connect(currentConversationModel,
-                     &ConversationModel::needsSyncingSet,
-                     this,
-                     &ConversationsAdapter::onNeedsSyncingSet,
-                     Qt::UniqueConnection);
-
     QObject::connect(lrcInstance_->getCurrentContactModel(),
                      &ContactModel::bannedStatusChanged,
                      this,
diff --git a/src/conversationsadapter.h b/src/conversationsadapter.h
index cae66565ba4e56f44d24bfa1564b745b0f73717a..aefc70ca5b8797ed57389c285254e2cf22268bc9 100644
--- a/src/conversationsadapter.h
+++ b/src/conversationsadapter.h
@@ -36,7 +36,6 @@ class ConversationsAdapter final : public QmlAdapterBase
     QML_PROPERTY(bool, filterRequests)
     QML_PROPERTY(int, totalUnreadMessageCount)
     QML_PROPERTY(int, pendingRequestCount)
-    QML_PROPERTY(bool, currentConvIsReadOnly)
 
 public:
     explicit ConversationsAdapter(SystemTray* systemTray,
@@ -82,15 +81,12 @@ private Q_SLOTS:
     void onSearchStatusChanged(const QString&);
     void onSearchResultUpdated();
     void onConversationReady(const QString&);
-    void onNeedsSyncingSet(const QString&);
     void onBannedStatusChanged(const QString&, bool);
 
+private:
     void updateConversation(const QString&);
     void updateConversationFilterData();
 
-private:
-    void updateConversationForNewContact(const QString& convUid);
-
     SystemTray* systemTray_;
 
     QScopedPointer<ConversationListModel> convSrcModel_;
diff --git a/src/currentconversation.cpp b/src/currentconversation.cpp
index 515ac4de304f77134d78219b98bef9debd1d52c7..e0ee604ac0f0a1e10ddf5b56424c5516be7afda0 100644
--- a/src/currentconversation.cpp
+++ b/src/currentconversation.cpp
@@ -49,21 +49,42 @@ CurrentConversation::updateData()
         auto accountId = lrcInstance_->get_currentAccountId();
         const auto& accInfo = lrcInstance_->accountModel().getAccountInfo(accountId);
         if (auto optConv = accInfo.conversationModel->getConversationForUid(convId)) {
+            auto& convInfo = optConv->get();
             set_title(accInfo.conversationModel->title(convId));
             set_uris(accInfo.conversationModel->peersForConversation(convId).toList());
-            set_isSwarm(optConv->get().isSwarm());
-            set_isLegacy(optConv->get().isLegacy());
-            set_isCoreDialog(optConv->get().isCoreDialog());
-            set_isRequest(optConv->get().isRequest);
-            set_readOnly(optConv->get().readOnly);
-            set_needsSyncing(optConv->get().needsSyncing);
+            set_isSwarm(convInfo.isSwarm());
+            set_isLegacy(convInfo.isLegacy());
+            set_isCoreDialog(convInfo.isCoreDialog());
+            set_isRequest(convInfo.isRequest);
+            set_readOnly(convInfo.readOnly);
+            set_needsSyncing(convInfo.needsSyncing);
             set_isSip(accInfo.profileInfo.type == profile::Type::SIP);
-            set_callId(optConv->get().getCallId());
+            set_callId(convInfo.getCallId());
             if (accInfo.callModel->hasCall(callId_)) {
-                set_callState(accInfo.callModel->getCall(callId_).status);
+                auto call = accInfo.callModel->getCall(callId_);
+                set_callState(call.status);
             } else {
                 set_callState(call::Status::INVALID);
             }
+            set_inCall(callState_ == call::Status::CONNECTED
+                       || callState_ == call::Status::IN_PROGRESS
+                       || callState_ == call::Status::PAUSED);
+
+            // The temporary status is only for dialogs.
+            // It can be used to display add contact/conversation UI and
+            // is consistently determined by the peer's uri being equal to
+            // the conversation id.
+            set_isTemporary(isCoreDialog_ ? convId == uris_.at(0) : false);
+
+            auto isContact {false};
+            if (isCoreDialog_)
+                try {
+                    auto& contact = accInfo.contactModel->getContact(uris_.at(0));
+                    isContact = contact.profileInfo.type != profile::Type::TEMPORARY;
+                } catch (...) {
+                    qInfo() << "Contact not found";
+                }
+            set_isContact(isContact);
         }
     } catch (...) {
         qWarning() << "Can't update current conversation data for" << convId;
diff --git a/src/currentconversation.h b/src/currentconversation.h
index 35404d81a4c01bc72ee16763e480ba80925593a1..1e0e14fae96b3691a5803584929d8908834d75ff 100644
--- a/src/currentconversation.h
+++ b/src/currentconversation.h
@@ -42,6 +42,8 @@ class CurrentConversation final : public QObject
     QML_PROPERTY(QString, callId)
     QML_PROPERTY(call::Status, callState)
     QML_PROPERTY(bool, inCall)
+    QML_PROPERTY(bool, isTemporary)
+    QML_PROPERTY(bool, isContact)
 
 public:
     explicit CurrentConversation(LRCInstance* lrcInstance, QObject* parent = nullptr);
diff --git a/src/lrcinstance.cpp b/src/lrcinstance.cpp
index 9380a2375946580c8583e09086c4e055455ad541..c443d5e5842f5f972d13fa4db0ebca6e4f377521 100644
--- a/src/lrcinstance.cpp
+++ b/src/lrcinstance.cpp
@@ -407,7 +407,7 @@ LRCInstance::makeConversationPermanent(const QString& convId, const QString& acc
     const auto& accInfo = accountModel().getAccountInfo(aId);
     auto cId = convId.isEmpty() ? selectedConvUid_ : convId;
     if (cId.isEmpty()) {
-        qWarning() << Q_FUNC_INFO << "no conversation to make permanent";
+        qInfo() << Q_FUNC_INFO << "no conversation to make permanent";
         return;
     }
     accInfo.conversationModel.get()->makePermanent(cId);
diff --git a/src/mainview/MainView.qml b/src/mainview/MainView.qml
index f468972c8f9469577bea87a4540900ddd0898196..188093d6674b167ea9512781ac073abb45dee31a 100644
--- a/src/mainview/MainView.qml
+++ b/src/mainview/MainView.qml
@@ -560,10 +560,7 @@ Rectangle {
     Shortcut {
         sequence: "Ctrl+Shift+A"
         context: Qt.ApplicationShortcut
-        onActivated: {
-            LRCInstance.makeConversationPermanent()
-            communicationPageMessageWebView.setSendContactRequestButtonVisible(false)
-        }
+        onActivated: LRCInstance.makeConversationPermanent()
     }
 
     Shortcut {
diff --git a/src/mainview/components/CallStackView.qml b/src/mainview/components/CallStackView.qml
index 05e5254d1fe98b40597a8ff7bfb8587b4d92241c..5182f70a4e41768bbfd21c84271ad8a2119f5b25 100644
--- a/src/mainview/components/CallStackView.qml
+++ b/src/mainview/components/CallStackView.qml
@@ -191,7 +191,6 @@ Rectangle {
 
         onCallAccepted: {
             CallAdapter.acceptACall(responsibleAccountId, responsibleConvUid)
-            communicationPageMessageWebView.setSendContactRequestButtonVisible(false)
             mainViewSidePanel.selectTab(SidePanelTabBar.Conversations)
         }
 
diff --git a/src/mainview/components/ConversationListView.qml b/src/mainview/components/ConversationListView.qml
index 7ddfff43e6453f8e55bc38c9b9049c545ca89e38..bf981eb1532da53a53cbb29f5b2c5bdbfcccaf5f 100644
--- a/src/mainview/components/ConversationListView.qml
+++ b/src/mainview/components/ConversationListView.qml
@@ -133,13 +133,15 @@ ListView {
                 "displayId": model.dataForRow(row, ConversationList.BestId),
                 "title": model.dataForRow(row, ConversationList.Title),
                 "uri": model.dataForRow(row, ConversationList.URI),
-                "isSwarm": model.dataForRow(row, ConversationList.IsSwarm)
+                "isSwarm": model.dataForRow(row, ConversationList.IsSwarm),
+                "readOnly": model.dataForRow(row, ConversationList.ReadOnly)
             }
 
             responsibleAccountId = LRCInstance.currentAccountId
             responsibleConvUid = item.convId
             isSwarm = item.isSwarm
             contactType = LRCInstance.currentAccountType
+            readOnly = item.readOnly
 
             if (model.dataForRow(row, ConversationList.IsCoreDialog)) {
                 userProfile.aliasText = item.title
@@ -157,20 +159,14 @@ ListView {
         sequence: "Ctrl+Shift+X"
         context: Qt.ApplicationShortcut
         enabled: root.visible
-        onActivated: {
-            CallAdapter.placeCall()
-            communicationPageMessageWebView.setSendContactRequestButtonVisible(false)
-        }
+        onActivated: CallAdapter.placeCall()
     }
 
     Shortcut {
         sequence: "Ctrl+Shift+C"
         context: Qt.ApplicationShortcut
         enabled: root.visible
-        onActivated: {
-            CallAdapter.placeAudioOnlyCall()
-            communicationPageMessageWebView.setSendContactRequestButtonVisible(false)
-        }
+        onActivated: CallAdapter.placeAudioOnlyCall()
     }
 
     Shortcut {
diff --git a/src/mainview/components/ConversationSmartListContextMenu.qml b/src/mainview/components/ConversationSmartListContextMenu.qml
index dd9fe7ff6106493de60ebfb13b52cdbd4fa47855..e2f463ec430794f9a15b1283438eb10fe13ec288 100644
--- a/src/mainview/components/ConversationSmartListContextMenu.qml
+++ b/src/mainview/components/ConversationSmartListContextMenu.qml
@@ -40,34 +40,31 @@ ContextMenuAutoLoader {
                                           responsibleConvUid) !== ""
         return false
     }
+    property bool readOnly
 
     property list<GeneralMenuItem> menuItems: [
         GeneralMenuItem {
             id: startVideoCallItem
 
-            canTrigger: !hasCall && !ConversationsAdapter.currentConvIsReadOnly
+            canTrigger: !hasCall && !readOnly
             itemName: JamiStrings.startVideoCall
             iconSource: JamiResources.videocam_24dp_svg
             onClicked: {
                 LRCInstance.selectConversation(responsibleConvUid,
                                                responsibleAccountId)
                 CallAdapter.placeCall()
-                communicationPageMessageWebView.setSendContactRequestButtonVisible(
-                            false)
             }
         },
         GeneralMenuItem {
             id: startAudioCall
 
-            canTrigger: !hasCall && !ConversationsAdapter.currentConvIsReadOnly
+            canTrigger: !hasCall && !readOnly
             itemName: JamiStrings.startAudioCall
             iconSource: JamiResources.place_audiocall_24dp_svg
             onClicked: {
                 LRCInstance.selectConversation(responsibleConvUid,
                                                responsibleAccountId)
                 CallAdapter.placeAudioOnlyCall()
-                communicationPageMessageWebView.setSendContactRequestButtonVisible(
-                            false)
             }
         },
         GeneralMenuItem {
@@ -76,11 +73,9 @@ ContextMenuAutoLoader {
             canTrigger: !isSwarm && !hasCall
             itemName: JamiStrings.clearConversation
             iconSource: JamiResources.ic_clear_24dp_svg
-            onClicked: {
-                MessagesAdapter.clearConversationHistory(
-                            responsibleAccountId,
-                            responsibleConvUid)
-            }
+            onClicked: MessagesAdapter.clearConversationHistory(
+                           responsibleAccountId,
+                           responsibleConvUid)
         },
         GeneralMenuItem {
             id: removeContact
@@ -89,10 +84,8 @@ ContextMenuAutoLoader {
                                      || contactType === Profile.Type.SIP)
             itemName: JamiStrings.removeContact
             iconSource: JamiResources.ic_hangup_participant_24dp_svg
-            onClicked: {
-                MessagesAdapter.removeConversation(responsibleAccountId,
-                                                   responsibleConvUid)
-            }
+            onClicked: MessagesAdapter.removeConversation(responsibleAccountId,
+                                                          responsibleConvUid)
         },
         GeneralMenuItem {
             id: hangup
@@ -103,10 +96,8 @@ ContextMenuAutoLoader {
             addMenuSeparatorAfter: contactType !== Profile.Type.SIP
                                    && (contactType === Profile.Type.PENDING
                                        || !hasCall)
-            onClicked: {
-                CallAdapter.hangUpACall(responsibleAccountId,
-                                        responsibleConvUid)
-            }
+            onClicked: CallAdapter.hangUpACall(responsibleAccountId,
+                                               responsibleConvUid)
         },
         GeneralMenuItem {
             id: acceptContactRequest
@@ -114,11 +105,7 @@ ContextMenuAutoLoader {
             canTrigger: contactType === Profile.Type.PENDING
             itemName: JamiStrings.acceptContactRequest
             iconSource: JamiResources.add_people_24dp_svg
-            onClicked: {
-                MessagesAdapter.acceptInvitation(responsibleConvUid)
-                communicationPageMessageWebView.setSendContactRequestButtonVisible(
-                            false)
-            }
+            onClicked: MessagesAdapter.acceptInvitation(responsibleConvUid)
         },
         GeneralMenuItem {
             id: declineContactRequest
@@ -126,9 +113,7 @@ ContextMenuAutoLoader {
             canTrigger: contactType === Profile.Type.PENDING
             itemName: JamiStrings.declineContactRequest
             iconSource: JamiResources.round_close_24dp_svg
-            onClicked: {
-                MessagesAdapter.refuseInvitation(responsibleConvUid)
-            }
+            onClicked: MessagesAdapter.refuseInvitation(responsibleConvUid)
         },
         GeneralMenuItem {
             id: blockContact
@@ -137,9 +122,7 @@ ContextMenuAutoLoader {
             itemName: JamiStrings.blockContact
             iconSource: JamiResources.block_black_24dp_svg
             addMenuSeparatorAfter: contactType !== Profile.Type.SIP
-            onClicked: {
-                MessagesAdapter.blockConversation(responsibleConvUid)
-            }
+            onClicked: MessagesAdapter.blockConversation(responsibleConvUid)
         },
         GeneralMenuItem {
             id: contactDetails
@@ -147,9 +130,7 @@ ContextMenuAutoLoader {
             canTrigger: contactType !== Profile.Type.SIP
             itemName: JamiStrings.contactDetails
             iconSource: JamiResources.person_24dp_svg
-            onClicked: {
-                userProfile.open()
-            }
+            onClicked: userProfile.open()
         }
     ]
 
diff --git a/src/mainview/components/InitialCallPage.qml b/src/mainview/components/InitialCallPage.qml
index b4afe2792a66bad219adacb7f3d9c87180525740..406929e1d7f8525bcf690b00ed261cb92e2fbb57 100644
--- a/src/mainview/components/InitialCallPage.qml
+++ b/src/mainview/components/InitialCallPage.qml
@@ -212,11 +212,8 @@ Rectangle {
     Shortcut {
         sequence: "Ctrl+Y"
         context: Qt.ApplicationShortcut
-        onActivated: {
-            CallAdapter.acceptACall(root.accountConvPair[0],
-                                    root.accountConvPair[1])
-            communicationPageMessageWebView.setSendContactRequestButtonVisible(false)
-        }
+        onActivated: CallAdapter.acceptACall(root.accountConvPair[0],
+                                             root.accountConvPair[1])
     }
 
     Shortcut {
diff --git a/src/mainview/components/InvitationView.qml b/src/mainview/components/InvitationView.qml
index 5056a6cdfdd6bb90e8202c9e674fc537147b80e0..03c9da13e387f474e35b14b10de081b5a589c15c 100644
--- a/src/mainview/components/InvitationView.qml
+++ b/src/mainview/components/InvitationView.qml
@@ -30,10 +30,6 @@ import "../../commoncomponents"
 Rectangle {
     id: root
 
-    property alias imageId: avatar.imageId
-    property string title
-    property bool needSyncing
-
     property real marginSize: 20
     property real textMarginSize: 50
 
@@ -49,7 +45,7 @@ Rectangle {
         width: infoColumnLayout.width - textMarginSize
         height: visible ? contentHeight : 0
 
-        visible: !needSyncing
+        visible: !CurrentConversation.needsSyncing
 
         horizontalAlignment: Text.AlignHCenter
         verticalAlignment: Text.AlignVCenter
@@ -58,7 +54,8 @@ Rectangle {
         color: JamiTheme.textColor
         wrapMode: Text.Wrap
 
-        text: JamiStrings.invitationViewSentRequest.arg(title)
+        text: JamiStrings.invitationViewSentRequest.arg(
+                  CurrentConversation.title)
     }
 
     ColumnLayout {
@@ -78,6 +75,7 @@ Rectangle {
 
             showPresenceIndicator: false
             mode: Avatar.Mode.Conversation
+            imageId: CurrentConversation.id
         }
 
         Text {
@@ -95,7 +93,7 @@ Rectangle {
             color: JamiTheme.textColor
             wrapMode: Text.Wrap
 
-            text: needSyncing ?
+            text: CurrentConversation.needsSyncing ?
                       JamiStrings.invitationViewAcceptedConversation :
                       JamiStrings.invitationViewJoinConversation
         }
@@ -108,7 +106,7 @@ Rectangle {
             Layout.preferredWidth: infoColumnLayout.width - textMarginSize
             Layout.preferredHeight: visible ? contentHeight : 0
 
-            visible: needSyncing
+            visible: CurrentConversation.needsSyncing
 
             horizontalAlignment: Text.AlignHCenter
             verticalAlignment: Text.AlignVCenter
@@ -117,7 +115,8 @@ Rectangle {
             color: JamiTheme.textColor
             wrapMode: Text.Wrap
 
-            text: JamiStrings.invitationViewWaitingForSync.arg(title)
+            text: JamiStrings.invitationViewWaitingForSync.arg(
+                      CurrentConversation.title)
         }
 
         RowLayout {
@@ -128,7 +127,7 @@ Rectangle {
 
             spacing: JamiTheme.invitationViewButtonsSpacing
 
-            visible: !needSyncing
+            visible: !CurrentConversation.needsSyncing
 
             PushButton {
                 id: blockButton
diff --git a/src/mainview/components/MessageWebView.qml b/src/mainview/components/MessageWebView.qml
index 84aac50b8eb41d4d76166dfee8ab51ebf273362f..095e7caffd4a2635a076f42904935e6e6b122976 100644
--- a/src/mainview/components/MessageWebView.qml
+++ b/src/mainview/components/MessageWebView.qml
@@ -32,15 +32,9 @@ import "../js/pluginhandlerpickercreation.js" as PluginHandlerPickerCreation
 Rectangle {
     id: root
 
-    enum Mode {
-        Chat = 0,
-        Invitation
-    }
-
     property string headerUserAliasLabelText: ""
     property string headerUserUserNameLabelText: ""
     property bool jsLoaded: false
-    property var mode: MessageWebView.Mode.Chat
 
     signal needToHideConversationInCall
     signal messagesCleared
@@ -58,18 +52,6 @@ Rectangle {
         messageWebView.runJavaScript(arg)
     }
 
-    function setSendContactRequestButtonVisible(visible) {
-        messageWebViewHeader.sendContactRequestButtonVisible = visible
-    }
-
-    function setMessagingHeaderButtonsVisible(visible) {
-        messageWebViewHeader.toggleMessagingHeaderButtonsVisible(visible)
-    }
-
-    function resetMessagingHeaderBackButtonSource(reset) {
-        messageWebViewHeader.resetBackToWelcomeViewButtonSource(reset)
-    }
-
     function updateChatviewTheme() {
         var theme = 'setTheme("\
             --svg-invert-percentage:' + JamiTheme.invertPercentageInDecimal + ';\
@@ -111,35 +93,6 @@ Rectangle {
         }
     }
 
-    Connections {
-        target: MessagesAdapter
-
-        function onSetChatViewMode(showInvitationPage,
-                                   isSwarm, needsSyncing,
-                                   title, convId) {
-            if (showInvitationPage)
-                root.mode = MessageWebView.Mode.Invitation
-            else {
-                root.mode = MessageWebView.Mode.Chat
-                return
-            }
-
-            invitationView.imageId = convId
-            invitationView.title = title
-            invitationView.needSyncing = needsSyncing
-        }
-    }
-
-    Connections {
-        target: ConversationsAdapter
-
-        function onCurrentConvIsReadOnlyChanged() {
-            var isVisible = !ConversationsAdapter.currentConvIsReadOnly
-            setMessagingHeaderButtonsVisible(isVisible)
-            messageWebViewFooter.visible = isVisible
-        }
-    }
-
     QtObject {
         id: jsBridgeObject
 
@@ -241,7 +194,7 @@ Rectangle {
             Layout.topMargin: JamiTheme.messageWebViewHairLineSize
             Layout.bottomMargin: JamiTheme.messageWebViewHairLineSize
 
-            currentIndex: root.mode
+            currentIndex: CurrentConversation.isRequest || CurrentConversation.needsSyncing
 
             GeneralWebEngineView {
                 id: messageWebView
@@ -307,6 +260,14 @@ Rectangle {
         MessageWebViewFooter {
             id: messageWebViewFooter
 
+            visible: {
+                if (CurrentConversation.needsSyncing || CurrentConversation.readOnly)
+                    return false
+                else if (CurrentConversation.isSwarm && CurrentConversation.isRequest)
+                    return false
+                return true
+            }
+
             Layout.alignment: Qt.AlignHCenter
             Layout.fillWidth: true
             Layout.preferredHeight: implicitHeight
diff --git a/src/mainview/components/MessageWebViewFooter.qml b/src/mainview/components/MessageWebViewFooter.qml
index 48821c80fd846b6ec10b2d50fa09c96723f08273..bdcd0c7e64c8be8d229a3b3931390f13c808c45a 100644
--- a/src/mainview/components/MessageWebViewFooter.qml
+++ b/src/mainview/components/MessageWebViewFooter.qml
@@ -82,18 +82,6 @@ Rectangle {
         function onNewTextPasted() {
             messageBar.textAreaObj.pasteText()
         }
-
-        function onSetChatViewMode(showInvitationPage,
-                                   isSwarm, needsSyncing,
-                                   title, convId, readOnly) {
-            var footerVisibility = showInvitationPage ?
-                        !isSwarm :
-                        !showInvitationPage
-            footerVisibility &= !readOnly
-            messageBar.visible = footerVisibility
-            dataTransferSendContainer.visible = footerVisibility
-            root.visible = footerVisibility
-        }
     }
 
     RecordBox{
diff --git a/src/mainview/components/MessageWebViewHeader.qml b/src/mainview/components/MessageWebViewHeader.qml
index 24751ae3d82a50be5171e40b7eb5f8b8e73d1df9..722ae858800bc6bf91a393f40dec9c9c42c19533 100644
--- a/src/mainview/components/MessageWebViewHeader.qml
+++ b/src/mainview/components/MessageWebViewHeader.qml
@@ -31,22 +31,22 @@ Rectangle {
 
     property string userAliasLabelText
     property string userUserNameLabelText
-    property string backToWelcomeViewButtonSource: JamiResources.back_24dp_svg
-    property alias sendContactRequestButtonVisible: sendContactRequestButton.visible
 
     signal backClicked
     signal needToHideConversationInCall
     signal pluginSelector
 
-    function resetBackToWelcomeViewButtonSource(reset) {
-        backToWelcomeViewButtonSource = reset ?
-                    JamiResources.back_24dp_svg :
-                    JamiResources.round_close_24dp_svg
-    }
-
-    function toggleMessagingHeaderButtonsVisible(visible) {
-        startAAudioCallButton.visible = visible
-        startAVideoCallButton.visible = visible
+    property bool callButtonsVisibility: {
+        if (CurrentConversation.inCall)
+            return false
+        if (CurrentConversation.isSwarm &&
+                CurrentConversation.readOnly)
+            return false
+        if (CurrentConversation.isSwarm &&
+                (CurrentConversation.isRequest ||
+                 CurrentConversation.needsSyncing))
+            return false
+        return true
     }
 
     color: JamiTheme.chatviewBgColor
@@ -64,18 +64,17 @@ Rectangle {
 
             preferredSize: 24
 
-            source: backToWelcomeViewButtonSource
+            source: CurrentConversation.inCall ?
+                        JamiResources.round_close_24dp_svg :
+                        JamiResources.back_24dp_svg
             toolTipText: JamiStrings.hideChatView
 
             normalColor: JamiTheme.chatviewBgColor
             imageColor: JamiTheme.chatviewButtonColor
 
-            onClicked: {
-                if (backToWelcomeViewButtonSource === JamiResources.back_24dp_svg)
-                    root.backClicked()
-                else
-                    root.needToHideConversationInCall()
-            }
+            onClicked: CurrentConversation.inCall ?
+                           root.needToHideConversationInCall() :
+                           root.backClicked()
         }
 
         Rectangle {
@@ -132,7 +131,7 @@ Rectangle {
             }
         }
 
-        Rectangle {
+        Item {
             id: buttonGroup
 
             Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
@@ -140,11 +139,11 @@ Rectangle {
             Layout.preferredHeight: childrenRect.height
             Layout.rightMargin: 8
 
-            color: "transparent"
-
             PushButton {
                 id: startAAudioCallButton
 
+                visible: callButtonsVisibility
+
                 anchors.right: startAVideoCallButton.left
                 anchors.rightMargin: 8
                 anchors.verticalCenter: buttonGroup.verticalCenter
@@ -155,17 +154,15 @@ Rectangle {
                 normalColor: JamiTheme.chatviewBgColor
                 imageColor: JamiTheme.chatviewButtonColor
 
-                onClicked: {
-                    MessagesAdapter.sendConversationRequest()
-                    CallAdapter.placeAudioOnlyCall()
-                    communicationPageMessageWebView.setSendContactRequestButtonVisible(false)
-                }
+                onClicked: CallAdapter.placeAudioOnlyCall()
             }
 
             PushButton {
                 id: startAVideoCallButton
 
-                anchors.right:  selectPluginButton.visible ? selectPluginButton.left :
+                visible: callButtonsVisibility
+
+                anchors.right: selectPluginButton.visible ? selectPluginButton.left :
                                    sendContactRequestButton.visible ?
                                    sendContactRequestButton.left :
                                    buttonGroup.right
@@ -178,11 +175,7 @@ Rectangle {
                 normalColor: JamiTheme.chatviewBgColor
                 imageColor: JamiTheme.chatviewButtonColor
 
-                onClicked: {
-                    MessagesAdapter.sendConversationRequest()
-                    CallAdapter.placeCall()
-                    communicationPageMessageWebView.setSendContactRequestButtonVisible(false)
-                }
+                onClicked: CallAdapter.placeCall()
             }
 
             PushButton {
@@ -208,6 +201,8 @@ Rectangle {
             PushButton {
                 id: sendContactRequestButton
 
+                visible: CurrentConversation.isTemporary
+
                 anchors.right: buttonGroup.right
                 anchors.rightMargin: 8
                 anchors.verticalCenter: buttonGroup.verticalCenter
@@ -218,10 +213,7 @@ Rectangle {
                 normalColor: JamiTheme.chatviewBgColor
                 imageColor: JamiTheme.chatviewButtonColor
 
-                onClicked: {
-                    MessagesAdapter.sendConversationRequest()
-                    visible = false
-                }
+                onClicked: MessagesAdapter.sendConversationRequest()
             }
         }
     }
diff --git a/src/mainview/components/OngoingCallPage.qml b/src/mainview/components/OngoingCallPage.qml
index b7f0b0cc6bedd67ee1dfad9caf2208426d2a69f1..2153100254a9afdc25ee218d213af4ec93a63a74 100644
--- a/src/mainview/components/OngoingCallPage.qml
+++ b/src/mainview/components/OngoingCallPage.qml
@@ -72,19 +72,11 @@ Rectangle {
     }
 
     function openInCallConversation() {
-        if (linkedWebview) {
-            linkedWebview.resetMessagingHeaderBackButtonSource(false)
-            linkedWebview.setMessagingHeaderButtonsVisible(false)
-        }
         inCallMessageWebViewStack.visible = true
         inCallMessageWebViewStack.push(linkedWebview)
     }
 
     function closeInCallConversation() {
-        if (linkedWebview) {
-            linkedWebview.resetMessagingHeaderBackButtonSource(true)
-            linkedWebview.setMessagingHeaderButtonsVisible(true)
-        }
         inCallMessageWebViewStack.visible = false
         inCallMessageWebViewStack.clear()
     }
diff --git a/src/mainview/components/SmartListItemDelegate.qml b/src/mainview/components/SmartListItemDelegate.qml
index 9aae5880ba470de151affdcf6506dcb4a2615cb2..1999a3d921148b36a2ba399d03f1cdf1c855626b 100644
--- a/src/mainview/components/SmartListItemDelegate.qml
+++ b/src/mainview/components/SmartListItemDelegate.qml
@@ -161,12 +161,10 @@ ItemDelegate {
         if (LRCInstance.currentAccountType === Profile.Type.SIP)
             CallAdapter.placeAudioOnlyCall()
         else {
-            if (!ConversationsAdapter.currentConvIsReadOnly) {
+            if (!CurrentConversation.readOnly) {
                 CallAdapter.placeCall()
             }
         }
-        // TODO: factor this out (visible should be observing)
-        communicationPageMessageWebView.setSendContactRequestButtonVisible(false)
     }
     onPressAndHold: ListView.view.openContextMenuAt(pressX, pressY, root)
 
diff --git a/src/messagesadapter.cpp b/src/messagesadapter.cpp
index 32b406607e0055b65e17c70865c23c1d35a82ee8..32d0416403628e085bbdba6dc792c88f38990091 100644
--- a/src/messagesadapter.cpp
+++ b/src/messagesadapter.cpp
@@ -59,29 +59,8 @@ MessagesAdapter::safeInit()
 void
 MessagesAdapter::setupChatView(const QVariantMap& convInfo)
 {
-    bool isLegacy = !convInfo["isSwarm"].toBool();
-    bool isRequest = convInfo["isRequest"].toBool();
-    bool needsSyncing = convInfo["needsSyncing"].toBool();
-    bool readOnly = convInfo["readOnly"].toBool();
-
-    QMetaObject::invokeMethod(qmlObj_,
-                              "setSendContactRequestButtonVisible",
-                              Q_ARG(QVariant, isLegacy && isRequest));
-    QMetaObject::invokeMethod(qmlObj_,
-                              "setMessagingHeaderButtonsVisible",
-                              Q_ARG(QVariant,
-                                    !readOnly && !(isLegacy && (isRequest || needsSyncing))));
-
-    setMessagesVisibility(false);
-    setIsSwarm(!isLegacy);
-    Q_EMIT setChatViewMode(isRequest || needsSyncing,
-                           isLegacy,
-                           needsSyncing,
-                           convInfo["title"].toString(),
-                           convInfo["convId"].toString(),
-                           readOnly);
-
     Utils::oneShotConnect(qmlObj_, SIGNAL(messagesCleared()), this, SLOT(slotMessagesCleared()));
+    setMessagesVisibility(false);
     clearChatView();
 
     Q_EMIT newMessageBarPlaceholderText(convInfo["title"].toString());
@@ -181,12 +160,6 @@ MessagesAdapter::connectConversationModel()
                      &MessagesAdapter::updateConversation,
                      Qt::UniqueConnection);
 
-    QObject::connect(currentConversationModel,
-                     &ConversationModel::needsSyncingSet,
-                     this,
-                     &MessagesAdapter::updateConversation,
-                     Qt::UniqueConnection);
-
     QObject::connect(currentConversationModel,
                      &ConversationModel::composingStatusChanged,
                      this,
@@ -354,53 +327,21 @@ MessagesAdapter::userIsComposing(bool isComposing)
 }
 
 void
-MessagesAdapter::setConversationProfileData(const lrc::api::conversation::Info& convInfo)
+MessagesAdapter::setConversationProfileData(const conversation::Info& convInfo)
 {
-    auto accInfo = &lrcInstance_->getCurrentAccountInfo();
-
+    auto& accInfo = lrcInstance_->getCurrentAccountInfo();
     if (convInfo.participants.isEmpty()) {
         return;
     }
 
-    auto contactUri = convInfo.participants.front();
-    if (contactUri.isEmpty()) {
-        return;
-    }
-    try {
-        auto title = accInfo->conversationModel->title(convInfo.uid);
-        QMetaObject::invokeMethod(qmlObj_,
-                                  "setMessagingHeaderButtonsVisible",
-                                  Q_ARG(QVariant,
-                                        !convInfo.readOnly
-                                            && !(convInfo.isSwarm()
-                                                 && (convInfo.isRequest || convInfo.needsSyncing))));
-
-        Q_EMIT setChatViewMode(convInfo.isRequest || convInfo.needsSyncing,
-                               convInfo.isSwarm(),
-                               convInfo.needsSyncing,
-                               title,
-                               convInfo.uid,
-                               convInfo.readOnly);
-        if (convInfo.isSwarm())
-            return;
+    auto title = accInfo.conversationModel->title(convInfo.uid);
 
-        // TODO: swarmify me
-        auto& contact = accInfo->contactModel->getContact(contactUri);
-        bool isPending = contact.profileInfo.type == profile::Type::TEMPORARY;
-        QMetaObject::invokeMethod(qmlObj_,
-                                  "setSendContactRequestButtonVisible",
-                                  Q_ARG(QVariant, isPending));
-        if (!contact.profileInfo.avatar.isEmpty()) {
-            setSenderImage(contactUri, contact.profileInfo.avatar);
-        } else {
-            auto avatar = Utils::contactPhoto(lrcInstance_, convInfo.participants[0]);
-            QByteArray ba;
-            QBuffer bu(&ba);
-            avatar.save(&bu, "PNG");
-            setSenderImage(contactUri, QString::fromLocal8Bit(ba.toBase64()));
-        }
-    } catch (...) {
-    }
+    // make the conversation avatar available within the web view
+    auto avatar = Utils::conversationAvatar(lrcInstance_, convInfo.uid);
+    QByteArray ba;
+    QBuffer bu(&ba);
+    avatar.save(&bu, "PNG");
+    setSenderImage(title, QString::fromLocal8Bit(ba.toBase64()));
 }
 
 void
@@ -433,13 +374,6 @@ MessagesAdapter::setMessagesVisibility(bool visible)
     QMetaObject::invokeMethod(qmlObj_, "webViewRunJavaScript", Q_ARG(QVariant, s));
 }
 
-void
-MessagesAdapter::setIsSwarm(bool isSwarm)
-{
-    QString s = QString::fromLatin1("set_is_swarm(%1)").arg(isSwarm);
-    QMetaObject::invokeMethod(qmlObj_, "webViewRunJavaScript", Q_ARG(QVariant, s));
-}
-
 void
 MessagesAdapter::clearChatView()
 {
@@ -462,15 +396,12 @@ MessagesAdapter::updateHistory(lrc::api::ConversationModel& conversationModel,
                                bool allLoaded)
 {
     auto conversationId = lrcInstance_->get_selectedConvUid();
-    auto interactionsStr = interactionsToJsonArrayObject(conversationModel,
-                                                         conversationId,
-                                                         interactions)
-                               .toUtf8();
+    auto interactionsStr
+        = interactionsToJsonArrayObject(conversationModel, conversationId, interactions).toUtf8();
     QString s = QString::fromLatin1("updateHistory(%1, %2);")
                     .arg(interactionsStr.constData())
                     .arg(allLoaded);
     QMetaObject::invokeMethod(qmlObj_, "webViewRunJavaScript", Q_ARG(QVariant, s));
-    auto* convModel = lrcInstance_->getCurrentConversationModel();
     conversationModel.clearUnreadInteractions(conversationId);
 }
 
@@ -588,7 +519,6 @@ MessagesAdapter::refuseInvitation(const QString& convUid)
 {
     const auto currentConvUid = convUid.isEmpty() ? lrcInstance_->get_selectedConvUid() : convUid;
     lrcInstance_->getCurrentConversationModel()->removeConversation(currentConvUid, false);
-    Q_EMIT setChatViewMode(false);
 }
 
 void
@@ -596,7 +526,6 @@ MessagesAdapter::blockConversation(const QString& convUid)
 {
     const auto currentConvUid = convUid.isEmpty() ? lrcInstance_->get_selectedConvUid() : convUid;
     lrcInstance_->getCurrentConversationModel()->removeConversation(currentConvUid, true);
-    Q_EMIT setChatViewMode(false);
 }
 
 void
diff --git a/src/messagesadapter.h b/src/messagesadapter.h
index 06c674de741dffe9e70633014a2047b3ad7a1f49..2b27a3620af9b864ccdddafcf8c640e50cda0cbb 100644
--- a/src/messagesadapter.h
+++ b/src/messagesadapter.h
@@ -69,7 +69,6 @@ protected:
 
     // Run corrsponding js functions, c++ to qml.
     void setMessagesVisibility(bool visible);
-    void setIsSwarm(bool isSwarm);
     void clearChatView();
     void updateHistory(ConversationModel& conversationModel,
                        MessagesList interactions,
@@ -92,12 +91,6 @@ Q_SIGNALS:
     void newMessageBarPlaceholderText(QString placeholderText);
     void newFilePasted(QString filePath);
     void newTextPasted();
-    void setChatViewMode(bool showInvitationPage,
-                         bool isSwarm = false,
-                         bool needsSyncing = false,
-                         QString contactTitle = {},
-                         QString contactUri = {},
-                         bool readOnly = false);
 
 private Q_SLOTS:
     void slotMessagesCleared();