fix #LINQT-1622 connection succeed popup
set new privacy policy and terms of use urls fix mic volume tester visibility in call fix #LINQT-1583 secured avatar on unsecured address in call history fix #LINQT-1631 zrtp to verify devices fix #LINQT-1526 title inside stackview to avoid freeze effect fix #LINQT-1579 spacing in layouts fix #LINQT-1625 right panel closes before new call starts crop text sticker fix verified icon size
This commit is contained in:
parent
063cdfb33b
commit
db6fc41480
17 changed files with 435 additions and 478 deletions
|
|
@ -66,8 +66,8 @@ public:
|
||||||
static constexpr char VersionCheckReleaseUrl[] = "https://linphone.org/releases";
|
static constexpr char VersionCheckReleaseUrl[] = "https://linphone.org/releases";
|
||||||
static constexpr char VersionCheckNightlyUrl[] = "https://linphone.org/snapshots";
|
static constexpr char VersionCheckNightlyUrl[] = "https://linphone.org/snapshots";
|
||||||
static constexpr char PasswordRecoveryUrl[] = "https://subscribe.linphone.org/recovery/email";
|
static constexpr char PasswordRecoveryUrl[] = "https://subscribe.linphone.org/recovery/email";
|
||||||
static constexpr char CguUrl[] = "https://www.linphone.org/general-terms";
|
static constexpr char CguUrl[] = "https://www.linphone.org/en/terms-of-use/";
|
||||||
static constexpr char PrivatePolicyUrl[] = "https://www.linphone.org/privacy-policy";
|
static constexpr char PrivatePolicyUrl[] = "https://www.linphone.org/en/privacy-policy/";
|
||||||
static constexpr char ContactUrl[] = "https://www.linphone.org/contact";
|
static constexpr char ContactUrl[] = "https://www.linphone.org/contact";
|
||||||
static constexpr char TranslationUrl[] = "https://weblate.linphone.org/projects/linphone-desktop/";
|
static constexpr char TranslationUrl[] = "https://weblate.linphone.org/projects/linphone-desktop/";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -135,8 +135,10 @@ void Utils::createCall(const QString &sipAddress,
|
||||||
LinphoneEnums::MediaEncryption mediaEncryption,
|
LinphoneEnums::MediaEncryption mediaEncryption,
|
||||||
const QString &prepareTransfertAddress,
|
const QString &prepareTransfertAddress,
|
||||||
const QHash<QString, QString> &headers) {
|
const QHash<QString, QString> &headers) {
|
||||||
mediaEncryption =
|
// if default value use the settings' value
|
||||||
App::getInstance()->getSettings()->getMediaEncryption()["id"].value<LinphoneEnums::MediaEncryption>();
|
if (mediaEncryption == LinphoneEnums::MediaEncryption::None)
|
||||||
|
mediaEncryption =
|
||||||
|
App::getInstance()->getSettings()->getMediaEncryption()["id"].value<LinphoneEnums::MediaEncryption>();
|
||||||
lDebug() << "[Utils] create call with uri :" << sipAddress << mediaEncryption;
|
lDebug() << "[Utils] create call with uri :" << sipAddress << mediaEncryption;
|
||||||
App::postModelAsync([sipAddress, options, mediaEncryption, prepareTransfertAddress, headers]() {
|
App::postModelAsync([sipAddress, options, mediaEncryption, prepareTransfertAddress, headers]() {
|
||||||
QString errorMessage;
|
QString errorMessage;
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,7 @@ ColumnLayout {
|
||||||
_address: mainItem.conferenceInfo
|
_address: mainItem.conferenceInfo
|
||||||
? mainItem.conferenceInfo.core.subject
|
? mainItem.conferenceInfo.core.subject
|
||||||
: mainItem.contactAddress || mainItem.contactName
|
: mainItem.contactAddress || mainItem.contactName
|
||||||
secured: securityLevel === LinphoneEnums.SecurityLevel.EndToEndEncrypted
|
secured: securityLevel === LinphoneEnums.SecurityLevel.EndToEndEncryptedAndVerified
|
||||||
}
|
}
|
||||||
Item {
|
Item {
|
||||||
id: rightButton
|
id: rightButton
|
||||||
|
|
|
||||||
|
|
@ -215,7 +215,7 @@ Flickable{
|
||||||
ColumnLayout{
|
ColumnLayout{
|
||||||
id: contentsLayout
|
id: contentsLayout
|
||||||
width: parent.width
|
width: parent.width
|
||||||
spacing: 0
|
spacing: 20 * DefaultStyle.dp
|
||||||
BusyIndicator {
|
BusyIndicator {
|
||||||
Layout.alignment: Qt.AlignCenter
|
Layout.alignment: Qt.AlignCenter
|
||||||
Layout.preferredHeight: visible ? 60 * DefaultStyle.dp : 0
|
Layout.preferredHeight: visible ? 60 * DefaultStyle.dp : 0
|
||||||
|
|
@ -228,6 +228,7 @@ Flickable{
|
||||||
|
|
||||||
ContactListView{
|
ContactListView{
|
||||||
id: favoritesList
|
id: favoritesList
|
||||||
|
visible: contentHeight > 0
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredHeight: implicitHeight
|
Layout.preferredHeight: implicitHeight
|
||||||
interactive: false
|
interactive: false
|
||||||
|
|
@ -259,6 +260,7 @@ Flickable{
|
||||||
|
|
||||||
ContactListView{
|
ContactListView{
|
||||||
id: contactsList
|
id: contactsList
|
||||||
|
visible: contentHeight > 0
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredHeight: implicitHeight
|
Layout.preferredHeight: implicitHeight
|
||||||
Layout.topMargin: favoritesList.height > 0 ? 4 * DefaultStyle.dp : 0
|
Layout.topMargin: favoritesList.height > 0 ? 4 * DefaultStyle.dp : 0
|
||||||
|
|
@ -296,6 +298,7 @@ Flickable{
|
||||||
}
|
}
|
||||||
ContactListView{
|
ContactListView{
|
||||||
id: suggestionsList
|
id: suggestionsList
|
||||||
|
visible: contentHeight > 0
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredHeight: implicitHeight
|
Layout.preferredHeight: implicitHeight
|
||||||
Layout.topMargin: contactsList.height + favoritesList.height > 0 ? 4 * DefaultStyle.dp : 0
|
Layout.topMargin: contactsList.height + favoritesList.height > 0 ? 4 * DefaultStyle.dp : 0
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ Loader{
|
||||||
property string computedAvatarUri: avatarObj ? avatarObj.value : ''
|
property string computedAvatarUri: avatarObj ? avatarObj.value : ''
|
||||||
|
|
||||||
// To get the secured property for a specific address,
|
// 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 securityLevelObj: UtilsCpp.getFriendAddressSecurityLevel(_address)
|
||||||
property var securityLevel: securityLevelObj ? securityLevelObj.value : LinphoneEnums.SecurityLevel.None
|
property var securityLevel: securityLevelObj ? securityLevelObj.value : LinphoneEnums.SecurityLevel.None
|
||||||
property bool secured: call && call.core.encryption === LinphoneEnums.MediaEncryption.Zrtp
|
property bool secured: call && call.core.encryption === LinphoneEnums.MediaEncryption.Zrtp
|
||||||
|
|
|
||||||
|
|
@ -245,10 +245,13 @@ Item {
|
||||||
}
|
}
|
||||||
Text {
|
Text {
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
anchors.bottom: parent.bottom
|
anchors.bottom: parent.bottom
|
||||||
anchors.leftMargin: 10 * DefaultStyle.dp
|
anchors.leftMargin: 10 * DefaultStyle.dp
|
||||||
|
anchors.rightMargin: 10 * DefaultStyle.dp
|
||||||
anchors.bottomMargin: 10 * DefaultStyle.dp
|
anchors.bottomMargin: 10 * DefaultStyle.dp
|
||||||
width: implicitWidth
|
width: implicitWidth
|
||||||
|
maximumLineCount: 1
|
||||||
property string _text: mainItem.displayName != ''
|
property string _text: mainItem.displayName != ''
|
||||||
? mainItem.displayName
|
? mainItem.displayName
|
||||||
: mainItem.account && mainItem.identityAddress
|
: mainItem.account && mainItem.identityAddress
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ import 'qrc:/qt/qml/Linphone/view/Style/buttonStyle.js' as ButtonStyle
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
id: mainItem
|
id: mainItem
|
||||||
spacing: 10 * DefaultStyle.dp
|
spacing: 10 * DefaultStyle.dp
|
||||||
signal connectionSucceed()
|
|
||||||
|
|
||||||
FormItemLayout {
|
FormItemLayout {
|
||||||
id: username
|
id: username
|
||||||
|
|
@ -47,11 +46,6 @@ ColumnLayout {
|
||||||
if (passwordEdit.text.length > 0 || usernameEdit.text.length > 0)
|
if (passwordEdit.text.length > 0 || usernameEdit.text.length > 0)
|
||||||
errorText.setText(LoginPageCpp.errorMessage)
|
errorText.setText(LoginPageCpp.errorMessage)
|
||||||
}
|
}
|
||||||
function onRegistrationStateChanged() {
|
|
||||||
if (LoginPageCpp.registrationState === LinphoneEnums.RegistrationState.Ok) {
|
|
||||||
mainItem.connectionSucceed()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -227,7 +227,6 @@ ColumnLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Connections {
|
Connections {
|
||||||
enabled: !mainItem.call
|
|
||||||
target: SettingsCpp
|
target: SettingsCpp
|
||||||
onMicVolumeChanged: (value) => {
|
onMicVolumeChanged: (value) => {
|
||||||
audioTestSlider.value = value
|
audioTestSlider.value = value
|
||||||
|
|
|
||||||
|
|
@ -64,14 +64,12 @@ FocusScope {
|
||||||
}
|
}
|
||||||
onVisibleChanged: if (!visible) mainItem.numPadPopup.close()
|
onVisibleChanged: if (!visible) mainItem.numPadPopup.close()
|
||||||
contentItem: ColumnLayout {
|
contentItem: ColumnLayout {
|
||||||
// anchors.fill: parent
|
spacing: 38 * DefaultStyle.dp
|
||||||
spacing: 10 * DefaultStyle.dp
|
|
||||||
SearchBar {
|
SearchBar {
|
||||||
id: searchBar
|
id: searchBar
|
||||||
Layout.alignment: Qt.AlignTop
|
Layout.alignment: Qt.AlignTop
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.rightMargin: 39 * DefaultStyle.dp
|
Layout.rightMargin: 39 * DefaultStyle.dp
|
||||||
//Layout.maximumWidth: mainItem.width
|
|
||||||
focus: true
|
focus: true
|
||||||
color: mainItem.searchBarColor
|
color: mainItem.searchBarColor
|
||||||
borderColor: mainItem.searchBarBorderColor
|
borderColor: mainItem.searchBarBorderColor
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@ LoginLayout {
|
||||||
signal useSIPButtonClicked()
|
signal useSIPButtonClicked()
|
||||||
signal useRemoteConfigButtonClicked()
|
signal useRemoteConfigButtonClicked()
|
||||||
signal goToRegister()
|
signal goToRegister()
|
||||||
signal connectionSucceed()
|
|
||||||
|
|
||||||
titleContent: [
|
titleContent: [
|
||||||
BigButton {
|
BigButton {
|
||||||
|
|
@ -82,7 +81,6 @@ LoginLayout {
|
||||||
spacing: 0
|
spacing: 0
|
||||||
LoginForm {
|
LoginForm {
|
||||||
id: loginForm
|
id: loginForm
|
||||||
onConnectionSucceed: mainItem.connectionSucceed()
|
|
||||||
}
|
}
|
||||||
BigButton {
|
BigButton {
|
||||||
Layout.preferredWidth: loginForm.width
|
Layout.preferredWidth: loginForm.width
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@ LoginLayout {
|
||||||
id: mainItem
|
id: mainItem
|
||||||
signal goBack()
|
signal goBack()
|
||||||
signal goToRegister()
|
signal goToRegister()
|
||||||
signal connectionSucceed()
|
|
||||||
property bool showBackButton: false
|
property bool showBackButton: false
|
||||||
|
|
||||||
titleContent: [
|
titleContent: [
|
||||||
|
|
@ -271,11 +270,6 @@ LoginLayout {
|
||||||
function onErrorMessageChanged(error) {
|
function onErrorMessageChanged(error) {
|
||||||
errorText.setText(error)
|
errorText.setText(error)
|
||||||
}
|
}
|
||||||
function onRegistrationStateChanged() {
|
|
||||||
if (LoginPageCpp.registrationState === LinphoneEnums.RegistrationState.Ok) {
|
|
||||||
mainItem.connectionSucceed()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ FocusScope{
|
||||||
ListView {
|
ListView {
|
||||||
id: participantList
|
id: participantList
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
visible: contentHeight > 0
|
||||||
Layout.preferredHeight: contentHeight
|
Layout.preferredHeight: contentHeight
|
||||||
Layout.maximumHeight: mainItem.height / 3
|
Layout.maximumHeight: mainItem.height / 3
|
||||||
width: mainItem.width
|
width: mainItem.width
|
||||||
|
|
|
||||||
|
|
@ -81,27 +81,11 @@ AbstractMainPage {
|
||||||
id: leftPanel
|
id: leftPanel
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.fillHeight: 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 {
|
Control.StackView {
|
||||||
id: listStackView
|
id: listStackView
|
||||||
anchors.top: titleLoader.bottom
|
anchors.fill: parent
|
||||||
anchors.topMargin: 18 * DefaultStyle.dp
|
|
||||||
anchors.left: parent.left
|
|
||||||
anchors.leftMargin: 45 * DefaultStyle.dp
|
anchors.leftMargin: 45 * DefaultStyle.dp
|
||||||
anchors.right: parent.right
|
|
||||||
anchors.bottom: parent.bottom
|
|
||||||
clip: true
|
clip: true
|
||||||
initialItem: historyListItem
|
initialItem: historyListItem
|
||||||
focus: true
|
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 {
|
Component {
|
||||||
id: historyListItem
|
id: historyListItem
|
||||||
FocusScope{
|
FocusScope{
|
||||||
objectName: "historyListItem"
|
objectName: "historyListItem"
|
||||||
property alias listView: historyListView
|
property alias listView: historyListView
|
||||||
Control.StackView.onActivated: titleLoader.sourceComponent = historyListTitle
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
anchors.fill: parent
|
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 {
|
SearchBar {
|
||||||
id: searchBar
|
id: searchBar
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 18 * DefaultStyle.dp
|
||||||
Layout.rightMargin: 39 * DefaultStyle.dp
|
Layout.rightMargin: 39 * DefaultStyle.dp
|
||||||
placeholderText: qsTr("Rechercher un appel")
|
placeholderText: qsTr("Rechercher un appel")
|
||||||
visible: historyListView.count !== 0 || text.length !== 0
|
visible: historyListView.count !== 0 || text.length !== 0
|
||||||
|
|
@ -229,224 +205,224 @@ AbstractMainPage {
|
||||||
|
|
||||||
background: Item{}
|
background: Item{}
|
||||||
contentItem: ColumnLayout {
|
contentItem: ColumnLayout {
|
||||||
Text {
|
Text {
|
||||||
visible: historyListView.count === 0
|
visible: historyListView.count === 0
|
||||||
Layout.alignment: Qt.AlignHCenter
|
Layout.alignment: Qt.AlignHCenter
|
||||||
text: qsTr("Aucun appel%1").arg(searchBar.text.length != 0 ? " correspondant" : "")
|
text: qsTr("Aucun appel%1").arg(searchBar.text.length != 0 ? " correspondant" : "")
|
||||||
font {
|
font {
|
||||||
pixelSize: 16 * DefaultStyle.dp
|
pixelSize: 16 * DefaultStyle.dp
|
||||||
weight: 800 * 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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
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 {
|
ScrollBar {
|
||||||
id: 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 {
|
Component {
|
||||||
id: newCallItem
|
id: newCallItem
|
||||||
FocusScope{
|
FocusScope{
|
||||||
|
|
@ -503,14 +445,39 @@ AbstractMainPage {
|
||||||
width: parent?.width
|
width: parent?.width
|
||||||
height: parent?.height
|
height: parent?.height
|
||||||
Control.StackView.onActivated:{
|
Control.StackView.onActivated:{
|
||||||
titleLoader.sourceComponent = newCallTitle
|
|
||||||
callContactsList.forceActiveFocus()
|
callContactsList.forceActiveFocus()
|
||||||
}
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
anchors.fill: parent
|
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 {
|
NewCallForm {
|
||||||
id: callContactsList
|
id: callContactsList
|
||||||
|
Layout.topMargin: 18 * DefaultStyle.dp
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
focus: 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 {
|
Component {
|
||||||
id: groupCallItem
|
id: groupCallItem
|
||||||
FocusScope{
|
FocusScope{
|
||||||
objectName: "groupCallItem"
|
objectName: "groupCallItem"
|
||||||
Control.StackView.onActivated: {
|
Control.StackView.onActivated: {
|
||||||
titleLoader.sourceComponent = groupCallTitle
|
|
||||||
addParticipantsLayout.forceActiveFocus()
|
addParticipantsLayout.forceActiveFocus()
|
||||||
}
|
}
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
spacing: 5 * DefaultStyle.dp
|
spacing: 0
|
||||||
anchors.fill: parent
|
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 {
|
RowLayout {
|
||||||
spacing: 0
|
spacing: 0
|
||||||
|
Layout.topMargin: 18 * DefaultStyle.dp
|
||||||
Layout.rightMargin: 38 * DefaultStyle.dp
|
Layout.rightMargin: 38 * DefaultStyle.dp
|
||||||
Text {
|
Text {
|
||||||
font.pixelSize: 13 * DefaultStyle.dp
|
font.pixelSize: 13 * DefaultStyle.dp
|
||||||
|
|
@ -636,6 +592,7 @@ AbstractMainPage {
|
||||||
id: addParticipantsLayout
|
id: addParticipantsLayout
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.fillHeight: true
|
Layout.fillHeight: true
|
||||||
|
Layout.topMargin: 15 * DefaultStyle.dp
|
||||||
onSelectedParticipantsCountChanged: mainItem.selectedParticipantsCount = selectedParticipantsCount
|
onSelectedParticipantsCountChanged: mainItem.selectedParticipantsCount = selectedParticipantsCount
|
||||||
focus: true
|
focus: true
|
||||||
Connections {
|
Connections {
|
||||||
|
|
|
||||||
|
|
@ -628,11 +628,11 @@ AbstractMainPage {
|
||||||
font.pixelSize: 14 * DefaultStyle.dp
|
font.pixelSize: 14 * DefaultStyle.dp
|
||||||
}
|
}
|
||||||
Item{Layout.fillWidth: true}
|
Item{Layout.fillWidth: true}
|
||||||
Image{
|
EffectImage {
|
||||||
visible: listViewModelData.securityLevel === LinphoneEnums.SecurityLevel.EndToEndEncryptedAndVerified
|
visible: listViewModelData.securityLevel === LinphoneEnums.SecurityLevel.EndToEndEncryptedAndVerified
|
||||||
source: AppIcons.trusted
|
source: AppIcons.trusted
|
||||||
width: 22 * DefaultStyle.dp
|
Layout.preferredWidth: 22 * DefaultStyle.dp
|
||||||
height: 22 * DefaultStyle.dp
|
Layout.preferredHeight: 22 * DefaultStyle.dp
|
||||||
}
|
}
|
||||||
|
|
||||||
SmallButton {
|
SmallButton {
|
||||||
|
|
|
||||||
|
|
@ -454,24 +454,26 @@ AbstractMainPage {
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
property Control.StackView container
|
property Control.StackView container
|
||||||
property ConferenceInfoGui conferenceInfoGui
|
property ConferenceInfoGui conferenceInfoGui
|
||||||
|
spacing: 18 * DefaultStyle.dp
|
||||||
FocusScope{
|
FocusScope{
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredHeight: addParticipantsButtons.implicitHeight
|
Layout.preferredHeight: childrenRect.height
|
||||||
RowLayout {
|
ColumnLayout {
|
||||||
id: addParticipantsButtons
|
spacing: 4 * DefaultStyle.dp
|
||||||
spacing: 5 * DefaultStyle.dp
|
Layout.fillWidth: true
|
||||||
Button {
|
RowLayout {
|
||||||
id: removeButton
|
id: addParticipantsButtons
|
||||||
style: ButtonStyle.noBackgroundOrange
|
spacing: 10 * DefaultStyle.dp
|
||||||
icon.source: AppIcons.leftArrow
|
Button {
|
||||||
icon.width: 24 * DefaultStyle.dp
|
id: addParticipantsBackButton
|
||||||
icon.height: 24 * DefaultStyle.dp
|
style: ButtonStyle.noBackgroundOrange
|
||||||
KeyNavigation.right: addButton
|
icon.source: AppIcons.leftArrow
|
||||||
KeyNavigation.down: addParticipantLayout
|
icon.width: 24 * DefaultStyle.dp
|
||||||
onClicked: container.pop()
|
icon.height: 24 * DefaultStyle.dp
|
||||||
}
|
KeyNavigation.right: addButton
|
||||||
ColumnLayout {
|
KeyNavigation.down: addParticipantLayout
|
||||||
spacing: 8 * DefaultStyle.dp
|
onClicked: container.pop()
|
||||||
|
}
|
||||||
Text {
|
Text {
|
||||||
text: qsTr("Ajouter des participants")
|
text: qsTr("Ajouter des participants")
|
||||||
color: DefaultStyle.main1_500_main
|
color: DefaultStyle.main1_500_main
|
||||||
|
|
@ -482,29 +484,30 @@ AbstractMainPage {
|
||||||
}
|
}
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
}
|
}
|
||||||
Text {
|
SmallButton {
|
||||||
text: qsTr("%1 participant%2 sélectionné%2").arg(addParticipantLayout.selectedParticipantsCount).arg(addParticipantLayout.selectedParticipantsCount > 1 ? "s" : "")
|
id: addButton
|
||||||
color: DefaultStyle.main2_500main
|
enabled: addParticipantLayout.selectedParticipantsCount.length != 0
|
||||||
maximumLineCount: 1
|
Layout.leftMargin: 11 * DefaultStyle.dp
|
||||||
font {
|
focus: enabled
|
||||||
pixelSize: 12 * DefaultStyle.dp
|
style: ButtonStyle.main
|
||||||
weight: 300 * DefaultStyle.dp
|
text: qsTr("Ajouter")
|
||||||
|
KeyNavigation.left: addParticipantsBackButton
|
||||||
|
KeyNavigation.down: addParticipantLayout
|
||||||
|
onClicked: {
|
||||||
|
mainItem.addParticipantsValidated(addParticipantLayout.selectedParticipants)
|
||||||
}
|
}
|
||||||
Layout.fillWidth: true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SmallButton {
|
Text {
|
||||||
id: addButton
|
text: qsTr("%1 participant%2 sélectionné%2").arg(addParticipantLayout.selectedParticipantsCount).arg(addParticipantLayout.selectedParticipantsCount > 1 ? "s" : "")
|
||||||
enabled: addParticipantLayout.selectedParticipantsCount.length != 0
|
color: DefaultStyle.main2_500main
|
||||||
Layout.rightMargin: 21 * DefaultStyle.dp
|
Layout.leftMargin: addParticipantsBackButton.width + addParticipantsButtons.spacing
|
||||||
focus: enabled
|
maximumLineCount: 1
|
||||||
style: ButtonStyle.main
|
font {
|
||||||
text: qsTr("Ajouter")
|
pixelSize: 12 * DefaultStyle.dp
|
||||||
KeyNavigation.left: removeButton
|
weight: 300 * DefaultStyle.dp
|
||||||
KeyNavigation.down: addParticipantLayout
|
|
||||||
onClicked: {
|
|
||||||
mainItem.addParticipantsValidated(addParticipantLayout.selectedParticipants)
|
|
||||||
}
|
}
|
||||||
|
Layout.fillWidth: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -647,9 +647,12 @@ AbstractWindow {
|
||||||
searchBarBorderColor: DefaultStyle.grey_200
|
searchBarBorderColor: DefaultStyle.grey_200
|
||||||
numPadPopup: numericPad
|
numPadPopup: numericPad
|
||||||
onContactClicked: (contact) => {
|
onContactClicked: (contact) => {
|
||||||
rightPanel.visible = false
|
|
||||||
mainWindow.startCallWithContact(contact, false, rightPanel)
|
mainWindow.startCallWithContact(contact, false, rightPanel)
|
||||||
}
|
}
|
||||||
|
Connections {
|
||||||
|
target: mainWindow
|
||||||
|
function onCallChanged(){ if (newCallForm.Control.StackView.status === Control.StackView.Active) rightPanel.visible = false}
|
||||||
|
}
|
||||||
|
|
||||||
NumericPadPopup {
|
NumericPadPopup {
|
||||||
id: numericPad
|
id: numericPad
|
||||||
|
|
|
||||||
|
|
@ -29,8 +29,9 @@ AbstractWindow {
|
||||||
// color: DefaultStyle.grey_100
|
// color: DefaultStyle.grey_100
|
||||||
// }
|
// }
|
||||||
|
|
||||||
function openMainPage(){
|
function openMainPage(connectionSucceed){
|
||||||
if (mainWindowStackView.currentItem.objectName !== "mainPage") mainWindowStackView.replace(mainPage, StackView.Immediate)
|
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() {
|
function goToCallHistory() {
|
||||||
openMainPage()
|
openMainPage()
|
||||||
|
|
@ -46,7 +47,7 @@ AbstractWindow {
|
||||||
}
|
}
|
||||||
function transferCallSucceed() {
|
function transferCallSucceed() {
|
||||||
openMainPage()
|
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() {
|
function initStackViewItem() {
|
||||||
if(accountProxy && accountProxy.isInitialized) {
|
if(accountProxy && accountProxy.isInitialized) {
|
||||||
|
|
@ -96,6 +97,16 @@ AbstractWindow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: LoginPageCpp
|
||||||
|
function onRegistrationStateChanged() {
|
||||||
|
if (LoginPageCpp.registrationState === LinphoneEnums.RegistrationState.Ok) {
|
||||||
|
openMainPage(true)
|
||||||
|
proposeH264CodecsDownload()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
id: accountProxyLoader
|
id: accountProxyLoader
|
||||||
active: AppCpp.coreStarted
|
active: AppCpp.coreStarted
|
||||||
|
|
@ -144,10 +155,6 @@ AbstractWindow {
|
||||||
onGoBack: openMainPage()
|
onGoBack: openMainPage()
|
||||||
onUseSIPButtonClicked: mainWindowStackView.push(sipLoginPage)
|
onUseSIPButtonClicked: mainWindowStackView.push(sipLoginPage)
|
||||||
onGoToRegister: mainWindowStackView.replace(registerPage)
|
onGoToRegister: mainWindowStackView.replace(registerPage)
|
||||||
onConnectionSucceed: {
|
|
||||||
openMainPage()
|
|
||||||
proposeH264CodecsDownload()
|
|
||||||
}
|
|
||||||
StackView.onActivated:{
|
StackView.onActivated:{
|
||||||
if (accountProxy?.haveAccount) showBackButton = true
|
if (accountProxy?.haveAccount) showBackButton = true
|
||||||
}
|
}
|
||||||
|
|
@ -164,11 +171,6 @@ AbstractWindow {
|
||||||
mainWindowStackView.pop()
|
mainWindowStackView.pop()
|
||||||
}
|
}
|
||||||
onGoToRegister: mainWindowStackView.replace(registerPage)
|
onGoToRegister: mainWindowStackView.replace(registerPage)
|
||||||
|
|
||||||
onConnectionSucceed: {
|
|
||||||
openMainPage()
|
|
||||||
proposeH264CodecsDownload()
|
|
||||||
}
|
|
||||||
StackView.onActivated:{
|
StackView.onActivated:{
|
||||||
if (!SettingsCpp.assistantGoDirectlyToThirdPartySipAccountLogin || accountProxy?.haveAccount) showBackButton = true
|
if (!SettingsCpp.assistantGoDirectlyToThirdPartySipAccountLogin || accountProxy?.haveAccount) showBackButton = true
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue