mirror of
https://gitlab.linphone.org/BC/public/linphone-desktop.git
synced 2026-01-21 21:58:06 +00:00
feat(app): calls in progress
This commit is contained in:
parent
af60c28e22
commit
90c35eb2be
14 changed files with 309 additions and 216 deletions
13
tests/assets/images/call_sign_ended.svg
Normal file
13
tests/assets/images/call_sign_ended.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="#DC4100" 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 |
|
|
@ -40,15 +40,15 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>resumeCall</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>RESUME CALL</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>transferCall</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>TRANSFER CALL</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>pauseCall</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>PAUSE CALL</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
|
|
|||
|
|
@ -32,15 +32,15 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>resumeCall</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>REPRENDRE APPEL</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>transferCall</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>TRANSFERER APPEL</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>pauseCall</source>
|
||||
<translation type="unfinished"></translation>
|
||||
<translation>PAUSE</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
<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_ended.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>
|
||||
|
|
|
|||
|
|
@ -62,6 +62,14 @@ App::App (int &argc, char **argv) : QApplication(argc, argv) {
|
|||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
QQuickWindow *App::getCallsWindow () const {
|
||||
QQuickWindow *window = m_engine.rootContext()->contextProperty("CallsWindow").value<QQuickWindow *>();
|
||||
if (!window)
|
||||
qFatal("Unable to get calls window.");
|
||||
|
||||
return window;
|
||||
}
|
||||
|
||||
bool App::hasFocus () const {
|
||||
QQmlApplicationEngine &engine = const_cast<QQmlApplicationEngine &>(m_engine);
|
||||
const QQuickWindow *root = qobject_cast<QQuickWindow *>(engine.rootObjects().at(0));
|
||||
|
|
@ -182,7 +190,6 @@ void App::addContextProperties () {
|
|||
qInfo() << "Adding context properties...";
|
||||
QQmlContext *context = m_engine.rootContext();
|
||||
|
||||
// TODO: Avoid context properties. Use qmlRegister...
|
||||
QQmlComponent component(&m_engine, QUrl(QML_VIEW_CALL_WINDOW));
|
||||
if (component.isError()) {
|
||||
qWarning() << component.errors();
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include <QApplication>
|
||||
#include <QQmlApplicationEngine>
|
||||
#include <QQmlFileSelector>
|
||||
#include <QQuickWindow>
|
||||
#include <QSystemTrayIcon>
|
||||
|
||||
#include "../components/notifier/Notifier.hpp"
|
||||
|
|
@ -25,6 +26,8 @@ public:
|
|||
return m_notifier;
|
||||
}
|
||||
|
||||
QQuickWindow *getCallsWindow () const;
|
||||
|
||||
bool hasFocus () const;
|
||||
|
||||
Q_INVOKABLE QString locale () const {
|
||||
|
|
|
|||
|
|
@ -1,10 +1,14 @@
|
|||
#include <QDebug>
|
||||
#include <QTimer>
|
||||
|
||||
#include "../../app/App.hpp"
|
||||
#include "../core/CoreManager.hpp"
|
||||
|
||||
#include "CallsListModel.hpp"
|
||||
|
||||
/* Delay before removing call in ms. */
|
||||
#define DELAY_BEFORE_REMOVE_CALL 3000
|
||||
|
||||
using namespace std;
|
||||
|
||||
// =============================================================================
|
||||
|
|
@ -16,17 +20,16 @@ CallsListModel::CallsListModel (QObject *parent) : QAbstractListModel(parent) {
|
|||
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:
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -80,11 +83,13 @@ bool CallsListModel::removeRows (int row, int count, const QModelIndex &parent)
|
|||
// -----------------------------------------------------------------------------
|
||||
|
||||
void CallsListModel::addCall (const shared_ptr<linphone::Call> &linphone_call) {
|
||||
App::getInstance()->getCallsWindow()->show();
|
||||
|
||||
CallModel *call = new CallModel(linphone_call);
|
||||
App::getInstance()->getEngine()->setObjectOwnership(call, QQmlEngine::CppOwnership);
|
||||
linphone_call->setData("call-model", *call);
|
||||
|
||||
int row = rowCount();
|
||||
int row = m_list.count();
|
||||
|
||||
beginInsertRows(QModelIndex(), row, row);
|
||||
m_list << call;
|
||||
|
|
@ -92,12 +97,20 @@ void CallsListModel::addCall (const shared_ptr<linphone::Call> &linphone_call) {
|
|||
}
|
||||
|
||||
void CallsListModel::removeCall (const shared_ptr<linphone::Call> &linphone_call) {
|
||||
CallModel &call = linphone_call->getData<CallModel>("call-model");
|
||||
CallModel *call = &linphone_call->getData<CallModel>("call-model");
|
||||
linphone_call->unsetData("call-model");
|
||||
|
||||
qInfo() << "Removing call:" << &call;
|
||||
// TODO: It will be (maybe) necessary to use a single scheduled function in the future.
|
||||
QTimer::singleShot(
|
||||
DELAY_BEFORE_REMOVE_CALL, this, [this, call]() {
|
||||
qInfo() << "Removing call:" << call;
|
||||
|
||||
int index = m_list.indexOf(&call);
|
||||
if (index == -1 || !removeRow(index))
|
||||
qWarning() << "Unable to remove call:" << &call;
|
||||
int index = m_list.indexOf(call);
|
||||
if (index == -1 || !removeRow(index))
|
||||
qWarning() << "Unable to remove call:" << call;
|
||||
|
||||
if (m_list.empty())
|
||||
App::getInstance()->getCallsWindow()->close();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -520,7 +520,7 @@ void ChatModel::removeEntry (ChatEntryData &pair) {
|
|||
}
|
||||
|
||||
void ChatModel::insertMessageAtEnd (const shared_ptr<linphone::ChatMessage> &message) {
|
||||
int row = rowCount();
|
||||
int row = m_entries.count();
|
||||
|
||||
beginInsertRows(QModelIndex(), row, row);
|
||||
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ ContactModel *ContactsListModel::addContact (VcardModel *vcard) {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
int row = rowCount();
|
||||
int row = m_list.count();
|
||||
|
||||
beginInsertRows(QModelIndex(), row, row);
|
||||
addContact(contact);
|
||||
|
|
|
|||
|
|
@ -6,75 +6,75 @@ import Common.Styles 1.0
|
|||
// =============================================================================
|
||||
|
||||
BusyIndicator {
|
||||
id: busyIndicator
|
||||
id: busyIndicator
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
readonly property int _rotation: 360
|
||||
readonly property int _size: width < height ? width : height
|
||||
readonly property int _rotation: 360
|
||||
readonly property int _size: width < height ? width : height
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
contentItem: Item {
|
||||
x: parent.width / 2 - width / 2
|
||||
y: parent.height / 2 - height / 2
|
||||
contentItem: Item {
|
||||
x: parent.width / 2 - width / 2
|
||||
y: parent.height / 2 - height / 2
|
||||
|
||||
height: _size
|
||||
width: _size
|
||||
height: _size
|
||||
width: _size
|
||||
|
||||
Item {
|
||||
id: item
|
||||
Item {
|
||||
id: item
|
||||
|
||||
height: parent.height
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
width: parent.width
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Animation.
|
||||
// -----------------------------------------------------------------------
|
||||
// -----------------------------------------------------------------------
|
||||
// Animation.
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
RotationAnimator {
|
||||
duration: BusyIndicatorStyle.duration
|
||||
loops: Animation.Infinite
|
||||
running: busyIndicator.visible && busyIndicator.running
|
||||
target: item
|
||||
RotationAnimator {
|
||||
duration: BusyIndicatorStyle.duration
|
||||
loops: Animation.Infinite
|
||||
running: busyIndicator.visible && busyIndicator.running
|
||||
target: item
|
||||
|
||||
from: 0
|
||||
to: busyIndicator._rotation
|
||||
}
|
||||
from: 0
|
||||
to: busyIndicator._rotation
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------
|
||||
// Items to draw.
|
||||
// -----------------------------------------------------------------------
|
||||
// -----------------------------------------------------------------------
|
||||
// Items to draw.
|
||||
// -----------------------------------------------------------------------
|
||||
|
||||
Repeater {
|
||||
id: repeater
|
||||
Repeater {
|
||||
id: repeater
|
||||
|
||||
model: BusyIndicatorStyle.nSpheres
|
||||
model: BusyIndicatorStyle.nSpheres
|
||||
|
||||
Rectangle {
|
||||
x: item.width / 2 - width / 2
|
||||
y: item.height / 2 - height / 2
|
||||
Rectangle {
|
||||
x: item.width / 2 - width / 2
|
||||
y: item.height / 2 - height / 2
|
||||
|
||||
height: item.height / 3
|
||||
width: item.width / 3
|
||||
height: item.height / 3
|
||||
width: item.width / 3
|
||||
|
||||
color: BusyIndicatorStyle.color
|
||||
radius: (width > height ? width : height) / 2
|
||||
color: BusyIndicatorStyle.color
|
||||
radius: (width > height ? width : height) / 2
|
||||
|
||||
transform: [
|
||||
Translate {
|
||||
y: busyIndicator._size / 2
|
||||
},
|
||||
Rotation {
|
||||
angle: index / repeater.count * busyIndicator._rotation
|
||||
origin {
|
||||
x: width / 2
|
||||
y: height / 2
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
transform: [
|
||||
Translate {
|
||||
y: busyIndicator._size / 2
|
||||
},
|
||||
Rotation {
|
||||
angle: index / repeater.count * busyIndicator._rotation
|
||||
origin {
|
||||
x: width / 2
|
||||
y: height / 2
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import Common 1.0
|
|||
// =============================================================================
|
||||
|
||||
QtObject {
|
||||
property color color: Colors.i
|
||||
property int duration: 1250
|
||||
property int nSpheres: 6
|
||||
property color color: Colors.i
|
||||
property int duration: 1250
|
||||
property int nSpheres: 6
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,172 +7,207 @@ import Linphone.Styles 1.0
|
|||
// =============================================================================
|
||||
|
||||
ListView {
|
||||
id: calls
|
||||
id: calls
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
property var _mapStatusToParams
|
||||
property var _mapStatusToParams
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
signal entrySelected (var entry)
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
function _getSignIcon (call) {
|
||||
if (call) {
|
||||
var string = _mapStatusToParams[call.status].string
|
||||
return string ? 'call_sign_' + string : ''
|
||||
}
|
||||
function _getSignIcon (call) {
|
||||
if (call) {
|
||||
return 'call_sign_' + _mapStatusToParams[call.status].string
|
||||
}
|
||||
|
||||
return ''
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
function _getParams (call) {
|
||||
if (call) {
|
||||
return _mapStatusToParams[call.status]
|
||||
}
|
||||
}
|
||||
function _getParams (call) {
|
||||
if (call) {
|
||||
return _mapStatusToParams[call.status]
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
boundsBehavior: Flickable.StopAtBounds
|
||||
clip: true
|
||||
spacing: 0
|
||||
boundsBehavior: Flickable.StopAtBounds
|
||||
clip: true
|
||||
spacing: 0
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
Component.onCompleted: {
|
||||
_mapStatusToParams = {}
|
||||
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.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.CallStatusEnded] = {
|
||||
string: 'ended'
|
||||
}
|
||||
|
||||
_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.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.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'
|
||||
}
|
||||
}
|
||||
_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
|
||||
Component {
|
||||
id: callAction
|
||||
|
||||
ActionButton {
|
||||
icon: params.icon
|
||||
iconSize: CallsStyle.entry.iconActionSize
|
||||
ActionButton {
|
||||
icon: params.icon
|
||||
iconSize: CallsStyle.entry.iconActionSize
|
||||
|
||||
onClicked: params.handler(call)
|
||||
}
|
||||
}
|
||||
onClicked: params.handler(call)
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
Component {
|
||||
id: callActions
|
||||
Component {
|
||||
id: callActions
|
||||
|
||||
ActionButton {
|
||||
id: button
|
||||
ActionButton {
|
||||
id: button
|
||||
|
||||
icon: 'burger_menu'
|
||||
iconSize: CallsStyle.entry.iconMenuSize
|
||||
icon: calls.currentIndex === callId && call.status !== CallModel.CallStatusEnded
|
||||
? 'burger_menu_light'
|
||||
: 'burger_menu'
|
||||
iconSize: CallsStyle.entry.iconMenuSize
|
||||
|
||||
onClicked: menu.showMenu()
|
||||
onClicked: menu.showMenu()
|
||||
|
||||
DropDownMenu {
|
||||
id: menu
|
||||
DropDownMenu {
|
||||
id: menu
|
||||
|
||||
implicitWidth: actionMenu.width
|
||||
launcher: button
|
||||
relativeTo: callControls
|
||||
relativeX: callControls.width
|
||||
implicitWidth: actionMenu.width
|
||||
launcher: button
|
||||
relativeTo: callControls
|
||||
relativeX: callControls.width
|
||||
|
||||
ActionMenu {
|
||||
id: actionMenu
|
||||
ActionMenu {
|
||||
id: actionMenu
|
||||
|
||||
entryHeight: CallsStyle.entry.height
|
||||
entryWidth: CallsStyle.entry.width
|
||||
entryHeight: CallsStyle.entry.height
|
||||
entryWidth: CallsStyle.entry.width
|
||||
|
||||
Repeater {
|
||||
model: params.actions
|
||||
Repeater {
|
||||
model: params.actions
|
||||
|
||||
ActionMenuEntry {
|
||||
entryName: modelData.name
|
||||
ActionMenuEntry {
|
||||
entryName: modelData.name
|
||||
|
||||
onClicked: {
|
||||
menu.hideMenu()
|
||||
params.actions[index].handler(call)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
onClicked: {
|
||||
menu.hideMenu()
|
||||
params.actions[index].handler(call)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
delegate: CallControls {
|
||||
id: _callControls
|
||||
delegate: CallControls {
|
||||
id: _callControls
|
||||
|
||||
signIcon: _getSignIcon($call)
|
||||
sipAddress: $call.sipAddress
|
||||
width: parent.width
|
||||
function useColorStatus () {
|
||||
return calls.currentIndex === index && $call.status !== CallModel.CallStatusEnded
|
||||
}
|
||||
|
||||
Loader {
|
||||
property var call: $call
|
||||
property var callControls: _callControls
|
||||
property var params: _getParams($call)
|
||||
color: useColorStatus()
|
||||
? CallsStyle.entry.color.selected
|
||||
: CallsStyle.entry.color.normal
|
||||
sipAddressColor: useColorStatus()
|
||||
? CallsStyle.entry.sipAddressColor.selected
|
||||
: CallsStyle.entry.sipAddressColor.normal
|
||||
usernameColor: useColorStatus()
|
||||
? CallsStyle.entry.usernameColor.selected
|
||||
: CallsStyle.entry.usernameColor.normal
|
||||
|
||||
anchors.centerIn: parent
|
||||
sourceComponent: params.component
|
||||
}
|
||||
}
|
||||
signIcon: _getSignIcon($call)
|
||||
sipAddress: $call.sipAddress
|
||||
width: parent.width
|
||||
|
||||
Loader {
|
||||
property int callId: index
|
||||
property var call: $call
|
||||
property var callControls: _callControls
|
||||
property var params: _getParams($call)
|
||||
|
||||
anchors.centerIn: parent
|
||||
sourceComponent: params.component
|
||||
}
|
||||
|
||||
SequentialAnimation on color {
|
||||
loops: CallsStyle.entry.endCallAnimation.loops
|
||||
running: $call.status === CallModel.CallStatusEnded
|
||||
|
||||
ColorAnimation {
|
||||
duration: CallsStyle.entry.endCallAnimation.duration
|
||||
from: CallsStyle.entry.color.normal
|
||||
to: CallsStyle.entry.endCallAnimation.blinkColor
|
||||
}
|
||||
|
||||
ColorAnimation {
|
||||
duration: CallsStyle.entry.endCallAnimation.duration
|
||||
from: CallsStyle.entry.endCallAnimation.blinkColor
|
||||
to: CallsStyle.entry.color.normal
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,10 +6,10 @@ 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
|
||||
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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,10 +6,31 @@ 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
|
||||
}
|
||||
property QtObject entry: QtObject {
|
||||
property int iconActionSize: 30
|
||||
property int iconMenuSize: 17
|
||||
property int height: 30
|
||||
property int width: 200
|
||||
|
||||
property QtObject color: QtObject {
|
||||
property color normal: Colors.e
|
||||
property color selected: Colors.j
|
||||
}
|
||||
|
||||
property QtObject endCallAnimation: QtObject {
|
||||
property color blinkColor: Colors.i
|
||||
property int duration: 300
|
||||
property int loops: 3
|
||||
}
|
||||
|
||||
property QtObject sipAddressColor: QtObject {
|
||||
property color normal: Colors.w
|
||||
property color selected: Colors.k
|
||||
}
|
||||
|
||||
property QtObject usernameColor: QtObject {
|
||||
property color normal: Colors.j
|
||||
property color selected: Colors.k
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue