diff --git a/Linphone/core/login/LoginPage.cpp b/Linphone/core/login/LoginPage.cpp index 8fd9e26ad..a3ef4438c 100644 --- a/Linphone/core/login/LoginPage.cpp +++ b/Linphone/core/login/LoginPage.cpp @@ -25,19 +25,27 @@ #include "model/account/AccountManager.hpp" +DEFINE_ABSTRACT_OBJECT(LoginPage) + LoginPage::LoginPage(QObject *parent) : QObject(parent) { + mustBeInMainThread(getClassName()); } -bool LoginPage::isLogged() const { +LoginPage::~LoginPage() { + mustBeInMainThread("~" + getClassName()); +} + +linphone::RegistrationState LoginPage::getRegistrationState() const { // View thread - return mIsLogged; + return mRegistrationState; } -void LoginPage::setIsLogged(bool status) { +void LoginPage::setRegistrationState(linphone::RegistrationState status) { // Should be view thread only because of object updates. - if (mIsLogged != status) { - mIsLogged = status; - emit isLoggedChanged(); + mustBeInMainThread(log().arg(Q_FUNC_INFO)); + if (mRegistrationState != status) { + mRegistrationState = status; + emit registrationStateChanged(); } } @@ -45,11 +53,25 @@ void LoginPage::login(const QString &username, const QString &password) { App::postModelAsync([=]() { // Create on Model thread. AccountManager *accountManager = new AccountManager(); - connect(accountManager, &AccountManager::logged, this, [accountManager, this](bool isLoggued) mutable { - // View thread - setIsLogged(isLoggued); - accountManager->deleteLater(); - }); - accountManager->login(username, password); + connect(accountManager, &AccountManager::registrationStateChanged, this, + [accountManager, this](linphone::RegistrationState state) mutable { + // View thread + setRegistrationState(state); + switch (state) { + case linphone::RegistrationState::Ok: + case linphone::RegistrationState::Cleared: + case linphone::RegistrationState::Failed: { + accountManager->deleteLater(); + break; + } + case linphone::RegistrationState::None: + case linphone::RegistrationState::Progress: + case linphone::RegistrationState::Refreshing: + break; + } + }); + if (!accountManager->login(username, password)) { + emit accountManager->registrationStateChanged(linphone::RegistrationState::Failed); + } }); } diff --git a/Linphone/core/login/LoginPage.hpp b/Linphone/core/login/LoginPage.hpp index 77ec6d812..edda6c8c6 100644 --- a/Linphone/core/login/LoginPage.hpp +++ b/Linphone/core/login/LoginPage.hpp @@ -18,23 +18,34 @@ * along with this program. If not, see . */ -#include +#ifndef LOGINPAGE_H_ +#define LOGINPAGE_H_ -class LoginPage : public QObject { +#include "tool/AbstractObject.hpp" +#include +#include + +class LoginPage : public QObject, public AbstractObject { Q_OBJECT public: LoginPage(QObject *parent = nullptr); + ~LoginPage(); - Q_PROPERTY(bool isLogged READ isLogged NOTIFY isLoggedChanged) - - Q_INVOKABLE void login(const QString& username, const QString& password); + Q_PROPERTY(linphone::RegistrationState registrationState READ getRegistrationState NOTIFY registrationStateChanged) - bool isLogged() const; - void setIsLogged(bool status); + Q_INVOKABLE void login(const QString &username, const QString &password); + + linphone::RegistrationState getRegistrationState() const; + void setRegistrationState(linphone::RegistrationState status); signals: - void isLoggedChanged(); + void registrationStateChanged(); + private: - bool mIsLogged = false; + linphone::RegistrationState mRegistrationState = linphone::RegistrationState::None; + + DECLARE_ABSTRACT_OBJECT }; + +#endif \ No newline at end of file diff --git a/Linphone/data/CMakeLists.txt b/Linphone/data/CMakeLists.txt index ed63eabe2..f3cdd0be1 100644 --- a/Linphone/data/CMakeLists.txt +++ b/Linphone/data/CMakeLists.txt @@ -15,6 +15,8 @@ list(APPEND _LINPHONEAPP_RC_FILES data/assistant/use-app-sip-account.rc "data/image/caret-left.svg" "data/image/verif_page_image.svg" "data/image/check.svg" + "data/image/chiffrement.svg" + "data/image/interoperable.svg" ) set(_LINPHONEAPP_RC_FILES ${_LINPHONEAPP_RC_FILES} PARENT_SCOPE) diff --git a/Linphone/data/image/chiffrement.svg b/Linphone/data/image/chiffrement.svg new file mode 100644 index 000000000..5bfafca43 --- /dev/null +++ b/Linphone/data/image/chiffrement.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/Linphone/data/image/down_arrow.svg b/Linphone/data/image/down_arrow.svg new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/Linphone/data/image/down_arrow.svg @@ -0,0 +1 @@ + diff --git a/Linphone/data/image/info.svg b/Linphone/data/image/info.svg index 2f26d80a1..992048dd0 100644 --- a/Linphone/data/image/info.svg +++ b/Linphone/data/image/info.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/Linphone/data/image/interoperable.svg b/Linphone/data/image/interoperable.svg new file mode 100644 index 000000000..1259f5feb --- /dev/null +++ b/Linphone/data/image/interoperable.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/Linphone/data/image/return_arrow.svg b/Linphone/data/image/return_arrow.svg new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/Linphone/data/image/return_arrow.svg @@ -0,0 +1 @@ + diff --git a/Linphone/data/image/welcome_linphone_logo.svg b/Linphone/data/image/welcome_linphone_logo.svg new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/Linphone/data/image/welcome_linphone_logo.svg @@ -0,0 +1 @@ + diff --git a/Linphone/data/image/welcome_lock.svg b/Linphone/data/image/welcome_lock.svg new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/Linphone/data/image/welcome_lock.svg @@ -0,0 +1 @@ + diff --git a/Linphone/data/image/welcome_opensource.svg b/Linphone/data/image/welcome_opensource.svg new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/Linphone/data/image/welcome_opensource.svg @@ -0,0 +1 @@ + diff --git a/Linphone/model/account/AccountManager.cpp b/Linphone/model/account/AccountManager.cpp index 0dc1c4080..34bf64b64 100644 --- a/Linphone/model/account/AccountManager.cpp +++ b/Linphone/model/account/AccountManager.cpp @@ -91,14 +91,13 @@ void AccountManager::onRegistrationStateChanged(const std::shared_ptrremoveAccount(account); emit mAccountModel->removeListener(); mAccountModel = nullptr; - emit logged(false); break; case linphone::RegistrationState::Ok: emit mAccountModel->removeListener(); mAccountModel = nullptr; - emit logged(true); break; default: { } } + emit registrationStateChanged(state); } diff --git a/Linphone/model/account/AccountManager.hpp b/Linphone/model/account/AccountManager.hpp index 2184127c5..4b9f02a47 100644 --- a/Linphone/model/account/AccountManager.hpp +++ b/Linphone/model/account/AccountManager.hpp @@ -41,7 +41,7 @@ public: linphone::RegistrationState state, const std::string &message); signals: - void logged(bool isLoggued); + void registrationStateChanged(linphone::RegistrationState state); private: std::shared_ptr mAccountModel; diff --git a/Linphone/tool/CMakeLists.txt b/Linphone/tool/CMakeLists.txt index 9e5064217..638ddecf8 100644 --- a/Linphone/tool/CMakeLists.txt +++ b/Linphone/tool/CMakeLists.txt @@ -1,6 +1,7 @@ list(APPEND _LINPHONEAPP_SOURCES tool/Constants.cpp tool/Utils.cpp + tool/LinphoneEnums.cpp tool/thread/Thread.cpp tool/providers/ImageProvider.cpp diff --git a/Linphone/view/App/Layout/OverviewLayout.qml b/Linphone/view/App/Layout/OverviewLayout.qml new file mode 100644 index 000000000..4d4e0f919 --- /dev/null +++ b/Linphone/view/App/Layout/OverviewLayout.qml @@ -0,0 +1,35 @@ +/** +* Qml template used for welcome and login/register pages +**/ + +import QtQuick 2.15 +import QtQuick.Layouts 1.3 +import QtQuick.Controls 2.2 as Control + +import Linphone + +Item { + id: mainItem + + RowLayout { + spacing: 10 + Layout.fillHeight: true + VerticalTabBar { + Layout.fillHeight: true + } + ColumnLayout { + Layout.fillHeight: true + TextInput { + fillWidth: true + placeholderText: qsTr("Rechercher un contact, appeler ou envoyer un message...") + } + Image { + //avatar + } + Button { + // color: DefaultStyle.moreButtonBackground + } + } + } +} + diff --git a/Linphone/view/App/Main.qml b/Linphone/view/App/Main.qml index 013208d70..9d42684e9 100644 --- a/Linphone/view/App/Main.qml +++ b/Linphone/view/App/Main.qml @@ -10,6 +10,7 @@ Window { height: 641 visible: true title: qsTr("Linphone") + property bool firstConnection: true StackView { id: mainWindowStackView @@ -29,6 +30,13 @@ Window { LoginPage { onUseSIPButtonClicked: mainWindowStackView.push(sipLoginPage) onGoToRegister: mainWindowStackView.replace(registerPage) + onConnectionSucceed: { + if (mainWindow.firstConnection) { + mainWindowStackView.replace(securityModePage) + } else { + mainWindowStackView.replace(callPage) + } + } } } Component { @@ -36,6 +44,14 @@ Window { SIPLoginPage { onReturnToLogin: mainWindowStackView.pop() onGoToRegister: mainWindowStackView.replace(registerPage) + + onConnectionSucceed: { + if (mainWindow.firstConnection) { + mainWindowStackView.replace(securityModePage) + } else { + mainWindowStackView.replace(callPage) + } + } } } Component { @@ -53,5 +69,20 @@ Window { onReturnToRegister: mainWindowStackView.pop() } } + Component { + id: securityModePage + SecurityModePage { + onModeSelected: (index) => { + var selectedMode = index == 0 ? "chiffrement" : "interoperable" + console.debug("[SelectMode]User: User selected mode " + selectedMode) + mainWindowStackView.replace(callPage) + } + } + } + Component { + id: callPage + CallPage { + } + } } diff --git a/Linphone/view/CMakeLists.txt b/Linphone/view/CMakeLists.txt index 86951e6d0..9aaf623e4 100644 --- a/Linphone/view/CMakeLists.txt +++ b/Linphone/view/CMakeLists.txt @@ -2,6 +2,7 @@ list(APPEND _LINPHONEAPP_QML_FILES view/App/Main.qml view/App/Layout/LoginLayout.qml + view/App/Layout/OverviewLayout.qml view/Item/Button.qml view/Item/Carousel.qml @@ -10,11 +11,13 @@ list(APPEND _LINPHONEAPP_QML_FILES view/Item/DigitInput.qml view/Item/PhoneNumberComboBox.qml view/Item/PhoneNumberInput.qml + view/Item/RadioButton.qml view/Item/RectangleTest.qml view/Item/TabBar.qml view/Item/Text.qml view/Item/TextInput.qml view/Item/ToolTip.qml + view/Item/VerticalTabBar.qml view/Item/Form/LoginForm.qml @@ -22,9 +25,12 @@ list(APPEND _LINPHONEAPP_QML_FILES view/Page/Login/LoginPage.qml view/Page/Login/RegisterPage.qml - view/Page/Login/SIPLoginPage.qml view/Page/Login/RegisterCheckingPage.qml + view/Page/Login/SIPLoginPage.qml + view/Page/Login/SecurityModePage.qml view/Page/Login/WelcomePage.qml + + view/Page/Overview/CallPage.qml # Prototypes view/Prototype/PhoneNumberPrototype.qml diff --git a/Linphone/view/Item/Button.qml b/Linphone/view/Item/Button.qml index bf872461c..c7520f08c 100644 --- a/Linphone/view/Item/Button.qml +++ b/Linphone/view/Item/Button.qml @@ -19,6 +19,12 @@ Control.Button { : DefaultStyle.buttonBackground radius: 24 border.color: inversedColors ? DefaultStyle.buttonBackground : DefaultStyle.buttonInversedBackground + + MouseArea { + anchors.fill: parent + hoverEnabled: true + cursorShape: hovered ? Qt.PointingHandCursor : Qt.ArrowCursor + } } leftPadding: 13 diff --git a/Linphone/view/Item/CheckBox.qml b/Linphone/view/Item/CheckBox.qml index f46f608d2..b3184e342 100644 --- a/Linphone/view/Item/CheckBox.qml +++ b/Linphone/view/Item/CheckBox.qml @@ -13,7 +13,7 @@ Control.CheckBox { radius: 3 border.color: DefaultStyle.checkboxBorderColor border.width: DefaultStyle.checkboxBorderWidth - // color: checkbox.checked ? DefaultStyle.checkboxBorderColor : "transparent" + // color: mainItem.checked ? DefaultStyle.checkboxBorderColor : "transparent" Text { visible: mainItem.checked diff --git a/Linphone/view/Item/ComboBox.qml b/Linphone/view/Item/ComboBox.qml index 89fcef60f..e4022d99c 100644 --- a/Linphone/view/Item/ComboBox.qml +++ b/Linphone/view/Item/ComboBox.qml @@ -172,4 +172,4 @@ ColumnLayout { } } } -} \ No newline at end of file +} diff --git a/Linphone/view/Item/Form/LoginForm.qml b/Linphone/view/Item/Form/LoginForm.qml index f69cfa48a..17ab8e7f1 100644 --- a/Linphone/view/Item/Form/LoginForm.qml +++ b/Linphone/view/Item/Form/LoginForm.qml @@ -3,8 +3,12 @@ import QtQuick.Layouts 1.0 import QtQuick.Controls as Control import Linphone + ColumnLayout { + id: mainItem spacing: 15 + signal connectionSucceed() + TextInput { id: username label: "Username" @@ -19,13 +23,66 @@ ColumnLayout { textInputWidth: 250 } + Text { + id: errorText + text: "Connection has failed. Please verify your credentials" + color: DefaultStyle.errorMessageColor + opacity: 0 + states: [ + State{ + name: "Visible" + PropertyChanges{target: errorText; opacity: 1.0} + }, + State{ + name:"Invisible" + PropertyChanges{target: errorText; opacity: 0.0} + } + ] + transitions: [ + Transition { + from: "Visible" + to: "Invisible" + NumberAnimation { + property: "opacity" + duration: 1000 + } + } + ] + Timer { + id: autoHideErrorMessage + interval: 2500 + onTriggered: errorText.state = "Invisible" + } + Connections { + target: LoginPageCpp + onRegistrationStateChanged: { + if (LoginPageCpp.registrationState === LinphoneEnums.RegistrationState.Failed) { + errorText.state = "Visible" + autoHideErrorMessage.restart() + } else if (LoginPageCpp.registrationState === LinphoneEnums.RegistrationState.Ok) { + mainItem.connectionSucceed() + } + } + } + } + RowLayout { id: lastFormLineLayout Button { - text: 'Log in' + text: "Log in" Layout.rightMargin: 20 onClicked: { - LoginPageCpp.login(username.inputText, password.inputText); + username.errorMessage = "" + password.errorMessage = "" + + if (username.inputText.length == 0 || password.inputText.length == 0) { + if (username.inputText.length == 0) + username.errorMessage = qsTr("You must enter a username") + if (password.inputText.length == 0) + password.errorMessage = qsTr("You must enter a password") + return + } + LoginPageCpp.login(username.inputText, password.inputText) } } Button { diff --git a/Linphone/view/Item/PhoneNumberComboBox.qml b/Linphone/view/Item/PhoneNumberComboBox.qml index 029fabb55..7ca586772 100644 --- a/Linphone/view/Item/PhoneNumberComboBox.qml +++ b/Linphone/view/Item/PhoneNumberComboBox.qml @@ -152,4 +152,4 @@ ColumnLayout { } } } -} \ No newline at end of file +} diff --git a/Linphone/view/Item/PhoneNumberInput.qml b/Linphone/view/Item/PhoneNumberInput.qml index f0f5426d0..e34790843 100644 --- a/Linphone/view/Item/PhoneNumberInput.qml +++ b/Linphone/view/Item/PhoneNumberInput.qml @@ -74,4 +74,4 @@ ColumnLayout { } Layout.preferredWidth: mainItem.textInputWidth } -} \ No newline at end of file +} diff --git a/Linphone/view/Item/RadioButton.qml b/Linphone/view/Item/RadioButton.qml new file mode 100644 index 000000000..fe5925c2b --- /dev/null +++ b/Linphone/view/Item/RadioButton.qml @@ -0,0 +1,100 @@ +import QtQuick 2.7 +import QtQuick.Controls 2.2 as Control +import QtQuick.Layouts +import Linphone + +Control.RadioButton { + id: mainItem + property bool inversedColors: false + property string title + property string contentText + property string imgUrl + hoverEnabled: true + + MouseArea { + anchors.fill: parent + hoverEnabled: false + cursorShape: mainItem.hovered ? Qt.PointingHandCursor : Qt.ArrowCursor + onClicked: if (!mainItem.checked) mainItem.toggle() + } + + background: Rectangle { + color: DefaultStyle.formItemBackgroundColor + border.color: mainItem.checked ? DefaultStyle.radioButtonCheckedColor : "transparent" + radius: 20 + } + + indicator: RowLayout { + anchors.left: parent.left + anchors.leftMargin: 13 + anchors.top: parent.top + anchors.topMargin: 8 + spacing: 4 + Rectangle { + implicitWidth: 16 + implicitHeight: 16 + radius: implicitWidth/2 + border.color: mainItem.checked ? DefaultStyle.radioButtonCheckedColor : DefaultStyle.radioButtonUncheckedColor + + Rectangle { + width: parent.width/2 + height: parent.height/2 + x: parent.width/4 + y: parent.width/4 + radius: width/2 + color: DefaultStyle.radioButtonCheckedColor + visible: mainItem.checked + } + } + Text { + text: mainItem.title + font.bold: true + color: DefaultStyle.radioButtonTitleColor + font.pointSize: DefaultStyle.radioButtonTitleSize + } + Control.Button { + padding: 0 + background: Item { + visible: false + } + contentItem: Image { + fillMode: Image.PreserveAspectFit + source: AppIcons.info + width: 2 + height: 2 + } + } + } + + contentItem: ColumnLayout { + anchors.top: indicator.bottom + anchors.bottom: parent.bottom + anchors.left: parent.left + anchors.right: parent.right + anchors.leftMargin: 13 + RowLayout { + Layout.fillWidth: true + Layout.fillHeight: true + Layout.bottomMargin: 10 + Layout.rightMargin: 10 + Layout.alignment: Qt.AlignVCenter + Text { + id: innerText + verticalAlignment: Text.AlignVCenter + Layout.preferredWidth: 220 + Layout.preferredHeight: 100 + font.pointSize: DefaultStyle.defaultTextSize + text: mainItem.contentText + Layout.fillHeight: true + } + Image { + id: image + Layout.fillHeight: true + Layout.preferredWidth: 100 + Layout.preferredHeight: 100 + fillMode: Image.PreserveAspectFit + source: mainItem.imgUrl + } + } + } +} diff --git a/Linphone/view/Item/TabBar.qml b/Linphone/view/Item/TabBar.qml index 314964a36..2e0d751fb 100644 --- a/Linphone/view/Item/TabBar.qml +++ b/Linphone/view/Item/TabBar.qml @@ -87,4 +87,4 @@ Control.TabBar { } } } -} \ No newline at end of file +} diff --git a/Linphone/view/Item/VerticalTabBar.qml b/Linphone/view/Item/VerticalTabBar.qml new file mode 100644 index 000000000..5d69aac95 --- /dev/null +++ b/Linphone/view/Item/VerticalTabBar.qml @@ -0,0 +1,60 @@ +import QtQuick 2.7 +import QtQuick.Layouts 1.3 +import QtQuick.Controls 2.2 as Control +import Linphone + +Control.TabBar { + id: mainItem + spacing: 40 + property color tabBarColor: DefaultStyle.verticalTabBarColor + + function appendTab(label) { + var newTab = tab.createObject(mainItem, {title: label, index: mainItem.count}) + } + + contentItem: ListView { + orientation: ListView.Vertical + model: mainItem.model + } + + background: Item { + anchors.fill: parent + + Rectangle { + id: barBG + height: 4 + color: mainItem.tabBarColor + anchors.bottom: parent.bottom + width: parent.width + } + } + + Component { + id: tab + Control.TabButton { + property string title + property int index + width: txtMeter. advanceWidth + + background: Item { + visible: false + } + + contentItem: Text { + id: tabText + anchors.fill: parent + font.bold: true + font.pointSize: DefaultStyle.tabButtonTextSize + text: txtMeter.text + bottomPadding: 5 + width: txtMeter.advanceWidth + } + + TextMetrics { + id: txtMeter + font: tabText.font + text: title + } + } + } +} \ No newline at end of file diff --git a/Linphone/view/Page/Login/LoginItem.qml b/Linphone/view/Page/Login/LoginItem.qml deleted file mode 100644 index 9ff564197..000000000 --- a/Linphone/view/Page/Login/LoginItem.qml +++ /dev/null @@ -1,60 +0,0 @@ -import QtQuick 2.15 -import QtQuick.Layouts 1.0 -import QtQuick.Controls as Control -import Linphone - -RowLayout { - Layout.alignment: Qt.AlignBottom - ColumnLayout { - FormTextInputCell { - id: username - label: "Username" - mandatory: true - textInputWidth: 250 - } - FormTextInputCell { - id: password - label: "Password" - mandatory: true - hidden: true - textInputWidth: 250 - } - - RowLayout { - id: lastFormLineLayout - Button { - text: 'Log in' - Layout.rightMargin: 20 - onClicked: { - console.debug("[LoginItem] User: Log in") - LoginPageCpp.login(username.inputText, password.inputText); - } - } - Text { - color: DefaultStyle.grayColor - text: "Forgotten password?" - font.underline: true - font.pointSize: DefaultStyle.defaultTextSize - } - - } - Button { - Layout.topMargin: 40 - inversedColors: true - text: "Use SIP Account" - onClicked: { - console.debug("[LoginItem] User: click use Sip") - root.useSIP() - } - } - } - Item { - Layout.fillWidth: true - } - Image { - Layout.rightMargin: 40 - Layout.preferredWidth: 300 - fillMode: Image.PreserveAspectFit - source: AppIcons.loginImage - } -} diff --git a/Linphone/view/Page/Login/LoginLayout.qml b/Linphone/view/Page/Login/LoginLayout.qml index 4dd1930c7..25fbdbbc4 100644 --- a/Linphone/view/Page/Login/LoginLayout.qml +++ b/Linphone/view/Page/Login/LoginLayout.qml @@ -32,7 +32,7 @@ Item { fillMode: Image.PreserveAspectFit source: AppIcons.info } - onClicked: console.debug("[LoginLayout] Userr: open about popup") + onClicked: console.debug("[LoginLayout] User: open about popup") } Text { diff --git a/Linphone/view/Page/Login/LoginPage.qml b/Linphone/view/Page/Login/LoginPage.qml index 658f2d479..e2b5e3710 100644 --- a/Linphone/view/Page/Login/LoginPage.qml +++ b/Linphone/view/Page/Login/LoginPage.qml @@ -7,6 +7,7 @@ LoginLayout { id: mainItem signal useSIPButtonClicked() signal goToRegister() + signal connectionSucceed() titleContent: RowLayout { Image { @@ -37,18 +38,15 @@ LoginLayout { } } } - centerContent: ColumnLayout { - signal useSIPButtonClicked() + Layout.alignment: Qt.AlignBottom + RowLayout { + ColumnLayout { - Layout.fillHeight: true - Layout.fillWidth: true - clip: true - spacing: 15 - - LoginForm{} - + LoginForm { + onConnectionSucceed: mainItem.connectionSucceed() + } Button { Layout.topMargin: 40 inversedColors: true diff --git a/Linphone/view/Page/Login/RegisterPage.qml b/Linphone/view/Page/Login/RegisterPage.qml index f6279653b..da463950d 100644 --- a/Linphone/view/Page/Login/RegisterPage.qml +++ b/Linphone/view/Page/Login/RegisterPage.qml @@ -38,7 +38,7 @@ LoginLayout { inversedColors: true text: "Log in" onClicked: { - console.debug("[LoginItem] User: return") + console.debug("[RegisterPage] User: return") returnToLogin() } } diff --git a/Linphone/view/Page/Login/SIPLoginPage.qml b/Linphone/view/Page/Login/SIPLoginPage.qml index e9552c890..c7f1885db 100644 --- a/Linphone/view/Page/Login/SIPLoginPage.qml +++ b/Linphone/view/Page/Login/SIPLoginPage.qml @@ -8,6 +8,8 @@ LoginLayout { id: mainItem signal returnToLogin() signal goToRegister() + signal connectionSucceed() + titleContent: RowLayout { Control.Button { Layout.preferredHeight: 40 @@ -19,7 +21,7 @@ LoginLayout { color: "transparent" } onClicked: { - console.debug("[LoginItem] User: return") + console.debug("[SIPLoginPage] User: return") mainItem.returnToLogin() } } @@ -103,7 +105,7 @@ LoginLayout { inversedColors: true text: "I prefer creating an account" onClicked: { - console.debug("[LoginItem] User: click register") + console.debug("[SIPLoginPage] User: click register") mainItem.goToRegister() } } @@ -148,11 +150,50 @@ LoginLayout { ComboBox { label: "Transport" backgroundWidth: 250 - modelList:[ - {text:"TCP"}, - {text:"UDP"}, - {text:"TLS"} + modelList:[ "TCP", "UDP", "TLS"] + } + + Text { + id: errorText + text: "Connection has failed. Please verify your credentials" + color: DefaultStyle.errorMessageColor + opacity: 0 + states: [ + State{ + name: "Visible" + PropertyChanges{target: errorText; opacity: 1.0} + }, + State{ + name:"Invisible" + PropertyChanges{target: errorText; opacity: 0.0} + } ] + transitions: [ + Transition { + from: "Visible" + to: "Invisible" + NumberAnimation { + property: "opacity" + duration: 1000 + } + } + ] + Timer { + id: autoHideErrorMessage + interval: 2500 + onTriggered: errorText.state = "Invisible" + } + Connections { + target: LoginPageCpp + onRegistrationStateChanged: { + if (LoginPageCpp.registrationState === LinphoneEnums.RegistrationState.Failed) { + errorText.state = "Visible" + autoHideErrorMessage.restart() + } else if (LoginPageCpp.registrationState === LinphoneEnums.RegistrationState.Ok) { + mainItem.connectionSucceed() + } + } + } } Button { diff --git a/Linphone/view/Page/Login/SecurityModePage.qml b/Linphone/view/Page/Login/SecurityModePage.qml new file mode 100644 index 000000000..9a85159fa --- /dev/null +++ b/Linphone/view/Page/Login/SecurityModePage.qml @@ -0,0 +1,70 @@ +import QtQuick 2.15 +import QtQuick.Layouts 1.0 +import QtQuick.Controls as Control +import Linphone + +LoginLayout { + id: mainItem + signal modeSelected(int index) + + titleContent: RowLayout { + Image { + fillMode: Image.PreserveAspectFit + source: AppIcons.profile + } + ColumnLayout { + Text { + text: qsTr("Choisir votre mode") + font.pointSize: DefaultStyle.title2FontPointSize + font.bold: true + scaleLettersFactor: 1.1 + } + Text { + text: qsTr("Vous pourrez changer de mode plus tard.") + font.bold: true + scaleLettersFactor: 1.1 + } + } + } + + centerContent: ColumnLayout { + spacing: 80 + Layout.topMargin: 70 + Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter + RowLayout { + id: radioButtonsLayout + Layout.fillWidth: true + Layout.alignment: Qt.AlignHCenter + spacing: 70 + Repeater { + model: [ + {checked: true, title: qsTr("Chiffrement de bout en bout"), text: qsTr("Ce mode vous garanti la confidentialité de tous vos échanges. Notre technologie de chiffrement de bout en bout assure un niveau de sécurité maximal pour tous vos échanges."), imgUrl: AppIcons.chiffrement}, + {checked: false, title: qsTr("Interoperable"), text: qsTr("Ce mode vous permet de profiter de toute les fonctionnalités de Linphone, toute en restant interopérable avec n’importe qu’elle autre service SIP."), imgUrl: AppIcons.interoperable} + ] + RadioButton { + title: modelData.title + contentText: modelData.text + imgUrl: modelData.imgUrl + checked: modelData.checked + onCheckedChanged: { + if (checked) continueButton.selectedIndex = index + } + } + } + } + Button { + id: continueButton + property int selectedIndex: 0 + Layout.alignment: Qt.AlignHCenter + leftPadding: 100 + rightPadding: 100 + text: qsTr("Continuer") + onClicked: mainItem.modeSelected(selectedIndex) + } + Item { + Layout.fillWidth: true + Layout.fillHeight: true + } + } +} + diff --git a/Linphone/view/Page/Login/WelcomePage.qml b/Linphone/view/Page/Login/WelcomePage.qml index ac8ee02f5..1ed308c10 100644 --- a/Linphone/view/Page/Login/WelcomePage.qml +++ b/Linphone/view/Page/Login/WelcomePage.qml @@ -41,7 +41,7 @@ LoginLayout { font.underline: true } onClicked: { - console.debug("[LoginItem] User: Click skip") + console.debug("[WelcomePage] User: Click skip") mainItem.startButtonPressed() } } diff --git a/Linphone/view/Page/Overview/CallPage.qml b/Linphone/view/Page/Overview/CallPage.qml new file mode 100644 index 000000000..62a1a469b --- /dev/null +++ b/Linphone/view/Page/Overview/CallPage.qml @@ -0,0 +1,9 @@ +import QtQuick 2.15 +import QtQuick.Layouts 1.0 +import QtQuick.Controls as Control +import Linphone + +OverviewLayout { + id: mainItem +} + diff --git a/Linphone/view/Style/AppIcons.qml b/Linphone/view/Style/AppIcons.qml index 2696f13fe..6fa163403 100644 --- a/Linphone/view/Style/AppIcons.qml +++ b/Linphone/view/Style/AppIcons.qml @@ -15,4 +15,6 @@ QtObject { property string profile: "image://internal/user-circle.svg" property string verif_page_image: "image://internal/verif_page_image.svg" property string check: "image://internal/check.svg" + property string chiffrement: "image://internal/chiffrement.svg" + property string interoperable: "image://internal/interoperable.svg" } diff --git a/Linphone/view/Style/DefaultStyle.qml b/Linphone/view/Style/DefaultStyle.qml index 619bada8b..7059639e5 100644 --- a/Linphone/view/Style/DefaultStyle.qml +++ b/Linphone/view/Style/DefaultStyle.qml @@ -10,11 +10,15 @@ QtObject { property color buttonInversedBackground: "white" property color buttonPressedInversedBackground: "#fff1e8" property color buttonTextColor: "white" + property color radioButtonCheckedColor: "#4AA8FF" + property color radioButtonUncheckedColor: "#FE5E00" + property color radioButtonTitleColor: "#070707" + property int radioButtonTextSize: 8 + property int radioButtonTitleSize: 9 property color buttonInversedTextColor: "#FE5E00" property color checkboxBorderColor: "#FE5E00" property double checkboxBorderWidth: 2 property int buttonTextSize: 10 - property int tabButtonTextSize: 11 property color carouselLightGrayColor: "#DFECF2" property color formItemLabelColor: "#4E6074" property int formItemLabelSize: 8 @@ -24,6 +28,9 @@ QtObject { property color formItemBorderColor: "#EDEDED" property color formItemFocusBorderColor: "#FE5E00" + property int tabButtonTextSize: 11 + property color verticalTabBarColor: "#FE5E00" + property color comboBoxHighlightColor: "#C0D1D9" property color comboBoxHoverColor: "#6C7A87"