Compare commits

..

1 Commits

Author SHA1 Message Date
Torrie Fischer
be7617d366 wip: accessability :D 2023-07-15 17:28:25 +02:00
133 changed files with 10400 additions and 12067 deletions

View File

@@ -58,9 +58,5 @@ Dependencies:
'require':
'frameworks/kdbusaddons': '@latest-kf6'
- 'on': ['Linux/Qt6', 'Linux/Qt5']
'require':
'sdk/selenium-webdriver-at-spi': '@latest-kf6'
Options:
require-passing-tests-on: [ 'Linux/Qt5', 'FreeBSD', 'Windows' ]
require-passing-tests-on: [ 'Linux/Qt5', 'FreeBSD' ]

View File

@@ -8,7 +8,7 @@ cmake_minimum_required(VERSION 3.16)
# KDE Applications version, managed by release script.
set(RELEASE_SERVICE_VERSION_MAJOR "23")
set(RELEASE_SERVICE_VERSION_MINOR "11")
set(RELEASE_SERVICE_VERSION_MINOR "07")
set(RELEASE_SERVICE_VERSION_MICRO "70")
set(RELEASE_SERVICE_VERSION "${RELEASE_SERVICE_VERSION_MAJOR}.${RELEASE_SERVICE_VERSION_MINOR}.${RELEASE_SERVICE_VERSION_MICRO}")
@@ -53,24 +53,13 @@ if(QT_MAJOR_VERSION STREQUAL "6")
set(OVERLAYSHEET_OPEN "onOpened")
set(QTQUICK_MODULE_QML_VERSION "")
set(QTLOCATION_MODULE_QML_VERSION "")
set(QTMULTIMEDIA_MODULE_QML_VERSION "")
set(QTMULTIMEDIA_AUDIO "MediaPlayer")
# in Audio qt6 we don't have it but we disable it in qt5 => it seems ok
set(QTMULTIMEDIA_AUDIO_AUTOLOAD "")
# In Video qml qt6 we don't have it.
set(QTMULTIMEDIA_VIDEO_FLUSHMODE "")
else()
set(BASICLISTITEM_BOLD "bold")
set(OVERLAYSHEET_OPEN "onSheetOpenChanged")
set(QTQUICK_MODULE_QML_VERSION "2.15")
set(QTLOCATION_MODULE_QML_VERSION "5.15")
set(QTMULTIMEDIA_MODULE_QML_VERSION "5.15")
set(QTMULTIMEDIA_AUDIO "Audio")
set(QTMULTIMEDIA_AUDIO_AUTOLOAD "autoLoad: false")
set(QTMULTIMEDIA_VIDEO_FLUSHMODE "flushMode: VideoOutput.FirstFrame")
endif()
set(QUOTIENT_FORCE_NAMESPACED_INCLUDES TRUE)
ecm_setup_version(${PROJECT_VERSION}
VARIABLE_PREFIX NEOCHAT
@@ -93,6 +82,12 @@ set_package_properties(KF${QT_MAJOR_VERSION}Kirigami2 PROPERTIES
)
find_package(KF${QT_MAJOR_VERSION}KirigamiAddons 0.7.2 REQUIRED)
find_package(Qt${QT_MAJOR_VERSION}Keychain)
set_package_properties(Qt${QT_MAJOR_VERSION}Keychain PROPERTIES
TYPE REQUIRED
PURPOSE "Secure storage of account secrets"
)
if(ANDROID)
find_package(OpenSSL)
set_package_properties(OpenSSL PROPERTIES
@@ -154,6 +149,10 @@ set_package_properties(KF${QT_MAJOR_VERSION}DocTools PROPERTIES DESCRIPTION
TYPE OPTIONAL
)
if(NOT Quotient${QUOTIENT_SUFFIX}_VERSION_MINOR GREATER 6)
cmake_policy(SET CMP0063 OLD)
endif()
if(ANDROID)
find_package(Sqlite3)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/android/version.gradle.in ${CMAKE_BINARY_DIR}/version.gradle)
@@ -169,11 +168,9 @@ install(FILES org.kde.neochat.tray.svg DESTINATION ${KDE_INSTALL_FULL_ICONDIR}/h
add_definitions(-DQT_NO_FOREACH)
add_subdirectory(src)
if (BUILD_TESTING)
if (BUILD_TESTING AND Quotient${QUOTIENT_SUFFIX}_VERSION_MINOR GREATER 6)
find_package(Qt${QT_MAJOR_VERSION} ${QT_MIN_VERSION} NO_MODULE COMPONENTS Test)
add_subdirectory(autotests)
add_subdirectory(appiumtests)
endif()
if(KF${QT_MAJOR_VERSION}DocTools_FOUND)

View File

@@ -1,23 +0,0 @@
# SPDX-License-Identifier: BSD-3-Clause
# SPDX-FileCopyrightText: 2022 Harald Sitter <sitter@kde.org>
if(NOT BUILD_TESTING OR NOT CMAKE_SYSTEM_NAME MATCHES "Linux")
return()
endif()
find_package(SeleniumWebDriverATSPI)
set_package_properties(SeleniumWebDriverATSPI PROPERTIES
DESCRIPTION "Server component for selenium tests using Linux accessibility infrastructure"
PURPOSE "Needed for GUI tests"
URL "https://invent.kde.org/sdk/selenium-webdriver-at-spi"
TYPE OPTIONAL
)
if(NOT SeleniumWebDriverATSPI_FOUND)
return()
endif()
add_test(
NAME logintest
COMMAND selenium-webdriver-at-spi-run ${CMAKE_CURRENT_SOURCE_DIR}/logintest.py
)

View File

@@ -1,42 +0,0 @@
# SPDX-License-Identifier: MIT
# SPDX-FileCopyrightText: 2023 Tobias Fella <tobias.fella@kde.org>
from flask import Flask, request, abort
app = Flask(__name__)
@app.route("/_matrix/client/v3/login", methods=["GET"])
def login_get():
result = dict()
result["flows"] = [dict()]
result["flows"][0]["type"] = "m.login.password"
return result
@app.route("/_matrix/client/v3/login", methods=["POST"])
def login_post():
data = request.get_json()
if data["identifier"]["user"] != "user" or data["password"] != "1234":
abort(403)
print(data)
result = dict()
result["access_token"] = "token_1234"
result["device_id"] = "device_1234"
result["user_id"] = "@user:localhost:1234"
return result
@app.route("/_matrix/client/r0/sync")
def sync():
result = dict()
result["next_batch"] = "batch1234"
return result
@app.route("/.well-known/matrix/client")
def well_known():
reply = dict()
reply["m.homeserver"] = dict()
reply["m.homeserver"]["base_url"] = "https://localhost:1234"
return reply
if __name__ == "__main__":
app.run(ssl_context='adhoc', port=1234)

View File

@@ -1,44 +0,0 @@
#!/usr/bin/env python3
# SPDX-License-Identifier: MIT
# SPDX-FileCopyrightText: 2021-2022 Harald Sitter <sitter@kde.org>
# SPDX-FileCopyrightText: 2023 Tobias Fella <tobias.fella@kde.org>
import unittest
from appium import webdriver
from appium.webdriver.common.appiumby import AppiumBy
from selenium.webdriver.support.ui import WebDriverWait
import time
import subprocess
class LoginTest(unittest.TestCase):
@classmethod
def setUpClass(self):
desired_caps = {}
desired_caps["app"] = "neochat --ignore-ssl-errors"
desired_caps["timeouts"] = {'implicit': 10000}
self.driver = webdriver.Remote(
command_executor='http://127.0.0.1:4723',
desired_capabilities=desired_caps)
subprocess.Popen(["python","login-server.py"])
def setUp(self):
pass
def tearDown(self):
if not self._outcome.result.wasSuccessful():
self.driver.get_screenshot_as_file("failed_test_shot_{}.png".format(self.id()))
@classmethod
def tearDownClass(self):
self.driver.quit()
def test_login(self):
self.driver.find_element(by=AppiumBy.NAME, value="Matrix ID").send_keys("@user:localhost:1234")
self.driver.find_element(by=AppiumBy.NAME, value="Continue").click()
self.driver.find_element(by=AppiumBy.NAME, value="Password").send_keys("1234")
self.driver.find_element(by=AppiumBy.NAME, value="Login").click()
self.driver.find_element(by=AppiumBy.NAME, value="Join some rooms to get started").click()
if __name__ == '__main__':
unittest.main()

View File

@@ -7,9 +7,9 @@
#include "neochatroom.h"
#include <Quotient/connection.h>
#include <Quotient/quotient_common.h>
#include <Quotient/syncdata.h>
#include <connection.h>
#include <quotient_common.h>
#include <syncdata.h>
using namespace Quotient;

View File

@@ -4,13 +4,11 @@
#include <QObject>
#include <QTest>
#include "neochatuser.h"
#include "texthandler.h"
#include <Quotient/quotient_common.h>
#include <Quotient/syncdata.h>
#include <Quotient/user.h>
#include <qnamespace.h>
#include <quotient_common.h>
#include <syncdata.h>
using namespace Quotient;
@@ -557,9 +555,9 @@ void TextHandlerTest::receiveRichPlainUrl()
void TextHandlerTest::receiveRichEmote()
{
auto event = room->messageEvents().at(1).get();
auto author = new NeoChatUser(event->senderId(), connection);
auto author = static_cast<NeoChatUser *>(room->user(event->senderId()));
const QString testInputString = QStringLiteral("This is an emote.");
const QString testOutputString = QStringLiteral("* <a href=\"https://matrix.to/#/@example:example.org\" style=\"color:#000000")
const QString testOutputString = QStringLiteral("* <a href=\"https://matrix.to/#/@example:example.org\" style=\"color:") + author->color().name()
+ QStringLiteral("\">@example:example.org</a> This is an emote.");
TextHandler testTextHandler;
@@ -646,5 +644,5 @@ void TextHandlerTest::linkPreviewsReject()
QCOMPARE(testTextHandler.getLinkPreviews(), testOutputLinks);
}
QTEST_MAIN(TextHandlerTest)
QTEST_GUILESS_MAIN(TextHandlerTest)
#include "texthandlertest.moc"

View File

@@ -266,12 +266,10 @@ to provide a convergent experience across multiple platforms.</p>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="ca">Vista principal amb la llista de sales, xats i informació de les sales</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="ca-valencia">Vista principal amb la llista de sales, xats i informació de les sales</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="es">Vista principal con la lista de salas, chat e información de la sala</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="fr">Vue principale avec la liste des salons ainsi que des informations sur les salons et forums de discussions</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="ka">მთავარი ხედი სურათების სიით, ჩატით და ოთახის ინფორმაციით</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="nl">Hoofdweergave met lijst met rooms, chat en roominformatie</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="pt">A área principal com a lista de salas e com informações sobre a conversa e a sala</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="sl">Glavni pogled s seznamom sob, klepetom in informacijami o sobah</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="ta">அரங்குப்பட்டியல், உரையாடல், மற்றும் அரங்குவிவரங்களைக் கொண்டுள்ள பிரதான காட்சி</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="tr">Oda listesini, sohbet penceresini ve oda bilgisini gösteren ana görünüm</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="uk">Головна панель із списком кімнат, спілкуванням та даними щодо кімнати</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="x-test">xxMain view with room list, chat, and room informationxx</value>
@@ -280,12 +278,10 @@ to provide a convergent experience across multiple platforms.</p>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="ca">Pantalla d'inici de sessió</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="ca-valencia">Pantalla d'inici de sessió</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="es">Pantalla de inicio de sesión</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="fr">Écran de connexion</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="ka">შესვლის ეკრანი</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="nl">Aanmeldscherm</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="pt">Ecrã de autenticação</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="sl">Prijavni zaslon</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="ta">நுழைவுத் திரை</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="tr">Oturum açma ekranı</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="uk">Вікно входу</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="x-test">xxLogin screenxx</value>

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

@@ -7,8 +7,6 @@ configure_file(qml/Page/RoomList/RoomDelegate.qml ${CMAKE_CURRENT_BINARY_DIR}/qm
configure_file(qml/Component/QuickSwitcher.qml ${CMAKE_CURRENT_BINARY_DIR}/qml/Component/QuickSwitcher.qml)
configure_file(qml/Dialog/UserDetailDialog.qml ${CMAKE_CURRENT_BINARY_DIR}/qml/Dialog/UserDetailDialog.qml)
configure_file(qml/Dialog/PowerLevelDialog.qml ${CMAKE_CURRENT_BINARY_DIR}/qml/Dialog/PowerLevelDialog.qml)
configure_file(qml/Component/Timeline/AudioDelegate.qml ${CMAKE_CURRENT_BINARY_DIR}/qml/Component/Timeline/AudioDelegate.qml)
configure_file(qml/Component/Timeline/VideoDelegate.qml ${CMAKE_CURRENT_BINARY_DIR}/qml/Component/Timeline/VideoDelegate.qml)
configure_file(qml/Component/Timeline/OsmLocationPlugin.qml ${CMAKE_CURRENT_BINARY_DIR}/qml/Component/Timeline/OsmLocationPlugin.qml)
configure_file(res.qrc ${CMAKE_CURRENT_SOURCE_DIR}/res.generated.qrc)
@@ -66,7 +64,6 @@ add_library(neochat STATIC
chatdocumenthandler.h
models/devicesmodel.cpp
models/devicesmodel.h
models/devicesproxymodel.cpp
filetypesingleton.cpp
filetypesingleton.h
login.cpp
@@ -175,7 +172,7 @@ else()
endif()
target_include_directories(neochat PRIVATE ${CMAKE_BINARY_DIR})
target_link_libraries(neochat PUBLIC Qt::Core Qt::Quick Qt::Qml Qt::Gui Qt::Multimedia Qt::Network Qt::QuickControls2 KF${QT_MAJOR_VERSION}::I18n KF${QT_MAJOR_VERSION}::Kirigami2 KF${QT_MAJOR_VERSION}::Notifications KF${QT_MAJOR_VERSION}::ConfigCore KF${QT_MAJOR_VERSION}::ConfigGui KF${QT_MAJOR_VERSION}::CoreAddons KF${QT_MAJOR_VERSION}::SonnetCore KF${QT_MAJOR_VERSION}::ItemModels Quotient${QUOTIENT_SUFFIX} cmark::cmark QCoro::Core)
target_link_libraries(neochat PUBLIC Qt::Core Qt::Quick Qt::Qml Qt::Gui Qt::Multimedia Qt::Network Qt::QuickControls2 KF${QT_MAJOR_VERSION}::I18n KF${QT_MAJOR_VERSION}::Kirigami2 KF${QT_MAJOR_VERSION}::Notifications KF${QT_MAJOR_VERSION}::ConfigCore KF${QT_MAJOR_VERSION}::ConfigGui KF${QT_MAJOR_VERSION}::CoreAddons KF${QT_MAJOR_VERSION}::SonnetCore KF${QT_MAJOR_VERSION}::ItemModels Quotient${QUOTIENT_SUFFIX} cmark::cmark ${QTKEYCHAIN_LIBRARIES} QCoro::Core)
kconfig_add_kcfg_files(neochat GENERATE_MOC neochatconfig.kcfgc)
if(NEOCHAT_FLATPAK)

View File

@@ -3,8 +3,8 @@
#include "actionshandler.h"
#include <Quotient/csapi/joining.h>
#include <Quotient/events/roommemberevent.h>
#include <csapi/joining.h>
#include <events/roommemberevent.h>
#include <cmark.h>

View File

@@ -5,7 +5,7 @@
#include <QObject>
#include <Quotient/events/roommessageevent.h>
#include <events/roommessageevent.h>
#include "neochatroom.h"

View File

@@ -31,15 +31,16 @@
#include <signal.h>
#include <Quotient/accountregistry.h>
#include <Quotient/connection.h>
#include <Quotient/csapi/content-repo.h>
#include <Quotient/csapi/logout.h>
#include <Quotient/csapi/profile.h>
#include <Quotient/jobs/downloadfilejob.h>
#include <Quotient/qt_connection_util.h>
#include <Quotient/csapi/notifications.h>
#include <Quotient/eventstats.h>
#include "accountregistry.h"
#include <connection.h>
#include <csapi/content-repo.h>
#include <csapi/logout.h>
#include <csapi/profile.h>
#include <jobs/downloadfilejob.h>
#include <qt_connection_util.h>
#include <eventstats.h>
#include "neochatconfig.h"
#include "neochatroom.h"
@@ -101,17 +102,17 @@ Controller::Controller(QObject *parent)
}
#endif
connect(&m_accountRegistry, &AccountRegistry::accountCountChanged, this, &Controller::activeConnectionIndexChanged);
connect(&Accounts, &AccountRegistry::accountCountChanged, this, &Controller::activeConnectionIndexChanged);
static int oldAccountCount = 0;
connect(&m_accountRegistry, &AccountRegistry::accountCountChanged, this, [this]() {
if (m_accountRegistry.size() > oldAccountCount) {
auto connection = m_accountRegistry.accounts()[m_accountRegistry.size() - 1];
connect(&Accounts, &AccountRegistry::accountCountChanged, this, [this]() {
if (Accounts.size() > oldAccountCount) {
auto connection = Accounts.accounts()[Accounts.size() - 1];
connect(connection, &Connection::syncDone, this, [connection]() {
NotificationsManager::instance().handleNotifications(connection);
});
}
oldAccountCount = m_accountRegistry.size();
oldAccountCount = Accounts.size();
});
QTimer::singleShot(0, this, [this] {
@@ -147,10 +148,10 @@ void Controller::logout(Connection *conn, bool serverSideLogout)
job.start();
loop.exec();
if (m_accountRegistry.count() > 1) {
if (Accounts.count() > 1) {
// Only set the connection if the the account being logged out is currently active
if (conn == activeConnection()) {
setActiveConnection(m_accountRegistry.accounts()[0]);
setActiveConnection(Accounts.accounts()[0]);
}
} else {
setActiveConnection(nullptr);
@@ -165,7 +166,7 @@ void Controller::addConnection(Connection *c)
{
Q_ASSERT_X(c, __FUNCTION__, "Attempt to add a null connection");
m_accountRegistry.add(c);
Accounts.add(c);
c->setLazyLoading(true);
@@ -180,7 +181,7 @@ void Controller::addConnection(Connection *c)
});
connect(c, &Connection::requestFailed, this, [this](BaseJob *job) {
if (job->error() == BaseJob::UserConsentRequired) {
if (job->error() == BaseJob::UserConsentRequiredError) {
Q_EMIT userConsentRequired(job->errorUrl());
}
});
@@ -247,7 +248,7 @@ void Controller::invokeLogin()
connect(connection, &Connection::networkError, this, [this](const QString &error, const QString &, int, int) {
Q_EMIT errorOccured(i18n("Network Error: %1", error));
});
connection->assumeIdentity(account.userId(), accessToken);
connection->assumeIdentity(account.userId(), accessToken, account.deviceId());
});
}
}
@@ -263,7 +264,7 @@ QKeychain::ReadPasswordJob *Controller::loadAccessTokenFromKeyChain(const Accoun
job->setKey(account.userId());
// Handling of errors
connect(job, &QKeychain::Job::finished, this, [this, job]() {
connect(job, &QKeychain::Job::finished, this, [this, &account, job]() {
if (job->error() == QKeychain::Error::NoError) {
return;
}
@@ -391,7 +392,7 @@ NeochatChangePasswordJob::NeochatChangePasswordJob(const QString &newPassword, b
int Controller::accountCount() const
{
return m_accountRegistry.count();
return Accounts.count();
}
void Controller::setQuitOnLastWindowClosed()
@@ -625,10 +626,10 @@ void Controller::setApplicationProxy()
int Controller::activeConnectionIndex() const
{
auto result = std::find_if(m_accountRegistry.accounts().begin(), m_accountRegistry.accounts().end(), [this](const auto &it) {
auto result = std::find_if(Accounts.accounts().begin(), Accounts.accounts().end(), [this](const auto &it) {
return it == m_connection;
});
return result - m_accountRegistry.accounts().begin();
return result - Accounts.accounts().begin();
}
int Controller::quotientMinorVersion() const
@@ -681,9 +682,4 @@ QVariantList Controller::getSupportedRoomVersions(Quotient::Connection *connecti
return supportedRoomVersions;
}
AccountRegistry &Controller::accounts()
{
return m_accountRegistry;
}
#include "moc_controller.cpp"

View File

@@ -9,9 +9,8 @@
#include <KFormat>
#include <Quotient/accountregistry.h>
#include <Quotient/jobs/basejob.h>
#include <Quotient/settings.h>
#include <jobs/basejob.h>
#include <settings.h>
class NeoChatRoom;
class NeoChatUser;
@@ -230,8 +229,6 @@ public:
Q_INVOKABLE QVariantList getSupportedRoomVersions(Quotient::Connection *connection);
Quotient::AccountRegistry &accounts();
private:
explicit Controller(QObject *parent = nullptr);
@@ -248,7 +245,6 @@ private:
bool hasWindowSystem() const;
QPointer<PushRuleModel> m_pushRuleModel;
Quotient::AccountRegistry m_accountRegistry;
private Q_SLOTS:
void invokeLogin();

View File

@@ -4,8 +4,8 @@
#pragma once
#include <QVector>
#include <Quotient/events/eventcontent.h>
#include <Quotient/events/stateevent.h>
#include <events/eventcontent.h>
#include <events/stateevent.h>
namespace Quotient
{

View File

@@ -3,7 +3,7 @@
#pragma once
#include <Quotient/events/stateevent.h>
#include <events/stateevent.h>
namespace Quotient
{

View File

@@ -3,7 +3,8 @@
#pragma once
#include <Quotient/events/roomevent.h>
#include <events/eventcontent.h>
#include <events/roomevent.h>
namespace Quotient
{

View File

@@ -3,10 +3,8 @@
#include "linkpreviewer.h"
#include "controller.h"
#include <Quotient/connection.h>
#include <Quotient/csapi/content-repo.h>
#include <connection.h>
#include <csapi/content-repo.h>
#include "neochatroom.h"

View File

@@ -3,9 +3,10 @@
#include "login.h"
#include <Quotient/accountregistry.h>
#include <Quotient/connection.h>
#include <Quotient/qt_connection_util.h>
#include <accountregistry.h>
#include <connection.h>
#include <qt_connection_util.h>
#include "controller.h"
@@ -42,7 +43,7 @@ void Login::init()
return;
}
m_isLoggedIn = Controller::instance().accounts().isLoggedIn(m_matrixId);
m_isLoggedIn = Accounts.isLoggedIn(m_matrixId);
Q_EMIT isLoggedInChanged();
if (m_isLoggedIn) {
return;

View File

@@ -4,7 +4,6 @@
#include <QCommandLineParser>
#include <QIcon>
#include <QNetworkProxyFactory>
#include <QObject>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QQmlNetworkAccessManagerFactory>
@@ -29,11 +28,10 @@
#include "neochat-version.h"
#include <Quotient/keyverificationsession.h>
#include <Quotient/accountregistry.h>
#include <Quotient/networkaccessmanager.h>
#include <Quotient/room.h>
#include <Quotient/util.h>
#include <accountregistry.h>
#include <networkaccessmanager.h>
#include <room.h>
#include <util.h>
#include "actionshandler.h"
#include "blurhashimageprovider.h"
@@ -51,7 +49,6 @@
#include "models/collapsestateproxymodel.h"
#include "models/customemojimodel.h"
#include "models/devicesmodel.h"
#include "models/devicesproxymodel.h"
#include "models/emojimodel.h"
#include "models/emoticonfiltermodel.h"
#include "models/imagepacksmodel.h"
@@ -83,7 +80,7 @@
#include "spacehierarchycache.h"
#include "urlhelper.h"
#include "windowcontroller.h"
#include <keyverificationsession.h>
#ifdef HAVE_COLORSCHEME
#include "colorschemer.h"
#endif
@@ -219,7 +216,7 @@ int main(int argc, char *argv[])
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "LoginHelper", login);
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "UrlHelper", &urlHelper);
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "EmojiModel", &EmojiModel::instance());
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "AccountRegistry", &Controller::instance().accounts());
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "AccountRegistry", &Quotient::Accounts);
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "SpaceHierarchyCache", &SpaceHierarchyCache::instance());
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "CustomEmojiModel", &CustomEmojiModel::instance());
qmlRegisterType<ActionsHandler>("org.kde.neochat", 1, 0, "ActionsHandler");
@@ -239,7 +236,6 @@ int main(int argc, char *argv[])
qmlRegisterType<SortFilterRoomListModel>("org.kde.neochat", 1, 0, "SortFilterRoomListModel");
qmlRegisterType<SortFilterSpaceListModel>("org.kde.neochat", 1, 0, "SortFilterSpaceListModel");
qmlRegisterType<DevicesModel>("org.kde.neochat", 1, 0, "DevicesModel");
qmlRegisterType<DevicesProxyModel>("org.kde.neochat", 1, 0, "DevicesProxyModel");
qmlRegisterType<LinkPreviewer>("org.kde.neochat", 1, 0, "LinkPreviewer");
qmlRegisterType<CompletionModel>("org.kde.neochat", 1, 0, "CompletionModel");
qmlRegisterType<StateModel>("org.kde.neochat", 1, 0, "StateModel");
@@ -324,18 +320,11 @@ int main(int argc, char *argv[])
QCommandLineParser parser;
parser.setApplicationDescription(i18n("Client for the matrix communication protocol"));
parser.addPositionalArgument(QStringLiteral("urls"), i18n("Supports matrix: url scheme"));
parser.addOption(QCommandLineOption("ignore-ssl-errors", i18n("Ignore all SSL Errors, e.g., unsigned certificates.")));
about.setupCommandLine(&parser);
parser.process(app);
about.processCommandLine(&parser);
if (parser.isSet("ignore-ssl-errors")) {
QObject::connect(NetworkAccessManager::instance(), &QNetworkAccessManager::sslErrors, NetworkAccessManager::instance(), [](QNetworkReply *reply) {
reply->ignoreSslErrors();
});
}
engine.addImageProvider(QLatin1String("mxc"), new MatrixImageProvider);
engine.addImageProvider(QLatin1String("blurhash"), new BlurhashImageProvider);

View File

@@ -13,7 +13,7 @@
#include <KLocalizedString>
#include "controller.h"
#include <Quotient/connection.h>
#include <connection.h>
using namespace Quotient;

View File

@@ -6,7 +6,7 @@
#include <QQuickAsyncImageProvider>
#include <Quotient/jobs/mediathumbnailjob.h>
#include <jobs/mediathumbnailjob.h>
#include <QReadWriteLock>
@@ -26,7 +26,7 @@ class ThumbnailResponse : public QQuickImageResponse
{
Q_OBJECT
public:
explicit ThumbnailResponse(QString mediaId, QSize requestedSize);
ThumbnailResponse(QString mediaId, QSize requestedSize);
~ThumbnailResponse() override = default;
private Q_SLOTS:

View File

@@ -3,7 +3,7 @@
#include "accountemoticonmodel.h"
#include <Quotient/csapi/content-repo.h>
#include <csapi/content-repo.h>
#include <qcoro/qcorosignal.h>
using namespace Quotient;

View File

@@ -4,14 +4,12 @@
#pragma once
#include "events/imagepackevent.h"
#include <QAbstractListModel>
#include <QCoroTask>
#include <QObject>
#include <QPointer>
#include <QVector>
#include <Quotient/connection.h>
#include <connection.h>
class ImagePacksModel;

View File

@@ -6,8 +6,8 @@
#include "controller.h"
#include "neochatroom.h"
#include "roommanager.h"
#include <Quotient/events/roommemberevent.h>
#include <Quotient/events/roompowerlevelsevent.h>
#include <events/roommemberevent.h>
#include <events/roompowerlevelsevent.h>
#include <KLocalizedString>
@@ -436,10 +436,7 @@ QVector<ActionsModel::Action> actions{
Q_EMIT room->showMessage(NeoChatRoom::Info, i18nc("<user> is already banned from this room.", "%1 is already banned from this room.", text));
return QString();
}
auto plEvent = room->currentState().get<RoomPowerLevelsEvent>();
if (!plEvent) {
return QString();
}
auto plEvent = room->getCurrentState<RoomPowerLevelsEvent>();
if (plEvent->ban() > plEvent->powerLevelForUser(room->localUser()->id())) {
Q_EMIT room->showMessage(NeoChatRoom::Error, i18n("You are not allowed to ban users from this room."));
return QString();
@@ -469,10 +466,7 @@ QVector<ActionsModel::Action> actions{
Q_EMIT room->showMessage(NeoChatRoom::Error, i18nc("'<text>' does not look like a matrix id.", "'%1' does not look like a matrix id.", text));
return QString();
}
auto plEvent = room->currentState().get<RoomPowerLevelsEvent>();
if (!plEvent) {
return QString();
}
auto plEvent = room->getCurrentState<RoomPowerLevelsEvent>();
if (plEvent->ban() > plEvent->powerLevelForUser(room->localUser()->id())) {
Q_EMIT room->showMessage(NeoChatRoom::Error, i18n("You are not allowed to unban users from this room."));
return QString();
@@ -512,10 +506,7 @@ QVector<ActionsModel::Action> actions{
Q_EMIT room->showMessage(NeoChatRoom::Error, i18nc("<username> is not in this room", "%1 is not in this room.", parts[0]));
return QString();
}
auto plEvent = room->currentState().get<RoomPowerLevelsEvent>();
if (!plEvent) {
return QString();
}
auto plEvent = room->getCurrentState<RoomPowerLevelsEvent>();
auto kick = plEvent->kick();
if (plEvent->powerLevelForUser(room->localUser()->id()) < kick) {
Q_EMIT room->showMessage(NeoChatRoom::Error, i18n("You are not allowed to kick users from this room."));

View File

@@ -5,7 +5,7 @@
#include <KLazyLocalizedString>
#include <QAbstractListModel>
#include <Quotient/events/roommessageevent.h>
#include <events/roommessageevent.h>
class NeoChatRoom;

View File

@@ -71,7 +71,7 @@ public:
};
Q_ENUM(Roles)
explicit CompletionModel(QObject *parent = nullptr);
CompletionModel(QObject *parent = nullptr);
/**
* @brief Get the given role value at the given index.

View File

@@ -9,9 +9,10 @@
#include "controller.h"
#include "emojimodel.h"
#include <Quotient/connection.h>
#include <Quotient/csapi/account-data.h>
#include <Quotient/csapi/content-repo.h>
#include <connection.h>
#include <csapi/account-data.h>
#include <csapi/content-repo.h>
#include <events/eventcontent.h>
using namespace Quotient;

View File

@@ -3,19 +3,23 @@
#include "devicesmodel.h"
#include <csapi/device_management.h>
#include "controller.h"
#include <KLocalizedString>
#include <Quotient/csapi/device_management.h>
#include <Quotient/connection.h>
#include <Quotient/user.h>
#include <connection.h>
#include <user.h>
using namespace Quotient;
DevicesModel::DevicesModel(QObject *parent)
: QAbstractListModel(parent)
{
connect(&Controller::instance(), &Controller::activeConnectionChanged, this, [this]() {
DevicesModel::fetchDevices();
Q_EMIT connectionChanged();
});
fetchDevices();
}
void DevicesModel::fetchDevices()
@@ -26,7 +30,6 @@ void DevicesModel::fetchDevices()
beginResetModel();
m_devices = job->devices();
endResetModel();
Q_EMIT countChanged();
});
}
}
@@ -37,33 +40,16 @@ QVariant DevicesModel::data(const QModelIndex &index, int role) const
return {};
}
const auto &device = m_devices[index.row()];
switch (role) {
case Id:
return device.deviceId;
return m_devices[index.row()].deviceId;
case DisplayName:
return device.displayName;
return m_devices[index.row()].displayName;
case LastIp:
return device.lastSeenIp;
return m_devices[index.row()].lastSeenIp;
case LastTimestamp:
if (device.lastSeenTs) {
return *device.lastSeenTs;
} else {
return false;
}
case Type:
if (device.deviceId == m_connection->deviceId()) {
return This;
}
if (!m_connection->isKnownE2eeCapableDevice(m_connection->userId(), device.deviceId)) {
return Unencrypted;
}
if (m_connection->isVerifiedDevice(m_connection->userId(), device.deviceId)) {
return Verified;
} else {
return Unverified;
}
if (m_devices[index.row()].lastSeenTs)
return *m_devices[index.row()].lastSeenTs;
}
return {};
}
@@ -76,21 +62,11 @@ int DevicesModel::rowCount(const QModelIndex &parent) const
QHash<int, QByteArray> DevicesModel::roleNames() const
{
return {
{Id, "id"},
{DisplayName, "displayName"},
{LastIp, "lastIp"},
{LastTimestamp, "lastTimestamp"},
{Type, "type"},
};
return {{Id, "id"}, {DisplayName, "displayName"}, {LastIp, "lastIp"}, {LastTimestamp, "lastTimestamp"}};
}
void DevicesModel::logout(const QString &deviceId, const QString &password)
void DevicesModel::logout(int index, const QString &password)
{
int index;
for (index = 0; m_devices[index].deviceId != deviceId; index++)
;
auto job = Controller::instance().activeConnection()->callApi<NeochatDeleteDeviceJob>(m_devices[index].deviceId);
connect(job, &BaseJob::result, this, [this, job, password, index] {
@@ -98,7 +74,6 @@ void DevicesModel::logout(const QString &deviceId, const QString &password)
beginRemoveRows(QModelIndex(), index, index);
m_devices.remove(index);
endRemoveRows();
Q_EMIT countChanged();
};
if (job->error() != BaseJob::Success) {
QJsonObject replyData = job->jsonData();
@@ -116,11 +91,8 @@ void DevicesModel::logout(const QString &deviceId, const QString &password)
});
}
void DevicesModel::setName(const QString &deviceId, const QString &name)
void DevicesModel::setName(int index, const QString &name)
{
int index;
for (index = 0; m_devices[index].deviceId != deviceId; index++);
auto job = Controller::instance().activeConnection()->callApi<UpdateDeviceJob>(m_devices[index].deviceId, name);
QString oldName = m_devices[index].displayName;
beginResetModel();
@@ -135,27 +107,7 @@ void DevicesModel::setName(const QString &deviceId, const QString &name)
Connection *DevicesModel::connection() const
{
return m_connection;
}
void DevicesModel::setConnection(Connection *connection)
{
if (m_connection) {
disconnect(m_connection, nullptr, this, nullptr);
}
m_connection = connection;
Q_EMIT connectionChanged();
fetchDevices();
connect(m_connection, &Connection::sessionVerified, this, [this](const QString &userId, const QString &deviceId) {
Q_UNUSED(deviceId);
if (userId == Controller::instance().activeConnection()->userId()) {
fetchDevices();
}
});
connect(m_connection, &Connection::finishedQueryingKeys, this, [this]() {
fetchDevices();
});
return Controller::instance().activeConnection();
}
#include "moc_devicesmodel.cpp"

View File

@@ -4,9 +4,8 @@
#pragma once
#include <QAbstractListModel>
#include <QPointer>
#include <Quotient/csapi/definitions/client_device.h>
#include <csapi/definitions/client_device.h>
namespace Quotient
{
@@ -29,7 +28,7 @@ class DevicesModel : public QAbstractListModel
/**
* @brief The current connection that the model is getting its devices from.
*/
Q_PROPERTY(Quotient::Connection *connection READ connection WRITE setConnection NOTIFY connectionChanged REQUIRED)
Q_PROPERTY(Quotient::Connection *connection READ connection NOTIFY connectionChanged)
public:
/**
@@ -40,17 +39,10 @@ public:
DisplayName, /**< Display name set by the user for this device. */
LastIp, /**< The IP address where this device was last seen. */
LastTimestamp, /**< The timestamp when this devices was last seen. */
Type, /**< The category to sort this device into. */
};
Q_ENUM(Roles)
enum DeviceType {
This,
Verified,
Unverified,
Unencrypted,
};
Q_ENUM(DeviceType);
DevicesModel(QObject *parent = nullptr);
/**
* @brief Get the given role value at the given index.
@@ -74,27 +66,21 @@ public:
QHash<int, QByteArray> roleNames() const override;
/**
* @brief Logout the device with the given id.
* @brief Logout the device at the given index.
*/
Q_INVOKABLE void logout(const QString &deviceId, const QString &password);
Q_INVOKABLE void logout(int index, const QString &password);
/**
* @brief Set the display name of the device with the given id.
* @brief Set the display name of the device at the given index.
*/
Q_INVOKABLE void setName(const QString &deviceId, const QString &name);
Q_INVOKABLE void setName(int index, const QString &name);
explicit DevicesModel(QObject *parent = nullptr);
[[nodiscard]] Quotient::Connection *connection() const;
void setConnection(Quotient::Connection *connection);
Quotient::Connection *connection() const;
Q_SIGNALS:
void connectionChanged();
void countChanged();
private:
void fetchDevices();
QVector<Quotient::Device> m_devices;
QPointer<Quotient::Connection> m_connection;
};

View File

@@ -1,30 +0,0 @@
// SPDX-FileCopyrightText: 2023 Tobias Fella <tobias.fella@kde.org>
// SPDX-License-Identifier: GPL-2.0-or-later
#include "devicesproxymodel.h"
#include "devicesmodel.h"
int DevicesProxyModel::type() const
{
return m_type;
}
void DevicesProxyModel::setType(int type)
{
m_type = type;
Q_EMIT typeChanged();
}
bool DevicesProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
{
Q_UNUSED(source_parent)
return sourceModel()->data(sourceModel()->index(source_row, 0), DevicesModel::Type).toInt() == m_type;
}
DevicesProxyModel::DevicesProxyModel(QObject *parent)
: QSortFilterProxyModel(parent)
, m_type(0)
{
setSortRole(DevicesModel::LastTimestamp);
sort(0, Qt::DescendingOrder);
}
#include "moc_devicesproxymodel.cpp"

View File

@@ -1,25 +0,0 @@
// SPDX-FileCopyrightText: 2023 Tobias Fella <tobias.fella@kde.org>
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <QSortFilterProxyModel>
class DevicesProxyModel : public QSortFilterProxyModel
{
Q_OBJECT
Q_PROPERTY(int type READ type WRITE setType NOTIFY typeChanged);
public:
DevicesProxyModel(QObject *parent = nullptr);
[[nodiscard]] bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override;
void setType(int type);
[[nodiscard]] int type() const;
Q_SIGNALS:
void typeChanged();
private:
int m_type;
};

View File

@@ -1,112 +0,0 @@
// SPDX-FileCopyrightText: 2022 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 "keywordnotificationrulemodel.h"
#include "controller.h"
#include "notificationsmanager.h"
#include <QDebug>
#include <Quotient/connection.h>
#include <Quotient/converters.h>
#include <Quotient/csapi/definitions/push_ruleset.h>
#include <Quotient/csapi/pushrules.h>
#include <Quotient/jobs/basejob.h>
KeywordNotificationRuleModel::KeywordNotificationRuleModel(QObject *parent)
: QAbstractListModel(parent)
{
if (Controller::instance().activeConnection()) {
controllerConnectionChanged();
}
connect(&Controller::instance(), &Controller::activeConnectionChanged, this, &KeywordNotificationRuleModel::controllerConnectionChanged);
}
void KeywordNotificationRuleModel::controllerConnectionChanged()
{
connect(Controller::instance().activeConnection(), &Quotient::Connection::accountDataChanged, this, &KeywordNotificationRuleModel::updateNotificationRules);
updateNotificationRules("m.push_rules");
}
void KeywordNotificationRuleModel::updateNotificationRules(const QString &type)
{
if (type != "m.push_rules") {
return;
}
const QJsonObject ruleDataJson = Controller::instance().activeConnection()->accountDataJson("m.push_rules");
const Quotient::PushRuleset ruleData = Quotient::fromJson<Quotient::PushRuleset>(ruleDataJson["global"].toObject());
const QVector<Quotient::PushRule> contentRules = ruleData.content;
beginResetModel();
m_notificationRules.clear();
for (const auto &i : contentRules) {
if (!m_notificationRules.contains(i.ruleId) && i.ruleId[0] != '.') {
m_notificationRules.append(i.ruleId);
}
}
endResetModel();
}
QVariant KeywordNotificationRuleModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid()) {
return {};
}
if (index.row() >= m_notificationRules.count()) {
qDebug() << "KeywordNotificationRuleModel, something's wrong: index.row() >= m_notificationRules.count()";
return {};
}
if (role == NameRole) {
return m_notificationRules.at(index.row());
}
return {};
}
int KeywordNotificationRuleModel::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent)
return m_notificationRules.count();
}
void KeywordNotificationRuleModel::addKeyword(const QString &keyword)
{
if (m_notificationRules.count() == 0) {
NotificationsManager::instance().initializeKeywordNotificationAction();
}
const QVector<QVariant> actions = NotificationsManager::instance().getKeywordNotificationActions();
auto job = Controller::instance()
.activeConnection()
->callApi<Quotient::SetPushRuleJob>("global", "content", keyword, actions, "", "", QVector<Quotient::PushCondition>(), keyword);
connect(job, &Quotient::BaseJob::success, this, [this, keyword]() {
beginInsertRows(QModelIndex(), m_notificationRules.count(), m_notificationRules.count());
m_notificationRules.append(keyword);
endInsertRows();
});
}
void KeywordNotificationRuleModel::removeKeywordAtIndex(int index)
{
auto job = Controller::instance().activeConnection()->callApi<Quotient::DeletePushRuleJob>("global", "content", m_notificationRules[index]);
connect(job, &Quotient::BaseJob::success, this, [this, index]() {
beginRemoveRows(QModelIndex(), index, index);
m_notificationRules.removeAt(index);
endRemoveRows();
if (m_notificationRules.count() == 0) {
NotificationsManager::instance().deactivateKeywordNotificationAction();
}
});
}
QHash<int, QByteArray> KeywordNotificationRuleModel::roleNames() const
{
return {{NameRole, QByteArrayLiteral("name")}};
}
#include "moc_keywordnotificationrulemodel.cpp"

View File

@@ -1,66 +0,0 @@
// SPDX-FileCopyrightText: 2022 James Graham <james.h.graham@protonmail.com>
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
#pragma once
#include <Quotient/csapi/definitions/push_rule.h>
#include <QAbstractListModel>
/**
* @class KeywordNotificationRuleModel
*
* This class defines the model for managing notification push rule keywords.
*/
class KeywordNotificationRuleModel : public QAbstractListModel
{
Q_OBJECT
public:
/**
* @brief Defines the model roles.
*/
enum EventRoles {
NameRole = Qt::DisplayRole, /**< The push rule keyword. */
};
KeywordNotificationRuleModel(QObject *parent = nullptr);
/**
* @brief Get the given role value at the given index.
*
* @sa QAbstractItemModel::data
*/
[[nodiscard]] QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
/**
* @brief Number of rows in the model.
*
* @sa QAbstractItemModel::rowCount
*/
[[nodiscard]] int rowCount(const QModelIndex &parent = QModelIndex()) const override;
/**
* @brief Returns a mapping from Role enum values to role names.
*
* @sa EventRoles, QAbstractItemModel::roleNames()
*/
[[nodiscard]] QHash<int, QByteArray> roleNames() const override;
/**
* @brief Add a new keyword to the model.
*/
Q_INVOKABLE void addKeyword(const QString &keyword);
/**
* @brief Remove a keyword from the model.
*/
Q_INVOKABLE void removeKeywordAtIndex(int index);
private Q_SLOTS:
void controllerConnectionChanged();
void updateNotificationRules(const QString &type);
private:
QList<QString> m_notificationRules;
};

View File

@@ -4,7 +4,7 @@
#include "livelocationsmodel.h"
#include <Quotient/events/roommessageevent.h>
#include <events/roommessageevent.h>
#include <QDebug>

View File

@@ -110,7 +110,6 @@ QVariant LocationsModel::data(const QModelIndex &index, int roleName) const
int LocationsModel::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent);
return m_locations.size();
}

View File

@@ -9,7 +9,7 @@
#include "neochatroom.h"
#include <Quotient/events/roommessageevent.h>
#include <events/roommessageevent.h>
class LocationsModel : public QAbstractListModel
{

View File

@@ -3,7 +3,7 @@
#include "mediamessagefiltermodel.h"
#include "models/messageeventmodel.h"
#include <Quotient/room.h>
#include <room.h>
MediaMessageFilterModel::MediaMessageFilterModel(QObject *parent)
: QSortFilterProxyModel(parent)

View File

@@ -31,7 +31,7 @@ public:
};
Q_ENUM(Roles)
explicit MediaMessageFilterModel(QObject *parent = nullptr);
MediaMessageFilterModel(QObject *parent = nullptr);
/**
* @brief Custom filter to show only image and video messages.

View File

@@ -5,18 +5,17 @@
#include "messageeventmodel_logging.h"
#include "neochatconfig.h"
#include <Quotient/connection.h>
#include <Quotient/csapi/rooms.h>
#include <Quotient/events/reactionevent.h>
#include <Quotient/events/redactionevent.h>
#include <Quotient/events/roomavatarevent.h>
#include <Quotient/events/roommemberevent.h>
#include <Quotient/events/simplestateevents.h>
#include <Quotient/user.h>
#include <connection.h>
#include <events/reactionevent.h>
#include <events/redactionevent.h>
#include <events/roomavatarevent.h>
#include <events/roommemberevent.h>
#include <events/simplestateevents.h>
#include <qt_connection_util.h>
#include <user.h>
#include "events/pollevent.h"
#include <Quotient/events/stickerevent.h>
#include "events/stickerevent.h"
#include <QDebug>
#include <QGuiApplication>
@@ -228,7 +227,7 @@ void MessageEventModel::setRoom(NeoChatRoom *room)
beginRemoveRows({}, i, i);
});
connect(m_currentRoom, &Room::pendingEventDiscarded, this, &MessageEventModel::endRemoveRows);
connect(m_currentRoom, &Room::fullyReadMarkerMoved, this, [this](const QString &fromEventId, const QString &toEventId) {
connect(m_currentRoom, &Room::readMarkerMoved, this, [this](const QString &fromEventId, const QString &toEventId) {
Q_UNUSED(fromEventId);
moveReadMarker(toEventId);
});
@@ -609,7 +608,7 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
return EventStatus::Hidden;
}
if (evt.isStateEvent() && static_cast<const StateEvent &>(evt).repeatsState()) {
if (evt.isStateEvent() && static_cast<const StateEventBase &>(evt).repeatsState()) {
return EventStatus::Hidden;
}
@@ -1053,7 +1052,7 @@ void MessageEventModel::createReactionModelForEvent(const Quotient::RoomMessageE
return;
}
auto eventId = event->id();
const auto &annotations = m_currentRoom->relatedEvents(eventId, EventRelation::AnnotationType);
const auto &annotations = m_currentRoom->relatedEvents(eventId, EventRelation::Annotation());
if (annotations.isEmpty()) {
if (m_reactionModels.contains(eventId)) {
delete m_reactionModels[eventId];
@@ -1068,7 +1067,7 @@ void MessageEventModel::createReactionModelForEvent(const Quotient::RoomMessageE
continue;
}
if (const auto &e = eventCast<const ReactionEvent>(a)) {
reactions[e->key()].append(static_cast<NeoChatUser *>(m_currentRoom->user(e->senderId())));
reactions[e->relation().key].append(static_cast<NeoChatUser *>(m_currentRoom->user(e->senderId())));
}
}

View File

@@ -16,7 +16,7 @@ class MessageFilterModel : public QSortFilterProxyModel
{
Q_OBJECT
public:
explicit MessageFilterModel(QObject *parent = nullptr);
MessageFilterModel(QObject *parent = nullptr);
/**
* @brief Custom filter function to remove hidden messages.

View File

@@ -3,7 +3,7 @@
#include "publicroomlistmodel.h"
#include <Quotient/connection.h>
#include <connection.h>
using namespace Quotient;

View File

@@ -6,7 +6,7 @@
#include <QAbstractListModel>
#include <QObject>
#include <Quotient/csapi/list_public_rooms.h>
#include <csapi/list_public_rooms.h>
namespace Quotient
{
@@ -64,7 +64,7 @@ public:
IsJoinedRole, /**< Whether the local user has joined the room. */
};
explicit PublicRoomListModel(QObject *parent = nullptr);
PublicRoomListModel(QObject *parent = nullptr);
/**
* @brief Get the given role value at the given index.

View File

@@ -5,11 +5,12 @@
#include <QDebug>
#include <Quotient/connection.h>
#include <Quotient/converters.h>
#include <Quotient/csapi/definitions/push_ruleset.h>
#include <Quotient/csapi/pushrules.h>
#include <Quotient/jobs/basejob.h>
#include <connection.h>
#include <converters.h>
#include <csapi/definitions/push_ruleset.h>
#include <csapi/pushrules.h>
#include <jobs/basejob.h>
#include <qobjectdefs.h>
#include "controller.h"
#include "neochatconfig.h"

View File

@@ -5,7 +5,7 @@
#include <QAbstractListModel>
#include <Quotient/csapi/definitions/push_rule.h>
#include <csapi/definitions/push_rule.h>
#include "notificationsmanager.h"
@@ -172,7 +172,7 @@ public:
};
Q_ENUM(EventRoles)
explicit PushRuleModel(QObject *parent = nullptr);
PushRuleModel(QObject *parent = nullptr);
[[nodiscard]] PushNotificationAction::Action defaultState() const;
void setDefaultState(PushNotificationAction::Action defaultState);

View File

@@ -36,7 +36,7 @@ public:
HasLocalUser, /**< Whether the local user is in the list of authors. */
};
explicit ReactionModel(QObject *parent = nullptr, QList<Reaction> reactions = {}, NeoChatUser *localUser = nullptr);
ReactionModel(QObject *parent = nullptr, QList<Reaction> reactions = {}, NeoChatUser *localUser = nullptr);
/**
* @brief Get the given role value at the given index.

View File

@@ -8,8 +8,7 @@
#include "neochatroom.h"
#include "roommanager.h"
#include "spacehierarchycache.h"
#include <Quotient/user.h>
#include "user.h"
#include <QDebug>
#if QT_VERSION < QT_VERSION_CHECK(6, 6, 0)
@@ -156,7 +155,7 @@ void RoomListModel::connectRoomSignals(NeoChatRoom *room)
connect(room, &Room::displaynameChanged, this, [this, room] {
refresh(room, {DisplayNameRole});
});
connect(room, &Room::unreadStatsChanged, this, [this, room] {
connect(room, &Room::unreadMessagesChanged, this, [this, room] {
refresh(room, {NotificationCountRole, HighlightCountRole});
});
connect(room, &Room::notificationCountChanged, this, [this, room] {
@@ -338,7 +337,7 @@ QVariant RoomListModel::data(const QModelIndex &index, int role) const
if (role == AvatarImageRole) {
return room->avatar(128);
}
if (role == RoomIdRole) {
if (role == IdRole) {
return room->id();
}
if (role == IsSpaceRole) {
@@ -379,7 +378,7 @@ QHash<int, QByteArray> RoomListModel::roleNames() const
roles[CategoryVisibleRole] = "categoryVisible";
roles[SubtitleTextRole] = "subtitleText";
roles[IsSpaceRole] = "isSpace";
roles[RoomIdRole] = "roomId";
roles[IdRole] = "id";
roles[IsChildSpaceRole] = "isChildSpace";
return roles;
}

View File

@@ -3,7 +3,7 @@
#pragma once
#include <Quotient/events/roomevent.h>
#include <events/roomevent.h>
#include <QAbstractListModel>
@@ -72,7 +72,7 @@ public:
CategoryVisibleRole, /**< If the room's category is visible. */
SubtitleTextRole, /**< The text to show as the room subtitle. */
AvatarImageRole, /**< The room avatar as an image. */
RoomIdRole, /**< The room matrix ID. */
IdRole, /**< The room matrix ID. */
IsSpaceRole, /**< Whether the room is a space. */
IsChildSpaceRole, /**< Whether this space is a child of a different space. */
};

View File

@@ -2,15 +2,12 @@
// SPDX-License-Identifier: LGPL-2.0-or-later
#include "searchmodel.h"
#include "events/stickerevent.h"
#include "messageeventmodel.h"
#include "neochatroom.h"
#include "neochatuser.h"
#include <Quotient/events/stickerevent.h>
#include <KLocalizedString>
#include <Quotient/connection.h>
#include <connection.h>
using namespace Quotient;

View File

@@ -6,7 +6,7 @@
#include <QAbstractListModel>
#include <QString>
#include <Quotient/csapi/search.h>
#include <csapi/search.h>
namespace Quotient
{

View File

@@ -5,7 +5,7 @@
#include "controller.h"
#include <Quotient/connection.h>
#include <connection.h>
#include <QDebug>

View File

@@ -3,7 +3,7 @@
#pragma once
#include <Quotient/csapi/list_public_rooms.h>
#include <csapi/list_public_rooms.h>
#include <QAbstractListModel>
#include <QPointer>

View File

@@ -87,8 +87,7 @@ bool SortFilterRoomListModel::filterAcceptsRow(int source_row, const QModelIndex
return acceptRoom;
} else {
const auto &rooms = SpaceHierarchyCache::instance().getRoomListForSpace(m_activeSpaceId, false);
return std::find(rooms.begin(), rooms.end(), sourceModel()->data(sourceModel()->index(source_row, 0), RoomListModel::RoomIdRole).toString())
!= rooms.end()
return std::find(rooms.begin(), rooms.end(), sourceModel()->data(sourceModel()->index(source_row, 0), RoomListModel::IdRole).toString()) != rooms.end()
&& acceptRoom;
}
}

View File

@@ -8,7 +8,7 @@
SortFilterSpaceListModel::SortFilterSpaceListModel(QObject *parent)
: QSortFilterProxyModel{parent}
{
setSortRole(RoomListModel::RoomIdRole);
setSortRole(RoomListModel::IdRole);
sort(0);
invalidateFilter();
connect(this, &QAbstractProxyModel::sourceModelChanged, this, [this]() {
@@ -33,8 +33,8 @@ bool SortFilterSpaceListModel::filterAcceptsRow(int source_row, const QModelInde
bool SortFilterSpaceListModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const
{
const auto idLeft = sourceModel()->data(source_left, RoomListModel::RoomIdRole).toString();
const auto idRight = sourceModel()->data(source_right, RoomListModel::RoomIdRole).toString();
const auto idLeft = sourceModel()->data(source_left, RoomListModel::IdRole).toString();
const auto idRight = sourceModel()->data(source_right, RoomListModel::IdRole).toString();
return idLeft < idRight;
}

View File

@@ -3,8 +3,8 @@
#include "userdirectorylistmodel.h"
#include <Quotient/connection.h>
#include <Quotient/room.h>
#include <connection.h>
#include <room.h>
using namespace Quotient;

View File

@@ -6,7 +6,7 @@
#include <QAbstractListModel>
#include <QObject>
#include <Quotient/csapi/users.h>
#include <csapi/users.h>
namespace Quotient
{

View File

@@ -3,8 +3,8 @@
#include "userlistmodel.h"
#include <Quotient/connection.h>
#include <Quotient/events/roompowerlevelsevent.h>
#include <connection.h>
#include <events/roompowerlevelsevent.h>
#include "neochatroom.h"
@@ -78,11 +78,8 @@ QVariant UserListModel::data(const QModelIndex &index, int role) const
return QVariant::fromValue(user);
}
if (role == PowerLevelRole) {
auto plEvent = m_currentRoom->currentState().get<RoomPowerLevelsEvent>();
if (!plEvent) {
return 0;
}
return plEvent->powerLevelForUser(user->id());
auto pl = m_currentRoom->getCurrentState<RoomPowerLevelsEvent>();
return pl->powerLevelForUser(user->id());
}
if (role == PowerLevelStringRole) {
auto pl = m_currentRoom->currentState().get<RoomPowerLevelsEvent>();

View File

@@ -3,8 +3,6 @@
#pragma once
#include <Quotient/room.h>
#include <QAbstractListModel>
#include <QObject>
#include <QPointer>

View File

@@ -12,33 +12,35 @@
#include <QMediaMetaData>
#include <QMediaPlayer>
#include <Quotient/jobs/basejob.h>
#include <jobs/basejob.h>
#include <qcoro/qcorosignal.h>
#include <Quotient/connection.h>
#include <Quotient/csapi/account-data.h>
#include <Quotient/csapi/directory.h>
#include <Quotient/csapi/pushrules.h>
#include <Quotient/csapi/redaction.h>
#include <Quotient/csapi/report_content.h>
#include <Quotient/csapi/room_state.h>
#include <Quotient/csapi/rooms.h>
#include <Quotient/csapi/typing.h>
#include <Quotient/events/encryptionevent.h>
#include <Quotient/events/reactionevent.h>
#include <Quotient/events/redactionevent.h>
#include <Quotient/events/roomavatarevent.h>
#include <Quotient/events/roomcanonicalaliasevent.h>
#include <Quotient/events/roommemberevent.h>
#include <Quotient/events/roompowerlevelsevent.h>
#include <Quotient/events/simplestateevents.h>
#include <Quotient/events/stickerevent.h>
#include <Quotient/jobs/downloadfilejob.h>
#include <Quotient/qt_connection_util.h>
#include <connection.h>
#include <csapi/account-data.h>
#include <csapi/directory.h>
#include <csapi/event_context.h>
#include <csapi/pushrules.h>
#include <csapi/redaction.h>
#include <csapi/report_content.h>
#include <csapi/room_state.h>
#include <csapi/rooms.h>
#include <csapi/typing.h>
#include <events/encryptionevent.h>
#include <events/reactionevent.h>
#include <events/redactionevent.h>
#include <events/roomavatarevent.h>
#include <events/roomcanonicalaliasevent.h>
#include <events/roommemberevent.h>
#include <events/roompowerlevelsevent.h>
#include <events/simplestateevents.h>
#include <jobs/downloadfilejob.h>
#include <qt_connection_util.h>
#include "controller.h"
#include "events/joinrulesevent.h"
#include "events/pollevent.h"
#include "events/stickerevent.h"
#include "filetransferpseudojob.h"
#include "neochatconfig.h"
#include "notificationsmanager.h"
@@ -97,9 +99,7 @@ NeoChatRoom::NeoChatRoom(Connection *connection, QString roomId, JoinState joinS
if (this->joinState() != JoinState::Invite) {
return;
}
auto roomMemberEvent = currentState().get<RoomMemberEvent>(localUser()->id());
Q_ASSERT(roomMemberEvent);
const QString senderId = roomMemberEvent->senderId();
const QString senderId = getCurrentState<RoomMemberEvent>(localUser()->id())->senderId();
QImage avatar_image;
if (!user(senderId)->avatarUrl(this).isEmpty()) {
avatar_image = user(senderId)->avatar(128, this);
@@ -273,7 +273,7 @@ const RoomEvent *NeoChatRoom::lastEvent() const
continue;
}
}
if (event->isStateEvent() && static_cast<const StateEvent &>(*event).repeatsState()) {
if (event->isStateEvent() && static_cast<const StateEventBase &>(*event).repeatsState()) {
continue;
}
@@ -340,7 +340,7 @@ bool NeoChatRoom::lastEventIsSpoiler() const
QString NeoChatRoom::lastEventToString(Qt::TextFormat format, bool stripNewlines) const
{
if (auto event = lastEvent()) {
return safeMemberName(event->senderId()) + (event->isStateEvent() ? QLatin1String(" ") : QLatin1String(": "))
return roomMembername(event->senderId()) + (event->isStateEvent() ? QLatin1String(" ") : QLatin1String(": "))
+ eventToString(*event, format, stripNewlines);
}
return {};
@@ -359,7 +359,7 @@ void NeoChatRoom::checkForHighlights(const Quotient::TimelineItem &ti)
}
if (auto *e = ti.viewAs<RoomMessageEvent>()) {
const auto &text = e->plainBody();
if (text.contains(localUserId) || text.contains(safeMemberName(localUserId))) {
if (text.contains(localUserId) || text.contains(roomMembername(localUserId))) {
highlights.insert(e);
}
}
@@ -382,7 +382,7 @@ void NeoChatRoom::onAddHistoricalTimelineEvents(rev_iter_t from)
void NeoChatRoom::onRedaction(const RoomEvent &prevEvent, const RoomEvent & /*after*/)
{
if (const auto &e = eventCast<const ReactionEvent>(&prevEvent)) {
if (auto relatedEventId = e->eventId(); !relatedEventId.isEmpty()) {
if (auto relatedEventId = e->relation().eventId; !relatedEventId.isEmpty()) {
Q_EMIT updatedEvent(relatedEventId);
}
}
@@ -531,7 +531,7 @@ QString NeoChatRoom::eventToString(const RoomEvent &evt, Qt::TextFormat format,
[this, prettyPrint](const RoomMemberEvent &e) {
// FIXME: Rewind to the name that was at the time of this event
auto subjectName = this->htmlSafeMemberName(e.userId());
if (e.membership() == Membership::Leave) {
if (e.membership() == MembershipType::Leave) {
if (e.prevContent() && e.prevContent()->displayName) {
subjectName = sanitized(*e.prevContent()->displayName).toHtmlEscaped();
}
@@ -544,7 +544,7 @@ QString NeoChatRoom::eventToString(const RoomEvent &evt, Qt::TextFormat format,
// The below code assumes senderName output in AuthorRole
switch (e.membership()) {
case Membership::Invite:
case MembershipType::Invite:
if (e.repeatsState()) {
auto text = i18n("reinvited %1 to the room", subjectName);
if (!e.reason().isEmpty()) {
@@ -553,13 +553,13 @@ QString NeoChatRoom::eventToString(const RoomEvent &evt, Qt::TextFormat format,
return text;
}
Q_FALLTHROUGH();
case Membership::Join: {
case MembershipType::Join: {
QString text{};
// Part 1: invites and joins
if (e.repeatsState()) {
text = i18n("joined the room (repeated)");
} else if (e.changesMembership()) {
text = e.membership() == Membership::Invite ? i18n("invited %1 to the room", subjectName) : i18n("joined the room");
text = e.membership() == MembershipType::Invite ? i18n("invited %1 to the room", subjectName) : i18n("joined the room");
}
if (!text.isEmpty()) {
if (!e.reason().isEmpty()) {
@@ -569,17 +569,17 @@ QString NeoChatRoom::eventToString(const RoomEvent &evt, Qt::TextFormat format,
}
// Part 2: profile changes of joined members
if (e.isRename()) {
if (!e.newDisplayName()) {
if (e.displayName().isEmpty()) {
text = i18nc("their refers to a singular user", "cleared their display name");
} else {
text = i18nc("their refers to a singular user", "changed their display name to %1", e.newDisplayName()->toHtmlEscaped());
text = i18nc("their refers to a singular user", "changed their display name to %1", e.displayName().toHtmlEscaped());
}
}
if (e.isAvatarUpdate()) {
if (!text.isEmpty()) {
text += i18n(" and ");
}
if (!e.newAvatarUrl()) {
if (e.avatarUrl().isEmpty()) {
text += i18nc("their refers to a singular user", "cleared their avatar");
} else if (!e.prevContent()->avatarUrl) {
text += i18n("set an avatar");
@@ -592,18 +592,18 @@ QString NeoChatRoom::eventToString(const RoomEvent &evt, Qt::TextFormat format,
}
return text;
}
case Membership::Leave:
if (e.prevContent() && e.prevContent()->membership == Membership::Invite) {
case MembershipType::Leave:
if (e.prevContent() && e.prevContent()->membership == MembershipType::Invite) {
return (e.senderId() != e.userId()) ? i18n("withdrew %1's invitation", subjectName) : i18n("rejected the invitation");
}
if (e.prevContent() && e.prevContent()->membership == Membership::Ban) {
if (e.prevContent() && e.prevContent()->membership == MembershipType::Ban) {
return (e.senderId() != e.userId()) ? i18n("unbanned %1", subjectName) : i18n("self-unbanned");
}
return (e.senderId() != e.userId())
? i18n("has put %1 out of the room: %2", subjectName, e.contentJson()["reason"_ls].toString().toHtmlEscaped())
: i18n("left the room");
case Membership::Ban:
case MembershipType::Ban:
if (e.senderId() != e.userId()) {
if (e.reason().isEmpty()) {
return i18n("banned %1 from the room", subjectName);
@@ -613,7 +613,7 @@ QString NeoChatRoom::eventToString(const RoomEvent &evt, Qt::TextFormat format,
} else {
return i18n("self-banned from the room");
}
case Membership::Knock: {
case MembershipType::Knock: {
QString reason(e.contentJson()["reason"_ls].toString().toHtmlEscaped());
return reason.isEmpty() ? i18n("requested an invite") : i18n("requested an invite with reason: %1", reason);
}
@@ -647,7 +647,7 @@ QString NeoChatRoom::eventToString(const RoomEvent &evt, Qt::TextFormat format,
[](const RoomPowerLevelsEvent &) {
return i18nc("'power level' means permission level", "changed the power levels for this room");
},
[](const StateEvent &e) {
[](const StateEventBase &e) {
if (e.matrixType() == QLatin1String("m.room.server_acl")) {
return i18n("changed the server access control lists for this room");
}
@@ -686,25 +686,25 @@ QString NeoChatRoom::eventToGenericString(const RoomEvent &evt) const
},
[](const RoomMemberEvent &e) {
switch (e.membership()) {
case Membership::Invite:
case MembershipType::Invite:
if (e.repeatsState()) {
return i18n("reinvited someone to the room");
}
Q_FALLTHROUGH();
case Membership::Join: {
case MembershipType::Join: {
QString text{};
// Part 1: invites and joins
if (e.repeatsState()) {
text = i18n("joined the room (repeated)");
} else if (e.changesMembership()) {
text = e.membership() == Membership::Invite ? i18n("invited someone to the room") : i18n("joined the room");
text = e.membership() == MembershipType::Invite ? i18n("invited someone to the room") : i18n("joined the room");
}
if (!text.isEmpty()) {
return text;
}
// Part 2: profile changes of joined members
if (e.isRename()) {
if (!e.newDisplayName()) {
if (e.displayName().isEmpty()) {
text = i18nc("their refers to a singular user", "cleared their display name");
} else {
text = i18nc("their refers to a singular user", "changed their display name");
@@ -714,7 +714,7 @@ QString NeoChatRoom::eventToGenericString(const RoomEvent &evt) const
if (!text.isEmpty()) {
text += i18n(" and ");
}
if (!e.newAvatarUrl()) {
if (e.avatarUrl().isEmpty()) {
text += i18nc("their refers to a singular user", "cleared their avatar");
} else if (!e.prevContent()->avatarUrl) {
text += i18n("set an avatar");
@@ -727,22 +727,22 @@ QString NeoChatRoom::eventToGenericString(const RoomEvent &evt) const
}
return text;
}
case Membership::Leave:
if (e.prevContent() && e.prevContent()->membership == Membership::Invite) {
case MembershipType::Leave:
if (e.prevContent() && e.prevContent()->membership == MembershipType::Invite) {
return (e.senderId() != e.userId()) ? i18n("withdrew a user's invitation") : i18n("rejected the invitation");
}
if (e.prevContent() && e.prevContent()->membership == Membership::Ban) {
if (e.prevContent() && e.prevContent()->membership == MembershipType::Ban) {
return (e.senderId() != e.userId()) ? i18n("unbanned a user") : i18n("self-unbanned");
}
return (e.senderId() != e.userId()) ? i18n("put a user out of the room") : i18n("left the room");
case Membership::Ban:
case MembershipType::Ban:
if (e.senderId() != e.userId()) {
return i18n("banned a user from the room");
} else {
return i18n("self-banned from the room");
}
case Membership::Knock: {
case MembershipType::Knock: {
return i18n("requested an invite");
}
default:;
@@ -770,7 +770,7 @@ QString NeoChatRoom::eventToGenericString(const RoomEvent &evt) const
[](const RoomPowerLevelsEvent &) {
return i18nc("'power level' means permission level", "changed the power levels for this room");
},
[](const StateEvent &e) {
[](const StateEventBase &e) {
if (e.matrixType() == QLatin1String("m.room.server_acl")) {
return i18n("changed the server access control lists for this room");
}
@@ -906,11 +906,11 @@ void NeoChatRoom::toggleReaction(const QString &eventId, const QString &reaction
QStringList redactEventIds; // What if there are multiple reaction events?
const auto &annotations = relatedEvents(evt, EventRelation::AnnotationType);
const auto &annotations = relatedEvents(evt, EventRelation::Annotation());
if (!annotations.isEmpty()) {
for (const auto &a : annotations) {
if (auto e = eventCast<const ReactionEvent>(a)) {
if (e->key() != reaction) {
if (e->relation().key != reaction) {
continue;
}
@@ -938,10 +938,7 @@ bool NeoChatRoom::containsUser(const QString &userID) const
bool NeoChatRoom::canSendEvent(const QString &eventType) const
{
auto plEvent = currentState().get<RoomPowerLevelsEvent>();
if (!plEvent) {
return false;
}
auto plEvent = getCurrentState<RoomPowerLevelsEvent>();
auto pl = plEvent->powerLevelForEvent(eventType);
auto currentPl = plEvent->powerLevelForUser(localUser()->id());
@@ -950,10 +947,7 @@ bool NeoChatRoom::canSendEvent(const QString &eventType) const
bool NeoChatRoom::canSendState(const QString &eventType) const
{
auto plEvent = currentState().get<RoomPowerLevelsEvent>();
if (!plEvent) {
return false;
}
auto plEvent = getCurrentState<RoomPowerLevelsEvent>();
auto pl = plEvent->powerLevelForState(eventType);
auto currentPl = plEvent->powerLevelForUser(localUser()->id());
@@ -973,11 +967,7 @@ bool NeoChatRoom::isInvite() const
bool NeoChatRoom::isUserBanned(const QString &user) const
{
auto roomMemberEvent = currentState().get<RoomMemberEvent>(user);
if (!roomMemberEvent) {
return false;
}
return roomMemberEvent->membership() == Membership::Ban;
return getCurrentState<RoomMemberEvent>(user)->membership() == MembershipType::Ban;
}
QString NeoChatRoom::htmlSafeDisplayName() const
@@ -992,11 +982,7 @@ void NeoChatRoom::deleteMessagesByUser(const QString &user, const QString &reaso
QString NeoChatRoom::joinRule() const
{
auto joinRulesEvent = currentState().get<JoinRulesEvent>();
if (joinRulesEvent) {
return {};
}
return joinRulesEvent->joinRule();
return getCurrentState<JoinRulesEvent>()->joinRule();
}
void NeoChatRoom::setJoinRule(const QString &joinRule)
@@ -1130,10 +1116,7 @@ void NeoChatRoom::setUserPowerLevel(const QString &userID, const int &powerLevel
int NeoChatRoom::getUserPowerLevel(const QString &userId) const
{
auto powerLevelEvent = currentState().get<RoomPowerLevelsEvent>();
if (!powerLevelEvent) {
return 0;
}
auto powerLevelEvent = getCurrentState<RoomPowerLevelsEvent>();
return powerLevelEvent->powerLevelForUser(userId);
}
@@ -1941,7 +1924,7 @@ QByteArray NeoChatRoom::roomAcountDataJson(const QString &eventType)
QUrl NeoChatRoom::avatarForMember(NeoChatUser *user) const
{
const auto &url = memberAvatarUrl(user->id());
if (url.isEmpty() || url.scheme() != "mxc"_ls) {
if (url.isEmpty()) {
return {};
}
auto avatar = connection()->makeMediaUrl(url);

View File

@@ -3,7 +3,8 @@
#pragma once
#include <Quotient/room.h>
#include <qobjectdefs.h>
#include <room.h>
#include <QCache>
#include <QObject>

View File

@@ -7,7 +7,7 @@
#include <QJsonObject>
#include <QPalette>
#include <Quotient/connection.h>
#include <connection.h>
using namespace Quotient;

View File

@@ -5,7 +5,7 @@
#include <QObject>
#include <Quotient/user.h>
#include <user.h>
/**
* @class NeoChatUser
@@ -23,7 +23,7 @@ class NeoChatUser : public Quotient::User
*/
Q_PROPERTY(QColor color READ color WRITE setColor NOTIFY colorChanged)
public:
explicit NeoChatUser(QString userId, Quotient::Connection *connection);
NeoChatUser(QString userId, Quotient::Connection *connection);
public Q_SLOTS:
QColor color();

View File

@@ -11,10 +11,11 @@
#include <KNotification>
#include <KNotificationReplyAction>
#include <Quotient/accountregistry.h>
#include <Quotient/connection.h>
#include <Quotient/csapi/pushrules.h>
#include <Quotient/user.h>
#include <accountregistry.h>
#include <connection.h>
#include <csapi/pushrules.h>
#include <user.h>
#include "controller.h"
#include "neochatconfig.h"
@@ -212,7 +213,7 @@ void NotificationsManager::postNotification(NeoChatRoom *room,
return;
}
if (room->localUser()->id() != Controller::instance().activeConnection()->userId()) {
Controller::instance().setActiveConnection(Controller::instance().accounts().get(room->localUser()->id()));
Controller::instance().setActiveConnection(Accounts.get(room->localUser()->id()));
}
RoomManager::instance().enterRoom(room);
});

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