mirror of
https://git.jami.net/savoirfairelinux/jami-client-qt.git
synced 2025-08-22 15:54:00 +02:00
swarm: transform non swarm to swarm conversations
+ Remove readOnly from conversation's as it was never used and not necessary in multi swarm as you can re-add members anyway so it's never read only. + Makes non swarm conversations just readable. Users can save whatever they want and replace old non migrated conversations to new swarm. Change-Id: I8aa2521bc524b6159d7ba0b613834438e293e09e
This commit is contained in:
parent
216f10b6de
commit
1881ffb45f
14 changed files with 38 additions and 46 deletions
2
qml.qrc
2
qml.qrc
|
@ -168,7 +168,7 @@
|
||||||
<file>src/app/commoncomponents/BubbleLabel.qml</file>
|
<file>src/app/commoncomponents/BubbleLabel.qml</file>
|
||||||
<file>src/app/commoncomponents/BackButton.qml</file>
|
<file>src/app/commoncomponents/BackButton.qml</file>
|
||||||
<file>src/app/commoncomponents/JamiSwitch.qml</file>
|
<file>src/app/commoncomponents/JamiSwitch.qml</file>
|
||||||
<file>src/app/mainview/components/ReadOnlyFooter.qml</file>
|
<file>src/app/mainview/components/UpdateToSwarm.qml</file>
|
||||||
<file>src/app/commoncomponents/TextMessageDelegate.qml</file>
|
<file>src/app/commoncomponents/TextMessageDelegate.qml</file>
|
||||||
<file>src/app/mainview/components/MessageListView.qml</file>
|
<file>src/app/mainview/components/MessageListView.qml</file>
|
||||||
<file>src/app/commoncomponents/MessageBubble.qml</file>
|
<file>src/app/commoncomponents/MessageBubble.qml</file>
|
||||||
|
|
|
@ -41,8 +41,8 @@ Item {
|
||||||
property string contactSearchInvitations: qsTr("Search your invitations")
|
property string contactSearchInvitations: qsTr("Search your invitations")
|
||||||
property string invitations: qsTr("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 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 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 newConversation: qsTr("Start new conversation")
|
property string migrateConversation: qsTr("Migrate conversation")
|
||||||
|
|
||||||
// DaemonReconnectWindow
|
// DaemonReconnectWindow
|
||||||
property string reconnectWarn: qsTr("Could not re-connect to the Jami daemon (jamid).\nJami will now quit.")
|
property string reconnectWarn: qsTr("Could not re-connect to the Jami daemon (jamid).\nJami will now quit.")
|
||||||
|
|
|
@ -147,8 +147,6 @@ ConversationListModelBase::dataForItem(item_t item, int role) const
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
case Role::ReadOnly:
|
|
||||||
return QVariant(item.readOnly);
|
|
||||||
case Role::Presence: {
|
case Role::Presence: {
|
||||||
// The conversation can show a green dot if at least one peer is present
|
// The conversation can show a green dot if at least one peer is present
|
||||||
Q_FOREACH (const auto& peerUri, model_->peersForConversation(item.uid))
|
Q_FOREACH (const auto& peerUri, model_->peersForConversation(item.uid))
|
||||||
|
|
|
@ -48,8 +48,7 @@
|
||||||
X(IsRequest) \
|
X(IsRequest) \
|
||||||
X(Mode) \
|
X(Mode) \
|
||||||
X(Uris) \
|
X(Uris) \
|
||||||
X(Monikers) \
|
X(Monikers)
|
||||||
X(ReadOnly)
|
|
||||||
|
|
||||||
namespace ConversationList {
|
namespace ConversationList {
|
||||||
Q_NAMESPACE
|
Q_NAMESPACE
|
||||||
|
|
|
@ -438,18 +438,15 @@ ConversationsAdapter::getConvInfoMap(const QString& convId)
|
||||||
{"needsSyncing", convInfo.needsSyncing},
|
{"needsSyncing", convInfo.needsSyncing},
|
||||||
{"isAudioOnly", isAudioOnly},
|
{"isAudioOnly", isAudioOnly},
|
||||||
{"callState", static_cast<int>(callState)},
|
{"callState", static_cast<int>(callState)},
|
||||||
{"callStackViewShouldShow", callStackViewShouldShow},
|
{"callStackViewShouldShow", callStackViewShouldShow}};
|
||||||
{"readOnly", convInfo.readOnly}};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ConversationsAdapter::restartConversation(const QString& convId)
|
ConversationsAdapter::restartConversation(const QString& convId)
|
||||||
{
|
{
|
||||||
// make sure this conversation meets the criteria of a "restartable" conv
|
|
||||||
// 'readOnly' implies 'isSwarm'
|
|
||||||
auto& accInfo = lrcInstance_->getCurrentAccountInfo();
|
auto& accInfo = lrcInstance_->getCurrentAccountInfo();
|
||||||
const auto& convInfo = lrcInstance_->getConversationFromConvUid(convId);
|
const auto& convInfo = lrcInstance_->getConversationFromConvUid(convId);
|
||||||
if (convInfo.uid.isEmpty() || !convInfo.isCoreDialog() || !convInfo.readOnly) {
|
if (convInfo.uid.isEmpty() || !convInfo.isCoreDialog()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -474,7 +471,7 @@ ConversationsAdapter::restartConversation(const QString& convId)
|
||||||
[this, peerUri, &accInfo](const QString& convId) {
|
[this, peerUri, &accInfo](const QString& convId) {
|
||||||
const auto& convInfo = lrcInstance_->getConversationFromConvUid(convId);
|
const auto& convInfo = lrcInstance_->getConversationFromConvUid(convId);
|
||||||
// 3. filter for the correct contact-conversation and select it
|
// 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
|
&& peerUri
|
||||||
== accInfo.conversationModel->peersForConversation(convId).at(0)) {
|
== accInfo.conversationModel->peersForConversation(convId).at(0)) {
|
||||||
lrcInstance_->selectConversation(convId);
|
lrcInstance_->selectConversation(convId);
|
||||||
|
|
|
@ -57,7 +57,6 @@ CurrentConversation::updateData()
|
||||||
set_isLegacy(convInfo.isLegacy());
|
set_isLegacy(convInfo.isLegacy());
|
||||||
set_isCoreDialog(convInfo.isCoreDialog());
|
set_isCoreDialog(convInfo.isCoreDialog());
|
||||||
set_isRequest(convInfo.isRequest);
|
set_isRequest(convInfo.isRequest);
|
||||||
set_readOnly(convInfo.readOnly);
|
|
||||||
set_needsSyncing(convInfo.needsSyncing);
|
set_needsSyncing(convInfo.needsSyncing);
|
||||||
set_color(Utils::getAvatarColor(convId).name());
|
set_color(Utils::getAvatarColor(convId).name());
|
||||||
set_isSip(accInfo.profileInfo.type == profile::Type::SIP);
|
set_isSip(accInfo.profileInfo.type == profile::Type::SIP);
|
||||||
|
|
|
@ -37,7 +37,6 @@ class CurrentConversation final : public QObject
|
||||||
QML_PROPERTY(bool, isLegacy)
|
QML_PROPERTY(bool, isLegacy)
|
||||||
QML_PROPERTY(bool, isCoreDialog)
|
QML_PROPERTY(bool, isCoreDialog)
|
||||||
QML_PROPERTY(bool, isRequest)
|
QML_PROPERTY(bool, isRequest)
|
||||||
QML_PROPERTY(bool, readOnly)
|
|
||||||
QML_PROPERTY(bool, needsSyncing)
|
QML_PROPERTY(bool, needsSyncing)
|
||||||
QML_PROPERTY(bool, isSip)
|
QML_PROPERTY(bool, isSip)
|
||||||
QML_PROPERTY(bool, isBanned)
|
QML_PROPERTY(bool, isBanned)
|
||||||
|
|
|
@ -160,8 +160,8 @@ Rectangle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ReadOnlyFooter {
|
UpdateToSwarm {
|
||||||
visible: CurrentConversation.readOnly
|
visible: !CurrentConversation.isSwarm && !CurrentConversation.isTemporary
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,11 +171,11 @@ Rectangle {
|
||||||
visible: {
|
visible: {
|
||||||
if (CurrentConversation.isBlocked)
|
if (CurrentConversation.isBlocked)
|
||||||
return false
|
return false
|
||||||
else if (CurrentConversation.needsSyncing || CurrentConversation.readOnly)
|
else if (CurrentConversation.needsSyncing)
|
||||||
return false
|
return false
|
||||||
else if (CurrentConversation.isSwarm && CurrentConversation.isRequest)
|
else if (CurrentConversation.isSwarm && CurrentConversation.isRequest)
|
||||||
return false
|
return false
|
||||||
return true
|
return CurrentConversation.isSwarm || CurrentConversation.isTemporary
|
||||||
}
|
}
|
||||||
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
|
|
@ -46,12 +46,9 @@ Rectangle {
|
||||||
property bool interactionButtonsVisibility: {
|
property bool interactionButtonsVisibility: {
|
||||||
if (CurrentConversation.inCall)
|
if (CurrentConversation.inCall)
|
||||||
return false
|
return false
|
||||||
if (CurrentConversation.isSwarm &&
|
if (!CurrentConversation.isTemporary && !CurrentConversation.isSwarm)
|
||||||
CurrentConversation.readOnly)
|
|
||||||
return false
|
return false
|
||||||
if (CurrentConversation.isSwarm &&
|
if (CurrentConversation.isRequest || CurrentConversation.needsSyncing)
|
||||||
(CurrentConversation.isRequest ||
|
|
||||||
CurrentConversation.needsSyncing))
|
|
||||||
return false
|
return false
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
|
@ -133,7 +133,7 @@ JamiListView {
|
||||||
"isSwarm": model.dataForRow(row, ConversationList.IsSwarm),
|
"isSwarm": model.dataForRow(row, ConversationList.IsSwarm),
|
||||||
"isBanned": model.dataForRow(row, ConversationList.IsBanned),
|
"isBanned": model.dataForRow(row, ConversationList.IsBanned),
|
||||||
"mode": model.dataForRow(row, ConversationList.Mode),
|
"mode": model.dataForRow(row, ConversationList.Mode),
|
||||||
"readOnly": model.dataForRow(row, ConversationList.ReadOnly)
|
"isTemporary": model.dataForRow(row, ConversationList.ContactType) === Profile.Type.TEMPORARY,
|
||||||
}
|
}
|
||||||
|
|
||||||
responsibleAccountId = LRCInstance.currentAccountId
|
responsibleAccountId = LRCInstance.currentAccountId
|
||||||
|
@ -142,7 +142,7 @@ JamiListView {
|
||||||
isBanned = item.isBanned
|
isBanned = item.isBanned
|
||||||
mode = item.mode
|
mode = item.mode
|
||||||
contactType = LRCInstance.currentAccountType
|
contactType = LRCInstance.currentAccountType
|
||||||
readOnly = item.readOnly
|
readOnly = mode === Conversation.Mode.NON_SWARM && !item.isTemporary
|
||||||
|
|
||||||
if (model.dataForRow(row, ConversationList.IsCoreDialog)) {
|
if (model.dataForRow(row, ConversationList.IsCoreDialog)) {
|
||||||
userProfile.aliasText = item.title
|
userProfile.aliasText = item.title
|
||||||
|
|
|
@ -168,13 +168,6 @@ ItemDelegate {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// read-only conversation indicator
|
|
||||||
ResponsiveImage {
|
|
||||||
visible: ReadOnly
|
|
||||||
source: JamiResources.lock_black_24dp_svg
|
|
||||||
color: JamiTheme.primaryForegroundColor
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draft indicator
|
// Draft indicator
|
||||||
ResponsiveImage {
|
ResponsiveImage {
|
||||||
visible: Draft && !root.highlighted
|
visible: Draft && !root.highlighted
|
||||||
|
|
|
@ -46,7 +46,7 @@ Control {
|
||||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
text: JamiStrings.contactLeft
|
text: JamiStrings.updateToSwarm
|
||||||
font.pointSize: JamiTheme.textFontSize + 2
|
font.pointSize: JamiTheme.textFontSize + 2
|
||||||
color: JamiTheme.textColor
|
color: JamiTheme.textColor
|
||||||
wrapMode: Text.Wrap
|
wrapMode: Text.Wrap
|
||||||
|
@ -60,6 +60,7 @@ Control {
|
||||||
|
|
||||||
MaterialButton {
|
MaterialButton {
|
||||||
text: JamiStrings.removeContact
|
text: JamiStrings.removeContact
|
||||||
|
padding: 8
|
||||||
autoAccelerator: true
|
autoAccelerator: true
|
||||||
font.pointSize: JamiTheme.textFontSize + 2
|
font.pointSize: JamiTheme.textFontSize + 2
|
||||||
onClicked: MessagesAdapter.removeContact(
|
onClicked: MessagesAdapter.removeContact(
|
||||||
|
@ -67,7 +68,8 @@ Control {
|
||||||
}
|
}
|
||||||
|
|
||||||
MaterialButton {
|
MaterialButton {
|
||||||
text: JamiStrings.newConversation
|
text: JamiStrings.migrateConversation
|
||||||
|
padding: 8
|
||||||
autoAccelerator: true
|
autoAccelerator: true
|
||||||
font.pointSize: JamiTheme.textFontSize + 2
|
font.pointSize: JamiTheme.textFontSize + 2
|
||||||
onClicked: ConversationsAdapter.restartConversation(
|
onClicked: ConversationsAdapter.restartConversation(
|
|
@ -82,13 +82,25 @@ struct Info
|
||||||
|
|
||||||
MapStringString infos {};
|
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 isLegacy() const
|
||||||
inline bool isSwarm() const { return !isLegacy(); }
|
{
|
||||||
|
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
|
// 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.
|
// 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
|
inline QStringList participantsUris() const
|
||||||
{
|
{
|
||||||
|
@ -101,7 +113,6 @@ struct Info
|
||||||
Mode mode = Mode::NON_SWARM;
|
Mode mode = Mode::NON_SWARM;
|
||||||
bool needsSyncing = false;
|
bool needsSyncing = false;
|
||||||
bool isRequest = false;
|
bool isRequest = false;
|
||||||
bool readOnly = false;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace conversation
|
} // namespace conversation
|
||||||
|
|
|
@ -112,10 +112,9 @@ public:
|
||||||
* return a vector of conversation indices for the given contact uri empty
|
* return a vector of conversation indices for the given contact uri empty
|
||||||
* if no index is found
|
* if no index is found
|
||||||
* @param uri of the contact to search
|
* @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
|
* @return an vector of indices
|
||||||
*/
|
*/
|
||||||
std::vector<int> getIndicesForContact(const QString& uri, bool writable = false) const;
|
std::vector<int> getIndicesForContact(const QString& uri) const;
|
||||||
/**
|
/**
|
||||||
* Initialize conversations_ and filteredConversations_
|
* Initialize conversations_ and filteredConversations_
|
||||||
*/
|
*/
|
||||||
|
@ -2657,7 +2656,6 @@ ConversationModelPimpl::slotConversationMemberEvent(const QString& accountId,
|
||||||
membersRemaining.append(member["uri"]);
|
membersRemaining.append(member["uri"]);
|
||||||
}
|
}
|
||||||
conversation.participants = participants;
|
conversation.participants = participants;
|
||||||
conversation.readOnly = membersRemaining == VectorString(1, linked.owner.profileInfo.uri);
|
|
||||||
invalidateModel();
|
invalidateModel();
|
||||||
Q_EMIT linked.modelChanged();
|
Q_EMIT linked.modelChanged();
|
||||||
Q_EMIT linked.conversationUpdated(conversationId);
|
Q_EMIT linked.conversationUpdated(conversationId);
|
||||||
|
@ -2938,7 +2936,6 @@ ConversationModelPimpl::addSwarmConversation(const QString& convId)
|
||||||
if (member["role"] == "left")
|
if (member["role"] == "left")
|
||||||
membersLeft.append(member["uri"]);
|
membersLeft.append(member["uri"]);
|
||||||
}
|
}
|
||||||
conversation.readOnly = mode == conversation::Mode::ONE_TO_ONE && membersLeft.size() == 1;
|
|
||||||
conversation.participants = participants;
|
conversation.participants = participants;
|
||||||
conversation.mode = mode;
|
conversation.mode = mode;
|
||||||
conversation.unreadMessages = ConfigurationManager::instance().countInteractions(linked.owner.id,
|
conversation.unreadMessages = ConfigurationManager::instance().countInteractions(linked.owner.id,
|
||||||
|
@ -3097,12 +3094,12 @@ ConversationModelPimpl::getConversationForPeerUri(const QString& uri,
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<int>
|
std::vector<int>
|
||||||
ConversationModelPimpl::getIndicesForContact(const QString& uri, bool writable) const
|
ConversationModelPimpl::getIndicesForContact(const QString& uri) const
|
||||||
{
|
{
|
||||||
std::vector<int> ret;
|
std::vector<int> ret;
|
||||||
for (unsigned int i = 0; i < conversations.size(); ++i) {
|
for (unsigned int i = 0; i < conversations.size(); ++i) {
|
||||||
const auto& convInfo = conversations.at(i);
|
const auto& convInfo = conversations.at(i);
|
||||||
if (!convInfo.isCoreDialog() || (writable && convInfo.readOnly)) {
|
if (!convInfo.isCoreDialog()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
auto peers = peersForConversation(convInfo);
|
auto peers = peersForConversation(convInfo);
|
||||||
|
|
Loading…
Add table
Reference in a new issue