mirror of
https://github.com/laurent22/joplin.git
synced 2024-12-24 10:27:10 +02:00
Handle login frontend
This commit is contained in:
parent
7e0ee0ba9c
commit
e16122d978
@ -21,7 +21,8 @@ SOURCES += \
|
||||
models/change.cpp \
|
||||
models/basemodel.cpp \
|
||||
models/setting.cpp \
|
||||
paths.cpp
|
||||
paths.cpp \
|
||||
window.cpp
|
||||
|
||||
RESOURCES += qml.qrc \
|
||||
database.qrc
|
||||
@ -57,7 +58,8 @@ HEADERS += \
|
||||
enum.h \
|
||||
models/setting.h \
|
||||
paths.h \
|
||||
constants.h
|
||||
constants.h \
|
||||
window.h
|
||||
|
||||
DISTFILES += \
|
||||
AndroidManifest.xml
|
||||
|
@ -1,4 +1,29 @@
|
||||
import QtQuick 2.4
|
||||
|
||||
LoginPageForm {
|
||||
|
||||
property Item appRoot
|
||||
|
||||
id: root
|
||||
|
||||
Connections {
|
||||
target: root
|
||||
onLoginButtonClicked: {
|
||||
dispatcher.emitLoginClicked(root.apiBaseUrl, root.email, root.password);
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: dispatcher
|
||||
onLoginStarted: {
|
||||
root.enabled = false;
|
||||
}
|
||||
onLoginFailed: {
|
||||
root.enabled = true;
|
||||
}
|
||||
onLoginSuccess: {
|
||||
root.enabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3,8 +3,19 @@ import QtQuick.Controls 2.0
|
||||
import QtQuick.Layouts 1.3
|
||||
|
||||
Item {
|
||||
id: root
|
||||
width: 400
|
||||
height: 400
|
||||
signal loginButtonClicked()
|
||||
property alias apiBaseUrl: apiBaseUrlTF.text
|
||||
property alias email: emailTF.text
|
||||
property alias password: passwordTF.text
|
||||
|
||||
Rectangle {
|
||||
id: rectangle2
|
||||
color: "#ffffff"
|
||||
anchors.fill: parent
|
||||
}
|
||||
|
||||
GridLayout {
|
||||
id: gridLayout1
|
||||
@ -15,11 +26,12 @@ Item {
|
||||
|
||||
Label {
|
||||
id: label1
|
||||
text: qsTr("Domain")
|
||||
text: qsTr("API base URL")
|
||||
}
|
||||
|
||||
TextField {
|
||||
id: textField1
|
||||
id: apiBaseUrlTF
|
||||
text: "http://joplin.local"
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
@ -29,7 +41,8 @@ Item {
|
||||
}
|
||||
|
||||
TextField {
|
||||
id: textField2
|
||||
id: emailTF
|
||||
text: "laurent@cozic.net"
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
@ -39,12 +52,13 @@ Item {
|
||||
}
|
||||
|
||||
TextField {
|
||||
id: textField3
|
||||
id: passwordTF
|
||||
text: "12345678"
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Button {
|
||||
id: button1
|
||||
id: loginButton
|
||||
text: qsTr("Login")
|
||||
Layout.fillWidth: true
|
||||
Layout.columnSpan: 2
|
||||
@ -65,4 +79,10 @@ Item {
|
||||
|
||||
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: loginButton
|
||||
onClicked: root.loginButtonClicked()
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -12,17 +12,49 @@ Item {
|
||||
signal addNoteButtonClicked()
|
||||
signal addFolderButtonClicked()
|
||||
signal syncButtonClicked()
|
||||
signal loginButtonClicked()
|
||||
property alias currentFolderIndex: mainPage.currentFolderIndex
|
||||
property alias currentNoteIndex: mainPage.currentNoteIndex
|
||||
|
||||
property var pages : ({})
|
||||
|
||||
function pageByName(pageName) {
|
||||
if (root.pages[pageName]) return root.pages[pageName];
|
||||
|
||||
var page = null;
|
||||
if (pageName === "main") {
|
||||
page = mainPage
|
||||
} else if (pageName === "login") {
|
||||
var s = '
|
||||
LoginPage {
|
||||
id: loginPage
|
||||
anchors.fill: parent
|
||||
visible: false
|
||||
appRoot: root
|
||||
}';
|
||||
page = Qt.createQmlObject(s, root);
|
||||
}
|
||||
|
||||
root.pages[pageName] = page;
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
function showPage(pageName) {
|
||||
for (var n in root.pages) {
|
||||
root.pages[n].visible = false;
|
||||
}
|
||||
|
||||
print("Switching to page: " + pageName);
|
||||
var page = pageByName(pageName);
|
||||
page.visible = true;
|
||||
}
|
||||
|
||||
MainPage {
|
||||
id: mainPage
|
||||
anchors.fill: parent
|
||||
appRoot: root
|
||||
}
|
||||
|
||||
LoginPage {
|
||||
|
||||
visible: false
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -16,8 +16,7 @@ using namespace jop;
|
||||
Application::Application(int &argc, char **argv) :
|
||||
QGuiApplication(argc, argv),
|
||||
db_(jop::db()),
|
||||
api_(jop::API_BASE_URL),
|
||||
synchronizer_(api_.baseUrl(), db_),
|
||||
synchronizer_(db_),
|
||||
folderModel_(db_)
|
||||
|
||||
{
|
||||
@ -43,6 +42,7 @@ Application::Application(int &argc, char **argv) :
|
||||
ctxt->setContextProperty("folderListModel", &folderModel_);
|
||||
ctxt->setContextProperty("noteListModel", ¬eModel_);
|
||||
ctxt->setContextProperty("noteModel", &selectedQmlNote_);
|
||||
ctxt->setContextProperty("dispatcher", &dispatcher());
|
||||
|
||||
view_.setSource(QUrl("qrc:/app.qml"));
|
||||
|
||||
@ -56,6 +56,7 @@ Application::Application(int &argc, char **argv) :
|
||||
connect(&dispatcher(), SIGNAL(folderCreated(QString)), this, SLOT(dispatcher_folderCreated(QString)));
|
||||
connect(&dispatcher(), SIGNAL(folderUpdated(QString)), this, SLOT(dispatcher_folderUpdated(QString)));
|
||||
connect(&dispatcher(), SIGNAL(folderDeleted(QString)), this, SLOT(dispatcher_folderDeleted(QString)));
|
||||
connect(&dispatcher(), SIGNAL(loginClicked(QString,QString,QString)), this, SLOT(dispatcher_loginClicked(QString,QString,QString)));
|
||||
|
||||
view_.show();
|
||||
|
||||
@ -66,6 +67,12 @@ Application::Application(int &argc, char **argv) :
|
||||
|
||||
connect(&api_, SIGNAL(requestDone(const QJsonObject&, const QString&)), this, SLOT(api_requestDone(const QJsonObject&, const QString&)));
|
||||
|
||||
if (!settings.contains("user.email") || !settings.contains("session.id") || !settings.contains("api.baseUrl")) {
|
||||
view_.showPage("login");
|
||||
} else {
|
||||
view_.showPage("main");
|
||||
}
|
||||
|
||||
// Don't store password, store session ID
|
||||
// QString clientId = "B6E12222B6E12222";
|
||||
// if (!settings.contains("user.email")) {
|
||||
@ -77,7 +84,19 @@ Application::Application(int &argc, char **argv) :
|
||||
// postData.addQueryItem("email", settings.value("user.email").toString());
|
||||
// postData.addQueryItem("password", settings.value("user.password").toString());
|
||||
// postData.addQueryItem("client_id", clientId);
|
||||
// api_.post("sessions", QUrlQuery(), postData, "getSession");
|
||||
// api_.post("sessions", QUrlQuery(), postData, "getSession");
|
||||
}
|
||||
|
||||
void Application::login(const QString &email, const QString &password) {
|
||||
QUrlQuery postData;
|
||||
postData.addQueryItem("email", email);
|
||||
postData.addQueryItem("password", password);
|
||||
postData.addQueryItem("client_id", clientId());
|
||||
api_.post("sessions", QUrlQuery(), postData, "getSession");
|
||||
}
|
||||
|
||||
QString Application::clientId() const {
|
||||
return "2222222222222222";
|
||||
}
|
||||
|
||||
void Application::api_requestDone(const QJsonObject& response, const QString& tag) {
|
||||
@ -85,10 +104,18 @@ void Application::api_requestDone(const QJsonObject& response, const QString& ta
|
||||
// Handle expired sessions
|
||||
|
||||
if (tag == "getSession") {
|
||||
QString sessionId = response.value("id").toString();
|
||||
Settings settings;
|
||||
settings.setValue("sessionId", sessionId);
|
||||
afterSessionInitialization();
|
||||
if (response.contains("error")) {
|
||||
qCritical() << "Could not get session:" << response.value("error").toString();
|
||||
dispatcher().emitLoginFailed();
|
||||
} else {
|
||||
QString sessionId = response.value("id").toString();
|
||||
qDebug() << "Got session" << sessionId;
|
||||
Settings settings;
|
||||
settings.setValue("session.id", sessionId);
|
||||
afterSessionInitialization();
|
||||
dispatcher().emitLoginSuccess();
|
||||
}
|
||||
view_.showPage("main");
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -108,6 +135,19 @@ void Application::dispatcher_folderDeleted(const QString &folderId) {
|
||||
//synchronizerTimer_.start(1000 * 3);
|
||||
}
|
||||
|
||||
void Application::dispatcher_loginClicked(const QString &apiBaseUrl, const QString &email, const QString &password) {
|
||||
qDebug() << apiBaseUrl << email << password;
|
||||
dispatcher().emitLoginStarted();
|
||||
|
||||
Settings settings;
|
||||
settings.setValue("user.email", email);
|
||||
settings.setValue("api.baseUrl", apiBaseUrl);
|
||||
|
||||
api_.setBaseUrl(apiBaseUrl);
|
||||
|
||||
login(email, password);
|
||||
}
|
||||
|
||||
void Application::synchronizerTimer_timeout() {
|
||||
//synchronizerTimer_.start(1000 * 10);
|
||||
synchronizer_.start();
|
||||
@ -134,7 +174,7 @@ void Application::afterSessionInitialization() {
|
||||
// request a new session everytime on startup.
|
||||
|
||||
Settings settings;
|
||||
QString sessionId = settings.value("sessionId").toString();
|
||||
QString sessionId = settings.value("session.id").toString();
|
||||
qDebug() << "Session:" << sessionId;
|
||||
api_.setSessionId(sessionId);
|
||||
synchronizer_.setSessionId(sessionId);
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "models/qmlnote.h"
|
||||
#include "webapi.h"
|
||||
#include "synchronizer.h"
|
||||
#include "window.h"
|
||||
|
||||
namespace jop {
|
||||
|
||||
@ -20,10 +21,12 @@ class Application : public QGuiApplication {
|
||||
public:
|
||||
|
||||
Application(int &argc, char **argv);
|
||||
void login(const QString& email, const QString& password);
|
||||
QString clientId() const;
|
||||
|
||||
private:
|
||||
|
||||
QQuickView view_;
|
||||
Window view_;
|
||||
Database& db_;
|
||||
NoteCollection noteCollection_;
|
||||
FolderModel folderModel_;
|
||||
@ -50,6 +53,7 @@ public slots:
|
||||
void dispatcher_folderCreated(const QString& folderId);
|
||||
void dispatcher_folderUpdated(const QString& folderId);
|
||||
void dispatcher_folderDeleted(const QString& folderId);
|
||||
void dispatcher_loginClicked(const QString &domain, const QString &email, const QString &password);
|
||||
|
||||
void synchronizerTimer_timeout();
|
||||
|
||||
|
@ -8,7 +8,6 @@ namespace jop {
|
||||
const QString ORG_NAME = "Cozic";
|
||||
const QString ORG_DOMAIN = "cozic.net";
|
||||
const QString APP_NAME = "Joplin";
|
||||
const QString API_BASE_URL = "https://joplin.cozic.net";
|
||||
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,22 @@ void Dispatcher::emitFolderDeleted(const QString &folderId) {
|
||||
emit folderDeleted(folderId);
|
||||
}
|
||||
|
||||
void Dispatcher::emitLoginClicked(const QString &apiBaseUrl, const QString &email, const QString &password) {
|
||||
emit loginClicked(apiBaseUrl, email, password);
|
||||
}
|
||||
|
||||
void Dispatcher::emitLoginStarted() {
|
||||
emit loginStarted();
|
||||
}
|
||||
|
||||
void Dispatcher::emitLoginFailed() {
|
||||
emit loginFailed();
|
||||
}
|
||||
|
||||
void Dispatcher::emitLoginSuccess() {
|
||||
emit loginSuccess();
|
||||
}
|
||||
|
||||
Dispatcher dispatcherInstance_;
|
||||
|
||||
Dispatcher& jop::dispatcher() {
|
||||
|
@ -12,15 +12,26 @@ class Dispatcher : public QObject {
|
||||
public:
|
||||
|
||||
Dispatcher();
|
||||
|
||||
public slots:
|
||||
|
||||
void emitFolderCreated(const QString& folderId);
|
||||
void emitFolderUpdated(const QString& folderId);
|
||||
void emitFolderDeleted(const QString& folderId);
|
||||
void emitLoginClicked(const QString& domain, const QString& email, const QString &password);
|
||||
void emitLoginStarted();
|
||||
void emitLoginFailed();
|
||||
void emitLoginSuccess();
|
||||
|
||||
signals:
|
||||
|
||||
void folderCreated(const QString& folderId);
|
||||
void folderUpdated(const QString& folderId);
|
||||
void folderDeleted(const QString& folderId);
|
||||
void loginClicked(const QString& domain, const QString& email, const QString& password);
|
||||
void loginStarted();
|
||||
void loginFailed();
|
||||
void loginSuccess();
|
||||
|
||||
};
|
||||
|
||||
|
@ -5,8 +5,7 @@
|
||||
|
||||
using namespace jop;
|
||||
|
||||
Synchronizer::Synchronizer(const QString &apiUrl, Database &database) : api_(apiUrl), db_(database) {
|
||||
qDebug() << api_.baseUrl();
|
||||
Synchronizer::Synchronizer(Database &database) : db_(database) {
|
||||
state_ = Idle;
|
||||
uploadsRemaining_ = 0;
|
||||
connect(&api_, SIGNAL(requestDone(QJsonObject,QString)), this, SLOT(api_requestDone(QJsonObject,QString)));
|
||||
|
@ -16,7 +16,7 @@ public:
|
||||
|
||||
enum SynchronizationState { Idle, UploadingChanges, DownloadingChanges };
|
||||
|
||||
Synchronizer(const QString& apiUrl, Database& database);
|
||||
Synchronizer(Database& database);
|
||||
void start();
|
||||
void setSessionId(const QString& v);
|
||||
|
||||
|
@ -4,8 +4,8 @@
|
||||
|
||||
using namespace jop;
|
||||
|
||||
WebApi::WebApi(const QString &baseUrl) {
|
||||
baseUrl_ = baseUrl;
|
||||
WebApi::WebApi() {
|
||||
baseUrl_ = "";
|
||||
sessionId_ = "";
|
||||
connect(&manager_, SIGNAL(finished(QNetworkReply*)), this, SLOT(request_finished(QNetworkReply*)));
|
||||
}
|
||||
@ -15,6 +15,14 @@ QString WebApi::baseUrl() const {
|
||||
}
|
||||
|
||||
void WebApi::execRequest(HttpMethod method, const QString &path, const QUrlQuery &query, const QUrlQuery &data, const QString& tag) {
|
||||
if (baseUrl() == "") {
|
||||
qCritical() << "Trying to execute request before base URL has been set";
|
||||
QJsonObject obj;
|
||||
obj["error"] = "Trying to execute request before base URL has been set";
|
||||
emit requestDone(obj, tag);
|
||||
return;
|
||||
}
|
||||
|
||||
QueuedRequest r;
|
||||
r.method = method;
|
||||
r.path = path;
|
||||
@ -136,3 +144,7 @@ void WebApi::request_finished(QNetworkReply *reply) {
|
||||
void WebApi::request_error(QNetworkReply::NetworkError e) {
|
||||
qDebug() << "Network error" << e;
|
||||
}
|
||||
|
||||
void jop::WebApi::setBaseUrl(const QString &v) {
|
||||
baseUrl_ = v;
|
||||
}
|
||||
|
@ -23,7 +23,8 @@ public:
|
||||
QBuffer* buffer;
|
||||
};
|
||||
|
||||
WebApi(const QString& baseUrl);
|
||||
WebApi();
|
||||
void setBaseUrl(const QString& v);
|
||||
QString baseUrl() const;
|
||||
void execRequest(HttpMethod method, const QString& path,const QUrlQuery& query = QUrlQuery(), const QUrlQuery& data = QUrlQuery(), const QString& tag = "");
|
||||
void post(const QString& path,const QUrlQuery& query = QUrlQuery(), const QUrlQuery& data = QUrlQuery(), const QString& tag = "");
|
||||
|
11
QtClient/JoplinQtClient/window.cpp
Executable file
11
QtClient/JoplinQtClient/window.cpp
Executable file
@ -0,0 +1,11 @@
|
||||
#include "window.h"
|
||||
|
||||
using namespace jop;
|
||||
|
||||
Window::Window() : QQuickView() {}
|
||||
|
||||
void Window::showPage(const QString &pageName) {
|
||||
QVariant pageNameV(pageName);
|
||||
QVariant returnedValue;
|
||||
QMetaObject::invokeMethod((QObject*)rootObject(), "showPage", Q_RETURN_ARG(QVariant, returnedValue), Q_ARG(QVariant, pageNameV));
|
||||
}
|
21
QtClient/JoplinQtClient/window.h
Executable file
21
QtClient/JoplinQtClient/window.h
Executable file
@ -0,0 +1,21 @@
|
||||
#ifndef WINDOW_H
|
||||
#define WINDOW_H
|
||||
|
||||
#include <stable.h>
|
||||
|
||||
namespace jop {
|
||||
|
||||
class Window : public QQuickView {
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
Window();
|
||||
void showPage(const QString& pageName);
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // WINDOW_H
|
Loading…
Reference in New Issue
Block a user