Compare commits
6 Commits
v24.04.80
...
work/adapt
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7cc68d2658 | ||
|
|
f4b87caefe | ||
|
|
07a9497f4c | ||
|
|
35f1ace458 | ||
|
|
11dd0ee151 | ||
|
|
07e200c74f |
@@ -110,7 +110,7 @@
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/quotient-im/libQuotient.git",
|
||||
"branch": "0.8.x",
|
||||
"branch": "dev",
|
||||
"disable-submodules": true
|
||||
}
|
||||
],
|
||||
|
||||
@@ -9,7 +9,7 @@ cmake_minimum_required(VERSION 3.16)
|
||||
# KDE Applications version, managed by release script.
|
||||
set(RELEASE_SERVICE_VERSION_MAJOR "24")
|
||||
set(RELEASE_SERVICE_VERSION_MINOR "04")
|
||||
set(RELEASE_SERVICE_VERSION_MICRO "80")
|
||||
set(RELEASE_SERVICE_VERSION_MICRO "70")
|
||||
set(RELEASE_SERVICE_VERSION "${RELEASE_SERVICE_VERSION_MAJOR}.${RELEASE_SERVICE_VERSION_MINOR}.${RELEASE_SERVICE_VERSION_MICRO}")
|
||||
|
||||
project(NeoChat VERSION ${RELEASE_SERVICE_VERSION})
|
||||
|
||||
@@ -105,7 +105,7 @@ void EventHandlerTest::author()
|
||||
|
||||
auto eventHandlerAuthor = eventHandler.getAuthor();
|
||||
|
||||
QCOMPARE(eventHandlerAuthor["isLocalUser"_ls], author->id() == room->localUser()->id());
|
||||
QCOMPARE(eventHandlerAuthor["isLocalUser"_ls], author->id() == room->localMember().id());
|
||||
QCOMPARE(eventHandlerAuthor["id"_ls], author->id());
|
||||
QCOMPARE(eventHandlerAuthor["displayName"_ls], author->displayname(room));
|
||||
QCOMPARE(eventHandlerAuthor["avatarSource"_ls], room->avatarForMember(author));
|
||||
@@ -390,7 +390,7 @@ void EventHandlerTest::replyAuthor()
|
||||
|
||||
auto eventHandlerReplyAuthor = eventHandler.getReplyAuthor();
|
||||
|
||||
QCOMPARE(eventHandlerReplyAuthor["isLocalUser"_ls], replyAuthor->id() == room->localUser()->id());
|
||||
QCOMPARE(eventHandlerReplyAuthor["isLocalUser"_ls], replyAuthor->id() == room->localMember().id());
|
||||
QCOMPARE(eventHandlerReplyAuthor["id"_ls], replyAuthor->id());
|
||||
QCOMPARE(eventHandlerReplyAuthor["displayName"_ls], replyAuthor->displayname(room));
|
||||
QCOMPARE(eventHandlerReplyAuthor["avatarSource"_ls], room->avatarForMember(replyAuthor));
|
||||
|
||||
407
po/ar/neochat.po
407
po/ar/neochat.po
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
405
po/az/neochat.po
405
po/az/neochat.po
File diff suppressed because it is too large
Load Diff
397
po/ca/neochat.po
397
po/ca/neochat.po
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
400
po/cs/neochat.po
400
po/cs/neochat.po
File diff suppressed because it is too large
Load Diff
398
po/da/neochat.po
398
po/da/neochat.po
File diff suppressed because it is too large
Load Diff
407
po/de/neochat.po
407
po/de/neochat.po
File diff suppressed because it is too large
Load Diff
407
po/el/neochat.po
407
po/el/neochat.po
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
403
po/eo/neochat.po
403
po/eo/neochat.po
File diff suppressed because it is too large
Load Diff
399
po/es/neochat.po
399
po/es/neochat.po
File diff suppressed because it is too large
Load Diff
403
po/eu/neochat.po
403
po/eu/neochat.po
File diff suppressed because it is too large
Load Diff
402
po/fi/neochat.po
402
po/fi/neochat.po
File diff suppressed because it is too large
Load Diff
407
po/fr/neochat.po
407
po/fr/neochat.po
File diff suppressed because it is too large
Load Diff
402
po/hu/neochat.po
402
po/hu/neochat.po
File diff suppressed because it is too large
Load Diff
405
po/ia/neochat.po
405
po/ia/neochat.po
File diff suppressed because it is too large
Load Diff
407
po/id/neochat.po
407
po/id/neochat.po
File diff suppressed because it is too large
Load Diff
400
po/ie/neochat.po
400
po/ie/neochat.po
File diff suppressed because it is too large
Load Diff
456
po/it/neochat.po
456
po/it/neochat.po
File diff suppressed because it is too large
Load Diff
392
po/ja/neochat.po
392
po/ja/neochat.po
File diff suppressed because it is too large
Load Diff
403
po/ka/neochat.po
403
po/ka/neochat.po
File diff suppressed because it is too large
Load Diff
402
po/ko/neochat.po
402
po/ko/neochat.po
File diff suppressed because it is too large
Load Diff
392
po/lt/neochat.po
392
po/lt/neochat.po
File diff suppressed because it is too large
Load Diff
402
po/lv/neochat.po
402
po/lv/neochat.po
File diff suppressed because it is too large
Load Diff
403
po/nl/neochat.po
403
po/nl/neochat.po
File diff suppressed because it is too large
Load Diff
407
po/nn/neochat.po
407
po/nn/neochat.po
File diff suppressed because it is too large
Load Diff
405
po/pa/neochat.po
405
po/pa/neochat.po
File diff suppressed because it is too large
Load Diff
403
po/pl/neochat.po
403
po/pl/neochat.po
File diff suppressed because it is too large
Load Diff
407
po/pt/neochat.po
407
po/pt/neochat.po
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
402
po/ru/neochat.po
402
po/ru/neochat.po
File diff suppressed because it is too large
Load Diff
406
po/sk/neochat.po
406
po/sk/neochat.po
File diff suppressed because it is too large
Load Diff
399
po/sl/neochat.po
399
po/sl/neochat.po
File diff suppressed because it is too large
Load Diff
407
po/sv/neochat.po
407
po/sv/neochat.po
File diff suppressed because it is too large
Load Diff
450
po/ta/neochat.po
450
po/ta/neochat.po
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
405
po/tr/neochat.po
405
po/tr/neochat.po
File diff suppressed because it is too large
Load Diff
403
po/uk/neochat.po
403
po/uk/neochat.po
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -204,6 +204,7 @@ qt_add_qml_module(neochat URI org.kde.neochat NO_PLUGIN
|
||||
qml/InviteUserPage.qml
|
||||
qml/ImageEditorPage.qml
|
||||
qml/NeochatMaximizeComponent.qml
|
||||
qml/FancyEffectsContainer.qml
|
||||
qml/TypingPane.qml
|
||||
qml/QuickSwitcher.qml
|
||||
qml/HoverActions.qml
|
||||
@@ -280,6 +281,9 @@ qt_add_qml_module(neochat URI org.kde.neochat NO_PLUGIN
|
||||
qml/ConfirmLeaveDialog.qml
|
||||
qml/CodeMaximizeComponent.qml
|
||||
qml/EditStateDialog.qml
|
||||
RESOURCES
|
||||
qml/confetti.png
|
||||
qml/glowdot.png
|
||||
)
|
||||
|
||||
add_subdirectory(settings)
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
#include "models/actionsmodel.h"
|
||||
#include "neochatconfig.h"
|
||||
#include "texthandler.h"
|
||||
#include "utils.h"
|
||||
|
||||
using namespace Quotient;
|
||||
|
||||
@@ -92,7 +91,7 @@ void ActionsHandler::handleMessage(const QString &text, QString handledText, Cha
|
||||
|
||||
for (auto it = m_room->messageEvents().crbegin(); it != m_room->messageEvents().crend(); it++) {
|
||||
if (const auto event = eventCast<const RoomMessageEvent>(&**it)) {
|
||||
if (event->senderId() == m_room->localUser()->id() && event->hasTextContent()) {
|
||||
if (event->senderId() == m_room->localMember().id() && event->hasTextContent()) {
|
||||
QString originalString;
|
||||
if (event->content()) {
|
||||
originalString = static_cast<const Quotient::EventContent::TextContent *>(event->content())->body;
|
||||
@@ -146,26 +145,6 @@ void ActionsHandler::handleMessage(const QString &text, QString handledText, Cha
|
||||
return;
|
||||
}
|
||||
|
||||
// We want to add back the <mx-reply> if it's in the original message but not in the edit, to preserve the reply.
|
||||
for (auto it = m_room->messageEvents().crbegin(); it != m_room->messageEvents().crend(); it++) {
|
||||
if (const auto event = eventCast<const RoomMessageEvent>(&**it)) {
|
||||
if (event->senderId() == m_room->localUser()->id() && event->hasTextContent()) {
|
||||
QString originalString;
|
||||
if (event->content()) {
|
||||
originalString = static_cast<const Quotient::EventContent::TextContent *>(event->content())->body;
|
||||
} else {
|
||||
originalString = event->plainBody();
|
||||
}
|
||||
|
||||
const QRegularExpression exp(TextRegex::removeRichReply);
|
||||
const auto match = exp.match(originalString);
|
||||
if (match.hasCaptured(0) && !handledText.contains(TextRegex::removeRichReply)) {
|
||||
handledText.prepend(match.captured(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_room->postMessage(text, handledText, messageType, chatBarCache->replyId(), chatBarCache->editId(), chatBarCache->threadId());
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
#include <signal.h>
|
||||
|
||||
#include <Quotient/accountregistry.h>
|
||||
#include <Quotient/connection.h>
|
||||
#include <Quotient/csapi/logout.h>
|
||||
#include <Quotient/csapi/notifications.h>
|
||||
#include <Quotient/eventstats.h>
|
||||
|
||||
@@ -117,7 +117,7 @@ private:
|
||||
|
||||
Quotient::AccountRegistry m_accountRegistry;
|
||||
QStringList m_accountsLoading;
|
||||
QMap<QString, QPointer<NeoChatConnection>> m_connectionsLoading;
|
||||
QMap<QString, QPointer<Quotient::Connection>> m_connectionsLoading;
|
||||
QString m_endpoint;
|
||||
|
||||
private Q_SLOTS:
|
||||
|
||||
@@ -15,12 +15,6 @@ FormCard.FormCardPage {
|
||||
FormCard.FormCard {
|
||||
Layout.topMargin: Kirigami.Units.largeSpacing
|
||||
|
||||
FormCard.FormCheckDelegate {
|
||||
text: i18nc("@option:check", "Show hidden events in the timeline")
|
||||
checked: Config.showAllEvents
|
||||
|
||||
onToggled: Config.showAllEvents = checked
|
||||
}
|
||||
FormCard.FormCheckDelegate {
|
||||
id: roomAccountDataVisibleCheck
|
||||
text: i18nc("@option:check Enable the matrix 'threads' feature", "Always allow device verification")
|
||||
@@ -29,14 +23,5 @@ FormCard.FormCardPage {
|
||||
|
||||
onToggled: Config.alwaysVerifyDevice = checked
|
||||
}
|
||||
FormCard.FormCheckDelegate {
|
||||
text: i18nc("@option:check", "Show focus in window header")
|
||||
checked: Config.windowTitleFocus
|
||||
|
||||
onToggled: {
|
||||
Config.windowTitleFocus = checked;
|
||||
Config.save();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,10 +25,9 @@ ColumnLayout {
|
||||
text: i18n("Room")
|
||||
textRole: "escapedDisplayName"
|
||||
valueRole: "roomId"
|
||||
displayText: RoomManager.roomListModel.data(RoomManager.roomListModel.index(currentIndex, 0), RoomListModel.EscapedDisplayNameRole)
|
||||
displayText: RoomManager.roomListModel.data(RoomManager.roomListModel.index(currentIndex, 0), RoomListModel.DisplayNameRole)
|
||||
model: RoomManager.roomListModel
|
||||
currentIndex: 0
|
||||
displayMode: FormCard.FormComboBoxDelegate.Page
|
||||
Component.onCompleted: currentIndex = RoomManager.roomListModel.rowForRoom(root.room)
|
||||
onCurrentValueChanged: root.room = RoomManager.roomListModel.roomByAliasOrId(roomComboBox.currentValue)
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ public:
|
||||
* @brief Defines the room list categories a room can be assigned.
|
||||
*/
|
||||
enum Types {
|
||||
Search = 0, /**< So we can show a search delegate if needed, e.g. collapsed mode. */
|
||||
Invited, /**< The user has been invited to the room. */
|
||||
Favorite, /**< The room is set as a favourite. */
|
||||
Direct, /**< The room is a direct chat. */
|
||||
@@ -67,6 +68,8 @@ public:
|
||||
return i18n("Low priority");
|
||||
case NeoChatRoomType::Space:
|
||||
return i18n("Spaces");
|
||||
case NeoChatRoomType::Search:
|
||||
return i18n("Search");
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
@@ -86,6 +89,8 @@ public:
|
||||
return QStringLiteral("object-order-lower");
|
||||
case NeoChatRoomType::Space:
|
||||
return QStringLiteral("group");
|
||||
case NeoChatRoomType::Search:
|
||||
return QStringLiteral("search");
|
||||
default:
|
||||
return QStringLiteral("tools-report-bug");
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ QVariantMap EventHandler::getAuthor(bool isPending) const
|
||||
return m_room->getUser(nullptr);
|
||||
}
|
||||
|
||||
const auto author = isPending ? m_room->localUser() : m_room->user(m_event->senderId());
|
||||
const auto author = isPending ? m_room->localMember() : m_room->user(m_event->senderId());
|
||||
return m_room->getUser(author);
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ QString EventHandler::getAuthorDisplayName(bool isPending) const
|
||||
}
|
||||
return previousDisplayName;
|
||||
} else {
|
||||
const auto author = isPending ? m_room->localUser() : m_room->user(m_event->senderId());
|
||||
const auto author = isPending ? m_room->localMember() : m_room->user(m_event->senderId());
|
||||
return m_room->htmlSafeMemberName(author->id());
|
||||
}
|
||||
}
|
||||
@@ -112,7 +112,7 @@ QString EventHandler::singleLineAuthorDisplayname(bool isPending) const
|
||||
return {};
|
||||
}
|
||||
|
||||
const auto author = isPending ? m_room->localUser() : m_room->user(m_event->senderId());
|
||||
const auto author = isPending ? m_room->localMember() : m_room->user(m_event->senderId());
|
||||
auto displayName = m_room->safeMemberName(author->id());
|
||||
displayName.replace(QStringLiteral("<br>\n"), QStringLiteral(" "));
|
||||
displayName.replace(QStringLiteral("<br>"), QStringLiteral(" "));
|
||||
@@ -963,7 +963,7 @@ bool EventHandler::hasReadMarkers() const
|
||||
}
|
||||
|
||||
auto userIds = m_room->userIdsAtEvent(m_event->id());
|
||||
userIds.remove(m_room->localUser()->id());
|
||||
userIds.remove(m_room->localMember().id());
|
||||
return userIds.size() > 0;
|
||||
}
|
||||
|
||||
@@ -979,7 +979,7 @@ QVariantList EventHandler::getReadMarkers(int maxMarkers) const
|
||||
}
|
||||
|
||||
auto userIds_temp = m_room->userIdsAtEvent(m_event->id());
|
||||
userIds_temp.remove(m_room->localUser()->id());
|
||||
userIds_temp.remove(m_room->localMember().id());
|
||||
|
||||
auto userIds = userIds_temp.values();
|
||||
if (userIds.count() > maxMarkers) {
|
||||
@@ -1008,7 +1008,7 @@ QString EventHandler::getNumberExcessReadMarkers(int maxMarkers) const
|
||||
}
|
||||
|
||||
auto userIds = m_room->userIdsAtEvent(m_event->id());
|
||||
userIds.remove(m_room->localUser()->id());
|
||||
userIds.remove(m_room->localMember().id());
|
||||
|
||||
if (userIds.count() > maxMarkers) {
|
||||
return QStringLiteral("+ ") + QString::number(userIds.count() - maxMarkers);
|
||||
@@ -1029,7 +1029,7 @@ QString EventHandler::getReadMarkersString() const
|
||||
}
|
||||
|
||||
auto userIds = m_room->userIdsAtEvent(m_event->id());
|
||||
userIds.remove(m_room->localUser()->id());
|
||||
userIds.remove(m_room->localMember().id());
|
||||
|
||||
/**
|
||||
* The string ends up in the form
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "login.h"
|
||||
|
||||
#include <Quotient/accountregistry.h>
|
||||
#include <Quotient/connection.h>
|
||||
#include <Quotient/qt_connection_util.h>
|
||||
|
||||
#include "controller.h"
|
||||
@@ -53,7 +54,7 @@ void LoginHelper::init()
|
||||
m_connection = new NeoChatConnection();
|
||||
}
|
||||
m_connection->resolveServer(m_matrixId);
|
||||
connectSingleShot(m_connection.get(), &Connection::loginFlowsChanged, this, [this]() {
|
||||
connectSingleShot(m_connection, &Connection::loginFlowsChanged, this, [this]() {
|
||||
setHomeserverReachable(true);
|
||||
m_testing = false;
|
||||
Q_EMIT testingChanged();
|
||||
@@ -99,7 +100,7 @@ void LoginHelper::init()
|
||||
Q_EMIT Controller::instance().errorOccured(i18n("Network Error"), std::move(error));
|
||||
});
|
||||
|
||||
connectSingleShot(m_connection.get(), &Connection::syncDone, this, [this]() {
|
||||
connectSingleShot(m_connection, &Connection::syncDone, this, [this]() {
|
||||
Q_EMIT loaded();
|
||||
});
|
||||
}
|
||||
@@ -181,7 +182,7 @@ QUrl LoginHelper::ssoUrl() const
|
||||
void LoginHelper::loginWithSso()
|
||||
{
|
||||
m_connection->resolveServer(m_matrixId);
|
||||
connectSingleShot(m_connection.get(), &Connection::loginFlowsChanged, this, [this]() {
|
||||
connectSingleShot(m_connection, &Connection::loginFlowsChanged, this, [this]() {
|
||||
SsoSession *session = m_connection->prepareForSso(m_deviceName);
|
||||
m_ssoUrl = session->ssoUrl();
|
||||
Q_EMIT ssoUrlChanged();
|
||||
|
||||
@@ -146,7 +146,7 @@ private:
|
||||
QString m_deviceName;
|
||||
bool m_supportsSso = false;
|
||||
bool m_supportsPassword = false;
|
||||
QPointer<NeoChatConnection> m_connection;
|
||||
NeoChatConnection *m_connection = nullptr;
|
||||
QUrl m_ssoUrl;
|
||||
bool m_testing = false;
|
||||
bool m_isLoggingIn = false;
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
|
||||
#include "neochatconnection.h"
|
||||
|
||||
#include <Quotient/connection.h>
|
||||
|
||||
using namespace Quotient;
|
||||
|
||||
ThumbnailResponse::ThumbnailResponse(QString id, QSize size, NeoChatConnection *connection)
|
||||
|
||||
@@ -35,7 +35,7 @@ private:
|
||||
QSize requestedSize;
|
||||
const QString localFile;
|
||||
Quotient::MediaThumbnailJob *job = nullptr;
|
||||
QPointer<NeoChatConnection> m_connection;
|
||||
NeoChatConnection *m_connection;
|
||||
|
||||
QImage image;
|
||||
QString errorStr;
|
||||
@@ -75,6 +75,6 @@ public:
|
||||
QQuickImageResponse *requestImageResponse(const QString &id, const QSize &requestedSize) override;
|
||||
|
||||
private:
|
||||
QPointer<NeoChatConnection> m_connection;
|
||||
NeoChatConnection *m_connection = nullptr;
|
||||
MatrixImageProvider() = default;
|
||||
};
|
||||
|
||||
@@ -10,8 +10,6 @@
|
||||
#include <Quotient/events/eventcontent.h>
|
||||
#include <qcoro/qcorosignal.h>
|
||||
|
||||
#include "neochatconnection.h"
|
||||
|
||||
using namespace Quotient;
|
||||
|
||||
AccountEmoticonModel::AccountEmoticonModel(QObject *parent)
|
||||
@@ -79,12 +77,12 @@ QHash<int, QByteArray> AccountEmoticonModel::roleNames() const
|
||||
};
|
||||
}
|
||||
|
||||
NeoChatConnection *AccountEmoticonModel::connection() const
|
||||
Connection *AccountEmoticonModel::connection() const
|
||||
{
|
||||
return m_connection;
|
||||
}
|
||||
|
||||
void AccountEmoticonModel::setConnection(NeoChatConnection *connection)
|
||||
void AccountEmoticonModel::setConnection(Connection *connection)
|
||||
{
|
||||
if (m_connection) {
|
||||
disconnect(m_connection, nullptr, this, nullptr);
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include <QPointer>
|
||||
#include <QQmlEngine>
|
||||
|
||||
class NeoChatConnection;
|
||||
#include <Quotient/connection.h>
|
||||
|
||||
/**
|
||||
* @class AccountEmoticonModel
|
||||
@@ -29,7 +29,7 @@ class AccountEmoticonModel : public QAbstractListModel
|
||||
/**
|
||||
* @brief The connection to get emoticons from.
|
||||
*/
|
||||
Q_PROPERTY(NeoChatConnection *connection READ connection WRITE setConnection NOTIFY connectionChanged)
|
||||
Q_PROPERTY(Quotient::Connection *connection READ connection WRITE setConnection NOTIFY connectionChanged)
|
||||
|
||||
public:
|
||||
enum Roles {
|
||||
@@ -63,8 +63,8 @@ public:
|
||||
*/
|
||||
[[nodiscard]] QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
[[nodiscard]] NeoChatConnection *connection() const;
|
||||
void setConnection(NeoChatConnection *connection);
|
||||
[[nodiscard]] Quotient::Connection *connection() const;
|
||||
void setConnection(Quotient::Connection *connection);
|
||||
|
||||
/**
|
||||
* @brief Deletes the emoticon at the given index.
|
||||
@@ -96,7 +96,7 @@ Q_SIGNALS:
|
||||
|
||||
private:
|
||||
std::optional<Quotient::ImagePackEventContent> m_images;
|
||||
QPointer<NeoChatConnection> m_connection;
|
||||
QPointer<Quotient::Connection> m_connection;
|
||||
QCoro::Task<void> doSetEmoticonImage(int index, QUrl source);
|
||||
QCoro::Task<void> doAddEmoticon(QUrl source, QString shortcode, QString description, QString type);
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
#include "actionsmodel.h"
|
||||
|
||||
#include "chatbarcache.h"
|
||||
#include "neochatconnection.h"
|
||||
#include "neochatroom.h"
|
||||
#include "roommanager.h"
|
||||
#include <Quotient/events/roommemberevent.h>
|
||||
@@ -202,7 +201,7 @@ QList<ActionsModel::Action> actions{
|
||||
Q_EMIT room->showMessage(NeoChatRoom::Info, i18nc("<user> is banned from this room.", "%1 is banned from this room.", text));
|
||||
return QString();
|
||||
}
|
||||
if (room->localUser()->id() == text) {
|
||||
if (room->localMember().id() == text) {
|
||||
Q_EMIT room->showMessage(NeoChatRoom::Positive, i18n("You are already in this room."));
|
||||
return QString();
|
||||
}
|
||||
@@ -261,7 +260,7 @@ QList<ActionsModel::Action> actions{
|
||||
return QString();
|
||||
}
|
||||
Q_EMIT room->showMessage(NeoChatRoom::Info, i18nc("Knocking room <roomname>.", "Knocking room %1.", text));
|
||||
auto connection = dynamic_cast<NeoChatConnection *>(room->connection());
|
||||
auto connection = room->connection();
|
||||
const auto knownServer = roomName.mid(roomName.indexOf(":"_ls) + 1);
|
||||
if (parts.length() >= 2) {
|
||||
RoomManager::instance().knockRoom(connection, roomName, parts[1], QStringList{knownServer});
|
||||
@@ -431,11 +430,11 @@ QList<ActionsModel::Action> actions{
|
||||
if (!plEvent) {
|
||||
return QString();
|
||||
}
|
||||
if (plEvent->ban() > plEvent->powerLevelForUser(room->localUser()->id())) {
|
||||
if (plEvent->ban() > plEvent->powerLevelForUser(room->localMember().id())) {
|
||||
Q_EMIT room->showMessage(NeoChatRoom::Error, i18n("You are not allowed to ban users from this room."));
|
||||
return QString();
|
||||
}
|
||||
if (plEvent->powerLevelForUser(room->localUser()->id()) <= plEvent->powerLevelForUser(parts[0])) {
|
||||
if (plEvent->powerLevelForUser(room->localMember().id()) <= plEvent->powerLevelForUser(parts[0])) {
|
||||
Q_EMIT room->showMessage(
|
||||
NeoChatRoom::Error,
|
||||
i18nc("You are not allowed to ban <username> from this room.", "You are not allowed to ban %1 from this room.", parts[0]));
|
||||
@@ -464,7 +463,7 @@ QList<ActionsModel::Action> actions{
|
||||
if (!plEvent) {
|
||||
return QString();
|
||||
}
|
||||
if (plEvent->ban() > plEvent->powerLevelForUser(room->localUser()->id())) {
|
||||
if (plEvent->ban() > plEvent->powerLevelForUser(room->localMember().id())) {
|
||||
Q_EMIT room->showMessage(NeoChatRoom::Error, i18n("You are not allowed to unban users from this room."));
|
||||
return QString();
|
||||
}
|
||||
@@ -495,7 +494,7 @@ QList<ActionsModel::Action> actions{
|
||||
i18nc("'<text>' does not look like a matrix id.", "'%1' does not look like a matrix id.", parts[0]));
|
||||
return QString();
|
||||
}
|
||||
if (parts[0] == room->localUser()->id()) {
|
||||
if (parts[0] == room->localMember().id()) {
|
||||
Q_EMIT room->showMessage(NeoChatRoom::Error, i18n("You cannot kick yourself from the room."));
|
||||
return QString();
|
||||
}
|
||||
@@ -508,11 +507,11 @@ QList<ActionsModel::Action> actions{
|
||||
return QString();
|
||||
}
|
||||
auto kick = plEvent->kick();
|
||||
if (plEvent->powerLevelForUser(room->localUser()->id()) < kick) {
|
||||
if (plEvent->powerLevelForUser(room->localMember().id()) < kick) {
|
||||
Q_EMIT room->showMessage(NeoChatRoom::Error, i18n("You are not allowed to kick users from this room."));
|
||||
return QString();
|
||||
}
|
||||
if (plEvent->powerLevelForUser(room->localUser()->id()) <= plEvent->powerLevelForUser(parts[0])) {
|
||||
if (plEvent->powerLevelForUser(room->localMember().id()) <= plEvent->powerLevelForUser(parts[0])) {
|
||||
Q_EMIT room->showMessage(
|
||||
NeoChatRoom::Error,
|
||||
i18nc("You are not allowed to kick <username> from this room", "You are not allowed to kick %1 from this room.", parts[0]));
|
||||
|
||||
@@ -110,7 +110,7 @@ Q_SIGNALS:
|
||||
private:
|
||||
explicit CustomEmojiModel(QObject *parent = nullptr);
|
||||
QList<CustomEmoji> m_emojis;
|
||||
QPointer<NeoChatConnection> m_connection;
|
||||
NeoChatConnection *m_connection = nullptr;
|
||||
|
||||
void fetchEmojis();
|
||||
};
|
||||
|
||||
@@ -5,8 +5,7 @@
|
||||
|
||||
#include "customemojimodel.h"
|
||||
#include <QRegularExpression>
|
||||
|
||||
class NeoChatConnection;
|
||||
#include <connection.h>
|
||||
|
||||
struct CustomEmoji {
|
||||
QString name; // with :semicolons:
|
||||
@@ -15,6 +14,6 @@ struct CustomEmoji {
|
||||
};
|
||||
|
||||
struct CustomEmojiModel::Private {
|
||||
QPointer<NeoChatConnection> connection;
|
||||
Quotient::Connection *conn = nullptr;
|
||||
QList<CustomEmoji> emojies;
|
||||
};
|
||||
|
||||
@@ -11,10 +11,9 @@
|
||||
#include <KLocalizedString>
|
||||
|
||||
#include <Quotient/csapi/device_management.h>
|
||||
#include <Quotient/connection.h>
|
||||
#include <Quotient/user.h>
|
||||
|
||||
#include "neochatconnection.h"
|
||||
|
||||
using namespace Quotient;
|
||||
|
||||
DevicesModel::DevicesModel(QObject *parent)
|
||||
@@ -153,12 +152,12 @@ void DevicesModel::setName(const QString &deviceId, const QString &name)
|
||||
});
|
||||
}
|
||||
|
||||
NeoChatConnection *DevicesModel::connection() const
|
||||
Connection *DevicesModel::connection() const
|
||||
{
|
||||
return m_connection;
|
||||
}
|
||||
|
||||
void DevicesModel::setConnection(NeoChatConnection *connection)
|
||||
void DevicesModel::setConnection(Connection *connection)
|
||||
{
|
||||
if (m_connection) {
|
||||
disconnect(m_connection, nullptr, this, nullptr);
|
||||
|
||||
@@ -9,7 +9,10 @@
|
||||
|
||||
#include <Quotient/csapi/definitions/client_device.h>
|
||||
|
||||
class NeoChatConnection;
|
||||
namespace Quotient
|
||||
{
|
||||
class Connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @class DevicesModel
|
||||
@@ -28,7 +31,7 @@ class DevicesModel : public QAbstractListModel
|
||||
/**
|
||||
* @brief The current connection that the model is getting its devices from.
|
||||
*/
|
||||
Q_PROPERTY(NeoChatConnection *connection READ connection WRITE setConnection NOTIFY connectionChanged REQUIRED)
|
||||
Q_PROPERTY(Quotient::Connection *connection READ connection WRITE setConnection NOTIFY connectionChanged REQUIRED)
|
||||
|
||||
public:
|
||||
/**
|
||||
@@ -85,8 +88,9 @@ public:
|
||||
|
||||
explicit DevicesModel(QObject *parent = nullptr);
|
||||
|
||||
[[nodiscard]] NeoChatConnection *connection() const;
|
||||
void setConnection(NeoChatConnection *connection);
|
||||
|
||||
[[nodiscard]] Quotient::Connection *connection() const;
|
||||
void setConnection(Quotient::Connection *connection);
|
||||
|
||||
Q_SIGNALS:
|
||||
void connectionChanged();
|
||||
@@ -95,5 +99,5 @@ Q_SIGNALS:
|
||||
private:
|
||||
void fetchDevices();
|
||||
QList<Quotient::Device> m_devices;
|
||||
QPointer<NeoChatConnection> m_connection;
|
||||
QPointer<Quotient::Connection> m_connection;
|
||||
};
|
||||
|
||||
@@ -246,86 +246,70 @@ void MessageContentModel::updateComponents(bool isEditing)
|
||||
if (eventCast<const Quotient::RoomMessageEvent>(m_event)
|
||||
&& eventCast<const Quotient::RoomMessageEvent>(m_event)->rawMsgtype() == QStringLiteral("m.key.verification.request")) {
|
||||
m_components += MessageComponent{MessageComponentType::Verification, QString(), {}};
|
||||
endResetModel();
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_event->isRedacted()) {
|
||||
m_components += MessageComponent{MessageComponentType::Text, QString(), {}};
|
||||
endResetModel();
|
||||
return;
|
||||
}
|
||||
|
||||
EventHandler eventHandler(m_room, m_event);
|
||||
if (eventHandler.hasReply()) {
|
||||
if (m_room->findInTimeline(eventHandler.getReplyId()) == m_room->historyEdge()) {
|
||||
m_components += MessageComponent{MessageComponentType::ReplyLoad, QString(), {}};
|
||||
m_room->loadReply(m_event->id(), eventHandler.getReplyId());
|
||||
} else {
|
||||
m_components += MessageComponent{MessageComponentType::Reply, QString(), {}};
|
||||
}
|
||||
}
|
||||
|
||||
if (isEditing) {
|
||||
m_components += MessageComponent{MessageComponentType::Edit, QString(), {}};
|
||||
} else {
|
||||
m_components.append(componentsForType(eventHandler.messageComponentType()));
|
||||
}
|
||||
EventHandler eventHandler(m_room, m_event);
|
||||
if (eventHandler.hasReply()) {
|
||||
if (m_room->findInTimeline(eventHandler.getReplyId()) == m_room->historyEdge()) {
|
||||
m_components += MessageComponent{MessageComponentType::ReplyLoad, QString(), {}};
|
||||
m_room->loadReply(m_event->id(), eventHandler.getReplyId());
|
||||
} else {
|
||||
m_components += MessageComponent{MessageComponentType::Reply, QString(), {}};
|
||||
}
|
||||
}
|
||||
|
||||
if (m_linkPreviewer != nullptr) {
|
||||
if (m_linkPreviewer->loaded()) {
|
||||
m_components += MessageComponent{MessageComponentType::LinkPreview, QString(), {}};
|
||||
if (isEditing) {
|
||||
m_components += MessageComponent{MessageComponentType::Edit, QString(), {}};
|
||||
} else if (m_event->isRedacted()) {
|
||||
m_components += MessageComponent{MessageComponentType::Text, QString(), {}};
|
||||
} else {
|
||||
m_components += MessageComponent{MessageComponentType::LinkPreviewLoad, QString(), {}};
|
||||
if (eventHandler.messageComponentType() == MessageComponentType::Text) {
|
||||
const auto event = eventCast<const Quotient::RoomMessageEvent>(m_event);
|
||||
auto body = EventHandler::rawMessageBody(*event);
|
||||
m_components.append(TextHandler().textComponents(body, EventHandler::messageBodyInputFormat(*event), m_room, event, event->isReplaced()));
|
||||
} else if (eventHandler.messageComponentType() == MessageComponentType::File) {
|
||||
m_components += MessageComponent{MessageComponentType::File, QString(), {}};
|
||||
if (m_emptyItinerary) {
|
||||
auto fileTransferInfo = fileInfo();
|
||||
|
||||
#ifndef Q_OS_ANDROID
|
||||
KSyntaxHighlighting::Repository repository;
|
||||
const auto definitionForFile = repository.definitionForFileName(fileTransferInfo.localPath.toString());
|
||||
if (definitionForFile.isValid() || QFileInfo(fileTransferInfo.localPath.path()).suffix() == QStringLiteral("txt")) {
|
||||
QFile file(fileTransferInfo.localPath.path());
|
||||
file.open(QIODevice::ReadOnly);
|
||||
m_components += MessageComponent{MessageComponentType::Code,
|
||||
QString::fromStdString(file.readAll().toStdString()),
|
||||
{{QStringLiteral("class"), definitionForFile.name()}}};
|
||||
}
|
||||
#endif
|
||||
|
||||
if (FileType::instance().fileHasImage(fileTransferInfo.localPath)) {
|
||||
QImageReader reader(fileTransferInfo.localPath.path());
|
||||
m_components += MessageComponent{MessageComponentType::Pdf, QString(), {{QStringLiteral("size"), reader.size()}}};
|
||||
}
|
||||
} else {
|
||||
updateItineraryModel();
|
||||
if (m_itineraryModel != nullptr) {
|
||||
m_components += MessageComponent{MessageComponentType::Itinerary, QString(), {}};
|
||||
}
|
||||
}
|
||||
} else {
|
||||
m_components += MessageComponent{eventHandler.messageComponentType(), QString(), {}};
|
||||
}
|
||||
}
|
||||
|
||||
if (m_linkPreviewer != nullptr) {
|
||||
if (m_linkPreviewer->loaded()) {
|
||||
m_components += MessageComponent{MessageComponentType::LinkPreview, QString(), {}};
|
||||
} else {
|
||||
m_components += MessageComponent{MessageComponentType::LinkPreviewLoad, QString(), {}};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
QList<MessageComponent> MessageContentModel::componentsForType(MessageComponentType::Type type)
|
||||
{
|
||||
switch (type) {
|
||||
case MessageComponentType::Text: {
|
||||
const auto event = eventCast<const Quotient::RoomMessageEvent>(m_event);
|
||||
auto body = EventHandler::rawMessageBody(*event);
|
||||
return TextHandler().textComponents(body, EventHandler::messageBodyInputFormat(*event), m_room, event, event->isReplaced());
|
||||
}
|
||||
case MessageComponentType::File: {
|
||||
QList<MessageComponent> components;
|
||||
components += MessageComponent{MessageComponentType::File, QString(), {}};
|
||||
if (m_emptyItinerary) {
|
||||
auto fileTransferInfo = fileInfo();
|
||||
|
||||
#ifndef Q_OS_ANDROID
|
||||
KSyntaxHighlighting::Repository repository;
|
||||
const auto definitionForFile = repository.definitionForFileName(fileTransferInfo.localPath.toString());
|
||||
if (definitionForFile.isValid() || QFileInfo(fileTransferInfo.localPath.path()).suffix() == QStringLiteral("txt")) {
|
||||
QFile file(fileTransferInfo.localPath.path());
|
||||
file.open(QIODevice::ReadOnly);
|
||||
components += MessageComponent{MessageComponentType::Code,
|
||||
QString::fromStdString(file.readAll().toStdString()),
|
||||
{{QStringLiteral("class"), definitionForFile.name()}}};
|
||||
}
|
||||
#endif
|
||||
|
||||
if (FileType::instance().fileHasImage(fileTransferInfo.localPath)) {
|
||||
QImageReader reader(fileTransferInfo.localPath.path());
|
||||
components += MessageComponent{MessageComponentType::Pdf, QString(), {{QStringLiteral("size"), reader.size()}}};
|
||||
}
|
||||
} else {
|
||||
updateItineraryModel();
|
||||
if (m_itineraryModel != nullptr) {
|
||||
components += MessageComponent{MessageComponentType::Itinerary, QString(), {}};
|
||||
}
|
||||
}
|
||||
return components;
|
||||
}
|
||||
default:
|
||||
return {MessageComponent{type, QString(), {}}};
|
||||
}
|
||||
}
|
||||
|
||||
void MessageContentModel::updateLinkPreviewer()
|
||||
{
|
||||
if (m_room == nullptr || m_event == nullptr) {
|
||||
|
||||
@@ -98,8 +98,6 @@ private:
|
||||
QPointer<LinkPreviewer> m_linkPreviewer;
|
||||
ItineraryModel *m_itineraryModel = nullptr;
|
||||
|
||||
QList<MessageComponent> componentsForType(MessageComponentType::Type type);
|
||||
|
||||
void updateLinkPreviewer();
|
||||
void updateItineraryModel();
|
||||
bool m_emptyItinerary = false;
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
#include "neochatconfig.h"
|
||||
|
||||
#include <Quotient/connection.h>
|
||||
#include <Quotient/csapi/rooms.h>
|
||||
#include <Quotient/events/redactionevent.h>
|
||||
#include <Quotient/events/roommessageevent.h>
|
||||
@@ -116,6 +117,34 @@ void MessageEventModel::setRoom(NeoChatRoom *room)
|
||||
|
||||
if (message != nullptr) {
|
||||
createEventObjects(message);
|
||||
if (NeoChatConfig::self()->showFancyEffects()) {
|
||||
QString planBody = message->plainBody();
|
||||
// snowflake
|
||||
const QString snowlakeEmoji = QString::fromUtf8("\xE2\x9D\x84");
|
||||
if (planBody.contains(snowlakeEmoji)) {
|
||||
Q_EMIT fancyEffectsReasonFound(QStringLiteral("snowflake"));
|
||||
}
|
||||
// fireworks
|
||||
const QString fireworksEmoji = QString::fromUtf8("\xF0\x9F\x8E\x86");
|
||||
if (planBody.contains(fireworksEmoji)) {
|
||||
Q_EMIT fancyEffectsReasonFound(QStringLiteral("fireworks"));
|
||||
}
|
||||
// sparkler
|
||||
const QString sparklerEmoji = QString::fromUtf8("\xF0\x9F\x8E\x87");
|
||||
if (planBody.contains(sparklerEmoji)) {
|
||||
Q_EMIT fancyEffectsReasonFound(QStringLiteral("fireworks"));
|
||||
}
|
||||
// party pooper
|
||||
const QString partyEmoji = QString::fromUtf8("\xF0\x9F\x8E\x89");
|
||||
if (planBody.contains(partyEmoji)) {
|
||||
Q_EMIT fancyEffectsReasonFound(QStringLiteral("confetti"));
|
||||
}
|
||||
// confetti ball
|
||||
const QString confettiEmoji = QString::fromUtf8("\xF0\x9F\x8E\x8A");
|
||||
if (planBody.contains(confettiEmoji)) {
|
||||
Q_EMIT fancyEffectsReasonFound(QStringLiteral("confetti"));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (event->is<PollStartEvent>()) {
|
||||
m_currentRoom->createPollHandler(eventCast<const PollStartEvent>(event.get()));
|
||||
@@ -222,7 +251,7 @@ void MessageEventModel::setRoom(NeoChatRoom *room)
|
||||
beginResetModel();
|
||||
endResetModel();
|
||||
});
|
||||
qCDebug(MessageEvent) << "Connected to room" << room->id() << "as" << room->localUser()->id();
|
||||
qCDebug(MessageEvent) << "Connected to room" << room->id() << "as" << room->localMember().id();
|
||||
} else {
|
||||
lastReadEventId.clear();
|
||||
}
|
||||
@@ -592,7 +621,7 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
|
||||
}
|
||||
|
||||
if (role == IsEditableRole) {
|
||||
return eventHandler.messageComponentType() == MessageComponentType::Text && evt.senderId() == m_currentRoom->localUser()->id();
|
||||
return eventHandler.messageComponentType() == MessageComponentType::Text && evt.senderId() == m_currentRoom->localMember().id();
|
||||
}
|
||||
|
||||
return {};
|
||||
|
||||
@@ -140,4 +140,5 @@ private:
|
||||
|
||||
Q_SIGNALS:
|
||||
void roomChanged();
|
||||
void fancyEffectsReasonFound(const QString &fancyEffect);
|
||||
};
|
||||
|
||||
@@ -36,14 +36,6 @@ MessageFilterModel::MessageFilterModel(QObject *parent, TimelineModel *sourceMod
|
||||
}
|
||||
|
||||
bool MessageFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
|
||||
{
|
||||
if (NeoChatConfig::self()->showAllEvents()) {
|
||||
return true;
|
||||
}
|
||||
return eventIsVisible(sourceRow, sourceParent);
|
||||
}
|
||||
|
||||
bool MessageFilterModel::eventIsVisible(int sourceRow, const QModelIndex &sourceParent) const
|
||||
{
|
||||
const QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
|
||||
|
||||
@@ -67,8 +59,9 @@ bool MessageFilterModel::eventIsVisible(int sourceRow, const QModelIndex &source
|
||||
// Don't show state events that are not the first in a consecutive group on the
|
||||
// same day as they will be grouped as a single delegate.
|
||||
const bool notLastRow = sourceRow < sourceModel()->rowCount() - 1;
|
||||
const bool previousEventIsState =
|
||||
notLastRow ? sourceModel()->data(sourceModel()->index(sourceRow + 1, 0), MessageEventModel::DelegateTypeRole) == DelegateType::State : false;
|
||||
const bool previousEventIsState = notLastRow
|
||||
? sourceModel()->data(sourceModel()->index(sourceRow + 1, 0), MessageEventModel::DelegateTypeRole) == DelegateType::State
|
||||
: false;
|
||||
const bool newDay = sourceModel()->data(sourceModel()->index(sourceRow, 0), MessageEventModel::ShowSectionRole).toBool();
|
||||
if (eventType == DelegateType::State && notLastRow && previousEventIsState && !newDay) {
|
||||
return false;
|
||||
@@ -79,11 +72,7 @@ bool MessageFilterModel::eventIsVisible(int sourceRow, const QModelIndex &source
|
||||
|
||||
QVariant MessageFilterModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (role == MessageEventModel::DelegateTypeRole && NeoChatConfig::self()->showAllEvents()) {
|
||||
if (!eventIsVisible(index.row(), index.parent())) {
|
||||
return DelegateType::Other;
|
||||
}
|
||||
} else if (role == AggregateDisplayRole) {
|
||||
if (role == AggregateDisplayRole) {
|
||||
return aggregateEventToString(mapToSource(index).row());
|
||||
} else if (role == StateEventsRole) {
|
||||
return stateEventsList(mapToSource(index).row());
|
||||
|
||||
@@ -60,8 +60,6 @@ public:
|
||||
[[nodiscard]] QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
private:
|
||||
bool eventIsVisible(int sourceRow, const QModelIndex &sourceParent) const;
|
||||
|
||||
/**
|
||||
* @brief Aggregation of the text of consecutive state events starting at row.
|
||||
*
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "notificationsmodel.h"
|
||||
|
||||
#include <Quotient/connection.h>
|
||||
#include <Quotient/events/event.h>
|
||||
#include <Quotient/uri.h>
|
||||
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
|
||||
#include "publicroomlistmodel.h"
|
||||
|
||||
#include "neochatconnection.h"
|
||||
#include <Quotient/connection.h>
|
||||
|
||||
#include "publicroomlist_logging.h"
|
||||
|
||||
using namespace Quotient;
|
||||
@@ -13,14 +14,14 @@ PublicRoomListModel::PublicRoomListModel(QObject *parent)
|
||||
{
|
||||
}
|
||||
|
||||
NeoChatConnection *PublicRoomListModel::connection() const
|
||||
Quotient::Connection *PublicRoomListModel::connection() const
|
||||
{
|
||||
return m_connection;
|
||||
}
|
||||
|
||||
void PublicRoomListModel::setConnection(NeoChatConnection *connection)
|
||||
void PublicRoomListModel::setConnection(Connection *conn)
|
||||
{
|
||||
if (m_connection == connection) {
|
||||
if (m_connection == conn) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -37,7 +38,7 @@ void PublicRoomListModel::setConnection(NeoChatConnection *connection)
|
||||
|
||||
endResetModel();
|
||||
|
||||
m_connection = connection;
|
||||
m_connection = conn;
|
||||
|
||||
if (job) {
|
||||
job->abandon();
|
||||
|
||||
@@ -9,7 +9,10 @@
|
||||
|
||||
#include <Quotient/csapi/list_public_rooms.h>
|
||||
|
||||
class NeoChatConnection;
|
||||
namespace Quotient
|
||||
{
|
||||
class Connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @class PublicRoomListModel
|
||||
@@ -30,7 +33,7 @@ class PublicRoomListModel : public QAbstractListModel
|
||||
/**
|
||||
* @brief The current connection that the model is getting its rooms from.
|
||||
*/
|
||||
Q_PROPERTY(NeoChatConnection *connection READ connection WRITE setConnection NOTIFY connectionChanged)
|
||||
Q_PROPERTY(Quotient::Connection *connection READ connection WRITE setConnection NOTIFY connectionChanged)
|
||||
|
||||
/**
|
||||
* @brief The server to get the public room list from.
|
||||
@@ -92,8 +95,8 @@ public:
|
||||
*/
|
||||
[[nodiscard]] QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
[[nodiscard]] NeoChatConnection *connection() const;
|
||||
void setConnection(NeoChatConnection *connection);
|
||||
[[nodiscard]] Quotient::Connection *connection() const;
|
||||
void setConnection(Quotient::Connection *conn);
|
||||
|
||||
[[nodiscard]] QString server() const;
|
||||
void setServer(const QString &value);
|
||||
@@ -114,7 +117,7 @@ public:
|
||||
Q_INVOKABLE void search(int limit = 50);
|
||||
|
||||
private:
|
||||
QPointer<NeoChatConnection> m_connection = nullptr;
|
||||
QPointer<Quotient::Connection> m_connection = nullptr;
|
||||
QString m_server;
|
||||
QString m_searchText;
|
||||
bool m_showOnlySpaces = false;
|
||||
|
||||
@@ -5,13 +5,13 @@
|
||||
|
||||
#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 "neochatconfig.h"
|
||||
#include "neochatconnection.h"
|
||||
|
||||
#include <KLazyLocalizedString>
|
||||
|
||||
@@ -454,7 +454,7 @@ void PushRuleModel::setConnection(NeoChatConnection *connection)
|
||||
Q_EMIT connectionChanged();
|
||||
|
||||
if (m_connection) {
|
||||
connect(m_connection, &NeoChatConnection::accountDataChanged, this, &PushRuleModel::updateNotificationRules);
|
||||
connect(m_connection, &Quotient::Connection::accountDataChanged, this, &PushRuleModel::updateNotificationRules);
|
||||
updateNotificationRules(QStringLiteral("m.push_rules"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ private Q_SLOTS:
|
||||
private:
|
||||
PushRuleAction::Action m_defaultKeywordAction;
|
||||
QList<Rule> m_rules;
|
||||
QPointer<NeoChatConnection> m_connection;
|
||||
NeoChatConnection *m_connection;
|
||||
|
||||
void setRules(QList<Quotient::PushRule> rules, PushRuleKind::Kind kind);
|
||||
|
||||
|
||||
@@ -90,7 +90,7 @@ QVariant ReactionModel::data(const QModelIndex &index, int role) const
|
||||
|
||||
if (role == HasLocalUser) {
|
||||
for (auto author : reaction.authors) {
|
||||
if (author.toMap()[QStringLiteral("id")] == m_room->localUser()->id()) {
|
||||
if (author.toMap()[QStringLiteral("id")] == m_room->localMember().id()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,12 +25,12 @@ RoomListModel::RoomListModel(QObject *parent)
|
||||
|
||||
RoomListModel::~RoomListModel() = default;
|
||||
|
||||
NeoChatConnection *RoomListModel::connection() const
|
||||
Quotient::Connection *RoomListModel::connection() const
|
||||
{
|
||||
return m_connection;
|
||||
}
|
||||
|
||||
void RoomListModel::setConnection(NeoChatConnection *connection)
|
||||
void RoomListModel::setConnection(Connection *connection)
|
||||
{
|
||||
if (connection == m_connection) {
|
||||
return;
|
||||
|
||||
@@ -12,11 +12,10 @@ class NeoChatRoom;
|
||||
|
||||
namespace Quotient
|
||||
{
|
||||
class Connection;
|
||||
class Room;
|
||||
}
|
||||
|
||||
class NeoChatConnection;
|
||||
|
||||
/**
|
||||
* @class RoomListModel
|
||||
*
|
||||
@@ -30,7 +29,7 @@ class RoomListModel : public QAbstractListModel
|
||||
/**
|
||||
* @brief The current connection that the model is getting its rooms from.
|
||||
*/
|
||||
Q_PROPERTY(NeoChatConnection *connection READ connection WRITE setConnection NOTIFY connectionChanged)
|
||||
Q_PROPERTY(Quotient::Connection *connection READ connection WRITE setConnection NOTIFY connectionChanged)
|
||||
|
||||
public:
|
||||
/**
|
||||
@@ -61,8 +60,8 @@ public:
|
||||
explicit RoomListModel(QObject *parent = nullptr);
|
||||
~RoomListModel() override;
|
||||
|
||||
[[nodiscard]] NeoChatConnection *connection() const;
|
||||
void setConnection(NeoChatConnection *connection);
|
||||
[[nodiscard]] Quotient::Connection *connection() const;
|
||||
void setConnection(Quotient::Connection *connection);
|
||||
|
||||
/**
|
||||
* @brief Get the given role value at the given index.
|
||||
@@ -110,7 +109,7 @@ private Q_SLOTS:
|
||||
void refresh(NeoChatRoom *room, const QList<int> &roles = {});
|
||||
|
||||
private:
|
||||
QPointer<NeoChatConnection> m_connection;
|
||||
Quotient::Connection *m_connection = nullptr;
|
||||
QList<NeoChatRoom *> m_rooms;
|
||||
|
||||
QString m_activeSpaceId;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "roomtreemodel.h"
|
||||
|
||||
#include <Quotient/connection.h>
|
||||
#include <Quotient/room.h>
|
||||
|
||||
#include "eventhandler.h"
|
||||
@@ -299,6 +300,9 @@ QVariant RoomTreeModel::data(const QModelIndex &index, int role) const
|
||||
return NeoChatRoomType::typeName(index.row());
|
||||
}
|
||||
if (role == DelegateTypeRole) {
|
||||
if (index.row() == NeoChatRoomType::Search) {
|
||||
return QStringLiteral("search");
|
||||
}
|
||||
if (index.row() == NeoChatRoomType::AddDirect) {
|
||||
return QStringLiteral("addDirect");
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
#include <QGuiApplication>
|
||||
|
||||
#include <Quotient/connection.h>
|
||||
#include <Quotient/events/stickerevent.h>
|
||||
|
||||
#include <KLocalizedString>
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
|
||||
#include "serverlistmodel.h"
|
||||
|
||||
#include <Quotient/connection.h>
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#include <KConfig>
|
||||
|
||||
@@ -110,7 +110,7 @@ Q_SIGNALS:
|
||||
private:
|
||||
QList<Server> m_servers;
|
||||
QPointer<Quotient::QueryPublicRoomsJob> m_checkServerJob = nullptr;
|
||||
QPointer<NeoChatConnection> m_connection;
|
||||
NeoChatConnection *m_connection = nullptr;
|
||||
|
||||
void initialize();
|
||||
};
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
|
||||
#include "roomlistmodel.h"
|
||||
|
||||
#include "neochatconnection.h"
|
||||
|
||||
SortFilterRoomListModel::SortFilterRoomListModel(RoomListModel *sourceModel, QObject *parent)
|
||||
: QSortFilterProxyModel(parent)
|
||||
{
|
||||
|
||||
@@ -129,6 +129,10 @@ QString SortFilterRoomTreeModel::filterText() const
|
||||
bool SortFilterRoomTreeModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
|
||||
{
|
||||
if (!source_parent.isValid()) {
|
||||
if (sourceModel()->data(sourceModel()->index(source_row, 0), RoomTreeModel::CategoryRole).toInt() == NeoChatRoomType::Search
|
||||
&& NeoChatConfig::collapsed()) {
|
||||
return true;
|
||||
}
|
||||
if (sourceModel()->data(sourceModel()->index(source_row, 0), RoomTreeModel::CategoryRole).toInt() == NeoChatRoomType::AddDirect
|
||||
&& m_mode == DirectChats) {
|
||||
return true;
|
||||
@@ -201,14 +205,4 @@ void SortFilterRoomTreeModel::setMode(SortFilterRoomTreeModel::Mode mode)
|
||||
invalidate();
|
||||
}
|
||||
|
||||
QModelIndex SortFilterRoomTreeModel::currentRoomIndex() const
|
||||
{
|
||||
const auto roomModel = dynamic_cast<RoomTreeModel *>(sourceModel());
|
||||
if (roomModel == nullptr) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return mapFromSource(roomModel->indexForRoom(RoomManager::instance().currentRoom()));
|
||||
}
|
||||
|
||||
#include "moc_sortfilterroomtreemodel.cpp"
|
||||
|
||||
@@ -76,8 +76,6 @@ public:
|
||||
Mode mode() const;
|
||||
void setMode(Mode mode);
|
||||
|
||||
Q_INVOKABLE QModelIndex currentRoomIndex() const;
|
||||
|
||||
protected:
|
||||
/**
|
||||
* @brief Returns true if the value of source_left is less than source_right.
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include "spacechildrenmodel.h"
|
||||
|
||||
#include <Quotient/connection.h>
|
||||
#include <Quotient/jobs/basejob.h>
|
||||
#include <Quotient/room.h>
|
||||
|
||||
@@ -46,7 +47,7 @@ void SpaceChildrenModel::setSpace(NeoChatRoom *space)
|
||||
}
|
||||
|
||||
auto connection = m_space->connection();
|
||||
connect(connection, &NeoChatConnection::loadedRoomState, this, [this](Quotient::Room *room) {
|
||||
connect(connection, &Quotient::Connection::loadedRoomState, this, [this](Quotient::Room *room) {
|
||||
if (m_pendingChildren.contains(room->name())) {
|
||||
m_pendingChildren.removeAll(room->name());
|
||||
refreshModel();
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
// SPDX-FileCopyrightText: 2023 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 <QPointer>
|
||||
|
||||
#include <Quotient/csapi/space_hierarchy.h>
|
||||
#include <Quotient/events/stateevent.h>
|
||||
|
||||
@@ -151,7 +149,7 @@ public:
|
||||
bool isSuggested() const;
|
||||
|
||||
private:
|
||||
QPointer<NeoChatConnection> m_connection;
|
||||
NeoChatConnection *m_connection;
|
||||
std::vector<std::unique_ptr<SpaceTreeItem>> m_children;
|
||||
SpaceTreeItem *m_parentItem;
|
||||
|
||||
|
||||
@@ -3,10 +3,9 @@
|
||||
|
||||
#include "userdirectorylistmodel.h"
|
||||
|
||||
#include <Quotient/connection.h>
|
||||
#include <Quotient/room.h>
|
||||
|
||||
#include "neochatconnection.h"
|
||||
|
||||
using namespace Quotient;
|
||||
|
||||
UserDirectoryListModel::UserDirectoryListModel(QObject *parent)
|
||||
@@ -14,14 +13,14 @@ UserDirectoryListModel::UserDirectoryListModel(QObject *parent)
|
||||
{
|
||||
}
|
||||
|
||||
NeoChatConnection *UserDirectoryListModel::connection() const
|
||||
Quotient::Connection *UserDirectoryListModel::connection() const
|
||||
{
|
||||
return m_connection;
|
||||
}
|
||||
|
||||
void UserDirectoryListModel::setConnection(NeoChatConnection *connection)
|
||||
void UserDirectoryListModel::setConnection(Connection *conn)
|
||||
{
|
||||
if (m_connection == connection) {
|
||||
if (m_connection == conn) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -36,7 +35,7 @@ void UserDirectoryListModel::setConnection(NeoChatConnection *connection)
|
||||
|
||||
endResetModel();
|
||||
|
||||
m_connection = connection;
|
||||
m_connection = conn;
|
||||
Q_EMIT connectionChanged();
|
||||
|
||||
if (m_job) {
|
||||
|
||||
@@ -9,7 +9,10 @@
|
||||
|
||||
#include <Quotient/csapi/users.h>
|
||||
|
||||
class NeoChatConnection;
|
||||
namespace Quotient
|
||||
{
|
||||
class Connection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @class UserDirectoryListModel
|
||||
@@ -29,7 +32,7 @@ class UserDirectoryListModel : public QAbstractListModel
|
||||
/**
|
||||
* @brief The current connection that the model is getting users from.
|
||||
*/
|
||||
Q_PROPERTY(NeoChatConnection *connection READ connection WRITE setConnection NOTIFY connectionChanged)
|
||||
Q_PROPERTY(Quotient::Connection *connection READ connection WRITE setConnection NOTIFY connectionChanged)
|
||||
|
||||
/**
|
||||
* @brief The text to search the public room list for.
|
||||
@@ -54,8 +57,8 @@ public:
|
||||
|
||||
explicit UserDirectoryListModel(QObject *parent = nullptr);
|
||||
|
||||
[[nodiscard]] NeoChatConnection *connection() const;
|
||||
void setConnection(NeoChatConnection *connection);
|
||||
[[nodiscard]] Quotient::Connection *connection() const;
|
||||
void setConnection(Quotient::Connection *conn);
|
||||
|
||||
[[nodiscard]] QString searchText() const;
|
||||
void setSearchText(const QString &searchText);
|
||||
@@ -96,7 +99,7 @@ Q_SIGNALS:
|
||||
void searchingChanged();
|
||||
|
||||
private:
|
||||
QPointer<NeoChatConnection> m_connection;
|
||||
Quotient::Connection *m_connection = nullptr;
|
||||
QString m_searchText;
|
||||
|
||||
bool attempted = false;
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
#include <QGuiApplication>
|
||||
|
||||
#include <Quotient/connection.h>
|
||||
#include <Quotient/events/roompowerlevelsevent.h>
|
||||
|
||||
#include "neochatroom.h"
|
||||
|
||||
@@ -100,6 +100,10 @@
|
||||
<label>Minimize to system tray on startup</label>
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="ShowFancyEffects" type="bool">
|
||||
<label>Show Fancy Effects</label>
|
||||
<default>true</default>
|
||||
</entry>
|
||||
<entry name="MediaMaxWidth" type="int">
|
||||
<label>The maximum width any media item in the timeline can be.</label>
|
||||
<default>540</default>
|
||||
@@ -157,18 +161,10 @@
|
||||
</entry>
|
||||
</group>
|
||||
<group name="Debug">
|
||||
<entry name="ShowAllEvents" type="bool">
|
||||
<label>Don't hide any events in the timeline</label>
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="AlwaysVerifyDevice" type="bool">
|
||||
<label>Always allow device verification</label>
|
||||
<default>false</default>
|
||||
</entry>
|
||||
<entry name="WindowTitleFocus" type="bool">
|
||||
<label>Show the current focus item in the window title</label>
|
||||
<default>false</default>
|
||||
</entry>
|
||||
</group>
|
||||
<group name="FeatureFlags">
|
||||
<entry name="Threads" type="bool">
|
||||
|
||||
@@ -101,15 +101,17 @@ NeoChatRoom::NeoChatRoom(Connection *connection, QString roomId, JoinState joinS
|
||||
if (this->joinState() != JoinState::Invite) {
|
||||
return;
|
||||
}
|
||||
auto roomMemberEvent = currentState().get<RoomMemberEvent>(localUser()->id());
|
||||
auto roomMemberEvent = currentState().get<RoomMemberEvent>(localMember().id());
|
||||
QImage avatar_image;
|
||||
if (roomMemberEvent && !user(roomMemberEvent->senderId())->avatarUrl(this).isEmpty()) {
|
||||
avatar_image = user(roomMemberEvent->senderId())->avatar(128, this);
|
||||
if (roomMemberEvent && !member(roomMemberEvent->senderId()).avatarUrl().isEmpty()) {
|
||||
// TODO: Fix acessing Avatar Image.
|
||||
// avatar_image = member(roomMemberEvent->senderId()).avatarMediaId();
|
||||
avatar_image = avatar(128);
|
||||
} else {
|
||||
qWarning() << "using this room's avatar";
|
||||
avatar_image = avatar(128);
|
||||
}
|
||||
NotificationsManager::instance().postInviteNotification(this, displayName(), htmlSafeMemberName(roomMemberEvent->senderId()), avatar_image);
|
||||
NotificationsManager::instance().postInviteNotification(this, displayName(), member(roomMemberEvent->senderId()).htmlSafeDisplayName(), avatar_image);
|
||||
});
|
||||
connect(this, &Room::changed, this, [this] {
|
||||
Q_EMIT canEncryptRoomChanged();
|
||||
@@ -257,18 +259,18 @@ void NeoChatRoom::forget()
|
||||
|
||||
QVariantList NeoChatRoom::getUsersTyping() const
|
||||
{
|
||||
auto users = usersTyping();
|
||||
users.removeAll(localUser());
|
||||
auto users = membersTyping();
|
||||
users.removeAll(localMember());
|
||||
QVariantList userVariants;
|
||||
for (const auto &user : users) {
|
||||
if (connection()->isIgnored(user->id())) {
|
||||
if (connection()->isIgnored(user.id())) {
|
||||
continue;
|
||||
}
|
||||
userVariants.append(QVariantMap{
|
||||
{"id"_ls, user->id()},
|
||||
{"avatarMediaId"_ls, user->avatarMediaId(this)},
|
||||
{"displayName"_ls, user->displayname(this)},
|
||||
{"display"_ls, user->name()},
|
||||
{"id"_ls, user.id()},
|
||||
{"avatarMediaId"_ls, user.avatarMediaId()},
|
||||
{"displayName"_ls, user.displayName()},
|
||||
{"display"_ls, user.name()},
|
||||
});
|
||||
}
|
||||
return userVariants;
|
||||
@@ -276,7 +278,7 @@ QVariantList NeoChatRoom::getUsersTyping() const
|
||||
|
||||
void NeoChatRoom::sendTypingNotification(bool isTyping)
|
||||
{
|
||||
connection()->callApi<SetTypingJob>(BackgroundRequest, localUser()->id(), id(), isTyping, 10000);
|
||||
connection()->callApi<SetTypingJob>(BackgroundRequest, localMember().id(), id(), isTyping, 10000);
|
||||
}
|
||||
|
||||
const RoomEvent *NeoChatRoom::lastEvent() const
|
||||
@@ -314,7 +316,7 @@ const RoomEvent *NeoChatRoom::lastEvent() const
|
||||
}
|
||||
}
|
||||
|
||||
if (connection()->isIgnored(user(event->senderId()))) {
|
||||
if (connection()->isIgnored(event->senderId())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -374,13 +376,13 @@ bool NeoChatRoom::isEventHighlighted(const RoomEvent *e) const
|
||||
|
||||
void NeoChatRoom::checkForHighlights(const Quotient::TimelineItem &ti)
|
||||
{
|
||||
auto localUserId = localUser()->id();
|
||||
if (ti->senderId() == localUserId) {
|
||||
auto localMemberId = localMember().id();
|
||||
if (ti->senderId() == localMemberId) {
|
||||
return;
|
||||
}
|
||||
if (auto *e = ti.viewAs<RoomMessageEvent>()) {
|
||||
const auto &text = e->plainBody();
|
||||
if (text.contains(localUserId) || text.contains(safeMemberName(localUserId))) {
|
||||
if (text.contains(localMemberId) || text.contains(member(localMemberId).htmlSafeDisplayName())) {
|
||||
highlights.insert(e);
|
||||
}
|
||||
}
|
||||
@@ -439,7 +441,8 @@ static const QVariantMap emptyUser = {
|
||||
|
||||
QVariantMap NeoChatRoom::getUser(const QString &userID) const
|
||||
{
|
||||
return getUser(user(userID));
|
||||
auto u = User(userID, connection());
|
||||
return getUser(&u);
|
||||
}
|
||||
|
||||
QVariantMap NeoChatRoom::getUser(User *user) const
|
||||
@@ -449,13 +452,13 @@ QVariantMap NeoChatRoom::getUser(User *user) const
|
||||
}
|
||||
|
||||
return QVariantMap{
|
||||
{QStringLiteral("isLocalUser"), user->id() == localUser()->id()},
|
||||
{QStringLiteral("isLocalUser"), user->id() == localMember().id()},
|
||||
{QStringLiteral("id"), user->id()},
|
||||
{QStringLiteral("displayName"), user->displayname(this)},
|
||||
{QStringLiteral("escapedDisplayName"), htmlSafeMemberName(user->id())},
|
||||
{QStringLiteral("displayName"), user->displayname()},
|
||||
{QStringLiteral("escapedDisplayName"), member(user->id()).htmlSafeDisplayName()},
|
||||
{QStringLiteral("avatarSource"), avatarForMember(user)},
|
||||
{QStringLiteral("avatarMediaId"), user->avatarMediaId(this)},
|
||||
{QStringLiteral("color"), Utils::getUserColor(user->hueF())},
|
||||
{QStringLiteral("avatarMediaId"), user->avatarMediaId()},
|
||||
{QStringLiteral("color"), member(user->id()).hueF()},
|
||||
{QStringLiteral("object"), QVariant::fromValue(user)},
|
||||
};
|
||||
}
|
||||
@@ -467,10 +470,10 @@ QString NeoChatRoom::avatarMediaId() const
|
||||
}
|
||||
|
||||
// Use the first (excluding self) user's avatar for direct chats
|
||||
const auto dcUsers = directChatUsers();
|
||||
const auto dcUsers = directChatMembers();
|
||||
for (const auto u : dcUsers) {
|
||||
if (u != localUser()) {
|
||||
return u->avatarMediaId(this);
|
||||
if (u != localMember()) {
|
||||
return u.avatarMediaId();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -637,7 +640,7 @@ void NeoChatRoom::toggleReaction(const QString &eventId, const QString &reaction
|
||||
continue;
|
||||
}
|
||||
|
||||
if (e->senderId() == localUser()->id()) {
|
||||
if (e->senderId() == localMember().id()) {
|
||||
redactEventIds.push_back(e->id());
|
||||
break;
|
||||
}
|
||||
@@ -666,7 +669,7 @@ bool NeoChatRoom::canSendEvent(const QString &eventType) const
|
||||
return false;
|
||||
}
|
||||
auto pl = plEvent->powerLevelForEvent(eventType);
|
||||
auto currentPl = plEvent->powerLevelForUser(localUser()->id());
|
||||
auto currentPl = plEvent->powerLevelForUser(localMember().id());
|
||||
|
||||
return currentPl >= pl;
|
||||
}
|
||||
@@ -678,7 +681,7 @@ bool NeoChatRoom::canSendState(const QString &eventType) const
|
||||
return false;
|
||||
}
|
||||
auto pl = plEvent->powerLevelForState(eventType);
|
||||
auto currentPl = plEvent->powerLevelForUser(localUser()->id());
|
||||
auto currentPl = plEvent->powerLevelForUser(localMember().id());
|
||||
|
||||
return currentPl >= pl;
|
||||
}
|
||||
@@ -856,7 +859,7 @@ void NeoChatRoom::setUrlPreviewEnabled(const bool &urlPreviewEnabled)
|
||||
* "type": "org.matrix.room.preview_urls",
|
||||
* }
|
||||
*/
|
||||
connection()->callApi<SetAccountDataPerRoomJob>(localUser()->id(),
|
||||
connection()->callApi<SetAccountDataPerRoomJob>(localMember().id(),
|
||||
id(),
|
||||
"org.matrix.room.preview_urls"_ls,
|
||||
QJsonObject{{"disable"_ls, !urlPreviewEnabled}});
|
||||
@@ -1768,7 +1771,7 @@ void NeoChatRoom::editLastMessage()
|
||||
}
|
||||
|
||||
// check if the current message's sender's id is same as the user's id
|
||||
if ((*it)->senderId() == localUser()->id()) {
|
||||
if ((*it)->senderId() == localMember().id()) {
|
||||
auto content = (*it)->contentJson();
|
||||
|
||||
if (e->msgtype() != MessageEventType::Unknown) {
|
||||
@@ -1933,16 +1936,16 @@ QByteArray NeoChatRoom::roomAcountDataJson(const QString &eventType)
|
||||
|
||||
QUrl NeoChatRoom::avatarForMember(Quotient::User *user) const
|
||||
{
|
||||
const auto &url = memberAvatarUrl(user->id());
|
||||
if (url.isEmpty() || url.scheme() != "mxc"_ls) {
|
||||
const auto &avatar = memberAvatar(user->id());
|
||||
if (avatar.url().isEmpty() || avatar.url().scheme() != "mxc"_ls) {
|
||||
return {};
|
||||
}
|
||||
auto avatar = connection()->makeMediaUrl(url);
|
||||
if (avatar.isValid() && avatar.scheme() == QStringLiteral("mxc")) {
|
||||
return avatar;
|
||||
} else {
|
||||
|
||||
auto localFile = connection()->makeMediaUrl(avatar.url());
|
||||
if (!localFile.isValid() || localFile.scheme() != QStringLiteral("mxc")) {
|
||||
return QUrl();
|
||||
}
|
||||
return localFile;
|
||||
}
|
||||
|
||||
const RoomEvent *NeoChatRoom::getReplyForEvent(const RoomEvent &event) const
|
||||
|
||||
@@ -213,7 +213,7 @@ void NotificationsManager::postNotification(NeoChatRoom *room,
|
||||
if (!room) {
|
||||
return;
|
||||
}
|
||||
auto connection = dynamic_cast<NeoChatConnection *>(Controller::instance().accounts().get(room->localUser()->id()));
|
||||
auto connection = dynamic_cast<NeoChatConnection *>(Controller::instance().accounts().get(room->localMember().id()));
|
||||
Controller::instance().setActiveConnection(connection);
|
||||
RoomManager::instance().setConnection(connection);
|
||||
RoomManager::instance().resolveResource(room->id());
|
||||
@@ -230,7 +230,7 @@ void NotificationsManager::postNotification(NeoChatRoom *room,
|
||||
notification->setReplyAction(std::move(replyAction));
|
||||
}
|
||||
|
||||
notification->setHint(QStringLiteral("x-kde-origin-name"), room->localUser()->id());
|
||||
notification->setHint(QStringLiteral("x-kde-origin-name"), room->localMember().id());
|
||||
notification->sendEvent();
|
||||
}
|
||||
|
||||
@@ -286,7 +286,7 @@ void NotificationsManager::postInviteNotification(NeoChatRoom *rawRoom, const QS
|
||||
m_invitations.remove(room->id());
|
||||
});
|
||||
|
||||
notification->setHint(QStringLiteral("x-kde-origin-name"), room->localUser()->id());
|
||||
notification->setHint(QStringLiteral("x-kde-origin-name"), room->localMember().id());
|
||||
|
||||
notification->sendEvent();
|
||||
m_invitations.insert(room->id(), notification);
|
||||
|
||||
@@ -154,7 +154,7 @@ void PollHandler::sendPollAnswer(const QString &eventId, const QString &answerId
|
||||
return;
|
||||
}
|
||||
QStringList ownAnswers;
|
||||
for (const auto &answer : m_answers[room->localUser()->id()].toArray()) {
|
||||
for (const auto &answer : m_answers[room->localMember().id()].toArray()) {
|
||||
ownAnswers += answer.toString();
|
||||
}
|
||||
if (ownAnswers.contains(answerId)) {
|
||||
@@ -169,7 +169,7 @@ void PollHandler::sendPollAnswer(const QString &eventId, const QString &answerId
|
||||
}
|
||||
|
||||
auto response = new PollResponseEvent(eventId, ownAnswers);
|
||||
handleAnswer(response->contentJson(), room->localUser()->id(), QDateTime::currentDateTime());
|
||||
handleAnswer(response->contentJson(), room->localMember().id(), QDateTime::currentDateTime());
|
||||
room->postEvent(response);
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
"Name[nl]": "Tobias Fella",
|
||||
"Name[pl]": "Tobias Fella",
|
||||
"Name[sl]": "Tobias Fella",
|
||||
"Name[ta]": "டோபியாஸ் ஃபெல்லா",
|
||||
"Name[tr]": "Tobias Fella",
|
||||
"Name[uk]": "Tobias Fella",
|
||||
"Name[x-test]": "xxTobias Fellaxx",
|
||||
@@ -41,7 +40,6 @@
|
||||
"Description[nl]": "Delen via NeoChat",
|
||||
"Description[pl]": "Udostępnij przez NeoChat",
|
||||
"Description[sl]": "Deli prek NeoChat",
|
||||
"Description[ta]": "நியோச்சாட் மூலம் பகிர்",
|
||||
"Description[tr]": "NeoChat ile Paylaş",
|
||||
"Description[uk]": "Оприлюднити за допомогою NeoChat",
|
||||
"Description[x-test]": "xxShare via NeoChatxx",
|
||||
@@ -65,7 +63,6 @@
|
||||
"Name[nl]": "NeoChat",
|
||||
"Name[pl]": "NeoChat",
|
||||
"Name[sl]": "NeoChat",
|
||||
"Name[ta]": "நியோச்சாட்",
|
||||
"Name[tr]": "NeoChat",
|
||||
"Name[uk]": "NeoChat",
|
||||
"Name[x-test]": "xxNeoChatxx",
|
||||
|
||||
@@ -278,8 +278,6 @@ QQC2.Control {
|
||||
Keys.onTabPressed: {
|
||||
if (completionMenu.visible) {
|
||||
completionMenu.complete();
|
||||
} else {
|
||||
contextDrawer.handle.children[0].forceActiveFocus()
|
||||
}
|
||||
}
|
||||
Keys.onPressed: event => {
|
||||
|
||||
@@ -48,10 +48,10 @@ QQC2.ItemDelegate {
|
||||
|
||||
background: Rectangle {
|
||||
color: root.checked ? Kirigami.Theme.highlightColor : Kirigami.Theme.backgroundColor
|
||||
radius: Kirigami.Units.cornerRadius
|
||||
radius: Kirigami.Units.smallSpacing
|
||||
|
||||
Rectangle {
|
||||
radius: Kirigami.Units.cornerRadius
|
||||
radius: Kirigami.Units.smallSpacing
|
||||
anchors.fill: parent
|
||||
color: Kirigami.Theme.highlightColor
|
||||
opacity: root.hovered && !root.pressed ? 0.2 : 0
|
||||
|
||||
@@ -40,7 +40,7 @@ QQC2.Popup {
|
||||
background: Kirigami.ShadowedRectangle {
|
||||
Kirigami.Theme.colorSet: Kirigami.Theme.View
|
||||
color: Kirigami.Theme.backgroundColor
|
||||
radius: Kirigami.Units.cornerRadius
|
||||
radius: Kirigami.Units.mediumSpacing
|
||||
shadow {
|
||||
size: Kirigami.Units.largeSpacing
|
||||
color: Qt.rgba(0.0, 0.0, 0.0, 0.3)
|
||||
|
||||
@@ -30,7 +30,7 @@ QQC2.Popup {
|
||||
onOpened: x = Math.min(parent.mapFromGlobal(QQC2.Overlay.overlay.width - root.width, 0).x, -(width - parent.width) / 2)
|
||||
background: Kirigami.ShadowedRectangle {
|
||||
color: Kirigami.Theme.backgroundColor
|
||||
radius: Kirigami.Units.cornerRadius
|
||||
radius: Kirigami.Units.mediumSpacing
|
||||
shadow {
|
||||
size: Kirigami.Units.largeSpacing
|
||||
color: Qt.rgba(0.0, 0.0, 0.0, 0.3)
|
||||
|
||||
@@ -17,7 +17,7 @@ RowLayout {
|
||||
property bool collapsed: false
|
||||
required property NeoChatConnection connection
|
||||
|
||||
signal search
|
||||
property alias roomSearchFieldFocussed: roomSearchField.activeFocus
|
||||
|
||||
property Kirigami.Action exploreAction: Kirigami.Action {
|
||||
text: i18n("Explore rooms")
|
||||
@@ -83,30 +83,15 @@ RowLayout {
|
||||
*/
|
||||
signal textChanged(string newText)
|
||||
|
||||
Item {
|
||||
Layout.preferredWidth: Kirigami.Units.largeSpacing
|
||||
}
|
||||
|
||||
Kirigami.Heading {
|
||||
Kirigami.SearchField {
|
||||
id: roomSearchField
|
||||
Layout.topMargin: Kirigami.Units.smallSpacing
|
||||
Layout.bottomMargin: Kirigami.Units.smallSpacing
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredWidth: root.desiredWidth ? root.desiredWidth - menuButton.width - root.spacing : -1
|
||||
visible: !root.collapsed
|
||||
text: i18nc("@title", "Rooms")
|
||||
}
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
visible: root.collapsed
|
||||
}
|
||||
|
||||
QQC2.ToolButton {
|
||||
id: searchButton
|
||||
display: QQC2.AbstractButton.IconOnly
|
||||
onClicked: root.search();
|
||||
icon.name: "search"
|
||||
text: i18nc("@action", "Search Room")
|
||||
Shortcut {
|
||||
sequence: "Ctrl+F"
|
||||
onActivated: searchButton.clicked()
|
||||
}
|
||||
onTextChanged: root.textChanged(text)
|
||||
KeyNavigation.tab: treeView
|
||||
}
|
||||
|
||||
QQC2.ToolButton {
|
||||
@@ -115,8 +100,8 @@ RowLayout {
|
||||
display: QQC2.AbstractButton.IconOnly
|
||||
checkable: true
|
||||
action: Kirigami.Action {
|
||||
text: i18nc("@action:button", "Show Menu")
|
||||
icon.name: "application-menu-symbolic"
|
||||
text: i18n("Create rooms and chats")
|
||||
icon.name: "irc-join-channel"
|
||||
onTriggered: {
|
||||
if (Kirigami.isMobile) {
|
||||
const menu = mobileMenu.createObject();
|
||||
|
||||
304
src/qml/FancyEffectsContainer.qml
Normal file
304
src/qml/FancyEffectsContainer.qml
Normal file
@@ -0,0 +1,304 @@
|
||||
// SPDX-FileCopyrightText: 2021 Alexey Andreyev <aa13q@ya.ru>
|
||||
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Particles
|
||||
|
||||
import org.kde.kirigami as Kirigami
|
||||
|
||||
Item {
|
||||
id: root
|
||||
property bool enabled: false
|
||||
property int effectInterval: Kirigami.Units.veryLongDuration * 10
|
||||
property color darkSnowColor: "grey"
|
||||
property bool isThemeDark: Kirigami.Theme.backgroundColor.hslLightness <= darkSnowColor.hslLightness
|
||||
|
||||
function showConfettiEffect() {
|
||||
confettiTimer.start();
|
||||
}
|
||||
|
||||
function showSnowEffect() {
|
||||
snowTimer.start();
|
||||
}
|
||||
|
||||
function showFireworksEffect() {
|
||||
fireworksTimer.start();
|
||||
}
|
||||
|
||||
// Confetti
|
||||
|
||||
Timer {
|
||||
id: confettiTimer
|
||||
interval: root.effectInterval
|
||||
running: false
|
||||
repeat: false
|
||||
triggeredOnStart: true
|
||||
onTriggered: {
|
||||
if (root.enabled) {
|
||||
confettiSystem.running = !confettiSystem.running;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ParticleSystem {
|
||||
id: confettiSystem
|
||||
anchors.fill: parent
|
||||
|
||||
running: false
|
||||
onRunningChanged: {
|
||||
if (running) {
|
||||
opacity = 1;
|
||||
} else {
|
||||
opacity = 0;
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on opacity {
|
||||
SequentialAnimation {
|
||||
NumberAnimation {
|
||||
duration: Kirigami.Units.longDuration
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImageParticle {
|
||||
source: "qrc:/qt/qml/org/kde/neochat/qml/confetti.png"
|
||||
entryEffect: ImageParticle.Scale
|
||||
rotationVariation: 360
|
||||
rotationVelocity: 90
|
||||
color: Qt.hsla(Math.random(), 0.5, 0.6, 1)
|
||||
colorVariation: 1
|
||||
}
|
||||
|
||||
Emitter {
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
top: parent.top
|
||||
}
|
||||
|
||||
sizeVariation: Kirigami.Units.iconSizes.small / 2
|
||||
lifeSpan: Kirigami.Units.veryLongDuration * 10
|
||||
size: Kirigami.Units.iconSizes.small
|
||||
|
||||
velocity: AngleDirection {
|
||||
angle: 90
|
||||
angleVariation: 42
|
||||
magnitude: 500
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Snow
|
||||
|
||||
Timer {
|
||||
id: snowTimer
|
||||
interval: root.effectInterval
|
||||
running: false
|
||||
repeat: false
|
||||
triggeredOnStart: true
|
||||
onTriggered: {
|
||||
if (root.enabled) {
|
||||
snowSystem.running = !snowSystem.running;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ParticleSystem {
|
||||
id: snowSystem
|
||||
anchors.fill: parent
|
||||
|
||||
running: false
|
||||
onRunningChanged: {
|
||||
if (running) {
|
||||
opacity = 1;
|
||||
} else {
|
||||
opacity = 0;
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on opacity {
|
||||
SequentialAnimation {
|
||||
NumberAnimation {
|
||||
duration: Kirigami.Units.longDuration
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ItemParticle {
|
||||
delegate: Rectangle {
|
||||
width: 10
|
||||
height: width
|
||||
radius: width
|
||||
color: root.isThemeDark ? "white" : darkSnowColor
|
||||
scale: Math.random()
|
||||
opacity: Math.random()
|
||||
}
|
||||
}
|
||||
|
||||
Emitter {
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
top: parent.top
|
||||
}
|
||||
|
||||
sizeVariation: Kirigami.Units.iconSizes.medium
|
||||
lifeSpan: Kirigami.Units.veryLongDuration * 10
|
||||
size: Kirigami.Units.iconSizes.large
|
||||
emitRate: 42
|
||||
|
||||
velocity: AngleDirection {
|
||||
angle: 90
|
||||
angleVariation: 10
|
||||
magnitude: 300
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fireworks
|
||||
|
||||
Timer {
|
||||
id: fireworksTimer
|
||||
interval: root.effectInterval
|
||||
running: false
|
||||
repeat: false
|
||||
triggeredOnStart: true
|
||||
onTriggered: {
|
||||
if (root.enabled) {
|
||||
fireworksInternalTimer.running = !fireworksInternalTimer.running;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: fireworksInternalTimer
|
||||
interval: 300
|
||||
triggeredOnStart: true
|
||||
running: false
|
||||
repeat: true
|
||||
onTriggered: {
|
||||
var x = Math.random() * parent.width;
|
||||
var y = Math.random() * parent.height;
|
||||
customEmit(x, y);
|
||||
customEmit(x, y);
|
||||
customEmit(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
ParticleSystem {
|
||||
id: fireworksSystem
|
||||
anchors.fill: parent
|
||||
running: fireworksInternalTimer.running
|
||||
onRunningChanged: {
|
||||
if (running) {
|
||||
opacity = 1;
|
||||
} else {
|
||||
opacity = 0;
|
||||
}
|
||||
}
|
||||
|
||||
Behavior on opacity {
|
||||
SequentialAnimation {
|
||||
NumberAnimation {
|
||||
duration: Kirigami.Units.longDuration
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ImageParticle {
|
||||
id: fireworksParticleA
|
||||
system: fireworksSystem
|
||||
source: "qrc:/qt/qml/org/kde/neochat/qml/glowdot.png"
|
||||
alphaVariation: root.isThemeDark ? 0.1 : 0.1
|
||||
alpha: root.isThemeDark ? 0.5 : 1
|
||||
groups: ["a"]
|
||||
opacity: fireworksSystem.opacity
|
||||
entryEffect: ImageParticle.Scale
|
||||
rotationVariation: 360
|
||||
}
|
||||
|
||||
ImageParticle {
|
||||
system: fireworksSystem
|
||||
source: "qrc:/qt/qml/org/kde/neochat/qml/glowdot.png"
|
||||
color: root.isThemeDark ? "white" : "gold"
|
||||
alphaVariation: root.isThemeDark ? 0.1 : 0.1
|
||||
alpha: root.isThemeDark ? 0.5 : 1
|
||||
groups: ["light"]
|
||||
opacity: fireworksSystem.opacity
|
||||
entryEffect: ImageParticle.Scale
|
||||
rotationVariation: 360
|
||||
}
|
||||
|
||||
ImageParticle {
|
||||
id: fireworksParticleB
|
||||
system: fireworksSystem
|
||||
source: "qrc:/qt/qml/org/kde/neochat/qml/glowdot.png"
|
||||
alphaVariation: root.isThemeDark ? 0.1 : 0.1
|
||||
alpha: root.isThemeDark ? 0.5 : 1
|
||||
groups: ["b"]
|
||||
opacity: fireworksSystem.opacity
|
||||
entryEffect: ImageParticle.Scale
|
||||
rotationVariation: 360
|
||||
}
|
||||
|
||||
Component {
|
||||
id: emitterComp
|
||||
Emitter {
|
||||
id: container
|
||||
property int life: 23
|
||||
property real targetX: 0
|
||||
property real targetY: 0
|
||||
width: 1
|
||||
height: 1
|
||||
system: fireworksSystem
|
||||
size: 16
|
||||
endSize: 8
|
||||
sizeVariation: 5
|
||||
Timer {
|
||||
interval: life
|
||||
running: true
|
||||
onTriggered: {
|
||||
container.destroy();
|
||||
var randomHue = Math.random();
|
||||
var lightness = root.isThemeDark ? 0.8 : 0.7;
|
||||
fireworksParticleA.color = Qt.hsla(randomHue, 0.8, lightness, 1);
|
||||
fireworksParticleB.color = Qt.hsla(1 - randomHue, 0.8, lightness, 1);
|
||||
}
|
||||
}
|
||||
velocity: AngleDirection {
|
||||
angleVariation: 360
|
||||
magnitude: 200
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function customEmit(x, y) {
|
||||
var currentSize = Math.round(Math.random() * 200) + 40;
|
||||
var currentLifeSpan = Math.round(Math.random() * 1000) + 100;
|
||||
for (var i = 0; i < 8; i++) {
|
||||
var obj = emitterComp.createObject(parent);
|
||||
obj.x = x;
|
||||
obj.y = y;
|
||||
obj.targetX = Math.random() * currentSize - currentSize / 2 + obj.x;
|
||||
obj.targetY = Math.random() * currentSize - currentSize / 2 + obj.y;
|
||||
obj.life = Math.round(Math.random() * 23) + 150;
|
||||
obj.emitRate = Math.round(Math.random() * 32) + 5;
|
||||
obj.lifeSpan = currentLifeSpan;
|
||||
const group = Math.round(Math.random() * 3);
|
||||
switch (group) {
|
||||
case 0:
|
||||
obj.group = "light";
|
||||
break;
|
||||
case 1:
|
||||
obj.group = "a";
|
||||
break;
|
||||
case 2:
|
||||
obj.group = "b";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user