FIXES:
error text display show welcome page on first launch only try to fix crash in variant object (to fix properly) forbid connection if account already connected contacts list first row size + contact selected signal accounts layout rm layout rearrange warning login error messages layout trust circle avatar no error message on status ok busy indicator on login
This commit is contained in:
parent
f9abfb9fbc
commit
517c6b96a5
23 changed files with 304 additions and 144 deletions
|
|
@ -81,6 +81,7 @@ void App::init() {
|
|||
// Core. Manage the logger so it must be instantiate at first.
|
||||
auto coreModel = CoreModel::create("", mLinphoneThread);
|
||||
connect(mLinphoneThread, &QThread::started, coreModel.get(), &CoreModel::start);
|
||||
mFirstLaunch = mSettings.value("firstLaunch", 1).toInt();
|
||||
// Console Commands
|
||||
createCommandParser();
|
||||
mParser->parse(this->arguments());
|
||||
|
|
@ -264,6 +265,17 @@ void App::closeCallsWindow() {
|
|||
}
|
||||
}
|
||||
|
||||
void App::setFirstLaunch(bool first) {
|
||||
if (mFirstLaunch != first) {
|
||||
mFirstLaunch = first;
|
||||
mSettings.setValue("firstLaunch", first);
|
||||
}
|
||||
}
|
||||
|
||||
bool App::getFirstLaunch() const {
|
||||
return mFirstLaunch;
|
||||
}
|
||||
|
||||
QQuickWindow *App::getMainWindow() {
|
||||
return mMainWindow;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include <QCommandLineParser>
|
||||
#include <QQmlApplicationEngine>
|
||||
#include <QSettings>
|
||||
#include <QSharedPointer>
|
||||
|
||||
#include "core/singleapplication/singleapplication.h"
|
||||
|
|
@ -93,6 +94,9 @@ public:
|
|||
QQuickWindow *getCallsWindow(QVariant callGui);
|
||||
void closeCallsWindow();
|
||||
|
||||
bool getFirstLaunch() const;
|
||||
void setFirstLaunch(bool first);
|
||||
|
||||
QQuickWindow *getMainWindow();
|
||||
|
||||
QQmlApplicationEngine *mEngine = nullptr;
|
||||
|
|
@ -108,6 +112,8 @@ private:
|
|||
Notifier *mNotifier = nullptr;
|
||||
QQuickWindow *mMainWindow = nullptr;
|
||||
QQuickWindow *mCallsWindow = nullptr;
|
||||
QSettings mSettings;
|
||||
bool mFirstLaunch = true;
|
||||
// TODO : changer ce count lorsqu'on aura liste d'appels
|
||||
int callsCount = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -49,28 +49,48 @@ void LoginPage::setRegistrationState(linphone::RegistrationState status) {
|
|||
}
|
||||
}
|
||||
|
||||
QString LoginPage::getErrorMessage() const {
|
||||
return mErrorMessage;
|
||||
}
|
||||
|
||||
void LoginPage::setErrorMessage(const QString &error) {
|
||||
// force signal emission to display the error even if it doesn't change
|
||||
mErrorMessage = error;
|
||||
emit errorMessageChanged();
|
||||
}
|
||||
|
||||
void LoginPage::login(const QString &username, const QString &password) {
|
||||
App::postModelAsync([=]() {
|
||||
QString *error = new QString(tr("Le couple identifiant mot de passe ne correspont pas"));
|
||||
// Create on Model thread.
|
||||
AccountManager *accountManager = new AccountManager();
|
||||
connect(accountManager, &AccountManager::registrationStateChanged, this,
|
||||
[accountManager, this](linphone::RegistrationState state) mutable {
|
||||
[accountManager, this, error](linphone::RegistrationState state) mutable {
|
||||
// View thread
|
||||
setRegistrationState(state);
|
||||
switch (state) {
|
||||
case linphone::RegistrationState::Ok:
|
||||
case linphone::RegistrationState::Cleared:
|
||||
case linphone::RegistrationState::Failed: {
|
||||
emit accountManager->errorMessageChanged(*error);
|
||||
accountManager->deleteLater();
|
||||
break;
|
||||
}
|
||||
case linphone::RegistrationState::Ok: {
|
||||
emit accountManager->errorMessageChanged("");
|
||||
break;
|
||||
}
|
||||
case linphone::RegistrationState::Cleared:
|
||||
case linphone::RegistrationState::None:
|
||||
case linphone::RegistrationState::Progress:
|
||||
case linphone::RegistrationState::Refreshing:
|
||||
break;
|
||||
}
|
||||
});
|
||||
if (!accountManager->login(username, password)) {
|
||||
connect(accountManager, &AccountManager::errorMessageChanged, this,
|
||||
[this](QString errorMessage) { setErrorMessage(errorMessage); });
|
||||
|
||||
connect(accountManager, &AccountManager::destroyed, [error]() { delete error; });
|
||||
|
||||
if (!accountManager->login(username, password, error)) {
|
||||
emit accountManager->registrationStateChanged(linphone::RegistrationState::Failed);
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -33,17 +33,23 @@ public:
|
|||
~LoginPage();
|
||||
|
||||
Q_PROPERTY(linphone::RegistrationState registrationState READ getRegistrationState NOTIFY registrationStateChanged)
|
||||
Q_PROPERTY(QString errorMessage READ getErrorMessage NOTIFY errorMessageChanged)
|
||||
|
||||
Q_INVOKABLE void login(const QString &username, const QString &password);
|
||||
|
||||
linphone::RegistrationState getRegistrationState() const;
|
||||
void setRegistrationState(linphone::RegistrationState status);
|
||||
|
||||
QString getErrorMessage() const;
|
||||
void setErrorMessage(const QString &error);
|
||||
|
||||
signals:
|
||||
void registrationStateChanged();
|
||||
void errorMessageChanged();
|
||||
|
||||
private:
|
||||
linphone::RegistrationState mRegistrationState = linphone::RegistrationState::None;
|
||||
QString mErrorMessage;
|
||||
|
||||
DECLARE_ABSTRACT_OBJECT
|
||||
};
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ std::shared_ptr<linphone::Account> AccountManager::createAccount(const QString &
|
|||
return core->createAccount(core->createAccountParams());
|
||||
}
|
||||
|
||||
bool AccountManager::login(QString username, QString password) {
|
||||
bool AccountManager::login(QString username, QString password, QString *errorMessage) {
|
||||
mustBeInLinphoneThread(log().arg(Q_FUNC_INFO));
|
||||
auto core = CoreModel::getInstance()->getCore();
|
||||
auto factory = linphone::Factory::get();
|
||||
|
|
@ -56,13 +56,23 @@ bool AccountManager::login(QString username, QString password) {
|
|||
auto params = account->getParams()->clone();
|
||||
// Sip address.
|
||||
auto identity = params->getIdentityAddress()->clone();
|
||||
|
||||
if (mAccountModel) return false;
|
||||
auto accounts = core->getAccountList();
|
||||
for (auto account : accounts) {
|
||||
if (account->getParams()->getIdentityAddress()->getUsername() == Utils::appStringToCoreString(username)) {
|
||||
*errorMessage = tr("Le compte est déjà connecté");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
identity->setUsername(Utils::appStringToCoreString(username));
|
||||
if (params->setIdentityAddress(identity)) {
|
||||
qWarning() << log()
|
||||
.arg(QStringLiteral("Unable to set identity address: `%1`."))
|
||||
.arg(Utils::coreStringToAppString(identity->asStringUriOnly()));
|
||||
*errorMessage =
|
||||
tr("Unable to set identity address: `%1`.").arg(Utils::coreStringToAppString(identity->asStringUriOnly()));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ public:
|
|||
AccountManager(QObject *parent = nullptr);
|
||||
~AccountManager();
|
||||
|
||||
bool login(QString username, QString password);
|
||||
bool login(QString username, QString password, QString *errorMessage = nullptr);
|
||||
|
||||
std::shared_ptr<linphone::Account> createAccount(const QString &assistantFile);
|
||||
|
||||
|
|
@ -42,6 +42,7 @@ public:
|
|||
const std::string &message);
|
||||
signals:
|
||||
void registrationStateChanged(linphone::RegistrationState state);
|
||||
void errorMessageChanged(const QString &errorMessage);
|
||||
|
||||
private:
|
||||
std::shared_ptr<AccountModel> mAccountModel;
|
||||
|
|
|
|||
|
|
@ -37,10 +37,16 @@ VariantObject::VariantObject(QVariant defaultValue, QObject *parent) {
|
|||
new SafeConnection<SafeObject, SafeObject>(mCoreObject, mModelObject), &QObject::deleteLater);
|
||||
|
||||
mConnection->makeConnectToCore(&SafeObject::setValue, [this](QVariant value) {
|
||||
mConnection->invokeToModel([this, value]() { mModelObject->onSetValue(value); });
|
||||
mConnection->invokeToModel([this, value]() {
|
||||
// TODO : fix this properly
|
||||
if (mModelObject) mModelObject->onSetValue(value);
|
||||
});
|
||||
});
|
||||
mConnection->makeConnectToModel(&SafeObject::setValue, [this](QVariant value) {
|
||||
mConnection->invokeToCore([this, value]() { mCoreObject->onSetValue(value); });
|
||||
mConnection->invokeToCore([this, value]() {
|
||||
// TODO : fix this properly
|
||||
if (mCoreObject) mCoreObject->onSetValue(value);
|
||||
});
|
||||
});
|
||||
mConnection->makeConnectToModel(&SafeObject::valueChanged, [this](QVariant value) {
|
||||
mConnection->invokeToCore([this, value]() { mCoreObject->valueChanged(value); });
|
||||
|
|
|
|||
|
|
@ -315,7 +315,6 @@ Q_DECLARE_METATYPE(LinphoneEnums::FriendCapability)
|
|||
Q_DECLARE_METATYPE(LinphoneEnums::MediaEncryption)
|
||||
Q_DECLARE_METATYPE(LinphoneEnums::ParticipantDeviceState)
|
||||
Q_DECLARE_METATYPE(LinphoneEnums::RecorderState)
|
||||
Q_DECLARE_METATYPE(LinphoneEnums::RegistrationState)
|
||||
Q_DECLARE_METATYPE(LinphoneEnums::TunnelMode)
|
||||
Q_DECLARE_METATYPE(LinphoneEnums::TransportType)
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -98,6 +98,15 @@ VariantObject *Utils::createCall(const QString &sipAddress,
|
|||
|
||||
return data;
|
||||
}
|
||||
|
||||
void Utils::setFirstLaunch(bool first) {
|
||||
App::getInstance()->setFirstLaunch(first);
|
||||
}
|
||||
|
||||
bool Utils::getFirstLaunch() {
|
||||
return App::getInstance()->getFirstLaunch();
|
||||
}
|
||||
|
||||
void Utils::openCallsWindow(CallGui *call) {
|
||||
if (call) App::getInstance()->getCallsWindow(QVariant::fromValue(call))->show();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,6 +57,8 @@ public:
|
|||
Q_INVOKABLE static VariantObject *createCall(const QString &sipAddress,
|
||||
const QString &prepareTransfertAddress = "",
|
||||
const QHash<QString, QString> &headers = {});
|
||||
Q_INVOKABLE static void setFirstLaunch(bool first);
|
||||
Q_INVOKABLE static bool getFirstLaunch();
|
||||
Q_INVOKABLE static void openCallsWindow(CallGui *call);
|
||||
Q_INVOKABLE static QQuickWindow *getMainWindow();
|
||||
Q_INVOKABLE static QQuickWindow *getCallsWindow(CallGui *callGui);
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import QtQuick 2.15
|
|||
import QtQuick.Layouts 1.3
|
||||
import QtQuick.Controls
|
||||
import Linphone
|
||||
//import UI 1.0
|
||||
import UtilsCpp 1.0
|
||||
|
||||
Window {
|
||||
id: mainWindow
|
||||
|
|
@ -10,6 +10,7 @@ Window {
|
|||
height: 982 * DefaultStyle.dp
|
||||
visible: true
|
||||
title: qsTr("Linphone")
|
||||
// TODO : handle this bool when security mode is implemented
|
||||
property bool firstConnection: true
|
||||
|
||||
function goToNewCall() {
|
||||
|
|
@ -21,25 +22,23 @@ Window {
|
|||
mainWindowStackView.currentItem.transferCallSucceed()
|
||||
}
|
||||
|
||||
AccountProxy{
|
||||
AccountProxy {
|
||||
// TODO : change this so it does not display the main page for one second
|
||||
// when we fail trying to connect the first account (account is added and
|
||||
// removed shortly after)
|
||||
id: accountProxy
|
||||
onHaveAccountChanged: {
|
||||
if(haveAccount)
|
||||
mainWindowStackView.replace(mainPage, StackView.Immediate)
|
||||
else
|
||||
mainWindowStackView.replace(loginPage, StackView.Immediate)
|
||||
}
|
||||
}
|
||||
StackView {
|
||||
id: mainWindowStackView
|
||||
anchors.fill: parent
|
||||
initialItem: accountProxy.haveAccount ? mainPage : welcomePage
|
||||
initialItem: accountProxy.haveAccount ? mainPage : UtilsCpp.getFirstLaunch() ? welcomePage : loginPage
|
||||
}
|
||||
Component {
|
||||
id: welcomePage
|
||||
WelcomePage {
|
||||
onStartButtonPressed: {
|
||||
mainWindowStackView.replace(loginPage)// Replacing the first item will destroy the old.
|
||||
UtilsCpp.setFirstLaunch(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -51,11 +50,7 @@ Window {
|
|||
onUseSIPButtonClicked: mainWindowStackView.push(sipLoginPage)
|
||||
onGoToRegister: mainWindowStackView.replace(registerPage)
|
||||
onConnectionSucceed: {
|
||||
if (mainWindow.firstConnection) {
|
||||
mainWindowStackView.replace(securityModePage)
|
||||
} else {
|
||||
mainWindowStackView.replace(mainPage)
|
||||
}
|
||||
mainWindowStackView.replace(mainPage)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -66,11 +61,7 @@ Window {
|
|||
onGoToRegister: mainWindowStackView.replace(registerPage)
|
||||
|
||||
onConnectionSucceed: {
|
||||
if (mainWindow.firstConnection) {
|
||||
mainWindowStackView.replace(securityModePage)
|
||||
} else {
|
||||
mainWindowStackView.replace(mainPage)
|
||||
}
|
||||
mainWindowStackView.replace(mainPage)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -92,7 +83,9 @@ Window {
|
|||
Component {
|
||||
id: securityModePage
|
||||
SecurityModePage {
|
||||
id: securePage
|
||||
onModeSelected: (index) => {
|
||||
// TODO : connect to cpp part when ready
|
||||
var selectedMode = index == 0 ? "chiffrement" : "interoperable"
|
||||
console.debug("[SelectMode]User: User selected mode " + selectedMode)
|
||||
mainWindowStackView.replace(mainPage)
|
||||
|
|
@ -103,7 +96,7 @@ Window {
|
|||
id: mainPage
|
||||
MainLayout {
|
||||
onAddAccountRequest: mainWindowStackView.replace(loginPage)
|
||||
// StackView.onActivated: connectionSecured(0) // TODO : connect to cpp part when ready
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -11,21 +11,23 @@ Item {
|
|||
id: mainItem
|
||||
width: 517 * DefaultStyle.dp
|
||||
readonly property int topPadding: 23 * DefaultStyle.dp
|
||||
readonly property int bottomPadding: 18 * DefaultStyle.dp
|
||||
readonly property int bottomPadding: 23 * DefaultStyle.dp
|
||||
readonly property int leftPadding: 32 * DefaultStyle.dp
|
||||
readonly property int rightPadding: 32 * DefaultStyle.dp
|
||||
readonly property int spacing: 16 * DefaultStyle.dp
|
||||
|
||||
signal addAccountRequest()
|
||||
|
||||
implicitHeight: list.contentHeight + topPadding + bottomPadding + 32 * DefaultStyle.dp + 1 + newAccountArea.height
|
||||
ColumnLayout{
|
||||
id: childLayout
|
||||
anchors.top: parent.top
|
||||
anchors.topMargin: mainItem.topPadding
|
||||
anchors.left: parent.left
|
||||
anchors.leftMargin: mainItem.leftPadding
|
||||
anchors.right: parent.right
|
||||
anchors.rightMargin: mainItem.rightPadding
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.bottomMargin: mainItem.bottomPadding
|
||||
ListView{
|
||||
id: list
|
||||
Layout.preferredHeight: contentHeight
|
||||
|
|
@ -69,8 +71,10 @@ Item {
|
|||
EffectImage {
|
||||
id: newAccount
|
||||
source: AppIcons.plusCircle
|
||||
Layout.fillHeight: true
|
||||
Layout.preferredWidth: height
|
||||
width: 32 * DefaultStyle.dp
|
||||
height: 32 * DefaultStyle.dp
|
||||
Layout.preferredWidth: 32 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 32 * DefaultStyle.dp
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
fillMode: Image.PreserveAspectFit
|
||||
colorizationColor: DefaultStyle.main2_500main
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ Item {
|
|||
Control.BusyIndicator {
|
||||
id: busyIndicator
|
||||
running: mainItem.visible
|
||||
anchors.centerIn: mainItem
|
||||
}
|
||||
MultiEffect {
|
||||
source: busyIndicator
|
||||
|
|
|
|||
|
|
@ -55,9 +55,9 @@ Item {
|
|||
}
|
||||
Repeater {
|
||||
id: adresses
|
||||
model: [{label: "SIP", address: startCallPopup.contact ? startCallPopup.contact.core.address : ""},
|
||||
{label: "Work", address: "06000000000"},
|
||||
{label: "Personal", address: "060000000"}
|
||||
model: [{label: "SIP", address: startCallPopup.contact ? startCallPopup.contact.core.address : ""}
|
||||
// {label: "Work", address: "06000000000"},
|
||||
// {label: "Personal", address: "060000000"}
|
||||
] //account.adresses
|
||||
Button {
|
||||
id: channel
|
||||
|
|
@ -235,6 +235,10 @@ Item {
|
|||
Layout.fillWidth: true
|
||||
id: contactList
|
||||
searchBarText: searchBar.text
|
||||
onContactSelected: (contact) => {
|
||||
startCallPopup.contact = contact
|
||||
startCallPopup.open()
|
||||
}
|
||||
}
|
||||
}
|
||||
ColumnLayout {
|
||||
|
|
@ -254,6 +258,10 @@ Item {
|
|||
sourceFlags: LinphoneEnums.MagicSearchSource.FavoriteFriends
|
||||
aggregationFlag: LinphoneEnums.MagicSearchAggregation.Friend
|
||||
}
|
||||
onContactSelected: (contact) => {
|
||||
startCallPopup.contact = contact
|
||||
startCallPopup.open()
|
||||
}
|
||||
}
|
||||
}
|
||||
Item {
|
||||
|
|
|
|||
|
|
@ -27,8 +27,32 @@ StackView{
|
|||
|| (contact && contact.core.pictureUri)
|
||||
|
||||
onHaveAvatarChanged: replace(haveAvatar ? avatar : initials, StackView.Immediate)
|
||||
|
||||
property bool secured: false
|
||||
|
||||
initialItem: haveAvatar ? avatar : initials
|
||||
|
||||
Rectangle {
|
||||
visible: mainItem.secured
|
||||
anchors.fill: mainItem.currentItem
|
||||
radius: mainItem.width / 2
|
||||
z: 1
|
||||
color: "transparent"
|
||||
border {
|
||||
width: 3 * DefaultStyle.dp
|
||||
color: DefaultStyle.info_500_main
|
||||
}
|
||||
Image {
|
||||
source: AppIcons.trusted
|
||||
x: mainItem.width / 7
|
||||
width: mainItem.width / 4.5
|
||||
height: width
|
||||
sourceSize.width: width
|
||||
sourceSize.height: height
|
||||
fillMode: Image.PreserveAspectFit
|
||||
anchors.bottom: parent.bottom
|
||||
}
|
||||
}
|
||||
Component{
|
||||
id: initials
|
||||
Rectangle {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import QtQuick
|
|||
import QtQuick.Effects
|
||||
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls as Control
|
||||
|
||||
|
||||
import Linphone
|
||||
|
|
@ -31,68 +32,76 @@ Rectangle{
|
|||
onClicked: mainItem.avatarClicked()
|
||||
}
|
||||
}
|
||||
ContactDescription{
|
||||
id: description
|
||||
Layout.fillWidth: true
|
||||
Item {
|
||||
Layout.preferredWidth: 200 * DefaultStyle.dp
|
||||
Layout.fillHeight: true
|
||||
Layout.leftMargin: 10 * DefaultStyle.dp
|
||||
account: mainItem.account
|
||||
}
|
||||
Item{
|
||||
id: registrationStatusItem
|
||||
Layout.preferredWidth: 97 * DefaultStyle.dp
|
||||
Layout.fillHeight: true
|
||||
Rectangle{
|
||||
id: registrationStatus
|
||||
anchors.left: parent.left
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
width: Math.min(text.implicitWidth + (2 * 8 * DefaultStyle.dp), registrationStatusItem.width)
|
||||
height: 24 * DefaultStyle.dp
|
||||
color: DefaultStyle.main2_200
|
||||
radius: 90 * DefaultStyle.dp
|
||||
Text{
|
||||
id: text
|
||||
anchors.fill: parent
|
||||
anchors.leftMargin: 8 * DefaultStyle.dp
|
||||
anchors.rightMargin: 8 * DefaultStyle.dp
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
visible: mainItem.account
|
||||
readonly property int mode : !mainItem.account || mainItem.account.core.registrationState == LinphoneEnums.RegistrationState.Ok
|
||||
? 0
|
||||
: mainItem.account.core.registrationState == LinphoneEnums.RegistrationState.Cleared || mainItem.account.core.registrationState == LinphoneEnums.RegistrationState.None
|
||||
? 1
|
||||
: mainItem.account.core.registrationState == LinphoneEnums.RegistrationState.Progress || mainItem.account.core.registrationState == LinphoneEnums.RegistrationState.Refreshing
|
||||
? 2
|
||||
: 3
|
||||
// Test texts
|
||||
//Timer{
|
||||
// running: true
|
||||
// interval: 1000
|
||||
// repeat: true
|
||||
// onTriggered: text.mode = (++text.mode) % 4
|
||||
//}
|
||||
font.weight: 300 * DefaultStyle.dp
|
||||
font.pixelSize: 12 * DefaultStyle.dp
|
||||
color: mode == 0
|
||||
? DefaultStyle.success_500main
|
||||
: mode == 1
|
||||
? DefaultStyle.warning_600
|
||||
: mode == 2
|
||||
? DefaultStyle.main2_500main
|
||||
: DefaultStyle.danger_500main
|
||||
text: mode == 0
|
||||
? 'Connecté'
|
||||
: mode == 1
|
||||
? 'Désactivé'
|
||||
: mode == 2
|
||||
? 'Connexion...'
|
||||
: 'Erreur'
|
||||
}
|
||||
Layout.rightMargin: 10 * DefaultStyle.dp
|
||||
ContactDescription{
|
||||
id: description
|
||||
anchors.fill: parent
|
||||
account: mainItem.account
|
||||
}
|
||||
}
|
||||
Control.Control {
|
||||
id: registrationStatusItem
|
||||
Layout.minimumWidth: 49 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 24 * DefaultStyle.dp
|
||||
topPadding: 4 * DefaultStyle.dp
|
||||
bottomPadding: 4 * DefaultStyle.dp
|
||||
leftPadding: 8 * DefaultStyle.dp
|
||||
rightPadding: 8 * DefaultStyle.dp
|
||||
Layout.preferredWidth: text.implicitWidth + (2 * 8 * DefaultStyle.dp)
|
||||
background: Rectangle{
|
||||
id: registrationStatus
|
||||
anchors.fill: parent
|
||||
color: DefaultStyle.main2_200
|
||||
radius: 90 * DefaultStyle.dp
|
||||
}
|
||||
contentItem: Text {
|
||||
id: text
|
||||
anchors.fill: parent
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
visible: mainItem.account
|
||||
property int mode : !mainItem.account || mainItem.account.core.registrationState == LinphoneEnums.RegistrationState.Ok
|
||||
? 0
|
||||
: mainItem.account.core.registrationState == LinphoneEnums.RegistrationState.Cleared || mainItem.account.core.registrationState == LinphoneEnums.RegistrationState.None
|
||||
? 1
|
||||
: mainItem.account.core.registrationState == LinphoneEnums.RegistrationState.Progress || mainItem.account.core.registrationState == LinphoneEnums.RegistrationState.Refreshing
|
||||
? 2
|
||||
: 3
|
||||
// Test texts
|
||||
// Timer{
|
||||
// running: true
|
||||
// interval: 1000
|
||||
// repeat: true
|
||||
// onTriggered: text.mode = (++text.mode) % 4
|
||||
// }
|
||||
font.weight: 300 * DefaultStyle.dp
|
||||
font.pixelSize: 12 * DefaultStyle.dp
|
||||
color: mode == 0
|
||||
? DefaultStyle.success_500main
|
||||
: mode == 1
|
||||
? DefaultStyle.warning_600
|
||||
: mode == 2
|
||||
? DefaultStyle.main2_500main
|
||||
: DefaultStyle.danger_500main
|
||||
text: mode == 0
|
||||
? qsTr("Connecté")
|
||||
: mode == 1
|
||||
? qsTr("Désactivé")
|
||||
: mode == 2
|
||||
? qsTr("Connexion...")
|
||||
: qsTr("Erreur")
|
||||
}
|
||||
}
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
Item{
|
||||
Layout.preferredWidth: 100 * DefaultStyle.dp
|
||||
Layout.preferredWidth: 22 * DefaultStyle.dp
|
||||
Layout.preferredHeight: 22 * DefaultStyle.dp
|
||||
Layout.fillHeight: true
|
||||
Rectangle{
|
||||
id: unreadNotifications
|
||||
|
|
|
|||
|
|
@ -12,9 +12,9 @@ ColumnLayout{
|
|||
property string topText: displayName ? displayName.value : ''
|
||||
property string bottomText: account ? account.core.identityAddress : ''
|
||||
spacing: 0
|
||||
Text{
|
||||
width: topTextItem.implicitWidth
|
||||
Text {
|
||||
id: topTextItem
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
verticalAlignment: (bottomTextItem.visible?Text.AlignBottom:Text.AlignVCenter)
|
||||
visible: text != ''
|
||||
|
|
@ -22,10 +22,13 @@ ColumnLayout{
|
|||
font.pixelSize: 14 * DefaultStyle.dp
|
||||
color: DefaultStyle.main2_700
|
||||
text: mainItem.topText
|
||||
width: mainItem.width
|
||||
Layout.preferredWidth: mainItem.width
|
||||
wrapMode: Text.WrapAnywhere
|
||||
maximumLineCount: 1
|
||||
}
|
||||
Text{
|
||||
Text {
|
||||
id: bottomTextItem
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
verticalAlignment: (topTextItem.visible?Text.AlignTop:Text.AlignVCenter)
|
||||
visible: text != ''
|
||||
|
|
@ -33,5 +36,8 @@ ColumnLayout{
|
|||
font.pixelSize: 12 * DefaultStyle.dp
|
||||
color: DefaultStyle.main2_400
|
||||
text: mainItem.bottomText
|
||||
Layout.preferredWidth: mainItem.width
|
||||
maximumLineCount: 1
|
||||
wrapMode: Text.WrapAnywhere
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@ ListView {
|
|||
property bool contactMenuVisible: true
|
||||
property bool initialHeadersVisible: true
|
||||
|
||||
signal contactSelected(var contact)
|
||||
|
||||
model: MagicSearchProxy {
|
||||
searchText: searchBarText.length === 0 ? "*" : searchBarText
|
||||
}
|
||||
|
|
@ -40,6 +42,7 @@ ListView {
|
|||
}
|
||||
Item {
|
||||
width: mainItem.width
|
||||
Layout.preferredWidth: mainItem.width
|
||||
height: 56 * DefaultStyle.dp
|
||||
RowLayout {
|
||||
anchors.fill: parent
|
||||
|
|
@ -129,9 +132,7 @@ ListView {
|
|||
visible: contactArea.containsMouse || friendPopup.hovered
|
||||
}
|
||||
onClicked: {
|
||||
startCallPopup.contact = modelData
|
||||
startCallPopup.open()
|
||||
// mainItem.callButtonPressed(modelData.core.address)
|
||||
mainItem.contactSelected(modelData)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,12 @@ Text {
|
|||
id: mainItem
|
||||
color: DefaultStyle.danger_500main
|
||||
opacity: 0
|
||||
function displayText() {
|
||||
mainItem.state = "Visible"
|
||||
}
|
||||
function hideText() {
|
||||
mainItem.state = "Invisible"
|
||||
}
|
||||
font {
|
||||
pixelSize: 13 * DefaultStyle.dp
|
||||
weight: 600 * DefaultStyle.dp
|
||||
|
|
@ -30,10 +36,6 @@ Text {
|
|||
property: "opacity"
|
||||
duration: 1000
|
||||
}
|
||||
// NumberAnimation {
|
||||
// property: "visible"
|
||||
// duration: 1100
|
||||
// }
|
||||
}
|
||||
]
|
||||
Timer {
|
||||
|
|
@ -48,7 +50,7 @@ Text {
|
|||
target: mainItem
|
||||
onTextChanged: {
|
||||
if (mainItem.text.length > 0) {
|
||||
errorText.state = "Visible"
|
||||
mainItem.state = "Visible"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Layouts 1.0
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Controls as Control
|
||||
import Linphone
|
||||
|
||||
|
|
@ -24,32 +24,38 @@ ColumnLayout {
|
|||
value: DefaultStyle.danger_500main
|
||||
}
|
||||
}
|
||||
TextInput {
|
||||
id: password
|
||||
label: "Password"
|
||||
mandatory: true
|
||||
hidden: true
|
||||
enableErrorText: true
|
||||
|
||||
Binding on background.border.color {
|
||||
when: errorText.opacity != 0
|
||||
value: DefaultStyle.danger_500main
|
||||
}
|
||||
Binding on textField.color {
|
||||
when: errorText.opacity != 0
|
||||
value: DefaultStyle.danger_500main
|
||||
}
|
||||
}
|
||||
Item {
|
||||
Layout.preferredHeight: password.implicitHeight
|
||||
TextInput {
|
||||
id: password
|
||||
label: "Password"
|
||||
mandatory: true
|
||||
hidden: true
|
||||
enableErrorText: true
|
||||
|
||||
ErrorText {
|
||||
id: errorText
|
||||
Connections {
|
||||
target: LoginPageCpp
|
||||
onRegistrationStateChanged: {
|
||||
if (LoginPageCpp.registrationState === LinphoneEnums.RegistrationState.Failed) {
|
||||
errorText.text = qsTr("Le couple identifiant mot de passe ne correspont pas")
|
||||
} else if (LoginPageCpp.registrationState === LinphoneEnums.RegistrationState.Ok) {
|
||||
mainItem.connectionSucceed()
|
||||
Binding on background.border.color {
|
||||
when: errorText.opacity != 0
|
||||
value: DefaultStyle.danger_500main
|
||||
}
|
||||
Binding on textField.color {
|
||||
when: errorText.opacity != 0
|
||||
value: DefaultStyle.danger_500main
|
||||
}
|
||||
}
|
||||
|
||||
ErrorText {
|
||||
anchors.bottom: password.bottom
|
||||
id: errorText
|
||||
Connections {
|
||||
target: LoginPageCpp
|
||||
onErrorMessageChanged: {
|
||||
errorText.text = LoginPageCpp.errorMessage
|
||||
}
|
||||
onRegistrationStateChanged: {
|
||||
if (LoginPageCpp.registrationState === LinphoneEnums.RegistrationState.Ok) {
|
||||
mainItem.connectionSucceed()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -58,11 +64,43 @@ ColumnLayout {
|
|||
RowLayout {
|
||||
id: lastFormLineLayout
|
||||
Button {
|
||||
text: qsTr("Connexion")
|
||||
contentItem: StackLayout {
|
||||
id: connectionButton
|
||||
currentIndex: 0
|
||||
Text {
|
||||
text: qsTr("Connexion")
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
|
||||
font {
|
||||
pixelSize: 18 * DefaultStyle.dp
|
||||
weight: 600 * DefaultStyle.dp
|
||||
}
|
||||
color: DefaultStyle.grey_0
|
||||
}
|
||||
BusyIndicator {
|
||||
width: parent.height
|
||||
height: parent.height
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
indicatorColor: DefaultStyle.grey_0
|
||||
}
|
||||
Connections {
|
||||
target: LoginPageCpp
|
||||
onRegistrationStateChanged: {
|
||||
if (LoginPageCpp.registrationState != LinphoneEnums.RegistrationState.Progress) {
|
||||
connectionButton.currentIndex = 0
|
||||
}
|
||||
}
|
||||
onErrorMessageChanged: {
|
||||
connectionButton.currentIndex = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
Layout.rightMargin: 20 * DefaultStyle.dp
|
||||
onClicked: {
|
||||
username.errorMessage = ""
|
||||
password.errorMessage = ""
|
||||
errorText.text = ""
|
||||
|
||||
if (username.text.length == 0 || password.text.length == 0) {
|
||||
if (username.text.length == 0)
|
||||
|
|
@ -72,6 +110,7 @@ ColumnLayout {
|
|||
return
|
||||
}
|
||||
LoginPageCpp.login(username.text, password.text)
|
||||
connectionButton.currentIndex = 1
|
||||
}
|
||||
}
|
||||
Button {
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ ColumnLayout {
|
|||
property string initialText
|
||||
|
||||
property bool enableErrorText: false
|
||||
property bool errorTextVisible: errorText.opacity > 0
|
||||
|
||||
property alias textField: textField
|
||||
property alias background: input
|
||||
|
|
@ -61,11 +62,11 @@ ColumnLayout {
|
|||
radius: 79 * DefaultStyle.dp
|
||||
color: mainItem.enableBackgroundColors ? DefaultStyle.grey_100 : "transparent"
|
||||
border.color: mainItem.enableBackgroundColors
|
||||
? errorText.opacity === 0
|
||||
? textField.activeFocus
|
||||
? mainItem.errorTextVisible
|
||||
? DefaultStyle.danger_500main
|
||||
: textField.activeFocus
|
||||
? DefaultStyle.main1_500_main
|
||||
: DefaultStyle.grey_200
|
||||
: DefaultStyle.danger_500main
|
||||
: "transparent"
|
||||
|
||||
Control.TextField {
|
||||
|
|
@ -82,7 +83,7 @@ ColumnLayout {
|
|||
pixelSize: 14 * DefaultStyle.dp
|
||||
weight: 400 * DefaultStyle.dp
|
||||
}
|
||||
color: errorText.opacity === 0 ? DefaultStyle.main2_600 : DefaultStyle.danger_500main
|
||||
color: mainItem.errorTextVisible ? DefaultStyle.danger_500main : DefaultStyle.main2_600
|
||||
selectByMouse: true
|
||||
validator: mainItem.validator
|
||||
background: Item {
|
||||
|
|
@ -117,6 +118,6 @@ ColumnLayout {
|
|||
id: errorText
|
||||
visible: mainItem.enableErrorText
|
||||
text: mainItem.errorMessage
|
||||
Layout.preferredWidth: mainItem.textInputWidth
|
||||
Layout.preferredWidth: implicitWidth
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -76,7 +76,6 @@ LoginLayout {
|
|||
required property int index
|
||||
Layout.preferredWidth: width
|
||||
Layout.preferredHeight: height
|
||||
Component.onCompleted: console.log("completed", width, Layout.preferredWidth)
|
||||
onTextEdited: {
|
||||
console.log("textfield text", text, index)
|
||||
if (text.length > 0 ) {
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ LoginLayout {
|
|||
}
|
||||
}
|
||||
}
|
||||
centerContent: ColumnLayout {
|
||||
centerContent: Item {
|
||||
id: centerLayout
|
||||
Layout.bottomMargin: 20 * DefaultStyle.dp
|
||||
Layout.fillWidth: false
|
||||
|
|
@ -62,6 +62,7 @@ LoginLayout {
|
|||
Layout.leftMargin: 250 * DefaultStyle.dp
|
||||
Layout.topMargin: 165 * DefaultStyle.dp
|
||||
RowLayout {
|
||||
id: carouselLayout
|
||||
Image {
|
||||
id: carouselImg
|
||||
Layout.rightMargin: 40 * DefaultStyle.dp
|
||||
|
|
@ -104,10 +105,11 @@ LoginLayout {
|
|||
}
|
||||
|
||||
Button {
|
||||
Layout.topMargin: 20 * DefaultStyle.dp
|
||||
Layout.bottomMargin: 20 * DefaultStyle.dp
|
||||
Layout.leftMargin: (centerLayout.width - width) * DefaultStyle.dp
|
||||
Layout.alignment: Qt.AlignBottom | Qt.AlignRight
|
||||
anchors.top: carouselLayout.bottom
|
||||
anchors.right: carouselLayout.right
|
||||
anchors.topMargin: 20 * DefaultStyle.dp
|
||||
anchors.bottomMargin: 20 * DefaultStyle.dp
|
||||
anchors.leftMargin: (centerLayout.width - width) * DefaultStyle.dp
|
||||
y: centerLayout.implicitWidth - width
|
||||
text: carousel.currentIndex < (carousel.itemsCount - 1) ? qsTr("Suivant") : qsTr("Commencer")
|
||||
onClicked: {
|
||||
|
|
|
|||
Loading…
Reference in a new issue