Compare commits

..

1 Commits

Author SHA1 Message Date
Joshua Goins
a4e6f0c4c2 Add spell-checking suggestions to the chat bar context menu
This is natively integrated into the existing chat document handler, and
emulates normal Sonnet behavior.
2023-09-13 13:06:05 +00:00
261 changed files with 14889 additions and 20112 deletions

View File

@@ -37,4 +37,4 @@ Dependencies:
Options:
per-test-timeout: 90
require-passing-tests-on: [ '@all' ]
require-passing-tests-on: [ 'FreeBSD', 'Windows' ]

View File

@@ -34,7 +34,7 @@ Files: src/neochat.notifyrc
Copyright: 2020 Tobias Fella <tobias.fella@kde.org>
License: BSD-2-Clause
Files: src/qml/confetti.png src/qml/glowdot.png
Files: src/qml/Component/confetti.png src/qml/Component/glowdot.png
Copyright: 2021 Alexey Andreyev <aa13q@ya.ru>
License: CC0-1.0

View File

@@ -68,8 +68,6 @@ set_package_properties(KF6Kirigami2 PROPERTIES
)
find_package(KF6KirigamiAddons 0.7.2 REQUIRED)
find_package(KUnifiedPush)
if(ANDROID)
find_package(OpenSSL)
set_package_properties(OpenSSL PROPERTIES

View File

@@ -55,13 +55,11 @@
<summary xml:lang="eu">Berriketan jardun zure lagunekin «Matrix»en</summary>
<summary xml:lang="fr">Discuter avec vos ami(e)s sur le réseau Matrix</summary>
<summary xml:lang="gl">Charle coas súas amizades en Matrix.</summary>
<summary xml:lang="ia">Starta Conversation conntu amicos sur matrix</summary>
<summary xml:lang="it">Conversa con i tuoi contatti su matrix</summary>
<summary xml:lang="ka">ესაუბრეთ მეგობრებს Matrix-ზე</summary>
<summary xml:lang="ko">Matrix를 사용하여 친구들과 대화하기</summary>
<summary xml:lang="nl">Met uw vrienden chatten op matrix</summary>
<summary xml:lang="nn">Prat med vennar på Matrix</summary>
<summary xml:lang="pl">Rozmawiaj ze swoimi znajomymi w Matriksie</summary>
<summary xml:lang="sl">Klepet z vašimi prijatelji na matrixu</summary>
<summary xml:lang="sv">Chatta med dina vänner på Matrix</summary>
<summary xml:lang="ta">மேட்ரிக்ஸு மூலம் உங்கள் நண்பர்களிடம் பேசலாம்</summary>
@@ -294,7 +292,6 @@ to provide a convergent experience across multiple platforms.</p>
<caption xml:lang="fi">Päänäkymä, jossa huoneluettelo, keskustelu ja huoneen tiedot</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="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="ka">მთავარი ხედი სურათების სიით, ჩატით და ოთახის ინფორმაციით</caption>
<caption xml:lang="ko">대화방 목록, 채팅, 대화방 정보가 표시된 주 보기</caption>
@@ -321,7 +318,6 @@ to provide a convergent experience across multiple platforms.</p>
<caption xml:lang="fi">Kirjautumisnäkymä</caption>
<caption xml:lang="fr">Écran de connexion</caption>
<caption xml:lang="gl">Pantalla de identificación.</caption>
<caption xml:lang="ia">Schermo de accesso</caption>
<caption xml:lang="it">Schermata di accesso</caption>
<caption xml:lang="ka">შესვლის ეკრანი</caption>
<caption xml:lang="ko">로그인 화면</caption>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -97,7 +97,7 @@ SPDX-License-Identifier: CC-BY-SA-4.0
>Vegeu també</title>
<simplelist>
<member
>Una llista de les preguntes més freqüents quant a Matrix <ulink url="https://matrix.org/faq/"
>Una llista de les preguntes més freqüents quan a Matrix <ulink url="https://matrix.org/faq/"
>https://matrix.org/faq/</ulink
> </member>
<member

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

@@ -55,8 +55,8 @@ add_library(neochat STATIC
models/devicesmodel.cpp
models/devicesmodel.h
models/devicesproxymodel.cpp
filetype.cpp
filetype.h
filetypesingleton.cpp
filetypesingleton.h
login.cpp
login.h
models/webshortcutmodel.cpp
@@ -129,153 +129,6 @@ add_library(neochat STATIC
enums/delegatetype.h
)
qt_add_qml_module(neochat URI org.kde.neochat NO_PLUGIN
QML_FILES
qml/main.qml
qml/AccountMenu.qml
qml/ExploreComponent.qml
qml/ContextMenu.qml
qml/CollapsedRoomDelegate.qml
qml/RoomDelegate.qml
qml/RoomListPage.qml
qml/SpaceListContextMenu.qml
qml/UserInfo.qml
qml/LoadingPage.qml
qml/RoomPage.qml
qml/RoomWindow.qml
qml/JoinRoomPage.qml
qml/ExplorerDelegate.qml
qml/InviteUserPage.qml
qml/StartChatPage.qml
qml/ImageEditorPage.qml
qml/WelcomePage.qml
qml/General.qml
qml/Security.qml
qml/PushNotification.qml
qml/Categories.qml
qml/Permissions.qml
qml/NeochatMaximizeComponent.qml
qml/FancyEffectsContainer.qml
qml/TypingPane.qml
qml/ShimmerGradient.qml
qml/QuickSwitcher.qml
qml/HoverActions.qml
qml/ChatBox.qml
qml/ChatBar.qml
qml/AttachmentPane.qml
qml/ReplyPane.qml
qml/CompletionMenu.qml
qml/PieProgressBar.qml
qml/QuickFormatBar.qml
qml/RoomData.qml
qml/ServerData.qml
qml/EmojiPicker.qml
qml/TimelineDelegate.qml
qml/ReplyComponent.qml
qml/StateDelegate.qml
qml/RichLabel.qml
qml/MessageDelegate.qml
qml/Bubble.qml
qml/SectionDelegate.qml
qml/VideoDelegate.qml
qml/ReactionDelegate.qml
qml/LinkPreviewDelegate.qml
qml/AudioDelegate.qml
qml/FileDelegate.qml
qml/ImageDelegate.qml
qml/EncryptedDelegate.qml
qml/EventDelegate.qml
qml/TextDelegate.qml
qml/ReadMarkerDelegate.qml
qml/PollDelegate.qml
qml/MimeComponent.qml
qml/StateComponent.qml
qml/MessageEditComponent.qml
qml/AvatarFlow.qml
qml/LoginStep.qml
qml/Login.qml
qml/Homeserver.qml
qml/Username.qml
qml/RegisterPassword.qml
qml/Captcha.qml
qml/Terms.qml
qml/Email.qml
qml/Password.qml
qml/LoginRegister.qml
qml/Loading.qml
qml/LoginMethod.qml
qml/Sso.qml
qml/UserDetailDialog.qml
qml/CreateRoomDialog.qml
qml/CreateSpaceDialog.qml
qml/EmojiDialog.qml
qml/OpenFileDialog.qml
qml/KeyVerificationDialog.qml
qml/ConfirmLogoutDialog.qml
qml/PowerLevelDialog.qml
qml/Message.qml
qml/EmojiItem.qml
qml/EmojiRow.qml
qml/EmojiSas.qml
qml/ConfirmDeactivateAccountDialog.qml
qml/VerificationCanceled.qml
qml/GlobalMenu.qml
qml/EditMenu.qml
qml/MessageDelegateContextMenu.qml
qml/FileDelegateContextMenu.qml
qml/MessageSourceSheet.qml
qml/ReportSheet.qml
qml/SettingsPage.qml
qml/ThemeRadioButton.qml
qml/ColorScheme.qml
qml/GeneralSettingsPage.qml
qml/EmoticonsPage.qml
qml/EmoticonEditorPage.qml
qml/EmoticonFormCard.qml
qml/GlobalNotificationsPage.qml
qml/NotificationRuleItem.qml
qml/AppearanceSettingsPage.qml
qml/AccountsPage.qml
qml/AccountEditorPage.qml
qml/DevicesPage.qml
qml/DeviceDelegate.qml
qml/DevicesCard.qml
qml/About.qml
qml/AboutKDE.qml
qml/SonnetConfigPage.qml
qml/NetworkProxyPage.qml
qml/DevtoolsPage.qml
qml/ConfirmEncryptionDialog.qml
qml/RemoveSheet.qml
qml/BanSheet.qml
qml/EmojiTonesPicker.qml
qml/EmojiDelegate.qml
qml/EmojiGrid.qml
qml/SearchPage.qml
qml/LocationDelegate.qml
qml/LocationChooser.qml
qml/TimelineView.qml
qml/InvitationView.qml
qml/AvatarTabButton.qml
qml/SpaceDrawer.qml
qml/OsmLocationPlugin.qml
qml/LiveLocationDelegate.qml
qml/FullScreenMap.qml
qml/LocationsPage.qml
qml/LocationMapItem.qml
qml/RoomDrawer.qml
qml/RoomDrawerPage.qml
qml/DirectChatDrawerHeader.qml
qml/GroupChatDrawerHeader.qml
qml/RoomInformation.qml
qml/RoomMedia.qml
qml/ChooseRoomDialog.qml
qml/ShareAction.qml
RESOURCES
qml/confetti.png
qml/glowdot.png
)
ecm_qt_declare_logging_category(neochat
HEADER "messageeventmodel_logging.h"
IDENTIFIER "MessageEvent"
@@ -294,6 +147,7 @@ ecm_qt_declare_logging_category(neochat
add_executable(neochat-app
main.cpp
res.qrc
)
if(TARGET Qt::WebView)
@@ -325,19 +179,17 @@ if(NOT ANDROID)
endif()
if (NOT ANDROID AND NOT WIN32 AND NOT APPLE)
target_sources(neochat-app PRIVATE res_desktop.qrc)
target_compile_definitions(neochat PUBLIC -DHAVE_RUNNER)
target_compile_definitions(neochat PUBLIC -DHAVE_X11)
target_sources(neochat PRIVATE runner.cpp)
else()
target_sources(neochat-app PRIVATE res_android.qrc)
endif()
target_include_directories(neochat PRIVATE ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/models ${CMAKE_CURRENT_SOURCE_DIR}/enums)
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 KF6::I18n KF6::Kirigami2 KF6::Notifications KF6::ConfigCore KF6::ConfigGui KF6::CoreAddons KF6::SonnetCore KF6::ItemModels QuotientQt6 cmark::cmark QCoro::Core)
if(TARGET KUnifiedPush)
target_link_libraries(neochat PUBLIC KUnifiedPush)
target_compile_definitions(neochat PUBLIC -DHAVE_KUNIFIEDPUSH)
endif()
kconfig_add_kcfg_files(neochat GENERATE_MOC neochatconfig.kcfgc)
if(NEOCHAT_FLATPAK)
@@ -443,9 +295,6 @@ endif()
install(TARGETS neochat-app ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})
configure_file(org.kde.neochat.notifier.service.in ${CMAKE_CURRENT_BINARY_DIR}/org.kde.neochat.notifier.service)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/org.kde.neochat.notifier.service DESTINATION ${KDE_INSTALL_DBUSSERVICEDIR})
if (NOT ANDROID AND NOT WIN32 AND NOT APPLE)
install(FILES plasma-runner-neochat.desktop DESTINATION ${KDE_INSTALL_DATAROOTDIR}/krunner/dbusplugins)
endif()

View File

@@ -4,7 +4,6 @@
#pragma once
#include <QObject>
#include <QQmlEngine>
#include <Quotient/events/roommessageevent.h>
@@ -33,7 +32,6 @@ class NeoChatRoom;
class ActionsHandler : public QObject
{
Q_OBJECT
QML_ELEMENT
/**
* @brief The room that messages will be sent to.

View File

@@ -90,6 +90,11 @@ public:
}),
mentions->end());
}
QStringList suggestions(const QString &word) const
{
return checker->suggest(word);
}
};
ChatDocumentHandler::ChatDocumentHandler(QObject *parent)
@@ -263,6 +268,47 @@ void ChatDocumentHandler::complete(int index)
}
}
QStringList ChatDocumentHandler::getSuggestions(int mousePosition)
{
QTextCursor cursorAtMouse(document()->textDocument());
cursorAtMouse.setPosition(mousePosition);
// Get the word under the (mouse-)cursor and see if it is misspelled.
// Don't include apostrophes at the start/end of the word in the selection.
QTextCursor wordSelectCursor(cursorAtMouse);
wordSelectCursor.clearSelection();
wordSelectCursor.select(QTextCursor::WordUnderCursor);
m_selectedWord = wordSelectCursor.selectedText();
return m_highlighter->suggestions(m_selectedWord);
}
bool ChatDocumentHandler::getActive() const
{
return m_highlighter->settings.checkerEnabledByDefault();
}
bool ChatDocumentHandler::getIsWordIsMisspelled() const
{
return !m_highlighter->errors.isEmpty();
}
QString ChatDocumentHandler::getWordUnderMouse() const
{
return m_selectedWord;
}
void ChatDocumentHandler::replaceWord(const QString &word)
{
QTextCursor cursor(document()->textDocument());
const auto &text = m_room->chatBoxText();
auto at = text.indexOf(m_highlighter->previousText);
cursor.setPosition(at);
cursor.setPosition(at + m_highlighter->previousText.length(), QTextCursor::KeepAnchor);
cursor.insertText(word);
}
CompletionModel *ChatDocumentHandler::completionModel() const
{
return m_completionModel;

View File

@@ -4,7 +4,6 @@
#pragma once
#include <QObject>
#include <QQmlEngine>
#include <QQuickTextDocument>
#include <QTextCursor>
@@ -59,7 +58,6 @@ class SyntaxHighlighter;
class ChatDocumentHandler : public QObject
{
Q_OBJECT
QML_ELEMENT
/**
* @brief Is the instance being used to handle an edit message.
@@ -89,6 +87,10 @@ class ChatDocumentHandler : public QObject
*/
Q_PROPERTY(int selectionEnd READ selectionEnd WRITE setSelectionEnd NOTIFY selectionEndChanged)
Q_PROPERTY(bool active READ getActive NOTIFY cursorPositionChanged)
Q_PROPERTY(bool wordIsMisspelled READ getIsWordIsMisspelled NOTIFY cursorPositionChanged)
Q_PROPERTY(QString wordUnderMouse READ getWordUnderMouse NOTIFY cursorPositionChanged)
/**
* @brief The current CompletionModel.
*
@@ -135,6 +137,12 @@ public:
Q_INVOKABLE void complete(int index);
Q_INVOKABLE void replaceWord(const QString &word);
Q_INVOKABLE QStringList getSuggestions(int mousePosition);
bool getActive() const;
bool getIsWordIsMisspelled() const;
QString getWordUnderMouse() const;
void updateCompletions();
CompletionModel *completionModel() const;
@@ -180,4 +188,6 @@ private:
CompletionModel::AutoCompletionType m_completionType = CompletionModel::None;
CompletionModel *m_completionModel = nullptr;
QString m_selectedWord;
};

View File

@@ -4,7 +4,6 @@
#pragma once
#include <QObject>
#include <QQmlEngine>
class QClipboard;
class QImage;
@@ -19,8 +18,6 @@ class QImage;
class Clipboard : public QObject
{
Q_OBJECT
QML_ELEMENT
QML_SINGLETON
/**
* @brief Whether the current clipboard content is an image.

View File

@@ -4,7 +4,6 @@
#pragma once
#include <QObject>
#include <QQmlEngine>
class QAbstractItemModel;
class KColorSchemeManager;
@@ -20,8 +19,6 @@ class KColorSchemeManager;
class ColorSchemer : public QObject
{
Q_OBJECT
QML_ELEMENT
QML_SINGLETON
/**
* @brief A QAbstractItemModel of all available color schemes.

View File

@@ -14,13 +14,6 @@
#include <KWindowEffects>
#endif
#ifdef HAVE_KUNIFIEDPUSH
#include <KUnifiedPush/Connector>
#include <QCoroNetworkReply>
#include <QDBusConnection>
#include <qcoro/qcorosignal.h>
#endif
#include <QFile>
#include <QFileInfo>
#include <QGuiApplication>
@@ -48,11 +41,6 @@
#include "roommanager.h"
#include "windowcontroller.h"
#ifdef HAVE_KUNIFIEDPUSH
#include <Quotient/csapi/pusher.h>
#include <Quotient/networkaccessmanager.h>
#endif
#if defined(Q_OS_WIN) || defined(Q_OS_MAC)
#include "trayicon.h"
#elif !defined(Q_OS_ANDROID)
@@ -61,54 +49,9 @@
using namespace Quotient;
#ifdef HAVE_KUNIFIEDPUSH
QCoro::Task<void> Controller::setupPush(const QString &endpoint)
{
while (!activeConnection()) {
co_await qCoro(this, &Controller::activeConnectionChanged);
}
QUrl gatewayEndpoint(endpoint);
gatewayEndpoint.setPath("/_matrix/push/v1/notify");
QNetworkRequest checkGateway(gatewayEndpoint);
auto reply = co_await NetworkAccessManager::instance()->get(checkGateway);
const QJsonObject replyJson = QJsonDocument::fromJson(reply->readAll()).object();
if (replyJson["unifiedpush"]["gateway"].toString() == QStringLiteral("matrix")) {
Controller::instance().activeConnection()->callApi<PostPusherJob>(endpoint,
"http",
"neochat-foo1",
"NeoChat",
"Device 1",
"en",
PostPusherJob::PusherData{{gatewayEndpoint.toString()}, " "});
} else {
qWarning() << "There's no gateway";
}
}
#endif
Controller::Controller(QObject *parent)
: QObject(parent)
{
#ifdef HAVE_KUNIFIEDPUSH
const auto serviceName = QStringLiteral("org.kde.neochat.notifier");
if (!QDBusConnection::sessionBus().registerService(serviceName)) {
qCritical() << "Service name already in use";
return;
}
auto connector = new KUnifiedPush::Connector(serviceName);
connect(connector, &KUnifiedPush::Connector::stateChanged, [](auto state) {
// TODO ?
});
connect(connector, &KUnifiedPush::Connector::messageReceived, [](const auto &msg) {
NotificationsManager::instance().postPushNotification(msg);
});
connect(connector, &KUnifiedPush::Connector::endpointChanged, [this](const auto &endpoint) {
setupPush(endpoint);
});
connector->registerClient(i18n("Receiving Matrix messages"));
#endif
Connection::setRoomType<NeoChatRoom>();
setApplicationProxy();

View File

@@ -5,7 +5,6 @@
#include "models/pushrulemodel.h"
#include <QObject>
#include <QQmlEngine>
#include <QQuickItem>
#include <KFormat>
@@ -15,10 +14,6 @@
#include <Quotient/jobs/basejob.h>
#include <Quotient/settings.h>
#ifdef HAVE_KUNIFIEDPUSH
#include <qcoro/task.h>
#endif
class NeoChatRoom;
class TrayIcon;
class QQuickTextDocument;
@@ -45,8 +40,6 @@ class ReadPasswordJob;
class Controller : public QObject
{
Q_OBJECT
QML_ELEMENT
QML_SINGLETON
/**
* @brief The current connection for the rest of NeoChat to use.
@@ -97,10 +90,6 @@ public:
Q_ENUM(PasswordStatus)
static Controller &instance();
static Controller *create(QQmlEngine *, QJSEngine *)
{
return &instance();
}
void setActiveConnection(NeoChatConnection *connection);
[[nodiscard]] NeoChatConnection *activeConnection() const;
@@ -181,11 +170,6 @@ private:
explicit Controller(QObject *parent = nullptr);
QPointer<NeoChatConnection> m_connection;
#ifdef HAVE_KUNIFIEDPUSH
QCoro::Task<void> setupPush(const QString &endpoint);
#endif
TrayIcon *m_trayIcon = nullptr;
QKeychain::ReadPasswordJob *loadAccessTokenFromKeyChain(const Quotient::AccountSettings &account);

View File

@@ -4,7 +4,6 @@
#pragma once
#include <QObject>
#include <QQmlEngine>
/**
* @class DelegateSizeHelper
@@ -24,7 +23,6 @@
class DelegateSizeHelper : public QObject
{
Q_OBJECT
QML_ELEMENT
/**
* @brief The width of the component's parent.

View File

@@ -4,18 +4,15 @@
#pragma once
#include <QObject>
#include <QQmlEngine>
/**
* @class DelegateType
*
* This class is designed to define the DelegateType enumeration.
*/
class DelegateType : public QObject
class DelegateType
{
Q_OBJECT
QML_ELEMENT
QML_UNCREATABLE("")
Q_GADGET
public:
/**

View File

@@ -1,116 +0,0 @@
// SPDX-FileCopyrightText: 2021 Noah Davis <noahadvs@gmail.com>
// SPDX-License-Identifier: LicenseRef-KDE-Accepted-LGPL
#include "filetype.h"
#include <QImageReader>
#include <QMovie>
static QStringList byteArrayListToStringList(const QByteArrayList &byteArrayList)
{
QStringList stringList;
for (const QByteArray &byteArray : byteArrayList) {
stringList.append(QString::fromLocal8Bit(byteArray));
}
return stringList;
}
class FileTypePrivate
{
Q_DECLARE_PUBLIC(FileType)
Q_DISABLE_COPY(FileTypePrivate)
public:
FileTypePrivate(FileType *qq);
FileType *const q_ptr;
QMimeDatabase mimetypeDatabase;
QStringList supportedImageFormats = byteArrayListToStringList(QImageReader::supportedImageFormats());
QStringList supportedAnimatedImageFormats = byteArrayListToStringList(QMovie::supportedFormats());
};
FileTypePrivate::FileTypePrivate(FileType *qq)
: q_ptr(qq)
{
}
FileType::FileType(QObject *parent)
: QObject(parent)
, d_ptr(new FileTypePrivate(this))
{
}
FileType::~FileType() noexcept
{
}
QMimeType FileType::mimeTypeForName(const QString &nameOrAlias) const
{
Q_D(const FileType);
return d->mimetypeDatabase.mimeTypeForName(nameOrAlias);
}
QMimeType FileType::mimeTypeForFile(const QString &fileName, MatchMode mode) const
{
Q_D(const FileType);
return d->mimetypeDatabase.mimeTypeForFile(fileName, static_cast<QMimeDatabase::MatchMode>(mode));
}
QMimeType FileType::mimeTypeForFile(const QFileInfo &fileInfo, MatchMode mode) const
{
Q_D(const FileType);
return d->mimetypeDatabase.mimeTypeForFile(fileInfo, static_cast<QMimeDatabase::MatchMode>(mode));
}
QList<QMimeType> FileType::mimeTypesForFileName(const QString &fileName) const
{
Q_D(const FileType);
return d->mimetypeDatabase.mimeTypesForFileName(fileName);
}
QMimeType FileType::mimeTypeForData(const QByteArray &data) const
{
Q_D(const FileType);
return d->mimetypeDatabase.mimeTypeForData(data);
}
QMimeType FileType::mimeTypeForData(QIODevice *device) const
{
Q_D(const FileType);
return d->mimetypeDatabase.mimeTypeForData(device);
}
QMimeType FileType::mimeTypeForUrl(const QUrl &url) const
{
Q_D(const FileType);
return d->mimetypeDatabase.mimeTypeForUrl(url);
}
QMimeType FileType::mimeTypeForFileNameAndData(const QString &fileName, QIODevice *device) const
{
Q_D(const FileType);
return d->mimetypeDatabase.mimeTypeForFileNameAndData(fileName, device);
}
QMimeType FileType::mimeTypeForFileNameAndData(const QString &fileName, const QByteArray &data) const
{
Q_D(const FileType);
return d->mimetypeDatabase.mimeTypeForFileNameAndData(fileName, data);
}
QString FileType::suffixForFileName(const QString &fileName) const
{
Q_D(const FileType);
return d->mimetypeDatabase.suffixForFileName(fileName);
}
QStringList FileType::supportedImageFormats() const
{
Q_D(const FileType);
return d->supportedImageFormats;
}
QStringList FileType::supportedAnimatedImageFormats() const
{
Q_D(const FileType);
return d->supportedAnimatedImageFormats;
}
#include "moc_filetype.cpp"

116
src/filetypesingleton.cpp Normal file
View File

@@ -0,0 +1,116 @@
// SPDX-FileCopyrightText: 2021 Noah Davis <noahadvs@gmail.com>
// SPDX-License-Identifier: LicenseRef-KDE-Accepted-LGPL
#include "filetypesingleton.h"
#include <QImageReader>
#include <QMovie>
static QStringList byteArrayListToStringList(const QByteArrayList &byteArrayList)
{
QStringList stringList;
for (const QByteArray &byteArray : byteArrayList) {
stringList.append(QString::fromLocal8Bit(byteArray));
}
return stringList;
}
class FileTypeSingletonPrivate
{
Q_DECLARE_PUBLIC(FileTypeSingleton)
Q_DISABLE_COPY(FileTypeSingletonPrivate)
public:
FileTypeSingletonPrivate(FileTypeSingleton *qq);
FileTypeSingleton *const q_ptr;
QMimeDatabase mimetypeDatabase;
QStringList supportedImageFormats = byteArrayListToStringList(QImageReader::supportedImageFormats());
QStringList supportedAnimatedImageFormats = byteArrayListToStringList(QMovie::supportedFormats());
};
FileTypeSingletonPrivate::FileTypeSingletonPrivate(FileTypeSingleton *qq)
: q_ptr(qq)
{
}
FileTypeSingleton::FileTypeSingleton(QObject *parent)
: QObject(parent)
, d_ptr(new FileTypeSingletonPrivate(this))
{
}
FileTypeSingleton::~FileTypeSingleton() noexcept
{
}
QMimeType FileTypeSingleton::mimeTypeForName(const QString &nameOrAlias) const
{
Q_D(const FileTypeSingleton);
return d->mimetypeDatabase.mimeTypeForName(nameOrAlias);
}
QMimeType FileTypeSingleton::mimeTypeForFile(const QString &fileName, MatchMode mode) const
{
Q_D(const FileTypeSingleton);
return d->mimetypeDatabase.mimeTypeForFile(fileName, static_cast<QMimeDatabase::MatchMode>(mode));
}
QMimeType FileTypeSingleton::mimeTypeForFile(const QFileInfo &fileInfo, MatchMode mode) const
{
Q_D(const FileTypeSingleton);
return d->mimetypeDatabase.mimeTypeForFile(fileInfo, static_cast<QMimeDatabase::MatchMode>(mode));
}
QList<QMimeType> FileTypeSingleton::mimeTypesForFileName(const QString &fileName) const
{
Q_D(const FileTypeSingleton);
return d->mimetypeDatabase.mimeTypesForFileName(fileName);
}
QMimeType FileTypeSingleton::mimeTypeForData(const QByteArray &data) const
{
Q_D(const FileTypeSingleton);
return d->mimetypeDatabase.mimeTypeForData(data);
}
QMimeType FileTypeSingleton::mimeTypeForData(QIODevice *device) const
{
Q_D(const FileTypeSingleton);
return d->mimetypeDatabase.mimeTypeForData(device);
}
QMimeType FileTypeSingleton::mimeTypeForUrl(const QUrl &url) const
{
Q_D(const FileTypeSingleton);
return d->mimetypeDatabase.mimeTypeForUrl(url);
}
QMimeType FileTypeSingleton::mimeTypeForFileNameAndData(const QString &fileName, QIODevice *device) const
{
Q_D(const FileTypeSingleton);
return d->mimetypeDatabase.mimeTypeForFileNameAndData(fileName, device);
}
QMimeType FileTypeSingleton::mimeTypeForFileNameAndData(const QString &fileName, const QByteArray &data) const
{
Q_D(const FileTypeSingleton);
return d->mimetypeDatabase.mimeTypeForFileNameAndData(fileName, data);
}
QString FileTypeSingleton::suffixForFileName(const QString &fileName) const
{
Q_D(const FileTypeSingleton);
return d->mimetypeDatabase.suffixForFileName(fileName);
}
QStringList FileTypeSingleton::supportedImageFormats() const
{
Q_D(const FileTypeSingleton);
return d->supportedImageFormats;
}
QStringList FileTypeSingleton::supportedAnimatedImageFormats() const
{
Q_D(const FileTypeSingleton);
return d->supportedAnimatedImageFormats;
}
#include "moc_filetypesingleton.cpp"

View File

@@ -8,10 +8,9 @@
#include <QFileInfo>
#include <QMimeDatabase>
#include <QObject>
#include <QQmlEngine>
#include <qqml.h>
class FileTypePrivate;
class FileTypeSingletonPrivate;
/**
* @class FileTypeSingleton
@@ -20,11 +19,9 @@ class FileTypePrivate;
*
* @sa QMimeDatabase
*/
class FileType : public QObject
class FileTypeSingleton : public QObject
{
Q_OBJECT
QML_ELEMENT
QML_SINGLETON
/**
* @brief List of supported image formats.
@@ -40,9 +37,12 @@ class FileType : public QObject
*/
Q_PROPERTY(QStringList supportedAnimatedImageFormats READ supportedAnimatedImageFormats CONSTANT FINAL)
QML_NAMED_ELEMENT(FileType)
QML_SINGLETON
public:
explicit FileType(QObject *parent = nullptr);
~FileType();
explicit FileTypeSingleton(QObject *parent = nullptr);
~FileTypeSingleton();
/**
* @brief Returns a MIME type for nameOrAlias or an invalid one if none found.
@@ -59,14 +59,14 @@ public:
*
* @sa QMimeDatabase
*/
Q_INVOKABLE QMimeType mimeTypeForFile(const QString &fileName, FileType::MatchMode mode = MatchDefault) const;
Q_INVOKABLE QMimeType mimeTypeForFile(const QString &fileName, FileTypeSingleton::MatchMode mode = MatchDefault) const;
/**
* @brief Returns a MIME type for fileInfo.
*
* @sa QMimeDatabase
*/
Q_INVOKABLE QMimeType mimeTypeForFile(const QFileInfo &fileInfo, FileType::MatchMode mode = MatchDefault) const;
Q_INVOKABLE QMimeType mimeTypeForFile(const QFileInfo &fileInfo, FileTypeSingleton::MatchMode mode = MatchDefault) const;
/**
* @brief Returns the MIME types for the file name fileName.
@@ -121,7 +121,9 @@ public:
QStringList supportedAnimatedImageFormats() const;
private:
const QScopedPointer<FileTypePrivate> d_ptr;
Q_DECLARE_PRIVATE(FileType)
Q_DISABLE_COPY(FileType)
const QScopedPointer<FileTypeSingletonPrivate> d_ptr;
Q_DECLARE_PRIVATE(FileTypeSingleton)
Q_DISABLE_COPY(FileTypeSingleton)
};
QML_DECLARE_TYPE(FileTypeSingleton)

View File

@@ -4,7 +4,6 @@
#pragma once
#include <QObject>
#include <QQmlEngine>
#include <QUrl>
class NeoChatRoom;
@@ -20,8 +19,6 @@ class NeoChatRoom;
class LinkPreviewer : public QObject
{
Q_OBJECT
QML_ELEMENT
/**
* @brief The URL to get the preview for.
*/

View File

@@ -2,17 +2,14 @@
// SPDX-License-Identifier: LGPL-2.0-or-later
#pragma once
#include "linkpreviewer.h"
#include <QMetaType>
#include <QObject>
#include <QQmlEngine>
#include <QRectF>
/** Location related helper functions for QML. */
class LocationHelper : public QObject
class LocationHelper
{
Q_OBJECT
QML_ELEMENT
QML_UNCREATABLE("")
Q_GADGET
public:
/** Unite two rectanlges. */
Q_INVOKABLE static QRectF unite(const QRectF &r1, const QRectF &r2);

View File

@@ -13,13 +13,13 @@
using namespace Quotient;
LoginHelper::LoginHelper(QObject *parent)
Login::Login(QObject *parent)
: QObject(parent)
{
init();
}
void LoginHelper::init()
void Login::init()
{
m_homeserverReachable = false;
m_connection = new NeoChatConnection();
@@ -31,7 +31,7 @@ void LoginHelper::init()
m_supportsPassword = false;
m_ssoUrl = QUrl();
connect(this, &LoginHelper::matrixIdChanged, this, [this]() {
connect(this, &Login::matrixIdChanged, this, [this]() {
setHomeserverReachable(false);
QRegularExpression validator(QStringLiteral("^\\@?[a-zA-Z0-9\\._=\\-/]+\\:[a-zA-Z0-9\\-]+(\\.[a-zA-Z0-9\\-]+)*(\\:[0-9]+)?$"));
if (!validator.match(m_matrixId).hasMatch()) {
@@ -105,23 +105,23 @@ void LoginHelper::init()
});
}
void LoginHelper::setHomeserverReachable(bool reachable)
void Login::setHomeserverReachable(bool reachable)
{
m_homeserverReachable = reachable;
Q_EMIT homeserverReachableChanged();
}
bool LoginHelper::homeserverReachable() const
bool Login::homeserverReachable() const
{
return m_homeserverReachable;
}
QString LoginHelper::matrixId() const
QString Login::matrixId() const
{
return m_matrixId;
}
void LoginHelper::setMatrixId(const QString &matrixId)
void Login::setMatrixId(const QString &matrixId)
{
m_matrixId = matrixId;
if (!m_matrixId.startsWith(QLatin1Char('@'))) {
@@ -130,30 +130,30 @@ void LoginHelper::setMatrixId(const QString &matrixId)
Q_EMIT matrixIdChanged();
}
QString LoginHelper::password() const
QString Login::password() const
{
return m_password;
}
void LoginHelper::setPassword(const QString &password)
void Login::setPassword(const QString &password)
{
setInvalidPassword(false);
m_password = password;
Q_EMIT passwordChanged();
}
QString LoginHelper::deviceName() const
QString Login::deviceName() const
{
return m_deviceName;
}
void LoginHelper::setDeviceName(const QString &deviceName)
void Login::setDeviceName(const QString &deviceName)
{
m_deviceName = deviceName;
Q_EMIT deviceNameChanged();
}
void LoginHelper::login()
void Login::login()
{
m_isLoggingIn = true;
Q_EMIT isLoggingInChanged();
@@ -164,22 +164,22 @@ void LoginHelper::login()
m_connection->loginWithPassword(username, m_password, m_deviceName, QString());
}
bool LoginHelper::supportsPassword() const
bool Login::supportsPassword() const
{
return m_supportsPassword;
}
bool LoginHelper::supportsSso() const
bool Login::supportsSso() const
{
return m_supportsSso;
}
QUrl LoginHelper::ssoUrl() const
QUrl Login::ssoUrl() const
{
return m_ssoUrl;
}
void LoginHelper::loginWithSso()
void Login::loginWithSso()
{
m_connection->resolveServer(m_matrixId);
connectSingleShot(m_connection, &Connection::loginFlowsChanged, this, [this]() {
@@ -189,28 +189,28 @@ void LoginHelper::loginWithSso()
});
}
bool LoginHelper::testing() const
bool Login::testing() const
{
return m_testing;
}
bool LoginHelper::isLoggingIn() const
bool Login::isLoggingIn() const
{
return m_isLoggingIn;
}
bool LoginHelper::isLoggedIn() const
bool Login::isLoggedIn() const
{
return m_isLoggedIn;
}
void LoginHelper::setInvalidPassword(bool invalid)
void Login::setInvalidPassword(bool invalid)
{
m_invalidPassword = invalid;
Q_EMIT isInvalidPasswordChanged();
}
bool LoginHelper::isInvalidPassword() const
bool Login::isInvalidPassword() const
{
return m_invalidPassword;
}

View File

@@ -4,21 +4,18 @@
#pragma once
#include <QObject>
#include <QQmlEngine>
#include <QUrl>
class NeoChatConnection;
/**
* @class LoginHelper
* @class Login
*
* A helper class for logging into a Matrix account.
*/
class LoginHelper : public QObject
class Login : public QObject
{
Q_OBJECT
QML_ELEMENT
QML_SINGLETON
/**
* @brief Whether the home server for the account is reachable.
@@ -79,7 +76,7 @@ class LoginHelper : public QObject
Q_PROPERTY(bool isInvalidPassword READ isInvalidPassword NOTIFY isInvalidPasswordChanged)
public:
explicit LoginHelper(QObject *parent = nullptr);
explicit Login(QObject *parent = nullptr);
Q_INVOKABLE void init();

View File

@@ -44,9 +44,11 @@
#include "actionshandler.h"
#include "blurhashimageprovider.h"
#include "chatdocumenthandler.h"
#include "clipboard.h"
#include "controller.h"
#include "delegatesizehelper.h"
#include "enums/delegatetype.h"
#include "filetypesingleton.h"
#include "linkpreviewer.h"
#include "locationhelper.h"
#include "logger.h"
@@ -80,6 +82,9 @@
#include "models/userlistmodel.h"
#include "models/webshortcutmodel.h"
#include "neochatconfig.h"
#include "neochatconnection.h"
#include "neochatroom.h"
#include "notificationsmanager.h"
#include "pollhandler.h"
#include "roommanager.h"
#include "spacehierarchycache.h"
@@ -104,8 +109,6 @@
using namespace Quotient;
void qml_register_types_org_kde_neochat();
class NetworkAccessManagerFactory : public QQmlNetworkAccessManagerFactory
{
QNetworkAccessManager *create(QObject *) override
@@ -212,18 +215,96 @@ int main(int argc, char *argv[])
QStringLiteral("/var/config/fontconfig/conf.d/99-noto-mono-color-emoji.conf"));
#endif
Clipboard clipboard;
auto config = NeoChatConfig::self();
FileTypeSingleton fileTypeSingleton;
Login *login = new Login();
UrlHelper urlHelper;
#ifdef HAVE_COLORSCHEME
ColorSchemer colorScheme;
if (!NeoChatConfig::self()->colorScheme().isEmpty()) {
colorScheme.apply(NeoChatConfig::self()->colorScheme());
qmlRegisterSingletonInstance<ColorSchemer>("org.kde.neochat", 1, 0, "ColorSchemer", &colorScheme);
if (!config->colorScheme().isEmpty()) {
colorScheme.apply(config->colorScheme());
}
#endif
qml_register_types_org_kde_neochat();
qmlRegisterSingletonInstance("org.kde.neochat.config", 1, 0, "Config", NeoChatConfig::self());
qmlRegisterSingletonInstance("org.kde.neochat.accounts", 1, 0, "AccountRegistry", &Controller::instance().accounts());
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "Controller", &Controller::instance());
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "NotificationsManager", &NotificationsManager::instance());
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "Clipboard", &clipboard);
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "Config", config);
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "RoomManager", &RoomManager::instance());
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "FileType", &fileTypeSingleton);
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, "SpaceHierarchyCache", &SpaceHierarchyCache::instance());
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "CustomEmojiModel", &CustomEmojiModel::instance());
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "Registration", &Registration::instance());
qmlRegisterType<ActionsHandler>("org.kde.neochat", 1, 0, "ActionsHandler");
qmlRegisterType<ChatDocumentHandler>("org.kde.neochat", 1, 0, "ChatDocumentHandler");
qmlRegisterType<RoomListModel>("org.kde.neochat", 1, 0, "RoomListModel");
qmlRegisterType<KWebShortcutModel>("org.kde.neochat", 1, 0, "WebShortcutModel");
qmlRegisterType<UserListModel>("org.kde.neochat", 1, 0, "UserListModel");
qmlRegisterType<MessageEventModel>("org.kde.neochat", 1, 0, "MessageEventModel");
qmlRegisterType<ReactionModel>("org.kde.neochat", 1, 0, "ReactionModel");
qmlRegisterType<MediaMessageFilterModel>("org.kde.neochat", 1, 0, "MediaMessageFilterModel");
qmlRegisterType<MessageFilterModel>("org.kde.neochat", 1, 0, "MessageFilterModel");
qmlRegisterType<UserFilterModel>("org.kde.neochat", 1, 0, "UserFilterModel");
qmlRegisterType<PublicRoomListModel>("org.kde.neochat", 1, 0, "PublicRoomListModel");
qmlRegisterType<UserDirectoryListModel>("org.kde.neochat", 1, 0, "UserDirectoryListModel");
qmlRegisterType<ServerListModel>("org.kde.neochat", 1, 0, "ServerListModel");
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");
qmlRegisterType<StateFilterModel>("org.kde.neochat", 1, 0, "StateFilterModel");
qmlRegisterType<SearchModel>("org.kde.neochat", 1, 0, "SearchModel");
qmlRegisterType<LiveLocationsModel>("org.kde.neochat", 1, 0, "LiveLocationsModel");
qmlRegisterType<LocationsModel>("org.kde.neochat", 1, 0, "LocationsModel");
qmlRegisterType<PollHandler>("org.kde.neochat", 1, 0, "PollHandler");
qmlRegisterType<PushRuleModel>("org.kde.neochat", 1, 0, "PushRuleModel");
qmlRegisterType<StickerModel>("org.kde.neochat", 1, 0, "StickerModel");
qmlRegisterType<ImagePacksModel>("org.kde.neochat", 1, 0, "ImagePacksModel");
qmlRegisterType<AccountEmoticonModel>("org.kde.neochat", 1, 0, "AccountEmoticonModel");
qmlRegisterType<EmoticonFilterModel>("org.kde.neochat", 1, 0, "EmoticonFilterModel");
qmlRegisterType<DelegateSizeHelper>("org.kde.neochat", 1, 0, "DelegateSizeHelper");
qmlRegisterType<MediaSizeHelper>("org.kde.neochat", 1, 0, "MediaSizeHelper");
qmlRegisterUncreatableType<DelegateType>("org.kde.neochat", 1, 0, "DelegateType", "ENUM"_ls);
qmlRegisterUncreatableType<PushNotificationKind>("org.kde.neochat", 1, 0, "PushNotificationKind", "ENUM"_ls);
qmlRegisterUncreatableType<PushNotificationSection>("org.kde.neochat", 1, 0, "PushNotificationSection", "ENUM"_ls);
qmlRegisterUncreatableType<PushNotificationState>("org.kde.neochat", 1, 0, "PushNotificationState", "ENUM"_ls);
qmlRegisterUncreatableType<PushNotificationAction>("org.kde.neochat", 1, 0, "PushNotificationAction", "ENUM"_ls);
qmlRegisterUncreatableType<NeoChatRoomType>("org.kde.neochat", 1, 0, "NeoChatRoomType", "ENUM"_ls);
qmlRegisterUncreatableType<User>("org.kde.neochat", 1, 0, "User", {});
qmlRegisterUncreatableType<NeoChatRoom>("org.kde.neochat", 1, 0, "NeoChatRoom", {});
qmlRegisterUncreatableType<NeoChatConnection>("org.kde.neochat", 1, 0, "NeoChatConnection", {});
// qmlRegisterUncreatableType<KeyVerificationSession>("org.kde.neochat", 1, 0, "KeyVerificationSession", {});
qmlRegisterSingletonType(QUrl("qrc:/ContextMenu.qml"), "org.kde.neochat", 1, 0, "ContextMenu");
qRegisterMetaType<User *>("User*");
qRegisterMetaType<User *>("const User*");
qRegisterMetaType<User *>("const Quotient::User*");
qRegisterMetaType<Room *>("Room*");
qRegisterMetaType<MessageEventType>("MessageEventType");
qRegisterMetaType<NeoChatRoom *>("NeoChatRoom*");
qRegisterMetaType<User *>("User*");
qRegisterMetaType<GetRoomEventsJob *>("GetRoomEventsJob*");
qRegisterMetaType<QMimeType>("QMimeType");
qRegisterMetaType<KeyVerificationSession *>("KeyVerificationSession*");
qmlRegisterUncreatableType<KeyVerificationSession>("org.kde.neochat", 1, 0, "KeyVerificationSession", {});
qRegisterMetaType<QVector<EmojiEntry>>("QVector<EmojiEntry>");
qmlRegisterSingletonType("org.kde.neochat", 1, 0, "About", [](QQmlEngine *engine, QJSEngine *) -> QJSValue {
return engine->toScriptValue(KAboutData::applicationData());
});
qmlRegisterSingletonType(QUrl("qrc:/OsmLocationPlugin.qml"_ls), "org.kde.neochat", 1, 0, "OsmLocationPlugin");
qmlRegisterSingletonType("org.kde.neochat", 1, 0, "LocationHelper", [](QQmlEngine *engine, QJSEngine *) -> QJSValue {
return engine->toScriptValue(LocationHelper());
});
QQmlApplicationEngine engine;
@@ -274,7 +355,7 @@ int main(int argc, char *argv[])
engine.addImageProvider(QLatin1String("mxc"), new MatrixImageProvider);
engine.addImageProvider(QLatin1String("blurhash"), new BlurhashImageProvider);
engine.load(QUrl(QStringLiteral("qrc:/org/kde/neochat/qml/main.qml")));
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty()) {
return -1;
}

View File

@@ -4,7 +4,6 @@
#pragma once
#include <QObject>
#include <QQmlEngine>
#include <QSize>
/**
@@ -29,7 +28,6 @@
class MediaSizeHelper : public QObject
{
Q_OBJECT
QML_ELEMENT
/**
* @brief The maximum width (in px) the media can be.

View File

@@ -9,7 +9,6 @@
#include <QCoroTask>
#include <QObject>
#include <QPointer>
#include <QQmlEngine>
#include <QVector>
#include <Quotient/connection.h>
@@ -24,8 +23,6 @@
class AccountEmoticonModel : public QAbstractListModel
{
Q_OBJECT
QML_ELEMENT
/**
* @brief The connection to get emoticons from.
*/

View File

@@ -87,11 +87,8 @@ QVariant CompletionModel::data(const QModelIndex &index, int role) const
return m_filterModel->data(filterIndex, RoomListModel::CanonicalAliasRole);
}
if (role == IconNameRole) {
auto mediaId = m_filterModel->data(filterIndex, RoomListModel::AvatarRole).toString();
if (mediaId.isEmpty()) {
return QVariant();
}
return m_room->connection()->makeMediaUrl(QUrl(QStringLiteral("mxc://%1").arg(mediaId)));
return QStringLiteral("mxc://%1")
.arg(m_roomListModel->connection()->makeMediaUrl(m_filterModel->data(filterIndex, RoomListModel::AvatarRole).toUrl()).toString());
}
}
if (m_autoCompletionType == Emoji) {

View File

@@ -4,7 +4,6 @@
#pragma once
#include <QConcatenateTablesProxyModel>
#include <QQmlEngine>
#include <QSortFilterProxyModel>
#include "roomlistmodel.h"
@@ -25,7 +24,6 @@ class RoomListModel;
class CompletionModel : public QAbstractListModel
{
Q_OBJECT
QML_ELEMENT
/**
* @brief The current text to search for completions.

View File

@@ -4,7 +4,6 @@
#pragma once
#include <QAbstractListModel>
#include <QQmlEngine>
#include <QRegularExpression>
#include <memory>
@@ -28,8 +27,6 @@ struct CustomEmoji {
class CustomEmojiModel : public QAbstractListModel
{
Q_OBJECT
QML_ELEMENT
QML_SINGLETON
public:
/**
@@ -51,10 +48,6 @@ public:
static CustomEmojiModel _instance;
return _instance;
}
static CustomEmojiModel *create(QQmlEngine *, QJSEngine *)
{
return &instance();
}
/**
* @brief Get the given role value at the given index.

View File

@@ -5,7 +5,6 @@
#include <QAbstractListModel>
#include <QPointer>
#include <QQmlEngine>
#include <Quotient/csapi/definitions/client_device.h>
@@ -26,7 +25,6 @@ class Connection;
class DevicesModel : public QAbstractListModel
{
Q_OBJECT
QML_ELEMENT
/**
* @brief The current connection that the model is getting its devices from.

View File

@@ -3,14 +3,11 @@
#pragma once
#include <QQmlEngine>
#include <QSortFilterProxyModel>
class DevicesProxyModel : public QSortFilterProxyModel
{
Q_OBJECT
QML_ELEMENT
Q_PROPERTY(int type READ type WRITE setType NOTIFY typeChanged)
public:

View File

@@ -5,7 +5,6 @@
#include <QAbstractListModel>
#include <QObject>
#include <QQmlEngine>
#include <QSettings>
struct Emoji {
@@ -60,8 +59,6 @@ Q_DECLARE_METATYPE(Emoji)
class EmojiModel : public QAbstractListModel
{
Q_OBJECT
QML_ELEMENT
QML_SINGLETON
/**
* @brief Return a list of recently used emojis.
@@ -86,10 +83,6 @@ public:
static EmojiModel _instance;
return _instance;
}
static EmojiModel *create(QQmlEngine *, QJSEngine *)
{
return &instance();
}
/**
* @brief Defines the model roles.

View File

@@ -3,7 +3,6 @@
#pragma once
#include <QQmlEngine>
#include <QSortFilterProxyModel>
/**
@@ -15,7 +14,6 @@
class EmoticonFilterModel : public QSortFilterProxyModel
{
Q_OBJECT
QML_ELEMENT
/**
* @brief Whether stickers should be shown

View File

@@ -6,7 +6,6 @@
#include "events/imagepackevent.h"
#include <QAbstractListModel>
#include <QPointer>
#include <QQmlEngine>
#include <QVector>
class NeoChatRoom;
@@ -22,7 +21,6 @@ class NeoChatRoom;
class ImagePacksModel : public QAbstractListModel
{
Q_OBJECT
QML_ELEMENT
/**
* @brief The current room that the model is being used in.

View File

@@ -8,7 +8,6 @@
#include <QAbstractListModel>
#include <QPointer>
#include <QQmlEngine>
#include <QRectF>
struct LiveLocationData {
@@ -25,8 +24,6 @@ bool operator<(const LiveLocationData &lhs, const LiveLocationData &rhs);
class LiveLocationsModel : public QAbstractListModel
{
Q_OBJECT
QML_ELEMENT
Q_PROPERTY(NeoChatRoom *room MEMBER m_room NOTIFY roomChanged)
/** The event id of the beacon start event, ie. the one all suspequent
* events use to relate to the same beacon.

View File

@@ -5,7 +5,6 @@
#include <QAbstractListModel>
#include <QPointer>
#include <QQmlEngine>
#include <QRectF>
#include "neochatroom.h"
@@ -16,7 +15,6 @@
class LocationsModel : public QAbstractListModel
{
Q_OBJECT
QML_ELEMENT
public:
enum Roles {

View File

@@ -3,8 +3,8 @@
#pragma once
#include <QQmlEngine>
#include <QSortFilterProxyModel>
#include <qobjectdefs.h>
#include "models/messagefiltermodel.h"
@@ -20,8 +20,6 @@ class MessageFilterModel;
class MediaMessageFilterModel : public QSortFilterProxyModel
{
Q_OBJECT
QML_ELEMENT
public:
enum MediaType {
Image = 0,

View File

@@ -55,6 +55,7 @@ QHash<int, QByteArray> MessageEventModel::roleNames() const
roles[ShowReadMarkersRole] = "showReadMarkers";
roles[ReactionRole] = "reaction";
roles[ShowReactionsRole] = "showReactions";
roles[SourceRole] = "jsonSource";
roles[AuthorIdRole] = "authorId";
roles[VerifiedRole] = "verified";
roles[AuthorDisplayNameRole] = "authorDisplayName";
@@ -466,6 +467,10 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
return eventHandler.getPlainBody();
}
if (role == SourceRole) {
return QJsonDocument(evt.fullJson()).toJson();
}
if (role == DelegateTypeRole) {
return eventHandler.getDelegateType();
}

View File

@@ -5,7 +5,6 @@
#include <KFormat>
#include <QAbstractListModel>
#include <QQmlEngine>
#include "linkpreviewer.h"
#include "neochatroom.h"
@@ -26,7 +25,6 @@ class ReactionModel;
class MessageEventModel : public QAbstractListModel
{
Q_OBJECT
QML_ELEMENT
/**
* @brief The current room that the model is getting its messages from.
@@ -72,6 +70,7 @@ public:
ShowReadMarkersRole, /**< Whether there are any other user read markers to be shown. */
ReactionRole, /**< List model for this event. */
ShowReactionsRole, /**< Whether there are any reactions to be shown. */
SourceRole, /**< The full message source JSON. */
AuthorIdRole, /**< Matrix ID of the message author. */

View File

@@ -3,7 +3,6 @@
#pragma once
#include <QQmlEngine>
#include <QSortFilterProxyModel>
#include "messageeventmodel.h"
@@ -22,8 +21,6 @@
class MessageFilterModel : public QSortFilterProxyModel
{
Q_OBJECT
QML_ELEMENT
public:
/**
* @brief Defines the model roles.

View File

@@ -5,7 +5,6 @@
#include <QAbstractListModel>
#include <QObject>
#include <QQmlEngine>
#include <Quotient/csapi/list_public_rooms.h>
@@ -28,7 +27,6 @@ class Connection;
class PublicRoomListModel : public QAbstractListModel
{
Q_OBJECT
QML_ELEMENT
/**
* @brief The current connection that the model is getting its rooms from.

View File

@@ -171,7 +171,7 @@ PushNotificationSection::Section PushRuleModel::getSection(Quotient::PushRule ru
if (!testUserId.startsWith(u'@')) {
testUserId.prepend(u'@');
}
if (testUserId.startsWith(u'@') && !Quotient::serverPart(testUserId).isEmpty() && connection->user(testUserId) != nullptr) {
if (connection->user(testUserId) != nullptr) {
return PushNotificationSection::Undefined;
}
// If the rule has push conditions and one is a room ID it is a room only keyword.

View File

@@ -4,7 +4,6 @@
#pragma once
#include <QAbstractListModel>
#include <QQmlEngine>
#include <Quotient/csapi/definitions/push_rule.h>
@@ -21,8 +20,6 @@
class PushNotificationKind : public QObject
{
Q_OBJECT
QML_ELEMENT
QML_UNCREATABLE("")
public:
/**
@@ -74,8 +71,6 @@ public:
class PushNotificationSection : public QObject
{
Q_OBJECT
QML_ELEMENT
QML_UNCREATABLE("")
public:
/**
@@ -135,7 +130,6 @@ public:
class PushRuleModel : public QAbstractListModel
{
Q_OBJECT
QML_ELEMENT
/**
* @brief The default state for any newly created keyword rule.

View File

@@ -4,7 +4,6 @@
#pragma once
#include <QAbstractListModel>
#include <QQmlEngine>
namespace Quotient
{
@@ -19,7 +18,6 @@ class User;
class ReactionModel : public QAbstractListModel
{
Q_OBJECT
QML_ELEMENT
public:
/**

View File

@@ -6,7 +6,6 @@
#include <Quotient/events/roomevent.h>
#include <QAbstractListModel>
#include <QQmlEngine>
class NeoChatRoom;
@@ -19,8 +18,6 @@ class Room;
class NeoChatRoomType : public QObject
{
Q_OBJECT
QML_ELEMENT
QML_UNCREATABLE("")
public:
/**
@@ -45,7 +42,6 @@ public:
class RoomListModel : public QAbstractListModel
{
Q_OBJECT
QML_ELEMENT
/**
* @brief The current connection that the model is getting its rooms from.

View File

@@ -184,6 +184,7 @@ QHash<int, QByteArray> SearchModel::roleNames() const
{MimeTypeRole, "mimeType"},
{ShowLinkPreviewRole, "showLinkPreview"},
{LinkPreviewRole, "linkPreview"},
{SourceRole, "jsonSource"},
};
}

View File

@@ -4,7 +4,6 @@
#pragma once
#include <QAbstractListModel>
#include <QQmlEngine>
#include <QString>
#include <Quotient/csapi/search.h>
@@ -24,7 +23,6 @@ class NeoChatRoom;
class SearchModel : public QAbstractListModel
{
Q_OBJECT
QML_ELEMENT
/**
* @brief The text to search messages for.
@@ -85,6 +83,7 @@ public:
MimeTypeRole,
ShowLinkPreviewRole,
LinkPreviewRole,
SourceRole,
};
Q_ENUM(Roles)
explicit SearchModel(QObject *parent = nullptr);

View File

@@ -7,7 +7,6 @@
#include <QAbstractListModel>
#include <QPointer>
#include <QQmlEngine>
#include <QUrl>
/**
@@ -25,7 +24,6 @@
class ServerListModel : public QAbstractListModel
{
Q_OBJECT
QML_ELEMENT
public:
/**

View File

@@ -3,7 +3,6 @@
#pragma once
#include <QQmlEngine>
#include <QSortFilterProxyModel>
/**
@@ -28,7 +27,6 @@
class SortFilterRoomListModel : public QSortFilterProxyModel
{
Q_OBJECT
QML_ELEMENT
/**
* @brief The order by which the rooms will be sorted.

View File

@@ -3,7 +3,6 @@
#pragma once
#include <QQmlEngine>
#include <QSortFilterProxyModel>
/**
@@ -17,8 +16,6 @@
class SortFilterSpaceListModel : public QSortFilterProxyModel
{
Q_OBJECT
QML_ELEMENT
/**
* @brief The number of spaces in the model.
*/

View File

@@ -3,7 +3,6 @@
#pragma once
#include <QQmlEngine>
#include <QSortFilterProxyModel>
/**
@@ -15,7 +14,6 @@
class StateFilterModel : public QSortFilterProxyModel
{
Q_OBJECT
QML_ELEMENT
public:
/**

View File

@@ -4,7 +4,6 @@
#pragma once
#include <QAbstractListModel>
#include <QQmlEngine>
#include "neochatroom.h"
@@ -16,7 +15,6 @@
class StateModel : public QAbstractListModel
{
Q_OBJECT
QML_ELEMENT
/**
* @brief The current room that the model is getting its state events from.

View File

@@ -7,7 +7,6 @@
#include "neochatroom.h"
#include <QAbstractListModel>
#include <QObject>
#include <QQmlEngine>
#include <QVector>
class ImagePacksModel;
@@ -23,7 +22,6 @@ class ImagePacksModel;
class StickerModel : public QAbstractListModel
{
Q_OBJECT
QML_ELEMENT
/**
* @brief The image pack that the stickers come from.

View File

@@ -5,7 +5,6 @@
#include <QAbstractListModel>
#include <QObject>
#include <QQmlEngine>
#include <Quotient/csapi/users.h>
@@ -27,7 +26,6 @@ class Connection;
class UserDirectoryListModel : public QAbstractListModel
{
Q_OBJECT
QML_ELEMENT
/**
* @brief The current connection that the model is getting users from.

View File

@@ -3,7 +3,6 @@
#pragma once
#include <QQmlEngine>
#include <QSortFilterProxyModel>
/**
@@ -16,7 +15,6 @@
class UserFilterModel : public QSortFilterProxyModel
{
Q_OBJECT
QML_ELEMENT
/**
* @brief This property hold the text of the filter.

View File

@@ -8,7 +8,6 @@
#include <QAbstractListModel>
#include <QObject>
#include <QPointer>
#include <QQmlEngine>
class NeoChatRoom;
@@ -30,7 +29,6 @@ class User;
class UserListModel : public QAbstractListModel
{
Q_OBJECT
QML_ELEMENT
/**
* @brief The room that the model is getting its users from.

View File

@@ -10,7 +10,7 @@
#endif
#include <KStringHandler>
struct WebShortcutModelPrivate {
struct KWebShortcutModelPrivate {
QString selectedText;
#ifdef HAVE_KIO
KUriFilterData filterData;
@@ -18,27 +18,27 @@ struct WebShortcutModelPrivate {
QStringList searchProviders;
};
WebShortcutModel::WebShortcutModel(QObject *parent)
KWebShortcutModel::KWebShortcutModel(QObject *parent)
: QAbstractListModel(parent)
, d(new WebShortcutModelPrivate)
, d(new KWebShortcutModelPrivate)
{
}
WebShortcutModel::~WebShortcutModel()
KWebShortcutModel::~KWebShortcutModel()
{
}
QString WebShortcutModel::selectedText() const
QString KWebShortcutModel::selectedText() const
{
return d->selectedText;
}
QString WebShortcutModel::trunkatedSearchText() const
QString KWebShortcutModel::trunkatedSearchText() const
{
return KStringHandler::rsqueeze(d->selectedText, 21);
}
bool WebShortcutModel::enabled() const
bool KWebShortcutModel::enabled() const
{
#ifdef HAVE_KIO
return true;
@@ -47,7 +47,7 @@ bool WebShortcutModel::enabled() const
#endif
}
void WebShortcutModel::setSelectedText(const QString &selectedText)
void KWebShortcutModel::setSelectedText(const QString &selectedText)
{
if (d->selectedText == selectedText) {
return;
@@ -80,7 +80,7 @@ void WebShortcutModel::setSelectedText(const QString &selectedText)
Q_EMIT selectedTextChanged();
}
int WebShortcutModel::rowCount(const QModelIndex &parent) const
int KWebShortcutModel::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent);
#ifdef HAVE_KIO
@@ -91,7 +91,7 @@ int WebShortcutModel::rowCount(const QModelIndex &parent) const
return 0;
}
QVariant WebShortcutModel::data(const QModelIndex &index, int role) const
QVariant KWebShortcutModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid()) {
return {};
@@ -110,7 +110,7 @@ QVariant WebShortcutModel::data(const QModelIndex &index, int role) const
return {};
}
void WebShortcutModel::trigger(const QString &data)
void KWebShortcutModel::trigger(const QString &data)
{
#ifdef HAVE_KIO
KUriFilterData filterData(data);
@@ -122,7 +122,7 @@ void WebShortcutModel::trigger(const QString &data)
#endif
}
void WebShortcutModel::configureWebShortcuts()
void KWebShortcutModel::configureWebShortcuts()
{
#ifdef HAVE_KIO
auto job = new KIO::CommandLauncherJob(QStringLiteral("kcmshell5"), QStringList() << QStringLiteral("webshortcuts"), this);

View File

@@ -4,13 +4,12 @@
#pragma once
#include <QAbstractListModel>
#include <QQmlEngine>
#include <memory>
struct WebShortcutModelPrivate;
struct KWebShortcutModelPrivate;
/**
* @class WebShortcutModel
* @class KWebShortcutModel
*
* This class defines the model for listing web shortcuts for a specified selectedText.
*
@@ -46,10 +45,9 @@ struct WebShortcutModelPrivate;
* }
* ```
*/
class WebShortcutModel : public QAbstractListModel
class KWebShortcutModel : public QAbstractListModel
{
Q_OBJECT
QML_ELEMENT
/**
* @brief The text to find web shortcuts for.
@@ -66,8 +64,8 @@ class WebShortcutModel : public QAbstractListModel
*/
Q_PROPERTY(bool enabled READ enabled CONSTANT)
public:
explicit WebShortcutModel(QObject *parent = nullptr);
~WebShortcutModel();
explicit KWebShortcutModel(QObject *parent = nullptr);
~KWebShortcutModel();
QString selectedText() const;
void setSelectedText(const QString &selectedText);
@@ -105,5 +103,5 @@ Q_SIGNALS:
void openUrl(const QUrl &url);
private:
std::unique_ptr<WebShortcutModelPrivate> d;
std::unique_ptr<KWebShortcutModelPrivate> d;
};

View File

@@ -4,15 +4,12 @@
#pragma once
#include <QObject>
#include <QQmlEngine>
#include <Quotient/connection.h>
class NeoChatConnection : public Quotient::Connection
{
Q_OBJECT
QML_ELEMENT
QML_UNCREATABLE("")
/**
* @brief The account label for this account.

View File

@@ -39,7 +39,6 @@
#include <Quotient/jobs/downloadfilejob.h>
#include <Quotient/qt_connection_util.h>
#include "clipboard.h"
#include "controller.h"
#include "eventhandler.h"
#include "events/joinrulesevent.h"
@@ -48,7 +47,6 @@
#include "neochatconfig.h"
#include "notificationsmanager.h"
#include "texthandler.h"
#include "urlhelper.h"
#include "utils.h"
#include <KConfig>
@@ -1336,72 +1334,6 @@ void NeoChatRoom::reportEvent(const QString &eventId, const QString &reason)
});
}
QByteArray NeoChatRoom::getEventJsonSource(const QString &eventId)
{
auto evtIt = findInTimeline(eventId);
if (evtIt != messageEvents().rend() && is<RoomEvent>(**evtIt)) {
const auto event = evtIt->viewAs<RoomEvent>();
return QJsonDocument(event->fullJson()).toJson();
}
return {};
}
void NeoChatRoom::openEventMediaExternally(const QString &eventId)
{
const auto evtIt = findInTimeline(eventId);
if (evtIt != messageEvents().rend() && is<RoomMessageEvent>(**evtIt)) {
const auto event = evtIt->viewAs<RoomMessageEvent>();
if (event->hasFileContent()) {
const auto transferInfo = fileTransferInfo(eventId);
if (transferInfo.completed()) {
UrlHelper helper;
helper.openUrl(transferInfo.localPath);
} else {
downloadFile(eventId,
QUrl(QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + u'/'
+ event->id().replace(u':', u'_').replace(u'/', u'_').replace(u'+', u'_') + fileNameToDownload(eventId)));
connect(this, &Room::fileTransferCompleted, this, [this, eventId](QString id, QUrl localFile, FileSourceInfo fileMetadata) {
Q_UNUSED(localFile);
Q_UNUSED(fileMetadata);
if (id == eventId) {
auto transferInfo = fileTransferInfo(eventId);
UrlHelper helper;
helper.openUrl(transferInfo.localPath);
}
});
}
}
}
}
void NeoChatRoom::copyEventMedia(const QString &eventId)
{
const auto evtIt = findInTimeline(eventId);
if (evtIt != messageEvents().rend() && is<RoomMessageEvent>(**evtIt)) {
const auto event = evtIt->viewAs<RoomMessageEvent>();
if (event->hasFileContent()) {
const auto transferInfo = fileTransferInfo(eventId);
if (transferInfo.completed()) {
Clipboard clipboard;
clipboard.setImage(transferInfo.localPath);
} else {
downloadFile(eventId,
QUrl(QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + u'/'
+ event->id().replace(u':', u'_').replace(u'/', u'_').replace(u'+', u'_') + fileNameToDownload(eventId)));
connect(this, &Room::fileTransferCompleted, this, [this, eventId](QString id, QUrl localFile, FileSourceInfo fileMetadata) {
Q_UNUSED(localFile);
Q_UNUSED(fileMetadata);
if (id == eventId) {
auto transferInfo = fileTransferInfo(eventId);
Clipboard clipboard;
clipboard.setImage(transferInfo.localPath);
}
});
}
}
}
}
QString NeoChatRoom::chatBoxText() const
{
return m_chatBoxText;
@@ -1488,11 +1420,8 @@ QString NeoChatRoom::chatBoxEditMessage() const
EventHandler eventhandler;
eventhandler.setRoom(this);
if (auto event = findInTimeline(m_chatBoxEditId); event != historyEdge()) {
eventhandler.setEvent(&**event);
return eventhandler.getPlainBody();
}
return {};
eventhandler.setEvent(&**findInTimeline(m_chatBoxEditId));
return eventhandler.getPlainBody();
}
QString NeoChatRoom::chatBoxAttachmentPath() const
@@ -1765,9 +1694,4 @@ void NeoChatRoom::loadReply(const QString &eventId, const QString &replyId)
});
}
User *NeoChatRoom::invitingUser() const
{
return connection()->user(currentState().get<RoomMemberEvent>(connection()->userId())->senderId());
}
#include "moc_neochatroom.cpp"

View File

@@ -7,7 +7,6 @@
#include <QCache>
#include <QObject>
#include <QQmlEngine>
#include <QTextCursor>
#include <QCoroTask>
@@ -23,8 +22,6 @@ class User;
class PushNotificationState : public QObject
{
Q_OBJECT
QML_ELEMENT
QML_UNCREATABLE("")
public:
/**
@@ -66,8 +63,6 @@ struct Mention {
class NeoChatRoom : public Quotient::Room
{
Q_OBJECT
QML_ELEMENT
QML_UNCREATABLE("")
/**
* @brief A list of users currently typing in the room.
@@ -556,22 +551,6 @@ public:
*/
Q_INVOKABLE void reportEvent(const QString &eventId, const QString &reason);
Q_INVOKABLE QByteArray getEventJsonSource(const QString &eventId);
/**
* @brief Open the media for the given event in an appropriate external app.
*
* Will do nothing if the event has no media.
*/
Q_INVOKABLE void openEventMediaExternally(const QString &eventId);
/**
* @brief Copy the media for the given event to the clipboard.
*
* Will do nothing if the event has no media.
*/
Q_INVOKABLE void copyEventMedia(const QString &eventId);
[[nodiscard]] bool readMarkerLoaded() const;
/**
@@ -815,11 +794,6 @@ public:
*/
Q_INVOKABLE void loadReply(const QString &eventId, const QString &replyId);
/**
* If we're invited to this room, the user that invited us. Undefined in other cases.
*/
Q_INVOKABLE Quotient::User *invitingUser() const;
private:
QSet<const Quotient::RoomEvent *> highlights;

View File

@@ -6,8 +6,6 @@
#include <memory>
#include <QGuiApplication>
#include <QJsonArray>
#include <QJsonDocument>
#include <KLocalizedString>
#include <KNotification>
@@ -248,7 +246,7 @@ void NotificationsManager::postInviteNotification(NeoChatRoom *room, const QStri
notification->close();
RoomManager::instance().enterRoom(room);
});
notification->setActions({i18nc("@action:button The thing being accepted is an invitation to chat", "Accept"), i18nc("@action:button The thing being rejected is an invitation to chat", "Reject"), i18nc("@action:button The thing being rejected is an invitation to chat", "Reject and Ignore User")});
notification->setActions({i18n("Accept Invitation"), i18n("Reject Invitation")});
connect(notification, &KNotification::action1Activated, this, [room, notification]() {
if (!room) {
return;
@@ -263,14 +261,6 @@ void NotificationsManager::postInviteNotification(NeoChatRoom *room, const QStri
RoomManager::instance().leaveRoom(room);
notification->close();
});
connect(notification, &KNotification::action3Activated, this, [room, notification]() {
if (!room) {
return;
}
RoomManager::instance().leaveRoom(room);
room->connection()->addToIgnoredUsers(room->invitingUser());
notification->close();
});
connect(notification, &KNotification::closed, this, [this, room]() {
if (!room) {
return;
@@ -328,33 +318,4 @@ QPixmap NotificationsManager::createNotificationImage(const QImage &icon, NeoCha
return QPixmap::fromImage(roundedImage);
}
void NotificationsManager::postPushNotification(const QByteArray &message)
{
KNotification *notification = new KNotification("message"_ls);
const auto json = QJsonDocument::fromJson(message).object();
auto sender = json["notification"_ls]["sender_display_name"_ls].toString();
auto roomName = json["notification"_ls]["room_name"_ls].toString();
auto roomId = json["notification"_ls]["room_id"_ls].toString();
auto text = json["notification"_ls]["content"_ls]["body"_ls].toString();
if (sender == roomName) {
notification->setTitle(sender);
} else {
notification->setTitle(i18n("%1 (%2)", sender, roomName));
}
notification->setText(text.toHtmlEscaped());
notification->setDefaultAction(i18n("Open NeoChat in this room"));
connect(notification, &KNotification::defaultActivated, this, [=]() {
WindowController::instance().showAndRaiseWindow(notification->xdgActivationToken());
});
notification->sendEvent();
m_notifications.insert(roomId, notification);
}
#include "moc_notificationsmanager.cpp"

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