Compare commits
56 Commits
work/redst
...
v24.05.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
283aa1dc72 | ||
|
|
c66c035dbb | ||
|
|
cce9b967b9 | ||
|
|
7b751a4e6e | ||
|
|
3b0cc5f4fc | ||
|
|
5a15c013ff | ||
|
|
2351d76466 | ||
|
|
f477ae0d5e | ||
|
|
f8d7a969ac | ||
|
|
c4f79ea73a | ||
|
|
9c132f2a7a | ||
|
|
ba2698585f | ||
|
|
c31b716846 | ||
|
|
49df3b2b2f | ||
|
|
8ef41b9c90 | ||
|
|
2398d917f0 | ||
|
|
3aefdb4aed | ||
|
|
9a2c3e1deb | ||
|
|
110d90bb51 | ||
|
|
0a0cde77e6 | ||
|
|
18d92ec475 | ||
|
|
fd69439927 | ||
|
|
ad97af20b7 | ||
|
|
ca85b99fe9 | ||
|
|
0cde5d6168 | ||
|
|
eeddf99ca5 | ||
|
|
09a35b1a7e | ||
|
|
533182ec55 | ||
|
|
70a8842f00 | ||
|
|
ab33d1ca88 | ||
|
|
9e45f22e09 | ||
|
|
6a627dfff0 | ||
|
|
a9f05a7f63 | ||
|
|
4dfd4b68eb | ||
|
|
3786710d81 | ||
|
|
3967b27352 | ||
|
|
714ea8413c | ||
|
|
4097addae9 | ||
|
|
e9ac9deb40 | ||
|
|
3b858ab7d5 | ||
|
|
08807797a5 | ||
|
|
923839d6c7 | ||
|
|
3d4a1d22b0 | ||
|
|
5aa7f499c0 | ||
|
|
40c3519737 | ||
|
|
6ec9cc2475 | ||
|
|
eba34b19ad | ||
|
|
8517636485 | ||
|
|
4a96dae57d | ||
|
|
09f433be45 | ||
|
|
b9901a9167 | ||
|
|
8b27d99d82 | ||
|
|
6b53c4d7b1 | ||
|
|
bd28a7f66d | ||
|
|
0d1c09696d | ||
|
|
aeb4013d26 |
@@ -110,7 +110,7 @@
|
||||
{
|
||||
"type": "git",
|
||||
"url": "https://github.com/quotient-im/libQuotient.git",
|
||||
"branch": "dev",
|
||||
"branch": "0.8.x",
|
||||
"disable-submodules": true
|
||||
}
|
||||
],
|
||||
|
||||
@@ -8,8 +8,8 @@ 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 "70")
|
||||
set(RELEASE_SERVICE_VERSION_MINOR "05")
|
||||
set(RELEASE_SERVICE_VERSION_MICRO "0")
|
||||
set(RELEASE_SERVICE_VERSION "${RELEASE_SERVICE_VERSION_MAJOR}.${RELEASE_SERVICE_VERSION_MINOR}.${RELEASE_SERVICE_VERSION_MICRO}")
|
||||
|
||||
project(NeoChat VERSION ${RELEASE_SERVICE_VERSION})
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
<p xml:lang="eo">NeoChat estas babilej-apo, kiu ebligas al vi plene profiti de la Matrix-reto. Ĝi provizas al vi sekuran manieron sendi tekstmesaĝojn, filmetojn kaj sondosierojn al via familio, kolegoj kaj amikoj.</p>
|
||||
<p xml:lang="es">NeoChat es una aplicación de chat que le permite aprovechar al máximo la red Matrix. Le proporciona un modo seguro de enviar mensajes de texto, vídeos y archivos de sonido a su familia, colegas y amigos.</p>
|
||||
<p xml:lang="eu">NeoChat, Matrix sarearen abantaila guztiei probetsua ateratzeko aukera ematen dizun berriketa aplikaizo bat da. Zure familiari, kideei eta lagunei testu mezuak, bideoak eta audio fitxategiak era seguruan bidaltzeko aukera ematen dizu.</p>
|
||||
<p xml:lang="fr">NeoChat est une application de discussions vous permettant de profiter pleinement du réseau Matrix. Elle vous offre un moyen sécurisé d’envoyer des messages de texte, des vidéos et des fichiers audio à votre famille, vos collègues et vos ami(e)s.</p>
|
||||
<p xml:lang="fr">NeoChat est une application de discussions vous permettant de profiter pleinement du réseau Matrix. Elle vous offre un moyen sécurisé d'envoyer des messages de texte, des vidéos et des fichiers audio à votre famille, vos collègues et vos ami(e)s.</p>
|
||||
<p xml:lang="hu">A NeoChat egy olyan csevegőalkalmazás, amellyel teljes mértékben kihasználhatja a Matrix hálózatot. Biztonságos módot biztosít szöveges üzenetek, videók és hangfájlok küldéséhez családtagjainak, kollégáinak és barátainak.</p>
|
||||
<p xml:lang="ia">NeoChat es un app de conversation que te permitte prender avantage plen del rete Matrix. Il te forni un modo secur de inviar messages de texto, videos e files audio a tui familia, collegas e amicos.</p>
|
||||
<p xml:lang="it">NeoChat è un'applicazione di chat che ti consente di sfruttare appieno la rete Matrix. Ti fornisce un modo sicuro per inviare messaggi di testo, video e file audio a familiari, colleghi e amici.</p>
|
||||
@@ -118,6 +118,7 @@
|
||||
<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="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="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 Şifreleme’nin 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>
|
||||
@@ -145,6 +146,7 @@
|
||||
<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="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="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>
|
||||
@@ -202,6 +204,7 @@
|
||||
<li xml:lang="nn">Klistremerke-pakkar – MSC2545</li>
|
||||
<li xml:lang="pl">Paczki naklejek - 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="sv">Sticker Packs - MSC2545</li>
|
||||
<li xml:lang="ta">ஒட்டி தொகுப்புகள் - MSC2545</li>
|
||||
@@ -230,6 +233,7 @@
|
||||
<li xml:lang="nn">Posisjonshendingar – MSC3488</li>
|
||||
<li xml:lang="pl">Wydarzenia w miejscach - 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="sv">Location Events - MSC3488</li>
|
||||
<li xml:lang="ta">இட நிகழ்வுகள் - MSC3488</li>
|
||||
@@ -291,6 +295,7 @@
|
||||
<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="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="sv">Huvudvy med rumslista, chatt, och rumsinformation</caption>
|
||||
<caption xml:lang="ta">அரங்குப்பட்டியல், உரையாடல், மற்றும் அரங்குவிவரங்களைக் கொண்டுள்ள பிரதான காட்சி</caption>
|
||||
@@ -350,6 +355,7 @@
|
||||
<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="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="sv">Huvudvy med rumslista, chatt, och rumsinformation</caption>
|
||||
<caption xml:lang="ta">அரங்குப்பட்டியல், உரையாடல், மற்றும் அரங்குவிவரங்களைக் கொண்டுள்ள பிரதான காட்சி</caption>
|
||||
@@ -381,6 +387,7 @@
|
||||
<caption xml:lang="nn">Innloggingsbilete</caption>
|
||||
<caption xml:lang="pl">Ekran logowania</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="sv">Inloggningsfönster</caption>
|
||||
<caption xml:lang="ta">நுழைவுத் திரை</caption>
|
||||
@@ -394,6 +401,7 @@
|
||||
<content_attribute id="social-chat">intense</content_attribute>
|
||||
</content_rating>
|
||||
<releases>
|
||||
<release version="24.05.0" date="2024-05-23"/>
|
||||
<release version="24.02.2" date="2024-04-11"/>
|
||||
<release version="24.02.1" date="2024-03-21"/>
|
||||
<release version="24.02.0" date="2024-02-28">
|
||||
|
||||
401
po/ar/neochat.po
401
po/ar/neochat.po
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
399
po/az/neochat.po
399
po/az/neochat.po
File diff suppressed because it is too large
Load Diff
438
po/ca/neochat.po
438
po/ca/neochat.po
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
420
po/cs/neochat.po
420
po/cs/neochat.po
File diff suppressed because it is too large
Load Diff
392
po/da/neochat.po
392
po/da/neochat.po
File diff suppressed because it is too large
Load Diff
401
po/de/neochat.po
401
po/de/neochat.po
File diff suppressed because it is too large
Load Diff
401
po/el/neochat.po
401
po/el/neochat.po
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
418
po/eo/neochat.po
418
po/eo/neochat.po
File diff suppressed because it is too large
Load Diff
393
po/es/neochat.po
393
po/es/neochat.po
File diff suppressed because it is too large
Load Diff
391
po/eu/neochat.po
391
po/eu/neochat.po
File diff suppressed because it is too large
Load Diff
396
po/fi/neochat.po
396
po/fi/neochat.po
File diff suppressed because it is too large
Load Diff
403
po/fr/neochat.po
403
po/fr/neochat.po
File diff suppressed because it is too large
Load Diff
588
po/hu/neochat.po
588
po/hu/neochat.po
File diff suppressed because it is too large
Load Diff
391
po/ia/neochat.po
391
po/ia/neochat.po
File diff suppressed because it is too large
Load Diff
401
po/id/neochat.po
401
po/id/neochat.po
File diff suppressed because it is too large
Load Diff
394
po/ie/neochat.po
394
po/ie/neochat.po
File diff suppressed because it is too large
Load Diff
444
po/it/neochat.po
444
po/it/neochat.po
File diff suppressed because it is too large
Load Diff
386
po/ja/neochat.po
386
po/ja/neochat.po
File diff suppressed because it is too large
Load Diff
391
po/ka/neochat.po
391
po/ka/neochat.po
File diff suppressed because it is too large
Load Diff
396
po/ko/neochat.po
396
po/ko/neochat.po
File diff suppressed because it is too large
Load Diff
386
po/lt/neochat.po
386
po/lt/neochat.po
File diff suppressed because it is too large
Load Diff
396
po/lv/neochat.po
396
po/lv/neochat.po
File diff suppressed because it is too large
Load Diff
397
po/nl/neochat.po
397
po/nl/neochat.po
File diff suppressed because it is too large
Load Diff
398
po/nn/neochat.po
398
po/nn/neochat.po
File diff suppressed because it is too large
Load Diff
399
po/pa/neochat.po
399
po/pa/neochat.po
File diff suppressed because it is too large
Load Diff
459
po/pl/neochat.po
459
po/pl/neochat.po
File diff suppressed because it is too large
Load Diff
401
po/pt/neochat.po
401
po/pt/neochat.po
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
550
po/ru/neochat.po
550
po/ru/neochat.po
File diff suppressed because it is too large
Load Diff
400
po/sk/neochat.po
400
po/sk/neochat.po
File diff suppressed because it is too large
Load Diff
393
po/sl/neochat.po
393
po/sl/neochat.po
File diff suppressed because it is too large
Load Diff
401
po/sv/neochat.po
401
po/sv/neochat.po
File diff suppressed because it is too large
Load Diff
438
po/ta/neochat.po
438
po/ta/neochat.po
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
401
po/tr/neochat.po
401
po/tr/neochat.po
File diff suppressed because it is too large
Load Diff
391
po/uk/neochat.po
391
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,7 +204,6 @@ 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
|
||||
@@ -281,9 +280,6 @@ 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)
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
#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<Quotient::Connection>> m_connectionsLoading;
|
||||
QMap<QString, QPointer<NeoChatConnection>> m_connectionsLoading;
|
||||
QString m_endpoint;
|
||||
|
||||
private Q_SLOTS:
|
||||
|
||||
@@ -15,6 +15,12 @@ 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")
|
||||
@@ -23,5 +29,14 @@ 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,9 +25,10 @@ ColumnLayout {
|
||||
text: i18n("Room")
|
||||
textRole: "escapedDisplayName"
|
||||
valueRole: "roomId"
|
||||
displayText: RoomManager.roomListModel.data(RoomManager.roomListModel.index(currentIndex, 0), RoomListModel.DisplayNameRole)
|
||||
displayText: RoomManager.roomListModel.data(RoomManager.roomListModel.index(currentIndex, 0), RoomListModel.EscapedDisplayNameRole)
|
||||
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,7 +21,6 @@ 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. */
|
||||
@@ -68,8 +67,6 @@ public:
|
||||
return i18n("Low priority");
|
||||
case NeoChatRoomType::Space:
|
||||
return i18n("Spaces");
|
||||
case NeoChatRoomType::Search:
|
||||
return i18n("Search");
|
||||
default:
|
||||
return {};
|
||||
}
|
||||
@@ -89,8 +86,6 @@ public:
|
||||
return QStringLiteral("object-order-lower");
|
||||
case NeoChatRoomType::Space:
|
||||
return QStringLiteral("group");
|
||||
case NeoChatRoomType::Search:
|
||||
return QStringLiteral("search");
|
||||
default:
|
||||
return QStringLiteral("tools-report-bug");
|
||||
}
|
||||
|
||||
@@ -1038,7 +1038,11 @@ QString EventHandler::getReadMarkersString() const
|
||||
QString readMarkersString = i18np("1 user: ", "%1 users: ", userIds.size());
|
||||
for (const auto &userId : userIds) {
|
||||
auto user = m_room->user(userId);
|
||||
readMarkersString += user->displayname(m_room) + i18nc("list separator", ", ");
|
||||
auto displayName = user->displayname(m_room);
|
||||
if (displayName.isEmpty()) {
|
||||
displayName = userId;
|
||||
}
|
||||
readMarkersString += displayName + i18nc("list separator", ", ");
|
||||
}
|
||||
readMarkersString.chop(2);
|
||||
return readMarkersString;
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
#include "login.h"
|
||||
|
||||
#include <Quotient/accountregistry.h>
|
||||
#include <Quotient/connection.h>
|
||||
#include <Quotient/qt_connection_util.h>
|
||||
|
||||
#include "controller.h"
|
||||
@@ -54,7 +53,7 @@ void LoginHelper::init()
|
||||
m_connection = new NeoChatConnection();
|
||||
}
|
||||
m_connection->resolveServer(m_matrixId);
|
||||
connectSingleShot(m_connection, &Connection::loginFlowsChanged, this, [this]() {
|
||||
connectSingleShot(m_connection.get(), &Connection::loginFlowsChanged, this, [this]() {
|
||||
setHomeserverReachable(true);
|
||||
m_testing = false;
|
||||
Q_EMIT testingChanged();
|
||||
@@ -100,7 +99,7 @@ void LoginHelper::init()
|
||||
Q_EMIT Controller::instance().errorOccured(i18n("Network Error"), std::move(error));
|
||||
});
|
||||
|
||||
connectSingleShot(m_connection, &Connection::syncDone, this, [this]() {
|
||||
connectSingleShot(m_connection.get(), &Connection::syncDone, this, [this]() {
|
||||
Q_EMIT loaded();
|
||||
});
|
||||
}
|
||||
@@ -182,7 +181,7 @@ QUrl LoginHelper::ssoUrl() const
|
||||
void LoginHelper::loginWithSso()
|
||||
{
|
||||
m_connection->resolveServer(m_matrixId);
|
||||
connectSingleShot(m_connection, &Connection::loginFlowsChanged, this, [this]() {
|
||||
connectSingleShot(m_connection.get(), &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;
|
||||
NeoChatConnection *m_connection = nullptr;
|
||||
QPointer<NeoChatConnection> m_connection;
|
||||
QUrl m_ssoUrl;
|
||||
bool m_testing = false;
|
||||
bool m_isLoggingIn = false;
|
||||
|
||||
@@ -14,8 +14,6 @@
|
||||
|
||||
#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;
|
||||
NeoChatConnection *m_connection;
|
||||
QPointer<NeoChatConnection> m_connection;
|
||||
|
||||
QImage image;
|
||||
QString errorStr;
|
||||
@@ -75,6 +75,6 @@ public:
|
||||
QQuickImageResponse *requestImageResponse(const QString &id, const QSize &requestedSize) override;
|
||||
|
||||
private:
|
||||
NeoChatConnection *m_connection = nullptr;
|
||||
QPointer<NeoChatConnection> m_connection;
|
||||
MatrixImageProvider() = default;
|
||||
};
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
#include <Quotient/events/eventcontent.h>
|
||||
#include <qcoro/qcorosignal.h>
|
||||
|
||||
#include "neochatconnection.h"
|
||||
|
||||
using namespace Quotient;
|
||||
|
||||
AccountEmoticonModel::AccountEmoticonModel(QObject *parent)
|
||||
@@ -77,12 +79,12 @@ QHash<int, QByteArray> AccountEmoticonModel::roleNames() const
|
||||
};
|
||||
}
|
||||
|
||||
Connection *AccountEmoticonModel::connection() const
|
||||
NeoChatConnection *AccountEmoticonModel::connection() const
|
||||
{
|
||||
return m_connection;
|
||||
}
|
||||
|
||||
void AccountEmoticonModel::setConnection(Connection *connection)
|
||||
void AccountEmoticonModel::setConnection(NeoChatConnection *connection)
|
||||
{
|
||||
if (m_connection) {
|
||||
disconnect(m_connection, nullptr, this, nullptr);
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include <QPointer>
|
||||
#include <QQmlEngine>
|
||||
|
||||
#include <Quotient/connection.h>
|
||||
class NeoChatConnection;
|
||||
|
||||
/**
|
||||
* @class AccountEmoticonModel
|
||||
@@ -29,7 +29,7 @@ class AccountEmoticonModel : public QAbstractListModel
|
||||
/**
|
||||
* @brief The connection to get emoticons from.
|
||||
*/
|
||||
Q_PROPERTY(Quotient::Connection *connection READ connection WRITE setConnection NOTIFY connectionChanged)
|
||||
Q_PROPERTY(NeoChatConnection *connection READ connection WRITE setConnection NOTIFY connectionChanged)
|
||||
|
||||
public:
|
||||
enum Roles {
|
||||
@@ -63,8 +63,8 @@ public:
|
||||
*/
|
||||
[[nodiscard]] QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
[[nodiscard]] Quotient::Connection *connection() const;
|
||||
void setConnection(Quotient::Connection *connection);
|
||||
[[nodiscard]] NeoChatConnection *connection() const;
|
||||
void setConnection(NeoChatConnection *connection);
|
||||
|
||||
/**
|
||||
* @brief Deletes the emoticon at the given index.
|
||||
@@ -96,7 +96,7 @@ Q_SIGNALS:
|
||||
|
||||
private:
|
||||
std::optional<Quotient::ImagePackEventContent> m_images;
|
||||
QPointer<Quotient::Connection> m_connection;
|
||||
QPointer<NeoChatConnection> m_connection;
|
||||
QCoro::Task<void> doSetEmoticonImage(int index, QUrl source);
|
||||
QCoro::Task<void> doAddEmoticon(QUrl source, QString shortcode, QString description, QString type);
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "actionsmodel.h"
|
||||
|
||||
#include "chatbarcache.h"
|
||||
#include "neochatconnection.h"
|
||||
#include "neochatroom.h"
|
||||
#include "roommanager.h"
|
||||
#include <Quotient/events/roommemberevent.h>
|
||||
@@ -260,7 +261,7 @@ QList<ActionsModel::Action> actions{
|
||||
return QString();
|
||||
}
|
||||
Q_EMIT room->showMessage(NeoChatRoom::Info, i18nc("Knocking room <roomname>.", "Knocking room %1.", text));
|
||||
auto connection = room->connection();
|
||||
auto connection = dynamic_cast<NeoChatConnection *>(room->connection());
|
||||
const auto knownServer = roomName.mid(roomName.indexOf(":"_ls) + 1);
|
||||
if (parts.length() >= 2) {
|
||||
RoomManager::instance().knockRoom(connection, roomName, parts[1], QStringList{knownServer});
|
||||
|
||||
@@ -110,7 +110,7 @@ Q_SIGNALS:
|
||||
private:
|
||||
explicit CustomEmojiModel(QObject *parent = nullptr);
|
||||
QList<CustomEmoji> m_emojis;
|
||||
NeoChatConnection *m_connection = nullptr;
|
||||
QPointer<NeoChatConnection> m_connection;
|
||||
|
||||
void fetchEmojis();
|
||||
};
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
|
||||
#include "customemojimodel.h"
|
||||
#include <QRegularExpression>
|
||||
#include <connection.h>
|
||||
|
||||
class NeoChatConnection;
|
||||
|
||||
struct CustomEmoji {
|
||||
QString name; // with :semicolons:
|
||||
@@ -14,6 +15,6 @@ struct CustomEmoji {
|
||||
};
|
||||
|
||||
struct CustomEmojiModel::Private {
|
||||
Quotient::Connection *conn = nullptr;
|
||||
QPointer<NeoChatConnection> connection;
|
||||
QList<CustomEmoji> emojies;
|
||||
};
|
||||
|
||||
@@ -11,9 +11,10 @@
|
||||
#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)
|
||||
@@ -152,12 +153,12 @@ void DevicesModel::setName(const QString &deviceId, const QString &name)
|
||||
});
|
||||
}
|
||||
|
||||
Connection *DevicesModel::connection() const
|
||||
NeoChatConnection *DevicesModel::connection() const
|
||||
{
|
||||
return m_connection;
|
||||
}
|
||||
|
||||
void DevicesModel::setConnection(Connection *connection)
|
||||
void DevicesModel::setConnection(NeoChatConnection *connection)
|
||||
{
|
||||
if (m_connection) {
|
||||
disconnect(m_connection, nullptr, this, nullptr);
|
||||
|
||||
@@ -9,10 +9,7 @@
|
||||
|
||||
#include <Quotient/csapi/definitions/client_device.h>
|
||||
|
||||
namespace Quotient
|
||||
{
|
||||
class Connection;
|
||||
}
|
||||
class NeoChatConnection;
|
||||
|
||||
/**
|
||||
* @class DevicesModel
|
||||
@@ -31,7 +28,7 @@ class DevicesModel : public QAbstractListModel
|
||||
/**
|
||||
* @brief The current connection that the model is getting its devices from.
|
||||
*/
|
||||
Q_PROPERTY(Quotient::Connection *connection READ connection WRITE setConnection NOTIFY connectionChanged REQUIRED)
|
||||
Q_PROPERTY(NeoChatConnection *connection READ connection WRITE setConnection NOTIFY connectionChanged REQUIRED)
|
||||
|
||||
public:
|
||||
/**
|
||||
@@ -88,9 +85,8 @@ public:
|
||||
|
||||
explicit DevicesModel(QObject *parent = nullptr);
|
||||
|
||||
|
||||
[[nodiscard]] Quotient::Connection *connection() const;
|
||||
void setConnection(Quotient::Connection *connection);
|
||||
[[nodiscard]] NeoChatConnection *connection() const;
|
||||
void setConnection(NeoChatConnection *connection);
|
||||
|
||||
Q_SIGNALS:
|
||||
void connectionChanged();
|
||||
@@ -99,5 +95,5 @@ Q_SIGNALS:
|
||||
private:
|
||||
void fetchDevices();
|
||||
QList<Quotient::Device> m_devices;
|
||||
QPointer<Quotient::Connection> m_connection;
|
||||
QPointer<NeoChatConnection> m_connection;
|
||||
};
|
||||
|
||||
@@ -246,70 +246,86 @@ 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(), {}};
|
||||
} else {
|
||||
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(), {}};
|
||||
}
|
||||
}
|
||||
endResetModel();
|
||||
return;
|
||||
}
|
||||
|
||||
if (isEditing) {
|
||||
m_components += MessageComponent{MessageComponentType::Edit, QString(), {}};
|
||||
} else if (m_event->isRedacted()) {
|
||||
m_components += MessageComponent{MessageComponentType::Text, QString(), {}};
|
||||
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 {
|
||||
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(), {}};
|
||||
}
|
||||
m_components += MessageComponent{MessageComponentType::Reply, QString(), {}};
|
||||
}
|
||||
}
|
||||
|
||||
if (m_linkPreviewer != nullptr) {
|
||||
if (m_linkPreviewer->loaded()) {
|
||||
m_components += MessageComponent{MessageComponentType::LinkPreview, QString(), {}};
|
||||
} else {
|
||||
m_components += MessageComponent{MessageComponentType::LinkPreviewLoad, QString(), {}};
|
||||
}
|
||||
if (isEditing) {
|
||||
m_components += MessageComponent{MessageComponentType::Edit, QString(), {}};
|
||||
} else {
|
||||
m_components.append(componentsForType(eventHandler.messageComponentType()));
|
||||
}
|
||||
|
||||
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,6 +98,8 @@ private:
|
||||
QPointer<LinkPreviewer> m_linkPreviewer;
|
||||
ItineraryModel *m_itineraryModel = nullptr;
|
||||
|
||||
QList<MessageComponent> componentsForType(MessageComponentType::Type type);
|
||||
|
||||
void updateLinkPreviewer();
|
||||
void updateItineraryModel();
|
||||
bool m_emptyItinerary = false;
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
|
||||
#include "neochatconfig.h"
|
||||
|
||||
#include <Quotient/connection.h>
|
||||
#include <Quotient/csapi/rooms.h>
|
||||
#include <Quotient/events/redactionevent.h>
|
||||
#include <Quotient/events/roommessageevent.h>
|
||||
@@ -117,34 +116,6 @@ 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()));
|
||||
|
||||
@@ -140,5 +140,4 @@ private:
|
||||
|
||||
Q_SIGNALS:
|
||||
void roomChanged();
|
||||
void fancyEffectsReasonFound(const QString &fancyEffect);
|
||||
};
|
||||
|
||||
@@ -36,6 +36,14 @@ 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);
|
||||
|
||||
@@ -59,9 +67,8 @@ bool MessageFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sour
|
||||
// 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;
|
||||
@@ -72,7 +79,11 @@ bool MessageFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sour
|
||||
|
||||
QVariant MessageFilterModel::data(const QModelIndex &index, int role) const
|
||||
{
|
||||
if (role == AggregateDisplayRole) {
|
||||
if (role == MessageEventModel::DelegateTypeRole && NeoChatConfig::self()->showAllEvents()) {
|
||||
if (!eventIsVisible(index.row(), index.parent())) {
|
||||
return DelegateType::Other;
|
||||
}
|
||||
} else if (role == AggregateDisplayRole) {
|
||||
return aggregateEventToString(mapToSource(index).row());
|
||||
} else if (role == StateEventsRole) {
|
||||
return stateEventsList(mapToSource(index).row());
|
||||
|
||||
@@ -60,6 +60,8 @@ 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,7 +3,6 @@
|
||||
|
||||
#include "notificationsmodel.h"
|
||||
|
||||
#include <Quotient/connection.h>
|
||||
#include <Quotient/events/event.h>
|
||||
#include <Quotient/uri.h>
|
||||
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
|
||||
#include "publicroomlistmodel.h"
|
||||
|
||||
#include <Quotient/connection.h>
|
||||
|
||||
#include "neochatconnection.h"
|
||||
#include "publicroomlist_logging.h"
|
||||
|
||||
using namespace Quotient;
|
||||
@@ -14,14 +13,14 @@ PublicRoomListModel::PublicRoomListModel(QObject *parent)
|
||||
{
|
||||
}
|
||||
|
||||
Quotient::Connection *PublicRoomListModel::connection() const
|
||||
NeoChatConnection *PublicRoomListModel::connection() const
|
||||
{
|
||||
return m_connection;
|
||||
}
|
||||
|
||||
void PublicRoomListModel::setConnection(Connection *conn)
|
||||
void PublicRoomListModel::setConnection(NeoChatConnection *connection)
|
||||
{
|
||||
if (m_connection == conn) {
|
||||
if (m_connection == connection) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -38,7 +37,7 @@ void PublicRoomListModel::setConnection(Connection *conn)
|
||||
|
||||
endResetModel();
|
||||
|
||||
m_connection = conn;
|
||||
m_connection = connection;
|
||||
|
||||
if (job) {
|
||||
job->abandon();
|
||||
|
||||
@@ -9,10 +9,7 @@
|
||||
|
||||
#include <Quotient/csapi/list_public_rooms.h>
|
||||
|
||||
namespace Quotient
|
||||
{
|
||||
class Connection;
|
||||
}
|
||||
class NeoChatConnection;
|
||||
|
||||
/**
|
||||
* @class PublicRoomListModel
|
||||
@@ -33,7 +30,7 @@ class PublicRoomListModel : public QAbstractListModel
|
||||
/**
|
||||
* @brief The current connection that the model is getting its rooms from.
|
||||
*/
|
||||
Q_PROPERTY(Quotient::Connection *connection READ connection WRITE setConnection NOTIFY connectionChanged)
|
||||
Q_PROPERTY(NeoChatConnection *connection READ connection WRITE setConnection NOTIFY connectionChanged)
|
||||
|
||||
/**
|
||||
* @brief The server to get the public room list from.
|
||||
@@ -95,8 +92,8 @@ public:
|
||||
*/
|
||||
[[nodiscard]] QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
[[nodiscard]] Quotient::Connection *connection() const;
|
||||
void setConnection(Quotient::Connection *conn);
|
||||
[[nodiscard]] NeoChatConnection *connection() const;
|
||||
void setConnection(NeoChatConnection *connection);
|
||||
|
||||
[[nodiscard]] QString server() const;
|
||||
void setServer(const QString &value);
|
||||
@@ -117,7 +114,7 @@ public:
|
||||
Q_INVOKABLE void search(int limit = 50);
|
||||
|
||||
private:
|
||||
QPointer<Quotient::Connection> m_connection = nullptr;
|
||||
QPointer<NeoChatConnection> 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, &Quotient::Connection::accountDataChanged, this, &PushRuleModel::updateNotificationRules);
|
||||
connect(m_connection, &NeoChatConnection::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;
|
||||
NeoChatConnection *m_connection;
|
||||
QPointer<NeoChatConnection> m_connection;
|
||||
|
||||
void setRules(QList<Quotient::PushRule> rules, PushRuleKind::Kind kind);
|
||||
|
||||
|
||||
@@ -68,7 +68,8 @@ QVariant ReactionModel::data(const QModelIndex &index, int role) const
|
||||
text += i18nc("Separate the usernames of users", " and ");
|
||||
}
|
||||
}
|
||||
text += reaction.authors.at(i).toMap()[QStringLiteral("displayName")].toString();
|
||||
auto displayName = 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) {
|
||||
|
||||
@@ -25,12 +25,12 @@ RoomListModel::RoomListModel(QObject *parent)
|
||||
|
||||
RoomListModel::~RoomListModel() = default;
|
||||
|
||||
Quotient::Connection *RoomListModel::connection() const
|
||||
NeoChatConnection *RoomListModel::connection() const
|
||||
{
|
||||
return m_connection;
|
||||
}
|
||||
|
||||
void RoomListModel::setConnection(Connection *connection)
|
||||
void RoomListModel::setConnection(NeoChatConnection *connection)
|
||||
{
|
||||
if (connection == m_connection) {
|
||||
return;
|
||||
|
||||
@@ -12,10 +12,11 @@ class NeoChatRoom;
|
||||
|
||||
namespace Quotient
|
||||
{
|
||||
class Connection;
|
||||
class Room;
|
||||
}
|
||||
|
||||
class NeoChatConnection;
|
||||
|
||||
/**
|
||||
* @class RoomListModel
|
||||
*
|
||||
@@ -29,7 +30,7 @@ class RoomListModel : public QAbstractListModel
|
||||
/**
|
||||
* @brief The current connection that the model is getting its rooms from.
|
||||
*/
|
||||
Q_PROPERTY(Quotient::Connection *connection READ connection WRITE setConnection NOTIFY connectionChanged)
|
||||
Q_PROPERTY(NeoChatConnection *connection READ connection WRITE setConnection NOTIFY connectionChanged)
|
||||
|
||||
public:
|
||||
/**
|
||||
@@ -60,8 +61,8 @@ public:
|
||||
explicit RoomListModel(QObject *parent = nullptr);
|
||||
~RoomListModel() override;
|
||||
|
||||
[[nodiscard]] Quotient::Connection *connection() const;
|
||||
void setConnection(Quotient::Connection *connection);
|
||||
[[nodiscard]] NeoChatConnection *connection() const;
|
||||
void setConnection(NeoChatConnection *connection);
|
||||
|
||||
/**
|
||||
* @brief Get the given role value at the given index.
|
||||
@@ -109,7 +110,7 @@ private Q_SLOTS:
|
||||
void refresh(NeoChatRoom *room, const QList<int> &roles = {});
|
||||
|
||||
private:
|
||||
Quotient::Connection *m_connection = nullptr;
|
||||
QPointer<NeoChatConnection> m_connection;
|
||||
QList<NeoChatRoom *> m_rooms;
|
||||
|
||||
QString m_activeSpaceId;
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
#include "roomtreemodel.h"
|
||||
|
||||
#include <Quotient/connection.h>
|
||||
#include <Quotient/room.h>
|
||||
|
||||
#include "eventhandler.h"
|
||||
@@ -300,9 +299,6 @@ 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,7 +10,6 @@
|
||||
|
||||
#include <QGuiApplication>
|
||||
|
||||
#include <Quotient/connection.h>
|
||||
#include <Quotient/events/stickerevent.h>
|
||||
|
||||
#include <KLocalizedString>
|
||||
|
||||
@@ -3,8 +3,6 @@
|
||||
|
||||
#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;
|
||||
NeoChatConnection *m_connection = nullptr;
|
||||
QPointer<NeoChatConnection> m_connection;
|
||||
|
||||
void initialize();
|
||||
};
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
#include "roomlistmodel.h"
|
||||
|
||||
#include "neochatconnection.h"
|
||||
|
||||
SortFilterRoomListModel::SortFilterRoomListModel(RoomListModel *sourceModel, QObject *parent)
|
||||
: QSortFilterProxyModel(parent)
|
||||
{
|
||||
|
||||
@@ -129,10 +129,6 @@ 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;
|
||||
@@ -205,4 +201,14 @@ 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,6 +76,8 @@ 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,7 +3,6 @@
|
||||
|
||||
#include "spacechildrenmodel.h"
|
||||
|
||||
#include <Quotient/connection.h>
|
||||
#include <Quotient/jobs/basejob.h>
|
||||
#include <Quotient/room.h>
|
||||
|
||||
@@ -47,7 +46,7 @@ void SpaceChildrenModel::setSpace(NeoChatRoom *space)
|
||||
}
|
||||
|
||||
auto connection = m_space->connection();
|
||||
connect(connection, &Quotient::Connection::loadedRoomState, this, [this](Quotient::Room *room) {
|
||||
connect(connection, &NeoChatConnection::loadedRoomState, this, [this](Quotient::Room *room) {
|
||||
if (m_pendingChildren.contains(room->name())) {
|
||||
m_pendingChildren.removeAll(room->name());
|
||||
refreshModel();
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
// 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>
|
||||
|
||||
@@ -149,7 +151,7 @@ public:
|
||||
bool isSuggested() const;
|
||||
|
||||
private:
|
||||
NeoChatConnection *m_connection;
|
||||
QPointer<NeoChatConnection> m_connection;
|
||||
std::vector<std::unique_ptr<SpaceTreeItem>> m_children;
|
||||
SpaceTreeItem *m_parentItem;
|
||||
|
||||
|
||||
@@ -3,9 +3,10 @@
|
||||
|
||||
#include "userdirectorylistmodel.h"
|
||||
|
||||
#include <Quotient/connection.h>
|
||||
#include <Quotient/room.h>
|
||||
|
||||
#include "neochatconnection.h"
|
||||
|
||||
using namespace Quotient;
|
||||
|
||||
UserDirectoryListModel::UserDirectoryListModel(QObject *parent)
|
||||
@@ -13,14 +14,14 @@ UserDirectoryListModel::UserDirectoryListModel(QObject *parent)
|
||||
{
|
||||
}
|
||||
|
||||
Quotient::Connection *UserDirectoryListModel::connection() const
|
||||
NeoChatConnection *UserDirectoryListModel::connection() const
|
||||
{
|
||||
return m_connection;
|
||||
}
|
||||
|
||||
void UserDirectoryListModel::setConnection(Connection *conn)
|
||||
void UserDirectoryListModel::setConnection(NeoChatConnection *connection)
|
||||
{
|
||||
if (m_connection == conn) {
|
||||
if (m_connection == connection) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -35,7 +36,7 @@ void UserDirectoryListModel::setConnection(Connection *conn)
|
||||
|
||||
endResetModel();
|
||||
|
||||
m_connection = conn;
|
||||
m_connection = connection;
|
||||
Q_EMIT connectionChanged();
|
||||
|
||||
if (m_job) {
|
||||
|
||||
@@ -9,10 +9,7 @@
|
||||
|
||||
#include <Quotient/csapi/users.h>
|
||||
|
||||
namespace Quotient
|
||||
{
|
||||
class Connection;
|
||||
}
|
||||
class NeoChatConnection;
|
||||
|
||||
/**
|
||||
* @class UserDirectoryListModel
|
||||
@@ -32,7 +29,7 @@ class UserDirectoryListModel : public QAbstractListModel
|
||||
/**
|
||||
* @brief The current connection that the model is getting users from.
|
||||
*/
|
||||
Q_PROPERTY(Quotient::Connection *connection READ connection WRITE setConnection NOTIFY connectionChanged)
|
||||
Q_PROPERTY(NeoChatConnection *connection READ connection WRITE setConnection NOTIFY connectionChanged)
|
||||
|
||||
/**
|
||||
* @brief The text to search the public room list for.
|
||||
@@ -57,8 +54,8 @@ public:
|
||||
|
||||
explicit UserDirectoryListModel(QObject *parent = nullptr);
|
||||
|
||||
[[nodiscard]] Quotient::Connection *connection() const;
|
||||
void setConnection(Quotient::Connection *conn);
|
||||
[[nodiscard]] NeoChatConnection *connection() const;
|
||||
void setConnection(NeoChatConnection *connection);
|
||||
|
||||
[[nodiscard]] QString searchText() const;
|
||||
void setSearchText(const QString &searchText);
|
||||
@@ -99,7 +96,7 @@ Q_SIGNALS:
|
||||
void searchingChanged();
|
||||
|
||||
private:
|
||||
Quotient::Connection *m_connection = nullptr;
|
||||
QPointer<NeoChatConnection> m_connection;
|
||||
QString m_searchText;
|
||||
|
||||
bool attempted = false;
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
|
||||
#include <QGuiApplication>
|
||||
|
||||
#include <Quotient/connection.h>
|
||||
#include <Quotient/events/roompowerlevelsevent.h>
|
||||
|
||||
#include "neochatroom.h"
|
||||
|
||||
@@ -254,7 +254,7 @@ Action=Popup
|
||||
[Event/Share]
|
||||
Name=Share
|
||||
Name[ca]=Compartició
|
||||
Name[ca@valencia]=Compartició
|
||||
Name[ca@valencia]=Compartiu
|
||||
Name[cs]=Sdílet
|
||||
Name[eo]=Kundividi
|
||||
Name[es]=Compartir
|
||||
|
||||
@@ -100,10 +100,6 @@
|
||||
<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>
|
||||
@@ -161,10 +157,18 @@
|
||||
</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">
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
"Name[es]": "Tobias Fella",
|
||||
"Name[eu]": "Tobias Fella",
|
||||
"Name[fr]": "Tobias Fella",
|
||||
"Name[gl]": "Tobias Fella",
|
||||
"Name[hu]": "Tobias Fella",
|
||||
"Name[ia]": "Tobias Fella",
|
||||
"Name[it]": "Tobias Fella",
|
||||
@@ -18,6 +19,7 @@
|
||||
"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",
|
||||
@@ -32,6 +34,7 @@
|
||||
"Description[es]": "Compartir mediante NeoChat",
|
||||
"Description[eu]": "Partekatu NeoChat bidez",
|
||||
"Description[fr]": "Partager grâce à NeoChat",
|
||||
"Description[gl]": "Compartir por NeoChat",
|
||||
"Description[hu]": "Megosztás NeoChatben",
|
||||
"Description[ia]": "Comparti via NeoChat",
|
||||
"Description[it]": "Condividi tramite NeoChat",
|
||||
@@ -40,6 +43,7 @@
|
||||
"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",
|
||||
@@ -55,6 +59,7 @@
|
||||
"Name[es]": "NeoChat",
|
||||
"Name[eu]": "NeoChat",
|
||||
"Name[fr]": "NeoChat",
|
||||
"Name[gl]": "NeoChat",
|
||||
"Name[hu]": "NeoChat",
|
||||
"Name[ia]": "Neochat",
|
||||
"Name[it]": "NeoChat",
|
||||
@@ -63,6 +68,7 @@
|
||||
"Name[nl]": "NeoChat",
|
||||
"Name[pl]": "NeoChat",
|
||||
"Name[sl]": "NeoChat",
|
||||
"Name[ta]": "நியோச்சாட்",
|
||||
"Name[tr]": "NeoChat",
|
||||
"Name[uk]": "NeoChat",
|
||||
"Name[x-test]": "xxNeoChatxx",
|
||||
|
||||
@@ -46,7 +46,7 @@ ColumnLayout {
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
let imageEditor = applicationWindow().pageStack.layers.push(imageEditorPage);
|
||||
let imageEditor = applicationWindow().pageStack.pushDialogLayer(imageEditorPage);
|
||||
imageEditor.newPathChanged.connect(function (newPath) {
|
||||
applicationWindow().pageStack.layers.pop();
|
||||
root.attachmentPath = newPath;
|
||||
|
||||
@@ -278,6 +278,8 @@ 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.smallSpacing
|
||||
radius: Kirigami.Units.cornerRadius
|
||||
|
||||
Rectangle {
|
||||
radius: Kirigami.Units.smallSpacing
|
||||
radius: Kirigami.Units.cornerRadius
|
||||
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.mediumSpacing
|
||||
radius: Kirigami.Units.cornerRadius
|
||||
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.mediumSpacing
|
||||
radius: Kirigami.Units.cornerRadius
|
||||
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
|
||||
|
||||
property alias roomSearchFieldFocussed: roomSearchField.activeFocus
|
||||
signal search
|
||||
|
||||
property Kirigami.Action exploreAction: Kirigami.Action {
|
||||
text: i18n("Explore rooms")
|
||||
@@ -83,15 +83,30 @@ RowLayout {
|
||||
*/
|
||||
signal textChanged(string newText)
|
||||
|
||||
Kirigami.SearchField {
|
||||
id: roomSearchField
|
||||
Layout.topMargin: Kirigami.Units.smallSpacing
|
||||
Layout.bottomMargin: Kirigami.Units.smallSpacing
|
||||
Item {
|
||||
Layout.preferredWidth: Kirigami.Units.largeSpacing
|
||||
}
|
||||
|
||||
Kirigami.Heading {
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredWidth: root.desiredWidth ? root.desiredWidth - menuButton.width - root.spacing : -1
|
||||
visible: !root.collapsed
|
||||
onTextChanged: root.textChanged(text)
|
||||
KeyNavigation.tab: treeView
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
QQC2.ToolButton {
|
||||
@@ -100,8 +115,8 @@ RowLayout {
|
||||
display: QQC2.AbstractButton.IconOnly
|
||||
checkable: true
|
||||
action: Kirigami.Action {
|
||||
text: i18n("Create rooms and chats")
|
||||
icon.name: "irc-join-channel"
|
||||
text: i18nc("@action:button", "Show Menu")
|
||||
icon.name: "application-menu-symbolic"
|
||||
onTriggered: {
|
||||
if (Kirigami.isMobile) {
|
||||
const menu = mobileMenu.createObject();
|
||||
|
||||
@@ -1,304 +0,0 @@
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,8 @@ Kirigami.ApplicationWindow {
|
||||
|
||||
property NeoChatConnection connection: Controller.activeConnection
|
||||
|
||||
title: Config.windowTitleFocus ? activeFocusItem + " " + (activeFocusItem ? activeFocusItem.Accessible.name : "") : "NeoChat"
|
||||
|
||||
minimumWidth: Kirigami.Units.gridUnit * 20
|
||||
minimumHeight: Kirigami.Units.gridUnit * 15
|
||||
|
||||
@@ -96,12 +98,9 @@ Kirigami.ApplicationWindow {
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: quickView
|
||||
active: !Kirigami.Settings.isMobile
|
||||
sourceComponent: QuickSwitcher {
|
||||
connection: root.connection
|
||||
}
|
||||
QuickSwitcher {
|
||||
id: quickSwitcher
|
||||
connection: root.connection
|
||||
}
|
||||
|
||||
Connections {
|
||||
@@ -160,8 +159,11 @@ Kirigami.ApplicationWindow {
|
||||
|
||||
connection: root.connection
|
||||
|
||||
handleOpenIcon.source: "arrow-right"
|
||||
handleClosedIcon.source: "arrow-left"
|
||||
handleClosedIcon.source: "documentinfo-symbolic"
|
||||
handleClosedToolTip: i18nc("@action:button", "Show Room Information")
|
||||
|
||||
// Default icon is fine, only need to override the tooltip text
|
||||
handleOpenToolTip: i18nc("@action:button", "Close Room Information Drawer")
|
||||
|
||||
// Connect to the onClicked function of the RoomDrawer handle button
|
||||
Connections {
|
||||
@@ -221,6 +223,8 @@ Kirigami.ApplicationWindow {
|
||||
RoomListPage {
|
||||
id: roomList
|
||||
|
||||
onSearch: quickSwitcher.open()
|
||||
|
||||
connection: root.connection
|
||||
|
||||
Shortcut {
|
||||
@@ -258,7 +262,7 @@ Kirigami.ApplicationWindow {
|
||||
function onRowsRemoved() {
|
||||
if (AccountRegistry.rowCount() === 0) {
|
||||
pageStack.clear();
|
||||
pageStack.push(Qt.createComponent('org.kde.neochat', 'WelcomePage'));
|
||||
pageStack.push(Qt.createComponent('org.kde.neochat.login', 'WelcomePage'));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import QtQuick.Controls as QQC2
|
||||
import QtQuick.Layouts
|
||||
|
||||
import org.kde.kirigami as Kirigami
|
||||
import org.kde.kirigamiaddons.components
|
||||
import org.kde.kitemmodels
|
||||
|
||||
import org.kde.neochat
|
||||
@@ -19,10 +20,10 @@ QQC2.Dialog {
|
||||
width: Math.min(700, parent.width)
|
||||
height: 400
|
||||
|
||||
leftPadding: 0
|
||||
rightPadding: 0
|
||||
bottomPadding: 1
|
||||
topPadding: 0
|
||||
leftPadding: Kirigami.Units.smallSpacing
|
||||
rightPadding: Kirigami.Units.smallSpacing
|
||||
bottomPadding: Kirigami.Units.smallSpacing
|
||||
topPadding: Kirigami.Units.smallSpacing
|
||||
|
||||
anchors.centerIn: applicationWindow().overlay
|
||||
|
||||
@@ -40,53 +41,60 @@ QQC2.Dialog {
|
||||
roomList.currentIndex = 0;
|
||||
}
|
||||
|
||||
header: Kirigami.SearchField {
|
||||
id: searchField
|
||||
Keys.onDownPressed: {
|
||||
roomList.forceActiveFocus();
|
||||
if (roomList.currentIndex < roomList.count - 1) {
|
||||
roomList.currentIndex++;
|
||||
} else {
|
||||
roomList.currentIndex = 0;
|
||||
background: DialogRoundedBackground {}
|
||||
|
||||
contentItem: ColumnLayout {
|
||||
Kirigami.SearchField {
|
||||
id: searchField
|
||||
Layout.fillWidth: true
|
||||
Keys.onDownPressed: {
|
||||
roomList.forceActiveFocus();
|
||||
if (roomList.currentIndex < roomList.count - 1) {
|
||||
roomList.currentIndex++;
|
||||
} else {
|
||||
roomList.currentIndex = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
Keys.onUpPressed: {
|
||||
if (roomList.currentIndex === 0) {
|
||||
roomList.currentIndex = roomList.count - 1;
|
||||
} else {
|
||||
roomList.currentIndex--;
|
||||
Keys.onUpPressed: {
|
||||
if (roomList.currentIndex === 0) {
|
||||
roomList.currentIndex = roomList.count - 1;
|
||||
} else {
|
||||
roomList.currentIndex--;
|
||||
}
|
||||
}
|
||||
Keys.onEnterPressed: {
|
||||
RoomManager.resolveResource(roomList.currentItem.currentRoom.id);
|
||||
root.close();
|
||||
}
|
||||
Keys.onReturnPressed: {
|
||||
RoomManager.resolveResource(roomList.currentItem.currentRoom.id);
|
||||
root.close();
|
||||
}
|
||||
focusSequence: ""
|
||||
onTextChanged: RoomManager.sortFilterRoomListModel.filterText = text
|
||||
}
|
||||
Keys.onEnterPressed: {
|
||||
RoomManager.resolveResource(roomList.currentItem.currentRoom.id);
|
||||
root.close();
|
||||
}
|
||||
Keys.onReturnPressed: {
|
||||
RoomManager.resolveResource(roomList.currentItem.currentRoom.id);
|
||||
root.close();
|
||||
}
|
||||
focusSequence: ""
|
||||
onTextChanged: RoomManager.sortFilterRoomListModel.filterText = text
|
||||
}
|
||||
|
||||
QQC2.ScrollView {
|
||||
anchors.fill: parent
|
||||
clip: true
|
||||
QQC2.ScrollView {
|
||||
clip: true
|
||||
|
||||
Keys.forwardTo: searchField
|
||||
|
||||
ListView {
|
||||
id: roomList
|
||||
|
||||
currentIndex: 0
|
||||
highlightMoveDuration: 200
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
Keys.forwardTo: searchField
|
||||
keyNavigationEnabled: true
|
||||
model: RoomManager.sortFilterRoomListModel
|
||||
|
||||
delegate: RoomDelegate {
|
||||
connection: root.connection
|
||||
onClicked: root.close()
|
||||
ListView {
|
||||
id: roomList
|
||||
|
||||
currentIndex: 0
|
||||
highlightMoveDuration: 200
|
||||
Keys.forwardTo: searchField
|
||||
keyNavigationEnabled: true
|
||||
model: RoomManager.sortFilterRoomListModel
|
||||
|
||||
delegate: RoomDelegate {
|
||||
connection: root.connection
|
||||
onClicked: root.close()
|
||||
showConfigure: false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user