Compare commits

..

2 Commits

Author SHA1 Message Date
Carl Schwan
fab2a81aee Ton down the intensity of the background on dark theme 2024-12-15 16:12:37 +01:00
Carl Schwan
4daff26747 Add background to room page
Similar to What's App, Telegram and Kaidan.
2024-12-12 12:57:18 +01:00
263 changed files with 40330 additions and 69949 deletions

View File

@@ -2,7 +2,5 @@
; SPDX-License-Identifier: CC0-1.0 ; SPDX-License-Identifier: CC0-1.0
[BlueprintSettings] [BlueprintSettings]
kde/frameworks/extra-cmake-modules.version=master
kde/unreleased/kirigami-addons.version=master
kde/applications/neochat.packageAppx=True kde/applications/neochat.packageAppx=True
libs/qt.qtMajorVersion=6 libs/qt.qtMajorVersion=6

View File

@@ -2,7 +2,7 @@
"id": "org.kde.neochat", "id": "org.kde.neochat",
"branch": "master", "branch": "master",
"runtime": "org.kde.Platform", "runtime": "org.kde.Platform",
"runtime-version": "6.8", "runtime-version": "6.7",
"sdk": "org.kde.Sdk", "sdk": "org.kde.Sdk",
"command": "neochat", "command": "neochat",
"tags": [ "tags": [
@@ -25,23 +25,13 @@
"modules": [ "modules": [
{ {
"name": "kirigamiaddons", "name": "kirigamiaddons",
"config-opts": [ "config-opts": [ "-DBUILD_TESTING=OFF" ],
"-DBUILD_TESTING=OFF"
],
"buildsystem": "cmake-ninja", "buildsystem": "cmake-ninja",
"sources": [ "sources": [ { "type": "git", "url": "https://invent.kde.org/libraries/kirigami-addons.git", "commit": "34d311219e8b7209746a98b3a29b91ded05ff936" } ]
{
"type": "git",
"url": "https://invent.kde.org/libraries/kirigami-addons.git"
}
]
}, },
{ {
"name": "kquickimageeditor", "name": "kquickimageeditor",
"config-opts": [ "config-opts": [ "-DBUILD_WITH_QT6=ON" ],
"-DBUILD_WITH_QT6=ON",
"-DBUILD_TESTING=OFF"
],
"buildsystem": "cmake-ninja", "buildsystem": "cmake-ninja",
"sources": [ "sources": [
{ {
@@ -53,19 +43,17 @@
{ {
"name": "olm", "name": "olm",
"buildsystem": "cmake-ninja", "buildsystem": "cmake-ninja",
"config-opts": [ "config-opts": [ "-DOLM_TESTS=OFF" ],
"-DOLM_TESTS=OFF"
],
"sources": [ "sources": [
{ {
"type": "git", "type": "git",
"url": "https://gitlab.matrix.org/matrix-org/olm.git", "url": "https://gitlab.matrix.org/matrix-org/olm.git",
"tag": "3.2.16", "tag": "3.2.10",
"x-checker-data": { "x-checker-data": {
"type": "git", "type": "git",
"tag-pattern": "^([\\d.]+)$" "tag-pattern": "^([\\d.]+)$"
}, },
"commit": "7e0c8277032e40308987257b711b38af8d77cc69" "commit": "9908862979147a71dc6abaecd521be526ae77be1"
} }
] ]
}, },
@@ -77,13 +65,13 @@
"-Dvapi=false", "-Dvapi=false",
"-Dgtk_doc=false", "-Dgtk_doc=false",
"-Dintrospection=false", "-Dintrospection=false",
"-Dcrypto=disabled" "-Dgcrypt=false"
], ],
"sources": [ "sources": [
{ {
"type": "archive", "type": "archive",
"url": "https://download.gnome.org/sources/libsecret/0.21/libsecret-0.21.6.tar.xz", "url": "https://download.gnome.org/sources/libsecret/0.20/libsecret-0.20.5.tar.xz",
"sha256": "747b8c175be108c880d3adfb9c3537ea66e520e4ad2dccf5dce58003aeeca090", "sha256": "3fb3ce340fcd7db54d87c893e69bfc2b1f6e4d4b279065ffe66dac9f0fd12b4d",
"x-checker-data": { "x-checker-data": {
"type": "gnome", "type": "gnome",
"name": "libsecret", "name": "libsecret",
@@ -98,13 +86,13 @@
"sources": [ "sources": [
{ {
"type": "archive", "type": "archive",
"url": "https://github.com/frankosterfeld/qtkeychain/archive/refs/tags/0.15.0.tar.gz", "url": "https://github.com/frankosterfeld/qtkeychain/archive/0.14.2.tar.gz",
"sha256": "f4254dc8f0933b06d90672d683eab08ef770acd8336e44dfa030ce041dc2ca22", "sha256": "cf2e972b783ba66334a79a30f6b3a1ea794a1dc574d6c3bebae5ffd2f0399571",
"x-checker-data": { "x-checker-data": {
"type": "anitya", "type": "anitya",
"project-id": 4138, "project-id": 4138,
"stable-only": true, "stable-only": true,
"url-template": "https://github.com/frankosterfeld/qtkeychain/archive/refs/tags/$version.tar.gz" "url-template": "https://github.com/frankosterfeld/qtkeychain/archive/v$version.tar.gz"
} }
} }
], ],
@@ -112,8 +100,7 @@
"-DBUILD_WITH_QT6=ON", "-DBUILD_WITH_QT6=ON",
"-DCMAKE_INSTALL_LIBDIR=/app/lib", "-DCMAKE_INSTALL_LIBDIR=/app/lib",
"-DLIB_INSTALL_DIR=/app/lib", "-DLIB_INSTALL_DIR=/app/lib",
"-DBUILD_TRANSLATIONS=NO", "-DBUILD_TRANSLATIONS=NO"
"-DBUILD_TESTING=OFF"
] ]
}, },
{ {
@@ -136,31 +123,29 @@
{ {
"name": "cmark", "name": "cmark",
"buildsystem": "cmake-ninja", "buildsystem": "cmake-ninja",
"config-opts": [ "config-opts": [ "-DCMARK_TESTS=OFF" ],
"-DCMARK_TESTS=OFF",
"-DCMAKE_BUILD_TYPE=Release",
"-DCMAKE_INSTALL_PREFIX=/app"
],
"sources": [ "sources": [
{ {
"type": "git", "type": "git",
"url": "https://github.com/commonmark/cmark.git" "url": "https://github.com/commonmark/cmark.git"
} }
], ],
"config-opts": [
"-DCMARK_TESTS=OFF",
"-DCMAKE_BUILD_TYPE=Release",
"-DCMAKE_INSTALL_PREFIX=/app"
],
"builddir": true "builddir": true
}, },
{ {
"name": "qcoro", "name": "qcoro",
"buildsystem": "cmake-ninja", "buildsystem": "cmake-ninja",
"config-opts": [ "config-opts": [ "-DQCORO_BUILD_EXAMPLES=OFF", "-DBUILD_TESTING=OFF" ],
"-DQCORO_BUILD_EXAMPLES=OFF",
"-DBUILD_TESTING=OFF"
],
"sources": [ "sources": [
{ {
"type": "archive", "type": "archive",
"url": "https://github.com/danvratil/qcoro/archive/refs/tags/v0.11.0.tar.gz", "url": "https://github.com/danvratil/qcoro/archive/refs/tags/v0.7.0.tar.gz",
"sha256": "9942c5b4c533192f6c5954dc6d10178b3829075e6a621b67df73f0a4b74d8297", "sha256": "23ef0217926e67c8d2eb861cf91617da2f7d8d5a9ae6c62321b21448b1669210",
"x-checker-data": { "x-checker-data": {
"type": "anitya", "type": "anitya",
"project-id": 236236, "project-id": 236236,
@@ -173,15 +158,14 @@
{ {
"name": "neochat", "name": "neochat",
"buildsystem": "cmake-ninja", "buildsystem": "cmake-ninja",
"config-opts": [
"-DBUILD_TESTING=OFF",
"-DNEOCHAT_FLATPAK=ON"
],
"sources": [ "sources": [
{ {
"type": "dir", "type": "dir",
"path": "." "path": "."
} }
],
"config-opts": [
"-DNEOCHAT_FLATPAK=ON"
] ]
} }
] ]

View File

@@ -5,14 +5,10 @@ include:
- project: sysadmin/ci-utilities - project: sysadmin/ci-utilities
file: file:
- /gitlab-templates/reuse-lint.yml - /gitlab-templates/reuse-lint.yml
- /gitlab-templates/json-validation.yml
- /gitlab-templates/xml-lint.yml
- /gitlab-templates/yaml-lint.yml
- /gitlab-templates/android-qt6.yml - /gitlab-templates/android-qt6.yml
- /gitlab-templates/linux-qt6.yml - /gitlab-templates/linux-qt6.yml
- /gitlab-templates/linux-qt6-next.yml
- /gitlab-templates/windows-qt6.yml - /gitlab-templates/windows-qt6.yml
# - /gitlab-templates/freebsd-qt6.yml # - /gitlab-templates/freebsd-qt6.yml
- /gitlab-templates/flatpak.yml - /gitlab-templates/flatpak.yml
- /gitlab-templates/snap-snapcraft-lxd.yml - /gitlab-templates/snap-snapcraft-lxd.yml
- /gitlab-templates/craft-android-qt6-apks.yml - /gitlab-templates/craft-android-qt6-apks.yml

View File

@@ -2,43 +2,42 @@
# SPDX-License-Identifier: BSD-2-Clause # SPDX-License-Identifier: BSD-2-Clause
Dependencies: Dependencies:
- 'on': ['Linux', 'Android', 'FreeBSD', 'Windows'] - 'on': ['Linux', 'Android', 'FreeBSD', 'Windows']
'require': 'require':
'frameworks/extra-cmake-modules': '@latest-kf6' 'frameworks/extra-cmake-modules': '@latest-kf6'
'frameworks/kcoreaddons': '@latest-kf6' 'frameworks/kcoreaddons': '@latest-kf6'
'frameworks/kirigami': '@latest-kf6' 'frameworks/kirigami': '@latest-kf6'
'frameworks/ki18n': '@latest-kf6' 'frameworks/ki18n': '@latest-kf6'
'frameworks/kconfig': '@latest-kf6' 'frameworks/kconfig': '@latest-kf6'
'frameworks/syntax-highlighting': '@latest-kf6' 'frameworks/syntax-highlighting': '@latest-kf6'
'frameworks/kitemmodels': '@latest-kf6' 'frameworks/kitemmodels': '@latest-kf6'
'frameworks/kquickcharts': '@latest-kf6' 'frameworks/kquickcharts': '@latest-kf6'
'frameworks/knotifications': '@latest-kf6' 'frameworks/knotifications': '@latest-kf6'
'frameworks/kcolorscheme': '@latest-kf6' 'frameworks/kcolorscheme': '@latest-kf6'
'frameworks/kiconthemes': '@latest-kf6' 'libraries/kquickimageeditor': '@latest-kf6'
'libraries/kquickimageeditor': '@latest-kf6' 'frameworks/sonnet': '@latest-kf6'
'frameworks/sonnet': '@latest-kf6' 'frameworks/prison': '@latest-kf6'
'frameworks/prison': '@latest-kf6' 'libraries/kirigami-addons': '@latest-kf6'
'libraries/kirigami-addons': '@latest-kf6' 'third-party/libquotient': '@latest'
'third-party/libquotient': '@latest' 'third-party/qtkeychain': '@latest'
'third-party/qtkeychain': '@latest' 'third-party/cmark': '@latest'
'third-party/cmark': '@latest' 'third-party/qcoro': '@latest'
'third-party/qcoro': '@latest' - 'on': ['Windows', 'Linux', 'FreeBSD']
- 'on': ['Windows', 'Linux', 'FreeBSD'] 'require':
'require': 'frameworks/qqc2-desktop-style': '@latest-kf6'
'frameworks/qqc2-desktop-style': '@latest-kf6' 'frameworks/kio': '@latest-kf6'
'frameworks/kio': '@latest-kf6' 'frameworks/kwindowsystem': '@latest-kf6'
'frameworks/kwindowsystem': '@latest-kf6' 'frameworks/kstatusnotifieritem': '@latest-kf6'
'frameworks/kstatusnotifieritem': '@latest-kf6' 'frameworks/kcrash': '@latest-kf6'
'frameworks/kcrash': '@latest-kf6' - 'on': ['Linux', 'FreeBSD']
- 'on': ['Linux', 'FreeBSD'] 'require':
'require': 'frameworks/kdbusaddons': '@latest-kf6'
'frameworks/kdbusaddons': '@latest-kf6' 'frameworks/purpose': '@latest-kf6'
'frameworks/purpose': '@latest-kf6'
- 'on': ['Linux'] - 'on': ['Linux']
'require': 'require':
'sdk/selenium-webdriver-at-spi': '@latest-kf6' 'sdk/selenium-webdriver-at-spi': '@latest-kf6'
Options: Options:
per-test-timeout: 90 per-test-timeout: 90
require-passing-tests-on: ['Linux', 'Android', 'FreeBSD', 'Windows'] require-passing-tests-on: [ 'Linux', 'Android', 'FreeBSD' ]

View File

@@ -8,8 +8,8 @@ cmake_minimum_required(VERSION 3.16)
# KDE Applications version, managed by release script. # KDE Applications version, managed by release script.
set(RELEASE_SERVICE_VERSION_MAJOR "25") set(RELEASE_SERVICE_VERSION_MAJOR "25")
set(RELEASE_SERVICE_VERSION_MINOR "04") set(RELEASE_SERVICE_VERSION_MINOR "03")
set(RELEASE_SERVICE_VERSION_MICRO "1") set(RELEASE_SERVICE_VERSION_MICRO "70")
set(RELEASE_SERVICE_VERSION "${RELEASE_SERVICE_VERSION_MAJOR}.${RELEASE_SERVICE_VERSION_MINOR}.${RELEASE_SERVICE_VERSION_MICRO}") set(RELEASE_SERVICE_VERSION "${RELEASE_SERVICE_VERSION_MAJOR}.${RELEASE_SERVICE_VERSION_MINOR}.${RELEASE_SERVICE_VERSION_MICRO}")
project(NeoChat VERSION ${RELEASE_SERVICE_VERSION}) project(NeoChat VERSION ${RELEASE_SERVICE_VERSION})
@@ -66,7 +66,7 @@ if (QT_KNOWN_POLICY_QTP0004)
qt_policy(SET QTP0004 NEW) qt_policy(SET QTP0004 NEW)
endif () endif ()
find_package(KF6 ${KF_MIN_VERSION} COMPONENTS Kirigami I18n Notifications Config CoreAddons Sonnet ItemModels IconThemes ColorScheme) find_package(KF6 ${KF_MIN_VERSION} COMPONENTS Kirigami I18n Notifications Config CoreAddons Sonnet ItemModels ColorScheme)
set_package_properties(KF6 PROPERTIES set_package_properties(KF6 PROPERTIES
TYPE REQUIRED TYPE REQUIRED
PURPOSE "Basic application components" PURPOSE "Basic application components"
@@ -174,9 +174,6 @@ if (BUILD_TESTING)
find_package(Qt6 ${QT_MIN_VERSION} NO_MODULE COMPONENTS Test) find_package(Qt6 ${QT_MIN_VERSION} NO_MODULE COMPONENTS Test)
add_subdirectory(autotests) add_subdirectory(autotests)
add_subdirectory(appiumtests) add_subdirectory(appiumtests)
if (NOT ANDROID)
add_subdirectory(memorytests)
endif()
endif() endif()
if(KF6DocTools_FOUND) if(KF6DocTools_FOUND)

View File

@@ -82,9 +82,3 @@ path = "src/purpose/purposeplugin.json"
precedence = "aggregate" precedence = "aggregate"
SPDX-FileCopyrightText = "2023 Tobias Fella <tobias.fella@kde.org>" SPDX-FileCopyrightText = "2023 Tobias Fella <tobias.fella@kde.org>"
SPDX-License-Identifier = "BSD-2-Clause" SPDX-License-Identifier = "BSD-2-Clause"
[[annotations]]
path = "memorytests/memtest-sync.json"
precedence = "aggregate"
SPDX-FileCopyrightText = "2024 James Graham <james.h.graham@protonmail.com>"
SPDX-License-Identifier = "BSD-2-Clause"

View File

@@ -12,7 +12,7 @@ buildscript {
} }
dependencies { dependencies {
classpath 'com.android.tools.build:gradle:8.6.0' classpath 'com.android.tools.build:gradle:7.4.1'
} }
} }

View File

@@ -11,13 +11,11 @@ ecm_add_test(
TEST_NAME neochatroomtest TEST_NAME neochatroomtest
) )
if (NOT $ENV{KDE_CI}) ecm_add_test(
ecm_add_test( texthandlertest.cpp
texthandlertest.cpp LINK_LIBRARIES neochat Qt::Test
LINK_LIBRARIES neochat Qt::Test TEST_NAME texthandlertest
TEST_NAME texthandlertest )
)
endif()
ecm_add_test( ecm_add_test(
delegatesizehelpertest.cpp delegatesizehelpertest.cpp
@@ -50,9 +48,9 @@ ecm_add_test(
) )
ecm_add_test( ecm_add_test(
timelinemessagemodeltest.cpp messageeventmodeltest.cpp
LINK_LIBRARIES neochat Qt::Test LINK_LIBRARIES neochat Qt::Test
TEST_NAME timelinemessagemodeltest TEST_NAME messageeventmodeltest
) )
ecm_add_test( ecm_add_test(
@@ -84,9 +82,3 @@ ecm_add_test(
LINK_LIBRARIES neochat Qt::Test LINK_LIBRARIES neochat Qt::Test
TEST_NAME messagecontentmodeltest TEST_NAME messagecontentmodeltest
) )
ecm_add_test(
actionstest.cpp
LINK_LIBRARIES neochat Qt::Test
TEST_NAME actionstest
)

View File

@@ -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"

View File

@@ -38,8 +38,8 @@ private Q_SLOTS:
void ChatBarCacheTest::initTestCase() void ChatBarCacheTest::initTestCase()
{ {
connection = Connection::makeMockConnection(u"@bob:kde.org"_s); connection = Connection::makeMockConnection(QStringLiteral("@bob:kde.org"));
room = new TestUtils::TestRoom(connection, u"#myroom:kde.org"_s, "test-min-sync.json"_L1); room = new TestUtils::TestRoom(connection, QStringLiteral("#myroom:kde.org"), QLatin1String("test-min-sync.json"));
} }
void ChatBarCacheTest::empty() void ChatBarCacheTest::empty()
@@ -59,7 +59,7 @@ void ChatBarCacheTest::empty()
void ChatBarCacheTest::noRoom() void ChatBarCacheTest::noRoom()
{ {
QScopedPointer<ChatBarCache> chatBarCache(new ChatBarCache()); 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 // These should return empty even though a reply ID has been set because the
// ChatBarCache has no parent. // ChatBarCache has no parent.
@@ -75,7 +75,7 @@ void ChatBarCacheTest::badParent()
{ {
QScopedPointer<QObject> badParent(new QObject()); QScopedPointer<QObject> badParent(new QObject());
QScopedPointer<ChatBarCache> chatBarCache(new ChatBarCache(badParent.get())); 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 // These should return empty even though a reply ID has been set because the
// ChatBarCache has no parent. // ChatBarCache has no parent.
@@ -90,17 +90,17 @@ void ChatBarCacheTest::badParent()
void ChatBarCacheTest::reply() void ChatBarCacheTest::reply()
{ {
QScopedPointer<ChatBarCache> chatBarCache(new ChatBarCache(room)); QScopedPointer<ChatBarCache> chatBarCache(new ChatBarCache(room));
chatBarCache->setText(u"some text"_s); chatBarCache->setText(QLatin1String("some text"));
chatBarCache->setAttachmentPath(u"some/path"_s); chatBarCache->setAttachmentPath(QLatin1String("some/path"));
chatBarCache->setReplyId(u"$153456789:example.org"_s); 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->isReplying(), true);
QCOMPARE(chatBarCache->replyId(), u"$153456789:example.org"_s); QCOMPARE(chatBarCache->replyId(), QLatin1String("$153456789:example.org"));
QCOMPARE(chatBarCache->isEditing(), false); QCOMPARE(chatBarCache->isEditing(), false);
QCOMPARE(chatBarCache->editId(), QString()); QCOMPARE(chatBarCache->editId(), QString());
QCOMPARE(chatBarCache->relationAuthor(), room->member(u"@example:example.org"_s)); QCOMPARE(chatBarCache->relationAuthor(), room->member(QLatin1String("@example:example.org")));
QCOMPARE(chatBarCache->relationMessage(), u"This is an example\ntext message"_s); QCOMPARE(chatBarCache->relationMessage(), QLatin1String("This is an example\ntext message"));
QCOMPARE(chatBarCache->attachmentPath(), QString()); QCOMPARE(chatBarCache->attachmentPath(), QString());
} }
@@ -108,39 +108,39 @@ void ChatBarCacheTest::edit()
{ {
QScopedPointer<ChatBarCache> chatBarCache(new ChatBarCache(room)); QScopedPointer<ChatBarCache> chatBarCache(new ChatBarCache(room));
chatBarCache->setText(u"some text"_s); chatBarCache->setText(QLatin1String("some text"));
chatBarCache->setAttachmentPath(u"some/path"_s); chatBarCache->setAttachmentPath(QLatin1String("some/path"));
connect(chatBarCache.get(), &ChatBarCache::relationIdChanged, this, [](const QString &oldEventId, const QString &newEventId) { connect(chatBarCache.get(), &ChatBarCache::relationIdChanged, this, [](const QString &oldEventId, const QString &newEventId) {
QCOMPARE(oldEventId, QString()); 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->isReplying(), false);
QCOMPARE(chatBarCache->replyId(), QString()); QCOMPARE(chatBarCache->replyId(), QString());
QCOMPARE(chatBarCache->isEditing(), true); QCOMPARE(chatBarCache->isEditing(), true);
QCOMPARE(chatBarCache->editId(), u"$153456789:example.org"_s); QCOMPARE(chatBarCache->editId(), QLatin1String("$153456789:example.org"));
QCOMPARE(chatBarCache->relationAuthor(), room->member(u"@example:example.org"_s)); QCOMPARE(chatBarCache->relationAuthor(), room->member(QLatin1String("@example:example.org")));
QCOMPARE(chatBarCache->relationMessage(), u"This is an example\ntext message"_s); QCOMPARE(chatBarCache->relationMessage(), QLatin1String("This is an example\ntext message"));
QCOMPARE(chatBarCache->attachmentPath(), QString()); QCOMPARE(chatBarCache->attachmentPath(), QString());
} }
void ChatBarCacheTest::attachment() void ChatBarCacheTest::attachment()
{ {
QScopedPointer<ChatBarCache> chatBarCache(new ChatBarCache(room)); QScopedPointer<ChatBarCache> chatBarCache(new ChatBarCache(room));
chatBarCache->setText(u"some text"_s); chatBarCache->setText(QLatin1String("some text"));
chatBarCache->setEditId(u"$153456789:example.org"_s); chatBarCache->setEditId(QLatin1String("$153456789:example.org"));
chatBarCache->setAttachmentPath(u"some/path"_s); chatBarCache->setAttachmentPath(QLatin1String("some/path"));
QCOMPARE(chatBarCache->text(), u"some text"_s); QCOMPARE(chatBarCache->text(), QLatin1String("some text"));
QCOMPARE(chatBarCache->isReplying(), false); QCOMPARE(chatBarCache->isReplying(), false);
QCOMPARE(chatBarCache->replyId(), QString()); QCOMPARE(chatBarCache->replyId(), QString());
QCOMPARE(chatBarCache->isEditing(), false); QCOMPARE(chatBarCache->isEditing(), false);
QCOMPARE(chatBarCache->editId(), QString()); QCOMPARE(chatBarCache->editId(), QString());
QCOMPARE(chatBarCache->relationAuthor(), room->member(QString())); QCOMPARE(chatBarCache->relationAuthor(), room->member(QString()));
QCOMPARE(chatBarCache->relationMessage(), QString()); QCOMPARE(chatBarCache->relationMessage(), QString());
QCOMPARE(chatBarCache->attachmentPath(), u"some/path"_s); QCOMPARE(chatBarCache->attachmentPath(), QLatin1String("some/path"));
} }
QTEST_MAIN(ChatBarCacheTest) QTEST_MAIN(ChatBarCacheTest)

View File

@@ -49,51 +49,6 @@
"unsigned": { "unsigned": {
"age": 1234 "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", "@alice:example.com",
"@bob:example.com" "@bob:example.com"
], ],
"m.invited_member_count": 1, "m.invited_member_count": 0,
"m.joined_member_count": 2 "m.joined_member_count": 2
}, },
"timeline": { "timeline": {

View File

@@ -11,8 +11,6 @@
#include <Quotient/connection.h> #include <Quotient/connection.h>
#include <Quotient/quotient_common.h> #include <Quotient/quotient_common.h>
#include <Quotient/syncdata.h> #include <Quotient/syncdata.h>
#include <qcbormap.h>
#include <qtestcase.h>
#include "linkpreviewer.h" #include "linkpreviewer.h"
#include "models/reactionmodel.h" #include "models/reactionmodel.h"
@@ -64,13 +62,13 @@ private Q_SLOTS:
void EventHandlerTest::initTestCase() void EventHandlerTest::initTestCase()
{ {
connection = Connection::makeMockConnection(u"@bob:kde.org"_s); connection = Connection::makeMockConnection(QStringLiteral("@bob:kde.org"));
room = new TestUtils::TestRoom(connection, u"#myroom:kde.org"_s, u"test-eventhandler-sync.json"_s); room = new TestUtils::TestRoom(connection, QStringLiteral("#myroom:kde.org"), QLatin1String("test-eventhandler-sync.json"));
} }
void EventHandlerTest::authorDisplayName() 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() void EventHandlerTest::nullAuthorDisplayName()
@@ -84,7 +82,8 @@ void EventHandlerTest::nullAuthorDisplayName()
void EventHandlerTest::singleLineSidplayName() 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() void EventHandlerTest::nullSingleLineDisplayName()
@@ -100,24 +99,18 @@ void EventHandlerTest::time()
{ {
const auto event = room->messageEvents().at(0).get(); const auto event = room->messageEvents().at(0).get();
QCOMPARE(EventHandler::time(room, event), QDateTime::fromMSecsSinceEpoch(1432735824654, QTimeZone(QTimeZone::UTC))); QCOMPARE(EventHandler::time(event), QDateTime::fromMSecsSinceEpoch(1432735824654, QTimeZone(QTimeZone::UTC)));
QCOMPARE(EventHandler::time(event, true, QDateTime::fromMSecsSinceEpoch(1234, QTimeZone(QTimeZone::UTC))),
const auto txID = room->postJson("m.room.message"_L1, event->fullJson()); QDateTime::fromMSecsSinceEpoch(1234, QTimeZone(QTimeZone::UTC)));
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);
} }
void EventHandlerTest::nullTime() 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."); 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() void EventHandlerTest::timeString()
@@ -126,27 +119,20 @@ void EventHandlerTest::timeString()
KFormat format; 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)); 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)); 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)); 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));
const auto txID = room->postJson("m.room.message"_L1, event->fullJson()); QCOMPARE(EventHandler::timeString(event, true, QLocale::ShortFormat, true, QDateTime::fromMSecsSinceEpoch(1690699214545, QTimeZone(QTimeZone::UTC))),
QCOMPARE(room->pendingEvents().size(), 1); format.formatRelativeDate(QDateTime::fromMSecsSinceEpoch(1690699214545, QTimeZone(QTimeZone::UTC)).toLocalTime().date(), QLocale::ShortFormat));
const auto pendingIt = room->findPendingEvent(txID); 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(room, pendingIt->event(), false, QLocale::ShortFormat, true), QCOMPARE(EventHandler::timeString(event, true, QLocale::LongFormat, true, QDateTime::fromMSecsSinceEpoch(1690699214545, QTimeZone(QTimeZone::UTC))),
QLocale().toString(pendingIt->lastUpdated().toLocalTime().time(), QLocale::ShortFormat)); format.formatRelativeDate(QDateTime::fromMSecsSinceEpoch(1690699214545, QTimeZone(QTimeZone::UTC)).toLocalTime().date(), QLocale::LongFormat));
QCOMPARE(EventHandler::timeString(room, pendingIt->event(), true, QLocale::ShortFormat, true), QCOMPARE(EventHandler::timeString(event, QStringLiteral("hh:mm")),
format.formatRelativeDate(pendingIt->lastUpdated().toLocalTime().date(), QLocale::ShortFormat)); QDateTime::fromMSecsSinceEpoch(1432735824654, QTimeZone(QTimeZone::UTC)).toString(QStringLiteral("hh:mm")));
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);
} }
void EventHandlerTest::highlighted() void EventHandlerTest::highlighted()
@@ -183,10 +169,10 @@ void EventHandlerTest::body()
{ {
const auto event = room->messageEvents().at(0).get(); 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), QStringLiteral("<b>This is an example<br>text message</b>"));
QCOMPARE(EventHandler::richBody(room, event, true), u"<b>This is an example text message</b>"_s); QCOMPARE(EventHandler::richBody(room, event, true), QStringLiteral("<b>This is an example text message</b>"));
QCOMPARE(EventHandler::plainBody(room, event), u"This is an example\ntext message"_s); QCOMPARE(EventHandler::plainBody(room, event), QStringLiteral("This is an example\ntext message"));
QCOMPARE(EventHandler::plainBody(room, event, true), u"This is an example text message"_s); QCOMPARE(EventHandler::plainBody(room, event, true), QStringLiteral("This is an example text message"));
} }
void EventHandlerTest::nullBody() void EventHandlerTest::nullBody()
@@ -209,11 +195,13 @@ void EventHandlerTest::genericBody_data()
QTest::addColumn<int>("eventNum"); QTest::addColumn<int>("eventNum");
QTest::addColumn<QString>("output"); 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("message") << 0 << QStringLiteral("<a href=\"https://matrix.to/#/@example:example.org\">after</a> sent a message");
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("member") << 1
QTest::newRow("message 2") << 2 << u"<a href=\"https://matrix.to/#/@example:example.org\">after</a> sent a message"_s; << QStringLiteral(
QTest::newRow("reaction") << 3 << u"Unknown event"_s; "<a href=\"https://matrix.to/#/@example:example.org\">after</a> changed their display name and updated their avatar");
QTest::newRow("video") << 4 << u"<a href=\"https://matrix.to/#/@example:example.org\">after</a> sent a message"_s; 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() void EventHandlerTest::genericBody()
@@ -235,19 +223,19 @@ void EventHandlerTest::nullGenericBody()
void EventHandlerTest::markdownBody() 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() 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() 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()), 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() void EventHandlerTest::nullSubtitle()
@@ -263,21 +251,21 @@ void EventHandlerTest::mediaInfo()
{ {
auto event = room->messageEvents().at(4).get(); auto event = room->messageEvents().at(4).get();
auto mediaInfo = EventHandler::mediaInfo(room, event); 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["source"_ls], room->makeMediaUrl(event->id(), QUrl("mxc://kde.org/1234567"_ls)));
QCOMPARE(mediaInfo["mimeType"_L1], u"video/mp4"_s); QCOMPARE(mediaInfo["mimeType"_ls], QStringLiteral("video/mp4"));
QCOMPARE(mediaInfo["mimeIcon"_L1], u"video-mp4"_s); QCOMPARE(mediaInfo["mimeIcon"_ls], QStringLiteral("video-mp4"));
QCOMPARE(mediaInfo["size"_L1], 62650636); QCOMPARE(mediaInfo["size"_ls], 62650636);
QCOMPARE(mediaInfo["duration"_L1], 10); QCOMPARE(mediaInfo["duration"_ls], 10);
QCOMPARE(mediaInfo["width"_L1], 1920); QCOMPARE(mediaInfo["width"_ls], 1920);
QCOMPARE(mediaInfo["height"_L1], 1080); QCOMPARE(mediaInfo["height"_ls], 1080);
QCOMPARE(thumbnailInfo["source"_L1], room->makeMediaUrl(event->id(), QUrl("mxc://kde.org/2234567"_L1))); QCOMPARE(thumbnailInfo["source"_ls], room->makeMediaUrl(event->id(), QUrl("mxc://kde.org/2234567"_ls)));
QCOMPARE(thumbnailInfo["mimeType"_L1], u"image/jpeg"_s); QCOMPARE(thumbnailInfo["mimeType"_ls], QStringLiteral("image/jpeg"));
QCOMPARE(thumbnailInfo["mimeIcon"_L1], u"image-jpeg"_s); QCOMPARE(thumbnailInfo["mimeIcon"_ls], QStringLiteral("image-jpeg"));
QCOMPARE(thumbnailInfo["size"_L1], 382249); QCOMPARE(thumbnailInfo["size"_ls], 382249);
QCOMPARE(thumbnailInfo["width"_L1], 800); QCOMPARE(thumbnailInfo["width"_ls], 800);
QCOMPARE(thumbnailInfo["height"_L1], 450); QCOMPARE(thumbnailInfo["height"_ls], 450);
} }
void EventHandlerTest::nullMediaInfo() void EventHandlerTest::nullMediaInfo()
@@ -316,9 +304,9 @@ void EventHandlerTest::nullReplyAuthor()
void EventHandlerTest::location() void EventHandlerTest::location()
{ {
QCOMPARE(EventHandler::latitude(room->messageEvents().at(7).get()), u"51.7035"_s.toFloat()); QCOMPARE(EventHandler::latitude(room->messageEvents().at(7).get()), QStringLiteral("51.7035").toFloat());
QCOMPARE(EventHandler::longitude(room->messageEvents().at(7).get()), u"-1.14394"_s.toFloat()); QCOMPARE(EventHandler::longitude(room->messageEvents().at(7).get()), QStringLiteral("-1.14394").toFloat());
QCOMPARE(EventHandler::locationAssetType(room->messageEvents().at(7).get()), u"m.pin"_s); QCOMPARE(EventHandler::locationAssetType(room->messageEvents().at(7).get()), QStringLiteral("m.pin"));
} }
void EventHandlerTest::nullLocation() void EventHandlerTest::nullLocation()

View File

@@ -38,8 +38,8 @@ private Q_SLOTS:
void LinkPreviewerTest::initTestCase() void LinkPreviewerTest::initTestCase()
{ {
connection = Connection::makeMockConnection(u"@bob:example.org"_s); connection = Connection::makeMockConnection(QStringLiteral("@bob:example.org"));
room = new TestUtils::TestRoom(connection, u"!test:example.org"_s); room = new TestUtils::TestRoom(connection, QStringLiteral("!test:example.org"));
} }
void LinkPreviewerTest::linkPreviewsMatch_data() void LinkPreviewerTest::linkPreviewsMatch_data()
@@ -47,9 +47,9 @@ void LinkPreviewerTest::linkPreviewsMatch_data()
QTest::addColumn<QString>("inputString"); QTest::addColumn<QString>("inputString");
QTest::addColumn<QUrl>("testOutputLink"); QTest::addColumn<QUrl>("testOutputLink");
QTest::newRow("plainHttps") << u"https://kde.org"_s << QUrl(u"https://kde.org"_s); QTest::newRow("plainHttps") << QStringLiteral("https://kde.org") << QUrl("https://kde.org"_ls);
QTest::newRow("richHttps") << u"<a href=\"https://kde.org\">Rich Link</a>"_s << QUrl(u"https://kde.org"_s); QTest::newRow("richHttps") << QStringLiteral("<a href=\"https://kde.org\">Rich Link</a>") << QUrl("https://kde.org"_ls);
QTest::newRow("richHttpsLinkDescription") << u"<a href=\"https://kde.org\">https://kde.org</a>"_s << QUrl(u"https://kde.org"_s); QTest::newRow("richHttpsLinkDescription") << QStringLiteral("<a href=\"https://kde.org\">https://kde.org</a>") << QUrl("https://kde.org"_ls);
} }
void LinkPreviewerTest::linkPreviewsMatch() void LinkPreviewerTest::linkPreviewsMatch()
@@ -67,8 +67,8 @@ void LinkPreviewerTest::multipleLinkPreviewsMatch_data()
QTest::addColumn<QString>("inputString"); QTest::addColumn<QString>("inputString");
QTest::addColumn<QList<QUrl>>("testOutputLinks"); 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("multipleHttps") << QStringLiteral("www.example.org https://kde.org") << QList{QUrl("www.example.org"_ls), QUrl("https://kde.org"_ls)};
QTest::newRow("multipleHttps1Invalid") << u"www.example.org mxc://example.org/SEsfnsuifSDFSSEF"_s << QList{QUrl(u"www.example.org"_s)}; QTest::newRow("multipleHttps1Invalid") << QStringLiteral("www.example.org mxc://example.org/SEsfnsuifSDFSSEF") << QList{QUrl("www.example.org"_ls)};
} }
void LinkPreviewerTest::multipleLinkPreviewsMatch() void LinkPreviewerTest::multipleLinkPreviewsMatch()
@@ -85,9 +85,9 @@ void LinkPreviewerTest::linkPreviewsReject_data()
{ {
QTest::addColumn<QString>("inputString"); QTest::addColumn<QString>("inputString");
QTest::newRow("mxc") << u"mxc://example.org/SEsfnsuifSDFSSEF"_s; QTest::newRow("mxc") << QStringLiteral("mxc://example.org/SEsfnsuifSDFSSEF");
QTest::newRow("matrixTo") << u"https://matrix.to/#/@alice:example.org"_s; QTest::newRow("matrixTo") << QStringLiteral("https://matrix.to/#/@alice:example.org");
QTest::newRow("noSpace") << u"testhttps://kde.org"_s; QTest::newRow("noSpace") << QStringLiteral("testhttps://kde.org");
} }
void LinkPreviewerTest::linkPreviewsReject() void LinkPreviewerTest::linkPreviewsReject()

View File

@@ -32,25 +32,25 @@ private Q_SLOTS:
void MessageContentModelTest::initTestCase() void MessageContentModelTest::initTestCase()
{ {
connection = Connection::makeMockConnection(u"@bob:kde.org"_s); connection = Connection::makeMockConnection(QStringLiteral("@bob:kde.org"));
} }
void MessageContentModelTest::missingEvent() void MessageContentModelTest::missingEvent()
{ {
auto room = new TestUtils::TestRoom(connection, u"#firstRoom:kde.org"_s); auto room = new TestUtils::TestRoom(connection, QStringLiteral("#firstRoom:kde.org"));
auto model1 = MessageContentModel(room, u"$153456789:example.org"_s); auto model1 = MessageContentModel(room, "$153456789:example.org"_L1);
QCOMPARE(model1.rowCount(), 1); QCOMPARE(model1.rowCount(), 1);
QCOMPARE(model1.data(model1.index(0), MessageContentModel::ComponentTypeRole), MessageComponentType::Loading); 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.rowCount(), 1);
QCOMPARE(model2.data(model2.index(0), MessageContentModel::ComponentTypeRole), MessageComponentType::Loading); 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.rowCount(), 2);
QCOMPARE(model1.data(model1.index(0), MessageContentModel::ComponentTypeRole), MessageComponentType::Author); QCOMPARE(model1.data(model1.index(0), MessageContentModel::ComponentTypeRole), MessageComponentType::Author);
QCOMPARE(model1.data(model1.index(1), MessageContentModel::ComponentTypeRole), MessageComponentType::Text); QCOMPARE(model1.data(model1.index(1), MessageContentModel::ComponentTypeRole), MessageComponentType::Text);

View File

@@ -10,20 +10,20 @@
#include <Quotient/syncdata.h> #include <Quotient/syncdata.h>
#include "enums/delegatetype.h" #include "enums/delegatetype.h"
#include "models/timelinemessagemodel.h" #include "models/messageeventmodel.h"
#include "neochatroom.h" #include "neochatroom.h"
#include "testutils.h" #include "testutils.h"
using namespace Quotient; using namespace Quotient;
class TimelineMessageModelTest : public QObject class MessageEventModelTest : public QObject
{ {
Q_OBJECT Q_OBJECT
private: private:
Connection *connection = nullptr; Connection *connection = nullptr;
TimelineMessageModel *model = nullptr; MessageEventModel *model = nullptr;
private Q_SLOTS: private Q_SLOTS:
void initTestCase(); void initTestCase();
@@ -40,70 +40,70 @@ private Q_SLOTS:
void cleanup(); 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); QCOMPARE(model, nullptr);
model = new TimelineMessageModel; model = new MessageEventModel;
} }
// Make sure that basic empty rooms can be switched without crashing. // 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 firstRoom = new TestUtils::TestRoom(connection, QStringLiteral("#firstRoom:kde.org"));
auto secondRoom = new TestUtils::TestRoom(connection, u"#secondRoom:kde.org"_s); auto secondRoom = new TestUtils::TestRoom(connection, QStringLiteral("#secondRoom:kde.org"));
QSignalSpy spy(model, SIGNAL(roomChanged())); QSignalSpy spy(model, SIGNAL(roomChanged()));
QCOMPARE(model->room(), nullptr); QCOMPARE(model->room(), nullptr);
model->setRoom(firstRoom); model->setRoom(firstRoom);
QCOMPARE(spy.count(), 1); QCOMPARE(spy.count(), 1);
QCOMPARE(model->room()->id(), u"#firstRoom:kde.org"_s); QCOMPARE(model->room()->id(), QStringLiteral("#firstRoom:kde.org"));
model->setRoom(secondRoom); model->setRoom(secondRoom);
QCOMPARE(spy.count(), 2); QCOMPARE(spy.count(), 2);
QCOMPARE(model->room()->id(), u"#secondRoom:kde.org"_s); QCOMPARE(model->room()->id(), QStringLiteral("#secondRoom:kde.org"));
model->setRoom(nullptr); model->setRoom(nullptr);
QCOMPARE(spy.count(), 3); QCOMPARE(spy.count(), 3);
QCOMPARE(model->room(), nullptr); QCOMPARE(model->room(), nullptr);
} }
// Make sure that rooms with some events can be switched without crashing // 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 firstRoom = new TestUtils::TestRoom(connection, QStringLiteral("#firstRoom:kde.org"), QLatin1String("test-messageventmodel-sync.json"));
auto secondRoom = new TestUtils::TestRoom(connection, u"#secondRoom:kde.org"_s, u"test-messageventmodel-sync.json"_s); auto secondRoom = new TestUtils::TestRoom(connection, QStringLiteral("#secondRoom:kde.org"), QLatin1String("test-messageventmodel-sync.json"));
QSignalSpy spy(model, SIGNAL(roomChanged())); QSignalSpy spy(model, SIGNAL(roomChanged()));
QCOMPARE(model->room(), nullptr); QCOMPARE(model->room(), nullptr);
model->setRoom(firstRoom); model->setRoom(firstRoom);
QCOMPARE(spy.count(), 1); QCOMPARE(spy.count(), 1);
QCOMPARE(model->room()->id(), u"#firstRoom:kde.org"_s); QCOMPARE(model->room()->id(), QStringLiteral("#firstRoom:kde.org"));
model->setRoom(secondRoom); model->setRoom(secondRoom);
QCOMPARE(spy.count(), 2); QCOMPARE(spy.count(), 2);
QCOMPARE(model->room()->id(), u"#secondRoom:kde.org"_s); QCOMPARE(model->room()->id(), QStringLiteral("#secondRoom:kde.org"));
model->setRoom(nullptr); model->setRoom(nullptr);
QCOMPARE(spy.count(), 3); QCOMPARE(spy.count(), 3);
QCOMPARE(model->room(), nullptr); 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); model->setRoom(room);
QCOMPARE(model->rowCount(), 2); QCOMPARE(model->rowCount(), 2);
QCOMPARE(model->data(model->index(0), TimelineMessageModel::DelegateTypeRole), DelegateType::State); QCOMPARE(model->data(model->index(0), MessageEventModel::DelegateTypeRole), DelegateType::State);
QCOMPARE(model->data(model->index(0)), u"changed their display name to Example Changed"_s); 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)), QStringLiteral("<b>This is an example<br>text message</b>"));
QCOMPARE(model->data(model->index(1), TimelineMessageModel::DelegateTypeRole), DelegateType::Message); QCOMPARE(model->data(model->index(1), MessageEventModel::DelegateTypeRole), DelegateType::Message);
QCOMPARE(model->data(model->index(1), TimelineMessageModel::EventIdRole), u"$153456789:example.org"_s); 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)"); QTest::ignoreMessage(QtWarningMsg, "Index QModelIndex(-1,-1,0x0,QObject(0x0)) is not valid (expected valid)");
QCOMPARE(model->data(model->index(-1)), QVariant()); QCOMPARE(model->data(model->index(-1)), QVariant());
@@ -111,37 +111,33 @@ void TimelineMessageModelTest::simpleTimeline()
QCOMPARE(model->data(model->index(model->rowCount())), QVariant()); QCOMPARE(model->data(model->index(model->rowCount())), QVariant());
} }
// Sync some events into the TimelineMessageModel's current room and don't crash. // Sync some events into the MessageEventModel's current room and don't crash.
void TimelineMessageModelTest::syncNewEvents() 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))); QSignalSpy spy(room, SIGNAL(aboutToAddNewMessages(Quotient::RoomEventsRange)));
model->setRoom(room); model->setRoom(room);
QCOMPARE(model->rowCount(), 0); QCOMPARE(model->rowCount(), 0);
room->syncNewEvents(u"test-messageventmodel-sync.json"_s); room->syncNewEvents(QLatin1String("test-messageventmodel-sync.json"));
QCOMPARE(model->rowCount(), 2); QCOMPARE(model->rowCount(), 2);
QCOMPARE(spy.count(), 1); QCOMPARE(spy.count(), 1);
} }
// Check the adding of pending events to the room doesn't cause any issues in the model. // 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 spyInsert(model, SIGNAL(rowsInserted(const QModelIndex &, int, int)));
QSignalSpy spyRemove(model, SIGNAL(rowsRemoved(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> &))); 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); model->setRoom(room);
QCOMPARE(model->rowCount(), 0); QCOMPARE(model->rowCount(), 0);
#if Quotient_VERSION_MINOR > 9 auto txnId = room->postPlainText("New plain message"_ls);
auto txnId = room->postText("New plain message"_L1);
#else
auto txnId = room->postPlainText("New plain message"_L1);
#endif
QCOMPARE(model->rowCount(), 1); QCOMPARE(model->rowCount(), 1);
QCOMPARE(spyInsert.count(), 1); QCOMPARE(spyInsert.count(), 1);
@@ -149,30 +145,26 @@ void TimelineMessageModelTest::pendingEvent()
QCOMPARE(model->rowCount(), 0); QCOMPARE(model->rowCount(), 0);
QCOMPARE(spyRemove.count(), 1); QCOMPARE(spyRemove.count(), 1);
#if Quotient_VERSION_MINOR > 9 txnId = room->postPlainText("New plain message"_ls);
txnId = room->postText("New plain message"_L1);
#else
txnId = room->postPlainText("New plain message"_L1);
#endif
QCOMPARE(model->rowCount(), 1); QCOMPARE(model->rowCount(), 1);
QCOMPARE(spyInsert.count(), 2); QCOMPARE(spyInsert.count(), 2);
// We need to manually set the transaction ID of the new message as it will be // We need to manually set the transaction ID of the new message as it will be
// different every time. // different every time.
QFile testSyncFile; 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); testSyncFile.open(QIODevice::ReadOnly);
auto testSyncJson = QJsonDocument::fromJson(testSyncFile.readAll()); auto testSyncJson = QJsonDocument::fromJson(testSyncFile.readAll());
auto root = testSyncJson.object(); auto root = testSyncJson.object();
auto timeline = root["timeline"_L1].toObject(); auto timeline = root["timeline"_ls].toObject();
auto events = timeline["events"_L1].toArray(); auto events = timeline["events"_ls].toArray();
auto firstEvent = events[0].toObject(); 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; events[0] = firstEvent;
timeline.insert("events"_L1, events); timeline.insert("events"_ls, events);
root.insert("timeline"_L1, timeline); root.insert("timeline"_ls, timeline);
testSyncJson.setObject(root); 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)); room->update(std::move(roomData));
QCOMPARE(model->rowCount(), 1); QCOMPARE(model->rowCount(), 1);
@@ -182,7 +174,7 @@ void TimelineMessageModelTest::pendingEvent()
auto isPendingChanged = false; auto isPendingChanged = false;
for (auto signal : spyChanged) { for (auto signal : spyChanged) {
auto roles = signal.at(2).toList(); auto roles = signal.at(2).toList();
if (roles.contains(TimelineMessageModel::IsPendingRole)) { if (roles.contains(MessageEventModel::IsPendingRole)) {
isPendingChanged = true; isPendingChanged = true;
} }
} }
@@ -190,33 +182,33 @@ void TimelineMessageModelTest::pendingEvent()
} }
// Make sure that the signals are disconnecting correctly when a room is switched. // 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); model->setRoom(room);
QSignalSpy spy(model, SIGNAL(rowsInserted(const QModelIndex &, int, int))); QSignalSpy spy(model, SIGNAL(rowsInserted(const QModelIndex &, int, int)));
model->setRoom(nullptr); model->setRoom(nullptr);
room->syncNewEvents(u"test-messageventmodel-sync.json"_s); room->syncNewEvents(QLatin1String("test-messageventmodel-sync.json"));
QCOMPARE(spy.count(), 0); 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); 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; delete model;
model = nullptr; model = nullptr;
QCOMPARE(model, nullptr); QCOMPARE(model, nullptr);
} }
QTEST_MAIN(TimelineMessageModelTest) QTEST_MAIN(MessageEventModelTest)
#include "timelinemessagemodeltest.moc" #include "messageeventmodeltest.moc"

View File

@@ -27,8 +27,8 @@ private Q_SLOTS:
void NeoChatRoomTest::initTestCase() void NeoChatRoomTest::initTestCase()
{ {
connection = Connection::makeMockConnection(u"@bob:kde.org"_s); connection = Connection::makeMockConnection(QStringLiteral("@bob:kde.org"));
room = new TestUtils::TestRoom(connection, u"#myroom:kde.org"_s, u"test-min-sync.json"_s); room = new TestUtils::TestRoom(connection, QStringLiteral("#myroom:kde.org"), "test-min-sync.json"_ls);
} }
void NeoChatRoomTest::eventTest() void NeoChatRoomTest::eventTest()

View File

@@ -31,8 +31,8 @@ private Q_SLOTS:
void PollHandlerTest::initTestCase() void PollHandlerTest::initTestCase()
{ {
connection = Connection::makeMockConnection(u"@bob:kde.org"_s); connection = Connection::makeMockConnection(QStringLiteral("@bob:kde.org"));
room = new TestUtils::TestRoom(connection, u"#myroom:kde.org"_s, u"test-pollhandlerstart-sync.json"_s); room = new TestUtils::TestRoom(connection, QStringLiteral("#myroom:kde.org"), "test-pollhandlerstart-sync.json"_ls);
} }
// Basically don't crash. // Basically don't crash.
@@ -54,16 +54,16 @@ void PollHandlerTest::poll()
auto startEvent = eventCast<const PollStartEvent>(room->messageEvents().at(0).get()); auto startEvent = eventCast<const PollStartEvent>(room->messageEvents().at(0).get());
auto pollHandler = PollHandler(room, startEvent); auto pollHandler = PollHandler(room, startEvent);
auto options = QJsonArray{QJsonObject{{"id"_L1, "option1"_L1}, {"org.matrix.msc1767.text"_L1, "option1"_L1}}, auto options = QJsonArray{QJsonObject{{"id"_ls, "option1"_ls}, {"org.matrix.msc1767.text"_ls, "option1"_ls}},
QJsonObject{{"id"_L1, "option2"_L1}, {"org.matrix.msc1767.text"_L1, "option2"_L1}}}; QJsonObject{{"id"_ls, "option2"_ls}, {"org.matrix.msc1767.text"_ls, "option2"_ls}}};
QCOMPARE(pollHandler.hasEnded(), false); QCOMPARE(pollHandler.hasEnded(), false);
QCOMPARE(pollHandler.answerCount(), 0); QCOMPARE(pollHandler.answerCount(), 0);
QCOMPARE(pollHandler.question(), u"test"_s); QCOMPARE(pollHandler.question(), QStringLiteral("test"));
QCOMPARE(pollHandler.options(), options); QCOMPARE(pollHandler.options(), options);
QCOMPARE(pollHandler.answers(), QJsonObject()); QCOMPARE(pollHandler.answers(), QJsonObject());
QCOMPARE(pollHandler.counts(), 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) QTEST_GUILESS_MAIN(PollHandlerTest)

View File

@@ -20,50 +20,59 @@ class ReactionModelTest : public QObject
private: private:
Connection *connection = nullptr; Connection *connection = nullptr;
TestUtils::TestRoom *room = nullptr; TestUtils::TestRoom *room = nullptr;
MessageContentModel *parentModel;
private Q_SLOTS: private Q_SLOTS:
void initTestCase(); void initTestCase();
void nullModel();
void basicReaction(); void basicReaction();
void newReaction(); void newReaction();
}; };
void ReactionModelTest::initTestCase() void ReactionModelTest::initTestCase()
{ {
connection = Connection::makeMockConnection(u"@bob:kde.org"_s); connection = Connection::makeMockConnection(QStringLiteral("@bob:kde.org"));
room = new TestUtils::TestRoom(connection, u"#myroom:kde.org"_s, u"test-reactionmodel-sync.json"_s); room = new TestUtils::TestRoom(connection, QStringLiteral("#myroom:kde.org"), QLatin1String("test-reactionmodel-sync.json"));
parentModel = new MessageContentModel(room, "123456"_L1); }
void ReactionModelTest::nullModel()
{
auto model = ReactionModel(nullptr, nullptr);
QCOMPARE(model.rowCount(), 0);
QCOMPARE(model.data(model.index(0), ReactionModel::TextContentRole), QVariant());
} }
void ReactionModelTest::basicReaction() void ReactionModelTest::basicReaction()
{ {
auto event = eventCast<const RoomMessageEvent>(room->messageEvents().at(0).get()); auto event = eventCast<const RoomMessageEvent>(room->messageEvents().at(0).get());
auto model = ReactionModel(parentModel, event->id(), room); auto model = ReactionModel(event, room);
QCOMPARE(model.rowCount(), 1); 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::TextContentRole), QStringLiteral("<span style=\"font-family: 'emoji';\">👍</span>"));
QCOMPARE(model.data(model.index(0), ReactionModel::ReactionRole), u"👍"_s); QCOMPARE(model.data(model.index(0), ReactionModel::ReactionRole), QStringLiteral("👍"));
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>"));
QCOMPARE(model.data(model.index(0), ReactionModel::HasLocalMember), false); QCOMPARE(model.data(model.index(0), ReactionModel::HasLocalMember), false);
} }
void ReactionModelTest::newReaction() void ReactionModelTest::newReaction()
{ {
auto event = eventCast<const RoomMessageEvent>(room->messageEvents().at(0).get()); auto event = eventCast<const RoomMessageEvent>(room->messageEvents().at(0).get());
auto model = new ReactionModel(parentModel, event->id(), room); auto model = new ReactionModel(event, room);
QCOMPARE(model->rowCount(), 1); 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())); 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(model->rowCount(), 2);
QCOMPARE(spy.count(), 2); // Once for each of the 2 new reactions. 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), 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; delete model;
} }

View File

@@ -31,7 +31,7 @@ public:
{ {
if (!syncFileName.isEmpty()) { if (!syncFileName.isEmpty()) {
QFile testSyncFile; QFile testSyncFile;
testSyncFile.setFileName(QStringLiteral(DATA_DIR) + u'/' + syncFileName); testSyncFile.setFileName(QLatin1String(DATA_DIR) + u'/' + syncFileName);
testSyncFile.open(QIODevice::ReadOnly); testSyncFile.open(QIODevice::ReadOnly);
const auto testSyncJson = QJsonDocument::fromJson(testSyncFile.readAll()); const auto testSyncJson = QJsonDocument::fromJson(testSyncFile.readAll());
Quotient::SyncRoomData roomData(id(), Quotient::JoinState::Join, testSyncJson.object()); 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()) { if (!eventFileName.isEmpty()) {
QFile testEventFile; QFile testEventFile;
testEventFile.setFileName(QStringLiteral(DATA_DIR) + u'/' + eventFileName); testEventFile.setFileName(QLatin1String(DATA_DIR) + u'/' + eventFileName);
testEventFile.open(QIODevice::ReadOnly); testEventFile.open(QIODevice::ReadOnly);
auto testSyncJson = QJsonDocument::fromJson(testEventFile.readAll()).object(); auto testSyncJson = QJsonDocument::fromJson(testEventFile.readAll()).object();
return Quotient::loadEvent<EventT>(testSyncJson); return Quotient::loadEvent<EventT>(testSyncJson);

View File

@@ -63,7 +63,6 @@ private Q_SLOTS:
void receiveRichEdited(); void receiveRichEdited();
void receiveLineSeparator(); void receiveLineSeparator();
void receiveRichCodeUrl(); void receiveRichCodeUrl();
void receiveRichColor();
void componentOutput_data(); void componentOutput_data();
void componentOutput(); void componentOutput();
@@ -71,25 +70,25 @@ private Q_SLOTS:
void TextHandlerTest::initTestCase() void TextHandlerTest::initTestCase()
{ {
connection = Connection::makeMockConnection(u"@bob:kde.org"_s); connection = Connection::makeMockConnection(QStringLiteral("@bob:kde.org"));
connection->setAccountData(u"im.ponies.user_emotes"_s, connection->setAccountData("im.ponies.user_emotes"_ls,
QJsonObject{{"images"_L1, QJsonObject{{"images"_ls,
QJsonObject{{"test"_L1, QJsonObject{{"test"_ls,
QJsonObject{{"body"_L1, "Test custom emoji"_L1}, QJsonObject{{"body"_ls, "Test custom emoji"_ls},
{"url"_L1, "mxc://example.org/test"_L1}, {"url"_ls, "mxc://example.org/test"_ls},
{"usage"_L1, QJsonArray{"emoticon"_L1}}}}}}}); {"usage"_ls, QJsonArray{"emoticon"_ls}}}}}}});
CustomEmojiModel::instance().setConnection(static_cast<NeoChatConnection *>(connection)); 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() void TextHandlerTest::allowedAttributes()
{ {
const QString testInputString1 = 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 = u"<span data-mx-spoiler><font color=#FFFFFF>Test</font><span>"_s; 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. // 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 testInputString2 = QStringLiteral("<a href=\"https://kde.org\">link</a><a href='https://kde.org'>link</a>");
const QString testOutputString2 = u"<a href=\"https://kde.org\">link</a><a href='https://kde.org'>link</a>"_s; const QString testOutputString2 = QStringLiteral("<a href=\"https://kde.org\">link</a><a href='https://kde.org'>link</a>");
TextHandler testTextHandler; TextHandler testTextHandler;
testTextHandler.setData(testInputString1); testTextHandler.setData(testInputString1);
@@ -104,8 +103,8 @@ void TextHandlerTest::allowedAttributes()
void TextHandlerTest::stripDisallowedTags() void TextHandlerTest::stripDisallowedTags()
{ {
const QString testInputString = u"<p>Allowed</p> <span>Allowed</span> <body>Disallowed</body>"_s; const QString testInputString = QStringLiteral("<p>Allowed</p> <span>Allowed</span> <body>Disallowed</body>");
const QString testOutputString = u"<p>Allowed</p> <span>Allowed</span> Disallowed"_s; const QString testOutputString = QStringLiteral("<p>Allowed</p> <span>Allowed</span> Disallowed");
TextHandler testTextHandler; TextHandler testTextHandler;
testTextHandler.setData(testInputString); testTextHandler.setData(testInputString);
@@ -116,8 +115,8 @@ void TextHandlerTest::stripDisallowedTags()
void TextHandlerTest::stripDisallowedAttributes() void TextHandlerTest::stripDisallowedAttributes()
{ {
const QString testInputString = u"<p style=\"font-size:50px;\" color=#FFFFFF>Test</p>"_s; const QString testInputString = QStringLiteral("<p style=\"font-size:50px;\" color=#FFFFFF>Test</p>");
const QString testOutputString = u"Test"_s; const QString testOutputString = QStringLiteral("Test");
TextHandler testTextHandler; TextHandler testTextHandler;
testTextHandler.setData(testInputString); testTextHandler.setData(testInputString);
@@ -132,8 +131,8 @@ void TextHandlerTest::stripDisallowedAttributes()
*/ */
void TextHandlerTest::emptyCodeTags() void TextHandlerTest::emptyCodeTags()
{ {
const QString testInputString = u"<pre><code></code></pre>"_s; const QString testInputString = QStringLiteral("<pre><code></code></pre>");
const QString testOutputString = u"<pre><code></code></pre>"_s; const QString testOutputString = QStringLiteral("<pre><code></code></pre>");
TextHandler testTextHandler; TextHandler testTextHandler;
testTextHandler.setData(testInputString); testTextHandler.setData(testInputString);
@@ -144,8 +143,8 @@ void TextHandlerTest::emptyCodeTags()
void TextHandlerTest::sendSimpleStringCase() void TextHandlerTest::sendSimpleStringCase()
{ {
const QString testInputString = u"This data should just be left alone."_s; const QString testInputString = QStringLiteral("This data should just be left alone.");
const QString testOutputString = u"This data should just be left alone."_s; const QString testOutputString = QStringLiteral("This data should just be left alone.");
TextHandler testTextHandler; TextHandler testTextHandler;
testTextHandler.setData(testInputString); testTextHandler.setData(testInputString);
@@ -155,10 +154,11 @@ void TextHandlerTest::sendSimpleStringCase()
void TextHandlerTest::sendSingleParaMarkup() void TextHandlerTest::sendSingleParaMarkup()
{ {
const QString testInputString = const QString testInputString = QStringLiteral(
u"Text para with **bold**, *italic*, [link](https://kde.org), ![image](mxc://kde.org/aebd3ffd40503e1ef0525bf8f0d60282fec6183e), `inline code`."_s; "Text para with **bold**, *italic*, [link](https://kde.org), ![image](mxc://kde.org/aebd3ffd40503e1ef0525bf8f0d60282fec6183e), `inline code`.");
const QString testOutputString = const QString testOutputString = QStringLiteral(
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; "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; TextHandler testTextHandler;
testTextHandler.setData(testInputString); testTextHandler.setData(testInputString);
@@ -169,9 +169,11 @@ void TextHandlerTest::sendSingleParaMarkup()
void TextHandlerTest::sendMultipleSectionMarkup() void TextHandlerTest::sendMultipleSectionMarkup()
{ {
const QString testInputString = 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; 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 = const QString testOutputString = QStringLiteral(
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; "<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; TextHandler testTextHandler;
testTextHandler.setData(testInputString); testTextHandler.setData(testInputString);
@@ -181,8 +183,8 @@ void TextHandlerTest::sendMultipleSectionMarkup()
void TextHandlerTest::sendBadLinks() void TextHandlerTest::sendBadLinks()
{ {
const QString testInputString = u"[link](kde.org), ![image](https://kde.org/aebd3ffd40503e1ef0525bf8f0d60282fec6183e)"_s; const QString testInputString = QStringLiteral("[link](kde.org), ![image](https://kde.org/aebd3ffd40503e1ef0525bf8f0d60282fec6183e)");
const QString testOutputString = u"<a>link</a>, <img alt=\"image\">"_s; const QString testOutputString = QStringLiteral("<a>link</a>, <img alt=\"image\">");
TextHandler testTextHandler; TextHandler testTextHandler;
testTextHandler.setData(testInputString); testTextHandler.setData(testInputString);
@@ -195,9 +197,9 @@ void TextHandlerTest::sendBadLinks()
*/ */
void TextHandlerTest::sendEscapeCode() 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 = const QString testOutputString =
u"<pre><code>&lt;p&gt;Test &lt;span style=&quot;font-size:50px;&quot;&gt;some&lt;/span&gt; code&lt;/p&gt;\n</code></pre>"_s; QStringLiteral("<pre><code>&lt;p&gt;Test &lt;span style=&quot;font-size:50px;&quot;&gt;some&lt;/span&gt; code&lt;/p&gt;\n</code></pre>");
TextHandler testTextHandler; TextHandler testTextHandler;
testTextHandler.setData(testInputString); testTextHandler.setData(testInputString);
@@ -207,8 +209,8 @@ void TextHandlerTest::sendEscapeCode()
void TextHandlerTest::sendCodeClass() 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 testInputString = QStringLiteral("```html\nsome code\n```\n<pre><code class=\"code-underline\">some more code</code></pre>");
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 testOutputString = QStringLiteral("<pre><code class=\"language-html\">some code\n</code></pre>\n<pre><code>some more code</code></pre>");
TextHandler testTextHandler; TextHandler testTextHandler;
testTextHandler.setData(testInputString); testTextHandler.setData(testInputString);
@@ -218,9 +220,9 @@ void TextHandlerTest::sendCodeClass()
void TextHandlerTest::sendCustomEmoji() void TextHandlerTest::sendCustomEmoji()
{ {
const QString testInputString = u":test:"_s; const QString testInputString = QStringLiteral(":test:");
const QString testOutputString = 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; TextHandler testTextHandler;
testTextHandler.setData(testInputString); testTextHandler.setData(testInputString);
@@ -233,8 +235,8 @@ void TextHandlerTest::sendCustomEmojiCode_data()
QTest::addColumn<QString>("testInputString"); QTest::addColumn<QString>("testInputString");
QTest::addColumn<QString>("testOutputString"); QTest::addColumn<QString>("testOutputString");
QTest::newRow("inline") << u"`:test:`"_s << u"<code>:test:</code>"_s; QTest::newRow("inline") << QStringLiteral("`:test:`") << QStringLiteral("<code>:test:</code>");
QTest::newRow("block") << u"```\n:test:\n```"_s << u"<pre><code>:test:\n</code></pre>"_s; QTest::newRow("block") << QStringLiteral("```\n:test:\n```") << QStringLiteral("<pre><code>:test:\n</code></pre>");
} }
// Custom emojis in code blocks should be left alone. // Custom emojis in code blocks should be left alone.
@@ -251,9 +253,9 @@ void TextHandlerTest::sendCustomEmojiCode()
void TextHandlerTest::receiveSpacelessSelfClosingTag() void TextHandlerTest::receiveSpacelessSelfClosingTag()
{ {
const QString testInputString = u"Test...<br/>...ing"_s; const QString testInputString = QStringLiteral("Test...<br/>...ing");
const QString testRichOutputString = u"Test...<br/>...ing"_s; const QString testRichOutputString = QStringLiteral("Test...<br/>...ing");
const QString testPlainOutputString = u"Test...\n...ing"_s; const QString testPlainOutputString = QStringLiteral("Test...\n...ing");
TextHandler testTextHandler; TextHandler testTextHandler;
testTextHandler.setData(testInputString); testTextHandler.setData(testInputString);
@@ -264,9 +266,10 @@ void TextHandlerTest::receiveSpacelessSelfClosingTag()
void TextHandlerTest::receiveStripReply() void TextHandlerTest::receiveStripReply()
{ {
const QString testInputString = const QString testInputString = QStringLiteral(
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; "<mx-reply><blockquote><a href=\"https://matrix.to/#/!somewhere:example.org/$event:example.org\">In reply to</a><a "
const QString testOutputString = u"Reply message."_s; "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; TextHandler testTextHandler;
testTextHandler.setData(testInputString); testTextHandler.setData(testInputString);
@@ -280,10 +283,10 @@ void TextHandlerTest::receiveRichInPlainOut_data()
QTest::addColumn<QString>("testInputString"); QTest::addColumn<QString>("testInputString");
QTest::addColumn<QString>("testOutputString"); QTest::addColumn<QString>("testOutputString");
QTest::newRow("ampersand") << u"a &amp; b"_s << u"a & b"_s; QTest::newRow("ampersand") << QStringLiteral("a &amp; b") << QStringLiteral("a & b");
QTest::newRow("quote") << u"&quot;a and b&quot;"_s << u"\"a and b\""_s; QTest::newRow("quote") << QStringLiteral("&quot;a and b&quot;") << QStringLiteral("\"a and b\"");
QTest::newRow("new line") << u"new<br>line"_s << u"new\nline"_s; QTest::newRow("new line") << QStringLiteral("new<br>line") << QStringLiteral("new\nline");
QTest::newRow("unescape") << u"can&#x27;t"_s << u"can't"_s; QTest::newRow("unescape") << QStringLiteral("can&#x27;t") << QStringLiteral("can't");
} }
void TextHandlerTest::receiveRichInPlainOut() void TextHandlerTest::receiveRichInPlainOut()
@@ -299,13 +302,13 @@ void TextHandlerTest::receiveRichInPlainOut()
void TextHandlerTest::receivePlainTextIn() void TextHandlerTest::receivePlainTextIn()
{ {
const QString testInputString = 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 = u"&lt;plain text in tag bracket&gt;<br>Test link <a href=\"https://kde.org\">https://kde.org</a>."_s; const QString testOutputStringRich = QStringLiteral("&lt;plain text in tag bracket&gt;<br>Test link <a href=\"https://kde.org\">https://kde.org</a>.");
QString testOutputStringPlain = u"<plain text in tag bracket>\nTest link https://kde.org."_s; QString testOutputStringPlain = QStringLiteral("<plain text in tag bracket>\nTest link https://kde.org.");
// Make sure quotes are maintained in a plain string. // 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 testInputString2 = QStringLiteral("last line is \"Time to switch to a new topic.\"");
const QString testOutputString2 = u"last line is \"Time to switch to a new topic.\""_s; const QString testOutputString2 = QStringLiteral("last line is \"Time to switch to a new topic.\"");
TextHandler testTextHandler; TextHandler testTextHandler;
testTextHandler.setData(testInputString); testTextHandler.setData(testInputString);
@@ -320,12 +323,12 @@ void TextHandlerTest::receivePlainTextIn()
void TextHandlerTest::receiveStripNewlines() void TextHandlerTest::receiveStripNewlines()
{ {
const QString testInputStringPlain = u"Test\nmany\nnew\nlines."_s; const QString testInputStringPlain = QStringLiteral("Test\nmany\nnew\nlines.");
const QString testInputStringRich = u"Test<br>many<br />new<br>lines."_s; const QString testInputStringRich = QStringLiteral("Test<br>many<br />new<br>lines.");
const QString testOutputString = u"Test many new lines."_s; const QString testOutputString = QStringLiteral("Test many new lines.");
const QString testInputStringPlain2 = u"* List\n* Items"_s; const QString testInputStringPlain2 = QStringLiteral("* List\n* Items");
const QString testOutputString2 = u"List Items"_s; const QString testOutputString2 = QStringLiteral("List Items");
TextHandler testTextHandler; TextHandler testTextHandler;
testTextHandler.setData(testInputStringPlain); testTextHandler.setData(testInputStringPlain);
@@ -347,8 +350,8 @@ void TextHandlerTest::receiveStripNewlines()
*/ */
void TextHandlerTest::receivePlainStripHtml() void TextHandlerTest::receivePlainStripHtml()
{ {
const QString testInputString = 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 = u"Test Some code <strong>with tags</strong>"_s; const QString testOutputString = QStringLiteral("Test Some code <strong>with tags</strong>");
TextHandler testTextHandler; TextHandler testTextHandler;
testTextHandler.setData(testInputString); testTextHandler.setData(testInputString);
@@ -358,8 +361,8 @@ void TextHandlerTest::receivePlainStripHtml()
void TextHandlerTest::receivePlainStripMarkup() void TextHandlerTest::receivePlainStripMarkup()
{ {
const QString testInputString = u"**bold** `<p>inline code</p>` *italic*"_s; const QString testInputString = QStringLiteral("**bold** `<p>inline code</p>` *italic*");
const QString testOutputString = u"bold <p>inline code</p> italic"_s; const QString testOutputString = QStringLiteral("bold <p>inline code</p> italic");
TextHandler testTextHandler; TextHandler testTextHandler;
testTextHandler.setData(testInputString); testTextHandler.setData(testInputString);
@@ -369,8 +372,8 @@ void TextHandlerTest::receivePlainStripMarkup()
void TextHandlerTest::receiveRichUserPill() void TextHandlerTest::receiveRichUserPill()
{ {
const QString testInputString = u"<p><a href=\"https://matrix.to/#/@alice:example.org\">@alice:example.org</a></p>"_s; const QString testInputString = QStringLiteral("<p><a href=\"https://matrix.to/#/@alice:example.org\">@alice:example.org</a></p>");
const QString testOutputString = u"<b><a href=\"https://matrix.to/#/@alice:example.org\">@alice:example.org</a></b>"_s; const QString testOutputString = QStringLiteral("<b><a href=\"https://matrix.to/#/@alice:example.org\">@alice:example.org</a></b>");
TextHandler testTextHandler; TextHandler testTextHandler;
testTextHandler.setData(testInputString); testTextHandler.setData(testInputString);
@@ -380,8 +383,8 @@ void TextHandlerTest::receiveRichUserPill()
void TextHandlerTest::receiveRichStrikethrough() void TextHandlerTest::receiveRichStrikethrough()
{ {
const QString testInputString = u"<p><del>Test</del></p>"_s; const QString testInputString = QStringLiteral("<p><del>Test</del></p>");
const QString testOutputString = u"<s>Test</s>"_s; const QString testOutputString = QStringLiteral("<s>Test</s>");
TextHandler testTextHandler; TextHandler testTextHandler;
testTextHandler.setData(testInputString); testTextHandler.setData(testInputString);
@@ -391,8 +394,8 @@ void TextHandlerTest::receiveRichStrikethrough()
void TextHandlerTest::receiveRichtextIn() void TextHandlerTest::receiveRichtextIn()
{ {
const QString testInputString = 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 = u"<p>Test</p> <pre><code>Some code &lt;strong&gt;with tags&lt;/strong&gt;</code></pre>"_s; const QString testOutputString = QStringLiteral("<p>Test</p> <pre><code>Some code &lt;strong&gt;with tags&lt;/strong&gt;</code></pre>");
TextHandler testTextHandler; TextHandler testTextHandler;
testTextHandler.setData(testInputString); testTextHandler.setData(testInputString);
@@ -402,10 +405,15 @@ void TextHandlerTest::receiveRichtextIn()
void TextHandlerTest::receiveRichMxcUrl() void TextHandlerTest::receiveRichMxcUrl()
{ {
const QString testInputString = const QString testInputString = QStringLiteral(
u"<img src=\"mxc://kde.org/aebd3ffd40503e1ef0525bf8f0d60282fec6183e\" alt=\"image\"><img src=\"mxc://kde.org/34c3464b3a1bd7f55af2d559e07d2c773c430e73\" alt=\"image\">"_s; "<img src=\"mxc://kde.org/aebd3ffd40503e1ef0525bf8f0d60282fec6183e\" alt=\"image\"><img src=\"mxc://kde.org/34c3464b3a1bd7f55af2d559e07d2c773c430e73\" "
const QString testOutputString = "alt=\"image\">");
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 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; TextHandler testTextHandler;
testTextHandler.setData(testInputString); 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 // 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. // so we can confirm consistent behaviour for complex urls.
const QString testInputStringLink1 = const QString testInputStringLink1 = QStringLiteral(
u"https://matrix.to/#/!RvzunyTWZGfNxJVQqv:matrix.org/$-9TJVTh5PvW6MvIhFDwteiyLBVGriinueO5eeIazQS8?via=libera.chat&amp;via=matrix.org&amp;via=fedora.im <a href=\"https://matrix.to/#/!RvzunyTWZGfNxJVQqv:matrix.org/$-9TJVTh5PvW6MvIhFDwteiyLBVGriinueO5eeIazQS8?via=libera.chat&amp;via=matrix.org&amp;via=fedora.im\">Link already rich</a>"_s; "https://matrix.to/#/!RvzunyTWZGfNxJVQqv:matrix.org/$-9TJVTh5PvW6MvIhFDwteiyLBVGriinueO5eeIazQS8?via=libera.chat&amp;via=matrix.org&amp;via=fedora.im "
const QString testOutputStringLink1 = "<a "
u"<a href=\"https://matrix.to/#/!RvzunyTWZGfNxJVQqv:matrix.org/$-9TJVTh5PvW6MvIhFDwteiyLBVGriinueO5eeIazQS8?via=libera.chat&amp;via=matrix.org&amp;via=fedora.im\">https://matrix.to/#/!RvzunyTWZGfNxJVQqv:matrix.org/$-9TJVTh5PvW6MvIhFDwteiyLBVGriinueO5eeIazQS8?via=libera.chat&amp;via=matrix.org&amp;via=fedora.im</a> <a href=\"https://matrix.to/#/!RvzunyTWZGfNxJVQqv:matrix.org/$-9TJVTh5PvW6MvIhFDwteiyLBVGriinueO5eeIazQS8?via=libera.chat&amp;via=matrix.org&amp;via=fedora.im\">Link already rich</a>"_s; "href=\"https://matrix.to/#/!RvzunyTWZGfNxJVQqv:matrix.org/"
"$-9TJVTh5PvW6MvIhFDwteiyLBVGriinueO5eeIazQS8?via=libera.chat&amp;via=matrix.org&amp;via=fedora.im\">Link already rich</a>");
const QString testOutputStringLink1 = QStringLiteral(
"<a "
"href=\"https://matrix.to/#/!RvzunyTWZGfNxJVQqv:matrix.org/"
"$-9TJVTh5PvW6MvIhFDwteiyLBVGriinueO5eeIazQS8?via=libera.chat&amp;via=matrix.org&amp;via=fedora.im\">https://matrix.to/#/"
"!RvzunyTWZGfNxJVQqv:matrix.org/$-9TJVTh5PvW6MvIhFDwteiyLBVGriinueO5eeIazQS8?via=libera.chat&amp;via=matrix.org&amp;via=fedora.im</a> <a "
"href=\"https://matrix.to/#/!RvzunyTWZGfNxJVQqv:matrix.org/"
"$-9TJVTh5PvW6MvIhFDwteiyLBVGriinueO5eeIazQS8?via=libera.chat&amp;via=matrix.org&amp;via=fedora.im\">Link already rich</a>");
// Another real case. The linkification wasn't handling it when a single link // 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 // contains what looks like and email. It was been broken into 3 but needs to
// be just single link. // be just single link.
const QString testInputStringLink2 = u"https://lore.kernel.org/lkml/CAHk-=wio46vC4t6xXD-sFqjoPwFm_u515jm3suzmkGxQTeA1_A@mail.gmail.com/"_s; const QString testInputStringLink2 = QStringLiteral("https://lore.kernel.org/lkml/CAHk-=wio46vC4t6xXD-sFqjoPwFm_u515jm3suzmkGxQTeA1_A@mail.gmail.com/");
const QString testOutputStringLink2 = const QString testOutputStringLink2 = QStringLiteral(
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; "<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 testInputStringEmail = QStringLiteral(R"(email@example.com <a href="mailto:email@example.com">Link already rich</a>)");
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 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 testInputStringMxId = QStringLiteral("@user:kde.org <a href=\"https://matrix.to/#/@user:kde.org\">Link already rich</a>");
QString testOutputStringMxId = QString testOutputStringMxId = QStringLiteral(
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; "<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 testInputStringMxIdWithPrefix = QStringLiteral("a @user:kde.org b");
QString testOutputStringMxIdWithPrefix = u"a <b><a href=\"https://matrix.to/#/@user:kde.org\">@user:kde.org</a></b> b"_s; QString testOutputStringMxIdWithPrefix = QStringLiteral("a <b><a href=\"https://matrix.to/#/@user:kde.org\">@user:kde.org</a></b> b");
TextHandler testTextHandler; TextHandler testTextHandler;
testTextHandler.setData(testInputStringLink1); testTextHandler.setData(testInputStringLink1);
@@ -468,9 +487,9 @@ void TextHandlerTest::receiveRichEdited_data()
QTest::addColumn<QString>("testInputString"); QTest::addColumn<QString>("testInputString");
QTest::addColumn<QString>("testOutputString"); QTest::addColumn<QString>("testOutputString");
QTest::newRow("basic") << u"Edited"_s << u"Edited <span style=\"color:#000000\">(edited)</span>"_s; QTest::newRow("basic") << QStringLiteral("Edited") << QStringLiteral("Edited <span style=\"color:#000000\">(edited)</span>");
QTest::newRow("multiple paragraphs") << u"<p>Edited</p>\n<p>Edited</p>"_s QTest::newRow("multiple paragraphs") << QStringLiteral("<p>Edited</p>\n<p>Edited</p>")
<< u"<p>Edited</p>\n<p>Edited <span style=\"color:#000000\">(edited)</span></p>"_s; << QStringLiteral("<p>Edited</p>\n<p>Edited <span style=\"color:#000000\">(edited)</span></p>");
} }
void TextHandlerTest::receiveRichEdited() void TextHandlerTest::receiveRichEdited()
@@ -487,72 +506,61 @@ void TextHandlerTest::receiveRichEdited()
void TextHandlerTest::receiveLineSeparator() void TextHandlerTest::receiveLineSeparator()
{ {
auto text = u"foo\u2028bar"_s; auto text = QStringLiteral("foo\u2028bar");
TextHandler textHandler; TextHandler textHandler;
textHandler.setData(text); 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() void TextHandlerTest::receiveRichCodeUrl()
{ {
auto input = u"<code>https://kde.org</code>"_s; auto input = QStringLiteral("<code>https://kde.org</code>");
TextHandler testTextHandler; TextHandler testTextHandler;
testTextHandler.setData(input); testTextHandler.setData(input);
QCOMPARE(testTextHandler.handleRecieveRichText(), 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() void TextHandlerTest::componentOutput_data()
{ {
QTest::addColumn<QString>("testInputString"); QTest::addColumn<QString>("testInputString");
QTest::addColumn<QList<MessageComponent>>("testOutputComponents"); QTest::addColumn<QList<MessageComponent>>("testOutputComponents");
QTest::newRow("multiple paragraphs") << u"<p>Text</p>\n<p>Text</p>"_s QTest::newRow("multiple paragraphs") << QStringLiteral("<p>Text</p>\n<p>Text</p>")
<< QList<MessageComponent>{MessageComponent{MessageComponentType::Text, u"Text"_s, {}}, << QList<MessageComponent>{MessageComponent{MessageComponentType::Text, QStringLiteral("Text"), {}},
MessageComponent{MessageComponentType::Text, u"Text"_s, {}}}; MessageComponent{MessageComponentType::Text, QStringLiteral("Text"), {}}};
QTest::newRow("code") << u"<p>Text</p>\n<pre><code class=\"language-html\">Some code\n</code></pre>"_s QTest::newRow("code") << QStringLiteral("<p>Text</p>\n<pre><code class=\"language-html\">Some code\n</code></pre>")
<< QList<MessageComponent>{MessageComponent{MessageComponentType::Text, u"Text"_s, {}}, << QList<MessageComponent>{MessageComponent{MessageComponentType::Text, QStringLiteral("Text"), {}},
MessageComponent{MessageComponentType::Code, u"Some code"_s, QVariantMap{{u"class"_s, u"html"_s}}}}; MessageComponent{MessageComponentType::Code,
QTest::newRow("quote") << u"<p>Text</p>\n<blockquote>\n<p>blockquote</p>\n</blockquote>"_s QStringLiteral("Some code"),
<< QList<MessageComponent>{MessageComponent{MessageComponentType::Text, u"Text"_s, {}}, QVariantMap{{QStringLiteral("class"), QStringLiteral("html")}}}};
MessageComponent{MessageComponentType::Quote, u"“blockquote”"_s, {}}}; QTest::newRow("quote") << QStringLiteral("<p>Text</p>\n<blockquote>\n<p>blockquote</p>\n</blockquote>")
QTest::newRow("multiple paragraph quote") << u"<blockquote>\n<p>blockquote</p>\n<p>next paragraph</p>\n</blockquote>"_s << 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>{ << QList<MessageComponent>{
MessageComponent{MessageComponentType::Quote, u"<p>“blockquote</p>\n<p>next paragraph”</p>"_s, {}}}; MessageComponent{MessageComponentType::Text, QStringLiteral("<code>https://kde.org</code>"), {}}};
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("long start tag") 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>{ << QList<MessageComponent>{
MessageComponent{MessageComponentType::Text, u"Ah, you mean something like<br/>"_s, {}}, MessageComponent{MessageComponentType::Text, QStringLiteral("Ah, you mean something like<br/>"), {}},
MessageComponent{ MessageComponent{
MessageComponentType::Code, MessageComponentType::Code,
u"# main.qml\nimport CustomQml\n...\nControls.TextField { id: someField }\nCustomQml {\n someTextProperty: someField.text\n}"_s, QStringLiteral(
QVariantMap{{u"class"_s, u"qml"_s}}}, "# main.qml\nimport CustomQml\n...\nControls.TextField { id: someField }\nCustomQml {\n someTextProperty: someField.text\n}"),
MessageComponent{MessageComponentType::Text, u"Sure you can, it's still local to the same file where you defined the id"_s, {}}}; 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() void TextHandlerTest::componentOutput()

View File

@@ -1,34 +0,0 @@
# SPDX-FileCopyrightText: 2024 James Graham <james.h.graham@protonmail.com>
# SPDX-License-Identifier: BSD-2-Clause
add_definitions(-DDATA_DIR="${CMAKE_CURRENT_SOURCE_DIR}" )
qt_add_executable(timeline-memtest
main.cpp
)
target_link_libraries(timeline-memtest PRIVATE neochatplugin timelineplugin)
target_link_libraries(timeline-memtest PUBLIC
Qt::Core
Qt::Quick
Qt::Qml
Qt::Gui
Qt::QuickControls2
KF6::Kirigami
QuotientQt6
neochat
)
ecm_add_qml_module(timeline-memtest URI org.kde.neochat.timeline-memtest GENERATE_PLUGIN_SOURCE
OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/src/org/kde/timeline-memtest
QML_FILES
Main.qml
SOURCES
memtesttimelinemodel.cpp
memtesttimelinemodel.h
DEPENDENCIES
QtCore
QtQuick
IMPORTS
org.kde.neochat
)

View File

@@ -1,33 +0,0 @@
// 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
import QtQuick
import QtQuick.Controls as QQC2
import org.kde.kirigami as Kirigami
import org.kde.neochat
QQC2.ApplicationWindow {
id: root
title: "Timeline Memory Test"
minimumWidth: Kirigami.Units.gridUnit * 30
minimumHeight: Kirigami.Units.gridUnit * 30
visible: true
QQC2.ScrollView {
width: root.width
height: root.height
contentItem: ListView {
model: messageFilterModel
delegate: EventDelegate {
room: memTestTimelineModel.room
}
}
}
}

View File

@@ -1,30 +0,0 @@
// 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 <QApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <KLocalizedString>
#include "memtesttimelinemodel.h"
#include "models/messagefiltermodel.h"
using namespace Qt::StringLiterals;
int main(int argc, char **argv)
{
QApplication app(argc, argv);
KLocalizedString::setApplicationDomain(QByteArrayLiteral("neochat"));
QQmlApplicationEngine engine;
engine.loadFromModule("org.kde.neochat.timeline-memtest", "Main");
MemTestTimelineModel *memTestTimelineModel = new MemTestTimelineModel;
MessageFilterModel *messageFilterModel = new MessageFilterModel(nullptr, memTestTimelineModel);
engine.rootContext()->setContextProperty(u"memTestTimelineModel"_s, memTestTimelineModel);
engine.rootContext()->setContextProperty(u"messageFilterModel"_s, messageFilterModel);
return app.exec();
}

View File

@@ -1,655 +0,0 @@
{
"ephemeral": {
"events": [
{
"content": {
"$1000000000000:example.org": {
"m.read": {
"@alice:example.org": {
"ts": 1000000000000
}
}
}
},
"type": "m.receipt"
},
{
"content": {
"$1000000000000:example.org": {
"m.read": {
"@bob:example.org": {
"ts": 1000000000000
}
}
}
},
"type": "m.receipt"
},
{
"content": {
"$1000000000003:example.org": {
"m.read": {
"@tim:example.org": {
"ts": 1000000000000
}
}
}
},
"type": "m.receipt"
},
{
"content": {
"$1000000000003:example.org": {
"m.read": {
"@example:example.org": {
"ts": 1000000000000
}
}
}
},
"type": "m.receipt"
},
{
"content": {
"$1000000000003:example.org": {
"m.read": {
"@jeff:example.org": {
"ts": 1000000000000
}
}
}
},
"type": "m.receipt"
},
{
"content": {
"$1000000000003:example.org": {
"m.read": {
"@tina:example.org": {
"ts": 1000000000000
}
}
}
},
"type": "m.receipt"
},
{
"content": {
"$1000000000003:example.org": {
"m.read": {
"@sally:example.org": {
"ts": 1000000000000
}
}
}
},
"type": "m.receipt"
},
{
"content": {
"$1000000000003:example.org": {
"m.read": {
"@fred:example.org": {
"ts": 1000000000000
}
}
}
},
"type": "m.receipt"
}
]
},
"state": {
"events": [
{
"content": {
"avatar_url": "mxc://example.org/SEsfnsuifSDFSSEF",
"displayname": "Example",
"membership": "join"
},
"event_id": "$143273582555PhrSn:example.org",
"origin_server_ts": 1000000000000,
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
"sender": "example:example.org",
"state_key": "@example:example.org",
"type": "m.room.member",
"unsigned": {
"age": 1234
}
},
{
"content": {
"avatar_url": "mxc://example.org/SEsfnsuifSDFSSEF",
"displayname": "Alice",
"membership": "join",
"reason": "Looking for support"
},
"event_id": "$143273582443PhrSn:example.org",
"origin_server_ts": 1000000000000,
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
"sender": "alice:example.org",
"state_key": "@alice:example.org",
"type": "m.room.member",
"unsigned": {
"age": 1234
}
},
{
"content": {
"avatar_url": "mxc://example.org/SEsfnsuifSDFSSEF",
"displayname": "Bob",
"membership": "join"
},
"event_id": "$143273582443PhrSn:example.org",
"origin_server_ts": 1000000000000,
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
"sender": "bob:example.org",
"state_key": "@bob:example.org",
"type": "m.room.member",
"unsigned": {
"age": 1234
}
},
{
"content": {
"avatar_url": "mxc://example.org/SEsfnsuifSDFSSEF",
"displayname": "Tim",
"membership": "join"
},
"event_id": "$143273582443PhrSn:example.org",
"origin_server_ts": 1000000000000,
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
"sender": "tim:example.org",
"state_key": "@tim:example.org",
"type": "m.room.member",
"unsigned": {
"age": 1234
}
},
{
"content": {
"avatar_url": "mxc://example.org/SEsfnsuifSDFSSEF",
"displayname": "Jeff",
"membership": "join"
},
"event_id": "$143273582443PhrSn:example.org",
"origin_server_ts": 1000000000000,
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
"sender": "jeff:example.org",
"state_key": "@jeff:example.org",
"type": "m.room.member",
"unsigned": {
"age": 1234
}
},
{
"content": {
"avatar_url": "mxc://example.org/SEsfnsuifSDFSSEF",
"displayname": "Tina",
"membership": "join"
},
"event_id": "$143273582443PhrSn:example.org",
"origin_server_ts": 1000000000000,
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
"sender": "tina:example.org",
"state_key": "@tina:example.org",
"type": "m.room.member",
"unsigned": {
"age": 1234
}
},
{
"content": {
"avatar_url": "mxc://example.org/SEsfnsuifSDFSSEF",
"displayname": "Sally",
"membership": "join"
},
"event_id": "$143273582443PhrSn:example.org",
"origin_server_ts": 1000000000000,
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
"sender": "sally:example.org",
"state_key": "@sally:example.org",
"type": "m.room.member",
"unsigned": {
"age": 1234
}
},
{
"content": {
"avatar_url": "mxc://example.org/SEsfnsuifSDFSSEF",
"displayname": "Fred",
"membership": "join"
},
"event_id": "$143273582443PhrSn:example.org",
"origin_server_ts": 1000000000000,
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
"sender": "fred:example.org",
"state_key": "@fred:example.org",
"type": "m.room.member",
"unsigned": {
"age": 1234
}
}
]
},
"timeline": {
"events": [
{
"content": {
"body": "This is an example text message",
"format": "org.matrix.custom.html",
"formatted_body": "This is an example<br>text message",
"msgtype": "m.text"
},
"event_id": "$1000000000000:example.org",
"origin_server_ts": 1000000000000,
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
"sender": "@example:example.org",
"type": "m.room.message",
"unsigned": {
"age": 1232
}
},
{
"content": {
"body": "This is a highlight @bob:example.org",
"msgtype": "m.text"
},
"event_id": "$1000000000001:example.org",
"origin_server_ts": 1000000000001,
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
"sender": "@example:example.org",
"type": "m.room.message",
"unsigned": {
"age": 1233
}
},
{
"content": {
"m.relates_to": {
"event_id": "$1000000000001:example.org",
"key": "👍",
"rel_type": "m.annotation"
}
},
"origin_server_ts": 1000000000002,
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
"sender": "@alice:example.org",
"type": "m.reaction",
"unsigned": {
"age": 390159120
},
"event_id": "$1000000000002:example.org",
"age": 390159120
},
{
"content": {
"body": "reply",
"format": "org.matrix.custom.html",
"formatted_body": "reply",
"m.relates_to": {
"m.in_reply_to": {
"event_id": "$1000000000000:example.org"
}
},
"msgtype": "m.text"
},
"origin_server_ts": 1000000000003,
"sender": "@alice:example.org",
"type": "m.room.message",
"unsigned": {
"age": 98
},
"event_id": "$1000000000003:example.org",
"room_id": "!jEsUZKDJdhlrceRyVU:example.org"
},
{
"age": 96845207,
"content": {
"body": "Lat: 51.7035, Lon: -1.14394",
"geo_uri": "geo:51.7035,-1.14394",
"msgtype": "m.location",
"org.matrix.msc1767.text": "Lat: 51.7035, Lon: -1.14394",
"org.matrix.msc3488.asset": {
"type": "m.pin"
},
"org.matrix.msc3488.location": {
"uri": "geo:51.7035,-1.14394"
}
},
"event_id": "$1000000000004:example.org",
"origin_server_ts": 1000000000004,
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
"sender": "@example:example.org",
"type": "m.room.message",
"unsigned": {
"age": 96845207
}
},
{
"content": {
"body": "```cpp\nint main(int argc, char **argv)\n{\n QApplication app(argc, argv);\n\n KLocalizedString::setApplicationDomain(QByteArrayLiteral(\"neochat\"));\n\n QQmlApplicationEngine engine;\n engine.loadFromModule(\"org.kde.neochat.timeline-memtest\", \"Main\");\n\n return app.exec();\n}\n```",
"format": "org.matrix.custom.html",
"formatted_body": "<pre><code class=\"language-cpp\">int main(int argc, char **argv)\n{\n QApplication app(argc, argv);\n\n KLocalizedString::setApplicationDomain(QByteArrayLiteral(&quot;neochat&quot;));\n\n QQmlApplicationEngine engine;\n engine.loadFromModule(&quot;org.kde.neochat.timeline-memtest&quot;, &quot;Main&quot;);\n\n return app.exec();\n}\n</code></pre>",
"msgtype": "m.text"
},
"event_id": "$1000000000005:example.org",
"origin_server_ts": 1000000000005,
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
"sender": "@bob:example.org",
"type": "m.room.message",
"unsigned": {
"age": 1233
}
},
{
"content": {
"body": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam sed fringilla risus, eget lacinia risus. Suspendisse at magna id justo sagittis suscipit. Maecenas eros quam, pulvinar a consequat sed, varius vitae risus. Cras congue est eget felis porttitor lobortis. Nam cursus, nulla ut finibus suscipit, tellus eros tincidunt ante, a volutpat velit lectus sit amet turpis. Morbi leo justo, fringilla sed rutrum a, suscipit a quam. Proin rhoncus neque eget ligula ullamcorper pellentesque. Mauris volutpat malesuada nunc. Nullam finibus enim eu nibh placerat imperdiet. Nullam in mi in diam luctus scelerisque dignissim non erat. ",
"msgtype": "m.text"
},
"event_id": "$1000000000006:example.org",
"origin_server_ts": 1000000000006,
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
"sender": "@example:example.org",
"type": "m.room.message",
"unsigned": {
"age": 1232
}
},
{
"content": {
"body": "> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam sed fringilla risus, eget lacinia risus. Suspendisse at magna id justo sagittis suscipit. Maecenas eros quam, pulvinar a consequat sed, varius vitae risus. Cras congue est eget felis porttitor lobortis. Nam cursus, nulla ut finibus suscipit, tellus eros tincidunt ante, a volutpat velit lectus sit amet turpis. Morbi leo justo, fringilla sed rutrum a, suscipit a quam. Proin rhoncus neque eget ligula ullamcorper pellentesque. Mauris volutpat malesuada nunc. Nullam finibus enim eu nibh placerat imperdiet. Nullam in mi in diam luctus scelerisque dignissim non erat. ",
"format": "org.matrix.custom.html",
"formatted_body": "<blockquote>\n<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam sed fringilla risus, eget lacinia risus. Suspendisse at magna id justo sagittis suscipit. Maecenas eros quam, pulvinar a consequat sed, varius vitae risus. Cras congue est eget felis porttitor lobortis. Nam cursus, nulla ut finibus suscipit, tellus eros tincidunt ante, a volutpat velit lectus sit amet turpis. Morbi leo justo, fringilla sed rutrum a, suscipit a quam. Proin rhoncus neque eget ligula ullamcorper pellentesque. Mauris volutpat malesuada nunc. Nullam finibus enim eu nibh placerat imperdiet. Nullam in mi in diam luctus scelerisque dignissim non erat.</p>\n</blockquote>",
"msgtype": "m.text"
},
"event_id": "$1000000000007:example.org",
"origin_server_ts": 1000000000007,
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
"sender": "@example:example.org",
"type": "m.room.message",
"unsigned": {
"age": 1232
}
},
{
"content": {
"body": "This is an example text message",
"format": "org.matrix.custom.html",
"formatted_body": "This is an example<br>text message",
"msgtype": "m.text"
},
"event_id": "$1000000000008:example.org",
"origin_server_ts": 1000000000008,
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
"sender": "@example:example.org",
"type": "m.room.message",
"unsigned": {
"age": 1232
}
},
{
"content": {
"body": "This is a highlight @bob:example.org",
"msgtype": "m.text"
},
"event_id": "$1000000000009:example.org",
"origin_server_ts": 1000000000009,
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
"sender": "@example:example.org",
"type": "m.room.message",
"unsigned": {
"age": 1233
}
},
{
"content": {
"m.relates_to": {
"event_id": "$1000000000009:example.org",
"key": "👍",
"rel_type": "m.annotation"
}
},
"origin_server_ts": 1000000000010,
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
"sender": "@alice:example.org",
"type": "m.reaction",
"unsigned": {
"age": 390159120
},
"event_id": "$1000000000010:example.org",
"age": 390159120
},
{
"content": {
"body": "reply",
"format": "org.matrix.custom.html",
"formatted_body": "reply",
"m.relates_to": {
"m.in_reply_to": {
"event_id": "$1000000000008:example.org"
}
},
"msgtype": "m.text"
},
"origin_server_ts": 1000000000011,
"sender": "@alice:example.org",
"type": "m.room.message",
"unsigned": {
"age": 98
},
"event_id": "$1000000000011:example.org",
"room_id": "!jEsUZKDJdhlrceRyVU:example.org"
},
{
"age": 96845207,
"content": {
"body": "Lat: 51.7035, Lon: -1.14394",
"geo_uri": "geo:51.7035,-1.14394",
"msgtype": "m.location",
"org.matrix.msc1767.text": "Lat: 51.7035, Lon: -1.14394",
"org.matrix.msc3488.asset": {
"type": "m.pin"
},
"org.matrix.msc3488.location": {
"uri": "geo:51.7035,-1.14394"
}
},
"event_id": "$1000000000012:example.org",
"origin_server_ts": 1000000000012,
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
"sender": "@example:example.org",
"type": "m.room.message",
"unsigned": {
"age": 96845207
}
},
{
"content": {
"body": "```cpp\nint main(int argc, char **argv)\n{\n QApplication app(argc, argv);\n\n KLocalizedString::setApplicationDomain(QByteArrayLiteral(\"neochat\"));\n\n QQmlApplicationEngine engine;\n engine.loadFromModule(\"org.kde.neochat.timeline-memtest\", \"Main\");\n\n return app.exec();\n}\n```",
"format": "org.matrix.custom.html",
"formatted_body": "<pre><code class=\"language-cpp\">int main(int argc, char **argv)\n{\n QApplication app(argc, argv);\n\n KLocalizedString::setApplicationDomain(QByteArrayLiteral(&quot;neochat&quot;));\n\n QQmlApplicationEngine engine;\n engine.loadFromModule(&quot;org.kde.neochat.timeline-memtest&quot;, &quot;Main&quot;);\n\n return app.exec();\n}\n</code></pre>",
"msgtype": "m.text"
},
"event_id": "$1000000000013:example.org",
"origin_server_ts": 1000000000013,
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
"sender": "@bob:example.org",
"type": "m.room.message",
"unsigned": {
"age": 1233
}
},
{
"content": {
"body": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam sed fringilla risus, eget lacinia risus. Suspendisse at magna id justo sagittis suscipit. Maecenas eros quam, pulvinar a consequat sed, varius vitae risus. Cras congue est eget felis porttitor lobortis. Nam cursus, nulla ut finibus suscipit, tellus eros tincidunt ante, a volutpat velit lectus sit amet turpis. Morbi leo justo, fringilla sed rutrum a, suscipit a quam. Proin rhoncus neque eget ligula ullamcorper pellentesque. Mauris volutpat malesuada nunc. Nullam finibus enim eu nibh placerat imperdiet. Nullam in mi in diam luctus scelerisque dignissim non erat. ",
"msgtype": "m.text"
},
"event_id": "$1000000000014:example.org",
"origin_server_ts": 1000000000014,
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
"sender": "@example:example.org",
"type": "m.room.message",
"unsigned": {
"age": 1232
}
},
{
"content": {
"body": "> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam sed fringilla risus, eget lacinia risus. Suspendisse at magna id justo sagittis suscipit. Maecenas eros quam, pulvinar a consequat sed, varius vitae risus. Cras congue est eget felis porttitor lobortis. Nam cursus, nulla ut finibus suscipit, tellus eros tincidunt ante, a volutpat velit lectus sit amet turpis. Morbi leo justo, fringilla sed rutrum a, suscipit a quam. Proin rhoncus neque eget ligula ullamcorper pellentesque. Mauris volutpat malesuada nunc. Nullam finibus enim eu nibh placerat imperdiet. Nullam in mi in diam luctus scelerisque dignissim non erat. ",
"format": "org.matrix.custom.html",
"formatted_body": "<blockquote>\n<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam sed fringilla risus, eget lacinia risus. Suspendisse at magna id justo sagittis suscipit. Maecenas eros quam, pulvinar a consequat sed, varius vitae risus. Cras congue est eget felis porttitor lobortis. Nam cursus, nulla ut finibus suscipit, tellus eros tincidunt ante, a volutpat velit lectus sit amet turpis. Morbi leo justo, fringilla sed rutrum a, suscipit a quam. Proin rhoncus neque eget ligula ullamcorper pellentesque. Mauris volutpat malesuada nunc. Nullam finibus enim eu nibh placerat imperdiet. Nullam in mi in diam luctus scelerisque dignissim non erat.</p>\n</blockquote>",
"msgtype": "m.text"
},
"event_id": "$1000000000015:example.org",
"origin_server_ts": 1000000000015,
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
"sender": "@example:example.org",
"type": "m.room.message",
"unsigned": {
"age": 1232
}
},
{
"content": {
"body": "This is an example text message",
"format": "org.matrix.custom.html",
"formatted_body": "This is an example<br>text message",
"msgtype": "m.text"
},
"event_id": "$1000000000016:example.org",
"origin_server_ts": 1000000000016,
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
"sender": "@example:example.org",
"type": "m.room.message",
"unsigned": {
"age": 1232
}
},
{
"content": {
"body": "This is a highlight @bob:example.org",
"msgtype": "m.text"
},
"event_id": "$1000000000017:example.org",
"origin_server_ts": 1000000000017,
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
"sender": "@example:example.org",
"type": "m.room.message",
"unsigned": {
"age": 1233
}
},
{
"content": {
"m.relates_to": {
"event_id": "$1000000000017:example.org",
"key": "👍",
"rel_type": "m.annotation"
}
},
"origin_server_ts": 1000000000018,
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
"sender": "@alice:example.org",
"type": "m.reaction",
"unsigned": {
"age": 390159120
},
"event_id": "$1000000000018:example.org",
"age": 390159120
},
{
"content": {
"body": "reply",
"format": "org.matrix.custom.html",
"formatted_body": "reply",
"m.relates_to": {
"m.in_reply_to": {
"event_id": "$1000000000016:example.org"
}
},
"msgtype": "m.text"
},
"origin_server_ts": 1000000000019,
"sender": "@alice:example.org",
"type": "m.room.message",
"unsigned": {
"age": 98
},
"event_id": "$1000000000019:example.org",
"room_id": "!jEsUZKDJdhlrceRyVU:example.org"
},
{
"age": 96845207,
"content": {
"body": "Lat: 51.7035, Lon: -1.14394",
"geo_uri": "geo:51.7035,-1.14394",
"msgtype": "m.location",
"org.matrix.msc1767.text": "Lat: 51.7035, Lon: -1.14394",
"org.matrix.msc3488.asset": {
"type": "m.pin"
},
"org.matrix.msc3488.location": {
"uri": "geo:51.7035,-1.14394"
}
},
"event_id": "$1000000000020:example.org",
"origin_server_ts": 1000000000020,
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
"sender": "@example:example.org",
"type": "m.room.message",
"unsigned": {
"age": 96845207
}
},
{
"content": {
"body": "```cpp\nint main(int argc, char **argv)\n{\n QApplication app(argc, argv);\n\n KLocalizedString::setApplicationDomain(QByteArrayLiteral(\"neochat\"));\n\n QQmlApplicationEngine engine;\n engine.loadFromModule(\"org.kde.neochat.timeline-memtest\", \"Main\");\n\n return app.exec();\n}\n```",
"format": "org.matrix.custom.html",
"formatted_body": "<pre><code class=\"language-cpp\">int main(int argc, char **argv)\n{\n QApplication app(argc, argv);\n\n KLocalizedString::setApplicationDomain(QByteArrayLiteral(&quot;neochat&quot;));\n\n QQmlApplicationEngine engine;\n engine.loadFromModule(&quot;org.kde.neochat.timeline-memtest&quot;, &quot;Main&quot;);\n\n return app.exec();\n}\n</code></pre>",
"msgtype": "m.text"
},
"event_id": "$1000000000021:example.org",
"origin_server_ts": 1000000000021,
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
"sender": "@bob:example.org",
"type": "m.room.message",
"unsigned": {
"age": 1233
}
},
{
"content": {
"body": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam sed fringilla risus, eget lacinia risus. Suspendisse at magna id justo sagittis suscipit. Maecenas eros quam, pulvinar a consequat sed, varius vitae risus. Cras congue est eget felis porttitor lobortis. Nam cursus, nulla ut finibus suscipit, tellus eros tincidunt ante, a volutpat velit lectus sit amet turpis. Morbi leo justo, fringilla sed rutrum a, suscipit a quam. Proin rhoncus neque eget ligula ullamcorper pellentesque. Mauris volutpat malesuada nunc. Nullam finibus enim eu nibh placerat imperdiet. Nullam in mi in diam luctus scelerisque dignissim non erat. ",
"msgtype": "m.text"
},
"event_id": "$1000000000022:example.org",
"origin_server_ts": 1000000000022,
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
"sender": "@example:example.org",
"type": "m.room.message",
"unsigned": {
"age": 1232
}
},
{
"content": {
"body": "> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam sed fringilla risus, eget lacinia risus. Suspendisse at magna id justo sagittis suscipit. Maecenas eros quam, pulvinar a consequat sed, varius vitae risus. Cras congue est eget felis porttitor lobortis. Nam cursus, nulla ut finibus suscipit, tellus eros tincidunt ante, a volutpat velit lectus sit amet turpis. Morbi leo justo, fringilla sed rutrum a, suscipit a quam. Proin rhoncus neque eget ligula ullamcorper pellentesque. Mauris volutpat malesuada nunc. Nullam finibus enim eu nibh placerat imperdiet. Nullam in mi in diam luctus scelerisque dignissim non erat. ",
"format": "org.matrix.custom.html",
"formatted_body": "<blockquote>\n<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam sed fringilla risus, eget lacinia risus. Suspendisse at magna id justo sagittis suscipit. Maecenas eros quam, pulvinar a consequat sed, varius vitae risus. Cras congue est eget felis porttitor lobortis. Nam cursus, nulla ut finibus suscipit, tellus eros tincidunt ante, a volutpat velit lectus sit amet turpis. Morbi leo justo, fringilla sed rutrum a, suscipit a quam. Proin rhoncus neque eget ligula ullamcorper pellentesque. Mauris volutpat malesuada nunc. Nullam finibus enim eu nibh placerat imperdiet. Nullam in mi in diam luctus scelerisque dignissim non erat.</p>\n</blockquote>",
"msgtype": "m.text"
},
"event_id": "$1000000000023:example.org",
"origin_server_ts": 1000000000023,
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
"sender": "@example:example.org",
"type": "m.room.message",
"unsigned": {
"age": 1232
}
}
],
"limited": true,
"prev_batch": "t34-23535_0_0"
}
}

View File

@@ -1,36 +0,0 @@
// 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 "memtesttimelinemodel.h"
#include <Quotient/events/eventcontent.h>
#include <Quotient/events/roommessageevent.h>
using namespace Quotient;
MemTestTimelineModel::MemTestTimelineModel(QObject *parent)
: MessageModel(parent)
{
beginResetModel();
m_connection = Connection::makeMockConnection(u"@bob:example.org"_s);
m_room = new MemTestRoom(m_connection, u"#memtestroom:example.org"_s, u"memtest-sync.json"_s);
for (const auto &eventIt : m_room->messageEvents()) {
Q_EMIT newEventAdded(eventIt.event());
}
endResetModel();
}
std::optional<std::reference_wrapper<const RoomEvent>> MemTestTimelineModel::getEventForIndex(QModelIndex index) const
{
return *m_room->messageEvents().at(index.row()).event();
}
int MemTestTimelineModel::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent);
return m_room->messageEvents().size();
}
#include "moc_memtesttimelinemodel.cpp"

View File

@@ -1,75 +0,0 @@
// 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 <QAbstractListModel>
#include <QQmlEngine>
#include <Quotient/events/roomevent.h>
#include <Quotient/syncdata.h>
#include "models/messagemodel.h"
namespace Quotient
{
class Connection;
}
class NeoChatRoom;
class MemTestRoom : public NeoChatRoom
{
public:
MemTestRoom(Quotient::Connection *connection, const QString &roomName, const QString &syncFileName = {})
: NeoChatRoom(connection, roomName, Quotient::JoinState::Join)
{
syncNewEvents(syncFileName);
}
void update(Quotient::SyncRoomData &&data, bool fromCache = false)
{
Room::updateData(std::move(data), fromCache);
}
void syncNewEvents(const QString &syncFileName)
{
if (!syncFileName.isEmpty()) {
QFile testSyncFile;
testSyncFile.setFileName(QStringLiteral(DATA_DIR) + u'/' + syncFileName);
testSyncFile.open(QIODevice::ReadOnly);
auto testSyncJson = QJsonDocument::fromJson(testSyncFile.readAll()).object();
Quotient::SyncRoomData roomData(id(), Quotient::JoinState::Join, testSyncJson);
update(std::move(roomData));
}
}
};
/**
* @class MemTestTimelineModel
*
* This is a special version of the MessageModel design to load an unchanging set
* of events from a json file so that timeline memory optimisations can be measured.
*/
class MemTestTimelineModel : public MessageModel
{
Q_OBJECT
QML_ELEMENT
public:
explicit MemTestTimelineModel(QObject *parent = nullptr);
/**
* @brief Number of rows in the model.
*
* @sa QAbstractItemModel::rowCount
*/
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
private:
QPointer<Quotient::Connection> m_connection;
std::vector<Quotient::RoomEventPtr> m_events;
std::optional<std::reference_wrapper<const Quotient::RoomEvent>> getEventForIndex(QModelIndex index) const override;
};

View File

@@ -26,7 +26,6 @@
<name xml:lang="fr">NeoChat</name> <name xml:lang="fr">NeoChat</name>
<name xml:lang="gl">NeoChat</name> <name xml:lang="gl">NeoChat</name>
<name xml:lang="he">NeoChat</name> <name xml:lang="he">NeoChat</name>
<name xml:lang="hi">नियोचैट</name>
<name xml:lang="hu">NeoChat</name> <name xml:lang="hu">NeoChat</name>
<name xml:lang="ia">Neochat</name> <name xml:lang="ia">Neochat</name>
<name xml:lang="id">NeoChat</name> <name xml:lang="id">NeoChat</name>
@@ -42,7 +41,6 @@
<name xml:lang="pt">NeoChat</name> <name xml:lang="pt">NeoChat</name>
<name xml:lang="pt-BR">NeoChat</name> <name xml:lang="pt-BR">NeoChat</name>
<name xml:lang="ru">NeoChat</name> <name xml:lang="ru">NeoChat</name>
<name xml:lang="sa">नवचैट्</name>
<name xml:lang="sk">NeoChat</name> <name xml:lang="sk">NeoChat</name>
<name xml:lang="sl">NeoChat</name> <name xml:lang="sl">NeoChat</name>
<name xml:lang="sv">NeoChat</name> <name xml:lang="sv">NeoChat</name>
@@ -58,25 +56,20 @@
<summary xml:lang="ca-valencia">Xat a Matrix</summary> <summary xml:lang="ca-valencia">Xat a Matrix</summary>
<summary xml:lang="de">Über Matrix unterhalten</summary> <summary xml:lang="de">Über Matrix unterhalten</summary>
<summary xml:lang="en-GB">Chat on Matrix</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="es">Charle en Matrix</summary>
<summary xml:lang="eu">Berriketa Matrix-en</summary> <summary xml:lang="eu">Berriketa Matrix-en</summary>
<summary xml:lang="fi">Keskustelu Matrixissä</summary> <summary xml:lang="fi">Keskustelu Matrixissä</summary>
<summary xml:lang="fr">Discuter sur Matrix</summary> <summary xml:lang="fr">Discuter sur Matrix</summary>
<summary xml:lang="gl">Charlar en Matrix</summary> <summary xml:lang="gl">Charlar en Matrix</summary>
<summary xml:lang="he">התכתבות דרך Matrix</summary> <summary xml:lang="he">התכתבות דרך Matrix</summary>
<summary xml:lang="hi">मैट्रिक्स पर चैट करें</summary>
<summary xml:lang="hu">Csevegés Matrixon</summary> <summary xml:lang="hu">Csevegés Matrixon</summary>
<summary xml:lang="ia">Conversation en ditecto sur Matrix</summary> <summary xml:lang="ia">Conversation en ditecto sur Matrix</summary>
<summary xml:lang="it">Chat su Matrix</summary> <summary xml:lang="it">Chat su Matrix</summary>
<summary xml:lang="ka">ისაუბრეთ Matrix-ზე</summary> <summary xml:lang="ka">ისაუბრეთ Matrix-ზე</summary>
<summary xml:lang="ko">Matrix에서 대화하기</summary>
<summary xml:lang="lv">Tērzējiet „Matrix“ tīklā</summary> <summary xml:lang="lv">Tērzējiet „Matrix“ tīklā</summary>
<summary xml:lang="nl">Chat op Matrix</summary> <summary xml:lang="nl">Chat op Matrix</summary>
<summary xml:lang="nn">Prat med via Matrix</summary> <summary xml:lang="nn">Prat med via Matrix</summary>
<summary xml:lang="pl">Rozmawiaj na Matriksie</summary> <summary xml:lang="pl">Rozmawiaj na Matriksie</summary>
<summary xml:lang="ru">Общение в Matrix</summary>
<summary xml:lang="sa">Matrix इत्यत्र गपशपं कुर्वन्तु</summary>
<summary xml:lang="sl">Klepet na Matrixu</summary> <summary xml:lang="sl">Klepet na Matrixu</summary>
<summary xml:lang="sv">Chatta på Matrix</summary> <summary xml:lang="sv">Chatta på Matrix</summary>
<summary xml:lang="ta">மேட்ரிக்ஸுக்கான உரையாடல் செயலி</summary> <summary xml:lang="ta">மேட்ரிக்ஸுக்கான உரையாடல் செயலி</summary>
@@ -99,18 +92,15 @@
<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="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="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="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="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="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> <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>
<p xml:lang="ka">NeoChat ჩატის აპია, რომელიც საშუალება გაძლევთ, Matrix-ის ქსელის საშუალებები ბოლომდე გამოიყენოთ. ის გაძლევთ უსაფრთხო გზას, გააგზავნოთ ტექსტური შეტყობინებები, ვიდეოებ და აუდიოფაილები თქვენს ოჯახთან, კოლეგებთან და მეგობრებთან.</p> <p xml:lang="ka">NeoChat ჩატის აპია, რომელიც საშუალება გაძლევთ, Matrix-ის ქსელის საშუალებები ბოლომდე გამოიყენოთ. ის გაძლევთ უსაფრთხო გზას, გააგზავნოთ ტექსტური შეტყობინებები, ვიდეოებ და აუდიოფაილები თქვენს ოჯახთან, კოლეგებთან და მეგობრებთან.</p>
<p xml:lang="ko">NeoChat은 Matrix 네트워크를 사용하는 채팅 앱입니다. 텍스트 메시지, 동영상, 오디오 파일을 가족, 친구, 동료와 안전하게 공유할 수 있습니다.</p>
<p xml:lang="lv">„NeoChat“ ir tērzēšanas programma, kas ļauj pilnvērtīgi izmantot „Matrix“ tīklu. Tā sniedz drošu veidu teksta ziņu, video un audio sūtīšanai ģimenes locekļiem, kolēģiem un draugiem.</p> <p xml:lang="lv">„NeoChat“ ir tērzēšanas programma, kas ļauj pilnvērtīgi izmantot „Matrix“ tīklu. Tā sniedz drošu veidu teksta ziņu, video un audio sūtīšanai ģimenes locekļiem, kolēģiem un draugiem.</p>
<p xml:lang="nl">NeoChat is een chat-toepassing die u het volledige voordeel van het Matrix-netwerk laat genieten. Het levert u op een veilige manier tekstberichten, video's en geluidsbestanden naar uw familie, collega's en vrienden te verzenden.</p> <p xml:lang="nl">NeoChat is een chat-toepassing die u het volledige voordeel van het Matrix-netwerk laat genieten. Het levert u op een veilige manier tekstberichten, video's en geluidsbestanden naar uw familie, collega's en vrienden te verzenden.</p>
<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="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="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="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="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="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> <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>
@@ -129,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="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="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="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="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="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="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> <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>
@@ -143,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="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="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="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="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="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 Şifrelemenin 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> <p xml:lang="tr">NeoChat, Matrix belirtimi için tam özellikli bir uygulama olmayı hedefler. Bu nedenle; VoIP, ileti zincirleri ve Uçtan Uca Şifrelemenin 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>
@@ -164,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="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="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="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="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="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> <p xml:lang="it">A causa della natura dello sviluppo delle specifiche Matrix, NeoChat supporta anche numerose funzionalità instabili. Attualmente queste sono:</p>
@@ -176,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="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="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="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="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="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> <p xml:lang="ta">மேட்ரிக்ஸு நெறிமுறை வரையறுக்கப்படும் வித‍த்தின் காரணமாக, பல நிலையற்ற அம்சங்களையும் நியோச்சாட் ஆதரிக்கிறது. தற்போது ஆதரிக்கப்படுபவை:</p>
@@ -198,7 +184,6 @@
<li xml:lang="fr">Sondages - MSC3381</li> <li xml:lang="fr">Sondages - MSC3381</li>
<li xml:lang="gl">Enquisas — MSC3381</li> <li xml:lang="gl">Enquisas — MSC3381</li>
<li xml:lang="he">סקרים - 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="hu">Szavazások - MSC3381</li>
<li xml:lang="ia">Inquestas - MSC3381</li> <li xml:lang="ia">Inquestas - MSC3381</li>
<li xml:lang="it">Sondaggi - MSC3381</li> <li xml:lang="it">Sondaggi - MSC3381</li>
@@ -210,7 +195,6 @@
<li xml:lang="pl">Ankiety - MSC3381</li> <li xml:lang="pl">Ankiety - MSC3381</li>
<li xml:lang="pt">Inquéritos - MSC3381</li> <li xml:lang="pt">Inquéritos - MSC3381</li>
<li xml:lang="ru">Голосования — MSC3381</li> <li xml:lang="ru">Голосования — MSC3381</li>
<li xml:lang="sa">मतदान - MSC3381</li>
<li xml:lang="sl">Polls - MSC3381</li> <li xml:lang="sl">Polls - MSC3381</li>
<li xml:lang="sv">Polls - MSC3381</li> <li xml:lang="sv">Polls - MSC3381</li>
<li xml:lang="ta">வாக்கெடுப்புகள் - MSC3381</li> <li xml:lang="ta">வாக்கெடுப்புகள் - MSC3381</li>
@@ -231,7 +215,6 @@
<li xml:lang="fr">Paquets d'auto-collants - MSC2545</li> <li xml:lang="fr">Paquets d'auto-collants - MSC2545</li>
<li xml:lang="gl">Paquetes de adhesivos — MSC2545</li> <li xml:lang="gl">Paquetes de adhesivos — MSC2545</li>
<li xml:lang="he">חבילות מדבקות - MSC2545</li> <li xml:lang="he">חבילות מדבקות - MSC2545</li>
<li xml:lang="hi">स्टिकर पैक - MSC2545</li>
<li xml:lang="hu">Matricacsomagok - MSC2545</li> <li xml:lang="hu">Matricacsomagok - MSC2545</li>
<li xml:lang="ia">Etiquetta gummate (sticker) -MSC2545</li> <li xml:lang="ia">Etiquetta gummate (sticker) -MSC2545</li>
<li xml:lang="it">Pacchetti di adesivi - MSC2545</li> <li xml:lang="it">Pacchetti di adesivi - MSC2545</li>
@@ -243,7 +226,6 @@
<li xml:lang="pl">Paczki naklejek - MSC2545</li> <li xml:lang="pl">Paczki naklejek - MSC2545</li>
<li xml:lang="pt">Pacotes de Autocolantes - MSC2545</li> <li xml:lang="pt">Pacotes de Autocolantes - MSC2545</li>
<li xml:lang="ru">Наборы стикеров — 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="sl">Sticker Packs - MSC2545</li>
<li xml:lang="sv">Sticker Packs - MSC2545</li> <li xml:lang="sv">Sticker Packs - MSC2545</li>
<li xml:lang="ta">ஒட்டி தொகுப்புகள் - MSC2545</li> <li xml:lang="ta">ஒட்டி தொகுப்புகள் - MSC2545</li>
@@ -264,7 +246,6 @@
<li xml:lang="fr">Événements de lieu - MSC3488</li> <li xml:lang="fr">Événements de lieu - MSC3488</li>
<li xml:lang="gl">Localización de eventos — MSC3488</li> <li xml:lang="gl">Localización de eventos — MSC3488</li>
<li xml:lang="he">אירועי מקום - 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="hu">Események helyadatai - MSC3488</li>
<li xml:lang="ia">Eventos de Location - MSC3488</li> <li xml:lang="ia">Eventos de Location - MSC3488</li>
<li xml:lang="it">Località eventi - MSC3488</li> <li xml:lang="it">Località eventi - MSC3488</li>
@@ -276,7 +257,6 @@
<li xml:lang="pl">Wydarzenia w miejscach - MSC3488</li> <li xml:lang="pl">Wydarzenia w miejscach - MSC3488</li>
<li xml:lang="pt">Eventos com Localizações - MSC3488</li> <li xml:lang="pt">Eventos com Localizações - MSC3488</li>
<li xml:lang="ru">События местоположения — 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="sl">Location Events - MSC3488</li>
<li xml:lang="sv">Location Events - MSC3488</li> <li xml:lang="sv">Location Events - MSC3488</li>
<li xml:lang="ta">இட நிகழ்வுகள் - MSC3488</li> <li xml:lang="ta">இட நிகழ்வுகள் - MSC3488</li>
@@ -333,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="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="gl">Vista principal coa lista de salas, a charla, e información da sala.</caption>
<caption xml:lang="he">תצוגה ראשית עם רשימת חדרים, צ׳אט ופרטי חדר</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="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="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> <caption xml:lang="it">Vista principale con elenco delle stanze, chat e informazioni sulla stanza</caption>
@@ -345,7 +324,6 @@
<caption xml:lang="pl">Główny widok z wykazem pokojów, rozmowami i szczegółami pokojów</caption> <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="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="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="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="sv">Huvudvy med rumslista, chatt, och rumsinformation</caption>
<caption xml:lang="ta">அரங்குப்பட்டியல், உரையாடல், மற்றும் அரங்குவிவரங்களைக் கொண்டுள்ள பிரதான காட்சி</caption> <caption xml:lang="ta">அரங்குப்பட்டியல், உரையாடல், மற்றும் அரங்குவிவரங்களைக் கொண்டுள்ள பிரதான காட்சி</caption>
@@ -370,18 +348,15 @@
<caption xml:lang="fr">Découvrez de nouvelles communautés avec les espaces sous Matrix</caption> <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="gl">Descubra novas comunidades dos espazos de Matrix.</caption>
<caption xml:lang="he">אפשר להיחשף לקהילות חדשות דרך Matrix Spaces</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="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="ia">Discoperi nove communitate con Matrix Spaces (Spatios de Matrix)</caption>
<caption xml:lang="it">Scopri nuove comunità con Matrix Spaces</caption> <caption xml:lang="it">Scopri nuove comunità con Matrix Spaces</caption>
<caption xml:lang="ka">აღმოაჩინეთ ახალი საზოგადოებები Matrix Spaces-თან ერთად</caption> <caption xml:lang="ka">აღმოაჩინეთ ახალი საზოგადოებები Matrix Spaces-თან ერთად</caption>
<caption xml:lang="ko">Matrix 스페이스에서 새로운 커뮤니티 탐험</caption>
<caption xml:lang="lv">Atklājiet jaunas kopienas ar „Matrix“ telpām</caption> <caption xml:lang="lv">Atklājiet jaunas kopienas ar „Matrix“ telpām</caption>
<caption xml:lang="nl">Ontdek nieuwe gemeenschappen met Matrix-ruimten</caption> <caption xml:lang="nl">Ontdek nieuwe gemeenschappen met Matrix-ruimten</caption>
<caption xml:lang="nn">Oppdag nye fellesskap med Matrix Spaces</caption> <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="pl">Odkrywaj nowe społeczności w Przestrzeniach Matriksa</caption>
<caption xml:lang="ru">Поиск новых сообществ с помощью Matrix Spaces</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="sl">Odkrijte nove skupnosti z Matrix Spaces</caption>
<caption xml:lang="sv">Upptäck nya gemenskaper med Matrix Spaces</caption> <caption xml:lang="sv">Upptäck nya gemenskaper med Matrix Spaces</caption>
<caption xml:lang="ta">மேட்ரிக்ஸு இடங்களின் மூலம் புதிய சமூகங்களைக் கண்டுபிடிக்கலாம்</caption> <caption xml:lang="ta">மேட்ரிக்ஸு இடங்களின் மூலம் புதிய சமூகங்களைக் கண்டுபிடிக்கலாம்</caption>
@@ -413,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="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="gl">Vista principal coa lista de salas, a charla, e información da sala.</caption>
<caption xml:lang="he">תצוגה ראשית עם רשימת חדרים, צ׳אט ופרטי חדר</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="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="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> <caption xml:lang="it">Vista principale con elenco delle stanze, chat e informazioni sulla stanza</caption>
@@ -425,7 +399,6 @@
<caption xml:lang="pl">Główny widok z wykazem pokojów, rozmowami i szczegółami pokojów</caption> <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="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="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="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="sv">Huvudvy med rumslista, chatt, och rumsinformation</caption>
<caption xml:lang="ta">அரங்குப்பட்டியல், உரையாடல், மற்றும் அரங்குவிவரங்களைக் கொண்டுள்ள பிரதான காட்சி</caption> <caption xml:lang="ta">அரங்குப்பட்டியல், உரையாடல், மற்றும் அரங்குவிவரங்களைக் கொண்டுள்ள பிரதான காட்சி</caption>
@@ -451,7 +424,6 @@
<caption xml:lang="fr">Écran de connexion</caption> <caption xml:lang="fr">Écran de connexion</caption>
<caption xml:lang="gl">Pantalla de identificación.</caption> <caption xml:lang="gl">Pantalla de identificación.</caption>
<caption xml:lang="he">מסך כניסה</caption> <caption xml:lang="he">מסך כניסה</caption>
<caption xml:lang="hi">लॉगिन स्क्रीन</caption>
<caption xml:lang="hu">Bejelentkező képernyő</caption> <caption xml:lang="hu">Bejelentkező képernyő</caption>
<caption xml:lang="ia">Schermo de accesso</caption> <caption xml:lang="ia">Schermo de accesso</caption>
<caption xml:lang="it">Schermata di accesso</caption> <caption xml:lang="it">Schermata di accesso</caption>
@@ -463,7 +435,6 @@
<caption xml:lang="pl">Ekran logowania</caption> <caption xml:lang="pl">Ekran logowania</caption>
<caption xml:lang="pt">Ecrã de autenticação</caption> <caption xml:lang="pt">Ecrã de autenticação</caption>
<caption xml:lang="ru">Окно входа</caption> <caption xml:lang="ru">Окно входа</caption>
<caption xml:lang="sa">लॉगिन् स्क्रीन</caption>
<caption xml:lang="sl">Prijavni zaslon</caption> <caption xml:lang="sl">Prijavni zaslon</caption>
<caption xml:lang="sv">Inloggningsfönster</caption> <caption xml:lang="sv">Inloggningsfönster</caption>
<caption xml:lang="ta">நுழைவுத் திரை</caption> <caption xml:lang="ta">நுழைவுத் திரை</caption>
@@ -477,11 +448,6 @@
<content_attribute id="social-chat">intense</content_attribute> <content_attribute id="social-chat">intense</content_attribute>
</content_rating> </content_rating>
<releases> <releases>
<release version="25.04.1" date="2025-05-08"/>
<release version="25.04.0" date="2025-04-17"/>
<release version="24.12.3" date="2025-03-06"/>
<release version="24.12.2" date="2025-02-06"/>
<release version="24.12.1" date="2025-01-09"/>
<release version="24.12.0" date="2024-12-12"/> <release version="24.12.0" date="2024-12-12"/>
<release version="24.08.3" date="2024-11-07"/> <release version="24.08.3" date="2024-11-07"/>
<release version="24.08.2" date="2024-10-10"/> <release version="24.08.2" date="2024-10-10"/>
@@ -657,9 +623,6 @@
<url>https://carlschwan.eu/2020/12/23/announcing-neochat-1.0-the-kde-matrix-client/</url> <url>https://carlschwan.eu/2020/12/23/announcing-neochat-1.0-the-kde-matrix-client/</url>
</release> </release>
</releases> </releases>
<requires>
<display_length compare="ge">360</display_length>
</requires>
<branding> <branding>
<color type="primary" scheme_preference="light">#a6e4f3</color> <color type="primary" scheme_preference="light">#a6e4f3</color>
<color type="primary" scheme_preference="dark">#235670</color> <color type="primary" scheme_preference="dark">#235670</color>

View File

@@ -19,7 +19,6 @@ Name[fi]=NeoChat
Name[fr]=NeoChat Name[fr]=NeoChat
Name[gl]=NeoChat Name[gl]=NeoChat
Name[he]=NeoChat Name[he]=NeoChat
Name[hi]=नियोचैट
Name[hu]=NeoChat Name[hu]=NeoChat
Name[ia]=Neochat Name[ia]=Neochat
Name[id]=NeoChat Name[id]=NeoChat
@@ -37,7 +36,6 @@ Name[pt]=NeoChat
Name[pt_BR]=NeoChat Name[pt_BR]=NeoChat
Name[ro]=NeoChat Name[ro]=NeoChat
Name[ru]=NeoChat Name[ru]=NeoChat
Name[sa]=नवचैट्
Name[sk]=NeoChat Name[sk]=NeoChat
Name[sl]=NeoChat Name[sl]=NeoChat
Name[sv]=NeoChat Name[sv]=NeoChat
@@ -63,7 +61,6 @@ GenericName[fi]=Matrix-asiakas
GenericName[fr]=Client « Matrix » GenericName[fr]=Client « Matrix »
GenericName[gl]=Cliente de Matrix GenericName[gl]=Cliente de Matrix
GenericName[he]=לקוח Matrix GenericName[he]=לקוח Matrix
GenericName[hi]=मैट्रिक्स क्लाइंट
GenericName[hu]=Matrix kliens GenericName[hu]=Matrix kliens
GenericName[ia]=Cliente de Matrice GenericName[ia]=Cliente de Matrice
GenericName[id]=Klien Matrix GenericName[id]=Klien Matrix
@@ -81,7 +78,6 @@ GenericName[pt]=Cliente de Matrix
GenericName[pt_BR]=Cliente Matrix GenericName[pt_BR]=Cliente Matrix
GenericName[ro]=Client Matrix GenericName[ro]=Client Matrix
GenericName[ru]=Клиент Matrix GenericName[ru]=Клиент Matrix
GenericName[sa]=मैट्रिक्स क्लाइंट
GenericName[sk]=Matrix Client GenericName[sk]=Matrix Client
GenericName[sl]=Odjemalec Matrix GenericName[sl]=Odjemalec Matrix
GenericName[sv]=Matrix-klient GenericName[sv]=Matrix-klient
@@ -97,32 +93,25 @@ Comment[ca]=Xat a Matrix
Comment[ca@valencia]=Xat a Matrix Comment[ca@valencia]=Xat a Matrix
Comment[de]=Über Matrix unterhalten Comment[de]=Über Matrix unterhalten
Comment[en_GB]=Chat on Matrix Comment[en_GB]=Chat on Matrix
Comment[eo]=Babilo en Matrix
Comment[es]=Chat en Matrix Comment[es]=Chat en Matrix
Comment[eu]=Berriketa Matrix-en Comment[eu]=Berriketa Matrix-en
Comment[fi]=Keskustele Matrixissä Comment[fi]=Keskustele Matrixissä
Comment[fr]=Clavarder sur Matrix Comment[fr]=Clavarder sur Matrix
Comment[gl]=Charle en Matrix Comment[gl]=Charle en Matrix
Comment[he]=התכתבות דרך Matrix Comment[he]=התכתבות דרך Matrix
Comment[hi]=मैट्रिक्स पर चैट करें
Comment[hu]=Csevegés Matrixon Comment[hu]=Csevegés Matrixon
Comment[ia]=Conversation en ditecto sur Matrix Comment[ia]=Conversation en ditecto sur Matrix
Comment[it]= su Matrix Comment[it]= su Matrix
Comment[ka]=ჩატი Matrix-ზე Comment[ka]=ჩატი Matrix-ზე
Comment[ko]=Matrix에서 대화하기
Comment[lv]=Tērzējiet „Matrix“ tīklā Comment[lv]=Tērzējiet „Matrix“ tīklā
Comment[nl]=Chat op Matrix Comment[nl]=Chat op Matrix
Comment[pl]=Rozmawiaj na Matriksie Comment[pl]=Rozmawiaj na Matriksie
Comment[pt_BR]=Bate papo na Matrix
Comment[ru]=Общение в Matrix
Comment[sa]=Matrix इत्यत्र गपशपं कुर्वन्तु
Comment[sl]=Klepet na Matrixu Comment[sl]=Klepet na Matrixu
Comment[sv]=Chatta på Matrix Comment[sv]=Chatta på Matrix
Comment[ta]=மேட்ரிக்ஸில் உரையாட உதவும் Comment[ta]=மேட்ரிக்ஸில் உரையாட உதவும்
Comment[tr]=Matrix üzerinde sohbet edin Comment[tr]=Matrix Üzerinde Sohbet Et
Comment[uk]=Спілкування у Matrix Comment[uk]=Спілкування у Matrix
Comment[x-test]=xxChat on Matrixxx Comment[x-test]=xxChat on Matrixxx
Comment[zh_CN]=在 Matrix 上聊天
Comment[zh_TW]=在 Matrix 上聊天 Comment[zh_TW]=在 Matrix 上聊天
MimeType=x-scheme-handler/matrix; MimeType=x-scheme-handler/matrix;
Exec=neochat %u Exec=neochat %u

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

View File

@@ -1,9 +1,9 @@
# SPDX-FileCopyrightText: 2024-2025 Scarlett Moore <sgmoore@kde.org> # SPDX-FileCopyrightText: 2024 Scarlett Moore <sgmoore@kde.org>
# #
# SPDX-License-Identifier: CC0-1.0 # SPDX-License-Identifier: CC0-1.0
--- ---
name: neochat name: neochat
base: core24 base: core22
adopt-info: neochat adopt-info: neochat
grade: stable grade: stable
confinement: strict confinement: strict
@@ -24,16 +24,9 @@ apps:
- network-manager-observe - network-manager-observe
- password-manager-service - password-manager-service
- accounts-service - accounts-service
environment:
QT_PLUGIN_PATH: "$SNAP/usr/lib/$CRAFT_ARCH_TRIPLET/plugins/snap/kf6-core24/current/usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/plugins"
QML_IMPORT_PATH: "$SNAP/usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/qml:/snap/kf6-core24/current/usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/qml"
compression: lzo compression: lzo
package-repositories:
- type: apt
ppa: ubuntu-toolchain-r/test
slots: slots:
session-dbus-interface: session-dbus-interface:
interface: dbus interface: dbus
@@ -44,12 +37,11 @@ parts:
olm: olm:
source: https://gitlab.matrix.org/matrix-org/olm.git source: https://gitlab.matrix.org/matrix-org/olm.git
source-depth: 1 source-depth: 1
source-tag: '3.2.16' source-tag: '3.2.12'
plugin: cmake plugin: cmake
cmake-parameters: cmake-parameters:
- -DCMAKE_BUILD_TYPE=Release - -DCMAKE_BUILD_TYPE=Release
- -DCMAKE_INSTALL_PREFIX=/usr - -DCMAKE_INSTALL_PREFIX=/usr
- -DCMAKE_POLICY_VERSION_MINIMUM=3.5
prime: prime:
- -usr/include - -usr/include
- -usr/lib/*/pkgconfig - -usr/lib/*/pkgconfig
@@ -84,8 +76,7 @@ parts:
source-depth: 1 source-depth: 1
plugin: cmake plugin: cmake
build-environment: build-environment:
- PATH: /snap/bin:${PATH} - PKG_CONFIG_PATH: $CRAFT_STAGE/usr/lib/$CRAFT_ARCH_TRIPLET/pkgconfig:$PKG_CONFIG_PATH
- PKG_CONFIG_PATH: "$CRAFT_STAGE/usr/lib/$CRAFT_ARCH_TRIPLET/pkgconfig:$PKG_CONFIG_PATH"
cmake-parameters: cmake-parameters:
- -DCMAKE_INSTALL_PREFIX=/usr - -DCMAKE_INSTALL_PREFIX=/usr
- -DCMAKE_BUILD_TYPE=Release - -DCMAKE_BUILD_TYPE=Release
@@ -104,10 +95,6 @@ parts:
source-tag: 0.9.1 source-tag: 0.9.1
source-depth: 1 source-depth: 1
plugin: cmake plugin: cmake
build-environment:
- PATH: /snap/bin:${PATH}
build-snaps:
- cmake
build-packages: build-packages:
- libssl-dev - libssl-dev
cmake-parameters: cmake-parameters:
@@ -126,10 +113,6 @@ parts:
source-tag: 'v0.3.0' source-tag: 'v0.3.0'
source-depth: 1 source-depth: 1
plugin: cmake plugin: cmake
build-environment:
- PATH: /snap/bin:${PATH}
- PYTHONPATH: ${CRAFT_STAGE}/lib/python3.12/site-packages:${CRAFT_STAGE}/usr/lib/python3/dist-packages
- LD_LIBRARY_PATH: "/snap/mesa-2404/current/usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR:$CRAFT_STAGE/usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR:/snap/kde-qt6-core24-sdk/current/usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libproxy:$LD_LIBRARY_PATH"
cmake-parameters: cmake-parameters:
- -DCMAKE_INSTALL_PREFIX=/usr - -DCMAKE_INSTALL_PREFIX=/usr
- -DCMAKE_BUILD_TYPE=Release - -DCMAKE_BUILD_TYPE=Release
@@ -140,32 +123,16 @@ parts:
- -usr/lib/*/pkgconfig - -usr/lib/*/pkgconfig
- -usr/lib/*/cmake - -usr/lib/*/cmake
kunifiedpush:
source: https://invent.kde.org/libraries/kunifiedpush.git
plugin: cmake
build-environment:
- PATH: /snap/bin:${PATH}
- PYTHONPATH: ${CRAFT_STAGE}/lib/python3.12/site-packages:${CRAFT_STAGE}/usr/lib/python3/dist-packages
- LD_LIBRARY_PATH: "/snap/mesa-2404/current/usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR:$CRAFT_STAGE/usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR:/snap/kde-qt6-core24-sdk/current/usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libproxy:$LD_LIBRARY_PATH"
cmake-parameters:
- -DCMAKE_INSTALL_PREFIX=/usr
- -DCMAKE_BUILD_TYPE=Release
- -DBUILD_TESTING=OFF
neochat: neochat:
after: after:
- qtkeychain - qtkeychain
- libquotient - libquotient
- kquickimageeditor - kquickimageeditor
- kunifiedpush
parse-info: parse-info:
- usr/share/metainfo/org.kde.neochat.appdata.xml - usr/share/metainfo/org.kde.neochat.appdata.xml
source: . source: https://invent.kde.org/network/neochat.git
source-tag: 'v24.08.1'
plugin: cmake plugin: cmake
build-environment:
- PATH: /snap/bin:${PATH}
- PYTHONPATH: ${CRAFT_STAGE}/lib/python3.12/site-packages:${CRAFT_STAGE}/usr/lib/python3/dist-packages
- LD_LIBRARY_PATH: "/snap/mesa-2404/current/usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR:$CRAFT_STAGE/usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR:/snap/kde-qt6-core24-sdk/current/usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libproxy:$LD_LIBRARY_PATH"
build-packages: build-packages:
- cmark - cmark
- libcmark-dev - libcmark-dev
@@ -189,12 +156,3 @@ parts:
prime: prime:
- usr/lib/*/libcmark.so* - usr/lib/*/libcmark.so*
gpu-2404:
after: [neochat]
source: https://github.com/canonical/gpu-snap.git
plugin: dump
override-prime: |
craftctl default
${CRAFT_PART_SRC}/bin/gpu-2404-cleanup mesa-2404
prime:
- bin/gpu-2404-wrapper

View File

@@ -18,8 +18,8 @@ add_library(neochat STATIC
models/customemojimodel.h models/customemojimodel.h
clipboard.cpp clipboard.cpp
clipboard.h clipboard.h
models/timelinemessagemodel.cpp models/messageeventmodel.cpp
models/timelinemessagemodel.h models/messageeventmodel.h
models/messagefiltermodel.cpp models/messagefiltermodel.cpp
models/messagefiltermodel.h models/messagefiltermodel.h
models/roomlistmodel.cpp models/roomlistmodel.cpp
@@ -107,6 +107,8 @@ add_library(neochat STATIC
models/imagepacksmodel.h models/imagepacksmodel.h
events/imagepackevent.cpp events/imagepackevent.cpp
events/imagepackevent.h events/imagepackevent.h
events/joinrulesevent.cpp
events/joinrulesevent.h
models/reactionmodel.cpp models/reactionmodel.cpp
models/reactionmodel.h models/reactionmodel.h
delegatesizehelper.cpp delegatesizehelper.cpp
@@ -124,6 +126,12 @@ add_library(neochat STATIC
registration.cpp registration.cpp
neochatconnection.cpp neochatconnection.cpp
neochatconnection.h 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.cpp
jobs/neochatgetcommonroomsjob.h jobs/neochatgetcommonroomsjob.h
mediasizehelper.cpp mediasizehelper.cpp
@@ -168,6 +176,8 @@ add_library(neochat STATIC
models/threepidmodel.h models/threepidmodel.h
threepidaddhelper.cpp threepidaddhelper.cpp
threepidaddhelper.h threepidaddhelper.h
jobs/neochatadd3pidjob.cpp
jobs/neochatadd3pidjob.h
identityserverhelper.cpp identityserverhelper.cpp
identityserverhelper.h identityserverhelper.h
enums/powerlevel.cpp enums/powerlevel.cpp
@@ -186,16 +196,6 @@ add_library(neochat STATIC
messagecomponent.h messagecomponent.h
enums/roomsortparameter.cpp enums/roomsortparameter.cpp
enums/roomsortparameter.h enums/roomsortparameter.h
models/roomsortparametermodel.cpp
models/roomsortparametermodel.h
models/messagemodel.cpp
models/messagemodel.h
models/messagecontentfiltermodel.cpp
models/messagecontentfiltermodel.h
models/pinnedmessagemodel.cpp
models/pinnedmessagemodel.h
models/commonroomsmodel.cpp
models/commonroomsmodel.h
) )
set_source_files_properties(qml/OsmLocationPlugin.qml PROPERTIES set_source_files_properties(qml/OsmLocationPlugin.qml PROPERTIES
@@ -215,7 +215,7 @@ ecm_add_qml_module(neochat URI org.kde.neochat GENERATE_PLUGIN_SOURCE
qml/AccountMenu.qml qml/AccountMenu.qml
qml/ExploreComponent.qml qml/ExploreComponent.qml
qml/ExploreComponentMobile.qml qml/ExploreComponentMobile.qml
qml/RoomContextMenu.qml qml/ContextMenu.qml
qml/CollapsedRoomDelegate.qml qml/CollapsedRoomDelegate.qml
qml/RoomDelegate.qml qml/RoomDelegate.qml
qml/RoomListPage.qml qml/RoomListPage.qml
@@ -251,7 +251,6 @@ ecm_add_qml_module(neochat URI org.kde.neochat GENERATE_PLUGIN_SOURCE
qml/MessageSourceSheet.qml qml/MessageSourceSheet.qml
qml/ConfirmEncryptionDialog.qml qml/ConfirmEncryptionDialog.qml
qml/RoomSearchPage.qml qml/RoomSearchPage.qml
qml/RoomPinnedMessagesPage.qml
qml/LocationChooser.qml qml/LocationChooser.qml
qml/TimelineView.qml qml/TimelineView.qml
qml/InvitationView.qml qml/InvitationView.qml
@@ -330,10 +329,10 @@ if(WIN32)
endif() endif()
ecm_qt_declare_logging_category(neochat ecm_qt_declare_logging_category(neochat
HEADER "messagemodel_logging.h" HEADER "messageeventmodel_logging.h"
IDENTIFIER "Message" IDENTIFIER "MessageEvent"
CATEGORY_NAME "org.kde.neochat.messagemodel" CATEGORY_NAME "org.kde.neochat.messageeventmodel"
DESCRIPTION "Neochat: messagemodel" DESCRIPTION "Neochat: messageeventmodel"
DEFAULT_SEVERITY Info DEFAULT_SEVERITY Info
EXPORT NEOCHAT EXPORT NEOCHAT
) )
@@ -421,7 +420,6 @@ target_link_libraries(neochat PUBLIC
KF6::ConfigGui KF6::ConfigGui
KF6::CoreAddons KF6::CoreAddons
KF6::SonnetCore KF6::SonnetCore
KF6::IconThemes
KF6::ColorScheme KF6::ColorScheme
KF6::ItemModels KF6::ItemModels
QuotientQt6 QuotientQt6
@@ -495,7 +493,6 @@ if(ANDROID)
"network-connect" "network-connect"
"list-remove-user" "list-remove-user"
"org.kde.neochat" "org.kde.neochat"
"org.kde.neochat.tray"
"preferences-system-users" "preferences-system-users"
"preferences-desktop-theme-global" "preferences-desktop-theme-global"
"notifications" "notifications"
@@ -533,16 +530,12 @@ if(ANDROID)
"object-rotate-left" "object-rotate-left"
"object-rotate-right" "object-rotate-right"
"add-subtitle" "add-subtitle"
"security-high"
"security-low" "security-low"
"security-low-symbolic" "security-low-symbolic"
"kde" "kde"
"list-remove-symbolic" "list-remove-symbolic"
"edit-delete" "edit-delete"
"user-home-symbolic" "user-home-symbolic"
"pin-symbolic"
"kt-restore-defaults-symbolic"
"user-symbolic"
) )
ecm_add_android_apk(neochat-app ANDROID_DIR ${CMAKE_SOURCE_DIR}/android) ecm_add_android_apk(neochat-app ANDROID_DIR ${CMAKE_SOURCE_DIR}/android)
else() else()

View File

@@ -237,6 +237,20 @@ QQC2.Control {
onFormattingSelected: _private.formatText(format, selectionStart, selectionEnd) onFormattingSelected: _private.formatText(format, selectionStart, selectionEnd)
} }
Keys.onDeletePressed: {
if (selectedText.length > 0) {
remove(selectionStart, selectionEnd);
} else {
remove(cursorPosition, cursorPosition + 1);
}
if (textField.text == selectedText || textField.text.length <= 1) {
root.currentRoom.sendTypingNotification(false);
repeatTimer.stop();
}
if (quickFormatBar.visible) {
quickFormatBar.close();
}
}
Keys.onEnterPressed: event => { Keys.onEnterPressed: event => {
const controlIsPressed = event.modifiers & Qt.ControlModifier; const controlIsPressed = event.modifiers & Qt.ControlModifier;
if (completionMenu.visible) { if (completionMenu.visible) {
@@ -275,7 +289,7 @@ QQC2.Control {
completionMenu.decrementIndex(); completionMenu.decrementIndex();
} else if (event.key === Qt.Key_Down && completionMenu.visible) { } else if (event.key === Qt.Key_Down && completionMenu.visible) {
completionMenu.incrementIndex(); completionMenu.incrementIndex();
} else if (event.key === Qt.Key_Backspace || event.key === Qt.Key_Delete) { } else if (event.key === Qt.Key_Backspace) {
if (textField.text == selectedText || textField.text.length <= 1) { if (textField.text == selectedText || textField.text.length <= 1) {
root.currentRoom.sendTypingNotification(false); root.currentRoom.sendTypingNotification(false);
repeatTimer.stop(); repeatTimer.stop();

View File

@@ -57,7 +57,7 @@ QString ChatBarCache::formatMentions() const
} }
formattedText = formattedText.replace(mention.cursor.anchor(), formattedText = formattedText.replace(mention.cursor.anchor(),
mention.cursor.position() - 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; return formattedText;
@@ -256,7 +256,7 @@ void ChatBarCache::updateMentions(QQuickTextDocument *document, ChatDocumentHand
if (auto event = room->findInTimeline(m_relationId); event != room->historyEdge()) { if (auto event = room->findInTimeline(m_relationId); event != room->historyEdge()) {
if (const auto &roomMessageEvent = &*event->viewAs<Quotient::RoomMessageEvent>()) { if (const auto &roomMessageEvent = &*event->viewAs<Quotient::RoomMessageEvent>()) {
// Replaces the mentions that are baked into the HTML but plaintext in the original markdown // 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(); m_mentions.clear();
@@ -309,7 +309,7 @@ void ChatBarCache::postMessage()
} }
const auto result = ActionsModel::handleAction(room, this); const auto result = ActionsModel::handleAction(room, this);
if (!result.second.has_value()) { if (!result.first.has_value()) {
return; return;
} }
@@ -338,7 +338,8 @@ void ChatBarCache::postMessage()
relatesTo = Quotient::EventRelation::replyTo(replyId()); 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(); clearCache();
} }

View File

@@ -16,8 +16,6 @@
#include "chatdocumenthandler_logging.h" #include "chatdocumenthandler_logging.h"
using namespace Qt::StringLiterals;
class SyntaxHighlighter : public QSyntaxHighlighter class SyntaxHighlighter : public QSyntaxHighlighter
{ {
public: public:
@@ -222,18 +220,15 @@ void ChatDocumentHandler::complete(int index)
return; return;
} }
// Ensure we only search for the beginning of the current completion identifier
const auto fromIndex = qMax(completionStartIndex(), 0);
if (m_completionModel->autoCompletionType() == CompletionModel::User) { if (m_completionModel->autoCompletionType() == CompletionModel::User) {
auto name = m_completionModel->data(m_completionModel->index(index, 0), CompletionModel::DisplayNameRole).toString(); auto name = m_completionModel->data(m_completionModel->index(index, 0), CompletionModel::DisplayNameRole).toString();
auto id = m_completionModel->data(m_completionModel->index(index, 0), CompletionModel::SubtitleRole).toString(); auto id = m_completionModel->data(m_completionModel->index(index, 0), CompletionModel::SubtitleRole).toString();
auto text = getText(); auto text = getText();
auto at = text.indexOf(QLatin1Char('@'), fromIndex); auto at = text.lastIndexOf(QLatin1Char('@'), cursorPosition() - 1);
QTextCursor cursor(document()->textDocument()); QTextCursor cursor(document()->textDocument());
cursor.setPosition(at); cursor.setPosition(at);
cursor.setPosition(cursorPosition(), QTextCursor::KeepAnchor); cursor.setPosition(cursorPosition(), QTextCursor::KeepAnchor);
cursor.insertText(name + u" "_s); cursor.insertText(name + QStringLiteral(" "));
cursor.setPosition(at); cursor.setPosition(at);
cursor.setPosition(cursor.position() + name.size(), QTextCursor::KeepAnchor); cursor.setPosition(cursor.position() + name.size(), QTextCursor::KeepAnchor);
cursor.setKeepPositionOnInsert(true); cursor.setKeepPositionOnInsert(true);
@@ -242,19 +237,19 @@ void ChatDocumentHandler::complete(int index)
} else if (m_completionModel->autoCompletionType() == CompletionModel::Command) { } else if (m_completionModel->autoCompletionType() == CompletionModel::Command) {
auto command = m_completionModel->data(m_completionModel->index(index, 0), CompletionModel::ReplacedTextRole).toString(); auto command = m_completionModel->data(m_completionModel->index(index, 0), CompletionModel::ReplacedTextRole).toString();
auto text = getText(); auto text = getText();
auto at = text.indexOf(QLatin1Char('/'), fromIndex); auto at = text.lastIndexOf(QLatin1Char('/'));
QTextCursor cursor(document()->textDocument()); QTextCursor cursor(document()->textDocument());
cursor.setPosition(at); cursor.setPosition(at);
cursor.setPosition(cursorPosition(), QTextCursor::KeepAnchor); 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) { } else if (m_completionModel->autoCompletionType() == CompletionModel::Room) {
auto alias = m_completionModel->data(m_completionModel->index(index, 0), CompletionModel::SubtitleRole).toString(); auto alias = m_completionModel->data(m_completionModel->index(index, 0), CompletionModel::SubtitleRole).toString();
auto text = getText(); auto text = getText();
auto at = text.indexOf(QLatin1Char('#'), fromIndex); auto at = text.lastIndexOf(QLatin1Char('#'), cursorPosition() - 1);
QTextCursor cursor(document()->textDocument()); QTextCursor cursor(document()->textDocument());
cursor.setPosition(at); cursor.setPosition(at);
cursor.setPosition(cursorPosition(), QTextCursor::KeepAnchor); cursor.setPosition(cursorPosition(), QTextCursor::KeepAnchor);
cursor.insertText(alias + u" "_s); cursor.insertText(alias + QStringLiteral(" "));
cursor.setPosition(at); cursor.setPosition(at);
cursor.setPosition(cursor.position() + alias.size(), QTextCursor::KeepAnchor); cursor.setPosition(cursor.position() + alias.size(), QTextCursor::KeepAnchor);
cursor.setKeepPositionOnInsert(true); cursor.setKeepPositionOnInsert(true);
@@ -263,7 +258,7 @@ void ChatDocumentHandler::complete(int index)
} else if (m_completionModel->autoCompletionType() == CompletionModel::Emoji) { } else if (m_completionModel->autoCompletionType() == CompletionModel::Emoji) {
auto shortcode = m_completionModel->data(m_completionModel->index(index, 0), CompletionModel::ReplacedTextRole).toString(); auto shortcode = m_completionModel->data(m_completionModel->index(index, 0), CompletionModel::ReplacedTextRole).toString();
auto text = getText(); auto text = getText();
auto at = text.indexOf(QLatin1Char(':'), fromIndex); auto at = text.lastIndexOf(QLatin1Char(':'));
QTextCursor cursor(document()->textDocument()); QTextCursor cursor(document()->textDocument());
cursor.setPosition(at); cursor.setPosition(at);
cursor.setPosition(cursorPosition(), QTextCursor::KeepAnchor); cursor.setPosition(cursorPosition(), QTextCursor::KeepAnchor);

View File

@@ -14,8 +14,6 @@
#include <QStandardPaths> #include <QStandardPaths>
#include <QUrl> #include <QUrl>
using namespace Qt::StringLiterals;
Clipboard::Clipboard(QObject *parent) Clipboard::Clipboard(QObject *parent)
: QObject(parent) : QObject(parent)
, m_clipboard(QGuiApplication::clipboard()) , m_clipboard(QGuiApplication::clipboard())
@@ -35,14 +33,14 @@ QImage Clipboard::image() const
QString Clipboard::saveImage(QString localPath) 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)) { if (!QDir().exists(imageDir)) {
QDir().mkdir(imageDir); QDir().mkdir(imageDir);
} }
if (localPath.isEmpty()) { 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); QUrl url(localPath);
if (!url.isLocalFile()) { if (!url.isLocalFile()) {
@@ -63,7 +61,7 @@ QString Clipboard::saveImage(QString localPath) const
void Clipboard::saveText(QString message) void Clipboard::saveText(QString message)
{ {
static QRegularExpression re(u"<[^>]*>"_s); static QRegularExpression re(QStringLiteral("<[^>]*>"));
auto *mimeData = new QMimeData; // ownership is transferred to clipboard auto *mimeData = new QMimeData; // ownership is transferred to clipboard
mimeData->setHtml(message); mimeData->setHtml(message);
mimeData->setText(message.replace(re, QString())); mimeData->setText(message.replace(re, QString()));

View File

@@ -63,7 +63,7 @@ Controller::Controller(QObject *parent)
}); });
} else { } else {
auto c = new NeoChatConnection(this); 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]() { connect(c, &Connection::connected, this, [c, this]() {
m_accountRegistry.add(c); m_accountRegistry.add(c);
c->syncLoop(); c->syncLoop();
@@ -117,7 +117,7 @@ Controller::Controller(QObject *parent)
}); });
#ifdef HAVE_KUNIFIEDPUSH #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) { connect(connector, &KUnifiedPush::Connector::endpointChanged, this, [this](const QString &endpoint) {
m_endpoint = endpoint; m_endpoint = endpoint;
for (auto &quotientConnection : m_accountRegistry) { for (auto &quotientConnection : m_accountRegistry) {
@@ -168,6 +168,7 @@ void Controller::addConnection(NeoChatConnection *c)
connect(c, &NeoChatConnection::syncDone, this, [this, c]() { connect(c, &NeoChatConnection::syncDone, this, [this, c]() {
m_notificationsManager.handleNotifications(c); m_notificationsManager.handleNotifications(c);
}); });
connect(c, &NeoChatConnection::showInviteNotification, &m_notificationsManager, &NotificationsManager::postInviteNotification);
c->sync(); c->sync();
@@ -186,7 +187,7 @@ void Controller::dropConnection(NeoChatConnection *c)
void Controller::invokeLogin() void Controller::invokeLogin()
{ {
const auto accounts = SettingsGroup("Accounts"_L1).childGroups(); const auto accounts = SettingsGroup("Accounts"_ls).childGroups();
for (const auto &accountId : accounts) { for (const auto &accountId : accounts) {
AccountSettings account{accountId}; AccountSettings account{accountId};
m_accountsLoading += accountId; m_accountsLoading += accountId;
@@ -287,14 +288,14 @@ bool Controller::supportSystemTray() const
return false; return false;
#else #else
auto de = QString::fromLatin1(qgetenv("XDG_CURRENT_DESKTOP")); 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 #endif
} }
void Controller::setQuitOnLastWindowClosed() void Controller::setQuitOnLastWindowClosed()
{ {
#ifndef Q_OS_ANDROID #ifndef Q_OS_ANDROID
if (supportSystemTray() && NeoChatConfig::self()->systemTray()) { if (NeoChatConfig::self()->systemTray()) {
m_trayIcon = new TrayIcon(this); m_trayIcon = new TrayIcon(this);
m_trayIcon->show(); m_trayIcon->show();
} else { } else {
@@ -340,7 +341,7 @@ void Controller::setActiveConnection(NeoChatConnection *connection)
void Controller::listenForNotifications() void Controller::listenForNotifications()
{ {
#ifdef HAVE_KUNIFIEDPUSH #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(); auto timer = new QTimer();
connect(timer, &QTimer::timeout, qGuiApp, &QGuiApplication::quit); connect(timer, &QTimer::timeout, qGuiApp, &QGuiApplication::quit);
@@ -369,19 +370,19 @@ void Controller::updateBadgeNotificationCount(NeoChatConnection *connection, int
#if QT_VERSION < QT_VERSION_CHECK(6, 6, 0) #if QT_VERSION < QT_VERSION_CHECK(6, 6, 0)
#ifndef Q_OS_ANDROID #ifndef Q_OS_ANDROID
// copied from Telegram desktop // 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 // Gnome requires that count is a 64bit integer
const qint64 counterSlice = std::min(count, 9999); const qint64 counterSlice = std::min(count, 9999);
QVariantMap dbusUnityProperties; QVariantMap dbusUnityProperties;
if (counterSlice > 0) { if (counterSlice > 0) {
dbusUnityProperties["count"_L1] = counterSlice; dbusUnityProperties["count"_ls] = counterSlice;
dbusUnityProperties["count-visible"_L1] = true; dbusUnityProperties["count-visible"_ls] = true;
} else { } 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}); signal.setArguments({launcherUrl, dbusUnityProperties});
@@ -430,7 +431,7 @@ void Controller::removeConnection(const QString &userId)
} }
if (m_connectionsLoading.contains(userId) && m_connectionsLoading[userId]) { if (m_connectionsLoading.contains(userId) && m_connectionsLoading[userId]) {
auto connection = m_connectionsLoading[userId]; auto connection = m_connectionsLoading[userId];
SettingsGroup("Accounts"_L1).remove(userId); SettingsGroup("Accounts"_ls).remove(userId);
} }
} }

View File

@@ -11,6 +11,7 @@
#include <Quotient/accountregistry.h> #include <Quotient/accountregistry.h>
class TrayIcon; class TrayIcon;
class QQuickTextDocument;
namespace QKeychain namespace QKeychain
{ {

View File

@@ -3,7 +3,6 @@
import QtQuick import QtQuick
import QtQuick.Layouts import QtQuick.Layouts
import QtQuick.Window
import org.kde.kirigami as Kirigami import org.kde.kirigami as Kirigami
import org.kde.kirigamiaddons.formcard as FormCard import org.kde.kirigamiaddons.formcard as FormCard
@@ -38,7 +37,7 @@ FormCard.FormCardPage {
} }
function openEventSource(stateKey: string): void { function openEventSource(stateKey: string): void {
root.Window.window.pageStack.pushDialogLayer(Qt.createComponent('org.kde.neochat', 'MessageSourceSheet'), { pageStack.pushDialogLayer(Qt.createComponent('org.kde.neochat', 'MessageSourceSheet'), {
model: stateKeysModel, model: stateKeysModel,
allowEdit: true, allowEdit: true,
room: root.room, room: root.room,

File diff suppressed because it is too large Load Diff

View File

@@ -4,8 +4,6 @@
#include "emojitones.h" #include "emojitones.h"
#include "models/emojimodel.h" #include "models/emojimodel.h"
using namespace Qt::StringLiterals;
QMultiHash<QString, QVariant> EmojiTones::_tones = { QMultiHash<QString, QVariant> EmojiTones::_tones = {
#include "emojitones_data.h" #include "emojitones_data.h"
}; };

File diff suppressed because it is too large Load Diff

View File

@@ -13,8 +13,6 @@
#include "events/pollevent.h" #include "events/pollevent.h"
using namespace Qt::StringLiterals;
/** /**
* @class DelegateType * @class DelegateType
* *
@@ -60,7 +58,7 @@ public:
return Message; return Message;
} }
if (event.isStateEvent()) { 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 Message;
} }
return State; return State;

View File

@@ -13,8 +13,6 @@
#include "events/pollevent.h" #include "events/pollevent.h"
using namespace Qt::StringLiterals;
/** /**
* @class MessageComponentType * @class MessageComponentType
* *
@@ -50,17 +48,11 @@ public:
LiveLocation, /**< The initial event of a shared live location (i.e., the place where this is supposed to be shown in the timeline). */ LiveLocation, /**< The initial event of a shared live location (i.e., the place where this is supposed to be shown in the timeline). */
Encrypted, /**< An encrypted message that cannot be decrypted. */ Encrypted, /**< An encrypted message that cannot be decrypted. */
Reply, /**< A component to show a replied-to message. */ Reply, /**< A component to show a replied-to message. */
Reaction, /**< A component to show the reactions to this message. */
LinkPreview, /**< A preview of a URL in the message. */ LinkPreview, /**< A preview of a URL in the message. */
LinkPreviewLoad, /**< A loading dialog for a link preview. */ LinkPreviewLoad, /**< A loading dialog for a link preview. */
ChatBar, /**< A text edit for editing a message. */ ChatBar, /**< A text edit for editing a message. */
ThreadRoot, /**< The root message of the thread. */
ThreadBody, /**< The other messages in the thread. */
ReplyButton, /**< A button to reply in the current thread. */
FetchButton, /**< A button to fetch more messages in the current thread. */
Verification, /**< A user verification session start message. */ Verification, /**< A user verification session start message. */
Loading, /**< The component is loading. */ Loading, /**< The component is loading. */
Separator, /**< A horizontal separator. */
Other, /**< Anything that cannot be classified as another type. */ Other, /**< Anything that cannot be classified as another type. */
}; };
Q_ENUM(Type); Q_ENUM(Type);
@@ -100,7 +92,7 @@ public:
return MessageComponentType::Image; return MessageComponentType::Image;
} }
if (event.isStateEvent()) { 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::LiveLocation;
} }
return MessageComponentType::Other; return MessageComponentType::Other;
@@ -128,10 +120,10 @@ public:
*/ */
static Type typeForTag(const QString &tag) static Type typeForTag(const QString &tag)
{ {
if (tag == u"pre"_s || tag == u"pre"_s) { if (tag == QLatin1String("pre") || tag == QLatin1String("pre")) {
return Code; return Code;
} }
if (tag == u"blockquote"_s) { if (tag == QLatin1String("blockquote")) {
return Quote; return Quote;
} }
return Text; return Text;

View File

@@ -10,8 +10,6 @@
#include <KLocalizedString> #include <KLocalizedString>
using namespace Qt::StringLiterals;
class NeoChatRoomType : public QObject class NeoChatRoomType : public QObject
{ {
Q_OBJECT Q_OBJECT
@@ -77,19 +75,19 @@ public:
{ {
switch (category) { switch (category) {
case NeoChatRoomType::Invited: case NeoChatRoomType::Invited:
return u"user-invisible"_s; return QStringLiteral("user-invisible");
case NeoChatRoomType::Favorite: case NeoChatRoomType::Favorite:
return u"favorite"_s; return QStringLiteral("favorite");
case NeoChatRoomType::Direct: case NeoChatRoomType::Direct:
return u"dialog-messages"_s; return QStringLiteral("dialog-messages");
case NeoChatRoomType::Normal: case NeoChatRoomType::Normal:
return u"group"_s; return QStringLiteral("group");
case NeoChatRoomType::Deprioritized: case NeoChatRoomType::Deprioritized:
return u"object-order-lower"_s; return QStringLiteral("object-order-lower");
case NeoChatRoomType::Space: case NeoChatRoomType::Space:
return u"group"_s; return QStringLiteral("group");
default: default:
return u"tools-report-bug"_s; return QStringLiteral("tools-report-bug");
} }
} }
}; };

View File

@@ -6,8 +6,6 @@
#include <QObject> #include <QObject>
#include <QQmlEngine> #include <QQmlEngine>
using namespace Qt::StringLiterals;
/** /**
* @class PushRuleKind * @class PushRuleKind
* *
@@ -44,15 +42,15 @@ public:
{ {
switch (kind) { switch (kind) {
case Kind::Override: case Kind::Override:
return u"override"_s; return QLatin1String("override");
case Kind::Content: case Kind::Content:
return u"content"_s; return QLatin1String("content");
case Kind::Room: case Kind::Room:
return u"room"_s; return QLatin1String("room");
case Kind::Sender: case Kind::Sender:
return u"sender"_s; return QLatin1String("sender");
case Kind::Underride: case Kind::Underride:
return u"underride"_s; return QLatin1String("underride");
default: default:
return {}; return {};
} }
@@ -172,15 +170,15 @@ public:
{ {
switch (section) { switch (section) {
case Section::Master: case Section::Master:
return u"Master"_s; return QLatin1String("Master");
case Section::Room: case Section::Room:
return u"Room Notifications"_s; return QLatin1String("Room Notifications");
case Section::Mentions: case Section::Mentions:
return u"@Mentions"_s; return QLatin1String("@Mentions");
case Section::Keywords: case Section::Keywords:
return u"Keywords"_s; return QLatin1String("Keywords");
case Section::Invites: case Section::Invites:
return u"Invites"_s; return QLatin1String("Invites");
default: default:
return {}; return {};
} }

View File

@@ -3,11 +3,6 @@
#include "roomsortparameter.h" #include "roomsortparameter.h"
#include <algorithm>
#include "neochatconfig.h"
#include "neochatroom.h"
namespace namespace
{ {
template<typename T> template<typename T>
@@ -21,78 +16,6 @@ int typeCompare<QString>(QString left, QString right)
{ {
return left.localeAwareCompare(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) int RoomSortParameter::compareParameter(Parameter parameter, NeoChatRoom *leftRoom, NeoChatRoom *rightRoom)
@@ -113,7 +36,7 @@ int RoomSortParameter::compareParameter(Parameter parameter, NeoChatRoom *leftRo
case LastActive: case LastActive:
return compareParameter<LastActive>(leftRoom, rightRoom); return compareParameter<LastActive>(leftRoom, rightRoom);
default: default:
return 0; return false;
} }
} }

View File

@@ -3,13 +3,12 @@
#pragma once #pragma once
#include "neochatroom.h"
#include <QObject> #include <QObject>
#include <QQmlEngine> #include <QQmlEngine>
#include <KLocalizedString> #include <KLocalizedString>
class NeoChatRoom;
/** /**
* @class RoomSortParameter * @class RoomSortParameter
* *
@@ -24,19 +23,15 @@ class RoomSortParameter : public QObject
public: public:
/** /**
* @brief Defines the available sort parameters. * @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 { enum Parameter {
AlphabeticalAscending = 0, AlphabeticalAscending,
AlphabeticalDescending = 1, AlphabeticalDescending,
HasUnread = 2, HasUnread,
MostUnread = 3, MostUnread,
HasHighlight = 4, HasHighlight,
MostHighlights = 5, MostHighlights,
LastActive = 6, LastActive,
}; };
Q_ENUM(Parameter) Q_ENUM(Parameter)
@@ -45,7 +40,7 @@ public:
* *
* @sa Parameter * @sa Parameter
*/ */
Q_INVOKABLE static QString parameterName(Parameter parameter) static QString parameterName(Parameter parameter)
{ {
switch (parameter) { switch (parameter) {
case Parameter::AlphabeticalAscending: case Parameter::AlphabeticalAscending:
@@ -72,7 +67,7 @@ public:
* *
* @sa Parameter * @sa Parameter
*/ */
Q_INVOKABLE static QString parameterDescription(Parameter parameter) static QString parameterDescription(Parameter parameter)
{ {
switch (parameter) { switch (parameter) {
case Parameter::AlphabeticalAscending: 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. * @brief Compare the given parameter of the two given rooms.
* *

View File

@@ -60,9 +60,9 @@ QString EventHandler::authorDisplayName(const NeoChatRoom *room, const Quotient:
return {}; 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()) { && 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()) { if (previousDisplayName.isEmpty()) {
previousDisplayName = event->senderId(); previousDisplayName = event->senderId();
} }
@@ -86,39 +86,32 @@ QString EventHandler::singleLineAuthorDisplayname(const NeoChatRoom *room, const
const auto author = isPending ? room->localMember() : room->member(event->senderId()); const auto author = isPending ? room->localMember() : room->member(event->senderId());
auto displayName = author.displayName(); auto displayName = author.displayName();
displayName.replace(u"<br>\n"_s, u" "_s); displayName.replace(QStringLiteral("<br>\n"), QStringLiteral(" "));
displayName.replace(u"<br>"_s, u" "_s); displayName.replace(QStringLiteral("<br>"), QStringLiteral(" "));
displayName.replace(u"<br />\n"_s, u" "_s); displayName.replace(QStringLiteral("<br />\n"), QStringLiteral(" "));
displayName.replace(u"<br />"_s, u" "_s); displayName.replace(QStringLiteral("<br />"), QStringLiteral(" "));
displayName.replace(u'\n', u" "_s); displayName.replace(u'\n', QStringLiteral(" "));
displayName.replace(u'\u2028', u" "_s); displayName.replace(u'\u2028', QStringLiteral(" "));
return displayName; 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) { if (event == nullptr) {
qCWarning(EventHandling) << "time called with event set to nullptr."; qCWarning(EventHandling) << "time called with event set to nullptr.";
return {}; return {};
} }
if (isPending && lastUpdated == QDateTime()) {
if (isPending) { qCWarning(EventHandling) << "a value must be provided for lastUpdated for a pending event.";
const auto pendingIt = room->findPendingEvent(event->transactionId());
if (pendingIt != room->pendingEvents().end()) {
return pendingIt->lastUpdated();
}
return {}; 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 (ts.isValid()) {
if (relative) { if (relative) {
KFormat formatter; KFormat formatter;
@@ -130,9 +123,9 @@ QString EventHandler::timeString(const NeoChatRoom *room, const Quotient::RoomEv
return {}; 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) 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 // 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; return true;
} }
@@ -211,7 +204,7 @@ bool EventHandler::isHidden(const NeoChatRoom *room, const Quotient::RoomEvent *
Qt::TextFormat EventHandler::messageBodyInputFormat(const Quotient::RoomMessageEvent &event) 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; return Qt::PlainText;
} else { } else {
return Qt::RichText; return Qt::RichText;
@@ -316,8 +309,8 @@ QString EventHandler::getBody(const NeoChatRoom *room, const Quotient::RoomEvent
} }
if (prettyPrint) { if (prettyPrint) {
subjectName = subjectName = QStringLiteral("<a href=\"https://matrix.to/#/%1\" style=\"color: %2\">%3</a>")
u"<a href=\"https://matrix.to/#/%1\" style=\"color: %2\">%3</a>"_s.arg(e.userId(), room->member(e.userId()).color().name(), subjectName); .arg(e.userId(), room->member(e.userId()).color().name(), subjectName);
} }
// The below code assumes senderName output in AuthorRole // 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()) { if (e.senderId() == e.userId()) {
return i18n("left the room"); 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: %2", subjectName, reason);
} }
return i18n("has put %1 out of the room", subjectName); 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"); return i18n("self-banned from the room");
} }
case Membership::Knock: { 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); return reason.isEmpty() ? i18n("requested an invite") : i18n("requested an invite with reason: %1", reason);
} }
default:; default:;
@@ -426,26 +419,26 @@ QString EventHandler::getBody(const NeoChatRoom *room, const Quotient::RoomEvent
}, },
[prettyPrint](const RoomCreateEvent &e) { [prettyPrint](const RoomCreateEvent &e) {
return e.isUpgrade() return e.isUpgrade()
? i18n("upgraded the room to 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"_L1 : (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 &) { [](const RoomPowerLevelsEvent &) {
return i18nc("'power level' means permission level", "changed the power levels for this room"); return i18nc("'power level' means permission level", "changed the power levels for this room");
}, },
[](const LocationBeaconEvent &e) { [](const LocationBeaconEvent &e) {
return e.contentJson()["description"_L1].toString(); return e.contentJson()["description"_ls].toString();
}, },
[](const RoomServerAclEvent &) { [](const RoomServerAclEvent &) {
return i18n("changed the server access control lists for this room"); return i18n("changed the server access control lists for this room");
}, },
[](const WidgetEvent &e) { [](const WidgetEvent &e) {
if (e.fullJson()["unsigned"_L1]["prev_content"_L1].toObject().isEmpty()) { if (e.fullJson()["unsigned"_ls]["prev_content"_ls].toObject().isEmpty()) {
return i18nc("[User] added <name> widget", "added %1 widget", e.contentJson()["name"_L1].toString()); return i18nc("[User] added <name> widget", "added %1 widget", e.contentJson()["name"_ls].toString());
} }
if (e.contentJson().isEmpty()) { 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) { [prettyPrint](const StateEvent &e) {
return e.stateKey().isEmpty() ? i18n("updated %1 state", e.matrixType()) 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()) { if (fileCaption.isEmpty()) {
fileCaption = event.plainBody(); fileCaption = event.plainBody();
} else if (fileCaption != event.plainBody()) { } else if (fileCaption != event.plainBody()) {
fileCaption = event.plainBody() + " | "_L1 + fileCaption; fileCaption = event.plainBody() + " | "_ls + fileCaption;
} }
textHandler.setData(fileCaption); textHandler.setData(fileCaption);
return !fileCaption.isEmpty() ? textHandler.handleRecievePlainText(Qt::PlainText, stripNewlines) : i18n("a file"); 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); textHandler.setData(body);
Qt::TextFormat inputFormat; Qt::TextFormat inputFormat;
if (event.mimeType().name() == "text/plain"_L1) { if (event.mimeType().name() == "text/plain"_ls) {
inputFormat = Qt::PlainText; inputFormat = Qt::PlainText;
} else { } else {
inputFormat = Qt::RichText; 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 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( return switchOnType(
*event, *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); return i18n("%1 changed the server access control lists for this room", senderString);
}, },
[senderString](const WidgetEvent &e) { [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); return i18n("%1 added a widget", senderString);
} }
if (e.contentJson().isEmpty()) { 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."; qCWarning(EventHandling) << "subtitleText called with event set to nullptr.";
return {}; 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) 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); QVariantMap mediaInfo = getMediaInfoFromFileInfo(room, content.get(), eventId, false, false);
// if filename isn't specifically given, it is in body // if filename isn't specifically given, it is in body
// https://spec.matrix.org/latest/client-server-api/#mfile // 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; return mediaInfo;
} else if (event->is<StickerEvent>()) { } else if (event->is<StickerEvent>()) {
@@ -719,80 +712,80 @@ QVariantMap EventHandler::getMediaInfoFromFileInfo(const NeoChatRoom *room,
QVariantMap mediaInfo; QVariantMap mediaInfo;
// Get the mxc URL for the media. // Get the mxc URL for the media.
if (!fileContent->url().isValid() || fileContent->url().scheme() != u"mxc"_s || eventId.isEmpty()) { if (!fileContent->url().isValid() || fileContent->url().scheme() != QStringLiteral("mxc") || eventId.isEmpty()) {
mediaInfo["source"_L1] = QUrl(); mediaInfo["source"_ls] = QUrl();
} else { } else {
QUrl source = room->makeMediaUrl(eventId, fileContent->url()); QUrl source = room->makeMediaUrl(eventId, fileContent->url());
if (source.isValid()) { if (source.isValid()) {
mediaInfo["source"_L1] = source; mediaInfo["source"_ls] = source;
} else { } else {
mediaInfo["source"_L1] = QUrl(); mediaInfo["source"_ls] = QUrl();
} }
} }
auto mimeType = fileContent->type(); auto mimeType = fileContent->type();
// Add the MIME type for the media if available. // 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. // Add the MIME type icon if available.
mediaInfo["mimeIcon"_L1] = mimeType.iconName(); mediaInfo["mimeIcon"_ls] = mimeType.iconName();
// Add media size if available. // 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. // 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)) { if (auto castInfo = static_cast<const EventContent::ImageContent *>(fileContent)) {
mediaInfo["width"_L1] = castInfo->imageSize.width(); mediaInfo["width"_ls] = castInfo->imageSize.width();
mediaInfo["height"_L1] = castInfo->imageSize.height(); 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. // 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; QVariantMap tempInfo;
auto thumbnailInfo = getMediaInfoFromTumbnail(room, castInfo->thumbnail, eventId); 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; tempInfo = thumbnailInfo;
} else { } else {
QString blurhash = castInfo->originalInfoJson["xyz.amorgan.blurhash"_L1].toString(); QString blurhash = castInfo->originalInfoJson["xyz.amorgan.blurhash"_ls].toString();
if (blurhash.isEmpty()) { if (blurhash.isEmpty()) {
tempInfo["source"_L1] = QUrl(); tempInfo["source"_ls] = QUrl();
} else { } 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)) { if (auto castInfo = static_cast<const EventContent::VideoContent *>(fileContent)) {
mediaInfo["width"_L1] = castInfo->imageSize.width(); mediaInfo["width"_ls] = castInfo->imageSize.width();
mediaInfo["height"_L1] = castInfo->imageSize.height(); mediaInfo["height"_ls] = castInfo->imageSize.height();
mediaInfo["duration"_L1] = castInfo->duration; mediaInfo["duration"_ls] = castInfo->duration;
if (!isThumbnail) { if (!isThumbnail) {
QVariantMap tempInfo; QVariantMap tempInfo;
auto thumbnailInfo = getMediaInfoFromTumbnail(room, castInfo->thumbnail, eventId); 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; tempInfo = thumbnailInfo;
} else { } else {
QString blurhash = castInfo->originalInfoJson["xyz.amorgan.blurhash"_L1].toString(); QString blurhash = castInfo->originalInfoJson["xyz.amorgan.blurhash"_ls].toString();
if (blurhash.isEmpty()) { if (blurhash.isEmpty()) {
tempInfo["source"_L1] = QUrl(); tempInfo["source"_ls] = QUrl();
} else { } 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)) { 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; QVariantMap thumbnailInfo;
if (!thumbnail.url().isValid() || thumbnail.url().scheme() != u"mxc"_s || eventId.isEmpty()) { if (!thumbnail.url().isValid() || thumbnail.url().scheme() != QStringLiteral("mxc") || eventId.isEmpty()) {
thumbnailInfo["source"_L1] = QUrl(); thumbnailInfo["source"_ls] = QUrl();
} else { } else {
QUrl source = room->makeMediaUrl(eventId, thumbnail.url()); QUrl source = room->makeMediaUrl(eventId, thumbnail.url());
if (source.isValid()) { if (source.isValid()) {
thumbnailInfo["source"_L1] = source; thumbnailInfo["source"_ls] = source;
} else { } else {
thumbnailInfo["source"_L1] = QUrl(); thumbnailInfo["source"_ls] = QUrl();
} }
} }
auto mimeType = thumbnail.mimeType; auto mimeType = thumbnail.mimeType;
// Add the MIME type for the media if available. // 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. // Add the MIME type icon if available.
thumbnailInfo["mimeIcon"_L1] = mimeType.iconName(); thumbnailInfo["mimeIcon"_ls] = mimeType.iconName();
// Add media size if available. // Add media size if available.
thumbnailInfo["size"_L1] = thumbnail.payloadSize; thumbnailInfo["size"_ls] = thumbnail.payloadSize;
thumbnailInfo["width"_L1] = thumbnail.imageSize.width(); thumbnailInfo["width"_ls] = thumbnail.imageSize.width();
thumbnailInfo["height"_L1] = thumbnail.imageSize.height(); thumbnailInfo["height"_ls] = thumbnail.imageSize.height();
return thumbnailInfo; return thumbnailInfo;
} }
@@ -856,7 +849,7 @@ float EventHandler::latitude(const Quotient::RoomEvent *event)
return -100.0; return -100.0;
} }
const auto geoUri = event->contentJson()["geo_uri"_L1].toString(); const auto geoUri = event->contentJson()["geo_uri"_ls].toString();
if (geoUri.isEmpty()) { if (geoUri.isEmpty()) {
return -100.0; // latitude runs from -90deg to +90deg so -100 is out of range. 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; return -200.0;
} }
const auto geoUri = event->contentJson()["geo_uri"_L1].toString(); const auto geoUri = event->contentJson()["geo_uri"_ls].toString();
if (geoUri.isEmpty()) { if (geoUri.isEmpty()) {
return -200.0; // longitude runs from -180deg to +180deg so -200 is out of range. 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 {}; 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()) { if (assetType.isEmpty()) {
return {}; return {};
} }

View File

@@ -64,7 +64,7 @@ public:
/** /**
* @brief Return a QDateTime object for the event timestamp. * @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. * @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 * @param lastUpdated the time the event was last updated locally as this cannot be
* obtained from the event. * obtained from the event.
*/ */
static QString timeString(const NeoChatRoom *room, static QString timeString(const Quotient::RoomEvent *event,
const Quotient::RoomEvent *event,
bool relative, bool relative,
QLocale::FormatType format = QLocale::ShortFormat, QLocale::FormatType format = QLocale::ShortFormat,
bool isPending = false); bool isPending = false,
QDateTime lastUpdated = {});
/** /**
* @brief Return a QString for the event timestamp. * @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 * @param lastUpdated the time the event was last updated locally as this cannot be
* obtained from the event. * 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. * @brief Whether the event should be highlighted in the timeline.

View File

@@ -8,31 +8,31 @@ using namespace Quotient;
ImagePackEventContent::ImagePackEventContent(const QJsonObject &json) ImagePackEventContent::ImagePackEventContent(const QJsonObject &json)
{ {
if (json.contains("pack"_L1)) { if (json.contains(QStringLiteral("pack"))) {
pack = ImagePackEventContent::Pack{ pack = ImagePackEventContent::Pack{
fromJson<std::optional<QString>>(json["pack"_L1].toObject()["display_name"_L1]), fromJson<std::optional<QString>>(json["pack"_ls].toObject()["display_name"_ls]),
fromJson<std::optional<QUrl>>(json["pack"_L1].toObject()["avatar_url"_L1]), fromJson<std::optional<QUrl>>(json["pack"_ls].toObject()["avatar_url"_ls]),
fromJson<std::optional<QStringList>>(json["pack"_L1].toObject()["usage"_L1]), fromJson<std::optional<QStringList>>(json["pack"_ls].toObject()["usage"_ls]),
fromJson<std::optional<QString>>(json["pack"_L1].toObject()["attribution"_L1]), fromJson<std::optional<QString>>(json["pack"_ls].toObject()["attribution"_ls]),
}; };
} else { } else {
pack = std::nullopt; pack = std::nullopt;
} }
const auto &keys = json["images"_L1].toObject().keys(); const auto &keys = json["images"_ls].toObject().keys();
for (const auto &k : keys) { for (const auto &k : keys) {
std::optional<EventContent::ImageInfo> info; std::optional<EventContent::ImageInfo> info;
if (json["images"_L1][k].toObject().contains("info"_L1)) { if (json["images"_ls][k].toObject().contains(QStringLiteral("info"))) {
info = EventContent::ImageInfo(QUrl(json["images"_L1][k]["url"_L1].toString()), json["images"_L1][k]["info"_L1].toObject(), k); info = EventContent::ImageInfo(QUrl(json["images"_ls][k]["url"_ls].toString()), json["images"_ls][k]["info"_ls].toObject(), k);
} else { } else {
info = std::nullopt; info = std::nullopt;
} }
images += ImagePackImage{ images += ImagePackImage{
k, k,
fromJson<QUrl>(json["images"_L1][k]["url"_L1].toString()), fromJson<QUrl>(json["images"_ls][k]["url"_ls].toString()),
fromJson<std::optional<QString>>(json["images"_L1][k]["body"_L1]), fromJson<std::optional<QString>>(json["images"_ls][k]["body"_ls]),
info, 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) { if (pack) {
QJsonObject packJson; QJsonObject packJson;
if (pack->displayName) { if (pack->displayName) {
packJson["display_name"_L1] = *pack->displayName; packJson["display_name"_ls] = *pack->displayName;
} }
if (pack->usage) { if (pack->usage) {
QJsonArray usageJson; QJsonArray usageJson;
for (const auto &usage : *pack->usage) { for (const auto &usage : *pack->usage) {
usageJson += usage; usageJson += usage;
} }
packJson["usage"_L1] = usageJson; packJson["usage"_ls] = usageJson;
} }
if (pack->avatarUrl) { if (pack->avatarUrl) {
packJson["avatar_url"_L1] = pack->avatarUrl->toString(); packJson["avatar_url"_ls] = pack->avatarUrl->toString();
} }
if (pack->attribution) { if (pack->attribution) {
packJson["attribution"_L1] = *pack->attribution; packJson["attribution"_ls] = *pack->attribution;
} }
(*o)["pack"_L1] = packJson; (*o)["pack"_ls] = packJson;
} }
QJsonObject imagesJson; QJsonObject imagesJson;
for (const auto &image : images) { for (const auto &image : images) {
QJsonObject imageJson; QJsonObject imageJson;
imageJson["url"_L1] = image.url.toString(); imageJson["url"_ls] = image.url.toString();
if (image.body) { if (image.body) {
imageJson["body"_L1] = *image.body; imageJson["body"_ls] = *image.body;
} }
if (image.usage) { if (image.usage) {
QJsonArray usageJson; QJsonArray usageJson;
for (const auto &usage : *image.usage) { for (const auto &usage : *image.usage) {
usageJson += usage; usageJson += usage;
} }
imageJson["usage"_L1] = usageJson; imageJson["usage"_ls] = usageJson;
} }
if (image.info.has_value()) { 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; imagesJson[image.shortcode] = imageJson;
} }
(*o)["images"_L1] = imagesJson; (*o)["images"_ls] = imagesJson;
} }

View File

@@ -0,0 +1,16 @@
// SPDX-FileCopyrightText: 2019 Kitsune Ral <Kitsune-Ral@users.sf.net>
// SPDX-License-Identifier: LGPL-2.1-or-later
#include "joinrulesevent.h"
using namespace Quotient;
QString JoinRulesEvent::joinRule() const
{
return fromJson<QString>(contentJson()["join_rule"_ls]);
}
QJsonArray JoinRulesEvent::allow() const
{
return contentJson()["allow"_ls].toArray();
}

View File

@@ -0,0 +1,43 @@
// SPDX-FileCopyrightText: 2021 Carl Schwan <carl@carlschwan.eu>
// SPDX-License-Identifier: LGPL-2.1-or-later
#pragma once
#include <Quotient/events/stateevent.h>
namespace Quotient
{
/**
* @class JoinRulesEvent
*
* Class to define a join rule state event.
*
* @sa Quotient::StateEvent
*/
class JoinRulesEvent : public StateEvent
{
public:
QUO_EVENT(JoinRulesEvent, "m.room.join_rules")
explicit JoinRulesEvent(const QJsonObject &obj)
: StateEvent(obj)
{
}
/**
* @brief The join rule for the room.
*
* see https://spec.matrix.org/latest/client-server-api/#mroomjoin_rules for
* the available join rules for a room.
*/
QString joinRule() const;
/**
* @brief The allow rule for restricted rooms.
*
* see https://spec.matrix.org/latest/client-server-api/#mroomjoin_rules for
* full details on allow rules.
*/
QJsonArray allow() const;
};
}

View File

@@ -12,12 +12,12 @@ PollStartEvent::PollStartEvent(const QJsonObject &obj)
int PollStartEvent::maxSelections() const 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 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) PollResponseEvent::PollResponseEvent(const QJsonObject &obj)
@@ -32,7 +32,7 @@ PollEndEvent::PollEndEvent(const QJsonObject &obj)
PollResponseEvent::PollResponseEvent(const QString &pollStartEventId, QStringList responses) PollResponseEvent::PollResponseEvent(const QString &pollStartEventId, QStringList responses)
: RoomEvent(basicJson(TypeId, : RoomEvent(basicJson(TypeId,
{{"org.matrix.msc3381.poll.response"_L1, QJsonObject{{"answers"_L1, QJsonArray::fromStringList(responses)}}}, {{"org.matrix.msc3381.poll.response"_ls, QJsonObject{{"answers"_ls, QJsonArray::fromStringList(responses)}}},
{"m.relates_to"_L1, QJsonObject{{"rel_type"_L1, "m.reference"_L1}, {"event_id"_L1, pollStartEventId}}}})) {"m.relates_to"_ls, QJsonObject{{"rel_type"_ls, "m.reference"_ls}, {"event_id"_ls, pollStartEventId}}}}))
{ {
} }

View File

@@ -12,7 +12,6 @@ FileTransferPseudoJob::FileTransferPseudoJob(Operation operation, const QString
, m_eventId(eventId) , m_eventId(eventId)
, m_operation(operation) , m_operation(operation)
{ {
setCapabilities(KJob::Killable);
} }
void FileTransferPseudoJob::fileTransferProgress(const QString &id, qint64 progress, qint64 total) void FileTransferPseudoJob::fileTransferProgress(const QString &id, qint64 progress, qint64 total)
@@ -42,15 +41,6 @@ void FileTransferPseudoJob::fileTransferFailed(const QString &id, const QString
emitResult(); emitResult();
} }
void FileTransferPseudoJob::fileTransferCanceled(const QString &id)
{
if (id != m_eventId) {
return;
}
setError(KJob::KilledJobError);
emitResult();
}
void FileTransferPseudoJob::start() void FileTransferPseudoJob::start()
{ {
setTotalAmount(Unit::Files, 1); setTotalAmount(Unit::Files, 1);
@@ -59,9 +49,3 @@ void FileTransferPseudoJob::start()
{i18nc("The URL being downloaded/uploaded", "Source"), m_path}, {i18nc("The URL being downloaded/uploaded", "Source"), m_path},
{i18nc("The location being downloaded to", "Destination"), m_path}); {i18nc("The location being downloaded to", "Destination"), m_path});
} }
bool FileTransferPseudoJob::doKill()
{
Q_EMIT cancelRequested(m_eventId);
return true;
}

View File

@@ -15,7 +15,6 @@
*/ */
class FileTransferPseudoJob : public KJob class FileTransferPseudoJob : public KJob
{ {
Q_OBJECT
public: public:
enum Operation { enum Operation {
Download, Download,
@@ -39,22 +38,11 @@ public:
*/ */
void fileTransferFailed(const QString &id, const QString &errorMessage = {}); void fileTransferFailed(const QString &id, const QString &errorMessage = {});
/**
* @brief Set the file transfer as canceled.
*/
void fileTransferCanceled(const QString &id);
/** /**
* @brief Start the file transfer. * @brief Start the file transfer.
*/ */
void start() override; void start() override;
protected:
bool doKill() override;
Q_SIGNALS:
void cancelRequested(const QString &id);
private: private:
QString m_path; QString m_path;
QString m_eventId; QString m_eventId;

View File

@@ -11,8 +11,6 @@
#include "neochatconnection.h" #include "neochatconnection.h"
using namespace Qt::StringLiterals;
IdentityServerHelper::IdentityServerHelper(QObject *parent) IdentityServerHelper::IdentityServerHelper(QObject *parent)
: QObject(parent) : QObject(parent)
{ {
@@ -77,8 +75,8 @@ void IdentityServerHelper::checkUrl()
return; return;
} }
const auto requestUrl = QUrl(m_url + u"/_matrix/identity/v2"_s); const auto requestUrl = QUrl(m_url + QStringLiteral("/_matrix/identity/v2"));
if (!(requestUrl.scheme() == u"https"_s || requestUrl.scheme() == u"http"_s)) { if (!(requestUrl.scheme() == QStringLiteral("https") || requestUrl.scheme() == QStringLiteral("http"))) {
m_status = Invalid; m_status = Invalid;
Q_EMIT statusChanged(); Q_EMIT statusChanged();
return; return;
@@ -103,7 +101,7 @@ void IdentityServerHelper::setIdentityServer()
return; 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; m_status = Ready;
Q_EMIT statusChanged(); Q_EMIT statusChanged();
} }
@@ -113,7 +111,7 @@ void IdentityServerHelper::clearIdentityServer()
if (m_connection->identityServer().isEmpty()) { if (m_connection->identityServer().isEmpty()) {
return; 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; m_status = Ready;
Q_EMIT statusChanged(); Q_EMIT statusChanged();
} }

Some files were not shown because too many files have changed in this diff Show More