Fix register checking ui #LINQT-2332

Add accessibility focus ui on register country combobox and fix register page spacings and interaction #LINQT-2333
This commit is contained in:
Gaelle Braud 2026-01-13 13:25:09 +01:00
parent 7b7d382cc6
commit 2e7c250d8d
11 changed files with 699 additions and 686 deletions

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -357,10 +357,11 @@ void AccountManager::linkNewAccountUsingCode(const QString &code,
const std::string &errorMessage, const std::shared_ptr<const linphone::Dictionary> &parameterErrors) {
if (request->getType() == linphone::AccountManagerServicesRequest::Type::LinkEmailUsingCode) {
lInfo() << "[AccountManager] error linking email to account" << errorMessage;
emit linkingNewAccountWithCodeFailed(Utils::coreStringToAppString(errorMessage));
} else if (request->getType() == linphone::AccountManagerServicesRequest::Type::LinkPhoneNumberUsingCode) {
lInfo() << "[AccountManager] error linking phone number to account" << errorMessage;
emit linkingNewAccountWithCodeFailed(Utils::coreStringToAppString(errorMessage));
}
emit linkingNewAccountWithCodeFailed(Utils::coreStringToAppString(errorMessage));
});
if (registerType == RegisterType::Email)
mAccountManagerServicesModel->linkEmailToAccountUsingCode(sipIdentityAddress,

View file

@ -3,12 +3,18 @@ import QtQuick.Controls.Basic as Control
import QtQuick.Layouts
import QtQuick.Effects
import Linphone
import CustomControls 1.0
import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
Control.ComboBox {
id: mainItem
property string defaultCallingCode: ""
property bool enableBackgroundColors: false
onKeyboardFocusChanged: console.log("keyboard focus combobox", keyboardFocus)
property bool keyboardFocus: FocusHelper.keyboardFocus
property color keyboardFocusedBorderColor: DefaultStyle.main2_900
property real borderWidth: Utils.getSizeWithScreenRatio(1)
property real keyboardFocusedBorderWidth: Utils.getSizeWithScreenRatio(3)
property string text: combobox.model.getAt(combobox.currentIndex) ? combobox.model.getAt(combobox.currentIndex).countryCallingCode : ""
currentIndex: phoneNumberModel.count > 0 ? Math.max(0, phoneNumberModel.findIndexByCountryCallingCode(defaultCallingCode)) : -1
Accessible.name: mainItem.Accessible.name
@ -19,13 +25,16 @@ Control.ComboBox {
anchors.fill: parent
radius: Utils.getSizeWithScreenRatio(63)
color: mainItem.enableBackgroundColor ? DefaultStyle.grey_100 : "transparent"
border.color: mainItem.enableBackgroundColors
? (mainItem.errorMessage.length > 0
? DefaultStyle.danger_500_main
: textField.activeFocus
? DefaultStyle.main1_500_main
: DefaultStyle.grey_200)
: "transparent"
border.color: mainItem.keyboardFocus
? mainItem.keyboardFocusedBorderColor
: mainItem.enableBackgroundColors
? (mainItem.errorMessage.length > 0
? DefaultStyle.danger_500_main
: mainItem.activeFocus || textField.activeFocus
? DefaultStyle.main1_500_main
: DefaultStyle.grey_200)
: "transparent"
border.width: mainItem.keyboardFocus ? mainItem.keyboardFocusedBorderWidth : mainItem.borderWidth
}
contentItem: RowLayout {
readonly property var currentItem: combobox.model.getAt(combobox.currentIndex)
@ -95,8 +104,6 @@ Control.ComboBox {
maximumFlickVelocity: 1500
spacing: Utils.getSizeWithScreenRatio(10)
highlight: Rectangle {
anchors.left: parent.left
anchors.right: parent.right
width: listView.width
height: listView.height
color: DefaultStyle.main2_300

View file

@ -12,6 +12,7 @@ FocusScope{
property string labelIndication
property string tooltip: ""
property bool mandatory: false
property int errorTextTopMargin: 0//
property alias errorTextItem: errorText
property alias errorMessage: errorText.text
@ -85,7 +86,7 @@ FocusScope{
Item {
Layout.preferredHeight: childrenRect.height
Layout.fillWidth: true
StackLayout {
FocusScope {
id: contentItem
height: childrenRect.height
anchors.left: parent.left
@ -94,6 +95,7 @@ FocusScope{
TemporaryText {
id: errorText
anchors.top: contentItem.bottom
anchors.topMargin: mainItem.errorTextTopMargin
color: DefaultStyle.danger_500_main
}
}

View file

@ -6,6 +6,7 @@ import "qrc:/qt/qml/Linphone/view/Control/Tool/Helper/utils.js" as Utils
Control.TextField {
id: mainItem
property real inputSize: Utils.getSizeWithScreenRatio(100)
property bool isError: false
color: activeFocus ? DefaultStyle.main1_500_main : DefaultStyle.main2_500_main
validator: IntValidator{bottom: 0; top: 9}
@ -34,7 +35,11 @@ Control.TextField {
Rectangle {
id: background
border.width: Utils.getSizeWithScreenRatio(1)
border.color: mainItem.activeFocus ? DefaultStyle.main1_500_main : DefaultStyle.main2_500_main
border.color: mainItem.isError
? DefaultStyle.danger_500_main
: mainItem.activeFocus
? DefaultStyle.main1_500_main
: DefaultStyle.main2_500_main
radius: mainItem.inputSize * 0.15
width: mainItem.inputSize * 0.9
height: mainItem.inputSize

View file

@ -18,7 +18,10 @@ ColumnLayout {
readonly property string phoneNumber: textField.text
readonly property string countryCode: combobox.text
property string defaultCallingCode
property bool keyboardFocus: FocusHelper.keyboardFocus
property bool keyboardFocus: combobox.keyboardFocus || textField.keyboardFocus
property color keyboardFocusedBorderColor: DefaultStyle.main2_900
property real borderWidth: Utils.getSizeWithScreenRatio(1)
property real keyboardFocusedBorderWidth: Utils.getSizeWithScreenRatio(3)
spacing: Utils.getSizeWithScreenRatio(5)
@ -26,7 +29,7 @@ ColumnLayout {
visible: label.length > 0
verticalAlignment: Text.AlignVCenter
text: mainItem.label + (mainItem.mandatory ? "*" : "")
color: (combobox.hasActiveFocus || textField.hasActiveFocus) ? DefaultStyle.main1_500_main : DefaultStyle.main2_600
color: (combobox.activeFocus || textField.activeFocus) ? DefaultStyle.main1_500_main : DefaultStyle.main2_600
font {
pixelSize: Typography.p2.pixelSize
weight: Typography.p2.weight
@ -36,25 +39,25 @@ ColumnLayout {
Control.Control {
Layout.preferredWidth: mainItem.width
Layout.preferredHeight: Utils.getSizeWithScreenRatio(49)
leftPadding: Utils.getSizeWithScreenRatio(16)
background: Rectangle {
id: contentBackground
anchors.fill: parent
radius: Utils.getSizeWithScreenRatio(63)
color: DefaultStyle.grey_100
border.color: mainItem.errorMessage.length > 0
? DefaultStyle.danger_500_main
: (textField.hasActiveFocus || combobox.hasActiveFocus)
? DefaultStyle.main1_500_main
: DefaultStyle.grey_200
? DefaultStyle.danger_500_main
: (textField.activeFocus || combobox.activeFocus)
? DefaultStyle.main1_500_main
: DefaultStyle.grey_200
border.width: mainItem.borderWidth
}
contentItem: RowLayout {
CountryIndicatorCombobox {
id: combobox
implicitWidth: Utils.getSizeWithScreenRatio(110)
leftPadding: Utils.getSizeWithScreenRatio(16)
Layout.fillHeight: true
defaultCallingCode: mainItem.defaultCallingCode
property bool keyboardFocus: FocusHelper.keyboardFocus
//: %1 prefix
Accessible.name: qsTr("prefix_phone_number_accessible_name").arg(mainItem.Accessible.name)
}
@ -69,10 +72,15 @@ ColumnLayout {
id: textField
Layout.fillWidth: true
placeholderText: mainItem.placeholderText
background: Item{}
background: Rectangle {
visible: textField.keyboardFocus
radius: Utils.getSizeWithScreenRatio(63)
color: "transparent"
border.color: mainItem.keyboardFocusedBorderColor
border.width: mainItem.keyboardFocusedBorderWidth
}
initialText: initialPhoneNumber
validator: RegularExpressionValidator{ regularExpression: /[0-9]+/}
property bool keyboardFocus: FocusHelper.keyboardFocus
//: %1 number
Accessible.name: qsTr("number_phone_number_accessible_name").arg(mainItem.Accessible.name)
}

View file

@ -14,6 +14,7 @@ LoginLayout {
property string address
property string sipIdentityAddress
property string code
property alias errorMessage: codeItemLayout.errorMessage
property bool ctrlIsPressed
onCtrlIsPressedChanged: console.log("ctrl is pressed", ctrlIsPressed)
titleContent: [
@ -78,66 +79,71 @@ LoginLayout {
text = qsTr("assistant_account_creation_confirmation_explanation").arg(completeString).arg(address)
}
}
RowLayout {
spacing: Utils.getSizeWithScreenRatio(45)
Repeater {
model: 4
id: repeater
signal pasteRequested(string text)
DigitInput {
id: digitInput
required property int index
Layout.preferredWidth: width
Layout.preferredHeight: height
Connections {
target: repeater
function onPasteRequested(text) {
console.log("paste requested", text[digitInput.index])
var test= text;
if (UtilsCpp.isInteger(text))
{
digitInput.text = text[digitInput.index]
FormItemLayout {
id: codeItemLayout
errorTextTopMargin: Utils.getSizeWithScreenRatio(5)
contentItem: RowLayout {
spacing: Utils.getSizeWithScreenRatio(45)
Repeater {
model: 4
id: repeater
signal pasteRequested(string text)
DigitInput {
id: digitInput
required property int index
Layout.preferredWidth: width
Layout.preferredHeight: height
isError: codeItemLayout.errorMessage !== ""
Connections {
target: repeater
function onPasteRequested(text) {
console.log("paste requested", text[digitInput.index])
var test= text;
if (UtilsCpp.isInteger(text))
{
digitInput.text = text[digitInput.index]
}
}
}
}
onTextChanged: {
console.log("text edited", text)
if (text.length > 0 ) {
mainItem.code = mainItem.code.slice(0, index) + text + mainItem.code.slice(index)
if (index < 3)
nextItemInFocusChain(true).forceActiveFocus()
else {
mainItem.sendCode(mainItem.code)
mainItem.code = ""
}
} else {
if (index > 0)
nextItemInFocusChain(false).forceActiveFocus()
}
}
Keys.onPressed: (event) => {
if (event.key == Qt.Key_Backspace) {
if (text.length === 0) {
nextItemInFocusChain(false).forceActiveFocus()
event.accepted = true
onTextChanged: {
console.log("text edited", text)
if (text.length > 0 ) {
mainItem.code = mainItem.code.slice(0, index) + text + mainItem.code.slice(index)
if (index < 3)
nextItemInFocusChain(true).forceActiveFocus()
else {
mainItem.sendCode(mainItem.code)
mainItem.code = ""
}
} else {
event.accepted = false
if (index > 0)
nextItemInFocusChain(false).forceActiveFocus()
}
} else if (event.key == Qt.Key_Control) {
mainItem.ctrlIsPressed = true
event.accepted = false
} else if (mainItem.ctrlIsPressed && event.key == Qt.Key_V) {
var clipboard = UtilsCpp.getClipboardText()
console.log("paste", clipboard)
repeater.pasteRequested(clipboard)
} else {
event.accepted = false
}
}
Keys.onReleased: (event) => {
if (event.key == Qt.Key_Control) {
mainItem.ctrlIsPressed = false
event.accepted = true
Keys.onPressed: (event) => {
if (event.key == Qt.Key_Backspace) {
if (text.length === 0) {
nextItemInFocusChain(false).forceActiveFocus()
event.accepted = true
} else {
event.accepted = false
}
} else if (event.key == Qt.Key_Control) {
mainItem.ctrlIsPressed = true
event.accepted = false
} else if (mainItem.ctrlIsPressed && event.key == Qt.Key_V) {
var clipboard = UtilsCpp.getClipboardText()
console.log("paste", clipboard)
repeater.pasteRequested(clipboard)
} else {
event.accepted = false
}
}
Keys.onReleased: (event) => {
if (event.key == Qt.Key_Control) {
mainItem.ctrlIsPressed = false
event.accepted = true
}
}
}
}

View file

@ -128,15 +128,11 @@ LoginLayout {
ColumnLayout {
id: contentLayout
anchors.left: parent.left
anchors.right: parent.right
spacing: Utils.getSizeWithScreenRatio(8)
ColumnLayout {
id: formLayout
spacing: Utils.getSizeWithScreenRatio(24)
RowLayout {
Layout.preferredHeight: usernameItem.height
spacing: Utils.getSizeWithScreenRatio(16)
FormItemLayout {
id: usernameItem
label: qsTr("username")
@ -152,6 +148,7 @@ LoginLayout {
}
RowLayout {
spacing: Utils.getSizeWithScreenRatio(10)
Layout.leftMargin: Utils.getSizeWithScreenRatio(16)
ComboBox {
Layout.preferredWidth: Utils.getSizeWithScreenRatio(210)
Layout.preferredHeight: Utils.getSizeWithScreenRatio(49)
@ -171,7 +168,8 @@ LoginLayout {
currentIndex: bar.currentIndex
PhoneNumberInput {
id: phoneNumberInput
Layout.preferredWidth: Utils.getSizeWithScreenRatio(346)
Layout.fillWidth: false
Layout.preferredWidth: Utils.getSizeWithScreenRatio(390)
property string completePhoneNumber: countryCode + phoneNumber
//: "Numéro de téléphone"
label: qsTr("phone_number")
@ -221,6 +219,7 @@ LoginLayout {
}
FormItemLayout {
Layout.preferredWidth: Utils.getSizeWithScreenRatio(346)
Layout.leftMargin: Utils.getSizeWithScreenRatio(16)
//: "Confirmation mot de passe"
label: qsTr("assistant_account_register_password_confirmation")
mandatory: true
@ -235,13 +234,14 @@ LoginLayout {
}
}
}
TemporaryText {
id: otherErrorText
Layout.fillWidth: true
Layout.topMargin: Utils.getSizeWithScreenRatio(5)
}
}
}
TemporaryText {
id: otherErrorText
Layout.fillWidth: true
Layout.preferredHeight: implicitHeight
// Layout.topMargin: Utils.getSizeWithScreenRatio(5)
}
// ColumnLayout {
// spacing: Utils.getSizeWithScreenRatio(18)
// RowLayout {
@ -276,6 +276,7 @@ LoginLayout {
Accessible.name: acceptCguAndPrivacyPolicyItem.associatedText
}
Text {
id: privacyLinkText
text: acceptCguAndPrivacyPolicyItem.associatedText
onLinkActivated: (link) => Qt.openUrlExternally(link)
font {
@ -284,9 +285,17 @@ LoginLayout {
}
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.NoButton
acceptedButtons: Qt.LeftButton
cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
onClicked: termsCheckBox.toggle()
onClicked: (mouse) => {
mouse.accepted = false
if (parent.hoveredLink) {
privacyLinkText.linkActivated(privacyLinkText.linkAt(mouse.x, mouse.y))
}
else {
termsCheckBox.toggle()
}
}
}
}
}

View file

@ -230,6 +230,7 @@ AbstractWindow {
Component {
id: checkingPage
RegisterCheckingPage {
id: registerCheckingPage
onReturnToRegister: mainWindowStackView.pop()
onSendCode: (code) => {
RegisterPageCpp.linkNewAccountUsingCode(code, registerWithEmail, sipIdentityAddress)
@ -238,15 +239,16 @@ AbstractWindow {
target: RegisterPageCpp
function onLinkingNewAccountWithCodeSucceed() {
goToLogin()
//: "Compte créé"
mainWindow.showInformationPopup(qsTr("assistant_register_success_title"),
//: "Le compte a été créé. Vous pouvez maintenant vous connecter"
qsTr("assistant_register_success_message"), true)
//: "Compte créé"
mainWindow.showInformationPopup(qsTr("assistant_register_success_title"),
//: "Le compte a été créé. Vous pouvez maintenant vous connecter"
qsTr("assistant_register_success_message"), true)
}
function onLinkingNewAccountWithCodeFailed(errorMessage) {
//: "Erreur dans le code de validation"
if (errorMessage.length === 0) errorMessage = qsTr("assistant_register_error_code")
mainWindow.showInformationPopup(qsTr("information_popup_error_title"), errorMessage, false)
registerCheckingPage.errorMessage = ""
//: "Erreur dans le code de validation"
if (errorMessage.length === 0) errorMessage = qsTr("assistant_register_error_code")
registerCheckingPage.errorMessage = errorMessage
}
}
}