diff --git a/app/icons/WarnLogoImage.svg b/app/icons/WarnLogoImage.svg new file mode 100644 index 0000000000..8b2719d0bf --- /dev/null +++ b/app/icons/WarnLogoImage.svg @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/icons/icons.qrc b/app/icons/icons.qrc index 37ac51f4c5..3b078b110d 100644 --- a/app/icons/icons.qrc +++ b/app/icons/icons.qrc @@ -63,6 +63,7 @@ WaterResources.svg XMark.svg XTwitter.svg + WarnLogoImage.svg Youtube.svg ZoomToProject.svg diff --git a/app/main.cpp b/app/main.cpp index 04190cf7ea..39d0af40be 100644 --- a/app/main.cpp +++ b/app/main.cpp @@ -33,7 +33,7 @@ #include "qgsmaplayerproxymodel.h" #include "qgsnetworkaccessmanager.h" #include "geodiffutils.h" - +#include "merginerrortypes.h" #include "androidutils.h" #include "ios/iosutils.h" #include "inpututils.h" diff --git a/app/mmstyle.h b/app/mmstyle.h index 51a60e91cb..98b30eff22 100644 --- a/app/mmstyle.h +++ b/app/mmstyle.h @@ -147,6 +147,7 @@ class MMStyle: public QObject Q_PROPERTY( QUrl acceptInvitationLogoImage READ acceptInvitationLogoImage CONSTANT ) Q_PROPERTY( QUrl reachedDataLimitImage READ reachedDataLimitImage CONSTANT ) Q_PROPERTY( QUrl uploadImage READ uploadImage CONSTANT ) + Q_PROPERTY( QUrl warnLogoImage READ warnLogoImage CONSTANT ) // Map items Q_PROPERTY( double mapItemHeight READ mapItemHeight CONSTANT ) @@ -279,6 +280,7 @@ class MMStyle: public QObject QUrl acceptInvitationImage() {return QUrl( "qrc:/AcceptInvitationImage.svg" ); } QUrl uploadImage() {return QUrl( "qrc:/UploadImage.svg" );} QUrl reachedDataLimitImage() {return QUrl( "qrc:/ReachedDataLimitImage.svg" );} + QUrl warnLogoImage() {return QUrl( "qrc:/WarnLogoImage.svg" );} double mapItemHeight() {return 50 * mDp;} diff --git a/app/qml/CMakeLists.txt b/app/qml/CMakeLists.txt index b795a448e7..0fa25e1a2f 100644 --- a/app/qml/CMakeLists.txt +++ b/app/qml/CMakeLists.txt @@ -71,6 +71,7 @@ set(MM_QML components/MMToolbarButton.qml components/MMToolbarLongButton.qml components/MMToolbarMenuButton.qml + components/MMWarningBubble.qml onboarding/MMAcceptInvitation.qml onboarding/MMCreateWorkspace.qml onboarding/MMHowYouFoundUs.qml diff --git a/app/qml/components/MMWarningBubble.qml b/app/qml/components/MMWarningBubble.qml new file mode 100644 index 0000000000..f953e4dc4f --- /dev/null +++ b/app/qml/components/MMWarningBubble.qml @@ -0,0 +1,53 @@ +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +Item { + id: root + + height: row.height + + required property string text + + Rectangle { + width: root.width + height: row.height + color: __style.nightColor + radius: __style.inputRadius + } + + Row { + id: row + + padding: 20 * __dp + spacing: 10 * __dp + + Image { + id: icon + + width: 50 * __dp + height: width + + source: __style.warnLogoImage + } + + Text { + width: root.width - icon.width - 4 * row.spacing - 2 * row.padding + height: icon.height + text: root.text + font: __style.t3 + color: __style.whiteColor + wrapMode: Label.WordWrap + lineHeight: 1.5 + } + } +} diff --git a/app/qml/onboarding/MMCreateWorkspace.qml b/app/qml/onboarding/MMCreateWorkspace.qml index a7521c6258..58bb2e78b9 100644 --- a/app/qml/onboarding/MMCreateWorkspace.qml +++ b/app/qml/onboarding/MMCreateWorkspace.qml @@ -107,8 +107,8 @@ Page { MMTextBubble { width: root.width - 2 * root.hPadding - title: "Tip from Mergin Maps" - description: "A good candidate for a workspace name is the name of your team or organisation" + title: qsTr("Tip from Mergin Maps") + description: qsTr("A good candidate for a workspace name is the name of your team or organisation") } MMButton { diff --git a/app/qml/onboarding/MMHowYouFoundUs.qml b/app/qml/onboarding/MMHowYouFoundUs.qml index 6fa1e821f3..cf2b91c476 100644 --- a/app/qml/onboarding/MMHowYouFoundUs.qml +++ b/app/qml/onboarding/MMHowYouFoundUs.qml @@ -13,6 +13,8 @@ import QtQuick.Controls import "../components" import "../inputs" +import notificationType 1.0 + Page { id: root @@ -28,6 +30,8 @@ Page { ? 20 * __dp : (20 + (width - __style.maxPageWidth) / 2) * __dp + readonly property string specifySourceText: qsTr("Please specify the source") + Rectangle { anchors.fill: parent color: __style.lightGreenColor @@ -104,22 +108,34 @@ Page { checked: listView.currentIndex === index onClicked: { - root.selectedText = model.name + listView.currentIndex = index if(listView.model.count === listView.currentIndex + 1) + { + root.selectedText = "" listView.positionViewAtEnd() + } + else { + if (model.icon === __style.socialMediaIcon) { + // need to select subcategory + root.selectedText = "" + } else { + root.selectedText = model.name + } + } } } footer: Column { width: root.width - 2 * root.hPadding topPadding: 20 * __dp - visible: listView.model.count === listView.currentIndex + 1 + visible: listView.model.count === listView.currentIndex + 1 // === Other MMInputEditor { + id: otherSourceText title: qsTr("Source") - placeholderText: qsTr("Please specify the source") + placeholderText: root.specifySourceText onTextChanged: root.selectedText = text onVisibleChanged: if(visible) hasFocus = true } @@ -137,8 +153,16 @@ Page { text: qsTr("Continue") onClicked: { - // TODO not allow in case there is missing selected text! - root.howYouFoundUsSelected(root.selectedText) + if (root.selectedText.length > 0 ) { + root.howYouFoundUsSelected(root.selectedText) + } else { + notificationModel.add( + root.specifySourceText, + 5, + NotificationType.Error, + NotificationType.None + ) + } } } } diff --git a/app/qml/onboarding/MMLogin.qml b/app/qml/onboarding/MMLogin.qml index 468938ec8b..0def65b4bf 100644 --- a/app/qml/onboarding/MMLogin.qml +++ b/app/qml/onboarding/MMLogin.qml @@ -94,15 +94,21 @@ Page { Text { // !TODO - need graphic designer input! - visible: root.warningMsg + width: parent.width - 2 * root.hPadding - text: root.warningMsg + font: __style.h2 color: __style.negativeColor wrapMode: Text.WordWrap horizontalAlignment: Text.AlignHCenter } + MMWarningBubble { + visible: root.warningMsg + text: root.warningMsg + width: root.width - 2 * root.hPadding + } + MMInputEditor { id: username width: parent.width - 2 * root.hPadding diff --git a/app/qml/onboarding/MMWhichIndustry.qml b/app/qml/onboarding/MMWhichIndustry.qml index e8a0bbd9c0..0742aa2670 100644 --- a/app/qml/onboarding/MMWhichIndustry.qml +++ b/app/qml/onboarding/MMWhichIndustry.qml @@ -13,6 +13,8 @@ import QtQuick.Controls import "../components" import "../inputs" +import notificationType 1.0 + Page { id: root diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 732d8327ad..ae8b6e8d2f 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -20,6 +20,7 @@ set(MM_CORE_HDRS coreutils.h merginapi.h merginapistatus.h + merginerrortypes.h merginsubscriptioninfo.h merginsubscriptionstatus.h merginservertype.h diff --git a/core/merginapi.cpp b/core/merginapi.cpp index 3b47d87c9a..9e702bfbc7 100644 --- a/core/merginapi.cpp +++ b/core/merginapi.cpp @@ -25,6 +25,7 @@ #include "geodiffutils.h" #include "localprojectsmanager.h" #include "../app/enumhelper.h" +#include "merginerrortypes.h" #include diff --git a/core/merginapi.h b/core/merginapi.h index 2d67c3d646..d34db06eb7 100644 --- a/core/merginapi.h +++ b/core/merginapi.h @@ -35,22 +35,6 @@ #include "merginworkspaceinfo.h" #include "merginuserauth.h" -class RegistrationError -{ - Q_GADGET - public: - enum RegistrationErrorType - { - OTHER = 0, - USERNAME, - EMAIL, - PASSWORD, - CONFIRM_PASSWORD, - TOC - }; - Q_ENUM( RegistrationErrorType ) -}; - struct ProjectDiff { // changes that should be pushed diff --git a/core/merginerrortypes.h b/core/merginerrortypes.h new file mode 100644 index 0000000000..0c471ba74f --- /dev/null +++ b/core/merginerrortypes.h @@ -0,0 +1,31 @@ +/*************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef MERGINERRORTYPES_H +#define MERGINERRORTYPES_H + +#include + +class RegistrationError +{ + Q_GADGET +public: + enum RegistrationErrorType + { + OTHER = 0, + USERNAME, + EMAIL, + PASSWORD, + CONFIRM_PASSWORD, + TOC + }; + Q_ENUM( RegistrationErrorType ) +}; + +#endif diff --git a/gallery/CMakeLists.txt b/gallery/CMakeLists.txt index 0f8a077551..4c26cb45c3 100644 --- a/gallery/CMakeLists.txt +++ b/gallery/CMakeLists.txt @@ -29,7 +29,12 @@ find_package( qt_standard_project_setup() qt_policy(SET QTP0001 NEW) -set(GALLERY_HDRS helper.h notificationmodel.h ../app/mmstyle.h) +set(GALLERY_HDRS + helper.h + notificationmodel.h + ../app/mmstyle.h + ../core/merginerrortypes.h +) set(GALLERY_SRCS helper.cpp notificationmodel.cpp main.cpp) @@ -74,7 +79,7 @@ set_target_properties( ) target_link_libraries(MerginMapsGallery PRIVATE Qt6::Quick) -target_include_directories(MerginMapsGallery PRIVATE ../app) +target_include_directories(MerginMapsGallery PRIVATE ../app ../core) install( TARGETS MerginMapsGallery diff --git a/gallery/main.cpp b/gallery/main.cpp index f4e74460c9..c87ae169c5 100644 --- a/gallery/main.cpp +++ b/gallery/main.cpp @@ -18,6 +18,8 @@ #include #include #include "notificationmodel.h" +#include "merginerrortypes.h" + int main( int argc, char *argv[] ) { QGuiApplication app( argc, argv ); @@ -26,6 +28,10 @@ int main( int argc, char *argv[] ) QQmlApplicationEngine engine; + // Register C++ enums + qmlRegisterUncreatableType( "lc", 1, 0, "RegistrationError", "RegistrationError Enum" ); + + #ifdef DESKTOP_OS HotReload hotReload( engine ); engine.rootContext()->setContextProperty( "_hotReload", &hotReload ); @@ -36,6 +42,7 @@ int main( int argc, char *argv[] ) NotificationModel notificationModel; engine.rootContext()->setContextProperty( "notificationModel", ¬ificationModel ); + // path to local wrapper pages engine.rootContext()->setContextProperty( "_qmlWrapperPath", QGuiApplication::applicationDirPath() + "/HotReload/qml/pages/" ); engine.rootContext()->setContextProperty( "__dp", dp ); diff --git a/gallery/qml.qrc b/gallery/qml.qrc index c2a1f484de..fbd99f0d53 100644 --- a/gallery/qml.qrc +++ b/gallery/qml.qrc @@ -68,5 +68,6 @@ ../app/qml/components/MMBackButton.qml ../app/qml/components/MMIconCheckBoxHorizontal.qml ../app/qml/components/MMIconCheckBoxVertical.qml + ../app/qml/components/MMWarningBubble.qml diff --git a/gallery/qml/pages/MiscPage.qml b/gallery/qml/pages/MiscPage.qml index 25a7085616..26aa7cac81 100644 --- a/gallery/qml/pages/MiscPage.qml +++ b/gallery/qml/pages/MiscPage.qml @@ -196,5 +196,26 @@ ScrollView { } } } + + GroupBox { + title: "MMWarningBubble" + background: Rectangle { + color: "white" + } + label: Label { + color: "black" + text: parent.title + padding: 5 + } + + Column { + spacing: 20 + anchors.fill: parent + MMWarningBubble { + width: page.width - 64 + text: "Server is broken, sorry. \n Please wait for tomorrow" + } + } + } } } diff --git a/gallery/qml/pages/OnboardingPage.qml b/gallery/qml/pages/OnboardingPage.qml index 8e9309035e..ec84141cda 100644 --- a/gallery/qml/pages/OnboardingPage.qml +++ b/gallery/qml/pages/OnboardingPage.qml @@ -12,6 +12,8 @@ import QtQuick.Controls import QtQuick.Layouts import "../../app/qml/onboarding" +import "../../app/qml/components" +import notificationType 1.0 Page { id: pane @@ -80,14 +82,25 @@ Page { MMLogin { id: login + apiRoot: "app.merginmaps.com" + warningMsg: "This is warning message like server offline" anchors.fill: parent visible: false - onSignInClicked: console.log("Sign in clicked") + onSignInClicked: function(username, password) { + pending = true + console.log("Sign in clicked: " + username + " ; " + password) + } onSignUpClicked: console.log("Sign up clicked") - onChangeServerClicked: console.log("Change server clicked") - onBackClicked: visible = false + onChangeServerClicked: function (newServer) { + console.log("Change server clicked: " + newServer) + } + onBackClicked: { + pending = false + visible = false + } + onForgotPasswordClicked: console.log("Forgot password clicked") } MMSignUp { @@ -96,9 +109,14 @@ Page { anchors.fill: parent visible: false + tocString: "Please read our Terms and Conditions" + onSignInClicked: console.log("Sign in clicked") - onSignUpClicked: console.log("Sign up clicked") + onSignUpClicked: function(username, email, password, passwordConfirm, tocAccept, newsletterSubscribe) { + console.log("Sign up clicked: " + username + ";" + email + ";" + password + ";" + passwordConfirm + ";" + tocAccept + ";" + newsletterSubscribe) + } onBackClicked: visible = false + } MMAcceptInvitation { @@ -108,9 +126,12 @@ Page { visible: false user: "Lubos" workspace: "my-workspace.funny" + workspaceUuid: "86c4c459-bb7b-4baa-b5d1-690fb05a9310" + haveBack: true + showCreate: true onBackClicked: visible = false - onContinueClicked: console.log("Join workspace clicked") + onJoinWorkspaceClicked: function(workspaceUuid) { console.log("Join workspace clicked " + workspaceUuid) } onCreateWorkspaceClicked: console.log("Create new workspace clicked") } @@ -120,7 +141,10 @@ Page { anchors.fill: parent visible: false - onContinueClicked: visible = false + onCreateWorkspaceClicked: function (name) { + visible = false + console.log("Create workspace clicked " + name) + } } MMHowYouFoundUs { @@ -130,8 +154,8 @@ Page { visible: false onBackClicked: visible = false - onContinueClicked: function(selectedText) { - console.log("Selected: " + selectedText) + onHowYouFoundUsSelected: function(selectedText) { + console.log("Selected how you found us: " + selectedText) visible = false } } @@ -143,9 +167,11 @@ Page { visible: false onBackClicked: visible = false - onContinueClicked: function(selectedText) { - console.log("Selected: " + selectedText) + onIndustrySelected: function(selectedText) { + console.log("Selected industry: " + selectedText) visible = false } } + + MMNotificationView {} }