Commit d301a906 authored by Ronan Abhamon's avatar Ronan Abhamon

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

parent 6a051cb2
...@@ -128,7 +128,7 @@ set(SOURCES ...@@ -128,7 +128,7 @@ set(SOURCES
src/components/sip-addresses/SipAddressesProxyModel.cpp src/components/sip-addresses/SipAddressesProxyModel.cpp
src/components/sip-addresses/SipAddressObserver.cpp src/components/sip-addresses/SipAddressObserver.cpp
src/components/sound-player/SoundPlayer.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/text-to-speech/TextToSpeech.cpp
src/components/timeline/TimelineModel.cpp src/components/timeline/TimelineModel.cpp
src/externals/single-application/SingleApplication.cpp src/externals/single-application/SingleApplication.cpp
...@@ -176,7 +176,7 @@ set(HEADERS ...@@ -176,7 +176,7 @@ set(HEADERS
src/components/sip-addresses/SipAddressesProxyModel.hpp src/components/sip-addresses/SipAddressesProxyModel.hpp
src/components/sip-addresses/SipAddressObserver.hpp src/components/sip-addresses/SipAddressObserver.hpp
src/components/sound-player/SoundPlayer.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/text-to-speech/TextToSpeech.hpp
src/components/timeline/TimelineModel.hpp src/components/timeline/TimelineModel.hpp
src/externals/single-application/SingleApplication.hpp src/externals/single-application/SingleApplication.hpp
......
...@@ -150,6 +150,22 @@ ...@@ -150,6 +150,22 @@
<source>emailActivationFailed</source> <source>emailActivationFailed</source>
<translation>Please verify that you have validated your account or try again.</translation> <translation>Please verify that you have validated your account or try again.</translation>
</message> </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>
<context> <context>
<name>AuthenticationRequest</name> <name>AuthenticationRequest</name>
...@@ -605,6 +621,14 @@ Server url not configured.</translation> ...@@ -605,6 +621,14 @@ Server url not configured.</translation>
<source>displayNameLabel</source> <source>displayNameLabel</source>
<translation>Display name (optional)</translation> <translation>Display name (optional)</translation>
</message> </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>
<context> <context>
<name>DroppableTextArea</name> <name>DroppableTextArea</name>
......
...@@ -150,6 +150,22 @@ ...@@ -150,6 +150,22 @@
<source>emailActivationFailed</source> <source>emailActivationFailed</source>
<translation>Merci de vérifier que vous avez validé votre compte ou réessayez plus tard.</translation> <translation>Merci de vérifier que vous avez validé votre compte ou réessayez plus tard.</translation>
</message> </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>
<context> <context>
<name>AuthenticationRequest</name> <name>AuthenticationRequest</name>
...@@ -605,6 +621,14 @@ Url du serveur non configurée.</translation> ...@@ -605,6 +621,14 @@ Url du serveur non configurée.</translation>
<source>displayNameLabel</source> <source>displayNameLabel</source>
<translation>Nom d&apos;affichage (optionnel)</translation> <translation>Nom d&apos;affichage (optionnel)</translation>
</message> </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>
<context> <context>
<name>DroppableTextArea</name> <name>DroppableTextArea</name>
......
...@@ -353,7 +353,7 @@ void App::registerTypes () { ...@@ -353,7 +353,7 @@ void App::registerTypes () {
registerType<ContactsListProxyModel>("ContactsListProxyModel"); registerType<ContactsListProxyModel>("ContactsListProxyModel");
registerType<SipAddressesProxyModel>("SipAddressesProxyModel"); registerType<SipAddressesProxyModel>("SipAddressesProxyModel");
registerType<SoundPlayer>("SoundPlayer"); registerType<SoundPlayer>("SoundPlayer");
registerType<TelephoneNumbers>("TelephoneNumbers"); registerType<TelephoneNumbersModel>("TelephoneNumbersModel");
registerSingletonType<AudioCodecsModel>("AudioCodecsModel"); registerSingletonType<AudioCodecsModel>("AudioCodecsModel");
registerSingletonType<Clipboard>("Clipboard"); registerSingletonType<Clipboard>("Clipboard");
......
...@@ -40,7 +40,7 @@ ...@@ -40,7 +40,7 @@
#include "settings/AccountSettingsModel.hpp" #include "settings/AccountSettingsModel.hpp"
#include "sip-addresses/SipAddressesProxyModel.hpp" #include "sip-addresses/SipAddressesProxyModel.hpp"
#include "sound-player/SoundPlayer.hpp" #include "sound-player/SoundPlayer.hpp"
#include "telephone-numbers/TelephoneNumbers.hpp" #include "telephone-numbers/TelephoneNumbersModel.hpp"
#include "text-to-speech/TextToSpeech.hpp" #include "text-to-speech/TextToSpeech.hpp"
#include "timeline/TimelineModel.hpp" #include "timeline/TimelineModel.hpp"
......
...@@ -180,6 +180,7 @@ void AssistantModel::login () { ...@@ -180,6 +180,7 @@ void AssistantModel::login () {
} }
void AssistantModel::reset () { void AssistantModel::reset () {
mCountryCode = "";
mAccountCreator->reset(); mAccountCreator->reset();
emit emailChanged("", ""); emit emailChanged("", "");
...@@ -246,15 +247,43 @@ void AssistantModel::setPassword (const QString &password) { ...@@ -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 { QString AssistantModel::getPhoneNumber () const {
return ::Utils::coreStringToAppString(mAccountCreator->getPhoneNumber()); return ::Utils::coreStringToAppString(mAccountCreator->getPhoneNumber());
} }
void AssistantModel::setPhoneNumber (const QString &phoneNumber) { 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; 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); emit phoneNumberChanged(phoneNumber, error);
} }
......
...@@ -35,6 +35,7 @@ class AssistantModel : public QObject { ...@@ -35,6 +35,7 @@ class AssistantModel : public QObject {
Q_PROPERTY(QString email READ getEmail WRITE setEmail NOTIFY emailChanged); Q_PROPERTY(QString email READ getEmail WRITE setEmail NOTIFY emailChanged);
Q_PROPERTY(QString password READ getPassword WRITE setPassword NOTIFY passwordChanged); 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 phoneNumber READ getPhoneNumber WRITE setPhoneNumber NOTIFY phoneNumberChanged);
Q_PROPERTY(QString username READ getUsername WRITE setUsername NOTIFY usernameChanged); Q_PROPERTY(QString username READ getUsername WRITE setUsername NOTIFY usernameChanged);
Q_PROPERTY(QString displayName READ getDisplayName WRITE setDisplayName NOTIFY displayNameChanged); Q_PROPERTY(QString displayName READ getDisplayName WRITE setDisplayName NOTIFY displayNameChanged);
...@@ -52,6 +53,7 @@ public: ...@@ -52,6 +53,7 @@ public:
signals: signals:
void emailChanged (const QString &email, const QString &error); void emailChanged (const QString &email, const QString &error);
void passwordChanged (const QString &password, 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 phoneNumberChanged (const QString &phoneNumber, const QString &error);
void usernameChanged (const QString &username, const QString &error); void usernameChanged (const QString &username, const QString &error);
void displayNameChanged (const QString &displayName, const QString &error); void displayNameChanged (const QString &displayName, const QString &error);
...@@ -69,6 +71,9 @@ private: ...@@ -69,6 +71,9 @@ private:
QString getPassword () const; QString getPassword () const;
void setPassword (const QString &password); void setPassword (const QString &password);
QString getCountryCode () const;
void setCountryCode (const QString &countryCode);
QString getPhoneNumber () const; QString getPhoneNumber () const;
void setPhoneNumber (const QString &phoneNumber); void setPhoneNumber (const QString &phoneNumber);
...@@ -83,6 +88,7 @@ private: ...@@ -83,6 +88,7 @@ private:
QString mapAccountCreatorUsernameStatusToString (linphone::AccountCreatorUsernameStatus status) const; QString mapAccountCreatorUsernameStatusToString (linphone::AccountCreatorUsernameStatus status) const;
QString mCountryCode;
QString mConfigFilename; QString mConfigFilename;
std::shared_ptr<linphone::AccountCreator> mAccountCreator; std::shared_ptr<linphone::AccountCreator> mAccountCreator;
......
/* /*
* TelephoneNumbers.cpp * TelephoneNumbersModel.cpp
* Copyright (C) 2017 Belledonne Communications, Grenoble, France * Copyright (C) 2017 Belledonne Communications, Grenoble, France
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
...@@ -20,11 +20,13 @@ ...@@ -20,11 +20,13 @@
* Author: Ronan Abhamon * 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::Afghanistan, "93" },
{ QLocale::Albania, "355" }, { QLocale::Albania, "355" },
{ QLocale::Algeria, "213" }, { QLocale::Algeria, "213" },
...@@ -252,19 +254,19 @@ const QList<QPair<QLocale::Country, QString> > TelephoneNumbers::mCountryCodes = ...@@ -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(); return mCountryCodes.count();
} }
QHash<int, QByteArray> TelephoneNumbers::roleNames () const { QHash<int, QByteArray> TelephoneNumbersModel::roleNames () const {
QHash<int, QByteArray> roles; QHash<int, QByteArray> roles;
roles[Qt::DisplayRole] = "$phoneNumber"; roles[Qt::DisplayRole] = "$phoneNumber";
return roles; return roles;
} }
QVariant TelephoneNumbers::data (const QModelIndex &index, int role) const { QVariant TelephoneNumbersModel::data (const QModelIndex &index, int role) const {
int row = index.row(); int row = index.row();
if (!index.isValid() || row < 0 || row >= mCountryCodes.count()) if (!index.isValid() || row < 0 || row >= mCountryCodes.count())
...@@ -272,11 +274,24 @@ QVariant TelephoneNumbers::data (const QModelIndex &index, int role) const { ...@@ -272,11 +274,24 @@ QVariant TelephoneNumbers::data (const QModelIndex &index, int role) const {
if (role == Qt::DisplayRole) { if (role == Qt::DisplayRole) {
const QPair<QLocale::Country, QString> &countryCode = mCountryCodes[row]; const QPair<QLocale::Country, QString> &countryCode = mCountryCodes[row];
QVariantMap map;
QVariantMap map;
map["countryCode"] = countryCode.second; 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(); 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 * Copyright (C) 2017 Belledonne Communications, Grenoble, France
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
...@@ -20,18 +20,22 @@ ...@@ -20,18 +20,22 @@
* Author: Ronan Abhamon * Author: Ronan Abhamon
*/ */
#ifndef TELEPHONE_NUMBERS_H_ #ifndef TELEPHONE_NUMBERS_MODEL_H_
#define TELEPHONE_NUMBERS_H_ #define TELEPHONE_NUMBERS_MODEL_H_
#include <QAbstractListModel> #include <QAbstractListModel>
#include <QLocale> #include <QLocale>
// ============================================================================= // =============================================================================
class TelephoneNumbers : public QAbstractListModel { class TelephoneNumbersModel : public QAbstractListModel {
Q_OBJECT;
Q_PROPERTY(int defaultIndex READ getDefaultIndex CONSTANT);
public: public:
TelephoneNumbers (QObject *parent = Q_NULLPTR); TelephoneNumbersModel (QObject *parent = Q_NULLPTR);
~TelephoneNumbers () = default; ~TelephoneNumbersModel () = default;
int rowCount (const QModelIndex &index = QModelIndex()) const override; int rowCount (const QModelIndex &index = QModelIndex()) const override;
...@@ -39,7 +43,9 @@ public: ...@@ -39,7 +43,9 @@ public:
QVariant data (const QModelIndex &index, int role = Qt::DisplayRole) const override; QVariant data (const QModelIndex &index, int role = Qt::DisplayRole) const override;
private: private:
int getDefaultIndex () const;
static const QList<QPair<QLocale::Country, QString> > mCountryCodes; 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 () { ...@@ -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) { function getEntryIcon (item) {
var iconRole = comboBox.iconRole var iconRole = comboBox.iconRole
if (iconRole == null || iconRole.length === 0) { if (iconRole == null || iconRole.length === 0) {
......
...@@ -53,7 +53,7 @@ ComboBox { ...@@ -53,7 +53,7 @@ ComboBox {
font.pointSize: ComboBoxStyle.contentItem.text.fontSize font.pointSize: ComboBoxStyle.contentItem.text.fontSize
rightPadding: comboBox.indicator.width + comboBox.spacing rightPadding: comboBox.indicator.width + comboBox.spacing
text: comboBox.displayText text: Logic.getSelectedEntryText()
} }
} }
......
...@@ -9,55 +9,101 @@ AssistantAbstractView { ...@@ -9,55 +9,101 @@ AssistantAbstractView {
id: view id: view
property alias usernameError: username.error 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') 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 anchors.fill: parent
dealWithErrors: true Form {
orientation: Qt.Vertical 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 { inputMethodHints: Qt.ImhDialableCharactersOnly
FormGroup {
label: qsTr('countryLabel')
ComboBox { onTextChanged: assistantModel.phoneNumber = text
id: country }
} }
} }
}
FormLine { FormLine {
FormGroup { FormGroup {
label: qsTr('phoneNumberLabel') label: qsTr('usernameLabel')
TextField {
id: username
TextField { onTextChanged: assistantModel.username = text
id: phoneNumber }
} }
} }
}
FormLine {
FormGroup {
label: qsTr('usernameLabel')
TextField { FormLine {
id: username FormGroup {
label: qsTr('displayNameLabel')
onTextChanged: assistantModel.username = text TextField {
onTextChanged: assistantModel.displayName = text
}
} }
} }
} }
FormLine { RequestBlock {
FormGroup { id: requestBlock
label: qsTr('displayNameLabel')
TextField { action: function () {
onTextChanged: assistantModel.displayName = text window.lockView({
} descriptionText: qsTr('quitWarning')
})
assistantModel.create()
} }
width: parent.width
} }
} }
...@@ -70,12 +116,19 @@ AssistantAbstractView { ...@@ -70,12 +116,19 @@ AssistantAbstractView {
configFilename: 'create-linphone-sip-account.rc' configFilename: 'create-linphone-sip-account.rc'
Component.onCompleted: view.setCountryCode(country.model.defaultIndex)
onPhoneNumberChanged: phoneNumberError = error
onUsernameChanged: usernameError = error onUsernameChanged: usernameError = error
onCreateStatusChanged: { onCreateStatusChanged: {
requestBlock.stop(error) requestBlock.stop(error)
if (!error.length) { if (!error.length) {
// TODO. assistant.pushView('ActivateLinphoneSipAccountWithPhoneNumber', {
assistantModel: assistantModel
})
} else {
window.unlockView()
} }
} }
} }
......
...@@ -40,7 +40,7 @@ DialogPlus { ...@@ -40,7 +40,7 @@ DialogPlus {
ComboBox { ComboBox {
currentIndex: Utils.findIndex(OwnPresenceModel.statuses, function (status) { currentIndex: Utils.findIndex(OwnPresenceModel.statuses, function (status) {
return status.presenceStatus == OwnPresenceModel.presenceStatus return status.presenceStatus === OwnPresenceModel.presenceStatus
}) })
model: OwnPresenceModel.statuses 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