diff --git a/daemon b/daemon index 09ec8e6f43ea5c68742bffb5e40ece15fa687c46..842128f09bf0f1259602de70604285e8a2a427f1 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 7d82f6232a6361bfca97f3a2c0d2e8b982c593ca..b5663728eb7ec18f9d6c3ed1aaf46816107903c3 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 b2e6f6b71d35797f013242b8fd17b3a8c5185e97..f9067e1d314861d2f3a3b549712f090885b5afd3 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 3ebbc0da7e2c985af000cd371a11d0f581be94a4..03f93a4fb5dd27be3ebce3f3b271e8da270bc9fc 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 d5f75b489252f2f340e6f923d8ae9ba5395ac8b2..a07a7fe8c8f1b5e7ab7c0a82c4b12dd250e197ab 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 1c98b14b8f30278078aba9877cd7ee1fb43ea73b..a3d801942a476f3b9a5f7422299e09ffb95c2f78 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 ef439fe160445c3252754e150aacbb6d767f6fdf..7c2521db60df887cf7b3b7655533f67017b3e182 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 70f559fa819e3df502feaa7b502dba9a532c4790..882474ecc64a665ab7d938dc697ce3e1cbeef1b5 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 d4e1aa920438fa31da5677a480129ca092602e29..8616d847fe65b8efe8c7db6c0f0dd5d288192ae3 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 bbb1935e5f832460c5f5db9403729db5c2a9aa03..008e3c4fdf17bc7d83eb3f90e306c6fba25e08ca 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 685dae9bbb0f9739171028b3bd8c5ecd1f5feae3..06c7df295e29e34be7f80c94d4714718aa7b5647 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 d92c70dce659ddb23e33b972192072520e5b213d..78c73a639998c0b32b8292f303672c30886c875c 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 9771b2dd02dc395017127901e2768c2d74b00074..0d210492e27831b40a4363c77e9d9a1f625e4676 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 f9f3101cc14d85096228cb5bf0dc4d9484f1900f..a6d7ab1005a4f89a35272f8e552b9462e92e8be8 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 43f13f3ae4dd2c726ac40dcb133949e184dc70f5..2df328c72a61e635bd6d3f743f8021b30645c4a9 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 5a93b204dc32a1bbf0fe5e351b8b5caf340ce3ac..3e6e8fef3a0391fa2910320768d93fd191ad41cf 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 9acb379c3e08a0fea5f4593e31dbefab444d9810..253cecc07e98409817ffa1fe2bc4f968a56adb0d 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); };