diff --git a/.gitignore b/.gitignore
new file mode 100644
index 00000000..a589c2d8
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+*.Ruqola.pro.user
diff --git a/Ruqola.pro.user b/Ruqola.pro.user
deleted file mode 100644
index e0deed87..00000000
--- a/Ruqola.pro.user
+++ /dev/null
@@ -1,656 +0,0 @@
-
-
-
-
-
- EnvironmentId
- {ab19c5d8-e149-4a7a-9ecf-d7074f8c4302}
-
-
- ProjectExplorer.Project.ActiveTarget
- 0
-
-
- ProjectExplorer.Project.EditorSettings
-
- true
- false
- true
-
- Cpp
-
- CppGlobal
-
-
-
- QmlJS
-
- QmlJSGlobal
-
-
- 2
- UTF-8
- false
- 4
- false
- 80
- true
- true
- 1
- true
- false
- 0
- true
- true
- 0
- 8
- true
- 1
- true
- true
- true
- false
-
-
-
- ProjectExplorer.Project.PluginSettings
-
-
-
- ProjectExplorer.Project.Target.0
-
- Desktop Qt 5.8.0 GCC 64bit
- Desktop Qt 5.8.0 GCC 64bit
- qt.58.gcc_64_kit
- 0
- 0
- 0
-
- /home/vasudha/Qt/build-Ruqola-Desktop_Qt_5_8_0_GCC_64bit-Debug
-
-
- true
- qmake
-
- QtProjectManager.QMakeBuildStep
- true
-
- false
- false
- false
-
-
- true
- Make
-
- Qt4ProjectManager.MakeStep
-
- -w
- -r
-
- false
-
-
-
- 2
- Build
-
- ProjectExplorer.BuildSteps.Build
-
-
-
- true
- Make
-
- Qt4ProjectManager.MakeStep
-
- -w
- -r
-
- true
- clean
-
-
- 1
- Clean
-
- ProjectExplorer.BuildSteps.Clean
-
- 2
- false
-
- Debug
-
- Qt4ProjectManager.Qt4BuildConfiguration
- 2
- true
-
-
- /home/vasudha/Qt/build-Ruqola-Desktop_Qt_5_8_0_GCC_64bit-Release
-
-
- true
- qmake
-
- QtProjectManager.QMakeBuildStep
- false
-
- false
- false
- false
-
-
- true
- Make
-
- Qt4ProjectManager.MakeStep
-
- -w
- -r
-
- false
-
-
-
- 2
- Build
-
- ProjectExplorer.BuildSteps.Build
-
-
-
- true
- Make
-
- Qt4ProjectManager.MakeStep
-
- -w
- -r
-
- true
- clean
-
-
- 1
- Clean
-
- ProjectExplorer.BuildSteps.Clean
-
- 2
- false
-
- Release
-
- Qt4ProjectManager.Qt4BuildConfiguration
- 0
- true
-
-
- /home/vasudha/Qt/build-Ruqola-Desktop_Qt_5_8_0_GCC_64bit-Profile
-
-
- true
- qmake
-
- QtProjectManager.QMakeBuildStep
- true
-
- false
- true
- false
-
-
- true
- Make
-
- Qt4ProjectManager.MakeStep
-
- -w
- -r
-
- false
-
-
-
- 2
- Build
-
- ProjectExplorer.BuildSteps.Build
-
-
-
- true
- Make
-
- Qt4ProjectManager.MakeStep
-
- -w
- -r
-
- true
- clean
-
-
- 1
- Clean
-
- ProjectExplorer.BuildSteps.Clean
-
- 2
- false
-
- Profile
-
- Qt4ProjectManager.Qt4BuildConfiguration
- 0
- true
-
- 3
-
-
- 0
- Deploy
-
- ProjectExplorer.BuildSteps.Deploy
-
- 1
- Deploy locally
-
- ProjectExplorer.DefaultDeployConfiguration
-
- 1
-
-
- false
- false
- 1000
-
- true
-
- false
- false
- false
- false
- true
- 0.01
- 10
- true
- 1
- 25
-
- 1
- true
- false
- true
- valgrind
-
- 0
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
-
- 2
-
- Ruqola
- Ruqola2
- Qt4ProjectManager.Qt4RunConfiguration:/home/vasudha/Qt/Ruqola-desktop/Ruqola/Ruqola.pro
- true
-
- Ruqola.pro
- false
-
- /home/vasudha/Qt/build-Ruqola-Desktop_Qt_5_8_0_GCC_64bit-Debug
- 3768
- false
- true
- false
- false
- true
-
- 1
-
-
-
- ProjectExplorer.Project.Target.1
-
- Android for armeabi-v7a (GCC 4.9, Qt 5.8.0)
- Android for armeabi-v7a (GCC 4.9, Qt 5.8.0)
- {6065b6c8-337b-478a-8e04-5b38fdcd0119}
- 0
- 0
- 0
-
- /home/vasudha/Qt/build-Ruqola-Android_for_armeabi_v7a_GCC_4_9_Qt_5_8_0_6065b6-Debug
-
-
- true
- qmake
-
- QtProjectManager.QMakeBuildStep
- true
-
- false
- false
- false
-
-
- true
- Make
-
- Qt4ProjectManager.MakeStep
-
- -w
- -r
-
- false
-
-
-
-
- true
- Copy application data
-
- Qt4ProjectManager.AndroidPackageInstallationStep
-
-
- android-25
-
- true
- Build Android APK
-
- QmakeProjectManager.AndroidBuildApkStep
- 2
- false
- false
-
- 4
- Build
-
- ProjectExplorer.BuildSteps.Build
-
-
-
- true
- Make
-
- Qt4ProjectManager.MakeStep
-
- -w
- -r
-
- true
- clean
-
-
- 1
- Clean
-
- ProjectExplorer.BuildSteps.Clean
-
- 2
- false
-
- Debug
-
- Qt4ProjectManager.Qt4BuildConfiguration
- 2
- true
-
-
- /home/vasudha/Qt/build-Ruqola-Android_for_armeabi_v7a_GCC_4_9_Qt_5_8_0_6065b6-Release
-
-
- true
- qmake
-
- QtProjectManager.QMakeBuildStep
- false
-
- false
- false
- false
-
-
- true
- Make
-
- Qt4ProjectManager.MakeStep
-
- -w
- -r
-
- false
-
-
-
-
- true
- Copy application data
-
- Qt4ProjectManager.AndroidPackageInstallationStep
-
-
- android-25
-
- true
- Build Android APK
-
- QmakeProjectManager.AndroidBuildApkStep
- 2
- false
- false
-
- 4
- Build
-
- ProjectExplorer.BuildSteps.Build
-
-
-
- true
- Make
-
- Qt4ProjectManager.MakeStep
-
- -w
- -r
-
- true
- clean
-
-
- 1
- Clean
-
- ProjectExplorer.BuildSteps.Clean
-
- 2
- false
-
- Release
-
- Qt4ProjectManager.Qt4BuildConfiguration
- 0
- true
-
-
- /home/vasudha/Qt/build-Ruqola-Android_for_armeabi_v7a_GCC_4_9_Qt_5_8_0_6065b6-Profile
-
-
- true
- qmake
-
- QtProjectManager.QMakeBuildStep
- true
-
- false
- true
- false
-
-
- true
- Make
-
- Qt4ProjectManager.MakeStep
-
- -w
- -r
-
- false
-
-
-
-
- true
- Copy application data
-
- Qt4ProjectManager.AndroidPackageInstallationStep
-
-
- android-25
-
- true
- Build Android APK
-
- QmakeProjectManager.AndroidBuildApkStep
- 2
- false
- false
-
- 4
- Build
-
- ProjectExplorer.BuildSteps.Build
-
-
-
- true
- Make
-
- Qt4ProjectManager.MakeStep
-
- -w
- -r
-
- true
- clean
-
-
- 1
- Clean
-
- ProjectExplorer.BuildSteps.Clean
-
- 2
- false
-
- Profile
-
- Qt4ProjectManager.Qt4BuildConfiguration
- 0
- true
-
- 3
-
-
-
- true
- Deploy to Android device
-
- Qt4ProjectManager.AndroidDeployQtStep
- false
-
- 1
- Deploy
-
- ProjectExplorer.BuildSteps.Deploy
-
- 1
- Deploy to Android device
- Deploy to Android device
- Qt4ProjectManager.AndroidDeployConfiguration2
-
- 1
-
-
- false
- false
- 1000
-
- true
-
- false
- false
- false
- false
- true
- 0.01
- 10
- true
- 1
- 25
-
- 1
- true
- false
- true
- valgrind
-
- 0
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
-
- -1
-
-
-
- %{buildDir}
- Custom Executable
-
- ProjectExplorer.CustomExecutableRunConfiguration
- 3768
- false
- true
- false
- false
- true
-
- 1
-
-
-
- ProjectExplorer.Project.TargetCount
- 2
-
-
- ProjectExplorer.Project.Updater.FileVersion
- 18
-
-
- Version
- 18
-
-
diff --git a/src/ddpclient.cpp b/src/ddpclient.cpp
index 4b7c8fc8..5cdf2861 100644
--- a/src/ddpclient.cpp
+++ b/src/ddpclient.cpp
@@ -1,349 +1,344 @@
/*
*
* Copyright 2016 Riccardo Iaconelli
*
* 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) version 3 or any later version
* accepted by the membership of KDE e.V. (or its successor approved
* by the membership of KDE e.V.), which shall act as a proxy
* defined in Section 14 of version 3 of the license.
*
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
*/
#include "ddpclient.h"
#include
#include
#include
#include
#include
#include "ruqola.h"
void process_test(QJsonDocument doc)
{
qDebug() << "Callback test:" << doc;
qDebug() << "End callback";
}
void login_callback(QJsonDocument doc)
{
qDebug() << "LOGIN:" << doc;
Ruqola::self()->setAuthToken(doc.object().value("token").toString());
qDebug() << "End callback";
}
void DDPClient::resume_login_callback(QJsonDocument doc)
{
qDebug() << "LOGIN:" << doc;
Ruqola::self()->setAuthToken(doc.object().value("token").toString());
qDebug() << "End callback";
}
void empty_callback(QJsonDocument doc)
{
Q_UNUSED(doc);
}
DDPClient::DDPClient(const QString& url, QObject* parent)
: QObject(parent),
m_url(url),
m_uid(1),
m_loginJob(0),
m_loginStatus(NotConnected),
m_connected(false),
m_attemptedPasswordLogin(false),
m_attemptedTokenLogin(false)
{
m_webSocket.ignoreSslErrors();
connect(&m_webSocket, &QWebSocket::connected, this, &DDPClient::onWSConnected);
connect(&m_webSocket, &QWebSocket::textMessageReceived, this, &DDPClient::onTextMessageReceived);
connect(&m_webSocket, &QWebSocket::disconnected, this, &DDPClient::WSclosed);
connect(Ruqola::self(), &Ruqola::serverURLChanged, this, &DDPClient::onServerURLChange);
if (!url.isEmpty()) {
m_webSocket.open(QUrl("wss://"+url+"/websocket"));
}
qDebug() << "Trying to connect to URL" << url;
}
DDPClient::~DDPClient()
{
m_webSocket.close();
}
void DDPClient::onServerURLChange()
{
if (Ruqola::self()->serverURL() != m_url || !m_webSocket.isValid()) {
if (m_webSocket.isValid()) {
m_webSocket.flush();
m_webSocket.close();
}
m_url = Ruqola::self()->serverURL();
m_webSocket.open(QUrl("wss://"+m_url+"/websocket"));
connect(&m_webSocket, &QWebSocket::connected, this, &DDPClient::onWSConnected);
qDebug() << "Reconnecting" << m_url; //<< m_webSocket.st;
}
}
DDPClient::LoginStatus DDPClient::loginStatus() const
{
return m_loginStatus;
}
bool DDPClient::isConnected() const
{
return m_connected;
}
bool DDPClient::isLoggedIn() const
{
return m_loginStatus == LoggedIn;
}
unsigned int DDPClient::method(const QString& m, const QJsonDocument& params)
{
return method(m, params, empty_callback);
}
unsigned int DDPClient::method(const QString& method, const QJsonDocument& params, std::function callback)
{
QJsonObject json;
json["msg"] = "method";
json["method"] = method;
json["id"] = QString::number(m_uid);
if (params.isArray()){
json["params"] = params.array();
} else if (params.isObject()) {
QJsonArray arr;
arr.append(params.object());
json["params"] = arr;
// params.object();
}
qint64 bytes = m_webSocket.sendTextMessage(QJsonDocument(json).toJson(QJsonDocument::Compact));
if (bytes < json.length()) {
qDebug() << "ERROR! I couldn't send all of my message. This is a bug! (try again)";
qDebug() << m_webSocket.isValid() << m_webSocket.error() << m_webSocket.requestUrl();
} else {
qDebug() << "Successfully sent " << json;
}
//callback(QJsonDocument::fromJson(json.toUtf8()));
m_callbackHash[m_uid] = callback;
m_uid++;
return m_uid - 1 ;
}
void DDPClient::subscribe(const QString& collection, const QJsonArray& params)
{
QJsonObject json;
json["msg"] = "sub";
json["id"] = QString::number(m_uid);
json["name"] = collection;
json["params"] = params;
qint64 bytes = m_webSocket.sendTextMessage(QJsonDocument(json).toJson(QJsonDocument::Compact));
if (bytes < json.length()) {
qDebug() << "ERROR! I couldn't send all of my message. This is a bug! (try again)";
}
m_uid++;
}
void DDPClient::onTextMessageReceived(QString message)
{
QJsonDocument response = QJsonDocument::fromJson(message.toUtf8());
if (!response.isNull() && response.isObject()) {
QJsonObject root = response.object();
QString messageType = root.value("msg").toString();
qDebug() << "--------------------";
qDebug() << "--------------------";
// qDebug() << "Root is- " << root;
if (messageType == "updated") {
} else if (messageType == "result") {
unsigned id = root.value("id").toString().toInt();
if (m_callbackHash.contains(id)) {
std::function callback = m_callbackHash.take(id);
- //check message type
QJsonDocument res = QJsonDocument(root.value("result").toObject());
QJsonObject result = res.object();
QString type = result.value("type").toString();
QString msg = result.value("msg").toString();
QByteArray base64Image;
QImage image;
- QString path = "/home/vasudha/Qt/build-Ruqola-Desktop_Qt_5_8_0_GCC_64bit-Debug/Images";
- //QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
+ QString path = QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
QDir dir(path);
if (!dir.exists()){
dir.mkdir(path);
qDebug() << "Directory created at " << path;
}
QDir::setCurrent(path);
const QDateTime currentTime = QDateTime::currentDateTime();
const QString timestamp = currentTime.toString(QLatin1String("yyyyMMdd-hhmmsszzz"));
const QString filename = QString::fromLatin1("%1.jpg").arg(timestamp);
-// QString filename = "img.jpg";
-
- //USE QtQUICK, NOT QWIDGETS
if (type == "image"){
qDebug() << "I am here yay";
base64Image.append(msg);
image.loadFromData(QByteArray::fromBase64(base64Image), "JPG");
if ( !image.isNull() ){
qDebug() << "Saving Image to " << path;
if (image.save(filename, "JPEG") ){
qDebug() << "Image saved successfully";
} else {
qDebug() << "Image NOT saved";
}
} else{
qDebug() << "Image is NULL";
}
} else if (type == "text"){
}
callback( QJsonDocument(root.value("result").toObject()) );
}
emit result(id, QJsonDocument(root.value("result").toObject()));
if (id == m_loginJob) {
if (root.value("error").toObject().value("error").toInt() == 403) {
qDebug() << "Wrong password or token expired";
login(); // Let's keep trying to log in
} else {
Ruqola::self()->setAuthToken(root.value("result").toObject().value("token").toString());
setLoginStatus(DDPClient::LoggedIn);
}
// emit loggedInChanged();
}
} else if (messageType == "connected") {
qDebug() << "Connected";
m_connected = true;
emit connectedChanged();
setLoginStatus(DDPClient::LoggingIn);
login(); // Try to resume auth token login
} else if (messageType == "error") {
qDebug() << "ERROR!!" << message;
} else if (messageType == "ping") {
qDebug() << "Ping - Pong";
QJsonObject pong;
pong["msg"] = "pong";
m_webSocket.sendBinaryMessage(QJsonDocument(pong).toJson(QJsonDocument::Compact));
} else if (messageType == "added"){
qDebug() << "ADDING" <password().isEmpty()) {
// If we have a password and we couldn't log in, let's stop here
if (m_attemptedPasswordLogin) {
setLoginStatus(LoginFailed);
return;
}
m_attemptedPasswordLogin = true;
QJsonObject user;
user["username"] = Ruqola::self()->userName();
QJsonObject json;
json["password"] = Ruqola::self()->password();
json["user"] = user;
m_loginJob = method("login", QJsonDocument(json));
} else if (!Ruqola::self()->authToken().isEmpty() && !m_attemptedTokenLogin) {
m_attemptedPasswordLogin = true;
QJsonObject json;
json["resume"] = Ruqola::self()->authToken();
m_loginJob = method("login", QJsonDocument(json));
} else {
setLoginStatus(LoginFailed);
}
}
void DDPClient::logOut()
{
// setLoginStatus(NotConnected);
m_webSocket.close();
}
void DDPClient::onWSConnected()
{
qDebug() << "Websocket connected at URL" << m_url;
QJsonArray supportedVersions;
supportedVersions.append("1");
QJsonObject protocol;
protocol["msg"] = "connect";
protocol["version"] = "1";
protocol["support"] = supportedVersions;
// QString json("{\"msg\":\"connect\", \"version\": \"1\", \"support\": [\"1\"]}");
QByteArray serialize = QJsonDocument(protocol).toJson(QJsonDocument::Compact);
qint64 bytes = m_webSocket.sendTextMessage(serialize);
if (bytes < serialize.length()) {
qDebug() << "ERROR! I couldn't send all of my message. This is a bug! (try again)";
} else {
qDebug() << "Successfully sent " << serialize;
}
}
void DDPClient::WSclosed()
{
qDebug() << "WebSocket CLOSED" << m_webSocket.closeReason() << m_webSocket.error() << m_webSocket.closeCode();
setLoginStatus(NotConnected);
// m_connected = false;
}
diff --git a/src/messagemodel.h b/src/messagemodel.h
index f85de383..a66366d9 100644
--- a/src/messagemodel.h
+++ b/src/messagemodel.h
@@ -1,157 +1,158 @@
/*
*
* Copyright 2016 Riccardo Iaconelli
*
* 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) version 3 or any later version
* accepted by the membership of KDE e.V. (or its successor approved
* by the membership of KDE e.V.), which shall act as a proxy
* defined in Section 14 of version 3 of the license.
*
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
*/
#ifndef MESSAGEMODEL_H
#define MESSAGEMODEL_H
#include
#include
#include
#include
#include
#include
class Message
{
public:
// To be used in ID find: message ID
inline bool operator==(const Message &other) const
{
return other.messageID == messageID;
}
// To be used in sorted insert: timestamp
inline bool operator<(const Message &other) const
{
return timestamp < other.timestamp;
}
//Message Object Fields
// _id
QString messageID;
// rid
QString roomID;
// msg
QString message;
// ts
qint64 timestamp;
// u
QString username;
QString userID;
// _updatedAt
qint64 updatedAt;
// editedAt
qint64 editedAt;
// editedBy
QString editedByUsername;
QString editedByUserID;
// urls
QString url;
QString meta;
QString headers;
QString parsedUrl;
// attachments
QString image_url;
QString color;
// alias
QString alias;
// avatar
QString avatar;
// groupable
bool groupable;
// parseUrls
bool parseUrls;
bool systemMessage = false;
QString systemMessageType;
};
class MessageModel : public QAbstractListModel
{
Q_OBJECT
public:
enum MessageRoles {
Username = Qt::UserRole + 1,
MessageText,
Timestamp,
UserID,
SystemMessage,
SystemMessageType,
MessageID,
RoomID,
UpdatedAt,
- editedAt,
- editedByUserName,
- editedByUserID,
- url,
- meta,
- headers,
- parsedUrl,
- image_url,color,
- alias,
- avatar,
- groupable,
- parseUrls
+ EditedAt,
+ EditedByUserName,
+ EditedByUserID,
+ Url,
+ Meta,
+ Headers,
+ ParsedUrl,
+ Image_url,
+ Color,
+ Alias,
+ Avatar,
+ Groupable,
+ ParseUrls
};
MessageModel(const QString &roomID = "no_room", QObject *parent = 0);
virtual ~MessageModel();
void addMessage(const Message& message);
virtual int rowCount(const QModelIndex & parent = QModelIndex()) const;
virtual QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
qint64 lastTimestamp() const;
static Message fromJSon(const QJsonObject &source);
static QByteArray serialize(const Message &message);
protected:
virtual QHash roleNames() const;
private:
const QString m_roomID;
QVector m_allMessages;
// QMap m_allMessages;
// QMap m_allMessages;
QString m_writableLocation;
QFile *cacheWriter;
};
#endif
diff --git a/src/rocketchatbackend.cpp b/src/rocketchatbackend.cpp
index 4da95493..eed05bce 100644
--- a/src/rocketchatbackend.cpp
+++ b/src/rocketchatbackend.cpp
@@ -1,278 +1,278 @@
/*
*
* Copyright 2016 Riccardo Iaconelli
*
* 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) version 3 or any later version
* accepted by the membership of KDE e.V. (or its successor approved
* by the membership of KDE e.V.), which shall act as a proxy
* defined in Section 14 of version 3 of the license.
*
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
*/
#include "rocketchatbackend.h"
#include
#include
#include
#include "ruqola.h"
#include "ddpclient.h"
void debug_callback(QJsonDocument doc)
{
qDebug() << "DEBUG:" << doc;
}
void process_backlog(QJsonDocument messages)
{
qDebug() << messages.object().value("messages").toArray().size();
RocketChatBackend::processIncomingMessages(messages.object().value("messages").toArray());
}
void rooms_callback(QJsonDocument doc)
{
RoomModel *model = Ruqola::self()->roomModel();
QJsonArray removed = doc.object().value("remove").toArray();
QJsonArray updated = doc.object().value("update").toArray();
for (int i = 0; i < updated.size(); i++) {
QJsonObject room = updated.at(i).toObject();
if (room.value("t").toString() != "d") {
QString roomID = room.value("_id").toString();
MessageModel *roomModel = Ruqola::self()->getModelForRoom(roomID);
// let's be extra safe around crashes
if (Ruqola::self()->loginStatus() == DDPClient::LoggedIn) {
Room r;
r.id = roomID;
r.name = room["name"].toString();
r.topic = room["topic"].toString();
qDebug() << "Adding room" << r.name << r.id << r.topic;
model->addRoom(r);
}
QJsonArray params;
params.append(QJsonValue(roomID));
Ruqola::self()->ddp()->subscribe("stream-room-messages", params);
// Load history
params.append(QJsonValue(QJsonValue::Null));
params.append(QJsonValue(50)); // Max number of messages to load;
QJsonObject dateObject;
dateObject["$date"] = QJsonValue(roomModel->lastTimestamp());
params.append(dateObject);
Ruqola::self()->ddp()->method("loadHistory", QJsonDocument(params), process_backlog);
}
}
}
void subs_callback(QJsonDocument doc)
{
RoomModel *model = Ruqola::self()->roomModel();
QJsonArray removed = doc.object().value("remove").toArray();
QJsonArray updated = doc.object().value("update").toArray();
for (int i = 0; i < updated.size(); i++) {
QJsonObject room = updated.at(i).toObject();
if (room.value("t").toString() != "d") {
QString roomID = room.value("rid").toString();
MessageModel *roomModel = Ruqola::self()->getModelForRoom(roomID);
// let's be extra safe around crashes
if (Ruqola::self()->loginStatus() == DDPClient::LoggedIn) {
Room r;
r.id = roomID;
r.name = room["name"].toString();
r.topic = room["topic"].toString();
qDebug() << "Adding room" << r.name << r.id << r.topic;
model->addRoom(r);
}
QJsonArray params;
params.append(QJsonValue(roomID));
Ruqola::self()->ddp()->subscribe("stream-room-messages", params);
// Load history
params.append(QJsonValue(QJsonValue::Null));
params.append(QJsonValue(50)); // Max number of messages to load;
QJsonObject dateObject;
dateObject["$date"] = QJsonValue(roomModel->lastTimestamp());
params.append(dateObject);
Ruqola::self()->ddp()->method("loadHistory", QJsonDocument(params), process_backlog);
}
}
}
void RocketChatBackend::processIncomingMessages(QJsonArray messages)
{
foreach (const QJsonValue v, messages) {
QJsonObject o = v.toObject();
Message m;
QString roomId = o.value("rid").toString();
QString type = o.value("t").toString();
m.messageID = o.value("_id").toString();
m.roomID = roomId;
m.message = o.value("msg").toString();
m.timestamp = (qint64)o.value("ts").toObject().value("$date").toDouble();
m.username = o.value("u").toObject().value("username").toString();
m.userID = o.value("u").toObject().value("_id").toString();
m.updatedAt = o.value("_updatedAt").toObject().value("$date").toDouble();
m.editedAt = o.value("editedAt").toObject().value("$date").toDouble();
m.editedByUsername = o.value("editedBy").toObject().value("username").toString();
m.editedByUserID = o.value("editedBy").toObject().value("userID").toString();
m.url = o.value("urls").toObject().value("url").toString();
m.meta = o.value("urls").toObject().value("meta").toString();
m.headers = o.value("urls").toObject().value("headers").toString();
m.parsedUrl = o.value("urls").toObject().value("parsedUrl").toString();
m.image_url = o.value("attachments").toObject().value("image_url").toString();
m.color = o.value("attachments").toObject().value("color").toString();
m.alias = o.value("alias").toString();
m.avatar = o.value("avatar").toString();
m.groupable = o.value("groupable").toBool();
m.parseUrls = o.value("parseUrls").toBool();
if (!type.isEmpty()) {
m.systemMessage = true;
m.systemMessageType = type;
} else {
- m.systemMessage = false;
+ m.systemMessage = false;
}
Ruqola::self()->getModelForRoom(roomId)->addMessage(m);
// qDebug() << "RocketChatBackend::processIncomingMessages sending notification";
// //Send notifications only when user is logged in
// if ( Ruqola::self()->loginStatus() == DDPClient::LoggedIn) {
// QString userName = m.username;
// QString message = m.message;
// QString param = QString("%1 \n %2").arg(userName).arg(message);
// Ruqola::self()->notification()->setMessage(param);
// } else {
// qDebug() << m.username << " recieved message: " << m.message;
// }
}
}
RocketChatBackend::RocketChatBackend(QObject* parent)
: QObject(parent)
{
connect(Ruqola::self(), &Ruqola::loginStatusChanged, this, &RocketChatBackend::onLoginStatusChanged);
connect(Ruqola::self(), &Ruqola::userIDChanged, this, &RocketChatBackend::onUserIDChanged);
connect(Ruqola::self()->ddp(), &DDPClient::changed, this, &RocketChatBackend::onChanged);
connect(Ruqola::self()->ddp(), &DDPClient::added, this, &RocketChatBackend::onAdded);
}
RocketChatBackend::~RocketChatBackend()
{
}
void RocketChatBackend::onLoginStatusChanged()
{
if (Ruqola::self()->loginStatus() == DDPClient::LoggedIn) {
qDebug() << "GETTING LIST OF ROOMS";
// Ruqola::self()->ddp()->method("subscriptions/get", QJsonDocument::fromJson("{\"$date\": 0}"), rooms_callback);
QJsonObject params;
params["$date"] = QJsonValue(0); // get ALL rooms we've ever seen
Ruqola::self()->ddp()->method("rooms/get", QJsonDocument(params), rooms_callback);
// Ruqola::self()->ddp()->subscribe("stream-room-messages", QJsonDocument::fromJson(params.toLatin1()));
}
}
void RocketChatBackend::onLoggedIn()
{
// if (Ruqola::self()->loginStatus() != DDPClient::LoggedIn) {
// qDebug() << "not yet logged in:" << Ruqola::self()->loginStatus();
// return;
// }
// // get list of rooms
// Ruqola::self()->ddp()->method("rooms/get", QJsonDocument::fromJson("{\"$date\": 0}"), rooms_callback);
}
void RocketChatBackend::onAdded(QJsonObject object)
{
QString collection = object.value("collection").toString();
// qDebug() << "ROCKET BACK" << object << collection;
if (collection == "stream-room-messages") {
} else if (collection == "users") {
if (object["username"].isNull()) {
// it's us! get ID
Ruqola::self()->setUserID(object["id"].toString());
}
qDebug() << "NEW USER ADDED: " << object.value("userName").toString();
} else if (collection == "rooms") {
}
else if (collection == "stream-notify-user"){
}
}
void RocketChatBackend::onChanged(QJsonObject object)
{
QString collection = object["collection"].toString();
// qDebug() << "ROCKET CHAT BACK onChanged" << object << collection;
if (collection == "stream-room-messages") {
QJsonObject fields = object.value("fields").toObject();
QString roomId = fields.value("eventName").toString();
QJsonArray contents = fields.value("args").toArray();
processIncomingMessages(contents);
} else if (collection == "users") {
qDebug() << "USER CHANGED";
} else if (collection == "rooms") {
} else if (collection == "stream-notify-user") {
QJsonObject fields = object.value("fields").toObject();
QJsonArray contents = fields.value("args").toArray();
QString message = contents.at(0).toObject()["text"].toString();
Ruqola::self()->notification()->showMessage("New message", message, QSystemTrayIcon::Information, 5000 );
qDebug() << "New notification" << object.value("fields").toObject();
}
}
void RocketChatBackend::onUserIDChanged()
{
qDebug() << "subscribing to notification feed";
QJsonArray params;
params.append(QJsonValue(QString("%1/%2").arg(Ruqola::self()->userID()).arg(QString("notification"))));
Ruqola::self()->ddp()->subscribe("stream-notify-user", params);
}