Compare commits

..

6 Commits

Author SHA1 Message Date
Tomaz Canabrava
7cc68d2658 Adapt to newer API 2024-04-19 10:42:03 +02:00
Tomaz Canabrava
f4b87caefe Adapt to new AUP 2024-04-19 10:18:39 +02:00
Tomaz Canabrava
07a9497f4c Fix bad commit 2024-04-19 10:18:31 +02:00
Tomaz Canabrava
35f1ace458 Adapt to newer API
TODO: There are some missing methods and I do not know what to do there
2024-04-19 10:04:13 +02:00
Tomaz Canabrava
11dd0ee151 Adapt to new Avatar API 2024-04-19 10:03:49 +02:00
Tomaz Canabrava
07e200c74f Adapt to breaking changes in libQuotient
localUser() -> localMember()
2024-04-19 09:45:11 +02:00
139 changed files with 9095 additions and 10774 deletions

View File

@@ -110,7 +110,7 @@
{ {
"type": "git", "type": "git",
"url": "https://github.com/quotient-im/libQuotient.git", "url": "https://github.com/quotient-im/libQuotient.git",
"branch": "0.8.x", "branch": "dev",
"disable-submodules": true "disable-submodules": true
} }
], ],

View File

@@ -9,7 +9,7 @@ cmake_minimum_required(VERSION 3.16)
# KDE Applications version, managed by release script. # KDE Applications version, managed by release script.
set(RELEASE_SERVICE_VERSION_MAJOR "24") set(RELEASE_SERVICE_VERSION_MAJOR "24")
set(RELEASE_SERVICE_VERSION_MINOR "04") set(RELEASE_SERVICE_VERSION_MINOR "04")
set(RELEASE_SERVICE_VERSION_MICRO "90") set(RELEASE_SERVICE_VERSION_MICRO "70")
set(RELEASE_SERVICE_VERSION "${RELEASE_SERVICE_VERSION_MAJOR}.${RELEASE_SERVICE_VERSION_MINOR}.${RELEASE_SERVICE_VERSION_MICRO}") set(RELEASE_SERVICE_VERSION "${RELEASE_SERVICE_VERSION_MAJOR}.${RELEASE_SERVICE_VERSION_MINOR}.${RELEASE_SERVICE_VERSION_MICRO}")
project(NeoChat VERSION ${RELEASE_SERVICE_VERSION}) project(NeoChat VERSION ${RELEASE_SERVICE_VERSION})

View File

@@ -105,7 +105,7 @@ void EventHandlerTest::author()
auto eventHandlerAuthor = eventHandler.getAuthor(); 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["id"_ls], author->id());
QCOMPARE(eventHandlerAuthor["displayName"_ls], author->displayname(room)); QCOMPARE(eventHandlerAuthor["displayName"_ls], author->displayname(room));
QCOMPARE(eventHandlerAuthor["avatarSource"_ls], room->avatarForMember(author)); QCOMPARE(eventHandlerAuthor["avatarSource"_ls], room->avatarForMember(author));
@@ -390,7 +390,7 @@ void EventHandlerTest::replyAuthor()
auto eventHandlerReplyAuthor = eventHandler.getReplyAuthor(); 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["id"_ls], replyAuthor->id());
QCOMPARE(eventHandlerReplyAuthor["displayName"_ls], replyAuthor->displayname(room)); QCOMPARE(eventHandlerReplyAuthor["displayName"_ls], replyAuthor->displayname(room));
QCOMPARE(eventHandlerReplyAuthor["avatarSource"_ls], room->avatarForMember(replyAuthor)); QCOMPARE(eventHandlerReplyAuthor["avatarSource"_ls], room->avatarForMember(replyAuthor));

View File

@@ -118,7 +118,6 @@
<p xml:lang="nn">NeoChat har som mål å støtta all funksjonalitet i Matrix-spesifikasjonen. Førebels er alt i den gjeldande stabile spesifikasjonen støtta, med unntak av VoIP, trådar og nokre delar av ende-til-kryptering. Det finst òg andre småting som ikkje er støtta, sidan Matrix-spesifikasjon er i stadig endring, men målet er altså støtte for alt.</p> <p xml:lang="nn">NeoChat har som mål å støtta all funksjonalitet i Matrix-spesifikasjonen. Førebels er alt i den gjeldande stabile spesifikasjonen støtta, med unntak av VoIP, trådar og nokre delar av ende-til-kryptering. Det finst òg andre småting som ikkje er støtta, sidan Matrix-spesifikasjon er i stadig endring, men målet er altså støtte for alt.</p>
<p xml:lang="pl">NeoChat w zamyśle ma być pełnowartościową aplikacją wg wytycznych Matriksa. Z tego powodu, wszystko, co jest obecnie w stabilnych wytycznych z pominięciem VoIP, wątków i niektórych części szyfrowania Użytkownik-do-Użytkownika są obecnie obsługiwane. Pominięto też kilka mniejszych rzeczy ze względu na ciągły rozwój wytycznych Matriksa, lecz celem nadal jest zapewnienie obsługi wszystkich wytycznych.</p> <p xml:lang="pl">NeoChat w zamyśle ma być pełnowartościową aplikacją wg wytycznych Matriksa. Z tego powodu, wszystko, co jest obecnie w stabilnych wytycznych z pominięciem VoIP, wątków i niektórych części szyfrowania Użytkownik-do-Użytkownika są obecnie obsługiwane. Pominięto też kilka mniejszych rzeczy ze względu na ciągły rozwój wytycznych Matriksa, lecz celem nadal jest zapewnienie obsługi wszystkich wytycznych.</p>
<p xml:lang="pt">O NeoChat pretende ser uma aplicação completa para a especificação do Matrix. Como tal, tudo o que existe na especificação estável actual, com as notáveis excepções do VoIP, tópicos e alguns aspectos da Encriptação Ponto-a-Ponto, são suportados. Existem mais algumas omissões, devido ao facto que a norma do Matrix está em constante evolução, mas o objectivo continua a ser oferecer o suporte eventual para a norma por inteiro.</p> <p xml:lang="pt">O NeoChat pretende ser uma aplicação completa para a especificação do Matrix. Como tal, tudo o que existe na especificação estável actual, com as notáveis excepções do VoIP, tópicos e alguns aspectos da Encriptação Ponto-a-Ponto, são suportados. Existem mais algumas omissões, devido ao facto que a norma do Matrix está em constante evolução, mas o objectivo continua a ser oferecer o suporte eventual para a norma por inteiro.</p>
<p xml:lang="ru">Целью создания NeoChat является полноценная реализация программы для спецификации Matrix. Как следствие, реализовано всё в текущей стабильной спецификации (за исключением голосовой интернет-связи, потоков и некоторых аспектов сквозного шифрования). Есть также несколько других незначительных пробелов, обусловленных постоянными изменениями спецификации Matrix. Тем не менее, стоит задача в итоге предоставить полную поддержку спецификации.</p>
<p xml:lang="sl">Neochat cilja, da bi bila popolna aplikacija po specifikaciji Matrixa. Kot takšna vsebuje vse v trenutni stabilni specifikaciji z pomembnimi izjemami pri VoIP, nitih in nekaterih vidikov šifriranja od konca do konca. Obstaja nekaj drugih manjših opustitev zaradi dejstva, da se specifikacija Matrix nenehno razvija, vendar cilj ostaja zagotoviti morebitno podporo celotni specifikaciji.</p> <p xml:lang="sl">Neochat cilja, da bi bila popolna aplikacija po specifikaciji Matrixa. Kot takšna vsebuje vse v trenutni stabilni specifikaciji z pomembnimi izjemami pri VoIP, nitih in nekaterih vidikov šifriranja od konca do konca. Obstaja nekaj drugih manjših opustitev zaradi dejstva, da se specifikacija Matrix nenehno razvija, vendar cilj ostaja zagotoviti morebitno podporo celotni specifikaciji.</p>
<p xml:lang="sv">NeoChat har som mål att vara ett fullständigt program enligt Matrix-specifikationen. Som sådant stöds allt i den nuvarande stabila specifikationen, med de nämnvärda undantagen VoIP, trådar och några aspekter av kryptering hela vägen. Det finns några ytterligare utelämnanden på grund av att Matrix-specifikationen hela tiden utvecklas, men målet förblir att till slut erbjuda stöd för hela specifikationen.</p> <p xml:lang="sv">NeoChat har som mål att vara ett fullständigt program enligt Matrix-specifikationen. Som sådant stöds allt i den nuvarande stabila specifikationen, med de nämnvärda undantagen VoIP, trådar och några aspekter av kryptering hela vägen. Det finns några ytterligare utelämnanden på grund av att Matrix-specifikationen hela tiden utvecklas, men målet förblir att till slut erbjuda stöd för hela specifikationen.</p>
<p xml:lang="tr">NeoChat, Matrix belirtimi için tam özellikli bir uygulama olmayı hedefler. Bu nedenle; VoIP, ileti zincirleri ve Uçtan Uca Şifrelemenin bazı yönleri gibi dikkate değer istisnalar dışında var olan kararlı belirtimdeki her şey desteklenir. Matrix belirtiminin sürekli gelişmesi nedeniyle birkaç küçük eksiklik daha var; ancak amaç tüm belirtim için nihai destek sağlamak olmayı sürdürüyor.</p> <p xml:lang="tr">NeoChat, Matrix belirtimi için tam özellikli bir uygulama olmayı hedefler. Bu nedenle; VoIP, ileti zincirleri ve Uçtan Uca Şifrelemenin bazı yönleri gibi dikkate değer istisnalar dışında var olan kararlı belirtimdeki her şey desteklenir. Matrix belirtiminin sürekli gelişmesi nedeniyle birkaç küçük eksiklik daha var; ancak amaç tüm belirtim için nihai destek sağlamak olmayı sürdürüyor.</p>
@@ -146,7 +145,6 @@
<p xml:lang="nn">På grunn av måten Matrix-spesifikasjonen vert utvikla på, støttar NeoChat òg nokre uferdige funksjonar:</p> <p xml:lang="nn">På grunn av måten Matrix-spesifikasjonen vert utvikla på, støttar NeoChat òg nokre uferdige funksjonar:</p>
<p xml:lang="pl">Ze względu na sposób rozwoju Matriksa, NeoChat obsługuje także kilka niestabilnych możliwości. Obecnie są to:</p> <p xml:lang="pl">Ze względu na sposób rozwoju Matriksa, NeoChat obsługuje także kilka niestabilnych możliwości. Obecnie są to:</p>
<p xml:lang="pt">Devido à natureza do desenvolvimento da especificação do Matrix, o NeoChat também suporta diversas funcionalidades instáveis. De momento são:</p> <p xml:lang="pt">Devido à natureza do desenvolvimento da especificação do Matrix, o NeoChat também suporta diversas funcionalidades instáveis. De momento são:</p>
<p xml:lang="ru">В силу природы разработки спецификации Matrix в NeoChat тоже предусмотрена поддержка многочисленных нестабильных возможностей. В текущей версии это следующие возможности:</p>
<p xml:lang="sl">Zaradi narave razvoja specifikacije Matrixa NeoChat podpira tudi številne nestabilne zmožnosti. Trenutno so to:</p> <p xml:lang="sl">Zaradi narave razvoja specifikacije Matrixa NeoChat podpira tudi številne nestabilne zmožnosti. Trenutno so to:</p>
<p xml:lang="sv">På grund av sättet Matrix-specifikationens utvecklas, stöder NeoChat också ett stor antal instabila funktioner. För närvarande är de:</p> <p xml:lang="sv">På grund av sättet Matrix-specifikationens utvecklas, stöder NeoChat också ett stor antal instabila funktioner. För närvarande är de:</p>
<p xml:lang="ta">மேட்ரிக்ஸு நெறிமுறை வரையறுக்கப்படும் வித‍த்தின் காரணமாக, பல நிலையற்ற அம்சங்களையும் நியோச்சாட் ஆதரிக்கிறது. தற்போது ஆதரிக்கப்படுபவை:</p> <p xml:lang="ta">மேட்ரிக்ஸு நெறிமுறை வரையறுக்கப்படும் வித‍த்தின் காரணமாக, பல நிலையற்ற அம்சங்களையும் நியோச்சாட் ஆதரிக்கிறது. தற்போது ஆதரிக்கப்படுபவை:</p>
@@ -204,7 +202,6 @@
<li xml:lang="nn">Klistremerke-pakkar  MSC2545</li> <li xml:lang="nn">Klistremerke-pakkar  MSC2545</li>
<li xml:lang="pl">Paczki naklejek - MSC2545</li> <li xml:lang="pl">Paczki naklejek - MSC2545</li>
<li xml:lang="pt">Pacotes de Autocolantes - MSC2545</li> <li xml:lang="pt">Pacotes de Autocolantes - MSC2545</li>
<li xml:lang="ru">Наборы стикеров — MSC2545</li>
<li xml:lang="sl">Sticker Packs - MSC2545</li> <li xml:lang="sl">Sticker Packs - MSC2545</li>
<li xml:lang="sv">Sticker Packs - MSC2545</li> <li xml:lang="sv">Sticker Packs - MSC2545</li>
<li xml:lang="ta">ஒட்டி தொகுப்புகள் - MSC2545</li> <li xml:lang="ta">ஒட்டி தொகுப்புகள் - MSC2545</li>
@@ -233,7 +230,6 @@
<li xml:lang="nn">Posisjonshendingar  MSC3488</li> <li xml:lang="nn">Posisjonshendingar  MSC3488</li>
<li xml:lang="pl">Wydarzenia w miejscach - MSC3488</li> <li xml:lang="pl">Wydarzenia w miejscach - MSC3488</li>
<li xml:lang="pt">Eventos com Localizações - MSC3488</li> <li xml:lang="pt">Eventos com Localizações - MSC3488</li>
<li xml:lang="ru">События местоположения — MSC3488</li>
<li xml:lang="sl">Location Events - MSC3488</li> <li xml:lang="sl">Location Events - MSC3488</li>
<li xml:lang="sv">Location Events - MSC3488</li> <li xml:lang="sv">Location Events - MSC3488</li>
<li xml:lang="ta">இட நிகழ்வுகள் - MSC3488</li> <li xml:lang="ta">இட நிகழ்வுகள் - MSC3488</li>
@@ -295,7 +291,6 @@
<caption xml:lang="nn">Hovudvising med romliste, pratevindauge og rominformasjon</caption> <caption xml:lang="nn">Hovudvising med romliste, pratevindauge og rominformasjon</caption>
<caption xml:lang="pl">Główny widok z wykazem pokojów, rozmowami i szczegółami pokojów</caption> <caption xml:lang="pl">Główny widok z wykazem pokojów, rozmowami i szczegółami pokojów</caption>
<caption xml:lang="pt">A área principal com a lista de salas e com informações sobre a conversa e a sala</caption> <caption xml:lang="pt">A área principal com a lista de salas e com informações sobre a conversa e a sala</caption>
<caption xml:lang="ru">Главное окно со списком комнат, чатом и информацией о комнате</caption>
<caption xml:lang="sl">Glavni pogled s seznamom sob, klepetom in informacijami o sobah</caption> <caption xml:lang="sl">Glavni pogled s seznamom sob, klepetom in informacijami o sobah</caption>
<caption xml:lang="sv">Huvudvy med rumslista, chatt, och rumsinformation</caption> <caption xml:lang="sv">Huvudvy med rumslista, chatt, och rumsinformation</caption>
<caption xml:lang="ta">அரங்குப்பட்டியல், உரையாடல், மற்றும் அரங்குவிவரங்களைக் கொண்டுள்ள பிரதான காட்சி</caption> <caption xml:lang="ta">அரங்குப்பட்டியல், உரையாடல், மற்றும் அரங்குவிவரங்களைக் கொண்டுள்ள பிரதான காட்சி</caption>
@@ -355,7 +350,6 @@
<caption xml:lang="nn">Hovudvising med romliste, pratevindauge og rominformasjon</caption> <caption xml:lang="nn">Hovudvising med romliste, pratevindauge og rominformasjon</caption>
<caption xml:lang="pl">Główny widok z wykazem pokojów, rozmowami i szczegółami pokojów</caption> <caption xml:lang="pl">Główny widok z wykazem pokojów, rozmowami i szczegółami pokojów</caption>
<caption xml:lang="pt">A área principal com a lista de salas e com informações sobre a conversa e a sala</caption> <caption xml:lang="pt">A área principal com a lista de salas e com informações sobre a conversa e a sala</caption>
<caption xml:lang="ru">Главное окно со списком комнат, чатом и информацией о комнате</caption>
<caption xml:lang="sl">Glavni pogled s seznamom sob, klepetom in informacijami o sobah</caption> <caption xml:lang="sl">Glavni pogled s seznamom sob, klepetom in informacijami o sobah</caption>
<caption xml:lang="sv">Huvudvy med rumslista, chatt, och rumsinformation</caption> <caption xml:lang="sv">Huvudvy med rumslista, chatt, och rumsinformation</caption>
<caption xml:lang="ta">அரங்குப்பட்டியல், உரையாடல், மற்றும் அரங்குவிவரங்களைக் கொண்டுள்ள பிரதான காட்சி</caption> <caption xml:lang="ta">அரங்குப்பட்டியல், உரையாடல், மற்றும் அரங்குவிவரங்களைக் கொண்டுள்ள பிரதான காட்சி</caption>
@@ -387,7 +381,6 @@
<caption xml:lang="nn">Innloggingsbilete</caption> <caption xml:lang="nn">Innloggingsbilete</caption>
<caption xml:lang="pl">Ekran logowania</caption> <caption xml:lang="pl">Ekran logowania</caption>
<caption xml:lang="pt">Ecrã de autenticação</caption> <caption xml:lang="pt">Ecrã de autenticação</caption>
<caption xml:lang="ru">Окно входа</caption>
<caption xml:lang="sl">Prijavni zaslon</caption> <caption xml:lang="sl">Prijavni zaslon</caption>
<caption xml:lang="sv">Inloggningsfönster</caption> <caption xml:lang="sv">Inloggningsfönster</caption>
<caption xml:lang="ta">நுழைவுத் திரை</caption> <caption xml:lang="ta">நுழைவுத் திரை</caption>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -204,6 +204,7 @@ qt_add_qml_module(neochat URI org.kde.neochat NO_PLUGIN
qml/InviteUserPage.qml qml/InviteUserPage.qml
qml/ImageEditorPage.qml qml/ImageEditorPage.qml
qml/NeochatMaximizeComponent.qml qml/NeochatMaximizeComponent.qml
qml/FancyEffectsContainer.qml
qml/TypingPane.qml qml/TypingPane.qml
qml/QuickSwitcher.qml qml/QuickSwitcher.qml
qml/HoverActions.qml qml/HoverActions.qml
@@ -280,6 +281,9 @@ qt_add_qml_module(neochat URI org.kde.neochat NO_PLUGIN
qml/ConfirmLeaveDialog.qml qml/ConfirmLeaveDialog.qml
qml/CodeMaximizeComponent.qml qml/CodeMaximizeComponent.qml
qml/EditStateDialog.qml qml/EditStateDialog.qml
RESOURCES
qml/confetti.png
qml/glowdot.png
) )
add_subdirectory(settings) add_subdirectory(settings)

View File

@@ -91,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++) { for (auto it = m_room->messageEvents().crbegin(); it != m_room->messageEvents().crend(); it++) {
if (const auto event = eventCast<const RoomMessageEvent>(&**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; QString originalString;
if (event->content()) { if (event->content()) {
originalString = static_cast<const Quotient::EventContent::TextContent *>(event->content())->body; originalString = static_cast<const Quotient::EventContent::TextContent *>(event->content())->body;

View File

@@ -19,6 +19,7 @@
#include <signal.h> #include <signal.h>
#include <Quotient/accountregistry.h> #include <Quotient/accountregistry.h>
#include <Quotient/connection.h>
#include <Quotient/csapi/logout.h> #include <Quotient/csapi/logout.h>
#include <Quotient/csapi/notifications.h> #include <Quotient/csapi/notifications.h>
#include <Quotient/eventstats.h> #include <Quotient/eventstats.h>

View File

@@ -117,7 +117,7 @@ private:
Quotient::AccountRegistry m_accountRegistry; Quotient::AccountRegistry m_accountRegistry;
QStringList m_accountsLoading; QStringList m_accountsLoading;
QMap<QString, QPointer<NeoChatConnection>> m_connectionsLoading; QMap<QString, QPointer<Quotient::Connection>> m_connectionsLoading;
QString m_endpoint; QString m_endpoint;
private Q_SLOTS: private Q_SLOTS:

View File

@@ -15,12 +15,6 @@ FormCard.FormCardPage {
FormCard.FormCard { FormCard.FormCard {
Layout.topMargin: Kirigami.Units.largeSpacing 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 { FormCard.FormCheckDelegate {
id: roomAccountDataVisibleCheck id: roomAccountDataVisibleCheck
text: i18nc("@option:check Enable the matrix 'threads' feature", "Always allow device verification") text: i18nc("@option:check Enable the matrix 'threads' feature", "Always allow device verification")
@@ -29,14 +23,5 @@ FormCard.FormCardPage {
onToggled: Config.alwaysVerifyDevice = checked onToggled: Config.alwaysVerifyDevice = checked
} }
FormCard.FormCheckDelegate {
text: i18nc("@option:check", "Show focus in window header")
checked: Config.windowTitleFocus
onToggled: {
Config.windowTitleFocus = checked;
Config.save();
}
}
} }
} }

View File

@@ -25,10 +25,9 @@ ColumnLayout {
text: i18n("Room") text: i18n("Room")
textRole: "escapedDisplayName" textRole: "escapedDisplayName"
valueRole: "roomId" 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 model: RoomManager.roomListModel
currentIndex: 0 currentIndex: 0
displayMode: FormCard.FormComboBoxDelegate.Page
Component.onCompleted: currentIndex = RoomManager.roomListModel.rowForRoom(root.room) Component.onCompleted: currentIndex = RoomManager.roomListModel.rowForRoom(root.room)
onCurrentValueChanged: root.room = RoomManager.roomListModel.roomByAliasOrId(roomComboBox.currentValue) onCurrentValueChanged: root.room = RoomManager.roomListModel.roomByAliasOrId(roomComboBox.currentValue)
} }

View File

@@ -21,6 +21,7 @@ public:
* @brief Defines the room list categories a room can be assigned. * @brief Defines the room list categories a room can be assigned.
*/ */
enum Types { 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. */ Invited, /**< The user has been invited to the room. */
Favorite, /**< The room is set as a favourite. */ Favorite, /**< The room is set as a favourite. */
Direct, /**< The room is a direct chat. */ Direct, /**< The room is a direct chat. */
@@ -67,6 +68,8 @@ public:
return i18n("Low priority"); return i18n("Low priority");
case NeoChatRoomType::Space: case NeoChatRoomType::Space:
return i18n("Spaces"); return i18n("Spaces");
case NeoChatRoomType::Search:
return i18n("Search");
default: default:
return {}; return {};
} }
@@ -86,6 +89,8 @@ public:
return QStringLiteral("object-order-lower"); return QStringLiteral("object-order-lower");
case NeoChatRoomType::Space: case NeoChatRoomType::Space:
return QStringLiteral("group"); return QStringLiteral("group");
case NeoChatRoomType::Search:
return QStringLiteral("search");
default: default:
return QStringLiteral("tools-report-bug"); return QStringLiteral("tools-report-bug");
} }

View File

@@ -73,7 +73,7 @@ QVariantMap EventHandler::getAuthor(bool isPending) const
return m_room->getUser(nullptr); 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); return m_room->getUser(author);
} }
@@ -96,7 +96,7 @@ QString EventHandler::getAuthorDisplayName(bool isPending) const
} }
return previousDisplayName; return previousDisplayName;
} else { } 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()); return m_room->htmlSafeMemberName(author->id());
} }
} }
@@ -112,7 +112,7 @@ QString EventHandler::singleLineAuthorDisplayname(bool isPending) const
return {}; 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()); auto displayName = m_room->safeMemberName(author->id());
displayName.replace(QStringLiteral("<br>\n"), QStringLiteral(" ")); displayName.replace(QStringLiteral("<br>\n"), QStringLiteral(" "));
displayName.replace(QStringLiteral("<br>"), QStringLiteral(" ")); displayName.replace(QStringLiteral("<br>"), QStringLiteral(" "));
@@ -963,7 +963,7 @@ bool EventHandler::hasReadMarkers() const
} }
auto userIds = m_room->userIdsAtEvent(m_event->id()); auto userIds = m_room->userIdsAtEvent(m_event->id());
userIds.remove(m_room->localUser()->id()); userIds.remove(m_room->localMember().id());
return userIds.size() > 0; return userIds.size() > 0;
} }
@@ -979,7 +979,7 @@ QVariantList EventHandler::getReadMarkers(int maxMarkers) const
} }
auto userIds_temp = m_room->userIdsAtEvent(m_event->id()); 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(); auto userIds = userIds_temp.values();
if (userIds.count() > maxMarkers) { if (userIds.count() > maxMarkers) {
@@ -1008,7 +1008,7 @@ QString EventHandler::getNumberExcessReadMarkers(int maxMarkers) const
} }
auto userIds = m_room->userIdsAtEvent(m_event->id()); auto userIds = m_room->userIdsAtEvent(m_event->id());
userIds.remove(m_room->localUser()->id()); userIds.remove(m_room->localMember().id());
if (userIds.count() > maxMarkers) { if (userIds.count() > maxMarkers) {
return QStringLiteral("+ ") + QString::number(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()); 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 * The string ends up in the form
@@ -1038,11 +1038,7 @@ QString EventHandler::getReadMarkersString() const
QString readMarkersString = i18np("1 user: ", "%1 users: ", userIds.size()); QString readMarkersString = i18np("1 user: ", "%1 users: ", userIds.size());
for (const auto &userId : userIds) { for (const auto &userId : userIds) {
auto user = m_room->user(userId); auto user = m_room->user(userId);
auto displayName = user->displayname(m_room); readMarkersString += user->displayname(m_room) + i18nc("list separator", ", ");
if (displayName.isEmpty()) {
displayName = userId;
}
readMarkersString += displayName + i18nc("list separator", ", ");
} }
readMarkersString.chop(2); readMarkersString.chop(2);
return readMarkersString; return readMarkersString;

View File

@@ -4,6 +4,7 @@
#include "login.h" #include "login.h"
#include <Quotient/accountregistry.h> #include <Quotient/accountregistry.h>
#include <Quotient/connection.h>
#include <Quotient/qt_connection_util.h> #include <Quotient/qt_connection_util.h>
#include "controller.h" #include "controller.h"
@@ -53,7 +54,7 @@ void LoginHelper::init()
m_connection = new NeoChatConnection(); m_connection = new NeoChatConnection();
} }
m_connection->resolveServer(m_matrixId); m_connection->resolveServer(m_matrixId);
connectSingleShot(m_connection.get(), &Connection::loginFlowsChanged, this, [this]() { connectSingleShot(m_connection, &Connection::loginFlowsChanged, this, [this]() {
setHomeserverReachable(true); setHomeserverReachable(true);
m_testing = false; m_testing = false;
Q_EMIT testingChanged(); Q_EMIT testingChanged();
@@ -99,7 +100,7 @@ void LoginHelper::init()
Q_EMIT Controller::instance().errorOccured(i18n("Network Error"), std::move(error)); 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(); Q_EMIT loaded();
}); });
} }
@@ -181,7 +182,7 @@ QUrl LoginHelper::ssoUrl() const
void LoginHelper::loginWithSso() void LoginHelper::loginWithSso()
{ {
m_connection->resolveServer(m_matrixId); 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); SsoSession *session = m_connection->prepareForSso(m_deviceName);
m_ssoUrl = session->ssoUrl(); m_ssoUrl = session->ssoUrl();
Q_EMIT ssoUrlChanged(); Q_EMIT ssoUrlChanged();

View File

@@ -146,7 +146,7 @@ private:
QString m_deviceName; QString m_deviceName;
bool m_supportsSso = false; bool m_supportsSso = false;
bool m_supportsPassword = false; bool m_supportsPassword = false;
QPointer<NeoChatConnection> m_connection; NeoChatConnection *m_connection = nullptr;
QUrl m_ssoUrl; QUrl m_ssoUrl;
bool m_testing = false; bool m_testing = false;
bool m_isLoggingIn = false; bool m_isLoggingIn = false;

View File

@@ -14,6 +14,8 @@
#include "neochatconnection.h" #include "neochatconnection.h"
#include <Quotient/connection.h>
using namespace Quotient; using namespace Quotient;
ThumbnailResponse::ThumbnailResponse(QString id, QSize size, NeoChatConnection *connection) ThumbnailResponse::ThumbnailResponse(QString id, QSize size, NeoChatConnection *connection)

View File

@@ -35,7 +35,7 @@ private:
QSize requestedSize; QSize requestedSize;
const QString localFile; const QString localFile;
Quotient::MediaThumbnailJob *job = nullptr; Quotient::MediaThumbnailJob *job = nullptr;
QPointer<NeoChatConnection> m_connection; NeoChatConnection *m_connection;
QImage image; QImage image;
QString errorStr; QString errorStr;
@@ -75,6 +75,6 @@ public:
QQuickImageResponse *requestImageResponse(const QString &id, const QSize &requestedSize) override; QQuickImageResponse *requestImageResponse(const QString &id, const QSize &requestedSize) override;
private: private:
QPointer<NeoChatConnection> m_connection; NeoChatConnection *m_connection = nullptr;
MatrixImageProvider() = default; MatrixImageProvider() = default;
}; };

View File

@@ -10,8 +10,6 @@
#include <Quotient/events/eventcontent.h> #include <Quotient/events/eventcontent.h>
#include <qcoro/qcorosignal.h> #include <qcoro/qcorosignal.h>
#include "neochatconnection.h"
using namespace Quotient; using namespace Quotient;
AccountEmoticonModel::AccountEmoticonModel(QObject *parent) 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; return m_connection;
} }
void AccountEmoticonModel::setConnection(NeoChatConnection *connection) void AccountEmoticonModel::setConnection(Connection *connection)
{ {
if (m_connection) { if (m_connection) {
disconnect(m_connection, nullptr, this, nullptr); disconnect(m_connection, nullptr, this, nullptr);

View File

@@ -12,7 +12,7 @@
#include <QPointer> #include <QPointer>
#include <QQmlEngine> #include <QQmlEngine>
class NeoChatConnection; #include <Quotient/connection.h>
/** /**
* @class AccountEmoticonModel * @class AccountEmoticonModel
@@ -29,7 +29,7 @@ class AccountEmoticonModel : public QAbstractListModel
/** /**
* @brief The connection to get emoticons from. * @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: public:
enum Roles { enum Roles {
@@ -63,8 +63,8 @@ public:
*/ */
[[nodiscard]] QHash<int, QByteArray> roleNames() const override; [[nodiscard]] QHash<int, QByteArray> roleNames() const override;
[[nodiscard]] NeoChatConnection *connection() const; [[nodiscard]] Quotient::Connection *connection() const;
void setConnection(NeoChatConnection *connection); void setConnection(Quotient::Connection *connection);
/** /**
* @brief Deletes the emoticon at the given index. * @brief Deletes the emoticon at the given index.
@@ -96,7 +96,7 @@ Q_SIGNALS:
private: private:
std::optional<Quotient::ImagePackEventContent> m_images; 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> doSetEmoticonImage(int index, QUrl source);
QCoro::Task<void> doAddEmoticon(QUrl source, QString shortcode, QString description, QString type); QCoro::Task<void> doAddEmoticon(QUrl source, QString shortcode, QString description, QString type);

View File

@@ -4,7 +4,6 @@
#include "actionsmodel.h" #include "actionsmodel.h"
#include "chatbarcache.h" #include "chatbarcache.h"
#include "neochatconnection.h"
#include "neochatroom.h" #include "neochatroom.h"
#include "roommanager.h" #include "roommanager.h"
#include <Quotient/events/roommemberevent.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)); Q_EMIT room->showMessage(NeoChatRoom::Info, i18nc("<user> is banned from this room.", "%1 is banned from this room.", text));
return QString(); 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.")); Q_EMIT room->showMessage(NeoChatRoom::Positive, i18n("You are already in this room."));
return QString(); return QString();
} }
@@ -261,7 +260,7 @@ QList<ActionsModel::Action> actions{
return QString(); return QString();
} }
Q_EMIT room->showMessage(NeoChatRoom::Info, i18nc("Knocking room <roomname>.", "Knocking room %1.", text)); 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); const auto knownServer = roomName.mid(roomName.indexOf(":"_ls) + 1);
if (parts.length() >= 2) { if (parts.length() >= 2) {
RoomManager::instance().knockRoom(connection, roomName, parts[1], QStringList{knownServer}); RoomManager::instance().knockRoom(connection, roomName, parts[1], QStringList{knownServer});
@@ -431,11 +430,11 @@ QList<ActionsModel::Action> actions{
if (!plEvent) { if (!plEvent) {
return QString(); 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.")); Q_EMIT room->showMessage(NeoChatRoom::Error, i18n("You are not allowed to ban users from this room."));
return QString(); 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( Q_EMIT room->showMessage(
NeoChatRoom::Error, 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])); 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) { if (!plEvent) {
return QString(); 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.")); Q_EMIT room->showMessage(NeoChatRoom::Error, i18n("You are not allowed to unban users from this room."));
return QString(); 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])); i18nc("'<text>' does not look like a matrix id.", "'%1' does not look like a matrix id.", parts[0]));
return QString(); 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.")); Q_EMIT room->showMessage(NeoChatRoom::Error, i18n("You cannot kick yourself from the room."));
return QString(); return QString();
} }
@@ -508,11 +507,11 @@ QList<ActionsModel::Action> actions{
return QString(); return QString();
} }
auto kick = plEvent->kick(); 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.")); Q_EMIT room->showMessage(NeoChatRoom::Error, i18n("You are not allowed to kick users from this room."));
return QString(); 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( Q_EMIT room->showMessage(
NeoChatRoom::Error, 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])); i18nc("You are not allowed to kick <username> from this room", "You are not allowed to kick %1 from this room.", parts[0]));

View File

@@ -110,7 +110,7 @@ Q_SIGNALS:
private: private:
explicit CustomEmojiModel(QObject *parent = nullptr); explicit CustomEmojiModel(QObject *parent = nullptr);
QList<CustomEmoji> m_emojis; QList<CustomEmoji> m_emojis;
QPointer<NeoChatConnection> m_connection; NeoChatConnection *m_connection = nullptr;
void fetchEmojis(); void fetchEmojis();
}; };

View File

@@ -5,8 +5,7 @@
#include "customemojimodel.h" #include "customemojimodel.h"
#include <QRegularExpression> #include <QRegularExpression>
#include <connection.h>
class NeoChatConnection;
struct CustomEmoji { struct CustomEmoji {
QString name; // with :semicolons: QString name; // with :semicolons:
@@ -15,6 +14,6 @@ struct CustomEmoji {
}; };
struct CustomEmojiModel::Private { struct CustomEmojiModel::Private {
QPointer<NeoChatConnection> connection; Quotient::Connection *conn = nullptr;
QList<CustomEmoji> emojies; QList<CustomEmoji> emojies;
}; };

View File

@@ -11,10 +11,9 @@
#include <KLocalizedString> #include <KLocalizedString>
#include <Quotient/csapi/device_management.h> #include <Quotient/csapi/device_management.h>
#include <Quotient/connection.h>
#include <Quotient/user.h> #include <Quotient/user.h>
#include "neochatconnection.h"
using namespace Quotient; using namespace Quotient;
DevicesModel::DevicesModel(QObject *parent) 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; return m_connection;
} }
void DevicesModel::setConnection(NeoChatConnection *connection) void DevicesModel::setConnection(Connection *connection)
{ {
if (m_connection) { if (m_connection) {
disconnect(m_connection, nullptr, this, nullptr); disconnect(m_connection, nullptr, this, nullptr);

View File

@@ -9,7 +9,10 @@
#include <Quotient/csapi/definitions/client_device.h> #include <Quotient/csapi/definitions/client_device.h>
class NeoChatConnection; namespace Quotient
{
class Connection;
}
/** /**
* @class DevicesModel * @class DevicesModel
@@ -28,7 +31,7 @@ class DevicesModel : public QAbstractListModel
/** /**
* @brief The current connection that the model is getting its devices from. * @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: public:
/** /**
@@ -85,8 +88,9 @@ public:
explicit DevicesModel(QObject *parent = nullptr); 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: Q_SIGNALS:
void connectionChanged(); void connectionChanged();
@@ -95,5 +99,5 @@ Q_SIGNALS:
private: private:
void fetchDevices(); void fetchDevices();
QList<Quotient::Device> m_devices; QList<Quotient::Device> m_devices;
QPointer<NeoChatConnection> m_connection; QPointer<Quotient::Connection> m_connection;
}; };

View File

@@ -246,86 +246,70 @@ void MessageContentModel::updateComponents(bool isEditing)
if (eventCast<const Quotient::RoomMessageEvent>(m_event) if (eventCast<const Quotient::RoomMessageEvent>(m_event)
&& eventCast<const Quotient::RoomMessageEvent>(m_event)->rawMsgtype() == QStringLiteral("m.key.verification.request")) { && eventCast<const Quotient::RoomMessageEvent>(m_event)->rawMsgtype() == QStringLiteral("m.key.verification.request")) {
m_components += MessageComponent{MessageComponentType::Verification, QString(), {}}; 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 { } 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 (isEditing) {
if (m_linkPreviewer->loaded()) { m_components += MessageComponent{MessageComponentType::Edit, QString(), {}};
m_components += MessageComponent{MessageComponentType::LinkPreview, QString(), {}}; } else if (m_event->isRedacted()) {
m_components += MessageComponent{MessageComponentType::Text, QString(), {}};
} else { } 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(); 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() void MessageContentModel::updateLinkPreviewer()
{ {
if (m_room == nullptr || m_event == nullptr) { if (m_room == nullptr || m_event == nullptr) {

View File

@@ -98,8 +98,6 @@ private:
QPointer<LinkPreviewer> m_linkPreviewer; QPointer<LinkPreviewer> m_linkPreviewer;
ItineraryModel *m_itineraryModel = nullptr; ItineraryModel *m_itineraryModel = nullptr;
QList<MessageComponent> componentsForType(MessageComponentType::Type type);
void updateLinkPreviewer(); void updateLinkPreviewer();
void updateItineraryModel(); void updateItineraryModel();
bool m_emptyItinerary = false; bool m_emptyItinerary = false;

View File

@@ -7,6 +7,7 @@
#include "neochatconfig.h" #include "neochatconfig.h"
#include <Quotient/connection.h>
#include <Quotient/csapi/rooms.h> #include <Quotient/csapi/rooms.h>
#include <Quotient/events/redactionevent.h> #include <Quotient/events/redactionevent.h>
#include <Quotient/events/roommessageevent.h> #include <Quotient/events/roommessageevent.h>
@@ -116,6 +117,34 @@ void MessageEventModel::setRoom(NeoChatRoom *room)
if (message != nullptr) { if (message != nullptr) {
createEventObjects(message); 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>()) { if (event->is<PollStartEvent>()) {
m_currentRoom->createPollHandler(eventCast<const PollStartEvent>(event.get())); m_currentRoom->createPollHandler(eventCast<const PollStartEvent>(event.get()));
@@ -222,7 +251,7 @@ void MessageEventModel::setRoom(NeoChatRoom *room)
beginResetModel(); beginResetModel();
endResetModel(); endResetModel();
}); });
qCDebug(MessageEvent) << "Connected to room" << room->id() << "as" << room->localUser()->id(); qCDebug(MessageEvent) << "Connected to room" << room->id() << "as" << room->localMember().id();
} else { } else {
lastReadEventId.clear(); lastReadEventId.clear();
} }
@@ -592,7 +621,7 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
} }
if (role == IsEditableRole) { 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 {}; return {};

View File

@@ -140,4 +140,5 @@ private:
Q_SIGNALS: Q_SIGNALS:
void roomChanged(); void roomChanged();
void fancyEffectsReasonFound(const QString &fancyEffect);
}; };

View File

@@ -36,14 +36,6 @@ MessageFilterModel::MessageFilterModel(QObject *parent, TimelineModel *sourceMod
} }
bool MessageFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const 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); 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 // 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. // same day as they will be grouped as a single delegate.
const bool notLastRow = sourceRow < sourceModel()->rowCount() - 1; const bool notLastRow = sourceRow < sourceModel()->rowCount() - 1;
const bool previousEventIsState = const bool previousEventIsState = notLastRow
notLastRow ? sourceModel()->data(sourceModel()->index(sourceRow + 1, 0), MessageEventModel::DelegateTypeRole) == DelegateType::State : false; ? sourceModel()->data(sourceModel()->index(sourceRow + 1, 0), MessageEventModel::DelegateTypeRole) == DelegateType::State
: false;
const bool newDay = sourceModel()->data(sourceModel()->index(sourceRow, 0), MessageEventModel::ShowSectionRole).toBool(); const bool newDay = sourceModel()->data(sourceModel()->index(sourceRow, 0), MessageEventModel::ShowSectionRole).toBool();
if (eventType == DelegateType::State && notLastRow && previousEventIsState && !newDay) { if (eventType == DelegateType::State && notLastRow && previousEventIsState && !newDay) {
return false; return false;
@@ -79,11 +72,7 @@ bool MessageFilterModel::eventIsVisible(int sourceRow, const QModelIndex &source
QVariant MessageFilterModel::data(const QModelIndex &index, int role) const QVariant MessageFilterModel::data(const QModelIndex &index, int role) const
{ {
if (role == MessageEventModel::DelegateTypeRole && NeoChatConfig::self()->showAllEvents()) { if (role == AggregateDisplayRole) {
if (!eventIsVisible(index.row(), index.parent())) {
return DelegateType::Other;
}
} else if (role == AggregateDisplayRole) {
return aggregateEventToString(mapToSource(index).row()); return aggregateEventToString(mapToSource(index).row());
} else if (role == StateEventsRole) { } else if (role == StateEventsRole) {
return stateEventsList(mapToSource(index).row()); return stateEventsList(mapToSource(index).row());

View File

@@ -60,8 +60,6 @@ public:
[[nodiscard]] QHash<int, QByteArray> roleNames() const override; [[nodiscard]] QHash<int, QByteArray> roleNames() const override;
private: private:
bool eventIsVisible(int sourceRow, const QModelIndex &sourceParent) const;
/** /**
* @brief Aggregation of the text of consecutive state events starting at row. * @brief Aggregation of the text of consecutive state events starting at row.
* *

View File

@@ -3,6 +3,7 @@
#include "notificationsmodel.h" #include "notificationsmodel.h"
#include <Quotient/connection.h>
#include <Quotient/events/event.h> #include <Quotient/events/event.h>
#include <Quotient/uri.h> #include <Quotient/uri.h>

View File

@@ -3,7 +3,8 @@
#include "publicroomlistmodel.h" #include "publicroomlistmodel.h"
#include "neochatconnection.h" #include <Quotient/connection.h>
#include "publicroomlist_logging.h" #include "publicroomlist_logging.h"
using namespace Quotient; using namespace Quotient;
@@ -13,14 +14,14 @@ PublicRoomListModel::PublicRoomListModel(QObject *parent)
{ {
} }
NeoChatConnection *PublicRoomListModel::connection() const Quotient::Connection *PublicRoomListModel::connection() const
{ {
return m_connection; return m_connection;
} }
void PublicRoomListModel::setConnection(NeoChatConnection *connection) void PublicRoomListModel::setConnection(Connection *conn)
{ {
if (m_connection == connection) { if (m_connection == conn) {
return; return;
} }
@@ -37,7 +38,7 @@ void PublicRoomListModel::setConnection(NeoChatConnection *connection)
endResetModel(); endResetModel();
m_connection = connection; m_connection = conn;
if (job) { if (job) {
job->abandon(); job->abandon();

View File

@@ -9,7 +9,10 @@
#include <Quotient/csapi/list_public_rooms.h> #include <Quotient/csapi/list_public_rooms.h>
class NeoChatConnection; namespace Quotient
{
class Connection;
}
/** /**
* @class PublicRoomListModel * @class PublicRoomListModel
@@ -30,7 +33,7 @@ class PublicRoomListModel : public QAbstractListModel
/** /**
* @brief The current connection that the model is getting its rooms from. * @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. * @brief The server to get the public room list from.
@@ -92,8 +95,8 @@ public:
*/ */
[[nodiscard]] QHash<int, QByteArray> roleNames() const override; [[nodiscard]] QHash<int, QByteArray> roleNames() const override;
[[nodiscard]] NeoChatConnection *connection() const; [[nodiscard]] Quotient::Connection *connection() const;
void setConnection(NeoChatConnection *connection); void setConnection(Quotient::Connection *conn);
[[nodiscard]] QString server() const; [[nodiscard]] QString server() const;
void setServer(const QString &value); void setServer(const QString &value);
@@ -114,7 +117,7 @@ public:
Q_INVOKABLE void search(int limit = 50); Q_INVOKABLE void search(int limit = 50);
private: private:
QPointer<NeoChatConnection> m_connection = nullptr; QPointer<Quotient::Connection> m_connection = nullptr;
QString m_server; QString m_server;
QString m_searchText; QString m_searchText;
bool m_showOnlySpaces = false; bool m_showOnlySpaces = false;

View File

@@ -5,13 +5,13 @@
#include <QDebug> #include <QDebug>
#include <Quotient/connection.h>
#include <Quotient/converters.h> #include <Quotient/converters.h>
#include <Quotient/csapi/definitions/push_ruleset.h> #include <Quotient/csapi/definitions/push_ruleset.h>
#include <Quotient/csapi/pushrules.h> #include <Quotient/csapi/pushrules.h>
#include <Quotient/jobs/basejob.h> #include <Quotient/jobs/basejob.h>
#include "neochatconfig.h" #include "neochatconfig.h"
#include "neochatconnection.h"
#include <KLazyLocalizedString> #include <KLazyLocalizedString>
@@ -454,7 +454,7 @@ void PushRuleModel::setConnection(NeoChatConnection *connection)
Q_EMIT connectionChanged(); Q_EMIT connectionChanged();
if (m_connection) { 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")); updateNotificationRules(QStringLiteral("m.push_rules"));
} }
} }

View File

@@ -126,7 +126,7 @@ private Q_SLOTS:
private: private:
PushRuleAction::Action m_defaultKeywordAction; PushRuleAction::Action m_defaultKeywordAction;
QList<Rule> m_rules; QList<Rule> m_rules;
QPointer<NeoChatConnection> m_connection; NeoChatConnection *m_connection;
void setRules(QList<Quotient::PushRule> rules, PushRuleKind::Kind kind); void setRules(QList<Quotient::PushRule> rules, PushRuleKind::Kind kind);

View File

@@ -68,8 +68,7 @@ QVariant ReactionModel::data(const QModelIndex &index, int role) const
text += i18nc("Separate the usernames of users", " and "); text += i18nc("Separate the usernames of users", " and ");
} }
} }
auto displayName = reaction.authors.at(i).toMap()[QStringLiteral("displayName")].toString(); text += reaction.authors.at(i).toMap()[QStringLiteral("displayName")].toString();
text += displayName.isEmpty() ? reaction.authors.at(i).toMap()[QStringLiteral("id")].toString() : displayName;
} }
if (reaction.authors.count() > 3) { if (reaction.authors.count() > 3) {
@@ -91,7 +90,7 @@ QVariant ReactionModel::data(const QModelIndex &index, int role) const
if (role == HasLocalUser) { if (role == HasLocalUser) {
for (auto author : reaction.authors) { 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; return true;
} }
} }

View File

@@ -25,12 +25,12 @@ RoomListModel::RoomListModel(QObject *parent)
RoomListModel::~RoomListModel() = default; RoomListModel::~RoomListModel() = default;
NeoChatConnection *RoomListModel::connection() const Quotient::Connection *RoomListModel::connection() const
{ {
return m_connection; return m_connection;
} }
void RoomListModel::setConnection(NeoChatConnection *connection) void RoomListModel::setConnection(Connection *connection)
{ {
if (connection == m_connection) { if (connection == m_connection) {
return; return;

View File

@@ -12,11 +12,10 @@ class NeoChatRoom;
namespace Quotient namespace Quotient
{ {
class Connection;
class Room; class Room;
} }
class NeoChatConnection;
/** /**
* @class RoomListModel * @class RoomListModel
* *
@@ -30,7 +29,7 @@ class RoomListModel : public QAbstractListModel
/** /**
* @brief The current connection that the model is getting its rooms from. * @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: public:
/** /**
@@ -61,8 +60,8 @@ public:
explicit RoomListModel(QObject *parent = nullptr); explicit RoomListModel(QObject *parent = nullptr);
~RoomListModel() override; ~RoomListModel() override;
[[nodiscard]] NeoChatConnection *connection() const; [[nodiscard]] Quotient::Connection *connection() const;
void setConnection(NeoChatConnection *connection); void setConnection(Quotient::Connection *connection);
/** /**
* @brief Get the given role value at the given index. * @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 = {}); void refresh(NeoChatRoom *room, const QList<int> &roles = {});
private: private:
QPointer<NeoChatConnection> m_connection; Quotient::Connection *m_connection = nullptr;
QList<NeoChatRoom *> m_rooms; QList<NeoChatRoom *> m_rooms;
QString m_activeSpaceId; QString m_activeSpaceId;

View File

@@ -3,6 +3,7 @@
#include "roomtreemodel.h" #include "roomtreemodel.h"
#include <Quotient/connection.h>
#include <Quotient/room.h> #include <Quotient/room.h>
#include "eventhandler.h" #include "eventhandler.h"
@@ -299,6 +300,9 @@ QVariant RoomTreeModel::data(const QModelIndex &index, int role) const
return NeoChatRoomType::typeName(index.row()); return NeoChatRoomType::typeName(index.row());
} }
if (role == DelegateTypeRole) { if (role == DelegateTypeRole) {
if (index.row() == NeoChatRoomType::Search) {
return QStringLiteral("search");
}
if (index.row() == NeoChatRoomType::AddDirect) { if (index.row() == NeoChatRoomType::AddDirect) {
return QStringLiteral("addDirect"); return QStringLiteral("addDirect");
} }

View File

@@ -10,6 +10,7 @@
#include <QGuiApplication> #include <QGuiApplication>
#include <Quotient/connection.h>
#include <Quotient/events/stickerevent.h> #include <Quotient/events/stickerevent.h>
#include <KLocalizedString> #include <KLocalizedString>

View File

@@ -3,6 +3,8 @@
#include "serverlistmodel.h" #include "serverlistmodel.h"
#include <Quotient/connection.h>
#include <QDebug> #include <QDebug>
#include <KConfig> #include <KConfig>

View File

@@ -110,7 +110,7 @@ Q_SIGNALS:
private: private:
QList<Server> m_servers; QList<Server> m_servers;
QPointer<Quotient::QueryPublicRoomsJob> m_checkServerJob = nullptr; QPointer<Quotient::QueryPublicRoomsJob> m_checkServerJob = nullptr;
QPointer<NeoChatConnection> m_connection; NeoChatConnection *m_connection = nullptr;
void initialize(); void initialize();
}; };

View File

@@ -5,8 +5,6 @@
#include "roomlistmodel.h" #include "roomlistmodel.h"
#include "neochatconnection.h"
SortFilterRoomListModel::SortFilterRoomListModel(RoomListModel *sourceModel, QObject *parent) SortFilterRoomListModel::SortFilterRoomListModel(RoomListModel *sourceModel, QObject *parent)
: QSortFilterProxyModel(parent) : QSortFilterProxyModel(parent)
{ {

View File

@@ -129,6 +129,10 @@ QString SortFilterRoomTreeModel::filterText() const
bool SortFilterRoomTreeModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const bool SortFilterRoomTreeModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
{ {
if (!source_parent.isValid()) { 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 if (sourceModel()->data(sourceModel()->index(source_row, 0), RoomTreeModel::CategoryRole).toInt() == NeoChatRoomType::AddDirect
&& m_mode == DirectChats) { && m_mode == DirectChats) {
return true; return true;
@@ -201,14 +205,4 @@ void SortFilterRoomTreeModel::setMode(SortFilterRoomTreeModel::Mode mode)
invalidate(); 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" #include "moc_sortfilterroomtreemodel.cpp"

View File

@@ -76,8 +76,6 @@ public:
Mode mode() const; Mode mode() const;
void setMode(Mode mode); void setMode(Mode mode);
Q_INVOKABLE QModelIndex currentRoomIndex() const;
protected: protected:
/** /**
* @brief Returns true if the value of source_left is less than source_right. * @brief Returns true if the value of source_left is less than source_right.

View File

@@ -3,6 +3,7 @@
#include "spacechildrenmodel.h" #include "spacechildrenmodel.h"
#include <Quotient/connection.h>
#include <Quotient/jobs/basejob.h> #include <Quotient/jobs/basejob.h>
#include <Quotient/room.h> #include <Quotient/room.h>
@@ -46,7 +47,7 @@ void SpaceChildrenModel::setSpace(NeoChatRoom *space)
} }
auto connection = m_space->connection(); 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())) { if (m_pendingChildren.contains(room->name())) {
m_pendingChildren.removeAll(room->name()); m_pendingChildren.removeAll(room->name());
refreshModel(); refreshModel();

View File

@@ -1,8 +1,6 @@
// SPDX-FileCopyrightText: 2023 James Graham <james.h.graham@protonmail.com> // 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 // 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/csapi/space_hierarchy.h>
#include <Quotient/events/stateevent.h> #include <Quotient/events/stateevent.h>
@@ -151,7 +149,7 @@ public:
bool isSuggested() const; bool isSuggested() const;
private: private:
QPointer<NeoChatConnection> m_connection; NeoChatConnection *m_connection;
std::vector<std::unique_ptr<SpaceTreeItem>> m_children; std::vector<std::unique_ptr<SpaceTreeItem>> m_children;
SpaceTreeItem *m_parentItem; SpaceTreeItem *m_parentItem;

View File

@@ -3,10 +3,9 @@
#include "userdirectorylistmodel.h" #include "userdirectorylistmodel.h"
#include <Quotient/connection.h>
#include <Quotient/room.h> #include <Quotient/room.h>
#include "neochatconnection.h"
using namespace Quotient; using namespace Quotient;
UserDirectoryListModel::UserDirectoryListModel(QObject *parent) UserDirectoryListModel::UserDirectoryListModel(QObject *parent)
@@ -14,14 +13,14 @@ UserDirectoryListModel::UserDirectoryListModel(QObject *parent)
{ {
} }
NeoChatConnection *UserDirectoryListModel::connection() const Quotient::Connection *UserDirectoryListModel::connection() const
{ {
return m_connection; return m_connection;
} }
void UserDirectoryListModel::setConnection(NeoChatConnection *connection) void UserDirectoryListModel::setConnection(Connection *conn)
{ {
if (m_connection == connection) { if (m_connection == conn) {
return; return;
} }
@@ -36,7 +35,7 @@ void UserDirectoryListModel::setConnection(NeoChatConnection *connection)
endResetModel(); endResetModel();
m_connection = connection; m_connection = conn;
Q_EMIT connectionChanged(); Q_EMIT connectionChanged();
if (m_job) { if (m_job) {

View File

@@ -9,7 +9,10 @@
#include <Quotient/csapi/users.h> #include <Quotient/csapi/users.h>
class NeoChatConnection; namespace Quotient
{
class Connection;
}
/** /**
* @class UserDirectoryListModel * @class UserDirectoryListModel
@@ -29,7 +32,7 @@ class UserDirectoryListModel : public QAbstractListModel
/** /**
* @brief The current connection that the model is getting users from. * @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. * @brief The text to search the public room list for.
@@ -54,8 +57,8 @@ public:
explicit UserDirectoryListModel(QObject *parent = nullptr); explicit UserDirectoryListModel(QObject *parent = nullptr);
[[nodiscard]] NeoChatConnection *connection() const; [[nodiscard]] Quotient::Connection *connection() const;
void setConnection(NeoChatConnection *connection); void setConnection(Quotient::Connection *conn);
[[nodiscard]] QString searchText() const; [[nodiscard]] QString searchText() const;
void setSearchText(const QString &searchText); void setSearchText(const QString &searchText);
@@ -96,7 +99,7 @@ Q_SIGNALS:
void searchingChanged(); void searchingChanged();
private: private:
QPointer<NeoChatConnection> m_connection; Quotient::Connection *m_connection = nullptr;
QString m_searchText; QString m_searchText;
bool attempted = false; bool attempted = false;

View File

@@ -5,6 +5,7 @@
#include <QGuiApplication> #include <QGuiApplication>
#include <Quotient/connection.h>
#include <Quotient/events/roompowerlevelsevent.h> #include <Quotient/events/roompowerlevelsevent.h>
#include "neochatroom.h" #include "neochatroom.h"

View File

@@ -254,7 +254,7 @@ Action=Popup
[Event/Share] [Event/Share]
Name=Share Name=Share
Name[ca]=Compartició Name[ca]=Compartició
Name[ca@valencia]=Compartiu Name[ca@valencia]=Compartició
Name[cs]=Sdílet Name[cs]=Sdílet
Name[eo]=Kundividi Name[eo]=Kundividi
Name[es]=Compartir Name[es]=Compartir

View File

@@ -100,6 +100,10 @@
<label>Minimize to system tray on startup</label> <label>Minimize to system tray on startup</label>
<default>false</default> <default>false</default>
</entry> </entry>
<entry name="ShowFancyEffects" type="bool">
<label>Show Fancy Effects</label>
<default>true</default>
</entry>
<entry name="MediaMaxWidth" type="int"> <entry name="MediaMaxWidth" type="int">
<label>The maximum width any media item in the timeline can be.</label> <label>The maximum width any media item in the timeline can be.</label>
<default>540</default> <default>540</default>
@@ -157,18 +161,10 @@
</entry> </entry>
</group> </group>
<group name="Debug"> <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"> <entry name="AlwaysVerifyDevice" type="bool">
<label>Always allow device verification</label> <label>Always allow device verification</label>
<default>false</default> <default>false</default>
</entry> </entry>
<entry name="WindowTitleFocus" type="bool">
<label>Show the current focus item in the window title</label>
<default>false</default>
</entry>
</group> </group>
<group name="FeatureFlags"> <group name="FeatureFlags">
<entry name="Threads" type="bool"> <entry name="Threads" type="bool">

View File

@@ -101,15 +101,17 @@ NeoChatRoom::NeoChatRoom(Connection *connection, QString roomId, JoinState joinS
if (this->joinState() != JoinState::Invite) { if (this->joinState() != JoinState::Invite) {
return; return;
} }
auto roomMemberEvent = currentState().get<RoomMemberEvent>(localUser()->id()); auto roomMemberEvent = currentState().get<RoomMemberEvent>(localMember().id());
QImage avatar_image; QImage avatar_image;
if (roomMemberEvent && !user(roomMemberEvent->senderId())->avatarUrl(this).isEmpty()) { if (roomMemberEvent && !member(roomMemberEvent->senderId()).avatarUrl().isEmpty()) {
avatar_image = user(roomMemberEvent->senderId())->avatar(128, this); // TODO: Fix acessing Avatar Image.
// avatar_image = member(roomMemberEvent->senderId()).avatarMediaId();
avatar_image = avatar(128);
} else { } else {
qWarning() << "using this room's avatar"; qWarning() << "using this room's avatar";
avatar_image = avatar(128); 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] { connect(this, &Room::changed, this, [this] {
Q_EMIT canEncryptRoomChanged(); Q_EMIT canEncryptRoomChanged();
@@ -257,18 +259,18 @@ void NeoChatRoom::forget()
QVariantList NeoChatRoom::getUsersTyping() const QVariantList NeoChatRoom::getUsersTyping() const
{ {
auto users = usersTyping(); auto users = membersTyping();
users.removeAll(localUser()); users.removeAll(localMember());
QVariantList userVariants; QVariantList userVariants;
for (const auto &user : users) { for (const auto &user : users) {
if (connection()->isIgnored(user->id())) { if (connection()->isIgnored(user.id())) {
continue; continue;
} }
userVariants.append(QVariantMap{ userVariants.append(QVariantMap{
{"id"_ls, user->id()}, {"id"_ls, user.id()},
{"avatarMediaId"_ls, user->avatarMediaId(this)}, {"avatarMediaId"_ls, user.avatarMediaId()},
{"displayName"_ls, user->displayname(this)}, {"displayName"_ls, user.displayName()},
{"display"_ls, user->name()}, {"display"_ls, user.name()},
}); });
} }
return userVariants; return userVariants;
@@ -276,7 +278,7 @@ QVariantList NeoChatRoom::getUsersTyping() const
void NeoChatRoom::sendTypingNotification(bool isTyping) 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 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; continue;
} }
@@ -374,13 +376,13 @@ bool NeoChatRoom::isEventHighlighted(const RoomEvent *e) const
void NeoChatRoom::checkForHighlights(const Quotient::TimelineItem &ti) void NeoChatRoom::checkForHighlights(const Quotient::TimelineItem &ti)
{ {
auto localUserId = localUser()->id(); auto localMemberId = localMember().id();
if (ti->senderId() == localUserId) { if (ti->senderId() == localMemberId) {
return; return;
} }
if (auto *e = ti.viewAs<RoomMessageEvent>()) { if (auto *e = ti.viewAs<RoomMessageEvent>()) {
const auto &text = e->plainBody(); 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); highlights.insert(e);
} }
} }
@@ -439,7 +441,8 @@ static const QVariantMap emptyUser = {
QVariantMap NeoChatRoom::getUser(const QString &userID) const 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 QVariantMap NeoChatRoom::getUser(User *user) const
@@ -449,13 +452,13 @@ QVariantMap NeoChatRoom::getUser(User *user) const
} }
return QVariantMap{ return QVariantMap{
{QStringLiteral("isLocalUser"), user->id() == localUser()->id()}, {QStringLiteral("isLocalUser"), user->id() == localMember().id()},
{QStringLiteral("id"), user->id()}, {QStringLiteral("id"), user->id()},
{QStringLiteral("displayName"), user->displayname(this)}, {QStringLiteral("displayName"), user->displayname()},
{QStringLiteral("escapedDisplayName"), htmlSafeMemberName(user->id())}, {QStringLiteral("escapedDisplayName"), member(user->id()).htmlSafeDisplayName()},
{QStringLiteral("avatarSource"), avatarForMember(user)}, {QStringLiteral("avatarSource"), avatarForMember(user)},
{QStringLiteral("avatarMediaId"), user->avatarMediaId(this)}, {QStringLiteral("avatarMediaId"), user->avatarMediaId()},
{QStringLiteral("color"), Utils::getUserColor(user->hueF())}, {QStringLiteral("color"), member(user->id()).hueF()},
{QStringLiteral("object"), QVariant::fromValue(user)}, {QStringLiteral("object"), QVariant::fromValue(user)},
}; };
} }
@@ -467,10 +470,10 @@ QString NeoChatRoom::avatarMediaId() const
} }
// Use the first (excluding self) user's avatar for direct chats // Use the first (excluding self) user's avatar for direct chats
const auto dcUsers = directChatUsers(); const auto dcUsers = directChatMembers();
for (const auto u : dcUsers) { for (const auto u : dcUsers) {
if (u != localUser()) { if (u != localMember()) {
return u->avatarMediaId(this); return u.avatarMediaId();
} }
} }
@@ -637,7 +640,7 @@ void NeoChatRoom::toggleReaction(const QString &eventId, const QString &reaction
continue; continue;
} }
if (e->senderId() == localUser()->id()) { if (e->senderId() == localMember().id()) {
redactEventIds.push_back(e->id()); redactEventIds.push_back(e->id());
break; break;
} }
@@ -666,7 +669,7 @@ bool NeoChatRoom::canSendEvent(const QString &eventType) const
return false; return false;
} }
auto pl = plEvent->powerLevelForEvent(eventType); auto pl = plEvent->powerLevelForEvent(eventType);
auto currentPl = plEvent->powerLevelForUser(localUser()->id()); auto currentPl = plEvent->powerLevelForUser(localMember().id());
return currentPl >= pl; return currentPl >= pl;
} }
@@ -678,7 +681,7 @@ bool NeoChatRoom::canSendState(const QString &eventType) const
return false; return false;
} }
auto pl = plEvent->powerLevelForState(eventType); auto pl = plEvent->powerLevelForState(eventType);
auto currentPl = plEvent->powerLevelForUser(localUser()->id()); auto currentPl = plEvent->powerLevelForUser(localMember().id());
return currentPl >= pl; return currentPl >= pl;
} }
@@ -856,7 +859,7 @@ void NeoChatRoom::setUrlPreviewEnabled(const bool &urlPreviewEnabled)
* "type": "org.matrix.room.preview_urls", * "type": "org.matrix.room.preview_urls",
* } * }
*/ */
connection()->callApi<SetAccountDataPerRoomJob>(localUser()->id(), connection()->callApi<SetAccountDataPerRoomJob>(localMember().id(),
id(), id(),
"org.matrix.room.preview_urls"_ls, "org.matrix.room.preview_urls"_ls,
QJsonObject{{"disable"_ls, !urlPreviewEnabled}}); 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 // 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(); auto content = (*it)->contentJson();
if (e->msgtype() != MessageEventType::Unknown) { if (e->msgtype() != MessageEventType::Unknown) {
@@ -1933,16 +1936,16 @@ QByteArray NeoChatRoom::roomAcountDataJson(const QString &eventType)
QUrl NeoChatRoom::avatarForMember(Quotient::User *user) const QUrl NeoChatRoom::avatarForMember(Quotient::User *user) const
{ {
const auto &url = memberAvatarUrl(user->id()); const auto &avatar = memberAvatar(user->id());
if (url.isEmpty() || url.scheme() != "mxc"_ls) { if (avatar.url().isEmpty() || avatar.url().scheme() != "mxc"_ls) {
return {}; return {};
} }
auto avatar = connection()->makeMediaUrl(url);
if (avatar.isValid() && avatar.scheme() == QStringLiteral("mxc")) { auto localFile = connection()->makeMediaUrl(avatar.url());
return avatar; if (!localFile.isValid() || localFile.scheme() != QStringLiteral("mxc")) {
} else {
return QUrl(); return QUrl();
} }
return localFile;
} }
const RoomEvent *NeoChatRoom::getReplyForEvent(const RoomEvent &event) const const RoomEvent *NeoChatRoom::getReplyForEvent(const RoomEvent &event) const

View File

@@ -213,7 +213,7 @@ void NotificationsManager::postNotification(NeoChatRoom *room,
if (!room) { if (!room) {
return; 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); Controller::instance().setActiveConnection(connection);
RoomManager::instance().setConnection(connection); RoomManager::instance().setConnection(connection);
RoomManager::instance().resolveResource(room->id()); RoomManager::instance().resolveResource(room->id());
@@ -230,7 +230,7 @@ void NotificationsManager::postNotification(NeoChatRoom *room,
notification->setReplyAction(std::move(replyAction)); 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(); notification->sendEvent();
} }
@@ -286,7 +286,7 @@ void NotificationsManager::postInviteNotification(NeoChatRoom *rawRoom, const QS
m_invitations.remove(room->id()); 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(); notification->sendEvent();
m_invitations.insert(room->id(), notification); m_invitations.insert(room->id(), notification);

View File

@@ -154,7 +154,7 @@ void PollHandler::sendPollAnswer(const QString &eventId, const QString &answerId
return; return;
} }
QStringList ownAnswers; 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(); ownAnswers += answer.toString();
} }
if (ownAnswers.contains(answerId)) { if (ownAnswers.contains(answerId)) {
@@ -169,7 +169,7 @@ void PollHandler::sendPollAnswer(const QString &eventId, const QString &answerId
} }
auto response = new PollResponseEvent(eventId, ownAnswers); 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); room->postEvent(response);
} }

View File

@@ -18,7 +18,6 @@
"Name[nl]": "Tobias Fella", "Name[nl]": "Tobias Fella",
"Name[pl]": "Tobias Fella", "Name[pl]": "Tobias Fella",
"Name[sl]": "Tobias Fella", "Name[sl]": "Tobias Fella",
"Name[ta]": "டோபியாஸ் ஃபெல்லா",
"Name[tr]": "Tobias Fella", "Name[tr]": "Tobias Fella",
"Name[uk]": "Tobias Fella", "Name[uk]": "Tobias Fella",
"Name[x-test]": "xxTobias Fellaxx", "Name[x-test]": "xxTobias Fellaxx",
@@ -41,7 +40,6 @@
"Description[nl]": "Delen via NeoChat", "Description[nl]": "Delen via NeoChat",
"Description[pl]": "Udostępnij przez NeoChat", "Description[pl]": "Udostępnij przez NeoChat",
"Description[sl]": "Deli prek NeoChat", "Description[sl]": "Deli prek NeoChat",
"Description[ta]": "நியோச்சாட் மூலம் பகிர்",
"Description[tr]": "NeoChat ile Paylaş", "Description[tr]": "NeoChat ile Paylaş",
"Description[uk]": "Оприлюднити за допомогою NeoChat", "Description[uk]": "Оприлюднити за допомогою NeoChat",
"Description[x-test]": "xxShare via NeoChatxx", "Description[x-test]": "xxShare via NeoChatxx",
@@ -65,7 +63,6 @@
"Name[nl]": "NeoChat", "Name[nl]": "NeoChat",
"Name[pl]": "NeoChat", "Name[pl]": "NeoChat",
"Name[sl]": "NeoChat", "Name[sl]": "NeoChat",
"Name[ta]": "நியோச்சாட்",
"Name[tr]": "NeoChat", "Name[tr]": "NeoChat",
"Name[uk]": "NeoChat", "Name[uk]": "NeoChat",
"Name[x-test]": "xxNeoChatxx", "Name[x-test]": "xxNeoChatxx",

View File

@@ -46,7 +46,7 @@ ColumnLayout {
} }
onClicked: { onClicked: {
let imageEditor = applicationWindow().pageStack.pushDialogLayer(imageEditorPage); let imageEditor = applicationWindow().pageStack.layers.push(imageEditorPage);
imageEditor.newPathChanged.connect(function (newPath) { imageEditor.newPathChanged.connect(function (newPath) {
applicationWindow().pageStack.layers.pop(); applicationWindow().pageStack.layers.pop();
root.attachmentPath = newPath; root.attachmentPath = newPath;

View File

@@ -278,8 +278,6 @@ QQC2.Control {
Keys.onTabPressed: { Keys.onTabPressed: {
if (completionMenu.visible) { if (completionMenu.visible) {
completionMenu.complete(); completionMenu.complete();
} else {
contextDrawer.handle.children[0].forceActiveFocus()
} }
} }
Keys.onPressed: event => { Keys.onPressed: event => {

View File

@@ -48,10 +48,10 @@ QQC2.ItemDelegate {
background: Rectangle { background: Rectangle {
color: root.checked ? Kirigami.Theme.highlightColor : Kirigami.Theme.backgroundColor color: root.checked ? Kirigami.Theme.highlightColor : Kirigami.Theme.backgroundColor
radius: Kirigami.Units.cornerRadius radius: Kirigami.Units.smallSpacing
Rectangle { Rectangle {
radius: Kirigami.Units.cornerRadius radius: Kirigami.Units.smallSpacing
anchors.fill: parent anchors.fill: parent
color: Kirigami.Theme.highlightColor color: Kirigami.Theme.highlightColor
opacity: root.hovered && !root.pressed ? 0.2 : 0 opacity: root.hovered && !root.pressed ? 0.2 : 0

View File

@@ -40,7 +40,7 @@ QQC2.Popup {
background: Kirigami.ShadowedRectangle { background: Kirigami.ShadowedRectangle {
Kirigami.Theme.colorSet: Kirigami.Theme.View Kirigami.Theme.colorSet: Kirigami.Theme.View
color: Kirigami.Theme.backgroundColor color: Kirigami.Theme.backgroundColor
radius: Kirigami.Units.cornerRadius radius: Kirigami.Units.mediumSpacing
shadow { shadow {
size: Kirigami.Units.largeSpacing size: Kirigami.Units.largeSpacing
color: Qt.rgba(0.0, 0.0, 0.0, 0.3) color: Qt.rgba(0.0, 0.0, 0.0, 0.3)

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