diff --git a/Linphone/core/login/LoginPage.cpp b/Linphone/core/login/LoginPage.cpp index c6c9e35e..67979b04 100644 --- a/Linphone/core/login/LoginPage.cpp +++ b/Linphone/core/login/LoginPage.cpp @@ -59,7 +59,11 @@ void LoginPage::setErrorMessage(const QString &error) { emit errorMessageChanged(); } -void LoginPage::login(const QString &username, const QString &password) { +void LoginPage::login(const QString &username, + const QString &password, + QString displayName, + QString domain, + LinphoneEnums::TransportType transportType) { App::postModelAsync([=]() { QString *error = new QString(tr("Le couple identifiant mot de passe ne correspond pas")); // Create on Model thread. @@ -103,7 +107,8 @@ void LoginPage::login(const QString &username, const QString &password) { connect(accountManager, &AccountManager::destroyed, [error]() { delete error; }); - if (!accountManager->login(username, password, error)) { + if (!accountManager->login(username, password, displayName, domain, LinphoneEnums::toLinphone(transportType), + error)) { emit accountManager->registrationStateChanged(linphone::RegistrationState::Failed); } }); diff --git a/Linphone/core/login/LoginPage.hpp b/Linphone/core/login/LoginPage.hpp index 0eb118dd..462d7fca 100644 --- a/Linphone/core/login/LoginPage.hpp +++ b/Linphone/core/login/LoginPage.hpp @@ -22,6 +22,7 @@ #define LOGINPAGE_H_ #include "tool/AbstractObject.hpp" +#include "tool/LinphoneEnums.hpp" #include #include @@ -35,7 +36,11 @@ public: Q_PROPERTY(linphone::RegistrationState registrationState READ getRegistrationState NOTIFY registrationStateChanged) Q_PROPERTY(QString errorMessage READ getErrorMessage NOTIFY errorMessageChanged) - Q_INVOKABLE void login(const QString &username, const QString &password); + Q_INVOKABLE void login(const QString &username, + const QString &password, + QString displayName = QString(), + QString domain = QString(), + LinphoneEnums::TransportType transportType = LinphoneEnums::TransportType::Udp); linphone::RegistrationState getRegistrationState() const; void setRegistrationState(linphone::RegistrationState status); diff --git a/Linphone/model/account/AccountManager.cpp b/Linphone/model/account/AccountManager.cpp index 2e062140..f1c083d2 100644 --- a/Linphone/model/account/AccountManager.cpp +++ b/Linphone/model/account/AccountManager.cpp @@ -54,7 +54,12 @@ std::shared_ptr AccountManager::createAccount(const QString & return core->createAccount(core->createAccountParams()); } -bool AccountManager::login(QString username, QString password, QString *errorMessage) { +bool AccountManager::login(QString username, + QString password, + QString displayName, + QString domain, + linphone::TransportType transportType, + QString *errorMessage) { mustBeInLinphoneThread(log().arg(Q_FUNC_INFO)); auto core = CoreModel::getInstance()->getCore(); auto factory = linphone::Factory::get(); @@ -74,6 +79,9 @@ bool AccountManager::login(QString username, QString password, QString *errorMes username = Utils::getUsername(username); identity->setUsername(Utils::appStringToCoreString(username)); + if (!displayName.isEmpty()) identity->setDisplayName(Utils::appStringToCoreString(displayName)); + identity->setTransport(transportType); + if (!domain.isEmpty()) identity->setDomain(Utils::appStringToCoreString(domain)); if (params->setIdentityAddress(identity)) { qWarning() << log() .arg(QStringLiteral("Unable to set identity address: `%1`.")) diff --git a/Linphone/model/account/AccountManager.hpp b/Linphone/model/account/AccountManager.hpp index dad8785d..ef58eedb 100644 --- a/Linphone/model/account/AccountManager.hpp +++ b/Linphone/model/account/AccountManager.hpp @@ -36,7 +36,12 @@ public: AccountManager(QObject *parent = nullptr); ~AccountManager(); - bool login(QString username, QString password, QString *errorMessage = nullptr); + bool login(QString username, + QString password, + QString displayName = QString(), + QString domain = QString(), + linphone::TransportType transportType = linphone::TransportType::Udp, + QString *errorMessage = nullptr); std::shared_ptr createAccount(const QString &assistantFile); enum RegisterType { PhoneNumber = 0, Email = 1 }; diff --git a/Linphone/tool/LinphoneEnums.cpp b/Linphone/tool/LinphoneEnums.cpp index 3100e191..a8901345 100644 --- a/Linphone/tool/LinphoneEnums.cpp +++ b/Linphone/tool/LinphoneEnums.cpp @@ -303,7 +303,8 @@ void LinphoneEnums::fromString(const QString &transportType, LinphoneEnums::Tran if (transportType.toUpper() == QLatin1String("TCP")) *transport = TransportType::Tcp; else if (transportType.toUpper() == QLatin1String("UDP")) *transport = TransportType::Udp; else if (transportType.toUpper() == QLatin1String("TLS")) *transport = TransportType::Tls; - else *transport = TransportType::Dtls; + else if (transportType.toUpper() == QLatin1String("DTLS")) *transport = TransportType::Dtls; + else *transport = TransportType::Udp; } linphone::VideoSourceScreenSharingType diff --git a/Linphone/view/Item/Form/LoginForm.qml b/Linphone/view/Item/Form/LoginForm.qml index be1cd6b1..32d40481 100644 --- a/Linphone/view/Item/Form/LoginForm.qml +++ b/Linphone/view/Item/Form/LoginForm.qml @@ -16,20 +16,9 @@ ColumnLayout { enableErrorText: true contentItem: TextField { id: usernameEdit + isError: username.errorTextVisible Layout.preferredWidth: 360 * DefaultStyle.dp Layout.preferredHeight: 49 * DefaultStyle.dp - Binding on backgroundBorderColor { - when: errorText.opacity != 0 - value: DefaultStyle.danger_500main - } - Binding on backgroundBorderColor { - when: username.errorTextItem.opacity != 0 - value: DefaultStyle.danger_500main - } - Binding on color { - when: errorText.opacity != 0 - value: DefaultStyle.danger_500main - } } } Item { @@ -41,21 +30,10 @@ ColumnLayout { enableErrorText: true contentItem: TextField { id: passwordEdit + isError: password.errorTextVisible Layout.preferredWidth: 360 * DefaultStyle.dp Layout.preferredHeight: 49 * DefaultStyle.dp hidden: true - Binding on backgroundBorderColor { - when: errorText.opacity != 0 - value: DefaultStyle.danger_500main - } - Binding on backgroundBorderColor { - when: password.errorTextItem.opacity != 0 - value: DefaultStyle.danger_500main - } - Binding on color { - when: errorText.opacity != 0 - value: DefaultStyle.danger_500main - } } } diff --git a/Linphone/view/Item/TextField.qml b/Linphone/view/Item/TextField.qml index ad12502f..9f02a04b 100644 --- a/Linphone/view/Item/TextField.qml +++ b/Linphone/view/Item/TextField.qml @@ -12,7 +12,7 @@ Control.TextField { rightPadding: eyeButton.visible ? 5 * DefaultStyle.dp + eyeButton.width + eyeButton.rightMargin : 15 * DefaultStyle.dp echoMode: (hidden && !eyeButton.checked) ? TextInput.Password : TextInput.Normal verticalAlignment: TextInput.AlignVCenter - color: DefaultStyle.main2_600 + color: isError ? DefaultStyle.danger_500main : DefaultStyle.main2_600 placeholderTextColor: DefaultStyle.placeholders font { family: DefaultStyle.defaultFont @@ -24,6 +24,7 @@ Control.TextField { property bool controlIsDown: false property bool hidden: false + property bool isError: false property bool backgroundVisible: true property color backgroundColor: DefaultStyle.grey_100 property color backgroundBorderColor: DefaultStyle.grey_200 @@ -47,9 +48,11 @@ Control.TextField { anchors.fill: parent radius: 79 * DefaultStyle.dp color: mainItem.backgroundColor - border.color: activeFocus - ? DefaultStyle.main1_500_main - : mainItem.backgroundBorderColor + border.color: mainItem.isError + ? DefaultStyle.danger_500main + : mainItem.activeFocus + ? DefaultStyle.main1_500_main + : mainItem.backgroundBorderColor } cursorDelegate: Rectangle { diff --git a/Linphone/view/Page/Login/SIPLoginPage.qml b/Linphone/view/Page/Login/SIPLoginPage.qml index ba66097e..61f1e4bf 100644 --- a/Linphone/view/Page/Login/SIPLoginPage.qml +++ b/Linphone/view/Page/Login/SIPLoginPage.qml @@ -142,36 +142,45 @@ LoginLayout { Component { id: secondItem ColumnLayout { - spacing: 0 + spacing: 2 * DefaultStyle.dp ColumnLayout { spacing: 16 * DefaultStyle.dp FormItemLayout { - label: qsTr("Username") + id: username + label: qsTr("Nom d'utilisateur") mandatory: true + enableErrorText: true contentItem: TextField { - id: username + id: usernameEdit + isError: username.errorTextVisible Layout.preferredWidth: 360 * DefaultStyle.dp } } FormItemLayout { - label: qsTr("Password") + id: password + label: qsTr("Mot de passe") mandatory: true + enableErrorText: true contentItem: TextField { - id: password + id: passwordEdit + isError: password.errorTextVisible hidden: true Layout.preferredWidth: 360 * DefaultStyle.dp } } FormItemLayout { - label: qsTr("Domain") + id: domain + label: qsTr("Domaine") mandatory: true + enableErrorText: true contentItem: TextField { - id: domain + id: domainEdit + isError: domain.errorTextVisible Layout.preferredWidth: 360 * DefaultStyle.dp } } FormItemLayout { - label: qsTr("Display Name") + label: qsTr("Nom d'affichage") contentItem: TextField { id: displayName Layout.preferredWidth: 360 * DefaultStyle.dp @@ -180,9 +189,17 @@ LoginLayout { FormItemLayout { label: qsTr("Transport") contentItem: ComboBox { + id: transportCbox height: 49 * DefaultStyle.dp width: 360 * DefaultStyle.dp - model:[ "TCP", "UDP", "TLS", "DTLS"] + textRole: "text" + valueRole: "value" + model: [ + {text: "TCP", value: LinphoneEnums.TransportType.Tcp}, + {text: "UDP", value: LinphoneEnums.TransportType.Udp}, + {text: "TLS", value: LinphoneEnums.TransportType.Tls}, + {text: "DTLS", value: LinphoneEnums.TransportType.Dtls} + ] } } } @@ -191,10 +208,11 @@ LoginLayout { id: errorText Connections { target: LoginPageCpp + function onErrorMessageChanged() { + errorText.text = LoginPageCpp.errorMessage + } function onRegistrationStateChanged() { - if (LoginPageCpp.registrationState === LinphoneEnums.RegistrationState.Failed) { - errorText.text = qsTr("Connection has failed. Please verify your credentials") - } else if (LoginPageCpp.registrationState === LinphoneEnums.RegistrationState.Ok) { + if (LoginPageCpp.registrationState === LinphoneEnums.RegistrationState.Ok) { mainItem.connectionSucceed() } } @@ -202,16 +220,75 @@ LoginLayout { } Button { + id: connectionButton Layout.topMargin: 32 * DefaultStyle.dp leftPadding: 20 * DefaultStyle.dp rightPadding: 20 * DefaultStyle.dp topPadding: 11 * DefaultStyle.dp bottomPadding: 11 * DefaultStyle.dp - text: qsTr("Log in") - onClicked: { - console.debug("[SIPLoginPage] User: Log in") - LoginPageCpp.login(username.inputText, password.inputText); + contentItem: StackLayout { + id: connectionButtonContent + currentIndex: 0 + Text { + text: qsTr("Connexion") + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + + font { + pixelSize: 18 * DefaultStyle.dp + weight: 600 * DefaultStyle.dp + } + color: DefaultStyle.grey_0 + } + BusyIndicator { + implicitWidth: parent.height + implicitHeight: parent.height + Layout.alignment: Qt.AlignCenter + indicatorColor: DefaultStyle.grey_0 + } + Connections { + target: LoginPageCpp + function onRegistrationStateChanged() { + if (LoginPageCpp.registrationState != LinphoneEnums.RegistrationState.Progress) { + connectionButton.enabled = true + connectionButtonContent.currentIndex = 0 + } + } + function onErrorMessageChanged() { + connectionButton.enabled = true + connectionButtonContent.currentIndex = 0 + } + } } + + function trigger() { + username.errorMessage = "" + password.errorMessage = "" + domain.errorMessage = "" + errorText.text = "" + + if (usernameEdit.text.length == 0 || passwordEdit.text.length == 0 || domainEdit.text.length == 0) { + if (usernameEdit.text.length == 0) + username.errorMessage = qsTr("Veuillez saisir un nom d'utilisateur") + if (passwordEdit.text.length == 0) + password.errorMessage = qsTr("Veuillez saisir un mot de passe") + if (domainEdit.text.length == 0) + domain.errorMessage = qsTr("Veuillez saisir un nom de domaine") + return + } + console.debug("[SIPLoginPage] User: Log in") + LoginPageCpp.login(usernameEdit.text, passwordEdit.text, displayName.text, domainEdit.text, transportCbox.currentValue); + connectionButton.enabled = false + connectionButtonContent.currentIndex = 1 + } + + Shortcut { + sequences: ["Return", "Enter"] + onActivated: if(domain.activeFocus) connectionButton.trigger() + else if(username.activeFocus) password.forceActiveFocus() + else if(password.activeFocus) domain.forceActiveFocus() + } + onPressed: connectionButton.trigger() } Item { Layout.fillHeight: true