Commit d301a906 authored by Ronan's avatar Ronan

feat(ui/views/App/Main/Assistant/CreateLinphoneSipAccountWithPhoneNumber): view done

parent 6a051cb2
......@@ -128,7 +128,7 @@ set(SOURCES
src/components/sip-addresses/SipAddressesProxyModel.cpp
src/components/sip-addresses/SipAddressObserver.cpp
src/components/sound-player/SoundPlayer.cpp
src/components/telephone-numbers/TelephoneNumbers.cpp
src/components/telephone-numbers/TelephoneNumbersModel.cpp
src/components/text-to-speech/TextToSpeech.cpp
src/components/timeline/TimelineModel.cpp
src/externals/single-application/SingleApplication.cpp
......@@ -176,7 +176,7 @@ set(HEADERS
src/components/sip-addresses/SipAddressesProxyModel.hpp
src/components/sip-addresses/SipAddressObserver.hpp
src/components/sound-player/SoundPlayer.hpp
src/components/telephone-numbers/TelephoneNumbers.hpp
src/components/telephone-numbers/TelephoneNumbersModel.hpp
src/components/text-to-speech/TextToSpeech.hpp
src/components/timeline/TimelineModel.hpp
src/externals/single-application/SingleApplication.hpp
......
......@@ -150,6 +150,22 @@
<source>emailActivationFailed</source>
<translation>Please verify that you have validated your account or try again.</translation>
</message>
<message>
<source>phoneNumberStatusInvalid</source>
<translation>Invalid phone number!</translation>
</message>
<message>
<source>phoneNumberStatusTooShort</source>
<translation>Too short!</translation>
</message>
<message>
<source>phoneNumberStatusTooLong</source>
<translation>Too short!</translation>
</message>
<message>
<source>phoneNumberStatusInvalidCountryCode</source>
<translation>Invalid country code!</translation>
</message>
</context>
<context>
<name>AuthenticationRequest</name>
......@@ -605,6 +621,14 @@ Server url not configured.</translation>
<source>displayNameLabel</source>
<translation>Display name (optional)</translation>
</message>
<message>
<source>confirmAction</source>
<translation>CREATE</translation>
</message>
<message>
<source>quitWarning</source>
<translation>Your account has been created but is not yet validated. If you quit this view, you should add manually your account and validate it within 24 hours.</translation>
</message>
</context>
<context>
<name>DroppableTextArea</name>
......
......@@ -150,6 +150,22 @@
<source>emailActivationFailed</source>
<translation>Merci de vérifier que vous avez validé votre compte ou réessayez plus tard.</translation>
</message>
<message>
<source>phoneNumberStatusInvalid</source>
<translation>Numéro de tél. invalide !</translation>
</message>
<message>
<source>phoneNumberStatusTooShort</source>
<translation>Trop court !</translation>
</message>
<message>
<source>phoneNumberStatusTooLong</source>
<translation>Trop long !</translation>
</message>
<message>
<source>phoneNumberStatusInvalidCountryCode</source>
<translation>Indicatif tél. invalide !</translation>
</message>
</context>
<context>
<name>AuthenticationRequest</name>
......@@ -605,6 +621,14 @@ Url du serveur non configurée.</translation>
<source>displayNameLabel</source>
<translation>Nom d&apos;affichage (optionnel)</translation>
</message>
<message>
<source>confirmAction</source>
<translation>CRÉER</translation>
</message>
<message>
<source>quitWarning</source>
<translation>Votre compte a été crée mais il n&apos;a pas été validé. Si vous quittez cette vue, vous devrez ajouter manuellement votre compte et le valider dans les 24 heures.</translation>
</message>
</context>
<context>
<name>DroppableTextArea</name>
......
......@@ -353,7 +353,7 @@ void App::registerTypes () {
registerType<ContactsListProxyModel>("ContactsListProxyModel");
registerType<SipAddressesProxyModel>("SipAddressesProxyModel");
registerType<SoundPlayer>("SoundPlayer");
registerType<TelephoneNumbers>("TelephoneNumbers");
registerType<TelephoneNumbersModel>("TelephoneNumbersModel");
registerSingletonType<AudioCodecsModel>("AudioCodecsModel");
registerSingletonType<Clipboard>("Clipboard");
......
......@@ -40,7 +40,7 @@
#include "settings/AccountSettingsModel.hpp"
#include "sip-addresses/SipAddressesProxyModel.hpp"
#include "sound-player/SoundPlayer.hpp"
#include "telephone-numbers/TelephoneNumbers.hpp"
#include "telephone-numbers/TelephoneNumbersModel.hpp"
#include "text-to-speech/TextToSpeech.hpp"
#include "timeline/TimelineModel.hpp"
......
......@@ -180,6 +180,7 @@ void AssistantModel::login () {
}
void AssistantModel::reset () {
mCountryCode = "";
mAccountCreator->reset();
emit emailChanged("", "");
......@@ -246,15 +247,43 @@ void AssistantModel::setPassword (const QString &password) {
// -----------------------------------------------------------------------------
QString AssistantModel::getCountryCode () const {
return mCountryCode;
}
void AssistantModel::setCountryCode (const QString &countryCode) {
mCountryCode = countryCode;
emit countryCodeChanged(countryCode);
}
// -----------------------------------------------------------------------------
QString AssistantModel::getPhoneNumber () const {
return ::Utils::coreStringToAppString(mAccountCreator->getPhoneNumber());
}
void AssistantModel::setPhoneNumber (const QString &phoneNumber) {
// shared_ptr<linphone::Config> config = CoreManager::getInstance()->getCore()->getConfig();
shared_ptr<linphone::Config> config = CoreManager::getInstance()->getCore()->getConfig();
QString error;
// TODO: use the future wrapped function: `set_phone_number`.
switch (mAccountCreator->setPhoneNumber(::Utils::appStringToCoreString(phoneNumber), ::Utils::appStringToCoreString(mCountryCode))) {
case linphone::AccountCreatorPhoneNumberStatusOk:
break;
case linphone::AccountCreatorPhoneNumberStatusInvalid:
error = tr("phoneNumberStatusInvalid");
break;
case linphone::AccountCreatorPhoneNumberStatusTooShort:
error = tr("phoneNumberStatusTooShort");
break;
case linphone::AccountCreatorPhoneNumberStatusTooLong:
error = tr("phoneNumberStatusTooLong");
break;
case linphone::AccountCreatorPhoneNumberStatusInvalidCountryCode:
error = tr("phoneNumberStatusInvalidCountryCode");
break;
default:
break;
}
emit phoneNumberChanged(phoneNumber, error);
}
......
......@@ -35,6 +35,7 @@ class AssistantModel : public QObject {
Q_PROPERTY(QString email READ getEmail WRITE setEmail NOTIFY emailChanged);
Q_PROPERTY(QString password READ getPassword WRITE setPassword NOTIFY passwordChanged);
Q_PROPERTY(QString countryCode READ getCountryCode WRITE setCountryCode NOTIFY countryCodeChanged);
Q_PROPERTY(QString phoneNumber READ getPhoneNumber WRITE setPhoneNumber NOTIFY phoneNumberChanged);
Q_PROPERTY(QString username READ getUsername WRITE setUsername NOTIFY usernameChanged);
Q_PROPERTY(QString displayName READ getDisplayName WRITE setDisplayName NOTIFY displayNameChanged);
......@@ -52,6 +53,7 @@ public:
signals:
void emailChanged (const QString &email, const QString &error);
void passwordChanged (const QString &password, const QString &error);
void countryCodeChanged (const QString &countryCode);
void phoneNumberChanged (const QString &phoneNumber, const QString &error);
void usernameChanged (const QString &username, const QString &error);
void displayNameChanged (const QString &displayName, const QString &error);
......@@ -69,6 +71,9 @@ private:
QString getPassword () const;
void setPassword (const QString &password);
QString getCountryCode () const;
void setCountryCode (const QString &countryCode);
QString getPhoneNumber () const;
void setPhoneNumber (const QString &phoneNumber);
......@@ -83,6 +88,7 @@ private:
QString mapAccountCreatorUsernameStatusToString (linphone::AccountCreatorUsernameStatus status) const;
QString mCountryCode;
QString mConfigFilename;
std::shared_ptr<linphone::AccountCreator> mAccountCreator;
......
/*
* TelephoneNumbers.cpp
* TelephoneNumbersModel.cpp
* Copyright (C) 2017 Belledonne Communications, Grenoble, France
*
* This program is free software; you can redistribute it and/or
......@@ -20,11 +20,13 @@
* Author: Ronan Abhamon
*/
#include "TelephoneNumbers.hpp"
#include "TelephoneNumbersModel.hpp"
using namespace std;
// =============================================================================
const QList<QPair<QLocale::Country, QString> > TelephoneNumbers::mCountryCodes = {
const QList<QPair<QLocale::Country, QString> > TelephoneNumbersModel::mCountryCodes = {
{ QLocale::Afghanistan, "93" },
{ QLocale::Albania, "355" },
{ QLocale::Algeria, "213" },
......@@ -252,19 +254,19 @@ const QList<QPair<QLocale::Country, QString> > TelephoneNumbers::mCountryCodes =
// -----------------------------------------------------------------------------
TelephoneNumbers::TelephoneNumbers (QObject *parent) : QAbstractListModel(parent) {}
TelephoneNumbersModel::TelephoneNumbersModel (QObject *parent) : QAbstractListModel(parent) {}
int TelephoneNumbers::rowCount (const QModelIndex &) const {
int TelephoneNumbersModel::rowCount (const QModelIndex &) const {
return mCountryCodes.count();
}
QHash<int, QByteArray> TelephoneNumbers::roleNames () const {
QHash<int, QByteArray> TelephoneNumbersModel::roleNames () const {
QHash<int, QByteArray> roles;
roles[Qt::DisplayRole] = "$phoneNumber";
return roles;
}
QVariant TelephoneNumbers::data (const QModelIndex &index, int role) const {
QVariant TelephoneNumbersModel::data (const QModelIndex &index, int role) const {
int row = index.row();
if (!index.isValid() || row < 0 || row >= mCountryCodes.count())
......@@ -272,11 +274,24 @@ QVariant TelephoneNumbers::data (const QModelIndex &index, int role) const {
if (role == Qt::DisplayRole) {
const QPair<QLocale::Country, QString> &countryCode = mCountryCodes[row];
QVariantMap map;
QVariantMap map;
map["countryCode"] = countryCode.second;
map["countryName"] = QLocale::countryToString(countryCode.first);
map["countryName"] = QStringLiteral("%1 (+%2)")
.arg(QLocale::countryToString(countryCode.first))
.arg(countryCode.second);
return map;
}
return QVariant();
}
int TelephoneNumbersModel::getDefaultIndex () const {
QLocale::Country country = QLocale().country();
const auto it = find_if(
mCountryCodes.cbegin(), mCountryCodes.cend(), [&country](const QPair<QLocale::Country, QString> &pair) {
return country == pair.first;
}
);
return it != mCountryCodes.cend() ? static_cast<int>(distance(mCountryCodes.cbegin(), it)) : 0;
}
/*
* TelephoneNumbers.hpp
* TelephoneNumbersModel.hpp
* Copyright (C) 2017 Belledonne Communications, Grenoble, France
*
* This program is free software; you can redistribute it and/or
......@@ -20,18 +20,22 @@
* Author: Ronan Abhamon
*/
#ifndef TELEPHONE_NUMBERS_H_
#define TELEPHONE_NUMBERS_H_
#ifndef TELEPHONE_NUMBERS_MODEL_H_
#define TELEPHONE_NUMBERS_MODEL_H_
#include <QAbstractListModel>
#include <QLocale>
// =============================================================================
class TelephoneNumbers : public QAbstractListModel {
class TelephoneNumbersModel : public QAbstractListModel {
Q_OBJECT;
Q_PROPERTY(int defaultIndex READ getDefaultIndex CONSTANT);
public:
TelephoneNumbers (QObject *parent = Q_NULLPTR);
~TelephoneNumbers () = default;
TelephoneNumbersModel (QObject *parent = Q_NULLPTR);
~TelephoneNumbersModel () = default;
int rowCount (const QModelIndex &index = QModelIndex()) const override;
......@@ -39,7 +43,9 @@ public:
QVariant data (const QModelIndex &index, int role = Qt::DisplayRole) const override;
private:
int getDefaultIndex () const;
static const QList<QPair<QLocale::Country, QString> > mCountryCodes;
};
#endif // ifndef TELEPHONE_NUMBERS_H_
#endif // ifndef TELEPHONE_NUMBERS_MODEL_H_
......@@ -34,6 +34,27 @@ function getSelectedEntryIcon () {
) || ''
}
function getSelectedEntryText () {
if (comboBox.currentIndex < 0) {
return ''
}
var text = comboBox.displayText
if (text.length > 0) {
return text
}
// With a `QAbstractListModel`, `text` is empty. QML bug?
var model = comboBox.model
if (model.data) {
var item = model.data(model.index(comboBox.currentIndex, 0))
var textRole = comboBox.textRole
return textRole.length > 0 ? item[textRole] : item
}
return ''
}
function getEntryIcon (item) {
var iconRole = comboBox.iconRole
if (iconRole == null || iconRole.length === 0) {
......
......@@ -53,7 +53,7 @@ ComboBox {
font.pointSize: ComboBoxStyle.contentItem.text.fontSize
rightPadding: comboBox.indicator.width + comboBox.spacing
text: comboBox.displayText
text: Logic.getSelectedEntryText()
}
}
......
......@@ -9,55 +9,101 @@ AssistantAbstractView {
id: view
property alias usernameError: username.error
property alias phoneNumberError: phoneNumber.error
function setCountryCode (index) {
var model = country.model
assistantModel.countryCode = model.data(model.index(index, 0)).countryCode
}
title: qsTr('createLinphoneSipAccountTitle')
Form {
mainAction: requestBlock.execute
mainActionEnabled: phoneNumber.text.length
&& username.text.length
&& !phoneNumberError.length
&& !usernameError.length
&& !requestBlock.loading
mainActionLabel: qsTr('confirmAction')
Column {
anchors.fill: parent
dealWithErrors: true
orientation: Qt.Vertical
Form {
dealWithErrors: true
orientation: Qt.Vertical
width: parent.width
FormLine {
FormGroup {
label: qsTr('countryLabel')
ComboBox {
id: country
currentIndex: model.defaultIndex
model: TelephoneNumbersModel {}
textRole: 'countryName'
onActivated: {
view.setCountryCode(index)
var text = phoneNumber.text
if (text.length > 0) {
assistantModel.phoneNumber = text
}
}
}
}
}
FormLine {
FormGroup {
label: qsTr('phoneNumberLabel')
TextField {
id: phoneNumber
FormLine {
FormGroup {
label: qsTr('countryLabel')
inputMethodHints: Qt.ImhDialableCharactersOnly
ComboBox {
id: country
onTextChanged: assistantModel.phoneNumber = text
}
}
}
}
FormLine {
FormGroup {
label: qsTr('phoneNumberLabel')
FormLine {
FormGroup {
label: qsTr('usernameLabel')
TextField {
id: username
TextField {
id: phoneNumber
onTextChanged: assistantModel.username = text
}
}
}
}
FormLine {
FormGroup {
label: qsTr('usernameLabel')
TextField {
id: username
FormLine {
FormGroup {
label: qsTr('displayNameLabel')
onTextChanged: assistantModel.username = text
TextField {
onTextChanged: assistantModel.displayName = text
}
}
}
}
FormLine {
FormGroup {
label: qsTr('displayNameLabel')
RequestBlock {
id: requestBlock
TextField {
onTextChanged: assistantModel.displayName = text
}
action: function () {
window.lockView({
descriptionText: qsTr('quitWarning')
})
assistantModel.create()
}
width: parent.width
}
}
......@@ -70,12 +116,19 @@ AssistantAbstractView {
configFilename: 'create-linphone-sip-account.rc'
Component.onCompleted: view.setCountryCode(country.model.defaultIndex)
onPhoneNumberChanged: phoneNumberError = error
onUsernameChanged: usernameError = error
onCreateStatusChanged: {
requestBlock.stop(error)
if (!error.length) {
// TODO.
assistant.pushView('ActivateLinphoneSipAccountWithPhoneNumber', {
assistantModel: assistantModel
})
} else {
window.unlockView()
}
}
}
......
......@@ -40,7 +40,7 @@ DialogPlus {
ComboBox {
currentIndex: Utils.findIndex(OwnPresenceModel.statuses, function (status) {
return status.presenceStatus == OwnPresenceModel.presenceStatus
return status.presenceStatus === OwnPresenceModel.presenceStatus
})
model: OwnPresenceModel.statuses
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment