diff --git a/images/icons/arrow_back-white-24dp.svg b/images/icons/arrow_back-white-24dp.svg
new file mode 100644
index 00000000..bc39c046
--- /dev/null
+++ b/images/icons/arrow_back-white-24dp.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/images/icons/close-white-24dp.svg b/images/icons/close-white-24dp.svg
new file mode 100644
index 00000000..14dc9e49
--- /dev/null
+++ b/images/icons/close-white-24dp.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/images/icons/done-white-24dp.svg b/images/icons/done-white-24dp.svg
new file mode 100644
index 00000000..f835a956
--- /dev/null
+++ b/images/icons/done-white-24dp.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/qml.qrc b/qml.qrc
index e4d6e500..ffd94949 100644
--- a/qml.qrc
+++ b/qml.qrc
@@ -112,5 +112,6 @@
src/wizardview/components/AccountCreationStepIndicator.qml
src/commoncomponents/SpinnerButton.qml
src/commoncomponents/UsernameLineEdit.qml
+ src/mainview/components/UserInfoCallPage.qml
diff --git a/resources.qrc b/resources.qrc
index 5a412778..0ea0cf0b 100644
--- a/resources.qrc
+++ b/resources.qrc
@@ -119,5 +119,6 @@
images/icons/person_add-24px.svg
images/icons/router-24px.svg
images/icons/insert_drive_file-24dp.svg
+ images/icons/arrow_back-white-24dp.svg
diff --git a/src/calladapter.cpp b/src/calladapter.cpp
index 97835d5e..c49ce85e 100644
--- a/src/calladapter.cpp
+++ b/src/calladapter.cpp
@@ -23,10 +23,10 @@
*/
#include "calladapter.h"
-
-#include "globalsystemtray.h"
#include "utils.h"
+#include
+
CallAdapter::CallAdapter(QObject* parent)
: QmlAdapterBase(parent)
, oneSecondTimer_(new QTimer(this))
@@ -94,7 +94,6 @@ CallAdapter::refuseACall(const QString& accountId, const QString& convUid)
void
CallAdapter::acceptACall(const QString& accountId, const QString& convUid)
{
- emit incomingCallNeedToSetupMainView(accountId, convUid);
auto* convModel = LRCInstance::getCurrentConversationModel();
const auto convInfo = convModel->getConversationForUID(convUid);
if (!convInfo.uid.isEmpty()) {
@@ -107,50 +106,35 @@ CallAdapter::acceptACall(const QString& accountId, const QString& convUid)
void
CallAdapter::slotShowIncomingCallView(const QString& accountId, const conversation::Info& convInfo)
{
+ auto selectedAccountId = LRCInstance::getCurrAccId();
auto* callModel = LRCInstance::getCurrentCallModel();
-
if (!callModel->hasCall(convInfo.callId)) {
- /*
- * Connection to close potential incoming call page when it is not current account.
- */
- auto& accInfo = LRCInstance::accountModel().getAccountInfo(accountId);
- QObject::disconnect(closeIncomingCallPageConnection_);
-
- closeIncomingCallPageConnection_
- = QObject::connect(accInfo.callModel.get(),
- &lrc::api::NewCallModel::callStatusChanged,
- [this, accountId, uid = convInfo.uid](const QString& callId) {
- auto& accInfo = LRCInstance::accountModel().getAccountInfo(
- accountId);
- auto& callModel = accInfo.callModel;
- auto call = callModel->getCall(callId);
-
- switch (call.status) {
- case lrc::api::call::Status::INVALID:
- case lrc::api::call::Status::INACTIVE:
- case lrc::api::call::Status::ENDED:
- case lrc::api::call::Status::PEER_BUSY:
- case lrc::api::call::Status::TIMEOUT:
- case lrc::api::call::Status::TERMINATING: {
- if (!uid.isEmpty())
- emit closePotentialIncomingCallPageWindow(accountId, uid);
- break;
- }
- default:
- break;
- }
-
- emit updateConversationSmartList();
- QObject::disconnect(closeIncomingCallPageConnection_);
- });
- /*
- * Show incoming call page only.
- */
- auto accountProperties = LRCInstance::accountModel().getAccountConfig(accountId);
- if (!accountProperties.autoAnswer && !accountProperties.isRendezVous) {
- emit showIncomingCallPage(accountId, convInfo.uid);
+ if (QApplication::focusObject() == nullptr || accountId != selectedAccountId) {
+ showNotification(accountId, convInfo);
+ return;
}
+
+ auto* convModel = LRCInstance::getCurrentConversationModel();
+ const auto currentConvUid = LRCInstance::getCurrentConvUid();
+ const auto currentConvInfo = convModel->getConversationForUID(currentConvUid);
+
+ // Call in current conversation
+ auto currentConvHasCall = callModel->hasCall(currentConvInfo.callId);
+
+ // Check INCOMING / OUTGOING call in current conversation
+ if (currentConvHasCall) {
+ auto currentCall = callModel->getCall(currentConvInfo.callId);
+ if (currentCall.status == lrc::api::call::Status::CONNECTED ||
+ currentCall.status == lrc::api::call::Status::IN_PROGRESS) {
+ showNotification(accountId, convInfo);
+ return;
+ }
+ }
+ emit incomingCallNeedToSetupMainView(accountId, convInfo.uid);
+ emit showIncomingCallPage(accountId, convInfo.uid);
+ emit showCallStack(accountId, convInfo.uid, true);
+ emit updateConversationSmartList();
return;
}
@@ -163,15 +147,55 @@ CallAdapter::slotShowIncomingCallView(const QString& accountId, const conversati
emit showCallStack(accountId, convInfo.uid);
}
} else {
- auto selectedAccountId = LRCInstance::getCurrentAccountInfo().id;
+ auto showIncomingCall = false;
auto accountProperties = LRCInstance::accountModel().getAccountConfig(selectedAccountId);
if (!accountProperties.autoAnswer && !accountProperties.isRendezVous) {
+
+ // App not focused or in different account
+ if (QApplication::focusObject() == nullptr || accountId != selectedAccountId) {
+ showNotification(accountId, convInfo);
+ return;
+ }
+
+ auto* convModel = LRCInstance::getCurrentConversationModel();
+ const auto currentConvUid = LRCInstance::getCurrentConvUid();
+ const auto currentConvInfo = convModel->getConversationForUID(currentConvUid);
+
+ // Call in current conversation
+ auto currentConvHasCall = callModel->hasCall(currentConvInfo.callId);
+
+ // Check INCOMING / OUTGOING call in current conversation
+ if (isCallSelected) {
+ if (currentConvHasCall) {
+ auto currentCall = callModel->getCall(currentConvInfo.callId);
+ if (currentCall.status == lrc::api::call::Status::OUTGOING_RINGING) {
+ showNotification(accountId, convInfo);
+ } else {
+ showIncomingCall = true;
+ }
+ } else {
+ showIncomingCall = true;
+ }
+ } else { // Not current conversation
+ if (currentConvHasCall) {
+ auto currentCall = callModel->getCall(currentConvInfo.callId);
+ if (currentCall.status == lrc::api::call::Status::CONNECTED ||
+ currentCall.status == lrc::api::call::Status::IN_PROGRESS) {
+ showNotification(accountId, convInfo);
+ return;
+ }
+ }
+ showIncomingCall = true;
+ }
+ }
+
+ if (showIncomingCall) {
+ emit incomingCallNeedToSetupMainView(accountId, convInfo.uid);
emit showIncomingCallPage(accountId, convInfo.uid);
+ emit showCallStack(accountId, convInfo.uid, true);
}
}
-
emit callStatusChanged(static_cast(call.status), accountId, convInfo.uid);
-
emit updateConversationSmartList();
}
@@ -275,6 +299,48 @@ CallAdapter::getConferencesInfos()
return map;
}
+void
+CallAdapter::showNotification(const QString& accountId, const lrc::api::conversation::Info& convInfo)
+{
+ // Hack for handling multiple consecutive calls to slotShowIncomingCallView (bug)
+ // Do not set notification if it is already active for the account and conversation
+ if (accountId == GlobalSystemTray::instance().getTriggeredAccountId() &&
+ convInfo.uid == GlobalSystemTray::instance().getPossibleOnGoingConversationUid()) {
+ return;
+ }
+
+ QString sender = convInfo.uid;
+ if (accountId != "") {
+ auto& accInfo = LRCInstance::getAccountInfo(accountId);
+ if (!convInfo.participants.isEmpty()) {
+ auto &contact = accInfo.contactModel->getContact(convInfo.participants[0]);
+ sender = Utils::bestNameForContact(contact);
+ }
+ }
+
+ GlobalSystemTray::instance().setPossibleOnGoingConversationUid(convInfo.uid);
+
+ QObject::connect(&GlobalSystemTray::instance(), &GlobalSystemTray::messageClicked,
+ this, [this, accountId, convInfo]() {
+ if (accountId != "" && convInfo.uid != "") {
+
+ emit incomingCallNeedToSetupMainView(accountId, convInfo.uid, true);
+
+ auto call = LRCInstance::getCallInfoForConversation(convInfo);
+ if (call->status == lrc::api::call::Status::INCOMING_RINGING) {
+ emit showIncomingCallPage(accountId, convInfo.uid);
+ emit showCallStack(accountId, convInfo.uid, true);
+ }
+ emit updateConversationSmartList();
+ }
+ GlobalSystemTray::instance().setTriggeredAccountId("");
+ GlobalSystemTray::instance().setPossibleOnGoingConversationUid("");
+
+ }, Qt::UniqueConnection);
+
+ Utils::showSystemNotification(QApplication::focusWidget(), sender, tr("is calling you"), 0, accountId);
+}
+
void
CallAdapter::connectCallModel(const QString& accountId)
{
@@ -385,7 +451,6 @@ CallAdapter::connectCallModel(const QString& accountId)
}
} else {
emit closeCallStack(accountId, convInfo.uid);
- emit closePotentialIncomingCallPageWindow(accountId, convInfo.uid);
}
break;
diff --git a/src/calladapter.h b/src/calladapter.h
index 498f4570..cfc18edc 100644
--- a/src/calladapter.h
+++ b/src/calladapter.h
@@ -21,10 +21,12 @@
#include "lrcinstance.h"
#include "qmladapterbase.h"
+#include "globalsystemtray.h"
#include
#include
#include
+#include
class CallAdapter final : public QmlAdapterBase
{
@@ -70,14 +72,14 @@ signals:
void showVideoCallPage(const QString& accountId, const QString& convUid, const QString& callId);
void showCallStack(const QString& accountId, const QString& convUid, bool forceReset = false);
void closeCallStack(const QString& accountId, const QString& convUid);
- void closePotentialIncomingCallPageWindow(const QString& accountId, const QString& convUid);
void callStatusChanged(int index, const QString& accountId, const QString& convUid);
void updateConversationSmartList();
void updateParticipantsInfos(const QVariantList& infos,
const QString& accountId,
const QString& callId);
- void incomingCallNeedToSetupMainView(const QString& accountId, const QString& convUid);
+ void incomingCallNeedToSetupMainView(const QString& accountId, const QString& convUid,
+ bool fromNotification = false);
void previewVisibilityNeedToChange(bool visible);
/*
@@ -105,6 +107,7 @@ private:
const QString& accountId = {},
bool forceCallOnly = false);
bool shouldShowPreview(bool force);
+ void showNotification(const QString& accountId, const lrc::api::conversation::Info& convInfo);
/*
* Current conf/call info.
@@ -115,6 +118,7 @@ private:
QMetaObject::Connection callStatusChangedConnection_;
QMetaObject::Connection onParticipantsChangedConnection_;
QMetaObject::Connection closeIncomingCallPageConnection_;
+ QMetaObject::Connection appStateChangedConnection_;
/*
* For Call Overlay
diff --git a/src/globalsystemtray.cpp b/src/globalsystemtray.cpp
index ae98ff29..73b9fddb 100644
--- a/src/globalsystemtray.cpp
+++ b/src/globalsystemtray.cpp
@@ -33,13 +33,13 @@ GlobalSystemTray::getTriggeredAccountId()
}
void
-GlobalSystemTray::setPossibleOnGoingConversationInfo(const lrc::api::conversation::Info& convInfo)
+GlobalSystemTray::setPossibleOnGoingConversationUid(const QString& convUid)
{
- triggeredOnGoingConvInfo_ = convInfo;
+ triggeredOnGoingConvUid_ = convUid;
}
-const lrc::api::conversation::Info&
-GlobalSystemTray::getPossibleOnGoingConversationInfo()
+const QString&
+GlobalSystemTray::getPossibleOnGoingConversationUid()
{
- return triggeredOnGoingConvInfo_;
+ return triggeredOnGoingConvUid_;
}
diff --git a/src/globalsystemtray.h b/src/globalsystemtray.h
index 3c84808e..1ce513c2 100644
--- a/src/globalsystemtray.h
+++ b/src/globalsystemtray.h
@@ -41,13 +41,13 @@ public:
const QString& getTriggeredAccountId();
- void setPossibleOnGoingConversationInfo(const lrc::api::conversation::Info& convInfo);
+ void setPossibleOnGoingConversationUid(const QString& convUid);
- const lrc::api::conversation::Info& getPossibleOnGoingConversationInfo();
+ const QString& getPossibleOnGoingConversationUid();
private:
GlobalSystemTray();
QString triggeredAccountId_;
- lrc::api::conversation::Info triggeredOnGoingConvInfo_;
+ QString triggeredOnGoingConvUid_;
};
diff --git a/src/mainview/MainView.qml b/src/mainview/MainView.qml
index 26f66a91..9085882a 100644
--- a/src/mainview/MainView.qml
+++ b/src/mainview/MainView.qml
@@ -25,7 +25,6 @@ import net.jami.Models 1.0
import net.jami.Adapters 1.0
// Import qml component files.
-
import "components"
import "../wizardview"
import "../settingsview"
@@ -47,38 +46,76 @@ Window {
property int savedSidePanelViewMaxWidth: 0
property int savedWelcomeViewMinWidth: 0
property int savedWelcomeViewMaxWidth: 0
- property bool sidePanelHidden: false
+ property bool sidePanelHidden: !mainViewStack.visible
// To calculate tab bar bottom border hidden rect left margin.
property int tabBarLeftMargin: 8
property int tabButtonShrinkSize: 8
property bool inSettingsView: false
- property bool needToShowCallStack: false
- property bool needToCloseCallStack: false
signal closeApp
signal noAccountIsAvailable
- function pushCallStackView(){
- if (mainViewStack.visible) {
- mainViewStack.pop(null, StackView.Immediate)
- mainViewStack.push(callStackView, StackView.Immediate)
- } else {
- sidePanelViewStack.pop(null, StackView.Immediate)
- sidePanelViewStack.push(callStackView, StackView.Immediate)
+ function showWelcomeView() {
+ mainViewWindowSidePanel.deselectConversationSmartList()
+ if (communicationPageMessageWebView.visible || callStackView.visible) {
+ sidePanelViewStack.pop(StackView.Immediate)
+ if (!sidePanelHidden) {
+ mainViewStack.pop(welcomePage, StackView.Immediate)
+ }
}
}
- function pushCommunicationMessageWebView(){
- if (mainViewStack.visible) {
- mainViewStack.pop(null, StackView.Immediate)
- mainViewStack.push(communicationPageMessageWebView,
- StackView.Immediate)
+ function setCallStackView() {
+
+ mainViewWindowSidePanel.deselectConversationSmartList()
+
+ var currentAccount = AccountAdapter.currentAccountId
+ var currentCallConv = UtilsAdapter.getCallConvForAccount(currentAccount)
+
+ ConversationsAdapter.selectConversation(currentCallConv)
+ var callId = UtilsAdapter.getCallId(currentAccount, currentCallConv)
+ var callStatus = UtilsAdapter.getCallStatus(callId)
+
+ switch (callStatus) {
+ case Call.Status.INCOMING_RINGING:
+ callStackView.showIncomingCallPage(currentAccount, currentCallConv)
+ break
+ case Call.Status.OUTGOING_RINGING:
+ callStackView.showOutgoingCallPage()
+ break
+ default:
+ if (UtilsAdapter.hasVideoCall()) {
+ callStackView.showVideoCallPage(callId)
+ } else {
+ callStackView.showAudioCallPage()
+ }
+ }
+
+ pushCallStackView()
+
+ callStackView.responsibleAccountId = currentAccount
+ callStackView.responsibleConvUid = currentCallConv
+ callStackView.updateCorrespondingUI()
+ }
+
+
+ function pushCallStackView() {
+ if (sidePanelHidden) {
+ sidePanelViewStack.push(callStackView, StackView.Immediate)
} else {
- sidePanelViewStack.pop(null, StackView.Immediate)
- sidePanelViewStack.push(
- communicationPageMessageWebView,
- StackView.Immediate)
+ sidePanelViewStack.pop(StackView.Immediate)
+ mainViewStack.pop(null, StackView.Immediate)
+ mainViewStack.push(callStackView, StackView.Immediate)
+ }
+ }
+
+ function pushCommunicationMessageWebView() {
+ if (sidePanelHidden) {
+ sidePanelViewStack.push(communicationPageMessageWebView, StackView.Immediate)
+ } else {
+ mainViewStack.pop(null, StackView.Immediate)
+ mainViewStack.push(communicationPageMessageWebView, StackView.Immediate)
}
}
@@ -86,6 +123,10 @@ Window {
mainViewWindowSidePanel.refreshAccountComboBox(index)
}
+ function currentAccountIsCalling() {
+ return UtilsAdapter.hasCall(AccountAdapter.currentAccountId)
+ }
+
function recursionStackViewItemMove(stackOne, stackTwo, depth=1) {
// Move all items (expect the bottom item) to stacktwo by the same order in stackone.
@@ -111,28 +152,25 @@ Window {
mainViewStack.push(settingsView, StackView.Immediate)
sidePanelViewStack.push(leftPanelSettingsView, StackView.Immediate)
}
- ConversationsAdapter.disconnectConversationModel()
} else {
- ConversationsAdapter.connectConversationModel(false)
- ConversationsAdapter.refill() // to be sure to have latest informations
- mainViewWindowSidePanel.forceUpdateConversationSmartListView()
-
- if (!sidePanelHidden) {
- sidePanelViewStack.pop(mainViewWindowSidePanel, StackView.Immediate)
- mainViewStack.pop(StackView.Immediate)
- } else {
+ if (sidePanelHidden) {
recursionStackViewItemMove(sidePanelViewStack, mainViewStack, 2)
sidePanelViewStack.pop(StackView.Immediate)
mainViewStack.pop(StackView.Immediate)
recursionStackViewItemMove(mainViewStack, sidePanelViewStack, 1)
}
- if (needToCloseCallStack) {
- pushCommunicationMessageWebView()
- needToShowCallStack = false
- needToCloseCallStack = false
+ if (currentAccountIsCalling()) {
+ setCallStackView()
+ } else {
+ mainViewWindowSidePanel.deselectConversationSmartList()
+
+ sidePanelViewStack.pop(StackView.Immediate)
+ if (!sidePanelHidden) {
+ mainViewStack.pop(welcomePage, StackView.Immediate)
+ }
}
}
inSettingsView = !inSettingsView
@@ -150,13 +188,11 @@ Window {
function onShowCallStack(accountId, convUid, forceReset) {
- needToShowCallStack = true
if (forceReset) {
callStackView.responsibleAccountId = accountId
callStackView.responsibleConvUid = convUid
}
-
// Check if it is coming from the current responsible call,
// and push views onto the correct stackview
if (callStackView.responsibleAccountId === accountId
@@ -166,7 +202,6 @@ Window {
}
function onCloseCallStack(accountId, convUid) {
-
// Check if call stack view is on any of the stackview.
if (callStackView.responsibleAccountId === accountId
&& callStackView.responsibleConvUid === convUid) {
@@ -174,20 +209,16 @@ Window {
return item.objectName === "callStackViewObject"
}) || sidePanelViewStack.find(function (item, index) {
return item.objectName === "callStackViewObject"
- }) || (inSettingsView && needToShowCallStack)) {
- callStackView.needToCloseInCallConversationAndPotentialWindow()
-
+ })) {
if (!inSettingsView) {
+ callStackView.needToCloseInCallConversationAndPotentialWindow()
pushCommunicationMessageWebView()
- needToShowCallStack = false
- } else {
- needToCloseCallStack = true
}
}
}
}
- function onIncomingCallNeedToSetupMainView(accountId, convUid) {
+ function onIncomingCallNeedToSetupMainView(accountId, convUid, fromNotification) {
// Set up the call stack view that is needed by call overlay.
if (!inSettingsView) {
@@ -205,16 +236,14 @@ Window {
communicationPageMessageWebView.headerUserUserNameLabelText = (name !== id) ? id : ""
callStackView.needToCloseInCallConversationAndPotentialWindow()
- callStackView.setLinkedWebview(
- communicationPageMessageWebView)
+ callStackView.setLinkedWebview(communicationPageMessageWebView)
callStackView.responsibleAccountId = accountId
callStackView.responsibleConvUid = convUid
- callStackView.updateCorrspondingUI()
+ callStackView.updateCorrespondingUI()
mainViewWindowSidePanel.refreshAccountComboBox(index)
- ConversationsAdapter.selectConversation(accountId, convUid)
-
+ ConversationsAdapter.selectConversation(accountId, convUid, !fromNotification)
MessagesAdapter.setupChatView(convUid)
}
}
@@ -264,7 +293,9 @@ Window {
Rectangle {
implicitWidth: 1
implicitHeight: splitView.height
- color: SplitHandle.pressed ? JamiTheme.pressColor : (SplitHandle.hovered ? JamiTheme.hoverColor : JamiTheme.tabbarBorderColor)
+ color: SplitHandle.pressed ? JamiTheme.pressColor :
+ (SplitHandle.hovered ? JamiTheme.hoverColor :
+ JamiTheme.tabbarBorderColor)
}
}
@@ -272,9 +303,10 @@ Window {
id: mainViewSidePanelRect
SplitView.minimumWidth: sidePanelViewStackPreferredWidth
SplitView.maximumWidth: (sidePanelHidden ? splitView.width :
- splitView.width - sidePanelViewStackPreferredWidth)
+ splitView.width - sidePanelViewStackPreferredWidth)
SplitView.fillHeight: true
+
// AccountComboBox is always visible
AccountComboBox {
id: accountComboBox
@@ -304,24 +336,26 @@ Window {
}
onAccountChanged: {
+ mainViewWindowSidePanel.deselectConversationSmartList()
+
mainViewWindowSidePanel.refreshAccountComboBox(index)
+
settingsView.slotAccountListChanged()
settingsView.setSelected(settingsView.selectedMenu, true)
- if (needToShowCallStack
- && callStackView.responsibleAccountId === UtilsAdapter.getCurrAccId()){
- if (!AccountAdapter.hasVideoCall()) {
- pushCommunicationMessageWebView()
- needToShowCallStack = false
- } else if (needToShowCallStack) {
- pushCallStackView()
+ if (!inSettingsView) {
+ if (currentAccountIsCalling()) {
+ setCallStackView()
+ } else {
+ showWelcomeView()
}
}
}
onNeedToBackToWelcomePage: {
- if (!inSettingsView)
+ if (!inSettingsView && !currentAccountIsCalling()) {
mainViewWindowSidePanel.accountComboBoxNeedToShowWelcomePage()
+ }
}
onNewAccountButtonClicked: {
@@ -338,7 +372,8 @@ Window {
initialItem: mainViewWindowSidePanel
- anchors.top: accountComboBox.visible ? accountComboBox.bottom : mainViewSidePanelRect.top
+ anchors.top: accountComboBox.visible ? accountComboBox.bottom :
+ mainViewSidePanelRect.top
width: mainViewSidePanelRect.width
height: accountComboBox.visible ? mainViewSidePanelRect.height - accountComboBox.height :
mainViewSidePanelRect.height
@@ -352,7 +387,8 @@ Window {
initialItem: welcomePage
- SplitView.maximumWidth: sidePanelHidden ? splitView.width : splitView.width - sidePanelViewStackPreferredWidth
+ SplitView.maximumWidth: sidePanelHidden ? splitView.width :
+ splitView.width - sidePanelViewStackPreferredWidth
SplitView.minimumWidth: sidePanelViewStackPreferredWidth
SplitView.fillHeight: true
@@ -410,7 +446,6 @@ Window {
}
}
-
SidePanel {
id: mainViewWindowSidePanel
@@ -422,11 +457,11 @@ Window {
callStackView.needToCloseInCallConversationAndPotentialWindow()
callStackView.responsibleAccountId = UtilsAdapter.getCurrAccId()
callStackView.responsibleConvUid = currentUID
- callStackView.updateCorrspondingUI()
+ callStackView.updateCorrespondingUI()
if (callStackViewShouldShow) {
if (callState === Call.Status.IN_PROGRESS || callState === Call.Status.PAUSED) {
- UtilsAdapter.setCurrentCall(UtilsAdapter.getCurrAccId(), currentUID)
+ UtilsAdapter.setCurrentCall(AccountAdapter.currentAccountId, currentUID)
if (isAudioOnly)
callStackView.showAudioCallPage()
else
@@ -434,15 +469,17 @@ Window {
UtilsAdapter.getCallId(
callStackView.responsibleAccountId,
callStackView.responsibleConvUid))
+ } else if (callState === Call.Status.INCOMING_RINGING) {
+ callStackView.showIncomingCallPage(AccountAdapter.currentAccountId,
+ currentUID)
} else {
- callStackView.showOutgoingCallPage(callStateStr)
+ callStackView.showOutgoingCallPage()
}
}
// Set up chatview.
MessagesAdapter.setupChatView(currentUID)
- callStackView.setLinkedWebview(
- communicationPageMessageWebView)
+ callStackView.setLinkedWebview(communicationPageMessageWebView)
if (mainViewStack.find(function (item, index) {
return item.objectName === "communicationPageMessageWebView"
@@ -453,7 +490,6 @@ Window {
return
}
-
// Push messageWebView or callStackView onto the correct stackview
mainViewStack.pop(null, StackView.Immediate)
sidePanelViewStack.pop(null, StackView.Immediate)
@@ -483,13 +519,13 @@ Window {
onAccountComboBoxNeedToShowWelcomePage: {
// If the item argument is specified, all items down to (but not including) item will be popped.
- if (!inSettingsView) {
- mainViewStack.pop(welcomePage)
+ if (!inSettingsView && !currentAccountIsCalling()) {
+ showWelcomeView()
}
}
onConversationSmartListViewNeedToShowWelcomePage: {
- mainViewStack.pop(welcomePage)
+ showWelcomeView()
}
onNeedToUpdateConversationForAddedContact: {
@@ -559,22 +595,15 @@ Window {
}
onNeedToGoBackToWelcomeView: {
- mainViewWindowSidePanel.deselectConversationSmartList()
- if (communicationPageMessageWebView.visible
- && !mainViewStack.visible) {
- sidePanelViewStack.pop()
- } else if (communicationPageMessageWebView.visible
- && mainViewStack.visible) {
- mainViewStack.pop()
- }
+ showWelcomeView()
recordBox.visible = false
}
Component.onCompleted: {
sidePanelViewStack.SplitView.maximumWidth = Qt.binding(function() {
- return (hiddenView ? splitView.width :
- splitView.width - sidePanelViewStackPreferedWidth)
+ return (sidePanelHidden ? splitView.width :
+ splitView.width - sidePanelViewStackPreferredWidth)
})
recordBox.x = Qt.binding(function() {
@@ -592,7 +621,6 @@ Window {
sidePanelViewStack.height + recordBox.y_offset
})
-
// Set qml MessageWebView object pointer to c++.
MessagesAdapter.setQmlObject(this)
}
@@ -604,7 +632,6 @@ Window {
+ mainViewStackPreferredWidth - 5
&& mainViewStack.visible) {
mainViewStack.visible = false
- sidePanelHidden = true
// The find callback function is called for each item in the stack.
var inWelcomeViewStack = mainViewStack.find(
@@ -621,7 +648,6 @@ Window {
+ mainViewStackPreferredWidth + 5
&& !mainViewStack.visible) {
mainViewStack.visible = true
- sidePanelHidden = false
var inSidePanelViewStack = sidePanelViewStack.find(
function (item, index) {
@@ -631,6 +657,9 @@ Window {
recursionStackViewItemMove(sidePanelViewStack, mainViewStack, (inSettingsView ? 2 : 1))
}
+ if (!inSettingsView && currentAccountIsCalling())
+ pushCallStackView()
+
mainViewWindow.update()
}
}
diff --git a/src/mainview/components/CallOverlay.qml b/src/mainview/components/CallOverlay.qml
index ed5653ef..764a50d3 100644
--- a/src/mainview/components/CallOverlay.qml
+++ b/src/mainview/components/CallOverlay.qml
@@ -151,6 +151,31 @@ Rectangle {
anchors.fill: parent
+ HoverableButton {
+ id: backButton
+
+ Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
+ Layout.preferredWidth: JamiTheme.preferredFieldHeight
+ Layout.preferredHeight: JamiTheme.preferredFieldHeight
+ Layout.rightMargin: JamiTheme.preferredMarginSize
+ Layout.topMargin: JamiTheme.preferredMarginSize
+ Layout.leftMargin: JamiTheme.preferredMarginSize
+
+ radius: 32
+ source: "qrc:/images/icons/arrow_back-white-24dp.svg"
+ backgroundColor: "transparent"
+ onExitColor: "transparent"
+ onEnterColor: JamiTheme.lightGrey_
+ toolTipText: qsTr("Toggle to display side panel")
+ hoverEnabled: true
+
+ visible: mainViewWindow.sidePanelHidden
+
+ onClicked: {
+ mainViewWindow.showWelcomeView() // TODO: refactor with msg manager
+ }
+ }
+
Text {
id: jamiBestNameText
diff --git a/src/mainview/components/CallStackView.qml b/src/mainview/components/CallStackView.qml
index 5b20feef..38301eec 100644
--- a/src/mainview/components/CallStackView.qml
+++ b/src/mainview/components/CallStackView.qml
@@ -32,6 +32,12 @@ Rectangle {
anchors.fill: parent
+ Shortcut {
+ sequence: "Ctrl+D"
+ context: Qt.ApplicationShortcut
+ onActivated: CallAdapter.hangUpThisCall()
+ }
+
// When selected conversation is changed,
// these values will also be changed.
property string responsibleConvUid: ""
@@ -41,7 +47,6 @@ Rectangle {
audioCallPage.closeInCallConversation()
videoCallPage.closeInCallConversation()
-
// Close potential window, context menu releated windows.
audioCallPage.closeContextMenuAndRelatedWindows()
@@ -54,9 +59,10 @@ Rectangle {
videoCallPage.setLinkedWebview(webViewId)
}
- function updateCorrspondingUI() {
+ function updateCorrespondingUI() {
audioCallPage.updateUI(responsibleAccountId, responsibleConvUid)
outgoingCallPage.updateUI(responsibleAccountId, responsibleConvUid)
+ incomingCallPage.updateUI(responsibleAccountId, responsibleConvUid)
videoCallPage.updateUI(responsibleAccountId, responsibleConvUid)
}
@@ -73,7 +79,7 @@ Rectangle {
audioCallPage.updateUI(responsibleAccountId, responsibleConvUid)
}
- function showOutgoingCallPage(currentCallStatus) {
+ function showOutgoingCallPage() {
var itemToFind = callStackMainView.find(function (item) {
return item.stackNumber === 1
})
@@ -83,8 +89,21 @@ Rectangle {
} else {
callStackMainView.pop(itemToFind, StackView.Immediate)
}
- if (currentCallStatus)
- outgoingCallPage.callStatus = currentCallStatus
+ }
+
+ function showIncomingCallPage(accountId, convUid) {
+ var itemToFind = callStackMainView.find(function (item) {
+ return item.stackNumber === 3
+ })
+
+ if (!itemToFind) {
+ callStackMainView.push(incomingCallPage, StackView.Immediate)
+ } else {
+ callStackMainView.pop(itemToFind, StackView.Immediate)
+ }
+ responsibleAccountId = accountId
+ responsibleConvUid = convUid
+ incomingCallPage.updateUI(accountId, convUid)
}
function showVideoCallPage(callId) {
@@ -106,7 +125,6 @@ Rectangle {
function onShowOutgoingCallPage(accountId, convUid) {
-
// Need to check whether it is the current selected conversation.
if (responsibleConvUid === convUid
&& responsibleAccountId === accountId) {
@@ -115,18 +133,7 @@ Rectangle {
}
function onShowIncomingCallPage(accountId, convUid) {
-
-
- // Check is done within the js.
- IncomingCallPageCreation.createincomingCallPageWindowObjects(
- accountId, convUid)
- IncomingCallPageCreation.showIncomingCallPageWindow(accountId,
- convUid)
- }
-
- function onClosePotentialIncomingCallPageWindow(accountId, convUid) {
- IncomingCallPageCreation.closeIncomingCallPageWindow(accountId,
- convUid)
+ showIncomingCallPage(accountId, convUid)
}
function onShowAudioCallPage(accountId, convUid) {
@@ -196,6 +203,20 @@ Rectangle {
}
}
+ IncomingCallPage {
+ id: incomingCallPage
+
+ property int stackNumber: 3
+
+ onCallAcceptButtonIsClicked: {
+ CallAdapter.acceptACall(responsibleAccountId, responsibleConvUid)
+ }
+
+ onCallCancelButtonIsClicked: {
+ CallAdapter.hangUpACall(responsibleAccountId, responsibleConvUid)
+ }
+ }
+
StackView {
id: callStackMainView
diff --git a/src/mainview/components/IncomingCallPage.qml b/src/mainview/components/IncomingCallPage.qml
index 87d68eea..e01e4075 100644
--- a/src/mainview/components/IncomingCallPage.qml
+++ b/src/mainview/components/IncomingCallPage.qml
@@ -25,313 +25,128 @@ import net.jami.Models 1.0
import "../../commoncomponents"
-
-// IncomingCallPage as a seperate window,
-// exist at the right bottom, as a notification to user that
-// a call is incoming.
-Window {
+Rectangle {
id: incomingCallPage
- property int minWidth: 300
- property int minHeight: 400
+ property int buttonPreferredSize: 48
+ signal callCancelButtonIsClicked
+ signal callAcceptButtonIsClicked
- // The unique identifier for incomingCallPage
- property string responsibleAccountId: ""
- property string responsibleConvUid: ""
+ color: "black"
- property string contactImgSource: ""
- property string bestName: "Best Name"
- property string bestId: "Best Id"
-
- property int buttonPreferredSize: 50
- property variant clickPos: "1,1"
-
- function updateUI() {
- incomingCallPage.contactImgSource = "data:image/png;base64,"
- + UtilsAdapter.getContactImageString(responsibleAccountId,
- responsibleConvUid)
- incomingCallPage.bestName = UtilsAdapter.getBestName(
- responsibleAccountId, responsibleConvUid)
- var id = UtilsAdapter.getBestId(responsibleAccountId,
- responsibleConvUid)
- incomingCallPage.bestId = (incomingCallPage.bestName !== id) ? id : ""
+ function updateUI(accountId, convUid) {
+ userInfoIncomingCallPage.updateUI(accountId, convUid)
}
- function updatePositionToRightBottom() {
-
-
- // Screen right bottom,
- // since the qt screen.virtualY, virtualX does not work properly,
- // we need to calculate the screen x, y ourselves, by
- // using to fact that window will always be in the middle if no x or y
- // specificed.
- // ex: https://doc.qt.io/qt-5/qscreen.html#geometry-prop
- var virtualX = (incomingCallPage.x + width / 2) - screen.width / 2
- incomingCallPage.x = virtualX + screen.width - width
- incomingCallPage.y = screen.height - height - 50
+ // Prevent right click propagate to VideoCallPage.
+ MouseArea {
+ anchors.fill: parent
+ propagateComposedEvents: false
+ acceptedButtons: Qt.RightButton
}
- minimumWidth: minWidth
- minimumHeight: minHeight
-
- maximumWidth: minWidth + 300
- maximumHeight: minHeight + 300
-
- flags: Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint
- screen: Qt.application.screens[0]
-
- Rectangle {
- id: incomingCallPageColumnLayoutMainRect
+ ColumnLayout {
+ id: incomingCallPageColumnLayout
anchors.fill: parent
- radius: 15
- color: "black"
-
-
- // Simulate window drag. (top with height 30).
- MouseArea {
- id: dragMouseArea
-
- anchors.left: incomingCallPageColumnLayoutMainRect.left
- anchors.top: incomingCallPageColumnLayoutMainRect.top
-
- width: incomingCallPageColumnLayoutMainRect.width - closeButton.width - 10
- height: 30
-
- onPressed: {
- clickPos = Qt.point(mouse.x, mouse.y)
- }
-
- onPositionChanged: {
- var delta = Qt.point(mouse.x - clickPos.x, mouse.y - clickPos.y)
- incomingCallPage.x += delta.x
- incomingCallPage.y += delta.y
- }
+ // Common elements with OutgoingCallPage
+ UserInfoCallPage {
+ id: userInfoIncomingCallPage
+ Layout.fillWidth: true
+ Layout.fillHeight: true
}
- HoverableButton {
- id: closeButton
+ Text {
+ id: talkToYouText
- anchors.top: incomingCallPageColumnLayoutMainRect.top
- anchors.topMargin: 10
- anchors.right: incomingCallPageColumnLayoutMainRect.right
- anchors.rightMargin: 10
+ Layout.alignment: Qt.AlignCenter
+ Layout.preferredWidth: incomingCallPage.width
+ Layout.preferredHeight: 32
- width: 30
- height: 30
+ font.pointSize: JamiTheme.textFontSize
- radius: 30
- source: "qrc:/images/icons/ic_close_white_24dp.png"
- backgroundColor: "black"
- onEnterColor: JamiTheme.closeButtonLighterBlack
- onExitColor: "black"
- onPressColor: JamiTheme.declineButtonPressedRed
- onReleaseColor: "black"
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ color: "white"
- onClicked: {
- incomingCallPage.close()
- CallAdapter.refuseACall(responsibleAccountId,
- responsibleConvUid)
- }
+ text: "is calling you"
}
- ColumnLayout {
- id: incomingCallPageColumnLayout
+ RowLayout {
+ id: incomingCallPageRowLayout
- anchors.fill: parent
+ Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
+ Layout.bottomMargin: 48
+ Layout.topMargin: 48
- Image {
- id: contactImg
+ Layout.preferredWidth: incomingCallPage.width - 200
+ Layout.maximumWidth: 200
+ Layout.preferredHeight: buttonPreferredSize
- Layout.alignment: Qt.AlignCenter
- Layout.topMargin: 30
+ ColumnLayout {
+ id: callAnswerButtonColumnLayout
- Layout.preferredWidth: 100
- Layout.preferredHeight: 100
+ Layout.alignment: Qt.AlignLeft
- fillMode: Image.PreserveAspectFit
- source: contactImgSource
- }
+ HoverableButton {
+ id: callAnswerButton
- Rectangle {
- id: incomingCallPageTextRect
+ Layout.alignment: Qt.AlignCenter
- Layout.alignment: Qt.AlignCenter
- Layout.topMargin: 5
+ Layout.preferredWidth: buttonPreferredSize
+ Layout.preferredHeight: buttonPreferredSize
- Layout.preferredWidth: incomingCallPage.width
- Layout.preferredHeight: jamiBestNameText.height + jamiBestIdText.height
- + talkToYouText.height + 20
+ backgroundColor: JamiTheme.acceptButtonGreen
+ onEnterColor: JamiTheme.acceptButtonHoverGreen
+ onPressColor: JamiTheme.acceptButtonPressedGreen
+ onReleaseColor: JamiTheme.acceptButtonHoverGreen
+ onExitColor: JamiTheme.acceptButtonGreen
- ColumnLayout {
- id: incomingCallPageTextRectColumnLayout
+ buttonImageHeight: buttonPreferredSize / 2
+ buttonImageWidth: buttonPreferredSize / 2
+ source: "qrc:/images/icons/ic_check_white_18dp_2x.png"
+ radius: 32
- Text {
- id: jamiBestNameText
-
- Layout.alignment: Qt.AlignCenter
- Layout.preferredWidth: incomingCallPageTextRect.width
- Layout.preferredHeight: 50
-
- font.pointSize: JamiTheme.textFontSize + 3
-
- horizontalAlignment: Text.AlignHCenter
- verticalAlignment: Text.AlignVCenter
-
- text: textMetricsjamiBestNameText.elidedText
- color: "white"
-
- TextMetrics {
- id: textMetricsjamiBestNameText
- font: jamiBestNameText.font
- text: bestName
- elideWidth: incomingCallPageTextRect.width - 30
- elide: Qt.ElideMiddle
- }
- }
-
- Text {
- id: jamiBestIdText
-
- Layout.alignment: Qt.AlignCenter
- Layout.preferredWidth: incomingCallPageTextRect.width
- Layout.preferredHeight: 30
-
- font.pointSize: JamiTheme.textFontSize
-
- horizontalAlignment: Text.AlignHCenter
- verticalAlignment: Text.AlignVCenter
-
- text: textMetricsjamiBestIdText.elidedText
- color: "white"
-
- TextMetrics {
- id: textMetricsjamiBestIdText
- font: jamiBestIdText.font
- text: bestId
- elideWidth: incomingCallPageTextRect.width - 30
- elide: Qt.ElideMiddle
- }
- }
-
- Text {
- id: talkToYouText
-
- Layout.alignment: Qt.AlignCenter
- Layout.preferredWidth: incomingCallPageTextRect.width
- Layout.preferredHeight: 30
-
- font.pointSize: JamiTheme.textFontSize
-
- horizontalAlignment: Text.AlignHCenter
- verticalAlignment: Text.AlignVCenter
- color: "white"
-
- text: "is calling you"
+ onClicked: {
+ callAcceptButtonIsClicked()
}
}
-
- color: "transparent"
}
- RowLayout {
- id: incomingCallPageRowLayout
+ ColumnLayout {
+ id: callDeclineButtonColumnLayout
- Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
- Layout.bottomMargin: 5
+ Layout.alignment: Qt.AlignRight
- Layout.preferredWidth: incomingCallPage.width - 100
- Layout.preferredHeight: buttonPreferredSize
+ HoverableButton {
+ id: callDeclineButton
- ColumnLayout {
- id: callAnswerButtonColumnLayout
+ Layout.alignment: Qt.AlignCenter
- Layout.alignment: Qt.AlignLeft
+ Layout.preferredWidth: buttonPreferredSize
+ Layout.preferredHeight: buttonPreferredSize
- HoverableButton {
- id: callAnswerButton
+ backgroundColor: JamiTheme.declineButtonRed
+ onEnterColor: JamiTheme.declineButtonHoverRed
+ onPressColor: JamiTheme.declineButtonPressedRed
+ onReleaseColor: JamiTheme.declineButtonHoverRed
+ onExitColor: JamiTheme.declineButtonRed
- Layout.alignment: Qt.AlignCenter
+ buttonImageHeight: buttonPreferredSize / 2
+ buttonImageWidth: buttonPreferredSize / 2
+ source: "qrc:/images/icons/ic_close_white_24dp.png"
+ radius: 32
- Layout.preferredWidth: buttonPreferredSize
- Layout.preferredHeight: buttonPreferredSize
-
- backgroundColor: JamiTheme.acceptButtonGreen
- onEnterColor: JamiTheme.acceptButtonHoverGreen
- onPressColor: JamiTheme.acceptButtonPressedGreen
- onReleaseColor: JamiTheme.acceptButtonHoverGreen
- onExitColor: JamiTheme.acceptButtonGreen
-
- buttonImageHeight: buttonPreferredSize / 2
- buttonImageWidth: buttonPreferredSize / 2
- source: "qrc:/images/icons/ic_check_white_18dp_2x.png"
- radius: 30
-
- onClicked: {
- incomingCallPage.close()
- CallAdapter.acceptACall(responsibleAccountId,
- responsibleConvUid)
- }
- }
-
- Text {
- id: answerText
-
- Layout.alignment: Qt.AlignCenter
-
- font.pointSize: JamiTheme.textFontSize - 2
- text: qsTr("Answer")
- }
- }
-
- ColumnLayout {
- id: callDeclineButtonColumnLayout
-
- Layout.alignment: Qt.AlignRight
-
- HoverableButton {
- id: callDeclineButton
-
- Layout.alignment: Qt.AlignCenter
-
- Layout.preferredWidth: buttonPreferredSize
- Layout.preferredHeight: buttonPreferredSize
-
- backgroundColor: JamiTheme.declineButtonRed
- onEnterColor: JamiTheme.declineButtonHoverRed
- onPressColor: JamiTheme.declineButtonPressedRed
- onReleaseColor: JamiTheme.declineButtonHoverRed
- onExitColor: JamiTheme.declineButtonRed
-
- buttonImageHeight: buttonPreferredSize / 2
- buttonImageWidth: buttonPreferredSize / 2
- source: "qrc:/images/icons/ic_close_white_24dp.png"
- radius: 30
-
- onClicked: {
- incomingCallPage.close()
- CallAdapter.refuseACall(responsibleAccountId,
- responsibleConvUid)
- }
- }
-
- Text {
- id: ignoreText
-
- Layout.alignment: Qt.AlignCenter
-
- font.pointSize: JamiTheme.textFontSize - 2
- text: qsTr("Ignore")
+ onClicked: {
+ callCancelButtonIsClicked()
}
}
}
}
}
- color: "transparent"
-
Shortcut {
sequence: "Ctrl+Y"
context: Qt.ApplicationShortcut
diff --git a/src/mainview/components/OutgoingCallPage.qml b/src/mainview/components/OutgoingCallPage.qml
index 5acd4032..457f8f40 100644
--- a/src/mainview/components/OutgoingCallPage.qml
+++ b/src/mainview/components/OutgoingCallPage.qml
@@ -30,25 +30,16 @@ Rectangle {
property int buttonPreferredSize: 50
property int callStatus: 0
- property string contactImgSource: ""
- property string bestName: "Best Name"
- property string bestId: "Best Id"
-
signal callCancelButtonIsClicked
function updateUI(accountId, convUid) {
- contactImgSource = "data:image/png;base64," + UtilsAdapter.getContactImageString(
- accountId, convUid)
- bestName = UtilsAdapter.getBestName(accountId, convUid)
- var id = UtilsAdapter.getBestId(accountId, convUid)
- bestId = (bestName !== id) ? id : ""
+ userInfoCallPage.updateUI(accountId, convUid)
}
anchors.fill: parent
color: "black"
-
// Prevent right click propagate to VideoCallPage.
MouseArea {
anchors.fill: parent
@@ -61,114 +52,43 @@ Rectangle {
anchors.fill: parent
- Image {
- id: contactImg
-
- Layout.alignment: Qt.AlignCenter
-
- Layout.preferredWidth: 100
- Layout.preferredHeight: 100
-
- fillMode: Image.PreserveAspectFit
- source: contactImgSource
- asynchronous: true
+ UserInfoCallPage {
+ id: userInfoCallPage
+ Layout.fillHeight: true
+ Layout.fillWidth: true
}
- Rectangle {
- id: outgoingCallPageTextRect
+ AnimatedImage {
+ id: spinnerImage
Layout.alignment: Qt.AlignCenter
- Layout.topMargin: 5
+ Layout.preferredWidth: 24
+ Layout.preferredHeight: 8
+ source: "qrc:/images/waiting.gif"
+ }
+
+ Text {
+ id: callStatusText
+
+ Layout.alignment: Qt.AlignCenter
Layout.preferredWidth: outgoingCallPageRect.width
- Layout.preferredHeight: jamiBestNameText.height + jamiBestIdText.height
- + callStatusText.height + spinnerImage.height + 20
+ Layout.preferredHeight: 30
- color: "transparent"
+ font.pointSize: JamiTheme.textFontSize
- ColumnLayout {
- id: outgoingCallPageTextRectColumnLayout
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
- Text {
- id: jamiBestNameText
-
- Layout.alignment: Qt.AlignCenter
- Layout.preferredWidth: outgoingCallPageTextRect.width
- Layout.preferredHeight: 50
-
- font.pointSize: JamiTheme.textFontSize + 3
-
- horizontalAlignment: Text.AlignHCenter
- verticalAlignment: Text.AlignVCenter
-
- text: textMetricsjamiBestNameText.elidedText
- color: "white"
-
- TextMetrics {
- id: textMetricsjamiBestNameText
- font: jamiBestNameText.font
- text: bestName
- elideWidth: outgoingCallPageTextRect.width - 50
- elide: Qt.ElideMiddle
- }
- }
-
- Text {
- id: jamiBestIdText
-
- Layout.alignment: Qt.AlignCenter
- Layout.preferredWidth: outgoingCallPageTextRect.width
- Layout.preferredHeight: 30
-
- font.pointSize: JamiTheme.textFontSize
-
- horizontalAlignment: Text.AlignHCenter
- verticalAlignment: Text.AlignVCenter
-
- text: textMetricsjamiBestIdText.elidedText
- color: Qt.lighter("white", 1.5)
-
- TextMetrics {
- id: textMetricsjamiBestIdText
- font: jamiBestIdText.font
- text: bestId
- elideWidth: outgoingCallPageTextRect.width - 50
- elide: Qt.ElideMiddle
- }
- }
-
- AnimatedImage {
- id: spinnerImage
-
- Layout.alignment: Qt.AlignCenter
- Layout.preferredWidth: 20
- Layout.preferredHeight: 5
-
- source: "qrc:/images/waiting.gif"
- }
-
- Text {
- id: callStatusText
-
- Layout.alignment: Qt.AlignCenter
- Layout.preferredWidth: outgoingCallPageTextRect.width
- Layout.preferredHeight: 30
-
- font.pointSize: JamiTheme.textFontSize
-
- horizontalAlignment: Text.AlignHCenter
- verticalAlignment: Text.AlignVCenter
-
- text: UtilsAdapter.getCallStatusStr(callStatus) + "..."
- color: Qt.lighter("white", 1.5)
- }
- }
+ text: UtilsAdapter.getCallStatusStr(callStatus) + "..."
+ color: Qt.lighter("white", 1.5)
}
ColumnLayout {
id: callCancelButtonColumnLayout
Layout.alignment: Qt.AlignCenter
+ Layout.bottomMargin: 48
HoverableButton {
id: callCancelButton
@@ -192,18 +112,9 @@ Rectangle {
toolTipText: qsTr("Cancel the call")
onClicked: {
- outgoingCallPageRect.callCancelButtonIsClicked()
+ callCancelButtonIsClicked()
}
}
-
- Text {
- id: cancelText
-
- Layout.alignment: Qt.AlignCenter
-
- font.pointSize: JamiTheme.textFontSize - 2
- text: qsTr("Cancel")
- }
}
}
}
diff --git a/src/mainview/components/SidePanel.qml b/src/mainview/components/SidePanel.qml
index c7e169c3..bc9520d8 100644
--- a/src/mainview/components/SidePanel.qml
+++ b/src/mainview/components/SidePanel.qml
@@ -32,7 +32,7 @@ Rectangle {
property int pendingRequestCount: 0
property int totalUnreadMessagesCount: 0
- signal conversationSmartListNeedToAccessMessageWebView(string currentUserDisplayName, string currentUserAlias, string currentUID, bool callStackViewShouldShow, bool isAudioOnly, string callState)
+ signal conversationSmartListNeedToAccessMessageWebView(string currentUserDisplayName, string currentUserAlias, string currentUID, bool callStackViewShouldShow, bool isAudioOnly, int callState)
signal accountComboBoxNeedToShowWelcomePage()
signal conversationSmartListViewNeedToShowWelcomePage
signal needToUpdateConversationForAddedContact
@@ -188,8 +188,7 @@ Rectangle {
target: ConversationsAdapter
function onShowChatView(accountId, convUid) {
- conversationSmartListView.needToShowChatView(accountId,
- convUid)
+ conversationSmartListView.needToShowChatView(accountId, convUid)
}
function onShowConversationTabs(visible) {
diff --git a/src/mainview/components/UserInfoCallPage.qml b/src/mainview/components/UserInfoCallPage.qml
new file mode 100644
index 00000000..1e18bed2
--- /dev/null
+++ b/src/mainview/components/UserInfoCallPage.qml
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2020 by Savoir-faire Linux
+ * Author: Albert BabĂ
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ */
+import QtQuick 2.14
+import QtQuick.Controls 2.14
+import QtQuick.Layouts 1.14
+import QtQuick.Controls.Universal 2.12
+import net.jami.Models 1.0
+import net.jami.Adapters 1.0
+
+import "../../commoncomponents"
+
+// Common element for IncomingCallPage and OutgoingCallPage
+Rectangle {
+ id: userInfoCallRect
+
+ property int buttonPreferredSize: 48
+ property string contactImgSource: ""
+ property string bestName: "Best Name"
+ property string bestId: "Best Id"
+
+ function updateUI(accountId, convUid) {
+ contactImgSource = "data:image/png;base64," + UtilsAdapter.getContactImageString(
+ accountId, convUid)
+ bestName = UtilsAdapter.getBestName(accountId, convUid)
+ var id = UtilsAdapter.getBestId(accountId, convUid)
+ bestId = (bestName !== id) ? id : ""
+ }
+
+ color: "black"
+
+ ColumnLayout {
+ id: userInfoCallColumnLayout
+
+ anchors.fill: parent
+
+ HoverableButton {
+ id: backButton
+
+ Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
+ Layout.preferredWidth: JamiTheme.preferredFieldHeight
+ Layout.preferredHeight: JamiTheme.preferredFieldHeight
+ Layout.rightMargin: JamiTheme.preferredMarginSize
+ Layout.topMargin: JamiTheme.preferredMarginSize
+ Layout.leftMargin: JamiTheme.preferredMarginSize
+
+ radius: 32
+ source: "qrc:/images/icons/arrow_back-white-24dp.svg"
+ backgroundColor: "transparent"
+ onExitColor: "transparent"
+ onEnterColor: JamiTheme.lightGrey_
+ toolTipText: qsTr("Toggle to display side panel")
+ hoverEnabled: true
+
+ visible: mainViewWindow.sidePanelHidden
+
+ onClicked: {
+ mainViewWindow.showWelcomeView() // TODO: refactor with msg manager
+ }
+ }
+
+ Image {
+ id: contactImg
+
+ Layout.alignment: Qt.AlignCenter
+ Layout.topMargin: 48
+
+ Layout.preferredWidth: 100
+ Layout.preferredHeight: 100
+
+ fillMode: Image.PreserveAspectFit
+ source: contactImgSource
+ asynchronous: true
+ }
+
+ Rectangle {
+ id: userInfoCallPageTextRect
+
+ Layout.alignment: Qt.AlignCenter
+ Layout.topMargin: 8
+
+ Layout.preferredWidth: userInfoCallRect.width
+ Layout.preferredHeight: jamiBestNameText.height + jamiBestIdText.height + 100
+
+ color: "transparent"
+
+ ColumnLayout {
+ id: userInfoCallPageTextRectColumnLayout
+
+ Text {
+ id: jamiBestNameText
+
+ Layout.alignment: Qt.AlignCenter
+ Layout.preferredWidth: userInfoCallPageTextRect.width
+ Layout.preferredHeight: 48
+
+ font.pointSize: JamiTheme.headerFontSize
+
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+
+ text: textMetricsjamiBestNameText.elidedText
+ color: "white"
+
+ TextMetrics {
+ id: textMetricsjamiBestNameText
+ font: jamiBestNameText.font
+ text: bestName
+ elideWidth: userInfoCallPageTextRect.width - 48
+ elide: Qt.ElideMiddle
+ }
+ }
+
+ Text {
+ id: jamiBestIdText
+
+ Layout.alignment: Qt.AlignCenter
+ Layout.preferredWidth: userInfoCallPageTextRect.width
+ Layout.preferredHeight: 32
+
+ font.pointSize: JamiTheme.textFontSize
+
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+
+ text: textMetricsjamiBestIdText.elidedText
+ color: Qt.lighter("white", 1.5)
+
+ TextMetrics {
+ id: textMetricsjamiBestIdText
+ font: jamiBestIdText.font
+ text: bestId
+ elideWidth: userInfoCallPageTextRect.width - 48
+ elide: Qt.ElideMiddle
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/settingsview/components/CurrentAccountSettingsScrollPage.qml b/src/settingsview/components/CurrentAccountSettingsScrollPage.qml
index 33705639..96824346 100644
--- a/src/settingsview/components/CurrentAccountSettingsScrollPage.qml
+++ b/src/settingsview/components/CurrentAccountSettingsScrollPage.qml
@@ -112,7 +112,7 @@ Rectangle {
Connections {
id: accountConnections_ContactModel
target: AccountAdapter.contactModel
- enabled: accountViewRect.visible
+ enabled: root.visible
function onModelUpdated(uri, needsSorted) {
updateAndShowBannedContactsSlot()
@@ -130,7 +130,7 @@ Rectangle {
Connections {
id: accountConnections_DeviceModel
target: AccountAdapter.deviceModel
- enabled: accountViewRect.visible
+ enabled: root.visible
function onDeviceAdded(id) {
updateAndShowDevicesSlot()
diff --git a/src/smartlistmodel.cpp b/src/smartlistmodel.cpp
index 33a1194d..1e3d5964 100644
--- a/src/smartlistmodel.cpp
+++ b/src/smartlistmodel.cpp
@@ -335,7 +335,8 @@ SmartListModel::getConversationItemData(const conversation::Info& item,
return QVariant(callModel->hasCall(convInfo.callId)
&& ((!call.isOutgoing
&& (call.status == lrc::api::call::Status::IN_PROGRESS
- || call.status == lrc::api::call::Status::PAUSED))
+ || call.status == lrc::api::call::Status::PAUSED
+ || call.status == lrc::api::call::Status::INCOMING_RINGING))
|| call.isOutgoing));
}
return QVariant(false);
diff --git a/src/utils.h b/src/utils.h
index 5f8095aa..2cec141c 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -45,7 +45,7 @@
#include
#undef ERROR
#else
-#define LPCWSTR char*
+#define LPCWSTR char *
#endif
#include "api/account.h"
@@ -58,8 +58,8 @@ namespace Utils {
/*
* App/System
*/
-bool CreateStartupLink(const std::wstring& wstrAppName);
-void DeleteStartupLink(const std::wstring& wstrAppName);
+bool CreateStartupLink(const std::wstring &wstrAppName);
+void DeleteStartupLink(const std::wstring &wstrAppName);
bool CreateLink(LPCWSTR lpszPathObj, LPCWSTR lpszPathLink);
bool CheckStartupLink(const std::wstring& wstrAppName);
const char* WinGetEnv(const char* name);
@@ -69,14 +69,14 @@ QString GetISODate();
void showSystemNotification(QWidget* widget,
const QString& message,
long delay = 5000,
- const QString& triggeredAccountId = "");
-void showSystemNotification(QWidget* widget,
- const QString& sender,
- const QString& message,
+ const QString &triggeredAccountId = "");
+void showSystemNotification(QWidget *widget,
+ const QString &sender,
+ const QString &message,
long delay = 5000,
- const QString& triggeredAccountId = "");
-QSize getRealSize(QScreen* screen);
-void forceDeleteAsync(const QString& path);
+ const QString &triggeredAccountId = "");
+QSize getRealSize(QScreen *screen);
+void forceDeleteAsync(const QString &path);
QString getChangeLog();
QString getProjectCredits();
void removeOldVersions();
@@ -90,8 +90,8 @@ static constexpr bool isBeta = true;
static constexpr bool isBeta = false;
#endif
void cleanUpdateFiles();
-void checkForUpdates(bool withUI, QWidget* parent = nullptr);
-void applyUpdates(bool updateToBeta, QWidget* parent = nullptr);
+void checkForUpdates(bool withUI, QWidget *parent = nullptr);
+void applyUpdates(bool updateToBeta, QWidget *parent = nullptr);
/*
* LRC helpers
@@ -118,8 +118,8 @@ bool getReplyMessageBox(QWidget* widget, const QString& title, const QString& te
static const QSize defaultAvatarSize {128, 128};
QString getContactImageString(const QString& accountId, const QString& uid);
QImage getCirclePhoto(const QImage original, int sizePhoto);
-QImage conversationPhoto(const QString& convUid,
- const lrc::api::account::Info& accountInfo,
+QImage conversationPhoto(const QString &convUid,
+ const lrc::api::account::Info &accountInfo,
bool filtered = false);
QColor getAvatarColor(const QString& canonicalUri);
QImage fallbackAvatar(const QString& canonicalUriStr,
diff --git a/src/utilsadapter.cpp b/src/utilsadapter.cpp
index 993498f7..c6de3971 100644
--- a/src/utilsadapter.cpp
+++ b/src/utilsadapter.cpp
@@ -233,6 +233,32 @@ UtilsAdapter::hasVideoCall()
return LRCInstance::hasVideoCall();
}
+bool
+UtilsAdapter::hasCall(const QString &accountId)
+{
+ auto activeCalls = LRCInstance::getActiveCalls();
+ for (const auto &callId : activeCalls) {
+ auto &accountInfo = LRCInstance::accountModel().getAccountInfo(accountId);
+ if (accountInfo.callModel->hasCall(callId)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+const QString
+UtilsAdapter::getCallConvForAccount(const QString &accountId)
+{
+ // TODO: Currently returning first call, establish priority according to state?
+ for (const auto &callId : LRCInstance::getActiveCalls()) {
+ auto &accountInfo = LRCInstance::accountModel().getAccountInfo(accountId);
+ if (accountInfo.callModel->hasCall(callId)) {
+ return LRCInstance::getConversationFromCallId(callId, accountId).uid;
+ }
+ }
+ return "";
+}
+
const QString
UtilsAdapter::getCallId(const QString& accountId, const QString& convUid)
{
@@ -251,6 +277,14 @@ UtilsAdapter::getCallId(const QString& accountId, const QString& convUid)
return call->id;
}
+int
+UtilsAdapter::getCallStatus(const QString &callId)
+{
+ const auto callStatus = LRCInstance::getCallInfo(
+ callId, LRCInstance::getCurrAccId());
+ return static_cast(callStatus->status);
+}
+
const QString
UtilsAdapter::getCallStatusStr(int statusInt)
{
diff --git a/src/utilsadapter.h b/src/utilsadapter.h
index 4210fcfb..3306e5cc 100644
--- a/src/utilsadapter.h
+++ b/src/utilsadapter.h
@@ -64,7 +64,10 @@ public:
Q_INVOKABLE void startPreviewing(bool force);
Q_INVOKABLE void stopPreviewing();
Q_INVOKABLE bool hasVideoCall();
+ Q_INVOKABLE bool hasCall(const QString &accountId);
+ Q_INVOKABLE const QString getCallConvForAccount(const QString &accountId);
Q_INVOKABLE const QString getCallId(const QString& accountId, const QString& convUid);
+ Q_INVOKABLE int getCallStatus(const QString &callId);
Q_INVOKABLE const QString getCallStatusStr(int statusInt);
Q_INVOKABLE QString getStringUTF8(QString string);
Q_INVOKABLE bool validateRegNameForm(const QString& regName);