diff --git a/qml.qrc b/qml.qrc
index 42a243ac..e7ab3be1 100644
--- a/qml.qrc
+++ b/qml.qrc
@@ -168,7 +168,7 @@
src/app/commoncomponents/BubbleLabel.qml
src/app/commoncomponents/BackButton.qml
src/app/commoncomponents/JamiSwitch.qml
- src/app/mainview/components/ReadOnlyFooter.qml
+ src/app/mainview/components/UpdateToSwarm.qml
src/app/commoncomponents/TextMessageDelegate.qml
src/app/mainview/components/MessageListView.qml
src/app/commoncomponents/MessageBubble.qml
diff --git a/src/app/constant/JamiStrings.qml b/src/app/constant/JamiStrings.qml
index ad830bc8..9169e967 100644
--- a/src/app/constant/JamiStrings.qml
+++ b/src/app/constant/JamiStrings.qml
@@ -41,8 +41,8 @@ Item {
property string contactSearchInvitations: qsTr("Search your invitations")
property string invitations: qsTr("Invitations")
property string description: qsTr("Jami is a universal communication platform, with privacy as its foundation, that relies on a free distributed network for everyone.")
- property string contactLeft: qsTr("You are viewing a conversation where all participants other than you have left. New interactions will not be possible.")
- property string newConversation: qsTr("Start new conversation")
+ property string updateToSwarm: qsTr("Migrating to the Swarm technology will enable syncing this conversation across multiple devices and improve reliability. The legacy conversation history will be cleared in the process.")
+ property string migrateConversation: qsTr("Migrate conversation")
// DaemonReconnectWindow
property string reconnectWarn: qsTr("Could not re-connect to the Jami daemon (jamid).\nJami will now quit.")
diff --git a/src/app/conversationlistmodelbase.cpp b/src/app/conversationlistmodelbase.cpp
index 13d69e04..827c84bd 100644
--- a/src/app/conversationlistmodelbase.cpp
+++ b/src/app/conversationlistmodelbase.cpp
@@ -147,8 +147,6 @@ ConversationListModelBase::dataForItem(item_t item, int role) const
}
return ret;
}
- case Role::ReadOnly:
- return QVariant(item.readOnly);
case Role::Presence: {
// The conversation can show a green dot if at least one peer is present
Q_FOREACH (const auto& peerUri, model_->peersForConversation(item.uid))
diff --git a/src/app/conversationlistmodelbase.h b/src/app/conversationlistmodelbase.h
index 37a2300e..f22e1c92 100644
--- a/src/app/conversationlistmodelbase.h
+++ b/src/app/conversationlistmodelbase.h
@@ -48,8 +48,7 @@
X(IsRequest) \
X(Mode) \
X(Uris) \
- X(Monikers) \
- X(ReadOnly)
+ X(Monikers)
namespace ConversationList {
Q_NAMESPACE
diff --git a/src/app/conversationsadapter.cpp b/src/app/conversationsadapter.cpp
index de792930..5a50608d 100644
--- a/src/app/conversationsadapter.cpp
+++ b/src/app/conversationsadapter.cpp
@@ -438,18 +438,15 @@ ConversationsAdapter::getConvInfoMap(const QString& convId)
{"needsSyncing", convInfo.needsSyncing},
{"isAudioOnly", isAudioOnly},
{"callState", static_cast(callState)},
- {"callStackViewShouldShow", callStackViewShouldShow},
- {"readOnly", convInfo.readOnly}};
+ {"callStackViewShouldShow", callStackViewShouldShow}};
}
void
ConversationsAdapter::restartConversation(const QString& convId)
{
- // make sure this conversation meets the criteria of a "restartable" conv
- // 'readOnly' implies 'isSwarm'
auto& accInfo = lrcInstance_->getCurrentAccountInfo();
const auto& convInfo = lrcInstance_->getConversationFromConvUid(convId);
- if (convInfo.uid.isEmpty() || !convInfo.isCoreDialog() || !convInfo.readOnly) {
+ if (convInfo.uid.isEmpty() || !convInfo.isCoreDialog()) {
return;
}
@@ -474,7 +471,7 @@ ConversationsAdapter::restartConversation(const QString& convId)
[this, peerUri, &accInfo](const QString& convId) {
const auto& convInfo = lrcInstance_->getConversationFromConvUid(convId);
// 3. filter for the correct contact-conversation and select it
- if (!convInfo.uid.isEmpty() && convInfo.isCoreDialog() && !convInfo.readOnly
+ if (!convInfo.uid.isEmpty() && convInfo.isCoreDialog()
&& peerUri
== accInfo.conversationModel->peersForConversation(convId).at(0)) {
lrcInstance_->selectConversation(convId);
diff --git a/src/app/currentconversation.cpp b/src/app/currentconversation.cpp
index b27f9797..1ccda9c0 100644
--- a/src/app/currentconversation.cpp
+++ b/src/app/currentconversation.cpp
@@ -57,7 +57,6 @@ CurrentConversation::updateData()
set_isLegacy(convInfo.isLegacy());
set_isCoreDialog(convInfo.isCoreDialog());
set_isRequest(convInfo.isRequest);
- set_readOnly(convInfo.readOnly);
set_needsSyncing(convInfo.needsSyncing);
set_color(Utils::getAvatarColor(convId).name());
set_isSip(accInfo.profileInfo.type == profile::Type::SIP);
diff --git a/src/app/currentconversation.h b/src/app/currentconversation.h
index 99731795..72de66ed 100644
--- a/src/app/currentconversation.h
+++ b/src/app/currentconversation.h
@@ -37,7 +37,6 @@ class CurrentConversation final : public QObject
QML_PROPERTY(bool, isLegacy)
QML_PROPERTY(bool, isCoreDialog)
QML_PROPERTY(bool, isRequest)
- QML_PROPERTY(bool, readOnly)
QML_PROPERTY(bool, needsSyncing)
QML_PROPERTY(bool, isSip)
QML_PROPERTY(bool, isBanned)
diff --git a/src/app/mainview/components/ChatView.qml b/src/app/mainview/components/ChatView.qml
index 3159a74c..ce292076 100644
--- a/src/app/mainview/components/ChatView.qml
+++ b/src/app/mainview/components/ChatView.qml
@@ -160,8 +160,8 @@ Rectangle {
}
}
- ReadOnlyFooter {
- visible: CurrentConversation.readOnly
+ UpdateToSwarm {
+ visible: !CurrentConversation.isSwarm && !CurrentConversation.isTemporary
Layout.fillWidth: true
}
@@ -171,11 +171,11 @@ Rectangle {
visible: {
if (CurrentConversation.isBlocked)
return false
- else if (CurrentConversation.needsSyncing || CurrentConversation.readOnly)
+ else if (CurrentConversation.needsSyncing)
return false
else if (CurrentConversation.isSwarm && CurrentConversation.isRequest)
return false
- return true
+ return CurrentConversation.isSwarm || CurrentConversation.isTemporary
}
Layout.alignment: Qt.AlignHCenter
diff --git a/src/app/mainview/components/ChatViewHeader.qml b/src/app/mainview/components/ChatViewHeader.qml
index c63d39bb..9c0f9d9f 100644
--- a/src/app/mainview/components/ChatViewHeader.qml
+++ b/src/app/mainview/components/ChatViewHeader.qml
@@ -46,12 +46,9 @@ Rectangle {
property bool interactionButtonsVisibility: {
if (CurrentConversation.inCall)
return false
- if (CurrentConversation.isSwarm &&
- CurrentConversation.readOnly)
+ if (!CurrentConversation.isTemporary && !CurrentConversation.isSwarm)
return false
- if (CurrentConversation.isSwarm &&
- (CurrentConversation.isRequest ||
- CurrentConversation.needsSyncing))
+ if (CurrentConversation.isRequest || CurrentConversation.needsSyncing)
return false
return true
}
diff --git a/src/app/mainview/components/ConversationListView.qml b/src/app/mainview/components/ConversationListView.qml
index b2eeac5c..6433a9bf 100644
--- a/src/app/mainview/components/ConversationListView.qml
+++ b/src/app/mainview/components/ConversationListView.qml
@@ -133,7 +133,7 @@ JamiListView {
"isSwarm": model.dataForRow(row, ConversationList.IsSwarm),
"isBanned": model.dataForRow(row, ConversationList.IsBanned),
"mode": model.dataForRow(row, ConversationList.Mode),
- "readOnly": model.dataForRow(row, ConversationList.ReadOnly)
+ "isTemporary": model.dataForRow(row, ConversationList.ContactType) === Profile.Type.TEMPORARY,
}
responsibleAccountId = LRCInstance.currentAccountId
@@ -142,7 +142,7 @@ JamiListView {
isBanned = item.isBanned
mode = item.mode
contactType = LRCInstance.currentAccountType
- readOnly = item.readOnly
+ readOnly = mode === Conversation.Mode.NON_SWARM && !item.isTemporary
if (model.dataForRow(row, ConversationList.IsCoreDialog)) {
userProfile.aliasText = item.title
diff --git a/src/app/mainview/components/SmartListItemDelegate.qml b/src/app/mainview/components/SmartListItemDelegate.qml
index 39b65731..56361058 100644
--- a/src/app/mainview/components/SmartListItemDelegate.qml
+++ b/src/app/mainview/components/SmartListItemDelegate.qml
@@ -168,13 +168,6 @@ ItemDelegate {
}
}
- // read-only conversation indicator
- ResponsiveImage {
- visible: ReadOnly
- source: JamiResources.lock_black_24dp_svg
- color: JamiTheme.primaryForegroundColor
- }
-
// Draft indicator
ResponsiveImage {
visible: Draft && !root.highlighted
diff --git a/src/app/mainview/components/ReadOnlyFooter.qml b/src/app/mainview/components/UpdateToSwarm.qml
similarity index 93%
rename from src/app/mainview/components/ReadOnlyFooter.qml
rename to src/app/mainview/components/UpdateToSwarm.qml
index e639dfb5..d43b0cc3 100644
--- a/src/app/mainview/components/ReadOnlyFooter.qml
+++ b/src/app/mainview/components/UpdateToSwarm.qml
@@ -46,7 +46,7 @@ Control {
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
Layout.fillWidth: true
- text: JamiStrings.contactLeft
+ text: JamiStrings.updateToSwarm
font.pointSize: JamiTheme.textFontSize + 2
color: JamiTheme.textColor
wrapMode: Text.Wrap
@@ -60,6 +60,7 @@ Control {
MaterialButton {
text: JamiStrings.removeContact
+ padding: 8
autoAccelerator: true
font.pointSize: JamiTheme.textFontSize + 2
onClicked: MessagesAdapter.removeContact(
@@ -67,7 +68,8 @@ Control {
}
MaterialButton {
- text: JamiStrings.newConversation
+ text: JamiStrings.migrateConversation
+ padding: 8
autoAccelerator: true
font.pointSize: JamiTheme.textFontSize + 2
onClicked: ConversationsAdapter.restartConversation(
diff --git a/src/libclient/api/conversation.h b/src/libclient/api/conversation.h
index 4608b201..086fe5ff 100644
--- a/src/libclient/api/conversation.h
+++ b/src/libclient/api/conversation.h
@@ -82,13 +82,25 @@ struct Info
MapStringString infos {};
- QString getCallId() const { return confId.isEmpty() ? callId : confId; }
+ QString getCallId() const
+ {
+ return confId.isEmpty() ? callId : confId;
+ }
- inline bool isLegacy() const { return mode == Mode::NON_SWARM; }
- inline bool isSwarm() const { return !isLegacy(); }
+ inline bool isLegacy() const
+ {
+ return mode == Mode::NON_SWARM;
+ }
+ inline bool isSwarm() const
+ {
+ return !isLegacy();
+ }
// for each contact we must have one non-swarm conversation or one active one-to-one
// conversation. Where active means peer did not leave the conversation.
- inline bool isCoreDialog() const { return isLegacy() || mode == Mode::ONE_TO_ONE; };
+ inline bool isCoreDialog() const
+ {
+ return isLegacy() || mode == Mode::ONE_TO_ONE;
+ };
inline QStringList participantsUris() const
{
@@ -101,7 +113,6 @@ struct Info
Mode mode = Mode::NON_SWARM;
bool needsSyncing = false;
bool isRequest = false;
- bool readOnly = false;
};
} // namespace conversation
diff --git a/src/libclient/conversationmodel.cpp b/src/libclient/conversationmodel.cpp
index 1cacfaf7..89a0bc4c 100644
--- a/src/libclient/conversationmodel.cpp
+++ b/src/libclient/conversationmodel.cpp
@@ -112,10 +112,9 @@ public:
* return a vector of conversation indices for the given contact uri empty
* if no index is found
* @param uri of the contact to search
- * @param writable whether or not to exclude read-only conversations(use for interactions)
* @return an vector of indices
*/
- std::vector getIndicesForContact(const QString& uri, bool writable = false) const;
+ std::vector getIndicesForContact(const QString& uri) const;
/**
* Initialize conversations_ and filteredConversations_
*/
@@ -2657,7 +2656,6 @@ ConversationModelPimpl::slotConversationMemberEvent(const QString& accountId,
membersRemaining.append(member["uri"]);
}
conversation.participants = participants;
- conversation.readOnly = membersRemaining == VectorString(1, linked.owner.profileInfo.uri);
invalidateModel();
Q_EMIT linked.modelChanged();
Q_EMIT linked.conversationUpdated(conversationId);
@@ -2938,7 +2936,6 @@ ConversationModelPimpl::addSwarmConversation(const QString& convId)
if (member["role"] == "left")
membersLeft.append(member["uri"]);
}
- conversation.readOnly = mode == conversation::Mode::ONE_TO_ONE && membersLeft.size() == 1;
conversation.participants = participants;
conversation.mode = mode;
conversation.unreadMessages = ConfigurationManager::instance().countInteractions(linked.owner.id,
@@ -3097,12 +3094,12 @@ ConversationModelPimpl::getConversationForPeerUri(const QString& uri,
}
std::vector
-ConversationModelPimpl::getIndicesForContact(const QString& uri, bool writable) const
+ConversationModelPimpl::getIndicesForContact(const QString& uri) const
{
std::vector ret;
for (unsigned int i = 0; i < conversations.size(); ++i) {
const auto& convInfo = conversations.at(i);
- if (!convInfo.isCoreDialog() || (writable && convInfo.readOnly)) {
+ if (!convInfo.isCoreDialog()) {
continue;
}
auto peers = peersForConversation(convInfo);