diff --git a/autotests/roommodeltest.cpp b/autotests/roommodeltest.cpp index 4c0294c3..a173a6b1 100644 --- a/autotests/roommodeltest.cpp +++ b/autotests/roommodeltest.cpp @@ -1,526 +1,526 @@ /* Copyright (c) 2017-2019 Montel Laurent This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License or ( at your option ) version 3 or, at the discretion of KDE e.V. ( which shall act as a proxy as in section 14 of the GPLv3 ), any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "room.h" #include "roomwrapper.h" #include "roommodeltest.h" #include "test_model_helpers.h" #include "model/roommodel.h" #include "ruqola_autotest_helper.h" #include #include #include #include #include #include QTEST_GUILESS_MAIN(RoomModelTest) //TEST signal/slot RoomModelTest::RoomModelTest(QObject *parent) : QObject(parent) { } void RoomModelTest::shouldHaveDefaultValues() { RoomModel sampleModel; QCOMPARE(sampleModel.rowCount(), 0); QHash roles; roles[RoomModel::RoomName] = QByteArrayLiteral("name"); roles[RoomModel::RoomID] = QByteArrayLiteral("room_id"); roles[RoomModel::RoomSelected] = QByteArrayLiteral("selected"); roles[RoomModel::RoomUnread] = QByteArrayLiteral("unread"); roles[RoomModel::RoomType] = QByteArrayLiteral("type"); roles[RoomModel::RoomOwnerUserName] = QByteArrayLiteral("username"); roles[RoomModel::RoomOwnerUserID] = QByteArrayLiteral("userID"); roles[RoomModel::RoomTopic] = QByteArrayLiteral("topic"); roles[RoomModel::RoomMutedUsers] = QByteArrayLiteral("mutedUsers"); roles[RoomModel::RoomJitsiTimeout] = QByteArrayLiteral("jitsiTimeout"); roles[RoomModel::RoomRo] = QByteArrayLiteral("readOnly"); roles[RoomModel::RoomAnnouncement] = QByteArrayLiteral("announcement"); roles[RoomModel::RoomOpen] = QByteArrayLiteral("open"); roles[RoomModel::RoomAlert] = QByteArrayLiteral("alert"); roles[RoomModel::RoomOrder] = QByteArrayLiteral("roomorder"); roles[RoomModel::RoomFavorite] = QByteArrayLiteral("favorite"); roles[RoomModel::RoomSection] = QByteArrayLiteral("sectionname"); roles[RoomModel::RoomIcon] = QByteArrayLiteral("channelicon"); roles[RoomModel::RoomUserMentions] = QByteArrayLiteral("userMentions"); QCOMPARE(sampleModel.roleNames(), roles); } void RoomModelTest::shouldReturnRowCount() { RoomModel sampleModel; QSignalSpy rowInsertedSpy(&sampleModel, &RoomModel::rowsInserted); QSignalSpy rowABTInserted(&sampleModel, &RoomModel::rowsAboutToBeInserted); QSignalSpy rowRemovedSpy(&sampleModel, &RoomModel::rowsRemoved); QSignalSpy rowABTRemoved(&sampleModel, &RoomModel::rowsAboutToBeRemoved); QCOMPARE(sampleModel.rowCount(), 0); sampleModel.addRoom(QStringLiteral("myRoomID1"), QStringLiteral("myRoom1")); QCOMPARE(sampleModel.rowCount(), 1); QCOMPARE(rowInsertedSpy.count(), 1); QCOMPARE(rowABTInserted.count(), 1); QCOMPARE(rowRemovedSpy.count(), 0); QCOMPARE(rowABTRemoved.count(), 0); QCOMPARE(TestModelHelpers::rowSpyToText(rowInsertedSpy), QStringLiteral("0,0")); QCOMPARE(TestModelHelpers::rowSpyToText(rowABTInserted), QStringLiteral("0,0")); rowInsertedSpy.clear(); rowABTInserted.clear(); rowRemovedSpy.clear(); rowABTRemoved.clear(); sampleModel.addRoom(QStringLiteral("myRoomID1"), QStringLiteral("bla bla")); QCOMPARE(sampleModel.rowCount(), 1); //Fix it. We remove + readd after that ! it's not optimal QCOMPARE(rowInsertedSpy.count(), 1); QCOMPARE(rowABTInserted.count(), 1); QCOMPARE(rowRemovedSpy.count(), 0); QCOMPARE(rowABTRemoved.count(), 0); rowInsertedSpy.clear(); rowABTInserted.clear(); rowRemovedSpy.clear(); rowABTRemoved.clear(); sampleModel.addRoom(QStringLiteral("myRoomID2"), QStringLiteral("myRoom2"), true); QCOMPARE(sampleModel.rowCount(), 2); QCOMPARE(rowInsertedSpy.count(), 1); QCOMPARE(rowABTInserted.count(), 1); QCOMPARE(rowRemovedSpy.count(), 0); QCOMPARE(rowABTRemoved.count(), 0); QCOMPARE(TestModelHelpers::rowSpyToText(rowInsertedSpy), QStringLiteral("1,1")); QCOMPARE(TestModelHelpers::rowSpyToText(rowABTInserted), QStringLiteral("1,1")); } void RoomModelTest::shouldFindRoom() { RoomModel sampleModel; RoomWrapper *sampleWrapper = nullptr; sampleModel.addRoom(QStringLiteral("RA15"), QStringLiteral("master")); sampleWrapper = sampleModel.findRoomWrapper(QStringLiteral("RA151100ECE")); QVERIFY(!sampleWrapper); sampleModel.addRoom(QStringLiteral("RA151100ECE"), QStringLiteral("myRoom")); sampleWrapper = sampleModel.findRoomWrapper(QStringLiteral("RA151100ECE")); QVERIFY(sampleWrapper); QCOMPARE(QStringLiteral("myRoom"), sampleWrapper->name()); delete sampleWrapper; } void RoomModelTest::shouldAddRoom() { RoomModel sampleModel; RoomWrapper *sampleWrapper = nullptr; QCOMPARE(sampleModel.rowCount(), 0); sampleModel.addRoom(QStringLiteral("RA151100ECE"), QStringLiteral("myRoom")); QCOMPARE(sampleModel.rowCount(), 1); sampleWrapper = sampleModel.findRoomWrapper(QStringLiteral("RA151100ECE")); QVERIFY(sampleWrapper); QCOMPARE(QStringLiteral("myRoom"), sampleWrapper->name()); delete sampleWrapper; } void RoomModelTest::shouldUpdateRoom() { //FIXME!! /* RoomModel sampleModel; RoomWrapper *sampleWrapper = nullptr; sampleModel.addRoom(QStringLiteral("RA151100ECE"), QStringLiteral("myRoom")); QSignalSpy spy(&sampleModel, &RoomModel::dataChanged); const QString Id = QStringLiteral("RA151100ECE"); const QString name = QStringLiteral("newName"); const QString topic = QStringLiteral("myTopic"); const QString announcement = QStringLiteral("Happy New Year announcement"); const QString description = QStringLiteral("description"); sampleModel.updateRoom(name, Id, topic, announcement, true, description); sampleWrapper = sampleModel.findRoomWrapper(Id); QVERIFY(sampleWrapper); QCOMPARE(sampleWrapper->name(), name); QCOMPARE(sampleWrapper->topic(), topic); QCOMPARE(sampleWrapper->announcement(), announcement); QCOMPARE(sampleWrapper->description(), description); QVERIFY(sampleWrapper->readOnly()); QCOMPARE(spy.count(), 1); delete sampleWrapper; */ } void RoomModelTest::shouldUpdateRoomFromQJsonObject() { RoomModel sampleModel; RoomWrapper *sampleWrapper = nullptr; QJsonObject roomData; const QString name = QStringLiteral("newName"); const QString topic = QStringLiteral("myTopic"); const QString announcement = QStringLiteral("Happy New Year announcement"); roomData.insert(QStringLiteral("rid"), QJsonValue(QLatin1String("RA151100ECE"))); roomData.insert(QStringLiteral("name"), QJsonValue(name)); roomData.insert(QStringLiteral("announcement"), announcement); roomData.insert(QStringLiteral("topic"), topic); QCOMPARE(sampleModel.rowCount(), 0); sampleModel.addRoom(QStringLiteral("RA151100ECE"), QStringLiteral("myRoom")); QCOMPARE(sampleModel.rowCount(), 1); QSignalSpy spy(&sampleModel, &RoomModel::dataChanged); sampleModel.updateRoom(roomData); sampleWrapper = sampleModel.findRoomWrapper(QStringLiteral("RA151100ECE")); QVERIFY(sampleWrapper); QCOMPARE(name, sampleWrapper->name()); QCOMPARE(topic, sampleWrapper->topic()); QCOMPARE(announcement, sampleWrapper->announcement()); QCOMPARE(sampleWrapper->readOnly(), false); QCOMPARE(spy.count(), 1); delete sampleWrapper; } void RoomModelTest::shouldUpdateSubcriptionActionRemoved() { RoomModel sampleModel; QJsonArray input; QJsonObject roomData; roomData.insert(QStringLiteral("rid"), QJsonValue(QLatin1String("RA151100ECE"))); input.append(QJsonValue(QLatin1String("removed"))); input.append(QJsonValue(roomData)); QCOMPARE(sampleModel.rowCount(), 0); sampleModel.addRoom(QStringLiteral("RA151100ECE"), QStringLiteral("myRoom")); QCOMPARE(sampleModel.rowCount(), 1); sampleModel.updateSubscription(input); QCOMPARE(sampleModel.rowCount(), 0); roomData.insert(QStringLiteral("rid"), QJsonValue(QLatin1String("RA151100ECE_NEW"))); input.pop_back(); input.append(QJsonValue(roomData)); sampleModel.updateSubscription(input); QCOMPARE(sampleModel.rowCount(), 0); } void RoomModelTest::shouldUpdateSubcriptionActionInserted() { RoomModel sampleModel; QJsonArray input; QJsonObject roomData; roomData.insert(QStringLiteral("rid"), QJsonValue(QLatin1String("RA151100ECE"))); roomData.insert(QStringLiteral("name"), QJsonValue(QLatin1String("myRoom"))); input.append(QJsonValue(QLatin1String("inserted"))); input.append(QJsonValue(roomData)); QCOMPARE(sampleModel.rowCount(), 0); sampleModel.updateSubscription(input); QCOMPARE(sampleModel.rowCount(), 1); sampleModel.updateSubscription(input); QCOMPARE(sampleModel.rowCount(), 1); } void RoomModelTest::shouldUpdateSubcriptionActionUpdated() { //TODO rename autotests as it's not updatesubscrition but updateroom //Update subscription doesn't update topic and co RoomModel sampleModel; //QJsonArray input; QJsonObject roomData; RoomWrapper *sampleWrapper = nullptr; sampleModel.addRoom(QStringLiteral("RA151100ECE"), QStringLiteral("myRoom")); const QString name = QStringLiteral("newName"); const QString topic = QStringLiteral("myTopic"); const QString announcement = QStringLiteral("Happy New Year announcement"); roomData.insert(QStringLiteral("rid"), QJsonValue(QLatin1String("RA151100ECE"))); roomData.insert(QStringLiteral("name"), QJsonValue(name)); roomData.insert(QStringLiteral("announcement"), announcement); roomData.insert(QStringLiteral("topic"), topic); // input.append(QJsonValue(QLatin1String("updated"))); // input.append(roomData); QCOMPARE(sampleModel.rowCount(), 1); QSignalSpy spy(&sampleModel, &RoomModel::dataChanged); sampleModel.updateRoom(roomData); QCOMPARE(sampleModel.rowCount(), 1); sampleWrapper = sampleModel.findRoomWrapper(QStringLiteral("RA151100ECE")); QVERIFY(sampleWrapper); QCOMPARE(name, sampleWrapper->name()); QCOMPARE(topic, sampleWrapper->topic()); QCOMPARE(announcement, sampleWrapper->announcement()); QCOMPARE(sampleWrapper->readOnly(), false); QCOMPARE(spy.count(), 1); delete sampleWrapper; } void RoomModelTest::shouldClear() { RoomModel sampleModel; QSignalSpy rowInsertedSpy(&sampleModel, &RoomModel::rowsInserted); QSignalSpy rowABTInserted(&sampleModel, &RoomModel::rowsAboutToBeInserted); QSignalSpy rowRemovedSpy(&sampleModel, &RoomModel::rowsRemoved); QSignalSpy rowABTRemoved(&sampleModel, &RoomModel::rowsAboutToBeRemoved); QCOMPARE(sampleModel.rowCount(), 0); sampleModel.addRoom(QStringLiteral("RA151100ECE"), QStringLiteral("myRoom")); QCOMPARE(sampleModel.rowCount(), 1); QCOMPARE(rowInsertedSpy.count(), 1); QCOMPARE(rowABTInserted.count(), 1); QCOMPARE(rowRemovedSpy.count(), 0); QCOMPARE(rowABTRemoved.count(), 0); QCOMPARE(TestModelHelpers::rowSpyToText(rowInsertedSpy), QStringLiteral("0,0")); QCOMPARE(TestModelHelpers::rowSpyToText(rowABTInserted), QStringLiteral("0,0")); rowInsertedSpy.clear(); rowABTInserted.clear(); rowRemovedSpy.clear(); rowABTRemoved.clear(); sampleModel.clear(); QCOMPARE(sampleModel.rowCount(), 0); QCOMPARE(rowInsertedSpy.count(), 0); QCOMPARE(rowABTInserted.count(), 0); QCOMPARE(rowRemovedSpy.count(), 1); QCOMPARE(rowABTRemoved.count(), 1); QCOMPARE(TestModelHelpers::rowSpyToText(rowRemovedSpy), QStringLiteral("0,0")); QCOMPARE(TestModelHelpers::rowSpyToText(rowABTRemoved), QStringLiteral("0,0")); for (int i = 0; i < 15; i++) { sampleModel.addRoom(QStringLiteral("RA151100ECE%1").arg(i), QStringLiteral("myRoom%1").arg(i)); } QCOMPARE(sampleModel.rowCount(), 15); rowInsertedSpy.clear(); rowABTInserted.clear(); rowRemovedSpy.clear(); rowABTRemoved.clear(); sampleModel.clear(); QCOMPARE(rowInsertedSpy.count(), 0); QCOMPARE(rowABTInserted.count(), 0); QCOMPARE(rowRemovedSpy.count(), 1); QCOMPARE(rowABTRemoved.count(), 1); QCOMPARE(TestModelHelpers::rowSpyToText(rowRemovedSpy), QStringLiteral("0,14")); QCOMPARE(TestModelHelpers::rowSpyToText(rowABTRemoved), QStringLiteral("0,14")); } void RoomModelTest::shouldReset() { RoomModel sampleModel; //RoomWrapper *sampleWrapper; const QString Id = QStringLiteral("RA151100ECE"); const QString name = QStringLiteral("myRoom"); QCOMPARE(sampleModel.rowCount(), 0); sampleModel.addRoom(Id, name); QCOMPARE(sampleModel.rowCount(), 1); //TODO: should uncomment this after enabling cache in roomModel /* sampleModel.reset(); QCOMPARE(1, sampleModel.rowCount()); sampleWrapper = sampleModel.findRoomWrapper(Id); QCOMPARE(name, sampleWrapper->name()); */ } void RoomModelTest::shouldReturnDataDefault() { RoomModel sampleModel; QVariant output; QString Id = QStringLiteral("RA151100ECE"); QString name = QStringLiteral("myRoom"); sampleModel.addRoom(Id, name); output = sampleModel.data(sampleModel.index(0), RoomModel::RoomName); QCOMPARE(output.toString(), name); output = sampleModel.data(sampleModel.index(0), RoomModel::RoomID); QCOMPARE(output.toString(), Id); output = sampleModel.data(sampleModel.index(0), RoomModel::RoomSelected); QCOMPARE(output.toBool(), false); output = sampleModel.data(sampleModel.index(0), RoomModel::RoomType); //channel type QVERIFY(output.toString().isEmpty()); output = sampleModel.data(sampleModel.index(0), RoomModel::RoomOwnerUserID); QVERIFY(output.toString().isEmpty()); output = sampleModel.data(sampleModel.index(0), RoomModel::RoomOwnerUserName); QVERIFY(output.toString().isEmpty()); output = sampleModel.data(sampleModel.index(0), RoomModel::RoomTopic); QVERIFY(output.toString().isEmpty()); output = sampleModel.data(sampleModel.index(0), RoomModel::RoomMutedUsers); QVERIFY(output.toStringList().isEmpty()); output = sampleModel.data(sampleModel.index(0), RoomModel::RoomJitsiTimeout); QCOMPARE(output, QVariant(qint64(-1))); output = sampleModel.data(sampleModel.index(0), RoomModel::RoomRo); QCOMPARE(output.toBool(), false); output = sampleModel.data(sampleModel.index(0), RoomModel::RoomAnnouncement); QVERIFY(output.toString().isEmpty()); output = sampleModel.data(sampleModel.index(0), RoomModel::RoomUnread); QCOMPARE(output, QVariant(int(0))); //quint64 not used in room.cpp??? output = sampleModel.data(sampleModel.index(0), RoomModel::RoomFavorite); QCOMPARE(output.toBool(), false); output = sampleModel.data(sampleModel.index(0), RoomModel::RoomOpen); QCOMPARE(output.toBool(), false); output = sampleModel.data(sampleModel.index(0), RoomModel::RoomSection); QVERIFY(output.toString().isEmpty()); output = sampleModel.data(sampleModel.index(0), RoomModel::RoomOrder); QCOMPARE(output, QVariant(int(6))); // not favorite (3) + no channel selected or 'p' (3) = total order(6) output = sampleModel.data(sampleModel.index(0), RoomModel::RoomIcon); QCOMPARE(output, QVariant(QIcon())); } void RoomModelTest::shouldReturnData() { Room *input = new Room(nullptr); const QString Id = QStringLiteral("RA151100ECE"); const QString name = QStringLiteral("myRoom"); const bool selected = true; const QString roomType = QStringLiteral("p"); const QString userId = QStringLiteral("sdfsdfs"); const QString userName = QStringLiteral("pp"); const QString topic = QStringLiteral("topic"); const QStringList mutedUsers = QStringList{QStringLiteral("mutedUsers"), QStringLiteral("muted2")}; const qint64 time = 55; const bool readOnly = true; const QString announcement = QStringLiteral("AA"); const int unread = 66; const bool favorite = true; const bool open = true; input->setRoomId(Id); input->setName(name); input->setSelected(selected); input->setChannelType(roomType); input->setRoomCreatorUserId(userId); input->setRoomCreatorUserName(userName); input->setTopic(topic); input->setMutedUsers(mutedUsers); input->setJitsiTimeout(time); input->setReadOnly(readOnly); input->setAnnouncement(announcement); input->setUnread(unread); input->setFavorite(favorite); input->setOpen(open); RoomModel sampleModel; QVariant output; sampleModel.addRoom(input);//don't pass address. pass pointer variable output = sampleModel.data(sampleModel.index(0), RoomModel::RoomName); QCOMPARE(output.toString(), name); output = sampleModel.data(sampleModel.index(0), RoomModel::RoomID); QCOMPARE(output.toString(), Id); output = sampleModel.data(sampleModel.index(0), RoomModel::RoomSelected); QCOMPARE(output.toBool(), selected); output = sampleModel.data(sampleModel.index(0), RoomModel::RoomType); //channel type QCOMPARE(output.toString(), roomType); output = sampleModel.data(sampleModel.index(0), RoomModel::RoomOwnerUserID); QCOMPARE(output.toString(), userId); output = sampleModel.data(sampleModel.index(0), RoomModel::RoomOwnerUserName); QCOMPARE(output.toString(), userName); output = sampleModel.data(sampleModel.index(0), RoomModel::RoomTopic); QCOMPARE(output.toString(), topic); output = sampleModel.data(sampleModel.index(0), RoomModel::RoomMutedUsers); QCOMPARE(output.toStringList(), mutedUsers); output = sampleModel.data(sampleModel.index(0), RoomModel::RoomJitsiTimeout); QCOMPARE(output, QVariant(time)); output = sampleModel.data(sampleModel.index(0), RoomModel::RoomRo); QCOMPARE(output.toBool(), readOnly); output = sampleModel.data(sampleModel.index(0), RoomModel::RoomAnnouncement); QCOMPARE(output.toString(), announcement); output = sampleModel.data(sampleModel.index(0), RoomModel::RoomUnread); QCOMPARE(output, QVariant(unread)); //quint64 not used in room.cpp??? output = sampleModel.data(sampleModel.index(0), RoomModel::RoomFavorite); QCOMPARE(output.toBool(), favorite); output = sampleModel.data(sampleModel.index(0), RoomModel::RoomOpen); QCOMPARE(output.toBool(), open); output = sampleModel.data(sampleModel.index(0), RoomModel::RoomSection); - QCOMPARE(output.toString(), QStringLiteral("Favorites")); //first priority for favrites and then to channels + QCOMPARE(output.toString(), QStringLiteral("Favorites")); //first priority for favorites and then to channels output = sampleModel.data(sampleModel.index(0), RoomModel::RoomOrder); QCOMPARE(output, QVariant(int(1))); // Private room output = sampleModel.data(sampleModel.index(0), RoomModel::RoomIcon); QCOMPARE(output, QVariant(QIcon::fromTheme(QStringLiteral("lock")))); } void RoomModelTest::shouldInsertRoom_data() { QTest::addColumn("insertRoomFileName"); QTest::addColumn("roomId"); QTest::newRow("insertroom1") << QStringLiteral("insertroom1") << QStringLiteral("fooid"); QTest::newRow("insertroom2") << QStringLiteral("insertroom2") << QStringLiteral("bla1"); } void RoomModelTest::shouldInsertRoom() { QFETCH(QString, insertRoomFileName); QFETCH(QString, roomId); const QString originalJsonFile = QLatin1String(RUQOLA_DATA_DIR) + QStringLiteral("/insert-rooms/") + insertRoomFileName + QStringLiteral(".json"); QFile f(originalJsonFile); QVERIFY(f.open(QIODevice::ReadOnly)); const QByteArray content = f.readAll(); f.close(); const QJsonDocument doc = QJsonDocument::fromJson(content); const QJsonObject fields = doc.object(); RoomModel sampleModel; const QString generatedRoomId = sampleModel.insertRoom(fields); QCOMPARE(generatedRoomId, roomId); QCOMPARE(sampleModel.rowCount(), 1); Room *r = sampleModel.findRoom(generatedRoomId); QVERIFY(r); //qDebug() << " fields"< * Copyright (c) 2018-2019 Montel Laurent * * 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 #include #include #include #include "ruqolaregisterengine.h" #include "config-ruqola.h" #include #include #if defined(Q_OS_WIN) || defined(Q_OS_MAC) #include #endif int main(int argc, char *argv[]) { QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QApplication app(argc, argv); app.setAttribute(Qt::AA_UseHighDpiPixmaps, true); app.setWindowIcon(QIcon::fromTheme(QStringLiteral("ruqola"))); KCrash::initialize(); #if defined(Q_OS_WIN) || defined(Q_OS_MAC) // call KIconTheme to make sure KIconTheme is linked KIconTheme::list(); #endif KLocalizedString::setApplicationDomain("ruqola"); QCoreApplication::setOrganizationDomain(QStringLiteral("kde.org")); KAboutData aboutData(QStringLiteral("ruqola"), i18n("Ruqola"), QStringLiteral(RUQOLA_VERSION), i18n("Rocket Chat Client"), KAboutLicense::GPL_V2, i18n("Copyright © 2017-2019 Ruqola authors")); aboutData.addAuthor(i18n("Laurent Montel"), i18n("Maintainer"), QStringLiteral("montel@kde.org")); aboutData.addAuthor(i18n("Riccardo Iaconelli"), i18n("Original author"), QStringLiteral("riccardo@kde.org")); aboutData.addAuthor(i18n("Vasudha Mathur"), i18n("Former core developer"), QStringLiteral("vasudhamathur96@gmail.com")); aboutData.setOrganizationDomain(QByteArrayLiteral("kde.org")); aboutData.setProductName(QByteArrayLiteral("ruqola")); aboutData.addCredit(i18n("David Faure"), i18n("Bug fixing"), QStringLiteral("faure@kde.org")); aboutData.addCredit(i18n("Paul Lemire"), i18n("Help for debugging QML"), QStringLiteral("paul.lemire@kdab.com")); - aboutData.addCredit(i18n("Veluri Mithun"), i18n("Autotest Improvment and created some tests apps"), QStringLiteral("velurimithun38@gmail.com")); + aboutData.addCredit(i18n("Veluri Mithun"), i18n("Autotest improvement and created some tests apps"), QStringLiteral("velurimithun38@gmail.com")); aboutData.addCredit(i18n("Franck Arrecot"), i18n("Fix some QML bugs"), QStringLiteral("franck.arrecot@kdab.com")); KAboutData::setApplicationData(aboutData); QCommandLineParser parser; aboutData.setupCommandLine(&parser); parser.process(app); aboutData.processCommandLine(&parser); RuqolaRegisterEngine ruqolaEngine; if (!ruqolaEngine.initialize()) { return -1; } return app.exec(); } diff --git a/src/apps/qml/common/AvatarImage.qml b/src/apps/qml/common/AvatarImage.qml index 2f678121..e2b35c43 100644 --- a/src/apps/qml/common/AvatarImage.qml +++ b/src/apps/qml/common/AvatarImage.qml @@ -1,112 +1,112 @@ /* * Copyright (C) 2017-2019 Laurent Montel * * 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 . * */ import QtQuick 2.9 import QtQuick.Controls 2.5 as QQC2 import org.kde.kirigami 2.7 as Kirigami import QtQuick.Layouts 1.12 import "../js/message.js" as MessageScript; import QtQuick.Window 2.2 import KDE.Ruqola.RocketChatAccount 1.0 import KDE.Ruqola.DebugCategory 1.0 Rectangle { id: avatarRect property string avatarurl property string aliasname property string username signal showUserInfo() Layout.alignment: Qt.AlignTop | Qt.AlignCenter Layout.fillHeight: false //Customize it. implicitWidth: Kirigami.Units.iconSizes.large implicitHeight: implicitWidth radius: 3 anchors.rightMargin: 2*Kirigami.Units.smallSpacing color: avatarurl !== "" ? "transparent" : MessageScript.stringToColour(username) Image { id: avatarImage anchors.fill: parent visible: avatarurl !== "" source: avatarurl fillMode: Image.PreserveAspectFit MouseArea { anchors.fill: parent onClicked: { console.log(RuqolaDebugCategorySingleton.category, "Clicked"); avatarRect.showUserInfo(); } } onStatusChanged: { if (avatarImage.status === Image.Error) { - console.log(RuqolaDebugCategorySingleton.category, "An error occured when we try to load image"); + console.log(RuqolaDebugCategorySingleton.category, "An error occurred when we try to load image"); } } } QQC2.Label { id: avatarText visible: avatarurl == "" anchors.fill: parent anchors.margins: Kirigami.Units.smallSpacing renderType: Text.QtRendering color: Kirigami.Theme.backgroundColor font.weight: Font.Bold font.pointSize: 100 fontSizeMode: Text.Fit horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter text: { //TODO verify if it works with non latin char. if (aliasname.length > 0) { var match = aliasname.match(/([a-zA-Z0-9])([a-zA-Z0-9])/); var abbrev = match[1].toUpperCase(); if (match.length > 2) { abbrev += match[2].toLowerCase(); } return abbrev; } return ""; } } Connections { target: appid.rocketChatAccount onFileDownloaded: { //console.log(" filePath " + filePath + " username: " + username) if (filePath === "/avatar/" + username) { avatarurl = cacheImageUrl } } } } diff --git a/src/rocketchatrestapi-qt5/restapiabstractjob.cpp b/src/rocketchatrestapi-qt5/restapiabstractjob.cpp index ffbf5d6a..ce5747b6 100644 --- a/src/rocketchatrestapi-qt5/restapiabstractjob.cpp +++ b/src/rocketchatrestapi-qt5/restapiabstractjob.cpp @@ -1,458 +1,458 @@ /* Copyright (c) 2018-2019 Montel Laurent This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License or ( at your option ) version 3 or, at the discretion of KDE e.V. ( which shall act as a proxy as in section 14 of the GPLv3 ), any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "restapiabstractjob.h" #include "rocketchatqtrestapi_debug.h" #include "abstractlogger.h" #include #include #include #include using namespace RocketChatRestApi; RestApiAbstractJob::RestApiAbstractJob(QObject *parent) : QObject(parent) { } QNetworkAccessManager *RestApiAbstractJob::networkAccessManager() const { return mNetworkAccessManager; } void RestApiAbstractJob::setNetworkAccessManager(QNetworkAccessManager *networkAccessManager) { mNetworkAccessManager = networkAccessManager; } RocketChatRestApi::RestApiMethod *RestApiAbstractJob::restApiMethod() const { return mRestApiMethod; } void RestApiAbstractJob::setRestApiMethod(RocketChatRestApi::RestApiMethod *restApiMethod) { mRestApiMethod = restApiMethod; } QString RestApiAbstractJob::authToken() const { return mAuthToken; } void RestApiAbstractJob::setAuthToken(const QString &authToken) { mAuthToken = authToken; } QString RestApiAbstractJob::userId() const { return mUserId; } void RestApiAbstractJob::setUserId(const QString &userId) { mUserId = userId; } bool RestApiAbstractJob::hasAuthenticationValue() const { return !mAuthToken.isEmpty() && !mUserId.isEmpty(); } bool RestApiAbstractJob::hasQueryParameterSupport() const { return false; } bool RestApiAbstractJob::canStart() const { if (!mNetworkAccessManager) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Network manager not defined"; return false; } if (!mRestApiMethod) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "RestaApiMethod not defined"; return false; } if (requireHttpAuthentication() && !hasAuthenticationValue()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "Auth settings is empty. It's a bug"; return false; } return true; } void RestApiAbstractJob::addRequestAttribute(QNetworkRequest &request) const { request.setAttribute(QNetworkRequest::HttpPipeliningAllowedAttribute, true); request.setAttribute(QNetworkRequest::HTTP2AllowedAttribute, true); request.setHeader(QNetworkRequest::ContentTypeHeader, QStringLiteral("application/json")); } void RestApiAbstractJob::addAuthRawHeader(QNetworkRequest &request) const { request.setRawHeader(QByteArrayLiteral("X-Auth-Token"), mAuthToken.toLocal8Bit()); request.setRawHeader(QByteArrayLiteral("X-User-Id"), mUserId.toLocal8Bit()); } QueryParameters RestApiAbstractJob::queryParameters() const { return mQueryParameters; } void RestApiAbstractJob::setQueryParameters(const QueryParameters &queryParameters) { mQueryParameters = queryParameters; } void RestApiAbstractJob::addQueryParameter(QUrlQuery &urlQuery) const { if (hasQueryParameterSupport() && mQueryParameters.isValid()) { if (mQueryParameters.count() >= 0) { urlQuery.addQueryItem(QStringLiteral("count"), QString::number(mQueryParameters.count())); } if (mQueryParameters.offset() >= 0) { urlQuery.addQueryItem(QStringLiteral("offset"), QString::number(mQueryParameters.offset())); } if (!mQueryParameters.sorting().isEmpty()) { //example sort={"name" : -1,"status" : 1} QMapIterator i(mQueryParameters.sorting()); QString str; while (i.hasNext()) { i.next(); if (!str.isEmpty()) { str += QLatin1Char(','); } str += QLatin1Char('"') + i.key() + QLatin1Char('"') + QLatin1Char(':'); switch (i.value()) { case QueryParameters::SortOrder::Ascendant: str += QString::number(1); break; case QueryParameters::SortOrder::Descendant: str += QString::number(-1); break; case QueryParameters::SortOrder::NoSorting: qCWarning(ROCKETCHATQTRESTAPI_LOG) << "It's not a sorting attribute"; break; } } str = QStringLiteral("{%1}").arg(str); //It's ok for getAllMentions.... urlQuery.addQueryItem(QStringLiteral("sort"), str); } } } RocketChatRestApi::AbstractLogger *RestApiAbstractJob::restApiLogger() const { return mRestApiLogger; } void RestApiAbstractJob::setRestApiLogger(RocketChatRestApi::AbstractLogger *ruqolaLogger) { mRestApiLogger = ruqolaLogger; } void RestApiAbstractJob::addLoggerInfo(const QByteArray &str) { if (mRestApiLogger) { mRestApiLogger->dataSent("RESTAPI: " + str); } else { qCDebug(ROCKETCHATQTRESTAPI_LOG) << "RESTAPI: " << str; } } void RestApiAbstractJob::addLoggerWarning(const QByteArray &str) { if (mRestApiLogger) { mRestApiLogger->dataSent("WARNING RESTAPI: " + str); } else { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "RESTAPI: " << str; } } void RestApiAbstractJob::emitFailedMessage(const QJsonObject &replyObject) { const QString errorType = replyObject[QStringLiteral("errorType")].toString(); if (!errorType.isEmpty()) { qCWarning(ROCKETCHATQTRESTAPI_LOG) << "errorType" << errorType; const QString trStr = errorMessage(errorType); if (!trStr.isEmpty()) { Q_EMIT failed(trStr); } else { qCWarning(ROCKETCHATQTRESTAPI_LOG) << " errorType not defined as translated message: " << errorType; Q_EMIT failed(i18n("Unauthorized")); } } else { const QString error = replyObject[QStringLiteral("error")].toString(); qCWarning(ROCKETCHATQTRESTAPI_LOG) << "error " << error; Q_EMIT failed(generateErrorMessage(error)); } } QString RestApiAbstractJob::generateErrorMessage(const QString &errorStr) { if (jobName().isEmpty()) { return errorStr; } return i18n("%1:%2", jobName(), errorStr); } QString RestApiAbstractJob::errorMessage(const QString &str) { if (str == QLatin1String("error-action-not-allowed")) { return i18n("__action__ is not allowed"); } else if (str == QLatin1String("error-application-not-found")) { return i18n("Application not found"); } else if (str == QLatin1String("error-archived-duplicate-name")) { return i18n("There's an archived channel with name '__room_name__'"); } else if (str == QLatin1String("error-avatar-invalid-url")) { return i18n("Invalid avatar URL: __url__"); } else if (str == QLatin1String("error-avatar-url-handling")) { return i18n("Error while handling avatar setting from a URL (__url__) for __username__"); } else if (str == QLatin1String("error-cant-invite-for-direct-room")) { return i18n("Can't invite user to direct rooms"); } else if (str == QLatin1String("error-channels-setdefault-is-same")) { return i18n("The channel default setting is the same as what it would be changed to."); } else if (str == QLatin1String("error-channels-setdefault-missing-default-param")) { return i18n("The bodyParam 'default' is required"); } else if (str == QLatin1String("error-could-not-change-email")) { return i18n("Could not change email"); } else if (str == QLatin1String("error-could-not-change-name")) { return i18n("Could not change name"); } else if (str == QLatin1String("error-could-not-change-username")) { return i18n("Could not change username"); } else if (str == QLatin1String("error-delete-protected-role")) { return i18n("Cannot delete a protected role"); } else if (str == QLatin1String("error-department-not-found")) { return i18n("Department not found"); } else if (str == QLatin1String("error-direct-message-file-upload-not-allowed")) { return i18n("File sharing not allowed in direct messages"); } else if (str == QLatin1String("error-duplicate-channel-name")) { return i18n("A channel with name '__channel_name__' exists"); } else if (str == QLatin1String("error-edit-permissions-not-allowed")) { return i18n("Editing permissions is not allowed"); } else if (str == QLatin1String("error-email-domain-blacklisted")) { return i18n("The email domain is blacklisted"); } else if (str == QLatin1String("error-email-send-failed")) { return i18n("Error trying to send email: __message__"); } else if (str == QLatin1String("error-field-unavailable")) { return i18n("__field__ is already in use :("); } else if (str == QLatin1String("error-file-too-large")) { return i18n("File is too large"); } else if (str == QLatin1String("error-importer-not-defined")) { return i18n("The importer was not defined correctly, it is missing the Import class."); } else if (str == QLatin1String("error-import-file-extract-error")) { return i18n("Failed to extract import file."); } else if (str == QLatin1String("error-import-file-is-empty")) { return i18n("Imported file seems to be empty."); } else if (str == QLatin1String("error-import-file-missing")) { return i18n("The file to be imported was not found on the specified path."); } else if (str == QLatin1String("error-input-is-not-a-valid-field")) { return i18n("__input__ is not a valid __field__"); } else if (str == QLatin1String("error-invalid-actionlink")) { return i18n("Invalid action link"); } else if (str == QLatin1String("error-invalid-account")) { return i18n("Invalid Account"); } else if (str == QLatin1String("error-invalid-arguments")) { return i18n("Invalid arguments"); } else if (str == QLatin1String("error-invalid-asset")) { return i18n("Invalid asset"); } else if (str == QLatin1String("error-invalid-channel")) { return i18n("Invalid channel."); } else if (str == QLatin1String("error-invalid-channel-start-with-chars")) { return i18n("Invalid channel. Start with @ or #"); } else if (str == QLatin1String("error-invalid-custom-field")) { return i18n("Invalid custom field"); } else if (str == QLatin1String("error-invalid-custom-field-name")) { return i18n("Invalid custom field name. Use only letters, numbers, hyphens and underscores."); } else if (str == QLatin1String("error-invalid-date")) { return i18n("Invalid date provided."); } else if (str == QLatin1String("error-invalid-description")) { return i18n("Invalid description"); } else if (str == QLatin1String("error-invalid-domain")) { return i18n("Invalid domain"); } else if (str == QLatin1String("error-invalid-email")) { return i18n("Invalid email __email__"); } else if (str == QLatin1String("error-invalid-email-address")) { return i18n("Invalid email address"); } else if (str == QLatin1String("error-invalid-file-height")) { return i18n("Invalid file height"); } else if (str == QLatin1String("error-invalid-file-type")) { return i18n("Invalid file type"); } else if (str == QLatin1String("error-invalid-file-width")) { return i18n("Invalid file width"); } else if (str == QLatin1String("error-invalid-from-address")) { return i18n("You informed an invalid FROM address."); } else if (str == QLatin1String("error-invalid-integration")) { return i18n("Invalid integration"); } else if (str == QLatin1String("error-invalid-message")) { return i18n("Invalid message"); } else if (str == QLatin1String("error-invalid-method")) { return i18n("Invalid method"); } else if (str == QLatin1String("error-invalid-name")) { return i18n("Invalid name"); } else if (str == QLatin1String("error-invalid-password")) { return i18n("Invalid password"); } else if (str == QLatin1String("error-invalid-permission")) { return i18n("Invalid permission"); } else if (str == QLatin1String("error-invalid-redirectUri")) { return i18n("Invalid redirectUri"); } else if (str == QLatin1String("error-invalid-role")) { return i18n("Invalid role"); } else if (str == QLatin1String("error-invalid-room")) { return i18n("Invalid room"); } else if (str == QLatin1String("error-invalid-room-name")) { return i18n("__room_name__ is not a valid room name"); } else if (str == QLatin1String("error-invalid-room-type")) { return i18n("__type__ is not a valid room type."); } else if (str == QLatin1String("error-invalid-settings")) { return i18n("Invalid settings provided"); } else if (str == QLatin1String("error-invalid-subscription")) { return i18n("Invalid subscription"); } else if (str == QLatin1String("error-invalid-token")) { return i18n("Invalid token"); } else if (str == QLatin1String("error-invalid-triggerWords")) { return i18n("Invalid triggerWords"); } else if (str == QLatin1String("error-invalid-urls")) { return i18n("Invalid URLs"); } else if (str == QLatin1String("error-invalid-user")) { return i18n("Invalid user"); } else if (str == QLatin1String("error-invalid-username")) { return i18n("Invalid username"); } else if (str == QLatin1String("error-invalid-webhook-response")) { return i18n("The webhook URL responded with a status other than 200"); } else if (str == QLatin1String("error-message-deleting-blocked")) { return i18n("Message deleting is blocked"); } else if (str == QLatin1String("error-message-editing-blocked")) { return i18n("Message editing is blocked"); } else if (str == QLatin1String("error-message-size-exceeded")) { return i18n("Message size exceeds Message_MaxAllowedSize"); } else if (str == QLatin1String("error-missing-unsubscribe-link")) { return i18n("You must provide the [unsubscribe] link."); } else if (str == QLatin1String("error-no-tokens-for-this-user")) { return i18n("There are no tokens for this user"); } else if (str == QLatin1String("error-not-allowed")) { return i18n("Not allowed"); } else if (str == QLatin1String("error-not-authorized")) { return i18n("Not authorized"); } else if (str == QLatin1String("error-password-policy-not-met")) { return i18n("Password does not meet the server's policy"); } else if (str == QLatin1String("error-password-policy-not-met-maxLength")) { return i18n("Password does not meet the server's policy of maximum length (password too long)"); } else if (str == QLatin1String("error-password-policy-not-met-minLength")) { return i18n("Password does not meet the server's policy of minimum length (password too short)"); } else if (str == QLatin1String("error-password-policy-not-met-oneLowercase")) { return i18n("Password does not meet the server's policy of at least one lowercase character"); } else if (str == QLatin1String("error-password-policy-not-met-oneNumber")) { return i18n("Password does not meet the server's policy of at least one numerical character"); } else if (str == QLatin1String("error-password-policy-not-met-oneSpecial")) { return i18n("Password does not meet the server's policy of at least one special character"); } else if (str == QLatin1String("error-password-policy-not-met-oneUppercase")) { return i18n("Password does not meet the server's policy of at least one uppercase character"); } else if (str == QLatin1String("error-password-policy-not-met-repeatingCharacters")) { - return i18n("Password not not meet the server's policy of forbidden repeating characters (you have too many of the same characters next to each other)"); + return i18n("Password does not meet the server's policy of forbidden repeating characters (you have too many of the same characters next to each other)"); } else if (str == QLatin1String("error-push-disabled")) { return i18n("Push is disabled"); } else if (str == QLatin1String("error-remove-last-owner")) { return i18n("This is the last owner. Please set a new owner before removing this one."); } else if (str == QLatin1String("error-role-in-use")) { return i18n("Cannot delete role because it's in use"); } else if (str == QLatin1String("error-role-name-required")) { return i18n("Role name is required"); } else if (str == QLatin1String("error-room-is-not-closed")) { return i18n("Room is not closed"); } else if (str == QLatin1String("error-the-field-is-required")) { return i18n("The field __field__ is required."); } else if (str == QLatin1String("error-this-is-not-a-livechat-room")) { return i18n("This is not a Livechat room"); } else if (str == QLatin1String("error-personal-access-tokens-are-current-disabled")) { return i18n("Personal Access Tokens are currently disabled"); } else if (str == QLatin1String("error-token-already-exists")) { return i18n("A token with this name already exists"); } else if (str == QLatin1String("error-token-does-not-exists")) { return i18n("Token does not exists"); } else if (str == QLatin1String("error-too-many-requests")) { return i18n("Error, too many requests. Please slow down. You must wait __seconds__ seconds before trying again."); } else if (str == QLatin1String("error-user-has-no-roles")) { return i18n("User has no roles"); } else if (str == QLatin1String("error-user-is-not-activated")) { return i18n("User is not activated"); } else if (str == QLatin1String("error-user-limit-exceeded")) { return i18n("The number of users you are trying to invite to #channel_name exceeds the limit set by the administrator"); } else if (str == QLatin1String("error-user-not-in-room")) { return i18n("User is not in this room"); } else if (str == QLatin1String("error-logged-user-not-in-room")) { return i18n("You are not in the room `%s`"); } else if (str == QLatin1String("error-user-registration-disabled")) { return i18n("User registration is disabled"); } else if (str == QLatin1String("error-user-registration-secret")) { return i18n("User registration is only allowed via Secret URL"); } else if (str == QLatin1String("error-you-are-last-owner")) { return i18n("You are the last owner. Please set new owner before leaving the room."); } else { qCWarning(ROCKETCHATQTRESTAPI_LOG) << " unknown error type " << str; return {}; } } QString RestApiAbstractJob::jobName() const { return {}; } QueryParameters::QueryParameters() { } int QueryParameters::offset() const { return mOffset; } void QueryParameters::setOffset(int offset) { mOffset = offset; } int QueryParameters::count() const { return mCount; } void QueryParameters::setCount(int count) { mCount = count; } bool QueryParameters::isValid() const { return (mCount >= 0) || (mOffset >= 0) || (!mSorting.isEmpty()); } QMap QueryParameters::sorting() const { return mSorting; } void QueryParameters::setSorting(const QMap &sorting) { mSorting = sorting; } diff --git a/src/ruqolacore/messagequeue.h b/src/ruqolacore/messagequeue.h index 185d364d..24b4c974 100644 --- a/src/ruqolacore/messagequeue.h +++ b/src/ruqolacore/messagequeue.h @@ -1,64 +1,64 @@ /* * 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 MESSAGEQUEUE_H #define MESSAGEQUEUE_H #include class RocketChatAccount; class MessageQueue : public QObject { Q_OBJECT public: explicit MessageQueue(RocketChatAccount *account, QObject *parent = nullptr); ~MessageQueue(); /** - * @brief Retry to send unsent messages in DDPClient's abtract message queue + * @brief Retry to send unsent messages in DDPClient's abstract message queue */ void processQueue(); /** * @brief Constructs QPair object from QJsonObject * * @param object The Json containing message attributes * @return QPair, The pair containing the method and params */ Q_REQUIRED_RESULT static QPair fromJson(const QJsonObject &object); /** * @brief Constructs QBytearray from QPair object * * @param pair The pair containing method and params * @return QByteArray, The Json containing message attributes */ Q_REQUIRED_RESULT static QByteArray serialize(const QPair &pair); void loadCache(); private: Q_DISABLE_COPY(MessageQueue) void onLoginStatusChanged(); RocketChatAccount *mRocketChatAccount = nullptr; }; #endif // MESSAGEQUEUE_H diff --git a/src/ruqolacore/messages/message.h b/src/ruqolacore/messages/message.h index dad3fd30..eb5e66de 100644 --- a/src/ruqolacore/messages/message.h +++ b/src/ruqolacore/messages/message.h @@ -1,228 +1,228 @@ /* Copyright (c) 2017-2019 Montel Laurent This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License or ( at your option ) version 3 or, at the discretion of KDE e.V. ( which shall act as a proxy as in section 14 of the GPLv3 ), any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef MESSAGE_H #define MESSAGE_H #include "libruqola_private_export.h" #include "messageattachment.h" #include "messageurl.h" #include "messagepinned.h" #include "messagestarred.h" #include "reactions.h" #include #include #include class LIBRUQOLACORE_TESTS_EXPORT Message { Q_GADGET public: Message(); enum MessageType { System, NormalText, File, Video, Audio, Image }; Q_ENUM(MessageType) Q_REQUIRED_RESULT QString roomId() const; void setRoomId(const QString &roomId); Q_REQUIRED_RESULT bool groupable() const; void setGroupable(bool groupable); Q_REQUIRED_RESULT bool parseUrls() const; void setParseUrls(bool parseUrls); Q_REQUIRED_RESULT QString avatar() const; void setAvatar(const QString &avatar); /** * @brief Constructs Message object from QJsonObject * * @param source The Json containing message attributes * @return Message object, The message constructed from Json */ Q_REQUIRED_RESULT static Message fromJSon(const QJsonObject &source); /** * @brief Constructs QBytearray from Message object * * @param message The Message object * @return QByteArray, The Json containing message attributes */ Q_REQUIRED_RESULT static QByteArray serialize(const Message &message, bool toBinary = true); void parseMessage(const QJsonObject &o, bool restApi = false); Q_REQUIRED_RESULT bool operator==(const Message &other) const; Message &operator=(const Message &other); // To be used in sorted insert: timestamp bool operator<(const Message &other) const; Q_REQUIRED_RESULT QString messageId() const; void setMessageId(const QString &messageId); Q_REQUIRED_RESULT QString text() const; void setText(const QString &text); Q_REQUIRED_RESULT qint64 timeStamp() const; void setTimeStamp(const qint64 &timeStamp); Q_REQUIRED_RESULT QString username() const; void setUsername(const QString &username); Q_REQUIRED_RESULT QString userId() const; void setUserId(const QString &userId); Q_REQUIRED_RESULT qint64 updatedAt() const; void setUpdatedAt(const qint64 &updatedAt); Q_REQUIRED_RESULT qint64 editedAt() const; void setEditedAt(const qint64 &editedAt); Q_REQUIRED_RESULT QString editedByUsername() const; void setEditedByUsername(const QString &editedByUsername); Q_REQUIRED_RESULT QString editedByUserId() const; void setEditedByUserId(const QString &editedByUserId); Q_REQUIRED_RESULT QString imageUrl() const; void setImageUrl(const QString &imageUrl); Q_REQUIRED_RESULT QString alias() const; void setAlias(const QString &alias); Q_REQUIRED_RESULT QString systemMessageType() const; void setSystemMessageType(const QString &systemMessageType); Q_REQUIRED_RESULT MessageType messageType() const; void setMessageType(const MessageType &messageType); Q_REQUIRED_RESULT QVector attachements() const; void setAttachements(const QVector &attachements); Q_REQUIRED_RESULT QVector urls() const; void setUrls(const QVector &urls); Q_REQUIRED_RESULT QMap mentions() const; void setMentions(const QMap &mentions); Q_REQUIRED_RESULT bool starred() const; void setStarred(bool starred); Q_REQUIRED_RESULT Reactions reactions() const; void setReactions(const Reactions &reactions); Q_REQUIRED_RESULT QString messageTypeText() const; Q_REQUIRED_RESULT QString role() const; void setRole(const QString &role); Q_REQUIRED_RESULT bool unread() const; - void setUnread(bool uread); + void setUnread(bool unread); Q_REQUIRED_RESULT MessagePinned messagePinned() const; void setMessagePinned(const MessagePinned &messagePinned); Q_REQUIRED_RESULT MessageStarred messageStarred() const; void setMessageStarred(const MessageStarred &messageStarred); private: void parseMentions(const QJsonArray &mentions); void parseAttachment(const QJsonArray &attachments); void parseUrls(const QJsonArray &urls); void parseReactions(const QJsonObject &mentions); //Message Pinned MessagePinned mMessagePinned; //Message Starred MessageStarred mMessageStarred; //Message Object Fields QVector mAttachements; //Message urls object QVector mUrls; //Reactions Reactions mReactions; //Mentions QMap mMentions; //role used when we add/remove role. It will displaying in messagesystem QString mRole; // _id QString mMessageId; // msg QString mText; // u QString mUsername; QString mUserId; // editedBy QString mEditedByUsername; QString mEditedByUserId; // alias QString mAlias; QString mSystemMessageType; // rid QString mRoomId; // avatar QString mAvatar; // ts qint64 mTimeStamp = -1; // _updatedAt qint64 mUpdatedAt = -1; // editedAt qint64 mEditedAt = -1; MessageType mMessageType = MessageType::NormalText; // groupable bool mGroupable = false; // parseUrls bool mParseUrls = false; //Unread Message bool mUnread = false; }; Q_DECLARE_METATYPE(Message) LIBRUQOLACORE_EXPORT QDebug operator <<(QDebug d, const Message &t); #endif // MESSAGE_H diff --git a/src/ruqolacore/utils.cpp b/src/ruqolacore/utils.cpp index dd0ea74d..fb6ba0d1 100644 --- a/src/ruqolacore/utils.cpp +++ b/src/ruqolacore/utils.cpp @@ -1,161 +1,161 @@ /* Copyright (c) 2017-2019 Montel Laurent This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License or ( at your option ) version 3 or, at the discretion of KDE e.V. ( which shall act as a proxy as in section 14 of the GPLv3 ), any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "utils.h" #include "ruqola_debug.h" #include #include #include #include #include QUrl Utils::generateServerUrl(const QString &url) { if (url.isEmpty()) { return {}; } QString serverUrl = url; if (serverUrl.startsWith(QLatin1String("https://"))) { serverUrl.replace(QLatin1String("https://"), QLatin1String("wss://")); } else if (serverUrl.startsWith(QLatin1String("http://"))) { serverUrl.replace(QLatin1String("http://"), QLatin1String("ws://")); } else { serverUrl = QStringLiteral("wss://") + serverUrl; } return QUrl(serverUrl + QStringLiteral("/websocket")); } QString Utils::extractRoomUserFromUrl(QString url) { url.remove(QStringLiteral("ruqola:/user/")); url.remove(QStringLiteral("ruqola:/room/")); return url; } QString Utils::markdownToRichText(const QString &markDown) { //qCDebug(RUQOLA_LOG) << "BEFORE markdownToRichText "< need to investigate //str.remove(QStringLiteral("
")); //qCDebug(RUQOLA_LOG) << "markdownToRichText "< &mentions, const QString &username) { //Not using mentions for the moment. Q_UNUSED(mentions) QString newStr = Utils::markdownToRichText(str); static const QRegularExpression regularExpressionUser(QStringLiteral("(^|\\s+)@([\\w._-]+)")); QRegularExpressionMatchIterator userIterator = regularExpressionUser.globalMatch(newStr); while (userIterator.hasNext()) { const QRegularExpressionMatch match = userIterator.next(); const QString word = match.captured(2); //Highlight only if it's yours if (word == username) { //Improve color newStr.replace(QLatin1Char('@') + word, QStringLiteral("@%1").arg(word)); } else { newStr.replace(QLatin1Char('@') + word, QStringLiteral("@%1").arg(word)); } } static const QRegularExpression regularExpressionRoom(QStringLiteral("(^|\\s+)#([\\w._-]+)")); QRegularExpressionMatchIterator roomIterator = regularExpressionRoom.globalMatch(newStr); while (roomIterator.hasNext()) { const QRegularExpressionMatch match = roomIterator.next(); const QString word = match.captured(2); newStr.replace(QLatin1Char('#') + word, QStringLiteral("#%1").arg(word)); } return newStr; } QString Utils::presenceStatusToString(User::PresenceStatus status) { switch (status) { case User::PresenceStatus::PresenceOnline: return QStringLiteral("online"); case User::PresenceStatus::PresenceBusy: return QStringLiteral("busy"); case User::PresenceStatus::PresenceAway: return QStringLiteral("away"); case User::PresenceStatus::PresenceOffline: return QStringLiteral("offline"); case User::PresenceStatus::Unknown: return {}; } Q_UNREACHABLE(); return {}; } User::PresenceStatus Utils::presenceStatusFromString(const QString &status) { if (status == QStringLiteral("online")) { return User::PresenceStatus::PresenceOnline; } else if (status == QStringLiteral("busy")) { return User::PresenceStatus::PresenceBusy; } else if (status == QStringLiteral("away")) { return User::PresenceStatus::PresenceAway; } else if (status == QStringLiteral("offline")) { return User::PresenceStatus::PresenceOffline; } else { qCDebug(RUQOLA_LOG) << "Problem with status " << status; return User::PresenceStatus::Unknown; } } void Utils::parseNotification(const QJsonArray &contents, QString &message, QString &title, QString &sender) { QJsonObject obj = contents.at(0).toObject(); message = obj[QStringLiteral("text")].toString(); title = obj[QStringLiteral("title")].toString(); obj = obj.value(QLatin1String("payload")).toObject(); if (!obj.isEmpty()) { obj = obj.value(QLatin1String("sender")).toObject(); if (!obj.isEmpty()) { sender = obj.value(QLatin1String("_id")).toString(); } else { - qCDebug(RUQOLA_LOG) << "Problem with notication json: missing sender"; + qCDebug(RUQOLA_LOG) << "Problem with notification json: missing sender"; } } else { - qCDebug(RUQOLA_LOG) << "Problem with notication json: missing payload"; + qCDebug(RUQOLA_LOG) << "Problem with notification json: missing payload"; } } QString Utils::userIdFromDirectChannel(const QString &rid, const QString &userId) { QString newUserId = rid; newUserId.remove(userId); return newUserId; } qint64 Utils::parseDate(const QString &key, const QJsonObject &o) { return o.value(key).toObject().value(QLatin1String("$date")).toDouble(-1); } qint64 Utils::parseIsoDate(const QString &key, const QJsonObject &o) { return QDateTime::fromString(o.value(key).toString(), Qt::ISODate).toMSecsSinceEpoch(); }