mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-10-01 02:35:48 -04:00
commit
1ef11a27fd
@ -837,6 +837,7 @@ void ChatHandler::handleLobbies(Request &/*req*/, Response &resp)
|
||||
{
|
||||
tick();
|
||||
|
||||
{
|
||||
RS_STACK_MUTEX(mMtx); /********** LOCKED **********/
|
||||
resp.mDataStream.getStreamToMember();
|
||||
for(std::vector<Lobby>::iterator vit = mLobbies.begin(); vit != mLobbies.end(); ++vit)
|
||||
@ -854,6 +855,7 @@ void ChatHandler::handleLobbies(Request &/*req*/, Response &resp)
|
||||
resp.mDataStream.getStreamToMember() << *vit << makeKeyValueReference("unread_msg_count", unread_msgs);
|
||||
}
|
||||
resp.mStateToken = mLobbiesStateToken;
|
||||
}
|
||||
resp.setOk();
|
||||
}
|
||||
|
||||
@ -920,6 +922,12 @@ ResponseTask* ChatHandler::handleLobbyParticipants(Request &req, Response &resp)
|
||||
}
|
||||
|
||||
void ChatHandler::handleMessages(Request &req, Response &resp)
|
||||
{
|
||||
/* G10h4ck: Whithout this the request processing won't happen, copied from
|
||||
* ChatHandler::handleLobbies, is this a work around or is the right whay of
|
||||
* doing it? */
|
||||
tick();
|
||||
|
||||
{
|
||||
RS_STACK_MUTEX(mMtx); /********** LOCKED **********/
|
||||
ChatId id(req.mPath.top());
|
||||
@ -942,6 +950,7 @@ void ChatHandler::handleMessages(Request &req, Response &resp)
|
||||
resp.mStateToken = mMsgStateToken;
|
||||
handlePaginationRequest(req, resp, mit->second);
|
||||
}
|
||||
}
|
||||
|
||||
void ChatHandler::handleSendMessage(Request &req, Response &resp)
|
||||
{
|
||||
|
@ -121,32 +121,12 @@ void IdentityHandler::notifyGxsChange(const RsGxsChanges &changes)
|
||||
}
|
||||
}
|
||||
|
||||
void IdentityHandler::handleWildcard(Request &req, Response &resp)
|
||||
void IdentityHandler::handleWildcard(Request & /*req*/, Response &resp)
|
||||
{
|
||||
bool ok = true;
|
||||
|
||||
if(req.isPut())
|
||||
{
|
||||
#ifdef REMOVE
|
||||
RsIdentityParameters params;
|
||||
req.mStream << makeKeyValueReference("name", params.nickname);
|
||||
if(req.mStream.isOK())
|
||||
{
|
||||
uint32_t token;
|
||||
mRsIdentity->createIdentity(token, params);
|
||||
// not sure if should acknowledge the token
|
||||
// for now go the easier way
|
||||
}
|
||||
else
|
||||
{
|
||||
ok = false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
RS_STACK_MUTEX(mMtx); // ********** LOCKED **********
|
||||
RS_STACK_MUTEX(mMtx);
|
||||
resp.mStateToken = mStateToken;
|
||||
}
|
||||
RsTokReqOptions opts;
|
||||
@ -174,33 +154,22 @@ void IdentityHandler::handleWildcard(Request &req, Response &resp)
|
||||
for(std::vector<RsGxsIdGroup>::iterator vit = grps.begin(); vit != grps.end(); vit++)
|
||||
{
|
||||
RsGxsIdGroup& grp = *vit;
|
||||
KeyValueReference<RsGxsGroupId> id("id", grp.mMeta.mGroupId);
|
||||
KeyValueReference<RsPgpId> pgp_id("pgp_id",grp.mPgpId );
|
||||
// not very happy about this, i think the flags should stay hidden in rsidentities
|
||||
//electron: not very happy about this, i think the flags should stay hidden in rsidentities
|
||||
bool own = (grp.mMeta.mSubscribeFlags & GXS_SERV::GROUP_SUBSCRIBE_ADMIN);
|
||||
bool pgp_linked = (grp.mMeta.mGroupFlags & RSGXSID_GROUPFLAG_REALID);
|
||||
resp.mDataStream.getStreamToMember()
|
||||
<< id
|
||||
<< pgp_id
|
||||
<< makeKeyValueReference("id", grp.mMeta.mGroupId) /// @deprecated using "id" as key can cause problems in some JS based languages like Qml @see gxs_id instead
|
||||
<< makeKeyValueReference("gxs_id", grp.mMeta.mGroupId)
|
||||
<< makeKeyValueReference("pgp_id",grp.mPgpId )
|
||||
<< makeKeyValueReference("name", grp.mMeta.mGroupName)
|
||||
<< makeKeyValueReference("own", own)
|
||||
<< makeKeyValueReference("pgp_linked", pgp_linked);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ok = false;
|
||||
}
|
||||
}
|
||||
else ok = false;
|
||||
|
||||
if(ok)
|
||||
{
|
||||
resp.setOk();
|
||||
}
|
||||
else
|
||||
{
|
||||
resp.setFail();
|
||||
}
|
||||
if(ok) resp.setOk();
|
||||
else resp.setFail();
|
||||
}
|
||||
|
||||
ResponseTask* IdentityHandler::handleOwn(Request & /* req */, Response &resp)
|
||||
|
@ -482,8 +482,8 @@ bool RsDirUtil::checkCreateDirectory(const std::string& dir)
|
||||
|
||||
std::string RsDirUtil::removeSymLinks(const std::string& path)
|
||||
{
|
||||
#if defined(WINDOWS_SYS) || defined(__APPLE__)
|
||||
#warning (Mr.Alice): I don't know how to do this on windows/MacOS. See https://msdn.microsoft.com/en-us/library/windows/desktop/hh707084(v=vs.85).aspx'
|
||||
#if defined(WINDOWS_SYS) || defined(__APPLE__) || defined(__ANDROID__)
|
||||
#warning (Mr.Alice): I don't know how to do this on windows/MacOS/Android. See https://msdn.microsoft.com/en-us/library/windows/desktop/hh707084(v=vs.85).aspx'
|
||||
//if(!S_OK == PathCchCanonicalizeEx(tmp,...) ;
|
||||
return path ;
|
||||
#else
|
||||
|
@ -1,15 +0,0 @@
|
||||
#ifndef DEBUGUTILS_H
|
||||
#define DEBUGUTILS_H
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
//To switch between debugging and normal mode, un-/comment next line
|
||||
#define DEBUGGING
|
||||
#ifdef DEBUGGING
|
||||
#define myDebug(line) qDebug() << "| FILE:" << __FILE__ << " | LINE_NUMBER:"\
|
||||
<< __LINE__ << " | FUNCTION:" << __FUNCTION__ << " | CONTENT:" << line
|
||||
#else
|
||||
#define myDebug(line)
|
||||
#endif
|
||||
|
||||
#endif // DEBUGUTILS_H
|
@ -18,8 +18,8 @@
|
||||
*/
|
||||
|
||||
#include "libresapilocalclient.h"
|
||||
#include "debugutils.h"
|
||||
#include <QChar>
|
||||
|
||||
#include <QJSEngine>
|
||||
|
||||
|
||||
void LibresapiLocalClient::openConnection(QString socketPath)
|
||||
@ -31,12 +31,13 @@ void LibresapiLocalClient::openConnection(QString socketPath)
|
||||
mLocalSocket.connectToServer(socketPath);
|
||||
}
|
||||
|
||||
int LibresapiLocalClient::request(const QString & path, const QString & jsonData)
|
||||
int LibresapiLocalClient::request( const QString& path, const QString& jsonData,
|
||||
QJSValue callback )
|
||||
{
|
||||
qDebug() << "LibresapiLocalClient::request()" << path << jsonData;
|
||||
QByteArray data;
|
||||
data.append(path); data.append('\n');
|
||||
data.append(jsonData); data.append('\n');
|
||||
callbackQueue.enqueue(callback);
|
||||
mLocalSocket.write(data);
|
||||
|
||||
return 1;
|
||||
@ -44,41 +45,21 @@ int LibresapiLocalClient::request(const QString & path, const QString & jsonData
|
||||
|
||||
void LibresapiLocalClient::socketError(QLocalSocket::LocalSocketError)
|
||||
{
|
||||
myDebug("error!!!!\n" + mLocalSocket.errorString());
|
||||
qDebug() << "Socket Eerror!!" << mLocalSocket.errorString();
|
||||
}
|
||||
|
||||
void LibresapiLocalClient::read()
|
||||
{
|
||||
receivedBytes = mLocalSocket.readLine();
|
||||
|
||||
qDebug() << receivedBytes;
|
||||
|
||||
if(parseResponse()) // pensar en fer un buffer per parsejar, per evitar errors.
|
||||
emit goodResponseReceived(QString(receivedBytes));
|
||||
else
|
||||
QString receivedMsg(mLocalSocket.readLine());
|
||||
QJSValue callback(callbackQueue.dequeue());
|
||||
if(callback.isCallable())
|
||||
{
|
||||
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));
|
||||
}
|
||||
QJSValue params = callback.engine()->newObject();
|
||||
params.setProperty("response", receivedMsg);
|
||||
|
||||
callback.call(QJSValueList { params });
|
||||
}
|
||||
|
||||
bool LibresapiLocalClient::parseResponse()
|
||||
{
|
||||
QJsonParseError error;
|
||||
json = QJsonDocument::fromJson(receivedBytes, &error);
|
||||
myDebug(QString(json.toJson()).replace(QChar('\n'), QChar::LineSeparator));
|
||||
|
||||
if(error.error == QJsonParseError::NoError){
|
||||
return true;
|
||||
}
|
||||
myDebug(error.errorString());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
const QJsonDocument & LibresapiLocalClient::getJson()
|
||||
{
|
||||
return json;
|
||||
emit goodResponseReceived(receivedMsg); /// @deprecated
|
||||
emit responseReceived(receivedMsg);
|
||||
}
|
||||
|
@ -21,9 +21,8 @@
|
||||
#define LIBRESAPILOCALCLIENT_H
|
||||
|
||||
#include <QLocalSocket>
|
||||
#include <QDir>
|
||||
#include <QJsonDocument>
|
||||
#include <QVector>
|
||||
#include <QQueue>
|
||||
#include <QJSValue>
|
||||
|
||||
class LibresapiLocalClient : public QObject
|
||||
{
|
||||
@ -32,25 +31,27 @@ class LibresapiLocalClient : public QObject
|
||||
public:
|
||||
LibresapiLocalClient() : mLocalSocket(this) {}
|
||||
|
||||
// potser abstreure el següent amb QUrl urlPath (path) i amb QJson jsonData.
|
||||
Q_INVOKABLE int request(const QString & path, const QString & jsonData);
|
||||
const QJsonDocument & getJson();
|
||||
Q_INVOKABLE int request( const QString& path, const QString& jsonData = "",
|
||||
QJSValue callback = QJSValue::NullValue);
|
||||
Q_INVOKABLE void openConnection(QString socketPath);
|
||||
|
||||
private:
|
||||
QLocalSocket mLocalSocket;
|
||||
QByteArray receivedBytes;
|
||||
QJsonDocument json;
|
||||
//QVector<QJsonDocument> responses;
|
||||
|
||||
bool parseResponse(); //std::string msg);
|
||||
QQueue<QJSValue> callbackQueue;
|
||||
|
||||
private slots:
|
||||
void socketError(QLocalSocket::LocalSocketError error);
|
||||
void read();
|
||||
|
||||
signals:
|
||||
void goodResponseReceived(const QString & msg);//, int requestId);
|
||||
/// @deprecated @see LibresapiLocalClient::responseReceived instead
|
||||
void goodResponseReceived(const QString & msg);
|
||||
|
||||
/**
|
||||
* @brief responseReceived emitted when a response is received
|
||||
* @param msg
|
||||
*/
|
||||
void responseReceived(const QString & msg);
|
||||
};
|
||||
|
||||
#endif // LIBRESAPILOCALCLIENT_H
|
||||
|
@ -38,6 +38,8 @@ int main(int argc, char *argv[])
|
||||
QGuiApplication app(argc, argv);
|
||||
|
||||
QQmlApplicationEngine engine;
|
||||
|
||||
/// @deprecated
|
||||
qmlRegisterType<LibresapiLocalClient>(
|
||||
"org.retroshare.qml_components.LibresapiLocalClient", 1, 0,
|
||||
"LibresapiLocalClient");
|
||||
@ -45,16 +47,14 @@ int main(int argc, char *argv[])
|
||||
QString sockPath = QString::fromStdString(RsAccounts::ConfigDirectory());
|
||||
sockPath.append("/libresapi.sock");
|
||||
|
||||
LibresapiLocalClient rsApi;
|
||||
rsApi.openConnection(sockPath);
|
||||
|
||||
engine.rootContext()->setContextProperty("apiSocketPath", sockPath);
|
||||
engine.rootContext()->setContextProperty("rsApi", &rsApi);
|
||||
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 an activity?" << QtAndroid::androidActivity().isValid();
|
||||
#endif
|
||||
|
||||
qDebug() << "QML APP:" << sockPath << fileInfo.exists() << fileInfo.lastModified().toString();
|
||||
|
||||
return app.exec();
|
||||
|
@ -22,5 +22,6 @@
|
||||
<file>qml/AddTrustedNode.qml</file>
|
||||
<file>qml/RsLoginPassView.qml</file>
|
||||
<file>qml/TrustedNodesView.qml</file>
|
||||
<file>qml/ChatView.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
88
retroshare-qml-app/src/qml/ChatView.qml
Normal file
88
retroshare-qml-app/src/qml/ChatView.qml
Normal file
@ -0,0 +1,88 @@
|
||||
import QtQuick 2.0
|
||||
import QtQuick.Controls 1.4
|
||||
import org.retroshare.qml_components.LibresapiLocalClient 1.0
|
||||
|
||||
Item
|
||||
{
|
||||
id: chatView
|
||||
property string chatId
|
||||
|
||||
function refreshData() { rsApi.request("/chat/messages/"+ chatId, "", function(par) { chatModel.json = par.response }) }
|
||||
|
||||
onFocusChanged: focus && refreshData()
|
||||
|
||||
JSONListModel
|
||||
{
|
||||
id: chatModel
|
||||
query: "$.data[*]"
|
||||
}
|
||||
|
||||
Component
|
||||
{
|
||||
id: chatMessageDelegate
|
||||
Item
|
||||
{
|
||||
height: 20
|
||||
Row
|
||||
{
|
||||
Text { text: author_name }
|
||||
Text { text: ": " + msg }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ListView
|
||||
{
|
||||
width: parent.width
|
||||
height: 300
|
||||
model: chatModel.model
|
||||
delegate: chatMessageDelegate
|
||||
}
|
||||
|
||||
Rectangle
|
||||
{
|
||||
color: "green"
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: parent.left
|
||||
width: chatView.width - sendButton.width
|
||||
height: Math.max(20, msgComposer.height)
|
||||
}
|
||||
|
||||
TextEdit
|
||||
{
|
||||
id: msgComposer
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: parent.left
|
||||
width: chatView.width - sendButton.width
|
||||
}
|
||||
|
||||
Button
|
||||
{
|
||||
id: sendButton
|
||||
text: "Send"
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.right: parent.right
|
||||
|
||||
onClicked:
|
||||
{
|
||||
var jsonData = {"chat_id":chatView.chatId, "msg":msgComposer.text}
|
||||
sendRsApi.request("/chat/send_message", JSON.stringify(jsonData))
|
||||
}
|
||||
|
||||
LibresapiLocalClient
|
||||
{
|
||||
id: sendRsApi
|
||||
onGoodResponseReceived: { msgComposer.text = ""; console.log(msg)}
|
||||
Component.onCompleted: { openConnection(apiSocketPath) }
|
||||
}
|
||||
}
|
||||
|
||||
Timer
|
||||
{
|
||||
id: refreshTimer
|
||||
interval: 800
|
||||
repeat: true
|
||||
onTriggered: if(chatView.visible) chatView.refreshData()
|
||||
Component.onCompleted: start()
|
||||
}
|
||||
}
|
@ -18,21 +18,34 @@
|
||||
|
||||
import QtQuick 2.0
|
||||
import QtQuick.Controls 1.4
|
||||
import QtQuick.Dialogs 1.2
|
||||
import org.retroshare.qml_components.LibresapiLocalClient 1.0
|
||||
|
||||
Item
|
||||
{
|
||||
function refreshData() { rsApi.request("/identity/*/", "") }
|
||||
id: contactsView
|
||||
property string own_gxs_id: ""
|
||||
property string own_nick: ""
|
||||
|
||||
Component.onCompleted: refreshOwn()
|
||||
|
||||
function refreshData() { rsApi.request("/identity/*/", "", function(par) { locationsModel.json = par.response; if(contactsView.own_gxs_id == "") refreshOwn() }) }
|
||||
function refreshOwn()
|
||||
{
|
||||
rsApi.request("/identity/own", "", function(par)
|
||||
{
|
||||
var json = JSON.parse(par.response)
|
||||
if(json.data.length > 0)
|
||||
{
|
||||
contactsView.own_gxs_id = json.data[0].gxs_id
|
||||
contactsView.own_nick = json.data[0].name
|
||||
}
|
||||
else createIdentityDialog.visible = true
|
||||
})
|
||||
}
|
||||
|
||||
onFocusChanged: focus && refreshData()
|
||||
|
||||
LibresapiLocalClient
|
||||
{
|
||||
id: rsApi
|
||||
onGoodResponseReceived: locationsModel.json = msg
|
||||
Component.onCompleted: { openConnection(apiSocketPath) }
|
||||
}
|
||||
|
||||
JSONListModel
|
||||
{
|
||||
id: locationsModel
|
||||
@ -45,8 +58,73 @@ Item
|
||||
width: parent.width
|
||||
height: 300
|
||||
model: locationsModel.model
|
||||
delegate: Text { text: model.name }
|
||||
delegate: Item
|
||||
{
|
||||
height: 20
|
||||
width: parent.width
|
||||
|
||||
MouseArea
|
||||
{
|
||||
anchors.fill: parent
|
||||
onClicked:
|
||||
{
|
||||
console.log("Contacts view onclicked:", model.name, model.gxs_id)
|
||||
if(model.own) contactsView.own_gxs_id = model.gxs_id
|
||||
else
|
||||
{
|
||||
var jsonData = { "own_gxs_hex": contactsView.own_gxs_id, "remote_gxs_hex": model.gxs_id }
|
||||
rsApi.request("/chat/initiate_distant_chat", JSON.stringify(jsonData), function (par) { mainWindow.activeChatId = JSON.parse(par.response).data.chat_id })
|
||||
}
|
||||
}
|
||||
Text
|
||||
{
|
||||
color: model.own ? "blue" : "black"
|
||||
text: model.name + " " + model.gxs_id
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Text { text: "Contacts View"; anchors.bottom: parent.bottom }
|
||||
Text
|
||||
{
|
||||
id: selectedOwnIdentityView
|
||||
color: "green"
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: parent.left
|
||||
width: parent.width
|
||||
text: "Open Chat as: " + contactsView.own_nick + " " + contactsView.own_gxs_id
|
||||
}
|
||||
|
||||
Timer
|
||||
{
|
||||
id: refreshTimer
|
||||
interval: 5000
|
||||
repeat: true
|
||||
onTriggered: if(contactsView.visible) contactsView.refreshData()
|
||||
Component.onCompleted: start()
|
||||
}
|
||||
|
||||
|
||||
Dialog
|
||||
{
|
||||
id: createIdentityDialog
|
||||
visible: false
|
||||
title: "You need to create a GXS identity to chat!"
|
||||
standardButtons: StandardButton.Save
|
||||
|
||||
onAccepted: rsApi.request("/identity/create_identity", JSON.stringify({"name":identityNameTE.text, "pgp_linked": !psdnmCheckBox.checked }))
|
||||
|
||||
TextField
|
||||
{
|
||||
id: identityNameTE
|
||||
width: 300
|
||||
}
|
||||
|
||||
Row
|
||||
{
|
||||
anchors.top: identityNameTE.bottom
|
||||
Text { text: "Pseudonymous: " }
|
||||
CheckBox { id: psdnmCheckBox; checked: true; enabled: false }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,6 +28,8 @@ ApplicationWindow
|
||||
width: 400
|
||||
height: 400
|
||||
|
||||
property string activeChatId;
|
||||
|
||||
Rectangle
|
||||
{
|
||||
id: mainView
|
||||
@ -102,8 +104,13 @@ ApplicationWindow
|
||||
|
||||
Tab
|
||||
{
|
||||
title: "Blue"
|
||||
Rectangle { color: "blue"; anchors.fill: parent }
|
||||
title: "Chat"
|
||||
ChatView
|
||||
{
|
||||
id: chatView
|
||||
chatId: mainWindow.activeChatId
|
||||
onVisibleChanged: focus = visible
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,13 +4,14 @@ QT += qml quick
|
||||
|
||||
CONFIG += c++11
|
||||
|
||||
HEADERS += libresapilocalclient.h
|
||||
SOURCES += main.cpp \
|
||||
libresapilocalclient.cpp
|
||||
|
||||
RESOURCES += qml.qrc
|
||||
|
||||
# Additional import path used to resolve QML modules in Qt Creator's code model
|
||||
QML_IMPORT_PATH =
|
||||
#QML_IMPORT_PATH =
|
||||
|
||||
# Default rules for deployment.
|
||||
include(deployment.pri)
|
||||
@ -30,7 +31,3 @@ DEPENDPATH *= ../../libretroshare/src
|
||||
INCLUDEPATH *= ../../libretroshare/src
|
||||
PRE_TARGETDEPS *= ../../libretroshare/src/lib/libretroshare.a
|
||||
LIBS *= ../../libretroshare/src/lib/libretroshare.a
|
||||
|
||||
HEADERS += \
|
||||
libresapilocalclient.h \
|
||||
debugutils.h
|
||||
|
Loading…
Reference in New Issue
Block a user