From 2b5cb6bc64ef6fc7ff321481aaefb5133e2734fe Mon Sep 17 00:00:00 2001 From: Ronan Abhamon Date: Thu, 9 Feb 2017 14:37:12 +0100 Subject: [PATCH] feat(src/components/notifier/Notifier): supports messages & calls notifications --- linphone-desktop/assets/images/file_sign.svg | 13 +++ .../assets/images/message_sign.svg | 13 +++ linphone-desktop/resources.qrc | 12 +- linphone-desktop/src/app/App.cpp | 19 +-- linphone-desktop/src/app/App.hpp | 1 + .../src/components/call/CallModel.cpp | 13 +-- .../src/components/call/CallModel.hpp | 1 - .../src/components/calls/CallsListModel.cpp | 10 ++ .../src/components/calls/CallsListModel.hpp | 2 + .../src/components/camera/MSFunctions.cpp | 26 ++++- .../src/components/camera/MSFunctions.hpp | 22 ++++ .../src/components/chat/ChatModel.cpp | 3 + .../src/components/core/CoreHandlers.cpp | 7 +- .../src/components/core/CoreManager.cpp | 1 + .../src/components/core/CoreManager.hpp | 6 + .../src/components/notifier/Notifier.cpp | 85 +++++++++----- .../src/components/notifier/Notifier.hpp | 14 +-- linphone-desktop/src/main.cpp | 2 + .../ui/modules/Common/Popup/DesktopPopup.qml | 5 +- .../Linphone/Contact/MessagesCounter.qml | 6 +- .../Notifications/CallNotification.qml | 12 -- .../Linphone/Notifications/Notification.qml | 10 +- .../Notifications/Notification.spec.qml | 4 + .../NotificationReceivedCall.qml | 108 ++++++++++++++++++ .../NotificationReceivedFileMessage.qml | 80 +++++++++++++ .../NotificationReceivedMessage.qml | 100 ++++++++++++++++ .../ReceivedMessageNotification.qml | 12 -- .../NotificationReceivedCallStyle.qml | 22 ++++ .../NotificationReceivedFileMessageStyle.qml | 27 +++++ .../NotificationReceivedMessageStyle.qml | 28 +++++ .../{ => Notifications}/NotificationStyle.qml | 2 +- .../ui/modules/Linphone/Styles/qmldir | 27 +++-- linphone-desktop/ui/scripts/Utils/utils.js | 12 ++ .../ui/views/App/MainWindow/MainWindow.qml | 36 +++--- submodules/cmake-builder | 2 +- submodules/linphone | 2 +- 36 files changed, 616 insertions(+), 129 deletions(-) create mode 100644 linphone-desktop/assets/images/file_sign.svg create mode 100644 linphone-desktop/assets/images/message_sign.svg delete mode 100644 linphone-desktop/ui/modules/Linphone/Notifications/CallNotification.qml create mode 100644 linphone-desktop/ui/modules/Linphone/Notifications/NotificationReceivedCall.qml create mode 100644 linphone-desktop/ui/modules/Linphone/Notifications/NotificationReceivedFileMessage.qml create mode 100644 linphone-desktop/ui/modules/Linphone/Notifications/NotificationReceivedMessage.qml delete mode 100644 linphone-desktop/ui/modules/Linphone/Notifications/ReceivedMessageNotification.qml create mode 100644 linphone-desktop/ui/modules/Linphone/Styles/Notifications/NotificationReceivedCallStyle.qml create mode 100644 linphone-desktop/ui/modules/Linphone/Styles/Notifications/NotificationReceivedFileMessageStyle.qml create mode 100644 linphone-desktop/ui/modules/Linphone/Styles/Notifications/NotificationReceivedMessageStyle.qml rename linphone-desktop/ui/modules/Linphone/Styles/{ => Notifications}/NotificationStyle.qml (83%) diff --git a/linphone-desktop/assets/images/file_sign.svg b/linphone-desktop/assets/images/file_sign.svg new file mode 100644 index 000000000..fa89999c6 --- /dev/null +++ b/linphone-desktop/assets/images/file_sign.svg @@ -0,0 +1,13 @@ + + + + call_in_sign + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/linphone-desktop/assets/images/message_sign.svg b/linphone-desktop/assets/images/message_sign.svg new file mode 100644 index 000000000..fa89999c6 --- /dev/null +++ b/linphone-desktop/assets/images/message_sign.svg @@ -0,0 +1,13 @@ + + + + call_in_sign + Created with Sketch. + + + + + + + + \ No newline at end of file diff --git a/linphone-desktop/resources.qrc b/linphone-desktop/resources.qrc index d5ca3f940..f7423c29f 100644 --- a/linphone-desktop/resources.qrc +++ b/linphone-desktop/resources.qrc @@ -78,6 +78,7 @@ assets/images/edit_normal.svg assets/images/edit_pressed.svg assets/images/ended_call.svg + assets/images/file_sign.svg assets/images/filter.svg assets/images/fullscreen_hovered.svg assets/images/fullscreen_normal.svg @@ -101,6 +102,7 @@ assets/images/led_red.svg assets/images/led_white.svg assets/images/linphone.png + assets/images/message_sign.svg assets/images/micro_off_hovered.svg assets/images/micro_off_normal.svg assets/images/micro_off_pressed.svg @@ -228,9 +230,10 @@ ui/modules/Linphone/Contact/ContactDescription.qml ui/modules/Linphone/Contact/Contact.qml ui/modules/Linphone/Contact/MessagesCounter.qml - ui/modules/Linphone/Notifications/CallNotification.qml ui/modules/Linphone/Notifications/Notification.qml - ui/modules/Linphone/Notifications/ReceivedMessageNotification.qml + ui/modules/Linphone/Notifications/NotificationReceivedCall.qml + ui/modules/Linphone/Notifications/NotificationReceivedFileMessage.qml + ui/modules/Linphone/Notifications/NotificationReceivedMessage.qml ui/modules/Linphone/Presence/PresenceLevel.qml ui/modules/Linphone/Presence/PresenceString.qml ui/modules/Linphone/qmldir @@ -243,7 +246,10 @@ ui/modules/Linphone/Styles/Contact/ContactDescriptionStyle.qml ui/modules/Linphone/Styles/Contact/ContactStyle.qml ui/modules/Linphone/Styles/Contact/MessagesCounterStyle.qml - ui/modules/Linphone/Styles/NotificationStyle.qml + ui/modules/Linphone/Styles/Notifications/NotificationReceivedCallStyle.qml + ui/modules/Linphone/Styles/Notifications/NotificationReceivedFileMessageStyle.qml + ui/modules/Linphone/Styles/Notifications/NotificationReceivedMessageStyle.qml + ui/modules/Linphone/Styles/Notifications/NotificationStyle.qml ui/modules/Linphone/Styles/Presence/PresenceStringStyle.qml ui/modules/Linphone/Styles/qmldir ui/modules/Linphone/Styles/SmartSearchBarStyle.qml diff --git a/linphone-desktop/src/app/App.cpp b/linphone-desktop/src/app/App.cpp index 51d63c66c..f042a69a7 100644 --- a/linphone-desktop/src/app/App.cpp +++ b/linphone-desktop/src/app/App.cpp @@ -92,10 +92,13 @@ QQuickWindow *App::getCallsWindow () const { return window; } -bool App::hasFocus () const { +QQuickWindow *App::getMainWindow () const { QQmlApplicationEngine &engine = const_cast(m_engine); - const QQuickWindow *root = qobject_cast(engine.rootObjects().at(0)); - return !!root->activeFocusItem(); + return qobject_cast(engine.rootObjects().at(0)); +} + +bool App::hasFocus () const { + return getMainWindow()->isActive() || getCallsWindow()->isActive(); } // ----------------------------------------------------------------------------- @@ -109,6 +112,9 @@ void App::initContentApp () { registerTypes(); addContextProperties(); + // Enable notifications. + m_notifier = new Notifier(); + CoreManager::getInstance()->enableHandlers(); // Load main view. @@ -167,7 +173,7 @@ void App::registerTypes () { qmlRegisterSingletonType( "Linphone", 1, 0, "CallsListModel", [](QQmlEngine *, QJSEngine *) -> QObject *{ - return new CallsListModel(); + return CoreManager::getInstance()->getCallsListModel(); } ); @@ -219,13 +225,10 @@ void App::addContextProperties () { } context->setContextProperty("CallsWindow", component.create()); - - m_notifier = new Notifier(); - context->setContextProperty("Notifier", m_notifier); } void App::setTrayIcon () { - QQuickWindow *root = qobject_cast(m_engine.rootObjects().at(0)); + QQuickWindow *root = getMainWindow(); QMenu *menu = new QMenu(); m_system_tray_icon = new QSystemTrayIcon(root); diff --git a/linphone-desktop/src/app/App.hpp b/linphone-desktop/src/app/App.hpp index d89786c94..c79549520 100644 --- a/linphone-desktop/src/app/App.hpp +++ b/linphone-desktop/src/app/App.hpp @@ -49,6 +49,7 @@ public: } QQuickWindow *getCallsWindow () const; + QQuickWindow *getMainWindow () const; bool hasFocus () const; diff --git a/linphone-desktop/src/components/call/CallModel.cpp b/linphone-desktop/src/components/call/CallModel.cpp index 41d3f3d13..d69e2b639 100644 --- a/linphone-desktop/src/components/call/CallModel.cpp +++ b/linphone-desktop/src/components/call/CallModel.cpp @@ -226,18 +226,15 @@ float CallModel::getQuality () const { } bool CallModel::getMicroMuted () const { - return m_micro_muted; + return !CoreManager::getInstance()->getCore()->micEnabled(); } void CallModel::setMicroMuted (bool status) { - if (m_micro_muted != status) { - m_micro_muted = status; + shared_ptr core = CoreManager::getInstance()->getCore(); - shared_ptr core = CoreManager::getInstance()->getCore(); - if (m_micro_muted == core->micEnabled()) - core->enableMic(!m_micro_muted); - - emit microMutedChanged(m_micro_muted); + if (status != core->micEnabled()) { + core->enableMic(!status); + emit microMutedChanged(status); } } diff --git a/linphone-desktop/src/components/call/CallModel.hpp b/linphone-desktop/src/components/call/CallModel.hpp index 6f0bee527..13dc5b417 100644 --- a/linphone-desktop/src/components/call/CallModel.hpp +++ b/linphone-desktop/src/components/call/CallModel.hpp @@ -109,7 +109,6 @@ private: bool getRecording () const; - bool m_micro_muted = false; bool m_paused_by_remote = false; bool m_paused_by_user = false; bool m_recording = false; diff --git a/linphone-desktop/src/components/calls/CallsListModel.cpp b/linphone-desktop/src/components/calls/CallsListModel.cpp index 3ab091835..791eba248 100644 --- a/linphone-desktop/src/components/calls/CallsListModel.cpp +++ b/linphone-desktop/src/components/calls/CallsListModel.cpp @@ -81,6 +81,16 @@ QVariant CallsListModel::data (const QModelIndex &index, int role) const { return QVariant(); } +CallModel *CallsListModel::getCall (const shared_ptr &linphone_call) const { + auto it = find_if( + m_list.begin(), m_list.end(), [linphone_call](CallModel *call) { + return linphone_call == call->getLinphoneCall(); + } + ); + + return it != m_list.end() ? *it : nullptr; +} + // ----------------------------------------------------------------------------- void CallsListModel::launchAudioCall (const QString &sip_uri) const { diff --git a/linphone-desktop/src/components/calls/CallsListModel.hpp b/linphone-desktop/src/components/calls/CallsListModel.hpp index 03cf40255..f3d485469 100644 --- a/linphone-desktop/src/components/calls/CallsListModel.hpp +++ b/linphone-desktop/src/components/calls/CallsListModel.hpp @@ -43,6 +43,8 @@ public: QHash roleNames () const override; QVariant data (const QModelIndex &index, int role = Qt::DisplayRole) const override; + CallModel *getCall (const std::shared_ptr &linphone_call) const; + Q_INVOKABLE void launchAudioCall (const QString &sip_uri) const; Q_INVOKABLE void launchVideoCall (const QString &sip_uri) const; diff --git a/linphone-desktop/src/components/camera/MSFunctions.cpp b/linphone-desktop/src/components/camera/MSFunctions.cpp index 1fd826ed5..c6945645a 100644 --- a/linphone-desktop/src/components/camera/MSFunctions.cpp +++ b/linphone-desktop/src/components/camera/MSFunctions.cpp @@ -1,10 +1,30 @@ -#include +/* + * MSFunctions.cpp + * Copyright (C) 2017 Belledonne Communications, Grenoble, France + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Created on: February 9, 2017 + * Author: Ronan Abhamon + */ + +#include "MSFunctions.hpp" // Do not include this header before `QOpenGLFunctions`!!! #include -#include "MSFunctions.hpp" - // ============================================================================= MSFunctions *MSFunctions::m_instance = nullptr; diff --git a/linphone-desktop/src/components/camera/MSFunctions.hpp b/linphone-desktop/src/components/camera/MSFunctions.hpp index 9b1fc7624..e47fd91ea 100644 --- a/linphone-desktop/src/components/camera/MSFunctions.hpp +++ b/linphone-desktop/src/components/camera/MSFunctions.hpp @@ -1,3 +1,25 @@ +/* + * MSFunctions.hpp + * Copyright (C) 2017 Belledonne Communications, Grenoble, France + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Created on: February 9, 2017 + * Author: Ronan Abhamon + */ + #ifndef MS_FUNCTIONS_H_ #define MS_FUNCTIONS_H_ diff --git a/linphone-desktop/src/components/chat/ChatModel.cpp b/linphone-desktop/src/components/chat/ChatModel.cpp index 604ecb774..e2fa8a0e7 100644 --- a/linphone-desktop/src/components/chat/ChatModel.cpp +++ b/linphone-desktop/src/components/chat/ChatModel.cpp @@ -30,6 +30,7 @@ #include #include +#include "../../app/App.hpp" #include "../../app/Paths.hpp" #include "../../app/ThumbnailProvider.hpp" #include "../../utils.hpp" @@ -150,9 +151,11 @@ private: if (it == m_chat_model->m_entries.end()) return; + // File message downloaded. if (state == linphone::ChatMessageStateFileTransferDone && !message->isOutgoing()) { createThumbnail(message); fillThumbnailProperty((*it).first, message); + App::getInstance()->getNotifier()->notifyReceivedFileMessage(message); } (*it).first["status"] = state; diff --git a/linphone-desktop/src/components/core/CoreHandlers.cpp b/linphone-desktop/src/components/core/CoreHandlers.cpp index 9558a30bb..63594c44c 100644 --- a/linphone-desktop/src/components/core/CoreHandlers.cpp +++ b/linphone-desktop/src/components/core/CoreHandlers.cpp @@ -46,16 +46,19 @@ void CoreHandlers::onCallStateChanged ( const string & ) { emit callStateChanged(call, state); + + if (call->getState() == linphone::CallStateIncomingReceived) + App::getInstance()->getNotifier()->notifyReceivedCall(call); } void CoreHandlers::onMessageReceived ( const shared_ptr &, - const shared_ptr &room, + const shared_ptr &, const shared_ptr &message ) { emit messageReceived(message); const App *app = App::getInstance(); if (!app->hasFocus()) - app->getNotifier()->notifyReceivedMessage(10000, room, message); + app->getNotifier()->notifyReceivedMessage(message); } diff --git a/linphone-desktop/src/components/core/CoreManager.cpp b/linphone-desktop/src/components/core/CoreManager.cpp index f23b68527..a4608bb7e 100644 --- a/linphone-desktop/src/components/core/CoreManager.cpp +++ b/linphone-desktop/src/components/core/CoreManager.cpp @@ -49,6 +49,7 @@ void CoreManager::init () { if (!m_instance) { m_instance = new CoreManager(); + m_instance->m_calls_list_model = new CallsListModel(m_instance); m_instance->m_contacts_list_model = new ContactsListModel(m_instance); m_instance->m_sip_addresses_model = new SipAddressesModel(m_instance); diff --git a/linphone-desktop/src/components/core/CoreManager.hpp b/linphone-desktop/src/components/core/CoreManager.hpp index 371bff72e..fd0990332 100644 --- a/linphone-desktop/src/components/core/CoreManager.hpp +++ b/linphone-desktop/src/components/core/CoreManager.hpp @@ -23,6 +23,7 @@ #ifndef CORE_MANAGER_H_ #define CORE_MANAGER_H_ +#include "../calls/CallsListModel.hpp" #include "../contacts/ContactsListModel.hpp" #include "../sip-addresses/SipAddressesModel.hpp" #include "CoreHandlers.hpp" @@ -51,6 +52,10 @@ public: // Singleton models. // --------------------------------------------------------------------------- + CallsListModel *getCallsListModel () const { + return m_calls_list_model; + } + ContactsListModel *getContactsListModel () const { return m_contacts_list_model; } @@ -83,6 +88,7 @@ private: std::shared_ptr m_core; std::shared_ptr m_handlers; + CallsListModel *m_calls_list_model; ContactsListModel *m_contacts_list_model; SipAddressesModel *m_sip_addresses_model; diff --git a/linphone-desktop/src/components/notifier/Notifier.cpp b/linphone-desktop/src/components/notifier/Notifier.cpp index 2196b2071..2ef877033 100644 --- a/linphone-desktop/src/components/notifier/Notifier.cpp +++ b/linphone-desktop/src/components/notifier/Notifier.cpp @@ -20,23 +20,31 @@ * Author: Ronan Abhamon */ -#include "../../app/App.hpp" - -#include "Notifier.hpp" - #include #include #include #include +#include "../../app/App.hpp" +#include "../../utils.hpp" +#include "../core/CoreManager.hpp" + +#include "Notifier.hpp" + // Notifications QML properties/methods. #define NOTIFICATION_SHOW_METHOD_NAME "show" -#define NOTIFICATION_HEIGHT_PROPERTY "notificationHeight" -#define NOTIFICATION_OFFSET_PROPERTY_NAME "notificationOffset" +#define NOTIFICATION_PROPERTY_DATA "notificationData" +#define NOTIFICATION_PROPERTY_HEIGHT "notificationHeight" +#define NOTIFICATION_PROPERTY_OFFSET "notificationOffset" -#define QML_CALL_NOTIFICATION_PATH "qrc:/ui/modules/Linphone/Notifications/CallNotification.qml" -#define QML_MESSAGE_RECEIVED_NOTIFICATION_PATH "qrc:/ui/modules/Linphone/Notifications/ReceivedMessageNotification.qml" +#define QML_NOTIFICATION_PATH_RECEIVED_MESSAGE "qrc:/ui/modules/Linphone/Notifications/NotificationReceivedMessage.qml" +#define QML_NOTIFICATION_PATH_RECEIVED_FILE_MESSAGE "qrc:/ui/modules/Linphone/Notifications/NotificationReceivedFileMessage.qml" +#define QML_NOTIFICATION_PATH_RECEIVED_CALL "qrc:/ui/modules/Linphone/Notifications/NotificationReceivedCall.qml" + +#define NOTIFICATION_TIMEOUT_RECEIVED_MESSAGE 10000 +#define NOTIFICATION_TIMEOUT_RECEIVED_FILE_MESSAGE 10000 +#define NOTIFICATION_TIMEOUT_RECEIVED_CALL 10000 // Arbitrary hardcoded values. #define NOTIFICATION_SPACING 10 @@ -77,22 +85,22 @@ Notifier::Notifier (QObject *parent) : QQmlEngine *engine = App::getInstance()->getEngine(); // Build components. - m_components[Notifier::Call] = new QQmlComponent(engine, QUrl(QML_CALL_NOTIFICATION_PATH)); - m_components[Notifier::MessageReceived] = new QQmlComponent(engine, QUrl(QML_MESSAGE_RECEIVED_NOTIFICATION_PATH)); + m_components[Notifier::MessageReceived] = new QQmlComponent(engine, QUrl(QML_NOTIFICATION_PATH_RECEIVED_MESSAGE)); + m_components[Notifier::FileMessageReceived] = new QQmlComponent(engine, QUrl(QML_NOTIFICATION_PATH_RECEIVED_FILE_MESSAGE)); + m_components[Notifier::CallReceived] = new QQmlComponent(engine, QUrl(QML_NOTIFICATION_PATH_RECEIVED_CALL)); // Check errors. for (int i = 0; i < Notifier::MaxNbTypes; ++i) { QQmlComponent *component = m_components[i]; if (component->isError()) { - qWarning() << QStringLiteral("Errors found in `Notification` component %1:").arg(i) << - component->errors(); + qWarning() << QStringLiteral("Errors found in `Notification` component %1:").arg(i) << component->errors(); abort(); } } } Notifier::~Notifier () { - for (int i = 0; i < Notifier::MaxNbTypes; i++) + for (int i = 0; i < Notifier::MaxNbTypes; ++i) delete m_components[i]; } @@ -110,9 +118,9 @@ QObject *Notifier::createNotification (Notifier::NotificationType type) { // Create instance and set attributes. QObject *object = m_components[type]->create(); - int offset = getNotificationSize(*object, NOTIFICATION_HEIGHT_PROPERTY); + int offset = getNotificationSize(*object, NOTIFICATION_PROPERTY_HEIGHT); - if (offset == -1 || !::setProperty(*object, NOTIFICATION_OFFSET_PROPERTY_NAME, m_offset)) { + if (offset == -1 || !::setProperty(*object, NOTIFICATION_PROPERTY_OFFSET, m_offset)) { delete object; m_mutex.unlock(); return nullptr; @@ -149,7 +157,7 @@ void Notifier::showNotification (QObject *notification, int timeout) { qInfo() << "Update notifications counter, hidden notification detected."; if (visible) - qFatal("A notification cannot be visible twice!"); + qWarning("A notification cannot be visible twice!"); m_mutex.lock(); @@ -172,20 +180,41 @@ void Notifier::showNotification (QObject *notification, int timeout) { // ----------------------------------------------------------------------------- -void Notifier::notifyReceivedMessage ( - int timeout, - const shared_ptr &room, - const shared_ptr &message -) { - QObject *object = createNotification(Notifier::MessageReceived); +void Notifier::notifyReceivedMessage (const shared_ptr &message) { + QObject *notification = createNotification(Notifier::MessageReceived); + if (!notification) + return; - if (object) - showNotification(object, timeout); + QVariantMap map; + map["message"] = ::Utils::linphoneStringToQString(message->getText()); + map["sipAddress"] = ::Utils::linphoneStringToQString(message->getFromAddress()->asStringUriOnly()); + map["window"].setValue(App::getInstance()->getMainWindow()); + + ::setProperty(*notification, NOTIFICATION_PROPERTY_DATA, map); + showNotification(notification, NOTIFICATION_TIMEOUT_RECEIVED_MESSAGE); } -void Notifier::showCallMessage (int timeout, const QString &) { - QObject *object = createNotification(Notifier::Call); +void Notifier::notifyReceivedFileMessage (const shared_ptr &message) { + QObject *notification = createNotification(Notifier::FileMessageReceived); + if (!notification) + return; - if (object) - showNotification(object, timeout); + QVariantMap map; + map["fileUri"] = ::Utils::linphoneStringToQString(message->getFileTransferFilepath()); + map["fileSize"] = static_cast(message->getFileTransferInformation()->getSize()); + + ::setProperty(*notification, NOTIFICATION_PROPERTY_DATA, map); + showNotification(notification, NOTIFICATION_TIMEOUT_RECEIVED_FILE_MESSAGE); +} + +void Notifier::notifyReceivedCall (const shared_ptr &call) { + QObject *notification = createNotification(Notifier::CallReceived); + if (!notification) + return; + + QVariantMap map; + map["call"].setValue(CoreManager::getInstance()->getCallsListModel()->getCall(call)); + + ::setProperty(*notification, NOTIFICATION_PROPERTY_DATA, map); + showNotification(notification, NOTIFICATION_TIMEOUT_RECEIVED_CALL); } diff --git a/linphone-desktop/src/components/notifier/Notifier.hpp b/linphone-desktop/src/components/notifier/Notifier.hpp index 88021f40d..31f966049 100644 --- a/linphone-desktop/src/components/notifier/Notifier.hpp +++ b/linphone-desktop/src/components/notifier/Notifier.hpp @@ -40,19 +40,15 @@ public: ~Notifier (); enum NotificationType { - Call, MessageReceived, + FileMessageReceived, + CallReceived, MaxNbTypes }; - void notifyReceivedMessage ( - int timeout, - const std::shared_ptr &room, - const std::shared_ptr &message - ); - - // TODO - void showCallMessage (int timeout, const QString &); + void notifyReceivedMessage (const std::shared_ptr &message); + void notifyReceivedFileMessage (const std::shared_ptr &message); + void notifyReceivedCall (const std::shared_ptr &call); private: QObject *createNotification (NotificationType type); diff --git a/linphone-desktop/src/main.cpp b/linphone-desktop/src/main.cpp index 46eea6efa..235db5d1b 100644 --- a/linphone-desktop/src/main.cpp +++ b/linphone-desktop/src/main.cpp @@ -28,6 +28,8 @@ int main (int argc, char *argv[]) { Logger::init(); + QCoreApplication::setAttribute(Qt::AA_UseOpenGLES, true); + // Force shader version 2.0. QSurfaceFormat fmt; fmt.setVersion(2, 0); diff --git a/linphone-desktop/ui/modules/Common/Popup/DesktopPopup.qml b/linphone-desktop/ui/modules/Common/Popup/DesktopPopup.qml index 391363283..3ec156e87 100644 --- a/linphone-desktop/ui/modules/Common/Popup/DesktopPopup.qml +++ b/linphone-desktop/ui/modules/Common/Popup/DesktopPopup.qml @@ -77,7 +77,10 @@ Item { to: 'opened' ScriptAction { - script: popup.showNormal() + script: { + popup.showNormal() + popup.requestActivate() + } } NumberAnimation { diff --git a/linphone-desktop/ui/modules/Linphone/Contact/MessagesCounter.qml b/linphone-desktop/ui/modules/Linphone/Contact/MessagesCounter.qml index eb019ed36..a29f97606 100644 --- a/linphone-desktop/ui/modules/Linphone/Contact/MessagesCounter.qml +++ b/linphone-desktop/ui/modules/Linphone/Contact/MessagesCounter.qml @@ -23,8 +23,10 @@ Item { iconSize: MessagesCounterStyle.iconSize.message Icon { - anchors.horizontalCenter: parent.right - anchors.verticalCenter: parent.bottom + anchors { + horizontalCenter: parent.right + verticalCenter: parent.bottom + } icon: 'chat_amount' iconSize: MessagesCounterStyle.iconSize.amount diff --git a/linphone-desktop/ui/modules/Linphone/Notifications/CallNotification.qml b/linphone-desktop/ui/modules/Linphone/Notifications/CallNotification.qml deleted file mode 100644 index e25e060f0..000000000 --- a/linphone-desktop/ui/modules/Linphone/Notifications/CallNotification.qml +++ /dev/null @@ -1,12 +0,0 @@ -import QtQuick 2.7 - -// ============================================================================= - -Notification { - Rectangle { - color: 'red' - - width: 200 - height: 100 - } -} diff --git a/linphone-desktop/ui/modules/Linphone/Notifications/Notification.qml b/linphone-desktop/ui/modules/Linphone/Notifications/Notification.qml index 7204d3e85..ed859fd6a 100644 --- a/linphone-desktop/ui/modules/Linphone/Notifications/Notification.qml +++ b/linphone-desktop/ui/modules/Linphone/Notifications/Notification.qml @@ -15,15 +15,19 @@ DesktopPopup { // --------------------------------------------------------------------------- - property int notificationOffset: 0 property alias notificationHeight: notification.popupHeight + property int notificationOffset: 0 + property var notificationData: null + + readonly property var window: _window + property var _window // --------------------------------------------------------------------------- flags: Qt.Popup Component.onCompleted: { - var window = data[0] + var window = _window = data[0] Utils.assert( Utils.qmlTypeof(window, 'QQuickWindowQmlImpl'), true, @@ -45,7 +49,7 @@ DesktopPopup { } var height = screen.desktopAvailableHeight - window.height - return height - notificationOffset % height + return height - (notificationOffset % height) }) } } diff --git a/linphone-desktop/ui/modules/Linphone/Notifications/Notification.spec.qml b/linphone-desktop/ui/modules/Linphone/Notifications/Notification.spec.qml index 2f9839805..f1398a92f 100644 --- a/linphone-desktop/ui/modules/Linphone/Notifications/Notification.spec.qml +++ b/linphone-desktop/ui/modules/Linphone/Notifications/Notification.spec.qml @@ -11,6 +11,10 @@ TestCase { id: notification } + function test_notificationDataProperty () { + compare(Utils.isObject(notification.notificationData), true) + } + function test_notificationHeightProperty () { compare(Utils.isInteger(notification.notificationHeight), true) } diff --git a/linphone-desktop/ui/modules/Linphone/Notifications/NotificationReceivedCall.qml b/linphone-desktop/ui/modules/Linphone/Notifications/NotificationReceivedCall.qml new file mode 100644 index 000000000..0794e5298 --- /dev/null +++ b/linphone-desktop/ui/modules/Linphone/Notifications/NotificationReceivedCall.qml @@ -0,0 +1,108 @@ +import QtQuick 2.7 +import QtQuick.Layouts 1.3 + +import Common 1.0 +import Linphone 1.0 +import Linphone.Styles 1.0 + +// ============================================================================= + +Notification { + id: notification + + // --------------------------------------------------------------------------- + + property var _call: notificationData && notificationData.call + property var _contact: _contactObserver.contact + property var _contactObserver: SipAddressesModel.getContactObserver(_call ? _call.sipAddress : '') + + // --------------------------------------------------------------------------- + + function _close (cb) { + notification.window.setVisible(false) + cb() + } + + // --------------------------------------------------------------------------- + + Rectangle { + color: NotificationReceivedCallStyle.color + height: NotificationReceivedCallStyle.height + width: NotificationReceivedCallStyle.width + + Icon { + anchors { + left: parent.left + top: parent.top + } + + icon: 'call_sign_incoming' + iconSize: NotificationReceivedCallStyle.iconSize + } + + Loader { + active: notification._call + anchors { + fill: parent + + leftMargin: NotificationReceivedCallStyle.leftMargin + rightMargin: NotificationReceivedCallStyle.rightMargin + bottomMargin: NotificationReceivedCallStyle.bottomMargin + } + + sourceComponent: ColumnLayout { + spacing: NotificationReceivedCallStyle.spacing + + Contact { + Layout.fillWidth: true + + entry: ({ + contact: notification._contact, + sipAddress: notification._contactObserver.sipAddress + }) + } + + // --------------------------------------------------------------------- + // Action buttons. + // --------------------------------------------------------------------- + + Item { + Layout.fillHeight: true + Layout.fillWidth: true + + ActionBar { + anchors.centerIn: parent + iconSize: NotificationReceivedCallStyle.actionArea.iconSize + + ActionButton { + icon: 'video_call_accept' + + onClicked: notification._close(notification._call.acceptWithVideo) + } + + ActionButton { + icon: 'call_accept' + + onClicked: notification._close(notification._call.accept) + } + } + + ActionBar { + anchors { + right: parent.right + rightMargin: NotificationReceivedCallStyle.actionArea.rightButtonsGroupMargin + verticalCenter: parent.verticalCenter + } + iconSize: NotificationReceivedCallStyle.actionArea.iconSize + + ActionButton { + icon: 'hangup' + + onClicked: notification._close(notification._call.terminate) + } + } + } + } + } + } +} diff --git a/linphone-desktop/ui/modules/Linphone/Notifications/NotificationReceivedFileMessage.qml b/linphone-desktop/ui/modules/Linphone/Notifications/NotificationReceivedFileMessage.qml new file mode 100644 index 000000000..2651ef2f8 --- /dev/null +++ b/linphone-desktop/ui/modules/Linphone/Notifications/NotificationReceivedFileMessage.qml @@ -0,0 +1,80 @@ +import QtQuick 2.7 +import QtQuick.Layouts 1.3 + +import Common 1.0 +import Linphone 1.0 +import Linphone.Styles 1.0 +import Utils 1.0 + +// ============================================================================= + +Notification { + id: notification + + // --------------------------------------------------------------------------- + + property string _fileUri: notificationData ? notificationData.fileUri : '' + + // --------------------------------------------------------------------------- + + Rectangle { + color: NotificationReceivedFileMessageStyle.color + height: NotificationReceivedFileMessageStyle.height + width: NotificationReceivedFileMessageStyle.width + + Icon { + anchors { + left: parent.left + top: parent.top + } + + icon: 'file_sign' + iconSize: NotificationReceivedFileMessageStyle.iconSize + } + + Loader { + active: notification._fileUri.length > 0 + anchors { + fill: parent + + leftMargin: NotificationReceivedFileMessageStyle.leftMargin + rightMargin: NotificationReceivedFileMessageStyle.rightMargin + } + + sourceComponent: RowLayout { + anchors.fill: parent + spacing: NotificationReceivedFileMessageStyle.spacing + + Text { + Layout.fillWidth: true + + color: NotificationReceivedFileMessageStyle.fileName.color + elide: Text.ElideRight + font.pointSize: NotificationReceivedFileMessageStyle.fileName.fontSize + text: Utils.basename(notification._fileUri) + } + + Text { + Layout.preferredWidth: NotificationReceivedFileMessageStyle.fileSize.width + + color: NotificationReceivedFileMessageStyle.fileSize.color + elide: Text.ElideRight + font.pointSize: NotificationReceivedFileMessageStyle.fileSize.fontSize + horizontalAlignment: Text.AlignRight + text: Utils.formatSize(notification.notificationData.fileSize) + } + } + + MouseArea { + anchors.fill: parent + cursorShape: containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor + hoverEnabled: true + + onClicked: { + notification.window.setVisible(false) + Qt.openUrlExternally('file://' + Utils.dirname(notification._fileUri)) + } + } + } + } +} diff --git a/linphone-desktop/ui/modules/Linphone/Notifications/NotificationReceivedMessage.qml b/linphone-desktop/ui/modules/Linphone/Notifications/NotificationReceivedMessage.qml new file mode 100644 index 000000000..952ceb886 --- /dev/null +++ b/linphone-desktop/ui/modules/Linphone/Notifications/NotificationReceivedMessage.qml @@ -0,0 +1,100 @@ +import QtQuick 2.7 +import QtQuick.Layouts 1.3 + +import Common 1.0 +import Linphone 1.0 +import Linphone.Styles 1.0 + +// ============================================================================= + +Notification { + id: notification + + // --------------------------------------------------------------------------- + + property string _sipAddress: notificationData ? notificationData.sipAddress : '' + property var _contact: _contactObserver.contact + property var _contactObserver: SipAddressesModel.getContactObserver(_sipAddress) + + // --------------------------------------------------------------------------- + + Rectangle { + color: NotificationReceivedMessageStyle.color + height: NotificationReceivedMessageStyle.height + width: NotificationReceivedMessageStyle.width + + Icon { + anchors { + left: parent.left + top: parent.top + } + + icon: 'message_sign' + iconSize: NotificationReceivedMessageStyle.iconSize + } + + Loader { + active: notification._sipAddress.length > 0 + anchors { + fill: parent + + leftMargin: NotificationReceivedMessageStyle.leftMargin + rightMargin: NotificationReceivedMessageStyle.rightMargin + bottomMargin: NotificationReceivedMessageStyle.bottomMargin + } + + sourceComponent: ColumnLayout { + spacing: NotificationReceivedMessageStyle.spacing + + Contact { + Layout.fillWidth: true + + entry: ({ + contact: notification._contact, + sipAddress: notification._sipAddress + }) + } + + Rectangle { + Layout.fillHeight: true + Layout.fillWidth: true + + color: NotificationReceivedMessageStyle.messageContainer.color + radius: NotificationReceivedMessageStyle.messageContainer.radius + + Text { + anchors { + fill: parent + margins: NotificationReceivedMessageStyle.messageContainer.margins + } + + color: NotificationReceivedMessageStyle.messageContainer.text.color + elide: Text.ElideRight + + font { + italic: true + pointSize: NotificationReceivedMessageStyle.messageContainer.text.fontSize + } + + verticalAlignment: Text.AlignVCenter + text: notification.notificationData.message + wrapMode: Text.Wrap + } + } + } + } + + MouseArea { + anchors.fill: parent + cursorShape: containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor + hoverEnabled: true + + onClicked: { + notification.window.setVisible(false) + notification.notificationData.window.setView('Conversation', { + sipAddress: notification._sipAddress + }) + } + } + } +} diff --git a/linphone-desktop/ui/modules/Linphone/Notifications/ReceivedMessageNotification.qml b/linphone-desktop/ui/modules/Linphone/Notifications/ReceivedMessageNotification.qml deleted file mode 100644 index e25e060f0..000000000 --- a/linphone-desktop/ui/modules/Linphone/Notifications/ReceivedMessageNotification.qml +++ /dev/null @@ -1,12 +0,0 @@ -import QtQuick 2.7 - -// ============================================================================= - -Notification { - Rectangle { - color: 'red' - - width: 200 - height: 100 - } -} diff --git a/linphone-desktop/ui/modules/Linphone/Styles/Notifications/NotificationReceivedCallStyle.qml b/linphone-desktop/ui/modules/Linphone/Styles/Notifications/NotificationReceivedCallStyle.qml new file mode 100644 index 000000000..041149984 --- /dev/null +++ b/linphone-desktop/ui/modules/Linphone/Styles/Notifications/NotificationReceivedCallStyle.qml @@ -0,0 +1,22 @@ +pragma Singleton +import QtQuick 2.7 + +import Common 1.0 + +// ============================================================================= + +QtObject { + property color color: Colors.k + property int height: 120 + property int iconSize: 40 + property int spacing: 0 + property int width: 300 + property int bottomMargin: 15 + property int leftMargin: 15 + property int rightMargin: 15 + + property QtObject actionArea: QtObject { + property int iconSize: 40 + property int rightButtonsGroupMargin: 15 + } +} diff --git a/linphone-desktop/ui/modules/Linphone/Styles/Notifications/NotificationReceivedFileMessageStyle.qml b/linphone-desktop/ui/modules/Linphone/Styles/Notifications/NotificationReceivedFileMessageStyle.qml new file mode 100644 index 000000000..4f63c33fd --- /dev/null +++ b/linphone-desktop/ui/modules/Linphone/Styles/Notifications/NotificationReceivedFileMessageStyle.qml @@ -0,0 +1,27 @@ +pragma Singleton +import QtQuick 2.7 + +import Common 1.0 + +// ============================================================================= + +QtObject { + property color color: Colors.k + property int height: 55 + property int iconSize: 40 + property int leftMargin: 25 + property int rightMargin: 15 + property int spacing: 10 + property int width: 300 + + property QtObject fileName: QtObject { + property color color: Colors.h + property int fontSize: 10 + } + + property QtObject fileSize: QtObject { + property color color: Colors.h + property int fontSize: 9 + property int width: 100 + } +} diff --git a/linphone-desktop/ui/modules/Linphone/Styles/Notifications/NotificationReceivedMessageStyle.qml b/linphone-desktop/ui/modules/Linphone/Styles/Notifications/NotificationReceivedMessageStyle.qml new file mode 100644 index 000000000..ba4fc35f9 --- /dev/null +++ b/linphone-desktop/ui/modules/Linphone/Styles/Notifications/NotificationReceivedMessageStyle.qml @@ -0,0 +1,28 @@ +pragma Singleton +import QtQuick 2.7 + +import Common 1.0 + +// ============================================================================= + +QtObject { + property color color: Colors.k + property int bottomMargin: 15 + property int iconSize: 40 + property int leftMargin: 15 + property int rightMargin: 15 + property int spacing: 0 + property int width: 300 + property int height: 120 + + property QtObject messageContainer: QtObject { + property color color: Colors.m + property int radius: 6 + property int margins: 10 + + property QtObject text: QtObject { + property color color: Colors.l + property int fontSize: 9 + } + } +} diff --git a/linphone-desktop/ui/modules/Linphone/Styles/NotificationStyle.qml b/linphone-desktop/ui/modules/Linphone/Styles/Notifications/NotificationStyle.qml similarity index 83% rename from linphone-desktop/ui/modules/Linphone/Styles/NotificationStyle.qml rename to linphone-desktop/ui/modules/Linphone/Styles/Notifications/NotificationStyle.qml index 6d38e663b..50b95a441 100644 --- a/linphone-desktop/ui/modules/Linphone/Styles/NotificationStyle.qml +++ b/linphone-desktop/ui/modules/Linphone/Styles/Notifications/NotificationStyle.qml @@ -4,5 +4,5 @@ import QtQuick 2.7 // ============================================================================= QtObject { - property int margin: 10 + property int margin: 0 } diff --git a/linphone-desktop/ui/modules/Linphone/Styles/qmldir b/linphone-desktop/ui/modules/Linphone/Styles/qmldir index 0975f56a2..4f24185e9 100644 --- a/linphone-desktop/ui/modules/Linphone/Styles/qmldir +++ b/linphone-desktop/ui/modules/Linphone/Styles/qmldir @@ -4,22 +4,25 @@ module Linphone.Style # Components styles ------------------------------------------------------------ -singleton AccountStatusStyle 1.0 Account/AccountStatusStyle.qml +singleton AccountStatusStyle 1.0 Account/AccountStatusStyle.qml -singleton ChatStyle 1.0 ChatStyle.qml +singleton ChatStyle 1.0 ChatStyle.qml -singleton CallsStyle 1.0 Calls/CallsStyle.qml -singleton CallControlsStyle 1.0 Calls/CallControlsStyle.qml +singleton CallsStyle 1.0 Calls/CallsStyle.qml +singleton CallControlsStyle 1.0 Calls/CallControlsStyle.qml -singleton AvatarStyle 1.0 Contact/AvatarStyle.qml -singleton ContactDescriptionStyle 1.0 Contact/ContactDescriptionStyle.qml -singleton ContactStyle 1.0 Contact/ContactStyle.qml -singleton MessagesCounterStyle 1.0 Contact/MessagesCounterStyle.qml +singleton AvatarStyle 1.0 Contact/AvatarStyle.qml +singleton ContactDescriptionStyle 1.0 Contact/ContactDescriptionStyle.qml +singleton ContactStyle 1.0 Contact/ContactStyle.qml +singleton MessagesCounterStyle 1.0 Contact/MessagesCounterStyle.qml -singleton NotificationStyle 1.0 NotificationStyle.qml +singleton NotificationStyle 1.0 Notifications/NotificationStyle.qml +singleton NotificationReceivedCallStyle 1.0 Notifications/NotificationReceivedCallStyle.qml +singleton NotificationReceivedMessageStyle 1.0 Notifications/NotificationReceivedMessageStyle.qml +singleton NotificationReceivedFileMessageStyle 1.0 Notifications/NotificationReceivedFileMessageStyle.qml -singleton PresenceStringStyle 1.0 Presence/PresenceStringStyle.qml +singleton PresenceStringStyle 1.0 Presence/PresenceStringStyle.qml -singleton SmartSearchBarStyle 1.0 SmartSearchBarStyle.qml +singleton SmartSearchBarStyle 1.0 SmartSearchBarStyle.qml -singleton TimelineStyle 1.0 TimelineStyle.qml +singleton TimelineStyle 1.0 TimelineStyle.qml diff --git a/linphone-desktop/ui/scripts/Utils/utils.js b/linphone-desktop/ui/scripts/Utils/utils.js index ee3f197a7..4913b2e55 100644 --- a/linphone-desktop/ui/scripts/Utils/utils.js +++ b/linphone-desktop/ui/scripts/Utils/utils.js @@ -261,6 +261,18 @@ function assert (condition, message) { // ----------------------------------------------------------------------------- +function basename (str) { + return str.slice(str.lastIndexOf('/') + 1) +} + +// ----------------------------------------------------------------------------- + +function dirname (str) { + return str.slice(0, str.lastIndexOf('/') + 1) +} + +// ----------------------------------------------------------------------------- + function extractProperties (obj, pattern) { if (!pattern) { return {} diff --git a/linphone-desktop/ui/views/App/MainWindow/MainWindow.qml b/linphone-desktop/ui/views/App/MainWindow/MainWindow.qml index 39da05487..9caddc563 100644 --- a/linphone-desktop/ui/views/App/MainWindow/MainWindow.qml +++ b/linphone-desktop/ui/views/App/MainWindow/MainWindow.qml @@ -46,10 +46,6 @@ ApplicationWindow { }) } - function ensureCollapsed () { - collapse.setCollapsed(true) - } - // --------------------------------------------------------------------------- function _updateSelectedEntry (view, props) { @@ -66,6 +62,10 @@ ApplicationWindow { } function _setView (view, props) { + window.showNormal() + window.requestActivate() + collapse.setCollapsed(true) + _updateSelectedEntry(view, props) _currentView = view contentLoader.setSource(view + '.qml', props || {}) @@ -153,28 +153,20 @@ ApplicationWindow { model: SmartSearchBarModel {} - onAddContact: { - window.ensureCollapsed() - window.setView('ContactEdit', { - sipAddress: sipAddress - }) - } + onAddContact: window.setView('ContactEdit', { + sipAddress: sipAddress + }) onLaunchCall: CallsListModel.launchAudioCall(sipAddress) - onLaunchChat: { - window.ensureCollapsed() - window.setView('Conversation', { - sipAddress: sipAddress - }) - } + onLaunchChat: window.setView('Conversation', { + sipAddress: sipAddress + }) + onLaunchVideoCall: CallsListModel.launchVideoCall(sipAddress) - onEntryClicked: { - window.ensureCollapsed() - window.setView(entry.contact ? 'ContactEdit' : 'Conversation', { - sipAddress: entry.sipAddress - }) - } + onEntryClicked: window.setView(entry.contact ? 'ContactEdit' : 'Conversation', { + sipAddress: entry.sipAddress + }) } } } diff --git a/submodules/cmake-builder b/submodules/cmake-builder index a79e2826e..326a0976c 160000 --- a/submodules/cmake-builder +++ b/submodules/cmake-builder @@ -1 +1 @@ -Subproject commit a79e2826e056cc48b3b4d0eda4f38d82f124bb56 +Subproject commit 326a0976c0b42927056d39d99a396a2d0a8fc3da diff --git a/submodules/linphone b/submodules/linphone index 87bc9f7ea..2c3f66ef6 160000 --- a/submodules/linphone +++ b/submodules/linphone @@ -1 +1 @@ -Subproject commit 87bc9f7ea55f8e449cf1d6b83fefacd2d9e596b0 +Subproject commit 2c3f66ef6f160f4c23efc2dea9485ddae8194af1