Compare commits

..

5 Commits

Author SHA1 Message Date
Ingo Klöcker
238e31fe23 Add "16:9 Super hero art" for Microsoft Store
For details, where this image is used, see
https://learn.microsoft.com/en-us/windows/apps/publish/publish-your-app/screenshots-and-images?pivots=store-installer-msix#windows-10-and-xbox-image-169-super-hero-art
2023-06-26 15:38:12 +02:00
Ingo Klöcker
99aeba2882 Add some logos in different sizes for the Microsoft Store
For details, where those images are used see
https://learn.microsoft.com/en-us/windows/apps/publish/publish-your-app/screenshots-and-images?pivots=store-installer-msix#store-logos
2023-06-26 15:36:35 +02:00
Ingo Klöcker
a65724ebc7 Add features as custom values
Microsoft Store allows adding a list of up-to 20 features to an app
submission. It's not clear whether this adds value over the common
practice for KDE apps to add a list of features to the description.
If the search in Microsoft Store would rank matching features higher
than a full-text match in the description, then it might make sense.

The problem is that this would duplicate the list of features in
Microsoft Store because removing the list of features from the description
would remove the features from the app listing in Linux app stores.
Therefore, we should probably stick to the established practice and leave
the list of features in Microsoft Store empty.

See also https://github.com/ximion/appstream/issues/388
2023-06-26 15:31:06 +02:00
Ingo Klöcker
d5ab724edb Add Windows-specific screenshots as custom values
This is clearly a hack. It would be preferable to add those directly
to the existing list of screenshots with some property marking them as
screenshots of the Windows version for the Microsoft Store
(https://github.com/ximion/appstream/issues/390). The IDs are derived
from the IDs used by the CSV export of an app submission in Microsoft
Partner Center.
2023-06-26 15:19:16 +02:00
Ingo Klöcker
67ff7e0842 Add a few keywords for easier finding in stores
This is supported by AppStream
https://www.freedesktop.org/software/appstream/docs/chap-Metadata.html#tag-keywords
and can be used in the Microsoft Store.
2023-06-26 15:12:24 +02:00
179 changed files with 18790 additions and 17360 deletions

3
.gitignore vendored
View File

@@ -1,4 +1,4 @@
build*
build
.clang-format
.DS_Store
.kdev4/
@@ -11,4 +11,3 @@ kate.project.ctags.*
.flatpak-builder/
.idea/
cmake-build-*
src/res.generated.qrc

View File

@@ -5,10 +5,10 @@ include:
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/reuse-lint.yml
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/android.yml
# - https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/android-qt6.yml
# - https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/linux.yml
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/linux.yml
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/linux-qt6.yml
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/windows.yml
# - https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/windows-qt6.yml
# - https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/freebsd.yml
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/freebsd.yml
# - https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/freebsd-qt6.yml
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/flatpak.yml

View File

@@ -17,7 +17,7 @@ project(NeoChat VERSION ${RELEASE_SERVICE_VERSION})
set(KF_MIN_VERSION "5.105.0")
set(QT_MIN_VERSION "5.15.2")
if (ANDROID)
set(QT_MIN_VERSION "5.15.10")
set(QT_MIN_VERSION "5.15.8")
endif()
find_package(ECM ${KF_MIN_VERSION} REQUIRED NO_MODULE)
@@ -48,19 +48,6 @@ if(NEOCHAT_FLATPAK)
include(cmake/Flatpak.cmake)
endif()
if(QT_MAJOR_VERSION STREQUAL "6")
set(BASICLISTITEM_BOLD "font.bold")
set(OVERLAYSHEET_OPEN "onOpened")
set(QTQUICK_MODULE_QML_VERSION "")
set(QTLOCATION_MODULE_QML_VERSION "")
else()
set(BASICLISTITEM_BOLD "bold")
set(OVERLAYSHEET_OPEN "onSheetOpenChanged")
set(QTQUICK_MODULE_QML_VERSION "2.15")
set(QTLOCATION_MODULE_QML_VERSION "5.15")
endif()
ecm_setup_version(${PROJECT_VERSION}
VARIABLE_PREFIX NEOCHAT
VERSION_HEADER ${CMAKE_CURRENT_BINARY_DIR}/neochat-version.h
@@ -111,7 +98,7 @@ if(QT_MAJOR_VERSION STREQUAL "6" AND NOT ANDROID AND NOT WIN32)
set(QUOTIENT_SUFFIX "Qt6")
endif()
find_package(Quotient${QUOTIENT_SUFFIX} 0.7)
find_package(Quotient${QUOTIENT_SUFFIX} 0.6)
set_package_properties(Quotient${QUOTIENT_SUFFIX} PROPERTIES
TYPE REQUIRED
DESCRIPTION "Qt wrapper around Matrix API"
@@ -191,9 +178,3 @@ file(GLOB_RECURSE ALL_SOURCE_FILES *.cpp *.h *.qml)
# Fixes the test by excluding this directory
list(FILTER ALL_SOURCE_FILES EXCLUDE REGEX [[_(install|build)/.*]])
ecm_check_outbound_license(LICENSES GPL-3.0-only FILES ${ALL_SOURCE_FILES})
ecm_qt_install_logging_categories(
EXPORT NEOCHAT
FILE neochat.categories
DESTINATION ${KDE_INSTALL_LOGGINGCATEGORIESDIR}
)

View File

@@ -47,7 +47,6 @@ android {
compileSdkVersion androidCompileSdkVersion.toInteger()
buildToolsVersion androidBuildToolsVersion
ndkVersion androidNdkVersion
sourceSets {
main {

View File

@@ -71,6 +71,7 @@ private Q_SLOTS:
void linkPreviewsReject();
};
#ifdef QUOTIENT_07
void TextHandlerTest::initTestCase()
{
connection = Connection::makeMockConnection(QStringLiteral("@bob:kde.org"));
@@ -203,6 +204,7 @@ void TextHandlerTest::initTestCase()
SyncRoomData roomData(QStringLiteral("@bob:kde.org"), JoinState::Join, json.object());
room->update(std::move(roomData));
}
#endif
void TextHandlerTest::allowedAttributes()
{
@@ -477,6 +479,7 @@ void TextHandlerTest::receiveRichtextIn()
QCOMPARE(testTextHandler.handleRecieveRichText(), testOutputString);
}
#ifdef QUOTIENT_07
void TextHandlerTest::receiveRichMxcUrl()
{
const QString testInputString = QStringLiteral(
@@ -494,6 +497,7 @@ void TextHandlerTest::receiveRichMxcUrl()
QCOMPARE(testTextHandler.handleRecieveRichText(Qt::RichText, room, room->messageEvents().at(0).get()), testOutputString);
}
#endif
/**
* For when your rich input string has a plain text url left in.

View File

@@ -18,7 +18,6 @@
<name xml:lang="de">NeoChat</name>
<name xml:lang="el">NeoChat</name>
<name xml:lang="en-GB">NeoChat</name>
<name xml:lang="eo">NeoChat</name>
<name xml:lang="es">NeoChat</name>
<name xml:lang="eu">NeoChat</name>
<name xml:lang="fi">NeoChat</name>
@@ -55,7 +54,6 @@
<summary xml:lang="de">Ein Programm für Matrix, das dezentrale Kommunikationsprotokoll</summary>
<summary xml:lang="el">Ένας πελάτης για το Matrix, το αποκεντρωμένο πρωτόκολλο επικοινωνίας</summary>
<summary xml:lang="en-GB">A client for matrix, the decentralised communication protocol</summary>
<summary xml:lang="eo">Kliento por matrix, la malcentra komunikprotokolo</summary>
<summary xml:lang="es">Un cliente para Matrix, el protocolo de comunicaciones descentralizado</summary>
<summary xml:lang="eu">Matrix, deszentralizatutako komunikazio protokolorako bezero bat</summary>
<summary xml:lang="fi">Asiakas Matrixille, hajautetulle viestintäyhteyskäytännölle</summary>
@@ -69,7 +67,7 @@
<summary xml:lang="ka">კლიენტი Matrix-სთვის, დეცენტრალიზებული კომუნიკაციის პროტოკოლისთვის</summary>
<summary xml:lang="ko">Matrix, 분산 대화 프로토콜 클라이언트</summary>
<summary xml:lang="nl">Een client voor matrix, het gedecentraliseerde communicatieprotocol</summary>
<summary xml:lang="nn">Ein klient for Matrix  protokollen for desentralisert kommunikasjon</summary>
<summary xml:lang="nn">Ein klient for Matrix, den desentraliserte lynmeldings­protokollen</summary>
<summary xml:lang="pa">ਮੈਟਰਿਕਸ, ਸਰਬ-ਸਾਂਝੇ ਸੰਚਾਰ ਪਰੋਟੋਕਾਲ, ਲਈ ਕਲਾਈਂਟ ਹੈ</summary>
<summary xml:lang="pl">Program do obsługi matriksa, rozproszonego protokołu porozumiewania się</summary>
<summary xml:lang="pt">Um cliente para o Matrix, o protocolo de comunicação descentralizado</summary>
@@ -90,7 +88,6 @@ to provide a convergent experience across multiple platforms.</p>
<p xml:lang="ca">El NeoChat és un client de Matrix, el protocol descentralitzat de comunicacions de missatgeria instantània. Permet enviar missatges de text, fitxers de vídeo i d'àudio a la família, col·legues i amics. Fa servir els Frameworks de KDE i, sobretot, el Kirigami per a proporcionar una experiència convergent a través de diverses plataformes.</p>
<p xml:lang="ca-valencia">NeoChat és un client de Matrix, el protocol descentralitzat de comunicacions de missatgeria instantània. Permet enviar missatges de text, fitxers de vídeo i d'àudio a la família, col·legues i amics. Utilitza els Frameworks de KDE i, sobretot, Kirigami per a proporcionar una experiència convergent a través de diverses plataformes.</p>
<p xml:lang="en-GB">NeoChat is a client for Matrix, the decentralised communication protocol for instant messaging. It allows you to send text messages, videos and audio files to your family, colleagues and friends. It uses KDE frameworks and most notably Kirigami to provide a convergent experience across multiple platforms.</p>
<p xml:lang="eo">NeoChat estas kliento por Matrix, la malcentra komunikoprotokolo por tuja mesaĝado. Ĝi ebligas al vi sendi tekstmesaĝojn, filmetojn kaj sondosierojn al via familio, kolegoj kaj amikoj. Ĝi uzas KDE-framojn kaj precipe Kirigami por disponigi konverĝan sperton tra pluraj platformoj.</p>
<p xml:lang="es">NeoChat es un cliente para Matrix, el protocolo de comunicaciones descentralizado para mensajería instantánea. Le permite enviar mensajes de texto, vídeos y archivos de sonido a su familia, compañeros de trabajo y amigos. Usa la infraestructura de KDE y, en particular, Kirigami para proporcionar una experiencia convergente en muchas plataformas.</p>
<p xml:lang="fi">NeoChat on asiakassovellus Matrixille, hajautetulle pikaviestinyhteyskäytännölle. Sillä voi lähettää teksti-, video- ja ääniviestejä perheelle, tutuille ja ystäville. Se käyttää KDE-kehystä ja erityisesti Kirigamia tuottaakseen mukautuvan monialustaisen käyttökokemuksen.</p>
<p xml:lang="fr">NeoChat est un client pour le protocole Matrix, un protocole décentralisé de communications pour messagerie instantané. Il vous permet d'envoyer des messages de texte, des vidéos et des fichiers audio à votre famille, vos collègues et vos amis. Il utilise les environnements de développement et plus précisément Kirigami pour fournir une expérience convergente sur plusieurs plate-formes. </p>
@@ -99,7 +96,6 @@ to provide a convergent experience across multiple platforms.</p>
<p xml:lang="it">NeoChat è un client per Matrix, il protocollo di comunicazione decentralizzato per la messaggistica istantanea. Ti consente di inviare messaggi di testo, video e file audio a familiari, colleghi e amici. Utilizza i framework KDE e in particolare Kirigami per fornire un'esperienza convergente su più piattaforme.</p>
<p xml:lang="ka">NeoChat არის Matrix კლიენტი. ის საშუალებას გაძლევთ გაგზავნოთ ტექსტური შეტყობინებები, ვიდეოები და აუდიო ფაილები თქვენს ოჯახს, კოლეგებსა და მეგობრებს მატრიქსის პროტოკოლის გამოყენებით.</p>
<p xml:lang="nl">NeoChat is een client voor Matrix, het gedecentraliseerde communicatieprotocol voor instant messages. Het biedt u het verzenden van tekstberichten, video's en geluidsbestanden naar uw familie, collega's en vrienden. Het gebruik KDE frameworks en het meest opmerkelijk Kirigami om een convergente ervaring te leveren op meerdere platforms.</p>
<p xml:lang="nn">NeoChat er ein klient for Matrix, ein protokoll for desentralisert kommunikasjon. Du kan utveksla tekst, lyd og videoar med kollegaar, vennar og familie. Programmet brukar KDE Frameworks og Kirigami for å gje ei brukarflate tilpassa ulike plattformer.</p>
<p xml:lang="pl">NeoChat jest programem do Matriksa, protokołu rozproszonego porozumiewania się w czasie rzeczywistym. Umożliwia wysyłanie wiadomości tekstowych, filmów oraz dźwięku do twojej rodziny, znajomych oraz przyjaciół. Używa szkieletów KDE i głównie Kirigami, aby zapewnić spójne wrażenia na wielu platformach</p>
<p xml:lang="pt">O NeoChat é um cliente do Matrix. O mesmo permite-lhe enviar mensagens de texto, ficheiros de vídeo e áudio para a sua família, colegas e amigos com o protocolo Matrix. Usa as plataformas do KDE, e principalmente o Kirigami, para oferecer uma experiência convergente entre várias plataformas.</p>
<p xml:lang="sl">Neochat je odjemalec za Matrix, decentralizirani komunikacijski protokol za takojšnje sporočanje. Omogoča vam pošiljanje besedilnih sporočil, videoposnetkov in zvočnih datotek svoji družini, sodelavcem in prijateljem. Uporablja okvire ogrodje KDE frameworks in predvsem Kirigami za zagotavljanje konvergentne izkušnje na več platformah.</p>
@@ -119,7 +115,6 @@ to provide a convergent experience across multiple platforms.</p>
<p xml:lang="it">NeoChat mira ad essere un'applicazione completa per le specifiche Matrix. Pertanto, sono supportati tutti gli elementi dell'attuale specifica stabile con le notevoli eccezioni di VoIP, conversazioni e alcuni aspetti della cifratura end-to-end. Ci sono alcune altre piccole omissioni dovute al fatto che le specifiche Matrix sono in continua evoluzione, ma l'obiettivo rimane quello di fornire un eventuale supporto per l'intera specifica.</p>
<p xml:lang="ka">NeoChat-ი მიზნად ისახავს Matrix სპეციფიკაციის სრული განხორციელება ჰქონდეს. როგორც ასეთი, ყველაფერი მიმდინარე სპეციფიკაციიდან, VoIP-ის, ძაფებისა და გამჭოლი დაშიფვრის ზოგიერთი ასპექტის გარდა, მხარდაჭერილია. შეძლება ასევე იყოს მცირე ლაფსუსებიც იმის გამო, რომ Matrix-ის სპეციფიკაცია მუდმივად ვითარგდება, მაგრამ ჩვენი მიზანი მისი სრული მხარდაჭერაა.</p>
<p xml:lang="nl">NeoChat richt zich op het volledig bieden van alle mogelijkheden van de Matrix-specificatie. Alles in de huidige stabiele specificatie met merkbare uitzondering van VoIP, gekoppelde discussies en sommige aspecten van eind-tot-eind versleuteling worden ondersteund. Er zijn een paar andere kleinere omissies vanwege het feit dat de Matrix specificatie constant evolueert maar het doel blijft het eventueel bieden van ondersteuning van de gehele specificatie.</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="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="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>
@@ -139,7 +134,6 @@ to provide a convergent experience across multiple platforms.</p>
<p xml:lang="it">A causa della natura dello sviluppo delle specifiche Matrix, NeoChat supporta anche numerose funzionalità instabili. Attualmente queste sono:</p>
<p xml:lang="ka">Matrix-ის სპეციფიკაციის განვითარების ბუნების გამო NeoChat-ს ასევე აქვს უამრავი არასტაბილური ფუნქციაც. ახლა ისინია:</p>
<p xml:lang="nl">Vanwege de aard van de ontwikkeling van de Matrix specificatie ondersteunt NeoChat ook talloze onstabiele mogelijkheden. Dit zijn nu:</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="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="sl">Zaradi narave razvoja specifikacije Matrixa NeoChat podpira tudi številne nestabilne zmožnosti. Trenutno so to:</p>
@@ -160,7 +154,6 @@ to provide a convergent experience across multiple platforms.</p>
<li xml:lang="it">Sondaggi - MSC3381</li>
<li xml:lang="ka">Polls - MSC3381</li>
<li xml:lang="nl">Polls - MSC3381</li>
<li xml:lang="nn">Avstemmingar  MSC3381</li>
<li xml:lang="pt">Inquéritos - MSC3381</li>
<li xml:lang="sl">Polls - MSC3381</li>
<li xml:lang="ta">வாக்கெடுப்புகள் - MSC3381</li>
@@ -180,7 +173,6 @@ to provide a convergent experience across multiple platforms.</p>
<li xml:lang="it">Pacchetti di adesivi - MSC2545</li>
<li xml:lang="ka">სტიკერების პაკეტები - MSC2545</li>
<li xml:lang="nl">Sticker Packs - MSC2545</li>
<li xml:lang="nn">Klistremerke-pakkar  MSC2545</li>
<li xml:lang="pt">Pacotes de Autocolantes - MSC2545</li>
<li xml:lang="sl">Sticker Packs - MSC2545</li>
<li xml:lang="ta">ஒட்டி தொகுப்புகள் - MSC2545</li>
@@ -200,7 +192,6 @@ to provide a convergent experience across multiple platforms.</p>
<li xml:lang="it">Località eventi - MSC3488</li>
<li xml:lang="ka">მდებარეობის მოვლენები - MSC3488</li>
<li xml:lang="nl">Locatie gebeurtenissen - MSC3488</li>
<li xml:lang="nn">Posisjonshendingar  MSC3488</li>
<li xml:lang="pt">Eventos com Localizações - MSC3488</li>
<li xml:lang="sl">Location Events - MSC3488</li>
<li xml:lang="ta">இட நிகழ்வுகள் - MSC3488</li>
@@ -209,6 +200,11 @@ to provide a convergent experience across multiple platforms.</p>
<li xml:lang="x-test">xxLocation Events - MSC3488xx</li>
</ul>
</description>
<keywords>
<keyword>instant messaging</keyword>
<keyword>chat</keyword>
<keyword>matrix</keyword>
</keywords>
<url type="homepage">https://apps.kde.org/neochat/</url>
<url type="bugtracker">https://bugs.kde.org/buglist.cgi?component=General&amp;product=NeoChat</url>
<categories>
@@ -223,7 +219,6 @@ to provide a convergent experience across multiple platforms.</p>
<developer_name xml:lang="de">Die KDE-Gemeinschaft</developer_name>
<developer_name xml:lang="el">Η Κοινότητα του KDE</developer_name>
<developer_name xml:lang="en-GB">The KDE Community</developer_name>
<developer_name xml:lang="eo">La KDE-Komunumo</developer_name>
<developer_name xml:lang="es">La comunidad KDE</developer_name>
<developer_name xml:lang="eu">KDE komunitatea</developer_name>
<developer_name xml:lang="fi">KDE-yhteisö</developer_name>
@@ -261,30 +256,15 @@ to provide a convergent experience across multiple platforms.</p>
<value key="KDE::windows_store::StoreLogoSquare">https://invent.kde.org/network/neochat/-/raw/master/icons/windows/storelogo-1080x1080.png</value>
<value key="KDE::windows_store::Icon">https://invent.kde.org/network/neochat/-/raw/master/icons/300-apps-neochat.png</value>
<value key="KDE::windows_store::PromotionalArt16x9">https://invent.kde.org/network/neochat/-/raw/master/icons/windows/promoimage-1920x1080.png</value>
<value key="KDE::windows_store::screenshots::1::image">https://cdn.kde.org/screenshots/neochat/NeoChat-Windows-Timeline.png</value>
<value key="KDE::windows_store::screenshots::1::caption">Main view with room list, chat, and room information</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="ca">Vista principal amb la llista de sales, xats i informació de les sales</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="ca-valencia">Vista principal amb la llista de sales, xats i informació de les sales</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="es">Vista principal con la lista de salas, chat e información de la sala</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="ka">მთავარი ხედი სურათების სიით, ჩატით და ოთახის ინფორმაციით</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="nl">Hoofdweergave met lijst met rooms, chat en roominformatie</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="pt">A área principal com a lista de salas e com informações sobre a conversa e a sala</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="sl">Glavni pogled s seznamom sob, klepetom in informacijami o sobah</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="tr">Oda listesini, sohbet penceresini ve oda bilgisini gösteren ana görünüm</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="uk">Головна панель із списком кімнат, спілкуванням та даними щодо кімнати</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="x-test">xxMain view with room list, chat, and room informationxx</value>
<value key="KDE::windows_store::screenshots::2::image">https://cdn.kde.org/screenshots/neochat/NeoChat-Windows-Login.png</value>
<value key="KDE::windows_store::screenshots::2::caption">Login screen</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="ca">Pantalla d'inici de sessió</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="ca-valencia">Pantalla d'inici de sessió</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="es">Pantalla de inicio de sesión</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="ka">შესვლის ეკრანი</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="nl">Aanmeldscherm</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="pt">Ecrã de autenticação</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="sl">Prijavni zaslon</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="tr">Oturum açma ekranı</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="uk">Вікно входу</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="x-test">xxLogin screenxx</value>
<value key="KDE::feature1">Supports the Matrix protocol for instant messaging.</value>
<value key="KDE::feature2">End-to-End Encryption</value>
<value key="KDE::feature3">Polls (experimental)</value>
<value key="KDE::feature4">Sticker Packs (experimental)</value>
<value key="KDE::feature5">Location Events (experimental)</value>
<value key="KDE::windows_store::DesktopScreenshot1">https://cdn.kde.org/screenshots/neochat/NeoChat-Windows-Timeline.png</value>
<value key="KDE::windows_store::DesktopScreenshotCaption1">Main view of NeoChat with room list, chat, and room information pane</value>
<value key="KDE::windows_store::DesktopScreenshot2">https://cdn.kde.org/screenshots/neochat/NeoChat-Windows-Login.png</value>
<value key="KDE::windows_store::DesktopScreenshotCaption2">Login screen of NeoChat</value>
</custom>
<launchable type="desktop-id">org.kde.neochat.desktop</launchable>
<screenshots>
@@ -299,7 +279,6 @@ to provide a convergent experience across multiple platforms.</p>
<content_attribute id="social-chat">intense</content_attribute>
</content_rating>
<releases>
<release version="23.04.3" date="2023-07-06"/>
<release version="23.04.2" date="2023-06-08"/>
<release version="23.04.1" date="2023-05-11"/>
<release version="23.04.0" date="2023-04-20">

View File

@@ -11,7 +11,6 @@ Name[cs]=NeoChat
Name[de]=NeoChat
Name[el]=NeoChat
Name[en_GB]=NeoChat
Name[eo]=NeoChat
Name[es]=NeoChat
Name[eu]=NeoChat
Name[fi]=NeoChat
@@ -50,7 +49,6 @@ GenericName[cs]=Klient protokolu Matrix
GenericName[de]=Matrix-Programm
GenericName[el]=Εφαρμογή του Matrix
GenericName[en_GB]=Matrix Client
GenericName[eo]=Matrix-Kliento
GenericName[es]=Cliente para Matrix
GenericName[eu]=Matrix bezeroa
GenericName[fi]=Matrix-asiakas
@@ -88,7 +86,6 @@ Comment[ca@valencia]=Client per al protocol Matrix
Comment[de]=Programm für das Matrix-Protokoll
Comment[el]=Πελάτης για το πρωτόκολλο Matrix
Comment[en_GB]=Client for the Matrix protocol
Comment[eo]=Kliento por la Matrix-protokolo
Comment[es]=Cliente para el protocolo Matrix
Comment[eu]=Matrix protokolorako bezeroa
Comment[fi]=Asiakas Matrix-yhteyskäytännölle
@@ -103,7 +100,7 @@ Comment[ka]=კლიენტი Matrix-ის პროტოკოლის
Comment[ko]=Matrix 프로토콜용 클라이언트
Comment[lt]=Matrix protokolo kliento programa
Comment[nl]=Client voor het Matrix-protocol
Comment[nn]=Klient for Matrix-protokollen
Comment[nn]=Lynmeldings­klient for Matrix-protokollen
Comment[pa]=ਮੈਟਰਿਕਸ ਪਰੋਟੋਕਾਲ ਲਈ ਕਲਾਈਂਟ ਹੈ
Comment[pl]=Program obsługi protokołu Matriksa
Comment[pt]=Cliente para o protocolo Matrix

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

@@ -3,141 +3,74 @@
# SPDX-FileCopyrightText: 2020-2021 Tobias Fella <tobias.fella@kde.org>
# SPDX-License-Identifier: BSD-2-Clause
configure_file(qml/Page/RoomList/RoomDelegate.qml ${CMAKE_CURRENT_BINARY_DIR}/qml/Page/RoomList/RoomDelegate.qml)
configure_file(qml/Component/QuickSwitcher.qml ${CMAKE_CURRENT_BINARY_DIR}/qml/Component/QuickSwitcher.qml)
configure_file(qml/Dialog/UserDetailDialog.qml ${CMAKE_CURRENT_BINARY_DIR}/qml/Dialog/UserDetailDialog.qml)
configure_file(qml/Dialog/PowerLevelDialog.qml ${CMAKE_CURRENT_BINARY_DIR}/qml/Dialog/PowerLevelDialog.qml)
configure_file(qml/Component/Timeline/OsmLocationPlugin.qml ${CMAKE_CURRENT_BINARY_DIR}/qml/Component/Timeline/OsmLocationPlugin.qml)
configure_file(res.qrc ${CMAKE_CURRENT_SOURCE_DIR}/res.generated.qrc)
add_library(neochat STATIC
controller.cpp
controller.h
actionshandler.cpp
actionshandler.h
models/emojimodel.cpp
models/emojimodel.h
emojitones.cpp
emojitones.h
models/customemojimodel.cpp
models/customemojimodel.h
clipboard.cpp
clipboard.h
matriximageprovider.cpp
matriximageprovider.h
models/messageeventmodel.cpp
models/messageeventmodel.h
models/messagefiltermodel.cpp
models/messagefiltermodel.h
models/roomlistmodel.cpp
models/roomlistmodel.h
models/sortfilterspacelistmodel.cpp
models/sortfilterspacelistmodel.h
models/accountemoticonmodel.cpp
models/accountemoticonmodel.h
spacehierarchycache.cpp
spacehierarchycache.h
roommanager.cpp
roommanager.h
neochatroom.cpp
neochatroom.h
neochatuser.cpp
neochatuser.h
models/userlistmodel.cpp
models/userlistmodel.h
models/userfiltermodel.cpp
models/userfiltermodel.h
models/publicroomlistmodel.cpp
models/publicroomlistmodel.h
models/userdirectorylistmodel.cpp
models/userdirectorylistmodel.h
models/pushrulemodel.cpp
models/pushrulemodel.h
models/keywordnotificationrulemodel.cpp
models/emoticonfiltermodel.cpp
models/emoticonfiltermodel.h
notificationsmanager.cpp
notificationsmanager.h
models/sortfilterroomlistmodel.cpp
models/sortfilterroomlistmodel.h
chatdocumenthandler.cpp
chatdocumenthandler.h
models/devicesmodel.cpp
models/devicesmodel.h
filetypesingleton.cpp
filetypesingleton.h
login.cpp
login.h
models/webshortcutmodel.cpp
models/webshortcutmodel.h
blurhash.cpp
blurhash.h
blurhashimageprovider.cpp
blurhashimageprovider.h
models/collapsestateproxymodel.cpp
models/collapsestateproxymodel.h
models/mediamessagefiltermodel.cpp
models/mediamessagefiltermodel.h
urlhelper.cpp
urlhelper.h
windowcontroller.cpp
windowcontroller.h
linkpreviewer.cpp
linkpreviewer.h
models/completionmodel.cpp
models/completionmodel.h
models/completionproxymodel.cpp
models/completionproxymodel.h
models/actionsmodel.cpp
models/actionsmodel.h
models/serverlistmodel.cpp
models/serverlistmodel.h
models/statemodel.cpp
models/statemodel.h
models/statefiltermodel.cpp
models/statefiltermodel.h
filetransferpseudojob.cpp
filetransferpseudojob.h
models/searchmodel.cpp
models/searchmodel.h
texthandler.cpp
texthandler.h
logger.cpp
logger.h
models/stickermodel.cpp
models/stickermodel.h
models/imagepacksmodel.cpp
models/imagepacksmodel.h
events/imagepackevent.cpp
events/imagepackevent.h
events/joinrulesevent.cpp
events/joinrulesevent.h
events/stickerevent.cpp
models/reactionmodel.cpp
models/reactionmodel.h
delegatesizehelper.cpp
delegatesizehelper.h
models/livelocationsmodel.cpp
models/livelocationsmodel.h
models/locationsmodel.cpp
models/locationsmodel.h
locationhelper.cpp
locationhelper.h
events/pollevent.cpp
pollhandler.cpp
)
ecm_qt_declare_logging_category(neochat
HEADER "messageeventmodel_logging.h"
IDENTIFIER "MessageEvent"
CATEGORY_NAME "org.kde.neochat.messageeventmodel"
DESCRIPTION "Neochat: messageeventmodel"
DEFAULT_SEVERITY Info
EXPORT NEOCHAT
)
add_executable(neochat-app
main.cpp
${CMAKE_CURRENT_SOURCE_DIR}/res.generated.qrc
res.qrc
)
target_include_directories(neochat-app PRIVATE ${CMAKE_BINARY_DIR})
@@ -146,16 +79,24 @@ target_link_libraries(neochat-app PRIVATE
neochat
)
if(Quotient${QUOTIENT_SUFFIX}_VERSION_MINOR GREATER 6)
target_compile_definitions(neochat PUBLIC QUOTIENT_07)
target_sources(neochat PRIVATE events/pollevent.cpp pollhandler.cpp)
else()
target_compile_definitions(neochat PUBLIC QUOTIENT_VERSION=\"${Quotient${QUOTIENT_SUFFIX}_VERSION}\")
target_sources(neochat PRIVATE neochataccountregistry.cpp)
endif()
ecm_add_app_icon(NEOCHAT_ICON ICONS ${CMAKE_SOURCE_DIR}/128-logo.png)
target_sources(neochat-app PRIVATE ${NEOCHAT_ICON})
if(NOT ANDROID)
target_sources(neochat PRIVATE colorschemer.cpp colorschemer.h)
target_sources(neochat PRIVATE colorschemer.cpp)
if (NOT WIN32 AND NOT APPLE)
target_sources(neochat PRIVATE trayicon_sni.cpp trayicon_sni.h)
target_sources(neochat PRIVATE trayicon_sni.cpp)
else()
target_sources(neochat PRIVATE trayicon.cpp trayicon.h)
target_sources(neochat PRIVATE trayicon.cpp)
endif()
target_link_libraries(neochat PUBLIC KF${QT_MAJOR_VERSION}::ConfigWidgets KF${QT_MAJOR_VERSION}::WindowSystem)
target_compile_definitions(neochat PUBLIC -DHAVE_COLORSCHEME)

View File

@@ -14,6 +14,7 @@
#include "models/actionsmodel.h"
#include "models/customemojimodel.h"
#include "neochatconfig.h"
#include "neochatroom.h"
#include "texthandler.h"
using namespace Quotient;
@@ -182,5 +183,3 @@ void ActionsHandler::checkEffects(const QString &text)
Q_EMIT showEffect(*effect);
}
}
#include "moc_actionshandler.cpp"

View File

@@ -47,7 +47,7 @@ public:
Q_SIGNALS:
void roomChanged();
void showEffect(const QString &effect);
void showEffect(QString effect);
public Q_SLOTS:

View File

@@ -14,6 +14,8 @@
#include <Sonnet/BackgroundChecker>
#include <Sonnet/Settings>
#include "neochatroom.h"
class SyntaxHighlighter : public QSyntaxHighlighter
{
public:
@@ -353,5 +355,3 @@ void ChatDocumentHandler::setErrorColor(const QColor &color)
m_highlighter->rehighlight();
Q_EMIT errorColorChanged();
}
#include "moc_chatdocumenthandler.cpp"

View File

@@ -79,5 +79,3 @@ void Clipboard::setImage(const QUrl &url)
}
}
}
#include "moc_clipboard.cpp"

View File

@@ -44,5 +44,3 @@ QString ColorSchemer::nameForIndex(int index) const
{
return c->model()->data(c->model()->index(index, 0), Qt::DisplayRole).toString();
}
#include "moc_colorschemer.cpp"

View File

@@ -28,7 +28,7 @@ class ColorSchemer : public QObject
Q_PROPERTY(QAbstractItemModel *model READ model CONSTANT)
public:
explicit ColorSchemer(QObject *parent = nullptr);
ColorSchemer(QObject *parent = nullptr);
~ColorSchemer();
QAbstractItemModel *model() const;

View File

@@ -31,7 +31,11 @@
#include <signal.h>
#ifdef QUOTIENT_07
#include "accountregistry.h"
#else
#include "neochataccountregistry.h"
#endif
#include <connection.h>
#include <csapi/content-repo.h>
@@ -40,7 +44,9 @@
#include <jobs/downloadfilejob.h>
#include <qt_connection_util.h>
#ifdef QUOTIENT_07
#include <eventstats.h>
#endif
#include "neochatconfig.h"
#include "neochatroom.h"
@@ -102,8 +108,13 @@ Controller::Controller(QObject *parent)
}
#endif
#ifdef QUOTIENT_07
connect(&Accounts, &AccountRegistry::accountCountChanged, this, &Controller::activeConnectionIndexChanged);
#else
connect(&AccountRegistry::instance(), &AccountRegistry::accountCountChanged, this, &Controller::activeConnectionIndexChanged);
#endif
#ifdef QUOTIENT_07
static int oldAccountCount = 0;
connect(&Accounts, &AccountRegistry::accountCountChanged, this, [this]() {
if (Accounts.size() > oldAccountCount) {
@@ -114,10 +125,7 @@ Controller::Controller(QObject *parent)
}
oldAccountCount = Accounts.size();
});
QTimer::singleShot(0, this, [this] {
m_pushRuleModel = new PushRuleModel;
});
#endif
}
Controller &Controller::instance()
@@ -148,10 +156,18 @@ void Controller::logout(Connection *conn, bool serverSideLogout)
job.start();
loop.exec();
#ifdef QUOTIENT_07
if (Accounts.count() > 1) {
#else
if (AccountRegistry::instance().count() > 1) {
#endif
// Only set the connection if the the account being logged out is currently active
if (conn == activeConnection()) {
#ifdef QUOTIENT_07
setActiveConnection(Accounts.accounts()[0]);
#else
setActiveConnection(AccountRegistry::instance().accounts()[0]);
#endif
}
} else {
setActiveConnection(nullptr);
@@ -166,7 +182,11 @@ void Controller::addConnection(Connection *c)
{
Q_ASSERT_X(c, __FUNCTION__, "Attempt to add a null connection");
#ifdef QUOTIENT_07
Accounts.add(c);
#else
AccountRegistry::instance().add(c);
#endif
c->setLazyLoading(true);
@@ -196,8 +216,15 @@ void Controller::dropConnection(Connection *c)
{
Q_ASSERT_X(c, __FUNCTION__, "Attempt to drop a null connection");
#ifndef QUOTIENT_07
AccountRegistry::instance().drop(c);
#endif
Q_EMIT connectionDropped(c);
Q_EMIT accountCountChanged();
#ifndef QUOTIENT_07
c->deleteLater();
#endif
}
void Controller::invokeLogin()
@@ -370,7 +397,11 @@ bool Controller::setAvatar(Connection *connection, const QUrl &avatarSource)
User *localUser = connection->user();
QString decoded = avatarSource.path();
if (decoded.isEmpty()) {
#ifdef QUOTIENT_07
connection->callApi<SetAvatarUrlJob>(localUser->id(), avatarSource);
#else
connection->callApi<SetAvatarUrlJob>(localUser->id(), QString());
#endif
return true;
}
if (QImageReader(decoded).read().isNull()) {
@@ -381,7 +412,11 @@ bool Controller::setAvatar(Connection *connection, const QUrl &avatarSource)
}
NeochatChangePasswordJob::NeochatChangePasswordJob(const QString &newPassword, bool logoutDevices, const Omittable<QJsonObject> &auth)
#ifdef QUOTIENT_07
: BaseJob(HttpVerb::Post, QStringLiteral("ChangePasswordJob"), "/_matrix/client/r0/account/password")
#else
: BaseJob(HttpVerb::Post, QStringLiteral("ChangePasswordJob"), QStringLiteral("/_matrix/client/r0/account/password"))
#endif
{
QJsonObject _data;
addParam<>(_data, QStringLiteral("new_password"), newPassword);
@@ -392,7 +427,11 @@ NeochatChangePasswordJob::NeochatChangePasswordJob(const QString &newPassword, b
int Controller::accountCount() const
{
#ifdef QUOTIENT_07
return Accounts.count();
#else
return AccountRegistry::instance().count();
#endif
}
void Controller::setQuitOnLastWindowClosed()
@@ -468,18 +507,17 @@ void Controller::setActiveConnection(Connection *connection)
Q_EMIT activeAccountLabelChanged();
}
PushRuleModel *Controller::pushRuleModel() const
{
return m_pushRuleModel;
}
void Controller::saveWindowGeometry()
{
WindowController::instance().saveGeometry();
}
NeochatDeleteDeviceJob::NeochatDeleteDeviceJob(const QString &deviceId, const Omittable<QJsonObject> &auth)
#ifdef QUOTIENT_07
: Quotient::BaseJob(HttpVerb::Delete, QStringLiteral("DeleteDeviceJob"), QStringLiteral("/_matrix/client/r0/devices/%1").arg(deviceId).toLatin1())
#else
: Quotient::BaseJob(HttpVerb::Delete, QStringLiteral("DeleteDeviceJob"), QStringLiteral("/_matrix/client/r0/devices/%1").arg(deviceId))
#endif
{
QJsonObject _data;
addParam<IfNotEmpty>(_data, QStringLiteral("auth"), auth);
@@ -585,7 +623,11 @@ bool Controller::hasWindowSystem() const
bool Controller::encryptionSupported() const
{
#ifdef QUOTIENT_07
return Quotient::encryptionSupported();
#else
return false;
#endif
}
void Controller::forceRefreshTextDocument(QQuickTextDocument *textDocument, QQuickItem *item)
@@ -626,16 +668,29 @@ void Controller::setApplicationProxy()
int Controller::activeConnectionIndex() const
{
#ifdef QUOTIENT_07
auto result = std::find_if(Accounts.accounts().begin(), Accounts.accounts().end(), [this](const auto &it) {
return it == m_connection;
});
return result - Accounts.accounts().begin();
#else
for (int i = 0; i < AccountRegistry::instance().rowCount(); i++) {
if (AccountRegistry::instance().data(AccountRegistry::instance().index(i, 0), AccountRegistry::UserIdRole).toString() == m_connection->userId()) {
return i;
}
}
return 0;
#endif
}
int Controller::quotientMinorVersion() const
{
// TODO libQuotient 0.7: Replace with version function from libQuotient
// TODO libQuotient 0.7: Replace with version function from libQuotient
#ifdef QUOTIENT_07
return 7;
#else
return 6;
#endif
}
bool Controller::isFlatpak() const
@@ -681,5 +736,3 @@ QVariantList Controller::getSupportedRoomVersions(Quotient::Connection *connecti
return supportedRoomVersions;
}
#include "moc_controller.cpp"

View File

@@ -3,7 +3,6 @@
#pragma once
#include "models/pushrulemodel.h"
#include <QObject>
#include <QQuickItem>
@@ -51,11 +50,6 @@ class Controller : public QObject
*/
Q_PROPERTY(Quotient::Connection *activeConnection READ activeConnection WRITE setActiveConnection NOTIFY activeConnectionChanged)
/**
* @brief The PushRuleModel that has the active connection's push rules.
*/
Q_PROPERTY(PushRuleModel *pushRuleModel READ pushRuleModel CONSTANT)
/**
* @brief The row number in the accounts directory of the active connection.
*/
@@ -116,7 +110,7 @@ public:
Wrong, /**< The current password entered was wrong. */
Other, /**< An unknown problem occurred. */
};
Q_ENUM(PasswordStatus)
Q_ENUM(PasswordStatus);
static Controller &instance();
@@ -125,8 +119,6 @@ public:
void setActiveConnection(Quotient::Connection *connection);
[[nodiscard]] Quotient::Connection *activeConnection() const;
[[nodiscard]] PushRuleModel *pushRuleModel() const;
/**
* @brief Add a new connection to the account registry.
*/
@@ -244,8 +236,6 @@ private:
bool hasWindowSystem() const;
QPointer<PushRuleModel> m_pushRuleModel;
private Q_SLOTS:
void invokeLogin();
void showWindow();

View File

@@ -151,5 +151,3 @@ qreal DelegateSizeHelper::currentWidth() const
return std::ceil(std::min(absoluteWidth, m_maxWidth));
}
}
#include "moc_delegatesizehelper.cpp"

View File

@@ -77,7 +77,7 @@ class DelegateSizeHelper : public QObject
Q_PROPERTY(qreal currentWidth READ currentWidth NOTIFY currentWidthChanged)
public:
explicit DelegateSizeHelper(QObject *parent = nullptr);
DelegateSizeHelper(QObject *parent = nullptr);
qreal parentWidth() const;
void setParentWidth(qreal parentWidth);

View File

@@ -11,7 +11,11 @@ ImagePackEventContent::ImagePackEventContent(const QJsonObject &json)
if (json.contains(QStringLiteral("pack"))) {
pack = ImagePackEventContent::Pack{
fromJson<Omittable<QString>>(json["pack"].toObject()["display_name"]),
#ifdef QUOTIENT_07
fromJson<Omittable<QUrl>>(json["pack"].toObject()["avatar_url"]),
#else
QUrl(),
#endif
fromJson<Omittable<QStringList>>(json["pack"].toObject()["usage"]),
fromJson<Omittable<QString>>(json["pack"].toObject()["attribution"]),
};
@@ -23,13 +27,21 @@ ImagePackEventContent::ImagePackEventContent(const QJsonObject &json)
for (const auto &k : keys) {
Omittable<EventContent::ImageInfo> info;
if (json["images"][k].toObject().contains(QStringLiteral("info"))) {
#ifdef QUOTIENT_07
info = EventContent::ImageInfo(QUrl(json["images"][k]["url"].toString()), json["images"][k]["info"].toObject(), k);
#else
info = EventContent::ImageInfo(QUrl(json["images"][k]["url"].toString()), json["images"][k].toObject(), k);
#endif
} else {
info = none;
}
images += ImagePackImage{
k,
#ifdef QUOTIENT_07
fromJson<QUrl>(json["images"][k]["url"].toString()),
#else
QUrl(),
#endif
fromJson<Omittable<QString>>(json["images"][k]["body"]),
info,
fromJson<Omittable<QStringList>>(json["images"][k]["usage"]),

View File

@@ -83,11 +83,23 @@ public:
*
* @sa Quotient::StateEvent, ImagePackEventContent
*/
#ifdef QUOTIENT_07
class ImagePackEvent : public KeyedStateEventBase<ImagePackEvent, ImagePackEventContent>
#else
class ImagePackEvent : public StateEvent<ImagePackEventContent>
#endif
{
public:
#ifdef QUOTIENT_07
QUO_EVENT(ImagePackEvent, "im.ponies.room_emotes")
using KeyedStateEventBase::KeyedStateEventBase;
#else
DEFINE_EVENT_TYPEID("im.ponies.room_emotes", ImagePackEvent)
explicit ImagePackEvent(const QJsonObject &obj)
: StateEvent(typeId(), obj)
{
}
#endif
};
REGISTER_EVENT_TYPE(ImagePackEvent)

View File

@@ -14,13 +14,25 @@ namespace Quotient
*
* @sa Quotient::StateEvent
*/
#ifdef QUOTIENT_07
class JoinRulesEvent : public StateEvent
#else
class JoinRulesEvent : public StateEventBase
#endif
{
public:
#ifdef QUOTIENT_07
QUO_EVENT(JoinRulesEvent, "m.room.join_rules")
#else
DEFINE_EVENT_TYPEID("m.room.join_rules", JoinRulesEvent)
#endif
explicit JoinRulesEvent(const QJsonObject &obj)
#ifdef QUOTIENT_07
: StateEvent(obj)
#else
: StateEventBase(typeId(), obj)
#endif
{
}

View File

@@ -0,0 +1,35 @@
// SPDX-FileCopyrightText: 2020 Carl Schwan <carlschwan@kde.org>
// SPDX-License-Identifier: LGPL-2.1-or-later
#include "stickerevent.h"
using namespace Quotient;
StickerEvent::StickerEvent(const QJsonObject &obj)
#ifdef QUOTIENT_07
: RoomEvent(obj)
#else
: RoomEvent(typeId(), obj)
#endif
, m_imageContent(EventContent::ImageContent(obj["content"_ls].toObject()))
{
}
QString StickerEvent::body() const
{
return content<QString>("body"_ls);
}
const EventContent::ImageContent &StickerEvent::image() const
{
return m_imageContent;
}
QUrl StickerEvent::url() const
{
#ifdef QUOTIENT_07
return m_imageContent.url();
#else
return m_imageContent.url;
#endif
}

55
src/events/stickerevent.h Normal file
View File

@@ -0,0 +1,55 @@
// SPDX-FileCopyrightText: 2020 Carl Schwan <carlschwan@kde.org>
// SPDX-License-Identifier: LGPL-2.1-or-later
#pragma once
#include <events/eventcontent.h>
#include <events/roomevent.h>
namespace Quotient
{
/**
* @class StickerEvent
*
* Class to define a sticker event.
*
* Sticker messages are specialised image messages that are displayed without
* controls (e.g. no "download" link, or light-box view on click, as would be
* displayed for for m.image events).
*
* @sa Quotient::RoomEvent
*/
class StickerEvent : public RoomEvent
{
public:
#ifdef QUOTIENT_07
QUO_EVENT(StickerEvent, "m.sticker")
#else
DEFINE_EVENT_TYPEID("m.sticker", StickerEvent)
#endif
explicit StickerEvent(const QJsonObject &obj);
/**
* @brief A textual representation or associated description of the sticker image.
*
* This could be the alt text of the original image, or a message to accompany
* and further describe the sticker.
*/
QString body() const;
/**
* @brief Metadata about the image referred to in url including a thumbnail representation.
*/
const EventContent::ImageContent &image() const;
/**
* @brief The URL to the sticker image. This must be a valid mxc:// URI.
*/
QUrl url() const;
private:
EventContent::ImageContent m_imageContent;
};
REGISTER_EVENT_TYPE(StickerEvent)
}

View File

@@ -14,7 +14,7 @@ FileTransferPseudoJob::FileTransferPseudoJob(Operation operation, const QString
{
}
void FileTransferPseudoJob::fileTransferProgress(const QString &id, qint64 progress, qint64 total)
void FileTransferPseudoJob::fileTransferProgress(QString id, qint64 progress, qint64 total)
{
if (id != m_eventId) {
return;
@@ -23,7 +23,7 @@ void FileTransferPseudoJob::fileTransferProgress(const QString &id, qint64 progr
setTotalAmount(Unit::Bytes, total);
}
void FileTransferPseudoJob::fileTransferCompleted(const QString &id, const QUrl &localFile)
void FileTransferPseudoJob::fileTransferCompleted(QString id, QUrl localFile)
{
Q_UNUSED(localFile);
if (id != m_eventId) {
@@ -32,7 +32,7 @@ void FileTransferPseudoJob::fileTransferCompleted(const QString &id, const QUrl
emitResult();
}
void FileTransferPseudoJob::fileTransferFailed(const QString &id, const QString &errorMessage)
void FileTransferPseudoJob::fileTransferFailed(QString id, QString errorMessage)
{
if (id != m_eventId) {
return;

View File

@@ -20,23 +20,23 @@ public:
Download,
Upload,
};
Q_ENUM(Operation)
Q_ENUM(Operation);
FileTransferPseudoJob(Operation operation, const QString &srcDest, const QString &path);
/**
* @brief Set the current number of bytes transferred.
*/
void fileTransferProgress(const QString &id, qint64 progress, qint64 total);
void fileTransferProgress(QString id, qint64 progress, qint64 total);
/**
* @brief Set the file transfer as complete.
*/
void fileTransferCompleted(const QString &id, const QUrl &localFile);
void fileTransferCompleted(QString id, QUrl localFile);
/**
* @brief Set the file transfer as failed.
*/
void fileTransferFailed(const QString &id, const QString &errorMessage = {});
void fileTransferFailed(QString id, QString errorMessage = {});
/**
* @brief Start the file transfer.

View File

@@ -112,5 +112,3 @@ QStringList FileTypeSingleton::supportedAnimatedImageFormats() const
Q_D(const FileTypeSingleton);
return d->supportedAnimatedImageFormats;
}
#include "moc_filetypesingleton.cpp"

View File

@@ -5,7 +5,6 @@
#pragma once
#include <QFileInfo>
#include <QMimeDatabase>
#include <QObject>
#include <qqml.h>

View File

@@ -10,7 +10,7 @@
using namespace Quotient;
LinkPreviewer::LinkPreviewer(QObject *parent, NeoChatRoom *room, const QUrl &url)
LinkPreviewer::LinkPreviewer(QObject *parent, NeoChatRoom *room, QUrl url)
: QObject(parent)
, m_currentRoom(room)
, m_loaded(false)
@@ -69,7 +69,14 @@ void LinkPreviewer::loadUrlPreview()
auto imageUrl = QUrl(json["og:image"].toString());
if (imageUrl.isValid() && imageUrl.scheme() == QStringLiteral("mxc")) {
#ifdef QUOTIENT_07
m_imageSource = conn->makeMediaUrl(imageUrl);
#else
QUrlQuery q(imageUrl.query());
q.addQueryItem(QStringLiteral("user_id"), conn->userId());
imageUrl.setQuery(q);
m_imageSource = imageUrl;
#endif
} else {
m_imageSource = QUrl();
}
@@ -82,5 +89,3 @@ void LinkPreviewer::loadUrlPreview()
});
}
}
#include "moc_linkpreviewer.cpp"

View File

@@ -45,7 +45,7 @@ class LinkPreviewer : public QObject
Q_PROPERTY(QUrl imageSource READ imageSource NOTIFY imageSourceChanged)
public:
explicit LinkPreviewer(QObject *parent = nullptr, NeoChatRoom *room = nullptr, const QUrl &url = {});
explicit LinkPreviewer(QObject *parent = nullptr, NeoChatRoom *room = nullptr, QUrl url = {});
[[nodiscard]] QUrl url() const;
void setUrl(QUrl);

View File

@@ -42,5 +42,3 @@ float LocationHelper::zoomToFit(const QRectF &r, float mapWidth, float mapHeight
return std::clamp(z, 5.0, 18.0);
}
#include "moc_locationhelper.cpp"

View File

@@ -1,6 +1,5 @@
// SPDX-FileCopyrightText: 2023 Volker Krause <vkrause@kde.org>
// SPDX-License-Identifier: LGPL-2.0-or-later
#pragma once
#include "linkpreviewer.h"
#include <QMetaType>

View File

@@ -3,7 +3,11 @@
#include "login.h"
#ifdef QUOTIENT_07
#include <accountregistry.h>
#else
#include "neochataccountregistry.h"
#endif
#include <connection.h>
#include <qt_connection_util.h>
@@ -43,7 +47,11 @@ void Login::init()
return;
}
#ifdef QUOTIENT_07
m_isLoggedIn = Accounts.isLoggedIn(m_matrixId);
#else
m_isLoggedIn = AccountRegistry::instance().isLoggedIn(m_matrixId);
#endif
Q_EMIT isLoggedInChanged();
if (m_isLoggedIn) {
return;
@@ -97,7 +105,7 @@ void Login::init()
Q_EMIT Controller::instance().globalErrorOccured(i18n("Network Error"), std::move(error));
});
connectSingleShot(m_connection, &Connection::syncDone, this, []() {
connectSingleShot(m_connection, &Connection::syncDone, this, [this]() {
Q_EMIT Controller::instance().initiated();
});
}
@@ -199,5 +207,3 @@ bool Login::isLoggedIn() const
{
return m_isLoggedIn;
}
#include "moc_login.cpp"

View File

@@ -112,7 +112,7 @@ Q_SIGNALS:
void loginFlowsChanged();
void ssoUrlChanged();
void connected();
void errorOccured(const QString &message);
void errorOccured(QString message);
void testingChanged();
void isLoggingInChanged();
void isLoggedInChanged();

View File

@@ -28,7 +28,12 @@
#include "neochat-version.h"
#ifdef QUOTIENT_07
#include <accountregistry.h>
#else
#include "neochataccountregistry.h"
#endif
#include <networkaccessmanager.h>
#include <room.h>
#include <util.h>
@@ -52,21 +57,18 @@
#include "models/emojimodel.h"
#include "models/emoticonfiltermodel.h"
#include "models/imagepacksmodel.h"
#include "models/keywordnotificationrulemodel.h"
#include "models/livelocationsmodel.h"
#include "models/locationsmodel.h"
#include "models/mediamessagefiltermodel.h"
#include "models/messageeventmodel.h"
#include "models/messagefiltermodel.h"
#include "models/publicroomlistmodel.h"
#include "models/pushrulemodel.h"
#include "models/reactionmodel.h"
#include "models/roomlistmodel.h"
#include "models/searchmodel.h"
#include "models/serverlistmodel.h"
#include "models/sortfilterroomlistmodel.h"
#include "models/sortfilterspacelistmodel.h"
#include "models/statefiltermodel.h"
#include "models/stickermodel.h"
#include "models/userdirectorylistmodel.h"
#include "models/userfiltermodel.h"
#include "models/userlistmodel.h"
@@ -75,12 +77,18 @@
#include "neochatroom.h"
#include "neochatuser.h"
#include "notificationsmanager.h"
#ifdef QUOTIENT_07
#include "pollhandler.h"
#endif
#include "models/statefiltermodel.h"
#include "models/stickermodel.h"
#include "roommanager.h"
#include "spacehierarchycache.h"
#include "urlhelper.h"
#include "windowcontroller.h"
#ifdef QUOTIENT_07
#include <keyverificationsession.h>
#endif
#ifdef HAVE_COLORSCHEME
#include "colorschemer.h"
#endif
@@ -120,9 +128,7 @@ Q_DECL_EXPORT
#endif
int main(int argc, char *argv[])
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
QNetworkProxyFactory::setUseSystemConfiguration(true);
@@ -170,10 +176,14 @@ int main(int argc, char *argv[])
about.addComponent(QStringLiteral("libQuotient"),
i18n("A Qt5 library to write cross-platform clients for Matrix"),
#ifdef QUOTIENT_07
i18nc("<version number> (built against <possibly different version number>)",
"%1 (built against %2)",
Quotient::versionString(),
QStringLiteral(Quotient_VERSION_STRING)),
#else
QStringLiteral(QUOTIENT_VERSION),
#endif
QStringLiteral("https://github.com/quotient-im/libquotient"),
KAboutLicense::LGPL_V2_1);
@@ -182,10 +192,6 @@ int main(int argc, char *argv[])
initLogging();
#if Quotient_VERSION_MINOR == 8
Connection::setEncryptionDefault(true);
#endif
#ifdef NEOCHAT_FLATPAK
// Copy over the included FontConfig configuration to the
// app's config dir:
@@ -216,7 +222,11 @@ int main(int argc, char *argv[])
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "LoginHelper", login);
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "UrlHelper", &urlHelper);
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "EmojiModel", &EmojiModel::instance());
#ifdef QUOTIENT_07
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "AccountRegistry", &Quotient::Accounts);
#else
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "AccountRegistry", &Quotient::AccountRegistry::instance());
#endif
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "SpaceHierarchyCache", &SpaceHierarchyCache::instance());
qmlRegisterSingletonInstance("org.kde.neochat", 1, 0, "CustomEmojiModel", &CustomEmojiModel::instance());
qmlRegisterType<ActionsHandler>("org.kde.neochat", 1, 0, "ActionsHandler");
@@ -227,7 +237,6 @@ int main(int argc, char *argv[])
qmlRegisterType<MessageEventModel>("org.kde.neochat", 1, 0, "MessageEventModel");
qmlRegisterType<ReactionModel>("org.kde.neochat", 1, 0, "ReactionModel");
qmlRegisterType<CollapseStateProxyModel>("org.kde.neochat", 1, 0, "CollapseStateProxyModel");
qmlRegisterType<MediaMessageFilterModel>("org.kde.neochat", 1, 0, "MediaMessageFilterModel");
qmlRegisterType<MessageFilterModel>("org.kde.neochat", 1, 0, "MessageFilterModel");
qmlRegisterType<UserFilterModel>("org.kde.neochat", 1, 0, "UserFilterModel");
qmlRegisterType<PublicRoomListModel>("org.kde.neochat", 1, 0, "PublicRoomListModel");
@@ -243,16 +252,16 @@ int main(int argc, char *argv[])
qmlRegisterType<SearchModel>("org.kde.neochat", 1, 0, "SearchModel");
qmlRegisterType<LiveLocationsModel>("org.kde.neochat", 1, 0, "LiveLocationsModel");
qmlRegisterType<LocationsModel>("org.kde.neochat", 1, 0, "LocationsModel");
#ifdef QUOTIENT_07
qmlRegisterType<PollHandler>("org.kde.neochat", 1, 0, "PollHandler");
qmlRegisterType<PushRuleModel>("org.kde.neochat", 1, 0, "PushRuleModel");
#endif
qmlRegisterType<KeywordNotificationRuleModel>("org.kde.neochat", 1, 0, "KeywordNotificationRuleModel");
qmlRegisterType<StickerModel>("org.kde.neochat", 1, 0, "StickerModel");
qmlRegisterType<ImagePacksModel>("org.kde.neochat", 1, 0, "ImagePacksModel");
qmlRegisterType<AccountEmoticonModel>("org.kde.neochat", 1, 0, "AccountEmoticonModel");
qmlRegisterType<EmoticonFilterModel>("org.kde.neochat", 1, 0, "EmoticonFilterModel");
qmlRegisterType<DelegateSizeHelper>("org.kde.neochat", 1, 0, "DelegateSizeHelper");
qmlRegisterUncreatableType<RoomMessageEvent>("org.kde.neochat", 1, 0, "RoomMessageEvent", "ENUM");
qmlRegisterUncreatableType<PushNotificationKind>("org.kde.neochat", 1, 0, "PushNotificationKind", "ENUM");
qmlRegisterUncreatableType<PushNotificationSection>("org.kde.neochat", 1, 0, "PushNotificationSection", "ENUM");
qmlRegisterUncreatableType<PushNotificationState>("org.kde.neochat", 1, 0, "PushNotificationState", "ENUM");
qmlRegisterUncreatableType<PushNotificationAction>("org.kde.neochat", 1, 0, "PushNotificationAction", "ENUM");
qmlRegisterUncreatableType<NeoChatRoomType>("org.kde.neochat", 1, 0, "NeoChatRoomType", "ENUM");
@@ -269,10 +278,12 @@ int main(int argc, char *argv[])
qRegisterMetaType<NeoChatUser *>("NeoChatUser*");
qRegisterMetaType<GetRoomEventsJob *>("GetRoomEventsJob*");
qRegisterMetaType<QMimeType>("QMimeType");
#ifdef QUOTIENT_07
#ifdef Quotient_E2EE_ENABLED
qRegisterMetaType<KeyVerificationSession *>("KeyVerificationSession*");
qmlRegisterUncreatableType<KeyVerificationSession>("org.kde.neochat", 1, 0, "KeyVerificationSession", {});
qRegisterMetaType<QVector<EmojiEntry>>("QVector<EmojiEntry>");
#endif
#endif
qmlRegisterSingletonType("org.kde.neochat", 1, 0, "About", [](QQmlEngine *engine, QJSEngine *) -> QJSValue {
return engine->toScriptValue(KAboutData::applicationData());

View File

@@ -114,5 +114,3 @@ QQuickImageResponse *MatrixImageProvider::requestImageResponse(const QString &id
{
return new ThumbnailResponse(id, requestedSize);
}
#include "moc_matriximageprovider.cpp"

View File

@@ -27,7 +27,11 @@ QVariant AccountEmoticonModel::data(const QModelIndex &index, int role) const
const auto &row = index.row();
const auto &image = m_images->images[row];
if (role == UrlRole) {
#ifdef QUOTIENT_07
return m_connection->makeMediaUrl(image.url);
#else
return QUrl();
#endif
}
if (role == BodyRole) {
if (image.body) {
@@ -138,7 +142,11 @@ QCoro::Task<void> AccountEmoticonModel::doSetEmoticonImage(int index, QUrl sourc
if (job->error() != BaseJob::NoError) {
co_return;
}
#ifdef QUOTIENT_07
m_images->images[index].url = job->contentUri().toString();
#else
m_images->images[index].url = job->contentUri();
#endif
m_images->images[index].info = none;
QJsonObject data;
m_images->fillJson(&data);
@@ -168,5 +176,3 @@ void AccountEmoticonModel::addEmoticon(const QUrl &source, const QString &shortc
{
doAddEmoticon(source, shortcode, description, type);
}
#include "moc_accountemoticonmodel.cpp"

View File

@@ -191,6 +191,7 @@ QVector<ActionsModel::Action> actions{
Q_EMIT room->showMessage(NeoChatRoom::Error, i18nc("'<text>' does not look like a matrix id.", "'%1' does not look like a matrix id.", text));
return QString();
}
#ifdef QUOTIENT_07
const RoomMemberEvent *roomMemberEvent = room->currentState().get<RoomMemberEvent>(text);
if (roomMemberEvent && roomMemberEvent->membership() == Membership::Invite) {
Q_EMIT room->showMessage(NeoChatRoom::Info, i18nc("<user> is already invited to this room.", "%1 is already invited to this room.", text));
@@ -200,6 +201,7 @@ QVector<ActionsModel::Action> actions{
Q_EMIT room->showMessage(NeoChatRoom::Info, i18nc("<user> is banned from this room.", "%1 is banned from this room.", text));
return QString();
}
#endif
if (room->localUser()->id() == text) {
Q_EMIT room->showMessage(NeoChatRoom::Positive, i18n("You are already in this room."));
return QString();
@@ -241,6 +243,7 @@ QVector<ActionsModel::Action> actions{
kli18n("<room alias or id>"),
kli18n("Joins the given room"),
},
#ifdef QUOTIENT_07
Action{
QStringLiteral("knock"),
[](const QString &text, NeoChatRoom *room) {
@@ -273,6 +276,7 @@ QVector<ActionsModel::Action> actions{
kli18n("<room alias or id> [<reason>]"),
kli18n("Requests to join the given room"),
},
#endif
Action{
QStringLiteral("j"),
[](const QString &text, NeoChatRoom *room) {
@@ -431,11 +435,13 @@ QVector<ActionsModel::Action> actions{
Q_EMIT room->showMessage(NeoChatRoom::Error, i18nc("'<text>' does not look like a matrix id.", "'%1' does not look like a matrix id.", text));
return QString();
}
#ifdef QUOTIENT_07
auto state = room->currentState().get<RoomMemberEvent>(parts[0]);
if (state && state->membership() == Membership::Ban) {
Q_EMIT room->showMessage(NeoChatRoom::Info, i18nc("<user> is already banned from this room.", "%1 is already banned from this room.", text));
return QString();
}
#endif
auto plEvent = room->getCurrentState<RoomPowerLevelsEvent>();
if (plEvent->ban() > plEvent->powerLevelForUser(room->localUser()->id())) {
Q_EMIT room->showMessage(NeoChatRoom::Error, i18n("You are not allowed to ban users from this room."));
@@ -471,11 +477,13 @@ QVector<ActionsModel::Action> actions{
Q_EMIT room->showMessage(NeoChatRoom::Error, i18n("You are not allowed to unban users from this room."));
return QString();
}
#ifdef QUOTIENT_07
auto state = room->currentState().get<RoomMemberEvent>(text);
if (state && state->membership() != Membership::Ban) {
Q_EMIT room->showMessage(NeoChatRoom::Info, i18nc("<user> is not banned from this room.", "%1 is not banned from this room.", text));
return QString();
}
#endif
room->unban(text);
Q_EMIT room->showMessage(NeoChatRoom::Positive, i18nc("<username> was unbanned from this room.", "%1 was unbanned from this room.", text));
@@ -502,10 +510,12 @@ QVector<ActionsModel::Action> actions{
Q_EMIT room->showMessage(NeoChatRoom::Error, i18n("You cannot kick yourself from the room."));
return QString();
}
#ifdef QUOTIENT_07
if (!room->isMember(parts[0])) {
Q_EMIT room->showMessage(NeoChatRoom::Error, i18nc("<username> is not in this room", "%1 is not in this room.", parts[0]));
return QString();
}
#endif
auto plEvent = room->getCurrentState<RoomPowerLevelsEvent>();
auto kick = plEvent->kick();
if (plEvent->powerLevelForUser(room->localUser()->id()) < kick) {

View File

@@ -61,7 +61,7 @@ public:
CompletionType, /**< The completion type (always "action" for this model). */
Parameters, /**< The input parameters expected by the action. */
};
Q_ENUM(Roles)
Q_ENUM(Roles);
/**
* @brief Get the given role value at the given index.

View File

@@ -2,6 +2,7 @@
// SPDX-License-Identifier: LGPL-2.0-or-later
#include "collapsestateproxymodel.h"
#include "messageeventmodel.h"
#include <KLocalizedString>
@@ -173,5 +174,3 @@ QString CollapseStateProxyModel::excessAuthors(int row) const
return QStringLiteral("+ %1").arg(excessAuthors);
}
}
#include "moc_collapsestateproxymodel.cpp"

View File

@@ -27,7 +27,6 @@ public:
StateEventsRole, /**< List of state events in the aggregated state. */
AuthorListRole, /**< List of the first 5 unique authors of the aggregated state event. */
ExcessAuthorsRole, /**< The number of unique authors beyond the first 5. */
LastRole, // Keep this last
};
/**

View File

@@ -193,5 +193,3 @@ void CompletionModel::setRoomListModel(RoomListModel *roomListModel)
m_roomListModel = roomListModel;
Q_EMIT roomListModelChanged();
}
#include "moc_completionmodel.cpp"

View File

@@ -69,7 +69,7 @@ public:
Icon, /**< The icon to show. */
ReplacedText, /**< The text to replace the input text with for the completion. */
};
Q_ENUM(Roles)
Q_ENUM(Roles);
CompletionModel(QObject *parent = nullptr);

View File

@@ -59,5 +59,3 @@ void CompletionProxyModel::setFullText(const QString &fullText)
{
m_fullText = fullText;
}
#include "moc_completionproxymodel.cpp"

View File

@@ -62,7 +62,11 @@ void CustomEmojiModel::addEmoji(const QString &name, const QUrl &location)
auto emojiData = json["images"].toObject();
QString url;
#ifdef QUOTIENT_07
url = job->contentUri().toString();
#else
url = job->contentUri();
#endif
QImage image(location.toLocalFile());
QJsonObject imageInfo;
@@ -204,5 +208,3 @@ QVariantList CustomEmojiModel::filterModel(const QString &filter)
}
return results;
}
#include "moc_customemojimodel.cpp"

View File

@@ -41,7 +41,7 @@ public:
ReplacedTextRole = 52, /**< The name of the emoji. For compatibility with EmojiModel. */
DescriptionRole = 53, /**< Invalid, reserved. For compatibility with EmojiModel. */
};
Q_ENUM(Roles)
Q_ENUM(Roles);
static CustomEmojiModel &instance()
{

View File

@@ -109,5 +109,3 @@ Connection *DevicesModel::connection() const
{
return Controller::instance().activeConnection();
}
#include "moc_devicesmodel.cpp"

View File

@@ -40,7 +40,7 @@ public:
LastIp, /**< The IP address where this device was last seen. */
LastTimestamp, /**< The timestamp when this devices was last seen. */
};
Q_ENUM(Roles)
Q_ENUM(Roles);
DevicesModel(QObject *parent = nullptr);

View File

@@ -216,5 +216,3 @@ QVariantList EmojiModel::categoriesWithCustom() const
;
return cats;
}
#include "moc_emojimodel.cpp"

View File

@@ -95,7 +95,7 @@ public:
ReplacedTextRole = 52, /**< The text to replace the short name with (i.e. the unicode character). */
DescriptionRole = 53, /**< The long description of an emoji. */
};
Q_ENUM(RoleNames)
Q_ENUM(RoleNames);
/**
* @brief Defines the potential categories an emoji can be placed in.

View File

@@ -53,5 +53,3 @@ void EmoticonFilterModel::setShowEmojis(bool showEmojis)
endResetModel();
Q_EMIT showEmojisChanged();
}
#include "moc_emoticonfiltermodel.cpp"

View File

@@ -1,8 +1,6 @@
// SPDX-FileCopyrightText: 2023 Tobias Fella <tobias.fella@kde.org>
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <QSortFilterProxyModel>
/**

View File

@@ -33,9 +33,13 @@ QVariant ImagePacksModel::data(const QModelIndex &index, int role) const
}
if (role == AvatarUrlRole) {
if (event.pack->avatarUrl) {
#ifdef QUOTIENT_07
return m_room->connection()->makeMediaUrl(*event.pack->avatarUrl);
#endif
} else if (!event.images.empty()) {
#ifdef QUOTIENT_07
return m_room->connection()->makeMediaUrl(event.images[0].url);
#endif
}
}
return {};
@@ -102,6 +106,7 @@ void ImagePacksModel::reloadImages()
auto packs = rooms[roomId].toObject();
const auto &stickerRoom = m_room->connection()->room(roomId);
for (const auto &packKey : packs.keys()) {
#ifdef QUOTIENT_07
if (const auto &pack = stickerRoom->currentState().get<ImagePackEvent>(packKey)) {
const auto packContent = pack->content();
if ((!packContent.pack || !packContent.pack->usage || (packContent.pack->usage->contains("emoticon") && showEmoticons())
@@ -110,9 +115,11 @@ void ImagePacksModel::reloadImages()
m_events += packContent;
}
}
#endif
}
}
}
#ifdef QUOTIENT_07
// Load emoticons from the current room
auto events = m_room->currentState().eventsOfType("im.ponies.room_emotes");
@@ -125,6 +132,7 @@ void ImagePacksModel::reloadImages()
}
}
}
#endif
Q_EMIT imagesLoaded();
endResetModel();
}
@@ -157,5 +165,3 @@ QVector<Quotient::ImagePackEventContent::ImagePackImage> ImagePacksModel::images
}
return m_events[index].images;
}
#include "moc_imagepacksmodel.cpp"

View File

@@ -47,7 +47,7 @@ public:
AttributionRole, /**< The attribution for the pack author(s). */
IdRole, /**< The ID of the image pack. */
};
Q_ENUM(Roles)
Q_ENUM(Roles);
explicit ImagePacksModel(QObject *parent = nullptr);

View File

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

View File

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

View File

@@ -4,7 +4,7 @@
#include "livelocationsmodel.h"
#include <events/roommessageevent.h>
#include <Quotient/events/roommessageevent.h>
#include <QDebug>
@@ -169,5 +169,3 @@ void LiveLocationsModel::updateLocationData(LiveLocationData &&data)
Q_EMIT dataChanged(idx, idx);
}
#include "moc_livelocationsmodel.cpp"

View File

@@ -8,7 +8,7 @@ using namespace Quotient;
LocationsModel::LocationsModel(QObject *parent)
: QAbstractListModel(parent)
{
connect(this, &LocationsModel::roomChanged, this, [this]() {
connect(this, &LocationsModel::roomChanged, this, [=]() {
for (const auto &event : m_room->messageEvents()) {
if (!is<RoomMessageEvent>(*event)) {
continue;
@@ -18,7 +18,7 @@ LocationsModel::LocationsModel(QObject *parent)
addLocation(eventCast<const RoomMessageEvent>(&e));
}
}
connect(m_room, &NeoChatRoom::aboutToAddHistoricalMessages, this, [this](const auto &events) {
connect(m_room, &NeoChatRoom::aboutToAddHistoricalMessages, this, [=](const auto &events) {
for (const auto &event : events) {
if (!is<RoomMessageEvent>(*event)) {
continue;
@@ -29,7 +29,7 @@ LocationsModel::LocationsModel(QObject *parent)
}
}
});
connect(m_room, &NeoChatRoom::aboutToAddNewMessages, this, [this](const auto &events) {
connect(m_room, &NeoChatRoom::aboutToAddNewMessages, this, [=](const auto &events) {
for (const auto &event : events) {
if (!is<RoomMessageEvent>(*event)) {
continue;
@@ -127,5 +127,3 @@ QRectF LocationsModel::boundingBox() const
}
return bbox;
}
#include "moc_locationsmodel.cpp"

View File

@@ -1,81 +0,0 @@
// 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-LGPL
#include "mediamessagefiltermodel.h"
#include "models/messageeventmodel.h"
#include <room.h>
MediaMessageFilterModel::MediaMessageFilterModel(QObject *parent)
: QSortFilterProxyModel(parent)
{
}
bool MediaMessageFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
{
const QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
if (index.data(MessageEventModel::DelegateTypeRole).toInt() == MessageEventModel::DelegateType::Image
|| index.data(MessageEventModel::DelegateTypeRole).toInt() == MessageEventModel::DelegateType::Video) {
return true;
}
return false;
}
QVariant MediaMessageFilterModel::data(const QModelIndex &index, int role) const
{
if (role == SourceRole) {
if (mapToSource(index).data(MessageEventModel::DelegateTypeRole).toInt() == MessageEventModel::DelegateType::Image) {
return mapToSource(index).data(MessageEventModel::MediaInfoRole).toMap()["source"].toUrl();
} else if (mapToSource(index).data(MessageEventModel::DelegateTypeRole).toInt() == MessageEventModel::DelegateType::Video) {
auto progressInfo = mapToSource(index).data(MessageEventModel::ProgressInfoRole).value<Quotient::FileTransferInfo>();
if (progressInfo.completed()) {
return mapToSource(index).data(MessageEventModel::ProgressInfoRole).value<Quotient::FileTransferInfo>().localPath;
} else {
return QUrl();
}
} else {
return QUrl();
}
}
if (role == TempSourceRole) {
return mapToSource(index).data(MessageEventModel::MediaInfoRole).toMap()["tempInfo"].toMap()["source"].toUrl();
}
if (role == TypeRole) {
if (mapToSource(index).data(MessageEventModel::DelegateTypeRole).toInt() == MessageEventModel::DelegateType::Image) {
return 0;
} else {
return 1;
}
}
if (role == CaptionRole) {
return mapToSource(index).data(Qt::DisplayRole);
}
if (role == SourceWidthRole) {
return mapToSource(index).data(MessageEventModel::MediaInfoRole).toMap()["width"].toFloat();
}
if (role == SourceHeightRole) {
return mapToSource(index).data(MessageEventModel::MediaInfoRole).toMap()["height"].toFloat();
}
return sourceModel()->data(mapToSource(index), role);
}
QHash<int, QByteArray> MediaMessageFilterModel::roleNames() const
{
auto roles = sourceModel()->roleNames();
roles[SourceRole] = "source";
roles[TempSourceRole] = "tempSource";
roles[TypeRole] = "type";
roles[CaptionRole] = "caption";
roles[SourceWidthRole] = "sourceWidth";
roles[SourceHeightRole] = "sourceHeight";
return roles;
}
int MediaMessageFilterModel::getRowForSourceItem(int sourceRow) const
{
return mapFromSource(sourceModel()->index(sourceRow, 0)).row();
}
#include "moc_mediamessagefiltermodel.cpp"

View File

@@ -1,56 +0,0 @@
// 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-LGPL
#pragma once
#include <QSortFilterProxyModel>
#include "models/collapsestateproxymodel.h"
/**
* @class MediaMessageFilterModel
*
* This model filters a MessageEventModel for image and video messages.
*
* @sa MessageEventModel
*/
class MediaMessageFilterModel : public QSortFilterProxyModel
{
Q_OBJECT
public:
/**
* @brief Defines the model roles.
*/
enum Roles {
SourceRole = CollapseStateProxyModel::LastRole + 1, /**< The mxc source URL for the item. */
TempSourceRole, /**< Source for the temporary content (either blurhash or mxc URL). */
TypeRole, /**< The type of the media (image or video). */
CaptionRole, /**< The caption for the item. */
SourceWidthRole, /**< The width of the source item. */
SourceHeightRole, /**< The height of the source item. */
};
Q_ENUM(Roles)
MediaMessageFilterModel(QObject *parent = nullptr);
/**
* @brief Custom filter to show only image and video messages.
*/
bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
/**
* @brief Get the given role value at the given index.
*
* @sa QSortFilterProxyModel::data
*/
[[nodiscard]] QVariant data(const QModelIndex &idx, int role = Qt::DisplayRole) const override;
/**
* @brief Returns a mapping from Role enum values to role names.
*
* @sa Roles, QAbstractProxyModel::roleNames()
*/
[[nodiscard]] QHash<int, QByteArray> roleNames() const override;
Q_INVOKABLE int getRowForSourceItem(int sourceRow) const;
};

View File

@@ -14,13 +14,16 @@
#include <qt_connection_util.h>
#include <user.h>
#ifdef QUOTIENT_07
#include "events/pollevent.h"
#endif
#include "events/stickerevent.h"
#include <QDebug>
#include <QGuiApplication>
#include <QTimeZone>
#include <KFormat>
#include <KLocalizedString>
#include "models/reactionmodel.h"
@@ -58,7 +61,7 @@ QHash<int, QByteArray> MessageEventModel::roleNames() const
roles[ShowReadMarkersRole] = "showReadMarkers";
roles[ReactionRole] = "reaction";
roles[ShowReactionsRole] = "showReactions";
roles[SourceRole] = "jsonSource";
roles[SourceRole] = "source";
roles[MimeTypeRole] = "mimeType";
roles[AuthorIdRole] = "authorId";
roles[VerifiedRole] = "verified";
@@ -115,7 +118,11 @@ void MessageEventModel::setRoom(NeoChatRoom *room)
if (m_currentRoom->timelineSize() < 10 && !room->allHistoryLoaded()) {
room->getPreviousContent(50);
}
#ifdef QUOTIENT_07
lastReadEventId = room->lastFullyReadEventId();
#else
lastReadEventId = room->readMarkerEventId();
#endif
connect(m_currentRoom, &NeoChatRoom::replyLoaded, this, [this](const auto &eventId, const auto &replyId) {
Q_UNUSED(replyId);
auto row = eventIdToRow(eventId);
@@ -185,7 +192,11 @@ void MessageEventModel::setRoom(NeoChatRoom *room)
}
if (!m_lastReadEventIndex.isValid()) {
// no read marker, so see if we need to create one.
#ifdef QUOTIENT_07
moveReadMarker(m_currentRoom->lastFullyReadEventId());
#else
moveReadMarker(m_currentRoom->readMarkerEventId());
#endif
}
if (biggest < m_currentRoom->maxTimelineIndex()) {
auto rowBelowInserted = m_currentRoom->maxTimelineIndex() - biggest + timelineBaseIndex() - 1;
@@ -254,6 +265,9 @@ void MessageEventModel::setRoom(NeoChatRoom *room)
connect(m_currentRoom, &Room::fileTransferProgress, this, &MessageEventModel::refreshEvent);
connect(m_currentRoom, &Room::fileTransferCompleted, this, &MessageEventModel::refreshEvent);
connect(m_currentRoom, &Room::fileTransferFailed, this, &MessageEventModel::refreshEvent);
#ifndef QUOTIENT_07
connect(m_currentRoom, &Room::fileTransferCancelled, this, &MessageEventModel::refreshEvent);
#endif
connect(m_currentRoom->connection(), &Connection::ignoredUsersListChanged, this, [this] {
beginResetModel();
endResetModel();
@@ -519,12 +533,14 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
if (is<const EncryptedEvent>(evt)) {
return DelegateType::Encrypted;
}
#ifdef QUOTIENT_07
if (is<PollStartEvent>(evt)) {
if (evt.isRedacted()) {
return DelegateType::Message;
}
return DelegateType::Poll;
}
#endif
return DelegateType::Other;
}
@@ -796,6 +812,7 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
}
if (role == ReadMarkersRole) {
#ifdef QUOTIENT_07
auto userIds_temp = room()->userIdsAtEvent(evt.id());
userIds_temp.remove(m_currentRoom->localUser()->id());
@@ -803,11 +820,19 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
if (userIds.count() > 5) {
userIds = userIds.mid(0, 5);
}
#else
auto userIds = room()->usersAtEventId(evt.id());
userIds.removeAll(m_currentRoom->localUser());
#endif
QVariantList users;
users.reserve(userIds.size());
for (const auto &userId : userIds) {
#ifdef QUOTIENT_07
auto user = static_cast<NeoChatUser *>(m_currentRoom->user(userId));
#else
auto user = static_cast<NeoChatUser *>(userId);
#endif
users += m_currentRoom->getUser(user);
}
@@ -815,8 +840,13 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
}
if (role == ExcessReadMarkersRole) {
#ifdef QUOTIENT_07
auto userIds = room()->userIdsAtEvent(evt.id());
userIds.remove(m_currentRoom->localUser()->id());
#else
auto userIds = room()->usersAtEventId(evt.id());
userIds.removeAll(m_currentRoom->localUser());
#endif
if (userIds.count() > 5) {
return QStringLiteral("+ ") + QString::number(userIds.count() - 5);
@@ -826,16 +856,24 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
}
if (role == ReadMarkersStringRole) {
#ifdef QUOTIENT_07
auto userIds = room()->userIdsAtEvent(evt.id());
userIds.remove(m_currentRoom->localUser()->id());
#else
auto userIds = room()->usersAtEventId(evt.id());
userIds.removeAll(m_currentRoom->localUser());
#endif
/**
* The string ends up in the form
* "x users: user1DisplayName, user2DisplayName, etc."
*/
QString readMarkersString = i18np("1 user: ", "%1 users: ", userIds.size());
for (const auto &userId : userIds) {
#ifdef QUOTIENT_07
auto user = static_cast<NeoChatUser *>(m_currentRoom->user(userId));
#else
auto user = static_cast<NeoChatUser *>(userId);
#endif
readMarkersString += user->displayname(m_currentRoom) + i18nc("list separator", ", ");
}
readMarkersString.chop(2);
@@ -843,8 +881,13 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
}
if (role == ShowReadMarkersRole) {
#ifdef QUOTIENT_07
auto userIds = room()->userIdsAtEvent(evt.id());
userIds.remove(m_currentRoom->localUser()->id());
#else
auto userIds = room()->usersAtEventId(evt.id());
userIds.removeAll(m_currentRoom->localUser());
#endif
return userIds.size() > 0;
}
@@ -865,12 +908,14 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
}
if (role == VerifiedRole) {
#ifdef QUOTIENT_07
#ifdef Quotient_E2EE_ENABLED
if (evt.originalEvent()) {
auto encrypted = dynamic_cast<const EncryptedEvent *>(evt.originalEvent());
Q_ASSERT(encrypted);
return m_currentRoom->connection()->isVerifiedSession(encrypted->sessionId().toLatin1());
}
#endif
#endif
return false;
}
@@ -922,14 +967,22 @@ QVariantMap MessageEventModel::getMediaInfoForEvent(const RoomEvent &event) cons
// Get the file info for the event.
const EventContent::FileInfo *fileInfo;
#ifdef QUOTIENT_07
if (event.is<RoomMessageEvent>()) {
auto roomMessageEvent = eventCast<const RoomMessageEvent>(&event);
#else
if (auto roomMessageEvent = eventCast<const RoomMessageEvent>(&event)) {
#endif
if (!roomMessageEvent->hasFileContent()) {
return {};
}
fileInfo = roomMessageEvent->content()->fileInfo();
#ifdef QUOTIENT_07
} else if (event.is<StickerEvent>()) {
auto stickerEvent = eventCast<const StickerEvent>(&event);
#else
} else if (auto stickerEvent = eventCast<const StickerEvent>(&event)) {
#endif
fileInfo = &stickerEvent->image();
} else {
return {};
@@ -943,6 +996,7 @@ QVariantMap MessageEventModel::getMediaInfoFromFileInfo(const EventContent::File
QVariantMap mediaInfo;
// Get the mxc URL for the media.
#ifdef QUOTIENT_07
if (!fileInfo->url().isValid() || eventId.isEmpty()) {
mediaInfo["source"] = QUrl();
} else {
@@ -954,6 +1008,13 @@ QVariantMap MessageEventModel::getMediaInfoFromFileInfo(const EventContent::File
mediaInfo["source"] = QUrl();
}
}
#else
auto url = QUrl(m_currentRoom->connection()->homeserver().toString() + "/_matrix/media/r0/download/" + fileInfo->url.toString().remove("mxc://"));
QUrlQuery q(url.query());
q.addQueryItem("allow_remote", "true");
url.setQuery(q);
mediaInfo["source"] = url;
#endif
auto mimeType = fileInfo->mimeType;
// Add the MIME type for the media if available.
@@ -1102,5 +1163,3 @@ void MessageEventModel::createReactionModelForEvent(const Quotient::RoomMessageE
}
}
}
#include "moc_messageeventmodel.cpp"

View File

@@ -56,7 +56,7 @@ public:
LiveLocation, /**< The initial event of a shared live location (i.e., the place where this is supposed to be shown in the timeline). */
Other, /**< Anything that cannot be classified as another type. */
};
Q_ENUM(DelegateType)
Q_ENUM(DelegateType);
/**
* @brief Defines the model roles.

View File

@@ -49,5 +49,3 @@ bool MessageFilterModel::filterAcceptsRow(int sourceRow, const QModelIndex &sour
return true;
}
#include "moc_messagefiltermodel.cpp"

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