diff --git a/tests/resources.qrc b/tests/resources.qrc
index 3ecda11f3..06fca156e 100644
--- a/tests/resources.qrc
+++ b/tests/resources.qrc
@@ -143,9 +143,8 @@
assets/images/video_call_hovered.svg
assets/images/video_call_normal.svg
assets/images/video_call_pressed.svg
- ui/modules/Common/Animations/CaterpillarAnimation.qml
+ ui/modules/Common/Animations/BusyIndicator.qml
ui/modules/Common/Borders.qml
- ui/modules/Common/BusyIndicator.qml
ui/modules/Common/Collapse.qml
ui/modules/Common/Colors.qml
ui/modules/Common/Constants.qml
diff --git a/tests/src/components/call/CallModel.cpp b/tests/src/components/call/CallModel.cpp
index 7546e9443..e70a436fb 100644
--- a/tests/src/components/call/CallModel.cpp
+++ b/tests/src/components/call/CallModel.cpp
@@ -123,3 +123,11 @@ void CallModel::setPausedByUser (bool status) {
emit pausedByUserChanged(false);
}
}
+
+bool CallModel::getVideoOutputEnabled () const {
+ // TODO
+}
+
+void CallModel::setVideoOutputEnabled (bool status) {
+ // TODO
+}
diff --git a/tests/src/components/call/CallModel.hpp b/tests/src/components/call/CallModel.hpp
index 9f98cd63c..a5b07c5e7 100644
--- a/tests/src/components/call/CallModel.hpp
+++ b/tests/src/components/call/CallModel.hpp
@@ -14,6 +14,7 @@ class CallModel : public QObject {
Q_PROPERTY(bool isOutgoing READ isOutgoing CONSTANT);
Q_PROPERTY(bool microMuted READ getMicroMuted WRITE setMicroMuted NOTIFY microMutedChanged);
Q_PROPERTY(bool pausedByUser READ getPausedByUser WRITE setPausedByUser NOTIFY pausedByUserChanged);
+ Q_PROPERTY(bool videoOutputEnabled READ getVideoOutputEnabled WRITE setVideoOutputEnabled NOTIFY videoOutputEnabled);
public:
enum CallStatus {
@@ -39,6 +40,7 @@ signals:
void statusChanged (CallStatus status);
void pausedByUserChanged (bool status);
void microMutedChanged (bool status);
+ void videoOutputEnabled (bool status);
private:
QString getSipAddress () const;
@@ -54,6 +56,9 @@ private:
bool getPausedByUser () const;
void setPausedByUser (bool status);
+ bool getVideoOutputEnabled () const;
+ void setVideoOutputEnabled (bool status);
+
bool m_micro_muted = false;
linphone::CallState m_linphone_call_status = linphone::CallStateIdle;
diff --git a/tests/src/components/calls/CallsListModel.cpp b/tests/src/components/calls/CallsListModel.cpp
index 62fe0b5f0..64a72607b 100644
--- a/tests/src/components/calls/CallsListModel.cpp
+++ b/tests/src/components/calls/CallsListModel.cpp
@@ -2,6 +2,7 @@
#include
#include "../../app/App.hpp"
+#include "../../utils.hpp"
#include "../core/CoreManager.hpp"
#include "CallsListModel.hpp"
@@ -60,6 +61,19 @@ QVariant CallsListModel::data (const QModelIndex &index, int role) const {
// -----------------------------------------------------------------------------
+void CallsListModel::launchAudioCall (const QString &sip_uri) const {
+ shared_ptr core = CoreManager::getInstance()->getCore();
+ core->inviteAddress(
+ core->interpretUrl(::Utils::qStringToLinphoneString(sip_uri))
+ );
+}
+
+void CallsListModel::launchVideoCall (const QString &sip_uri) const {
+ // TODO
+}
+
+// -----------------------------------------------------------------------------
+
bool CallsListModel::removeRow (int row, const QModelIndex &parent) {
return removeRows(row, 1, parent);
}
@@ -86,6 +100,9 @@ void CallsListModel::addCall (const shared_ptr &linphone_call) {
App::getInstance()->getCallsWindow()->show();
CallModel *call = new CallModel(linphone_call);
+
+ qInfo() << "Add call:" << call;
+
App::getInstance()->getEngine()->setObjectOwnership(call, QQmlEngine::CppOwnership);
linphone_call->setData("call-model", *call);
@@ -97,12 +114,12 @@ void CallsListModel::addCall (const shared_ptr &linphone_call) {
}
void CallsListModel::removeCall (const shared_ptr &linphone_call) {
- CallModel *call = &linphone_call->getData("call-model");
- linphone_call->unsetData("call-model");
-
// TODO: It will be (maybe) necessary to use a single scheduled function in the future.
QTimer::singleShot(
- DELAY_BEFORE_REMOVE_CALL, this, [this, call]() {
+ DELAY_BEFORE_REMOVE_CALL, this, [this, linphone_call]() {
+ CallModel *call = &linphone_call->getData("call-model");
+ linphone_call->unsetData("call-model");
+
qInfo() << "Removing call:" << call;
int index = m_list.indexOf(call);
diff --git a/tests/src/components/calls/CallsListModel.hpp b/tests/src/components/calls/CallsListModel.hpp
index daf9ef5d7..715a2b9fb 100644
--- a/tests/src/components/calls/CallsListModel.hpp
+++ b/tests/src/components/calls/CallsListModel.hpp
@@ -21,6 +21,9 @@ public:
QHash roleNames () const override;
QVariant data (const QModelIndex &index, int role = Qt::DisplayRole) const override;
+ Q_INVOKABLE void launchAudioCall (const QString &sip_uri) const;
+ Q_INVOKABLE void launchVideoCall (const QString &sip_uri) const;
+
private:
bool removeRow (int row, const QModelIndex &parent = QModelIndex());
bool removeRows (int row, int count, const QModelIndex &parent = QModelIndex()) override;
diff --git a/tests/ui/modules/Common/BusyIndicator.qml b/tests/ui/modules/Common/Animations/BusyIndicator.qml
similarity index 95%
rename from tests/ui/modules/Common/BusyIndicator.qml
rename to tests/ui/modules/Common/Animations/BusyIndicator.qml
index 86cb30e80..a62fe70a3 100644
--- a/tests/ui/modules/Common/BusyIndicator.qml
+++ b/tests/ui/modules/Common/Animations/BusyIndicator.qml
@@ -10,6 +10,8 @@ BusyIndicator {
// ---------------------------------------------------------------------------
+ property color color: BusyIndicatorStyle.color
+
readonly property int _rotation: 360
readonly property int _size: width < height ? width : height
@@ -58,7 +60,7 @@ BusyIndicator {
height: item.height / 3
width: item.width / 3
- color: BusyIndicatorStyle.color
+ color: busyIndicator.color
radius: (width > height ? width : height) / 2
transform: [
diff --git a/tests/ui/modules/Common/Animations/CaterpillarAnimation.qml b/tests/ui/modules/Common/Animations/CaterpillarAnimation.qml
deleted file mode 100644
index 66e5212e4..000000000
--- a/tests/ui/modules/Common/Animations/CaterpillarAnimation.qml
+++ /dev/null
@@ -1,101 +0,0 @@
-import QtQuick 2.7
-
-import Common.Styles 1.0
-
-// =============================================================================
-
-Row {
- id: container
-
- property color sphereColor: CaterpillarAnimationStyle.sphere.color
- property int animationDuration: CaterpillarAnimationStyle.animation.duration
- property int nSpheres: CaterpillarAnimationStyle.nSpheres
- property int sphereSize: CaterpillarAnimationStyle.sphere.size
- property int animationSpace: CaterpillarAnimationStyle.animation.space
-
- spacing: CaterpillarAnimationStyle.spacing
-
- Repeater {
- id: repeater
-
- model: nSpheres
-
- Rectangle {
- id: sphere
-
- property bool forceRunning: false
- property int previousY: 0
-
- function startAnimation () {
- if (!animator.running) {
- animator.running = true
- } else {
- forceRunning = true
- }
- }
-
- color: sphereColor
- height: width
- radius: width / 2
- width: container.sphereSize
-
- // y can be: `0`, `animationSpace` or `animationSpace / 2`
- onYChanged: {
- // No call executed by last sphere.
- if (index === nSpheres - 1) {
- return
- }
-
- if (y === (animationSpace / 2) && previousY === 0) {
- repeater.itemAt(index + 1).startAnimation()
- }
-
- previousY = y
- }
-
- Component.onCompleted: {
- // Only start first sphere.
- if (index === 0) {
- animator.running = true
- }
- }
-
- YAnimator on y {
- id: animator
-
- duration: container.animationDuration
- from: 0
- running: false
- to: animationSpace / 2
-
- onRunningChanged: {
- if (running) {
- return
- }
-
- var mid = animationSpace / 2
- if (from === animationSpace && to === mid) {
- from = mid
- to = 0
- } else if (from === mid && to === 0) {
- from = 0
- to = mid
-
- if (index !== 0 && !forceRunning) {
- return
- }
- } else if (from === 0 && to === mid) {
- from = mid
- to = animationSpace
- } else {
- from = animationSpace
- to = mid
- }
-
- forceRunning = false
- animator.running = true
- }
- }
- }
- }
-}
diff --git a/tests/ui/modules/Common/qmldir b/tests/ui/modules/Common/qmldir
index ab7b8e95a..0830b2ed8 100644
--- a/tests/ui/modules/Common/qmldir
+++ b/tests/ui/modules/Common/qmldir
@@ -12,14 +12,11 @@ singleton Constants 1.0 Constants.qml
# Components -------------------------------------------------------------------
# Animations
-CaterpillarAnimation 1.0 Animations/CaterpillarAnimation.qml
+BusyIndicator 1.0 Animations/BusyIndicator.qml
# Chat
Borders 1.0 Borders.qml
-# BusyIndicator
-BusyIndicator 1.0 BusyIndicator.qml
-
# Collapse
Collapse 1.0 Collapse.qml
diff --git a/tests/ui/modules/Linphone/Calls/Calls.qml b/tests/ui/modules/Linphone/Calls/Calls.qml
index 6a37e87ff..01805226b 100644
--- a/tests/ui/modules/Linphone/Calls/Calls.qml
+++ b/tests/ui/modules/Linphone/Calls/Calls.qml
@@ -44,14 +44,14 @@ ListView {
_mapStatusToParams[CallModel.CallStatusConnected] = {
actions: [{
- name: qsTr('resumeCall'),
- handler: (function (call) { call.pausedByUser = false })
+ handler: (function (call) { call.pausedByUser = false }),
+ name: qsTr('resumeCall')
}, {
- name: qsTr('transferCall'),
- handler: (function (call) { call.transfer() })
+ handler: (function (call) { call.transfer() }),
+ name: qsTr('transferCall')
}, {
- name: qsTr('terminateCall'),
- handler: (function (call) { call.terminate() })
+ handler: (function (call) { call.terminate() }),
+ name: qsTr('terminateCall')
}],
component: callActions,
string: 'connected'
@@ -85,14 +85,14 @@ ListView {
_mapStatusToParams[CallModel.CallStatusPaused] = {
actions: [{
- name: qsTr('pauseCall'),
- handler: (function (call) { call.pausedByUser = true })
+ handler: (function (call) { call.pausedByUser = true }),
+ name: qsTr('pauseCall')
}, {
- name: qsTr('transferCall'),
- handler: (function (call) { call.transfer() })
+ handler: (function (call) { call.transfer() }),
+ name: qsTr('transferCall')
}, {
- name: qsTr('terminateCall'),
- handler: (function (call) { call.terminate() })
+ handler: (function (call) { call.terminate() }),
+ name: qsTr('terminateCall')
}],
component: callActions,
string: 'paused'
@@ -160,6 +160,29 @@ ListView {
// ---------------------------------------------------------------------------
+ SmartConnect {
+ Component.onCompleted: {
+ this.connect(model, 'rowsAboutToBeRemoved', function (_, first, last) {
+ var index = calls.currentIndex
+ if (index >= first && index <= last) { // Remove current call.
+ if (model.rowCount() - (last - first + 1) <= 0) {
+ calls.currentIndex = -1
+ } else {
+ calls.currentIndex = 0
+ }
+ } else if (last < index) { // Remove before current call.
+ calls.currentIndex = index - (last - first + 1)
+ }
+ })
+
+ this.connect(model, 'rowsInserted', function (_, first, last) {
+ calls.currentIndex = first
+ })
+ }
+ }
+
+ // ---------------------------------------------------------------------------
+
delegate: CallControls {
id: _callControls
diff --git a/tests/ui/views/App/Calls/AbstractStartingCall.qml b/tests/ui/views/App/Calls/AbstractStartingCall.qml
index f18641e90..4bc52158c 100644
--- a/tests/ui/views/App/Calls/AbstractStartingCall.qml
+++ b/tests/ui/views/App/Calls/AbstractStartingCall.qml
@@ -17,7 +17,8 @@ Rectangle {
property var call
default property alias _actionArea: actionArea.data
- property var _contact: SipAddressesModel.mapSipAddressToContact(call.sipAddress)
+
+ property var _contactObserver: SipAddressesModel.getContactObserver(sipAddress)
// ---------------------------------------------------------------------------
@@ -45,12 +46,16 @@ Rectangle {
height: StartingCallStyle.contactDescriptionHeight
horizontalTextAlignment: Text.AlignHCenter
sipAddress: call.sipAddress
- username: LinphoneUtils.getContactUsername(_contact || call.sipAddress)
+ username: LinphoneUtils.getContactUsername(_contactObserver.contact || call.sipAddress)
width: parent.width
}
- CaterpillarAnimation {
+ BusyIndicator {
anchors.horizontalCenter: parent.horizontalCenter
+ color: StartingCallStyle.busyIndicator.color
+ height: StartingCallStyle.busyIndicator.height
+ width: StartingCallStyle.busyIndicator.width
+
visible: call.isOutgoing
}
}
@@ -81,7 +86,7 @@ Rectangle {
anchors.centerIn: parent
backgroundColor: StartingCallStyle.avatar.backgroundColor
- image: _contact && _contact.avatar
+ image: _contactObserver.contact && _contactObserver.contact.avatar
username: contactDescription.username
height: _computeAvatarSize()
diff --git a/tests/ui/views/App/Calls/CallsWindow.qml b/tests/ui/views/App/Calls/CallsWindow.qml
index f69b25a32..df6baaccf 100644
--- a/tests/ui/views/App/Calls/CallsWindow.qml
+++ b/tests/ui/views/App/Calls/CallsWindow.qml
@@ -15,10 +15,7 @@ Window {
// ---------------------------------------------------------------------------
- readonly property var call: {
- console.log('hihi')
- return calls.selectedCall
- }
+ readonly property var call: calls.selectedCall
readonly property var sipAddress: {
if (call) {
return call.sipAddress
@@ -27,18 +24,6 @@ Window {
// ---------------------------------------------------------------------------
- function launchAudioCall (sipAddress) {
- window.show()
-
- }
-
- function launchVideoCall (sipAddress) {
- window.show()
-
- }
-
- // ---------------------------------------------------------------------------
-
minimumHeight: CallsWindowStyle.minimumHeight
minimumWidth: CallsWindowStyle.minimumWidth
title: CallsWindowStyle.title
@@ -125,7 +110,6 @@ Window {
id: incomingCall
IncomingCall {
- anchors.fill: parent
call: window.call
}
}
@@ -134,7 +118,6 @@ Window {
id: outgoingCall
OutgoingCall {
- anchors.fill: parent
call: window.call
}
}
@@ -143,11 +126,20 @@ Window {
id: incall
Incall {
- anchors.fill: parent
call: window.call
}
}
+ Component {
+ id: chat
+
+ Chat {
+ proxyModel: ChatProxyModel {
+ sipAddress: window.sipAddress
+ }
+ }
+ }
+
// -----------------------------------------------------------------------
childA: Loader {
@@ -158,11 +150,12 @@ Window {
if (!call) {
return null
}
- return incomingCall
+
var status = call.status
if (status === CallModel.CallStatusIncoming) {
return incomingCall
}
+
if (status === CallModel.CallStatusOutgoing) {
return outgoingCall
}
@@ -174,13 +167,7 @@ Window {
childB: Loader {
active: Boolean(window.call)
anchors.fill: parent
-
- sourceComponent: Chat {
- anchors.fill: parent
- proxyModel: ChatProxyModel {
- sipAddress: window.sipAddress || ''
- }
- }
+ sourceComponent: window.call ? chat : null
}
}
}
diff --git a/tests/ui/views/App/Calls/Incall.qml b/tests/ui/views/App/Calls/Incall.qml
index 7662f03c0..82d4353a4 100644
--- a/tests/ui/views/App/Calls/Incall.qml
+++ b/tests/ui/views/App/Calls/Incall.qml
@@ -11,10 +11,6 @@ import App.Styles 1.0
// =============================================================================
Rectangle {
- id: call
-
- // ---------------------------------------------------------------------------
-
property var call
property var _contactObserver: SipAddressesModel.getContactObserver(sipAddress)
diff --git a/tests/ui/views/App/Calls/IncomingCall.qml b/tests/ui/views/App/Calls/IncomingCall.qml
index e0fa0e67d..dfa9abc95 100644
--- a/tests/ui/views/App/Calls/IncomingCall.qml
+++ b/tests/ui/views/App/Calls/IncomingCall.qml
@@ -2,7 +2,7 @@ import Common 1.0
import App.Styles 1.0
-// ===================================================================
+// =============================================================================
AbstractStartingCall {
ActionBar {
@@ -11,18 +11,22 @@ AbstractStartingCall {
ActionButton {
icon: 'video_call_accept'
+
+ onClicked: call.acceptWithVideo()
}
ActionButton {
icon: 'call_accept'
+
+ onClicked: call.accept()
}
}
ActionBar {
anchors {
- verticalCenter: parent.verticalCenter
right: parent.right
rightMargin: StartingCallStyle.rightButtonsGroupMargin
+ verticalCenter: parent.verticalCenter
}
iconSize: StartingCallStyle.iconSize
diff --git a/tests/ui/views/App/Calls/OutgoingCall.qml b/tests/ui/views/App/Calls/OutgoingCall.qml
index 4604b696f..b9ae4daed 100644
--- a/tests/ui/views/App/Calls/OutgoingCall.qml
+++ b/tests/ui/views/App/Calls/OutgoingCall.qml
@@ -10,8 +10,8 @@ import App.Styles 1.0
AbstractStartingCall {
GridLayout {
+ columns: parent.width < 415 && call.videoOutputEnabled ? 1 : 2
rowSpacing: ActionBarStyle.spacing
- columns: parent.width < 415 && call.isVideoCall ? 1 : 2
anchors {
left: parent.left
@@ -24,7 +24,7 @@ AbstractStartingCall {
icon: 'micro'
iconSize: StartingCallStyle.iconSize
- onClicked: call.microMuted = !enabled
+ onClicked: call.microMuted = enabled
}
ActionSwitch {
@@ -40,7 +40,7 @@ AbstractStartingCall {
height: StartingCallStyle.userVideo.height
width: StartingCallStyle.userVideo.width
- visible: isVideoCall
+ visible: call.videoOutputEnabled
}
ActionBar {
diff --git a/tests/ui/views/App/MainWindow/Contacts.qml b/tests/ui/views/App/MainWindow/Contacts.qml
index dadfe78d2..837d4f55e 100644
--- a/tests/ui/views/App/MainWindow/Contacts.qml
+++ b/tests/ui/views/App/MainWindow/Contacts.qml
@@ -131,12 +131,12 @@ ColumnLayout {
ActionButton {
icon: 'video_call'
- onClicked: CallsWindow.launchVideoCall($contact.vcard.sipAddresses[0]) // FIXME: Display menu if many addresses.
+ onClicked: CallsListModel.launchVideoCall($contact.vcard.sipAddresses[0]) // FIXME: Display menu if many addresses.
}
ActionButton {
icon: 'call'
- onClicked: CallsWindow.launchAudioCall($contact.vcard.sipAddresses[0]) // FIXME: Display menu if many addresses.
+ onClicked: CallsListModel.launchAudioCall($contact.vcard.sipAddresses[0]) // FIXME: Display menu if many addresses.
}
ActionButton {
diff --git a/tests/ui/views/App/MainWindow/Conversation.qml b/tests/ui/views/App/MainWindow/Conversation.qml
index 878f7c4b6..03f77b91b 100644
--- a/tests/ui/views/App/MainWindow/Conversation.qml
+++ b/tests/ui/views/App/MainWindow/Conversation.qml
@@ -79,12 +79,12 @@ ColumnLayout {
ActionButton {
icon: 'video_call'
- onClicked: CallsWindow.launchVideoCall(conversation.sipAddress)
+ onClicked: CallsListModel.launchVideoCall(conversation.sipAddress)
}
ActionButton {
icon: 'call'
- onClicked: CallsWindow.launchAudioCall(conversation.sipAddress)
+ onClicked: CallsListModel.launchAudioCall(conversation.sipAddress)
}
}
@@ -92,7 +92,7 @@ ColumnLayout {
anchors.verticalCenter: parent.verticalCenter
ActionButton {
- icon: _contact ? 'contact_add' : 'contact_edit'
+ icon: !_contact ? 'contact_add' : 'contact_edit'
iconSize: ConversationStyle.bar.actions.edit.iconSize
onClicked: window.setView('ContactEdit', {
diff --git a/tests/ui/views/App/MainWindow/MainWindow.qml b/tests/ui/views/App/MainWindow/MainWindow.qml
index 95a04d84e..39da05487 100644
--- a/tests/ui/views/App/MainWindow/MainWindow.qml
+++ b/tests/ui/views/App/MainWindow/MainWindow.qml
@@ -160,14 +160,14 @@ ApplicationWindow {
})
}
- onLaunchCall: CallsWindow.launchAudioCall(sipAddress)
+ onLaunchCall: CallsListModel.launchAudioCall(sipAddress)
onLaunchChat: {
window.ensureCollapsed()
window.setView('Conversation', {
sipAddress: sipAddress
})
}
- onLaunchVideoCall: CallsWindow.launchVideoCall(sipAddress)
+ onLaunchVideoCall: CallsListModel.launchVideoCall(sipAddress)
onEntryClicked: {
window.ensureCollapsed()
diff --git a/tests/ui/views/App/Styles/Calls/StartingCallStyle.qml b/tests/ui/views/App/Styles/Calls/StartingCallStyle.qml
index d21d67864..e5dbf2531 100644
--- a/tests/ui/views/App/Styles/Calls/StartingCallStyle.qml
+++ b/tests/ui/views/App/Styles/Calls/StartingCallStyle.qml
@@ -19,6 +19,12 @@ QtObject {
property int maxSize: 300
}
+ property QtObject busyIndicator: QtObject {
+ property color color: Colors.g
+ property int height: 30
+ property int width: 30
+ }
+
property QtObject header: QtObject {
property int spacing: 10
property int topMargin: 26