multicall

This commit is contained in:
Gaelle Braud 2023-12-12 10:23:47 +01:00
parent f82f3cf189
commit 24c78564ef
18 changed files with 553 additions and 150 deletions

View file

@ -96,6 +96,8 @@ void App::init() {
} }
setQuitOnLastWindowClosed(true); // TODO: use settings to set it setQuitOnLastWindowClosed(true); // TODO: use settings to set it
qInfo() << log().arg("Display server : %1").arg(platformName());
// QML // QML
mEngine = new QQmlApplicationEngine(this); mEngine = new QQmlApplicationEngine(this);
// Provide `+custom` folders for custom components and `5.9` for old components. // Provide `+custom` folders for custom components and `5.9` for old components.
@ -119,9 +121,13 @@ void App::init() {
QObject::connect( QObject::connect(
mEngine, &QQmlApplicationEngine::objectCreated, this, mEngine, &QQmlApplicationEngine::objectCreated, this,
[this, url](QObject *obj, const QUrl &objUrl) { [this, url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl) { if (url == objUrl) {
qCritical() << log().arg("Main.qml couldn't be load. The app will exit"); if (!obj) {
exit(-1); qCritical() << log().arg("Main.qml couldn't be load. The app will exit");
exit(-1);
}
mMainWindow = qobject_cast<QQuickWindow *>(obj);
Q_ASSERT(mMainWindow);
} }
}, },
Qt::QueuedConnection); Qt::QueuedConnection);
@ -149,7 +155,6 @@ void App::initCppInterfaces() {
qmlRegisterType<AccountProxy>(Constants::MainQmlUri, 1, 0, "AccountProxy"); qmlRegisterType<AccountProxy>(Constants::MainQmlUri, 1, 0, "AccountProxy");
qmlRegisterType<AccountGui>(Constants::MainQmlUri, 1, 0, "AccountGui"); qmlRegisterType<AccountGui>(Constants::MainQmlUri, 1, 0, "AccountGui");
qmlRegisterUncreatableType<AccountCore>(Constants::MainQmlUri, 1, 0, "AccountCore", QLatin1String("Uncreatable")); qmlRegisterUncreatableType<AccountCore>(Constants::MainQmlUri, 1, 0, "AccountCore", QLatin1String("Uncreatable"));
qmlRegisterType<CallGui>(Constants::MainQmlUri, 1, 0, "CallGui");
qmlRegisterUncreatableType<CallCore>(Constants::MainQmlUri, 1, 0, "CallCore", QLatin1String("Uncreatable")); qmlRegisterUncreatableType<CallCore>(Constants::MainQmlUri, 1, 0, "CallCore", QLatin1String("Uncreatable"));
qmlRegisterType<CallProxy>(Constants::MainQmlUri, 1, 0, "CallProxy"); qmlRegisterType<CallProxy>(Constants::MainQmlUri, 1, 0, "CallProxy");
qmlRegisterType<CallGui>(Constants::MainQmlUri, 1, 0, "CallGui"); qmlRegisterType<CallGui>(Constants::MainQmlUri, 1, 0, "CallGui");
@ -240,14 +245,9 @@ QQuickWindow *App::getCallsWindow(QVariant callGui) {
qCritical() << log().arg("Calls window could not be created."); qCritical() << log().arg("Calls window could not be created.");
return nullptr; return nullptr;
} }
// window->setParent(mMainWindow);
mCallsWindow = window; mCallsWindow = window;
} }
postModelAsync([this]() {
auto core = CoreModel::getInstance()->getCore();
auto callsNb = core->getCallsNb();
postCoreAsync([this, callsNb] { mCallsWindow->setProperty("callsCount", callsNb); });
});
mCallsWindow->setProperty("call", callGui); mCallsWindow->setProperty("call", callGui);
return mCallsWindow; return mCallsWindow;
} }
@ -260,13 +260,6 @@ void App::closeCallsWindow() {
} }
} }
void App::smartShowWindow(QQuickWindow *window) { QQuickWindow *App::getMainWindow() {
if (!window) return; return mMainWindow;
window->setVisible(true); }
// Force show, maybe redundant with setVisible
if (window->visibility() == QWindow::Maximized) // Avoid to change visibility mode
window->showMaximized();
else window->show();
window->raise(); // Raise ensure to get focus on Mac
window->requestActivate();
}

View file

@ -93,7 +93,7 @@ public:
QQuickWindow *getCallsWindow(QVariant callGui); QQuickWindow *getCallsWindow(QVariant callGui);
void closeCallsWindow(); void closeCallsWindow();
Q_INVOKABLE static void smartShowWindow(QQuickWindow *window); QQuickWindow *getMainWindow();
QQmlApplicationEngine *mEngine = nullptr; QQmlApplicationEngine *mEngine = nullptr;
bool notify(QObject *receiver, QEvent *event) override; bool notify(QObject *receiver, QEvent *event) override;
@ -106,6 +106,7 @@ private:
QCommandLineParser *mParser = nullptr; QCommandLineParser *mParser = nullptr;
Thread *mLinphoneThread = nullptr; Thread *mLinphoneThread = nullptr;
Notifier *mNotifier = nullptr; Notifier *mNotifier = nullptr;
QQuickWindow *mMainWindow = nullptr;
QQuickWindow *mCallsWindow = nullptr; QQuickWindow *mCallsWindow = nullptr;
// TODO : changer ce count lorsqu'on aura liste d'appels // TODO : changer ce count lorsqu'on aura liste d'appels
int callsCount = 0; int callsCount = 0;

View file

@ -143,6 +143,9 @@ void CallCore::setSelf(QSharedPointer<CallCore> me) {
mAccountModelConnection->makeConnectToCore(&CallCore::lTerminate, [this]() { mAccountModelConnection->makeConnectToCore(&CallCore::lTerminate, [this]() {
mAccountModelConnection->invokeToModel([this]() { mCallModel->terminate(); }); mAccountModelConnection->invokeToModel([this]() { mCallModel->terminate(); });
}); });
mAccountModelConnection->makeConnectToCore(&CallCore::lTerminateAllCalls, [this]() {
mAccountModelConnection->invokeToModel([this]() { mCallModel->terminateAllCalls(); });
});
} }
QString CallCore::getPeerAddress() const { QString CallCore::getPeerAddress() const {

View file

@ -113,6 +113,7 @@ signals:
void lAccept(bool withVideo); // Accept an incoming call void lAccept(bool withVideo); // Accept an incoming call
void lDecline(); // Decline an incoming call void lDecline(); // Decline an incoming call
void lTerminate(); // Hangup a call void lTerminate(); // Hangup a call
void lTerminateAllCalls(); // Hangup all calls
void lSetSpeakerMuted(bool muted); void lSetSpeakerMuted(bool muted);
void lSetMicrophoneMuted(bool isMuted); void lSetMicrophoneMuted(bool isMuted);
void lSetCameraEnabled(bool enabled); void lSetCameraEnabled(bool enabled);

View file

@ -25,6 +25,7 @@ list(APPEND _LINPHONEAPP_RC_FILES data/assistant/use-app-sip-account.rc
"data/image/phone-selected.svg" "data/image/phone-selected.svg"
"data/image/phone-plus.svg" "data/image/phone-plus.svg"
"data/image/phone-disconnect.svg" "data/image/phone-disconnect.svg"
"data/image/phone-list.svg"
"data/image/phone-transfer.svg" "data/image/phone-transfer.svg"
"data/image/address-book.svg" "data/image/address-book.svg"
"data/image/address-book-selected.svg" "data/image/address-book-selected.svg"

View file

@ -0,0 +1,6 @@
<svg width="32" height="32" viewBox="0 0 32 32" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M26.8446 20.1351L21.1913 17.6019L21.1757 17.5947C20.8822 17.4691 20.5621 17.4188 20.2442 17.4481C19.9264 17.4774 19.6209 17.5855 19.3553 17.7627C19.3241 17.7833 19.294 17.8057 19.2653 17.8299L16.3445 20.3199C14.4941 19.4211 12.5837 17.5251 11.6849 15.6986L14.1785 12.7334C14.2025 12.7034 14.2253 12.6734 14.2469 12.641C14.4202 12.3762 14.5254 12.0726 14.553 11.7573C14.5806 11.442 14.5299 11.1248 14.4053 10.8338V10.8194L11.8649 5.15657C11.7002 4.77648 11.4169 4.45986 11.0575 4.25397C10.698 4.04807 10.2816 3.96395 9.87045 4.01416C8.2444 4.22813 6.75185 5.02669 5.67154 6.26069C4.59124 7.49469 3.99707 9.07974 4.00001 10.7198C4.00001 20.2479 11.7521 27.9999 21.2801 27.9999C22.9202 28.0029 24.5052 27.4087 25.7393 26.3284C26.9733 25.2481 27.7718 23.7555 27.9858 22.1295C28.0361 21.7184 27.9521 21.3021 27.7465 20.9427C27.5408 20.5833 27.2244 20.3 26.8446 20.1351ZM21.2801 26.0799C17.2077 26.0755 13.3034 24.4557 10.4238 21.5761C7.54419 18.6965 5.92447 14.7922 5.92002 10.7198C5.91551 9.54798 6.33769 8.41458 7.10772 7.53127C7.87774 6.64796 8.94297 6.07513 10.1045 5.91977C10.104 5.92456 10.104 5.92938 10.1045 5.93417L12.6245 11.5742L10.1441 14.543C10.1189 14.572 10.096 14.6029 10.0757 14.6354C9.89507 14.9125 9.78913 15.2316 9.76811 15.5617C9.74709 15.8918 9.81169 16.2217 9.95565 16.5194C11.0429 18.7431 13.2833 20.9667 15.5309 22.0527C15.8309 22.1953 16.1627 22.2577 16.494 22.2337C16.8252 22.2097 17.1446 22.1002 17.4209 21.9159C17.4517 21.8951 17.4814 21.8727 17.5097 21.8487L20.4269 19.3599L26.067 21.8859C26.067 21.8859 26.0766 21.8859 26.0802 21.8859C25.9267 23.049 25.3547 24.1164 24.4713 24.8883C23.5878 25.6602 22.4533 26.0839 21.2801 26.0799Z" fill="#6C7A87"/>
<path d="M16.9336 11.8652H27.3336" stroke="#343330" stroke-linecap="round"/>
<path d="M16.9336 8.26562H27.3336" stroke="#343330" stroke-linecap="round"/>
<path d="M16.9336 4.66602H27.3336" stroke="#343330" stroke-linecap="round"/>
</svg>

After

Width:  |  Height:  |  Size: 2 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.3 KiB

View file

@ -34,6 +34,10 @@ CallModel::CallModel(const std::shared_ptr<linphone::Call> &call, QObject *paren
mDurationTimer.setSingleShot(false); mDurationTimer.setSingleShot(false);
connect(&mDurationTimer, &QTimer::timeout, this, [this]() { this->durationChanged(mMonitor->getDuration()); }); connect(&mDurationTimer, &QTimer::timeout, this, [this]() { this->durationChanged(mMonitor->getDuration()); });
mDurationTimer.start(); mDurationTimer.start();
connect(this, &CallModel::stateChanged, this, [this] {
auto state = mMonitor->getState();
if (state == linphone::Call::State::Paused) setPaused(true);
});
} }
CallModel::~CallModel() { CallModel::~CallModel() {
@ -86,6 +90,10 @@ void CallModel::transferTo(const std::shared_ptr<linphone::Address> &address) {
<< log().arg(QStringLiteral("Unable to transfer: `%1`.")).arg(QString::fromStdString(address->asString())); << log().arg(QStringLiteral("Unable to transfer: `%1`.")).arg(QString::fromStdString(address->asString()));
} }
void CallModel::terminateAllCalls() {
auto status = mMonitor->getCore()->terminateAllCalls();
}
void CallModel::setMicrophoneMuted(bool isMuted) { void CallModel::setMicrophoneMuted(bool isMuted) {
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO)); mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
mMonitor->setMicrophoneMuted(isMuted); mMonitor->setMicrophoneMuted(isMuted);

View file

@ -45,6 +45,7 @@ public:
void setCameraEnabled(bool enabled); void setCameraEnabled(bool enabled);
void setPaused(bool paused); void setPaused(bool paused);
void transferTo(const std::shared_ptr<linphone::Address> &address); void transferTo(const std::shared_ptr<linphone::Address> &address);
void terminateAllCalls();
std::shared_ptr<const linphone::Address> getRemoteAddress(); std::shared_ptr<const linphone::Address> getRemoteAddress();
bool getAuthenticationTokenVerified(); bool getAuthenticationTokenVerified();

View file

@ -88,7 +88,7 @@ VariantObject *Utils::createCall(const QString &sipAddress,
App::postCoreSync([callGui]() { App::postCoreSync([callGui]() {
auto app = App::getInstance(); auto app = App::getInstance();
auto window = app->getCallsWindow(callGui); auto window = app->getCallsWindow(callGui);
window->show(); smartShowWindow(window);
}); });
return callGui; return callGui;
} else return QVariant(); } else return QVariant();
@ -104,7 +104,7 @@ void Utils::openCallsWindow(CallGui *call) {
QQuickWindow *Utils::getCallsWindow(CallGui *callGui) { QQuickWindow *Utils::getCallsWindow(CallGui *callGui) {
auto app = App::getInstance(); auto app = App::getInstance();
auto window = app->getCallsWindow(QVariant::fromValue(callGui)); auto window = app->getCallsWindow(QVariant::fromValue(callGui));
window->show(); smartShowWindow(window);
return window; return window;
} }
@ -112,6 +112,12 @@ void Utils::closeCallsWindow() {
App::getInstance()->closeCallsWindow(); App::getInstance()->closeCallsWindow();
} }
QQuickWindow *Utils::getMainWindow() {
auto win = App::getInstance()->getMainWindow();
smartShowWindow(win);
return win;
}
VariantObject *Utils::haveAccount() { VariantObject *Utils::haveAccount() {
VariantObject *result = new VariantObject(); VariantObject *result = new VariantObject();
@ -124,6 +130,16 @@ VariantObject *Utils::haveAccount() {
result->requestValue(); result->requestValue();
return result; return result;
} }
void Utils::smartShowWindow(QQuickWindow *window) {
if (!window) return;
if (window->visibility() == QWindow::Maximized) // Avoid to change visibility mode
window->showNormal();
else window->show();
window->raise(); // Raise ensure to get focus on Mac
window->requestActivate();
}
QString Utils::createAvatar(const QUrl &fileUrl) { QString Utils::createAvatar(const QUrl &fileUrl) {
QString filePath = fileUrl.toLocalFile(); QString filePath = fileUrl.toLocalFile();
QString fileId; // uuid.ext QString fileId; // uuid.ext

View file

@ -58,9 +58,11 @@ public:
const QString &prepareTransfertAddress = "", const QString &prepareTransfertAddress = "",
const QHash<QString, QString> &headers = {}); const QHash<QString, QString> &headers = {});
Q_INVOKABLE static void openCallsWindow(CallGui *call); Q_INVOKABLE static void openCallsWindow(CallGui *call);
Q_INVOKABLE static QQuickWindow *getMainWindow();
Q_INVOKABLE static QQuickWindow *getCallsWindow(CallGui *callGui); Q_INVOKABLE static QQuickWindow *getCallsWindow(CallGui *callGui);
Q_INVOKABLE static void closeCallsWindow(); Q_INVOKABLE static void closeCallsWindow();
Q_INVOKABLE static VariantObject *haveAccount(); Q_INVOKABLE static VariantObject *haveAccount();
Q_INVOKABLE static void smartShowWindow(QQuickWindow *window);
Q_INVOKABLE static QString createAvatar(const QUrl &fileUrl); // Return the avatar path Q_INVOKABLE static QString createAvatar(const QUrl &fileUrl); // Return the avatar path
Q_INVOKABLE static QString formatElapsedTime(int seconds); // Return the elapsed time formated Q_INVOKABLE static QString formatElapsedTime(int seconds); // Return the elapsed time formated

View file

@ -10,25 +10,43 @@ Window {
id: mainWindow id: mainWindow
width: 1512 * DefaultStyle.dp width: 1512 * DefaultStyle.dp
height: 982 * DefaultStyle.dp height: 982 * DefaultStyle.dp
flags: Qt.Window
// modality: Qt.WindowModal
property CallGui call property CallGui call
property int callsCount: 0 onCallChanged: {
onCallsCountChanged: console.log("calls count", callsCount) waitingTime.seconds = 0
waitingTimer.restart()
console.log("call changed", call, waitingTime.seconds)
}
property var peerName: UtilsCpp.getDisplayName(call.core.peerAddress) property var peerName: UtilsCpp.getDisplayName(call.core.peerAddress)
property string peerNameText: peerName ? peerName.value : "" property string peerNameText: peerName ? peerName.value : ""
// TODO : remove this, for debug only property var callState: call.core.state
property var callState: call && call.core.state
onCallStateChanged: { onCallStateChanged: {
console.log("State:", callState) console.log("State:", callState)
if (callState === LinphoneEnums.CallState.Error || callState === LinphoneEnums.CallState.End) { if (callState === LinphoneEnums.CallState.Error || callState === LinphoneEnums.CallState.End) {
endCall() endCall(call)
} }
} }
onClosing: { property var transferState: call.core.transferState
endCall() onTransferStateChanged: {
console.log("Transfer state:", transferState)
if (call.core.transferState === LinphoneEnums.CallState.Error) {
transferErrorPopup.visible = true
}
else if (call.core.transferState === LinphoneEnums.CallState.Connected){
var mainWin = UtilsCpp.getMainWindow()
UtilsCpp.smartShowWindow(mainWin)
mainWin.transferCallSucceed()
}
}
onClosing: (close) => {
close.accepted = false
terminateAllCallsDialog.open()
} }
Timer { Timer {
@ -39,24 +57,69 @@ Window {
} }
} }
function endCall() { function endCall(callToFinish) {
console.log("remaining calls before ending", mainWindow.callsCount) if (callToFinish) callToFinish.core.lTerminate()
callStatusText.text = qsTr("End of the call") if (!callsModel.haveCall) {
if (call) call.core.lTerminate()
if (callsCount === 1) {
bottomButtonsLayout.setButtonsEnabled(false) bottomButtonsLayout.setButtonsEnabled(false)
autoCloseWindow.restart() autoCloseWindow.restart()
} else if (callToFinish.core === mainWindow.call.core) {
mainWindow.call = callsModel.currentCall
} }
} }
Popup {
id: terminateAllCallsDialog
modal: true
anchors.centerIn: parent
closePolicy: Control.Popup.NoAutoClose
padding: 10 * DefaultStyle.dp
contentItem: ColumnLayout {
height: terminateAllCallsDialog.height
width: 278 * DefaultStyle.dp
spacing: 8 * DefaultStyle.dp
Text {
text: qsTr("La fenêtre est sur le point d'être fermée. Cela terminera tous les appels en cours. Souhaitez vous continuer ?")
Layout.preferredWidth: parent.width
font {
pixelSize: 14 * DefaultStyle.dp
weight: 400 * DefaultStyle.dp
}
wrapMode: Text.Wrap
horizontalAlignment: Text.AlignHCenter
}
RowLayout {
Layout.alignment: Qt.AlignHCenter
Button {
text: qsTr("Oui")
onClicked: {
call.core.lTerminateAllCalls()
terminateAllCallsDialog.close()
}
}
Button {
text: qsTr("Non")
onClicked: terminateAllCallsDialog.close()
}
}
}
}
CallProxy{ CallProxy{
id: callList id: callsModel
onCurrentCallChanged: { onCurrentCallChanged: {
console.log("Current call changed:"+currentCall) console.log("Current call changed:"+currentCall)
if(currentCall) mainWindow.call = currentCall if(currentCall) {
mainWindow.call = currentCall
}
}
onHaveCallChanged: {
if (!haveCall) {
mainWindow.endCall()
}
} }
} }
component BottomButton : Button { component BottomButton : Button {
required property string enabledIcon required property string enabledIcon
property string disabledIcon property string disabledIcon
@ -84,7 +147,7 @@ Window {
colorizationColor: disabledIcon && bottomButton.checked ? DefaultStyle.main2_0 : DefaultStyle.grey_0 colorizationColor: disabledIcon && bottomButton.checked ? DefaultStyle.main2_0 : DefaultStyle.grey_0
} }
} }
Control.Popup { Popup {
id: waitingPopup id: waitingPopup
visible: mainWindow.call.core.transferState === LinphoneEnums.CallState.OutgoingInit visible: mainWindow.call.core.transferState === LinphoneEnums.CallState.OutgoingInit
|| mainWindow.call.core.transferState === LinphoneEnums.CallState.OutgoingProgress || mainWindow.call.core.transferState === LinphoneEnums.CallState.OutgoingProgress
@ -93,23 +156,8 @@ Window {
closePolicy: Control.Popup.NoAutoClose closePolicy: Control.Popup.NoAutoClose
anchors.centerIn: parent anchors.centerIn: parent
padding: 20 * DefaultStyle.dp padding: 20 * DefaultStyle.dp
background: Item { underlineColor: DefaultStyle.main1_500_main
radius: 15 * DefaultStyle.dp
anchors.fill: parent
Rectangle {
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
height: parent.height + 2
color: DefaultStyle.main1_500_main
radius: 15 * DefaultStyle.dp
}
Rectangle {
id: mainBackground
anchors.fill: parent
radius: 15 * DefaultStyle.dp
}
}
contentItem: ColumnLayout { contentItem: ColumnLayout {
BusyIndicator{ BusyIndicator{
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
@ -127,9 +175,8 @@ Window {
transferErrorPopup.close() transferErrorPopup.close()
} }
} }
Control.Popup { Popup {
id: transferErrorPopup id: transferErrorPopup
visible: mainWindow.call.core.transferState === LinphoneEnums.CallState.Error
onVisibleChanged: if (visible) autoClosePopup.restart() onVisibleChanged: if (visible) autoClosePopup.restart()
closePolicy: Control.Popup.NoAutoClose closePolicy: Control.Popup.NoAutoClose
x : parent.x + parent.width - width x : parent.x + parent.width - width
@ -137,26 +184,8 @@ Window {
rightMargin: 20 * DefaultStyle.dp rightMargin: 20 * DefaultStyle.dp
bottomMargin: 20 * DefaultStyle.dp bottomMargin: 20 * DefaultStyle.dp
padding: 20 * DefaultStyle.dp padding: 20 * DefaultStyle.dp
background: Item { underlineColor: DefaultStyle.danger_500main
anchors.fill: parent radius: 0
Rectangle {
anchors.left: parent.left
anchors.right: parent.right
height: parent.height + 2 * DefaultStyle.dp
color: DefaultStyle.danger_500main
}
Rectangle {
id: transferErrorBackground
anchors.fill: parent
}
MultiEffect {
anchors.fill: transferErrorBackground
shadowEnabled: true
shadowColor: DefaultStyle.grey_900
shadowBlur: 1
// shadowOpacity: 0.1
}
}
contentItem: ColumnLayout { contentItem: ColumnLayout {
Text { Text {
text: qsTr("Erreur de transfert") text: qsTr("Erreur de transfert")
@ -189,24 +218,23 @@ Window {
image.height: 15 * DefaultStyle.dp image.height: 15 * DefaultStyle.dp
image.sourceSize.width: 15 * DefaultStyle.dp image.sourceSize.width: 15 * DefaultStyle.dp
image.sourceSize.height: 15 * DefaultStyle.dp image.sourceSize.height: 15 * DefaultStyle.dp
image.source: (mainWindow.call.core.state === LinphoneEnums.CallState.Paused image.source: mainWindow.call.core.paused
|| mainWindow.callState === LinphoneEnums.CallState.PausedByRemote)
? AppIcons.pause ? AppIcons.pause
: (mainWindow.callState === LinphoneEnums.CallState.End : (mainWindow.call.core.state === LinphoneEnums.CallState.End
|| mainWindow.callState === LinphoneEnums.CallState.Released) || mainWindow.call.core.state === LinphoneEnums.CallState.Released)
? AppIcons.endCall ? AppIcons.endCall
: mainWindow.call.core.dir === LinphoneEnums.CallDir.Outgoing : mainWindow.call.core.dir === LinphoneEnums.CallDir.Outgoing
? AppIcons.outgoingCall ? AppIcons.outgoingCall
: AppIcons.incomingCall : AppIcons.incomingCall
colorizationColor: mainWindow.callState === LinphoneEnums.CallState.Paused colorizationColor: mainWindow.call.core.state === LinphoneEnums.CallState.Paused
|| mainWindow.callState === LinphoneEnums.CallState.PausedByRemote || mainWindow.callState === LinphoneEnums.CallState.End || mainWindow.call.core.state === LinphoneEnums.CallState.PausedByRemote || mainWindow.call.core.state === LinphoneEnums.CallState.End
|| mainWindow.callState === LinphoneEnums.CallState.Released ? DefaultStyle.danger_500main : undefined || mainWindow.call.core.state === LinphoneEnums.CallState.Released ? DefaultStyle.danger_500main : undefined
} }
Text { Text {
id: callStatusText id: callStatusText
text: (mainWindow.callState === LinphoneEnums.CallState.End || mainWindow.callState === LinphoneEnums.CallState.Released) text: (mainWindow.call.core.state === LinphoneEnums.CallState.End || mainWindow.call.core.state === LinphoneEnums.CallState.Released)
? qsTr("End of the call") ? qsTr("End of the call")
: (mainWindow.callState === LinphoneEnums.CallState.Paused || mainWindow.callState === LinphoneEnums.CallState.PausedByRemote) : (mainWindow.call.core.paused)
? qsTr("Appel mis en pause") ? qsTr("Appel mis en pause")
: EnumsToStringCpp.dirToString(mainWindow.call.core.dir) + qsTr(" call") : EnumsToStringCpp.dirToString(mainWindow.call.core.dir) + qsTr(" call")
color: DefaultStyle.grey_0 color: DefaultStyle.grey_0
@ -216,8 +244,8 @@ Window {
} }
} }
Rectangle { Rectangle {
visible: mainWindow.callState === LinphoneEnums.CallState.Connected visible: mainWindow.call.core.state === LinphoneEnums.CallState.Connected
|| mainWindow.callState === LinphoneEnums.CallState.StreamsRunning || mainWindow.call.core.state === LinphoneEnums.CallState.StreamsRunning
Layout.preferredHeight: parent.height Layout.preferredHeight: parent.height
Layout.preferredWidth: 2 * DefaultStyle.dp Layout.preferredWidth: 2 * DefaultStyle.dp
} }
@ -228,8 +256,8 @@ Window {
pixelSize: 22 * DefaultStyle.dp pixelSize: 22 * DefaultStyle.dp
weight: 800 * DefaultStyle.dp weight: 800 * DefaultStyle.dp
} }
visible: mainWindow.callState === LinphoneEnums.CallState.Connected visible: mainWindow.call.core.state === LinphoneEnums.CallState.Connected
|| mainWindow.callState === LinphoneEnums.CallState.StreamsRunning || mainWindow.call.core.state === LinphoneEnums.CallState.StreamsRunning
} }
} }
@ -277,7 +305,7 @@ Window {
Layout.alignment: Qt.AlignCenter Layout.alignment: Qt.AlignCenter
background: Rectangle { background: Rectangle {
anchors.fill: parent anchors.fill: parent
color: DefaultStyle.grey_600 * DefaultStyle.dp color: DefaultStyle.grey_600
radius: 15 * DefaultStyle.dp radius: 15 * DefaultStyle.dp
} }
contentItem: Item { contentItem: Item {
@ -288,7 +316,7 @@ Window {
Connections { Connections {
target: mainWindow target: mainWindow
onCallStateChanged: { onCallStateChanged: {
if (mainWindow.callState === LinphoneEnums.CallState.Error) { if (mainWindow.call.core.state === LinphoneEnums.CallState.Error) {
centerLayout.currentIndex = 2 centerLayout.currentIndex = 2
} }
} }
@ -299,7 +327,7 @@ Window {
Layout.preferredWidth: parent.width Layout.preferredWidth: parent.width
Layout.preferredHeight: parent.height Layout.preferredHeight: parent.height
Timer { Timer {
id: secondsTimer id: waitingTimer
interval: 1000 interval: 1000
repeat: true repeat: true
onTriggered: waitingTime.seconds += 1 onTriggered: waitingTime.seconds += 1
@ -308,11 +336,11 @@ Window {
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top anchors.top: parent.top
anchors.topMargin: 30 * DefaultStyle.dp anchors.topMargin: 30 * DefaultStyle.dp
visible: mainWindow.callState == LinphoneEnums.CallState.OutgoingInit visible: mainWindow.call.core.state == LinphoneEnums.CallState.OutgoingInit
|| mainWindow.callState == LinphoneEnums.CallState.OutgoingProgress || mainWindow.call.core.state == LinphoneEnums.CallState.OutgoingProgress
|| mainWindow.callState == LinphoneEnums.CallState.OutgoingRinging || mainWindow.call.core.state == LinphoneEnums.CallState.OutgoingRinging
|| mainWindow.callState == LinphoneEnums.CallState.OutgoingEarlyMedia || mainWindow.call.core.state == LinphoneEnums.CallState.OutgoingEarlyMedia
|| mainWindow.callState == LinphoneEnums.CallState.IncomingReceived || mainWindow.call.core.state == LinphoneEnums.CallState.IncomingReceived
BusyIndicator { BusyIndicator {
indicatorColor: DefaultStyle.main2_100 indicatorColor: DefaultStyle.main2_100
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
@ -324,9 +352,12 @@ Window {
color: DefaultStyle.grey_0 color: DefaultStyle.grey_0
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
font.pointSize: 30 * DefaultStyle.dp font {
pixelSize: 30 * DefaultStyle.dp
weight: 300 * DefaultStyle.dp
}
Component.onCompleted: { Component.onCompleted: {
secondsTimer.restart() waitingTimer.restart()
} }
} }
} }
@ -402,25 +433,26 @@ Window {
property int currentIndex: 0 property int currentIndex: 0
Layout.rightMargin: 10 * DefaultStyle.dp Layout.rightMargin: 10 * DefaultStyle.dp
visible: false visible: false
headerContent: StackLayout { function replace(id) {
currentIndex: rightPanel.currentIndex rightPanelStack.replace(id, Control.StackView.Immediate)
}
headerContent: Text {
id: rightPanelTitle
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
Text { width: rightPanel.width
color: DefaultStyle.main2_700 color: DefaultStyle.main2_700
text: qsTr("Transfert d'appel") // text: qsTr("Transfert d'appel")
font.bold: true font {
} pixelSize: 16 * DefaultStyle.dp
Text { weight: 800 * DefaultStyle.dp
color: DefaultStyle.main2_700
text: qsTr("Dialer")
font.bold: true
} }
} }
contentItem: StackLayout { contentItem: Control.StackView {
currentIndex: rightPanel.currentIndex id: rightPanelStack
}
Component {
id: contactsListPanel
ContactsList { ContactsList {
Layout.fillWidth: true
Layout.fillHeight: true
sideMargin: 10 * DefaultStyle.dp sideMargin: 10 * DefaultStyle.dp
topMargin: 15 * DefaultStyle.dp topMargin: 15 * DefaultStyle.dp
groupCallVisible: false groupCallVisible: false
@ -429,10 +461,13 @@ Window {
onCallButtonPressed: (address) => { onCallButtonPressed: (address) => {
mainWindow.call.core.lTransferCall(address) mainWindow.call.core.lTransferCall(address)
} }
Control.StackView.onActivated: rightPanelTitle.text = qsTr("Transfert d'appel")
} }
}
Component {
id: dialerPanel
ColumnLayout { ColumnLayout {
Layout.fillWidth: true Control.StackView.onActivated: rightPanelTitle.text = qsTr("Dialer")
Layout.fillHeight: true
Item { Item {
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true Layout.fillHeight: true
@ -465,6 +500,200 @@ Window {
} }
} }
} }
Component {
id: callsListPanel
Control.Control {
Control.StackView.onActivated: rightPanelTitle.text = qsTr("Liste d'appel")
// width: callList.width
// height: callList.height
onHeightChanged: console.log("control height changed", height)
// padding: 15 * DefaultStyle.dp
topPadding: 15 * DefaultStyle.dp
bottomPadding: 15 * DefaultStyle.dp
leftPadding: 15 * DefaultStyle.dp
rightPadding: 15 * DefaultStyle.dp
background: Rectangle {
anchors.fill: parent
anchors.leftMargin: 10 * DefaultStyle.dp
anchors.rightMargin: 10 * DefaultStyle.dp
anchors.topMargin: 10 * DefaultStyle.dp
anchors.bottomMargin: 10 * DefaultStyle.dp
color: DefaultStyle.main2_0
radius: 15 * DefaultStyle.dp
}
contentItem: ListView {
id: callList
model: callsModel
height: contentHeight
onHeightChanged: console.log("height changzed lustviexw", height, contentHeight)
spacing: 15 * DefaultStyle.dp
onCountChanged: forceLayout()
delegate: Item {
anchors.left: parent.left
anchors.right: parent.right
id: callDelegate
height: 45 * DefaultStyle.dp
RowLayout {
id: delegateContent
anchors.fill: parent
anchors.leftMargin: 10 * DefaultStyle.dp
anchors.rightMargin: 10 * DefaultStyle.dp
Avatar {
id: delegateAvatar
address: modelData.core.peerAddress
Layout.preferredWidth: 45 * DefaultStyle.dp
Layout.preferredHeight: 45 * DefaultStyle.dp
}
Text {
id: delegateName
text: UtilsCpp.getDisplayName(modelData.core.peerAddress).value
Connections {
target: modelData.core
}
}
Item {
Layout.fillHeight: true
Layout.fillWidth: true
}
Text {
id: callStateText
text: modelData.core.state === LinphoneEnums.CallState.Paused
|| modelData.core.state === LinphoneEnums.CallState.PausedByRemote
? qsTr("Appel en pause") : qsTr("Appel en cours")
}
Button {
id: listCallOptionsButton
checked: listCallOptionsMenu.visible
Layout.preferredWidth: 24 * DefaultStyle.dp
Layout.preferredHeight: 24 * DefaultStyle.dp
Layout.alignment: Qt.AlignRight
leftPadding: 0
rightPadding: 0
topPadding: 0
bottomPadding: 0
background: Rectangle {
anchors.fill: listCallOptionsButton
opacity: listCallOptionsButton.checked ? 1 : 0
color: DefaultStyle.main2_300
radius: 40 * DefaultStyle.dp
}
contentItem: Image {
source: AppIcons.verticalDots
sourceSize.width: 24 * DefaultStyle.dp
sourceSize.height: 24 * DefaultStyle.dp
width: 24 * DefaultStyle.dp
height: 24 * DefaultStyle.dp
}
onPressed: {
console.log("listCallOptionsMenu visible", listCallOptionsMenu.visible, "opened", listCallOptionsMenu.opened)
if (listCallOptionsMenu.visible){
console.log("close popup")
listCallOptionsMenu.close()
}
else {
console.log("open popup")
listCallOptionsMenu.open()
}
}
Control.Popup {
id: listCallOptionsMenu
x: - width
y: listCallOptionsButton.height
onVisibleChanged: console.log("popup visible", visible)
closePolicy: Popup.CloseOnPressOutsideParent | Popup.CloseOnEscape
padding: 20 * DefaultStyle.dp
background: Item {
anchors.fill: parent
Rectangle {
id: callOptionsMenuPopup
anchors.fill: parent
color: DefaultStyle.grey_0
radius: 16 * DefaultStyle.dp
}
MultiEffect {
source: callOptionsMenuPopup
anchors.fill: callOptionsMenuPopup
shadowEnabled: true
shadowBlur: 1
shadowColor: DefaultStyle.grey_900
shadowOpacity: 0.4
}
}
contentItem: ColumnLayout {
spacing: 0
Control.Button {
background: Item {}
contentItem: RowLayout {
Image {
source: modelData.core.state === LinphoneEnums.CallState.Paused
|| modelData.core.state === LinphoneEnums.CallState.PausedByRemote
? AppIcons.phone : AppIcons.pause
sourceSize.width: 32 * DefaultStyle.dp
sourceSize.height: 32 * DefaultStyle.dp
Layout.preferredWidth: 32 * DefaultStyle.dp
Layout.preferredHeight: 32 * DefaultStyle.dp
fillMode: Image.PreserveAspectFit
}
Text {
text: modelData.core.state === LinphoneEnums.CallState.Paused
|| modelData.core.state === LinphoneEnums.CallState.PausedByRemote
? qsTr("Reprendre l'appel") : qsTr("Mettre en pause")
color: DefaultStyle.main2_500main
Layout.preferredWidth: metrics.width
}
TextMetrics {
id: metrics
text: qsTr("Reprendre l'appel")
}
Item {
Layout.fillWidth: true
}
}
onClicked: modelData.core.lSetPaused(!modelData.core.paused)
}
Control.Button {
background: Item {}
contentItem: RowLayout {
EffectImage {
image.source: AppIcons.endCall
colorizationColor: DefaultStyle.danger_500main
width: 32 * DefaultStyle.dp
height: 32 * DefaultStyle.dp
}
Text {
color: DefaultStyle.danger_500main
text: qsTr("Terminer l'appel")
}
Item {
Layout.fillWidth: true
}
}
onClicked: mainWindow.endCall(modelData)
}
}
}
}
}
// MouseArea{
// anchors.fill: delegateLayout
// onClicked: {
// callsModel.currentCall = modelData
// }
// }
}
}
}
}
} }
} }
GridLayout { GridLayout {
@ -474,13 +703,22 @@ Window {
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
layoutDirection: Qt.LeftToRight layoutDirection: Qt.LeftToRight
columnSpacing: 20 * DefaultStyle.dp columnSpacing: 20 * DefaultStyle.dp
Connections {
target: mainWindow function refreshLayout() {
onCallStateChanged: if (mainWindow.callState === LinphoneEnums.CallState.Connected || mainWindow.callState === LinphoneEnums.CallState.StreamsRunning) { if (mainWindow.call.core.state === LinphoneEnums.CallState.Connected || mainWindow.call.core.state === LinphoneEnums.CallState.StreamsRunning) {
bottomButtonsLayout.layoutDirection = Qt.RightToLeft bottomButtonsLayout.layoutDirection = Qt.RightToLeft
connectedCallButtons.visible = true connectedCallButtons.visible = true
} else if (mainWindow.callState === LinphoneEnums.CallState.OutgoingInit || mainWindow.callState === LinphoneEnums.CallState.End) {
connectedCallButtons.visible = false
bottomButtonsLayout.layoutDirection = Qt.LeftToRight
} }
} }
Connections {
target: mainWindow
onCallStateChanged: bottomButtonsLayout.refreshLayout()
onCallChanged: bottomButtonsLayout.refreshLayout()
}
function setButtonsEnabled(enabled) { function setButtonsEnabled(enabled) {
for(var i=0; i < children.length; ++i) { for(var i=0; i < children.length; ++i) {
children[i].enabled = false children[i].enabled = false
@ -490,11 +728,11 @@ Window {
Layout.row: 0 Layout.row: 0
enabledIcon: AppIcons.endCall enabledIcon: AppIcons.endCall
checkable: false checkable: false
Layout.column: mainWindow.callState == LinphoneEnums.CallState.OutgoingInit Layout.column: mainWindow.call.core.state == LinphoneEnums.CallState.OutgoingInit
|| mainWindow.callState == LinphoneEnums.CallState.OutgoingProgress || mainWindow.call.core.state == LinphoneEnums.CallState.OutgoingProgress
|| mainWindow.callState == LinphoneEnums.CallState.OutgoingRinging || mainWindow.call.core.state == LinphoneEnums.CallState.OutgoingRinging
|| mainWindow.callState == LinphoneEnums.CallState.OutgoingEarlyMedia || mainWindow.call.core.state == LinphoneEnums.CallState.OutgoingEarlyMedia
|| mainWindow.callState == LinphoneEnums.CallState.IncomingReceived || mainWindow.call.core.state == LinphoneEnums.CallState.IncomingReceived
? 0 : bottomButtonsLayout.columns - 1 ? 0 : bottomButtonsLayout.columns - 1
Layout.preferredWidth: 75 * DefaultStyle.dp Layout.preferredWidth: 75 * DefaultStyle.dp
Layout.preferredHeight: 55 * DefaultStyle.dp Layout.preferredHeight: 55 * DefaultStyle.dp
@ -503,7 +741,7 @@ Window {
color: DefaultStyle.danger_500main color: DefaultStyle.danger_500main
radius: 71 * DefaultStyle.dp radius: 71 * DefaultStyle.dp
} }
onClicked: mainWindow.endCall() onClicked: mainWindow.endCall(mainWindow.call)
} }
RowLayout { RowLayout {
id: connectedCallButtons id: connectedCallButtons
@ -524,30 +762,51 @@ Window {
: DefaultStyle.grey_500 : DefaultStyle.grey_500
: DefaultStyle.grey_600 : DefaultStyle.grey_600
} }
enabled: mainWindow.callState != LinphoneEnums.CallState.PausedByRemote enabled: mainWindow.call.core.state != LinphoneEnums.CallState.PausedByRemote
enabledIcon: enabled && checked ? AppIcons.play : AppIcons.pause enabledIcon: enabled && checked ? AppIcons.play : AppIcons.pause
checked: mainWindow.call && (mainWindow.call.callState === LinphoneEnums.CallState.Paused checked: mainWindow.call.core.paused
|| mainWindow.call.callState === LinphoneEnums.CallState.PausedByRemote) || false onClicked: {
onClicked: mainWindow.call.core.lSetPaused(!mainWindow.call.core.paused) mainWindow.call.core.lSetPaused(!callsModel.currentCall.core.paused)
}
}
BottomButton {
id: newCallButton
checkable: false
enabledIcon: AppIcons.newCall
Layout.preferredWidth: 55 * DefaultStyle.dp
Layout.preferredHeight: 55 * DefaultStyle.dp
onClicked: {
var mainWin = UtilsCpp.getMainWindow()
UtilsCpp.smartShowWindow(mainWin)
mainWin.goToNewCall()
}
} }
BottomButton { BottomButton {
id: transferCallButton id: transferCallButton
enabledIcon: AppIcons.transferCall enabledIcon: AppIcons.transferCall
Layout.preferredWidth: 55 * DefaultStyle.dp Layout.preferredWidth: 55 * DefaultStyle.dp
Layout.preferredHeight: 55 * DefaultStyle.dp Layout.preferredHeight: 55 * DefaultStyle.dp
onClicked: { onCheckedChanged: {
rightPanel.visible = true if (checked) {
rightPanel.currentIndex = 0 rightPanel.visible = true
rightPanel.replace(contactsListPanel)
} else {
rightPanel.visible = false
}
}
Connections {
target: rightPanel
onVisibleChanged: if(!rightPanel.visible) transferCallButton.checked = false
} }
} }
} }
RowLayout { RowLayout {
Layout.row: 0 Layout.row: 0
Layout.column: mainWindow.callState == LinphoneEnums.CallState.OutgoingInit Layout.column: mainWindow.call.core.state == LinphoneEnums.CallState.OutgoingInit
|| mainWindow.callState == LinphoneEnums.CallState.OutgoingProgress || mainWindow.call.core.state == LinphoneEnums.CallState.OutgoingProgress
|| mainWindow.callState == LinphoneEnums.CallState.OutgoingRinging || mainWindow.call.core.state == LinphoneEnums.CallState.OutgoingRinging
|| mainWindow.callState == LinphoneEnums.CallState.OutgoingEarlyMedia || mainWindow.call.core.state == LinphoneEnums.CallState.OutgoingEarlyMedia
|| mainWindow.callState == LinphoneEnums.CallState.IncomingReceived || mainWindow.call.core.state == LinphoneEnums.CallState.IncomingReceived
? bottomButtonsLayout.columns - 1 : 0 ? bottomButtonsLayout.columns - 1 : 0
BottomButton { BottomButton {
enabledIcon: AppIcons.videoCamera enabledIcon: AppIcons.videoCamera
@ -589,10 +848,30 @@ Window {
spacing: 10 * DefaultStyle.dp spacing: 10 * DefaultStyle.dp
Control.Button { Control.Button {
id: dialerButton id: callListButton
// width: 150 Layout.fillWidth: true
background: Item {
visible: false
}
contentItem: RowLayout {
Image {
width: 24 * DefaultStyle.dp
height: 24 * DefaultStyle.dp
source: AppIcons.callList
}
Text {
text: qsTr("Liste d'appel")
}
}
onClicked: {
rightPanel.visible = true
rightPanel.replace(callsListPanel)
moreOptionsMenu.close()
}
}
Control.Button {
id: dialerButton
Layout.fillWidth: true Layout.fillWidth: true
// height: 32 * DefaultStyle.dp
background: Item { background: Item {
visible: false visible: false
} }
@ -608,14 +887,13 @@ Window {
} }
onClicked: { onClicked: {
rightPanel.visible = true rightPanel.visible = true
rightPanel.currentIndex = 1 rightPanel.replace(dialerPanel)
moreOptionsMenu.close() moreOptionsMenu.close()
} }
} }
Control.Button { Control.Button {
id: speakerButton id: speakerButton
Layout.fillWidth: true Layout.fillWidth: true
// height: 32 * DefaultStyle.dp
checkable: true checkable: true
background: Item { background: Item {
visible: false visible: false

View file

@ -16,6 +16,71 @@ Item {
signal addAccountRequest() signal addAccountRequest()
function goToNewCall() {
tabbar.currentIndex = 0
callPage.goToNewCall()
}
function transferCallSucceed() {
transferSucceedPopup.open()
}
Timer {
id: autoClosePopup
interval: 5000
onTriggered: {
transferSucceedPopup.close()
}
}
Popup {
id: transferSucceedPopup
onVisibleChanged: if (visible) autoClosePopup.restart()
closePolicy: Control.Popup.NoAutoClose
x : parent.x + parent.width - width
y : parent.y + parent.height - height
rightMargin: 20 * DefaultStyle.dp
bottomMargin: 20 * DefaultStyle.dp
padding: 20 * DefaultStyle.dp
underlineColor: DefaultStyle.success_500main
radius: 0
contentItem: RowLayout {
spacing: 15 * DefaultStyle.dp
EffectImage {
image.source: AppIcons.smiley
colorizationColor: DefaultStyle.success_500main
Layout.preferredWidth: 32 * DefaultStyle.dp
Layout.preferredHeight: 32 * DefaultStyle.dp
width: 32 * DefaultStyle.dp
height: 32 * DefaultStyle.dp
}
Rectangle {
Layout.preferredWidth: 1 * DefaultStyle.dp
Layout.preferredHeight: parent.height
color: DefaultStyle.main2_200
}
ColumnLayout {
Text {
text: qsTr("Appel transféré")
color: DefaultStyle.success_500main
font {
pixelSize: 16 * DefaultStyle.dp
weight: 800 * DefaultStyle.dp
}
}
Text {
Layout.alignment: Qt.AlignHCenter
Layout.fillWidth: true
text: qsTr("Votre correspondant a été transféré au contact sélectionné")
color: DefaultStyle.main2_500main
font {
pixelSize: 12 * DefaultStyle.dp
weight: 300 * DefaultStyle.dp
}
}
}
}
}
RowLayout { RowLayout {
anchors.fill: parent anchors.fill: parent
// spacing: 30 // spacing: 30
@ -93,6 +158,7 @@ Item {
currentIndex: tabbar.currentIndex currentIndex: tabbar.currentIndex
CallPage { CallPage {
id: callPage
} }
//ContactPage{} //ContactPage{}
//ConversationPage{} //ConversationPage{}

View file

@ -11,6 +11,16 @@ Window {
visible: true visible: true
title: qsTr("Linphone") title: qsTr("Linphone")
property bool firstConnection: true property bool firstConnection: true
function goToNewCall() {
mainWindowStackView.replace(mainPage, StackView.Immediate)
mainWindowStackView.currentItem.goToNewCall()
}
function transferCallSucceed() {
mainWindowStackView.replace(mainPage, StackView.Immediate)
mainWindowStackView.currentItem.transferCallSucceed()
}
AccountProxy{ AccountProxy{
id: accountProxy id: accountProxy
onHaveAccountChanged: { onHaveAccountChanged: {

View file

@ -31,7 +31,6 @@ Control.Popup {
shadowEnabled: true shadowEnabled: true
shadowColor: DefaultStyle.grey_1000 shadowColor: DefaultStyle.grey_1000
shadowOpacity: 0.8 shadowOpacity: 0.8
shadowHorizontalOffset: 10 * DefaultStyle.dp
shadowBlur: 1 shadowBlur: 1
} }
Rectangle { Rectangle {

View file

@ -6,20 +6,29 @@ import Linphone
Control.Popup{ Control.Popup{
id: mainItem id: mainItem
padding: 0 padding: 0
property color underlineColor
property int radius: 16 * DefaultStyle.dp
background: Item{ background: Item{
Rectangle {
visible: mainItem.underlineColor != undefined
width: mainItem.width
height: mainItem.height + 2 * DefaultStyle.dp
color: mainItem.underlineColor
radius: mainItem.radius
}
Rectangle{ Rectangle{
id: backgroundItem id: backgroundItem
width: mainItem.width width: mainItem.width
height: mainItem.height height: mainItem.height
radius: 16 * DefaultStyle.dp radius: mainItem.radius
border.color: DefaultStyle.grey_0 border.color: DefaultStyle.grey_0
border.width: 1 // border.width: 1
} }
MultiEffect { MultiEffect {
anchors.fill: backgroundItem anchors.fill: backgroundItem
source: backgroundItem source: backgroundItem
maskSource: backgroundItem
shadowEnabled: true shadowEnabled: true
shadowColor: DefaultStyle.grey_900
shadowBlur: 1.0 shadowBlur: 1.0
shadowOpacity: 0.1 shadowOpacity: 0.1
} }

View file

@ -10,7 +10,11 @@ AbstractMainPage {
emptyListText: qsTr("Historique d'appel vide") emptyListText: qsTr("Historique d'appel vide")
newItemIconSource: AppIcons.newCall newItemIconSource: AppIcons.newCall
onNoItemButtonPressed: listStackView.push(newCallItem) onNoItemButtonPressed: goToNewCall()
function goToNewCall() {
listStackView.push(newCallItem)
}
leftPanelContent: Item { leftPanelContent: Item {
Layout.fillWidth: true Layout.fillWidth: true
@ -212,6 +216,7 @@ AbstractMainPage {
var addressEnd = "@sip.linphone.org" var addressEnd = "@sip.linphone.org"
if (!address.endsWith(addressEnd)) address += addressEnd if (!address.endsWith(addressEnd)) address += addressEnd
var callVarObject = UtilsCpp.createCall(address) var callVarObject = UtilsCpp.createCall(address)
// var window = UtilsCpp.getCallsWindow()
} }
} }
} }

View file

@ -25,6 +25,7 @@ QtObject {
property string phoneSelected: "image://internal/phone-selected.svg" property string phoneSelected: "image://internal/phone-selected.svg"
property string newCall: "image://internal/phone-plus.svg" property string newCall: "image://internal/phone-plus.svg"
property string endCall: "image://internal/phone-disconnect.svg" property string endCall: "image://internal/phone-disconnect.svg"
property string callList: "image://internal/phone-list.svg"
property string transferCall: "image://internal/phone-transfer.svg" property string transferCall: "image://internal/phone-transfer.svg"
property string adressBook: "image://internal/address-book.svg" property string adressBook: "image://internal/address-book.svg"
property string adressBookSelected: "image://internal/address-book-selected.svg" property string adressBookSelected: "image://internal/address-book-selected.svg"