From 402515365ddd255217312b237e7e0cd4551b3097 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Blin?= <sebastien.blin@savoirfairelinux.com> Date: Thu, 15 Feb 2024 15:47:55 -0500 Subject: [PATCH] presence: follow daemon changes for presence indicator Change-Id: Ie82a15da023ab97f133c8beadb8ddeb81b67666f --- daemon | 2 +- .../commoncomponents/PresenceIndicator.qml | 15 +++++ src/app/contactadapter.cpp | 2 +- src/app/conversationlistmodelbase.cpp | 5 +- .../components/ConversationAvatar.qml | 1 + .../components/SmartListItemDelegate.qml | 61 ++++++++----------- .../mainview/components/SwarmDetailsPanel.qml | 3 +- src/app/utilsadapter.cpp | 6 +- src/app/utilsadapter.h | 2 +- src/libclient/api/contact.h | 4 +- src/libclient/callbackshandler.cpp | 3 +- src/libclient/callbackshandler.h | 8 +-- src/libclient/contactmodel.cpp | 10 +-- src/libclient/interfaces/pixmapmanipulatori.h | 6 +- src/libclient/pixmapmanipulatordefault.cpp | 8 +-- src/libclient/pixmapmanipulatordefault.h | 4 +- .../qtwrapper/presencemanager_wrap.h | 4 +- 17 files changed, 73 insertions(+), 71 deletions(-) diff --git a/daemon b/daemon index 09ec8e6f4..842128f09 160000 --- a/daemon +++ b/daemon @@ -1 +1 @@ -Subproject commit 09ec8e6f43ea5c68742bffb5e40ece15fa687c46 +Subproject commit 842128f09bf0f1259602de70604285e8a2a427f1 diff --git a/src/app/commoncomponents/PresenceIndicator.qml b/src/app/commoncomponents/PresenceIndicator.qml index 7d82f6232..b5663728e 100644 --- a/src/app/commoncomponents/PresenceIndicator.qml +++ b/src/app/commoncomponents/PresenceIndicator.qml @@ -29,6 +29,17 @@ Rectangle { property int status: Account.Status.REGISTERED property int size: 15 + MaterialToolTip { + visible: text !== "" && hoverHandler.hovered + delay: Qt.styleHints.mousePressAndHoldInterval + text: status === 2 ? qsTr("Connected") : status === 1 ? qsTr("Available") : "" + } + + HoverHandler { + id: hoverHandler + target: parent + } + width: size height: size radius: size * 0.5 @@ -41,6 +52,10 @@ Rectangle { return JamiTheme.presenceGreen; else if (status === Account.Status.TRYING) return JamiTheme.unPresenceOrange; + else if (status === 2) + return JamiTheme.presenceGreen; + else if (status === 1) + return JamiTheme.unPresenceOrange; return JamiTheme.notificationRed; } } diff --git a/src/app/contactadapter.cpp b/src/app/contactadapter.cpp index b2e6f6b71..f9067e1d3 100644 --- a/src/app/contactadapter.cpp +++ b/src/app/contactadapter.cpp @@ -81,7 +81,7 @@ ContactAdapter::getContactSelectableModel(int type) } case SmartListModel::Type::CONFERENCE: selectableProxyModel_->setPredicate([](const QModelIndex& index, const QRegularExpression&) { - return index.data(Role::Presence).toBool(); + return index.data(Role::Presence).toInt(); }); break; case SmartListModel::Type::TRANSFER: diff --git a/src/app/conversationlistmodelbase.cpp b/src/app/conversationlistmodelbase.cpp index 3ebbc0da7..03f93a4fb 100644 --- a/src/app/conversationlistmodelbase.cpp +++ b/src/app/conversationlistmodelbase.cpp @@ -176,10 +176,9 @@ ConversationListModelBase::dataForItem(item_t item, int role) const try { auto& accInfo = lrcInstance_->getAccountInfo(accountId_); if (peerUri == accInfo.profileInfo.uri) - return true; // Self account + return 2; // Self account auto contact = accInfo.contactModel->getContact(peerUri); - if (contact.isPresent) - return true; + return contact.presence; } catch (const std::exception&) { } return false; diff --git a/src/app/mainview/components/ConversationAvatar.qml b/src/app/mainview/components/ConversationAvatar.qml index d5f75b489..a07a7fe8c 100644 --- a/src/app/mainview/components/ConversationAvatar.qml +++ b/src/app/mainview/components/ConversationAvatar.qml @@ -24,6 +24,7 @@ Item { id: root property alias imageId: avatar.imageId + property alias presenceStatus: avatar.presenceStatus property alias showPresenceIndicator: avatar.showPresenceIndicator property alias animationMode: animation.mode diff --git a/src/app/mainview/components/SmartListItemDelegate.qml b/src/app/mainview/components/SmartListItemDelegate.qml index 1c98b14b8..a3d801942 100644 --- a/src/app/mainview/components/SmartListItemDelegate.qml +++ b/src/app/mainview/components/SmartListItemDelegate.qml @@ -21,12 +21,10 @@ import QtQuick import QtQuick.Controls import QtQuick.Layouts import Qt5Compat.GraphicalEffects - import net.jami.Adapters 1.1 import net.jami.Constants 1.1 import net.jami.Enums 1.1 import net.jami.Models 1.1 - import "../../commoncomponents" ItemDelegate { @@ -40,9 +38,7 @@ ItemDelegate { highlighted: ListView.isCurrentItem property bool interactive: true - property string lastInteractionDate: LastInteractionTimeStamp === undefined - ? "" - : LastInteractionTimeStamp + property string lastInteractionDate: LastInteractionTimeStamp === undefined ? "" : LastInteractionTimeStamp property string lastInteractionFormattedDate: MessagesAdapter.getBestFormattedDate(lastInteractionDate) @@ -51,25 +47,25 @@ ItemDelegate { Connections { target: PositionManager - function onPositionShareConvIdsCountChanged () { - root.showSharePositionIndicator = PositionManager.isPositionSharedToConv(accountId, UID) + function onPositionShareConvIdsCountChanged() { + root.showSharePositionIndicator = PositionManager.isPositionSharedToConv(accountId, UID); } - function onSharingUrisCountChanged () { - root.showSharedPositionIndicator = PositionManager.isConvSharingPosition(accountId, UID) + function onSharingUrisCountChanged() { + root.showSharedPositionIndicator = PositionManager.isConvSharingPosition(accountId, UID); } } Connections { target: MessagesAdapter function onTimestampUpdated() { - lastInteractionFormattedDate = MessagesAdapter.getBestFormattedDate(lastInteractionDate) + lastInteractionFormattedDate = MessagesAdapter.getBestFormattedDate(lastInteractionDate); } } Component.onCompleted: { // Store to avoid undefined at the end - root.accountId = Qt.binding(() => CurrentAccount.id) - root.convId = UID + root.accountId = Qt.binding(() => CurrentAccount.id); + root.convId = UID; } RowLayout { @@ -82,6 +78,7 @@ ItemDelegate { id: avatar imageId: UID + presenceStatus: Presence showPresenceIndicator: Presence !== undefined ? Presence : false Layout.preferredWidth: JamiTheme.smartListAvatarSize @@ -111,7 +108,6 @@ ItemDelegate { source: JamiResources.check_black_24dp_svg } } - } ColumnLayout { @@ -133,10 +129,7 @@ ItemDelegate { color: JamiTheme.textColor } RowLayout { - visible: ContactType !== Profile.Type.TEMPORARY - && !IsBanned - && lastInteractionFormattedDate !== undefined - && interactive + visible: ContactType !== Profile.Type.TEMPORARY && !IsBanned && lastInteractionFormattedDate !== undefined && interactive Layout.fillWidth: true Layout.minimumHeight: 20 Layout.alignment: Qt.AlignTop @@ -157,9 +150,7 @@ ItemDelegate { Layout.fillWidth: true Layout.alignment: Qt.AlignVCenter horizontalAlignment: Text.AlignLeft - text: Draft ? - Draft : - (LastInteraction === undefined ? "" : LastInteraction) + text: Draft ? Draft : (LastInteraction === undefined ? "" : LastInteraction) textFormat: TextEdit.PlainText font.pointSize: JamiTheme.smallFontSize font.weight: UnreadMessagesCount ? Font.Normal : Font.Light @@ -222,7 +213,7 @@ ItemDelegate { Text { id: callStatusText - visible : text + visible: text Layout.minimumHeight: 20 Layout.alignment: Qt.AlignRight text: InCall ? UtilsAdapter.getCallStatusStr(CallState) : "" @@ -247,51 +238,47 @@ ItemDelegate { } } - - - - Accessible.role: Accessible.Button - Accessible.name: Title === undefined? "" : Title - Accessible.description: LastInteraction === undefined? "" : LastInteraction + Accessible.name: Title === undefined ? "" : Title + Accessible.description: LastInteraction === undefined ? "" : LastInteraction } background: Rectangle { color: { if (root.pressed || root.highlighted) - return JamiTheme.smartListSelectedColor + return JamiTheme.smartListSelectedColor; else if (root.hovered) - return JamiTheme.smartListHoveredColor + return JamiTheme.smartListHoveredColor; else - return "transparent" + return "transparent"; } } onClicked: { if (!interactive) { - highlighted = !highlighted + highlighted = !highlighted; return; } - ListView.view.model.select(index) + ListView.view.model.select(index); } onDoubleClicked: { if (!interactive) return; - ListView.view.model.select(index) + ListView.view.model.select(index); if (CurrentConversation.isSwarm && !CurrentConversation.isCoreDialog && !UtilsAdapter.getAppValue(Settings.EnableExperimentalSwarm)) return; // For now disable calls for swarm with multiple participants if (LRCInstance.currentAccountType === Profile.Type.SIP || !CurrentAccount.videoEnabled_Video) - CallAdapter.placeAudioOnlyCall() + CallAdapter.placeAudioOnlyCall(); else { if (!CurrentConversation.readOnly) { - CallAdapter.placeCall() + CallAdapter.placeCall(); } } } onPressAndHold: { if (!interactive) return; - ListView.view.openContextMenuAt(pressX, pressY, root) + ListView.view.openContextMenuAt(pressX, pressY, root); } MouseArea { @@ -299,7 +286,7 @@ ItemDelegate { enabled: interactive acceptedButtons: Qt.RightButton onClicked: function (mouse) { - root.ListView.view.openContextMenuAt(mouse.x, mouse.y, root) + root.ListView.view.openContextMenuAt(mouse.x, mouse.y, root); } } } diff --git a/src/app/mainview/components/SwarmDetailsPanel.qml b/src/app/mainview/components/SwarmDetailsPanel.qml index ef439fe16..7c2521db6 100644 --- a/src/app/mainview/components/SwarmDetailsPanel.qml +++ b/src/app/mainview/components/SwarmDetailsPanel.qml @@ -624,7 +624,8 @@ Rectangle { opacity: (MemberRole === Member.Role.INVITED || MemberRole === Member.Role.BANNED) ? 0.5 : 1 imageId: CurrentAccount.uri === MemberUri ? CurrentAccount.id : MemberUri - showPresenceIndicator: UtilsAdapter.getContactPresence(CurrentAccount.id, MemberUri) + presenceStatus: UtilsAdapter.getContactPresence(CurrentAccount.id, MemberUri) + showPresenceIndicator: presenceStatus > 0 mode: CurrentAccount.uri === MemberUri ? Avatar.Mode.Account : Avatar.Mode.Contact } diff --git a/src/app/utilsadapter.cpp b/src/app/utilsadapter.cpp index 70f559fa8..882474ecc 100644 --- a/src/app/utilsadapter.cpp +++ b/src/app/utilsadapter.cpp @@ -610,17 +610,17 @@ UtilsAdapter::setTempCreationImageFromImage(const QImage& image, const QString& } } -bool +int UtilsAdapter::getContactPresence(const QString& accountId, const QString& uri) { try { if (lrcInstance_->getAccountInfo(accountId).profileInfo.uri == uri) return true; // It's the same account auto info = lrcInstance_->getAccountInfo(accountId).contactModel->getContact(uri); - return info.isPresent; + return info.presence; } catch (...) { } - return false; + return 0; } QString diff --git a/src/app/utilsadapter.h b/src/app/utilsadapter.h index d4e1aa920..8616d847f 100644 --- a/src/app/utilsadapter.h +++ b/src/app/utilsadapter.h @@ -150,7 +150,7 @@ public: const QString& imageId = "temp"); // For Swarm details page - Q_INVOKABLE bool getContactPresence(const QString& accountId, const QString& uri); + Q_INVOKABLE int getContactPresence(const QString& accountId, const QString& uri); Q_INVOKABLE QString getContactBestName(const QString& accountId, const QString& uri); Q_INVOKABLE lrc::api::member::Role getParticipantRole(const QString& accountId, const QString& convId, diff --git a/src/libclient/api/contact.h b/src/libclient/api/contact.h index bbb1935e5..008e3c4fd 100644 --- a/src/libclient/api/contact.h +++ b/src/libclient/api/contact.h @@ -32,7 +32,7 @@ namespace contact { * @var profileInfo * @var registeredName * @var isTrusted - * @var isPresent + * @var presence * @var isBanned */ struct Info @@ -40,7 +40,7 @@ struct Info profile::Info profileInfo; QString registeredName; bool isTrusted = false; - bool isPresent = false; + int presence = 0; bool isBanned = false; QString conversationId {}; }; diff --git a/src/libclient/callbackshandler.cpp b/src/libclient/callbackshandler.cpp index 685dae9bb..06c7df295 100644 --- a/src/libclient/callbackshandler.cpp +++ b/src/libclient/callbackshandler.cpp @@ -408,10 +408,9 @@ CallbacksHandler::slotNewAccountMessage(const QString& accountId, void CallbacksHandler::slotNewBuddySubscription(const QString& accountId, const QString& uri, - bool status, + int status, const QString& message) { - Q_UNUSED(status) Q_UNUSED(message) Q_EMIT newBuddySubscription(accountId, uri, status); } diff --git a/src/libclient/callbackshandler.h b/src/libclient/callbackshandler.h index d92c70dce..78c73a639 100644 --- a/src/libclient/callbackshandler.h +++ b/src/libclient/callbackshandler.h @@ -66,9 +66,9 @@ Q_SIGNALS: * Connect this signal to get information when a peer is online. * @param accountId related account. * @param contactUri the peer. - * @param present if the peer is online. + * @param presence if the peer is online. */ - void newBuddySubscription(const QString& accountId, const QString& contactUri, bool present); + void newBuddySubscription(const QString& accountId, const QString& contactUri, int presence); /** * Connect this signal to get information when peer discovery changes. * @param contactUri the peer. @@ -407,12 +407,12 @@ private Q_SLOTS: * Emit newBuddySubscription * @param accountId * @param contactUri - * @param status if the contact is present + * @param status if the contact is present (1=dht presence, 0=offline, 2=connected) * @param message unused for now */ void slotNewBuddySubscription(const QString& accountId, const QString& contactUri, - bool status, + int status, const QString& message); /** * Emit contactAdded diff --git a/src/libclient/contactmodel.cpp b/src/libclient/contactmodel.cpp index 9771b2dd0..0d210492e 100644 --- a/src/libclient/contactmodel.cpp +++ b/src/libclient/contactmodel.cpp @@ -130,7 +130,7 @@ public Q_SLOTS: * @param contactUri * @param status */ - void slotNewBuddySubscription(const QString& accountId, const QString& uri, bool status); + void slotNewBuddySubscription(const QString& accountId, const QString& uri, int status); /** * Listen CallbacksHandler when a contact is added @@ -778,7 +778,7 @@ ContactModelPimpl::fillWithJamiContacts() std::lock_guard<std::mutex> lk(contactsMtx_); auto it = contacts.find(uri); if (it != contacts.end()) { - it->isPresent = key == "Online"; + it->presence = key == "Online" ? 1 : 0; linked.modelUpdated(uri); } } @@ -792,7 +792,7 @@ ContactModelPimpl::fillWithJamiContacts() void ContactModelPimpl::slotNewBuddySubscription(const QString& accountId, const QString& contactUri, - bool status) + int state) { if (accountId != linked.owner.id) return; @@ -800,7 +800,7 @@ ContactModelPimpl::slotNewBuddySubscription(const QString& accountId, std::lock_guard<std::mutex> lk(contactsMtx_); auto it = contacts.find(contactUri); if (it != contacts.end()) { - it->isPresent = status; + it->presence = state; } else return; } @@ -966,7 +966,7 @@ ContactModelPimpl::addToContacts(const QString& contactUri, if (iter != contacts.end()) { auto info = iter.value(); contactInfo.registeredName = info.registeredName; - contactInfo.isPresent = info.isPresent; + contactInfo.presence = info.presence; iter.value() = contactInfo; } else contacts.insert(iter, contactInfo.profileInfo.uri, contactInfo); diff --git a/src/libclient/interfaces/pixmapmanipulatori.h b/src/libclient/interfaces/pixmapmanipulatori.h index f9f3101cc..a6d7ab100 100644 --- a/src/libclient/interfaces/pixmapmanipulatori.h +++ b/src/libclient/interfaces/pixmapmanipulatori.h @@ -72,18 +72,18 @@ public: virtual QVariant conversationPhoto(const lrc::api::conversation::Info& conversation, const lrc::api::account::Info& accountInfo, const QSize& size, - bool displayPresence = true) + int presence = 0) { Q_UNUSED(conversation); Q_UNUSED(accountInfo); Q_UNUSED(size); - Q_UNUSED(displayPresence); + Q_UNUSED(presence); return {}; } virtual QVariant numberCategoryIcon(const QVariant& p, const QSize& size, bool displayPresence = false, - bool isPresent = false) + int presence = 0) = 0; virtual QByteArray toByteArray(const QVariant& pxm) = 0; virtual QVariant personPhoto(const QByteArray& data, const QString& type = "PNG") = 0; diff --git a/src/libclient/pixmapmanipulatordefault.cpp b/src/libclient/pixmapmanipulatordefault.cpp index 43f13f3ae..2df328c72 100644 --- a/src/libclient/pixmapmanipulatordefault.cpp +++ b/src/libclient/pixmapmanipulatordefault.cpp @@ -32,12 +32,12 @@ QVariant PixmapManipulatorDefault::numberCategoryIcon(const QVariant& p, const QSize& size, bool displayPresence, - bool isPresent) + int presence) { Q_UNUSED(p) Q_UNUSED(size) Q_UNUSED(displayPresence) - Q_UNUSED(isPresent) + Q_UNUSED(presence) return QVariant(); } @@ -45,12 +45,12 @@ QVariant PixmapManipulatorDefault::conversationPhoto(const lrc::api::conversation::Info& conversation, const lrc::api::account::Info& accountInfo, const QSize& size, - bool displayPresence) + int presence) { Q_UNUSED(conversation) Q_UNUSED(accountInfo) Q_UNUSED(size) - Q_UNUSED(displayPresence) + Q_UNUSED(presence) return QVariant(); } diff --git a/src/libclient/pixmapmanipulatordefault.h b/src/libclient/pixmapmanipulatordefault.h index 5a93b204d..3e6e8fef3 100644 --- a/src/libclient/pixmapmanipulatordefault.h +++ b/src/libclient/pixmapmanipulatordefault.h @@ -29,11 +29,11 @@ public: QVariant conversationPhoto(const lrc::api::conversation::Info& conversation, const lrc::api::account::Info& accountInfo, const QSize& size, - bool displayPresence = true) override; + int presence = 0) override; QVariant numberCategoryIcon(const QVariant& p, const QSize& size, bool displayPresence = false, - bool isPresent = false) override; + int presence = 0) override; QByteArray toByteArray(const QVariant& pxm) override; QVariant personPhoto(const QByteArray& data, const QString& type = "PNG") override; QVariant decorationRole(const QModelIndex& index) override; diff --git a/src/libclient/qtwrapper/presencemanager_wrap.h b/src/libclient/qtwrapper/presencemanager_wrap.h index 9acb379c3..253cecc07 100644 --- a/src/libclient/qtwrapper/presencemanager_wrap.h +++ b/src/libclient/qtwrapper/presencemanager_wrap.h @@ -60,7 +60,7 @@ public: exportable_callback<PresenceSignal::NewBuddyNotification>( [this](const std::string& accountID, const std::string& buddyUri, - bool status, + int status, const std::string& lineStatus) { Q_EMIT this->newBuddyNotification(QString(accountID.c_str()), QString(buddyUri.c_str()), @@ -126,7 +126,7 @@ Q_SIGNALS: // SIGNALS void serverError(const QString& accountID, const QString& error, const QString& msg); void newBuddyNotification(const QString& accountID, const QString& buddyUri, - bool status, + int status, const QString& lineStatus); void subscriptionStateChanged(const QString& accountID, const QString& buddyUri, bool state); }; -- GitLab