diff --git a/Linphone/tool/Constants.hpp b/Linphone/tool/Constants.hpp index ef52f4d33..927b7e070 100644 --- a/Linphone/tool/Constants.hpp +++ b/Linphone/tool/Constants.hpp @@ -66,8 +66,8 @@ public: static constexpr char VersionCheckReleaseUrl[] = "https://linphone.org/releases"; static constexpr char VersionCheckNightlyUrl[] = "https://linphone.org/snapshots"; static constexpr char PasswordRecoveryUrl[] = "https://subscribe.linphone.org/recovery/email"; - static constexpr char CguUrl[] = "https://www.linphone.org/general-terms"; - static constexpr char PrivatePolicyUrl[] = "https://www.linphone.org/privacy-policy"; + static constexpr char CguUrl[] = "https://www.linphone.org/en/terms-of-use/"; + static constexpr char PrivatePolicyUrl[] = "https://www.linphone.org/en/privacy-policy/"; static constexpr char ContactUrl[] = "https://www.linphone.org/contact"; static constexpr char TranslationUrl[] = "https://weblate.linphone.org/projects/linphone-desktop/"; diff --git a/Linphone/tool/Utils.cpp b/Linphone/tool/Utils.cpp index a8f50dfc4..2852a21be 100644 --- a/Linphone/tool/Utils.cpp +++ b/Linphone/tool/Utils.cpp @@ -135,8 +135,10 @@ void Utils::createCall(const QString &sipAddress, LinphoneEnums::MediaEncryption mediaEncryption, const QString &prepareTransfertAddress, const QHash &headers) { - mediaEncryption = - App::getInstance()->getSettings()->getMediaEncryption()["id"].value(); + // if default value use the settings' value + if (mediaEncryption == LinphoneEnums::MediaEncryption::None) + mediaEncryption = + App::getInstance()->getSettings()->getMediaEncryption()["id"].value(); lDebug() << "[Utils] create call with uri :" << sipAddress << mediaEncryption; App::postModelAsync([sipAddress, options, mediaEncryption, prepareTransfertAddress, headers]() { QString errorMessage; diff --git a/Linphone/view/Control/Container/Call/CallHistoryLayout.qml b/Linphone/view/Control/Container/Call/CallHistoryLayout.qml index 584ae4776..9ae9b4291 100644 --- a/Linphone/view/Control/Container/Call/CallHistoryLayout.qml +++ b/Linphone/view/Control/Container/Call/CallHistoryLayout.qml @@ -75,7 +75,7 @@ ColumnLayout { _address: mainItem.conferenceInfo ? mainItem.conferenceInfo.core.subject : mainItem.contactAddress || mainItem.contactName - secured: securityLevel === LinphoneEnums.SecurityLevel.EndToEndEncrypted + secured: securityLevel === LinphoneEnums.SecurityLevel.EndToEndEncryptedAndVerified } Item { id: rightButton diff --git a/Linphone/view/Control/Display/Contact/AllContactListView.qml b/Linphone/view/Control/Display/Contact/AllContactListView.qml index 9e159641b..39867e693 100644 --- a/Linphone/view/Control/Display/Contact/AllContactListView.qml +++ b/Linphone/view/Control/Display/Contact/AllContactListView.qml @@ -215,7 +215,7 @@ Flickable{ ColumnLayout{ id: contentsLayout width: parent.width - spacing: 0 + spacing: 20 * DefaultStyle.dp BusyIndicator { Layout.alignment: Qt.AlignCenter Layout.preferredHeight: visible ? 60 * DefaultStyle.dp : 0 @@ -228,6 +228,7 @@ Flickable{ ContactListView{ id: favoritesList + visible: contentHeight > 0 Layout.fillWidth: true Layout.preferredHeight: implicitHeight interactive: false @@ -259,6 +260,7 @@ Flickable{ ContactListView{ id: contactsList + visible: contentHeight > 0 Layout.fillWidth: true Layout.preferredHeight: implicitHeight Layout.topMargin: favoritesList.height > 0 ? 4 * DefaultStyle.dp : 0 @@ -296,6 +298,7 @@ Flickable{ } ContactListView{ id: suggestionsList + visible: contentHeight > 0 Layout.fillWidth: true Layout.preferredHeight: implicitHeight Layout.topMargin: contactsList.height + favoritesList.height > 0 ? 4 * DefaultStyle.dp : 0 diff --git a/Linphone/view/Control/Display/Contact/Avatar.qml b/Linphone/view/Control/Display/Contact/Avatar.qml index 0a258c95f..952c6d1c9 100644 --- a/Linphone/view/Control/Display/Contact/Avatar.qml +++ b/Linphone/view/Control/Display/Contact/Avatar.qml @@ -41,7 +41,7 @@ Loader{ property string computedAvatarUri: avatarObj ? avatarObj.value : '' // To get the secured property for a specific address, - // override it as secured: securityLevel === LinphoneEnums.SecurityLevel.EndToEndEncrypted + // override it as secured: securityLevel === LinphoneEnums.SecurityLevel.EndToEndEncryptedAndVerified property var securityLevelObj: UtilsCpp.getFriendAddressSecurityLevel(_address) property var securityLevel: securityLevelObj ? securityLevelObj.value : LinphoneEnums.SecurityLevel.None property bool secured: call && call.core.encryption === LinphoneEnums.MediaEncryption.Zrtp diff --git a/Linphone/view/Control/Display/Sticker.qml b/Linphone/view/Control/Display/Sticker.qml index 1c44a0c19..30f4ac9de 100644 --- a/Linphone/view/Control/Display/Sticker.qml +++ b/Linphone/view/Control/Display/Sticker.qml @@ -245,10 +245,13 @@ Item { } Text { anchors.left: parent.left + anchors.right: parent.right anchors.bottom: parent.bottom anchors.leftMargin: 10 * DefaultStyle.dp + anchors.rightMargin: 10 * DefaultStyle.dp anchors.bottomMargin: 10 * DefaultStyle.dp width: implicitWidth + maximumLineCount: 1 property string _text: mainItem.displayName != '' ? mainItem.displayName : mainItem.account && mainItem.identityAddress diff --git a/Linphone/view/Control/Form/Login/LoginForm.qml b/Linphone/view/Control/Form/Login/LoginForm.qml index 601b4414b..dba119ba5 100644 --- a/Linphone/view/Control/Form/Login/LoginForm.qml +++ b/Linphone/view/Control/Form/Login/LoginForm.qml @@ -8,7 +8,6 @@ import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle ColumnLayout { id: mainItem spacing: 10 * DefaultStyle.dp - signal connectionSucceed() FormItemLayout { id: username @@ -47,11 +46,6 @@ ColumnLayout { if (passwordEdit.text.length > 0 || usernameEdit.text.length > 0) errorText.setText(LoginPageCpp.errorMessage) } - function onRegistrationStateChanged() { - if (LoginPageCpp.registrationState === LinphoneEnums.RegistrationState.Ok) { - mainItem.connectionSucceed() - } - } } } } diff --git a/Linphone/view/Control/Form/Settings/MultimediaSettings.qml b/Linphone/view/Control/Form/Settings/MultimediaSettings.qml index 7ec0cb37c..629ac673e 100644 --- a/Linphone/view/Control/Form/Settings/MultimediaSettings.qml +++ b/Linphone/view/Control/Form/Settings/MultimediaSettings.qml @@ -227,7 +227,6 @@ ColumnLayout { } } Connections { - enabled: !mainItem.call target: SettingsCpp onMicVolumeChanged: (value) => { audioTestSlider.value = value diff --git a/Linphone/view/Page/Form/Call/NewCallForm.qml b/Linphone/view/Page/Form/Call/NewCallForm.qml index d115eb947..f254cb76a 100644 --- a/Linphone/view/Page/Form/Call/NewCallForm.qml +++ b/Linphone/view/Page/Form/Call/NewCallForm.qml @@ -64,14 +64,12 @@ FocusScope { } onVisibleChanged: if (!visible) mainItem.numPadPopup.close() contentItem: ColumnLayout { - // anchors.fill: parent - spacing: 10 * DefaultStyle.dp + spacing: 38 * DefaultStyle.dp SearchBar { id: searchBar Layout.alignment: Qt.AlignTop Layout.fillWidth: true Layout.rightMargin: 39 * DefaultStyle.dp - //Layout.maximumWidth: mainItem.width focus: true color: mainItem.searchBarColor borderColor: mainItem.searchBarBorderColor diff --git a/Linphone/view/Page/Form/Login/LoginPage.qml b/Linphone/view/Page/Form/Login/LoginPage.qml index 9e2e0f965..24a72ea8f 100644 --- a/Linphone/view/Page/Form/Login/LoginPage.qml +++ b/Linphone/view/Page/Form/Login/LoginPage.qml @@ -14,7 +14,6 @@ LoginLayout { signal useSIPButtonClicked() signal useRemoteConfigButtonClicked() signal goToRegister() - signal connectionSucceed() titleContent: [ BigButton { @@ -82,7 +81,6 @@ LoginLayout { spacing: 0 LoginForm { id: loginForm - onConnectionSucceed: mainItem.connectionSucceed() } BigButton { Layout.preferredWidth: loginForm.width diff --git a/Linphone/view/Page/Form/Login/SIPLoginPage.qml b/Linphone/view/Page/Form/Login/SIPLoginPage.qml index 3b0766372..e2752504c 100644 --- a/Linphone/view/Page/Form/Login/SIPLoginPage.qml +++ b/Linphone/view/Page/Form/Login/SIPLoginPage.qml @@ -11,7 +11,6 @@ LoginLayout { id: mainItem signal goBack() signal goToRegister() - signal connectionSucceed() property bool showBackButton: false titleContent: [ @@ -271,11 +270,6 @@ LoginLayout { function onErrorMessageChanged(error) { errorText.setText(error) } - function onRegistrationStateChanged() { - if (LoginPageCpp.registrationState === LinphoneEnums.RegistrationState.Ok) { - mainItem.connectionSucceed() - } - } } } diff --git a/Linphone/view/Page/Form/Meeting/AddParticipantsForm.qml b/Linphone/view/Page/Form/Meeting/AddParticipantsForm.qml index 13fc80510..0c38780e7 100644 --- a/Linphone/view/Page/Form/Meeting/AddParticipantsForm.qml +++ b/Linphone/view/Page/Form/Meeting/AddParticipantsForm.qml @@ -28,6 +28,7 @@ FocusScope{ ListView { id: participantList Layout.fillWidth: true + visible: contentHeight > 0 Layout.preferredHeight: contentHeight Layout.maximumHeight: mainItem.height / 3 width: mainItem.width diff --git a/Linphone/view/Page/Main/Call/CallPage.qml b/Linphone/view/Page/Main/Call/CallPage.qml index 70dd24db5..e2a55b7de 100644 --- a/Linphone/view/Page/Main/Call/CallPage.qml +++ b/Linphone/view/Page/Main/Call/CallPage.qml @@ -81,27 +81,11 @@ AbstractMainPage { id: leftPanel Layout.fillWidth: true Layout.fillHeight: true - Loader { - id: titleLoader - anchors.left: parent.left - anchors.leftMargin: 45 * DefaultStyle.dp - anchors.right: parent.right - asynchronous: false - onActiveFocusChanged:{ - if(activeFocus && item){ - item.forceActiveFocus() - } - } - } Control.StackView { id: listStackView - anchors.top: titleLoader.bottom - anchors.topMargin: 18 * DefaultStyle.dp - anchors.left: parent.left + anchors.fill: parent anchors.leftMargin: 45 * DefaultStyle.dp - anchors.right: parent.right - anchors.bottom: parent.bottom clip: true initialItem: historyListItem focus: true @@ -128,83 +112,75 @@ AbstractMainPage { } } - Component { - id: historyListTitle - FocusScope{ - objectName: "historyListTitle" - width: parent.width - height: titleCallLayout.implicitHeight - RowLayout { - id: titleCallLayout - anchors.fill: parent - spacing: 16 * DefaultStyle.dp - Text { - text: qsTr("Appels") - color: DefaultStyle.main2_700 - font.pixelSize: 29 * DefaultStyle.dp - font.weight: 800 * DefaultStyle.dp - } - Item { - Layout.fillWidth: true - } - PopupButton { - id: removeHistory - width: 24 * DefaultStyle.dp - height: 24 * DefaultStyle.dp - focus: true - popup.x: 0 - KeyNavigation.right: newCallButton - KeyNavigation.down: listStackView - popup.contentItem: ColumnLayout { - IconLabelButton { - Layout.fillWidth: true - focus: visible - text: qsTr("Supprimer l'historique") - icon.source: AppIcons.trashCan - style: ButtonStyle.hoveredBackgroundRed - onClicked: { - removeHistory.close() - deleteHistoryPopup.open() - } - } - } - Connections { - target: deleteHistoryPopup - onAccepted: { - if (listStackView.currentItem.listView) listStackView.currentItem.listView.model.removeAllEntries() - } - } - } - Button { - id: newCallButton - style: ButtonStyle.noBackground - icon.source: AppIcons.newCall - Layout.preferredWidth: 28 * DefaultStyle.dp - Layout.preferredHeight: 28 * DefaultStyle.dp - Layout.rightMargin: 39 * DefaultStyle.dp - icon.width: 28 * DefaultStyle.dp - icon.height: 28 * DefaultStyle.dp - KeyNavigation.left: removeHistory - KeyNavigation.down: listStackView - onClicked: { - console.debug("[CallPage]User: create new call") - listStackView.push(newCallItem) - } - } - } - } - } Component { id: historyListItem FocusScope{ objectName: "historyListItem" property alias listView: historyListView - Control.StackView.onActivated: titleLoader.sourceComponent = historyListTitle ColumnLayout { anchors.fill: parent + spacing: 0 + RowLayout { + id: titleCallLayout + spacing: 16 * DefaultStyle.dp + Text { + text: qsTr("Appels") + color: DefaultStyle.main2_700 + font.pixelSize: 29 * DefaultStyle.dp + font.weight: 800 * DefaultStyle.dp + } + Item { + Layout.fillWidth: true + } + PopupButton { + id: removeHistory + width: 24 * DefaultStyle.dp + height: 24 * DefaultStyle.dp + focus: true + popup.x: 0 + KeyNavigation.right: newCallButton + KeyNavigation.down: listStackView + popup.contentItem: ColumnLayout { + IconLabelButton { + Layout.fillWidth: true + focus: visible + text: qsTr("Supprimer l'historique") + icon.source: AppIcons.trashCan + style: ButtonStyle.hoveredBackgroundRed + onClicked: { + removeHistory.close() + deleteHistoryPopup.open() + } + } + } + Connections { + target: deleteHistoryPopup + onAccepted: { + if (listStackView.currentItem.listView) listStackView.currentItem.listView.model.removeAllEntries() + } + } + } + Button { + id: newCallButton + style: ButtonStyle.noBackground + icon.source: AppIcons.newCall + Layout.preferredWidth: 28 * DefaultStyle.dp + Layout.preferredHeight: 28 * DefaultStyle.dp + Layout.rightMargin: 39 * DefaultStyle.dp + icon.width: 28 * DefaultStyle.dp + icon.height: 28 * DefaultStyle.dp + KeyNavigation.left: removeHistory + KeyNavigation.down: listStackView + onClicked: { + console.debug("[CallPage]User: create new call") + listStackView.push(newCallItem) + } + } + } SearchBar { id: searchBar Layout.fillWidth: true + Layout.topMargin: 18 * DefaultStyle.dp Layout.rightMargin: 39 * DefaultStyle.dp placeholderText: qsTr("Rechercher un appel") visible: historyListView.count !== 0 || text.length !== 0 @@ -229,224 +205,224 @@ AbstractMainPage { background: Item{} contentItem: ColumnLayout { - Text { - visible: historyListView.count === 0 - Layout.alignment: Qt.AlignHCenter - text: qsTr("Aucun appel%1").arg(searchBar.text.length != 0 ? " correspondant" : "") - font { - pixelSize: 16 * DefaultStyle.dp - weight: 800 * DefaultStyle.dp - } - } - ListView { - id: historyListView - clip: true - Layout.fillWidth: true - Layout.fillHeight: true - model: CallHistoryProxy { - id: callHistoryProxy - filterText: searchBar.text - onFilterTextChanged: maxDisplayItems = initialDisplayItems - initialDisplayItems: Math.max(20, 2 * historyListView.height / (56 * DefaultStyle.dp)) - displayItemsStep: 3 * initialDisplayItems / 2 - } - cacheBuffer: contentHeight>0 ? contentHeight : 0// cache all items - flickDeceleration: 10000 - spacing: 10 * DefaultStyle.dp - - Keys.onPressed: (event) => { - if(event.key == Qt.Key_Escape){ - console.log("Back") - searchBar.forceActiveFocus() - event.accepted = true - } - } - // remove binding loop - onContentHeightChanged: Qt.callLater(function(){ - historyListView.cacheBuffer = Math.max(contentHeight,0) - }) - onActiveFocusChanged: if(activeFocus && currentIndex < 0 && count > 0) currentIndex = 0 - onCountChanged: { - if(currentIndex < 0 && count > 0){ - historyListView.currentIndex = 0 // Select first item after loading model - } - if(atYBeginning) - positionViewAtBeginning()// Stay at beginning - } - Connections { - target: deleteHistoryPopup - function onAccepted() { - historyListView.model.removeAllEntries() - } - } - Connections{ - target: mainItem - function onListViewUpdated(){ - callHistoryProxy.reload() - } - } - onAtYEndChanged: { - if(atYEnd && count > 0){ - callHistoryProxy.displayMore() - } - } -//---------------------------------------------------------------- - function moveToCurrentItem(){ - if( historyListView.currentIndex >= 0) - Utils.updatePosition(historyListView, historyListView) - } - onCurrentItemChanged: { - moveToCurrentItem() - } - // Update position only if we are moving to current item and its position is changing. - property var _currentItemY: currentItem?.y - on_CurrentItemYChanged: if(_currentItemY && moveAnimation.running){ - moveToCurrentItem() - } - Behavior on contentY{ - NumberAnimation { - id: moveAnimation - duration: 500 - easing.type: Easing.OutExpo - alwaysRunToEnd: true - } - } -//---------------------------------------------------------------- - - onCurrentIndexChanged: { - mainItem.selectedRowHistoryGui = model.getAt(currentIndex) - } - onVisibleChanged: { - if (!visible) currentIndex = -1 - } - // Qt bug: sometimes, containsMouse may not be send and update on each MouseArea. - // So we need to use this variable to switch off all hovered items. - property int lastMouseContainsIndex: -1 - delegate: FocusScope { - width:historyListView.width - height: 56 * DefaultStyle.dp - visible: !!modelData - - RowLayout { - z: 1 - anchors.fill: parent - anchors.leftMargin: 10 * DefaultStyle.dp - spacing: 10 * DefaultStyle.dp - Avatar { - id: historyAvatar - property var contactObj: UtilsCpp.findFriendByAddress(modelData.core.remoteAddress) - contact: contactObj?.value || null - _address: modelData.core.conferenceInfo - ? modelData.core.conferenceInfo.core.subject - : modelData.core.remoteAddress - width: 45 * DefaultStyle.dp - height: 45 * DefaultStyle.dp - isConference: modelData.core.isConference - } - ColumnLayout { - Layout.fillHeight: true - Layout.fillWidth: true - spacing: 5 * DefaultStyle.dp - Text { - id: friendAddress - Layout.fillWidth: true - maximumLineCount: 1 - text: historyAvatar.displayNameVal - font { - pixelSize: 14 * DefaultStyle.dp - weight: 400 * DefaultStyle.dp - capitalization: Font.Capitalize - } - } - RowLayout { - spacing: 6 * DefaultStyle.dp - EffectImage { - id: statusIcon - imageSource: modelData.core.status === LinphoneEnums.CallStatus.Declined - || modelData.core.status === LinphoneEnums.CallStatus.DeclinedElsewhere - || modelData.core.status === LinphoneEnums.CallStatus.Aborted - || modelData.core.status === LinphoneEnums.CallStatus.EarlyAborted - ? AppIcons.arrowElbow - : modelData.core.isOutgoing - ? AppIcons.arrowUpRight - : AppIcons.arrowDownLeft - colorizationColor: modelData.core.status === LinphoneEnums.CallStatus.Declined - || modelData.core.status === LinphoneEnums.CallStatus.DeclinedElsewhere - || modelData.core.status === LinphoneEnums.CallStatus.Aborted - || modelData.core.status === LinphoneEnums.CallStatus.EarlyAborted - || modelData.core.status === LinphoneEnums.CallStatus.Missed - ? DefaultStyle.danger_500main - : modelData.core.isOutgoing - ? DefaultStyle.info_500_main - : DefaultStyle.success_500main - Layout.preferredWidth: 12 * DefaultStyle.dp - Layout.preferredHeight: 12 * DefaultStyle.dp - transform: Rotation { - angle: modelData.core.isOutgoing && (modelData.core.status === LinphoneEnums.CallStatus.Declined - || modelData.core.status === LinphoneEnums.CallStatus.DeclinedElsewhere - || modelData.core.status === LinphoneEnums.CallStatus.Aborted - || modelData.core.status === LinphoneEnums.CallStatus.EarlyAborted) ? 180 : 0 - origin { - x: statusIcon.width/2 - y: statusIcon.height/2 - } - } - } - Text { - // text: modelData.core.date - text: UtilsCpp.formatDate(modelData.core.date) - font { - pixelSize: 12 * DefaultStyle.dp - weight: 300 * DefaultStyle.dp - } - } - } - } - BigButton { - style: ButtonStyle.noBackground - icon.source: AppIcons.phone - focus: true - activeFocusOnTab: false - onClicked: { - if (modelData.core.isConference) { - var callsWindow = UtilsCpp.getCallsWindow() - callsWindow.setupConference(modelData.core.conferenceInfo) - UtilsCpp.smartShowWindow(callsWindow) - } - else { - UtilsCpp.createCall(modelData.core.remoteAddress) - } - } - } - } - MouseArea { - hoverEnabled: true - anchors.fill: parent - focus: true - onContainsMouseChanged: { - if(containsMouse) - historyListView.lastMouseContainsIndex = index - else if( historyListView.lastMouseContainsIndex == index) - historyListView.lastMouseContainsIndex = -1 - } - Rectangle { - anchors.fill: parent - opacity: 0.7 - radius: 8 * DefaultStyle.dp - color: historyListView.currentIndex === index ? DefaultStyle.main2_200 : DefaultStyle.main2_100 - visible: historyListView.lastMouseContainsIndex === index || historyListView.currentIndex === index - } - onPressed: { - historyListView.currentIndex = model.index - historyListView.forceActiveFocus() - } - } - } - - Control.ScrollBar.vertical: scrollbar + Text { + visible: historyListView.count === 0 + Layout.alignment: Qt.AlignHCenter + text: qsTr("Aucun appel%1").arg(searchBar.text.length != 0 ? " correspondant" : "") + font { + pixelSize: 16 * DefaultStyle.dp + weight: 800 * DefaultStyle.dp } } - + ListView { + id: historyListView + clip: true + Layout.fillWidth: true + Layout.fillHeight: true + model: CallHistoryProxy { + id: callHistoryProxy + filterText: searchBar.text + onFilterTextChanged: maxDisplayItems = initialDisplayItems + initialDisplayItems: Math.max(20, 2 * historyListView.height / (56 * DefaultStyle.dp)) + displayItemsStep: 3 * initialDisplayItems / 2 + } + cacheBuffer: contentHeight>0 ? contentHeight : 0// cache all items + flickDeceleration: 10000 + spacing: 10 * DefaultStyle.dp + + Keys.onPressed: (event) => { + if(event.key == Qt.Key_Escape){ + console.log("Back") + searchBar.forceActiveFocus() + event.accepted = true + } + } + // remove binding loop + onContentHeightChanged: Qt.callLater(function(){ + historyListView.cacheBuffer = Math.max(contentHeight,0) + }) + onActiveFocusChanged: if(activeFocus && currentIndex < 0 && count > 0) currentIndex = 0 + onCountChanged: { + if(currentIndex < 0 && count > 0){ + historyListView.currentIndex = 0 // Select first item after loading model + } + if(atYBeginning) + positionViewAtBeginning()// Stay at beginning + } + Connections { + target: deleteHistoryPopup + function onAccepted() { + historyListView.model.removeAllEntries() + } + } + Connections{ + target: mainItem + function onListViewUpdated(){ + callHistoryProxy.reload() + } + } + onAtYEndChanged: { + if(atYEnd && count > 0){ + callHistoryProxy.displayMore() + } + } + //---------------------------------------------------------------- + function moveToCurrentItem(){ + if( historyListView.currentIndex >= 0) + Utils.updatePosition(historyListView, historyListView) + } + onCurrentItemChanged: { + moveToCurrentItem() + } + // Update position only if we are moving to current item and its position is changing. + property var _currentItemY: currentItem?.y + on_CurrentItemYChanged: if(_currentItemY && moveAnimation.running){ + moveToCurrentItem() + } + Behavior on contentY{ + NumberAnimation { + id: moveAnimation + duration: 500 + easing.type: Easing.OutExpo + alwaysRunToEnd: true + } + } + //---------------------------------------------------------------- + + onCurrentIndexChanged: { + mainItem.selectedRowHistoryGui = model.getAt(currentIndex) + } + onVisibleChanged: { + if (!visible) currentIndex = -1 + } + // Qt bug: sometimes, containsMouse may not be send and update on each MouseArea. + // So we need to use this variable to switch off all hovered items. + property int lastMouseContainsIndex: -1 + delegate: FocusScope { + width:historyListView.width + height: 56 * DefaultStyle.dp + visible: !!modelData + + RowLayout { + z: 1 + anchors.fill: parent + anchors.leftMargin: 10 * DefaultStyle.dp + spacing: 10 * DefaultStyle.dp + Avatar { + id: historyAvatar + property var contactObj: UtilsCpp.findFriendByAddress(modelData.core.remoteAddress) + contact: contactObj?.value || null + _address: modelData.core.conferenceInfo + ? modelData.core.conferenceInfo.core.subject + : modelData.core.remoteAddress + secured: securityLevel === LinphoneEnums.SecurityLevel.EndToEndEncryptedAndVerified + width: 45 * DefaultStyle.dp + height: 45 * DefaultStyle.dp + isConference: modelData.core.isConference + } + ColumnLayout { + Layout.fillHeight: true + Layout.fillWidth: true + spacing: 5 * DefaultStyle.dp + Text { + id: friendAddress + Layout.fillWidth: true + maximumLineCount: 1 + text: historyAvatar.displayNameVal + font { + pixelSize: 14 * DefaultStyle.dp + weight: 400 * DefaultStyle.dp + capitalization: Font.Capitalize + } + } + RowLayout { + spacing: 6 * DefaultStyle.dp + EffectImage { + id: statusIcon + imageSource: modelData.core.status === LinphoneEnums.CallStatus.Declined + || modelData.core.status === LinphoneEnums.CallStatus.DeclinedElsewhere + || modelData.core.status === LinphoneEnums.CallStatus.Aborted + || modelData.core.status === LinphoneEnums.CallStatus.EarlyAborted + ? AppIcons.arrowElbow + : modelData.core.isOutgoing + ? AppIcons.arrowUpRight + : AppIcons.arrowDownLeft + colorizationColor: modelData.core.status === LinphoneEnums.CallStatus.Declined + || modelData.core.status === LinphoneEnums.CallStatus.DeclinedElsewhere + || modelData.core.status === LinphoneEnums.CallStatus.Aborted + || modelData.core.status === LinphoneEnums.CallStatus.EarlyAborted + || modelData.core.status === LinphoneEnums.CallStatus.Missed + ? DefaultStyle.danger_500main + : modelData.core.isOutgoing + ? DefaultStyle.info_500_main + : DefaultStyle.success_500main + Layout.preferredWidth: 12 * DefaultStyle.dp + Layout.preferredHeight: 12 * DefaultStyle.dp + transform: Rotation { + angle: modelData.core.isOutgoing && (modelData.core.status === LinphoneEnums.CallStatus.Declined + || modelData.core.status === LinphoneEnums.CallStatus.DeclinedElsewhere + || modelData.core.status === LinphoneEnums.CallStatus.Aborted + || modelData.core.status === LinphoneEnums.CallStatus.EarlyAborted) ? 180 : 0 + origin { + x: statusIcon.width/2 + y: statusIcon.height/2 + } + } + } + Text { + // text: modelData.core.date + text: UtilsCpp.formatDate(modelData.core.date) + font { + pixelSize: 12 * DefaultStyle.dp + weight: 300 * DefaultStyle.dp + } + } + } + } + BigButton { + style: ButtonStyle.noBackground + icon.source: AppIcons.phone + focus: true + activeFocusOnTab: false + onClicked: { + if (modelData.core.isConference) { + var callsWindow = UtilsCpp.getCallsWindow() + callsWindow.setupConference(modelData.core.conferenceInfo) + UtilsCpp.smartShowWindow(callsWindow) + } + else { + UtilsCpp.createCall(modelData.core.remoteAddress) + } + } + } + } + MouseArea { + hoverEnabled: true + anchors.fill: parent + focus: true + onContainsMouseChanged: { + if(containsMouse) + historyListView.lastMouseContainsIndex = index + else if( historyListView.lastMouseContainsIndex == index) + historyListView.lastMouseContainsIndex = -1 + } + Rectangle { + anchors.fill: parent + opacity: 0.7 + radius: 8 * DefaultStyle.dp + color: historyListView.currentIndex === index ? DefaultStyle.main2_200 : DefaultStyle.main2_100 + visible: historyListView.lastMouseContainsIndex === index || historyListView.currentIndex === index + } + onPressed: { + historyListView.currentIndex = model.index + historyListView.forceActiveFocus() + } + } + } + + Control.ScrollBar.vertical: scrollbar + } + } } ScrollBar { id: scrollbar @@ -462,40 +438,6 @@ AbstractMainPage { } } - Component { - id: newCallTitle - FocusScope{ - objectName: "newCallTitle" - width: parent.width - height: parent.height - RowLayout { - anchors.fill: parent - spacing: 10 * DefaultStyle.dp - Button { - Layout.preferredWidth: 24 * DefaultStyle.dp - Layout.preferredHeight: 24 * DefaultStyle.dp - style: ButtonStyle.noBackground - icon.source: AppIcons.leftArrow - focus: true - KeyNavigation.down: listStackView - onClicked: { - console.debug("[CallPage]User: return to call history") - listStackView.pop() - listStackView.forceActiveFocus() - } - } - Text { - text: qsTr("Nouvel appel") - color: DefaultStyle.main2_700 - font.pixelSize: 29 * DefaultStyle.dp - font.weight: 800 * DefaultStyle.dp - } - Item { - Layout.fillWidth: true - } - } - } - } Component { id: newCallItem FocusScope{ @@ -503,14 +445,39 @@ AbstractMainPage { width: parent?.width height: parent?.height Control.StackView.onActivated:{ - titleLoader.sourceComponent = newCallTitle callContactsList.forceActiveFocus() } - ColumnLayout { anchors.fill: parent + spacing: 0 + RowLayout { + spacing: 10 * DefaultStyle.dp + Button { + Layout.preferredWidth: 24 * DefaultStyle.dp + Layout.preferredHeight: 24 * DefaultStyle.dp + style: ButtonStyle.noBackground + icon.source: AppIcons.leftArrow + focus: true + KeyNavigation.down: listStackView + onClicked: { + console.debug("[CallPage]User: return to call history") + listStackView.pop() + listStackView.forceActiveFocus() + } + } + Text { + text: qsTr("Nouvel appel") + color: DefaultStyle.main2_700 + font.pixelSize: 29 * DefaultStyle.dp + font.weight: 800 * DefaultStyle.dp + } + Item { + Layout.fillWidth: true + } + } NewCallForm { id: callContactsList + Layout.topMargin: 18 * DefaultStyle.dp Layout.fillWidth: true Layout.fillHeight: true focus: true @@ -533,84 +500,73 @@ AbstractMainPage { } } - Component { - id: groupCallTitle - FocusScope{ - objectName: "groupCallTitle" - width: parent.width - height: parent.height - RowLayout { - anchors.fill: parent - spacing: 10 * DefaultStyle.dp - visible: !SettingsCpp.disableMeetingsFeature - Button { - id: backGroupCallButton - style: ButtonStyle.noBackgroundOrange - icon.source: AppIcons.leftArrow - Layout.leftMargin: 21 * DefaultStyle.dp - Layout.preferredWidth: 24 * DefaultStyle.dp - Layout.preferredHeight: 24 * DefaultStyle.dp - KeyNavigation.down: listStackView - KeyNavigation.right: groupCallButton - KeyNavigation.left: groupCallButton - onClicked: { - listStackView.pop() - titleLoader.item.forceActiveFocus() - } - } - ColumnLayout { - spacing: 3 * DefaultStyle.dp - Text { - text: qsTr("Appel de groupe") - color: DefaultStyle.main1_500_main - maximumLineCount: 1 - font { - pixelSize: 18 * DefaultStyle.dp - weight: 800 * DefaultStyle.dp - } - Layout.fillWidth: true - } - Text { - text: qsTr("%1 participant%2 sélectionné").arg(mainItem.selectedParticipantsCount).arg(mainItem.selectedParticipantsCount > 1 ? "s" : "") - color: DefaultStyle.main2_500main - maximumLineCount: 1 - font { - pixelSize: 12 * DefaultStyle.dp - weight: 300 * DefaultStyle.dp - } - Layout.fillWidth: true - } - } - SmallButton { - id: groupCallButton - enabled: mainItem.selectedParticipantsCount.length != 0 - Layout.rightMargin: 21 * DefaultStyle.dp - text: qsTr("Lancer") - style: ButtonStyle.main - KeyNavigation.down: listStackView - KeyNavigation.left: backGroupCallButton - KeyNavigation.right: backGroupCallButton - onClicked: { - mainItem.startGroupCallRequested() - } - } - } - } - } - Component { id: groupCallItem FocusScope{ objectName: "groupCallItem" Control.StackView.onActivated: { - titleLoader.sourceComponent = groupCallTitle addParticipantsLayout.forceActiveFocus() } ColumnLayout { - spacing: 5 * DefaultStyle.dp + spacing: 0 anchors.fill: parent + RowLayout { + spacing: 10 * DefaultStyle.dp + visible: !SettingsCpp.disableMeetingsFeature + Button { + id: backGroupCallButton + style: ButtonStyle.noBackgroundOrange + icon.source: AppIcons.leftArrow + Layout.preferredWidth: 24 * DefaultStyle.dp + Layout.preferredHeight: 24 * DefaultStyle.dp + KeyNavigation.down: listStackView + KeyNavigation.right: groupCallButton + KeyNavigation.left: groupCallButton + onClicked: { + listStackView.pop() + titleLoader.item.forceActiveFocus() + } + } + ColumnLayout { + spacing: 3 * DefaultStyle.dp + Text { + text: qsTr("Appel de groupe") + color: DefaultStyle.main1_500_main + maximumLineCount: 1 + font { + pixelSize: 18 * DefaultStyle.dp + weight: 800 * DefaultStyle.dp + } + Layout.fillWidth: true + } + Text { + text: qsTr("%1 participant%2 sélectionné").arg(mainItem.selectedParticipantsCount).arg(mainItem.selectedParticipantsCount > 1 ? "s" : "") + color: DefaultStyle.main2_500main + maximumLineCount: 1 + font { + pixelSize: 12 * DefaultStyle.dp + weight: 300 * DefaultStyle.dp + } + Layout.fillWidth: true + } + } + SmallButton { + id: groupCallButton + enabled: mainItem.selectedParticipantsCount.length != 0 + Layout.rightMargin: 21 * DefaultStyle.dp + text: qsTr("Lancer") + style: ButtonStyle.main + KeyNavigation.down: listStackView + KeyNavigation.left: backGroupCallButton + KeyNavigation.right: backGroupCallButton + onClicked: { + mainItem.startGroupCallRequested() + } + } + } RowLayout { spacing: 0 + Layout.topMargin: 18 * DefaultStyle.dp Layout.rightMargin: 38 * DefaultStyle.dp Text { font.pixelSize: 13 * DefaultStyle.dp @@ -636,6 +592,7 @@ AbstractMainPage { id: addParticipantsLayout Layout.fillWidth: true Layout.fillHeight: true + Layout.topMargin: 15 * DefaultStyle.dp onSelectedParticipantsCountChanged: mainItem.selectedParticipantsCount = selectedParticipantsCount focus: true Connections { diff --git a/Linphone/view/Page/Main/Contact/ContactPage.qml b/Linphone/view/Page/Main/Contact/ContactPage.qml index fbe1802ad..27eeec8dd 100644 --- a/Linphone/view/Page/Main/Contact/ContactPage.qml +++ b/Linphone/view/Page/Main/Contact/ContactPage.qml @@ -628,11 +628,11 @@ AbstractMainPage { font.pixelSize: 14 * DefaultStyle.dp } Item{Layout.fillWidth: true} - Image{ + EffectImage { visible: listViewModelData.securityLevel === LinphoneEnums.SecurityLevel.EndToEndEncryptedAndVerified source: AppIcons.trusted - width: 22 * DefaultStyle.dp - height: 22 * DefaultStyle.dp + Layout.preferredWidth: 22 * DefaultStyle.dp + Layout.preferredHeight: 22 * DefaultStyle.dp } SmallButton { diff --git a/Linphone/view/Page/Main/Meeting/MeetingPage.qml b/Linphone/view/Page/Main/Meeting/MeetingPage.qml index f4ee4d39e..8f2baa59c 100644 --- a/Linphone/view/Page/Main/Meeting/MeetingPage.qml +++ b/Linphone/view/Page/Main/Meeting/MeetingPage.qml @@ -454,24 +454,26 @@ AbstractMainPage { ColumnLayout { property Control.StackView container property ConferenceInfoGui conferenceInfoGui + spacing: 18 * DefaultStyle.dp FocusScope{ Layout.fillWidth: true - Layout.preferredHeight: addParticipantsButtons.implicitHeight - RowLayout { - id: addParticipantsButtons - spacing: 5 * DefaultStyle.dp - Button { - id: removeButton - style: ButtonStyle.noBackgroundOrange - icon.source: AppIcons.leftArrow - icon.width: 24 * DefaultStyle.dp - icon.height: 24 * DefaultStyle.dp - KeyNavigation.right: addButton - KeyNavigation.down: addParticipantLayout - onClicked: container.pop() - } - ColumnLayout { - spacing: 8 * DefaultStyle.dp + Layout.preferredHeight: childrenRect.height + ColumnLayout { + spacing: 4 * DefaultStyle.dp + Layout.fillWidth: true + RowLayout { + id: addParticipantsButtons + spacing: 10 * DefaultStyle.dp + Button { + id: addParticipantsBackButton + style: ButtonStyle.noBackgroundOrange + icon.source: AppIcons.leftArrow + icon.width: 24 * DefaultStyle.dp + icon.height: 24 * DefaultStyle.dp + KeyNavigation.right: addButton + KeyNavigation.down: addParticipantLayout + onClicked: container.pop() + } Text { text: qsTr("Ajouter des participants") color: DefaultStyle.main1_500_main @@ -482,29 +484,30 @@ AbstractMainPage { } Layout.fillWidth: true } - Text { - text: qsTr("%1 participant%2 sélectionné%2").arg(addParticipantLayout.selectedParticipantsCount).arg(addParticipantLayout.selectedParticipantsCount > 1 ? "s" : "") - color: DefaultStyle.main2_500main - maximumLineCount: 1 - font { - pixelSize: 12 * DefaultStyle.dp - weight: 300 * DefaultStyle.dp + SmallButton { + id: addButton + enabled: addParticipantLayout.selectedParticipantsCount.length != 0 + Layout.leftMargin: 11 * DefaultStyle.dp + focus: enabled + style: ButtonStyle.main + text: qsTr("Ajouter") + KeyNavigation.left: addParticipantsBackButton + KeyNavigation.down: addParticipantLayout + onClicked: { + mainItem.addParticipantsValidated(addParticipantLayout.selectedParticipants) } - Layout.fillWidth: true } } - SmallButton { - id: addButton - enabled: addParticipantLayout.selectedParticipantsCount.length != 0 - Layout.rightMargin: 21 * DefaultStyle.dp - focus: enabled - style: ButtonStyle.main - text: qsTr("Ajouter") - KeyNavigation.left: removeButton - KeyNavigation.down: addParticipantLayout - onClicked: { - mainItem.addParticipantsValidated(addParticipantLayout.selectedParticipants) + Text { + text: qsTr("%1 participant%2 sélectionné%2").arg(addParticipantLayout.selectedParticipantsCount).arg(addParticipantLayout.selectedParticipantsCount > 1 ? "s" : "") + color: DefaultStyle.main2_500main + Layout.leftMargin: addParticipantsBackButton.width + addParticipantsButtons.spacing + maximumLineCount: 1 + font { + pixelSize: 12 * DefaultStyle.dp + weight: 300 * DefaultStyle.dp } + Layout.fillWidth: true } } } diff --git a/Linphone/view/Page/Window/Call/CallsWindow.qml b/Linphone/view/Page/Window/Call/CallsWindow.qml index b87682625..f8344a8d3 100644 --- a/Linphone/view/Page/Window/Call/CallsWindow.qml +++ b/Linphone/view/Page/Window/Call/CallsWindow.qml @@ -647,9 +647,12 @@ AbstractWindow { searchBarBorderColor: DefaultStyle.grey_200 numPadPopup: numericPad onContactClicked: (contact) => { - rightPanel.visible = false mainWindow.startCallWithContact(contact, false, rightPanel) } + Connections { + target: mainWindow + function onCallChanged(){ if (newCallForm.Control.StackView.status === Control.StackView.Active) rightPanel.visible = false} + } NumericPadPopup { id: numericPad diff --git a/Linphone/view/Page/Window/Main/MainWindow.qml b/Linphone/view/Page/Window/Main/MainWindow.qml index de5870506..3b049409c 100644 --- a/Linphone/view/Page/Window/Main/MainWindow.qml +++ b/Linphone/view/Page/Window/Main/MainWindow.qml @@ -29,8 +29,9 @@ AbstractWindow { // color: DefaultStyle.grey_100 // } - function openMainPage(){ + function openMainPage(connectionSucceed){ if (mainWindowStackView.currentItem.objectName !== "mainPage") mainWindowStackView.replace(mainPage, StackView.Immediate) + if (connectionSucceed) mainWindow.showInformationPopup(qsTr("Connexion réussie"), qsTr("Vous êtes connecté en mode %1").arg("interopérable")) } function goToCallHistory() { openMainPage() @@ -46,7 +47,7 @@ AbstractWindow { } function transferCallSucceed() { openMainPage() - UtilsCpp.showInformationPopup(qsTr("Appel transféré"), qsTr("Votre correspondant a été transféré au contact sélectionné")) + mainWindow.showInformationPopup(qsTr("Appel transféré"), qsTr("Votre correspondant a été transféré au contact sélectionné")) } function initStackViewItem() { if(accountProxy && accountProxy.isInitialized) { @@ -96,6 +97,16 @@ AbstractWindow { } } + Connections { + target: LoginPageCpp + function onRegistrationStateChanged() { + if (LoginPageCpp.registrationState === LinphoneEnums.RegistrationState.Ok) { + openMainPage(true) + proposeH264CodecsDownload() + } + } + } + Loader { id: accountProxyLoader active: AppCpp.coreStarted @@ -144,10 +155,6 @@ AbstractWindow { onGoBack: openMainPage() onUseSIPButtonClicked: mainWindowStackView.push(sipLoginPage) onGoToRegister: mainWindowStackView.replace(registerPage) - onConnectionSucceed: { - openMainPage() - proposeH264CodecsDownload() - } StackView.onActivated:{ if (accountProxy?.haveAccount) showBackButton = true } @@ -164,11 +171,6 @@ AbstractWindow { mainWindowStackView.pop() } onGoToRegister: mainWindowStackView.replace(registerPage) - - onConnectionSucceed: { - openMainPage() - proposeH264CodecsDownload() - } StackView.onActivated:{ if (!SettingsCpp.assistantGoDirectlyToThirdPartySipAccountLogin || accountProxy?.haveAccount) showBackButton = true }