Commit dae0dfe2 authored by Ronan Abhamon's avatar Ronan Abhamon

feat(app): calls in progress

parent de5376af
belcard @ ebd03758
Subproject commit f5a8603f8e379486d3a4bfa4d74861b0a2d880dd Subproject commit ebd037585965ce80f01be5290abc7e5455009eb8
belle-sip @ b1695fb5
Subproject commit b8bc7f2a5a899e8acfa59c7b49ebabcbab7d0efd Subproject commit b1695fb52ede996ed0b50167aab787d1373f49e4
linphone @ 758d516a
Subproject commit 030b1c05d5d77dac2d34a1be1c98516a8fb9887a Subproject commit 758d516a39ce3ee484e185a6e1a2653659f6fd81
...@@ -13,6 +13,7 @@ set(CMAKE_AUTOMOC ON) ...@@ -13,6 +13,7 @@ set(CMAKE_AUTOMOC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CUSTOM_FLAGS "\ set(CUSTOM_FLAGS "\
-Wall \
-Wcast-align \ -Wcast-align \
-Wconversion \ -Wconversion \
-Werror=suggest-override \ -Werror=suggest-override \
...@@ -58,6 +59,8 @@ set(SOURCES ...@@ -58,6 +59,8 @@ set(SOURCES
src/app/Paths.cpp src/app/Paths.cpp
src/app/ThumbnailProvider.cpp src/app/ThumbnailProvider.cpp
src/components/camera/Camera.cpp src/components/camera/Camera.cpp
src/components/call/CallModel.cpp
src/components/calls/CallsListModel.cpp
src/components/chat/ChatModel.cpp src/components/chat/ChatModel.cpp
src/components/chat/ChatProxyModel.cpp src/components/chat/ChatProxyModel.cpp
src/components/contact/ContactObserver.cpp src/components/contact/ContactObserver.cpp
...@@ -84,6 +87,8 @@ set(HEADERS ...@@ -84,6 +87,8 @@ set(HEADERS
src/app/Paths.hpp src/app/Paths.hpp
src/app/ThumbnailProvider.hpp src/app/ThumbnailProvider.hpp
src/components/camera/Camera.hpp src/components/camera/Camera.hpp
src/components/call/CallModel.hpp
src/components/calls/CallsListModel.hpp
src/components/chat/ChatModel.hpp src/components/chat/ChatModel.hpp
src/components/chat/ChatProxyModel.hpp src/components/chat/ChatProxyModel.hpp
src/components/contact/ContactObserver.hpp src/components/contact/ContactObserver.hpp
...@@ -103,9 +108,7 @@ set(HEADERS ...@@ -103,9 +108,7 @@ set(HEADERS
src/utils.hpp src/utils.hpp
) )
set(QRC_RESOURCES set(QRC_RESOURCES resources.qrc)
resources.qrc
)
set(LANGUAGES_DIRECTORY assets/languages) set(LANGUAGES_DIRECTORY assets/languages)
set(I18N_FILENAME i18n.qrc) set(I18N_FILENAME i18n.qrc)
......
<?xml version="1.0" encoding="UTF-8"?>
<svg width="15px" height="16px" viewBox="0 0 15 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 41 (35326) - http://www.bohemiancoding.com/sketch -->
<title>burger_menu_over_dark</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round">
<g id="burger_menu_over_dark" stroke-width="2" stroke="#4B5964">
<path d="M12.8672045,1.75461579 L2,1.75"></path>
<path d="M12.8672045,7.97683802 L2,7.97222222"></path>
<path d="M12.8672045,14.1990602 L2,14.1944444"></path>
</g>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="15px" height="16px" viewBox="0 0 15 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 41 (35326) - http://www.bohemiancoding.com/sketch -->
<title>burger_menu_over_bright</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round">
<g id="burger_menu_over_bright" stroke-width="2" stroke="#FFFFFF">
<path d="M12.8672045,1.75461579 L2,1.75"></path>
<path d="M12.8672045,7.97683802 L2,7.97222222"></path>
<path d="M12.8672045,14.1990602 L2,14.1944444"></path>
</g>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="15px" height="16px" viewBox="0 0 15 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 41 (35326) - http://www.bohemiancoding.com/sketch -->
<title>burger_menu_default</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round">
<g id="burger_menu_default" stroke-width="2" stroke="#96A6B1">
<path d="M12.8672045,1.75461579 L2,1.75"></path>
<path d="M12.8672045,7.97683802 L2,7.97222222"></path>
<path d="M12.8672045,14.1990602 L2,14.1944444"></path>
</g>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="15px" height="16px" viewBox="0 0 15 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 41 (35326) - http://www.bohemiancoding.com/sketch -->
<title>burger_menu_default</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round">
<g id="burger_menu_default" stroke-width="2" stroke="#96A6B1">
<path d="M12.8672045,1.75461579 L2,1.75"></path>
<path d="M12.8672045,7.97683802 L2,7.97222222"></path>
<path d="M12.8672045,14.1990602 L2,14.1944444"></path>
</g>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="15px" height="16px" viewBox="0 0 15 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 41 (35326) - http://www.bohemiancoding.com/sketch -->
<title>burger_menu_default</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round">
<g id="burger_menu_default" stroke-width="2" stroke="#96A6B1">
<path d="M12.8672045,1.75461579 L2,1.75"></path>
<path d="M12.8672045,7.97683802 L2,7.97222222"></path>
<path d="M12.8672045,14.1990602 L2,14.1944444"></path>
</g>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="15px" height="16px" viewBox="0 0 15 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 41 (35326) - http://www.bohemiancoding.com/sketch -->
<title>burger_menu_default</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round">
<g id="burger_menu_default" stroke-width="2" stroke="#96A6B1">
<path d="M12.8672045,1.75461579 L2,1.75"></path>
<path d="M12.8672045,7.97683802 L2,7.97222222"></path>
<path d="M12.8672045,14.1990602 L2,14.1944444"></path>
</g>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="40px" height="40px" viewBox="0 0 40 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 41 (35326) - http://www.bohemiancoding.com/sketch -->
<title>call_in_sign</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="call_in_sign">
<polygon fill="#FF5E00" points="0 0 40 0 0 40"></polygon>
<path d="M11.243716,8.71501414 L11.1871835,8.71501414 C8.47215269,8.71501414 5.21235367,10.3895588 4.11804501,12.8152126 L4.51732144,15.956733 L8.01512006,15.956733 L8.2626641,12.830113 L14.1683578,12.830113 L14.41529,15.956733 L17.9130886,15.956733 L18.3123651,12.8149535 C17.2174446,10.3886518 13.9583798,8.71501414 11.243716,8.71501414 Z" fill="#FFFFFF" transform="translate(11.215205, 12.335874) rotate(-135.000000) translate(-11.215205, -12.335874) "></path>
</g>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="40px" height="40px" viewBox="0 0 40 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 41 (35326) - http://www.bohemiancoding.com/sketch -->
<title>call_incoming_sign</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="call_incoming_sign">
<polygon fill="#9ECD1D" points="0 0 40 0 0 40"></polygon>
<path d="M7.03999987,7.12602166 L7.03999987,14.4551303 L7.04066968,14.9660218 L7.03999987,7.12602166 Z M14.88,14.9993302 L7.55089135,14.9993302 L7.03999987,15 L14.88,14.9993302 Z M7.46600278,14.5633861 L14.88,7.12602166 L7.46600278,14.5633861 Z" stroke="#FFFFFF" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" transform="translate(10.960000, 11.063011) rotate(-360.000000) translate(-10.960000, -11.063011) "></path>
</g>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="40px" height="40px" viewBox="0 0 40 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 41 (35326) - http://www.bohemiancoding.com/sketch -->
<title>call_outgoing_sign</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="call_outgoing_sign">
<polygon fill="#18A7AF" points="0 0 40 0 0 40"></polygon>
<path d="M7.11999998,7 L7.11999998,14.3291087 L7.1206698,14.8400002 L7.11999998,7 Z M14.9600001,14.8733085 L7.63089146,14.8733085 L7.11999998,14.8739783 L14.9600001,14.8733085 Z M7.5460029,14.4373645 L14.9600001,7 L7.5460029,14.4373645 Z" stroke="#FFFFFF" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" transform="translate(11.040000, 10.936989) rotate(-540.000000) translate(-11.040000, -10.936989) "></path>
</g>
</g>
</svg>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<svg width="40px" height="40px" viewBox="0 0 40 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<!-- Generator: Sketch 41 (35326) - http://www.bohemiancoding.com/sketch -->
<title>call_pausing_sign</title>
<desc>Created with Sketch.</desc>
<defs></defs>
<g id="Symbols" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
<g id="call_pausing_sign">
<polygon fill="#D0D8DE" points="0 0 40 0 0 40"></polygon>
<path d="M9,7.51071887 L9,14.4892811 M12.8,7.51071887 L12.8,14.4892811" stroke="#FFFFFF" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path>
</g>
</g>
</svg>
\ No newline at end of file
...@@ -11,17 +11,9 @@ ...@@ -11,17 +11,9 @@
<source>contactsEntry</source> <source>contactsEntry</source>
<translation type="obsolete">Contacts</translation> <translation type="obsolete">Contacts</translation>
</message> </message>
<message>
<source>acceptAudioCall</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>acceptVideoCall</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>hangup</source> <source>hangup</source>
<translation type="unfinished">End call</translation> <translation type="obsolete">End call</translation>
</message> </message>
</context> </context>
<context> <context>
...@@ -34,6 +26,30 @@ ...@@ -34,6 +26,30 @@
<source>newConference</source> <source>newConference</source>
<translation type="vanished">NEW CONFERENCE</translation> <translation type="vanished">NEW CONFERENCE</translation>
</message> </message>
<message>
<source>acceptAudioCall</source>
<translation>ACCEPT AUDIO CALL</translation>
</message>
<message>
<source>acceptVideoCall</source>
<translation>ACCEPT VIDEO CALL</translation>
</message>
<message>
<source>terminateCall</source>
<translation>HANGUP</translation>
</message>
<message>
<source>resumeCall</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>transferCall</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>pauseCall</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>Chat</name> <name>Chat</name>
......
...@@ -3,17 +3,9 @@ ...@@ -3,17 +3,9 @@
<TS version="2.1"> <TS version="2.1">
<context> <context>
<name>CallControls</name> <name>CallControls</name>
<message>
<source>acceptAudioCall</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>acceptVideoCall</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>hangup</source> <source>hangup</source>
<translation type="unfinished">Fin d&apos;appel</translation> <translation type="obsolete">Fin d&apos;appel</translation>
</message> </message>
</context> </context>
<context> <context>
...@@ -26,6 +18,30 @@ ...@@ -26,6 +18,30 @@
<source>newConference</source> <source>newConference</source>
<translation type="vanished">NOUVELLE CONFERENCE</translation> <translation type="vanished">NOUVELLE CONFERENCE</translation>
</message> </message>
<message>
<source>acceptAudioCall</source>
<translation>ACCEPTER APPEL AUDIO</translation>
</message>
<message>
<source>acceptVideoCall</source>
<translation>ACCEPTER APPEL VIDEO</translation>
</message>
<message>
<source>terminateCall</source>
<translation>RACCROCHER</translation>
</message>
<message>
<source>resumeCall</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>transferCall</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>pauseCall</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>Chat</name> <name>Chat</name>
......
...@@ -9,6 +9,12 @@ ...@@ -9,6 +9,12 @@
<file>assets/images/attachment_normal.svg</file> <file>assets/images/attachment_normal.svg</file>
<file>assets/images/attachment_pressed.svg</file> <file>assets/images/attachment_pressed.svg</file>
<file>assets/images/auto_answer.svg</file> <file>assets/images/auto_answer.svg</file>
<file>assets/images/burger_menu_hovered.svg</file>
<file>assets/images/burger_menu_light_hovered.svg</file>
<file>assets/images/burger_menu_light_normal.svg</file>
<file>assets/images/burger_menu_light_pressed.svg</file>
<file>assets/images/burger_menu_normal.svg</file>
<file>assets/images/burger_menu_pressed.svg</file>
<file>assets/images/call_accept_hovered.svg</file> <file>assets/images/call_accept_hovered.svg</file>
<file>assets/images/call_accept_normal.svg</file> <file>assets/images/call_accept_normal.svg</file>
<file>assets/images/call_accept_pressed.svg</file> <file>assets/images/call_accept_pressed.svg</file>
...@@ -19,6 +25,10 @@ ...@@ -19,6 +25,10 @@
<file>assets/images/call_quality_1.svg</file> <file>assets/images/call_quality_1.svg</file>
<file>assets/images/call_quality_2.svg</file> <file>assets/images/call_quality_2.svg</file>
<file>assets/images/call_quality_3.svg</file> <file>assets/images/call_quality_3.svg</file>
<file>assets/images/call_sign_connected.svg</file>
<file>assets/images/call_sign_incoming.svg</file>
<file>assets/images/call_sign_outgoing.svg</file>
<file>assets/images/call_sign_paused.svg</file>
<file>assets/images/camera_off_hovered.svg</file> <file>assets/images/camera_off_hovered.svg</file>
<file>assets/images/camera_off_normal.svg</file> <file>assets/images/camera_off_normal.svg</file>
<file>assets/images/camera_off_pressed.svg</file> <file>assets/images/camera_off_pressed.svg</file>
...@@ -200,11 +210,8 @@ ...@@ -200,11 +210,8 @@
<file>ui/modules/Common/Tooltip/Tooltip.qml</file> <file>ui/modules/Common/Tooltip/Tooltip.qml</file>
<file>ui/modules/Common/View/ScrollableListView.qml</file> <file>ui/modules/Common/View/ScrollableListView.qml</file>
<file>ui/modules/Linphone/Account/AccountStatus.qml</file> <file>ui/modules/Linphone/Account/AccountStatus.qml</file>
<file>ui/modules/Linphone/Call/CallControls.qml</file> <file>ui/modules/Linphone/Calls/CallControls.qml</file>
<file>ui/modules/Linphone/Call/ConnectedCallsControl.qml</file> <file>ui/modules/Linphone/Calls/Calls.qml</file>
<file>ui/modules/Linphone/Call/IncomingCallControls.qml</file>
<file>ui/modules/Linphone/Call/OutgoingCallControls.qml</file>
<file>ui/modules/Linphone/Call/PausedCallControls.qml</file>
<file>ui/modules/Linphone/Chat/Chat.qml</file> <file>ui/modules/Linphone/Chat/Chat.qml</file>
<file>ui/modules/Linphone/Chat/Event.qml</file> <file>ui/modules/Linphone/Chat/Event.qml</file>
<file>ui/modules/Linphone/Chat/FileMessage.qml</file> <file>ui/modules/Linphone/Chat/FileMessage.qml</file>
...@@ -223,6 +230,8 @@ ...@@ -223,6 +230,8 @@
<file>ui/modules/Linphone/qmldir</file> <file>ui/modules/Linphone/qmldir</file>
<file>ui/modules/Linphone/SmartSearchBar.qml</file> <file>ui/modules/Linphone/SmartSearchBar.qml</file>
<file>ui/modules/Linphone/Styles/Account/AccountStatusStyle.qml</file> <file>ui/modules/Linphone/Styles/Account/AccountStatusStyle.qml</file>
<file>ui/modules/Linphone/Styles/Calls/CallControlsStyle.qml</file>
<file>ui/modules/Linphone/Styles/Calls/CallsStyle.qml</file>
<file>ui/modules/Linphone/Styles/ChatStyle.qml</file> <file>ui/modules/Linphone/Styles/ChatStyle.qml</file>
<file>ui/modules/Linphone/Styles/Contact/AvatarStyle.qml</file> <file>ui/modules/Linphone/Styles/Contact/AvatarStyle.qml</file>
<file>ui/modules/Linphone/Styles/Contact/ContactDescriptionStyle.qml</file> <file>ui/modules/Linphone/Styles/Contact/ContactDescriptionStyle.qml</file>
......
...@@ -4,14 +4,15 @@ ...@@ -4,14 +4,15 @@
#include <QQuickView> #include <QQuickView>
#include <QtDebug> #include <QtDebug>
#include "../components/calls/CallsListModel.hpp"
#include "../components/camera/Camera.hpp" #include "../components/camera/Camera.hpp"
#include "../components/chat/ChatProxyModel.hpp" #include "../components/chat/ChatProxyModel.hpp"
#include "../components/contacts/ContactsListProxyModel.hpp" #include "../components/contacts/ContactsListProxyModel.hpp"
#include "../components/core/CoreManager.hpp" #include "../components/core/CoreManager.hpp"
#include "../components/settings/AccountSettingsModel.hpp" #include "../components/settings/AccountSettingsModel.hpp"
#include "../components/settings/SettingsModel.hpp" #include "../components/settings/SettingsModel.hpp"
#include "../components/timeline/TimelineModel.hpp"
#include "../components/smart-search-bar/SmartSearchBarModel.hpp" #include "../components/smart-search-bar/SmartSearchBarModel.hpp"
#include "../components/timeline/TimelineModel.hpp"
#include "App.hpp" #include "App.hpp"
...@@ -96,17 +97,20 @@ void App::initContentApp () { ...@@ -96,17 +97,20 @@ void App::initContentApp () {
void App::registerTypes () { void App::registerTypes () {
qInfo() << "Registering types..."; qInfo() << "Registering types...";
qmlRegisterUncreatableType<CallModel>(
"Linphone", 1, 0, "CallModel", "CallModel is uncreatable."
);
qmlRegisterUncreatableType<ContactModel>( qmlRegisterUncreatableType<ContactModel>(
"Linphone", 1, 0, "ContactModel", "ContactModel is uncreatable" "Linphone", 1, 0, "ContactModel", "ContactModel is uncreatable."
); );
qmlRegisterUncreatableType<ContactObserver>( qmlRegisterUncreatableType<ContactObserver>(
"Linphone", 1, 0, "ContactObserver", "ContactObserver is uncreatable" "Linphone", 1, 0, "ContactObserver", "ContactObserver is uncreatable."
);
qmlRegisterUncreatableType<VcardModel>(
"Linphone", 1, 0, "VcardModel", "VcardModel is uncreatable"
); );
qmlRegisterUncreatableType<Presence>( qmlRegisterUncreatableType<Presence>(
"Linphone", 1, 0, "Presence", "Presence is uncreatable" "Linphone", 1, 0, "Presence", "Presence is uncreatable."
);
qmlRegisterUncreatableType<VcardModel>(
"Linphone", 1, 0, "VcardModel", "VcardModel is uncreatable."
); );
qmlRegisterSingletonType<App>( qmlRegisterSingletonType<App>(
...@@ -123,24 +127,24 @@ void App::registerTypes () { ...@@ -123,24 +127,24 @@ void App::registerTypes () {
} }
); );
qmlRegisterSingletonType<ContactsListModel>( qmlRegisterSingletonType<AccountSettingsModel>(
"Linphone", 1, 0, "ContactsListModel", "Linphone", 1, 0, "AccountSettingsModel",
[](QQmlEngine *, QJSEngine *) -> QObject *{ [](QQmlEngine *, QJSEngine *) -> QObject *{
return CoreManager::getInstance()->getContactsListModel(); return new AccountSettingsModel();
} }
); );
qmlRegisterSingletonType<SipAddressesModel>( qmlRegisterSingletonType<CallsListModel>(
"Linphone", 1, 0, "SipAddressesModel", "Linphone", 1, 0, "CallsListModel",
[](QQmlEngine *, QJSEngine *) -> QObject *{ [](QQmlEngine *, QJSEngine *) -> QObject *{
return CoreManager::getInstance()->getSipAddressesModel(); return new CallsListModel();
} }
); );
qmlRegisterSingletonType<AccountSettingsModel>( qmlRegisterSingletonType<ContactsListModel>(
"Linphone", 1, 0, "AccountSettingsModel", "Linphone", 1, 0, "ContactsListModel",
[](QQmlEngine *, QJSEngine *) -> QObject *{ [](QQmlEngine *, QJSEngine *) -> QObject *{
return new AccountSettingsModel(); return CoreManager::getInstance()->getContactsListModel();
} }
); );
...@@ -151,6 +155,13 @@ void App::registerTypes () { ...@@ -151,6 +155,13 @@ void App::registerTypes () {
} }
); );
qmlRegisterSingletonType<SipAddressesModel>(
"Linphone", 1, 0, "SipAddressesModel",
[](QQmlEngine *, QJSEngine *) -> QObject *{
return CoreManager::getInstance()->getSipAddressesModel();
}
);
qmlRegisterSingletonType<TimelineModel>( qmlRegisterSingletonType<TimelineModel>(
"Linphone", 1, 0, "TimelineModel", "Linphone", 1, 0, "TimelineModel",
[](QQmlEngine *, QJSEngine *) -> QObject *{ [](QQmlEngine *, QJSEngine *) -> QObject *{
......
#include "../../utils.hpp"
#include "../core/CoreManager.hpp"
#include "CallModel.hpp"
// =============================================================================
CallModel::CallModel (shared_ptr<linphone::Call> linphone_call) {
m_linphone_call = linphone_call;
}
// -----------------------------------------------------------------------------
void CallModel::acceptAudioCall () {
CoreManager::getInstance()->getCore()->acceptCall(m_linphone_call);
}
void CallModel::terminateCall () {
CoreManager::getInstance()->getCore()->terminateCall(m_linphone_call);
}
// -----------------------------------------------------------------------------
QString CallModel::getSipAddress () const {
return ::Utils::linphoneStringToQString(m_linphone_call->getRemoteAddress()->asStringUriOnly());
}
CallModel::CallStatus CallModel::getStatus () const {
switch (m_linphone_call->getState()) {
case linphone::CallStateConnected:
case linphone::CallStateStreamsRunning:
return CallStatusConnected;
case linphone::CallStateEnd:
case linphone::CallStateError:
case linphone::CallStateRefered:
case linphone::CallStateReleased:
return CallStatusEnded;
case linphone::CallStatePaused:
case linphone::CallStatePausedByRemote:
return CallStatusPaused;
default:
break;
}
return m_linphone_call->getDir() == linphone::CallDirIncoming ? CallStatusIncoming : CallStatusOutgoing;
}
bool CallModel::getPausedByUser () const {
return m_linphone_call->getState() == linphone::CallStatePaused;
}
void CallModel::setPausedByUser (bool status) {
bool paused = getPausedByUser();
if (status) {
if (!paused) {
CoreManager::getInstance()->getCore()->pauseCall(m_linphone_call);
emit pausedByUserChanged(true);
}
return;
}
if (paused) {
CoreManager::getInstance()->getCore()->resumeCall(m_linphone_call);
emit pausedByUserChanged(false);
}
}
#ifndef CALL_MODEL_H_
#define CALL_MODEL_H_
#include <linphone++/linphone.hh>
#include <QObject>
// =============================================================================
class CallModel : public QObject {
Q_OBJECT;
Q_PROPERTY(QString sipAddress READ getSipAddress CONSTANT);
Q_PROPERTY(CallStatus status READ getStatus NOTIFY statusChanged);
Q_PROPERTY(bool isOutgoing READ isOutgoing CONSTANT);
Q_PROPERTY(bool pausedByUser READ getPausedByUser WRITE setPausedByUser NOTIFY pausedByUserChanged);
public:
enum CallStatus {
CallStatusConnected,
CallStatusEnded,
CallStatusIncoming,
CallStatusOutgoing,
CallStatusPaused
};
Q_ENUM(CallStatus);
CallModel (std::shared_ptr<linphone::Call> linphone_call);
~CallModel () = default;
Q_INVOKABLE void acceptAudioCall ();
Q_INVOKABLE void terminateCall ();
signals:
void statusChanged (CallStatus status);
void pausedByUserChanged (bool status);
private:
QString getSipAddress () const;
CallStatus getStatus () const;
bool isOutgoing () const {
return m_linphone_call->getDir() == linphone::CallDirOutgoing;
}
bool getPausedByUser () const;
void setPausedByUser (bool status);
std::shared_ptr<linphone::Call> m_linphone_call;
};
#endif // CALL_MODEL_H_
#include <QDebug>
#include "../../app/App.hpp"
#include "../core/CoreManager.hpp"
#include "CallsListModel.hpp"
using namespace std;
// =============================================================================
CallsListModel::CallsListModel (QObject *parent) : QAbstractListModel(parent) {
m_core_handlers = CoreManager::getInstance()->getHandlers();
QObject::connect(
&(*m_core_handlers), &CoreHandlers::callStateChanged,
this, [this](const shared_ptr<linphone::Call> &linphone_call, linphone::CallState state) {
switch (state) {
case linphone::CallStateIncomingReceived:
addCall(linphone_call);
break;
case linphone::CallStateOutgoingInit:
addCall(linphone_call);
break;
case linphone::CallStateEnd:
case linphone::CallStateError:
removeCall(linphone_call);
break;
default:
break;
}
}
);
}
int CallsListModel::rowCount (const QModelIndex &) const {
return m_list.count();
}
QHash<int, QByteArray> CallsListModel::roleNames () const {
QHash<int, QByteArray> roles;
roles[Qt::DisplayRole] = "$call";
return roles;
}
QVariant CallsListModel::data (const QModelIndex &index, int role) const {
int row = index.row();
if (!index.isValid() || row < 0 || row >= m_list.count())
return QVariant();
if (role == Qt::DisplayRole)
return QVariant::fromValue(m_list[row]);
return QVariant();
}
// -----------------------------------------------------------------------------
bool CallsListModel::removeRow (int row, const QModelIndex &parent) {
return removeRows(row, 1, parent);
}
bool CallsListModel::removeRows (int row, int count, const QModelIndex &parent) {
int limit = row + count - 1;
if (row < 0 || count < 0 || limit >= m_list.count())
return false;
beginRemoveRows(parent, row, limit);
for (int i = 0; i < count; ++i)
m_list.takeAt(row)->deleteLater();
endRemoveRows();
return true;
}
// -----------------------------------------------------------------------------
void CallsListModel::addCall (const shared_ptr<linphone::Call> &linphone_call) {
CallModel *call = new CallModel(linphone_call);
App::getInstance()->getEngine()->setObjectOwnership(call, QQmlEngine::CppOwnership);
linphone_call->setData("call-model", *call);
int row = rowCount();
beginInsertRows(QModelIndex(), row, row);
m_list << call;
endInsertRows();
}
void CallsListModel::removeCall (const shared_ptr<linphone::Call> &linphone_call) {
CallModel &call = linphone_call->getData<CallModel>("call-model");
linphone_call->unsetData("call-model");
qInfo() << "Removing call:" << &call;
int index = m_list.indexOf(&call);
if (index == -1 || !removeRow(index))
qWarning() << "Unable to remove call:" << &call;
}
#ifndef CALLS_LIST_MODEL_H_
#define CALLS_LIST_MODEL_H_
#include <QAbstractListModel>
#include "../call/CallModel.hpp"
// =============================================================================
class CoreHandlers;
class CallsListModel : public QAbstractListModel {
Q_OBJECT;
public:
CallsListModel (QObject *parent = Q_NULLPTR);
~CallsListModel () = default;
int rowCount (const QModelIndex &index = QModelIndex()) const override;
QHash<int, QByteArray> roleNames () const override;
QVariant data (const QModelIndex &index, int role = Qt::DisplayRole) const override;
private:
bool removeRow (int row, const QModelIndex &parent = QModelIndex());
bool removeRows (int row, int count, const QModelIndex &parent = QModelIndex()) override;
void addCall (const std::shared_ptr<linphone::Call> &linphone_call);
void removeCall (const std::shared_ptr<linphone::Call> &linphone_call);
QList<CallModel *> m_list;
std::shared_ptr<CoreHandlers> m_core_handlers;
};
#endif // CALLS_LIST_MODEL_H_
...@@ -111,6 +111,8 @@ void ContactsListModel::removeContact (ContactModel *contact) { ...@@ -111,6 +111,8 @@ void ContactsListModel::removeContact (ContactModel *contact) {
qWarning() << "Unable to remove contact:" << contact; qWarning() << "Unable to remove contact:" << contact;
} }
// -----------------------------------------------------------------------------
void ContactsListModel::addContact (ContactModel *contact) { void ContactsListModel::addContact (ContactModel *contact) {
QObject::connect( QObject::connect(
contact, &ContactModel::contactUpdated, contact, &ContactModel::contactUpdated,
......
...@@ -10,8 +10,8 @@ using namespace std; ...@@ -10,8 +10,8 @@ using namespace std;
// ============================================================================= // =============================================================================
void CoreHandlers::onAuthenticationRequested ( void CoreHandlers::onAuthenticationRequested (
const std::shared_ptr<linphone::Core> &, const shared_ptr<linphone::Core> &,
const std::shared_ptr<linphone::AuthInfo> &, const shared_ptr<linphone::AuthInfo> &,
linphone::AuthMethod linphone::AuthMethod
) { ) {
qDebug() << "Auth request"; qDebug() << "Auth request";
...@@ -19,11 +19,11 @@ void CoreHandlers::onAuthenticationRequested ( ...@@ -19,11 +19,11 @@ void CoreHandlers::onAuthenticationRequested (
void CoreHandlers::onCallStateChanged ( void CoreHandlers::onCallStateChanged (
const shared_ptr<linphone::Core> &, const shared_ptr<linphone::Core> &,
const shared_ptr<linphone::Call> &, const shared_ptr<linphone::Call> &call,
linphone::CallState, linphone::CallState state,
const string & const string &
) { ) {
qDebug() << "call"; emit callStateChanged(call, state);
} }
void CoreHandlers::onMessageReceived ( void CoreHandlers::onMessageReceived (
......
...@@ -12,6 +12,7 @@ class CoreHandlers : ...@@ -12,6 +12,7 @@ class CoreHandlers :
Q_OBJECT; Q_OBJECT;
signals: signals:
void callStateChanged (const std::shared_ptr<linphone::Call> &call, linphone::CallState state);
void messageReceived (const std::shared_ptr<linphone::ChatMessage> &message); void messageReceived (const std::shared_ptr<linphone::ChatMessage> &message);
private: private:
...@@ -24,7 +25,7 @@ private: ...@@ -24,7 +25,7 @@ private:
void onCallStateChanged ( void onCallStateChanged (
const std::shared_ptr<linphone::Core> &core, const std::shared_ptr<linphone::Core> &core,
const std::shared_ptr<linphone::Call> &call, const std::shared_ptr<linphone::Call> &call,
linphone::CallState cstate, linphone::CallState state,
const std::string &message const std::string &message
) override; ) override;
......
...@@ -152,8 +152,8 @@ void Notifier::showNotification (QObject *notification, int timeout) { ...@@ -152,8 +152,8 @@ void Notifier::showNotification (QObject *notification, int timeout) {
void Notifier::notifyReceivedMessage ( void Notifier::notifyReceivedMessage (
int timeout, int timeout,
const std::shared_ptr<linphone::ChatRoom> &room, const shared_ptr<linphone::ChatRoom> &room,
const std::shared_ptr<linphone::ChatMessage> &message const shared_ptr<linphone::ChatMessage> &message
) { ) {
QObject *object = createNotification(Notifier::MessageReceived); QObject *object = createNotification(Notifier::MessageReceived);
......
...@@ -19,10 +19,10 @@ SipAddressesModel::SipAddressesModel (QObject *parent) : QAbstractListModel(pare ...@@ -19,10 +19,10 @@ SipAddressesModel::SipAddressesModel (QObject *parent) : QAbstractListModel(pare
QObject::connect(contacts, &ContactsListModel::contactAdded, this, &SipAddressesModel::handleContactAdded); QObject::connect(contacts, &ContactsListModel::contactAdded, this, &SipAddressesModel::handleContactAdded);
QObject::connect(contacts, &ContactsListModel::contactRemoved, this, &SipAddressesModel::handleContactRemoved); QObject::connect(contacts, &ContactsListModel::contactRemoved, this, &SipAddressesModel::handleContactRemoved);
m_handlers = CoreManager::getInstance()->getHandlers(); m_core_handlers = CoreManager::getInstance()->getHandlers();
QObject::connect( QObject::connect(
&(*m_handlers), &CoreHandlers::messageReceived, &(*m_core_handlers), &CoreHandlers::messageReceived,
this, [this](const std::shared_ptr<linphone::ChatMessage> &message) { this, [this](const shared_ptr<linphone::ChatMessage> &message) {
const QString &sip_address = ::Utils::linphoneStringToQString(message->getFromAddress()->asStringUriOnly()); const QString &sip_address = ::Utils::linphoneStringToQString(message->getFromAddress()->asStringUriOnly());
addOrUpdateSipAddress(sip_address, nullptr, message); addOrUpdateSipAddress(sip_address, nullptr, message);
} }
...@@ -107,7 +107,7 @@ void SipAddressesModel::connectToChatModel (ChatModel *chat_model) { ...@@ -107,7 +107,7 @@ void SipAddressesModel::connectToChatModel (ChatModel *chat_model) {
for (auto &signal : { &ChatModel::messageSent, &ChatModel::messageReceived }) { for (auto &signal : { &ChatModel::messageSent, &ChatModel::messageReceived }) {
QObject::connect( QObject::connect(
chat_model, signal, chat_model, signal,
this, [this](const std::shared_ptr<linphone::ChatMessage> &message) { this, [this](const shared_ptr<linphone::ChatMessage> &message) {
addOrUpdateSipAddress( addOrUpdateSipAddress(
::Utils::linphoneStringToQString(message->getToAddress()->asStringUriOnly()), nullptr, message ::Utils::linphoneStringToQString(message->getToAddress()->asStringUriOnly()), nullptr, message
); );
......
...@@ -60,7 +60,7 @@ private: ...@@ -60,7 +60,7 @@ private:
QMultiHash<QString, ContactObserver *> m_observers; QMultiHash<QString, ContactObserver *> m_observers;
std::shared_ptr<CoreHandlers> m_handlers; std::shared_ptr<CoreHandlers> m_core_handlers;
}; };
#endif // SIP_ADDRESSES_MODEL_H_ #endif // SIP_ADDRESSES_MODEL_H_
...@@ -33,6 +33,7 @@ Rectangle { ...@@ -33,6 +33,7 @@ Rectangle {
color: ActionMenuStyle.entry.text.color color: ActionMenuStyle.entry.text.color
elide: Text.ElideRight elide: Text.ElideRight
font.pointSize: ActionMenuStyle.entry.text.fontSize font.pointSize: ActionMenuStyle.entry.text.fontSize
height: parent.height height: parent.height
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter
} }
...@@ -43,6 +44,6 @@ Rectangle { ...@@ -43,6 +44,6 @@ Rectangle {
anchors.fill: parent anchors.fill: parent
hoverEnabled: true hoverEnabled: true
onClicked: entry.clicked onClicked: entry.clicked()
} }
} }
...@@ -9,18 +9,18 @@ QtObject { ...@@ -9,18 +9,18 @@ QtObject {
property int spacing: 1 property int spacing: 1
property QtObject entry: QtObject { property QtObject entry: QtObject {
property int leftMargin: 4 property int leftMargin: 18
property int rightMargin: 4 property int rightMargin: 8
property QtObject color: QtObject { property QtObject color: QtObject {
property color hovered: Colors.s property color hovered: Colors.j
property color normal: Colors.i property color normal: Colors.g
property color pressed: Colors.t property color pressed: Colors.i
} }
property QtObject text: QtObject { property QtObject text: QtObject {
property color color: Colors.k property color color: Colors.k
property int fontSize: 8 property int fontSize: 9
} }
} }
} }
import QtQuick 2.7
import QtQuick.Layouts 1.3
import QtQuick.Controls 2.0
import Linphone 1.0
import Common 1.0
// ===================================================================
RowLayout {
property string sipAddress
// TODO.
property var contact: ContactsListModel.mapSipAddressTocd (
sipAddress
)
implicitHeight: contact.height
spacing: 1
Rectangle {
Layout.fillWidth: true
color: '#434343'
implicitHeight: _contact.height
Contact {
id: contact
anchors.fill: parent
sipAddressColor: '#FFFFFF'
usernameColor: '#FFFFFF'
}
}
Rectangle {
id: button
Layout.preferredHeight: contact.height
Layout.preferredWidth: 42
color: menu.isOpen() ? '#FE5E00' : '#434343'
Text {
anchors.centerIn: parent
color: '#FFFFFF'
text: '...'
}
MouseArea {
anchors.fill: parent
hoverEnabled: true
onClicked: {
menu.showMenu()
}
}
}
DropDownMenu {
id: menu
implicitWidth: actionMenu.width
launcher: button
relativeTo: button
relativeX: button.width + 1
ActionMenu {
id: actionMenu
entryHeight: 22
entryWidth: 120
ActionMenuEntry {
entryName: qsTr('acceptAudioCall')
onClicked: menu.hideMenu()
}
ActionMenuEntry {
entryName: qsTr('acceptVideoCall')
onClicked: menu.hideMenu()
}
ActionMenuEntry {
entryName: qsTr('hangup')
onClicked: menu.hideMenu()
}
}
}
}
import QtQuick 2.7
import QtQuick.Layouts 1.3
import Common 1.0
import Linphone 1.0
import Linphone.Styles 1.0
// =============================================================================
Rectangle {
id: callControls
// ---------------------------------------------------------------------------
default property alias _content: content.data
property alias signIcon: signIcon.icon
property alias sipAddressColor: contact.sipAddressColor
property alias usernameColor: contact.usernameColor
property string sipAddress
// ---------------------------------------------------------------------------
property var _contactObserver: SipAddressesModel.getContactObserver(sipAddress)
// ---------------------------------------------------------------------------
color: CallControlsStyle.color
height: CallControlsStyle.height
width: CallControlsStyle.width
RowLayout {
anchors {
fill: parent
leftMargin: CallControlsStyle.leftMargin
rightMargin: CallControlsStyle.rightMargin
}
spacing: 0
Contact {
id: contact
Layout.fillHeight: true
Layout.fillWidth: true
anchors.fill: parent
displayUnreadMessagesCount: true
entry: ({
contact: _contactObserver.contact,
sipAddress: callControls.sipAddress
})
}
Item {
id: content
Layout.fillHeight: true
}
}
// ---------------------------------------------------------------------------
Icon {
id: signIcon
anchors {
left: parent.left
top: parent.top
}
iconSize: CallControlsStyle.signSize
}
}
import QtQuick 2.7
import Common 1.0
import Linphone 1.0
import Linphone.Styles 1.0
// =============================================================================
ListView {
id: calls
property var _mapStatusToParams
// ---------------------------------------------------------------------------
function _getSignIcon (call) {
if (call) {
var string = _mapStatusToParams[call.status].string
return string ? 'call_sign_' + string : ''
}
return ''
}
function _getParams (call) {
if (call) {
return _mapStatusToParams[call.status]
}
}
// ---------------------------------------------------------------------------
boundsBehavior: Flickable.StopAtBounds
clip: true
spacing: 0
// ---------------------------------------------------------------------------
Component.onCompleted: {
_mapStatusToParams = {}
_mapStatusToParams[CallModel.CallStatusConnected] = {
actions: [{
name: qsTr('resumeCall'),
handler: (function (call) { call.pausedByUser = false })
}, {
name: qsTr('transferCall'),
handler: (function (call) { call.transferCall() })
}, {
name: qsTr('terminateCall'),
handler: (function (call) { call.terminateCall() })
}],
component: callActions,
string: 'connected'
}
_mapStatusToParams[CallModel.CallStatusEnded] = {}
_mapStatusToParams[CallModel.CallStatusIncoming] = {
actions: [{
name: qsTr('acceptAudioCall'),
handler: (function (call) { call.acceptAudioCall() })
}, {
name: qsTr('acceptVideoCall'),
handler: (function (call) { call.acceptVideoCall() })
}, {
name: qsTr('terminateCall'),
handler: (function (call) { call.terminateCall() })
}],
component: callActions,
string: 'incoming'
}
_mapStatusToParams[CallModel.CallStatusOutgoing] = {
component: callAction,
handler: (function (call) { call.terminateCall() }),
icon: 'hangup',
string: 'outgoing'
}
_mapStatusToParams[CallModel.CallStatusPaused] = {
actions: [{
name: qsTr('pauseCall'),
handler: (function (call) { call.pausedByUser = true })
}, {
name: qsTr('transferCall'),
handler: (function (call) { call.transferCall() })
}, {
name: qsTr('terminateCall'),
handler: (function (call) { call.terminateCall() })
}],
component: callActions,
string: 'paused'
}
}
// ---------------------------------------------------------------------------
Component {
id: callAction
ActionButton {
icon: params.icon
iconSize: CallsStyle.entry.iconActionSize
onClicked: params.handler(call)
}
}
// ---------------------------------------------------------------------------
Component {
id: callActions
ActionButton {
id: button
icon: 'burger_menu'
iconSize: CallsStyle.entry.iconMenuSize
onClicked: menu.showMenu()
DropDownMenu {
id: menu
implicitWidth: actionMenu.width
launcher: button
relativeTo: callControls
relativeX: callControls.width
ActionMenu {
id: actionMenu
entryHeight: CallsStyle.entry.height
entryWidth: CallsStyle.entry.width
Repeater {
model: params.actions
ActionMenuEntry {
entryName: modelData.name
onClicked: {
menu.hideMenu()
params.actions[index].handler(call)
}
}
}
}
}
}
}
// ---------------------------------------------------------------------------
delegate: CallControls {
id: _callControls
signIcon: _getSignIcon($call)
sipAddress: $call.sipAddress
width: parent.width
Loader {
property var call: $call
property var callControls: _callControls
property var params: _getParams($call)
anchors.centerIn: parent
sourceComponent: params.component
}
}
}
...@@ -77,7 +77,7 @@ SearchBox { ...@@ -77,7 +77,7 @@ SearchBox {
Layout.fillHeight: true Layout.fillHeight: true
Layout.fillWidth: true Layout.fillWidth: true
entry: Object ({ entry: ({
sipAddress: interpretableSipAddress sipAddress: interpretableSipAddress
}) })
} }
......
pragma Singleton
import QtQuick 2.7
import Common 1.0
// =============================================================================
QtObject {
property color color: Colors.e
property int height: 60
property int leftMargin: 12
property int rightMargin: 12
property int signSize: 40
property int width: 240
}
pragma Singleton
import QtQuick 2.7
import Common 1.0
// =============================================================================
QtObject {
property QtObject entry: QtObject {
property int iconActionSize: 30
property int iconMenuSize: 17
property int height: 30
property int width: 200
}
}
...@@ -8,6 +8,9 @@ singleton AccountStatusStyle 1.0 Account/AccountStatusStyle.qml ...@@ -8,6 +8,9 @@ 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 AvatarStyle 1.0 Contact/AvatarStyle.qml singleton AvatarStyle 1.0 Contact/AvatarStyle.qml
singleton ContactDescriptionStyle 1.0 Contact/ContactDescriptionStyle.qml singleton ContactDescriptionStyle 1.0 Contact/ContactDescriptionStyle.qml
singleton ContactStyle 1.0 Contact/ContactStyle.qml singleton ContactStyle 1.0 Contact/ContactStyle.qml
......
...@@ -9,8 +9,8 @@ module Linphone ...@@ -9,8 +9,8 @@ module Linphone
# Account # Account
AccountStatus 1.0 Account/AccountStatus.qml AccountStatus 1.0 Account/AccountStatus.qml
# Call # Calls
CallControls 1.0 Call/CallControls.qml Calls 1.0 Calls/Calls.qml
# Chat # Chat
Chat 1.0 Chat/Chat.qml Chat 1.0 Chat/Chat.qml
......
...@@ -9,11 +9,25 @@ import Linphone 1.0 ...@@ -9,11 +9,25 @@ import Linphone 1.0
import App.Styles 1.0 import App.Styles 1.0
// =================================================================== // =============================================================================
Window { Window {
id: window id: window
// ---------------------------------------------------------------------------
function launchAudioCall (sipAddress) {
window.show()
}
function launchVideoCall (sipAddress) {
window.show()
}
// ---------------------------------------------------------------------------
minimumHeight: 480 minimumHeight: 480
minimumWidth: 960 minimumWidth: 960
...@@ -33,6 +47,7 @@ Window { ...@@ -33,6 +47,7 @@ Window {
ColumnLayout { ColumnLayout {
anchors.fill: parent anchors.fill: parent
spacing: 0
Item { Item {
Layout.fillWidth: true Layout.fillWidth: true
...@@ -69,52 +84,15 @@ Window { ...@@ -69,52 +84,15 @@ Window {
} }
} }
ListView { Calls {
Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
spacing: 0 Layout.fillWidth: true
model: CallsListModel
} }
} }
} }
/* childA: ColumnLayout { */
/* anchors.fill: parent */
/* spacing: 0 */
/* Rectangle { */
/* Layout.fillWidth: true */
/* Layout.preferredHeight: 50 */
/* color: '#FFFFFF' */
/* ActionBar { */
/* anchors.verticalCenter: parent.verticalCenter */
/* anchors.leftMargin: 10 */
/* anchors.left: parent.left */
/* iconSize: 30 */
/* spacing: 16 */
/* ActionButton { */
/* icon: 'call' */
/* } */
/* ActionButton { */
/* icon: 'conference' */
/* } */
/* } */
/* } */
/* ScrollableListView { */
/* Layout.fillWidth: true */
/* Layout.fillHeight: true */
/* spacing: 1 */
/* delegate: CallControls { */
/* width: parent.width */
/* } */
/* model: callsList */
/* } */
/* } */
// --------------------------------------------------------------- // ---------------------------------------------------------------
// Content. // Content.
// --------------------------------------------------------------- // ---------------------------------------------------------------
......
...@@ -131,12 +131,12 @@ ColumnLayout { ...@@ -131,12 +131,12 @@ ColumnLayout {
ActionButton { ActionButton {
icon: 'video_call' icon: 'video_call'
onClicked: CallsWindow.show() onClicked: CallsWindow.launchVideoCall($contact.vcard.sipAddresses[0]) // FIXME: Display menu if many addresses.
} }
ActionButton { ActionButton {
icon: 'call' icon: 'call'
onClicked: CallsWindow.show() onClicked: CallsWindow.launchAudioCall($contact.vcard.sipAddresses[0]) // FIXME: Display menu if many addresses.
} }
ActionButton { ActionButton {
......
...@@ -15,9 +15,7 @@ ColumnLayout { ...@@ -15,9 +15,7 @@ ColumnLayout {
property string sipAddress property string sipAddress
property var _contact: SipAddressesModel.mapSipAddressToContact( property var _contact: SipAddressesModel.mapSipAddressToContact(sipAddress)
sipAddress
) || sipAddress
function _removeAllEntries () { function _removeAllEntries () {
Utils.openConfirmDialog(window, { Utils.openConfirmDialog(window, {
...@@ -57,9 +55,9 @@ ColumnLayout { ...@@ -57,9 +55,9 @@ ColumnLayout {
Layout.preferredHeight: ConversationStyle.bar.avatarSize Layout.preferredHeight: ConversationStyle.bar.avatarSize
Layout.preferredWidth: ConversationStyle.bar.avatarSize Layout.preferredWidth: ConversationStyle.bar.avatarSize
image: _contact.vcard ? _contact.vcard.avatar : '' image: _contact ? _contact.vcard.avatar : ''
presenceLevel: _contact.presenceLevel || -1 presenceLevel: _contact ? _contact.presenceLevel : -1
username: LinphoneUtils.getContactUsername(_contact) username: LinphoneUtils.getContactUsername(_contact || conversation.sipAddress)
} }
ContactDescription { ContactDescription {
...@@ -81,12 +79,12 @@ ColumnLayout { ...@@ -81,12 +79,12 @@ ColumnLayout {
ActionButton { ActionButton {
icon: 'video_call' icon: 'video_call'
onClicked: CallsWindow.show() onClicked: CallsWindow.launchVideoCall(conversation.sipAddress)
} }
ActionButton { ActionButton {
icon: 'call' icon: 'call'
onClicked: CallsWindow.show() onClicked: CallsWindow.launchAudioCall(conversation.sipAddress)
} }
} }
...@@ -94,7 +92,7 @@ ColumnLayout { ...@@ -94,7 +92,7 @@ ColumnLayout {
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
ActionButton { ActionButton {
icon: Utils.isString(_contact) ? 'contact_add' : 'contact_edit' icon: _contact ? 'contact_add' : 'contact_edit'
iconSize: ConversationStyle.bar.actions.edit.iconSize iconSize: ConversationStyle.bar.actions.edit.iconSize
onClicked: window.setView('ContactEdit', { onClicked: window.setView('ContactEdit', {
......
...@@ -159,14 +159,15 @@ ApplicationWindow { ...@@ -159,14 +159,15 @@ ApplicationWindow {
sipAddress: sipAddress sipAddress: sipAddress
}) })
} }
onLaunchCall: CallsWindow.show()
onLaunchCall: CallsWindow.launchAudioCall(sipAddress)
onLaunchChat: { onLaunchChat: {
window.ensureCollapsed() window.ensureCollapsed()
window.setView('Conversation', { window.setView('Conversation', {
sipAddress: sipAddress sipAddress: sipAddress
}) })
} }
onLaunchVideoCall: CallsWindow.show() onLaunchVideoCall: CallsWindow.launchVideoCall(sipAddress)
onEntryClicked: { onEntryClicked: {
window.ensureCollapsed() window.ensureCollapsed()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment