mirror of
https://gitlab.linphone.org/BC/public/linphone-desktop.git
synced 2026-01-17 11:28:07 +00:00
register
This commit is contained in:
parent
16757d0a85
commit
5beb0b84d0
41 changed files with 1119 additions and 271 deletions
|
|
@ -58,6 +58,7 @@
|
|||
#include "core/participant/ParticipantProxy.hpp"
|
||||
#include "core/phone-number/PhoneNumber.hpp"
|
||||
#include "core/phone-number/PhoneNumberProxy.hpp"
|
||||
#include "core/register/RegisterPage.hpp"
|
||||
#include "core/screen/ScreenList.hpp"
|
||||
#include "core/screen/ScreenProxy.hpp"
|
||||
#include "core/search/MagicSearchProxy.hpp"
|
||||
|
|
@ -294,8 +295,17 @@ void App::initCore() {
|
|||
|
||||
void App::initCppInterfaces() {
|
||||
qmlRegisterSingletonType<LoginPage>(
|
||||
Constants::MainQmlUri, 1, 0, "LoginPageCpp",
|
||||
[](QQmlEngine *engine, QJSEngine *) -> QObject * { return new LoginPage(engine); });
|
||||
Constants::MainQmlUri, 1, 0, "LoginPageCpp", [](QQmlEngine *engine, QJSEngine *) -> QObject * {
|
||||
static auto loginPage = new LoginPage(engine);
|
||||
App::getInstance()->mEngine->setObjectOwnership(loginPage, QQmlEngine::CppOwnership);
|
||||
return loginPage;
|
||||
});
|
||||
qmlRegisterSingletonType<RegisterPage>(
|
||||
Constants::MainQmlUri, 1, 0, "RegisterPageCpp", [](QQmlEngine *engine, QJSEngine *) -> QObject * {
|
||||
static RegisterPage *registerPage = new RegisterPage();
|
||||
App::getInstance()->mEngine->setObjectOwnership(registerPage, QQmlEngine::CppOwnership);
|
||||
return registerPage;
|
||||
});
|
||||
qmlRegisterSingletonType<Constants>(
|
||||
"ConstantsCpp", 1, 0, "ConstantsCpp",
|
||||
[](QQmlEngine *engine, QJSEngine *) -> QObject * { return new Constants(engine); });
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ list(APPEND _LINPHONEAPP_SOURCES
|
|||
core/phone-number/PhoneNumber.cpp
|
||||
core/phone-number/PhoneNumberList.cpp
|
||||
core/phone-number/PhoneNumberProxy.cpp
|
||||
core/register/RegisterPage.cpp
|
||||
|
||||
core/search/MagicSearchList.cpp
|
||||
core/search/MagicSearchProxy.cpp
|
||||
|
|
|
|||
|
|
@ -71,14 +71,27 @@ void LoginPage::login(const QString &username, const QString &password) {
|
|||
switch (state) {
|
||||
case linphone::RegistrationState::Failed: {
|
||||
emit accountManager->errorMessageChanged(*error);
|
||||
accountManager->deleteLater();
|
||||
if (accountManager) {
|
||||
accountManager->deleteLater();
|
||||
accountManager = nullptr;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case linphone::RegistrationState::Ok: {
|
||||
emit accountManager->errorMessageChanged("");
|
||||
if (accountManager) {
|
||||
accountManager->deleteLater();
|
||||
accountManager = nullptr;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case linphone::RegistrationState::Cleared: {
|
||||
if (accountManager) {
|
||||
accountManager->deleteLater();
|
||||
accountManager = nullptr;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case linphone::RegistrationState::Cleared:
|
||||
case linphone::RegistrationState::None:
|
||||
case linphone::RegistrationState::Progress:
|
||||
case linphone::RegistrationState::Refreshing:
|
||||
|
|
|
|||
|
|
@ -19,10 +19,17 @@
|
|||
*/
|
||||
|
||||
#include "PhoneNumber.hpp"
|
||||
#include "core/App.hpp"
|
||||
#include "tool/Utils.hpp"
|
||||
#include <QApplication>
|
||||
DEFINE_ABSTRACT_OBJECT(PhoneNumber)
|
||||
|
||||
QSharedPointer<PhoneNumber> PhoneNumber::create(const std::shared_ptr<linphone::DialPlan> &dialPlan) {
|
||||
auto sharedPointer = QSharedPointer<PhoneNumber>(new PhoneNumber(dialPlan), &QObject::deleteLater);
|
||||
sharedPointer->moveToThread(App::getInstance()->thread());
|
||||
return sharedPointer;
|
||||
}
|
||||
|
||||
PhoneNumber::PhoneNumber(const std::shared_ptr<linphone::DialPlan> &dialPlan) : QObject(nullptr) {
|
||||
// Should be call from model Thread
|
||||
mustBeInLinphoneThread(getClassName());
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ class PhoneNumber : public QObject, public AbstractObject {
|
|||
Q_PROPERTY(QString country MEMBER mCountry CONSTANT)
|
||||
|
||||
public:
|
||||
// Should be call from model Thread. Will be automatically in App thread after initialization
|
||||
static QSharedPointer<PhoneNumber> create(const std::shared_ptr<linphone::DialPlan> &dialPlan);
|
||||
PhoneNumber(const std::shared_ptr<linphone::DialPlan> &dialPlan);
|
||||
~PhoneNumber();
|
||||
|
||||
|
|
@ -47,6 +47,7 @@ public:
|
|||
QString mInternationalCallPrefix;
|
||||
QString mCountry;
|
||||
|
||||
private:
|
||||
DECLARE_ABSTRACT_OBJECT
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -28,22 +28,28 @@
|
|||
|
||||
DEFINE_ABSTRACT_OBJECT(PhoneNumberList)
|
||||
|
||||
QSharedPointer<PhoneNumberList> PhoneNumberList::create() {
|
||||
auto model = QSharedPointer<PhoneNumberList>(new PhoneNumberList(), &QObject::deleteLater);
|
||||
model->moveToThread(App::getInstance()->thread());
|
||||
return model;
|
||||
}
|
||||
|
||||
PhoneNumberList::PhoneNumberList(QObject *parent) : ListProxy(parent) {
|
||||
mustBeInMainThread(getClassName());
|
||||
App::postModelAsync([=]() {
|
||||
// Model thread.
|
||||
auto dialPlans = linphone::Factory::get()->getDialPlans();
|
||||
QList<QSharedPointer<PhoneNumber>> numbers;
|
||||
QVector<QVariantMap> results;
|
||||
QList<QSharedPointer<PhoneNumber>> *numbers = new QList<QSharedPointer<PhoneNumber>>();
|
||||
for (auto it : dialPlans) {
|
||||
auto numberModel = QSharedPointer<PhoneNumber>::create(it);
|
||||
numberModel->moveToThread(this->thread());
|
||||
numbers.push_back(numberModel);
|
||||
auto numberModel = PhoneNumber::create(it);
|
||||
numbers->push_back(numberModel);
|
||||
}
|
||||
// Invoke for adding stuffs in caller thread
|
||||
QMetaObject::invokeMethod(this, [this, numbers]() {
|
||||
mustBeInMainThread(this->log().arg(Q_FUNC_INFO));
|
||||
add(numbers);
|
||||
resetData();
|
||||
add(*numbers);
|
||||
delete numbers;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,9 +29,11 @@
|
|||
class PhoneNumberList : public ListProxy, public AbstractObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
static QSharedPointer<PhoneNumberList> create();
|
||||
PhoneNumberList(QObject *parent = Q_NULLPTR);
|
||||
~PhoneNumberList();
|
||||
|
||||
private:
|
||||
DECLARE_ABSTRACT_OBJECT
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -20,13 +20,19 @@
|
|||
|
||||
#include "PhoneNumberProxy.hpp"
|
||||
#include "PhoneNumber.hpp"
|
||||
#include "PhoneNumberList.hpp"
|
||||
|
||||
DEFINE_ABSTRACT_OBJECT(PhoneNumberProxy)
|
||||
|
||||
PhoneNumberProxy::PhoneNumberProxy(QObject *parent) : SortFilterProxy(parent) {
|
||||
setSourceModel(new PhoneNumberList(this));
|
||||
mPhoneNumberList = PhoneNumberList::create();
|
||||
setSourceModel(mPhoneNumberList.get());
|
||||
sort(0);
|
||||
}
|
||||
|
||||
PhoneNumberProxy::~PhoneNumberProxy() {
|
||||
setSourceModel(nullptr);
|
||||
}
|
||||
|
||||
QString PhoneNumberProxy::getFilterText() const {
|
||||
return mFilterText;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,21 +22,24 @@
|
|||
#define PHONE_NUMBER_PROXY_H_
|
||||
|
||||
#include "../proxy/SortFilterProxy.hpp"
|
||||
#include "PhoneNumberList.hpp"
|
||||
#include "tool/AbstractObject.hpp"
|
||||
|
||||
// =============================================================================
|
||||
|
||||
class PhoneNumberProxy : public SortFilterProxy {
|
||||
class PhoneNumberProxy : public SortFilterProxy, public AbstractObject {
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QString filterText READ getFilterText WRITE setFilterText NOTIFY filterTextChanged)
|
||||
|
||||
public:
|
||||
PhoneNumberProxy(QObject *parent = Q_NULLPTR);
|
||||
~PhoneNumberProxy();
|
||||
|
||||
QString getFilterText() const;
|
||||
void setFilterText(const QString &filter);
|
||||
|
||||
Q_INVOKABLE int findIndexByCountryCallingCode(const QString& countryCallingCode);
|
||||
Q_INVOKABLE int findIndexByCountryCallingCode(const QString &countryCallingCode);
|
||||
|
||||
signals:
|
||||
void filterTextChanged();
|
||||
|
|
@ -46,6 +49,10 @@ protected:
|
|||
virtual bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
|
||||
|
||||
QString mFilterText;
|
||||
QSharedPointer<PhoneNumberList> mPhoneNumberList;
|
||||
|
||||
private:
|
||||
DECLARE_ABSTRACT_OBJECT
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
107
Linphone/core/register/RegisterPage.cpp
Normal file
107
Linphone/core/register/RegisterPage.cpp
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2024 Belledonne Communications SARL.
|
||||
*
|
||||
* This file is part of linphone-desktop
|
||||
* (see https://www.linphone.org).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "RegisterPage.hpp"
|
||||
#include <QTimer>
|
||||
|
||||
#include "core/App.hpp"
|
||||
|
||||
#include "model/account/AccountManager.hpp"
|
||||
|
||||
DEFINE_ABSTRACT_OBJECT(RegisterPage)
|
||||
|
||||
RegisterPage::RegisterPage(QObject *parent) : QObject(parent) {
|
||||
mustBeInMainThread(getClassName());
|
||||
}
|
||||
|
||||
RegisterPage::~RegisterPage() {
|
||||
mustBeInMainThread("~" + getClassName());
|
||||
}
|
||||
|
||||
void RegisterPage::registerNewAccount(const QString &username,
|
||||
const QString &password,
|
||||
const QString &email,
|
||||
const QString &phoneNumber) {
|
||||
App::postModelAsync([=]() {
|
||||
// Create on Model thread.
|
||||
// registrationFailed(error); });
|
||||
AccountManager::RegisterType registerType;
|
||||
QString address;
|
||||
if (email.isEmpty()) {
|
||||
registerType = AccountManager::RegisterType::PhoneNumber;
|
||||
address = phoneNumber;
|
||||
} else {
|
||||
registerType = AccountManager::RegisterType::Email;
|
||||
address = email;
|
||||
}
|
||||
auto accountManager = new AccountManager();
|
||||
connect(accountManager, &AccountManager::newAccountCreationSucceed, this,
|
||||
[this, registerType, address, accountManager](const QString &sipAddress) mutable {
|
||||
App::postCoreAsync([this, registerType, address, sipAddress, accountManager]() {
|
||||
emit newAccountCreationSucceed(registerType == AccountManager::RegisterType::Email, address,
|
||||
sipAddress);
|
||||
});
|
||||
if (accountManager) {
|
||||
accountManager->deleteLater();
|
||||
accountManager = nullptr;
|
||||
}
|
||||
});
|
||||
connect(accountManager, &AccountManager::registerNewAccountFailed, this,
|
||||
[this, accountManager](const QString &errorMessage) mutable {
|
||||
App::postCoreAsync(
|
||||
[this, errorMessage, accountManager]() { emit registerNewAccountFailed(errorMessage); });
|
||||
if (accountManager) {
|
||||
accountManager->deleteLater();
|
||||
accountManager = nullptr;
|
||||
}
|
||||
});
|
||||
connect(accountManager, &AccountManager::errorInField, this,
|
||||
[this, accountManager](const QString &field, const QString &errorMessage) mutable {
|
||||
App::postCoreAsync([this, field, errorMessage]() { emit errorInField(field, errorMessage); });
|
||||
if (accountManager) {
|
||||
accountManager->deleteLater();
|
||||
accountManager = nullptr;
|
||||
}
|
||||
});
|
||||
connect(accountManager, &AccountManager::tokenConversionSucceed, this,
|
||||
[this, accountManager]() { App::postCoreAsync([this]() { emit tokenConversionSucceed(); }); });
|
||||
accountManager->registerNewAccount(username, password, registerType, address);
|
||||
});
|
||||
}
|
||||
|
||||
void RegisterPage::linkNewAccountUsingCode(const QString &code,
|
||||
bool registerWithEmail,
|
||||
const QString &sipIdentityAddress) {
|
||||
App::postModelAsync([=]() {
|
||||
auto accountManager = new AccountManager();
|
||||
connect(accountManager, &AccountManager::linkingNewAccountWithCodeSucceed, this, [this, accountManager]() {
|
||||
App::postCoreAsync([this]() { emit linkingNewAccountWithCodeSucceed(); });
|
||||
accountManager->deleteLater();
|
||||
});
|
||||
connect(accountManager, &AccountManager::linkingNewAccountWithCodeFailed, this,
|
||||
[this, accountManager](const QString &errorMessage) {
|
||||
App::postCoreAsync([this, errorMessage]() { emit linkingNewAccountWithCodeFailed(errorMessage); });
|
||||
accountManager->deleteLater();
|
||||
});
|
||||
accountManager->linkNewAccountUsingCode(
|
||||
code, registerWithEmail ? AccountManager::RegisterType::Email : AccountManager::RegisterType::PhoneNumber,
|
||||
sipIdentityAddress);
|
||||
});
|
||||
}
|
||||
68
Linphone/core/register/RegisterPage.hpp
Normal file
68
Linphone/core/register/RegisterPage.hpp
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2024 Belledonne Communications SARL.
|
||||
*
|
||||
* This file is part of linphone-desktop
|
||||
* (see https://www.linphone.org).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef REGISTERPAGE_H_
|
||||
#define REGISTERPAGE_H_
|
||||
|
||||
#include "tool/AbstractObject.hpp"
|
||||
#include "tool/thread/SafeConnection.hpp"
|
||||
#include <QObject>
|
||||
#include <linphone++/linphone.hh>
|
||||
|
||||
class AccountManager;
|
||||
class RegisterPage : public QObject, public AbstractObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
RegisterPage(QObject *parent = nullptr);
|
||||
~RegisterPage();
|
||||
|
||||
// Q_PROPERTY(linphone::RegistrationState registrationState READ getRegistrationState NOTIFY
|
||||
// registrationStateChanged) Q_PROPERTY(QString errorMessage READ getErrorMessage NOTIFY errorMessageChanged)
|
||||
|
||||
Q_INVOKABLE void registerNewAccount(const QString &username,
|
||||
const QString &password,
|
||||
const QString &email,
|
||||
const QString &phoneNumber);
|
||||
Q_INVOKABLE void
|
||||
linkNewAccountUsingCode(const QString &code, bool registerWithEmail, const QString &sipIdentityAddress);
|
||||
|
||||
signals:
|
||||
void registrationFailed(const QString &errorMessage);
|
||||
void errorMessageChanged();
|
||||
void newAccountCreationSucceed(bool withEmail, // false if creation with phone number
|
||||
const QString &address,
|
||||
const QString &sipIdentityAddress);
|
||||
void registerNewAccountFailed(const QString &error);
|
||||
void errorInField(const QString &field, const QString &error);
|
||||
void tokenConversionSucceed();
|
||||
void linkingNewAccountWithCodeSucceed();
|
||||
void linkingNewAccountWithCodeFailed(const QString &error);
|
||||
|
||||
private:
|
||||
linphone::RegistrationState mRegistrationState = linphone::RegistrationState::None;
|
||||
QSharedPointer<SafeConnection<RegisterPage, AccountManager>> mAccountManagerConnection;
|
||||
std::shared_ptr<AccountManager> mAccountManager;
|
||||
QString mErrorMessage;
|
||||
|
||||
DECLARE_ABSTRACT_OBJECT
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -3,6 +3,7 @@ backend=1
|
|||
# 1 means FlexiAPI, 0 is XMLRPC
|
||||
url=https://subscribe.linphone.org/api/
|
||||
# replace above URL by https://staging-subscribe.linphone.org/api/ for testing
|
||||
# url=https://flexisip-staging-master.linphone.org/api/
|
||||
|
||||
[alerts]
|
||||
alerts_enabled=1
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
list(APPEND _LINPHONEAPP_SOURCES
|
||||
model/account/AccountModel.cpp
|
||||
model/account/AccountManager.cpp
|
||||
model/account/AccountManagerServicesModel.cpp
|
||||
model/account/AccountManagerServicesRequestModel.cpp
|
||||
|
||||
model/call/CallModel.cpp
|
||||
|
||||
|
|
|
|||
|
|
@ -21,10 +21,16 @@
|
|||
#include "AccountManager.hpp"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QDesktopServices>
|
||||
#include <QEventLoop>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkReply>
|
||||
#include <QTemporaryFile>
|
||||
#include <QUrl>
|
||||
|
||||
#include "core/path/Paths.hpp"
|
||||
#include "model/core/CoreModel.hpp"
|
||||
#include "model/tool/ToolModel.hpp"
|
||||
#include "tool/Utils.hpp"
|
||||
|
||||
DEFINE_ABSTRACT_OBJECT(AccountManager)
|
||||
|
|
@ -93,6 +99,172 @@ bool AccountManager::login(QString username, QString password, QString *errorMes
|
|||
return true;
|
||||
}
|
||||
|
||||
void AccountManager::registerNewAccount(const QString &username,
|
||||
const QString &password,
|
||||
RegisterType type,
|
||||
const QString ®isterAddress) {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
if (!mAccountManagerServicesModel) {
|
||||
auto core = CoreModel::getInstance()->getCore();
|
||||
auto ams = core->createAccountManagerServices();
|
||||
mAccountManagerServicesModel = Utils::makeQObject_ptr<AccountManagerServicesModel>(ams);
|
||||
}
|
||||
connect(
|
||||
mAccountManagerServicesModel.get(), &AccountManagerServicesModel::requestSuccessfull, this,
|
||||
[this, username, password, type, registerAddress](
|
||||
const std::shared_ptr<const linphone::AccountManagerServicesRequest> &request, const std::string &data) {
|
||||
if (request->getType() == linphone::AccountManagerServicesRequest::Type::AccountCreationRequestToken) {
|
||||
QString verifyTokenUrl = Utils::coreStringToAppString(data);
|
||||
qDebug() << "[AccountManager] request token succeed" << verifyTokenUrl;
|
||||
|
||||
QDesktopServices::openUrl(verifyTokenUrl);
|
||||
auto creationToken = verifyTokenUrl.mid(verifyTokenUrl.lastIndexOf("/") + 1);
|
||||
|
||||
// QNetworkRequest req;
|
||||
timer.setSingleShot(true);
|
||||
timer.setInterval(2000);
|
||||
QObject::connect(&timer, &QTimer::timeout, this, [this, creationToken]() {
|
||||
mAccountManagerServicesModel->convertCreationRequestTokenIntoCreationToken(
|
||||
Utils::appStringToCoreString(creationToken));
|
||||
});
|
||||
timer.start();
|
||||
// req.setUrl(QUrl(verifyTokenUrl));
|
||||
|
||||
} else if (request->getType() == linphone::AccountManagerServicesRequest::Type::
|
||||
AccountCreationTokenFromAccountCreationRequestToken) {
|
||||
qDebug() << "[AccountManager] request token conversion succeed" << data;
|
||||
emit tokenConversionSucceed();
|
||||
timer.stop();
|
||||
mAccountManagerServicesModel->createAccountUsingToken(Utils::appStringToCoreString(username),
|
||||
Utils::appStringToCoreString(password), data);
|
||||
|
||||
} else if (request->getType() == linphone::AccountManagerServicesRequest::Type::CreateAccountUsingToken) {
|
||||
auto core = CoreModel::getInstance()->getCore();
|
||||
auto factory = linphone::Factory::get();
|
||||
mCreatedSipAddress = Utils::coreStringToAppString(data);
|
||||
auto createdSipIdentityAddress = ToolModel::interpretUrl(mCreatedSipAddress);
|
||||
core->addAuthInfo(factory->createAuthInfo(Utils::appStringToCoreString(username), // Username.
|
||||
"", // User ID.
|
||||
Utils::appStringToCoreString(password), // Password.
|
||||
"", // HA1.
|
||||
"", // Realm.
|
||||
createdSipIdentityAddress->getDomain() // Domain.
|
||||
));
|
||||
if (type == RegisterType::Email) {
|
||||
qDebug() << "[AccountManager] creation succeed, email verification" << registerAddress;
|
||||
mAccountManagerServicesModel->linkEmailByEmail(
|
||||
ToolModel::interpretUrl(Utils::coreStringToAppString(data)),
|
||||
Utils::appStringToCoreString(registerAddress));
|
||||
} else {
|
||||
qDebug() << "[AccountManager] creation succeed, sms verification" << registerAddress;
|
||||
mAccountManagerServicesModel->linkPhoneNumberBySms(
|
||||
ToolModel::interpretUrl(Utils::coreStringToAppString(data)),
|
||||
Utils::appStringToCoreString(registerAddress));
|
||||
}
|
||||
} else if (request->getType() ==
|
||||
linphone::AccountManagerServicesRequest::Type::SendEmailLinkingCodeByEmail) {
|
||||
qDebug() << "[AccountManager] send email succeed, link account using code";
|
||||
emit newAccountCreationSucceed(mCreatedSipAddress, type, registerAddress);
|
||||
mCreatedSipAddress.clear();
|
||||
} else if (request->getType() ==
|
||||
linphone::AccountManagerServicesRequest::Type::SendPhoneNumberLinkingCodeBySms) {
|
||||
qDebug() << "[AccountManager] send phone number succeed, link account using code";
|
||||
emit newAccountCreationSucceed(mCreatedSipAddress, type, registerAddress);
|
||||
mCreatedSipAddress.clear();
|
||||
}
|
||||
});
|
||||
connect(
|
||||
mAccountManagerServicesModel.get(), &AccountManagerServicesModel::requestError, this,
|
||||
[this](const std::shared_ptr<const linphone::AccountManagerServicesRequest> &request, int statusCode,
|
||||
const std::string &errorMessage, const std::shared_ptr<const linphone::Dictionary> ¶meterErrors) {
|
||||
if (request->getType() == linphone::AccountManagerServicesRequest::Type::AccountCreationRequestToken) {
|
||||
qDebug() << "[AccountManager] error creating request token :" << errorMessage;
|
||||
emit registerNewAccountFailed(Utils::coreStringToAppString(errorMessage));
|
||||
} else if (request->getType() == linphone::AccountManagerServicesRequest::Type::
|
||||
AccountCreationTokenFromAccountCreationRequestToken) {
|
||||
qDebug() << "[AccountManager] error converting token into creation token :" << errorMessage;
|
||||
if (parameterErrors) {
|
||||
timer.stop();
|
||||
emit registerNewAccountFailed(Utils::coreStringToAppString(errorMessage));
|
||||
} else {
|
||||
timer.start();
|
||||
}
|
||||
} else if (request->getType() == linphone::AccountManagerServicesRequest::Type::CreateAccountUsingToken) {
|
||||
qDebug() << "[AccountManager] error creating account :" << errorMessage;
|
||||
if (parameterErrors) {
|
||||
for (const std::string &key : parameterErrors->getKeys()) {
|
||||
emit errorInField(Utils::coreStringToAppString(key),
|
||||
Utils::coreStringToAppString(errorMessage));
|
||||
}
|
||||
} else {
|
||||
emit registerNewAccountFailed(Utils::coreStringToAppString(errorMessage));
|
||||
}
|
||||
} else if (request->getType() ==
|
||||
linphone::AccountManagerServicesRequest::Type::SendEmailLinkingCodeByEmail) {
|
||||
qDebug() << "[AccountManager] error sending code to email" << errorMessage;
|
||||
if (parameterErrors) {
|
||||
for (const std::string &key : parameterErrors->getKeys()) {
|
||||
emit errorInField(Utils::coreStringToAppString(key),
|
||||
Utils::coreStringToAppString(errorMessage));
|
||||
}
|
||||
} else {
|
||||
emit registerNewAccountFailed(Utils::coreStringToAppString(errorMessage));
|
||||
}
|
||||
} else if (request->getType() ==
|
||||
linphone::AccountManagerServicesRequest::Type::SendPhoneNumberLinkingCodeBySms) {
|
||||
qDebug() << "[AccountManager] error sending code to phone number" << errorMessage;
|
||||
if (parameterErrors) {
|
||||
for (const std::string &key : parameterErrors->getKeys()) {
|
||||
emit errorInField(Utils::coreStringToAppString(key),
|
||||
Utils::coreStringToAppString(errorMessage));
|
||||
}
|
||||
} else {
|
||||
emit registerNewAccountFailed(Utils::coreStringToAppString(errorMessage));
|
||||
}
|
||||
}
|
||||
});
|
||||
mAccountManagerServicesModel->requestToken();
|
||||
}
|
||||
|
||||
void AccountManager::linkNewAccountUsingCode(const QString &code,
|
||||
RegisterType registerType,
|
||||
const QString &sipAddress) {
|
||||
auto sipIdentityAddress = ToolModel::interpretUrl(sipAddress);
|
||||
if (!mAccountManagerServicesModel) {
|
||||
auto core = CoreModel::getInstance()->getCore();
|
||||
auto ams = core->createAccountManagerServices();
|
||||
mAccountManagerServicesModel = Utils::makeQObject_ptr<AccountManagerServicesModel>(ams);
|
||||
}
|
||||
connect(
|
||||
mAccountManagerServicesModel.get(), &AccountManagerServicesModel::requestSuccessfull, this,
|
||||
[this](const std::shared_ptr<const linphone::AccountManagerServicesRequest> &request, const std::string &data) {
|
||||
if (request->getType() == linphone::AccountManagerServicesRequest::Type::LinkEmailUsingCode) {
|
||||
qDebug() << "[AccountManager] link email to account succeed" << data;
|
||||
emit linkingNewAccountWithCodeSucceed();
|
||||
} else if (request->getType() == linphone::AccountManagerServicesRequest::Type::LinkPhoneNumberUsingCode) {
|
||||
qDebug() << "[AccountManager] link phone number to account succeed" << data;
|
||||
emit linkingNewAccountWithCodeSucceed();
|
||||
}
|
||||
});
|
||||
connect(
|
||||
mAccountManagerServicesModel.get(), &AccountManagerServicesModel::requestError, this,
|
||||
[this](const std::shared_ptr<const linphone::AccountManagerServicesRequest> &request, int statusCode,
|
||||
const std::string &errorMessage, const std::shared_ptr<const linphone::Dictionary> ¶meterErrors) {
|
||||
if (request->getType() == linphone::AccountManagerServicesRequest::Type::LinkEmailUsingCode) {
|
||||
qDebug() << "[AccountManager] error linking email to account" << errorMessage;
|
||||
} else if (request->getType() == linphone::AccountManagerServicesRequest::Type::LinkPhoneNumberUsingCode) {
|
||||
qDebug() << "[AccountManager] error linking phone number to account" << errorMessage;
|
||||
}
|
||||
emit linkingNewAccountWithCodeFailed(Utils::coreStringToAppString(errorMessage));
|
||||
});
|
||||
if (registerType == RegisterType::Email)
|
||||
mAccountManagerServicesModel->linkEmailToAccountUsingCode(sipIdentityAddress,
|
||||
Utils::appStringToCoreString(code));
|
||||
else
|
||||
mAccountManagerServicesModel->linkPhoneNumberToAccountUsingCode(sipIdentityAddress,
|
||||
Utils::appStringToCoreString(code));
|
||||
}
|
||||
|
||||
void AccountManager::onRegistrationStateChanged(const std::shared_ptr<linphone::Account> &account,
|
||||
linphone::RegistrationState state,
|
||||
const std::string &message) {
|
||||
|
|
@ -112,4 +284,4 @@ void AccountManager::onRegistrationStateChanged(const std::shared_ptr<linphone::
|
|||
}
|
||||
}
|
||||
emit registrationStateChanged(state);
|
||||
}
|
||||
}
|
||||
|
|
@ -22,8 +22,11 @@
|
|||
#define ACCOUNT_MANAGER_H_
|
||||
|
||||
#include <QObject>
|
||||
#include <QTimer>
|
||||
#include <linphone++/linphone.hh>
|
||||
|
||||
#include "AccountManagerServicesModel.hpp"
|
||||
#include "AccountManagerServicesRequestModel.hpp"
|
||||
#include "AccountModel.hpp"
|
||||
#include "tool/AbstractObject.hpp"
|
||||
|
||||
|
|
@ -34,18 +37,36 @@ public:
|
|||
~AccountManager();
|
||||
|
||||
bool login(QString username, QString password, QString *errorMessage = nullptr);
|
||||
|
||||
std::shared_ptr<linphone::Account> createAccount(const QString &assistantFile);
|
||||
|
||||
enum RegisterType { PhoneNumber = 0, Email = 1 };
|
||||
void registerNewAccount(const QString &username,
|
||||
const QString &password,
|
||||
RegisterType type,
|
||||
const QString ®isterAddress);
|
||||
|
||||
void linkNewAccountUsingCode(const QString &code, RegisterType registerType, const QString &sipAddress);
|
||||
|
||||
void onRegistrationStateChanged(const std::shared_ptr<linphone::Account> &account,
|
||||
linphone::RegistrationState state,
|
||||
const std::string &message);
|
||||
|
||||
signals:
|
||||
void registrationStateChanged(linphone::RegistrationState state);
|
||||
void errorMessageChanged(const QString &errorMessage);
|
||||
void newAccountCreationSucceed(QString sipAddress, RegisterType registerType, const QString ®isterAddress);
|
||||
void registerNewAccountFailed(const QString &error);
|
||||
void tokenConversionSucceed();
|
||||
void errorInField(const QString &field, const QString &error);
|
||||
void linkingNewAccountWithCodeSucceed();
|
||||
void linkingNewAccountWithCodeFailed(const QString &error);
|
||||
|
||||
private:
|
||||
std::shared_ptr<AccountModel> mAccountModel;
|
||||
std::shared_ptr<AccountManagerServicesModel> mAccountManagerServicesModel;
|
||||
QTimer timer;
|
||||
QString mCreatedSipAddress;
|
||||
// std::shared_ptr<linphone::Address> mCreatedSipIdentityAddress;
|
||||
DECLARE_ABSTRACT_OBJECT
|
||||
};
|
||||
|
||||
|
|
|
|||
101
Linphone/model/account/AccountManagerServicesModel.cpp
Normal file
101
Linphone/model/account/AccountManagerServicesModel.cpp
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2024 Belledonne Communications SARL.
|
||||
*
|
||||
* This file is part of linphone-desktop
|
||||
* (see https://www.linphone.org).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "AccountManagerServicesModel.hpp"
|
||||
|
||||
#include "core/path/Paths.hpp"
|
||||
#include "model/core/CoreModel.hpp"
|
||||
#include "tool/Utils.hpp"
|
||||
#include "tool/providers/AvatarProvider.hpp"
|
||||
#include <QDebug>
|
||||
#include <QUrl>
|
||||
|
||||
DEFINE_ABSTRACT_OBJECT(AccountManagerServicesModel)
|
||||
|
||||
AccountManagerServicesModel::AccountManagerServicesModel(
|
||||
const std::shared_ptr<linphone::AccountManagerServices> &accountManagerServices, QObject *parent)
|
||||
: mAccountManagerServices(accountManagerServices) {
|
||||
mustBeInLinphoneThread(getClassName());
|
||||
}
|
||||
|
||||
AccountManagerServicesModel::~AccountManagerServicesModel() {
|
||||
mustBeInLinphoneThread("~" + getClassName());
|
||||
}
|
||||
|
||||
void AccountManagerServicesModel::setRequestAndSubmit(
|
||||
const std::shared_ptr<linphone::AccountManagerServicesRequest> &request) {
|
||||
if (mRequest) {
|
||||
disconnect(mRequest.get(), &AccountManagerServicesRequestModel::requestSuccessfull, this, nullptr);
|
||||
disconnect(mRequest.get(), &AccountManagerServicesRequestModel::requestError, this, nullptr);
|
||||
disconnect(mRequest.get(), &AccountManagerServicesRequestModel::devicesListFetched, this, nullptr);
|
||||
mRequest = nullptr;
|
||||
}
|
||||
mRequest = Utils::makeQObject_ptr<AccountManagerServicesRequestModel>(request);
|
||||
mRequest->setSelf(mRequest);
|
||||
connect(mRequest.get(), &AccountManagerServicesRequestModel::requestSuccessfull, this,
|
||||
&AccountManagerServicesModel::requestSuccessfull);
|
||||
connect(mRequest.get(), &AccountManagerServicesRequestModel::requestError, this,
|
||||
&AccountManagerServicesModel::requestError);
|
||||
connect(mRequest.get(), &AccountManagerServicesRequestModel::devicesListFetched, this,
|
||||
&AccountManagerServicesModel::devicesListFetched);
|
||||
mRequest->submit();
|
||||
}
|
||||
|
||||
void AccountManagerServicesModel::requestToken() {
|
||||
auto req = mAccountManagerServices->createGetAccountCreationRequestTokenRequest();
|
||||
setRequestAndSubmit(req);
|
||||
}
|
||||
|
||||
void AccountManagerServicesModel::convertCreationRequestTokenIntoCreationToken(const std::string &token) {
|
||||
auto req = mAccountManagerServices->createGetAccountCreationTokenFromRequestTokenRequest(token);
|
||||
setRequestAndSubmit(req);
|
||||
}
|
||||
|
||||
void AccountManagerServicesModel::createAccountUsingToken(const std::string &username,
|
||||
const std::string &password,
|
||||
const std::string &token,
|
||||
const std::string &algorithm) {
|
||||
auto req = mAccountManagerServices->createNewAccountUsingTokenRequest(username, password, algorithm, token);
|
||||
setRequestAndSubmit(req);
|
||||
}
|
||||
|
||||
void AccountManagerServicesModel::linkPhoneNumberBySms(const std::shared_ptr<linphone::Address> &sipIdentityAddress,
|
||||
const std::string &phoneNumber) {
|
||||
auto req = mAccountManagerServices->createSendPhoneNumberLinkingCodeBySmsRequest(sipIdentityAddress, phoneNumber);
|
||||
setRequestAndSubmit(req);
|
||||
}
|
||||
|
||||
void AccountManagerServicesModel::linkEmailByEmail(const std::shared_ptr<linphone::Address> &sipIdentityAddress,
|
||||
const std::string &emailAddress) {
|
||||
auto req = mAccountManagerServices->createSendEmailLinkingCodeByEmailRequest(sipIdentityAddress, emailAddress);
|
||||
setRequestAndSubmit(req);
|
||||
}
|
||||
|
||||
void AccountManagerServicesModel::linkPhoneNumberToAccountUsingCode(
|
||||
const std::shared_ptr<linphone::Address> &sipIdentityAddress, const std::string &code) {
|
||||
auto req = mAccountManagerServices->createLinkPhoneNumberToAccountUsingCodeRequest(sipIdentityAddress, code);
|
||||
setRequestAndSubmit(req);
|
||||
}
|
||||
|
||||
void AccountManagerServicesModel::linkEmailToAccountUsingCode(
|
||||
const std::shared_ptr<linphone::Address> &sipIdentityAddress, const std::string &code) {
|
||||
auto req = mAccountManagerServices->createLinkEmailToAccountUsingCodeRequest(sipIdentityAddress, code);
|
||||
setRequestAndSubmit(req);
|
||||
}
|
||||
72
Linphone/model/account/AccountManagerServicesModel.hpp
Normal file
72
Linphone/model/account/AccountManagerServicesModel.hpp
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2024 Belledonne Communications SARL.
|
||||
*
|
||||
* This file is part of linphone-desktop
|
||||
* (see https://www.linphone.org).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef ACCOUNT_MANAGER_SERVICES_MODEL_H_
|
||||
#define ACCOUNT_MANAGER_SERVICES_MODEL_H_
|
||||
|
||||
#include "AccountManagerServicesRequestModel.hpp"
|
||||
#include "model/listener/Listener.hpp"
|
||||
#include "tool/AbstractObject.hpp"
|
||||
|
||||
#include <QObject>
|
||||
#include <linphone++/linphone.hh>
|
||||
|
||||
class AccountManagerServicesModel : public QObject, public AbstractObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
AccountManagerServicesModel(const std::shared_ptr<linphone::AccountManagerServices> &accountManagerServices,
|
||||
QObject *parent = nullptr);
|
||||
~AccountManagerServicesModel();
|
||||
|
||||
void requestToken();
|
||||
void convertCreationRequestTokenIntoCreationToken(const std::string &token);
|
||||
void createAccountUsingToken(const std::string &username,
|
||||
const std::string &password,
|
||||
const std::string &token,
|
||||
const std::string &algorithm = "SHA-256");
|
||||
void linkPhoneNumberBySms(const std::shared_ptr<linphone::Address> &sipIdentityAddress,
|
||||
const std::string &phoneNumber);
|
||||
void linkEmailByEmail(const std::shared_ptr<linphone::Address> &sipIdentityAddress,
|
||||
const std::string &emailAddress);
|
||||
|
||||
void linkPhoneNumberToAccountUsingCode(const std::shared_ptr<linphone::Address> &sipIdentityAddress,
|
||||
const std::string &code);
|
||||
void linkEmailToAccountUsingCode(const std::shared_ptr<linphone::Address> &sipIdentityAddress,
|
||||
const std::string &code);
|
||||
|
||||
void setRequestAndSubmit(const std::shared_ptr<linphone::AccountManagerServicesRequest> &request);
|
||||
|
||||
signals:
|
||||
void requestSuccessfull(const std::shared_ptr<const linphone::AccountManagerServicesRequest> &request,
|
||||
const std::string &data);
|
||||
void requestError(const std::shared_ptr<const linphone::AccountManagerServicesRequest> &request,
|
||||
int statusCode,
|
||||
const std::string &errorMessage,
|
||||
const std::shared_ptr<const linphone::Dictionary> ¶meterErrors);
|
||||
void devicesListFetched(const std::shared_ptr<const linphone::AccountManagerServicesRequest> &request,
|
||||
const std::list<std::shared_ptr<linphone::AccountDevice>> &devicesList);
|
||||
|
||||
private:
|
||||
DECLARE_ABSTRACT_OBJECT
|
||||
std::shared_ptr<linphone::AccountManagerServices> mAccountManagerServices;
|
||||
std::shared_ptr<AccountManagerServicesRequestModel> mRequest;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2024 Belledonne Communications SARL.
|
||||
*
|
||||
* This file is part of linphone-desktop
|
||||
* (see https://www.linphone.org).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "AccountManagerServicesRequestModel.hpp"
|
||||
|
||||
#include "core/path/Paths.hpp"
|
||||
#include "model/core/CoreModel.hpp"
|
||||
#include "tool/Utils.hpp"
|
||||
#include "tool/providers/AvatarProvider.hpp"
|
||||
#include <QDebug>
|
||||
#include <QUrl>
|
||||
|
||||
DEFINE_ABSTRACT_OBJECT(AccountManagerServicesRequestModel)
|
||||
|
||||
AccountManagerServicesRequestModel::AccountManagerServicesRequestModel(
|
||||
const std::shared_ptr<linphone::AccountManagerServicesRequest> &accountManagerServicesRequest, QObject *parent)
|
||||
: ::Listener<linphone::AccountManagerServicesRequest, linphone::AccountManagerServicesRequestListener>(
|
||||
accountManagerServicesRequest, parent) {
|
||||
mustBeInLinphoneThread(getClassName());
|
||||
}
|
||||
|
||||
AccountManagerServicesRequestModel::~AccountManagerServicesRequestModel() {
|
||||
mustBeInLinphoneThread("~" + getClassName());
|
||||
}
|
||||
|
||||
void AccountManagerServicesRequestModel::submit() {
|
||||
mMonitor->submit();
|
||||
}
|
||||
|
||||
linphone::AccountManagerServicesRequest::Type AccountManagerServicesRequestModel::getType() const {
|
||||
return mMonitor->getType();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
// LINPHONE
|
||||
//--------------------------------------------------------------------------------
|
||||
|
||||
void AccountManagerServicesRequestModel::onRequestSuccessful(
|
||||
const std::shared_ptr<const linphone::AccountManagerServicesRequest> &request, const std::string &data) {
|
||||
emit requestSuccessfull(request, data);
|
||||
}
|
||||
|
||||
void AccountManagerServicesRequestModel::onRequestError(
|
||||
const std::shared_ptr<const linphone::AccountManagerServicesRequest> &request,
|
||||
int statusCode,
|
||||
const std::string &errorMessage,
|
||||
const std::shared_ptr<const linphone::Dictionary> ¶meterErrors) {
|
||||
emit requestError(request, statusCode, errorMessage, parameterErrors);
|
||||
}
|
||||
|
||||
void AccountManagerServicesRequestModel::onDevicesListFetched(
|
||||
const std::shared_ptr<const linphone::AccountManagerServicesRequest> &request,
|
||||
const std::list<std::shared_ptr<linphone::AccountDevice>> &devicesList) {
|
||||
emit devicesListFetched(request, devicesList);
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* Copyright (c) 2010-2024 Belledonne Communications SARL.
|
||||
*
|
||||
* This file is part of linphone-desktop
|
||||
* (see https://www.linphone.org).
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef ACCOUNT_MANAGER_SERVICES_REQUEST_MODEL_H_
|
||||
#define ACCOUNT_MANAGER_SERVICES_REQUEST_MODEL_H_
|
||||
|
||||
#include "model/listener/Listener.hpp"
|
||||
#include "tool/AbstractObject.hpp"
|
||||
|
||||
#include <QObject>
|
||||
#include <linphone++/linphone.hh>
|
||||
|
||||
class AccountManagerServicesRequestModel
|
||||
: public ::Listener<linphone::AccountManagerServicesRequest, linphone::AccountManagerServicesRequestListener>,
|
||||
public linphone::AccountManagerServicesRequestListener,
|
||||
public AbstractObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
AccountManagerServicesRequestModel(
|
||||
const std::shared_ptr<linphone::AccountManagerServicesRequest> &accountManagerServicesRequest,
|
||||
QObject *parent = nullptr);
|
||||
~AccountManagerServicesRequestModel();
|
||||
|
||||
void submit();
|
||||
linphone::AccountManagerServicesRequest::Type getType() const;
|
||||
|
||||
signals:
|
||||
void requestSuccessfull(const std::shared_ptr<const linphone::AccountManagerServicesRequest> &request,
|
||||
const std::string &data);
|
||||
void requestError(const std::shared_ptr<const linphone::AccountManagerServicesRequest> &request,
|
||||
int statusCode,
|
||||
const std::string &errorMessage,
|
||||
const std::shared_ptr<const linphone::Dictionary> ¶meterErrors);
|
||||
void devicesListFetched(const std::shared_ptr<const linphone::AccountManagerServicesRequest> &request,
|
||||
const std::list<std::shared_ptr<linphone::AccountDevice>> &devicesList);
|
||||
|
||||
private:
|
||||
DECLARE_ABSTRACT_OBJECT
|
||||
|
||||
//--------------------------------------------------------------------------------
|
||||
// LINPHONE
|
||||
//--------------------------------------------------------------------------------
|
||||
virtual void onRequestSuccessful(const std::shared_ptr<const linphone::AccountManagerServicesRequest> &request,
|
||||
const std::string &data) override;
|
||||
virtual void onRequestError(const std::shared_ptr<const linphone::AccountManagerServicesRequest> &request,
|
||||
int statusCode,
|
||||
const std::string &errorMessage,
|
||||
const std::shared_ptr<const linphone::Dictionary> ¶meterErrors) override;
|
||||
virtual void onDevicesListFetched(const std::shared_ptr<const linphone::AccountManagerServicesRequest> &request,
|
||||
const std::list<std::shared_ptr<linphone::AccountDevice>> &devicesList) override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -28,6 +28,7 @@
|
|||
#include <QTimer>
|
||||
#include <linphone++/linphone.hh>
|
||||
|
||||
#include "model/account/AccountManager.hpp"
|
||||
#include "model/cli/CliModel.hpp"
|
||||
#include "model/listener/Listener.hpp"
|
||||
#include "model/logger/LoggerModel.hpp"
|
||||
|
|
|
|||
|
|
@ -28,9 +28,9 @@
|
|||
|
||||
#include "LoggerListener.hpp"
|
||||
#include "LoggerModel.hpp"
|
||||
#include "model/setting/SettingsModel.hpp"
|
||||
#include "tool/Constants.hpp"
|
||||
#include "tool/Utils.hpp"
|
||||
#include "model/setting/SettingsModel.hpp"
|
||||
|
||||
#include "core/logger/QtLogger.hpp"
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
@ -127,7 +127,9 @@ void LoggerModel::applyConfig(const std::shared_ptr<linphone::Config> &config) {
|
|||
const QString folder = SettingsModel::getLogsFolder(config);
|
||||
linphone::Core::setLogCollectionPath(Utils::appStringToCoreString(folder));
|
||||
enableFullLogs(SettingsModel::getFullLogsEnabled(config));
|
||||
enable(SettingsModel::getLogsEnabled(config));
|
||||
// TODO : uncomment when it is possible to change the config from settings
|
||||
// enable(SettingsModel::getLogsEnabled(config));
|
||||
enable(true);
|
||||
}
|
||||
|
||||
void LoggerModel::init() {
|
||||
|
|
|
|||
|
|
@ -19,11 +19,10 @@
|
|||
*/
|
||||
|
||||
#include "SettingsModel.hpp"
|
||||
#include "model/core/CoreModel.hpp"
|
||||
#include "tool/Utils.hpp"
|
||||
#include "model/tool/ToolModel.hpp"
|
||||
#include "core/path/Paths.hpp"
|
||||
|
||||
#include "model/core/CoreModel.hpp"
|
||||
#include "model/tool/ToolModel.hpp"
|
||||
#include "tool/Utils.hpp"
|
||||
|
||||
// =============================================================================
|
||||
|
||||
|
|
@ -63,18 +62,14 @@ QStringList SettingsModel::getVideoDevices() const {
|
|||
return result;
|
||||
}
|
||||
|
||||
QString SettingsModel::getVideoDevice () const {
|
||||
QString SettingsModel::getVideoDevice() const {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
return Utils::coreStringToAppString(
|
||||
CoreModel::getInstance()->getCore()->getVideoDevice()
|
||||
);
|
||||
return Utils::coreStringToAppString(CoreModel::getInstance()->getCore()->getVideoDevice());
|
||||
}
|
||||
|
||||
void SettingsModel::setVideoDevice (const QString &device) {
|
||||
void SettingsModel::setVideoDevice(const QString &device) {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
CoreModel::getInstance()->getCore()->setVideoDevice(
|
||||
Utils::appStringToCoreString(device)
|
||||
);
|
||||
CoreModel::getInstance()->getCore()->setVideoDevice(Utils::appStringToCoreString(device));
|
||||
emit videoDeviceChanged(device);
|
||||
}
|
||||
|
||||
|
|
@ -94,8 +89,8 @@ void SettingsModel::resetCaptureGraph() {
|
|||
}
|
||||
void SettingsModel::createCaptureGraph() {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
mSimpleCaptureGraph =
|
||||
new MediastreamerUtils::SimpleCaptureGraph(Utils::appStringToCoreString(getCaptureDevice()), Utils::appStringToCoreString(getPlaybackDevice()));
|
||||
mSimpleCaptureGraph = new MediastreamerUtils::SimpleCaptureGraph(Utils::appStringToCoreString(getCaptureDevice()),
|
||||
Utils::appStringToCoreString(getPlaybackDevice()));
|
||||
mSimpleCaptureGraph->start();
|
||||
emit captureGraphRunningChanged(getCaptureGraphRunning());
|
||||
}
|
||||
|
|
@ -135,7 +130,7 @@ void SettingsModel::deleteCaptureGraph() {
|
|||
mSimpleCaptureGraph = nullptr;
|
||||
}
|
||||
}
|
||||
//Force a call on the 'detect' method of all audio filters, updating new or removed devices
|
||||
// Force a call on the 'detect' method of all audio filters, updating new or removed devices
|
||||
void SettingsModel::accessCallSettings() {
|
||||
// Audio
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
|
|
@ -148,7 +143,8 @@ void SettingsModel::accessCallSettings() {
|
|||
emit playbackGainChanged(getPlaybackGain());
|
||||
emit captureGainChanged(getCaptureGain());
|
||||
|
||||
// Media cards must not be used twice (capture card + call) else we will get latencies issues and bad echo calibrations in call.
|
||||
// Media cards must not be used twice (capture card + call) else we will get latencies issues and bad echo
|
||||
// calibrations in call.
|
||||
if (!getIsInCall()) {
|
||||
qDebug() << "Starting capture graph from accessing audio panel";
|
||||
startCaptureGraph();
|
||||
|
|
@ -193,8 +189,7 @@ void SettingsModel::setPlaybackGain(float gain) {
|
|||
if (mSimpleCaptureGraph && mSimpleCaptureGraph->isRunning()) {
|
||||
mSimpleCaptureGraph->setPlaybackGain(gain);
|
||||
}
|
||||
if((int)(oldGain*1000) != (int)(gain*1000))
|
||||
emit playbackGainChanged(gain);
|
||||
if ((int)(oldGain * 1000) != (int)(gain * 1000)) emit playbackGainChanged(gain);
|
||||
}
|
||||
|
||||
float SettingsModel::getCaptureGain() const {
|
||||
|
|
@ -210,11 +205,10 @@ void SettingsModel::setCaptureGain(float gain) {
|
|||
if (mSimpleCaptureGraph && mSimpleCaptureGraph->isRunning()) {
|
||||
mSimpleCaptureGraph->setCaptureGain(gain);
|
||||
}
|
||||
if((int)(oldGain *1000) != (int)(gain *1000))
|
||||
emit captureGainChanged(gain);
|
||||
if ((int)(oldGain * 1000) != (int)(gain * 1000)) emit captureGainChanged(gain);
|
||||
}
|
||||
|
||||
QStringList SettingsModel::getCaptureDevices () const {
|
||||
QStringList SettingsModel::getCaptureDevices() const {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
shared_ptr<linphone::Core> core = CoreModel::getInstance()->getCore();
|
||||
QStringList list;
|
||||
|
|
@ -226,7 +220,7 @@ QStringList SettingsModel::getCaptureDevices () const {
|
|||
return list;
|
||||
}
|
||||
|
||||
QStringList SettingsModel::getPlaybackDevices () const {
|
||||
QStringList SettingsModel::getPlaybackDevices() const {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
shared_ptr<linphone::Core> core = CoreModel::getInstance()->getCore();
|
||||
QStringList list;
|
||||
|
|
@ -241,68 +235,64 @@ QStringList SettingsModel::getPlaybackDevices () const {
|
|||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
QString SettingsModel::getCaptureDevice () const {
|
||||
QString SettingsModel::getCaptureDevice() const {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
auto audioDevice = CoreModel::getInstance()->getCore()->getInputAudioDevice();
|
||||
return Utils::coreStringToAppString(audioDevice? audioDevice->getId() : CoreModel::getInstance()->getCore()->getCaptureDevice());
|
||||
return Utils::coreStringToAppString(audioDevice ? audioDevice->getId()
|
||||
: CoreModel::getInstance()->getCore()->getCaptureDevice());
|
||||
}
|
||||
|
||||
void SettingsModel::setCaptureDevice (const QString &device) {
|
||||
void SettingsModel::setCaptureDevice(const QString &device) {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
std::string devId = Utils::appStringToCoreString(device);
|
||||
auto list = CoreModel::getInstance()->getCore()->getExtendedAudioDevices();
|
||||
auto audioDevice = find_if(list.cbegin(), list.cend(), [&] ( const std::shared_ptr<linphone::AudioDevice> & audioItem) {
|
||||
return audioItem->getId() == devId;
|
||||
});
|
||||
if(audioDevice != list.cend()){
|
||||
auto audioDevice =
|
||||
find_if(list.cbegin(), list.cend(),
|
||||
[&](const std::shared_ptr<linphone::AudioDevice> &audioItem) { return audioItem->getId() == devId; });
|
||||
if (audioDevice != list.cend()) {
|
||||
CoreModel::getInstance()->getCore()->setCaptureDevice(devId);
|
||||
CoreModel::getInstance()->getCore()->setInputAudioDevice(*audioDevice);
|
||||
emit captureDeviceChanged(device);
|
||||
resetCaptureGraph();
|
||||
}else
|
||||
qWarning() << "Cannot set Capture device. The ID cannot be matched with an existant device : " << device;
|
||||
} else qWarning() << "Cannot set Capture device. The ID cannot be matched with an existant device : " << device;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
QString SettingsModel::getPlaybackDevice () const {
|
||||
QString SettingsModel::getPlaybackDevice() const {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
auto audioDevice = CoreModel::getInstance()->getCore()->getOutputAudioDevice();
|
||||
return Utils::coreStringToAppString(audioDevice? audioDevice->getId() : CoreModel::getInstance()->getCore()->getPlaybackDevice());
|
||||
return Utils::coreStringToAppString(audioDevice ? audioDevice->getId()
|
||||
: CoreModel::getInstance()->getCore()->getPlaybackDevice());
|
||||
}
|
||||
|
||||
void SettingsModel::setPlaybackDevice (const QString &device) {
|
||||
void SettingsModel::setPlaybackDevice(const QString &device) {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
std::string devId = Utils::appStringToCoreString(device);
|
||||
|
||||
auto list = CoreModel::getInstance()->getCore()->getExtendedAudioDevices();
|
||||
auto audioDevice = find_if(list.cbegin(), list.cend(), [&] ( const std::shared_ptr<linphone::AudioDevice> & audioItem) {
|
||||
return audioItem->getId() == devId;
|
||||
});
|
||||
if(audioDevice != list.cend()){
|
||||
auto audioDevice =
|
||||
find_if(list.cbegin(), list.cend(),
|
||||
[&](const std::shared_ptr<linphone::AudioDevice> &audioItem) { return audioItem->getId() == devId; });
|
||||
if (audioDevice != list.cend()) {
|
||||
|
||||
CoreModel::getInstance()->getCore()->setPlaybackDevice(devId);
|
||||
CoreModel::getInstance()->getCore()->setOutputAudioDevice(*audioDevice);
|
||||
emit playbackDeviceChanged(device);
|
||||
resetCaptureGraph();
|
||||
}else
|
||||
qWarning() << "Cannot set Playback device. The ID cannot be matched with an existant device : " << device;
|
||||
} else qWarning() << "Cannot set Playback device. The ID cannot be matched with an existant device : " << device;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
QString SettingsModel::getRingerDevice () const {
|
||||
QString SettingsModel::getRingerDevice() const {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
return Utils::coreStringToAppString(
|
||||
CoreModel::getInstance()->getCore()->getRingerDevice()
|
||||
);
|
||||
return Utils::coreStringToAppString(CoreModel::getInstance()->getCore()->getRingerDevice());
|
||||
}
|
||||
|
||||
void SettingsModel::setRingerDevice (const QString &device) {
|
||||
void SettingsModel::setRingerDevice(const QString &device) {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
CoreModel::getInstance()->getCore()->setRingerDevice(
|
||||
Utils::appStringToCoreString(device)
|
||||
);
|
||||
CoreModel::getInstance()->getCore()->setRingerDevice(Utils::appStringToCoreString(device));
|
||||
emit ringerDeviceChanged(device);
|
||||
}
|
||||
|
||||
|
|
@ -310,7 +300,7 @@ void SettingsModel::setRingerDevice (const QString &device) {
|
|||
|
||||
bool SettingsModel::getVideoEnabled() const {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
return CoreModel::getInstance()->getCore()->videoEnabled();
|
||||
return CoreModel::getInstance()->getCore()->videoEnabled();
|
||||
}
|
||||
|
||||
void SettingsModel::setVideoEnabled(const bool enabled) {
|
||||
|
|
@ -323,33 +313,33 @@ void SettingsModel::setVideoEnabled(const bool enabled) {
|
|||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
bool SettingsModel::getEchoCancellationEnabled () const {
|
||||
bool SettingsModel::getEchoCancellationEnabled() const {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
return CoreModel::getInstance()->getCore()->echoCancellationEnabled();
|
||||
}
|
||||
|
||||
void SettingsModel::setEchoCancellationEnabled (bool status) {
|
||||
void SettingsModel::setEchoCancellationEnabled(bool status) {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
CoreModel::getInstance()->getCore()->enableEchoCancellation(status);
|
||||
emit echoCancellationEnabledChanged(status);
|
||||
}
|
||||
|
||||
void SettingsModel::startEchoCancellerCalibration(){
|
||||
void SettingsModel::startEchoCancellerCalibration() {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
CoreModel::getInstance()->getCore()->startEchoCancellerCalibration();
|
||||
}
|
||||
|
||||
int SettingsModel::getEchoCancellationCalibration()const {
|
||||
int SettingsModel::getEchoCancellationCalibration() const {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
return CoreModel::getInstance()->getCore()->getEchoCancellationCalibration();
|
||||
}
|
||||
|
||||
bool SettingsModel::getAutomaticallyRecordCallsEnabled () const {
|
||||
bool SettingsModel::getAutomaticallyRecordCallsEnabled() const {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
return !!mConfig->getInt(UiSection, "automatically_record_calls", 0);
|
||||
}
|
||||
|
||||
void SettingsModel::setAutomaticallyRecordCallsEnabled (bool enabled) {
|
||||
void SettingsModel::setAutomaticallyRecordCallsEnabled(bool enabled) {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
mConfig->setInt(UiSection, "automatically_record_calls", enabled);
|
||||
emit automaticallyRecordCallsEnabledChanged(enabled);
|
||||
|
|
@ -359,12 +349,12 @@ void SettingsModel::setAutomaticallyRecordCallsEnabled (bool enabled) {
|
|||
// VFS.
|
||||
// =============================================================================
|
||||
|
||||
bool SettingsModel::getVfsEnabled () const {
|
||||
bool SettingsModel::getVfsEnabled() const {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
return !!mConfig->getInt(UiSection, "vfs_enabled", 0);
|
||||
}
|
||||
|
||||
void SettingsModel::setVfsEnabled (bool enabled) {
|
||||
void SettingsModel::setVfsEnabled(bool enabled) {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
mConfig->setInt(UiSection, "vfs_enabled", enabled);
|
||||
emit vfsEnabledChanged(enabled);
|
||||
|
|
@ -374,69 +364,67 @@ void SettingsModel::setVfsEnabled (bool enabled) {
|
|||
// Logs.
|
||||
// =============================================================================
|
||||
|
||||
bool SettingsModel::getLogsEnabled () const {
|
||||
bool SettingsModel::getLogsEnabled() const {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
return getLogsEnabled(mConfig);
|
||||
}
|
||||
|
||||
void SettingsModel::setLogsEnabled (bool status) {
|
||||
void SettingsModel::setLogsEnabled(bool status) {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
mConfig->setInt(UiSection, "logs_enabled", status);
|
||||
CoreModel::getInstance()->getLogger()->enable(status);
|
||||
emit logsEnabledChanged(status);
|
||||
}
|
||||
|
||||
bool SettingsModel::getFullLogsEnabled () const {
|
||||
bool SettingsModel::getFullLogsEnabled() const {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
return getFullLogsEnabled(mConfig);
|
||||
}
|
||||
|
||||
void SettingsModel::setFullLogsEnabled (bool status) {
|
||||
void SettingsModel::setFullLogsEnabled(bool status) {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
mConfig->setInt(UiSection, "full_logs_enabled", status);
|
||||
CoreModel::getInstance()->getLogger()->enableFullLogs(status);
|
||||
emit fullLogsEnabledChanged(status);
|
||||
}
|
||||
|
||||
bool SettingsModel::getLogsEnabled (const shared_ptr<linphone::Config> &config) {
|
||||
bool SettingsModel::getLogsEnabled(const shared_ptr<linphone::Config> &config) {
|
||||
mustBeInLinphoneThread(sLog().arg(Q_FUNC_INFO));
|
||||
return config ? config->getInt(UiSection, "logs_enabled", false) : true;
|
||||
}
|
||||
|
||||
bool SettingsModel::getFullLogsEnabled (const shared_ptr<linphone::Config> &config) {
|
||||
bool SettingsModel::getFullLogsEnabled(const shared_ptr<linphone::Config> &config) {
|
||||
mustBeInLinphoneThread(sLog().arg(Q_FUNC_INFO));
|
||||
return config ? config->getInt(UiSection, "full_logs_enabled", false) : false;
|
||||
}
|
||||
|
||||
QString SettingsModel::getLogsFolder () const {
|
||||
QString SettingsModel::getLogsFolder() const {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
return getLogsFolder(mConfig);
|
||||
}
|
||||
|
||||
QString SettingsModel::getLogsFolder (const shared_ptr<linphone::Config> &config) {
|
||||
QString SettingsModel::getLogsFolder(const shared_ptr<linphone::Config> &config) {
|
||||
mustBeInLinphoneThread(sLog().arg(Q_FUNC_INFO));
|
||||
return config
|
||||
? Utils::coreStringToAppString(config->getString(UiSection, "logs_folder", Utils::appStringToCoreString(Paths::getLogsDirPath())))
|
||||
: Paths::getLogsDirPath();
|
||||
return config ? Utils::coreStringToAppString(config->getString(
|
||||
UiSection, "logs_folder", Utils::appStringToCoreString(Paths::getLogsDirPath())))
|
||||
: Paths::getLogsDirPath();
|
||||
}
|
||||
|
||||
void SettingsModel::cleanLogs () const {
|
||||
void SettingsModel::cleanLogs() const {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
CoreModel::getInstance()->getCore()->resetLogCollection();
|
||||
}
|
||||
|
||||
void SettingsModel::sendLogs () const {
|
||||
void SettingsModel::sendLogs() const {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
auto core = CoreModel::getInstance()->getCore();
|
||||
qInfo() << QStringLiteral("Send logs to: `%1` from `%2`.")
|
||||
.arg(Utils::coreStringToAppString(core->getLogCollectionUploadServerUrl()))
|
||||
.arg(Utils::coreStringToAppString(core->getLogCollectionPath()));
|
||||
.arg(Utils::coreStringToAppString(core->getLogCollectionUploadServerUrl()))
|
||||
.arg(Utils::coreStringToAppString(core->getLogCollectionPath()));
|
||||
core->uploadLogCollection();
|
||||
}
|
||||
|
||||
QString SettingsModel::getLogsEmail () const {
|
||||
QString SettingsModel::getLogsEmail() const {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
return Utils::coreStringToAppString(
|
||||
mConfig->getString(UiSection, "logs_email", Constants::DefaultLogsEmail)
|
||||
);
|
||||
return Utils::coreStringToAppString(mConfig->getString(UiSection, "logs_email", Constants::DefaultLogsEmail));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ public:
|
|||
static constexpr char DownloadUrl[] = "https://www.linphone.org/technical-corner/linphone";
|
||||
static constexpr char VersionCheckReleaseUrl[] = "https://linphone.org/releases";
|
||||
static constexpr char VersionCheckNightlyUrl[] = "https://linphone.org/snapshots";
|
||||
static constexpr char PasswordRecoveryUrl[] = "https://subscribe.linphone.org/login/email";
|
||||
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 ContactUrl[] = "https://www.linphone.org/contact";
|
||||
|
|
|
|||
|
|
@ -323,6 +323,29 @@ LinphoneEnums::TransportType fromLinphone(const linphone::TransportType &type);
|
|||
QString toString(const LinphoneEnums::TransportType &type);
|
||||
void fromString(const QString &transportType, LinphoneEnums::TransportType *transport);
|
||||
|
||||
enum class AccountManagerServicesRequestType {
|
||||
SendAccountCreationTokenByPush = int(linphone::AccountManagerServicesRequest::Type::SendAccountCreationTokenByPush),
|
||||
AccountCreationRequestToken = int(linphone::AccountManagerServicesRequest::Type::AccountCreationRequestToken),
|
||||
AccountCreationTokenFromAccountCreationRequestToken =
|
||||
int(linphone::AccountManagerServicesRequest::Type::AccountCreationTokenFromAccountCreationRequestToken),
|
||||
CreateAccountUsingToken = int(linphone::AccountManagerServicesRequest::Type::CreateAccountUsingToken),
|
||||
SendPhoneNumberLinkingCodeBySms =
|
||||
int(linphone::AccountManagerServicesRequest::Type::SendPhoneNumberLinkingCodeBySms),
|
||||
LinkPhoneNumberUsingCode = int(linphone::AccountManagerServicesRequest::Type::LinkPhoneNumberUsingCode),
|
||||
SendEmailLinkingCodeByEmail = int(linphone::AccountManagerServicesRequest::Type::SendEmailLinkingCodeByEmail),
|
||||
LinkEmailUsingCode = int(linphone::AccountManagerServicesRequest::Type::LinkEmailUsingCode),
|
||||
GetDevicesList = int(linphone::AccountManagerServicesRequest::Type::GetDevicesList),
|
||||
DeleteDevice = int(linphone::AccountManagerServicesRequest::Type::DeleteDevice),
|
||||
GetCreationTokenAsAdmin = int(linphone::AccountManagerServicesRequest::Type::GetCreationTokenAsAdmin),
|
||||
GetAccountInfoAsAdmin = int(linphone::AccountManagerServicesRequest::Type::GetAccountInfoAsAdmin),
|
||||
DeleteAccountAsAdmin = int(linphone::AccountManagerServicesRequest::Type::DeleteAccountAsAdmin)
|
||||
};
|
||||
Q_ENUM_NS(AccountManagerServicesRequestType)
|
||||
|
||||
// linphone::AccountManagerServicesRequest::Type toLinphone(const LinphoneEnums::AccountManagerServicesRequestType
|
||||
// &type); LinphoneEnums::AccountManagerServicesRequestType fromLinphone(const
|
||||
// linphone::AccountManagerServicesRequest::Type &type);
|
||||
|
||||
enum VideoSourceScreenSharingType {
|
||||
VideoSourceScreenSharingTypeArea = int(linphone::VideoSourceScreenSharingType::Area),
|
||||
VideoSourceScreenSharingTypeDisplay = int(linphone::VideoSourceScreenSharingType::Display),
|
||||
|
|
|
|||
|
|
@ -374,6 +374,11 @@ bool Utils::copyToClipboard(const QString &text) {
|
|||
return !clipboardText.isEmpty();
|
||||
}
|
||||
|
||||
QString Utils::getClipboardText() {
|
||||
QClipboard *clipboard = QApplication::clipboard();
|
||||
return clipboard->text();
|
||||
}
|
||||
|
||||
QString Utils::getApplicationProduct() {
|
||||
// Note: Keep '-' as a separator between application name and application type
|
||||
return QString(APPLICATION_NAME "-Desktop").remove(' ') + "/" + QCoreApplication::applicationVersion();
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@ public:
|
|||
Q_INVOKABLE static QStringList generateSecurityLettersArray(int arraySize, int correctIndex, QString correctCode);
|
||||
Q_INVOKABLE static int getRandomIndex(int size);
|
||||
Q_INVOKABLE static bool copyToClipboard(const QString &text);
|
||||
Q_INVOKABLE static QString getClipboardText();
|
||||
Q_INVOKABLE static QString toDateString(QDateTime date, const QString &format = "");
|
||||
Q_INVOKABLE static QString toDateString(QDate date, const QString &format = "");
|
||||
Q_INVOKABLE static QString toDateDayString(const QDateTime &date);
|
||||
|
|
|
|||
|
|
@ -38,8 +38,10 @@ ApplicationWindow {
|
|||
infoPopup.open()
|
||||
infoPopup.closePopup.connect(removeFromPopupLayout)
|
||||
}
|
||||
function showLoadingPopup(text) {
|
||||
function showLoadingPopup(text, cancelButtonVisible) {
|
||||
if (cancelButtonVisible == undefined) cancelButtonVisible = false
|
||||
loadingPopup.text = text
|
||||
loadingPopup.cancelButtonVisible = cancelButtonVisible
|
||||
loadingPopup.open()
|
||||
}
|
||||
function closeLoadingPopup() {
|
||||
|
|
|
|||
|
|
@ -15,10 +15,12 @@ Rectangle {
|
|||
color: DefaultStyle.grey_0
|
||||
ColumnLayout {
|
||||
// anchors.leftMargin: 119 * DefaultStyle.dp
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.bottom: bottomMountains.top
|
||||
id: contentLayout
|
||||
// anchors.top: parent.top
|
||||
// anchors.left: parent.left
|
||||
// anchors.right: parent.right
|
||||
anchors.fill: parent
|
||||
// anchors.bottom: bottomMountains.top
|
||||
spacing: 0
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
|
|
@ -63,17 +65,16 @@ Rectangle {
|
|||
id: centerLayout
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: true
|
||||
z: 1
|
||||
}
|
||||
Image {
|
||||
id: bottomMountains
|
||||
source: AppIcons.belledonne
|
||||
fillMode: Image.Stretch
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: 108 * DefaultStyle.dp
|
||||
}
|
||||
}
|
||||
|
||||
Image {
|
||||
id: bottomMountains
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
height: 108 * DefaultStyle.dp
|
||||
source: AppIcons.belledonne
|
||||
fillMode: Image.Stretch
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -92,8 +92,17 @@ AppWindow {
|
|||
id: registerPage
|
||||
RegisterPage {
|
||||
onReturnToLogin: mainWindowStackView.replace(loginPage)
|
||||
onRegisterCalled: (countryCode, phoneNumber, email) => {
|
||||
mainWindowStackView.push(checkingPage, {"phoneNumber": phoneNumber, "email": email})
|
||||
onBrowserValidationRequested: mainWindow.showLoadingPopup(qsTr("Veuillez valider le captcha sur la page web"), true)
|
||||
Connections {
|
||||
target: RegisterPageCpp
|
||||
onNewAccountCreationSucceed: (withEmail, address, sipIdentityAddress) => {
|
||||
mainWindowStackView.push(checkingPage, {"registerWithEmail": withEmail, "address": address, "sipIdentityAddress": sipIdentityAddress})
|
||||
}
|
||||
onRegisterNewAccountFailed: (errorMessage) => {
|
||||
mainWindow.showInformationPopup(qsTr("Erreur lors de la création"), errorMessage, false)
|
||||
mainWindow.closeLoadingPopup()
|
||||
}
|
||||
onTokenConversionSucceed: mainWindow.closeLoadingPopup()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -101,6 +110,20 @@ AppWindow {
|
|||
id: checkingPage
|
||||
RegisterCheckingPage {
|
||||
onReturnToRegister: mainWindowStackView.pop()
|
||||
onSendCode: (code) => {
|
||||
RegisterPageCpp.linkNewAccountUsingCode(code, registerWithEmail, sipIdentityAddress)
|
||||
}
|
||||
Connections {
|
||||
target: RegisterPageCpp
|
||||
onLinkingNewAccountWithCodeSucceed: {
|
||||
mainWindowStackView.replace(loginPage)
|
||||
mainWindow.showInformationPopup(qsTr("Compte créé"), qsTr("Le compte a été créé avec succès. Vous pouvez maintenant vous connecter"), true)
|
||||
}
|
||||
onLinkingNewAccountWithCodeFailed: (errorMessage) => {
|
||||
if (errorMessage.length === 0) errorMessage = qsTr("Erreur dans le code de validation")
|
||||
mainWindow.showInformationPopup(qsTr("Erreur"), errorMessage, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Component {
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ Control.TextField {
|
|||
height: inputSize
|
||||
horizontalAlignment: TextInput.AlignHCenter
|
||||
verticalAlignment: TextInput.AlignVCenter
|
||||
overwriteMode: true
|
||||
|
||||
// just reserve the space for the background
|
||||
placeholderText: "0"
|
||||
|
|
|
|||
|
|
@ -8,12 +8,6 @@ Text {
|
|||
id: mainItem
|
||||
color: DefaultStyle.danger_500main
|
||||
opacity: 0
|
||||
function displayText() {
|
||||
mainItem.state = "Visible"
|
||||
}
|
||||
function hideText() {
|
||||
mainItem.state = "Invisible"
|
||||
}
|
||||
font {
|
||||
pixelSize: 12 * DefaultStyle.dp
|
||||
weight: 300 * DefaultStyle.dp
|
||||
|
|
@ -25,7 +19,7 @@ Text {
|
|||
},
|
||||
State{
|
||||
name:"Invisible"
|
||||
PropertyChanges{target: mainItem; opacity: 0.0}
|
||||
PropertyChanges{target: mainItem; opacity: 0.0; text: ""}
|
||||
}
|
||||
]
|
||||
transitions: [
|
||||
|
|
@ -34,7 +28,7 @@ Text {
|
|||
to: "Invisible"
|
||||
NumberAnimation {
|
||||
property: "opacity"
|
||||
duration: 1000
|
||||
duration: 500
|
||||
}
|
||||
}
|
||||
]
|
||||
|
|
@ -51,6 +45,8 @@ Text {
|
|||
onTextChanged: {
|
||||
if (mainItem.text.length > 0) {
|
||||
mainItem.state = "Visible"
|
||||
} else {
|
||||
mainItem.state = "Invisible"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import QtQuick
|
|||
import QtQuick.Layouts
|
||||
import QtQuick.Controls as Control
|
||||
import Linphone
|
||||
|
||||
import ConstantsCpp 1.0
|
||||
|
||||
ColumnLayout {
|
||||
id: mainItem
|
||||
|
|
@ -148,7 +148,7 @@ ColumnLayout {
|
|||
weight: 600 * DefaultStyle.dp
|
||||
}
|
||||
}
|
||||
onClicked: console.debug("[LoginForm]User: forgotten password button clicked")
|
||||
onClicked: Qt.openUrlExternally(ConstantsCpp.PasswordRecoveryUrl)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import Linphone
|
|||
Popup {
|
||||
id: mainItem
|
||||
property string text
|
||||
property bool cancelButtonVisible: false
|
||||
modal: true
|
||||
closePolicy: Control.Popup.NoAutoClose
|
||||
anchors.centerIn: parent
|
||||
|
|
@ -15,6 +16,8 @@ Popup {
|
|||
// onAboutToShow: width = contentText.implicitWidth
|
||||
contentItem: ColumnLayout {
|
||||
spacing: 15 * DefaultStyle.dp
|
||||
// width: childrenRect.width
|
||||
// height: childrenRect.height
|
||||
BusyIndicator{
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.preferredWidth: 33 * DefaultStyle.dp
|
||||
|
|
@ -28,5 +31,11 @@ Popup {
|
|||
text: mainItem.text
|
||||
font.pixelSize: 14 * DefaultStyle.dp
|
||||
}
|
||||
Button {
|
||||
visible: mainItem.cancelButtonVisible
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: qsTr("Annuler")
|
||||
onClicked: mainItem.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -7,7 +7,7 @@ import Linphone
|
|||
ColumnLayout {
|
||||
id: mainItem
|
||||
property string label: ""
|
||||
readonly property string currentText: combobox.model.getAt(combobox.currentIndex) ? combobox.model.getAt(combobox.currentIndex).countryCallingCode : ""
|
||||
readonly property string currentText: combobox.model.getAt(combobox.currentIndex) ? "+" + combobox.model.getAt(combobox.currentIndex).countryCallingCode : ""
|
||||
property string defaultCallingCode: ""
|
||||
property bool enableBackgroundColors: false
|
||||
|
||||
|
|
@ -101,7 +101,7 @@ ColumnLayout {
|
|||
id: listPopup
|
||||
y: combobox.height - 1
|
||||
width: 311 * DefaultStyle.dp
|
||||
height: 198 * DefaultStyle.dp
|
||||
height: 250 * DefaultStyle.dp
|
||||
|
||||
contentItem: ListView {
|
||||
id: listView
|
||||
|
|
@ -109,7 +109,9 @@ ColumnLayout {
|
|||
anchors.fill: parent
|
||||
model: PhoneNumberProxy{}
|
||||
currentIndex: combobox.highlightedIndex >= 0 ? combobox.highlightedIndex : 0
|
||||
highlightFollowsCurrentItem: true
|
||||
keyNavigationEnabled: true
|
||||
keyNavigationWraps: true
|
||||
maximumFlickVelocity: 1500
|
||||
highlight: Rectangle {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
|
@ -177,7 +179,7 @@ ColumnLayout {
|
|||
color: DefaultStyle.main2_500main
|
||||
visible: parent.containsMouse
|
||||
}
|
||||
onPressed: {
|
||||
onClicked: {
|
||||
combobox.currentIndex = index
|
||||
listPopup.close()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,13 +7,15 @@ ColumnLayout {
|
|||
id: mainItem
|
||||
|
||||
property string label: ""
|
||||
property string errorMessage: ""
|
||||
property alias errorMessage: errorText.text
|
||||
property string placeholderText : ""
|
||||
property bool mandatory: false
|
||||
property bool enableErrorText: true
|
||||
property int textInputWidth: width
|
||||
property string initialPhoneNumber
|
||||
readonly property string phoneNumber: textField.text
|
||||
readonly property string countryCode: combobox.currentText
|
||||
property string defaultCallingCode
|
||||
|
||||
Text {
|
||||
visible: label.length > 0
|
||||
|
|
@ -26,52 +28,60 @@ ColumnLayout {
|
|||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
Layout.preferredWidth: mainItem.textInputWidth
|
||||
Layout.preferredHeight: 49 * DefaultStyle.dp
|
||||
radius: 63 * DefaultStyle.dp
|
||||
color: DefaultStyle.grey_100
|
||||
border.color: mainItem.errorMessage.length > 0
|
||||
? DefaultStyle.danger_500main
|
||||
: (textField.hasActiveFocus || combobox.hasActiveFocus)
|
||||
? DefaultStyle.main1_500_main
|
||||
: DefaultStyle.grey_200
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
PhoneNumberComboBox {
|
||||
id: combobox
|
||||
implicitWidth: 110 * DefaultStyle.dp
|
||||
}
|
||||
Rectangle {
|
||||
Layout.preferredWidth: 1 * DefaultStyle.dp
|
||||
Layout.fillHeight: true
|
||||
Layout.topMargin: 10 * DefaultStyle.dp
|
||||
Layout.bottomMargin: 10 * DefaultStyle.dp
|
||||
color: DefaultStyle.main2_600
|
||||
}
|
||||
TextField {
|
||||
id: textField
|
||||
Layout.fillWidth: true
|
||||
placeholderText: mainItem.placeholderText
|
||||
background: Item{}
|
||||
initialText: initialPhoneNumber
|
||||
validator: RegularExpressionValidator{ regularExpression: /[0-9]+/}
|
||||
Item {
|
||||
Layout.preferredWidth: contentBackground.width
|
||||
Layout.preferredHeight: contentBackground.height
|
||||
Rectangle {
|
||||
id: contentBackground
|
||||
width: mainItem.textInputWidth
|
||||
height: 49 * DefaultStyle.dp
|
||||
radius: 63 * DefaultStyle.dp
|
||||
color: DefaultStyle.grey_100
|
||||
border.color: mainItem.errorMessage.length > 0
|
||||
? DefaultStyle.danger_500main
|
||||
: (textField.hasActiveFocus || combobox.hasActiveFocus)
|
||||
? DefaultStyle.main1_500_main
|
||||
: DefaultStyle.grey_200
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
PhoneNumberComboBox {
|
||||
id: combobox
|
||||
implicitWidth: 110 * DefaultStyle.dp
|
||||
defaultCallingCode: mainItem.defaultCallingCode
|
||||
}
|
||||
Rectangle {
|
||||
Layout.preferredWidth: 1 * DefaultStyle.dp
|
||||
Layout.fillHeight: true
|
||||
Layout.topMargin: 10 * DefaultStyle.dp
|
||||
Layout.bottomMargin: 10 * DefaultStyle.dp
|
||||
color: DefaultStyle.main2_600
|
||||
}
|
||||
TextField {
|
||||
id: textField
|
||||
Layout.fillWidth: true
|
||||
placeholderText: mainItem.placeholderText
|
||||
background: Item{}
|
||||
initialText: initialPhoneNumber
|
||||
validator: RegularExpressionValidator{ regularExpression: /[0-9]+/}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Text {
|
||||
visible: mainItem.errorMessage.length > 0
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
text: mainItem.errorMessage
|
||||
color: DefaultStyle.danger_500main
|
||||
elide: Text.ElideRight
|
||||
wrapMode: Text.Wrap
|
||||
font {
|
||||
pixelSize: 13 * DefaultStyle.dp
|
||||
family: DefaultStyle.defaultFont
|
||||
bold: true
|
||||
ErrorText {
|
||||
id: errorText
|
||||
anchors.top: contentBackground.bottom
|
||||
// visible: mainItem.enableErrorText
|
||||
text: mainItem.errorMessage
|
||||
color: DefaultStyle.danger_500main
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
elide: Text.ElideRight
|
||||
wrapMode: Text.Wrap
|
||||
font {
|
||||
pixelSize: 13 * DefaultStyle.dp
|
||||
family: DefaultStyle.defaultFont
|
||||
bold: true
|
||||
}
|
||||
Layout.preferredWidth: mainItem.textInputWidth
|
||||
// Layout.preferredWidth: implicitWidth
|
||||
}
|
||||
Layout.preferredWidth: mainItem.textInputWidth
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ Control.TextField {
|
|||
}
|
||||
}
|
||||
Keys.onPressed: (event) => {
|
||||
if (event.jey == Qt.Key_Control) mainItem.controlIsDown = true
|
||||
if (event.key == Qt.Key_Control) mainItem.controlIsDown = true
|
||||
if (event.key === Qt.Key_Enter || event.key === Qt.Key_Return) {
|
||||
enterPressed()
|
||||
if (mainItem.controlIsDown) {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ ColumnLayout {
|
|||
property string label: ""
|
||||
property bool mandatory: false
|
||||
|
||||
property string errorMessage: ""
|
||||
property alias errorMessage: errorText.text
|
||||
property bool enableErrorText: false
|
||||
property bool errorTextVisible: errorText.opacity > 0
|
||||
spacing: 5 * DefaultStyle.dp
|
||||
|
|
@ -32,16 +32,19 @@ ColumnLayout {
|
|||
}
|
||||
|
||||
Item {
|
||||
id: contentItem
|
||||
Layout.preferredHeight: childrenRect.height
|
||||
Layout.preferredWidth: childrenRect.width
|
||||
Layout.preferredHeight: contentItem.height
|
||||
Layout.preferredWidth: contentItem.width
|
||||
Item {
|
||||
id: contentItem
|
||||
height: childrenRect.height
|
||||
width: childrenRect.width
|
||||
}
|
||||
ErrorText {
|
||||
id: errorText
|
||||
anchors.top: contentItem.bottom
|
||||
color: DefaultStyle.danger_500main
|
||||
Layout.preferredWidth: implicitWidth
|
||||
}
|
||||
}
|
||||
|
||||
ErrorText {
|
||||
id: errorText
|
||||
visible: mainItem.enableErrorText
|
||||
text: mainItem.errorMessage
|
||||
color: DefaultStyle.main2_600
|
||||
Layout.preferredWidth: implicitWidth
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -104,6 +104,7 @@ LoginLayout {
|
|||
}
|
||||
},
|
||||
Image {
|
||||
z: -1
|
||||
anchors.top: parent.top
|
||||
anchors.right: parent.right
|
||||
anchors.topMargin: 129 * DefaultStyle.dp
|
||||
|
|
|
|||
|
|
@ -6,9 +6,11 @@ import Linphone
|
|||
LoginLayout {
|
||||
id: mainItem
|
||||
signal returnToRegister()
|
||||
property string phoneNumber
|
||||
property string email
|
||||
|
||||
signal sendCode(string code)
|
||||
property bool registerWithEmail
|
||||
property string address
|
||||
property string sipIdentityAddress
|
||||
property string code
|
||||
titleContent: [
|
||||
RowLayout {
|
||||
spacing: 21 * DefaultStyle.dp
|
||||
|
|
@ -34,7 +36,7 @@ LoginLayout {
|
|||
Text {
|
||||
wrapMode: Text.NoWrap
|
||||
text: {
|
||||
var completeString = (mainItem.email.length > 0) ? qsTr("email") : qsTr("numéro")
|
||||
var completeString = mainItem.registerWithEmail ? qsTr("email") : qsTr("numéro")
|
||||
text = qsTr("Inscription | Confirmer votre ") + completeString
|
||||
}
|
||||
font {
|
||||
|
|
@ -64,7 +66,7 @@ LoginLayout {
|
|||
}
|
||||
color: DefaultStyle.main2_700
|
||||
text: {
|
||||
var completeString = (mainItem.email.length > 0) ? ("email \"" + mainItem.email + "\"") : ("phone number \"" + mainItem.phoneNumber + "\"")
|
||||
var completeString = mainItem.registerWithEmail ? ("email \"") : ("phone number \"") + address + "\""
|
||||
text = "We have sent a verification code on your " + completeString + " <br>Please enter the verification code below:"
|
||||
}
|
||||
}
|
||||
|
|
@ -78,10 +80,12 @@ LoginLayout {
|
|||
Layout.preferredHeight: height
|
||||
onTextEdited: {
|
||||
if (text.length > 0 ) {
|
||||
mainItem.code = mainItem.code.slice(0, index) + text + mainItem.code.slice(index)
|
||||
if (index < 3)
|
||||
nextItemInFocusChain(true).forceActiveFocus()
|
||||
else {
|
||||
// TODO : validate()
|
||||
mainItem.sendCode(mainItem.code)
|
||||
mainItem.code = ""
|
||||
}
|
||||
} else {
|
||||
if (index > 0)
|
||||
|
|
|
|||
|
|
@ -2,15 +2,27 @@ import QtQuick 2.15
|
|||
import QtQuick.Layouts 1.3
|
||||
import QtQuick.Controls as Control
|
||||
import Linphone
|
||||
import UtilsCpp 1.0
|
||||
import ConstantsCpp 1.0
|
||||
|
||||
LoginLayout {
|
||||
id: mainItem
|
||||
signal returnToLogin()
|
||||
signal registerCalled(countryCode: string, phoneNumber: string, email: string)
|
||||
signal browserValidationRequested()
|
||||
readonly property string countryCode: phoneNumberInput.countryCode
|
||||
readonly property string phoneNumber: phoneNumberInput.phoneNumber
|
||||
readonly property string email: emailInput.text
|
||||
|
||||
Connections {
|
||||
target: RegisterPageCpp
|
||||
onErrorInField: (field, errorMessage) => {
|
||||
if (field == "username") usernameItem.errorMessage = errorMessage
|
||||
else if (field == "password") pwdItem.errorMessage = errorMessage
|
||||
else if (field == "phone") phoneNumberInput.errorMessage = errorMessage
|
||||
else if (field == "email") emailItem.errorMessage = errorMessage
|
||||
}
|
||||
}
|
||||
|
||||
titleContent: [
|
||||
RowLayout {
|
||||
spacing: 21 * DefaultStyle.dp
|
||||
|
|
@ -80,11 +92,13 @@ LoginLayout {
|
|||
RowLayout {
|
||||
spacing: 16 * DefaultStyle.dp
|
||||
FormItemLayout {
|
||||
id: usernameItem
|
||||
label: qsTr("Username")
|
||||
mandatory: true
|
||||
contentItem: TextField {
|
||||
id: usernameInput
|
||||
Layout.preferredWidth: 346 * DefaultStyle.dp
|
||||
backgroundBorderColor: usernameItem.errorMessage.length > 0 ? DefaultStyle.danger_500main : DefaultStyle.grey_200
|
||||
}
|
||||
}
|
||||
RowLayout {
|
||||
|
|
@ -109,17 +123,22 @@ LoginLayout {
|
|||
Layout.fillWidth: true
|
||||
PhoneNumberInput {
|
||||
id: phoneNumberInput
|
||||
label: qsTr("Phone number")
|
||||
property string completePhoneNumber: countryCode + phoneNumber
|
||||
label: qsTr("Numéro de téléphone")
|
||||
mandatory: true
|
||||
placeholderText: "Phone number"
|
||||
defaultCallingCode: "33"
|
||||
Layout.preferredWidth: 346 * DefaultStyle.dp
|
||||
}
|
||||
FormItemLayout {
|
||||
id: emailItem
|
||||
label: qsTr("Email")
|
||||
mandatory: true
|
||||
enableErrorText: true
|
||||
contentItem: TextField {
|
||||
id: emailInput
|
||||
Layout.preferredWidth: 346 * DefaultStyle.dp
|
||||
backgroundBorderColor: emailItem.errorMessage.length > 0 ? DefaultStyle.danger_500main : DefaultStyle.grey_200
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -128,130 +147,147 @@ LoginLayout {
|
|||
ColumnLayout {
|
||||
spacing: 5 * DefaultStyle.dp
|
||||
FormItemLayout {
|
||||
label: qsTr("Password")
|
||||
id: passwordItem
|
||||
label: qsTr("Mot de passe")
|
||||
mandatory: true
|
||||
enableErrorText: true
|
||||
contentItem: TextField {
|
||||
id: pwdInput
|
||||
hidden: true
|
||||
Layout.preferredWidth: 346 * DefaultStyle.dp
|
||||
}
|
||||
}
|
||||
Text {
|
||||
text: qsTr("The password must contain 6 characters minimum")
|
||||
font {
|
||||
pixelSize: 12 * DefaultStyle.dp
|
||||
weight: 300 * DefaultStyle.dp
|
||||
backgroundBorderColor: passwordItem.errorMessage.length > 0 ? DefaultStyle.danger_500main : DefaultStyle.grey_200
|
||||
}
|
||||
}
|
||||
}
|
||||
ColumnLayout {
|
||||
spacing: 5 * DefaultStyle.dp
|
||||
FormItemLayout {
|
||||
label: qsTr("Confirm password")
|
||||
label: qsTr("Confirmation mot de passe")
|
||||
mandatory: true
|
||||
enableErrorText: true
|
||||
contentItem: TextField {
|
||||
id: confirmPwdInput
|
||||
hidden: true
|
||||
Layout.preferredWidth: 346 * DefaultStyle.dp
|
||||
}
|
||||
}
|
||||
Text {
|
||||
text: qsTr("The password must contain 6 characters minimum")
|
||||
font {
|
||||
pixelSize: 12 * DefaultStyle.dp
|
||||
weight: 300 * DefaultStyle.dp
|
||||
backgroundBorderColor: passwordItem.errorMessage.length > 0 ? DefaultStyle.danger_500main : DefaultStyle.grey_200
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ColumnLayout {
|
||||
spacing: 18 * DefaultStyle.dp
|
||||
// ColumnLayout {
|
||||
// spacing: 18 * DefaultStyle.dp
|
||||
// RowLayout {
|
||||
// spacing: 10 * DefaultStyle.dp
|
||||
// CheckBox {
|
||||
// id: subscribeToNewsletterCheckBox
|
||||
// }
|
||||
// Text {
|
||||
// text: qsTr("Je souhaite souscrire à la newletter Linphone.")
|
||||
// font {
|
||||
// pixelSize: 14 * DefaultStyle.dp
|
||||
// weight: 400 * DefaultStyle.dp
|
||||
// }
|
||||
// MouseArea {
|
||||
// anchors.fill: parent
|
||||
// onClicked: subscribeToNewsletterCheckBox.toggle()
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
RowLayout {
|
||||
spacing: 10 * DefaultStyle.dp
|
||||
CheckBox {
|
||||
id: termsCheckBox
|
||||
}
|
||||
RowLayout {
|
||||
spacing: 10 * DefaultStyle.dp
|
||||
CheckBox {
|
||||
spacing: 0
|
||||
Layout.fillWidth: true
|
||||
Text {
|
||||
text: qsTr("J'accepte les ")
|
||||
font {
|
||||
pixelSize: 14 * DefaultStyle.dp
|
||||
weight: 400 * DefaultStyle.dp
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: termsCheckBox.toggle()
|
||||
}
|
||||
}
|
||||
Text {
|
||||
text: qsTr("I would like to suscribe to the newsletter")
|
||||
font {
|
||||
underline: true
|
||||
pixelSize: 14 * DefaultStyle.dp
|
||||
weight: 400 * DefaultStyle.dp
|
||||
}
|
||||
text: qsTr("conditions d’utilisation")
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||
onClicked: Qt.openUrlExternally(ConstantsCpp.CguUrl)
|
||||
}
|
||||
}
|
||||
Text {
|
||||
text: qsTr(" et la ")
|
||||
font {
|
||||
pixelSize: 14 * DefaultStyle.dp
|
||||
weight: 400 * DefaultStyle.dp
|
||||
}
|
||||
}
|
||||
}
|
||||
RowLayout {
|
||||
spacing: 10 * DefaultStyle.dp
|
||||
CheckBox {
|
||||
id: termsCheckBox
|
||||
}
|
||||
RowLayout {
|
||||
spacing: 0
|
||||
Layout.fillWidth: true
|
||||
Text {
|
||||
// Layout.preferredWidth: 450 * DefaultStyle.dp
|
||||
text: qsTr("I accept the Terms and Conditions: ")
|
||||
font {
|
||||
pixelSize: 14 * DefaultStyle.dp
|
||||
weight: 400 * DefaultStyle.dp
|
||||
}
|
||||
Text {
|
||||
font {
|
||||
underline: true
|
||||
pixelSize: 14 * DefaultStyle.dp
|
||||
weight: 400 * DefaultStyle.dp
|
||||
}
|
||||
Text {
|
||||
// Layout.preferredWidth: 450 * DefaultStyle.dp
|
||||
font {
|
||||
underline: true
|
||||
pixelSize: 14 * DefaultStyle.dp
|
||||
weight: 400 * DefaultStyle.dp
|
||||
}
|
||||
text: qsTr("Read the Terms and Conditions.")
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||
onClicked: console.log("TODO : display terms and conditions")
|
||||
}
|
||||
}
|
||||
Text {
|
||||
// Layout.preferredWidth: 450 * DefaultStyle.dp
|
||||
text: qsTr("I accept the Privacy policy: ")
|
||||
font {
|
||||
pixelSize: 14 * DefaultStyle.dp
|
||||
weight: 400 * DefaultStyle.dp
|
||||
}
|
||||
}
|
||||
Text {
|
||||
// Layout.preferredWidth: 450 * DefaultStyle.dp
|
||||
font {
|
||||
underline: true
|
||||
pixelSize: 14 * DefaultStyle.dp
|
||||
weight: 400 * DefaultStyle.dp
|
||||
}
|
||||
text: qsTr("Read the Privacy policy.")
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||
onClicked: console.log("TODO : display privacy policy")
|
||||
}
|
||||
text: qsTr("politique de confidentialité.")
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: containsMouse ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||
onClicked: Qt.openUrlExternally(ConstantsCpp.PrivatePolicyUrl)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// }
|
||||
Button {
|
||||
// enabled: termsCheckBox.checked && usernameInput.text.length != 0 && pwdInput.text.length != 0 && confirmPwdInput.text.length != 0
|
||||
// && (phoneNumberInput.phoneNumber.length != 0 || emailInput.text.length != 0)
|
||||
enabled: termsCheckBox.checked
|
||||
leftPadding: 20 * DefaultStyle.dp
|
||||
rightPadding: 20 * DefaultStyle.dp
|
||||
topPadding: 11 * DefaultStyle.dp
|
||||
bottomPadding: 11 * DefaultStyle.dp
|
||||
text: qsTr("Register")
|
||||
text: qsTr("Créer")
|
||||
onClicked:{
|
||||
console.log("[RegisterPage] User: Call register with phone number", phoneNumberInput.phoneNumber)
|
||||
mainItem.registerCalled(phoneNumberInput.countryCode, phoneNumberInput.phoneNumber, emailInput.text)
|
||||
if (usernameInput.text.length === 0) {
|
||||
console.log("ERROR username")
|
||||
usernameItem.errorMessage = qsTr("Veuillez entrer un nom d'utilisateur")
|
||||
} else if (pwdInput.text.length === 0) {
|
||||
console.log("ERROR password")
|
||||
passwordItem.errorMessage = qsTr("Veuillez entrer un mot de passe")
|
||||
} else if (pwdInput.text != confirmPwdInput.text) {
|
||||
console.log("ERROR confirm pwd")
|
||||
passwordItem.errorMessage = qsTr("Les mots de passe sont différents")
|
||||
} else if (bar.currentIndex === 0 && phoneNumberInput.phoneNumber.length === 0) {
|
||||
console.log("ERROR phone number")
|
||||
phoneNumberInput.errorMessage = qsTr("Veuillez entrer un numéro de téléphone")
|
||||
} else if (bar.currentIndex === 1 && emailInput.text.length === 0) {
|
||||
console.log("ERROR email")
|
||||
emailItem.errorMessage = qsTr("Veuillez entrer un email")
|
||||
} else {
|
||||
console.log("[RegisterPage] User: Call register")
|
||||
mainItem.browserValidationRequested()
|
||||
if (bar.currentIndex === 0)
|
||||
RegisterPageCpp.registerNewAccount(usernameInput.text, pwdInput.text, "", phoneNumberInput.completePhoneNumber)
|
||||
else
|
||||
RegisterPageCpp.registerNewAccount(usernameInput.text, pwdInput.text, emailInput.text, "")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
Image {
|
||||
z: -1
|
||||
anchors.top: parent.top
|
||||
anchors.right: parent.right
|
||||
anchors.topMargin: 129 * DefaultStyle.dp
|
||||
|
|
|
|||
|
|
@ -229,6 +229,7 @@ LoginLayout {
|
|||
clip: true
|
||||
},
|
||||
Image {
|
||||
z: -1
|
||||
anchors.top: parent.top
|
||||
anchors.right: parent.right
|
||||
anchors.topMargin: 129 * DefaultStyle.dp
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue