From c3aca0cf26ad625ecb265f0bd45549b4cd05d11c Mon Sep 17 00:00:00 2001 From: Gio Date: Thu, 8 Dec 2016 15:56:23 +0100 Subject: [PATCH 1/3] Implement a working Distant Chat prototype in Qml Deprecate id field in JSON API as it may cause problems in Qml Offer gxs_id field in JSON API as an id alternative LibresapiLocalClient support callbacks now an instance may be shared for different tasks Expose an instance of LibresapiLocalClient to Qml, type exposure is kept for retrocompatibility but deprecated Qml app now has a tab that permit to exchange some message with selected distant peer --- libresapi/src/api/IdentityHandler.cpp | 113 +++++++----------- libretroshare/src/util/rsdir.cc | 4 +- retroshare-qml-app/src/debugutils.h | 15 --- .../src/libresapilocalclient.cpp | 61 ++++------ retroshare-qml-app/src/libresapilocalclient.h | 25 ++-- retroshare-qml-app/src/main.cpp | 24 ++-- retroshare-qml-app/src/qml.qrc | 1 + retroshare-qml-app/src/qml/ChatView.qml | 92 ++++++++++++++ retroshare-qml-app/src/qml/Contacts.qml | 76 ++++++++++-- retroshare-qml-app/src/qml/main.qml | 11 +- retroshare-qml-app/src/retroshare-qml-app.pro | 7 +- 11 files changed, 259 insertions(+), 170 deletions(-) delete mode 100644 retroshare-qml-app/src/debugutils.h create mode 100644 retroshare-qml-app/src/qml/ChatView.qml diff --git a/libresapi/src/api/IdentityHandler.cpp b/libresapi/src/api/IdentityHandler.cpp index f707e3596..ab4af9f47 100644 --- a/libresapi/src/api/IdentityHandler.cpp +++ b/libresapi/src/api/IdentityHandler.cpp @@ -121,86 +121,55 @@ void IdentityHandler::notifyGxsChange(const RsGxsChanges &changes) } } -void IdentityHandler::handleWildcard(Request &req, Response &resp) +void IdentityHandler::handleWildcard(Request & /*req*/, Response &resp) { - bool ok = true; + 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 ********** - resp.mStateToken = mStateToken; - } - RsTokReqOptions opts; - opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; - uint32_t token; - mRsIdentity->getTokenService()->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts); + { + RS_STACK_MUTEX(mMtx); + resp.mStateToken = mStateToken; + } + RsTokReqOptions opts; + opts.mReqType = GXS_REQUEST_TYPE_GROUP_DATA; + uint32_t token; + mRsIdentity->getTokenService()->requestGroupInfo(token, RS_TOKREQ_ANSTYPE_DATA, opts); - time_t start = time(NULL); - while((mRsIdentity->getTokenService()->requestStatus(token) != RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE) - &&(mRsIdentity->getTokenService()->requestStatus(token) != RsTokenService::GXS_REQUEST_V2_STATUS_FAILED) - &&((time(NULL) < (start+10))) - ) - { + time_t start = time(NULL); + while((mRsIdentity->getTokenService()->requestStatus(token) != RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE) + &&(mRsIdentity->getTokenService()->requestStatus(token) != RsTokenService::GXS_REQUEST_V2_STATUS_FAILED) + &&((time(NULL) < (start+10))) + ) + { #ifdef WINDOWS_SYS - Sleep(500); + Sleep(500); #else - usleep(500*1000) ; + usleep(500*1000); #endif - } + } - if(mRsIdentity->getTokenService()->requestStatus(token) == RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE) - { - std::vector grps; - ok &= mRsIdentity->getGroupData(token, grps); - for(std::vector::iterator vit = grps.begin(); vit != grps.end(); vit++) - { - RsGxsIdGroup& grp = *vit; - KeyValueReference id("id", grp.mMeta.mGroupId); - KeyValueReference pgp_id("pgp_id",grp.mPgpId ); - // 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("name", grp.mMeta.mGroupName) - << makeKeyValueReference("own", own) - << makeKeyValueReference("pgp_linked", pgp_linked); - } - } - else - { - ok = false; - } - } + if(mRsIdentity->getTokenService()->requestStatus(token) == RsTokenService::GXS_REQUEST_V2_STATUS_COMPLETE) + { + std::vector grps; + ok &= mRsIdentity->getGroupData(token, grps); + for(std::vector::iterator vit = grps.begin(); vit != grps.end(); vit++) + { + RsGxsIdGroup& grp = *vit; + //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() + << 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; - if(ok) - { - resp.setOk(); - } - else - { - resp.setFail(); - } + if(ok) resp.setOk(); + else resp.setFail(); } ResponseTask* IdentityHandler::handleOwn(Request & /* req */, Response &resp) diff --git a/libretroshare/src/util/rsdir.cc b/libretroshare/src/util/rsdir.cc index 2b7ea22cb..7c1ff9794 100644 --- a/libretroshare/src/util/rsdir.cc +++ b/libretroshare/src/util/rsdir.cc @@ -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 diff --git a/retroshare-qml-app/src/debugutils.h b/retroshare-qml-app/src/debugutils.h deleted file mode 100644 index a9a2f39ff..000000000 --- a/retroshare-qml-app/src/debugutils.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef DEBUGUTILS_H -#define DEBUGUTILS_H - -#include - -//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 diff --git a/retroshare-qml-app/src/libresapilocalclient.cpp b/retroshare-qml-app/src/libresapilocalclient.cpp index 34831753d..f30b3373c 100644 --- a/retroshare-qml-app/src/libresapilocalclient.cpp +++ b/retroshare-qml-app/src/libresapilocalclient.cpp @@ -18,8 +18,8 @@ */ #include "libresapilocalclient.h" -#include "debugutils.h" -#include + +#include void LibresapiLocalClient::openConnection(QString socketPath) @@ -31,54 +31,35 @@ 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'); - mLocalSocket.write(data); + QByteArray data; + data.append(path); data.append('\n'); + data.append(jsonData); data.append('\n'); + callbackQueue.enqueue(callback); + mLocalSocket.write(data); - return 1; + return 1; } 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); } diff --git a/retroshare-qml-app/src/libresapilocalclient.h b/retroshare-qml-app/src/libresapilocalclient.h index cfbfb6dec..38737ca26 100644 --- a/retroshare-qml-app/src/libresapilocalclient.h +++ b/retroshare-qml-app/src/libresapilocalclient.h @@ -21,9 +21,8 @@ #define LIBRESAPILOCALCLIENT_H #include -#include -#include -#include +#include +#include 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 responses; - - bool parseResponse(); //std::string msg); + QQueue 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 diff --git a/retroshare-qml-app/src/main.cpp b/retroshare-qml-app/src/main.cpp index 2f03478c9..0be8e7b15 100644 --- a/retroshare-qml-app/src/main.cpp +++ b/retroshare-qml-app/src/main.cpp @@ -34,28 +34,28 @@ int main(int argc, char *argv[]) { - QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); - QGuiApplication app(argc, argv); + QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + QGuiApplication app(argc, argv); - QQmlApplicationEngine engine; + QQmlApplicationEngine engine; + + /// @deprecated qmlRegisterType( "org.retroshare.qml_components.LibresapiLocalClient", 1, 0, "LibresapiLocalClient"); - QString sockPath = QString::fromStdString(RsAccounts::ConfigDirectory()); - sockPath.append("/libresapi.sock"); + 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(); + return app.exec(); } diff --git a/retroshare-qml-app/src/qml.qrc b/retroshare-qml-app/src/qml.qrc index 54ce78395..7a7883377 100644 --- a/retroshare-qml-app/src/qml.qrc +++ b/retroshare-qml-app/src/qml.qrc @@ -22,5 +22,6 @@ qml/AddTrustedNode.qml qml/RsLoginPassView.qml qml/TrustedNodesView.qml + qml/ChatView.qml diff --git a/retroshare-qml-app/src/qml/ChatView.qml b/retroshare-qml-app/src/qml/ChatView.qml new file mode 100644 index 000000000..5057c9683 --- /dev/null +++ b/retroshare-qml-app/src/qml/ChatView.qml @@ -0,0 +1,92 @@ +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("/statetokenservice/*") + rsApi.request("/chat/messages/"+ chatId, "", function(par) { console.log("Callback called! -> " + par.response ); 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: 500 + repeat: true + onTriggered: if(chatView.visible) chatView.refreshData() + Component.onCompleted: start() + } +} diff --git a/retroshare-qml-app/src/qml/Contacts.qml b/retroshare-qml-app/src/qml/Contacts.qml index 63364d516..478b8f19e 100644 --- a/retroshare-qml-app/src/qml/Contacts.qml +++ b/retroshare-qml-app/src/qml/Contacts.qml @@ -22,17 +22,33 @@ 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 + { + selectedOwnIdentityView.color = "red" + selectedOwnIdentityView.text = "You need to create a GXS identity to chat!" + } + }) + } onFocusChanged: focus && refreshData() - LibresapiLocalClient - { - id: rsApi - onGoodResponseReceived: locationsModel.json = msg - Component.onCompleted: { openConnection(apiSocketPath) } - } - JSONListModel { id: locationsModel @@ -45,8 +61,48 @@ 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: + { + 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() + } } diff --git a/retroshare-qml-app/src/qml/main.qml b/retroshare-qml-app/src/qml/main.qml index e2cffc811..a031f103e 100644 --- a/retroshare-qml-app/src/qml/main.qml +++ b/retroshare-qml-app/src/qml/main.qml @@ -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 + } } } } diff --git a/retroshare-qml-app/src/retroshare-qml-app.pro b/retroshare-qml-app/src/retroshare-qml-app.pro index 63e34a404..c878a8b09 100644 --- a/retroshare-qml-app/src/retroshare-qml-app.pro +++ b/retroshare-qml-app/src/retroshare-qml-app.pro @@ -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 From 1fa20e16c233fea9f4157f95e1fb3a8589386b45 Mon Sep 17 00:00:00 2001 From: Gio Date: Thu, 8 Dec 2016 21:57:26 +0100 Subject: [PATCH 2/3] Added a dialog to create GXS Identities Now the basic functionaliteis to chat are in place ATM only pseudonymous identities are supported Everything is still very buggy --- retroshare-qml-app/src/qml/Contacts.qml | 32 +++++++++++++++++++++---- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/retroshare-qml-app/src/qml/Contacts.qml b/retroshare-qml-app/src/qml/Contacts.qml index 478b8f19e..b0cf5c3da 100644 --- a/retroshare-qml-app/src/qml/Contacts.qml +++ b/retroshare-qml-app/src/qml/Contacts.qml @@ -18,6 +18,7 @@ import QtQuick 2.0 import QtQuick.Controls 1.4 +import QtQuick.Dialogs 1.2 import org.retroshare.qml_components.LibresapiLocalClient 1.0 Item @@ -39,11 +40,7 @@ Item contactsView.own_gxs_id = json.data[0].gxs_id contactsView.own_nick = json.data[0].name } - else - { - selectedOwnIdentityView.color = "red" - selectedOwnIdentityView.text = "You need to create a GXS identity to chat!" - } + else createIdentityDialog.visible = true }) } @@ -71,6 +68,7 @@ Item 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 { @@ -105,4 +103,28 @@ Item 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 } + } + } } From 6c6b437db180245d634cdad6df4bef43cc254992 Mon Sep 17 00:00:00 2001 From: Gio Date: Sat, 10 Dec 2016 20:23:30 +0100 Subject: [PATCH 3/3] qml-app: Fix responsiveness of ChatView ChatHandler::handleMessages(...) tick() before repling so the raw message queue is processed ChatHandler::handleLobbies(...) make sure tick() is called without previous mutex locking, putting the critical section inside a block ChatView.qml remove unnecessary request to statetoken service that slowed down processing by half, increased chat message refresh time to reduce performance hit --- libresapi/src/api/ChatHandler.cpp | 9 +++++++++ retroshare-qml-app/src/qml/ChatView.qml | 8 ++------ retroshare-qml-app/src/qml/Contacts.qml | 18 +++++++++--------- 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/libresapi/src/api/ChatHandler.cpp b/libresapi/src/api/ChatHandler.cpp index 3944032fb..4335389df 100644 --- a/libresapi/src/api/ChatHandler.cpp +++ b/libresapi/src/api/ChatHandler.cpp @@ -837,6 +837,7 @@ void ChatHandler::handleLobbies(Request &/*req*/, Response &resp) { tick(); + { RS_STACK_MUTEX(mMtx); /********** LOCKED **********/ resp.mDataStream.getStreamToMember(); for(std::vector::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(); } @@ -921,6 +923,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()); // make response a list @@ -941,6 +949,7 @@ void ChatHandler::handleMessages(Request &req, Response &resp) } resp.mStateToken = mMsgStateToken; handlePaginationRequest(req, resp, mit->second); + } } void ChatHandler::handleSendMessage(Request &req, Response &resp) diff --git a/retroshare-qml-app/src/qml/ChatView.qml b/retroshare-qml-app/src/qml/ChatView.qml index 5057c9683..3194d97a8 100644 --- a/retroshare-qml-app/src/qml/ChatView.qml +++ b/retroshare-qml-app/src/qml/ChatView.qml @@ -7,11 +7,7 @@ Item id: chatView property string chatId - function refreshData() - { - rsApi.request("/statetokenservice/*") - rsApi.request("/chat/messages/"+ chatId, "", function(par) { console.log("Callback called! -> " + par.response ); chatModel.json = par.response }) - } + function refreshData() { rsApi.request("/chat/messages/"+ chatId, "", function(par) { chatModel.json = par.response }) } onFocusChanged: focus && refreshData() @@ -84,7 +80,7 @@ Item Timer { id: refreshTimer - interval: 500 + interval: 800 repeat: true onTriggered: if(chatView.visible) chatView.refreshData() Component.onCompleted: start() diff --git a/retroshare-qml-app/src/qml/Contacts.qml b/retroshare-qml-app/src/qml/Contacts.qml index b0cf5c3da..4ecd267ef 100644 --- a/retroshare-qml-app/src/qml/Contacts.qml +++ b/retroshare-qml-app/src/qml/Contacts.qml @@ -33,15 +33,15 @@ Item 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 - }) + { + 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()