feat(app): calls in progress
|
|
@ -1 +1 @@
|
|||
Subproject commit f5a8603f8e379486d3a4bfa4d74861b0a2d880dd
|
||||
Subproject commit ebd037585965ce80f01be5290abc7e5455009eb8
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit b8bc7f2a5a899e8acfa59c7b49ebabcbab7d0efd
|
||||
Subproject commit b1695fb52ede996ed0b50167aab787d1373f49e4
|
||||
|
|
@ -1 +1 @@
|
|||
Subproject commit 030b1c05d5d77dac2d34a1be1c98516a8fb9887a
|
||||
Subproject commit 758d516a39ce3ee484e185a6e1a2653659f6fd81
|
||||
|
|
@ -13,6 +13,7 @@ set(CMAKE_AUTOMOC ON)
|
|||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
|
||||
set(CUSTOM_FLAGS "\
|
||||
-Wall \
|
||||
-Wcast-align \
|
||||
-Wconversion \
|
||||
-Werror=suggest-override \
|
||||
|
|
@ -58,6 +59,8 @@ set(SOURCES
|
|||
src/app/Paths.cpp
|
||||
src/app/ThumbnailProvider.cpp
|
||||
src/components/camera/Camera.cpp
|
||||
src/components/call/CallModel.cpp
|
||||
src/components/calls/CallsListModel.cpp
|
||||
src/components/chat/ChatModel.cpp
|
||||
src/components/chat/ChatProxyModel.cpp
|
||||
src/components/contact/ContactObserver.cpp
|
||||
|
|
@ -84,6 +87,8 @@ set(HEADERS
|
|||
src/app/Paths.hpp
|
||||
src/app/ThumbnailProvider.hpp
|
||||
src/components/camera/Camera.hpp
|
||||
src/components/call/CallModel.hpp
|
||||
src/components/calls/CallsListModel.hpp
|
||||
src/components/chat/ChatModel.hpp
|
||||
src/components/chat/ChatProxyModel.hpp
|
||||
src/components/contact/ContactObserver.hpp
|
||||
|
|
@ -103,9 +108,7 @@ set(HEADERS
|
|||
src/utils.hpp
|
||||
)
|
||||
|
||||
set(QRC_RESOURCES
|
||||
resources.qrc
|
||||
)
|
||||
set(QRC_RESOURCES resources.qrc)
|
||||
|
||||
set(LANGUAGES_DIRECTORY assets/languages)
|
||||
set(I18N_FILENAME i18n.qrc)
|
||||
|
|
|
|||
14
tests/assets/images/burger_menu_hovered.svg
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
<?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>
|
||||
|
After Width: | Height: | Size: 789 B |
14
tests/assets/images/burger_menu_light_hovered.svg
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
<?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>
|
||||
|
After Width: | Height: | Size: 793 B |
14
tests/assets/images/burger_menu_light_normal.svg
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
<?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>
|
||||
|
After Width: | Height: | Size: 785 B |
14
tests/assets/images/burger_menu_light_pressed.svg
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
<?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>
|
||||
|
After Width: | Height: | Size: 785 B |
14
tests/assets/images/burger_menu_normal.svg
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
<?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>
|
||||
|
After Width: | Height: | Size: 785 B |
14
tests/assets/images/burger_menu_pressed.svg
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
<?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>
|
||||
|
After Width: | Height: | Size: 785 B |
13
tests/assets/images/call_sign_connected.svg
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<?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>
|
||||
|
After Width: | Height: | Size: 1 KiB |
13
tests/assets/images/call_sign_incoming.svg
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<?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>
|
||||
|
After Width: | Height: | Size: 1,023 B |
13
tests/assets/images/call_sign_outgoing.svg
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<?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>
|
||||
|
After Width: | Height: | Size: 1,016 B |
13
tests/assets/images/call_sign_paused.svg
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<?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>
|
||||
|
After Width: | Height: | Size: 748 B |
|
|
@ -11,17 +11,9 @@
|
|||
<source>contactsEntry</source>
|
||||
<translation type="obsolete">Contacts</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>acceptAudioCall</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>acceptVideoCall</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>hangup</source>
|
||||
<translation type="unfinished">End call</translation>
|
||||
<translation type="obsolete">End call</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
|
@ -34,6 +26,30 @@
|
|||
<source>newConference</source>
|
||||
<translation type="vanished">NEW CONFERENCE</translation>
|
||||
</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>
|
||||
<name>Chat</name>
|
||||
|
|
|
|||
|
|
@ -3,17 +3,9 @@
|
|||
<TS version="2.1">
|
||||
<context>
|
||||
<name>CallControls</name>
|
||||
<message>
|
||||
<source>acceptAudioCall</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>acceptVideoCall</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>hangup</source>
|
||||
<translation type="unfinished">Fin d'appel</translation>
|
||||
<translation type="obsolete">Fin d'appel</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
|
@ -26,6 +18,30 @@
|
|||
<source>newConference</source>
|
||||
<translation type="vanished">NOUVELLE CONFERENCE</translation>
|
||||
</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>
|
||||
<name>Chat</name>
|
||||
|
|
|
|||
|
|
@ -9,6 +9,12 @@
|
|||
<file>assets/images/attachment_normal.svg</file>
|
||||
<file>assets/images/attachment_pressed.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_normal.svg</file>
|
||||
<file>assets/images/call_accept_pressed.svg</file>
|
||||
|
|
@ -19,6 +25,10 @@
|
|||
<file>assets/images/call_quality_1.svg</file>
|
||||
<file>assets/images/call_quality_2.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_normal.svg</file>
|
||||
<file>assets/images/camera_off_pressed.svg</file>
|
||||
|
|
@ -200,11 +210,8 @@
|
|||
<file>ui/modules/Common/Tooltip/Tooltip.qml</file>
|
||||
<file>ui/modules/Common/View/ScrollableListView.qml</file>
|
||||
<file>ui/modules/Linphone/Account/AccountStatus.qml</file>
|
||||
<file>ui/modules/Linphone/Call/CallControls.qml</file>
|
||||
<file>ui/modules/Linphone/Call/ConnectedCallsControl.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/Calls/CallControls.qml</file>
|
||||
<file>ui/modules/Linphone/Calls/Calls.qml</file>
|
||||
<file>ui/modules/Linphone/Chat/Chat.qml</file>
|
||||
<file>ui/modules/Linphone/Chat/Event.qml</file>
|
||||
<file>ui/modules/Linphone/Chat/FileMessage.qml</file>
|
||||
|
|
@ -223,6 +230,8 @@
|
|||
<file>ui/modules/Linphone/qmldir</file>
|
||||
<file>ui/modules/Linphone/SmartSearchBar.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/Contact/AvatarStyle.qml</file>
|
||||
<file>ui/modules/Linphone/Styles/Contact/ContactDescriptionStyle.qml</file>
|
||||
|
|
|
|||
|
|
@ -4,14 +4,15 @@
|
|||
#include <QQuickView>
|
||||
#include <QtDebug>
|
||||
|
||||
#include "../components/calls/CallsListModel.hpp"
|
||||
#include "../components/camera/Camera.hpp"
|
||||
#include "../components/chat/ChatProxyModel.hpp"
|
||||
#include "../components/contacts/ContactsListProxyModel.hpp"
|
||||
#include "../components/core/CoreManager.hpp"
|
||||
#include "../components/settings/AccountSettingsModel.hpp"
|
||||
#include "../components/settings/SettingsModel.hpp"
|
||||
#include "../components/timeline/TimelineModel.hpp"
|
||||
#include "../components/smart-search-bar/SmartSearchBarModel.hpp"
|
||||
#include "../components/timeline/TimelineModel.hpp"
|
||||
|
||||
#include "App.hpp"
|
||||
|
||||
|
|
@ -96,17 +97,20 @@ void App::initContentApp () {
|
|||
void App::registerTypes () {
|
||||
qInfo() << "Registering types...";
|
||||
|
||||
qmlRegisterUncreatableType<CallModel>(
|
||||
"Linphone", 1, 0, "CallModel", "CallModel is uncreatable."
|
||||
);
|
||||
qmlRegisterUncreatableType<ContactModel>(
|
||||
"Linphone", 1, 0, "ContactModel", "ContactModel is uncreatable"
|
||||
"Linphone", 1, 0, "ContactModel", "ContactModel is uncreatable."
|
||||
);
|
||||
qmlRegisterUncreatableType<ContactObserver>(
|
||||
"Linphone", 1, 0, "ContactObserver", "ContactObserver is uncreatable"
|
||||
);
|
||||
qmlRegisterUncreatableType<VcardModel>(
|
||||
"Linphone", 1, 0, "VcardModel", "VcardModel is uncreatable"
|
||||
"Linphone", 1, 0, "ContactObserver", "ContactObserver is uncreatable."
|
||||
);
|
||||
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>(
|
||||
|
|
@ -123,20 +127,6 @@ void App::registerTypes () {
|
|||
}
|
||||
);
|
||||
|
||||
qmlRegisterSingletonType<ContactsListModel>(
|
||||
"Linphone", 1, 0, "ContactsListModel",
|
||||
[](QQmlEngine *, QJSEngine *) -> QObject *{
|
||||
return CoreManager::getInstance()->getContactsListModel();
|
||||
}
|
||||
);
|
||||
|
||||
qmlRegisterSingletonType<SipAddressesModel>(
|
||||
"Linphone", 1, 0, "SipAddressesModel",
|
||||
[](QQmlEngine *, QJSEngine *) -> QObject *{
|
||||
return CoreManager::getInstance()->getSipAddressesModel();
|
||||
}
|
||||
);
|
||||
|
||||
qmlRegisterSingletonType<AccountSettingsModel>(
|
||||
"Linphone", 1, 0, "AccountSettingsModel",
|
||||
[](QQmlEngine *, QJSEngine *) -> QObject *{
|
||||
|
|
@ -144,6 +134,20 @@ void App::registerTypes () {
|
|||
}
|
||||
);
|
||||
|
||||
qmlRegisterSingletonType<CallsListModel>(
|
||||
"Linphone", 1, 0, "CallsListModel",
|
||||
[](QQmlEngine *, QJSEngine *) -> QObject *{
|
||||
return new CallsListModel();
|
||||
}
|
||||
);
|
||||
|
||||
qmlRegisterSingletonType<ContactsListModel>(
|
||||
"Linphone", 1, 0, "ContactsListModel",
|
||||
[](QQmlEngine *, QJSEngine *) -> QObject *{
|
||||
return CoreManager::getInstance()->getContactsListModel();
|
||||
}
|
||||
);
|
||||
|
||||
qmlRegisterSingletonType<SettingsModel>(
|
||||
"Linphone", 1, 0, "SettingsModel",
|
||||
[](QQmlEngine *, QJSEngine *) -> QObject *{
|
||||
|
|
@ -151,6 +155,13 @@ void App::registerTypes () {
|
|||
}
|
||||
);
|
||||
|
||||
qmlRegisterSingletonType<SipAddressesModel>(
|
||||
"Linphone", 1, 0, "SipAddressesModel",
|
||||
[](QQmlEngine *, QJSEngine *) -> QObject *{
|
||||
return CoreManager::getInstance()->getSipAddressesModel();
|
||||
}
|
||||
);
|
||||
|
||||
qmlRegisterSingletonType<TimelineModel>(
|
||||
"Linphone", 1, 0, "TimelineModel",
|
||||
[](QQmlEngine *, QJSEngine *) -> QObject *{
|
||||
|
|
|
|||
71
tests/src/components/call/CallModel.cpp
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
#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);
|
||||
}
|
||||
}
|
||||
55
tests/src/components/call/CallModel.hpp
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
#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_
|
||||
103
tests/src/components/calls/CallsListModel.cpp
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
#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;
|
||||
}
|
||||
36
tests/src/components/calls/CallsListModel.hpp
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
#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) {
|
|||
qWarning() << "Unable to remove contact:" << contact;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void ContactsListModel::addContact (ContactModel *contact) {
|
||||
QObject::connect(
|
||||
contact, &ContactModel::contactUpdated,
|
||||
|
|
|
|||
|
|
@ -10,8 +10,8 @@ using namespace std;
|
|||
// =============================================================================
|
||||
|
||||
void CoreHandlers::onAuthenticationRequested (
|
||||
const std::shared_ptr<linphone::Core> &,
|
||||
const std::shared_ptr<linphone::AuthInfo> &,
|
||||
const shared_ptr<linphone::Core> &,
|
||||
const shared_ptr<linphone::AuthInfo> &,
|
||||
linphone::AuthMethod
|
||||
) {
|
||||
qDebug() << "Auth request";
|
||||
|
|
@ -19,11 +19,11 @@ void CoreHandlers::onAuthenticationRequested (
|
|||
|
||||
void CoreHandlers::onCallStateChanged (
|
||||
const shared_ptr<linphone::Core> &,
|
||||
const shared_ptr<linphone::Call> &,
|
||||
linphone::CallState,
|
||||
const shared_ptr<linphone::Call> &call,
|
||||
linphone::CallState state,
|
||||
const string &
|
||||
) {
|
||||
qDebug() << "call";
|
||||
emit callStateChanged(call, state);
|
||||
}
|
||||
|
||||
void CoreHandlers::onMessageReceived (
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ class CoreHandlers :
|
|||
Q_OBJECT;
|
||||
|
||||
signals:
|
||||
void callStateChanged (const std::shared_ptr<linphone::Call> &call, linphone::CallState state);
|
||||
void messageReceived (const std::shared_ptr<linphone::ChatMessage> &message);
|
||||
|
||||
private:
|
||||
|
|
@ -24,7 +25,7 @@ private:
|
|||
void onCallStateChanged (
|
||||
const std::shared_ptr<linphone::Core> &core,
|
||||
const std::shared_ptr<linphone::Call> &call,
|
||||
linphone::CallState cstate,
|
||||
linphone::CallState state,
|
||||
const std::string &message
|
||||
) override;
|
||||
|
||||
|
|
|
|||
|
|
@ -152,8 +152,8 @@ void Notifier::showNotification (QObject *notification, int timeout) {
|
|||
|
||||
void Notifier::notifyReceivedMessage (
|
||||
int timeout,
|
||||
const std::shared_ptr<linphone::ChatRoom> &room,
|
||||
const std::shared_ptr<linphone::ChatMessage> &message
|
||||
const shared_ptr<linphone::ChatRoom> &room,
|
||||
const shared_ptr<linphone::ChatMessage> &message
|
||||
) {
|
||||
QObject *object = createNotification(Notifier::MessageReceived);
|
||||
|
||||
|
|
|
|||
|
|
@ -19,10 +19,10 @@ SipAddressesModel::SipAddressesModel (QObject *parent) : QAbstractListModel(pare
|
|||
QObject::connect(contacts, &ContactsListModel::contactAdded, this, &SipAddressesModel::handleContactAdded);
|
||||
QObject::connect(contacts, &ContactsListModel::contactRemoved, this, &SipAddressesModel::handleContactRemoved);
|
||||
|
||||
m_handlers = CoreManager::getInstance()->getHandlers();
|
||||
m_core_handlers = CoreManager::getInstance()->getHandlers();
|
||||
QObject::connect(
|
||||
&(*m_handlers), &CoreHandlers::messageReceived,
|
||||
this, [this](const std::shared_ptr<linphone::ChatMessage> &message) {
|
||||
&(*m_core_handlers), &CoreHandlers::messageReceived,
|
||||
this, [this](const shared_ptr<linphone::ChatMessage> &message) {
|
||||
const QString &sip_address = ::Utils::linphoneStringToQString(message->getFromAddress()->asStringUriOnly());
|
||||
addOrUpdateSipAddress(sip_address, nullptr, message);
|
||||
}
|
||||
|
|
@ -107,7 +107,7 @@ void SipAddressesModel::connectToChatModel (ChatModel *chat_model) {
|
|||
for (auto &signal : { &ChatModel::messageSent, &ChatModel::messageReceived }) {
|
||||
QObject::connect(
|
||||
chat_model, signal,
|
||||
this, [this](const std::shared_ptr<linphone::ChatMessage> &message) {
|
||||
this, [this](const shared_ptr<linphone::ChatMessage> &message) {
|
||||
addOrUpdateSipAddress(
|
||||
::Utils::linphoneStringToQString(message->getToAddress()->asStringUriOnly()), nullptr, message
|
||||
);
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ private:
|
|||
|
||||
QMultiHash<QString, ContactObserver *> m_observers;
|
||||
|
||||
std::shared_ptr<CoreHandlers> m_handlers;
|
||||
std::shared_ptr<CoreHandlers> m_core_handlers;
|
||||
};
|
||||
|
||||
#endif // SIP_ADDRESSES_MODEL_H_
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ Rectangle {
|
|||
color: ActionMenuStyle.entry.text.color
|
||||
elide: Text.ElideRight
|
||||
font.pointSize: ActionMenuStyle.entry.text.fontSize
|
||||
|
||||
height: parent.height
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
|
|
@ -43,6 +44,6 @@ Rectangle {
|
|||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
|
||||
onClicked: entry.clicked
|
||||
onClicked: entry.clicked()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,18 +9,18 @@ QtObject {
|
|||
property int spacing: 1
|
||||
|
||||
property QtObject entry: QtObject {
|
||||
property int leftMargin: 4
|
||||
property int rightMargin: 4
|
||||
property int leftMargin: 18
|
||||
property int rightMargin: 8
|
||||
|
||||
property QtObject color: QtObject {
|
||||
property color hovered: Colors.s
|
||||
property color normal: Colors.i
|
||||
property color pressed: Colors.t
|
||||
property color hovered: Colors.j
|
||||
property color normal: Colors.g
|
||||
property color pressed: Colors.i
|
||||
}
|
||||
|
||||
property QtObject text: QtObject {
|
||||
property color color: Colors.k
|
||||
property int fontSize: 8
|
||||
property int fontSize: 9
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,91 +0,0 @@
|
|||
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()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
import QtQuick 2.7
|
||||
|
||||
Item {}
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
import QtQuick 2.7
|
||||
|
||||
Item {}
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
import QtQuick 2.7
|
||||
|
||||
Item {}
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
import QtQuick 2.7
|
||||
|
||||
Item {}
|
||||
74
tests/ui/modules/Linphone/Calls/CallControls.qml
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
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
|
||||
}
|
||||
}
|
||||
172
tests/ui/modules/Linphone/Calls/Calls.qml
Normal file
|
|
@ -0,0 +1,172 @@
|
|||
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 {
|
|||
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
entry: Object ({
|
||||
entry: ({
|
||||
sipAddress: interpretableSipAddress
|
||||
})
|
||||
}
|
||||
|
|
|
|||
15
tests/ui/modules/Linphone/Styles/Calls/CallControlsStyle.qml
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
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
|
||||
}
|
||||
15
tests/ui/modules/Linphone/Styles/Calls/CallsStyle.qml
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
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
|
|||
|
||||
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 ContactDescriptionStyle 1.0 Contact/ContactDescriptionStyle.qml
|
||||
singleton ContactStyle 1.0 Contact/ContactStyle.qml
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@ module Linphone
|
|||
# Account
|
||||
AccountStatus 1.0 Account/AccountStatus.qml
|
||||
|
||||
# Call
|
||||
CallControls 1.0 Call/CallControls.qml
|
||||
# Calls
|
||||
Calls 1.0 Calls/Calls.qml
|
||||
|
||||
# Chat
|
||||
Chat 1.0 Chat/Chat.qml
|
||||
|
|
|
|||
|
|
@ -9,11 +9,25 @@ import Linphone 1.0
|
|||
|
||||
import App.Styles 1.0
|
||||
|
||||
// ===================================================================
|
||||
// =============================================================================
|
||||
|
||||
Window {
|
||||
id: window
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
function launchAudioCall (sipAddress) {
|
||||
window.show()
|
||||
|
||||
}
|
||||
|
||||
function launchVideoCall (sipAddress) {
|
||||
window.show()
|
||||
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
minimumHeight: 480
|
||||
minimumWidth: 960
|
||||
|
||||
|
|
@ -33,6 +47,7 @@ Window {
|
|||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
spacing: 0
|
||||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
|
|
@ -69,52 +84,15 @@ Window {
|
|||
}
|
||||
}
|
||||
|
||||
ListView {
|
||||
Layout.fillWidth: true
|
||||
Calls {
|
||||
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.
|
||||
// ---------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -131,12 +131,12 @@ ColumnLayout {
|
|||
|
||||
ActionButton {
|
||||
icon: 'video_call'
|
||||
onClicked: CallsWindow.show()
|
||||
onClicked: CallsWindow.launchVideoCall($contact.vcard.sipAddresses[0]) // FIXME: Display menu if many addresses.
|
||||
}
|
||||
|
||||
ActionButton {
|
||||
icon: 'call'
|
||||
onClicked: CallsWindow.show()
|
||||
onClicked: CallsWindow.launchAudioCall($contact.vcard.sipAddresses[0]) // FIXME: Display menu if many addresses.
|
||||
}
|
||||
|
||||
ActionButton {
|
||||
|
|
|
|||
|
|
@ -15,9 +15,7 @@ ColumnLayout {
|
|||
|
||||
property string sipAddress
|
||||
|
||||
property var _contact: SipAddressesModel.mapSipAddressToContact(
|
||||
sipAddress
|
||||
) || sipAddress
|
||||
property var _contact: SipAddressesModel.mapSipAddressToContact(sipAddress)
|
||||
|
||||
function _removeAllEntries () {
|
||||
Utils.openConfirmDialog(window, {
|
||||
|
|
@ -57,9 +55,9 @@ ColumnLayout {
|
|||
|
||||
Layout.preferredHeight: ConversationStyle.bar.avatarSize
|
||||
Layout.preferredWidth: ConversationStyle.bar.avatarSize
|
||||
image: _contact.vcard ? _contact.vcard.avatar : ''
|
||||
presenceLevel: _contact.presenceLevel || -1
|
||||
username: LinphoneUtils.getContactUsername(_contact)
|
||||
image: _contact ? _contact.vcard.avatar : ''
|
||||
presenceLevel: _contact ? _contact.presenceLevel : -1
|
||||
username: LinphoneUtils.getContactUsername(_contact || conversation.sipAddress)
|
||||
}
|
||||
|
||||
ContactDescription {
|
||||
|
|
@ -81,12 +79,12 @@ ColumnLayout {
|
|||
|
||||
ActionButton {
|
||||
icon: 'video_call'
|
||||
onClicked: CallsWindow.show()
|
||||
onClicked: CallsWindow.launchVideoCall(conversation.sipAddress)
|
||||
}
|
||||
|
||||
ActionButton {
|
||||
icon: 'call'
|
||||
onClicked: CallsWindow.show()
|
||||
onClicked: CallsWindow.launchAudioCall(conversation.sipAddress)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -94,7 +92,7 @@ ColumnLayout {
|
|||
anchors.verticalCenter: parent.verticalCenter
|
||||
|
||||
ActionButton {
|
||||
icon: Utils.isString(_contact) ? 'contact_add' : 'contact_edit'
|
||||
icon: _contact ? 'contact_add' : 'contact_edit'
|
||||
iconSize: ConversationStyle.bar.actions.edit.iconSize
|
||||
|
||||
onClicked: window.setView('ContactEdit', {
|
||||
|
|
|
|||
|
|
@ -159,14 +159,15 @@ ApplicationWindow {
|
|||
sipAddress: sipAddress
|
||||
})
|
||||
}
|
||||
onLaunchCall: CallsWindow.show()
|
||||
|
||||
onLaunchCall: CallsWindow.launchAudioCall(sipAddress)
|
||||
onLaunchChat: {
|
||||
window.ensureCollapsed()
|
||||
window.setView('Conversation', {
|
||||
sipAddress: sipAddress
|
||||
})
|
||||
}
|
||||
onLaunchVideoCall: CallsWindow.show()
|
||||
onLaunchVideoCall: CallsWindow.launchVideoCall(sipAddress)
|
||||
|
||||
onEntryClicked: {
|
||||
window.ensureCollapsed()
|
||||
|
|
|
|||