mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-12-27 00:19:25 -05:00
Retroshare QML App: Implemesh some basic stuff
Implement location creation, selection and login Implement people listing Implement firends adding (not working yet) Depend on androidextra qt module only if compiling for android LibresapiLocalClient parse one line at time to avoid error if two requests are sent rapidly one after another LibresapiLocalClient socket path now is a parameter of openConnection() to use it as qml type constructor without parameter must be useful Added JSONListModel for JASON based MVC pattern
This commit is contained in:
parent
ad21d7202a
commit
8d6d3d1894
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
TARGET = retroshare-android-service
|
TARGET = retroshare-android-service
|
||||||
|
|
||||||
QT += core network androidextras
|
QT += core network
|
||||||
QT -= gui
|
QT -= gui
|
||||||
|
|
||||||
CONFIG += c++11
|
CONFIG += c++11
|
||||||
|
@ -18,7 +18,10 @@
|
|||||||
|
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QtAndroidExtras>
|
|
||||||
|
#ifdef __ANDROID__
|
||||||
|
# include <QtAndroidExtras>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "retroshare/rsinit.h"
|
#include "retroshare/rsinit.h"
|
||||||
#include "api/ApiServer.h"
|
#include "api/ApiServer.h"
|
||||||
@ -39,8 +42,10 @@ int main(int argc, char *argv[])
|
|||||||
qDebug() << "Listening on:" << sockPath;
|
qDebug() << "Listening on:" << sockPath;
|
||||||
ApiServerLocal apiServerLocal(&api, sockPath); (void) apiServerLocal;
|
ApiServerLocal apiServerLocal(&api, sockPath); (void) apiServerLocal;
|
||||||
|
|
||||||
|
#ifdef __ANDROID__
|
||||||
qDebug() << "Is service.cpp running as a service?" << QtAndroid::androidService().isValid();
|
qDebug() << "Is service.cpp running as a service?" << QtAndroid::androidService().isValid();
|
||||||
qDebug() << "Is service.cpp running as an activity?" << QtAndroid::androidActivity().isValid();
|
qDebug() << "Is service.cpp running as an activity?" << QtAndroid::androidActivity().isValid();
|
||||||
|
#endif
|
||||||
|
|
||||||
while (!ctrl_mod.processShouldExit())
|
while (!ctrl_mod.processShouldExit())
|
||||||
{
|
{
|
||||||
|
@ -1,35 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* RetroShare Android QML App
|
||||||
|
* Copyright (C) 2016 Gioacchino Mazzurco <gio@eigenlab.org>
|
||||||
|
* Copyright (C) 2016 Manu Pineda <manu@cooperativa.cat>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
#include "libresapilocalclient.h"
|
#include "libresapilocalclient.h"
|
||||||
#include "debugutils.h"
|
#include "debugutils.h"
|
||||||
#include <QChar>
|
#include <QChar>
|
||||||
|
|
||||||
/* Constructor de còpia per proves, no s'ha d'usar.
|
|
||||||
LibresapiLocalClient::LibresapiLocalClient(const LibresapiLocalClient & l)
|
|
||||||
{
|
|
||||||
//mLocalSocket = l.mLocalSocket;
|
|
||||||
receivedBytes = l.receivedBytes;
|
|
||||||
json = l.json;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
LibresapiLocalClient::LibresapiLocalClient(const QString & socketPath) :
|
void LibresapiLocalClient::openConnection(QString socketPath)
|
||||||
mLocalSocket(this)
|
|
||||||
{
|
{
|
||||||
myDebug(this);
|
connect(& mLocalSocket, SIGNAL(error(QLocalSocket::LocalSocketError)),
|
||||||
mSocketPath = socketPath;
|
this, SLOT(socketError(QLocalSocket::LocalSocketError)));
|
||||||
connect(& mLocalSocket, SIGNAL(error(QLocalSocket::LocalSocketError)),
|
connect(& mLocalSocket, SIGNAL(readyRead()),
|
||||||
this, SLOT(socketError(QLocalSocket::LocalSocketError)));
|
this, SLOT(read()));
|
||||||
connect(& mLocalSocket, SIGNAL(readyRead()),
|
mLocalSocket.connectToServer(socketPath);
|
||||||
this, SLOT(read()));
|
|
||||||
//openConnection();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void LibresapiLocalClient::openConnection()
|
|
||||||
{
|
|
||||||
mLocalSocket.connectToServer(mSocketPath);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int LibresapiLocalClient::request(const QString & path, const QString & jsonData)
|
int LibresapiLocalClient::request(const QString & path, const QString & jsonData)
|
||||||
{
|
{
|
||||||
|
qDebug() << "LibresapiLocalClient::request()" << path << jsonData;
|
||||||
QByteArray data;
|
QByteArray data;
|
||||||
data.append(path); data.append('\n');
|
data.append(path); data.append('\n');
|
||||||
data.append(jsonData); data.append('\n');
|
data.append(jsonData); data.append('\n');
|
||||||
@ -38,25 +42,24 @@ int LibresapiLocalClient::request(const QString & path, const QString & jsonData
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LibresapiLocalClient::socketError(QLocalSocket::LocalSocketError error)
|
void LibresapiLocalClient::socketError(QLocalSocket::LocalSocketError)
|
||||||
{
|
{
|
||||||
myDebug("error!!!!\n" + mLocalSocket.errorString());//error.errorString());
|
myDebug("error!!!!\n" + mLocalSocket.errorString());
|
||||||
}
|
}
|
||||||
|
|
||||||
void LibresapiLocalClient::read()
|
void LibresapiLocalClient::read()
|
||||||
{
|
{
|
||||||
receivedBytes = mLocalSocket.readAll();
|
receivedBytes = mLocalSocket.readLine();
|
||||||
|
|
||||||
if(parseResponse()){ // pensar en fer un buffer per parsejar, per evitar errors.
|
|
||||||
emit goodResponseReceived(QString(receivedBytes));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QString errMess = "The message was not understood!\n"
|
|
||||||
"It should be a JSON formatted text file\n"
|
|
||||||
"Its contents were:\n" + receivedBytes;
|
|
||||||
myDebug(errMess.replace(QChar('\n'), QChar::LineSeparator));
|
|
||||||
|
|
||||||
|
if(parseResponse()) // pensar en fer un buffer per parsejar, per evitar errors.
|
||||||
|
emit goodResponseReceived(QString(receivedBytes));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QString errMess = "The message was not understood!\n"
|
||||||
|
"It should be a JSON formatted text file\n"
|
||||||
|
"Its contents were:\n" + receivedBytes;
|
||||||
|
myDebug(errMess.replace(QChar('\n'), QChar::LineSeparator));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LibresapiLocalClient::parseResponse()
|
bool LibresapiLocalClient::parseResponse()
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* libresapi local socket client
|
* libresapi local socket client
|
||||||
|
* Copyright (C) 2016 Gioacchino Mazzurco <gio@eigenlab.org>
|
||||||
* Copyright (C) 2016 Manu Pineda <manu@cooperativa.cat>
|
* Copyright (C) 2016 Manu Pineda <manu@cooperativa.cat>
|
||||||
*
|
*
|
||||||
* This program is free software: you can redistribute it and/or modify
|
* This program is free software: you can redistribute it and/or modify
|
||||||
@ -26,39 +27,30 @@
|
|||||||
|
|
||||||
class LibresapiLocalClient : public QObject
|
class LibresapiLocalClient : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
LibresapiLocalClient() : mLocalSocket(this) {}
|
||||||
|
|
||||||
LibresapiLocalClient() {}
|
// potser abstreure el següent amb QUrl urlPath (path) i amb QJson jsonData.
|
||||||
// LibresapiLocalClient(const LibresapiLocalClient & l);
|
Q_INVOKABLE int request(const QString & path, const QString & jsonData);
|
||||||
LibresapiLocalClient(const QString & socketPath);
|
const QJsonDocument & getJson();
|
||||||
// potser abstreure el següent amb QUrl urlPath (path) i amb QJson jsonData.
|
Q_INVOKABLE void openConnection(QString socketPath);
|
||||||
Q_INVOKABLE int request(const QString & path, const QString & jsonData);
|
|
||||||
const QJsonDocument & getJson();
|
|
||||||
Q_INVOKABLE void openConnection();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
QLocalSocket mLocalSocket;
|
||||||
|
QByteArray receivedBytes;
|
||||||
|
QJsonDocument json;
|
||||||
|
//QVector<QJsonDocument> responses;
|
||||||
|
|
||||||
QString mSocketPath;
|
bool parseResponse(); //std::string msg);
|
||||||
QLocalSocket mLocalSocket;
|
|
||||||
QByteArray receivedBytes;
|
|
||||||
QJsonDocument json;
|
|
||||||
//QVector<QJsonDocument> responses;
|
|
||||||
|
|
||||||
bool parseResponse(); //std::string msg);
|
private slots:
|
||||||
|
void socketError(QLocalSocket::LocalSocketError error);
|
||||||
private slots:
|
void read();
|
||||||
|
|
||||||
void socketError(QLocalSocket::LocalSocketError error);
|
|
||||||
void read();
|
|
||||||
|
|
||||||
signals:
|
|
||||||
|
|
||||||
void goodResponseReceived(const QString & msg);//, int requestId);
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void goodResponseReceived(const QString & msg);//, int requestId);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // LIBRESAPILOCALCLIENT_H
|
#endif // LIBRESAPILOCALCLIENT_H
|
||||||
|
@ -22,7 +22,10 @@
|
|||||||
#include <QQmlComponent>
|
#include <QQmlComponent>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
#include <QtAndroidExtras>
|
#ifdef __ANDROID__
|
||||||
|
# include <QtAndroidExtras>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
#include <QDateTime>
|
#include <QDateTime>
|
||||||
|
|
||||||
@ -35,20 +38,28 @@ int main(int argc, char *argv[])
|
|||||||
QGuiApplication app(argc, argv);
|
QGuiApplication app(argc, argv);
|
||||||
|
|
||||||
QQmlApplicationEngine engine;
|
QQmlApplicationEngine engine;
|
||||||
|
qmlRegisterType<LibresapiLocalClient>(
|
||||||
|
"org.retroshare.qml_components.LibresapiLocalClient", 1, 0,
|
||||||
|
"LibresapiLocalClient");
|
||||||
|
|
||||||
QString sockPath = QString::fromStdString(RsAccounts::ConfigDirectory());
|
QString sockPath = QString::fromStdString(RsAccounts::ConfigDirectory());
|
||||||
sockPath.append("/libresapi.sock");
|
sockPath.append("/libresapi.sock");
|
||||||
LibresapiLocalClient llc(sockPath);
|
|
||||||
qmlRegisterType<LibresapiLocalClient>("LibresapiLocalClientQml", 1, 0, "LibresapiLocalClientComm");
|
|
||||||
|
|
||||||
engine.rootContext()->setContextProperty("llc", &llc);
|
#ifndef __ANDROID__
|
||||||
engine.load(QUrl(QLatin1String("qrc:/qml/main.qml")));
|
sockPath = "/home/gio/.retroshare/LOC06_8730499b55bb946424d537b180bee10a/libresapi.sock";
|
||||||
|
#endif
|
||||||
|
|
||||||
QFileInfo fileInfo(sockPath);
|
engine.rootContext()->setContextProperty("apiSocketPath", sockPath);
|
||||||
|
engine.load(QUrl(QLatin1String("qrc:/qml/main.qml")));
|
||||||
|
|
||||||
|
QFileInfo fileInfo(sockPath);
|
||||||
|
|
||||||
|
#ifdef __ANDROID__
|
||||||
qDebug() << "Is main.cpp running as a service?" << QtAndroid::androidService().isValid();
|
qDebug() << "Is main.cpp running as a service?" << QtAndroid::androidService().isValid();
|
||||||
qDebug() << "Is main.cpp running as an activity?" << QtAndroid::androidActivity().isValid();
|
qDebug() << "Is main.cpp running as an activity?" << QtAndroid::androidActivity().isValid();
|
||||||
qDebug() << "QML APP:" << sockPath << fileInfo.exists() << fileInfo.lastModified().toString();
|
#endif
|
||||||
|
|
||||||
|
qDebug() << "QML APP:" << sockPath << fileInfo.exists() << fileInfo.lastModified().toString();
|
||||||
|
|
||||||
return app.exec();
|
return app.exec();
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,10 @@
|
|||||||
<file>qml/ChannelGroupDelegate.qml</file>
|
<file>qml/ChannelGroupDelegate.qml</file>
|
||||||
<file>qml/ApplicationBar.qml</file>
|
<file>qml/ApplicationBar.qml</file>
|
||||||
<file>qml/AppButton.qml</file>
|
<file>qml/AppButton.qml</file>
|
||||||
<file>qml/LibresapiLocalClientComm.qml</file>
|
<file>qml/Locations.qml</file>
|
||||||
|
<file>qml/jsonpath.js</file>
|
||||||
|
<file>qml/JSONListModel.qml</file>
|
||||||
|
<file>qml/Contacts.qml</file>
|
||||||
|
<file>qml/AddTrustedNode.qml</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
</RCC>
|
</RCC>
|
||||||
|
39
retroshare-qml-app/src/qml/AddTrustedNode.qml
Normal file
39
retroshare-qml-app/src/qml/AddTrustedNode.qml
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import QtQuick 2.0
|
||||||
|
import QtQuick.Controls 1.4
|
||||||
|
import QtQuick.Layouts 1.3
|
||||||
|
import org.retroshare.qml_components.LibresapiLocalClient 1.0
|
||||||
|
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
Component.onCompleted:
|
||||||
|
{
|
||||||
|
rsApi.openConnection(apiSocketPath)
|
||||||
|
rsApi.request("/peers/self/certificate/", "")
|
||||||
|
}
|
||||||
|
|
||||||
|
LibresapiLocalClient
|
||||||
|
{
|
||||||
|
id: rsApi
|
||||||
|
onGoodResponseReceived: myKeyField.text = JSON.parse(msg).data.cert_string
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout
|
||||||
|
{
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.bottom: bottomButton.top
|
||||||
|
|
||||||
|
TextField { id: myKeyField }
|
||||||
|
TextField { id: otherKeyField }
|
||||||
|
}
|
||||||
|
|
||||||
|
Button
|
||||||
|
{
|
||||||
|
id: bottomButton
|
||||||
|
text: "Add trusted node"
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
onClicked:
|
||||||
|
{
|
||||||
|
rsApi.request("/peers/examine_cert/", JSON.stringify({ cert_string: otherKeyField.text }))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
56
retroshare-qml-app/src/qml/Contacts.qml
Normal file
56
retroshare-qml-app/src/qml/Contacts.qml
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* RetroShare Android QML App
|
||||||
|
* Copyright (C) 2016 Gioacchino Mazzurco <gio@eigenlab.org>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import QtQuick.Controls 1.4
|
||||||
|
import org.retroshare.qml_components.LibresapiLocalClient 1.0
|
||||||
|
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
function refreshData()
|
||||||
|
{
|
||||||
|
rsApi.openConnection(apiSocketPath)
|
||||||
|
rsApi.request("/identity/*/", "")
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: refreshData()
|
||||||
|
onFocusChanged: focus && refreshData()
|
||||||
|
|
||||||
|
LibresapiLocalClient
|
||||||
|
{
|
||||||
|
id: rsApi
|
||||||
|
onGoodResponseReceived: locationsModel.json = msg
|
||||||
|
}
|
||||||
|
|
||||||
|
JSONListModel
|
||||||
|
{
|
||||||
|
id: locationsModel
|
||||||
|
query: "$.data[*]"
|
||||||
|
}
|
||||||
|
|
||||||
|
ListView
|
||||||
|
{
|
||||||
|
id: locationsListView
|
||||||
|
width: parent.width
|
||||||
|
height: 300
|
||||||
|
model: locationsModel.model
|
||||||
|
delegate: Text { text: model.name }
|
||||||
|
}
|
||||||
|
|
||||||
|
Text { text: "Contacts View"; anchors.bottom: parent.bottom }
|
||||||
|
}
|
51
retroshare-qml-app/src/qml/JSONListModel.qml
Normal file
51
retroshare-qml-app/src/qml/JSONListModel.qml
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
/* JSONListModel - a QML ListModel with JSON and JSONPath support
|
||||||
|
*
|
||||||
|
* Copyright (c) 2012 Romain Pokrzywka (KDAB) (romain@kdab.com)
|
||||||
|
* Licensed under the MIT licence (http://opensource.org/licenses/mit-license.php)
|
||||||
|
*/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import "jsonpath.js" as JSONPath
|
||||||
|
|
||||||
|
Item {
|
||||||
|
property string source: ""
|
||||||
|
property string json: ""
|
||||||
|
property string query: ""
|
||||||
|
|
||||||
|
property ListModel model : ListModel { id: jsonModel }
|
||||||
|
property alias count: jsonModel.count
|
||||||
|
|
||||||
|
onSourceChanged: {
|
||||||
|
var xhr = new XMLHttpRequest;
|
||||||
|
xhr.open("GET", source);
|
||||||
|
xhr.onreadystatechange = function() {
|
||||||
|
if (xhr.readyState == XMLHttpRequest.DONE)
|
||||||
|
json = xhr.responseText;
|
||||||
|
}
|
||||||
|
xhr.send();
|
||||||
|
}
|
||||||
|
|
||||||
|
onJsonChanged: updateJSONModel()
|
||||||
|
onQueryChanged: updateJSONModel()
|
||||||
|
|
||||||
|
function updateJSONModel() {
|
||||||
|
jsonModel.clear();
|
||||||
|
|
||||||
|
if ( json === "" )
|
||||||
|
return;
|
||||||
|
|
||||||
|
var objectArray = parseJSONString(json, query);
|
||||||
|
for ( var key in objectArray ) {
|
||||||
|
var jo = objectArray[key];
|
||||||
|
jsonModel.append( jo );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseJSONString(jsonString, jsonPathQuery) {
|
||||||
|
var objectArray = JSON.parse(jsonString);
|
||||||
|
if ( jsonPathQuery !== "" )
|
||||||
|
objectArray = JSONPath.jsonPath(objectArray, jsonPathQuery);
|
||||||
|
|
||||||
|
return objectArray;
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +0,0 @@
|
|||||||
import LibresapiLocalClientQml 1.0
|
|
||||||
|
|
||||||
LibresapiLocalClientComm {
|
|
||||||
id: llc
|
|
||||||
}
|
|
152
retroshare-qml-app/src/qml/Locations.qml
Normal file
152
retroshare-qml-app/src/qml/Locations.qml
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
/*
|
||||||
|
* RetroShare Android QML App
|
||||||
|
* Copyright (C) 2016 Gioacchino Mazzurco <gio@eigenlab.org>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import QtQuick 2.0
|
||||||
|
import QtQuick.Controls 1.4
|
||||||
|
import QtQuick.Layouts 1.3
|
||||||
|
import org.retroshare.qml_components.LibresapiLocalClient 1.0
|
||||||
|
|
||||||
|
Item
|
||||||
|
{
|
||||||
|
id: locationView
|
||||||
|
state: "selectLocation"
|
||||||
|
|
||||||
|
states:
|
||||||
|
[
|
||||||
|
State
|
||||||
|
{
|
||||||
|
name: "selectLocation"
|
||||||
|
PropertyChanges { target: locationsListView; visible: true }
|
||||||
|
PropertyChanges { target: createLocationView; visible: false }
|
||||||
|
PropertyChanges
|
||||||
|
{
|
||||||
|
target: bottomButton
|
||||||
|
text: "Create new location"
|
||||||
|
onClicked: locationView.state = "createLocation"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State
|
||||||
|
{
|
||||||
|
name: "createLocation"
|
||||||
|
PropertyChanges { target: locationsListView; visible: false }
|
||||||
|
PropertyChanges { target: createLocationView; visible: true }
|
||||||
|
PropertyChanges
|
||||||
|
{
|
||||||
|
target: bottomButton
|
||||||
|
text: "Save"
|
||||||
|
onClicked:
|
||||||
|
{
|
||||||
|
var jsonData = { pgp_name: nameField.text, ssl_name: nameField.text, pgp_password: passwordField.text }
|
||||||
|
rsApi.request("/control/create_location/", JSON.stringify(jsonData))
|
||||||
|
onClicked: locationView.state = "savingLocation"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State
|
||||||
|
{
|
||||||
|
name: "savingLocation"
|
||||||
|
PropertyChanges { target: locationsListView; visible: false }
|
||||||
|
PropertyChanges { target: createLocationView; color: "grey" }
|
||||||
|
PropertyChanges
|
||||||
|
{
|
||||||
|
target: bottomButton
|
||||||
|
text: "Saving..."
|
||||||
|
enabled: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
State
|
||||||
|
{
|
||||||
|
name: "loggingIn"
|
||||||
|
PropertyChanges { target: locationsListView; visible: false }
|
||||||
|
PropertyChanges { target: createLocationView; visible: true }
|
||||||
|
PropertyChanges { target: nameField; enabled: false}
|
||||||
|
PropertyChanges
|
||||||
|
{
|
||||||
|
target: bottomButton
|
||||||
|
text: "Login"
|
||||||
|
enabled: true
|
||||||
|
onClicked:
|
||||||
|
{
|
||||||
|
var jsonData = { id: nameField.sslid, autologin: false }
|
||||||
|
rsApi.request("/control/login/", JSON.stringify(jsonData))
|
||||||
|
jsonData = { password: passwordField.text }
|
||||||
|
rsApi.request("/control/password/", JSON.stringify(jsonData))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
Component.onCompleted:
|
||||||
|
{
|
||||||
|
rsApi.openConnection(apiSocketPath)
|
||||||
|
rsApi.request("/control/locations/", "")
|
||||||
|
}
|
||||||
|
|
||||||
|
LibresapiLocalClient
|
||||||
|
{
|
||||||
|
id: rsApi
|
||||||
|
onGoodResponseReceived: locationsModel.json = msg
|
||||||
|
}
|
||||||
|
|
||||||
|
JSONListModel
|
||||||
|
{
|
||||||
|
id: locationsModel
|
||||||
|
query: "$.data[*]"
|
||||||
|
}
|
||||||
|
|
||||||
|
ListView
|
||||||
|
{
|
||||||
|
id: locationsListView
|
||||||
|
width: parent.width
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.bottom: bottomButton.top
|
||||||
|
model: locationsModel.model
|
||||||
|
delegate: Button
|
||||||
|
{
|
||||||
|
text: model.name
|
||||||
|
property string sslid: model.id
|
||||||
|
onClicked:
|
||||||
|
{
|
||||||
|
locationView.state = "loggingIn"
|
||||||
|
nameField.text = text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
visible: false
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout
|
||||||
|
{
|
||||||
|
id: createLocationView
|
||||||
|
width: parent.width
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.bottom: bottomButton.top
|
||||||
|
visible: false
|
||||||
|
|
||||||
|
Row { Text {text: "Name:" } TextField { id: nameField; property string sslid } }
|
||||||
|
Row { Text {text: "Password:" } TextField { id: passwordField; echoMode: PasswordEchoOnEdit } }
|
||||||
|
}
|
||||||
|
|
||||||
|
Text { text: "Locations View"; anchors.bottom: bottomButton.top }
|
||||||
|
|
||||||
|
Button
|
||||||
|
{
|
||||||
|
id: bottomButton
|
||||||
|
text: "Create new location"
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
}
|
||||||
|
}
|
88
retroshare-qml-app/src/qml/jsonpath.js
Normal file
88
retroshare-qml-app/src/qml/jsonpath.js
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
/* JSONPath 0.8.5 - XPath for JSON
|
||||||
|
*
|
||||||
|
* Copyright (c) 2007 Stefan Goessner (goessner.net)
|
||||||
|
* Licensed under the MIT (MIT-LICENSE.txt) licence.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
function jsonPath(obj, expr, arg) {
|
||||||
|
var P = {
|
||||||
|
resultType: arg && arg.resultType || "VALUE",
|
||||||
|
result: [],
|
||||||
|
normalize: function(expr) {
|
||||||
|
var subx = [];
|
||||||
|
return expr.replace(/[\['](\??\(.*?\))[\]']|\['(.*?)'\]/g, function($0,$1,$2){return "[#"+(subx.push($1||$2)-1)+"]";}) /* http://code.google.com/p/jsonpath/issues/detail?id=4 */
|
||||||
|
.replace(/'?\.'?|\['?/g, ";")
|
||||||
|
.replace(/;;;|;;/g, ";..;")
|
||||||
|
.replace(/;$|'?\]|'$/g, "")
|
||||||
|
.replace(/#([0-9]+)/g, function($0,$1){return subx[$1];});
|
||||||
|
},
|
||||||
|
asPath: function(path) {
|
||||||
|
var x = path.split(";"), p = "$";
|
||||||
|
for (var i=1,n=x.length; i<n; i++)
|
||||||
|
p += /^[0-9*]+$/.test(x[i]) ? ("["+x[i]+"]") : ("['"+x[i]+"']");
|
||||||
|
return p;
|
||||||
|
},
|
||||||
|
store: function(p, v) {
|
||||||
|
if (p) P.result[P.result.length] = P.resultType == "PATH" ? P.asPath(p) : v;
|
||||||
|
return !!p;
|
||||||
|
},
|
||||||
|
trace: function(expr, val, path) {
|
||||||
|
if (expr !== "") {
|
||||||
|
var x = expr.split(";"), loc = x.shift();
|
||||||
|
x = x.join(";");
|
||||||
|
if (val && val.hasOwnProperty(loc))
|
||||||
|
P.trace(x, val[loc], path + ";" + loc);
|
||||||
|
else if (loc === "*")
|
||||||
|
P.walk(loc, x, val, path, function(m,l,x,v,p) { P.trace(m+";"+x,v,p); });
|
||||||
|
else if (loc === "..") {
|
||||||
|
P.trace(x, val, path);
|
||||||
|
P.walk(loc, x, val, path, function(m,l,x,v,p) { typeof v[m] === "object" && P.trace("..;"+x,v[m],p+";"+m); });
|
||||||
|
}
|
||||||
|
else if (/^\(.*?\)$/.test(loc)) // [(expr)]
|
||||||
|
P.trace(P.eval(loc, val, path.substr(path.lastIndexOf(";")+1))+";"+x, val, path);
|
||||||
|
else if (/^\?\(.*?\)$/.test(loc)) // [?(expr)]
|
||||||
|
P.walk(loc, x, val, path, function(m,l,x,v,p) { if (P.eval(l.replace(/^\?\((.*?)\)$/,"$1"), v instanceof Array ? v[m] : v, m)) P.trace(m+";"+x,v,p); }); // issue 5 resolved
|
||||||
|
else if (/^(-?[0-9]*):(-?[0-9]*):?([0-9]*)$/.test(loc)) // [start:end:step] phyton slice syntax
|
||||||
|
P.slice(loc, x, val, path);
|
||||||
|
else if (/,/.test(loc)) { // [name1,name2,...]
|
||||||
|
for (var s=loc.split(/'?,'?/),i=0,n=s.length; i<n; i++)
|
||||||
|
P.trace(s[i]+";"+x, val, path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
P.store(path, val);
|
||||||
|
},
|
||||||
|
walk: function(loc, expr, val, path, f) {
|
||||||
|
if (val instanceof Array) {
|
||||||
|
for (var i=0,n=val.length; i<n; i++)
|
||||||
|
if (i in val)
|
||||||
|
f(i,loc,expr,val,path);
|
||||||
|
}
|
||||||
|
else if (typeof val === "object") {
|
||||||
|
for (var m in val)
|
||||||
|
if (val.hasOwnProperty(m))
|
||||||
|
f(m,loc,expr,val,path);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
slice: function(loc, expr, val, path) {
|
||||||
|
if (val instanceof Array) {
|
||||||
|
var len=val.length, start=0, end=len, step=1;
|
||||||
|
loc.replace(/^(-?[0-9]*):(-?[0-9]*):?(-?[0-9]*)$/g, function($0,$1,$2,$3){start=parseInt($1||start);end=parseInt($2||end);step=parseInt($3||step);});
|
||||||
|
start = (start < 0) ? Math.max(0,start+len) : Math.min(len,start);
|
||||||
|
end = (end < 0) ? Math.max(0,end+len) : Math.min(len,end);
|
||||||
|
for (var i=start; i<end; i+=step)
|
||||||
|
P.trace(i+";"+expr, val, path);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
eval: function(x, _v, _vname) {
|
||||||
|
try { return $ && _v && eval(x.replace(/(^|[^\\])@/g, "$1_v").replace(/\\@/g, "@")); } // issue 7 : resolved ..
|
||||||
|
catch(e) { throw new SyntaxError("jsonPath: " + e.message + ": " + x.replace(/(^|[^\\])@/g, "$1_v").replace(/\\@/g, "@")); } // issue 7 : resolved ..
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var $ = obj;
|
||||||
|
if (expr && obj && (P.resultType == "VALUE" || P.resultType == "PATH")) {
|
||||||
|
P.trace(P.normalize(expr).replace(/^\$;?/,""), obj, "$"); // issue 6 resolved
|
||||||
|
return P.result.length ? P.result : false;
|
||||||
|
}
|
||||||
|
}
|
@ -1,27 +1,98 @@
|
|||||||
//import QtQuick 2.7 //2.2
|
/*
|
||||||
//import QtQuick.Layouts 1.0 //1.1
|
* RetroShare Android QML App
|
||||||
//import QtQuick.Controls 2.0 //1.1
|
* Copyright (C) 2016 Gioacchino Mazzurco <gio@eigenlab.org>
|
||||||
import "."
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
import QtQuick 2.2
|
import QtQuick 2.2
|
||||||
import QtQuick.Layouts 1.1
|
import QtQuick.Controls 2.0
|
||||||
import QtQuick.Controls 1.1 // millor fer servir 2.0 o més
|
import org.retroshare.qml_components.LibresapiLocalClient 1.0
|
||||||
import LibresapiLocalClientQml 1.0
|
|
||||||
|
|
||||||
ApplicationWindow {
|
ApplicationWindow
|
||||||
visible: true
|
{
|
||||||
width: 640
|
id: mainWindow
|
||||||
height: 480
|
visible: true
|
||||||
title: qsTr("RSChat")
|
title: qsTr("RSChat")
|
||||||
|
|
||||||
|
Rectangle
|
||||||
|
{
|
||||||
|
id: mainView
|
||||||
|
anchors.fill: parent;
|
||||||
|
|
||||||
|
states:
|
||||||
|
[
|
||||||
|
State
|
||||||
|
{
|
||||||
|
name: "waiting_account_select";
|
||||||
|
PropertyChanges { target: swipeView; currentIndex: 1 }
|
||||||
|
},
|
||||||
|
State
|
||||||
|
{
|
||||||
|
name: "running_ok"
|
||||||
|
PropertyChanges { target: swipeView; currentIndex: 2 }
|
||||||
|
},
|
||||||
|
State
|
||||||
|
{
|
||||||
|
name: "running_ok_no_full_control"
|
||||||
|
PropertyChanges { target: swipeView; currentIndex: 2 }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
LibresapiLocalClient
|
||||||
|
{
|
||||||
|
onGoodResponseReceived:
|
||||||
|
{
|
||||||
|
var jsonReponse = JSON.parse(msg)
|
||||||
|
mainView.state = jsonReponse.data.runstate
|
||||||
|
}
|
||||||
|
Component.onCompleted:
|
||||||
|
{
|
||||||
|
openConnection(apiSocketPath)
|
||||||
|
request("/control/runstate/", "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SwipeView
|
||||||
|
{
|
||||||
|
id: swipeView
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: true
|
||||||
|
currentIndex: 1
|
||||||
|
|
||||||
|
Locations
|
||||||
|
{
|
||||||
|
id: locationsView
|
||||||
|
visible: true
|
||||||
|
}
|
||||||
|
|
||||||
|
AddTrustedNode
|
||||||
|
{
|
||||||
|
id: addTrustedNodeView
|
||||||
|
visible: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Contacts
|
||||||
|
{
|
||||||
|
id: contactsView
|
||||||
|
visible: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
LibresapiLocalClientComm{
|
onSceneGraphInitialized: llc.openConnection()
|
||||||
id: llc
|
|
||||||
onGoodResponseReceived: gxss.title = msg
|
|
||||||
|
|
||||||
}*/
|
|
||||||
onSceneGraphInitialized: llc.openConnection()
|
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: page
|
id: page
|
||||||
@ -154,7 +225,5 @@ ApplicationWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
!include("../../retroshare.pri"): error("Could not include file ../../retroshare.pri")
|
!include("../../retroshare.pri"): error("Could not include file ../../retroshare.pri")
|
||||||
|
|
||||||
QT += qml quick androidextras
|
QT += qml quick
|
||||||
|
|
||||||
CONFIG += c++11
|
CONFIG += c++11
|
||||||
|
|
||||||
|
@ -52,6 +52,7 @@ unix {
|
|||||||
android-g++ {
|
android-g++ {
|
||||||
CONFIG *= no_libresapihttpserver no_sqlcipher upnp_libupnp
|
CONFIG *= no_libresapihttpserver no_sqlcipher upnp_libupnp
|
||||||
CONFIG -= libresapihttpserver sqlcipher upnp_miniupnpc
|
CONFIG -= libresapihttpserver sqlcipher upnp_miniupnpc
|
||||||
|
QT *= androidextras
|
||||||
DEFINES *= "fopen64=fopen"
|
DEFINES *= "fopen64=fopen"
|
||||||
DEFINES *= "fseeko64=fseeko"
|
DEFINES *= "fseeko64=fseeko"
|
||||||
DEFINES *= "ftello64=ftello"
|
DEFINES *= "ftello64=ftello"
|
||||||
|
Loading…
Reference in New Issue
Block a user