Compare commits
2 Commits
work/nvrwh
...
work/carl/
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fab2a81aee | ||
|
|
4daff26747 |
@@ -2,7 +2,5 @@
|
||||
; SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
[BlueprintSettings]
|
||||
kde/unreleased/kirigami-addons.version=master
|
||||
|
||||
kde/applications/neochat.packageAppx=True
|
||||
libs/qt.qtMajorVersion=6
|
||||
|
||||
@@ -40,4 +40,4 @@ Dependencies:
|
||||
|
||||
Options:
|
||||
per-test-timeout: 90
|
||||
require-passing-tests-on: [ 'Linux', 'Android', 'FreeBSD', 'Windows' ]
|
||||
require-passing-tests-on: [ 'Linux', 'Android', 'FreeBSD' ]
|
||||
|
||||
@@ -12,7 +12,7 @@ buildscript {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:8.6.0'
|
||||
classpath 'com.android.tools.build:gradle:7.4.1'
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,13 +11,11 @@ ecm_add_test(
|
||||
TEST_NAME neochatroomtest
|
||||
)
|
||||
|
||||
if (NOT $ENV{KDE_CI})
|
||||
ecm_add_test(
|
||||
texthandlertest.cpp
|
||||
LINK_LIBRARIES neochat Qt::Test
|
||||
TEST_NAME texthandlertest
|
||||
)
|
||||
endif()
|
||||
ecm_add_test(
|
||||
texthandlertest.cpp
|
||||
LINK_LIBRARIES neochat Qt::Test
|
||||
TEST_NAME texthandlertest
|
||||
)
|
||||
|
||||
ecm_add_test(
|
||||
delegatesizehelpertest.cpp
|
||||
@@ -50,9 +48,9 @@ ecm_add_test(
|
||||
)
|
||||
|
||||
ecm_add_test(
|
||||
timelinemessagemodeltest.cpp
|
||||
messageeventmodeltest.cpp
|
||||
LINK_LIBRARIES neochat Qt::Test
|
||||
TEST_NAME timelinemessagemodeltest
|
||||
TEST_NAME messageeventmodeltest
|
||||
)
|
||||
|
||||
ecm_add_test(
|
||||
@@ -84,9 +82,3 @@ ecm_add_test(
|
||||
LINK_LIBRARIES neochat Qt::Test
|
||||
TEST_NAME messagecontentmodeltest
|
||||
)
|
||||
|
||||
ecm_add_test(
|
||||
actionstest.cpp
|
||||
LINK_LIBRARIES neochat Qt::Test
|
||||
TEST_NAME actionstest
|
||||
)
|
||||
|
||||
@@ -1,120 +0,0 @@
|
||||
// SPDX-FileCopyrightText: 2024 Tobias Fella <tobias.fella@kde.org>
|
||||
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||
|
||||
#include <QObject>
|
||||
#include <QTest>
|
||||
#include <QSignalSpy>
|
||||
#include <QVariantList>
|
||||
|
||||
#include "chatbarcache.h"
|
||||
#include "models/actionsmodel.h"
|
||||
|
||||
#include "testutils.h"
|
||||
|
||||
using namespace Quotient;
|
||||
|
||||
//TODO: rainbow, rainbowme, plain, spoiler, me, join, knock, j, part, leave, nick, roomnick, myroomnick, ignore, unignore, react, ban, unban, kick
|
||||
|
||||
class ActionsTest : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
Connection *connection = nullptr;
|
||||
TestUtils::TestRoom *room = nullptr;
|
||||
|
||||
void expectMessage(const QString &actionName, const QString &args, MessageType::Type type, const QString &message);
|
||||
|
||||
private Q_SLOTS:
|
||||
void initTestCase();
|
||||
void testActions();
|
||||
void testActions_data();
|
||||
void testInvite();
|
||||
};
|
||||
|
||||
void ActionsTest::initTestCase()
|
||||
{
|
||||
connection = Connection::makeMockConnection(QStringLiteral("@bob:kde.org"));
|
||||
room = new TestUtils::TestRoom(connection, QStringLiteral("#myroom:kde.org"), QLatin1String("test-min-sync.json"));
|
||||
}
|
||||
|
||||
void ActionsTest::testActions_data()
|
||||
{
|
||||
QTest::addColumn<QString>("command");
|
||||
QTest::addColumn<std::optional<QString>>("resultText");
|
||||
QTest::addColumn<std::optional<Quotient::RoomMessageEvent::MsgType>>("type");
|
||||
|
||||
QTest::newRow("shrug") << u"/shrug Hello"_s << std::make_optional(u"¯\\\\_(ツ)_/¯ Hello"_s)
|
||||
<< std::make_optional(Quotient::RoomMessageEvent::MsgType::Text);
|
||||
QTest::newRow("lenny") << u"/lenny Hello"_s << std::make_optional(u"( ͡° ͜ʖ ͡°) Hello"_s) << std::make_optional(Quotient::RoomMessageEvent::MsgType::Text);
|
||||
QTest::newRow("tableflip") << u"/tableflip Hello"_s << std::make_optional(u"(╯°□°)╯︵ ┻━┻ Hello"_s)
|
||||
<< std::make_optional(Quotient::RoomMessageEvent::MsgType::Text);
|
||||
QTest::newRow("unflip") << u"/unflip Hello"_s << std::make_optional(u"┬──┬ ノ( ゜-゜ノ) Hello"_s)
|
||||
<< std::make_optional(Quotient::RoomMessageEvent::MsgType::Text);
|
||||
QTest::newRow("rainbow") << u"/rainbow Hello"_s << std::optional<QString>() << std::optional<Quotient::RoomMessageEvent::MsgType>();
|
||||
QTest::newRow("rainbowme") << u"/rainbowme Hello"_s << std::optional<QString>() << std::optional<Quotient::RoomMessageEvent::MsgType>();
|
||||
QTest::newRow("plain") << u"/plain <b>Hello</b>"_s << std::optional<QString>() << std::optional<Quotient::RoomMessageEvent::MsgType>();
|
||||
QTest::newRow("spoiler") << u"/spoiler Hello"_s << std::optional<QString>() << std::optional<Quotient::RoomMessageEvent::MsgType>();
|
||||
QTest::newRow("me") << u"/me Hello"_s << std::make_optional(u"Hello"_s) << std::make_optional(Quotient::RoomMessageEvent::MsgType::Emote);
|
||||
QTest::newRow("notice") << u"/notice Hello"_s << std::make_optional(u"Hello"_s) << std::make_optional(Quotient::RoomMessageEvent::MsgType::Notice);
|
||||
QTest::newRow("message") << u"Hello"_s << std::make_optional(u"Hello"_s) << std::make_optional(Quotient::RoomMessageEvent::MsgType::Text);
|
||||
QTest::newRow("invite") << u"/invite @foo:example.com"_s << std::optional<QString>() << std::optional<Quotient::RoomMessageEvent::MsgType>();
|
||||
|
||||
//TODO: join, knock, j, part, leave, nick, roomnick, myroomnick, ignore, unignore, react, ban, unban, kick
|
||||
}
|
||||
|
||||
void ActionsTest::testActions()
|
||||
{
|
||||
QFETCH(QString, command);
|
||||
QFETCH(std::optional<QString>, resultText);
|
||||
QFETCH(std::optional<Quotient::RoomMessageEvent::MsgType>, type);
|
||||
|
||||
auto cache = new ChatBarCache();
|
||||
cache->setText(command);
|
||||
auto result = ActionsModel::handleAction(room, cache);
|
||||
QCOMPARE(resultText, std::get<std::optional<QString>>(result));
|
||||
QCOMPARE(type, std::get<std::optional<Quotient::RoomMessageEvent::MsgType>>(result));
|
||||
}
|
||||
|
||||
static ActionsModel::Action findAction(const QString &name)
|
||||
{
|
||||
for (const auto &action : ActionsModel::allActions()) {
|
||||
if (action.prefix == name) {
|
||||
return action;
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
void ActionsTest::expectMessage(const QString &actionName, const QString &args, MessageType::Type type, const QString &message)
|
||||
{
|
||||
auto action = findAction(actionName);
|
||||
QSignalSpy spy(room, &TestUtils::TestRoom::showMessage);
|
||||
auto result = action.handle(args, room, nullptr);
|
||||
auto expected = QVariantList {type, message};
|
||||
auto signal = spy.takeFirst();
|
||||
QCOMPARE(signal, expected);
|
||||
}
|
||||
|
||||
void ActionsTest::testInvite()
|
||||
{
|
||||
expectMessage(u"invite"_s, u"foo"_s, MessageType::Error, u"'foo' does not look like a matrix id."_s);
|
||||
expectMessage(u"invite"_s, u"@invited:example.com"_s, MessageType::Information, u"@invited:example.com is already invited to this room."_s);
|
||||
QCOMPARE(room->memberState(u"@invited:example.com"_s), Membership::Invite);
|
||||
expectMessage(u"invite"_s, u"@banned:example.com"_s, MessageType::Information, u"@banned:example.com is banned from this room."_s);
|
||||
QCOMPARE(room->memberState(u"@banned:example.com"_s), Membership::Ban);
|
||||
expectMessage(u"invite"_s, connection->userId(), MessageType::Positive, u"You are already in this room."_s);
|
||||
QCOMPARE(room->memberState(connection->userId()), Membership::Join);
|
||||
expectMessage(u"invite"_s, u"@example:example.org"_s, MessageType::Information, u"@example:example.org is already in this room."_s);
|
||||
QCOMPARE(room->memberState(u"@example:example.org"_s), Membership::Join);
|
||||
|
||||
QCOMPARE(room->memberState(u"@user:example.com"_s), Membership::Leave);
|
||||
expectMessage(u"invite"_s, u"@user:example.com"_s, MessageType::Positive, u"@user:example.com was invited into this room."_s);
|
||||
|
||||
//TODO mock server, wait for invite state to change
|
||||
//TODO QCOMPARE(room->memberState(u"@user:example.com"_s), Membership::Invite);
|
||||
}
|
||||
|
||||
QTEST_MAIN(ActionsTest)
|
||||
#include "actionstest.moc"
|
||||
@@ -38,8 +38,8 @@ private Q_SLOTS:
|
||||
|
||||
void ChatBarCacheTest::initTestCase()
|
||||
{
|
||||
connection = Connection::makeMockConnection(u"@bob:kde.org"_s);
|
||||
room = new TestUtils::TestRoom(connection, u"#myroom:kde.org"_s, "test-min-sync.json"_L1);
|
||||
connection = Connection::makeMockConnection(QStringLiteral("@bob:kde.org"));
|
||||
room = new TestUtils::TestRoom(connection, QStringLiteral("#myroom:kde.org"), QLatin1String("test-min-sync.json"));
|
||||
}
|
||||
|
||||
void ChatBarCacheTest::empty()
|
||||
@@ -59,7 +59,7 @@ void ChatBarCacheTest::empty()
|
||||
void ChatBarCacheTest::noRoom()
|
||||
{
|
||||
QScopedPointer<ChatBarCache> chatBarCache(new ChatBarCache());
|
||||
chatBarCache->setReplyId(u"$153456789:example.org"_s);
|
||||
chatBarCache->setReplyId(QLatin1String("$153456789:example.org"));
|
||||
|
||||
// These should return empty even though a reply ID has been set because the
|
||||
// ChatBarCache has no parent.
|
||||
@@ -75,7 +75,7 @@ void ChatBarCacheTest::badParent()
|
||||
{
|
||||
QScopedPointer<QObject> badParent(new QObject());
|
||||
QScopedPointer<ChatBarCache> chatBarCache(new ChatBarCache(badParent.get()));
|
||||
chatBarCache->setReplyId(u"$153456789:example.org"_s);
|
||||
chatBarCache->setReplyId(QLatin1String("$153456789:example.org"));
|
||||
|
||||
// These should return empty even though a reply ID has been set because the
|
||||
// ChatBarCache has no parent.
|
||||
@@ -90,17 +90,17 @@ void ChatBarCacheTest::badParent()
|
||||
void ChatBarCacheTest::reply()
|
||||
{
|
||||
QScopedPointer<ChatBarCache> chatBarCache(new ChatBarCache(room));
|
||||
chatBarCache->setText(u"some text"_s);
|
||||
chatBarCache->setAttachmentPath(u"some/path"_s);
|
||||
chatBarCache->setReplyId(u"$153456789:example.org"_s);
|
||||
chatBarCache->setText(QLatin1String("some text"));
|
||||
chatBarCache->setAttachmentPath(QLatin1String("some/path"));
|
||||
chatBarCache->setReplyId(QLatin1String("$153456789:example.org"));
|
||||
|
||||
QCOMPARE(chatBarCache->text(), u"some text"_s);
|
||||
QCOMPARE(chatBarCache->text(), QLatin1String("some text"));
|
||||
QCOMPARE(chatBarCache->isReplying(), true);
|
||||
QCOMPARE(chatBarCache->replyId(), u"$153456789:example.org"_s);
|
||||
QCOMPARE(chatBarCache->replyId(), QLatin1String("$153456789:example.org"));
|
||||
QCOMPARE(chatBarCache->isEditing(), false);
|
||||
QCOMPARE(chatBarCache->editId(), QString());
|
||||
QCOMPARE(chatBarCache->relationAuthor(), room->member(u"@example:example.org"_s));
|
||||
QCOMPARE(chatBarCache->relationMessage(), u"This is an example\ntext message"_s);
|
||||
QCOMPARE(chatBarCache->relationAuthor(), room->member(QLatin1String("@example:example.org")));
|
||||
QCOMPARE(chatBarCache->relationMessage(), QLatin1String("This is an example\ntext message"));
|
||||
QCOMPARE(chatBarCache->attachmentPath(), QString());
|
||||
}
|
||||
|
||||
@@ -108,39 +108,39 @@ void ChatBarCacheTest::edit()
|
||||
{
|
||||
QScopedPointer<ChatBarCache> chatBarCache(new ChatBarCache(room));
|
||||
|
||||
chatBarCache->setText(u"some text"_s);
|
||||
chatBarCache->setAttachmentPath(u"some/path"_s);
|
||||
chatBarCache->setText(QLatin1String("some text"));
|
||||
chatBarCache->setAttachmentPath(QLatin1String("some/path"));
|
||||
connect(chatBarCache.get(), &ChatBarCache::relationIdChanged, this, [](const QString &oldEventId, const QString &newEventId) {
|
||||
QCOMPARE(oldEventId, QString());
|
||||
QCOMPARE(newEventId, QString(u"$153456789:example.org"_s));
|
||||
QCOMPARE(newEventId, QString(QLatin1String("$153456789:example.org")));
|
||||
});
|
||||
chatBarCache->setEditId(u"$153456789:example.org"_s);
|
||||
chatBarCache->setEditId(QLatin1String("$153456789:example.org"));
|
||||
|
||||
QCOMPARE(chatBarCache->text(), u"some text"_s);
|
||||
QCOMPARE(chatBarCache->text(), QLatin1String("some text"));
|
||||
QCOMPARE(chatBarCache->isReplying(), false);
|
||||
QCOMPARE(chatBarCache->replyId(), QString());
|
||||
QCOMPARE(chatBarCache->isEditing(), true);
|
||||
QCOMPARE(chatBarCache->editId(), u"$153456789:example.org"_s);
|
||||
QCOMPARE(chatBarCache->relationAuthor(), room->member(u"@example:example.org"_s));
|
||||
QCOMPARE(chatBarCache->relationMessage(), u"This is an example\ntext message"_s);
|
||||
QCOMPARE(chatBarCache->editId(), QLatin1String("$153456789:example.org"));
|
||||
QCOMPARE(chatBarCache->relationAuthor(), room->member(QLatin1String("@example:example.org")));
|
||||
QCOMPARE(chatBarCache->relationMessage(), QLatin1String("This is an example\ntext message"));
|
||||
QCOMPARE(chatBarCache->attachmentPath(), QString());
|
||||
}
|
||||
|
||||
void ChatBarCacheTest::attachment()
|
||||
{
|
||||
QScopedPointer<ChatBarCache> chatBarCache(new ChatBarCache(room));
|
||||
chatBarCache->setText(u"some text"_s);
|
||||
chatBarCache->setEditId(u"$153456789:example.org"_s);
|
||||
chatBarCache->setAttachmentPath(u"some/path"_s);
|
||||
chatBarCache->setText(QLatin1String("some text"));
|
||||
chatBarCache->setEditId(QLatin1String("$153456789:example.org"));
|
||||
chatBarCache->setAttachmentPath(QLatin1String("some/path"));
|
||||
|
||||
QCOMPARE(chatBarCache->text(), u"some text"_s);
|
||||
QCOMPARE(chatBarCache->text(), QLatin1String("some text"));
|
||||
QCOMPARE(chatBarCache->isReplying(), false);
|
||||
QCOMPARE(chatBarCache->replyId(), QString());
|
||||
QCOMPARE(chatBarCache->isEditing(), false);
|
||||
QCOMPARE(chatBarCache->editId(), QString());
|
||||
QCOMPARE(chatBarCache->relationAuthor(), room->member(QString()));
|
||||
QCOMPARE(chatBarCache->relationMessage(), QString());
|
||||
QCOMPARE(chatBarCache->attachmentPath(), u"some/path"_s);
|
||||
QCOMPARE(chatBarCache->attachmentPath(), QLatin1String("some/path"));
|
||||
}
|
||||
|
||||
QTEST_MAIN(ChatBarCacheTest)
|
||||
|
||||
@@ -49,51 +49,6 @@
|
||||
"unsigned": {
|
||||
"age": 1234
|
||||
}
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"displayname": "Bob",
|
||||
"membership": "join"
|
||||
},
|
||||
"event_id": "$143273blorb3PhrSn:example.org",
|
||||
"origin_server_ts": 1432735824653,
|
||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||
"sender": "@bob:kde.org",
|
||||
"state_key": "@bob:kde.org",
|
||||
"type": "m.room.member",
|
||||
"unsigned": {
|
||||
"age": 1234
|
||||
}
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"displayname": "Invited",
|
||||
"membership": "invite"
|
||||
},
|
||||
"event_id": "$asdfpj443PhrSn:example.org",
|
||||
"origin_server_ts": 1432735824653,
|
||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||
"sender": "@example:example.org",
|
||||
"state_key": "@invited:example.com",
|
||||
"type": "m.room.member",
|
||||
"unsigned": {
|
||||
"age": 1234
|
||||
}
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"displayname": "Banned",
|
||||
"membership": "ban"
|
||||
},
|
||||
"event_id": "$asdfpj443PhrSnasfd:example.org",
|
||||
"origin_server_ts": 1432735824653,
|
||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||
"sender": "@banned:example.com",
|
||||
"state_key": "@banned:example.com",
|
||||
"type": "m.room.member",
|
||||
"unsigned": {
|
||||
"age": 1234
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -102,7 +57,7 @@
|
||||
"@alice:example.com",
|
||||
"@bob:example.com"
|
||||
],
|
||||
"m.invited_member_count": 1,
|
||||
"m.invited_member_count": 0,
|
||||
"m.joined_member_count": 2
|
||||
},
|
||||
"timeline": {
|
||||
|
||||
@@ -11,8 +11,6 @@
|
||||
#include <Quotient/connection.h>
|
||||
#include <Quotient/quotient_common.h>
|
||||
#include <Quotient/syncdata.h>
|
||||
#include <qcbormap.h>
|
||||
#include <qtestcase.h>
|
||||
|
||||
#include "linkpreviewer.h"
|
||||
#include "models/reactionmodel.h"
|
||||
@@ -64,13 +62,13 @@ private Q_SLOTS:
|
||||
|
||||
void EventHandlerTest::initTestCase()
|
||||
{
|
||||
connection = Connection::makeMockConnection(u"@bob:kde.org"_s);
|
||||
room = new TestUtils::TestRoom(connection, u"#myroom:kde.org"_s, u"test-eventhandler-sync.json"_s);
|
||||
connection = Connection::makeMockConnection(QStringLiteral("@bob:kde.org"));
|
||||
room = new TestUtils::TestRoom(connection, QStringLiteral("#myroom:kde.org"), QLatin1String("test-eventhandler-sync.json"));
|
||||
}
|
||||
|
||||
void EventHandlerTest::authorDisplayName()
|
||||
{
|
||||
QCOMPARE(EventHandler::authorDisplayName(room, room->messageEvents().at(1).get()), u"before"_s);
|
||||
QCOMPARE(EventHandler::authorDisplayName(room, room->messageEvents().at(1).get()), QStringLiteral("before"));
|
||||
}
|
||||
|
||||
void EventHandlerTest::nullAuthorDisplayName()
|
||||
@@ -84,7 +82,8 @@ void EventHandlerTest::nullAuthorDisplayName()
|
||||
|
||||
void EventHandlerTest::singleLineSidplayName()
|
||||
{
|
||||
QCOMPARE(EventHandler::singleLineAuthorDisplayname(room, room->messageEvents().at(11).get()), "Look at me I put newlines in my display name"_L1);
|
||||
QCOMPARE(EventHandler::singleLineAuthorDisplayname(room, room->messageEvents().at(11).get()),
|
||||
QStringLiteral("Look at me I put newlines in my display name"));
|
||||
}
|
||||
|
||||
void EventHandlerTest::nullSingleLineDisplayName()
|
||||
@@ -100,24 +99,18 @@ void EventHandlerTest::time()
|
||||
{
|
||||
const auto event = room->messageEvents().at(0).get();
|
||||
|
||||
QCOMPARE(EventHandler::time(room, event), QDateTime::fromMSecsSinceEpoch(1432735824654, QTimeZone(QTimeZone::UTC)));
|
||||
|
||||
const auto txID = room->postJson("m.room.message"_L1, event->fullJson());
|
||||
QCOMPARE(room->pendingEvents().size(), 1);
|
||||
const auto pendingIt = room->findPendingEvent(txID);
|
||||
QCOMPARE(EventHandler::time(room, pendingIt->event(), true), pendingIt->lastUpdated());
|
||||
|
||||
room->discardMessage(txID);
|
||||
QCOMPARE(room->pendingEvents().size(), 0);
|
||||
QCOMPARE(EventHandler::time(event), QDateTime::fromMSecsSinceEpoch(1432735824654, QTimeZone(QTimeZone::UTC)));
|
||||
QCOMPARE(EventHandler::time(event, true, QDateTime::fromMSecsSinceEpoch(1234, QTimeZone(QTimeZone::UTC))),
|
||||
QDateTime::fromMSecsSinceEpoch(1234, QTimeZone(QTimeZone::UTC)));
|
||||
}
|
||||
|
||||
void EventHandlerTest::nullTime()
|
||||
{
|
||||
QTest::ignoreMessage(QtWarningMsg, "time called with room set to nullptr.");
|
||||
QCOMPARE(EventHandler::time(nullptr, nullptr), QDateTime());
|
||||
|
||||
QTest::ignoreMessage(QtWarningMsg, "time called with event set to nullptr.");
|
||||
QCOMPARE(EventHandler::time(room, nullptr), QDateTime());
|
||||
QCOMPARE(EventHandler::time(nullptr), QDateTime());
|
||||
|
||||
QTest::ignoreMessage(QtWarningMsg, "a value must be provided for lastUpdated for a pending event.");
|
||||
QCOMPARE(EventHandler::time(room->messageEvents().at(0).get(), true), QDateTime());
|
||||
}
|
||||
|
||||
void EventHandlerTest::timeString()
|
||||
@@ -126,27 +119,20 @@ void EventHandlerTest::timeString()
|
||||
|
||||
KFormat format;
|
||||
|
||||
QCOMPARE(EventHandler::timeString(room, event, false),
|
||||
QCOMPARE(EventHandler::timeString(event, false),
|
||||
QLocale().toString(QDateTime::fromMSecsSinceEpoch(1432735824654, QTimeZone(QTimeZone::UTC)).toLocalTime().time(), QLocale::ShortFormat));
|
||||
QCOMPARE(EventHandler::timeString(room, event, true),
|
||||
QCOMPARE(EventHandler::timeString(event, true),
|
||||
format.formatRelativeDate(QDateTime::fromMSecsSinceEpoch(1432735824654, QTimeZone(QTimeZone::UTC)).toLocalTime().date(), QLocale::ShortFormat));
|
||||
QCOMPARE(EventHandler::timeString(room, event, u"hh:mm"_s), QDateTime::fromMSecsSinceEpoch(1432735824654, QTimeZone(QTimeZone::UTC)).toString(u"hh:mm"_s));
|
||||
|
||||
const auto txID = room->postJson("m.room.message"_L1, event->fullJson());
|
||||
QCOMPARE(room->pendingEvents().size(), 1);
|
||||
const auto pendingIt = room->findPendingEvent(txID);
|
||||
|
||||
QCOMPARE(EventHandler::timeString(room, pendingIt->event(), false, QLocale::ShortFormat, true),
|
||||
QLocale().toString(pendingIt->lastUpdated().toLocalTime().time(), QLocale::ShortFormat));
|
||||
QCOMPARE(EventHandler::timeString(room, pendingIt->event(), true, QLocale::ShortFormat, true),
|
||||
format.formatRelativeDate(pendingIt->lastUpdated().toLocalTime().date(), QLocale::ShortFormat));
|
||||
QCOMPARE(EventHandler::timeString(room, pendingIt->event(), false, QLocale::LongFormat, true),
|
||||
QLocale().toString(pendingIt->lastUpdated().toLocalTime().time(), QLocale::LongFormat));
|
||||
QCOMPARE(EventHandler::timeString(room, pendingIt->event(), true, QLocale::LongFormat, true),
|
||||
format.formatRelativeDate(pendingIt->lastUpdated().toLocalTime().date(), QLocale::LongFormat));
|
||||
|
||||
room->discardMessage(txID);
|
||||
QCOMPARE(room->pendingEvents().size(), 0);
|
||||
QCOMPARE(EventHandler::timeString(event, false, QLocale::ShortFormat, true, QDateTime::fromMSecsSinceEpoch(1690699214545, QTimeZone(QTimeZone::UTC))),
|
||||
QLocale().toString(QDateTime::fromMSecsSinceEpoch(1690699214545, QTimeZone(QTimeZone::UTC)).toLocalTime().time(), QLocale::ShortFormat));
|
||||
QCOMPARE(EventHandler::timeString(event, true, QLocale::ShortFormat, true, QDateTime::fromMSecsSinceEpoch(1690699214545, QTimeZone(QTimeZone::UTC))),
|
||||
format.formatRelativeDate(QDateTime::fromMSecsSinceEpoch(1690699214545, QTimeZone(QTimeZone::UTC)).toLocalTime().date(), QLocale::ShortFormat));
|
||||
QCOMPARE(EventHandler::timeString(event, false, QLocale::LongFormat, true, QDateTime::fromMSecsSinceEpoch(1690699214545, QTimeZone(QTimeZone::UTC))),
|
||||
QLocale().toString(QDateTime::fromMSecsSinceEpoch(1690699214545, QTimeZone(QTimeZone::UTC)).toLocalTime().time(), QLocale::LongFormat));
|
||||
QCOMPARE(EventHandler::timeString(event, true, QLocale::LongFormat, true, QDateTime::fromMSecsSinceEpoch(1690699214545, QTimeZone(QTimeZone::UTC))),
|
||||
format.formatRelativeDate(QDateTime::fromMSecsSinceEpoch(1690699214545, QTimeZone(QTimeZone::UTC)).toLocalTime().date(), QLocale::LongFormat));
|
||||
QCOMPARE(EventHandler::timeString(event, QStringLiteral("hh:mm")),
|
||||
QDateTime::fromMSecsSinceEpoch(1432735824654, QTimeZone(QTimeZone::UTC)).toString(QStringLiteral("hh:mm")));
|
||||
}
|
||||
|
||||
void EventHandlerTest::highlighted()
|
||||
@@ -183,10 +169,10 @@ void EventHandlerTest::body()
|
||||
{
|
||||
const auto event = room->messageEvents().at(0).get();
|
||||
|
||||
QCOMPARE(EventHandler::richBody(room, event), u"<b>This is an example<br>text message</b>"_s);
|
||||
QCOMPARE(EventHandler::richBody(room, event, true), u"<b>This is an example text message</b>"_s);
|
||||
QCOMPARE(EventHandler::plainBody(room, event), u"This is an example\ntext message"_s);
|
||||
QCOMPARE(EventHandler::plainBody(room, event, true), u"This is an example text message"_s);
|
||||
QCOMPARE(EventHandler::richBody(room, event), QStringLiteral("<b>This is an example<br>text message</b>"));
|
||||
QCOMPARE(EventHandler::richBody(room, event, true), QStringLiteral("<b>This is an example text message</b>"));
|
||||
QCOMPARE(EventHandler::plainBody(room, event), QStringLiteral("This is an example\ntext message"));
|
||||
QCOMPARE(EventHandler::plainBody(room, event, true), QStringLiteral("This is an example text message"));
|
||||
}
|
||||
|
||||
void EventHandlerTest::nullBody()
|
||||
@@ -209,11 +195,13 @@ void EventHandlerTest::genericBody_data()
|
||||
QTest::addColumn<int>("eventNum");
|
||||
QTest::addColumn<QString>("output");
|
||||
|
||||
QTest::newRow("message") << 0 << u"<a href=\"https://matrix.to/#/@example:example.org\">after</a> sent a message"_s;
|
||||
QTest::newRow("member") << 1 << u"<a href=\"https://matrix.to/#/@example:example.org\">after</a> changed their display name and updated their avatar"_s;
|
||||
QTest::newRow("message 2") << 2 << u"<a href=\"https://matrix.to/#/@example:example.org\">after</a> sent a message"_s;
|
||||
QTest::newRow("reaction") << 3 << u"Unknown event"_s;
|
||||
QTest::newRow("video") << 4 << u"<a href=\"https://matrix.to/#/@example:example.org\">after</a> sent a message"_s;
|
||||
QTest::newRow("message") << 0 << QStringLiteral("<a href=\"https://matrix.to/#/@example:example.org\">after</a> sent a message");
|
||||
QTest::newRow("member") << 1
|
||||
<< QStringLiteral(
|
||||
"<a href=\"https://matrix.to/#/@example:example.org\">after</a> changed their display name and updated their avatar");
|
||||
QTest::newRow("message 2") << 2 << QStringLiteral("<a href=\"https://matrix.to/#/@example:example.org\">after</a> sent a message");
|
||||
QTest::newRow("reaction") << 3 << QStringLiteral("Unknown event");
|
||||
QTest::newRow("video") << 4 << QStringLiteral("<a href=\"https://matrix.to/#/@example:example.org\">after</a> sent a message");
|
||||
}
|
||||
|
||||
void EventHandlerTest::genericBody()
|
||||
@@ -235,19 +223,19 @@ void EventHandlerTest::nullGenericBody()
|
||||
|
||||
void EventHandlerTest::markdownBody()
|
||||
{
|
||||
QCOMPARE(EventHandler::markdownBody(room->messageEvents().at(0).get()), u"This is an example\ntext message"_s);
|
||||
QCOMPARE(EventHandler::markdownBody(room->messageEvents().at(0).get()), QStringLiteral("This is an example\ntext message"));
|
||||
}
|
||||
|
||||
void EventHandlerTest::markdownBodyReply()
|
||||
{
|
||||
QCOMPARE(EventHandler::markdownBody(room->messageEvents().at(5).get()), u"reply"_s);
|
||||
QCOMPARE(EventHandler::markdownBody(room->messageEvents().at(5).get()), QStringLiteral("reply"));
|
||||
}
|
||||
|
||||
void EventHandlerTest::subtitle()
|
||||
{
|
||||
QCOMPARE(EventHandler::subtitleText(room, room->messageEvents().at(0).get()), u"after: This is an example text message"_s);
|
||||
QCOMPARE(EventHandler::subtitleText(room, room->messageEvents().at(0).get()), QStringLiteral("after: This is an example text message"));
|
||||
QCOMPARE(EventHandler::subtitleText(room, room->messageEvents().at(2).get()),
|
||||
u"after: This is a highlight @bob:kde.org and this is a link https://kde.org"_s);
|
||||
QStringLiteral("after: This is a highlight @bob:kde.org and this is a link https://kde.org"));
|
||||
}
|
||||
|
||||
void EventHandlerTest::nullSubtitle()
|
||||
@@ -263,21 +251,21 @@ void EventHandlerTest::mediaInfo()
|
||||
{
|
||||
auto event = room->messageEvents().at(4).get();
|
||||
auto mediaInfo = EventHandler::mediaInfo(room, event);
|
||||
auto thumbnailInfo = mediaInfo["tempInfo"_L1].toMap();
|
||||
auto thumbnailInfo = mediaInfo["tempInfo"_ls].toMap();
|
||||
|
||||
QCOMPARE(mediaInfo["source"_L1], room->makeMediaUrl(event->id(), QUrl("mxc://kde.org/1234567"_L1)));
|
||||
QCOMPARE(mediaInfo["mimeType"_L1], u"video/mp4"_s);
|
||||
QCOMPARE(mediaInfo["mimeIcon"_L1], u"video-mp4"_s);
|
||||
QCOMPARE(mediaInfo["size"_L1], 62650636);
|
||||
QCOMPARE(mediaInfo["duration"_L1], 10);
|
||||
QCOMPARE(mediaInfo["width"_L1], 1920);
|
||||
QCOMPARE(mediaInfo["height"_L1], 1080);
|
||||
QCOMPARE(thumbnailInfo["source"_L1], room->makeMediaUrl(event->id(), QUrl("mxc://kde.org/2234567"_L1)));
|
||||
QCOMPARE(thumbnailInfo["mimeType"_L1], u"image/jpeg"_s);
|
||||
QCOMPARE(thumbnailInfo["mimeIcon"_L1], u"image-jpeg"_s);
|
||||
QCOMPARE(thumbnailInfo["size"_L1], 382249);
|
||||
QCOMPARE(thumbnailInfo["width"_L1], 800);
|
||||
QCOMPARE(thumbnailInfo["height"_L1], 450);
|
||||
QCOMPARE(mediaInfo["source"_ls], room->makeMediaUrl(event->id(), QUrl("mxc://kde.org/1234567"_ls)));
|
||||
QCOMPARE(mediaInfo["mimeType"_ls], QStringLiteral("video/mp4"));
|
||||
QCOMPARE(mediaInfo["mimeIcon"_ls], QStringLiteral("video-mp4"));
|
||||
QCOMPARE(mediaInfo["size"_ls], 62650636);
|
||||
QCOMPARE(mediaInfo["duration"_ls], 10);
|
||||
QCOMPARE(mediaInfo["width"_ls], 1920);
|
||||
QCOMPARE(mediaInfo["height"_ls], 1080);
|
||||
QCOMPARE(thumbnailInfo["source"_ls], room->makeMediaUrl(event->id(), QUrl("mxc://kde.org/2234567"_ls)));
|
||||
QCOMPARE(thumbnailInfo["mimeType"_ls], QStringLiteral("image/jpeg"));
|
||||
QCOMPARE(thumbnailInfo["mimeIcon"_ls], QStringLiteral("image-jpeg"));
|
||||
QCOMPARE(thumbnailInfo["size"_ls], 382249);
|
||||
QCOMPARE(thumbnailInfo["width"_ls], 800);
|
||||
QCOMPARE(thumbnailInfo["height"_ls], 450);
|
||||
}
|
||||
|
||||
void EventHandlerTest::nullMediaInfo()
|
||||
@@ -316,9 +304,9 @@ void EventHandlerTest::nullReplyAuthor()
|
||||
|
||||
void EventHandlerTest::location()
|
||||
{
|
||||
QCOMPARE(EventHandler::latitude(room->messageEvents().at(7).get()), u"51.7035"_s.toFloat());
|
||||
QCOMPARE(EventHandler::longitude(room->messageEvents().at(7).get()), u"-1.14394"_s.toFloat());
|
||||
QCOMPARE(EventHandler::locationAssetType(room->messageEvents().at(7).get()), u"m.pin"_s);
|
||||
QCOMPARE(EventHandler::latitude(room->messageEvents().at(7).get()), QStringLiteral("51.7035").toFloat());
|
||||
QCOMPARE(EventHandler::longitude(room->messageEvents().at(7).get()), QStringLiteral("-1.14394").toFloat());
|
||||
QCOMPARE(EventHandler::locationAssetType(room->messageEvents().at(7).get()), QStringLiteral("m.pin"));
|
||||
}
|
||||
|
||||
void EventHandlerTest::nullLocation()
|
||||
|
||||
@@ -38,8 +38,8 @@ private Q_SLOTS:
|
||||
|
||||
void LinkPreviewerTest::initTestCase()
|
||||
{
|
||||
connection = Connection::makeMockConnection(u"@bob:example.org"_s);
|
||||
room = new TestUtils::TestRoom(connection, u"!test:example.org"_s);
|
||||
connection = Connection::makeMockConnection(QStringLiteral("@bob:example.org"));
|
||||
room = new TestUtils::TestRoom(connection, QStringLiteral("!test:example.org"));
|
||||
}
|
||||
|
||||
void LinkPreviewerTest::linkPreviewsMatch_data()
|
||||
@@ -47,9 +47,9 @@ void LinkPreviewerTest::linkPreviewsMatch_data()
|
||||
QTest::addColumn<QString>("inputString");
|
||||
QTest::addColumn<QUrl>("testOutputLink");
|
||||
|
||||
QTest::newRow("plainHttps") << u"https://kde.org"_s << QUrl(u"https://kde.org"_s);
|
||||
QTest::newRow("richHttps") << u"<a href=\"https://kde.org\">Rich Link</a>"_s << QUrl(u"https://kde.org"_s);
|
||||
QTest::newRow("richHttpsLinkDescription") << u"<a href=\"https://kde.org\">https://kde.org</a>"_s << QUrl(u"https://kde.org"_s);
|
||||
QTest::newRow("plainHttps") << QStringLiteral("https://kde.org") << QUrl("https://kde.org"_ls);
|
||||
QTest::newRow("richHttps") << QStringLiteral("<a href=\"https://kde.org\">Rich Link</a>") << QUrl("https://kde.org"_ls);
|
||||
QTest::newRow("richHttpsLinkDescription") << QStringLiteral("<a href=\"https://kde.org\">https://kde.org</a>") << QUrl("https://kde.org"_ls);
|
||||
}
|
||||
|
||||
void LinkPreviewerTest::linkPreviewsMatch()
|
||||
@@ -67,8 +67,8 @@ void LinkPreviewerTest::multipleLinkPreviewsMatch_data()
|
||||
QTest::addColumn<QString>("inputString");
|
||||
QTest::addColumn<QList<QUrl>>("testOutputLinks");
|
||||
|
||||
QTest::newRow("multipleHttps") << u"www.example.org https://kde.org"_s << QList{QUrl(u"www.example.org"_s), QUrl(u"https://kde.org"_s)};
|
||||
QTest::newRow("multipleHttps1Invalid") << u"www.example.org mxc://example.org/SEsfnsuifSDFSSEF"_s << QList{QUrl(u"www.example.org"_s)};
|
||||
QTest::newRow("multipleHttps") << QStringLiteral("www.example.org https://kde.org") << QList{QUrl("www.example.org"_ls), QUrl("https://kde.org"_ls)};
|
||||
QTest::newRow("multipleHttps1Invalid") << QStringLiteral("www.example.org mxc://example.org/SEsfnsuifSDFSSEF") << QList{QUrl("www.example.org"_ls)};
|
||||
}
|
||||
|
||||
void LinkPreviewerTest::multipleLinkPreviewsMatch()
|
||||
@@ -85,9 +85,9 @@ void LinkPreviewerTest::linkPreviewsReject_data()
|
||||
{
|
||||
QTest::addColumn<QString>("inputString");
|
||||
|
||||
QTest::newRow("mxc") << u"mxc://example.org/SEsfnsuifSDFSSEF"_s;
|
||||
QTest::newRow("matrixTo") << u"https://matrix.to/#/@alice:example.org"_s;
|
||||
QTest::newRow("noSpace") << u"testhttps://kde.org"_s;
|
||||
QTest::newRow("mxc") << QStringLiteral("mxc://example.org/SEsfnsuifSDFSSEF");
|
||||
QTest::newRow("matrixTo") << QStringLiteral("https://matrix.to/#/@alice:example.org");
|
||||
QTest::newRow("noSpace") << QStringLiteral("testhttps://kde.org");
|
||||
}
|
||||
|
||||
void LinkPreviewerTest::linkPreviewsReject()
|
||||
|
||||
@@ -32,25 +32,25 @@ private Q_SLOTS:
|
||||
|
||||
void MessageContentModelTest::initTestCase()
|
||||
{
|
||||
connection = Connection::makeMockConnection(u"@bob:kde.org"_s);
|
||||
connection = Connection::makeMockConnection(QStringLiteral("@bob:kde.org"));
|
||||
}
|
||||
|
||||
void MessageContentModelTest::missingEvent()
|
||||
{
|
||||
auto room = new TestUtils::TestRoom(connection, u"#firstRoom:kde.org"_s);
|
||||
auto model1 = MessageContentModel(room, u"$153456789:example.org"_s);
|
||||
auto room = new TestUtils::TestRoom(connection, QStringLiteral("#firstRoom:kde.org"));
|
||||
auto model1 = MessageContentModel(room, "$153456789:example.org"_L1);
|
||||
|
||||
QCOMPARE(model1.rowCount(), 1);
|
||||
QCOMPARE(model1.data(model1.index(0), MessageContentModel::ComponentTypeRole), MessageComponentType::Loading);
|
||||
QCOMPARE(model1.data(model1.index(0), MessageContentModel::DisplayRole), u"Loading"_s);
|
||||
QCOMPARE(model1.data(model1.index(0), MessageContentModel::DisplayRole), "Loading"_L1);
|
||||
|
||||
auto model2 = MessageContentModel(room, u"$153456789:example.org"_s, true);
|
||||
auto model2 = MessageContentModel(room, "$153456789:example.org"_L1, true);
|
||||
|
||||
QCOMPARE(model2.rowCount(), 1);
|
||||
QCOMPARE(model2.data(model2.index(0), MessageContentModel::ComponentTypeRole), MessageComponentType::Loading);
|
||||
QCOMPARE(model2.data(model2.index(0), MessageContentModel::DisplayRole), u"Loading reply"_s);
|
||||
QCOMPARE(model2.data(model2.index(0), MessageContentModel::DisplayRole), "Loading reply"_L1);
|
||||
|
||||
room->syncNewEvents(u"test-min-sync.json"_s);
|
||||
room->syncNewEvents(QLatin1String("test-min-sync.json"));
|
||||
QCOMPARE(model1.rowCount(), 2);
|
||||
QCOMPARE(model1.data(model1.index(0), MessageContentModel::ComponentTypeRole), MessageComponentType::Author);
|
||||
QCOMPARE(model1.data(model1.index(1), MessageContentModel::ComponentTypeRole), MessageComponentType::Text);
|
||||
|
||||
@@ -10,20 +10,20 @@
|
||||
#include <Quotient/syncdata.h>
|
||||
|
||||
#include "enums/delegatetype.h"
|
||||
#include "models/timelinemessagemodel.h"
|
||||
#include "models/messageeventmodel.h"
|
||||
#include "neochatroom.h"
|
||||
|
||||
#include "testutils.h"
|
||||
|
||||
using namespace Quotient;
|
||||
|
||||
class TimelineMessageModelTest : public QObject
|
||||
class MessageEventModelTest : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
Connection *connection = nullptr;
|
||||
TimelineMessageModel *model = nullptr;
|
||||
MessageEventModel *model = nullptr;
|
||||
|
||||
private Q_SLOTS:
|
||||
void initTestCase();
|
||||
@@ -40,70 +40,70 @@ private Q_SLOTS:
|
||||
void cleanup();
|
||||
};
|
||||
|
||||
void TimelineMessageModelTest::initTestCase()
|
||||
void MessageEventModelTest::initTestCase()
|
||||
{
|
||||
connection = Connection::makeMockConnection(u"@bob:kde.org"_s);
|
||||
connection = Connection::makeMockConnection(QStringLiteral("@bob:kde.org"));
|
||||
}
|
||||
|
||||
void TimelineMessageModelTest::init()
|
||||
void MessageEventModelTest::init()
|
||||
{
|
||||
QCOMPARE(model, nullptr);
|
||||
model = new TimelineMessageModel;
|
||||
model = new MessageEventModel;
|
||||
}
|
||||
|
||||
// Make sure that basic empty rooms can be switched without crashing.
|
||||
void TimelineMessageModelTest::switchEmptyRoom()
|
||||
void MessageEventModelTest::switchEmptyRoom()
|
||||
{
|
||||
auto firstRoom = new TestUtils::TestRoom(connection, u"#firstRoom:kde.org"_s);
|
||||
auto secondRoom = new TestUtils::TestRoom(connection, u"#secondRoom:kde.org"_s);
|
||||
auto firstRoom = new TestUtils::TestRoom(connection, QStringLiteral("#firstRoom:kde.org"));
|
||||
auto secondRoom = new TestUtils::TestRoom(connection, QStringLiteral("#secondRoom:kde.org"));
|
||||
|
||||
QSignalSpy spy(model, SIGNAL(roomChanged()));
|
||||
|
||||
QCOMPARE(model->room(), nullptr);
|
||||
model->setRoom(firstRoom);
|
||||
QCOMPARE(spy.count(), 1);
|
||||
QCOMPARE(model->room()->id(), u"#firstRoom:kde.org"_s);
|
||||
QCOMPARE(model->room()->id(), QStringLiteral("#firstRoom:kde.org"));
|
||||
model->setRoom(secondRoom);
|
||||
QCOMPARE(spy.count(), 2);
|
||||
QCOMPARE(model->room()->id(), u"#secondRoom:kde.org"_s);
|
||||
QCOMPARE(model->room()->id(), QStringLiteral("#secondRoom:kde.org"));
|
||||
model->setRoom(nullptr);
|
||||
QCOMPARE(spy.count(), 3);
|
||||
QCOMPARE(model->room(), nullptr);
|
||||
}
|
||||
|
||||
// Make sure that rooms with some events can be switched without crashing
|
||||
void TimelineMessageModelTest::switchSyncedRoom()
|
||||
void MessageEventModelTest::switchSyncedRoom()
|
||||
{
|
||||
auto firstRoom = new TestUtils::TestRoom(connection, u"#firstRoom:kde.org"_s, u"test-messageventmodel-sync.json"_s);
|
||||
auto secondRoom = new TestUtils::TestRoom(connection, u"#secondRoom:kde.org"_s, u"test-messageventmodel-sync.json"_s);
|
||||
auto firstRoom = new TestUtils::TestRoom(connection, QStringLiteral("#firstRoom:kde.org"), QLatin1String("test-messageventmodel-sync.json"));
|
||||
auto secondRoom = new TestUtils::TestRoom(connection, QStringLiteral("#secondRoom:kde.org"), QLatin1String("test-messageventmodel-sync.json"));
|
||||
|
||||
QSignalSpy spy(model, SIGNAL(roomChanged()));
|
||||
|
||||
QCOMPARE(model->room(), nullptr);
|
||||
model->setRoom(firstRoom);
|
||||
QCOMPARE(spy.count(), 1);
|
||||
QCOMPARE(model->room()->id(), u"#firstRoom:kde.org"_s);
|
||||
QCOMPARE(model->room()->id(), QStringLiteral("#firstRoom:kde.org"));
|
||||
model->setRoom(secondRoom);
|
||||
QCOMPARE(spy.count(), 2);
|
||||
QCOMPARE(model->room()->id(), u"#secondRoom:kde.org"_s);
|
||||
QCOMPARE(model->room()->id(), QStringLiteral("#secondRoom:kde.org"));
|
||||
model->setRoom(nullptr);
|
||||
QCOMPARE(spy.count(), 3);
|
||||
QCOMPARE(model->room(), nullptr);
|
||||
}
|
||||
|
||||
void TimelineMessageModelTest::simpleTimeline()
|
||||
void MessageEventModelTest::simpleTimeline()
|
||||
{
|
||||
auto room = new TestUtils::TestRoom(connection, u"#myroom:kde.org"_s, u"test-messageventmodel-sync.json"_s);
|
||||
auto room = new TestUtils::TestRoom(connection, QStringLiteral("#myroom:kde.org"), QLatin1String("test-messageventmodel-sync.json"));
|
||||
|
||||
model->setRoom(room);
|
||||
QCOMPARE(model->rowCount(), 2);
|
||||
|
||||
QCOMPARE(model->data(model->index(0), TimelineMessageModel::DelegateTypeRole), DelegateType::State);
|
||||
QCOMPARE(model->data(model->index(0)), u"changed their display name to Example Changed"_s);
|
||||
QCOMPARE(model->data(model->index(0), MessageEventModel::DelegateTypeRole), DelegateType::State);
|
||||
QCOMPARE(model->data(model->index(0)), QStringLiteral("changed their display name to Example Changed"));
|
||||
|
||||
QCOMPARE(model->data(model->index(1)), u"<b>This is an example<br>text message</b>"_s);
|
||||
QCOMPARE(model->data(model->index(1), TimelineMessageModel::DelegateTypeRole), DelegateType::Message);
|
||||
QCOMPARE(model->data(model->index(1), TimelineMessageModel::EventIdRole), u"$153456789:example.org"_s);
|
||||
QCOMPARE(model->data(model->index(1)), QStringLiteral("<b>This is an example<br>text message</b>"));
|
||||
QCOMPARE(model->data(model->index(1), MessageEventModel::DelegateTypeRole), DelegateType::Message);
|
||||
QCOMPARE(model->data(model->index(1), MessageEventModel::EventIdRole), QStringLiteral("$153456789:example.org"));
|
||||
|
||||
QTest::ignoreMessage(QtWarningMsg, "Index QModelIndex(-1,-1,0x0,QObject(0x0)) is not valid (expected valid)");
|
||||
QCOMPARE(model->data(model->index(-1)), QVariant());
|
||||
@@ -111,33 +111,33 @@ void TimelineMessageModelTest::simpleTimeline()
|
||||
QCOMPARE(model->data(model->index(model->rowCount())), QVariant());
|
||||
}
|
||||
|
||||
// Sync some events into the TimelineMessageModel's current room and don't crash.
|
||||
void TimelineMessageModelTest::syncNewEvents()
|
||||
// Sync some events into the MessageEventModel's current room and don't crash.
|
||||
void MessageEventModelTest::syncNewEvents()
|
||||
{
|
||||
auto room = new TestUtils::TestRoom(connection, u"#myroom:kde.org"_s);
|
||||
auto room = new TestUtils::TestRoom(connection, QStringLiteral("#myroom:kde.org"));
|
||||
QSignalSpy spy(room, SIGNAL(aboutToAddNewMessages(Quotient::RoomEventsRange)));
|
||||
|
||||
model->setRoom(room);
|
||||
QCOMPARE(model->rowCount(), 0);
|
||||
|
||||
room->syncNewEvents(u"test-messageventmodel-sync.json"_s);
|
||||
room->syncNewEvents(QLatin1String("test-messageventmodel-sync.json"));
|
||||
|
||||
QCOMPARE(model->rowCount(), 2);
|
||||
QCOMPARE(spy.count(), 1);
|
||||
}
|
||||
|
||||
// Check the adding of pending events to the room doesn't cause any issues in the model.
|
||||
void TimelineMessageModelTest::pendingEvent()
|
||||
void MessageEventModelTest::pendingEvent()
|
||||
{
|
||||
QSignalSpy spyInsert(model, SIGNAL(rowsInserted(const QModelIndex &, int, int)));
|
||||
QSignalSpy spyRemove(model, SIGNAL(rowsRemoved(const QModelIndex &, int, int)));
|
||||
QSignalSpy spyChanged(model, SIGNAL(dataChanged(const QModelIndex, const QModelIndex, const QList<int> &)));
|
||||
|
||||
auto room = new TestUtils::TestRoom(connection, u"#myroom:kde.org"_s);
|
||||
auto room = new TestUtils::TestRoom(connection, QStringLiteral("#myroom:kde.org"));
|
||||
model->setRoom(room);
|
||||
QCOMPARE(model->rowCount(), 0);
|
||||
|
||||
auto txnId = room->postPlainText("New plain message"_L1);
|
||||
auto txnId = room->postPlainText("New plain message"_ls);
|
||||
QCOMPARE(model->rowCount(), 1);
|
||||
QCOMPARE(spyInsert.count(), 1);
|
||||
|
||||
@@ -145,26 +145,26 @@ void TimelineMessageModelTest::pendingEvent()
|
||||
QCOMPARE(model->rowCount(), 0);
|
||||
QCOMPARE(spyRemove.count(), 1);
|
||||
|
||||
txnId = room->postPlainText("New plain message"_L1);
|
||||
txnId = room->postPlainText("New plain message"_ls);
|
||||
QCOMPARE(model->rowCount(), 1);
|
||||
QCOMPARE(spyInsert.count(), 2);
|
||||
|
||||
// We need to manually set the transaction ID of the new message as it will be
|
||||
// different every time.
|
||||
QFile testSyncFile;
|
||||
testSyncFile.setFileName(QStringLiteral(DATA_DIR) + u'/' + u"test-pending-sync.json"_s);
|
||||
testSyncFile.setFileName(QLatin1String(DATA_DIR) + u'/' + QLatin1String("test-pending-sync.json"));
|
||||
testSyncFile.open(QIODevice::ReadOnly);
|
||||
auto testSyncJson = QJsonDocument::fromJson(testSyncFile.readAll());
|
||||
auto root = testSyncJson.object();
|
||||
auto timeline = root["timeline"_L1].toObject();
|
||||
auto events = timeline["events"_L1].toArray();
|
||||
auto timeline = root["timeline"_ls].toObject();
|
||||
auto events = timeline["events"_ls].toArray();
|
||||
auto firstEvent = events[0].toObject();
|
||||
firstEvent.insert("unsigned"_L1, QJsonObject{{"transaction_id"_L1, txnId}});
|
||||
firstEvent.insert(QLatin1String("unsigned"), QJsonObject{{QLatin1String("transaction_id"), txnId}});
|
||||
events[0] = firstEvent;
|
||||
timeline.insert("events"_L1, events);
|
||||
root.insert("timeline"_L1, timeline);
|
||||
timeline.insert("events"_ls, events);
|
||||
root.insert("timeline"_ls, timeline);
|
||||
testSyncJson.setObject(root);
|
||||
SyncRoomData roomData(u"@bob:kde.org"_s, JoinState::Join, testSyncJson.object());
|
||||
SyncRoomData roomData(QStringLiteral("@bob:kde.org"), JoinState::Join, testSyncJson.object());
|
||||
room->update(std::move(roomData));
|
||||
|
||||
QCOMPARE(model->rowCount(), 1);
|
||||
@@ -174,7 +174,7 @@ void TimelineMessageModelTest::pendingEvent()
|
||||
auto isPendingChanged = false;
|
||||
for (auto signal : spyChanged) {
|
||||
auto roles = signal.at(2).toList();
|
||||
if (roles.contains(TimelineMessageModel::IsPendingRole)) {
|
||||
if (roles.contains(MessageEventModel::IsPendingRole)) {
|
||||
isPendingChanged = true;
|
||||
}
|
||||
}
|
||||
@@ -182,33 +182,33 @@ void TimelineMessageModelTest::pendingEvent()
|
||||
}
|
||||
|
||||
// Make sure that the signals are disconnecting correctly when a room is switched.
|
||||
void TimelineMessageModelTest::disconnect()
|
||||
void MessageEventModelTest::disconnect()
|
||||
{
|
||||
auto room = new TestUtils::TestRoom(connection, u"#myroom:kde.org"_s);
|
||||
auto room = new TestUtils::TestRoom(connection, QStringLiteral("#myroom:kde.org"));
|
||||
model->setRoom(room);
|
||||
|
||||
QSignalSpy spy(model, SIGNAL(rowsInserted(const QModelIndex &, int, int)));
|
||||
|
||||
model->setRoom(nullptr);
|
||||
room->syncNewEvents(u"test-messageventmodel-sync.json"_s);
|
||||
room->syncNewEvents(QLatin1String("test-messageventmodel-sync.json"));
|
||||
|
||||
QCOMPARE(spy.count(), 0);
|
||||
}
|
||||
|
||||
void TimelineMessageModelTest::idToRow()
|
||||
void MessageEventModelTest::idToRow()
|
||||
{
|
||||
auto room = new TestUtils::TestRoom(connection, u"#myroom:kde.org"_s, u"test-min-sync.json"_s);
|
||||
auto room = new TestUtils::TestRoom(connection, QStringLiteral("#myroom:kde.org"), QLatin1String("test-min-sync.json"));
|
||||
model->setRoom(room);
|
||||
|
||||
QCOMPARE(model->eventIdToRow(u"$153456789:example.org"_s), 0);
|
||||
QCOMPARE(model->eventIdToRow(QStringLiteral("$153456789:example.org")), 0);
|
||||
}
|
||||
|
||||
void TimelineMessageModelTest::cleanup()
|
||||
void MessageEventModelTest::cleanup()
|
||||
{
|
||||
delete model;
|
||||
model = nullptr;
|
||||
QCOMPARE(model, nullptr);
|
||||
}
|
||||
|
||||
QTEST_MAIN(TimelineMessageModelTest)
|
||||
#include "timelinemessagemodeltest.moc"
|
||||
QTEST_MAIN(MessageEventModelTest)
|
||||
#include "messageeventmodeltest.moc"
|
||||
@@ -27,8 +27,8 @@ private Q_SLOTS:
|
||||
|
||||
void NeoChatRoomTest::initTestCase()
|
||||
{
|
||||
connection = Connection::makeMockConnection(u"@bob:kde.org"_s);
|
||||
room = new TestUtils::TestRoom(connection, u"#myroom:kde.org"_s, u"test-min-sync.json"_s);
|
||||
connection = Connection::makeMockConnection(QStringLiteral("@bob:kde.org"));
|
||||
room = new TestUtils::TestRoom(connection, QStringLiteral("#myroom:kde.org"), "test-min-sync.json"_ls);
|
||||
}
|
||||
|
||||
void NeoChatRoomTest::eventTest()
|
||||
|
||||
@@ -31,8 +31,8 @@ private Q_SLOTS:
|
||||
|
||||
void PollHandlerTest::initTestCase()
|
||||
{
|
||||
connection = Connection::makeMockConnection(u"@bob:kde.org"_s);
|
||||
room = new TestUtils::TestRoom(connection, u"#myroom:kde.org"_s, u"test-pollhandlerstart-sync.json"_s);
|
||||
connection = Connection::makeMockConnection(QStringLiteral("@bob:kde.org"));
|
||||
room = new TestUtils::TestRoom(connection, QStringLiteral("#myroom:kde.org"), "test-pollhandlerstart-sync.json"_ls);
|
||||
}
|
||||
|
||||
// Basically don't crash.
|
||||
@@ -54,16 +54,16 @@ void PollHandlerTest::poll()
|
||||
auto startEvent = eventCast<const PollStartEvent>(room->messageEvents().at(0).get());
|
||||
auto pollHandler = PollHandler(room, startEvent);
|
||||
|
||||
auto options = QJsonArray{QJsonObject{{"id"_L1, "option1"_L1}, {"org.matrix.msc1767.text"_L1, "option1"_L1}},
|
||||
QJsonObject{{"id"_L1, "option2"_L1}, {"org.matrix.msc1767.text"_L1, "option2"_L1}}};
|
||||
auto options = QJsonArray{QJsonObject{{"id"_ls, "option1"_ls}, {"org.matrix.msc1767.text"_ls, "option1"_ls}},
|
||||
QJsonObject{{"id"_ls, "option2"_ls}, {"org.matrix.msc1767.text"_ls, "option2"_ls}}};
|
||||
|
||||
QCOMPARE(pollHandler.hasEnded(), false);
|
||||
QCOMPARE(pollHandler.answerCount(), 0);
|
||||
QCOMPARE(pollHandler.question(), u"test"_s);
|
||||
QCOMPARE(pollHandler.question(), QStringLiteral("test"));
|
||||
QCOMPARE(pollHandler.options(), options);
|
||||
QCOMPARE(pollHandler.answers(), QJsonObject());
|
||||
QCOMPARE(pollHandler.counts(), QJsonObject());
|
||||
QCOMPARE(pollHandler.kind(), u"org.matrix.msc3381.poll.disclosed"_s);
|
||||
QCOMPARE(pollHandler.kind(), QStringLiteral("org.matrix.msc3381.poll.disclosed"));
|
||||
}
|
||||
|
||||
QTEST_GUILESS_MAIN(PollHandlerTest)
|
||||
|
||||
@@ -31,8 +31,8 @@ private Q_SLOTS:
|
||||
|
||||
void ReactionModelTest::initTestCase()
|
||||
{
|
||||
connection = Connection::makeMockConnection(u"@bob:kde.org"_s);
|
||||
room = new TestUtils::TestRoom(connection, u"#myroom:kde.org"_s, u"test-reactionmodel-sync.json"_s);
|
||||
connection = Connection::makeMockConnection(QStringLiteral("@bob:kde.org"));
|
||||
room = new TestUtils::TestRoom(connection, QStringLiteral("#myroom:kde.org"), QLatin1String("test-reactionmodel-sync.json"));
|
||||
}
|
||||
|
||||
void ReactionModelTest::nullModel()
|
||||
@@ -49,9 +49,10 @@ void ReactionModelTest::basicReaction()
|
||||
auto model = ReactionModel(event, room);
|
||||
|
||||
QCOMPARE(model.rowCount(), 1);
|
||||
QCOMPARE(model.data(model.index(0), ReactionModel::TextContentRole), u"<span style=\"font-family: 'emoji';\">👍</span>"_s);
|
||||
QCOMPARE(model.data(model.index(0), ReactionModel::ReactionRole), u"👍"_s);
|
||||
QCOMPARE(model.data(model.index(0), ReactionModel::ToolTipRole), u"Alice Margatroid reacted with <span style=\"font-family: 'emoji';\">👍</span>"_s);
|
||||
QCOMPARE(model.data(model.index(0), ReactionModel::TextContentRole), QStringLiteral("<span style=\"font-family: 'emoji';\">👍</span>"));
|
||||
QCOMPARE(model.data(model.index(0), ReactionModel::ReactionRole), QStringLiteral("👍"));
|
||||
QCOMPARE(model.data(model.index(0), ReactionModel::ToolTipRole),
|
||||
QStringLiteral("Alice Margatroid reacted with <span style=\"font-family: 'emoji';\">👍</span>"));
|
||||
QCOMPARE(model.data(model.index(0), ReactionModel::HasLocalMember), false);
|
||||
}
|
||||
|
||||
@@ -61,16 +62,17 @@ void ReactionModelTest::newReaction()
|
||||
auto model = new ReactionModel(event, room);
|
||||
|
||||
QCOMPARE(model->rowCount(), 1);
|
||||
QCOMPARE(model->data(model->index(0), ReactionModel::ToolTipRole), u"Alice Margatroid reacted with <span style=\"font-family: 'emoji';\">👍</span>"_s);
|
||||
QCOMPARE(model->data(model->index(0), ReactionModel::ToolTipRole),
|
||||
QStringLiteral("Alice Margatroid reacted with <span style=\"font-family: 'emoji';\">👍</span>"));
|
||||
|
||||
QSignalSpy spy(model, SIGNAL(modelReset()));
|
||||
|
||||
room->syncNewEvents(u"test-reactionmodel-extra-sync.json"_s);
|
||||
room->syncNewEvents(QLatin1String("test-reactionmodel-extra-sync.json"));
|
||||
QCOMPARE(model->rowCount(), 2);
|
||||
QCOMPARE(spy.count(), 2); // Once for each of the 2 new reactions.
|
||||
QCOMPARE(model->data(model->index(1), ReactionModel::ReactionRole), u"😆"_s);
|
||||
QCOMPARE(model->data(model->index(1), ReactionModel::ReactionRole), QStringLiteral("😆"));
|
||||
QCOMPARE(model->data(model->index(0), ReactionModel::ToolTipRole),
|
||||
u"Alice Margatroid and Bob reacted with <span style=\"font-family: 'emoji';\">👍</span>"_s);
|
||||
QStringLiteral("Alice Margatroid and Bob reacted with <span style=\"font-family: 'emoji';\">👍</span>"));
|
||||
|
||||
delete model;
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ public:
|
||||
{
|
||||
if (!syncFileName.isEmpty()) {
|
||||
QFile testSyncFile;
|
||||
testSyncFile.setFileName(QStringLiteral(DATA_DIR) + u'/' + syncFileName);
|
||||
testSyncFile.setFileName(QLatin1String(DATA_DIR) + u'/' + syncFileName);
|
||||
testSyncFile.open(QIODevice::ReadOnly);
|
||||
const auto testSyncJson = QJsonDocument::fromJson(testSyncFile.readAll());
|
||||
Quotient::SyncRoomData roomData(id(), Quotient::JoinState::Join, testSyncJson.object());
|
||||
@@ -45,7 +45,7 @@ inline Quotient::event_ptr_tt<EventT> loadEventFromFile(const QString &eventFile
|
||||
{
|
||||
if (!eventFileName.isEmpty()) {
|
||||
QFile testEventFile;
|
||||
testEventFile.setFileName(QStringLiteral(DATA_DIR) + u'/' + eventFileName);
|
||||
testEventFile.setFileName(QLatin1String(DATA_DIR) + u'/' + eventFileName);
|
||||
testEventFile.open(QIODevice::ReadOnly);
|
||||
auto testSyncJson = QJsonDocument::fromJson(testEventFile.readAll()).object();
|
||||
return Quotient::loadEvent<EventT>(testSyncJson);
|
||||
|
||||
@@ -63,7 +63,6 @@ private Q_SLOTS:
|
||||
void receiveRichEdited();
|
||||
void receiveLineSeparator();
|
||||
void receiveRichCodeUrl();
|
||||
void receiveRichColor();
|
||||
|
||||
void componentOutput_data();
|
||||
void componentOutput();
|
||||
@@ -71,25 +70,25 @@ private Q_SLOTS:
|
||||
|
||||
void TextHandlerTest::initTestCase()
|
||||
{
|
||||
connection = Connection::makeMockConnection(u"@bob:kde.org"_s);
|
||||
connection->setAccountData(u"im.ponies.user_emotes"_s,
|
||||
QJsonObject{{"images"_L1,
|
||||
QJsonObject{{"test"_L1,
|
||||
QJsonObject{{"body"_L1, "Test custom emoji"_L1},
|
||||
{"url"_L1, "mxc://example.org/test"_L1},
|
||||
{"usage"_L1, QJsonArray{"emoticon"_L1}}}}}}});
|
||||
connection = Connection::makeMockConnection(QStringLiteral("@bob:kde.org"));
|
||||
connection->setAccountData("im.ponies.user_emotes"_ls,
|
||||
QJsonObject{{"images"_ls,
|
||||
QJsonObject{{"test"_ls,
|
||||
QJsonObject{{"body"_ls, "Test custom emoji"_ls},
|
||||
{"url"_ls, "mxc://example.org/test"_ls},
|
||||
{"usage"_ls, QJsonArray{"emoticon"_ls}}}}}}});
|
||||
CustomEmojiModel::instance().setConnection(static_cast<NeoChatConnection *>(connection));
|
||||
|
||||
room = new TestUtils::TestRoom(connection, u"#myroom:kde.org"_s, u"test-texthandler-sync.json"_s);
|
||||
room = new TestUtils::TestRoom(connection, QStringLiteral("#myroom:kde.org"), QLatin1String("test-texthandler-sync.json"));
|
||||
}
|
||||
|
||||
void TextHandlerTest::allowedAttributes()
|
||||
{
|
||||
const QString testInputString1 = u"<span data-mx-spoiler><font color=#FFFFFF>Test</font><span>"_s;
|
||||
const QString testOutputString1 = u"<span data-mx-spoiler><font color=#FFFFFF>Test</font><span>"_s;
|
||||
const QString testInputString1 = QStringLiteral("<span data-mx-spoiler><font color=#FFFFFF>Test</font><span>");
|
||||
const QString testOutputString1 = QStringLiteral("<span data-mx-spoiler><font color=#FFFFFF>Test</font><span>");
|
||||
// Handle urls where the href has either single (') or double (") quotes.
|
||||
const QString testInputString2 = u"<a href=\"https://kde.org\">link</a><a href='https://kde.org'>link</a>"_s;
|
||||
const QString testOutputString2 = u"<a href=\"https://kde.org\">link</a><a href='https://kde.org'>link</a>"_s;
|
||||
const QString testInputString2 = QStringLiteral("<a href=\"https://kde.org\">link</a><a href='https://kde.org'>link</a>");
|
||||
const QString testOutputString2 = QStringLiteral("<a href=\"https://kde.org\">link</a><a href='https://kde.org'>link</a>");
|
||||
|
||||
TextHandler testTextHandler;
|
||||
testTextHandler.setData(testInputString1);
|
||||
@@ -104,8 +103,8 @@ void TextHandlerTest::allowedAttributes()
|
||||
|
||||
void TextHandlerTest::stripDisallowedTags()
|
||||
{
|
||||
const QString testInputString = u"<p>Allowed</p> <span>Allowed</span> <body>Disallowed</body>"_s;
|
||||
const QString testOutputString = u"<p>Allowed</p> <span>Allowed</span> Disallowed"_s;
|
||||
const QString testInputString = QStringLiteral("<p>Allowed</p> <span>Allowed</span> <body>Disallowed</body>");
|
||||
const QString testOutputString = QStringLiteral("<p>Allowed</p> <span>Allowed</span> Disallowed");
|
||||
|
||||
TextHandler testTextHandler;
|
||||
testTextHandler.setData(testInputString);
|
||||
@@ -116,8 +115,8 @@ void TextHandlerTest::stripDisallowedTags()
|
||||
|
||||
void TextHandlerTest::stripDisallowedAttributes()
|
||||
{
|
||||
const QString testInputString = u"<p style=\"font-size:50px;\" color=#FFFFFF>Test</p>"_s;
|
||||
const QString testOutputString = u"Test"_s;
|
||||
const QString testInputString = QStringLiteral("<p style=\"font-size:50px;\" color=#FFFFFF>Test</p>");
|
||||
const QString testOutputString = QStringLiteral("Test");
|
||||
|
||||
TextHandler testTextHandler;
|
||||
testTextHandler.setData(testInputString);
|
||||
@@ -132,8 +131,8 @@ void TextHandlerTest::stripDisallowedAttributes()
|
||||
*/
|
||||
void TextHandlerTest::emptyCodeTags()
|
||||
{
|
||||
const QString testInputString = u"<pre><code></code></pre>"_s;
|
||||
const QString testOutputString = u"<pre><code></code></pre>"_s;
|
||||
const QString testInputString = QStringLiteral("<pre><code></code></pre>");
|
||||
const QString testOutputString = QStringLiteral("<pre><code></code></pre>");
|
||||
|
||||
TextHandler testTextHandler;
|
||||
testTextHandler.setData(testInputString);
|
||||
@@ -144,8 +143,8 @@ void TextHandlerTest::emptyCodeTags()
|
||||
|
||||
void TextHandlerTest::sendSimpleStringCase()
|
||||
{
|
||||
const QString testInputString = u"This data should just be left alone."_s;
|
||||
const QString testOutputString = u"This data should just be left alone."_s;
|
||||
const QString testInputString = QStringLiteral("This data should just be left alone.");
|
||||
const QString testOutputString = QStringLiteral("This data should just be left alone.");
|
||||
|
||||
TextHandler testTextHandler;
|
||||
testTextHandler.setData(testInputString);
|
||||
@@ -155,10 +154,11 @@ void TextHandlerTest::sendSimpleStringCase()
|
||||
|
||||
void TextHandlerTest::sendSingleParaMarkup()
|
||||
{
|
||||
const QString testInputString =
|
||||
u"Text para with **bold**, *italic*, [link](https://kde.org), , `inline code`."_s;
|
||||
const QString testOutputString =
|
||||
u"Text para with <strong>bold</strong>, <em>italic</em>, <a href=\"https://kde.org\">link</a>, <img src=\"mxc://kde.org/aebd3ffd40503e1ef0525bf8f0d60282fec6183e\" alt=\"image\">, <code>inline code</code>."_s;
|
||||
const QString testInputString = QStringLiteral(
|
||||
"Text para with **bold**, *italic*, [link](https://kde.org), , `inline code`.");
|
||||
const QString testOutputString = QStringLiteral(
|
||||
"Text para with <strong>bold</strong>, <em>italic</em>, <a href=\"https://kde.org\">link</a>, <img "
|
||||
"src=\"mxc://kde.org/aebd3ffd40503e1ef0525bf8f0d60282fec6183e\" alt=\"image\">, <code>inline code</code>.");
|
||||
|
||||
TextHandler testTextHandler;
|
||||
testTextHandler.setData(testInputString);
|
||||
@@ -169,9 +169,11 @@ void TextHandlerTest::sendSingleParaMarkup()
|
||||
void TextHandlerTest::sendMultipleSectionMarkup()
|
||||
{
|
||||
const QString testInputString =
|
||||
u"Text para\n> blockquote\n* List 1\n* List 2\n1. one\n2. two\n# Heading 1\n## Heading 2\nhorizontal rule\n\n---\n```\ncodeblock\n```"_s;
|
||||
const QString testOutputString =
|
||||
u"<p>Text para</p>\n<blockquote>\n<p>blockquote</p>\n</blockquote>\n<ul>\n<li>List 1</li>\n<li>List 2</li>\n</ul>\n<ol>\n<li>one</li>\n<li>two</li>\n</ol>\n<h1>Heading 1</h1>\n<h2>Heading 2</h2>\n<p>horizontal rule</p>\n<hr>\n<pre><code>codeblock\n</code></pre>"_s;
|
||||
QStringLiteral("Text para\n> blockquote\n* List 1\n* List 2\n1. one\n2. two\n# Heading 1\n## Heading 2\nhorizontal rule\n\n---\n```\ncodeblock\n```");
|
||||
const QString testOutputString = QStringLiteral(
|
||||
"<p>Text para</p>\n<blockquote>\n<p>blockquote</p>\n</blockquote>\n<ul>\n<li>List 1</li>\n<li>List "
|
||||
"2</li>\n</ul>\n<ol>\n<li>one</li>\n<li>two</li>\n</ol>\n<h1>Heading 1</h1>\n<h2>Heading 2</h2>\n<p>horizontal "
|
||||
"rule</p>\n<hr>\n<pre><code>codeblock\n</code></pre>");
|
||||
|
||||
TextHandler testTextHandler;
|
||||
testTextHandler.setData(testInputString);
|
||||
@@ -181,8 +183,8 @@ void TextHandlerTest::sendMultipleSectionMarkup()
|
||||
|
||||
void TextHandlerTest::sendBadLinks()
|
||||
{
|
||||
const QString testInputString = u"[link](kde.org), "_s;
|
||||
const QString testOutputString = u"<a>link</a>, <img alt=\"image\">"_s;
|
||||
const QString testInputString = QStringLiteral("[link](kde.org), ");
|
||||
const QString testOutputString = QStringLiteral("<a>link</a>, <img alt=\"image\">");
|
||||
|
||||
TextHandler testTextHandler;
|
||||
testTextHandler.setData(testInputString);
|
||||
@@ -195,9 +197,9 @@ void TextHandlerTest::sendBadLinks()
|
||||
*/
|
||||
void TextHandlerTest::sendEscapeCode()
|
||||
{
|
||||
const QString testInputString = u"```\n<p>Test <span style=\"font-size:50px;\">some</span> code</p>\n```"_s;
|
||||
const QString testInputString = QStringLiteral("```\n<p>Test <span style=\"font-size:50px;\">some</span> code</p>\n```");
|
||||
const QString testOutputString =
|
||||
u"<pre><code><p>Test <span style="font-size:50px;">some</span> code</p>\n</code></pre>"_s;
|
||||
QStringLiteral("<pre><code><p>Test <span style="font-size:50px;">some</span> code</p>\n</code></pre>");
|
||||
|
||||
TextHandler testTextHandler;
|
||||
testTextHandler.setData(testInputString);
|
||||
@@ -207,8 +209,8 @@ void TextHandlerTest::sendEscapeCode()
|
||||
|
||||
void TextHandlerTest::sendCodeClass()
|
||||
{
|
||||
const QString testInputString = u"```html\nsome code\n```\n<pre><code class=\"code-underline\">some more code</code></pre>"_s;
|
||||
const QString testOutputString = u"<pre><code class=\"language-html\">some code\n</code></pre>\n<pre><code>some more code</code></pre>"_s;
|
||||
const QString testInputString = QStringLiteral("```html\nsome code\n```\n<pre><code class=\"code-underline\">some more code</code></pre>");
|
||||
const QString testOutputString = QStringLiteral("<pre><code class=\"language-html\">some code\n</code></pre>\n<pre><code>some more code</code></pre>");
|
||||
|
||||
TextHandler testTextHandler;
|
||||
testTextHandler.setData(testInputString);
|
||||
@@ -218,9 +220,9 @@ void TextHandlerTest::sendCodeClass()
|
||||
|
||||
void TextHandlerTest::sendCustomEmoji()
|
||||
{
|
||||
const QString testInputString = u":test:"_s;
|
||||
const QString testInputString = QStringLiteral(":test:");
|
||||
const QString testOutputString =
|
||||
u"<img data-mx-emoticon=\"\" src=\"mxc://example.org/test\" alt=\":test:\" title=\":test:\" height=\"32\" vertical-align=\"middle\" />"_s;
|
||||
QStringLiteral("<img data-mx-emoticon=\"\" src=\"mxc://example.org/test\" alt=\":test:\" title=\":test:\" height=\"32\" vertical-align=\"middle\" />");
|
||||
|
||||
TextHandler testTextHandler;
|
||||
testTextHandler.setData(testInputString);
|
||||
@@ -233,8 +235,8 @@ void TextHandlerTest::sendCustomEmojiCode_data()
|
||||
QTest::addColumn<QString>("testInputString");
|
||||
QTest::addColumn<QString>("testOutputString");
|
||||
|
||||
QTest::newRow("inline") << u"`:test:`"_s << u"<code>:test:</code>"_s;
|
||||
QTest::newRow("block") << u"```\n:test:\n```"_s << u"<pre><code>:test:\n</code></pre>"_s;
|
||||
QTest::newRow("inline") << QStringLiteral("`:test:`") << QStringLiteral("<code>:test:</code>");
|
||||
QTest::newRow("block") << QStringLiteral("```\n:test:\n```") << QStringLiteral("<pre><code>:test:\n</code></pre>");
|
||||
}
|
||||
|
||||
// Custom emojis in code blocks should be left alone.
|
||||
@@ -251,9 +253,9 @@ void TextHandlerTest::sendCustomEmojiCode()
|
||||
|
||||
void TextHandlerTest::receiveSpacelessSelfClosingTag()
|
||||
{
|
||||
const QString testInputString = u"Test...<br/>...ing"_s;
|
||||
const QString testRichOutputString = u"Test...<br/>...ing"_s;
|
||||
const QString testPlainOutputString = u"Test...\n...ing"_s;
|
||||
const QString testInputString = QStringLiteral("Test...<br/>...ing");
|
||||
const QString testRichOutputString = QStringLiteral("Test...<br/>...ing");
|
||||
const QString testPlainOutputString = QStringLiteral("Test...\n...ing");
|
||||
|
||||
TextHandler testTextHandler;
|
||||
testTextHandler.setData(testInputString);
|
||||
@@ -264,9 +266,10 @@ void TextHandlerTest::receiveSpacelessSelfClosingTag()
|
||||
|
||||
void TextHandlerTest::receiveStripReply()
|
||||
{
|
||||
const QString testInputString =
|
||||
u"<mx-reply><blockquote><a href=\"https://matrix.to/#/!somewhere:example.org/$event:example.org\">In reply to</a><a href=\"https://matrix.to/#/@alice:example.org\">@alice:example.org</a><br />Message replied to.</blockquote></mx-reply>Reply message."_s;
|
||||
const QString testOutputString = u"Reply message."_s;
|
||||
const QString testInputString = QStringLiteral(
|
||||
"<mx-reply><blockquote><a href=\"https://matrix.to/#/!somewhere:example.org/$event:example.org\">In reply to</a><a "
|
||||
"href=\"https://matrix.to/#/@alice:example.org\">@alice:example.org</a><br />Message replied to.</blockquote></mx-reply>Reply message.");
|
||||
const QString testOutputString = QStringLiteral("Reply message.");
|
||||
|
||||
TextHandler testTextHandler;
|
||||
testTextHandler.setData(testInputString);
|
||||
@@ -280,10 +283,10 @@ void TextHandlerTest::receiveRichInPlainOut_data()
|
||||
QTest::addColumn<QString>("testInputString");
|
||||
QTest::addColumn<QString>("testOutputString");
|
||||
|
||||
QTest::newRow("ampersand") << u"a & b"_s << u"a & b"_s;
|
||||
QTest::newRow("quote") << u""a and b""_s << u"\"a and b\""_s;
|
||||
QTest::newRow("new line") << u"new<br>line"_s << u"new\nline"_s;
|
||||
QTest::newRow("unescape") << u"can't"_s << u"can't"_s;
|
||||
QTest::newRow("ampersand") << QStringLiteral("a & b") << QStringLiteral("a & b");
|
||||
QTest::newRow("quote") << QStringLiteral(""a and b"") << QStringLiteral("\"a and b\"");
|
||||
QTest::newRow("new line") << QStringLiteral("new<br>line") << QStringLiteral("new\nline");
|
||||
QTest::newRow("unescape") << QStringLiteral("can't") << QStringLiteral("can't");
|
||||
}
|
||||
|
||||
void TextHandlerTest::receiveRichInPlainOut()
|
||||
@@ -299,13 +302,13 @@ void TextHandlerTest::receiveRichInPlainOut()
|
||||
|
||||
void TextHandlerTest::receivePlainTextIn()
|
||||
{
|
||||
const QString testInputString = u"<plain text in tag bracket>\nTest link https://kde.org."_s;
|
||||
const QString testOutputStringRich = u"<plain text in tag bracket><br>Test link <a href=\"https://kde.org\">https://kde.org</a>."_s;
|
||||
QString testOutputStringPlain = u"<plain text in tag bracket>\nTest link https://kde.org."_s;
|
||||
const QString testInputString = QStringLiteral("<plain text in tag bracket>\nTest link https://kde.org.");
|
||||
const QString testOutputStringRich = QStringLiteral("<plain text in tag bracket><br>Test link <a href=\"https://kde.org\">https://kde.org</a>.");
|
||||
QString testOutputStringPlain = QStringLiteral("<plain text in tag bracket>\nTest link https://kde.org.");
|
||||
|
||||
// Make sure quotes are maintained in a plain string.
|
||||
const QString testInputString2 = u"last line is \"Time to switch to a new topic.\""_s;
|
||||
const QString testOutputString2 = u"last line is \"Time to switch to a new topic.\""_s;
|
||||
const QString testInputString2 = QStringLiteral("last line is \"Time to switch to a new topic.\"");
|
||||
const QString testOutputString2 = QStringLiteral("last line is \"Time to switch to a new topic.\"");
|
||||
|
||||
TextHandler testTextHandler;
|
||||
testTextHandler.setData(testInputString);
|
||||
@@ -320,12 +323,12 @@ void TextHandlerTest::receivePlainTextIn()
|
||||
|
||||
void TextHandlerTest::receiveStripNewlines()
|
||||
{
|
||||
const QString testInputStringPlain = u"Test\nmany\nnew\nlines."_s;
|
||||
const QString testInputStringRich = u"Test<br>many<br />new<br>lines."_s;
|
||||
const QString testOutputString = u"Test many new lines."_s;
|
||||
const QString testInputStringPlain = QStringLiteral("Test\nmany\nnew\nlines.");
|
||||
const QString testInputStringRich = QStringLiteral("Test<br>many<br />new<br>lines.");
|
||||
const QString testOutputString = QStringLiteral("Test many new lines.");
|
||||
|
||||
const QString testInputStringPlain2 = u"* List\n* Items"_s;
|
||||
const QString testOutputString2 = u"List Items"_s;
|
||||
const QString testInputStringPlain2 = QStringLiteral("* List\n* Items");
|
||||
const QString testOutputString2 = QStringLiteral("List Items");
|
||||
|
||||
TextHandler testTextHandler;
|
||||
testTextHandler.setData(testInputStringPlain);
|
||||
@@ -347,8 +350,8 @@ void TextHandlerTest::receiveStripNewlines()
|
||||
*/
|
||||
void TextHandlerTest::receivePlainStripHtml()
|
||||
{
|
||||
const QString testInputString = u"<p>Test</p> <pre><code>Some code <strong>with tags</strong></code></pre>"_s;
|
||||
const QString testOutputString = u"Test Some code <strong>with tags</strong>"_s;
|
||||
const QString testInputString = QStringLiteral("<p>Test</p> <pre><code>Some code <strong>with tags</strong></code></pre>");
|
||||
const QString testOutputString = QStringLiteral("Test Some code <strong>with tags</strong>");
|
||||
|
||||
TextHandler testTextHandler;
|
||||
testTextHandler.setData(testInputString);
|
||||
@@ -358,8 +361,8 @@ void TextHandlerTest::receivePlainStripHtml()
|
||||
|
||||
void TextHandlerTest::receivePlainStripMarkup()
|
||||
{
|
||||
const QString testInputString = u"**bold** `<p>inline code</p>` *italic*"_s;
|
||||
const QString testOutputString = u"bold <p>inline code</p> italic"_s;
|
||||
const QString testInputString = QStringLiteral("**bold** `<p>inline code</p>` *italic*");
|
||||
const QString testOutputString = QStringLiteral("bold <p>inline code</p> italic");
|
||||
|
||||
TextHandler testTextHandler;
|
||||
testTextHandler.setData(testInputString);
|
||||
@@ -369,8 +372,8 @@ void TextHandlerTest::receivePlainStripMarkup()
|
||||
|
||||
void TextHandlerTest::receiveRichUserPill()
|
||||
{
|
||||
const QString testInputString = u"<p><a href=\"https://matrix.to/#/@alice:example.org\">@alice:example.org</a></p>"_s;
|
||||
const QString testOutputString = u"<b><a href=\"https://matrix.to/#/@alice:example.org\">@alice:example.org</a></b>"_s;
|
||||
const QString testInputString = QStringLiteral("<p><a href=\"https://matrix.to/#/@alice:example.org\">@alice:example.org</a></p>");
|
||||
const QString testOutputString = QStringLiteral("<b><a href=\"https://matrix.to/#/@alice:example.org\">@alice:example.org</a></b>");
|
||||
|
||||
TextHandler testTextHandler;
|
||||
testTextHandler.setData(testInputString);
|
||||
@@ -380,8 +383,8 @@ void TextHandlerTest::receiveRichUserPill()
|
||||
|
||||
void TextHandlerTest::receiveRichStrikethrough()
|
||||
{
|
||||
const QString testInputString = u"<p><del>Test</del></p>"_s;
|
||||
const QString testOutputString = u"<s>Test</s>"_s;
|
||||
const QString testInputString = QStringLiteral("<p><del>Test</del></p>");
|
||||
const QString testOutputString = QStringLiteral("<s>Test</s>");
|
||||
|
||||
TextHandler testTextHandler;
|
||||
testTextHandler.setData(testInputString);
|
||||
@@ -391,8 +394,8 @@ void TextHandlerTest::receiveRichStrikethrough()
|
||||
|
||||
void TextHandlerTest::receiveRichtextIn()
|
||||
{
|
||||
const QString testInputString = u"<p>Test</p> <pre><code>Some code <strong>with tags</strong></code></pre>"_s;
|
||||
const QString testOutputString = u"<p>Test</p> <pre><code>Some code <strong>with tags</strong></code></pre>"_s;
|
||||
const QString testInputString = QStringLiteral("<p>Test</p> <pre><code>Some code <strong>with tags</strong></code></pre>");
|
||||
const QString testOutputString = QStringLiteral("<p>Test</p> <pre><code>Some code <strong>with tags</strong></code></pre>");
|
||||
|
||||
TextHandler testTextHandler;
|
||||
testTextHandler.setData(testInputString);
|
||||
@@ -402,10 +405,15 @@ void TextHandlerTest::receiveRichtextIn()
|
||||
|
||||
void TextHandlerTest::receiveRichMxcUrl()
|
||||
{
|
||||
const QString testInputString =
|
||||
u"<img src=\"mxc://kde.org/aebd3ffd40503e1ef0525bf8f0d60282fec6183e\" alt=\"image\"><img src=\"mxc://kde.org/34c3464b3a1bd7f55af2d559e07d2c773c430e73\" alt=\"image\">"_s;
|
||||
const QString testOutputString =
|
||||
u"<img src=\"mxc://kde.org/aebd3ffd40503e1ef0525bf8f0d60282fec6183e?user_id=@bob:kde.org&room_id=%23myroom:kde.org&event_id=$143273582443PhrSn:example.org\" alt=\"image\"><img src=\"mxc://kde.org/34c3464b3a1bd7f55af2d559e07d2c773c430e73?user_id=@bob:kde.org&room_id=%23myroom:kde.org&event_id=$143273582443PhrSn:example.org\" alt=\"image\">"_s;
|
||||
const QString testInputString = QStringLiteral(
|
||||
"<img src=\"mxc://kde.org/aebd3ffd40503e1ef0525bf8f0d60282fec6183e\" alt=\"image\"><img src=\"mxc://kde.org/34c3464b3a1bd7f55af2d559e07d2c773c430e73\" "
|
||||
"alt=\"image\">");
|
||||
const QString testOutputString = QStringLiteral(
|
||||
"<img "
|
||||
"src=\"mxc://kde.org/aebd3ffd40503e1ef0525bf8f0d60282fec6183e?user_id=@bob:kde.org&room_id=%23myroom:kde.org&event_id=$143273582443PhrSn:example.org\" "
|
||||
"alt=\"image\"><img "
|
||||
"src=\"mxc://kde.org/34c3464b3a1bd7f55af2d559e07d2c773c430e73?user_id=@bob:kde.org&room_id=%23myroom:kde.org&event_id=$143273582443PhrSn:example.org\" "
|
||||
"alt=\"image\">");
|
||||
|
||||
TextHandler testTextHandler;
|
||||
testTextHandler.setData(testInputString);
|
||||
@@ -423,27 +431,38 @@ void TextHandlerTest::receiveRichPlainUrl()
|
||||
{
|
||||
// This is an actual link that caused trouble which is why it's so long. Keeping
|
||||
// so we can confirm consistent behaviour for complex urls.
|
||||
const QString testInputStringLink1 =
|
||||
u"https://matrix.to/#/!RvzunyTWZGfNxJVQqv:matrix.org/$-9TJVTh5PvW6MvIhFDwteiyLBVGriinueO5eeIazQS8?via=libera.chat&via=matrix.org&via=fedora.im <a href=\"https://matrix.to/#/!RvzunyTWZGfNxJVQqv:matrix.org/$-9TJVTh5PvW6MvIhFDwteiyLBVGriinueO5eeIazQS8?via=libera.chat&via=matrix.org&via=fedora.im\">Link already rich</a>"_s;
|
||||
const QString testOutputStringLink1 =
|
||||
u"<a href=\"https://matrix.to/#/!RvzunyTWZGfNxJVQqv:matrix.org/$-9TJVTh5PvW6MvIhFDwteiyLBVGriinueO5eeIazQS8?via=libera.chat&via=matrix.org&via=fedora.im\">https://matrix.to/#/!RvzunyTWZGfNxJVQqv:matrix.org/$-9TJVTh5PvW6MvIhFDwteiyLBVGriinueO5eeIazQS8?via=libera.chat&via=matrix.org&via=fedora.im</a> <a href=\"https://matrix.to/#/!RvzunyTWZGfNxJVQqv:matrix.org/$-9TJVTh5PvW6MvIhFDwteiyLBVGriinueO5eeIazQS8?via=libera.chat&via=matrix.org&via=fedora.im\">Link already rich</a>"_s;
|
||||
const QString testInputStringLink1 = QStringLiteral(
|
||||
"https://matrix.to/#/!RvzunyTWZGfNxJVQqv:matrix.org/$-9TJVTh5PvW6MvIhFDwteiyLBVGriinueO5eeIazQS8?via=libera.chat&via=matrix.org&via=fedora.im "
|
||||
"<a "
|
||||
"href=\"https://matrix.to/#/!RvzunyTWZGfNxJVQqv:matrix.org/"
|
||||
"$-9TJVTh5PvW6MvIhFDwteiyLBVGriinueO5eeIazQS8?via=libera.chat&via=matrix.org&via=fedora.im\">Link already rich</a>");
|
||||
const QString testOutputStringLink1 = QStringLiteral(
|
||||
"<a "
|
||||
"href=\"https://matrix.to/#/!RvzunyTWZGfNxJVQqv:matrix.org/"
|
||||
"$-9TJVTh5PvW6MvIhFDwteiyLBVGriinueO5eeIazQS8?via=libera.chat&via=matrix.org&via=fedora.im\">https://matrix.to/#/"
|
||||
"!RvzunyTWZGfNxJVQqv:matrix.org/$-9TJVTh5PvW6MvIhFDwteiyLBVGriinueO5eeIazQS8?via=libera.chat&via=matrix.org&via=fedora.im</a> <a "
|
||||
"href=\"https://matrix.to/#/!RvzunyTWZGfNxJVQqv:matrix.org/"
|
||||
"$-9TJVTh5PvW6MvIhFDwteiyLBVGriinueO5eeIazQS8?via=libera.chat&via=matrix.org&via=fedora.im\">Link already rich</a>");
|
||||
|
||||
// Another real case. The linkification wasn't handling it when a single link
|
||||
// contains what looks like and email. It was been broken into 3 but needs to
|
||||
// be just single link.
|
||||
const QString testInputStringLink2 = u"https://lore.kernel.org/lkml/CAHk-=wio46vC4t6xXD-sFqjoPwFm_u515jm3suzmkGxQTeA1_A@mail.gmail.com/"_s;
|
||||
const QString testOutputStringLink2 =
|
||||
u"<a href=\"https://lore.kernel.org/lkml/CAHk-=wio46vC4t6xXD-sFqjoPwFm_u515jm3suzmkGxQTeA1_A@mail.gmail.com/\">https://lore.kernel.org/lkml/CAHk-=wio46vC4t6xXD-sFqjoPwFm_u515jm3suzmkGxQTeA1_A@mail.gmail.com/</a>"_s;
|
||||
const QString testInputStringLink2 = QStringLiteral("https://lore.kernel.org/lkml/CAHk-=wio46vC4t6xXD-sFqjoPwFm_u515jm3suzmkGxQTeA1_A@mail.gmail.com/");
|
||||
const QString testOutputStringLink2 = QStringLiteral(
|
||||
"<a "
|
||||
"href=\"https://lore.kernel.org/lkml/CAHk-=wio46vC4t6xXD-sFqjoPwFm_u515jm3suzmkGxQTeA1_A@mail.gmail.com/\">https://lore.kernel.org/lkml/"
|
||||
"CAHk-=wio46vC4t6xXD-sFqjoPwFm_u515jm3suzmkGxQTeA1_A@mail.gmail.com/</a>");
|
||||
|
||||
QString testInputStringEmail = uR"(email@example.com <a href="mailto:email@example.com">Link already rich</a>)"_s;
|
||||
QString testOutputStringEmail = uR"(<a href="mailto:email@example.com">email@example.com</a> <a href="mailto:email@example.com">Link already rich</a>)"_s;
|
||||
QString testInputStringEmail = QStringLiteral(R"(email@example.com <a href="mailto:email@example.com">Link already rich</a>)");
|
||||
QString testOutputStringEmail =
|
||||
QStringLiteral(R"(<a href="mailto:email@example.com">email@example.com</a> <a href="mailto:email@example.com">Link already rich</a>)");
|
||||
|
||||
QString testInputStringMxId = u"@user:kde.org <a href=\"https://matrix.to/#/@user:kde.org\">Link already rich</a>"_s;
|
||||
QString testOutputStringMxId =
|
||||
u"<b><a href=\"https://matrix.to/#/@user:kde.org\">@user:kde.org</a></b> <b><a href=\"https://matrix.to/#/@user:kde.org\">Link already rich</a></b>"_s;
|
||||
QString testInputStringMxId = QStringLiteral("@user:kde.org <a href=\"https://matrix.to/#/@user:kde.org\">Link already rich</a>");
|
||||
QString testOutputStringMxId = QStringLiteral(
|
||||
"<b><a href=\"https://matrix.to/#/@user:kde.org\">@user:kde.org</a></b> <b><a href=\"https://matrix.to/#/@user:kde.org\">Link already rich</a></b>");
|
||||
|
||||
QString testInputStringMxIdWithPrefix = u"a @user:kde.org b"_s;
|
||||
QString testOutputStringMxIdWithPrefix = u"a <b><a href=\"https://matrix.to/#/@user:kde.org\">@user:kde.org</a></b> b"_s;
|
||||
QString testInputStringMxIdWithPrefix = QStringLiteral("a @user:kde.org b");
|
||||
QString testOutputStringMxIdWithPrefix = QStringLiteral("a <b><a href=\"https://matrix.to/#/@user:kde.org\">@user:kde.org</a></b> b");
|
||||
|
||||
TextHandler testTextHandler;
|
||||
testTextHandler.setData(testInputStringLink1);
|
||||
@@ -468,9 +487,9 @@ void TextHandlerTest::receiveRichEdited_data()
|
||||
QTest::addColumn<QString>("testInputString");
|
||||
QTest::addColumn<QString>("testOutputString");
|
||||
|
||||
QTest::newRow("basic") << u"Edited"_s << u"Edited <span style=\"color:#000000\">(edited)</span>"_s;
|
||||
QTest::newRow("multiple paragraphs") << u"<p>Edited</p>\n<p>Edited</p>"_s
|
||||
<< u"<p>Edited</p>\n<p>Edited <span style=\"color:#000000\">(edited)</span></p>"_s;
|
||||
QTest::newRow("basic") << QStringLiteral("Edited") << QStringLiteral("Edited <span style=\"color:#000000\">(edited)</span>");
|
||||
QTest::newRow("multiple paragraphs") << QStringLiteral("<p>Edited</p>\n<p>Edited</p>")
|
||||
<< QStringLiteral("<p>Edited</p>\n<p>Edited <span style=\"color:#000000\">(edited)</span></p>");
|
||||
}
|
||||
|
||||
void TextHandlerTest::receiveRichEdited()
|
||||
@@ -487,69 +506,61 @@ void TextHandlerTest::receiveRichEdited()
|
||||
|
||||
void TextHandlerTest::receiveLineSeparator()
|
||||
{
|
||||
auto text = u"foo\u2028bar"_s;
|
||||
auto text = QStringLiteral("foo\u2028bar");
|
||||
TextHandler textHandler;
|
||||
textHandler.setData(text);
|
||||
QCOMPARE(textHandler.handleRecievePlainText(Qt::PlainText, true), u"foo bar"_s);
|
||||
QCOMPARE(textHandler.handleRecievePlainText(Qt::PlainText, true), QStringLiteral("foo bar"));
|
||||
}
|
||||
|
||||
void TextHandlerTest::receiveRichCodeUrl()
|
||||
{
|
||||
auto input = u"<code>https://kde.org</code>"_s;
|
||||
auto input = QStringLiteral("<code>https://kde.org</code>");
|
||||
TextHandler testTextHandler;
|
||||
testTextHandler.setData(input);
|
||||
QCOMPARE(testTextHandler.handleRecieveRichText(), input);
|
||||
}
|
||||
|
||||
void TextHandlerTest::receiveRichColor()
|
||||
{
|
||||
const QString testInputString =
|
||||
u"<span data-mx-color=\"#ff00be\">¯</span><span data-mx-color=\"#ff3b1d\">\\</span><span data-mx-color=\"#ffa600\">_</span><span data-mx-color=\"#64d200\">(</span><span data-mx-color=\"#00e261\">ツ</span><span data-mx-color=\"#00e7ff\">)</span><span data-mx-color=\"#00e1ff\">_</span><span data-mx-color=\"#00bdff\">/</span><span data-mx-color=\"#ff60ff\">¯</span>"_s;
|
||||
const QString testOutputString =
|
||||
u"<span style=\"color: #ff00be;\">¯</span><span style=\"color: #ff3b1d;\">\\</span><span style=\"color: #ffa600;\">_</span><span style=\"color: #64d200;\">(</span><span style=\"color: #00e261;\">ツ</span><span style=\"color: #00e7ff;\">)</span><span style=\"color: #00e1ff;\">_</span><span style=\"color: #00bdff;\">/</span><span style=\"color: #ff60ff;\">¯</span>"_s;
|
||||
|
||||
TextHandler testTextHandler;
|
||||
testTextHandler.setData(testInputString);
|
||||
|
||||
qInfo() << testTextHandler.handleRecieveRichText();
|
||||
|
||||
QCOMPARE(testTextHandler.handleRecieveRichText(), testOutputString);
|
||||
}
|
||||
|
||||
void TextHandlerTest::componentOutput_data()
|
||||
{
|
||||
QTest::addColumn<QString>("testInputString");
|
||||
QTest::addColumn<QList<MessageComponent>>("testOutputComponents");
|
||||
|
||||
QTest::newRow("multiple paragraphs") << u"<p>Text</p>\n<p>Text</p>"_s
|
||||
<< QList<MessageComponent>{MessageComponent{MessageComponentType::Text, u"Text"_s, {}},
|
||||
MessageComponent{MessageComponentType::Text, u"Text"_s, {}}};
|
||||
QTest::newRow("code") << u"<p>Text</p>\n<pre><code class=\"language-html\">Some code\n</code></pre>"_s
|
||||
<< QList<MessageComponent>{MessageComponent{MessageComponentType::Text, u"Text"_s, {}},
|
||||
MessageComponent{MessageComponentType::Code, u"Some code"_s, QVariantMap{{u"class"_s, u"html"_s}}}};
|
||||
QTest::newRow("quote") << u"<p>Text</p>\n<blockquote>\n<p>blockquote</p>\n</blockquote>"_s
|
||||
<< QList<MessageComponent>{MessageComponent{MessageComponentType::Text, u"Text"_s, {}},
|
||||
MessageComponent{MessageComponentType::Quote, u"“blockquote”"_s, {}}};
|
||||
QTest::newRow("no tag first paragraph") << u"Text\n<p>Text</p>"_s
|
||||
<< QList<MessageComponent>{MessageComponent{MessageComponentType::Text, u"Text"_s, {}},
|
||||
MessageComponent{MessageComponentType::Text, u"Text"_s, {}}};
|
||||
QTest::newRow("no tag last paragraph") << u"<p>Text</p>\nText"_s
|
||||
<< QList<MessageComponent>{MessageComponent{MessageComponentType::Text, u"Text"_s, {}},
|
||||
MessageComponent{MessageComponentType::Text, u"Text"_s, {}}};
|
||||
QTest::newRow("inline code") << u"<p><code>https://kde.org</code></p>\n<p>Text</p>"_s
|
||||
<< QList<MessageComponent>{MessageComponent{MessageComponentType::Text, u"<code>https://kde.org</code>"_s, {}},
|
||||
MessageComponent{MessageComponentType::Text, u"Text"_s, {}}};
|
||||
QTest::newRow("inline code single block") << u"<code>https://kde.org</code>"_s
|
||||
<< QList<MessageComponent>{MessageComponent{MessageComponentType::Text, u"<code>https://kde.org</code>"_s, {}}};
|
||||
QTest::newRow("multiple paragraphs") << QStringLiteral("<p>Text</p>\n<p>Text</p>")
|
||||
<< QList<MessageComponent>{MessageComponent{MessageComponentType::Text, QStringLiteral("Text"), {}},
|
||||
MessageComponent{MessageComponentType::Text, QStringLiteral("Text"), {}}};
|
||||
QTest::newRow("code") << QStringLiteral("<p>Text</p>\n<pre><code class=\"language-html\">Some code\n</code></pre>")
|
||||
<< QList<MessageComponent>{MessageComponent{MessageComponentType::Text, QStringLiteral("Text"), {}},
|
||||
MessageComponent{MessageComponentType::Code,
|
||||
QStringLiteral("Some code"),
|
||||
QVariantMap{{QStringLiteral("class"), QStringLiteral("html")}}}};
|
||||
QTest::newRow("quote") << QStringLiteral("<p>Text</p>\n<blockquote>\n<p>blockquote</p>\n</blockquote>")
|
||||
<< QList<MessageComponent>{MessageComponent{MessageComponentType::Text, QStringLiteral("Text"), {}},
|
||||
MessageComponent{MessageComponentType::Quote, QStringLiteral("“blockquote”"), {}}};
|
||||
QTest::newRow("no tag first paragraph") << QStringLiteral("Text\n<p>Text</p>")
|
||||
<< QList<MessageComponent>{MessageComponent{MessageComponentType::Text, QStringLiteral("Text"), {}},
|
||||
MessageComponent{MessageComponentType::Text, QStringLiteral("Text"), {}}};
|
||||
QTest::newRow("no tag last paragraph") << QStringLiteral("<p>Text</p>\nText")
|
||||
<< QList<MessageComponent>{MessageComponent{MessageComponentType::Text, QStringLiteral("Text"), {}},
|
||||
MessageComponent{MessageComponentType::Text, QStringLiteral("Text"), {}}};
|
||||
QTest::newRow("inline code") << QStringLiteral("<p><code>https://kde.org</code></p>\n<p>Text</p>")
|
||||
<< QList<MessageComponent>{MessageComponent{MessageComponentType::Text, QStringLiteral("<code>https://kde.org</code>"), {}},
|
||||
MessageComponent{MessageComponentType::Text, QStringLiteral("Text"), {}}};
|
||||
QTest::newRow("inline code single block") << QStringLiteral("<code>https://kde.org</code>")
|
||||
<< QList<MessageComponent>{
|
||||
MessageComponent{MessageComponentType::Text, QStringLiteral("<code>https://kde.org</code>"), {}}};
|
||||
QTest::newRow("long start tag")
|
||||
<< u"Ah, you mean something like<br/><pre data-md=\"```\"><code class=\"language-qml\"># main.qml\nimport CustomQml\n...\nControls.TextField { id: someField }\nCustomQml {\n someTextProperty: someField.text\n}\n</code></pre>Sure you can, it's still local to the same file where you defined the id"_s
|
||||
<< QStringLiteral(
|
||||
"Ah, you mean something like<br/><pre data-md=\"```\"><code class=\"language-qml\"># main.qml\nimport CustomQml\n...\nControls.TextField { id: "
|
||||
"someField }\nCustomQml {\n someTextProperty: someField.text\n}\n</code></pre>Sure you can, it's still local to the same file where you "
|
||||
"defined the id")
|
||||
<< QList<MessageComponent>{
|
||||
MessageComponent{MessageComponentType::Text, u"Ah, you mean something like<br/>"_s, {}},
|
||||
MessageComponent{MessageComponentType::Text, QStringLiteral("Ah, you mean something like<br/>"), {}},
|
||||
MessageComponent{
|
||||
MessageComponentType::Code,
|
||||
u"# main.qml\nimport CustomQml\n...\nControls.TextField { id: someField }\nCustomQml {\n someTextProperty: someField.text\n}"_s,
|
||||
QVariantMap{{u"class"_s, u"qml"_s}}},
|
||||
MessageComponent{MessageComponentType::Text, u"Sure you can, it's still local to the same file where you defined the id"_s, {}}};
|
||||
QStringLiteral(
|
||||
"# main.qml\nimport CustomQml\n...\nControls.TextField { id: someField }\nCustomQml {\n someTextProperty: someField.text\n}"),
|
||||
QVariantMap{{QStringLiteral("class"), QStringLiteral("qml")}}},
|
||||
MessageComponent{MessageComponentType::Text, QStringLiteral("Sure you can, it's still local to the same file where you defined the id"), {}}};
|
||||
}
|
||||
|
||||
void TextHandlerTest::componentOutput()
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
<name xml:lang="fr">NeoChat</name>
|
||||
<name xml:lang="gl">NeoChat</name>
|
||||
<name xml:lang="he">NeoChat</name>
|
||||
<name xml:lang="hi">नियोचैट</name>
|
||||
<name xml:lang="hu">NeoChat</name>
|
||||
<name xml:lang="ia">Neochat</name>
|
||||
<name xml:lang="id">NeoChat</name>
|
||||
@@ -42,7 +41,6 @@
|
||||
<name xml:lang="pt">NeoChat</name>
|
||||
<name xml:lang="pt-BR">NeoChat</name>
|
||||
<name xml:lang="ru">NeoChat</name>
|
||||
<name xml:lang="sa">नवचैट्</name>
|
||||
<name xml:lang="sk">NeoChat</name>
|
||||
<name xml:lang="sl">NeoChat</name>
|
||||
<name xml:lang="sv">NeoChat</name>
|
||||
@@ -58,14 +56,12 @@
|
||||
<summary xml:lang="ca-valencia">Xat a Matrix</summary>
|
||||
<summary xml:lang="de">Über Matrix unterhalten</summary>
|
||||
<summary xml:lang="en-GB">Chat on Matrix</summary>
|
||||
<summary xml:lang="eo">Babilo en Matrix</summary>
|
||||
<summary xml:lang="es">Charle en Matrix</summary>
|
||||
<summary xml:lang="eu">Berriketa Matrix-en</summary>
|
||||
<summary xml:lang="fi">Keskustelu Matrixissä</summary>
|
||||
<summary xml:lang="fr">Discuter sur Matrix</summary>
|
||||
<summary xml:lang="gl">Charlar en Matrix</summary>
|
||||
<summary xml:lang="he">התכתבות דרך Matrix</summary>
|
||||
<summary xml:lang="hi">मैट्रिक्स पर चैट करें</summary>
|
||||
<summary xml:lang="hu">Csevegés Matrixon</summary>
|
||||
<summary xml:lang="ia">Conversation en ditecto sur Matrix</summary>
|
||||
<summary xml:lang="it">Chat su Matrix</summary>
|
||||
@@ -74,7 +70,6 @@
|
||||
<summary xml:lang="nl">Chat op Matrix</summary>
|
||||
<summary xml:lang="nn">Prat med via Matrix</summary>
|
||||
<summary xml:lang="pl">Rozmawiaj na Matriksie</summary>
|
||||
<summary xml:lang="sa">Matrix इत्यत्र गपशपं कुर्वन्तु</summary>
|
||||
<summary xml:lang="sl">Klepet na Matrixu</summary>
|
||||
<summary xml:lang="sv">Chatta på Matrix</summary>
|
||||
<summary xml:lang="ta">மேட்ரிக்ஸுக்கான உரையாடல் செயலி</summary>
|
||||
@@ -97,7 +92,6 @@
|
||||
<p xml:lang="fr">NeoChat est une application de discussions vous permettant de profiter pleinement du réseau Matrix. Elle vous offre un moyen sécurisé d'envoyer des messages de texte, des vidéos et des fichiers audio à votre famille, vos collègues et vos ami(e)s.</p>
|
||||
<p xml:lang="gl">NeoChat é unha aplicación de conversa que lle permite usar todas as funcionalidades da rede Matrix. Fornece unha forma segura de enviar mensaxes de texto e ficheiros de vídeo e son a familiares, amizades ou no traballo.</p>
|
||||
<p xml:lang="he">NeoChat הוא יישום התכתבות שמאפשר לך לנצל את רשת Matrix במלואה. הוא מספק דרך מאובטחת לשליחת הודעות כתובות, סרטונים וקובצי שמע למשפחה, לעמיתים לעבודה ולחברים.</p>
|
||||
<p xml:lang="hi">नियोचैट एक चैट ऐप है जो आपको मैट्रिक्स नेटवर्क का पूरा लाभ उठाने देता है। यह आपको अपने परिवार, सहकर्मियों और दोस्तों को टेक्स्ट संदेश, वीडियो और ऑडियो फ़ाइलें भेजने का एक सुरक्षित तरीका प्रदान करता है।</p>
|
||||
<p xml:lang="hu">A NeoChat egy olyan csevegőalkalmazás, amellyel teljes mértékben kihasználhatja a Matrix hálózatot. Biztonságos módot biztosít szöveges üzenetek, videók és hangfájlok küldéséhez családtagjainak, kollégáinak és barátainak.</p>
|
||||
<p xml:lang="ia">NeoChat es un app de conversation que te permitte prender avantage plen del rete Matrix. Il te forni un modo secur de inviar messages de texto, videos e files audio a tui familia, collegas e amicos.</p>
|
||||
<p xml:lang="it">NeoChat è un'applicazione di chat che ti consente di sfruttare appieno la rete Matrix. Ti fornisce un modo sicuro per inviare messaggi di testo, video e file audio a familiari, colleghi e amici.</p>
|
||||
@@ -107,7 +101,6 @@
|
||||
<p xml:lang="nn">NeoChat er ein prateapp som lèt deg bruka all funksjonalitet i Matrix-nettverket. Du kan utveksla tekst, lyd og videoar med vennar, familie og kollegaar på ein trygg måte.</p>
|
||||
<p xml:lang="pl">NoeChat to aplikacja do rozmów, która umożliwia wykorzystanie wszystkich możliwości Matriksa. Umożliwia wysyłanie wiadomości tekstowych, filmów i dźwięków w bezpieczny sposób do twojej rodziny, kolegów i przyjaciół.</p>
|
||||
<p xml:lang="ru">NeoChat — приложение для общения, предоставляющее все преимущества сети Matrix. С его помощью можно безопасно отправлять текстовые сообщения, видеозаписи и звуковые файлы родственникам, коллегам и друзьям.</p>
|
||||
<p xml:lang="sa">NeoChat इति एकं गपशप-अनुप्रयोगं यत् भवान् Matrix-जालस्य पूर्णं लाभं ग्रहीतुं शक्नोति । एतत् भवन्तं भवतः परिवाराय, सहकारिभ्यः, मित्रेभ्यः च पाठसन्देशान्, भिडियो, श्रव्यसञ्चिकाः च प्रेषयितुं सुरक्षितं मार्गं प्रदाति ।</p>
|
||||
<p xml:lang="sl">NeoChat je aplikacija za klepet, ki vam omogoča, da v celoti izkoristite omrežje Matrix. Zagotavlja vam varen način za pošiljanje besedilnih sporočil, videoposnetkov in zvočnih datotek vaši družini, sodelavcem in prijateljem.</p>
|
||||
<p xml:lang="sv">NeoChat är ett chattprogram som låter dig dra full nytta av Matrix-nätverket. Det ger dig ett säkert sätt att skicka textmeddelanden, videor och ljudfiler till din familj, kollegor och vänner.</p>
|
||||
<p xml:lang="tr">NeoChat, Matrix ağının tüm özelliklerini kullanan bir sohbet uygulamasıdır. Ailenize, arkadaşlarınıza ve iş arkadaşlarınıza metin iletileri, ses ve video dosyaları göndermenin kolay bir yolunu sunar.</p>
|
||||
@@ -126,9 +119,8 @@
|
||||
<p xml:lang="eu">«NeoChat»ek «Matrix» zehaztapenaren ezaugarri guztiak eskaintzen dituen aplikazio bat izan nahi du. Beraz, egungo zehaztapen egonkorrean dagoen guztiaren euskarria du, VoIP, hariak eta muturren artean zifratzeko salbuespen nabarmenekin. Badira beste ez-betetze txikiago batzuk, «Matrix»en zehaztapena etengabe eboluzioan dagoelako, baina azken helburua zehaztapen osoaren euskarria ematea izaten jarraitzen du.</p>
|
||||
<p xml:lang="fi">NeoChat pyrkii olemaan Matrix-määritelmän täysominaisuuksinen sovellus, joten se tukee kaikkea nykyisessä vakaassa määritelmässä muutamaa huomattavaa poikkeusta lukuun ottamatta (VoIP, säikeet ja jotkin piirteet päästä päähän -salauksessa). Joitakin pienempiäkin puutteita on Matrix-määritelmän jatkuvan kehityksen vuoksi, mutta lopputavoitteena on tarjota määritelmän täysi tuki.</p>
|
||||
<p xml:lang="fr">L'objectif de NeoChat est d'être une application complète pour le protocole Matrix. En tant que tel, tout dans la spécification stable actuelle avec les exceptions notables de VoIP, les processus et certains aspects du chiffrement de bout en bout sont pris en charge. Il y a quelques autres petites omissions en raison du fait que la spécification du protocole Matrix est en constante évolution. Cependant, l'objectif reste de fournir un soutien éventuel pour l'ensemble de la spécification.</p>
|
||||
<p xml:lang="gl">NeoChat pretende ser unha aplicación completa para a especificación de Matrix. Coas excepcións de VoIP, conversas fiadas e algúns aspectos da cifraxe de extremo a extremo, a versión estábel segue as especificacións. Existen algunhas outras pequenas omisións debido ao feito de que Matrix está en continua evolución pero a intención é fornecer compatibilidade coa especificación completa.</p>
|
||||
<p xml:lang="gl">NeoChat pretende ser unha aplicación completa para a especificación de Matrix. Coas excepcións de VoIP, conversas fiadas e algúns aspectos da cifraxe de extremo a extremo, a versión estábel segue as especificacións. Existen algunhas outras pequenas omisións debido ao feito de que Matrix está en continua evolución pero a intención é implementar a especificación completa.</p>
|
||||
<p xml:lang="he">NeoChat מתיימר להיות יישום עתיר יכולות לפי מפרט Matrix. כיוון שזה ייעודו, כל מה שבמפרט היציב עם חריגות משמעותיות כגון VoIP, שרשורים ועוד מגוון היבטים של הצפנה מקצה לקצה נתמכים גם הם. יש מספר השמטות קטן עקב העובדה שהמפרט של Matrix ממשיך להתפתח אך המטרה היא להמשיך לספק תמיכה בסופו של דבר לכל המפרט.</p>
|
||||
<p xml:lang="hi">नियोचैट का लक्ष्य मैट्रिक्स विनिर्देश के लिए एक पूर्ण विशेषताओं वाला अनुप्रयोग बनना है। इस प्रकार वर्तमान स्थिर विनिर्देश में वीओआईपी, थ्रेड्स और एंड-टू-एंड एन्क्रिप्शन के कुछ पहलुओं के उल्लेखनीय अपवादों के साथ सब कुछ समर्थित है। मैट्रिक्स विनिर्देश लगातार विकसित हो रहा है, इस तथ्य के कारण कुछ अन्य छोटी चूकें हैं, लेकिन उद्देश्य पूरे विनिर्देश के लिए अंतिम समर्थन प्रदान करना है।</p>
|
||||
<p xml:lang="hu">A NeoChat célja, hogy a Matrix specifikációnak megfelelő teljes funkcionalitású alkalmazás legyen. Mint ilyen, a jelenlegi stabil specifikáció támogatott a VoIP, a szálak és a végpontok közötti titkosítás egyes elemeinek kivételével. Van még néhány kisebb hiányosság annak köszönhetően, hogy a Matrix specifikáció folyamatosan fejlődik, de végső cél a teljes specifikáció megvalósítása.</p>
|
||||
<p xml:lang="ia">NeoChat aspira a esser un application plenmente eminente per le specification de Matrix. Tal como omne cosas in le specification currentemente stabile con le exceptiones notabile de VOIP, threads e alcun aspectos del cryptation End-to-End es supportate. Il ha ltere pauc omissiones, debite al facto que le specification de Matrix es in evolution constante ma le aspiration remane a fornir supporto eventual per le integre specification.</p>
|
||||
<p xml:lang="it">NeoChat mira ad essere un'applicazione completa per le specifiche Matrix. Pertanto, sono supportati tutti gli elementi dell'attuale specifica stabile con le notevoli eccezioni di VoIP, conversazioni e alcuni aspetti della cifratura end-to-end. Ci sono alcune altre piccole omissioni dovute al fatto che le specifiche Matrix sono in continua evoluzione, ma l'obiettivo rimane quello di fornire un eventuale supporto per l'intera specifica.</p>
|
||||
@@ -140,7 +132,6 @@
|
||||
<p xml:lang="pl">NeoChat w zamyśle ma być pełnowartościową aplikacją wg wytycznych Matriksa. Z tego powodu, wszystko, co jest obecnie w stabilnych wytycznych z pominięciem VoIP, wątków i niektórych części szyfrowania Użytkownik-do-Użytkownika są obecnie obsługiwane. Pominięto też kilka mniejszych rzeczy ze względu na ciągły rozwój wytycznych Matriksa, lecz celem nadal jest zapewnienie obsługi wszystkich wytycznych.</p>
|
||||
<p xml:lang="pt">O NeoChat pretende ser uma aplicação completa para a especificação do Matrix. Como tal, tudo o que existe na especificação estável actual, com as notáveis excepções do VoIP, tópicos e alguns aspectos da Encriptação Ponto-a-Ponto, são suportados. Existem mais algumas omissões, devido ao facto que a norma do Matrix está em constante evolução, mas o objectivo continua a ser oferecer o suporte eventual para a norma por inteiro.</p>
|
||||
<p xml:lang="ru">Целью создания NeoChat является полноценная реализация программы для спецификации Matrix. Как следствие, реализовано всё в текущей стабильной спецификации (за исключением голосовой интернет-связи, потоков и некоторых аспектов сквозного шифрования). Есть также несколько других незначительных пробелов, обусловленных постоянными изменениями спецификации Matrix. Тем не менее, стоит задача в итоге предоставить полную поддержку спецификации.</p>
|
||||
<p xml:lang="sa">NeoChat इत्यस्य उद्देश्यं Matrix विनिर्देशस्य कृते पूर्णतया विशेषतायुक्तः अनुप्रयोगः भवितुम् अस्ति । यथा तथा वर्तमानस्थिरविनिर्देशे सर्वं VoIP इत्यस्य उल्लेखनीयअपवादैः सह, थ्रेड्स तथा च End-to-End Encryption इत्यस्य केचन पक्षाः समर्थिताः सन्ति । अन्ये कतिचन लघु लोपाः सन्ति यतोहि Matrix spec निरन्तरं विकसितः अस्ति परन्तु उद्देश्यं सम्पूर्ण spec कृते अन्ततः समर्थनं प्रदातुं अवशिष्टम् अस्ति</p>
|
||||
<p xml:lang="sl">Neochat cilja, da bi bila popolna aplikacija po specifikaciji Matrixa. Kot takšna vsebuje vse v trenutni stabilni specifikaciji z pomembnimi izjemami pri VoIP, nitih in nekaterih vidikov šifriranja od konca do konca. Obstaja nekaj drugih manjših opustitev zaradi dejstva, da se specifikacija Matrix nenehno razvija, vendar cilj ostaja zagotoviti morebitno podporo celotni specifikaciji.</p>
|
||||
<p xml:lang="sv">NeoChat har som mål att vara ett fullständigt program enligt Matrix-specifikationen. Som sådant stöds allt i den nuvarande stabila specifikationen, med de nämnvärda undantagen VoIP, trådar och några aspekter av kryptering hela vägen. Det finns några ytterligare utelämnanden på grund av att Matrix-specifikationen hela tiden utvecklas, men målet förblir att till slut erbjuda stöd för hela specifikationen.</p>
|
||||
<p xml:lang="tr">NeoChat, Matrix belirtimi için tam özellikli bir uygulama olmayı hedefler. Bu nedenle; VoIP, ileti zincirleri ve Uçtan Uca Şifreleme’nin bazı yönleri gibi dikkate değer istisnalar dışında var olan kararlı belirtimdeki her şey desteklenir. Matrix belirtiminin sürekli gelişmesi nedeniyle birkaç küçük eksiklik daha var; ancak amaç tüm belirtim için nihai destek sağlamak olmayı sürdürüyor.</p>
|
||||
@@ -161,7 +152,6 @@
|
||||
<p xml:lang="fr">En raison de la nature du développement des spécifications du protocole Matrix, NeoChat prend également en charge de nombreuses fonctionnalités instables. Actuellement, ce sont :</p>
|
||||
<p xml:lang="gl">Debido á natureza do desenvolvemento da especificación de Matrix, NeoChat tamén inclúe varias funcionalidades non estábeis:</p>
|
||||
<p xml:lang="he">מטבע הדברים, הפיתוח של NeoChat תומך במגוון יכולות מפוקפקות כתלות בהתפתחות המפרט הטכני של Matrix. היכולות האלה הן:</p>
|
||||
<p xml:lang="hi">मैट्रिक्स विनिर्देश विकास की प्रकृति के कारण नियोचैट कई अस्थिर सुविधाओं का भी समर्थन करता है। वर्तमान में ये हैं:</p>
|
||||
<p xml:lang="hu">A Matrix specifikáció fejlesztésének jellegéből adódóan a NeoChat számos instabil funkciót is támogat. Jelenleg a következőket:</p>
|
||||
<p xml:lang="ia">Debite al natura del disveloppamento de specification de Matrix NeoChat tamben supporta numerose characteristicas instabile. Currentemente istes es:</p>
|
||||
<p xml:lang="it">A causa della natura dello sviluppo delle specifiche Matrix, NeoChat supporta anche numerose funzionalità instabili. Attualmente queste sono:</p>
|
||||
@@ -173,7 +163,6 @@
|
||||
<p xml:lang="pl">Ze względu na sposób rozwoju Matriksa, NeoChat obsługuje także kilka niestabilnych możliwości. Obecnie są to:</p>
|
||||
<p xml:lang="pt">Devido à natureza do desenvolvimento da especificação do Matrix, o NeoChat também suporta diversas funcionalidades instáveis. De momento são:</p>
|
||||
<p xml:lang="ru">В силу природы разработки спецификации Matrix в NeoChat тоже предусмотрена поддержка многочисленных нестабильных возможностей. В текущей версии это следующие возможности:</p>
|
||||
<p xml:lang="sa">Matrix विनिर्देशविकासस्य प्रकृतेः कारणात् NeoChat अपि अनेकानाम् अस्थिरविशेषतानां समर्थनं करोति । सम्प्रति एते सन्ति :</p>
|
||||
<p xml:lang="sl">Zaradi narave razvoja specifikacije Matrixa NeoChat podpira tudi številne nestabilne zmožnosti. Trenutno so to:</p>
|
||||
<p xml:lang="sv">På grund av sättet Matrix-specifikationens utvecklas, stöder NeoChat också ett stor antal instabila funktioner. För närvarande är de:</p>
|
||||
<p xml:lang="ta">மேட்ரிக்ஸு நெறிமுறை வரையறுக்கப்படும் விதத்தின் காரணமாக, பல நிலையற்ற அம்சங்களையும் நியோச்சாட் ஆதரிக்கிறது. தற்போது ஆதரிக்கப்படுபவை:</p>
|
||||
@@ -195,7 +184,6 @@
|
||||
<li xml:lang="fr">Sondages - MSC3381</li>
|
||||
<li xml:lang="gl">Enquisas — MSC3381</li>
|
||||
<li xml:lang="he">סקרים - MSC3381</li>
|
||||
<li xml:lang="hi">पोल - MSC3381</li>
|
||||
<li xml:lang="hu">Szavazások - MSC3381</li>
|
||||
<li xml:lang="ia">Inquestas - MSC3381</li>
|
||||
<li xml:lang="it">Sondaggi - MSC3381</li>
|
||||
@@ -207,7 +195,6 @@
|
||||
<li xml:lang="pl">Ankiety - MSC3381</li>
|
||||
<li xml:lang="pt">Inquéritos - MSC3381</li>
|
||||
<li xml:lang="ru">Голосования — MSC3381</li>
|
||||
<li xml:lang="sa">मतदान - MSC3381</li>
|
||||
<li xml:lang="sl">Polls - MSC3381</li>
|
||||
<li xml:lang="sv">Polls - MSC3381</li>
|
||||
<li xml:lang="ta">வாக்கெடுப்புகள் - MSC3381</li>
|
||||
@@ -228,7 +215,6 @@
|
||||
<li xml:lang="fr">Paquets d'auto-collants - MSC2545</li>
|
||||
<li xml:lang="gl">Paquetes de adhesivos — MSC2545</li>
|
||||
<li xml:lang="he">חבילות מדבקות - MSC2545</li>
|
||||
<li xml:lang="hi">स्टिकर पैक - MSC2545</li>
|
||||
<li xml:lang="hu">Matricacsomagok - MSC2545</li>
|
||||
<li xml:lang="ia">Etiquetta gummate (sticker) -MSC2545</li>
|
||||
<li xml:lang="it">Pacchetti di adesivi - MSC2545</li>
|
||||
@@ -240,7 +226,6 @@
|
||||
<li xml:lang="pl">Paczki naklejek - MSC2545</li>
|
||||
<li xml:lang="pt">Pacotes de Autocolantes - MSC2545</li>
|
||||
<li xml:lang="ru">Наборы стикеров — MSC2545</li>
|
||||
<li xml:lang="sa">स्टिकर पैक - MSC2545</li>
|
||||
<li xml:lang="sl">Sticker Packs - MSC2545</li>
|
||||
<li xml:lang="sv">Sticker Packs - MSC2545</li>
|
||||
<li xml:lang="ta">ஒட்டி தொகுப்புகள் - MSC2545</li>
|
||||
@@ -261,7 +246,6 @@
|
||||
<li xml:lang="fr">Événements de lieu - MSC3488</li>
|
||||
<li xml:lang="gl">Localización de eventos — MSC3488</li>
|
||||
<li xml:lang="he">אירועי מקום - MSC3488</li>
|
||||
<li xml:lang="hi">स्थान घटनाएँ - MSC3488</li>
|
||||
<li xml:lang="hu">Események helyadatai - MSC3488</li>
|
||||
<li xml:lang="ia">Eventos de Location - MSC3488</li>
|
||||
<li xml:lang="it">Località eventi - MSC3488</li>
|
||||
@@ -273,7 +257,6 @@
|
||||
<li xml:lang="pl">Wydarzenia w miejscach - MSC3488</li>
|
||||
<li xml:lang="pt">Eventos com Localizações - MSC3488</li>
|
||||
<li xml:lang="ru">События местоположения — MSC3488</li>
|
||||
<li xml:lang="sa">स्थान घटनाएँ - MSC3488</li>
|
||||
<li xml:lang="sl">Location Events - MSC3488</li>
|
||||
<li xml:lang="sv">Location Events - MSC3488</li>
|
||||
<li xml:lang="ta">இட நிகழ்வுகள் - MSC3488</li>
|
||||
@@ -330,7 +313,6 @@
|
||||
<caption xml:lang="fr">Vue principale avec la liste des salons ainsi que des informations sur les salons et forums de discussions</caption>
|
||||
<caption xml:lang="gl">Vista principal coa lista de salas, a charla, e información da sala.</caption>
|
||||
<caption xml:lang="he">תצוגה ראשית עם רשימת חדרים, צ׳אט ופרטי חדר</caption>
|
||||
<caption xml:lang="hi">कमरे की सूची, चैट और कमरे की जानकारी के साथ मुख्य दृश्य</caption>
|
||||
<caption xml:lang="hu">A fő nézet a szobalistával, csevegéssel és szobainformációkkal</caption>
|
||||
<caption xml:lang="ia">Vista principal con lista de sala, chat e information de sala</caption>
|
||||
<caption xml:lang="it">Vista principale con elenco delle stanze, chat e informazioni sulla stanza</caption>
|
||||
@@ -342,7 +324,6 @@
|
||||
<caption xml:lang="pl">Główny widok z wykazem pokojów, rozmowami i szczegółami pokojów</caption>
|
||||
<caption xml:lang="pt">A área principal com a lista de salas e com informações sobre a conversa e a sala</caption>
|
||||
<caption xml:lang="ru">Главное окно со списком комнат, чатом и информацией о комнате</caption>
|
||||
<caption xml:lang="sa">कक्षसूची, गपशपः, कक्षसूचना च सह मुख्यदृश्यम्</caption>
|
||||
<caption xml:lang="sl">Glavni pogled s seznamom sob, klepetom in informacijami o sobah</caption>
|
||||
<caption xml:lang="sv">Huvudvy med rumslista, chatt, och rumsinformation</caption>
|
||||
<caption xml:lang="ta">அரங்குப்பட்டியல், உரையாடல், மற்றும் அரங்குவிவரங்களைக் கொண்டுள்ள பிரதான காட்சி</caption>
|
||||
@@ -367,7 +348,6 @@
|
||||
<caption xml:lang="fr">Découvrez de nouvelles communautés avec les espaces sous Matrix</caption>
|
||||
<caption xml:lang="gl">Descubra novas comunidades dos espazos de Matrix.</caption>
|
||||
<caption xml:lang="he">אפשר להיחשף לקהילות חדשות דרך Matrix Spaces</caption>
|
||||
<caption xml:lang="hi">मैट्रिक्स स्पेस के साथ नए समुदायों की खोज करें</caption>
|
||||
<caption xml:lang="hu">Fedezzen fel új közösségeket a Matrix Terek segítségével</caption>
|
||||
<caption xml:lang="ia">Discoperi nove communitate con Matrix Spaces (Spatios de Matrix)</caption>
|
||||
<caption xml:lang="it">Scopri nuove comunità con Matrix Spaces</caption>
|
||||
@@ -377,7 +357,6 @@
|
||||
<caption xml:lang="nn">Oppdag nye fellesskap med Matrix Spaces</caption>
|
||||
<caption xml:lang="pl">Odkrywaj nowe społeczności w Przestrzeniach Matriksa</caption>
|
||||
<caption xml:lang="ru">Поиск новых сообществ с помощью Matrix Spaces</caption>
|
||||
<caption xml:lang="sa">Matrix Spaces इत्यनेन सह नूतनानां समुदायानाम् अन्वेषणं कुर्वन्तु</caption>
|
||||
<caption xml:lang="sl">Odkrijte nove skupnosti z Matrix Spaces</caption>
|
||||
<caption xml:lang="sv">Upptäck nya gemenskaper med Matrix Spaces</caption>
|
||||
<caption xml:lang="ta">மேட்ரிக்ஸு இடங்களின் மூலம் புதிய சமூகங்களைக் கண்டுபிடிக்கலாம்</caption>
|
||||
@@ -409,7 +388,6 @@
|
||||
<caption xml:lang="fr">Vue principale avec la liste des salons ainsi que des informations sur les salons et forums de discussions</caption>
|
||||
<caption xml:lang="gl">Vista principal coa lista de salas, a charla, e información da sala.</caption>
|
||||
<caption xml:lang="he">תצוגה ראשית עם רשימת חדרים, צ׳אט ופרטי חדר</caption>
|
||||
<caption xml:lang="hi">कमरे की सूची, चैट और कमरे की जानकारी के साथ मुख्य दृश्य</caption>
|
||||
<caption xml:lang="hu">A fő nézet a szobalistával, csevegéssel és szobainformációkkal</caption>
|
||||
<caption xml:lang="ia">Vista principal con lista de sala, chat e information de sala</caption>
|
||||
<caption xml:lang="it">Vista principale con elenco delle stanze, chat e informazioni sulla stanza</caption>
|
||||
@@ -421,7 +399,6 @@
|
||||
<caption xml:lang="pl">Główny widok z wykazem pokojów, rozmowami i szczegółami pokojów</caption>
|
||||
<caption xml:lang="pt">A área principal com a lista de salas e com informações sobre a conversa e a sala</caption>
|
||||
<caption xml:lang="ru">Главное окно со списком комнат, чатом и информацией о комнате</caption>
|
||||
<caption xml:lang="sa">कक्षसूची, गपशपः, कक्षसूचना च सह मुख्यदृश्यम्</caption>
|
||||
<caption xml:lang="sl">Glavni pogled s seznamom sob, klepetom in informacijami o sobah</caption>
|
||||
<caption xml:lang="sv">Huvudvy med rumslista, chatt, och rumsinformation</caption>
|
||||
<caption xml:lang="ta">அரங்குப்பட்டியல், உரையாடல், மற்றும் அரங்குவிவரங்களைக் கொண்டுள்ள பிரதான காட்சி</caption>
|
||||
@@ -447,7 +424,6 @@
|
||||
<caption xml:lang="fr">Écran de connexion</caption>
|
||||
<caption xml:lang="gl">Pantalla de identificación.</caption>
|
||||
<caption xml:lang="he">מסך כניסה</caption>
|
||||
<caption xml:lang="hi">लॉगिन स्क्रीन</caption>
|
||||
<caption xml:lang="hu">Bejelentkező képernyő</caption>
|
||||
<caption xml:lang="ia">Schermo de accesso</caption>
|
||||
<caption xml:lang="it">Schermata di accesso</caption>
|
||||
@@ -459,7 +435,6 @@
|
||||
<caption xml:lang="pl">Ekran logowania</caption>
|
||||
<caption xml:lang="pt">Ecrã de autenticação</caption>
|
||||
<caption xml:lang="ru">Окно входа</caption>
|
||||
<caption xml:lang="sa">लॉगिन् स्क्रीन</caption>
|
||||
<caption xml:lang="sl">Prijavni zaslon</caption>
|
||||
<caption xml:lang="sv">Inloggningsfönster</caption>
|
||||
<caption xml:lang="ta">நுழைவுத் திரை</caption>
|
||||
|
||||
@@ -19,7 +19,6 @@ Name[fi]=NeoChat
|
||||
Name[fr]=NeoChat
|
||||
Name[gl]=NeoChat
|
||||
Name[he]=NeoChat
|
||||
Name[hi]=नियोचैट
|
||||
Name[hu]=NeoChat
|
||||
Name[ia]=Neochat
|
||||
Name[id]=NeoChat
|
||||
@@ -37,7 +36,6 @@ Name[pt]=NeoChat
|
||||
Name[pt_BR]=NeoChat
|
||||
Name[ro]=NeoChat
|
||||
Name[ru]=NeoChat
|
||||
Name[sa]=नवचैट्
|
||||
Name[sk]=NeoChat
|
||||
Name[sl]=NeoChat
|
||||
Name[sv]=NeoChat
|
||||
@@ -63,7 +61,6 @@ GenericName[fi]=Matrix-asiakas
|
||||
GenericName[fr]=Client « Matrix »
|
||||
GenericName[gl]=Cliente de Matrix
|
||||
GenericName[he]=לקוח Matrix
|
||||
GenericName[hi]=मैट्रिक्स क्लाइंट
|
||||
GenericName[hu]=Matrix kliens
|
||||
GenericName[ia]=Cliente de Matrice
|
||||
GenericName[id]=Klien Matrix
|
||||
@@ -81,7 +78,6 @@ GenericName[pt]=Cliente de Matrix
|
||||
GenericName[pt_BR]=Cliente Matrix
|
||||
GenericName[ro]=Client Matrix
|
||||
GenericName[ru]=Клиент Matrix
|
||||
GenericName[sa]=मैट्रिक्स क्लाइंट
|
||||
GenericName[sk]=Matrix Client
|
||||
GenericName[sl]=Odjemalec Matrix
|
||||
GenericName[sv]=Matrix-klient
|
||||
@@ -97,14 +93,12 @@ Comment[ca]=Xat a Matrix
|
||||
Comment[ca@valencia]=Xat a Matrix
|
||||
Comment[de]=Über Matrix unterhalten
|
||||
Comment[en_GB]=Chat on Matrix
|
||||
Comment[eo]=Babilo en Matrix
|
||||
Comment[es]=Chat en Matrix
|
||||
Comment[eu]=Berriketa Matrix-en
|
||||
Comment[fi]=Keskustele Matrixissä
|
||||
Comment[fr]=Clavarder sur Matrix
|
||||
Comment[gl]=Charle en Matrix
|
||||
Comment[he]=התכתבות דרך Matrix
|
||||
Comment[hi]=मैट्रिक्स पर चैट करें
|
||||
Comment[hu]=Csevegés Matrixon
|
||||
Comment[ia]=Conversation en ditecto sur Matrix
|
||||
Comment[it]= su Matrix
|
||||
@@ -112,11 +106,10 @@ Comment[ka]=ჩატი Matrix-ზე
|
||||
Comment[lv]=Tērzējiet „Matrix“ tīklā
|
||||
Comment[nl]=Chat op Matrix
|
||||
Comment[pl]=Rozmawiaj na Matriksie
|
||||
Comment[sa]=Matrix इत्यत्र गपशपं कुर्वन्तु
|
||||
Comment[sl]=Klepet na Matrixu
|
||||
Comment[sv]=Chatta på Matrix
|
||||
Comment[ta]=மேட்ரிக்ஸில் உரையாட உதவும்
|
||||
Comment[tr]=Matrix üzerinde sohbet edin
|
||||
Comment[tr]=Matrix Üzerinde Sohbet Et
|
||||
Comment[uk]=Спілкування у Matrix
|
||||
Comment[x-test]=xxChat on Matrixxx
|
||||
Comment[zh_TW]=在 Matrix 上聊天
|
||||
|
||||
663
po/ar/neochat.po
663
po/ar/neochat.po
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
595
po/az/neochat.po
595
po/az/neochat.po
File diff suppressed because it is too large
Load Diff
913
po/ca/neochat.po
913
po/ca/neochat.po
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
594
po/cs/neochat.po
594
po/cs/neochat.po
File diff suppressed because it is too large
Load Diff
588
po/da/neochat.po
588
po/da/neochat.po
File diff suppressed because it is too large
Load Diff
594
po/de/neochat.po
594
po/de/neochat.po
File diff suppressed because it is too large
Load Diff
594
po/el/neochat.po
594
po/el/neochat.po
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
987
po/eo/neochat.po
987
po/eo/neochat.po
File diff suppressed because it is too large
Load Diff
588
po/es/neochat.po
588
po/es/neochat.po
File diff suppressed because it is too large
Load Diff
588
po/eu/neochat.po
588
po/eu/neochat.po
File diff suppressed because it is too large
Load Diff
594
po/fi/neochat.po
594
po/fi/neochat.po
File diff suppressed because it is too large
Load Diff
644
po/fr/neochat.po
644
po/fr/neochat.po
File diff suppressed because it is too large
Load Diff
653
po/gl/neochat.po
653
po/gl/neochat.po
File diff suppressed because it is too large
Load Diff
6020
po/hi/neochat.po
6020
po/hi/neochat.po
File diff suppressed because it is too large
Load Diff
594
po/hu/neochat.po
594
po/hu/neochat.po
File diff suppressed because it is too large
Load Diff
838
po/ia/neochat.po
838
po/ia/neochat.po
File diff suppressed because it is too large
Load Diff
594
po/id/neochat.po
594
po/id/neochat.po
File diff suppressed because it is too large
Load Diff
591
po/ie/neochat.po
591
po/ie/neochat.po
File diff suppressed because it is too large
Load Diff
834
po/it/neochat.po
834
po/it/neochat.po
File diff suppressed because it is too large
Load Diff
582
po/ja/neochat.po
582
po/ja/neochat.po
File diff suppressed because it is too large
Load Diff
586
po/ka/neochat.po
586
po/ka/neochat.po
File diff suppressed because it is too large
Load Diff
594
po/ko/neochat.po
594
po/ko/neochat.po
File diff suppressed because it is too large
Load Diff
582
po/lt/neochat.po
582
po/lt/neochat.po
File diff suppressed because it is too large
Load Diff
594
po/lv/neochat.po
594
po/lv/neochat.po
File diff suppressed because it is too large
Load Diff
588
po/nl/neochat.po
588
po/nl/neochat.po
File diff suppressed because it is too large
Load Diff
606
po/nn/neochat.po
606
po/nn/neochat.po
File diff suppressed because it is too large
Load Diff
587
po/pa/neochat.po
587
po/pa/neochat.po
File diff suppressed because it is too large
Load Diff
901
po/pl/neochat.po
901
po/pl/neochat.po
File diff suppressed because it is too large
Load Diff
595
po/pt/neochat.po
595
po/pt/neochat.po
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
594
po/ru/neochat.po
594
po/ru/neochat.po
File diff suppressed because it is too large
Load Diff
5993
po/sa/neochat.po
5993
po/sa/neochat.po
File diff suppressed because it is too large
Load Diff
588
po/sk/neochat.po
588
po/sk/neochat.po
File diff suppressed because it is too large
Load Diff
586
po/sl/neochat.po
586
po/sl/neochat.po
File diff suppressed because it is too large
Load Diff
595
po/sv/neochat.po
595
po/sv/neochat.po
File diff suppressed because it is too large
Load Diff
655
po/ta/neochat.po
655
po/ta/neochat.po
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
586
po/tr/neochat.po
586
po/tr/neochat.po
File diff suppressed because it is too large
Load Diff
586
po/uk/neochat.po
586
po/uk/neochat.po
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -27,10 +27,6 @@ apps:
|
||||
|
||||
compression: lzo
|
||||
|
||||
package-repositories:
|
||||
- type: apt
|
||||
ppa: ubuntu-toolchain-r/test
|
||||
|
||||
slots:
|
||||
session-dbus-interface:
|
||||
interface: dbus
|
||||
@@ -66,7 +62,7 @@ parts:
|
||||
- -Dcrypto=disabled
|
||||
- -Dgtk_doc=false
|
||||
build-packages:
|
||||
- meson
|
||||
- meson
|
||||
- libglib2.0-dev
|
||||
- libgcrypt20-dev
|
||||
prime:
|
||||
@@ -80,7 +76,6 @@ parts:
|
||||
source-depth: 1
|
||||
plugin: cmake
|
||||
build-environment:
|
||||
- PATH: /snap/bin:${PATH}
|
||||
- PKG_CONFIG_PATH: $CRAFT_STAGE/usr/lib/$CRAFT_ARCH_TRIPLET/pkgconfig:$PKG_CONFIG_PATH
|
||||
cmake-parameters:
|
||||
- -DCMAKE_INSTALL_PREFIX=/usr
|
||||
@@ -100,13 +95,7 @@ parts:
|
||||
source-tag: 0.9.1
|
||||
source-depth: 1
|
||||
plugin: cmake
|
||||
build-environment:
|
||||
- PATH: /snap/bin:${PATH}
|
||||
build-snaps:
|
||||
- cmake
|
||||
build-packages:
|
||||
- gcc-13
|
||||
- g++-13
|
||||
- libssl-dev
|
||||
cmake-parameters:
|
||||
- -DCMAKE_INSTALL_PREFIX=/usr
|
||||
@@ -114,9 +103,6 @@ parts:
|
||||
- -DBUILD_TESTING=OFF
|
||||
- -DQuotient_ENABLE_E2EE=ON
|
||||
- -DBUILD_WITH_QT6=ON
|
||||
override-build: |
|
||||
update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-13 100 --slave /usr/bin/g++ g++ /usr/bin/g++-13 --slave /usr/bin/gcov gcov /usr/bin/gcov-13
|
||||
craftctl default
|
||||
prime:
|
||||
- -usr/include
|
||||
- -usr/lib/*/pkgconfig
|
||||
@@ -127,8 +113,6 @@ parts:
|
||||
source-tag: 'v0.3.0'
|
||||
source-depth: 1
|
||||
plugin: cmake
|
||||
build-environment:
|
||||
- PATH: /snap/bin:${PATH}
|
||||
cmake-parameters:
|
||||
- -DCMAKE_INSTALL_PREFIX=/usr
|
||||
- -DCMAKE_BUILD_TYPE=Release
|
||||
@@ -146,10 +130,9 @@ parts:
|
||||
- kquickimageeditor
|
||||
parse-info:
|
||||
- usr/share/metainfo/org.kde.neochat.appdata.xml
|
||||
source: .
|
||||
source: https://invent.kde.org/network/neochat.git
|
||||
source-tag: 'v24.08.1'
|
||||
plugin: cmake
|
||||
build-environment:
|
||||
- PATH: /snap/bin:${PATH}
|
||||
build-packages:
|
||||
- cmark
|
||||
- libcmark-dev
|
||||
|
||||
@@ -18,8 +18,8 @@ add_library(neochat STATIC
|
||||
models/customemojimodel.h
|
||||
clipboard.cpp
|
||||
clipboard.h
|
||||
models/timelinemessagemodel.cpp
|
||||
models/timelinemessagemodel.h
|
||||
models/messageeventmodel.cpp
|
||||
models/messageeventmodel.h
|
||||
models/messagefiltermodel.cpp
|
||||
models/messagefiltermodel.h
|
||||
models/roomlistmodel.cpp
|
||||
@@ -128,6 +128,10 @@ add_library(neochat STATIC
|
||||
neochatconnection.h
|
||||
jobs/neochatdeactivateaccountjob.cpp
|
||||
jobs/neochatdeactivateaccountjob.h
|
||||
jobs/neochatdeletedevicejob.cpp
|
||||
jobs/neochatdeletedevicejob.h
|
||||
jobs/neochatchangepasswordjob.cpp
|
||||
jobs/neochatchangepasswordjob.h
|
||||
jobs/neochatgetcommonroomsjob.cpp
|
||||
jobs/neochatgetcommonroomsjob.h
|
||||
mediasizehelper.cpp
|
||||
@@ -172,6 +176,8 @@ add_library(neochat STATIC
|
||||
models/threepidmodel.h
|
||||
threepidaddhelper.cpp
|
||||
threepidaddhelper.h
|
||||
jobs/neochatadd3pidjob.cpp
|
||||
jobs/neochatadd3pidjob.h
|
||||
identityserverhelper.cpp
|
||||
identityserverhelper.h
|
||||
enums/powerlevel.cpp
|
||||
@@ -190,10 +196,6 @@ add_library(neochat STATIC
|
||||
messagecomponent.h
|
||||
enums/roomsortparameter.cpp
|
||||
enums/roomsortparameter.h
|
||||
models/roomsortparametermodel.cpp
|
||||
models/roomsortparametermodel.h
|
||||
models/messagemodel.cpp
|
||||
models/messagemodel.h
|
||||
)
|
||||
|
||||
set_source_files_properties(qml/OsmLocationPlugin.qml PROPERTIES
|
||||
@@ -327,10 +329,10 @@ if(WIN32)
|
||||
endif()
|
||||
|
||||
ecm_qt_declare_logging_category(neochat
|
||||
HEADER "messagemodel_logging.h"
|
||||
IDENTIFIER "Message"
|
||||
CATEGORY_NAME "org.kde.neochat.messagemodel"
|
||||
DESCRIPTION "Neochat: messagemodel"
|
||||
HEADER "messageeventmodel_logging.h"
|
||||
IDENTIFIER "MessageEvent"
|
||||
CATEGORY_NAME "org.kde.neochat.messageeventmodel"
|
||||
DESCRIPTION "Neochat: messageeventmodel"
|
||||
DEFAULT_SEVERITY Info
|
||||
EXPORT NEOCHAT
|
||||
)
|
||||
|
||||
@@ -57,7 +57,7 @@ QString ChatBarCache::formatMentions() const
|
||||
}
|
||||
formattedText = formattedText.replace(mention.cursor.anchor(),
|
||||
mention.cursor.position() - mention.cursor.anchor(),
|
||||
u"[%1](https://matrix.to/#/%2)"_s.arg(mention.text.toHtmlEscaped(), mention.id));
|
||||
QStringLiteral("[%1](https://matrix.to/#/%2)").arg(mention.text.toHtmlEscaped(), mention.id));
|
||||
}
|
||||
|
||||
return formattedText;
|
||||
@@ -256,7 +256,7 @@ void ChatBarCache::updateMentions(QQuickTextDocument *document, ChatDocumentHand
|
||||
if (auto event = room->findInTimeline(m_relationId); event != room->historyEdge()) {
|
||||
if (const auto &roomMessageEvent = &*event->viewAs<Quotient::RoomMessageEvent>()) {
|
||||
// Replaces the mentions that are baked into the HTML but plaintext in the original markdown
|
||||
const QRegularExpression re(uR"lit(<a\shref="https:\/\/matrix.to\/#\/([\S]*)"\s?>([\S]*)<\/a>)lit"_s);
|
||||
const QRegularExpression re(QStringLiteral(R"lit(<a\shref="https:\/\/matrix.to\/#\/([\S]*)"\s?>([\S]*)<\/a>)lit"));
|
||||
|
||||
m_mentions.clear();
|
||||
|
||||
@@ -309,7 +309,7 @@ void ChatBarCache::postMessage()
|
||||
}
|
||||
|
||||
const auto result = ActionsModel::handleAction(room, this);
|
||||
if (!result.second.has_value()) {
|
||||
if (!result.first.has_value()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -338,7 +338,8 @@ void ChatBarCache::postMessage()
|
||||
relatesTo = Quotient::EventRelation::replyTo(replyId());
|
||||
}
|
||||
|
||||
room->post<Quotient::RoomMessageEvent>(text(), *std::get<std::optional<Quotient::RoomMessageEvent::MsgType>>(result), std::move(content), relatesTo);
|
||||
const auto type = std::get<std::optional<Quotient::RoomMessageEvent::MsgType>>(result);
|
||||
room->post<Quotient::RoomMessageEvent>(text(), type ? *type : Quotient::RoomMessageEvent::MsgType::Text, std::move(content), relatesTo);
|
||||
clearCache();
|
||||
}
|
||||
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
|
||||
#include "chatdocumenthandler_logging.h"
|
||||
|
||||
using namespace Qt::StringLiterals;
|
||||
|
||||
class SyntaxHighlighter : public QSyntaxHighlighter
|
||||
{
|
||||
public:
|
||||
@@ -230,7 +228,7 @@ void ChatDocumentHandler::complete(int index)
|
||||
QTextCursor cursor(document()->textDocument());
|
||||
cursor.setPosition(at);
|
||||
cursor.setPosition(cursorPosition(), QTextCursor::KeepAnchor);
|
||||
cursor.insertText(name + u" "_s);
|
||||
cursor.insertText(name + QStringLiteral(" "));
|
||||
cursor.setPosition(at);
|
||||
cursor.setPosition(cursor.position() + name.size(), QTextCursor::KeepAnchor);
|
||||
cursor.setKeepPositionOnInsert(true);
|
||||
@@ -243,7 +241,7 @@ void ChatDocumentHandler::complete(int index)
|
||||
QTextCursor cursor(document()->textDocument());
|
||||
cursor.setPosition(at);
|
||||
cursor.setPosition(cursorPosition(), QTextCursor::KeepAnchor);
|
||||
cursor.insertText(u"/%1 "_s.arg(command));
|
||||
cursor.insertText(QStringLiteral("/%1 ").arg(command));
|
||||
} else if (m_completionModel->autoCompletionType() == CompletionModel::Room) {
|
||||
auto alias = m_completionModel->data(m_completionModel->index(index, 0), CompletionModel::SubtitleRole).toString();
|
||||
auto text = getText();
|
||||
@@ -251,7 +249,7 @@ void ChatDocumentHandler::complete(int index)
|
||||
QTextCursor cursor(document()->textDocument());
|
||||
cursor.setPosition(at);
|
||||
cursor.setPosition(cursorPosition(), QTextCursor::KeepAnchor);
|
||||
cursor.insertText(alias + u" "_s);
|
||||
cursor.insertText(alias + QStringLiteral(" "));
|
||||
cursor.setPosition(at);
|
||||
cursor.setPosition(cursor.position() + alias.size(), QTextCursor::KeepAnchor);
|
||||
cursor.setKeepPositionOnInsert(true);
|
||||
|
||||
@@ -14,8 +14,6 @@
|
||||
#include <QStandardPaths>
|
||||
#include <QUrl>
|
||||
|
||||
using namespace Qt::StringLiterals;
|
||||
|
||||
Clipboard::Clipboard(QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_clipboard(QGuiApplication::clipboard())
|
||||
@@ -35,14 +33,14 @@ QImage Clipboard::image() const
|
||||
|
||||
QString Clipboard::saveImage(QString localPath) const
|
||||
{
|
||||
QString imageDir(u"%1/screenshots"_s.arg(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)));
|
||||
QString imageDir(QStringLiteral("%1/screenshots").arg(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)));
|
||||
|
||||
if (!QDir().exists(imageDir)) {
|
||||
QDir().mkdir(imageDir);
|
||||
}
|
||||
|
||||
if (localPath.isEmpty()) {
|
||||
localPath = u"file://%1/%2.png"_s.arg(imageDir, QDateTime::currentDateTime().toString(u"yyyy-MM-dd-hh-mm-ss"_s));
|
||||
localPath = QStringLiteral("file://%1/%2.png").arg(imageDir, QDateTime::currentDateTime().toString(QStringLiteral("yyyy-MM-dd-hh-mm-ss")));
|
||||
}
|
||||
QUrl url(localPath);
|
||||
if (!url.isLocalFile()) {
|
||||
@@ -63,7 +61,7 @@ QString Clipboard::saveImage(QString localPath) const
|
||||
|
||||
void Clipboard::saveText(QString message)
|
||||
{
|
||||
static QRegularExpression re(u"<[^>]*>"_s);
|
||||
static QRegularExpression re(QStringLiteral("<[^>]*>"));
|
||||
auto *mimeData = new QMimeData; // ownership is transferred to clipboard
|
||||
mimeData->setHtml(message);
|
||||
mimeData->setText(message.replace(re, QString()));
|
||||
|
||||
@@ -63,7 +63,7 @@ Controller::Controller(QObject *parent)
|
||||
});
|
||||
} else {
|
||||
auto c = new NeoChatConnection(this);
|
||||
c->assumeIdentity(u"@user:localhost:1234"_s, u"device_1234"_s, u"token_1234"_s);
|
||||
c->assumeIdentity(QStringLiteral("@user:localhost:1234"), QStringLiteral("device_1234"), QStringLiteral("token_1234"));
|
||||
connect(c, &Connection::connected, this, [c, this]() {
|
||||
m_accountRegistry.add(c);
|
||||
c->syncLoop();
|
||||
@@ -117,7 +117,7 @@ Controller::Controller(QObject *parent)
|
||||
});
|
||||
|
||||
#ifdef HAVE_KUNIFIEDPUSH
|
||||
auto connector = new KUnifiedPush::Connector(u"org.kde.neochat"_s);
|
||||
auto connector = new KUnifiedPush::Connector(QStringLiteral("org.kde.neochat"));
|
||||
connect(connector, &KUnifiedPush::Connector::endpointChanged, this, [this](const QString &endpoint) {
|
||||
m_endpoint = endpoint;
|
||||
for (auto "ientConnection : m_accountRegistry) {
|
||||
@@ -187,7 +187,7 @@ void Controller::dropConnection(NeoChatConnection *c)
|
||||
|
||||
void Controller::invokeLogin()
|
||||
{
|
||||
const auto accounts = SettingsGroup("Accounts"_L1).childGroups();
|
||||
const auto accounts = SettingsGroup("Accounts"_ls).childGroups();
|
||||
for (const auto &accountId : accounts) {
|
||||
AccountSettings account{accountId};
|
||||
m_accountsLoading += accountId;
|
||||
@@ -288,7 +288,7 @@ bool Controller::supportSystemTray() const
|
||||
return false;
|
||||
#else
|
||||
auto de = QString::fromLatin1(qgetenv("XDG_CURRENT_DESKTOP"));
|
||||
return de != u"GNOME"_s && de != u"Pantheon"_s;
|
||||
return de != QStringLiteral("GNOME") && de != QStringLiteral("Pantheon");
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -341,7 +341,7 @@ void Controller::setActiveConnection(NeoChatConnection *connection)
|
||||
void Controller::listenForNotifications()
|
||||
{
|
||||
#ifdef HAVE_KUNIFIEDPUSH
|
||||
auto connector = new KUnifiedPush::Connector(u"org.kde.neochat"_s);
|
||||
auto connector = new KUnifiedPush::Connector(QStringLiteral("org.kde.neochat"));
|
||||
|
||||
auto timer = new QTimer();
|
||||
connect(timer, &QTimer::timeout, qGuiApp, &QGuiApplication::quit);
|
||||
@@ -370,19 +370,19 @@ void Controller::updateBadgeNotificationCount(NeoChatConnection *connection, int
|
||||
#if QT_VERSION < QT_VERSION_CHECK(6, 6, 0)
|
||||
#ifndef Q_OS_ANDROID
|
||||
// copied from Telegram desktop
|
||||
const auto launcherUrl = "application://org.kde.neochat.desktop"_L1;
|
||||
const auto launcherUrl = "application://org.kde.neochat.desktop"_ls;
|
||||
// Gnome requires that count is a 64bit integer
|
||||
const qint64 counterSlice = std::min(count, 9999);
|
||||
QVariantMap dbusUnityProperties;
|
||||
|
||||
if (counterSlice > 0) {
|
||||
dbusUnityProperties["count"_L1] = counterSlice;
|
||||
dbusUnityProperties["count-visible"_L1] = true;
|
||||
dbusUnityProperties["count"_ls] = counterSlice;
|
||||
dbusUnityProperties["count-visible"_ls] = true;
|
||||
} else {
|
||||
dbusUnityProperties["count-visible"_L1] = false;
|
||||
dbusUnityProperties["count-visible"_ls] = false;
|
||||
}
|
||||
|
||||
auto signal = QDBusMessage::createSignal("/com/canonical/unity/launcherentry/neochat"_L1, "com.canonical.Unity.LauncherEntry"_L1, "Update"_L1);
|
||||
auto signal = QDBusMessage::createSignal("/com/canonical/unity/launcherentry/neochat"_ls, "com.canonical.Unity.LauncherEntry"_ls, "Update"_ls);
|
||||
|
||||
signal.setArguments({launcherUrl, dbusUnityProperties});
|
||||
|
||||
@@ -431,7 +431,7 @@ void Controller::removeConnection(const QString &userId)
|
||||
}
|
||||
if (m_connectionsLoading.contains(userId) && m_connectionsLoading[userId]) {
|
||||
auto connection = m_connectionsLoading[userId];
|
||||
SettingsGroup("Accounts"_L1).remove(userId);
|
||||
SettingsGroup("Accounts"_ls).remove(userId);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <Quotient/accountregistry.h>
|
||||
|
||||
class TrayIcon;
|
||||
class QQuickTextDocument;
|
||||
|
||||
namespace QKeychain
|
||||
{
|
||||
|
||||
3706
src/emojis.h
3706
src/emojis.h
File diff suppressed because it is too large
Load Diff
@@ -4,8 +4,6 @@
|
||||
#include "emojitones.h"
|
||||
#include "models/emojimodel.h"
|
||||
|
||||
using namespace Qt::StringLiterals;
|
||||
|
||||
QMultiHash<QString, QVariant> EmojiTones::_tones = {
|
||||
#include "emojitones_data.h"
|
||||
};
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -13,8 +13,6 @@
|
||||
|
||||
#include "events/pollevent.h"
|
||||
|
||||
using namespace Qt::StringLiterals;
|
||||
|
||||
/**
|
||||
* @class DelegateType
|
||||
*
|
||||
@@ -60,7 +58,7 @@ public:
|
||||
return Message;
|
||||
}
|
||||
if (event.isStateEvent()) {
|
||||
if (event.matrixType() == u"org.matrix.msc3672.beacon_info"_s) {
|
||||
if (event.matrixType() == QStringLiteral("org.matrix.msc3672.beacon_info")) {
|
||||
return Message;
|
||||
}
|
||||
return State;
|
||||
|
||||
@@ -13,8 +13,6 @@
|
||||
|
||||
#include "events/pollevent.h"
|
||||
|
||||
using namespace Qt::StringLiterals;
|
||||
|
||||
/**
|
||||
* @class MessageComponentType
|
||||
*
|
||||
@@ -53,7 +51,6 @@ public:
|
||||
LinkPreview, /**< A preview of a URL in the message. */
|
||||
LinkPreviewLoad, /**< A loading dialog for a link preview. */
|
||||
ChatBar, /**< A text edit for editing a message. */
|
||||
ReplyButton, /**< A button to reply in the current thread. */
|
||||
Verification, /**< A user verification session start message. */
|
||||
Loading, /**< The component is loading. */
|
||||
Other, /**< Anything that cannot be classified as another type. */
|
||||
@@ -95,7 +92,7 @@ public:
|
||||
return MessageComponentType::Image;
|
||||
}
|
||||
if (event.isStateEvent()) {
|
||||
if (event.matrixType() == u"org.matrix.msc3672.beacon_info"_s) {
|
||||
if (event.matrixType() == QStringLiteral("org.matrix.msc3672.beacon_info")) {
|
||||
return MessageComponentType::LiveLocation;
|
||||
}
|
||||
return MessageComponentType::Other;
|
||||
@@ -123,10 +120,10 @@ public:
|
||||
*/
|
||||
static Type typeForTag(const QString &tag)
|
||||
{
|
||||
if (tag == u"pre"_s || tag == u"pre"_s) {
|
||||
if (tag == QLatin1String("pre") || tag == QLatin1String("pre")) {
|
||||
return Code;
|
||||
}
|
||||
if (tag == u"blockquote"_s) {
|
||||
if (tag == QLatin1String("blockquote")) {
|
||||
return Quote;
|
||||
}
|
||||
return Text;
|
||||
|
||||
@@ -10,8 +10,6 @@
|
||||
|
||||
#include <KLocalizedString>
|
||||
|
||||
using namespace Qt::StringLiterals;
|
||||
|
||||
class NeoChatRoomType : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -77,19 +75,19 @@ public:
|
||||
{
|
||||
switch (category) {
|
||||
case NeoChatRoomType::Invited:
|
||||
return u"user-invisible"_s;
|
||||
return QStringLiteral("user-invisible");
|
||||
case NeoChatRoomType::Favorite:
|
||||
return u"favorite"_s;
|
||||
return QStringLiteral("favorite");
|
||||
case NeoChatRoomType::Direct:
|
||||
return u"dialog-messages"_s;
|
||||
return QStringLiteral("dialog-messages");
|
||||
case NeoChatRoomType::Normal:
|
||||
return u"group"_s;
|
||||
return QStringLiteral("group");
|
||||
case NeoChatRoomType::Deprioritized:
|
||||
return u"object-order-lower"_s;
|
||||
return QStringLiteral("object-order-lower");
|
||||
case NeoChatRoomType::Space:
|
||||
return u"group"_s;
|
||||
return QStringLiteral("group");
|
||||
default:
|
||||
return u"tools-report-bug"_s;
|
||||
return QStringLiteral("tools-report-bug");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
#include <QObject>
|
||||
#include <QQmlEngine>
|
||||
|
||||
using namespace Qt::StringLiterals;
|
||||
|
||||
/**
|
||||
* @class PushRuleKind
|
||||
*
|
||||
@@ -44,15 +42,15 @@ public:
|
||||
{
|
||||
switch (kind) {
|
||||
case Kind::Override:
|
||||
return u"override"_s;
|
||||
return QLatin1String("override");
|
||||
case Kind::Content:
|
||||
return u"content"_s;
|
||||
return QLatin1String("content");
|
||||
case Kind::Room:
|
||||
return u"room"_s;
|
||||
return QLatin1String("room");
|
||||
case Kind::Sender:
|
||||
return u"sender"_s;
|
||||
return QLatin1String("sender");
|
||||
case Kind::Underride:
|
||||
return u"underride"_s;
|
||||
return QLatin1String("underride");
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
@@ -172,15 +170,15 @@ public:
|
||||
{
|
||||
switch (section) {
|
||||
case Section::Master:
|
||||
return u"Master"_s;
|
||||
return QLatin1String("Master");
|
||||
case Section::Room:
|
||||
return u"Room Notifications"_s;
|
||||
return QLatin1String("Room Notifications");
|
||||
case Section::Mentions:
|
||||
return u"@Mentions"_s;
|
||||
return QLatin1String("@Mentions");
|
||||
case Section::Keywords:
|
||||
return u"Keywords"_s;
|
||||
return QLatin1String("Keywords");
|
||||
case Section::Invites:
|
||||
return u"Invites"_s;
|
||||
return QLatin1String("Invites");
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -3,11 +3,6 @@
|
||||
|
||||
#include "roomsortparameter.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "neochatconfig.h"
|
||||
#include "neochatroom.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
template<typename T>
|
||||
@@ -21,78 +16,6 @@ int typeCompare<QString>(QString left, QString right)
|
||||
{
|
||||
return left.localeAwareCompare(right);
|
||||
}
|
||||
|
||||
static const QList<RoomSortParameter::Parameter> allSortPriorities = {
|
||||
RoomSortParameter::AlphabeticalAscending,
|
||||
RoomSortParameter::AlphabeticalDescending,
|
||||
RoomSortParameter::HasUnread,
|
||||
RoomSortParameter::MostUnread,
|
||||
RoomSortParameter::HasHighlight,
|
||||
RoomSortParameter::MostHighlights,
|
||||
RoomSortParameter::LastActive,
|
||||
};
|
||||
|
||||
static const QList<RoomSortParameter::Parameter> alphabeticalSortPriorities = {
|
||||
RoomSortParameter::AlphabeticalAscending,
|
||||
};
|
||||
|
||||
static const QList<RoomSortParameter::Parameter> activitySortPriorities = {
|
||||
RoomSortParameter::HasHighlight,
|
||||
RoomSortParameter::MostHighlights,
|
||||
RoomSortParameter::HasUnread,
|
||||
RoomSortParameter::MostUnread,
|
||||
RoomSortParameter::LastActive,
|
||||
};
|
||||
|
||||
static const QList<RoomSortParameter::Parameter> lastMessageSortPriorities = {
|
||||
RoomSortParameter::LastActive,
|
||||
};
|
||||
}
|
||||
|
||||
QList<RoomSortParameter::Parameter> RoomSortParameter::allParameterList()
|
||||
{
|
||||
return allSortPriorities;
|
||||
}
|
||||
|
||||
QList<RoomSortParameter::Parameter> RoomSortParameter::currentParameterList()
|
||||
{
|
||||
QList<RoomSortParameter::Parameter> configParamList;
|
||||
switch (static_cast<NeoChatConfig::EnumSortOrder::type>(NeoChatConfig::sortOrder())) {
|
||||
case NeoChatConfig::EnumSortOrder::Activity:
|
||||
configParamList = activitySortPriorities;
|
||||
break;
|
||||
case NeoChatConfig::EnumSortOrder::Alphabetical:
|
||||
configParamList = alphabeticalSortPriorities;
|
||||
break;
|
||||
case NeoChatConfig::EnumSortOrder::LastMessage:
|
||||
configParamList = lastMessageSortPriorities;
|
||||
break;
|
||||
case NeoChatConfig::EnumSortOrder::Custom: {
|
||||
const auto intList = NeoChatConfig::customSortOrder();
|
||||
std::transform(intList.constBegin(), intList.constEnd(), std::back_inserter(configParamList), [](int param) {
|
||||
return static_cast<Parameter>(param);
|
||||
});
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (configParamList.isEmpty()) {
|
||||
return activitySortPriorities;
|
||||
}
|
||||
return configParamList;
|
||||
}
|
||||
|
||||
void RoomSortParameter::saveNewParameterList(const QList<Parameter> &newList)
|
||||
{
|
||||
QList<int> intList;
|
||||
std::transform(newList.constBegin(), newList.constEnd(), std::back_inserter(intList), [](Parameter param) {
|
||||
return static_cast<int>(param);
|
||||
});
|
||||
NeoChatConfig::setCustomSortOrder(intList);
|
||||
NeoChatConfig::setSortOrder(NeoChatConfig::EnumSortOrder::Custom);
|
||||
NeoChatConfig::self()->save();
|
||||
}
|
||||
|
||||
int RoomSortParameter::compareParameter(Parameter parameter, NeoChatRoom *leftRoom, NeoChatRoom *rightRoom)
|
||||
@@ -113,7 +36,7 @@ int RoomSortParameter::compareParameter(Parameter parameter, NeoChatRoom *leftRo
|
||||
case LastActive:
|
||||
return compareParameter<LastActive>(leftRoom, rightRoom);
|
||||
default:
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,13 +3,12 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "neochatroom.h"
|
||||
#include <QObject>
|
||||
#include <QQmlEngine>
|
||||
|
||||
#include <KLocalizedString>
|
||||
|
||||
class NeoChatRoom;
|
||||
|
||||
/**
|
||||
* @class RoomSortParameter
|
||||
*
|
||||
@@ -24,19 +23,15 @@ class RoomSortParameter : public QObject
|
||||
public:
|
||||
/**
|
||||
* @brief Defines the available sort parameters.
|
||||
*
|
||||
* @note All values are specifically numbered as they should never change even
|
||||
* if new options are later added. This is because they are stored in
|
||||
* the config as ints and changing would break someones config on upgrade.
|
||||
*/
|
||||
enum Parameter {
|
||||
AlphabeticalAscending = 0,
|
||||
AlphabeticalDescending = 1,
|
||||
HasUnread = 2,
|
||||
MostUnread = 3,
|
||||
HasHighlight = 4,
|
||||
MostHighlights = 5,
|
||||
LastActive = 6,
|
||||
AlphabeticalAscending,
|
||||
AlphabeticalDescending,
|
||||
HasUnread,
|
||||
MostUnread,
|
||||
HasHighlight,
|
||||
MostHighlights,
|
||||
LastActive,
|
||||
};
|
||||
Q_ENUM(Parameter)
|
||||
|
||||
@@ -45,7 +40,7 @@ public:
|
||||
*
|
||||
* @sa Parameter
|
||||
*/
|
||||
Q_INVOKABLE static QString parameterName(Parameter parameter)
|
||||
static QString parameterName(Parameter parameter)
|
||||
{
|
||||
switch (parameter) {
|
||||
case Parameter::AlphabeticalAscending:
|
||||
@@ -72,7 +67,7 @@ public:
|
||||
*
|
||||
* @sa Parameter
|
||||
*/
|
||||
Q_INVOKABLE static QString parameterDescription(Parameter parameter)
|
||||
static QString parameterDescription(Parameter parameter)
|
||||
{
|
||||
switch (parameter) {
|
||||
case Parameter::AlphabeticalAscending:
|
||||
@@ -94,21 +89,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief List of all available Parameter sort orders.
|
||||
*/
|
||||
static QList<Parameter> allParameterList();
|
||||
|
||||
/**
|
||||
* @brief The current Parameter sort order list.
|
||||
*/
|
||||
static QList<Parameter> currentParameterList();
|
||||
|
||||
/**
|
||||
* @brief Save the give Parameter sort order list as the custom sort order.
|
||||
*/
|
||||
static void saveNewParameterList(const QList<Parameter> &newList);
|
||||
|
||||
/**
|
||||
* @brief Compare the given parameter of the two given rooms.
|
||||
*
|
||||
|
||||
@@ -60,9 +60,9 @@ QString EventHandler::authorDisplayName(const NeoChatRoom *room, const Quotient:
|
||||
return {};
|
||||
}
|
||||
|
||||
if (is<RoomMemberEvent>(*event) && event->unsignedJson()["prev_content"_L1].toObject().contains("displayname"_L1)
|
||||
if (is<RoomMemberEvent>(*event) && event->unsignedJson()[QStringLiteral("prev_content")].toObject().contains("displayname"_L1)
|
||||
&& event->stateKey() == event->senderId()) {
|
||||
auto previousDisplayName = event->unsignedJson()["prev_content"_L1]["displayname"_L1].toString().toHtmlEscaped();
|
||||
auto previousDisplayName = event->unsignedJson()[QStringLiteral("prev_content")][QStringLiteral("displayname")].toString().toHtmlEscaped();
|
||||
if (previousDisplayName.isEmpty()) {
|
||||
previousDisplayName = event->senderId();
|
||||
}
|
||||
@@ -86,39 +86,32 @@ QString EventHandler::singleLineAuthorDisplayname(const NeoChatRoom *room, const
|
||||
|
||||
const auto author = isPending ? room->localMember() : room->member(event->senderId());
|
||||
auto displayName = author.displayName();
|
||||
displayName.replace(u"<br>\n"_s, u" "_s);
|
||||
displayName.replace(u"<br>"_s, u" "_s);
|
||||
displayName.replace(u"<br />\n"_s, u" "_s);
|
||||
displayName.replace(u"<br />"_s, u" "_s);
|
||||
displayName.replace(u'\n', u" "_s);
|
||||
displayName.replace(u'\u2028', u" "_s);
|
||||
displayName.replace(QStringLiteral("<br>\n"), QStringLiteral(" "));
|
||||
displayName.replace(QStringLiteral("<br>"), QStringLiteral(" "));
|
||||
displayName.replace(QStringLiteral("<br />\n"), QStringLiteral(" "));
|
||||
displayName.replace(QStringLiteral("<br />"), QStringLiteral(" "));
|
||||
displayName.replace(u'\n', QStringLiteral(" "));
|
||||
displayName.replace(u'\u2028', QStringLiteral(" "));
|
||||
return displayName;
|
||||
}
|
||||
|
||||
QDateTime EventHandler::time(const NeoChatRoom *room, const Quotient::RoomEvent *event, bool isPending)
|
||||
QDateTime EventHandler::time(const Quotient::RoomEvent *event, bool isPending, QDateTime lastUpdated)
|
||||
{
|
||||
if (room == nullptr) {
|
||||
qCWarning(EventHandling) << "time called with room set to nullptr.";
|
||||
return {};
|
||||
}
|
||||
if (event == nullptr) {
|
||||
qCWarning(EventHandling) << "time called with event set to nullptr.";
|
||||
return {};
|
||||
}
|
||||
|
||||
if (isPending) {
|
||||
const auto pendingIt = room->findPendingEvent(event->transactionId());
|
||||
if (pendingIt != room->pendingEvents().end()) {
|
||||
return pendingIt->lastUpdated();
|
||||
}
|
||||
if (isPending && lastUpdated == QDateTime()) {
|
||||
qCWarning(EventHandling) << "a value must be provided for lastUpdated for a pending event.";
|
||||
return {};
|
||||
}
|
||||
return event->originTimestamp();
|
||||
|
||||
return isPending ? lastUpdated : event->originTimestamp();
|
||||
}
|
||||
|
||||
QString EventHandler::timeString(const NeoChatRoom *room, const Quotient::RoomEvent *event, bool relative, QLocale::FormatType format, bool isPending)
|
||||
QString EventHandler::timeString(const Quotient::RoomEvent *event, bool relative, QLocale::FormatType format, bool isPending, QDateTime lastUpdated)
|
||||
{
|
||||
auto ts = time(room, event, isPending);
|
||||
auto ts = time(event, isPending, lastUpdated);
|
||||
if (ts.isValid()) {
|
||||
if (relative) {
|
||||
KFormat formatter;
|
||||
@@ -130,9 +123,9 @@ QString EventHandler::timeString(const NeoChatRoom *room, const Quotient::RoomEv
|
||||
return {};
|
||||
}
|
||||
|
||||
QString EventHandler::timeString(const NeoChatRoom *room, const Quotient::RoomEvent *event, const QString &format, bool isPending)
|
||||
QString EventHandler::timeString(const Quotient::RoomEvent *event, const QString &format, bool isPending, const QDateTime &lastUpdated)
|
||||
{
|
||||
return time(room, event, isPending).toLocalTime().toString(format);
|
||||
return time(event, isPending, lastUpdated).toLocalTime().toString(format);
|
||||
}
|
||||
|
||||
bool EventHandler::isHighlighted(const NeoChatRoom *room, const Quotient::RoomEvent *event)
|
||||
@@ -202,7 +195,7 @@ bool EventHandler::isHidden(const NeoChatRoom *room, const Quotient::RoomEvent *
|
||||
}
|
||||
|
||||
// hide ending live location beacons
|
||||
if (event->isStateEvent() && event->matrixType() == "org.matrix.msc3672.beacon_info"_L1 && !event->contentJson()["live"_L1].toBool()) {
|
||||
if (event->isStateEvent() && event->matrixType() == "org.matrix.msc3672.beacon_info"_ls && !event->contentJson()["live"_ls].toBool()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -211,7 +204,7 @@ bool EventHandler::isHidden(const NeoChatRoom *room, const Quotient::RoomEvent *
|
||||
|
||||
Qt::TextFormat EventHandler::messageBodyInputFormat(const Quotient::RoomMessageEvent &event)
|
||||
{
|
||||
if (event.mimeType().name() == "text/plain"_L1) {
|
||||
if (event.mimeType().name() == "text/plain"_ls) {
|
||||
return Qt::PlainText;
|
||||
} else {
|
||||
return Qt::RichText;
|
||||
@@ -316,8 +309,8 @@ QString EventHandler::getBody(const NeoChatRoom *room, const Quotient::RoomEvent
|
||||
}
|
||||
|
||||
if (prettyPrint) {
|
||||
subjectName =
|
||||
u"<a href=\"https://matrix.to/#/%1\" style=\"color: %2\">%3</a>"_s.arg(e.userId(), room->member(e.userId()).color().name(), subjectName);
|
||||
subjectName = QStringLiteral("<a href=\"https://matrix.to/#/%1\" style=\"color: %2\">%3</a>")
|
||||
.arg(e.userId(), room->member(e.userId()).color().name(), subjectName);
|
||||
}
|
||||
|
||||
// The below code assumes senderName output in AuthorRole
|
||||
@@ -383,7 +376,7 @@ QString EventHandler::getBody(const NeoChatRoom *room, const Quotient::RoomEvent
|
||||
if (e.senderId() == e.userId()) {
|
||||
return i18n("left the room");
|
||||
}
|
||||
if (const auto &reason = e.contentJson()["reason"_L1].toString().toHtmlEscaped(); !reason.isEmpty()) {
|
||||
if (const auto &reason = e.contentJson()["reason"_ls].toString().toHtmlEscaped(); !reason.isEmpty()) {
|
||||
return i18n("has put %1 out of the room: %2", subjectName, reason);
|
||||
}
|
||||
return i18n("has put %1 out of the room", subjectName);
|
||||
@@ -398,7 +391,7 @@ QString EventHandler::getBody(const NeoChatRoom *room, const Quotient::RoomEvent
|
||||
return i18n("self-banned from the room");
|
||||
}
|
||||
case Membership::Knock: {
|
||||
QString reason(e.contentJson()["reason"_L1].toString().toHtmlEscaped());
|
||||
QString reason(e.contentJson()["reason"_ls].toString().toHtmlEscaped());
|
||||
return reason.isEmpty() ? i18n("requested an invite") : i18n("requested an invite with reason: %1", reason);
|
||||
}
|
||||
default:;
|
||||
@@ -426,26 +419,26 @@ QString EventHandler::getBody(const NeoChatRoom *room, const Quotient::RoomEvent
|
||||
},
|
||||
[prettyPrint](const RoomCreateEvent &e) {
|
||||
return e.isUpgrade()
|
||||
? i18n("upgraded the room to version %1", e.version().isEmpty() ? "1"_L1 : (prettyPrint ? e.version().toHtmlEscaped() : e.version()))
|
||||
: i18n("created the room, version %1", e.version().isEmpty() ? "1"_L1 : (prettyPrint ? e.version().toHtmlEscaped() : e.version()));
|
||||
? i18n("upgraded the room to version %1", e.version().isEmpty() ? "1"_ls : (prettyPrint ? e.version().toHtmlEscaped() : e.version()))
|
||||
: i18n("created the room, version %1", e.version().isEmpty() ? "1"_ls : (prettyPrint ? e.version().toHtmlEscaped() : e.version()));
|
||||
},
|
||||
[](const RoomPowerLevelsEvent &) {
|
||||
return i18nc("'power level' means permission level", "changed the power levels for this room");
|
||||
},
|
||||
[](const LocationBeaconEvent &e) {
|
||||
return e.contentJson()["description"_L1].toString();
|
||||
return e.contentJson()["description"_ls].toString();
|
||||
},
|
||||
[](const RoomServerAclEvent &) {
|
||||
return i18n("changed the server access control lists for this room");
|
||||
},
|
||||
[](const WidgetEvent &e) {
|
||||
if (e.fullJson()["unsigned"_L1]["prev_content"_L1].toObject().isEmpty()) {
|
||||
return i18nc("[User] added <name> widget", "added %1 widget", e.contentJson()["name"_L1].toString());
|
||||
if (e.fullJson()["unsigned"_ls]["prev_content"_ls].toObject().isEmpty()) {
|
||||
return i18nc("[User] added <name> widget", "added %1 widget", e.contentJson()["name"_ls].toString());
|
||||
}
|
||||
if (e.contentJson().isEmpty()) {
|
||||
return i18nc("[User] removed <name> widget", "removed %1 widget", e.fullJson()["unsigned"_L1]["prev_content"_L1]["name"_L1].toString());
|
||||
return i18nc("[User] removed <name> widget", "removed %1 widget", e.fullJson()["unsigned"_ls]["prev_content"_ls]["name"_ls].toString());
|
||||
}
|
||||
return i18nc("[User] configured <name> widget", "configured %1 widget", e.contentJson()["name"_L1].toString());
|
||||
return i18nc("[User] configured <name> widget", "configured %1 widget", e.contentJson()["name"_ls].toString());
|
||||
},
|
||||
[prettyPrint](const StateEvent &e) {
|
||||
return e.stateKey().isEmpty() ? i18n("updated %1 state", e.matrixType())
|
||||
@@ -466,7 +459,7 @@ QString EventHandler::getMessageBody(const NeoChatRoom *room, const RoomMessageE
|
||||
if (fileCaption.isEmpty()) {
|
||||
fileCaption = event.plainBody();
|
||||
} else if (fileCaption != event.plainBody()) {
|
||||
fileCaption = event.plainBody() + " | "_L1 + fileCaption;
|
||||
fileCaption = event.plainBody() + " | "_ls + fileCaption;
|
||||
}
|
||||
textHandler.setData(fileCaption);
|
||||
return !fileCaption.isEmpty() ? textHandler.handleRecievePlainText(Qt::PlainText, stripNewlines) : i18n("a file");
|
||||
@@ -482,7 +475,7 @@ QString EventHandler::getMessageBody(const NeoChatRoom *room, const RoomMessageE
|
||||
textHandler.setData(body);
|
||||
|
||||
Qt::TextFormat inputFormat;
|
||||
if (event.mimeType().name() == "text/plain"_L1) {
|
||||
if (event.mimeType().name() == "text/plain"_ls) {
|
||||
inputFormat = Qt::PlainText;
|
||||
} else {
|
||||
inputFormat = Qt::RichText;
|
||||
@@ -510,7 +503,7 @@ QString EventHandler::genericBody(const NeoChatRoom *room, const Quotient::RoomE
|
||||
}
|
||||
|
||||
const auto sender = room->member(event->senderId());
|
||||
const auto senderString = u"<a href=\"https://matrix.to/#/%1\">%2</a>"_s.arg(sender.id(), sender.htmlSafeDisplayName());
|
||||
const auto senderString = QStringLiteral("<a href=\"https://matrix.to/#/%1\">%2</a>").arg(sender.id(), sender.htmlSafeDisplayName());
|
||||
|
||||
return switchOnType(
|
||||
*event,
|
||||
@@ -639,7 +632,7 @@ QString EventHandler::genericBody(const NeoChatRoom *room, const Quotient::RoomE
|
||||
return i18n("%1 changed the server access control lists for this room", senderString);
|
||||
},
|
||||
[senderString](const WidgetEvent &e) {
|
||||
if (e.fullJson()["unsigned"_L1]["prev_content"_L1].toObject().isEmpty()) {
|
||||
if (e.fullJson()["unsigned"_ls]["prev_content"_ls].toObject().isEmpty()) {
|
||||
return i18n("%1 added a widget", senderString);
|
||||
}
|
||||
if (e.contentJson().isEmpty()) {
|
||||
@@ -666,7 +659,7 @@ QString EventHandler::subtitleText(const NeoChatRoom *room, const Quotient::Room
|
||||
qCWarning(EventHandling) << "subtitleText called with event set to nullptr.";
|
||||
return {};
|
||||
}
|
||||
return singleLineAuthorDisplayname(room, event) + (event->isStateEvent() ? u" "_s : u": "_s) + plainBody(room, event, true);
|
||||
return singleLineAuthorDisplayname(room, event) + (event->isStateEvent() ? QLatin1String(" ") : QLatin1String(": ")) + plainBody(room, event, true);
|
||||
}
|
||||
|
||||
QVariantMap EventHandler::mediaInfo(const NeoChatRoom *room, const Quotient::RoomEvent *event)
|
||||
@@ -697,7 +690,7 @@ QVariantMap EventHandler::getMediaInfoForEvent(const NeoChatRoom *room, const Qu
|
||||
QVariantMap mediaInfo = getMediaInfoFromFileInfo(room, content.get(), eventId, false, false);
|
||||
// if filename isn't specifically given, it is in body
|
||||
// https://spec.matrix.org/latest/client-server-api/#mfile
|
||||
mediaInfo["filename"_L1] = content->commonInfo().originalName.isEmpty() ? roomMessageEvent->plainBody() : content->commonInfo().originalName;
|
||||
mediaInfo["filename"_ls] = content->commonInfo().originalName.isEmpty() ? roomMessageEvent->plainBody() : content->commonInfo().originalName;
|
||||
|
||||
return mediaInfo;
|
||||
} else if (event->is<StickerEvent>()) {
|
||||
@@ -719,80 +712,80 @@ QVariantMap EventHandler::getMediaInfoFromFileInfo(const NeoChatRoom *room,
|
||||
QVariantMap mediaInfo;
|
||||
|
||||
// Get the mxc URL for the media.
|
||||
if (!fileContent->url().isValid() || fileContent->url().scheme() != u"mxc"_s || eventId.isEmpty()) {
|
||||
mediaInfo["source"_L1] = QUrl();
|
||||
if (!fileContent->url().isValid() || fileContent->url().scheme() != QStringLiteral("mxc") || eventId.isEmpty()) {
|
||||
mediaInfo["source"_ls] = QUrl();
|
||||
} else {
|
||||
QUrl source = room->makeMediaUrl(eventId, fileContent->url());
|
||||
|
||||
if (source.isValid()) {
|
||||
mediaInfo["source"_L1] = source;
|
||||
mediaInfo["source"_ls] = source;
|
||||
} else {
|
||||
mediaInfo["source"_L1] = QUrl();
|
||||
mediaInfo["source"_ls] = QUrl();
|
||||
}
|
||||
}
|
||||
|
||||
auto mimeType = fileContent->type();
|
||||
// Add the MIME type for the media if available.
|
||||
mediaInfo["mimeType"_L1] = mimeType.name();
|
||||
mediaInfo["mimeType"_ls] = mimeType.name();
|
||||
|
||||
// Add the MIME type icon if available.
|
||||
mediaInfo["mimeIcon"_L1] = mimeType.iconName();
|
||||
mediaInfo["mimeIcon"_ls] = mimeType.iconName();
|
||||
|
||||
// Add media size if available.
|
||||
mediaInfo["size"_L1] = fileContent->commonInfo().payloadSize;
|
||||
mediaInfo["size"_ls] = fileContent->commonInfo().payloadSize;
|
||||
|
||||
mediaInfo["isSticker"_L1] = isSticker;
|
||||
mediaInfo["isSticker"_ls] = isSticker;
|
||||
|
||||
// Add parameter depending on media type.
|
||||
if (mimeType.name().contains(u"image"_s)) {
|
||||
if (mimeType.name().contains(QStringLiteral("image"))) {
|
||||
if (auto castInfo = static_cast<const EventContent::ImageContent *>(fileContent)) {
|
||||
mediaInfo["width"_L1] = castInfo->imageSize.width();
|
||||
mediaInfo["height"_L1] = castInfo->imageSize.height();
|
||||
mediaInfo["width"_ls] = castInfo->imageSize.width();
|
||||
mediaInfo["height"_ls] = castInfo->imageSize.height();
|
||||
|
||||
// TODO: Images in certain formats (e.g. WebP) will be erroneously marked as animated, even if they are static.
|
||||
mediaInfo["animated"_L1] = QMovie::supportedFormats().contains(mimeType.preferredSuffix().toUtf8());
|
||||
mediaInfo["animated"_ls] = QMovie::supportedFormats().contains(mimeType.preferredSuffix().toUtf8());
|
||||
|
||||
QVariantMap tempInfo;
|
||||
auto thumbnailInfo = getMediaInfoFromTumbnail(room, castInfo->thumbnail, eventId);
|
||||
if (thumbnailInfo["source"_L1].toUrl().scheme() == "mxc"_L1) {
|
||||
if (thumbnailInfo["source"_ls].toUrl().scheme() == "mxc"_ls) {
|
||||
tempInfo = thumbnailInfo;
|
||||
} else {
|
||||
QString blurhash = castInfo->originalInfoJson["xyz.amorgan.blurhash"_L1].toString();
|
||||
QString blurhash = castInfo->originalInfoJson["xyz.amorgan.blurhash"_ls].toString();
|
||||
if (blurhash.isEmpty()) {
|
||||
tempInfo["source"_L1] = QUrl();
|
||||
tempInfo["source"_ls] = QUrl();
|
||||
} else {
|
||||
tempInfo["source"_L1] = QUrl("image://blurhash/"_L1 + blurhash);
|
||||
tempInfo["source"_ls] = QUrl("image://blurhash/"_ls + blurhash);
|
||||
}
|
||||
}
|
||||
mediaInfo["tempInfo"_L1] = tempInfo;
|
||||
mediaInfo["tempInfo"_ls] = tempInfo;
|
||||
}
|
||||
}
|
||||
if (mimeType.name().contains(u"video"_s)) {
|
||||
if (mimeType.name().contains(QStringLiteral("video"))) {
|
||||
if (auto castInfo = static_cast<const EventContent::VideoContent *>(fileContent)) {
|
||||
mediaInfo["width"_L1] = castInfo->imageSize.width();
|
||||
mediaInfo["height"_L1] = castInfo->imageSize.height();
|
||||
mediaInfo["duration"_L1] = castInfo->duration;
|
||||
mediaInfo["width"_ls] = castInfo->imageSize.width();
|
||||
mediaInfo["height"_ls] = castInfo->imageSize.height();
|
||||
mediaInfo["duration"_ls] = castInfo->duration;
|
||||
|
||||
if (!isThumbnail) {
|
||||
QVariantMap tempInfo;
|
||||
auto thumbnailInfo = getMediaInfoFromTumbnail(room, castInfo->thumbnail, eventId);
|
||||
if (thumbnailInfo["source"_L1].toUrl().scheme() == "mxc"_L1) {
|
||||
if (thumbnailInfo["source"_ls].toUrl().scheme() == "mxc"_ls) {
|
||||
tempInfo = thumbnailInfo;
|
||||
} else {
|
||||
QString blurhash = castInfo->originalInfoJson["xyz.amorgan.blurhash"_L1].toString();
|
||||
QString blurhash = castInfo->originalInfoJson["xyz.amorgan.blurhash"_ls].toString();
|
||||
if (blurhash.isEmpty()) {
|
||||
tempInfo["source"_L1] = QUrl();
|
||||
tempInfo["source"_ls] = QUrl();
|
||||
} else {
|
||||
tempInfo["source"_L1] = QUrl("image://blurhash/"_L1 + blurhash);
|
||||
tempInfo["source"_ls] = QUrl("image://blurhash/"_ls + blurhash);
|
||||
}
|
||||
}
|
||||
mediaInfo["tempInfo"_L1] = tempInfo;
|
||||
mediaInfo["tempInfo"_ls] = tempInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mimeType.name().contains(u"audio"_s)) {
|
||||
if (mimeType.name().contains(QStringLiteral("audio"))) {
|
||||
if (auto castInfo = static_cast<const EventContent::AudioContent *>(fileContent)) {
|
||||
mediaInfo["duration"_L1] = castInfo->duration;
|
||||
mediaInfo["duration"_ls] = castInfo->duration;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -803,30 +796,30 @@ QVariantMap EventHandler::getMediaInfoFromTumbnail(const NeoChatRoom *room, cons
|
||||
{
|
||||
QVariantMap thumbnailInfo;
|
||||
|
||||
if (!thumbnail.url().isValid() || thumbnail.url().scheme() != u"mxc"_s || eventId.isEmpty()) {
|
||||
thumbnailInfo["source"_L1] = QUrl();
|
||||
if (!thumbnail.url().isValid() || thumbnail.url().scheme() != QStringLiteral("mxc") || eventId.isEmpty()) {
|
||||
thumbnailInfo["source"_ls] = QUrl();
|
||||
} else {
|
||||
QUrl source = room->makeMediaUrl(eventId, thumbnail.url());
|
||||
|
||||
if (source.isValid()) {
|
||||
thumbnailInfo["source"_L1] = source;
|
||||
thumbnailInfo["source"_ls] = source;
|
||||
} else {
|
||||
thumbnailInfo["source"_L1] = QUrl();
|
||||
thumbnailInfo["source"_ls] = QUrl();
|
||||
}
|
||||
}
|
||||
|
||||
auto mimeType = thumbnail.mimeType;
|
||||
// Add the MIME type for the media if available.
|
||||
thumbnailInfo["mimeType"_L1] = mimeType.name();
|
||||
thumbnailInfo["mimeType"_ls] = mimeType.name();
|
||||
|
||||
// Add the MIME type icon if available.
|
||||
thumbnailInfo["mimeIcon"_L1] = mimeType.iconName();
|
||||
thumbnailInfo["mimeIcon"_ls] = mimeType.iconName();
|
||||
|
||||
// Add media size if available.
|
||||
thumbnailInfo["size"_L1] = thumbnail.payloadSize;
|
||||
thumbnailInfo["size"_ls] = thumbnail.payloadSize;
|
||||
|
||||
thumbnailInfo["width"_L1] = thumbnail.imageSize.width();
|
||||
thumbnailInfo["height"_L1] = thumbnail.imageSize.height();
|
||||
thumbnailInfo["width"_ls] = thumbnail.imageSize.width();
|
||||
thumbnailInfo["height"_ls] = thumbnail.imageSize.height();
|
||||
|
||||
return thumbnailInfo;
|
||||
}
|
||||
@@ -856,7 +849,7 @@ float EventHandler::latitude(const Quotient::RoomEvent *event)
|
||||
return -100.0;
|
||||
}
|
||||
|
||||
const auto geoUri = event->contentJson()["geo_uri"_L1].toString();
|
||||
const auto geoUri = event->contentJson()["geo_uri"_ls].toString();
|
||||
if (geoUri.isEmpty()) {
|
||||
return -100.0; // latitude runs from -90deg to +90deg so -100 is out of range.
|
||||
}
|
||||
@@ -871,7 +864,7 @@ float EventHandler::longitude(const Quotient::RoomEvent *event)
|
||||
return -200.0;
|
||||
}
|
||||
|
||||
const auto geoUri = event->contentJson()["geo_uri"_L1].toString();
|
||||
const auto geoUri = event->contentJson()["geo_uri"_ls].toString();
|
||||
if (geoUri.isEmpty()) {
|
||||
return -200.0; // longitude runs from -180deg to +180deg so -200 is out of range.
|
||||
}
|
||||
@@ -886,7 +879,7 @@ QString EventHandler::locationAssetType(const Quotient::RoomEvent *event)
|
||||
return {};
|
||||
}
|
||||
|
||||
const auto assetType = event->contentJson()["org.matrix.msc3488.asset"_L1].toObject()["type"_L1].toString();
|
||||
const auto assetType = event->contentJson()["org.matrix.msc3488.asset"_ls].toObject()["type"_ls].toString();
|
||||
if (assetType.isEmpty()) {
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ public:
|
||||
/**
|
||||
* @brief Return a QDateTime object for the event timestamp.
|
||||
*/
|
||||
static QDateTime time(const NeoChatRoom *room, const Quotient::RoomEvent *event, bool isPending = false);
|
||||
static QDateTime time(const Quotient::RoomEvent *event, bool isPending = false, QDateTime lastUpdated = {});
|
||||
|
||||
/**
|
||||
* @brief Return a QString for the event timestamp.
|
||||
@@ -80,11 +80,11 @@ public:
|
||||
* @param lastUpdated the time the event was last updated locally as this cannot be
|
||||
* obtained from the event.
|
||||
*/
|
||||
static QString timeString(const NeoChatRoom *room,
|
||||
const Quotient::RoomEvent *event,
|
||||
static QString timeString(const Quotient::RoomEvent *event,
|
||||
bool relative,
|
||||
QLocale::FormatType format = QLocale::ShortFormat,
|
||||
bool isPending = false);
|
||||
bool isPending = false,
|
||||
QDateTime lastUpdated = {});
|
||||
|
||||
/**
|
||||
* @brief Return a QString for the event timestamp.
|
||||
@@ -98,7 +98,7 @@ public:
|
||||
* @param lastUpdated the time the event was last updated locally as this cannot be
|
||||
* obtained from the event.
|
||||
*/
|
||||
static QString timeString(const NeoChatRoom *room, const Quotient::RoomEvent *event, const QString &format, bool isPending = false);
|
||||
static QString timeString(const Quotient::RoomEvent *event, const QString &format, bool isPending = false, const QDateTime &lastUpdated = {});
|
||||
|
||||
/**
|
||||
* @brief Whether the event should be highlighted in the timeline.
|
||||
|
||||
@@ -8,31 +8,31 @@ using namespace Quotient;
|
||||
|
||||
ImagePackEventContent::ImagePackEventContent(const QJsonObject &json)
|
||||
{
|
||||
if (json.contains("pack"_L1)) {
|
||||
if (json.contains(QStringLiteral("pack"))) {
|
||||
pack = ImagePackEventContent::Pack{
|
||||
fromJson<std::optional<QString>>(json["pack"_L1].toObject()["display_name"_L1]),
|
||||
fromJson<std::optional<QUrl>>(json["pack"_L1].toObject()["avatar_url"_L1]),
|
||||
fromJson<std::optional<QStringList>>(json["pack"_L1].toObject()["usage"_L1]),
|
||||
fromJson<std::optional<QString>>(json["pack"_L1].toObject()["attribution"_L1]),
|
||||
fromJson<std::optional<QString>>(json["pack"_ls].toObject()["display_name"_ls]),
|
||||
fromJson<std::optional<QUrl>>(json["pack"_ls].toObject()["avatar_url"_ls]),
|
||||
fromJson<std::optional<QStringList>>(json["pack"_ls].toObject()["usage"_ls]),
|
||||
fromJson<std::optional<QString>>(json["pack"_ls].toObject()["attribution"_ls]),
|
||||
};
|
||||
} else {
|
||||
pack = std::nullopt;
|
||||
}
|
||||
|
||||
const auto &keys = json["images"_L1].toObject().keys();
|
||||
const auto &keys = json["images"_ls].toObject().keys();
|
||||
for (const auto &k : keys) {
|
||||
std::optional<EventContent::ImageInfo> info;
|
||||
if (json["images"_L1][k].toObject().contains("info"_L1)) {
|
||||
info = EventContent::ImageInfo(QUrl(json["images"_L1][k]["url"_L1].toString()), json["images"_L1][k]["info"_L1].toObject(), k);
|
||||
if (json["images"_ls][k].toObject().contains(QStringLiteral("info"))) {
|
||||
info = EventContent::ImageInfo(QUrl(json["images"_ls][k]["url"_ls].toString()), json["images"_ls][k]["info"_ls].toObject(), k);
|
||||
} else {
|
||||
info = std::nullopt;
|
||||
}
|
||||
images += ImagePackImage{
|
||||
k,
|
||||
fromJson<QUrl>(json["images"_L1][k]["url"_L1].toString()),
|
||||
fromJson<std::optional<QString>>(json["images"_L1][k]["body"_L1]),
|
||||
fromJson<QUrl>(json["images"_ls][k]["url"_ls].toString()),
|
||||
fromJson<std::optional<QString>>(json["images"_ls][k]["body"_ls]),
|
||||
info,
|
||||
fromJson<std::optional<QStringList>>(json["images"_L1][k]["usage"_L1]),
|
||||
fromJson<std::optional<QStringList>>(json["images"_ls][k]["usage"_ls]),
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -42,42 +42,42 @@ void ImagePackEventContent::fillJson(QJsonObject *o) const
|
||||
if (pack) {
|
||||
QJsonObject packJson;
|
||||
if (pack->displayName) {
|
||||
packJson["display_name"_L1] = *pack->displayName;
|
||||
packJson["display_name"_ls] = *pack->displayName;
|
||||
}
|
||||
if (pack->usage) {
|
||||
QJsonArray usageJson;
|
||||
for (const auto &usage : *pack->usage) {
|
||||
usageJson += usage;
|
||||
}
|
||||
packJson["usage"_L1] = usageJson;
|
||||
packJson["usage"_ls] = usageJson;
|
||||
}
|
||||
if (pack->avatarUrl) {
|
||||
packJson["avatar_url"_L1] = pack->avatarUrl->toString();
|
||||
packJson["avatar_url"_ls] = pack->avatarUrl->toString();
|
||||
}
|
||||
if (pack->attribution) {
|
||||
packJson["attribution"_L1] = *pack->attribution;
|
||||
packJson["attribution"_ls] = *pack->attribution;
|
||||
}
|
||||
(*o)["pack"_L1] = packJson;
|
||||
(*o)["pack"_ls] = packJson;
|
||||
}
|
||||
|
||||
QJsonObject imagesJson;
|
||||
for (const auto &image : images) {
|
||||
QJsonObject imageJson;
|
||||
imageJson["url"_L1] = image.url.toString();
|
||||
imageJson["url"_ls] = image.url.toString();
|
||||
if (image.body) {
|
||||
imageJson["body"_L1] = *image.body;
|
||||
imageJson["body"_ls] = *image.body;
|
||||
}
|
||||
if (image.usage) {
|
||||
QJsonArray usageJson;
|
||||
for (const auto &usage : *image.usage) {
|
||||
usageJson += usage;
|
||||
}
|
||||
imageJson["usage"_L1] = usageJson;
|
||||
imageJson["usage"_ls] = usageJson;
|
||||
}
|
||||
if (image.info.has_value()) {
|
||||
imageJson["info"_L1] = Quotient::EventContent::toInfoJson(*image.info);
|
||||
imageJson["info"_ls] = Quotient::EventContent::toInfoJson(*image.info);
|
||||
}
|
||||
imagesJson[image.shortcode] = imageJson;
|
||||
}
|
||||
(*o)["images"_L1] = imagesJson;
|
||||
(*o)["images"_ls] = imagesJson;
|
||||
}
|
||||
|
||||
@@ -7,10 +7,10 @@ using namespace Quotient;
|
||||
|
||||
QString JoinRulesEvent::joinRule() const
|
||||
{
|
||||
return fromJson<QString>(contentJson()["join_rule"_L1]);
|
||||
return fromJson<QString>(contentJson()["join_rule"_ls]);
|
||||
}
|
||||
|
||||
QJsonArray JoinRulesEvent::allow() const
|
||||
{
|
||||
return contentJson()["allow"_L1].toArray();
|
||||
return contentJson()["allow"_ls].toArray();
|
||||
}
|
||||
|
||||
@@ -12,12 +12,12 @@ PollStartEvent::PollStartEvent(const QJsonObject &obj)
|
||||
|
||||
int PollStartEvent::maxSelections() const
|
||||
{
|
||||
return contentJson()["org.matrix.msc3381.poll.start"_L1]["max_selections"_L1].toInt();
|
||||
return contentJson()["org.matrix.msc3381.poll.start"_ls]["max_selections"_ls].toInt();
|
||||
}
|
||||
|
||||
QString PollStartEvent::question() const
|
||||
{
|
||||
return contentJson()["org.matrix.msc3381.poll.start"_L1]["question"_L1]["body"_L1].toString();
|
||||
return contentJson()["org.matrix.msc3381.poll.start"_ls]["question"_ls]["body"_ls].toString();
|
||||
}
|
||||
|
||||
PollResponseEvent::PollResponseEvent(const QJsonObject &obj)
|
||||
@@ -32,7 +32,7 @@ PollEndEvent::PollEndEvent(const QJsonObject &obj)
|
||||
|
||||
PollResponseEvent::PollResponseEvent(const QString &pollStartEventId, QStringList responses)
|
||||
: RoomEvent(basicJson(TypeId,
|
||||
{{"org.matrix.msc3381.poll.response"_L1, QJsonObject{{"answers"_L1, QJsonArray::fromStringList(responses)}}},
|
||||
{"m.relates_to"_L1, QJsonObject{{"rel_type"_L1, "m.reference"_L1}, {"event_id"_L1, pollStartEventId}}}}))
|
||||
{{"org.matrix.msc3381.poll.response"_ls, QJsonObject{{"answers"_ls, QJsonArray::fromStringList(responses)}}},
|
||||
{"m.relates_to"_ls, QJsonObject{{"rel_type"_ls, "m.reference"_ls}, {"event_id"_ls, pollStartEventId}}}}))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -11,8 +11,6 @@
|
||||
|
||||
#include "neochatconnection.h"
|
||||
|
||||
using namespace Qt::StringLiterals;
|
||||
|
||||
IdentityServerHelper::IdentityServerHelper(QObject *parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
@@ -77,8 +75,8 @@ void IdentityServerHelper::checkUrl()
|
||||
return;
|
||||
}
|
||||
|
||||
const auto requestUrl = QUrl(m_url + u"/_matrix/identity/v2"_s);
|
||||
if (!(requestUrl.scheme() == u"https"_s || requestUrl.scheme() == u"http"_s)) {
|
||||
const auto requestUrl = QUrl(m_url + QStringLiteral("/_matrix/identity/v2"));
|
||||
if (!(requestUrl.scheme() == QStringLiteral("https") || requestUrl.scheme() == QStringLiteral("http"))) {
|
||||
m_status = Invalid;
|
||||
Q_EMIT statusChanged();
|
||||
return;
|
||||
@@ -103,7 +101,7 @@ void IdentityServerHelper::setIdentityServer()
|
||||
return;
|
||||
}
|
||||
|
||||
m_connection->setAccountData(u"m.identity_server"_s, {{"base_url"_L1, m_url}});
|
||||
m_connection->setAccountData(QLatin1String("m.identity_server"), {{QLatin1String("base_url"), m_url}});
|
||||
m_status = Ready;
|
||||
Q_EMIT statusChanged();
|
||||
}
|
||||
@@ -113,7 +111,7 @@ void IdentityServerHelper::clearIdentityServer()
|
||||
if (m_connection->identityServer().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
m_connection->setAccountData(u"m.identity_server"_s, {{"base_url"_L1, QString()}});
|
||||
m_connection->setAccountData(QLatin1String("m.identity_server"), {{QLatin1String("base_url"), QString()}});
|
||||
m_status = Ready;
|
||||
Q_EMIT statusChanged();
|
||||
}
|
||||
|
||||
16
src/jobs/neochatadd3pidjob.cpp
Normal file
16
src/jobs/neochatadd3pidjob.cpp
Normal file
@@ -0,0 +1,16 @@
|
||||
// SPDX-FileCopyrightText: 2024 James Graham <james.h.graham@protonmail.com>
|
||||
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||
|
||||
#include "neochatadd3pidjob.h"
|
||||
|
||||
using namespace Quotient;
|
||||
|
||||
NeochatAdd3PIdJob::NeochatAdd3PIdJob(const QString &clientSecret, const QString &sid, const std::optional<QJsonObject> &auth)
|
||||
: BaseJob(HttpVerb::Post, QStringLiteral("Add3PIDJob"), makePath("/_matrix/client/v3", "/account/3pid/add"))
|
||||
{
|
||||
QJsonObject _dataJson;
|
||||
addParam<IfNotEmpty>(_dataJson, QStringLiteral("auth"), auth);
|
||||
addParam<>(_dataJson, QStringLiteral("client_secret"), clientSecret);
|
||||
addParam<>(_dataJson, QStringLiteral("sid"), sid);
|
||||
setRequestData({_dataJson});
|
||||
}
|
||||
12
src/jobs/neochatadd3pidjob.h
Normal file
12
src/jobs/neochatadd3pidjob.h
Normal file
@@ -0,0 +1,12 @@
|
||||
// SPDX-FileCopyrightText: 2024 James Graham <james.h.graham@protonmail.com>
|
||||
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Quotient/jobs/basejob.h>
|
||||
|
||||
class NeochatAdd3PIdJob : public Quotient::BaseJob
|
||||
{
|
||||
public:
|
||||
explicit NeochatAdd3PIdJob(const QString &clientSecret, const QString &sid, const std::optional<QJsonObject> &auth = {});
|
||||
};
|
||||
16
src/jobs/neochatchangepasswordjob.cpp
Normal file
16
src/jobs/neochatchangepasswordjob.cpp
Normal file
@@ -0,0 +1,16 @@
|
||||
// SPDX-FileCopyrightText: 2023 Tobias Fella <tobias.fella@kde.org>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "neochatchangepasswordjob.h"
|
||||
|
||||
using namespace Quotient;
|
||||
|
||||
NeochatChangePasswordJob::NeochatChangePasswordJob(const QString &newPassword, bool logoutDevices, const std::optional<QJsonObject> &auth)
|
||||
: BaseJob(HttpVerb::Post, QStringLiteral("ChangePasswordJob"), "/_matrix/client/r0/account/password")
|
||||
{
|
||||
QJsonObject _data;
|
||||
addParam<>(_data, QStringLiteral("new_password"), newPassword);
|
||||
addParam<IfNotEmpty>(_data, QStringLiteral("logout_devices"), logoutDevices);
|
||||
addParam<IfNotEmpty>(_data, QStringLiteral("auth"), auth);
|
||||
setRequestData(_data);
|
||||
}
|
||||
12
src/jobs/neochatchangepasswordjob.h
Normal file
12
src/jobs/neochatchangepasswordjob.h
Normal file
@@ -0,0 +1,12 @@
|
||||
// SPDX-FileCopyrightText: 2023 Tobias Fella <tobias.fella@kde.org>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Quotient/jobs/basejob.h>
|
||||
|
||||
class NeochatChangePasswordJob : public Quotient::BaseJob
|
||||
{
|
||||
public:
|
||||
explicit NeochatChangePasswordJob(const QString &newPassword, bool logoutDevices, const std::optional<QJsonObject> &auth = {});
|
||||
};
|
||||
@@ -6,9 +6,9 @@
|
||||
using namespace Quotient;
|
||||
|
||||
NeoChatDeactivateAccountJob::NeoChatDeactivateAccountJob(const std::optional<QJsonObject> &auth)
|
||||
: BaseJob(HttpVerb::Post, u"DisableDeviceJob"_s, "_matrix/client/v3/account/deactivate")
|
||||
: BaseJob(HttpVerb::Post, QStringLiteral("DisableDeviceJob"), "_matrix/client/v3/account/deactivate")
|
||||
{
|
||||
QJsonObject data;
|
||||
addParam<IfNotEmpty>(data, u"auth"_s, auth);
|
||||
addParam<IfNotEmpty>(data, QStringLiteral("auth"), auth);
|
||||
setRequestData(data);
|
||||
}
|
||||
|
||||
14
src/jobs/neochatdeletedevicejob.cpp
Normal file
14
src/jobs/neochatdeletedevicejob.cpp
Normal file
@@ -0,0 +1,14 @@
|
||||
// SPDX-FileCopyrightText: 2023 Tobias Fella <tobias.fella@kde.org>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "neochatdeletedevicejob.h"
|
||||
|
||||
using namespace Quotient;
|
||||
|
||||
NeochatDeleteDeviceJob::NeochatDeleteDeviceJob(const QString &deviceId, const std::optional<QJsonObject> &auth)
|
||||
: BaseJob(HttpVerb::Delete, QStringLiteral("DeleteDeviceJob"), QStringLiteral("/_matrix/client/r0/devices/%1").arg(deviceId).toLatin1())
|
||||
{
|
||||
QJsonObject _data;
|
||||
addParam<IfNotEmpty>(_data, QStringLiteral("auth"), auth);
|
||||
setRequestData(std::move(_data));
|
||||
}
|
||||
12
src/jobs/neochatdeletedevicejob.h
Normal file
12
src/jobs/neochatdeletedevicejob.h
Normal file
@@ -0,0 +1,12 @@
|
||||
// SPDX-FileCopyrightText: 2023 Tobias Fella <tobias.fella@kde.org>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <Quotient/jobs/basejob.h>
|
||||
|
||||
class NeochatDeleteDeviceJob : public Quotient::BaseJob
|
||||
{
|
||||
public:
|
||||
explicit NeochatDeleteDeviceJob(const QString &deviceId, const std::optional<QJsonObject> &auth = {});
|
||||
};
|
||||
@@ -6,6 +6,9 @@
|
||||
using namespace Quotient;
|
||||
|
||||
NeochatGetCommonRoomsJob::NeochatGetCommonRoomsJob(const QString &userId)
|
||||
: BaseJob(HttpVerb::Get, u"GetCommonRoomsJob"_s, "/_matrix/client/unstable/uk.half-shot.msc2666/user/mutual_rooms", QUrlQuery({{u"user_id"_s, userId}}))
|
||||
: BaseJob(HttpVerb::Get,
|
||||
QStringLiteral("GetCommonRoomsJob"),
|
||||
QStringLiteral("/_matrix/client/unstable/uk.half-shot.msc2666/user/mutual_rooms").toLatin1(),
|
||||
QUrlQuery({{QStringLiteral("user_id"), userId}}))
|
||||
{
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ QUrl LinkPreviewer::url() const
|
||||
|
||||
void LinkPreviewer::loadUrlPreview()
|
||||
{
|
||||
if (m_url.scheme() == u"https"_s) {
|
||||
if (m_url.scheme() == QStringLiteral("https")) {
|
||||
m_loaded = false;
|
||||
Q_EMIT loadedChanged();
|
||||
|
||||
@@ -72,11 +72,11 @@ void LinkPreviewer::loadUrlPreview()
|
||||
|
||||
connect(job, &BaseJob::success, this, [this, job, conn]() {
|
||||
const auto json = job->jsonData();
|
||||
m_title = json["og:title"_L1].toString().trimmed();
|
||||
m_description = json["og:description"_L1].toString().trimmed().replace("\n"_L1, " "_L1);
|
||||
m_title = json["og:title"_ls].toString().trimmed();
|
||||
m_description = json["og:description"_ls].toString().trimmed().replace("\n"_ls, " "_ls);
|
||||
|
||||
auto imageUrl = QUrl(json["og:image"_L1].toString());
|
||||
if (imageUrl.isValid() && imageUrl.scheme() == u"mxc"_s) {
|
||||
auto imageUrl = QUrl(json["og:image"_ls].toString());
|
||||
if (imageUrl.isValid() && imageUrl.scheme() == QStringLiteral("mxc")) {
|
||||
m_imageSource = conn->makeMediaUrl(imageUrl);
|
||||
} else {
|
||||
m_imageSource = QUrl();
|
||||
@@ -103,7 +103,7 @@ QList<QUrl> LinkPreviewer::linkPreviews(QString string)
|
||||
QList<QUrl> links;
|
||||
while (linksMatch.hasNext()) {
|
||||
auto link = linksMatch.next().captured();
|
||||
if (!link.contains(u"matrix.to"_s) && !links.contains(QUrl(link))) {
|
||||
if (!link.contains(QStringLiteral("matrix.to")) && !links.contains(QUrl(link))) {
|
||||
links += QUrl(link);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,8 +13,6 @@
|
||||
#include <QMutex>
|
||||
#include <QStandardPaths>
|
||||
|
||||
using namespace Qt::StringLiterals;
|
||||
|
||||
static QLoggingCategory::CategoryFilter oldCategoryFilter = nullptr;
|
||||
static QtMessageHandler oldHandler = nullptr;
|
||||
static bool e2eeDebugEnabled = false;
|
||||
@@ -89,32 +87,32 @@ public:
|
||||
QMutexLocker locker(&mutex);
|
||||
QByteArray buf;
|
||||
QTextStream str(&buf);
|
||||
str << QDateTime::currentDateTime().toString(Qt::ISODate) << u" ["_s;
|
||||
str << QDateTime::currentDateTime().toString(Qt::ISODate) << QStringLiteral(" [");
|
||||
switch (type) {
|
||||
case QtDebugMsg:
|
||||
str << u"DEBUG"_s;
|
||||
str << QStringLiteral("DEBUG");
|
||||
break;
|
||||
case QtInfoMsg:
|
||||
str << u"INFO "_s;
|
||||
str << QStringLiteral("INFO ");
|
||||
break;
|
||||
case QtWarningMsg:
|
||||
str << u"WARN "_s;
|
||||
str << QStringLiteral("WARN ");
|
||||
break;
|
||||
case QtFatalMsg:
|
||||
str << u"FATAL"_s;
|
||||
str << QStringLiteral("FATAL");
|
||||
break;
|
||||
case QtCriticalMsg:
|
||||
str << u"CRITICAL"_s;
|
||||
str << QStringLiteral("CRITICAL");
|
||||
break;
|
||||
}
|
||||
str << u"] "_s << context.category << u": "_s;
|
||||
str << QStringLiteral("] ") << context.category << QStringLiteral(": ");
|
||||
if (context.file && *context.file && context.line) {
|
||||
str << context.file << u":"_s << context.line << u": "_s;
|
||||
str << context.file << QStringLiteral(":") << context.line << QStringLiteral(": ");
|
||||
}
|
||||
if (context.function && *context.function) {
|
||||
str << context.function << u": "_s;
|
||||
str << context.function << QStringLiteral(": ");
|
||||
}
|
||||
str << message << u"\n"_s;
|
||||
str << message << QStringLiteral("\n");
|
||||
str.flush();
|
||||
file.write(buf.constData(), buf.size());
|
||||
file.flush();
|
||||
@@ -131,18 +129,18 @@ public:
|
||||
if (file.isOpen()) {
|
||||
file.close();
|
||||
}
|
||||
const auto &filePath = u"%1%2%3"_s.arg(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation), QDir::separator(), appName);
|
||||
const auto &filePath = QStringLiteral("%1%2%3").arg(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation), QDir::separator(), appName);
|
||||
|
||||
QDir dir(QStandardPaths::writableLocation(QStandardPaths::AppDataLocation) + QDir::separator());
|
||||
auto entryList = dir.entryList({appName + u".*"_s});
|
||||
auto entryList = dir.entryList({appName + QStringLiteral(".*")});
|
||||
std::sort(entryList.begin(), entryList.end(), [](const auto &left, const auto &right) {
|
||||
auto leftIndex = left.split(u"."_s).last().toInt();
|
||||
auto rightIndex = right.split(u"."_s).last().toInt();
|
||||
auto leftIndex = left.split(QStringLiteral(".")).last().toInt();
|
||||
auto rightIndex = right.split(QStringLiteral(".")).last().toInt();
|
||||
return leftIndex > rightIndex;
|
||||
});
|
||||
for (const auto &entry : entryList) {
|
||||
bool ok = false;
|
||||
const auto index = entry.split(u"."_s).last().toInt(&ok);
|
||||
const auto index = entry.split(QStringLiteral(".")).last().toInt(&ok);
|
||||
if (!ok) {
|
||||
continue;
|
||||
}
|
||||
@@ -153,7 +151,7 @@ public:
|
||||
file.remove();
|
||||
continue;
|
||||
}
|
||||
const auto &newName = u"%1.%2"_s.arg(filePath, QString::number(index + 1));
|
||||
const auto &newName = QStringLiteral("%1.%2").arg(filePath, QString::number(index + 1));
|
||||
const auto success = file.copy(newName);
|
||||
if (success) {
|
||||
file.remove();
|
||||
@@ -170,7 +168,7 @@ public:
|
||||
if (!finfo.absoluteDir().exists()) {
|
||||
QDir().mkpath(finfo.absolutePath());
|
||||
}
|
||||
file.setFileName(filePath + u".0"_s);
|
||||
file.setFileName(filePath + QStringLiteral(".0"));
|
||||
file.open(QIODevice::WriteOnly | QIODevice::Unbuffered);
|
||||
}
|
||||
|
||||
@@ -217,7 +215,7 @@ void initLogging()
|
||||
oldCategoryFilter = QLoggingCategory::installFilter(filter);
|
||||
oldHandler = qInstallMessageHandler(messageHandler);
|
||||
sInstance->setOrigHandler(oldHandler);
|
||||
sInstance->setName(u"neochat.log"_s);
|
||||
sInstance->setName(QStringLiteral("neochat.log"));
|
||||
}
|
||||
|
||||
#include "logger.moc"
|
||||
|
||||
@@ -25,14 +25,14 @@ void LoginHelper::init()
|
||||
m_connection = new NeoChatConnection();
|
||||
m_matrixId = QString();
|
||||
m_password = QString();
|
||||
m_deviceName = u"NeoChat"_s;
|
||||
m_deviceName = QStringLiteral("NeoChat");
|
||||
m_supportsSso = false;
|
||||
m_supportsPassword = false;
|
||||
m_ssoUrl = QUrl();
|
||||
|
||||
connect(this, &LoginHelper::matrixIdChanged, this, [this]() {
|
||||
setHomeserverReachable(false);
|
||||
QRegularExpression validator(u"^\\@?[a-zA-Z0-9\\._=\\-/]+\\:[a-zA-Z0-9\\-]+(\\.[a-zA-Z0-9\\-]+)*(\\:[0-9]+)?$"_s);
|
||||
QRegularExpression validator(QStringLiteral("^\\@?[a-zA-Z0-9\\._=\\-/]+\\:[a-zA-Z0-9\\-]+(\\.[a-zA-Z0-9\\-]+)*(\\:[0-9]+)?$"));
|
||||
if (!validator.match(m_matrixId).hasMatch()) {
|
||||
return;
|
||||
}
|
||||
@@ -89,7 +89,7 @@ void LoginHelper::init()
|
||||
Q_EMIT isLoggingInChanged();
|
||||
});
|
||||
connect(m_connection, &Connection::loginError, this, [this](QString error, const QString &) {
|
||||
if (error == u"Invalid username or password"_s) {
|
||||
if (error == QStringLiteral("Invalid username or password")) {
|
||||
setInvalidPassword(true);
|
||||
} else {
|
||||
Q_EMIT loginErrorOccured(i18n("Login Failed: %1", error));
|
||||
|
||||
70
src/main.cpp
70
src/main.cpp
@@ -77,11 +77,11 @@ class NetworkAccessManagerFactory : public QQmlNetworkAccessManagerFactory
|
||||
auto nam = NetworkAccessManager::instance();
|
||||
nam->setRedirectPolicy(QNetworkRequest::NoLessSafeRedirectPolicy);
|
||||
|
||||
nam->enableStrictTransportSecurityStore(true, QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + u"/hsts/"_s);
|
||||
nam->enableStrictTransportSecurityStore(true, QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + QLatin1String("/hsts/"));
|
||||
nam->setStrictTransportSecurityEnabled(true);
|
||||
|
||||
auto namDiskCache = new QNetworkDiskCache(nam);
|
||||
namDiskCache->setCacheDirectory(QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + u"/nam/"_s);
|
||||
namDiskCache->setCacheDirectory(QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + QLatin1String("/nam/"));
|
||||
nam->setCache(namDiskCache);
|
||||
|
||||
return nam;
|
||||
@@ -111,13 +111,13 @@ int main(int argc, char *argv[])
|
||||
|
||||
#ifdef Q_OS_ANDROID
|
||||
QGuiApplication app(argc, argv);
|
||||
QQuickStyle::setStyle(u"org.kde.breeze"_s);
|
||||
QQuickStyle::setStyle(QStringLiteral("org.kde.breeze"));
|
||||
#else
|
||||
QIcon::setFallbackThemeName("breeze"_L1);
|
||||
QIcon::setFallbackThemeName("breeze"_ls);
|
||||
QApplication app(argc, argv);
|
||||
// Default to org.kde.desktop style unless the user forces another style
|
||||
if (qEnvironmentVariableIsEmpty("QT_QUICK_CONTROLS_STYLE")) {
|
||||
QQuickStyle::setStyle(u"org.kde.desktop"_s);
|
||||
QQuickStyle::setStyle(QStringLiteral("org.kde.desktop"));
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -127,46 +127,45 @@ int main(int argc, char *argv[])
|
||||
freopen("CONOUT$", "w", stderr);
|
||||
}
|
||||
|
||||
QApplication::setStyle(u"breeze"_s);
|
||||
QFont font(u"Segoe UI Emoji"_s);
|
||||
QApplication::setStyle(QStringLiteral("breeze"));
|
||||
QFont font(QStringLiteral("Segoe UI Emoji"));
|
||||
font.setPointSize(10);
|
||||
font.setHintingPreference(QFont::PreferNoHinting);
|
||||
app.setFont(font);
|
||||
#endif
|
||||
KLocalizedString::setApplicationDomain(QByteArrayLiteral("neochat"));
|
||||
|
||||
QGuiApplication::setOrganizationName("KDE"_L1);
|
||||
QGuiApplication::setOrganizationName("KDE"_ls);
|
||||
|
||||
KAboutData about(u"neochat"_s,
|
||||
KAboutData about(QStringLiteral("neochat"),
|
||||
i18n("NeoChat"),
|
||||
QStringLiteral(NEOCHAT_VERSION_STRING),
|
||||
i18n("Chat on Matrix"),
|
||||
KAboutLicense::GPL_V3,
|
||||
i18n("© 2018-2020 Black Hat, 2020-2024 KDE Community"));
|
||||
about.addAuthor(i18n("Carl Schwan"), i18n("Maintainer"), u"carl@carlschwan.eu"_s, u"https://carlschwan.eu"_s, QUrl(u"https://carlschwan.eu/avatar.png"_s));
|
||||
about.addAuthor(i18n("Tobias Fella"), i18n("Maintainer"), u"tobias.fella@kde.org"_s, u"https://tobiasfella.de"_s);
|
||||
about.addAuthor(i18n("James Graham"), i18n("Maintainer"), u"james.h.graham@protonmail.com"_s);
|
||||
about.addAuthor(i18n("Joshua Goins"),
|
||||
about.addAuthor(i18n("Carl Schwan"),
|
||||
i18n("Maintainer"),
|
||||
u"josh@redstrate.com"_s,
|
||||
u"https://redstrate.com/"_s,
|
||||
QUrl(u"https://redstrate.com/rss-image.png"_s));
|
||||
about.addCredit(i18n("Black Hat"), i18n("Original author of Spectral"), u"bhat@encom.eu.org"_s);
|
||||
about.addCredit(i18n("Alexey Rusakov"), i18n("Maintainer of libQuotient"), u"Kitsune-Ral@users.sf.net"_s);
|
||||
QStringLiteral("carl@carlschwan.eu"),
|
||||
QStringLiteral("https://carlschwan.eu"),
|
||||
QUrl(QStringLiteral("https://carlschwan.eu/avatar.png")));
|
||||
about.addAuthor(i18n("Tobias Fella"), i18n("Maintainer"), QStringLiteral("tobias.fella@kde.org"), QStringLiteral("https://tobiasfella.de"));
|
||||
about.addAuthor(i18n("James Graham"), i18n("Maintainer"), QStringLiteral("james.h.graham@protonmail.com"));
|
||||
about.addCredit(i18n("Black Hat"), i18n("Original author of Spectral"), QStringLiteral("bhat@encom.eu.org"));
|
||||
about.addCredit(i18n("Alexey Rusakov"), i18n("Maintainer of libQuotient"), QStringLiteral("Kitsune-Ral@users.sf.net"));
|
||||
about.setTranslator(i18nc("NAME OF TRANSLATORS", "Your names"), i18nc("EMAIL OF TRANSLATORS", "Your emails"));
|
||||
about.setOrganizationDomain("kde.org");
|
||||
|
||||
about.addComponent(u"libQuotient"_s,
|
||||
about.addComponent(QStringLiteral("libQuotient"),
|
||||
i18n("A Qt library to write cross-platform clients for Matrix"),
|
||||
i18nc("<version number> (built against <possibly different version number>)",
|
||||
"%1 (built against %2)",
|
||||
Quotient::versionString(),
|
||||
QStringLiteral(Quotient_VERSION_STRING)),
|
||||
u"https://github.com/quotient-im/libquotient"_s,
|
||||
QStringLiteral("https://github.com/quotient-im/libquotient"),
|
||||
KAboutLicense::LGPL_V2_1);
|
||||
|
||||
KAboutData::setApplicationData(about);
|
||||
QGuiApplication::setWindowIcon(QIcon::fromTheme(u"org.kde.neochat"_s));
|
||||
QGuiApplication::setWindowIcon(QIcon::fromTheme(QStringLiteral("org.kde.neochat")));
|
||||
|
||||
#if __has_include("KCrash")
|
||||
KCrash::initialize();
|
||||
@@ -180,33 +179,34 @@ int main(int argc, char *argv[])
|
||||
#ifdef NEOCHAT_FLATPAK
|
||||
// Copy over the included FontConfig configuration to the
|
||||
// app's config dir:
|
||||
QFile::copy(u"/app/etc/fonts/conf.d/99-noto-mono-color-emoji.conf"_s, u"/var/config/fontconfig/conf.d/99-noto-mono-color-emoji.conf"_s);
|
||||
QFile::copy(QStringLiteral("/app/etc/fonts/conf.d/99-noto-mono-color-emoji.conf"),
|
||||
QStringLiteral("/var/config/fontconfig/conf.d/99-noto-mono-color-emoji.conf"));
|
||||
#endif
|
||||
|
||||
ColorSchemer colorScheme;
|
||||
|
||||
QCommandLineParser parser;
|
||||
parser.setApplicationDescription(i18n("Client for the matrix communication protocol"));
|
||||
parser.addPositionalArgument(u"urls"_s, i18n("Supports matrix: url scheme"));
|
||||
parser.addOption(QCommandLineOption("ignore-ssl-errors"_L1, i18n("Ignore all SSL Errors, e.g., unsigned certificates.")));
|
||||
parser.addPositionalArgument(QStringLiteral("urls"), i18n("Supports matrix: url scheme"));
|
||||
parser.addOption(QCommandLineOption("ignore-ssl-errors"_ls, i18n("Ignore all SSL Errors, e.g., unsigned certificates.")));
|
||||
|
||||
QCommandLineOption testOption("test"_L1, i18n("Only used for autotests"));
|
||||
QCommandLineOption testOption("test"_ls, i18n("Only used for autotests"));
|
||||
testOption.setFlags(QCommandLineOption::HiddenFromHelp);
|
||||
parser.addOption(testOption);
|
||||
|
||||
#ifdef HAVE_KUNIFIEDPUSH
|
||||
QCommandLineOption dbusActivatedOption(u"dbus-activated"_s, i18n("Internal usage only."));
|
||||
QCommandLineOption dbusActivatedOption(QStringLiteral("dbus-activated"), i18n("Internal usage only."));
|
||||
dbusActivatedOption.setFlags(QCommandLineOption::Flag::HiddenFromHelp);
|
||||
parser.addOption(dbusActivatedOption);
|
||||
#endif
|
||||
|
||||
QCommandLineOption shareOption(u"share"_s, i18n("Share a URL to Matrix"), u"text"_s);
|
||||
QCommandLineOption shareOption(QStringLiteral("share"), i18n("Share a URL to Matrix"), QStringLiteral("text"));
|
||||
parser.addOption(shareOption);
|
||||
|
||||
about.setupCommandLine(&parser);
|
||||
parser.process(app);
|
||||
about.processCommandLine(&parser);
|
||||
Controller::setTestMode(parser.isSet("test"_L1));
|
||||
Controller::setTestMode(parser.isSet("test"_ls));
|
||||
|
||||
#ifdef HAVE_KUNIFIEDPUSH
|
||||
if (parser.isSet(dbusActivatedOption)) {
|
||||
@@ -218,7 +218,7 @@ int main(int argc, char *argv[])
|
||||
// Because KRunner may call us on the D-Bus (under the same service name org.kde.neochat) then it may
|
||||
// accidentally activate us for push notifications instead. If this happens, then immediately quit if the fake
|
||||
// runner is called.
|
||||
QDBusConnection::sessionBus().registerObject("/RoomRunner"_L1, new FakeRunner(), QDBusConnection::ExportScriptableContents);
|
||||
QDBusConnection::sessionBus().registerObject("/RoomRunner"_ls, new FakeRunner(), QDBusConnection::ExportScriptableContents);
|
||||
#endif
|
||||
|
||||
Controller::listenForNotifications();
|
||||
@@ -259,7 +259,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
auto args = arguments;
|
||||
args.removeFirst();
|
||||
if (args.length() == 2 && args[0] == "--share"_L1) {
|
||||
if (args.length() == 2 && args[0] == "--share"_ls) {
|
||||
ShareHandler::instance().setText(args[1]);
|
||||
return;
|
||||
}
|
||||
@@ -273,30 +273,30 @@ int main(int argc, char *argv[])
|
||||
engine.rootContext()->setContextObject(new KLocalizedContext(&engine));
|
||||
engine.setNetworkAccessManagerFactory(new NetworkAccessManagerFactory());
|
||||
|
||||
if (parser.isSet("ignore-ssl-errors"_L1)) {
|
||||
if (parser.isSet("ignore-ssl-errors"_ls)) {
|
||||
QObject::connect(NetworkAccessManager::instance(), &QNetworkAccessManager::sslErrors, NetworkAccessManager::instance(), [](QNetworkReply *reply) {
|
||||
reply->ignoreSslErrors();
|
||||
});
|
||||
}
|
||||
|
||||
if (parser.isSet("share"_L1)) {
|
||||
if (parser.isSet("share"_ls)) {
|
||||
ShareHandler::instance().setText(parser.value(shareOption));
|
||||
}
|
||||
|
||||
engine.addImageProvider(u"blurhash"_s, new BlurhashImageProvider);
|
||||
engine.addImageProvider(QLatin1String("blurhash"), new BlurhashImageProvider);
|
||||
|
||||
engine.loadFromModule("org.kde.neochat", "Main");
|
||||
if (engine.rootObjects().isEmpty()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!parser.positionalArguments().isEmpty() && !parser.isSet("share"_L1)) {
|
||||
if (!parser.positionalArguments().isEmpty() && !parser.isSet("share"_ls)) {
|
||||
RoomManager::instance().setUrlArgument(parser.positionalArguments()[0]);
|
||||
}
|
||||
|
||||
#ifdef HAVE_RUNNER
|
||||
auto runner = Runner::create(&engine, &engine);
|
||||
QDBusConnection::sessionBus().registerObject("/RoomRunner"_L1, runner, QDBusConnection::ExportScriptableContents);
|
||||
QDBusConnection::sessionBus().registerObject("/RoomRunner"_ls, runner, QDBusConnection::ExportScriptableContents);
|
||||
#endif
|
||||
|
||||
QWindow *window = windowFromEngine(&engine);
|
||||
|
||||
@@ -49,19 +49,19 @@ QVariant AccountEmoticonModel::data(const QModelIndex &index, int role) const
|
||||
}
|
||||
if (role == IsStickerRole) {
|
||||
if (image.usage) {
|
||||
return image.usage->isEmpty() || image.usage->contains("sticker"_L1);
|
||||
return image.usage->isEmpty() || image.usage->contains("sticker"_ls);
|
||||
}
|
||||
if (m_images->pack && m_images->pack->usage) {
|
||||
return m_images->pack->usage->isEmpty() || m_images->pack->usage->contains("sticker"_L1);
|
||||
return m_images->pack->usage->isEmpty() || m_images->pack->usage->contains("sticker"_ls);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (role == IsEmojiRole) {
|
||||
if (image.usage) {
|
||||
return image.usage->isEmpty() || image.usage->contains("emoticon"_L1);
|
||||
return image.usage->isEmpty() || image.usage->contains("emoticon"_ls);
|
||||
}
|
||||
if (m_images->pack && m_images->pack->usage) {
|
||||
return m_images->pack->usage->isEmpty() || m_images->pack->usage->contains("emoticon"_L1);
|
||||
return m_images->pack->usage->isEmpty() || m_images->pack->usage->contains("emoticon"_ls);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -93,7 +93,7 @@ void AccountEmoticonModel::setConnection(NeoChatConnection *connection)
|
||||
m_connection = connection;
|
||||
Q_EMIT connectionChanged();
|
||||
connect(m_connection, &Connection::accountDataChanged, this, [this](QString type) {
|
||||
if (type == u"im.ponies.user_emotes"_s) {
|
||||
if (type == QStringLiteral("im.ponies.user_emotes")) {
|
||||
reloadEmoticons();
|
||||
}
|
||||
});
|
||||
@@ -107,8 +107,8 @@ void AccountEmoticonModel::reloadEmoticons()
|
||||
}
|
||||
|
||||
QJsonObject json;
|
||||
if (m_connection->hasAccountData("im.ponies.user_emotes"_L1)) {
|
||||
json = m_connection->accountData("im.ponies.user_emotes"_L1)->contentJson();
|
||||
if (m_connection->hasAccountData("im.ponies.user_emotes"_ls)) {
|
||||
json = m_connection->accountData("im.ponies.user_emotes"_ls)->contentJson();
|
||||
}
|
||||
const auto &content = ImagePackEventContent(json);
|
||||
beginResetModel();
|
||||
@@ -125,7 +125,7 @@ void AccountEmoticonModel::deleteEmoticon(int index)
|
||||
QJsonObject data;
|
||||
m_images->images.removeAt(index);
|
||||
m_images->fillJson(&data);
|
||||
m_connection->setAccountData("im.ponies.user_emotes"_L1, data);
|
||||
m_connection->setAccountData("im.ponies.user_emotes"_ls, data);
|
||||
}
|
||||
|
||||
void AccountEmoticonModel::setEmoticonBody(int index, const QString &text)
|
||||
@@ -137,7 +137,7 @@ void AccountEmoticonModel::setEmoticonBody(int index, const QString &text)
|
||||
m_images->images[index].body = text;
|
||||
QJsonObject data;
|
||||
m_images->fillJson(&data);
|
||||
m_connection->setAccountData("im.ponies.user_emotes"_L1, data);
|
||||
m_connection->setAccountData("im.ponies.user_emotes"_ls, data);
|
||||
}
|
||||
|
||||
void AccountEmoticonModel::setEmoticonShortcode(int index, const QString &shortcode)
|
||||
@@ -149,7 +149,7 @@ void AccountEmoticonModel::setEmoticonShortcode(int index, const QString &shortc
|
||||
m_images->images[index].shortcode = shortcode;
|
||||
QJsonObject data;
|
||||
m_images->fillJson(&data);
|
||||
m_connection->setAccountData("im.ponies.user_emotes"_L1, data);
|
||||
m_connection->setAccountData("im.ponies.user_emotes"_ls, data);
|
||||
}
|
||||
|
||||
void AccountEmoticonModel::setEmoticonImage(int index, const QUrl &source)
|
||||
@@ -169,17 +169,17 @@ QCoro::Task<void> AccountEmoticonModel::doSetEmoticonImage(int index, QUrl sourc
|
||||
}
|
||||
m_images->images[index].url = job->contentUri();
|
||||
auto mime = QMimeDatabase().mimeTypeForUrl(source);
|
||||
source.setScheme("file"_L1);
|
||||
source.setScheme("file"_ls);
|
||||
QFileInfo fileInfo(source.isLocalFile() ? source.toLocalFile() : source.toString());
|
||||
EventContent::ImageInfo info;
|
||||
if (mime.name().startsWith("image/"_L1)) {
|
||||
if (mime.name().startsWith("image/"_ls)) {
|
||||
QImage image(source.toLocalFile());
|
||||
info = EventContent::ImageInfo(source, fileInfo.size(), mime, image.size(), fileInfo.fileName());
|
||||
}
|
||||
m_images->images[index].info = info;
|
||||
QJsonObject data;
|
||||
m_images->fillJson(&data);
|
||||
m_connection->setAccountData("im.ponies.user_emotes"_L1, data);
|
||||
m_connection->setAccountData("im.ponies.user_emotes"_ls, data);
|
||||
}
|
||||
|
||||
QCoro::Task<void> AccountEmoticonModel::doAddEmoticon(QUrl source, QString shortcode, QString description, QString type)
|
||||
@@ -191,10 +191,10 @@ QCoro::Task<void> AccountEmoticonModel::doAddEmoticon(QUrl source, QString short
|
||||
}
|
||||
|
||||
auto mime = QMimeDatabase().mimeTypeForUrl(source);
|
||||
source.setScheme("file"_L1);
|
||||
source.setScheme("file"_ls);
|
||||
QFileInfo fileInfo(source.isLocalFile() ? source.toLocalFile() : source.toString());
|
||||
EventContent::ImageInfo info;
|
||||
if (mime.name().startsWith("image/"_L1)) {
|
||||
if (mime.name().startsWith("image/"_ls)) {
|
||||
QImage image(source.toLocalFile());
|
||||
info = EventContent::ImageInfo(source, fileInfo.size(), mime, image.size(), fileInfo.fileName());
|
||||
}
|
||||
@@ -208,7 +208,7 @@ QCoro::Task<void> AccountEmoticonModel::doAddEmoticon(QUrl source, QString short
|
||||
});
|
||||
QJsonObject data;
|
||||
m_images->fillJson(&data);
|
||||
m_connection->setAccountData("im.ponies.user_emotes"_L1, data);
|
||||
m_connection->setAccountData("im.ponies.user_emotes"_ls, data);
|
||||
}
|
||||
|
||||
void AccountEmoticonModel::addEmoticon(const QUrl &source, const QString &shortcode, const QString &description, const QString &type)
|
||||
|
||||
@@ -20,17 +20,17 @@ using Action = ActionsModel::Action;
|
||||
using namespace Quotient;
|
||||
using namespace Qt::StringLiterals;
|
||||
|
||||
QStringList rainbowColors{"#ff2b00"_L1, "#ff5500"_L1, "#ff8000"_L1, "#ffaa00"_L1, "#ffd500"_L1, "#ffff00"_L1, "#d4ff00"_L1, "#aaff00"_L1, "#80ff00"_L1,
|
||||
"#55ff00"_L1, "#2bff00"_L1, "#00ff00"_L1, "#00ff2b"_L1, "#00ff55"_L1, "#00ff80"_L1, "#00ffaa"_L1, "#00ffd5"_L1, "#00ffff"_L1,
|
||||
"#00d4ff"_L1, "#00aaff"_L1, "#007fff"_L1, "#0055ff"_L1, "#002bff"_L1, "#0000ff"_L1, "#2a00ff"_L1, "#5500ff"_L1, "#7f00ff"_L1,
|
||||
"#aa00ff"_L1, "#d400ff"_L1, "#ff00ff"_L1, "#ff00d4"_L1, "#ff00aa"_L1, "#ff0080"_L1, "#ff0055"_L1, "#ff002b"_L1, "#ff0000"_L1};
|
||||
QStringList rainbowColors{"#ff2b00"_ls, "#ff5500"_ls, "#ff8000"_ls, "#ffaa00"_ls, "#ffd500"_ls, "#ffff00"_ls, "#d4ff00"_ls, "#aaff00"_ls, "#80ff00"_ls,
|
||||
"#55ff00"_ls, "#2bff00"_ls, "#00ff00"_ls, "#00ff2b"_ls, "#00ff55"_ls, "#00ff80"_ls, "#00ffaa"_ls, "#00ffd5"_ls, "#00ffff"_ls,
|
||||
"#00d4ff"_ls, "#00aaff"_ls, "#007fff"_ls, "#0055ff"_ls, "#002bff"_ls, "#0000ff"_ls, "#2a00ff"_ls, "#5500ff"_ls, "#7f00ff"_ls,
|
||||
"#aa00ff"_ls, "#d400ff"_ls, "#ff00ff"_ls, "#ff00d4"_ls, "#ff00aa"_ls, "#ff0080"_ls, "#ff0055"_ls, "#ff002b"_ls, "#ff0000"_ls};
|
||||
|
||||
auto leaveRoomLambda = [](const QString &text, NeoChatRoom *room, ChatBarCache *) {
|
||||
if (text.isEmpty()) {
|
||||
Q_EMIT room->showMessage(MessageType::Information, i18n("Leaving this room."));
|
||||
room->connection()->leaveRoom(room);
|
||||
} else {
|
||||
QRegularExpression roomRegex(uR"(^[#!][^:]+:\w(?:\w|\.|-)*\.\w+(?::\d{1,5})?)"_s);
|
||||
QRegularExpression roomRegex(QStringLiteral(R"(^[#!][^:]+:\w(?:\w|\.|-)*\.\w+(?::\d{1,5})?)"));
|
||||
auto regexMatch = roomRegex.match(text);
|
||||
if (!regexMatch.hasMatch()) {
|
||||
Q_EMIT room->showMessage(MessageType::Error,
|
||||
@@ -62,47 +62,51 @@ auto roomNickLambda = [](const QString &text, NeoChatRoom *room, ChatBarCache *)
|
||||
|
||||
QList<ActionsModel::Action> actions{
|
||||
Action{
|
||||
u"shrug"_s,
|
||||
QStringLiteral("shrug"),
|
||||
[](const QString &message, NeoChatRoom *, ChatBarCache *) {
|
||||
return u"¯\\\\_(ツ)_/¯ %1"_s.arg(message);
|
||||
return QStringLiteral("¯\\\\_(ツ)_/¯ %1").arg(message);
|
||||
},
|
||||
Quotient::RoomMessageEvent::MsgType::Text,
|
||||
true,
|
||||
std::nullopt,
|
||||
kli18n("<message>"),
|
||||
kli18n("Prepends ¯\\_(ツ)_/¯ to a plain-text message"),
|
||||
},
|
||||
Action{
|
||||
u"lenny"_s,
|
||||
QStringLiteral("lenny"),
|
||||
[](const QString &message, NeoChatRoom *, ChatBarCache *) {
|
||||
return u"( ͡° ͜ʖ ͡°) %1"_s.arg(message);
|
||||
return QStringLiteral("( ͡° ͜ʖ ͡°) %1").arg(message);
|
||||
},
|
||||
Quotient::RoomMessageEvent::MsgType::Text,
|
||||
true,
|
||||
std::nullopt,
|
||||
kli18n("<message>"),
|
||||
kli18n("Prepends ( ͡° ͜ʖ ͡°) to a plain-text message"),
|
||||
},
|
||||
Action{
|
||||
u"tableflip"_s,
|
||||
QStringLiteral("tableflip"),
|
||||
[](const QString &message, NeoChatRoom *, ChatBarCache *) {
|
||||
return u"(╯°□°)╯︵ ┻━┻ %1"_s.arg(message);
|
||||
return QStringLiteral("(╯°□°)╯︵ ┻━┻ %1").arg(message);
|
||||
},
|
||||
Quotient::RoomMessageEvent::MsgType::Text,
|
||||
true,
|
||||
std::nullopt,
|
||||
kli18n("<message>"),
|
||||
kli18n("Prepends (╯°□°)╯︵ ┻━┻ to a plain-text message"),
|
||||
},
|
||||
Action{
|
||||
u"unflip"_s,
|
||||
QStringLiteral("unflip"),
|
||||
[](const QString &message, NeoChatRoom *, ChatBarCache *) {
|
||||
return u"┬──┬ ノ( ゜-゜ノ) %1"_s.arg(message);
|
||||
return QStringLiteral("┬──┬ ノ( ゜-゜ノ) %1").arg(message);
|
||||
},
|
||||
Quotient::RoomMessageEvent::MsgType::Text,
|
||||
true,
|
||||
std::nullopt,
|
||||
kli18n("<message>"),
|
||||
kli18n("Prepends ┬──┬ ノ( ゜-゜ノ) to a plain-text message"),
|
||||
},
|
||||
Action{
|
||||
u"rainbow"_s,
|
||||
QStringLiteral("rainbow"),
|
||||
[](const QString &text, NeoChatRoom *room, ChatBarCache *chatBarCache) {
|
||||
QString rainbowText;
|
||||
for (int i = 0; i < text.length(); i++) {
|
||||
rainbowText += u"<font color='%2'>%3</font>"_s.arg(rainbowColors[i % rainbowColors.length()], text.at(i));
|
||||
rainbowText += QStringLiteral("<font color='%2'>%3</font>").arg(rainbowColors[i % rainbowColors.length()], text.at(i));
|
||||
}
|
||||
// Ideally, we would just return rainbowText and let that do the rest, but the colors don't survive markdownToHTML.
|
||||
auto content = std::make_unique<Quotient::EventContent::TextContent>(rainbowText, u"text/html"_s);
|
||||
@@ -111,40 +115,43 @@ QList<ActionsModel::Action> actions{
|
||||
room->post<Quotient::RoomMessageEvent>("/rainbow %1"_L1.arg(text), MessageEventType::Text, std::move(content), relatesTo);
|
||||
return QString();
|
||||
},
|
||||
false,
|
||||
std::nullopt,
|
||||
kli18n("<message>"),
|
||||
kli18n("Sends the given message colored as a rainbow"),
|
||||
},
|
||||
Action{
|
||||
u"rainbowme"_s,
|
||||
QStringLiteral("rainbowme"),
|
||||
[](const QString &text, NeoChatRoom *room, ChatBarCache *chatBarCache) {
|
||||
QString rainbowText;
|
||||
for (int i = 0; i < text.length(); i++) {
|
||||
rainbowText += u"<font color='%2'>%3</font>"_s.arg(rainbowColors[i % rainbowColors.length()], text.at(i));
|
||||
rainbowText += QStringLiteral("<font color='%2'>%3</font>").arg(rainbowColors[i % rainbowColors.length()], text.at(i));
|
||||
}
|
||||
// Ideally, we would just return rainbowText and let that do the rest, but the colors don't survive markdownToHTML.
|
||||
auto content = std::make_unique<Quotient::EventContent::TextContent>(rainbowText, u"text/html"_s);
|
||||
EventRelation relatesTo =
|
||||
chatBarCache->isReplying() ? EventRelation::replyTo(chatBarCache->replyId()) : EventRelation::replace(chatBarCache->editId());
|
||||
room->post<Quotient::RoomMessageEvent>(u"/rainbow %1"_s.arg(text), MessageEventType::Emote, std::move(content), relatesTo);
|
||||
room->post<Quotient::RoomMessageEvent>(u"/rainbow %1"_s.arg(text), MessageEventType::Text, std::move(content), relatesTo);
|
||||
return QString();
|
||||
},
|
||||
false,
|
||||
std::nullopt,
|
||||
kli18n("<message>"),
|
||||
kli18n("Sends the given emote colored as a rainbow"),
|
||||
},
|
||||
Action{
|
||||
u"plain"_s,
|
||||
QStringLiteral("plain"),
|
||||
[](const QString &text, NeoChatRoom *room, ChatBarCache *) {
|
||||
room->postPlainText(text.toHtmlEscaped());
|
||||
return QString();
|
||||
},
|
||||
false,
|
||||
std::nullopt,
|
||||
kli18n("<message>"),
|
||||
kli18n("Sends the given message as plain text"),
|
||||
},
|
||||
Action{
|
||||
u"spoiler"_s,
|
||||
QStringLiteral("spoiler"),
|
||||
[](const QString &text, NeoChatRoom *room, ChatBarCache *chatBarCache) {
|
||||
// Ideally, we would just return rainbowText and let that do the rest, but the colors don't survive markdownToHTML.
|
||||
auto content = std::make_unique<Quotient::EventContent::TextContent>(u"<span data-mx-spoiler>%1</span>"_s.arg(text), u"text/html"_s);
|
||||
@@ -153,32 +160,36 @@ QList<ActionsModel::Action> actions{
|
||||
room->post<Quotient::RoomMessageEvent>(u"/spoiler %1"_s.arg(text), MessageEventType::Text, std::move(content), relatesTo);
|
||||
return QString();
|
||||
},
|
||||
false,
|
||||
std::nullopt,
|
||||
kli18n("<message>"),
|
||||
kli18n("Sends the given message as a spoiler"),
|
||||
},
|
||||
Action{
|
||||
u"me"_s,
|
||||
QStringLiteral("me"),
|
||||
[](const QString &text, NeoChatRoom *, ChatBarCache *) {
|
||||
return text;
|
||||
},
|
||||
true,
|
||||
RoomMessageEvent::MsgType::Emote,
|
||||
kli18n("<message>"),
|
||||
kli18n("Sends the given emote"),
|
||||
},
|
||||
Action{
|
||||
u"notice"_s,
|
||||
QStringLiteral("notice"),
|
||||
[](const QString &text, NeoChatRoom *, ChatBarCache *) {
|
||||
return text;
|
||||
},
|
||||
true,
|
||||
RoomMessageEvent::MsgType::Notice,
|
||||
kli18n("<message>"),
|
||||
kli18n("Sends the given message as a notice"),
|
||||
},
|
||||
Action{
|
||||
u"invite"_s,
|
||||
QStringLiteral("invite"),
|
||||
[](const QString &text, NeoChatRoom *room, ChatBarCache *) {
|
||||
static const QRegularExpression mxidRegex(uR"((^|[][[:space:](){}`'";])([!#@][-a-z0-9_=#/.]{1,252}:\w(?:\w|\.|-)*\.\w+(?::\d{1,5})?))"_s);
|
||||
static const QRegularExpression mxidRegex(
|
||||
QStringLiteral(R"((^|[][[:space:](){}`'";])([!#@][-a-z0-9_=#/.]{1,252}:\w(?:\w|\.|-)*\.\w+(?::\d{1,5})?))"));
|
||||
auto regexMatch = mxidRegex.match(text);
|
||||
if (!regexMatch.hasMatch()) {
|
||||
Q_EMIT room->showMessage(MessageType::Error, i18nc("'<text>' does not look like a matrix id.", "'%1' does not look like a matrix id.", text));
|
||||
@@ -203,17 +214,18 @@ QList<ActionsModel::Action> actions{
|
||||
return QString();
|
||||
}
|
||||
room->inviteToRoom(text);
|
||||
Q_EMIT room->showMessage(MessageType::Positive, i18nc("<username> was invited into this room.", "%1 was invited into this room.", text));
|
||||
Q_EMIT room->showMessage(MessageType::Positive, i18nc("<username> was invited into this room", "%1 was invited into this room", text));
|
||||
return QString();
|
||||
},
|
||||
false,
|
||||
std::nullopt,
|
||||
kli18n("<user id>"),
|
||||
kli18n("Invites the user to this room"),
|
||||
},
|
||||
Action{
|
||||
u"join"_s,
|
||||
QStringLiteral("join"),
|
||||
[](const QString &text, NeoChatRoom *room, ChatBarCache *) {
|
||||
QRegularExpression roomRegex(uR"(^[#!][^:]+:\w(?:\w|\.|-)*\.\w+(?::\d{1,5})?)"_s);
|
||||
QRegularExpression roomRegex(QStringLiteral(R"(^[#!][^:]+:\w(?:\w|\.|-)*\.\w+(?::\d{1,5})?)"));
|
||||
auto regexMatch = roomRegex.match(text);
|
||||
if (!regexMatch.hasMatch()) {
|
||||
Q_EMIT room->showMessage(MessageType::Error,
|
||||
@@ -226,19 +238,20 @@ QList<ActionsModel::Action> actions{
|
||||
return QString();
|
||||
}
|
||||
Q_EMIT room->showMessage(MessageType::Information, i18nc("Joining room <roomname>.", "Joining room %1.", text));
|
||||
RoomManager::instance().resolveResource(text, "join"_L1);
|
||||
RoomManager::instance().resolveResource(text, "join"_ls);
|
||||
return QString();
|
||||
},
|
||||
false,
|
||||
std::nullopt,
|
||||
kli18n("<room alias or id>"),
|
||||
kli18n("Joins the given room"),
|
||||
},
|
||||
Action{
|
||||
u"knock"_s,
|
||||
QStringLiteral("knock"),
|
||||
[](const QString &text, NeoChatRoom *room, ChatBarCache *) {
|
||||
auto parts = text.split(u" "_s);
|
||||
auto parts = text.split(QLatin1String(" "));
|
||||
QString roomName = parts[0];
|
||||
QRegularExpression roomRegex(uR"(^[#!][^:]+:\w(?:\w|\.|-)*\.\w+(?::\d{1,5})?)"_s);
|
||||
QRegularExpression roomRegex(QStringLiteral(R"(^[#!][^:]+:\w(?:\w|\.|-)*\.\w+(?::\d{1,5})?)"));
|
||||
auto regexMatch = roomRegex.match(roomName);
|
||||
if (!regexMatch.hasMatch()) {
|
||||
Q_EMIT room->showMessage(MessageType::Error,
|
||||
@@ -252,7 +265,7 @@ QList<ActionsModel::Action> actions{
|
||||
}
|
||||
Q_EMIT room->showMessage(MessageType::Information, i18nc("Knocking room <roomname>.", "Knocking room %1.", text));
|
||||
auto connection = dynamic_cast<NeoChatConnection *>(room->connection());
|
||||
const auto knownServer = roomName.mid(roomName.indexOf(":"_L1) + 1);
|
||||
const auto knownServer = roomName.mid(roomName.indexOf(":"_ls) + 1);
|
||||
if (parts.length() >= 2) {
|
||||
RoomManager::instance().knockRoom(connection, roomName, parts[1], QStringList{knownServer});
|
||||
} else {
|
||||
@@ -260,14 +273,15 @@ QList<ActionsModel::Action> actions{
|
||||
}
|
||||
return QString();
|
||||
},
|
||||
false,
|
||||
std::nullopt,
|
||||
kli18n("<room alias or id> [<reason>]"),
|
||||
kli18n("Requests to join the given room"),
|
||||
},
|
||||
Action{
|
||||
u"j"_s,
|
||||
QStringLiteral("j"),
|
||||
[](const QString &text, NeoChatRoom *room, ChatBarCache *) {
|
||||
QRegularExpression roomRegex(uR"(^[#!][^:]+:\w(?:\w|\.|-)*\.\w+(?::\d{1,5})?)"_s);
|
||||
QRegularExpression roomRegex(QStringLiteral(R"(^[#!][^:]+:\w(?:\w|\.|-)*\.\w+(?::\d{1,5})?)"));
|
||||
auto regexMatch = roomRegex.match(text);
|
||||
if (!regexMatch.hasMatch()) {
|
||||
Q_EMIT room->showMessage(MessageType::Error,
|
||||
@@ -279,29 +293,32 @@ QList<ActionsModel::Action> actions{
|
||||
return QString();
|
||||
}
|
||||
Q_EMIT room->showMessage(MessageType::Information, i18nc("Joining room <roomname>.", "Joining room %1.", text));
|
||||
RoomManager::instance().resolveResource(text, "join"_L1);
|
||||
RoomManager::instance().resolveResource(text, "join"_ls);
|
||||
return QString();
|
||||
},
|
||||
false,
|
||||
std::nullopt,
|
||||
kli18n("<room alias or id>"),
|
||||
kli18n("Joins the given room"),
|
||||
},
|
||||
Action{
|
||||
u"part"_s,
|
||||
QStringLiteral("part"),
|
||||
leaveRoomLambda,
|
||||
false,
|
||||
std::nullopt,
|
||||
kli18n("[<room alias or id>]"),
|
||||
kli18n("Leaves the given room or this room, if there is none given"),
|
||||
},
|
||||
Action{
|
||||
u"leave"_s,
|
||||
QStringLiteral("leave"),
|
||||
leaveRoomLambda,
|
||||
false,
|
||||
std::nullopt,
|
||||
kli18n("[<room alias or id>]"),
|
||||
kli18n("Leaves the given room or this room, if there is none given"),
|
||||
},
|
||||
Action{
|
||||
u"nick"_s,
|
||||
QStringLiteral("nick"),
|
||||
[](const QString &text, NeoChatRoom *room, ChatBarCache *) {
|
||||
if (text.isEmpty()) {
|
||||
Q_EMIT room->showMessage(MessageType::Error, i18n("No new nickname provided, no changes will happen."));
|
||||
@@ -310,28 +327,32 @@ QList<ActionsModel::Action> actions{
|
||||
}
|
||||
return QString();
|
||||
},
|
||||
false,
|
||||
std::nullopt,
|
||||
kli18n("<display name>"),
|
||||
kli18n("Changes your global display name"),
|
||||
},
|
||||
Action{
|
||||
u"roomnick"_s,
|
||||
QStringLiteral("roomnick"),
|
||||
roomNickLambda,
|
||||
false,
|
||||
std::nullopt,
|
||||
kli18n("<display name>"),
|
||||
kli18n("Changes your display name in this room"),
|
||||
},
|
||||
Action{
|
||||
u"myroomnick"_s,
|
||||
QStringLiteral("myroomnick"),
|
||||
roomNickLambda,
|
||||
false,
|
||||
std::nullopt,
|
||||
kli18n("<display name>"),
|
||||
kli18n("Changes your display name in this room"),
|
||||
},
|
||||
Action{
|
||||
u"ignore"_s,
|
||||
QStringLiteral("ignore"),
|
||||
[](const QString &text, NeoChatRoom *room, ChatBarCache *) {
|
||||
static const QRegularExpression mxidRegex(uR"((^|[][[:space:](){}`'";])([!#@][-a-z0-9_=#/.]{1,252}:\w(?:\w|\.|-)*\.\w+(?::\d{1,5})?))"_s);
|
||||
static const QRegularExpression mxidRegex(
|
||||
QStringLiteral(R"((^|[][[:space:](){}`'";])([!#@][-a-z0-9_=#/.]{1,252}:\w(?:\w|\.|-)*\.\w+(?::\d{1,5})?))"));
|
||||
auto regexMatch = mxidRegex.match(text);
|
||||
if (!regexMatch.hasMatch()) {
|
||||
Q_EMIT room->showMessage(MessageType::Error, i18nc("'<text>' does not look like a matrix id.", "'%1' does not look like a matrix id.", text));
|
||||
@@ -346,14 +367,16 @@ QList<ActionsModel::Action> actions{
|
||||
|
||||
return QString();
|
||||
},
|
||||
false,
|
||||
std::nullopt,
|
||||
kli18n("<user id>"),
|
||||
kli18n("Ignores the given user"),
|
||||
},
|
||||
Action{
|
||||
u"unignore"_s,
|
||||
QStringLiteral("unignore"),
|
||||
[](const QString &text, NeoChatRoom *room, ChatBarCache *) {
|
||||
static const QRegularExpression mxidRegex(uR"((^|[][[:space:](){}`'";])([!#@][-a-z0-9_=#/.]{1,252}:\w(?:\w|\.|-)*\.\w+(?::\d{1,5})?))"_s);
|
||||
static const QRegularExpression mxidRegex(
|
||||
QStringLiteral(R"((^|[][[:space:](){}`'";])([!#@][-a-z0-9_=#/.]{1,252}:\w(?:\w|\.|-)*\.\w+(?::\d{1,5})?))"));
|
||||
auto regexMatch = mxidRegex.match(text);
|
||||
if (!regexMatch.hasMatch()) {
|
||||
Q_EMIT room->showMessage(MessageType::Error, i18nc("'<text>' does not look like a matrix id.", "'%1' does not look like a matrix id.", text));
|
||||
@@ -367,12 +390,13 @@ QList<ActionsModel::Action> actions{
|
||||
Q_EMIT room->showMessage(MessageType::Positive, i18nc("<username> is no longer ignored.", "%1 is no longer ignored.", text));
|
||||
return QString();
|
||||
},
|
||||
false,
|
||||
std::nullopt,
|
||||
kli18n("<user id>"),
|
||||
kli18n("Unignores the given user"),
|
||||
},
|
||||
Action{
|
||||
u"react"_s,
|
||||
QStringLiteral("react"),
|
||||
[](const QString &text, NeoChatRoom *room, ChatBarCache *chatBarCache) {
|
||||
if (chatBarCache->replyId().isEmpty()) {
|
||||
for (auto it = room->messageEvents().crbegin(); it != room->messageEvents().crend(); it++) {
|
||||
@@ -386,15 +410,17 @@ QList<ActionsModel::Action> actions{
|
||||
room->toggleReaction(chatBarCache->replyId(), text);
|
||||
return QString();
|
||||
},
|
||||
false,
|
||||
std::nullopt,
|
||||
kli18n("<reaction text>"),
|
||||
kli18n("React to the message with the given text"),
|
||||
},
|
||||
Action{
|
||||
u"ban"_s,
|
||||
QStringLiteral("ban"),
|
||||
[](const QString &text, NeoChatRoom *room, ChatBarCache *) {
|
||||
auto parts = text.split(u" "_s);
|
||||
static const QRegularExpression mxidRegex(uR"((^|[][[:space:](){}`'";])([!#@][-a-z0-9_=#/.]{1,252}:\w(?:\w|\.|-)*\.\w+(?::\d{1,5})?))"_s);
|
||||
auto parts = text.split(QLatin1String(" "));
|
||||
static const QRegularExpression mxidRegex(
|
||||
QStringLiteral(R"((^|[][[:space:](){}`'";])([!#@][-a-z0-9_=#/.]{1,252}:\w(?:\w|\.|-)*\.\w+(?::\d{1,5})?))"));
|
||||
auto regexMatch = mxidRegex.match(parts[0]);
|
||||
if (!regexMatch.hasMatch()) {
|
||||
Q_EMIT room->showMessage(MessageType::Error, i18nc("'<text>' does not look like a matrix id.", "'%1' does not look like a matrix id.", text));
|
||||
@@ -424,14 +450,16 @@ QList<ActionsModel::Action> actions{
|
||||
Q_EMIT room->showMessage(MessageType::Positive, i18nc("<username> was banned from this room.", "%1 was banned from this room.", parts[0]));
|
||||
return QString();
|
||||
},
|
||||
false,
|
||||
std::nullopt,
|
||||
kli18n("<user id> [<reason>]"),
|
||||
kli18n("Bans the given user"),
|
||||
},
|
||||
Action{
|
||||
u"unban"_s,
|
||||
QStringLiteral("unban"),
|
||||
[](const QString &text, NeoChatRoom *room, ChatBarCache *) {
|
||||
static const QRegularExpression mxidRegex(uR"((^|[][[:space:](){}`'";])([!#@][-a-z0-9_=#/.]{1,252}:\w(?:\w|\.|-)*\.\w+(?::\d{1,5})?))"_s);
|
||||
static const QRegularExpression mxidRegex(
|
||||
QStringLiteral(R"((^|[][[:space:](){}`'";])([!#@][-a-z0-9_=#/.]{1,252}:\w(?:\w|\.|-)*\.\w+(?::\d{1,5})?))"));
|
||||
auto regexMatch = mxidRegex.match(text);
|
||||
if (!regexMatch.hasMatch()) {
|
||||
Q_EMIT room->showMessage(MessageType::Error, i18nc("'<text>' does not look like a matrix id.", "'%1' does not look like a matrix id.", text));
|
||||
@@ -455,15 +483,17 @@ QList<ActionsModel::Action> actions{
|
||||
|
||||
return QString();
|
||||
},
|
||||
false,
|
||||
std::nullopt,
|
||||
kli18n("<user id>"),
|
||||
kli18n("Removes the ban of the given user"),
|
||||
},
|
||||
Action{
|
||||
u"kick"_s,
|
||||
QStringLiteral("kick"),
|
||||
[](const QString &text, NeoChatRoom *room, ChatBarCache *) {
|
||||
auto parts = text.split(u" "_s);
|
||||
static const QRegularExpression mxidRegex(uR"((^|[][[:space:](){}`'";])([!#@][-a-z0-9_=#/.]{1,252}:\w(?:\w|\.|-)*\.\w+(?::\d{1,5})?))"_s);
|
||||
auto parts = text.split(QLatin1String(" "));
|
||||
static const QRegularExpression mxidRegex(
|
||||
QStringLiteral(R"((^|[][[:space:](){}`'";])([!#@][-a-z0-9_=#/.]{1,252}:\w(?:\w|\.|-)*\.\w+(?::\d{1,5})?))"));
|
||||
auto regexMatch = mxidRegex.match(parts[0]);
|
||||
if (!regexMatch.hasMatch()) {
|
||||
Q_EMIT room->showMessage(MessageType::Error,
|
||||
@@ -497,6 +527,7 @@ QList<ActionsModel::Action> actions{
|
||||
Q_EMIT room->showMessage(MessageType::Positive, i18nc("<username> was kicked from this room.", "%1 was kicked from this room.", parts[0]));
|
||||
return QString();
|
||||
},
|
||||
false,
|
||||
std::nullopt,
|
||||
kli18n("<user id> [<reason>]"),
|
||||
kli18n("Removes the user from the room"),
|
||||
@@ -521,7 +552,7 @@ QVariant ActionsModel::data(const QModelIndex &index, int role) const
|
||||
return actions[index.row()].description.toString();
|
||||
}
|
||||
if (role == CompletionType) {
|
||||
return u"action"_s;
|
||||
return QStringLiteral("action");
|
||||
}
|
||||
if (role == Parameters) {
|
||||
return actions[index.row()].parameters.toString();
|
||||
@@ -538,7 +569,7 @@ QHash<int, QByteArray> ActionsModel::roleNames() const
|
||||
};
|
||||
}
|
||||
|
||||
QList<Action> &ActionsModel::allActions()
|
||||
QList<Action> &ActionsModel::allActions() const
|
||||
{
|
||||
return actions;
|
||||
}
|
||||
@@ -550,7 +581,7 @@ bool ActionsModel::handleQuickEditAction(NeoChatRoom *room, const QString &messa
|
||||
}
|
||||
|
||||
if (NeoChatConfig::allowQuickEdit()) {
|
||||
QRegularExpression sed(u"^s/([^/]*)/([^/]*)(/g)?$"_s);
|
||||
QRegularExpression sed(QStringLiteral("^s/([^/]*)/([^/]*)(/g)?$"));
|
||||
auto match = sed.match(messageText);
|
||||
if (match.hasMatch()) {
|
||||
const QString regex = match.captured(1);
|
||||
@@ -597,20 +628,23 @@ std::pair<std::optional<QString>, std::optional<Quotient::RoomMessageEvent::MsgT
|
||||
return std::make_pair(std::nullopt, std::nullopt);
|
||||
}
|
||||
|
||||
std::optional<Quotient::RoomMessageEvent::MsgType> messageType = Quotient::RoomMessageEvent::MsgType::Text;
|
||||
std::optional<Quotient::RoomMessageEvent::MsgType> messageType = std::nullopt;
|
||||
if (sendText.startsWith(QLatin1Char('/'))) {
|
||||
for (const auto &action : ActionsModel::instance().allActions()) {
|
||||
if (sendText.indexOf(action.prefix) == 1
|
||||
&& (sendText.indexOf(" "_L1) == action.prefix.length() + 1 || sendText.length() == action.prefix.length() + 1)) {
|
||||
&& (sendText.indexOf(" "_ls) == action.prefix.length() + 1 || sendText.length() == action.prefix.length() + 1)) {
|
||||
sendText = action.handle(sendText.mid(action.prefix.length() + 1).trimmed(), room, chatBarCache);
|
||||
if (action.messageType.has_value()) {
|
||||
messageType = action.messageType;
|
||||
}
|
||||
if (action.messageAction) {
|
||||
break;
|
||||
} else {
|
||||
messageType = std::nullopt;
|
||||
return std::make_pair(std::nullopt, std::nullopt);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return std::make_pair(messageType.has_value() ? std::make_optional(sendText) : std::nullopt, messageType);
|
||||
return std::make_pair(sendText, messageType);
|
||||
}
|
||||
|
||||
@@ -30,10 +30,18 @@ public:
|
||||
* @brief The function to execute when the action is triggered.
|
||||
*/
|
||||
std::function<QString(const QString &, NeoChatRoom *, ChatBarCache *)> handle;
|
||||
/**
|
||||
* @brief Whether the action is a message type action.
|
||||
*
|
||||
* If this is true, a message action will be sent. If this is false, this
|
||||
* message does some action on the client and should not be sent as a message.
|
||||
*/
|
||||
bool messageAction;
|
||||
/**
|
||||
* @brief The new message type of a message being sent.
|
||||
*
|
||||
* For a non-message action, it's nullopt.
|
||||
* For a non-message action or a message action that outputs the same type
|
||||
* as its input, it's nullopt.
|
||||
*/
|
||||
std::optional<Quotient::RoomMessageEvent::MsgType> messageType = std::nullopt;
|
||||
KLazyLocalizedString parameters; /**< The input parameters expected by the action. */
|
||||
@@ -80,7 +88,7 @@ public:
|
||||
/**
|
||||
* @brief Return a vector with all supported actions.
|
||||
*/
|
||||
static QList<Action> &allActions();
|
||||
QList<Action> &allActions() const;
|
||||
|
||||
/**
|
||||
* @brief Handle special sed style edit action.
|
||||
|
||||
@@ -64,14 +64,14 @@ QVariant CompletionModel::data(const QModelIndex &index, int role) const
|
||||
|
||||
if (m_autoCompletionType == Command) {
|
||||
if (role == DisplayNameRole) {
|
||||
return u"%1 %2"_s.arg(m_filterModel->data(filterIndex, ActionsModel::Prefix).toString(),
|
||||
m_filterModel->data(filterIndex, ActionsModel::Parameters).toString());
|
||||
return QStringLiteral("%1 %2").arg(m_filterModel->data(filterIndex, ActionsModel::Prefix).toString(),
|
||||
m_filterModel->data(filterIndex, ActionsModel::Parameters).toString());
|
||||
}
|
||||
if (role == SubtitleRole) {
|
||||
return m_filterModel->data(filterIndex, ActionsModel::Description);
|
||||
}
|
||||
if (role == IconNameRole) {
|
||||
return u"invalid"_s;
|
||||
return QStringLiteral("invalid");
|
||||
}
|
||||
if (role == ReplacedTextRole) {
|
||||
return m_filterModel->data(filterIndex, ActionsModel::Prefix);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user