Skip to content
Snippets Groups Projects
Commit f05ffbce authored by Andreas Traczyk's avatar Andreas Traczyk
Browse files

swarm: prevent interacting with read-only conversations

Read-only conversation has:
- a lock icon in the smartlist item
- no message send bar in the chat view
- no call actions available from the chat view header
- no call actions available from the smartlist context menu
- no double click to call

Change-Id: I0497b94038b450f0a0a22fc007de1281b7b2214d
Gitlab: #475
parent e2dbc33a
Branches
Tags
No related merge requests found
<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="#000000"><g fill="none"><path d="M0 0h24v24H0V0z"/><path d="M0 0h24v24H0V0z" opacity=".87"/></g><path d="M18 8h-1V6c0-2.76-2.24-5-5-5S7 3.24 7 6v2H6c-1.1 0-2 .9-2 2v10c0 1.1.9 2 2 2h12c1.1 0 2-.9 2-2V10c0-1.1-.9-2-2-2zM9 6c0-1.66 1.34-3 3-3s3 1.34 3 3v2H9V6zm9 14H6V10h12v10zm-6-3c1.1 0 2-.9 2-2s-.9-2-2-2-2 .9-2 2 .9 2 2 2z"/></svg>
\ No newline at end of file
...@@ -149,6 +149,8 @@ ConversationListModelBase::dataForItem(item_t item, int role) const ...@@ -149,6 +149,8 @@ ConversationListModelBase::dataForItem(item_t item, int role) const
} }
return ret; return ret;
} }
case Role::ReadOnly:
return QVariant(item.readOnly);
default: default:
break; break;
} }
......
...@@ -48,7 +48,8 @@ ...@@ -48,7 +48,8 @@
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
......
...@@ -274,8 +274,14 @@ ConversationsAdapter::onProfileUpdated(const QString& contactUri) ...@@ -274,8 +274,14 @@ ConversationsAdapter::onProfileUpdated(const QString& contactUri)
} }
void void
ConversationsAdapter::onConversationUpdated(const QString&) 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(); updateConversationFilterData();
} }
...@@ -283,8 +289,6 @@ void ...@@ -283,8 +289,6 @@ void
ConversationsAdapter::onFilterChanged() ConversationsAdapter::onFilterChanged()
{ {
updateConversationFilterData(); updateConversationFilterData();
if (!lrcInstance_->get_selectedConvUid().isEmpty())
Q_EMIT indexRepositionRequested();
} }
void void
...@@ -437,7 +441,8 @@ ConversationsAdapter::getConvInfoMap(const QString& convId) ...@@ -437,7 +441,8 @@ 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}};
} }
bool bool
......
...@@ -36,6 +36,7 @@ class ConversationsAdapter final : public QmlAdapterBase ...@@ -36,6 +36,7 @@ class ConversationsAdapter final : public QmlAdapterBase
QML_PROPERTY(bool, filterRequests) QML_PROPERTY(bool, filterRequests)
QML_PROPERTY(int, totalUnreadMessageCount) QML_PROPERTY(int, totalUnreadMessageCount)
QML_PROPERTY(int, pendingRequestCount) QML_PROPERTY(int, pendingRequestCount)
QML_PROPERTY(bool, currentConvIsReadOnly)
public: public:
explicit ConversationsAdapter(SystemTray* systemTray, explicit ConversationsAdapter(SystemTray* systemTray,
...@@ -56,7 +57,6 @@ Q_SIGNALS: ...@@ -56,7 +57,6 @@ Q_SIGNALS:
void showSearchStatus(const QString& status); void showSearchStatus(const QString& status);
void navigateToWelcomePageRequested(); void navigateToWelcomePageRequested();
void indexRepositionRequested();
void conversationReady(const QString& convId); void conversationReady(const QString& convId);
private Q_SLOTS: private Q_SLOTS:
......
...@@ -45,7 +45,7 @@ ContextMenuAutoLoader { ...@@ -45,7 +45,7 @@ ContextMenuAutoLoader {
GeneralMenuItem { GeneralMenuItem {
id: startVideoCallItem id: startVideoCallItem
canTrigger: !hasCall canTrigger: !hasCall && !ConversationsAdapter.currentConvIsReadOnly
itemName: JamiStrings.startVideoCall itemName: JamiStrings.startVideoCall
iconSource: JamiResources.videocam_24dp_svg iconSource: JamiResources.videocam_24dp_svg
onClicked: { onClicked: {
...@@ -59,7 +59,7 @@ ContextMenuAutoLoader { ...@@ -59,7 +59,7 @@ ContextMenuAutoLoader {
GeneralMenuItem { GeneralMenuItem {
id: startAudioCall id: startAudioCall
canTrigger: !hasCall canTrigger: !hasCall && !ConversationsAdapter.currentConvIsReadOnly
itemName: JamiStrings.startAudioCall itemName: JamiStrings.startAudioCall
iconSource: JamiResources.place_audiocall_24dp_svg iconSource: JamiResources.place_audiocall_24dp_svg
onClicked: { onClicked: {
......
...@@ -114,9 +114,10 @@ Rectangle { ...@@ -114,9 +114,10 @@ Rectangle {
Connections { Connections {
target: MessagesAdapter target: MessagesAdapter
function onChangeInvitationViewRequest(show, isSwarm, needsSyncing, function onSetChatViewMode(showInvitationPage,
isSwarm, needsSyncing,
title, convId) { title, convId) {
if (show) if (showInvitationPage)
root.mode = MessageWebView.Mode.Invitation root.mode = MessageWebView.Mode.Invitation
else { else {
root.mode = MessageWebView.Mode.Chat root.mode = MessageWebView.Mode.Chat
...@@ -129,6 +130,16 @@ Rectangle { ...@@ -129,6 +130,16 @@ Rectangle {
} }
} }
Connections {
target: ConversationsAdapter
function onCurrentConvIsReadOnlyChanged() {
var isVisible = !ConversationsAdapter.currentConvIsReadOnly
setMessagingHeaderButtonsVisible(isVisible)
messageWebViewFooter.visible = isVisible
}
}
QtObject { QtObject {
id: jsBridgeObject id: jsBridgeObject
......
...@@ -83,8 +83,13 @@ Rectangle { ...@@ -83,8 +83,13 @@ Rectangle {
messageBar.textAreaObj.pasteText() messageBar.textAreaObj.pasteText()
} }
function onChangeInvitationViewRequest(show, isSwarm) { function onSetChatViewMode(showInvitationPage,
var footerVisibility = show ? !isSwarm : !show isSwarm, needsSyncing,
title, convId, readOnly) {
var footerVisibility = showInvitationPage ?
!isSwarm :
!showInvitationPage
footerVisibility &= !readOnly
messageBar.visible = footerVisibility messageBar.visible = footerVisibility
dataTransferSendContainer.visible = footerVisibility dataTransferSendContainer.visible = footerVisibility
root.visible = footerVisibility root.visible = footerVisibility
......
...@@ -27,7 +27,7 @@ import net.jami.Adapters 1.0 ...@@ -27,7 +27,7 @@ import net.jami.Adapters 1.0
import "../../commoncomponents" import "../../commoncomponents"
Rectangle { Rectangle {
id: messagingHeaderRect id: root
property string userAliasLabelText property string userAliasLabelText
property string userUserNameLabelText property string userUserNameLabelText
...@@ -72,9 +72,9 @@ Rectangle { ...@@ -72,9 +72,9 @@ Rectangle {
onClicked: { onClicked: {
if (backToWelcomeViewButtonSource === JamiResources.back_24dp_svg) if (backToWelcomeViewButtonSource === JamiResources.back_24dp_svg)
messagingHeaderRect.backClicked() root.backClicked()
else else
messagingHeaderRect.needToHideConversationInCall() root.needToHideConversationInCall()
} }
} }
...@@ -84,7 +84,7 @@ Rectangle { ...@@ -84,7 +84,7 @@ Rectangle {
Layout.alignment: Qt.AlignLeft | Qt.AlignTop Layout.alignment: Qt.AlignLeft | Qt.AlignTop
// Width + margin. // Width + margin.
Layout.preferredWidth: messagingHeaderRect.width Layout.preferredWidth: root.width
- backToWelcomeViewButton.width - buttonGroup.width - 45 - backToWelcomeViewButton.width - buttonGroup.width - 45
Layout.fillHeight: true Layout.fillHeight: true
Layout.topMargin: 7 Layout.topMargin: 7
......
...@@ -107,8 +107,15 @@ ItemDelegate { ...@@ -107,8 +107,15 @@ ItemDelegate {
} }
} }
// read-only conversation indicator
ResponsiveImage {
visible: ReadOnly
source: JamiResources.lock_black_24dp_svg
color: JamiTheme.primaryForegroundColor
}
ColumnLayout { ColumnLayout {
visible: InCall || UnreadMessagesCount visible: (InCall || UnreadMessagesCount) && !ReadOnly
Layout.preferredWidth: childrenRect.width Layout.preferredWidth: childrenRect.width
Layout.fillHeight: true Layout.fillHeight: true
spacing: 2 spacing: 2
...@@ -153,9 +160,11 @@ ItemDelegate { ...@@ -153,9 +160,11 @@ ItemDelegate {
ListView.view.model.select(index) ListView.view.model.select(index)
if (LRCInstance.currentAccountType === Profile.Type.SIP) if (LRCInstance.currentAccountType === Profile.Type.SIP)
CallAdapter.placeAudioOnlyCall() CallAdapter.placeAudioOnlyCall()
else else {
if (!ConversationsAdapter.currentConvIsReadOnly) {
CallAdapter.placeCall() CallAdapter.placeCall()
}
}
// TODO: factor this out (visible should be observing) // TODO: factor this out (visible should be observing)
communicationPageMessageWebView.setSendContactRequestButtonVisible(false) communicationPageMessageWebView.setSendContactRequestButtonVisible(false)
} }
......
...@@ -62,21 +62,24 @@ MessagesAdapter::setupChatView(const QVariantMap& convInfo) ...@@ -62,21 +62,24 @@ MessagesAdapter::setupChatView(const QVariantMap& convInfo)
bool isLegacy = !convInfo["isSwarm"].toBool(); bool isLegacy = !convInfo["isSwarm"].toBool();
bool isRequest = convInfo["isRequest"].toBool(); bool isRequest = convInfo["isRequest"].toBool();
bool needsSyncing = convInfo["needsSyncing"].toBool(); bool needsSyncing = convInfo["needsSyncing"].toBool();
bool readOnly = convInfo["readOnly"].toBool();
QMetaObject::invokeMethod(qmlObj_, QMetaObject::invokeMethod(qmlObj_,
"setSendContactRequestButtonVisible", "setSendContactRequestButtonVisible",
Q_ARG(QVariant, isLegacy && isRequest)); Q_ARG(QVariant, isLegacy && isRequest));
QMetaObject::invokeMethod(qmlObj_, QMetaObject::invokeMethod(qmlObj_,
"setMessagingHeaderButtonsVisible", "setMessagingHeaderButtonsVisible",
Q_ARG(QVariant, !(isLegacy && (isRequest || needsSyncing)))); Q_ARG(QVariant,
!readOnly && !(isLegacy && (isRequest || needsSyncing))));
setMessagesVisibility(false); setMessagesVisibility(false);
setIsSwarm(!isLegacy); setIsSwarm(!isLegacy);
Q_EMIT changeInvitationViewRequest(isRequest || needsSyncing, Q_EMIT setChatViewMode(isRequest || needsSyncing,
isLegacy, isLegacy,
needsSyncing, needsSyncing,
convInfo["title"].toString(), convInfo["title"].toString(),
convInfo["convId"].toString()); convInfo["convId"].toString(),
readOnly);
Utils::oneShotConnect(qmlObj_, SIGNAL(messagesCleared()), this, SLOT(slotMessagesCleared())); Utils::oneShotConnect(qmlObj_, SIGNAL(messagesCleared()), this, SLOT(slotMessagesCleared()));
clearChatView(); clearChatView();
...@@ -369,14 +372,16 @@ MessagesAdapter::setConversationProfileData(const lrc::api::conversation::Info& ...@@ -369,14 +372,16 @@ MessagesAdapter::setConversationProfileData(const lrc::api::conversation::Info&
QMetaObject::invokeMethod(qmlObj_, QMetaObject::invokeMethod(qmlObj_,
"setMessagingHeaderButtonsVisible", "setMessagingHeaderButtonsVisible",
Q_ARG(QVariant, Q_ARG(QVariant,
!(convInfo.isSwarm() !convInfo.readOnly
&& !(convInfo.isSwarm()
&& (convInfo.isRequest || convInfo.needsSyncing)))); && (convInfo.isRequest || convInfo.needsSyncing))));
Q_EMIT changeInvitationViewRequest(convInfo.isRequest or convInfo.needsSyncing, Q_EMIT setChatViewMode(convInfo.isRequest || convInfo.needsSyncing,
convInfo.isSwarm(), convInfo.isSwarm(),
convInfo.needsSyncing, convInfo.needsSyncing,
title, title,
convInfo.uid); convInfo.uid,
convInfo.readOnly);
if (convInfo.isSwarm()) if (convInfo.isSwarm())
return; return;
...@@ -593,7 +598,7 @@ MessagesAdapter::refuseInvitation(const QString& convUid) ...@@ -593,7 +598,7 @@ MessagesAdapter::refuseInvitation(const QString& convUid)
{ {
const auto currentConvUid = convUid.isEmpty() ? lrcInstance_->get_selectedConvUid() : convUid; const auto currentConvUid = convUid.isEmpty() ? lrcInstance_->get_selectedConvUid() : convUid;
lrcInstance_->getCurrentConversationModel()->removeConversation(currentConvUid, false); lrcInstance_->getCurrentConversationModel()->removeConversation(currentConvUid, false);
changeInvitationViewRequest(false); Q_EMIT setChatViewMode(false);
} }
void void
...@@ -601,7 +606,7 @@ MessagesAdapter::blockConversation(const QString& convUid) ...@@ -601,7 +606,7 @@ MessagesAdapter::blockConversation(const QString& convUid)
{ {
const auto currentConvUid = convUid.isEmpty() ? lrcInstance_->get_selectedConvUid() : convUid; const auto currentConvUid = convUid.isEmpty() ? lrcInstance_->get_selectedConvUid() : convUid;
lrcInstance_->getCurrentConversationModel()->removeConversation(currentConvUid, true); lrcInstance_->getCurrentConversationModel()->removeConversation(currentConvUid, true);
changeInvitationViewRequest(false); Q_EMIT setChatViewMode(false);
} }
void void
......
...@@ -93,11 +93,12 @@ Q_SIGNALS: ...@@ -93,11 +93,12 @@ Q_SIGNALS:
void newMessageBarPlaceholderText(QString placeholderText); void newMessageBarPlaceholderText(QString placeholderText);
void newFilePasted(QString filePath); void newFilePasted(QString filePath);
void newTextPasted(); void newTextPasted();
void changeInvitationViewRequest(bool show, void setChatViewMode(bool showInvitationPage,
bool isSwarm = false, bool isSwarm = false,
bool needsSyncing = false, bool needsSyncing = false,
QString contactTitle = {}, QString contactTitle = {},
QString contactUri = {}); QString contactUri = {},
bool readOnly = false);
private Q_SLOTS: private Q_SLOTS:
void slotMessagesCleared(); void slotMessagesCleared();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment