From 0646040d25fa05bc6d456fcba32b5f6a80e69e70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ga=C3=ABlle=20Braud?= Date: Wed, 22 May 2024 11:29:04 +0000 Subject: [PATCH] missed calls notification in navigation bar + fix notif ui --- Linphone/core/App.cpp | 1 + Linphone/core/account/AccountCore.cpp | 27 ++++++++++++++++++++- Linphone/core/account/AccountCore.hpp | 9 +++++++ Linphone/model/account/AccountModel.cpp | 6 +++++ Linphone/model/account/AccountModel.hpp | 1 + Linphone/tool/Utils.cpp | 1 - Linphone/view/App/Layout/MainLayout.qml | 12 ++++++---- Linphone/view/Item/Contact/Contact.qml | 28 +++++++++++++--------- Linphone/view/Item/Meeting/MeetingList.qml | 4 ++-- Linphone/view/Item/VerticalTabBar.qml | 26 ++++++++++++++++++++ Linphone/view/Page/Main/CallPage.qml | 9 ++++--- 11 files changed, 101 insertions(+), 23 deletions(-) diff --git a/Linphone/core/App.cpp b/Linphone/core/App.cpp index e7aa69d44..566bb5ad7 100644 --- a/Linphone/core/App.cpp +++ b/Linphone/core/App.cpp @@ -112,6 +112,7 @@ void App::setSelf(QSharedPointer(me)) { new SafeConnection(me, CoreModel::getInstance()), &QObject::deleteLater); mCoreModelConnection->makeConnectToModel(&CoreModel::callCreated, [this](const std::shared_ptr &call) { + if (call->getDir() == linphone::Call::Dir::Incoming) return; auto callCore = CallCore::create(call); mCoreModelConnection->invokeToCore([this, callCore] { auto callGui = new CallGui(callCore); diff --git a/Linphone/core/account/AccountCore.cpp b/Linphone/core/account/AccountCore.cpp index f13899abf..5f5c76b39 100644 --- a/Linphone/core/account/AccountCore.cpp +++ b/Linphone/core/account/AccountCore.cpp @@ -80,6 +80,8 @@ void AccountCore::setSelf(QSharedPointer me) { &AccountModel::unreadNotificationsChanged, [this](int unreadMessagesCount, int unreadCallsCount) { mAccountModelConnection->invokeToCore([this, unreadMessagesCount, unreadCallsCount]() { this->setUnreadNotifications(unreadMessagesCount + unreadCallsCount); + this->setUnreadCallNotifications(unreadCallsCount); + this->setUnreadMessageNotifications(unreadMessagesCount); }); }); @@ -90,6 +92,9 @@ void AccountCore::setSelf(QSharedPointer me) { mAccountModelConnection->makeConnectToCore(&AccountCore::lSetDefaultAccount, [this]() { mAccountModelConnection->invokeToModel([this]() { mAccountModel->setDefault(); }); }); + mAccountModelConnection->makeConnectToCore(&AccountCore::lResetMissedCalls, [this]() { + mAccountModelConnection->invokeToModel([this]() { mAccountModel->resetMissedCallsCount(); }); + }); } QString AccountCore::getContactAddress() const { @@ -122,6 +127,26 @@ void AccountCore::setUnreadNotifications(int unread) { } } +int AccountCore::getUnreadCallNotifications() const { + return mUnreadCallNotifications; +} +void AccountCore::setUnreadCallNotifications(int unread) { + if (mUnreadCallNotifications != unread) { + mUnreadCallNotifications = unread; + emit unreadNotificationsChanged(unread); + } +} + +int AccountCore::getUnreadMessageNotifications() const { + return mUnreadMessageNotifications; +} +void AccountCore::setUnreadMessageNotifications(int unread) { + if (mUnreadMessageNotifications != unread) { + mUnreadMessageNotifications = unread; + emit unreadNotificationsChanged(unread); + } +} + void AccountCore::onRegistrationStateChanged(const std::shared_ptr &account, linphone::RegistrationState state, const std::string &message) { @@ -144,4 +169,4 @@ void AccountCore::onPictureUriChanged(QString uri) { void AccountCore::removeAccount() { mAccountModelConnection->invokeToModel([this]() { mAccountModel->removeAccount(); }); -} +} \ No newline at end of file diff --git a/Linphone/core/account/AccountCore.hpp b/Linphone/core/account/AccountCore.hpp index 50e17c72e..e4876a822 100644 --- a/Linphone/core/account/AccountCore.hpp +++ b/Linphone/core/account/AccountCore.hpp @@ -38,6 +38,8 @@ class AccountCore : public QObject, public AbstractObject { LinphoneEnums::RegistrationState registrationState READ getRegistrationState NOTIFY registrationStateChanged) Q_PROPERTY(bool isDefaultAccount READ getIsDefaultAccount NOTIFY defaultAccountChanged) Q_PROPERTY(int unreadNotifications READ getUnreadNotifications NOTIFY unreadNotificationsChanged) + Q_PROPERTY(int unreadCallNotifications READ getUnreadCallNotifications NOTIFY unreadNotificationsChanged) + Q_PROPERTY(int unreadMessageNotifications READ getUnreadMessageNotifications NOTIFY unreadNotificationsChanged) public: static QSharedPointer create(const std::shared_ptr &account); @@ -53,6 +55,10 @@ public: bool getIsDefaultAccount() const; int getUnreadNotifications() const; void setUnreadNotifications(int unread); + int getUnreadCallNotifications() const; + void setUnreadCallNotifications(int unread); + int getUnreadMessageNotifications() const; + void setUnreadMessageNotifications(int unread); void onPictureUriChanged(QString uri); void onRegistrationStateChanged(const std::shared_ptr &account, @@ -71,6 +77,7 @@ signals: // Account requests void lSetPictureUri(QString pictureUri); void lSetDefaultAccount(); + void lResetMissedCalls(); private: QString mContactAddress; @@ -79,6 +86,8 @@ private: bool mIsDefaultAccount = false; LinphoneEnums::RegistrationState mRegistrationState; int mUnreadNotifications = 0; + int mUnreadCallNotifications = 0; + int mUnreadMessageNotifications = 0; std::shared_ptr mAccountModel; QSharedPointer> mAccountModelConnection; diff --git a/Linphone/model/account/AccountModel.cpp b/Linphone/model/account/AccountModel.cpp index 0dfb4b819..a76ec6879 100644 --- a/Linphone/model/account/AccountModel.cpp +++ b/Linphone/model/account/AccountModel.cpp @@ -89,3 +89,9 @@ void AccountModel::setDefault() { void AccountModel::removeAccount() { CoreModel::getInstance()->getCore()->removeAccount(mMonitor); } + +void AccountModel::resetMissedCallsCount() { + mMonitor->resetMissedCallsCount(); + emit unreadNotificationsChanged(0 /*mMonitor->getUnreadChatMessageCount()*/, + mMonitor->getMissedCallsCount()); // TODO +} \ No newline at end of file diff --git a/Linphone/model/account/AccountModel.hpp b/Linphone/model/account/AccountModel.hpp index 940cb4021..0b21260c6 100644 --- a/Linphone/model/account/AccountModel.hpp +++ b/Linphone/model/account/AccountModel.hpp @@ -43,6 +43,7 @@ public: void setPictureUri(QString uri); void setDefault(); void removeAccount(); + void resetMissedCallsCount(); signals: void registrationStateChanged(const std::shared_ptr &account, diff --git a/Linphone/tool/Utils.cpp b/Linphone/tool/Utils.cpp index 7cf6e6535..cecc4f069 100644 --- a/Linphone/tool/Utils.cpp +++ b/Linphone/tool/Utils.cpp @@ -129,7 +129,6 @@ void Utils::openCallsWindow(CallGui *call) { QQuickWindow *Utils::getCallsWindow(CallGui *callGui) { auto app = App::getInstance(); auto window = app->getCallsWindow(QVariant::fromValue(callGui)); - smartShowWindow(window); return window; } diff --git a/Linphone/view/App/Layout/MainLayout.qml b/Linphone/view/App/Layout/MainLayout.qml index 061961029..c7d0dc33b 100644 --- a/Linphone/view/App/Layout/MainLayout.qml +++ b/Linphone/view/App/Layout/MainLayout.qml @@ -121,12 +121,14 @@ Item { Layout.fillHeight: true Layout.preferredWidth: 82 * DefaultStyle.dp model: [ - {icon: AppIcons.phone, selectedIcon: AppIcons.phoneSelected, label: qsTr("Appels")}, - {icon: AppIcons.adressBook, selectedIcon: AppIcons.adressBookSelected, label: qsTr("Contacts")}, - {icon: AppIcons.chatTeardropText, selectedIcon: AppIcons.chatTeardropTextSelected, label: qsTr("Conversations")}, - {icon: AppIcons.videoconference, selectedIcon: AppIcons.videoconferenceSelected, label: qsTr("Réunions")} + {icon: AppIcons.phone, selectedIcon: AppIcons.phoneSelected, label: qsTr("Appels"), unreadNotifications: accountProxy.defaultAccount.core.unreadCallNotifications}, + {icon: AppIcons.adressBook, selectedIcon: AppIcons.adressBookSelected, label: qsTr("Contacts"), unreadNotifications: 0}, + {icon: AppIcons.chatTeardropText, selectedIcon: AppIcons.chatTeardropTextSelected, label: qsTr("Conversations"), unreadNotifications: accountProxy.defaultAccount.core.unreadMessageNotifications}, + {icon: AppIcons.videoconference, selectedIcon: AppIcons.videoconferenceSelected, label: qsTr("Réunions"), unreadNotifications: 0} ] - + onCurrentIndexChanged: { + if (currentIndex === 0) accountProxy.defaultAccount.core.lResetMissedCalls() + } } ColumnLayout { spacing:0 diff --git a/Linphone/view/Item/Contact/Contact.qml b/Linphone/view/Item/Contact/Contact.qml index 980908ee5..d1772d05e 100644 --- a/Linphone/view/Item/Contact/Contact.qml +++ b/Linphone/view/Item/Contact/Contact.qml @@ -96,22 +96,20 @@ Rectangle{ : qsTr("Erreur") } } - Item { - Layout.fillWidth: true - } + // Item { + // Layout.fillWidth: true + // } Item{ - Layout.preferredWidth: 22 * DefaultStyle.dp - Layout.preferredHeight: 22 * DefaultStyle.dp + Layout.preferredWidth: 27 * DefaultStyle.dp + Layout.preferredHeight: 27 * DefaultStyle.dp Layout.fillHeight: true Rectangle{ id: unreadNotifications - anchors.left: parent.left - anchors.leftMargin: 10 * DefaultStyle.dp anchors.verticalCenter: parent.verticalCenter property int unread: mainItem.account.core.unreadNotifications visible: unread > 0 - width: 22 * DefaultStyle.dp - height: 22 * DefaultStyle.dp + width: 27 * DefaultStyle.dp + height: 27 * DefaultStyle.dp radius: width/2 color: DefaultStyle.danger_500main border.color: DefaultStyle.grey_0 @@ -125,10 +123,18 @@ Rectangle{ color: DefaultStyle.grey_0 minimumPixelSize: 5 fontSizeMode: Text.Fit - font.pixelSize: 20 * DefaultStyle.dp - text: parent.unread > 100 ? '+' : parent.unread + font.pixelSize: 11 * DefaultStyle.dp + font.weight: 700 * DefaultStyle.dp + text: parent.unread > 100 ? '99+' : parent.unread } } + MultiEffect { + anchors.fill: unreadNotifications + source: unreadNotifications + shadowEnabled: true + shadowBlur: 0.1 + shadowOpacity: 0.15 + } } EffectImage { id: manageAccount diff --git a/Linphone/view/Item/Meeting/MeetingList.qml b/Linphone/view/Item/Meeting/MeetingList.qml index 13326d82a..049ee3199 100644 --- a/Linphone/view/Item/Meeting/MeetingList.qml +++ b/Linphone/view/Item/Meeting/MeetingList.qml @@ -14,12 +14,12 @@ ListView { property string searchBarText property bool hoverEnabled: true property var delegateButtons - property ConferenceInfoGui selectedConference: currentIndex != -1 ? model.getAt(currentIndex) : null + property ConferenceInfoGui selectedConference: model && currentIndex != -1 ? model.getAt(currentIndex) : null spacing: 8 * DefaultStyle.dp currentIndex: confInfoProxy.currentDateIndex - onCountChanged: selectedConference = currentIndex != -1 ? model.getAt(currentIndex) : null + onCountChanged: selectedConference = model && currentIndex != -1 ? model.getAt(currentIndex) : null onCurrentIndexChanged: { selectedConference = model.getAt(currentIndex) } diff --git a/Linphone/view/Item/VerticalTabBar.qml b/Linphone/view/Item/VerticalTabBar.qml index 0870350a1..10d165b09 100644 --- a/Linphone/view/Item/VerticalTabBar.qml +++ b/Linphone/view/Item/VerticalTabBar.qml @@ -12,6 +12,26 @@ Control.TabBar { property var model readonly property alias cornerRadius: bottomLeftCorner.radius + + component UnreadNotification: Rectangle { + id: unreadNotifications + property int unread: 0 + visible: unread > 0 + width: 15 * DefaultStyle.dp + height: 15 * DefaultStyle.dp + radius: width/2 + color: DefaultStyle.danger_500main + Text{ + id: unreadCount + anchors.fill: parent + verticalAlignment: Text.AlignVCenter + horizontalAlignment: Text.AlignHCenter + color: DefaultStyle.grey_0 + fontSizeMode: Text.Fit + font.pixelSize: 15 * DefaultStyle.dp + text: parent.unread > 100 ? '99+' : parent.unread + } + } contentItem: ListView { model: mainItem.contentModel @@ -61,6 +81,12 @@ Control.TabBar { id: tabButton width: mainItem.width + UnreadNotification { + unread: modelData.unreadNotifications + anchors.right: parent.right + anchors.rightMargin: 15 * DefaultStyle.dp + anchors.top: parent.top + } contentItem: ColumnLayout { // height: tabButton.height // width: tabButton.width diff --git a/Linphone/view/Page/Main/CallPage.qml b/Linphone/view/Page/Main/CallPage.qml index 035ec549e..351390551 100644 --- a/Linphone/view/Page/Main/CallPage.qml +++ b/Linphone/view/Page/Main/CallPage.qml @@ -97,7 +97,7 @@ AbstractMainPage { width: parent.width height: parent.height onLaunchCall: { - mainItem.createCall(UtilsCpp.generateLinphoneSipAddress(searchBar.text)) + UtilsCpp.createCall(searchBar.text) // TODO : auto completion instead of sip linphone } } @@ -315,7 +315,10 @@ AbstractMainPage { icon.width: 24 * DefaultStyle.dp icon.height: 24 * DefaultStyle.dp onClicked: { - mainItem.createCall(modelData.core.remoteAddress) + if (modelData.core.isConference) { + + } + else UtilsCpp.createCall(modelData.core.remoteAddress) } } } @@ -408,7 +411,7 @@ AbstractMainPage { searchBarColor: DefaultStyle.grey_100 onCallButtonPressed: (address) => { - mainItem.createCall(address) + UtilsCpp.createCall(address) // var window = UtilsCpp.getCallsWindow() } onGroupCallCreationRequested: {