Compare commits

...

35 Commits

Author SHA1 Message Date
l10n daemon script
9c42b3c1a7 GIT_SILENT Sync po/docbooks with svn 2023-07-27 03:12:00 +00:00
l10n daemon script
d45cd5d9c9 GIT_SILENT made messages (after extraction) 2023-07-27 02:26:28 +00:00
Joshua Goins
8c503b8258 Use prettier notification images
Avatars are shown rounded in the main interface, so they should look the
same in the notification tray too. On top of that, if the room is a
group then show that group's icon when applicable in the bottom right.


(cherry picked from commit 470418f14f)
2023-07-26 10:31:47 +02:00
Joshua Goins
7078caac15 Fix errors preventing the avatar from being shown when uploaded
(cherry picked from commit 807a9ee779)
2023-07-26 10:29:06 +02:00
Joshua Goins
94bf65ab43 Add an obvious "upload" button in the account editor
It's not obvious at first glance that you can click on the avatar in the
account editor to upload an image. This adds a new button when there is
no image uploaded.


(cherry picked from commit 0ac3932303)
2023-07-26 10:28:32 +02:00
Joshua Goins
244e93c926 Fix settings button tooltip
(cherry picked from commit 4f32a168cd)
2023-07-26 08:38:06 +02:00
l10n daemon script
412856e882 GIT_SILENT Sync po/docbooks with svn 2023-07-26 03:13:49 +00:00
l10n daemon script
2421f11717 GIT_SILENT Sync po/docbooks with svn 2023-07-25 03:20:17 +00:00
l10n daemon script
2d42cfedec GIT_SILENT made messages (after extraction) 2023-07-25 02:30:45 +00:00
l10n daemon script
9308c84696 GIT_SILENT Sync po/docbooks with svn 2023-07-24 11:06:34 +00:00
l10n daemon script
72fc242364 SVN_SILENT made messages (.desktop file) - always resolve ours
In case of conflict in i18n, keep the version of the branch "ours"
To resolve a particular conflict, "git checkout --ours path/to/file.desktop"
2023-07-24 10:47:48 +00:00
Carl Schwan
7d3240c597 Refactor completion menu
- Use new Avatar
- Use required property in delegate


(cherry picked from commit 75cd77facb)
2023-07-24 10:46:57 +02:00
Carl Schwan
9906ba8b7d Move no connection info message to the top
(cherry picked from commit f8d3e25f8e)
2023-07-24 10:46:35 +02:00
Tobias Fella
b949092bc6 Fix clearing user search field text when switching rooms
(cherry picked from commit 9ba6b2f0a5)
2023-07-24 10:46:16 +02:00
Tobias Fella
5cce3bd692 Fix nullptr check 2023-07-23 23:12:01 +02:00
Carl Schwan
ef5d67e5bf Add back some spacing around the avatar in the timeline
(cherry picked from commit b486cb905c)
2023-07-22 22:32:28 +02:00
Carl Schwan
4711b954c5 Fix accessibility of StartChatPage and port to new components
(cherry picked from commit cdd5c9f484)
2023-07-22 22:32:27 +02:00
Carl Schwan
1688b00f48 Port Avatar usage in Settings KirigamiAddons
(cherry picked from commit 3e6c426397)
2023-07-22 22:32:27 +02:00
Carl Schwan
410befa4bf Port most Avatar usage to new KirigamiAddons Avatar
(cherry picked from commit 847f41e1ad)
2023-07-22 22:32:27 +02:00
Carl Schwan
b380c74b0e Remove hover effect on timeline events 2023-07-22 22:32:20 +02:00
Carl Schwan
da8227931f Remove duplicated code in QuickSwitcher for RoomDelegate 2023-07-22 22:31:42 +02:00
Carl Schwan
fdc45ec5c8 Redesign room list
Use KirigamiAddons.Delegated.RoundedItemDelegate
2023-07-22 22:31:38 +02:00
Carl Schwan
94dd69ea02 Scroll to top of RoomDrawer on loading of header
(cherry picked from commit c8b4da2b96)
2023-07-22 17:53:06 +00:00
Carl Schwan
80c3253a6e Discard wrong avatar urls
(cherry picked from commit ed5bb270ff)
2023-07-22 17:51:46 +00:00
l10n daemon script
c5f6a6607e GIT_SILENT Sync po/docbooks with svn 2023-07-21 03:39:31 +00:00
l10n daemon script
a10d5cbe75 GIT_SILENT Sync po/docbooks with svn 2023-07-20 03:31:32 +00:00
l10n daemon script
584cad19b1 GIT_SILENT made messages (after extraction) 2023-07-20 02:45:39 +00:00
Carl Schwan
3745414635 Port to KirigamAddons.Banner
(cherry picked from commit 3263a69880)
2023-07-19 22:48:56 +02:00
l10n daemon script
147ce42c04 GIT_SILENT Sync po/docbooks with svn 2023-07-19 05:18:38 +00:00
l10n daemon script
928feeca82 GIT_SILENT made messages (after extraction) 2023-07-18 08:31:37 +00:00
Tobias Fella
fc04af536d Fix opening user mentions
(cherry picked from commit 646c8ba8fe)
2023-07-18 08:06:16 +02:00
Tobias Fella
12b949d6cb Fix image loading in room avatars
(cherry picked from commit 918e805718)
2023-07-18 05:26:04 +00:00
l10n daemon script
6aaaabf159 GIT_SILENT Sync po/docbooks with svn 2023-07-18 04:13:52 +00:00
l10n daemon script
fe45ef85a6 GIT_SILENT made messages (after extraction) 2023-07-18 02:55:30 +00:00
Albert Astals Cid
13e38ed982 GIT_SILENT Upgrade release service version to 23.07.80. 2023-07-17 11:25:34 +02:00
92 changed files with 10361 additions and 14450 deletions

View File

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

View File

@@ -40,7 +40,6 @@
<name xml:lang="ru">NeoChat</name> <name xml:lang="ru">NeoChat</name>
<name xml:lang="sk">NeoChat</name> <name xml:lang="sk">NeoChat</name>
<name xml:lang="sl">NeoChat</name> <name xml:lang="sl">NeoChat</name>
<name xml:lang="sv">NeoChat</name>
<name xml:lang="ta">நியோச்சாட்</name> <name xml:lang="ta">நியோச்சாட்</name>
<name xml:lang="tr">NeoChat</name> <name xml:lang="tr">NeoChat</name>
<name xml:lang="uk">NeoChat</name> <name xml:lang="uk">NeoChat</name>
@@ -77,7 +76,6 @@
<summary xml:lang="ru">Клиент для Matrix — децентрализованного коммуникационного протокола</summary> <summary xml:lang="ru">Клиент для Matrix — децентрализованного коммуникационного протокола</summary>
<summary xml:lang="sk">Klient pre matrix, decentralizovaný komunikačný protokol</summary> <summary xml:lang="sk">Klient pre matrix, decentralizovaný komunikačný protokol</summary>
<summary xml:lang="sl">Odjemalec za matrix, decentralizirani komunikacijski protokol</summary> <summary xml:lang="sl">Odjemalec za matrix, decentralizirani komunikacijski protokol</summary>
<summary xml:lang="sv">En klient för Matrix, det decentraliserade kommunikationsprotokollet</summary>
<summary xml:lang="ta">மையமில்லா தகவல் பரிமாற்ற நெறிமுறையான மேட்ரிக்ஸுக்கான செயலி</summary> <summary xml:lang="ta">மையமில்லா தகவல் பரிமாற்ற நெறிமுறையான மேட்ரிக்ஸுக்கான செயலி</summary>
<summary xml:lang="tr">Merkezi olmayan iletişim protokolü Matrix için bir istemci</summary> <summary xml:lang="tr">Merkezi olmayan iletişim protokolü Matrix için bir istemci</summary>
<summary xml:lang="uk">Клієнт matrix, децентралізованого протоколу обміну даними</summary> <summary xml:lang="uk">Клієнт matrix, децентралізованого протоколу обміну даними</summary>
@@ -98,6 +96,7 @@ to provide a convergent experience across multiple platforms.</p>
<p xml:lang="ia">NeoChat es un cliente per Matrix, le protocollo de communication decentralisate per messager instantanee. Illo te permitte inviar messager de texto, files de video e audio a tu familia, collegas e amicos usante. Illo usa KDE frameworks e super toto Kirigamii forni un experientia convergente trans platteforme multiple.</p> <p xml:lang="ia">NeoChat es un cliente per Matrix, le protocollo de communication decentralisate per messager instantanee. Illo te permitte inviar messager de texto, files de video e audio a tu familia, collegas e amicos usante. Illo usa KDE frameworks e super toto Kirigamii forni un experientia convergente trans platteforme multiple.</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="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="ka">NeoChat არის Matrix კლიენტი. ის საშუალებას გაძლევთ გაგზავნოთ ტექსტური შეტყობინებები, ვიდეოები და აუდიო ფაილები თქვენს ოჯახს, კოლეგებსა და მეგობრებს მატრიქსის პროტოკოლის გამოყენებით.</p>
<p xml:lang="ko">NeoChat은 분산형 인스턴트 메시징 통신 프로토콜인 Matrix 클라이언트입니다. 가족, 동료, 친구에게 텍스트 메시지, 동영상, 오디오 파일을 전송할 수 있습니다. KDE 프레임워크와 Kirigami를 사용하여 다양한 플랫폼에서 일관적인 사용자 경험을 제공합니다.</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="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="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="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>
@@ -118,6 +117,7 @@ to provide a convergent experience across multiple platforms.</p>
<p xml:lang="ia">NeoChat aspira a esser un application plenemente eminente per le specification de Matrix. Tal como omne cosas in le specification currentemente stabile con le exceptiones notabile de VOIP, threads e alcun aspectos del cryptation End-to-End es supportate. Il ha ltere pauc omissiones, debite al facto que le specification de Matrix es in evolution constante ma le aspiration remane a fornir supporto eventual per le integre specification.</p> <p xml:lang="ia">NeoChat aspira a esser un application plenemente eminente per le specification de Matrix. Tal como omne cosas in le specification currentemente stabile con le exceptiones notabile de VOIP, threads e alcun aspectos del cryptation End-to-End es supportate. Il ha ltere pauc omissiones, debite al facto que le specification de Matrix es in evolution constante ma le aspiration remane a fornir supporto eventual per le integre specification.</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="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="ka">NeoChat-ი მიზნად ისახავს Matrix სპეციფიკაციის სრული განხორციელება ჰქონდეს. როგორც ასეთი, ყველაფერი მიმდინარე სპეციფიკაციიდან, VoIP-ის, ძაფებისა და გამჭოლი დაშიფვრის ზოგიერთი ასპექტის გარდა, მხარდაჭერილია. შეძლება ასევე იყოს მცირე ლაფსუსებიც იმის გამო, რომ Matrix-ის სპეციფიკაცია მუდმივად ვითარგდება, მაგრამ ჩვენი მიზანი მისი სრული მხარდაჭერაა.</p>
<p xml:lang="ko">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="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="nn">NeoChat har som mål å støtta all funksjonalitet i Matrix-spesifikasjonen. Førebels er alt i den gjeldande stabile spesifikasjonen støtta, med unntak av VoIP, trådar og nokre delar av ende-til-kryptering. Det finst òg andre småting som ikkje er støtta, sidan Matrix-spesifikasjon er i stadig endring, men målet er altså støtte for alt.</p>
<p xml:lang="pl">NeoChat w zamyśle ma być pełnowartościową aplikacją wg wytycznych Matriksa. Z tego powodu, wszystko, co jest obecnie w stabilnych wytycznych z pominięciem VoIP, wątków i niektórych części szyfrowania Użytkownik-do-Użytkownika są obecnie obsługiwane. Pominięto też kilka mniejszych rzeczy ze względu na ciągły rozwój wytycznych Matriksa, lecz celem nadal jest zapewnienie obsługi wszystkich wytycznych.</p> <p xml:lang="pl">NeoChat w zamyśle ma być pełnowartościową aplikacją wg wytycznych Matriksa. Z tego powodu, wszystko, co jest obecnie w stabilnych wytycznych z pominięciem VoIP, wątków i niektórych części szyfrowania Użytkownik-do-Użytkownika są obecnie obsługiwane. Pominięto też kilka mniejszych rzeczy ze względu na ciągły rozwój wytycznych Matriksa, lecz celem nadal jest zapewnienie obsługi wszystkich wytycznych.</p>
@@ -138,6 +138,7 @@ to provide a convergent experience across multiple platforms.</p>
<p xml:lang="ia">Debite al natura del disveloppamento de specification de Matrix NeoChat tamben supporta numerose characteristicas instabile. Currentemente istes es:</p> <p xml:lang="ia">Debite al natura del disveloppamento de specification de Matrix NeoChat tamben supporta numerose characteristicas instabile. Currentemente istes es:</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="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="ka">Matrix-ის სპეციფიკაციის განვითარების ბუნების გამო NeoChat-ს ასევე აქვს უამრავი არასტაბილური ფუნქციაც. ახლა ისინია:</p>
<p xml:lang="ko">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="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="nn">På grunn av måten Matrix-spesifikasjonen vert utvikla på, støttar NeoChat òg nokre uferdige funksjonar:</p>
<p xml:lang="pl">Ze względu na sposób rozwoju Matriksa, NeoChat obsługuje także kilka niestabilnych możliwości. Obecnie są to:</p> <p xml:lang="pl">Ze względu na sposób rozwoju Matriksa, NeoChat obsługuje także kilka niestabilnych możliwości. Obecnie są to:</p>
@@ -159,6 +160,7 @@ to provide a convergent experience across multiple platforms.</p>
<li xml:lang="ia">Inquestas - MSC3381</li> <li xml:lang="ia">Inquestas - MSC3381</li>
<li xml:lang="it">Sondaggi - MSC3381</li> <li xml:lang="it">Sondaggi - MSC3381</li>
<li xml:lang="ka">Polls - MSC3381</li> <li xml:lang="ka">Polls - MSC3381</li>
<li xml:lang="ko">투표 - MSC3381</li>
<li xml:lang="nl">Polls - MSC3381</li> <li xml:lang="nl">Polls - MSC3381</li>
<li xml:lang="nn">Avstemmingar  MSC3381</li> <li xml:lang="nn">Avstemmingar  MSC3381</li>
<li xml:lang="pt">Inquéritos - MSC3381</li> <li xml:lang="pt">Inquéritos - MSC3381</li>
@@ -179,6 +181,7 @@ to provide a convergent experience across multiple platforms.</p>
<li xml:lang="ia">Etiquetta gummate (sticker) -MSC2545</li> <li xml:lang="ia">Etiquetta gummate (sticker) -MSC2545</li>
<li xml:lang="it">Pacchetti di adesivi - MSC2545</li> <li xml:lang="it">Pacchetti di adesivi - MSC2545</li>
<li xml:lang="ka">სტიკერების პაკეტები - MSC2545</li> <li xml:lang="ka">სტიკერების პაკეტები - MSC2545</li>
<li xml:lang="ko">스티커 팩 - MSC2545</li>
<li xml:lang="nl">Sticker Packs - MSC2545</li> <li xml:lang="nl">Sticker Packs - MSC2545</li>
<li xml:lang="nn">Klistremerke-pakkar  MSC2545</li> <li xml:lang="nn">Klistremerke-pakkar  MSC2545</li>
<li xml:lang="pt">Pacotes de Autocolantes - MSC2545</li> <li xml:lang="pt">Pacotes de Autocolantes - MSC2545</li>
@@ -199,6 +202,7 @@ to provide a convergent experience across multiple platforms.</p>
<li xml:lang="ia">Eventos de Location - MSC3488</li> <li xml:lang="ia">Eventos de Location - MSC3488</li>
<li xml:lang="it">Località eventi - MSC3488</li> <li xml:lang="it">Località eventi - MSC3488</li>
<li xml:lang="ka">მდებარეობის მოვლენები - MSC3488</li> <li xml:lang="ka">მდებარეობის მოვლენები - MSC3488</li>
<li xml:lang="ko">위치 이벤트 - MSC3488</li>
<li xml:lang="nl">Locatie gebeurtenissen - MSC3488</li> <li xml:lang="nl">Locatie gebeurtenissen - MSC3488</li>
<li xml:lang="nn">Posisjonshendingar  MSC3488</li> <li xml:lang="nn">Posisjonshendingar  MSC3488</li>
<li xml:lang="pt">Eventos com Localizações - MSC3488</li> <li xml:lang="pt">Eventos com Localizações - MSC3488</li>
@@ -245,7 +249,6 @@ to provide a convergent experience across multiple platforms.</p>
<developer_name xml:lang="ru">Сообщество KDE</developer_name> <developer_name xml:lang="ru">Сообщество KDE</developer_name>
<developer_name xml:lang="sk">KDE Komunita</developer_name> <developer_name xml:lang="sk">KDE Komunita</developer_name>
<developer_name xml:lang="sl">Skupnost KDE</developer_name> <developer_name xml:lang="sl">Skupnost KDE</developer_name>
<developer_name xml:lang="sv">KDE-gemenskapen</developer_name>
<developer_name xml:lang="ta">கே.டீ.யீ. சமூகம்</developer_name> <developer_name xml:lang="ta">கே.டீ.யீ. சமூகம்</developer_name>
<developer_name xml:lang="tr">KDE Topluluğu</developer_name> <developer_name xml:lang="tr">KDE Topluluğu</developer_name>
<developer_name xml:lang="uk">Спільнота KDE</developer_name> <developer_name xml:lang="uk">Спільнота KDE</developer_name>
@@ -267,10 +270,14 @@ to provide a convergent experience across multiple platforms.</p>
<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="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="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="fr">Vue principale avec la liste des salons ainsi que des informations sur les salons et forums de discussions</value> <value key="KDE::windows_store::screenshots::1::caption" xml:lang="fr">Vue principale avec la liste des salons ainsi que des informations sur les salons et forums de discussions</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="ia">Vista principal con lista de sala, chat e information de sala</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="it">Vista principale con elenco delle stanze, chat e informazioni sulla stanza</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="ka">მთავარი ხედი სურათების სიით, ჩატით და ოთახის ინფორმაციით</value> <value key="KDE::windows_store::screenshots::1::caption" xml:lang="ka">მთავარი ხედი სურათების სიით, ჩატით და ოთახის ინფორმაციით</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="ko">대화방 목록, 채팅, 대화방 정보가 표시된 주 보기</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="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="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="sl">Glavni pogled s seznamom sob, klepetom in informacijami o sobah</value>
<value key="KDE::windows_store::screenshots::1::caption" xml:lang="ta">அரங்குப்பட்டியல், உரையாடல், மற்றும் அரங்குவிவரங்களைக் கொண்டுள்ள பிரதான காட்சி</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="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="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::1::caption" xml:lang="x-test">xxMain view with room list, chat, and room informationxx</value>
@@ -280,10 +287,14 @@ to provide a convergent experience across multiple platforms.</p>
<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="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="es">Pantalla de inicio de sesión</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="fr">Écran de connexion</value> <value key="KDE::windows_store::screenshots::2::caption" xml:lang="fr">Écran de connexion</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="ia">Schermo de accesso</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="it">Schermata di accesso</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="ka">შესვლის ეკრანი</value> <value key="KDE::windows_store::screenshots::2::caption" xml:lang="ka">შესვლის ეკრანი</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="ko">로그인 화면</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="nl">Aanmeldscherm</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="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="sl">Prijavni zaslon</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="ta">நுழைவுத் திரை</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="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="uk">Вікно входу</value>
<value key="KDE::windows_store::screenshots::2::caption" xml:lang="x-test">xxLogin screenxx</value> <value key="KDE::windows_store::screenshots::2::caption" xml:lang="x-test">xxLogin screenxx</value>

View File

@@ -35,7 +35,6 @@ Name[ro]=NeoChat
Name[ru]=NeoChat Name[ru]=NeoChat
Name[sk]=NeoChat Name[sk]=NeoChat
Name[sl]=NeoChat Name[sl]=NeoChat
Name[sv]=NeoChat
Name[ta]=நியோச்சாட் Name[ta]=நியோச்சாட்
Name[tr]=NeoChat Name[tr]=NeoChat
Name[uk]=NeoChat Name[uk]=NeoChat
@@ -74,7 +73,6 @@ GenericName[ro]=Client Matrix
GenericName[ru]=Клиент Matrix GenericName[ru]=Клиент Matrix
GenericName[sk]=Matrix Client GenericName[sk]=Matrix Client
GenericName[sl]=Odjemalec Matrix GenericName[sl]=Odjemalec Matrix
GenericName[sv]=Matrix-klient
GenericName[ta]=Matrix வாங்கி GenericName[ta]=Matrix வாங்கி
GenericName[tr]=Matrix İstemcisi GenericName[tr]=Matrix İstemcisi
GenericName[uk]=Клієнт Matrix GenericName[uk]=Клієнт Matrix
@@ -112,7 +110,6 @@ Comment[ro]=Client pentru protocolul Matrix
Comment[ru]=Клиент для протокола Matrix Comment[ru]=Клиент для протокола Matrix
Comment[sk]=Klient protokolu Matrix Comment[sk]=Klient protokolu Matrix
Comment[sl]=Odjemalec za protokol Matrix Comment[sl]=Odjemalec za protokol Matrix
Comment[sv]=Klient för protokollet Matrix
Comment[ta]=Matrix நெறிமுறைக்கான வாங்கி Comment[ta]=Matrix நெறிமுறைக்கான வாங்கி
Comment[tr]=Matrix protokolü için istemci Comment[tr]=Matrix protokolü için istemci
Comment[uk]=Клієнт протоколу Matrix Comment[uk]=Клієнт протоколу 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

@@ -218,8 +218,8 @@ void ChatDocumentHandler::setRoom(NeoChatRoom *room)
void ChatDocumentHandler::complete(int index) void ChatDocumentHandler::complete(int index)
{ {
if (m_completionModel->autoCompletionType() == CompletionModel::User) { if (m_completionModel->autoCompletionType() == CompletionModel::User) {
auto name = m_completionModel->data(m_completionModel->index(index, 0), CompletionModel::Text).toString(); auto name = m_completionModel->data(m_completionModel->index(index, 0), CompletionModel::DisplayNameRole).toString();
auto id = m_completionModel->data(m_completionModel->index(index, 0), CompletionModel::Subtitle).toString(); auto id = m_completionModel->data(m_completionModel->index(index, 0), CompletionModel::SubtitleRole).toString();
auto text = getText(); auto text = getText();
auto at = text.lastIndexOf(QLatin1Char('@'), cursorPosition() - 1); auto at = text.lastIndexOf(QLatin1Char('@'), cursorPosition() - 1);
QTextCursor cursor(document()->textDocument()); QTextCursor cursor(document()->textDocument());
@@ -232,7 +232,7 @@ void ChatDocumentHandler::complete(int index)
pushMention({cursor, name, 0, 0, id}); pushMention({cursor, name, 0, 0, id});
m_highlighter->rehighlight(); m_highlighter->rehighlight();
} else if (m_completionModel->autoCompletionType() == CompletionModel::Command) { } else if (m_completionModel->autoCompletionType() == CompletionModel::Command) {
auto command = m_completionModel->data(m_completionModel->index(index, 0), CompletionModel::ReplacedText).toString(); auto command = m_completionModel->data(m_completionModel->index(index, 0), CompletionModel::ReplacedTextRole).toString();
auto text = getText(); auto text = getText();
auto at = text.lastIndexOf(QLatin1Char('/')); auto at = text.lastIndexOf(QLatin1Char('/'));
QTextCursor cursor(document()->textDocument()); QTextCursor cursor(document()->textDocument());
@@ -240,7 +240,7 @@ void ChatDocumentHandler::complete(int index)
cursor.setPosition(cursorPosition(), QTextCursor::KeepAnchor); cursor.setPosition(cursorPosition(), QTextCursor::KeepAnchor);
cursor.insertText(QStringLiteral("/%1 ").arg(command)); cursor.insertText(QStringLiteral("/%1 ").arg(command));
} else if (m_completionModel->autoCompletionType() == CompletionModel::Room) { } else if (m_completionModel->autoCompletionType() == CompletionModel::Room) {
auto alias = m_completionModel->data(m_completionModel->index(index, 0), CompletionModel::Subtitle).toString(); auto alias = m_completionModel->data(m_completionModel->index(index, 0), CompletionModel::SubtitleRole).toString();
auto text = getText(); auto text = getText();
auto at = text.lastIndexOf(QLatin1Char('#'), cursorPosition() - 1); auto at = text.lastIndexOf(QLatin1Char('#'), cursorPosition() - 1);
QTextCursor cursor(document()->textDocument()); QTextCursor cursor(document()->textDocument());
@@ -253,7 +253,7 @@ void ChatDocumentHandler::complete(int index)
pushMention({cursor, alias, 0, 0, alias}); pushMention({cursor, alias, 0, 0, alias});
m_highlighter->rehighlight(); m_highlighter->rehighlight();
} else if (m_completionModel->autoCompletionType() == CompletionModel::Emoji) { } else if (m_completionModel->autoCompletionType() == CompletionModel::Emoji) {
auto shortcode = m_completionModel->data(m_completionModel->index(index, 0), CompletionModel::ReplacedText).toString(); auto shortcode = m_completionModel->data(m_completionModel->index(index, 0), CompletionModel::ReplacedTextRole).toString();
auto text = getText(); auto text = getText();
auto at = text.lastIndexOf(QLatin1Char(':')); auto at = text.lastIndexOf(QLatin1Char(':'));
QTextCursor cursor(document()->textDocument()); QTextCursor cursor(document()->textDocument());

View File

@@ -32,11 +32,17 @@ ThumbnailResponse::ThumbnailResponse(QString id, QSize size)
requestedSize.setWidth(100); requestedSize.setWidth(100);
} }
if (mediaId.count('/') != 1) { if (mediaId.count('/') != 1) {
errorStr = i18n("Media id '%1' doesn't follow server/mediaId pattern", mediaId); if (mediaId.startsWith(QLatin1Char('/'))) {
Q_EMIT finished(); mediaId = mediaId.mid(1);
return; } else {
errorStr = i18n("Media id '%1' doesn't follow server/mediaId pattern", mediaId);
Q_EMIT finished();
return;
}
} }
mediaId = mediaId.split(QLatin1Char('?'))[0];
QImage cachedImage; QImage cachedImage;
if (cachedImage.load(localFile)) { if (cachedImage.load(localFile)) {
image = cachedImage; image = cachedImage;

View File

@@ -34,7 +34,7 @@ private Q_SLOTS:
void prepareResult(); void prepareResult();
private: private:
const QString mediaId; QString mediaId;
QSize requestedSize; QSize requestedSize;
const QString localFile; const QString localFile;
Quotient::MediaThumbnailJob *job = nullptr; Quotient::MediaThumbnailJob *job = nullptr;

View File

@@ -53,54 +53,54 @@ QVariant CompletionModel::data(const QModelIndex &index, int role) const
} }
auto filterIndex = m_filterModel->index(index.row(), 0); auto filterIndex = m_filterModel->index(index.row(), 0);
if (m_autoCompletionType == User) { if (m_autoCompletionType == User) {
if (role == Text) { if (role == DisplayNameRole) {
return m_filterModel->data(filterIndex, UserListModel::DisplayNameRole); return m_filterModel->data(filterIndex, UserListModel::DisplayNameRole);
} }
if (role == Subtitle) { if (role == SubtitleRole) {
return m_filterModel->data(filterIndex, UserListModel::UserIdRole); return m_filterModel->data(filterIndex, UserListModel::UserIdRole);
} }
if (role == Icon) { if (role == IconNameRole) {
return m_filterModel->data(filterIndex, UserListModel::AvatarRole); return m_filterModel->data(filterIndex, UserListModel::AvatarRole);
} }
} }
if (m_autoCompletionType == Command) { if (m_autoCompletionType == Command) {
if (role == Text) { if (role == DisplayNameRole) {
return m_filterModel->data(filterIndex, ActionsModel::Prefix).toString() + QStringLiteral(" ") return m_filterModel->data(filterIndex, ActionsModel::Prefix).toString() + QStringLiteral(" ")
+ m_filterModel->data(filterIndex, ActionsModel::Parameters).toString(); + m_filterModel->data(filterIndex, ActionsModel::Parameters).toString();
} }
if (role == Subtitle) { if (role == SubtitleRole) {
return m_filterModel->data(filterIndex, ActionsModel::Description); return m_filterModel->data(filterIndex, ActionsModel::Description);
} }
if (role == Icon) { if (role == IconNameRole) {
return QStringLiteral("invalid"); return QStringLiteral("invalid");
} }
if (role == ReplacedText) { if (role == ReplacedTextRole) {
return m_filterModel->data(filterIndex, ActionsModel::Prefix); return m_filterModel->data(filterIndex, ActionsModel::Prefix);
} }
} }
if (m_autoCompletionType == Room) { if (m_autoCompletionType == Room) {
if (role == Text) { if (role == DisplayNameRole) {
return m_filterModel->data(filterIndex, RoomListModel::DisplayNameRole); return m_filterModel->data(filterIndex, RoomListModel::DisplayNameRole);
} }
if (role == Subtitle) { if (role == SubtitleRole) {
return m_filterModel->data(filterIndex, RoomListModel::CanonicalAliasRole); return m_filterModel->data(filterIndex, RoomListModel::CanonicalAliasRole);
} }
if (role == Icon) { if (role == IconNameRole) {
return m_filterModel->data(filterIndex, RoomListModel::AvatarRole); return m_filterModel->data(filterIndex, RoomListModel::AvatarRole);
} }
} }
if (m_autoCompletionType == Emoji) { if (m_autoCompletionType == Emoji) {
if (role == Text) { if (role == DisplayNameRole) {
return m_filterModel->data(filterIndex, CustomEmojiModel::DisplayRole); return m_filterModel->data(filterIndex, CustomEmojiModel::DisplayRole);
} }
if (role == Icon) { if (role == IconNameRole) {
return m_filterModel->data(filterIndex, CustomEmojiModel::MxcUrl); return m_filterModel->data(filterIndex, CustomEmojiModel::MxcUrl);
} }
if (role == ReplacedText) { if (role == ReplacedTextRole) {
return m_filterModel->data(filterIndex, CustomEmojiModel::ReplacedTextRole); return m_filterModel->data(filterIndex, CustomEmojiModel::ReplacedTextRole);
} }
if (role == Subtitle) { if (role == SubtitleRole) {
return m_filterModel->data(filterIndex, EmojiModel::DescriptionRole); return m_filterModel->data(filterIndex, EmojiModel::DescriptionRole);
} }
} }
@@ -111,10 +111,10 @@ QVariant CompletionModel::data(const QModelIndex &index, int role) const
QHash<int, QByteArray> CompletionModel::roleNames() const QHash<int, QByteArray> CompletionModel::roleNames() const
{ {
return { return {
{Text, "text"}, {DisplayNameRole, "displayName"},
{Subtitle, "subtitle"}, {SubtitleRole, "subtitle"},
{Icon, "icon"}, {IconNameRole, "iconName"},
{ReplacedText, "replacedText"}, {ReplacedTextRole, "replacedText"},
}; };
} }

View File

@@ -64,10 +64,10 @@ public:
* @brief Defines the model roles. * @brief Defines the model roles.
*/ */
enum Roles { enum Roles {
Text = Qt::DisplayRole, /**< The main text to show. */ DisplayNameRole = Qt::DisplayRole, /**< The main text to show. */
Subtitle, /**< The subtitle text to show. */ SubtitleRole, /**< The subtitle text to show. */
Icon, /**< The icon to show. */ IconNameRole, /**< The icon to show. */
ReplacedText, /**< The text to replace the input text with for the completion. */ ReplacedTextRole, /**< The text to replace the input text with for the completion. */
}; };
Q_ENUM(Roles) Q_ENUM(Roles)

View File

@@ -338,7 +338,7 @@ QVariant RoomListModel::data(const QModelIndex &index, int role) const
if (role == AvatarImageRole) { if (role == AvatarImageRole) {
return room->avatar(128); return room->avatar(128);
} }
if (role == IdRole) { if (role == RoomIdRole) {
return room->id(); return room->id();
} }
if (role == IsSpaceRole) { if (role == IsSpaceRole) {
@@ -379,7 +379,7 @@ QHash<int, QByteArray> RoomListModel::roleNames() const
roles[CategoryVisibleRole] = "categoryVisible"; roles[CategoryVisibleRole] = "categoryVisible";
roles[SubtitleTextRole] = "subtitleText"; roles[SubtitleTextRole] = "subtitleText";
roles[IsSpaceRole] = "isSpace"; roles[IsSpaceRole] = "isSpace";
roles[IdRole] = "id"; roles[RoomIdRole] = "roomId";
roles[IsChildSpaceRole] = "isChildSpace"; roles[IsChildSpaceRole] = "isChildSpace";
return roles; return roles;
} }

View File

@@ -72,7 +72,7 @@ public:
CategoryVisibleRole, /**< If the room's category is visible. */ CategoryVisibleRole, /**< If the room's category is visible. */
SubtitleTextRole, /**< The text to show as the room subtitle. */ SubtitleTextRole, /**< The text to show as the room subtitle. */
AvatarImageRole, /**< The room avatar as an image. */ AvatarImageRole, /**< The room avatar as an image. */
IdRole, /**< The room matrix ID. */ RoomIdRole, /**< The room matrix ID. */
IsSpaceRole, /**< Whether the room is a space. */ IsSpaceRole, /**< Whether the room is a space. */
IsChildSpaceRole, /**< Whether this space is a child of a different space. */ IsChildSpaceRole, /**< Whether this space is a child of a different space. */
}; };

View File

@@ -87,7 +87,8 @@ bool SortFilterRoomListModel::filterAcceptsRow(int source_row, const QModelIndex
return acceptRoom; return acceptRoom;
} else { } else {
const auto &rooms = SpaceHierarchyCache::instance().getRoomListForSpace(m_activeSpaceId, false); const auto &rooms = SpaceHierarchyCache::instance().getRoomListForSpace(m_activeSpaceId, false);
return std::find(rooms.begin(), rooms.end(), sourceModel()->data(sourceModel()->index(source_row, 0), RoomListModel::IdRole).toString()) != rooms.end() return std::find(rooms.begin(), rooms.end(), sourceModel()->data(sourceModel()->index(source_row, 0), RoomListModel::RoomIdRole).toString())
!= rooms.end()
&& acceptRoom; && acceptRoom;
} }
} }

View File

@@ -8,7 +8,7 @@
SortFilterSpaceListModel::SortFilterSpaceListModel(QObject *parent) SortFilterSpaceListModel::SortFilterSpaceListModel(QObject *parent)
: QSortFilterProxyModel{parent} : QSortFilterProxyModel{parent}
{ {
setSortRole(RoomListModel::IdRole); setSortRole(RoomListModel::RoomIdRole);
sort(0); sort(0);
invalidateFilter(); invalidateFilter();
connect(this, &QAbstractProxyModel::sourceModelChanged, this, [this]() { connect(this, &QAbstractProxyModel::sourceModelChanged, this, [this]() {
@@ -33,8 +33,8 @@ bool SortFilterSpaceListModel::filterAcceptsRow(int source_row, const QModelInde
bool SortFilterSpaceListModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const bool SortFilterSpaceListModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const
{ {
const auto idLeft = sourceModel()->data(source_left, RoomListModel::IdRole).toString(); const auto idLeft = sourceModel()->data(source_left, RoomListModel::RoomIdRole).toString();
const auto idRight = sourceModel()->data(source_right, RoomListModel::IdRole).toString(); const auto idRight = sourceModel()->data(source_right, RoomListModel::RoomIdRole).toString();
return idLeft < idRight; return idLeft < idRight;
} }

View File

@@ -144,7 +144,7 @@ QVariant UserDirectoryListModel::data(const QModelIndex &index, int role) const
auto avatarUrl = user.avatarUrl; auto avatarUrl = user.avatarUrl;
if (avatarUrl.isEmpty()) { if (avatarUrl.isEmpty()) {
return ""; return QString();
} }
return avatarUrl.url().remove(0, 6); return avatarUrl.url().remove(0, 6);
} }
@@ -153,7 +153,7 @@ QVariant UserDirectoryListModel::data(const QModelIndex &index, int role) const
} }
if (role == DirectChatsRole) { if (role == DirectChatsRole) {
if (!m_connection) { if (!m_connection) {
return {}; return QStringList();
}; };
auto userObj = m_connection->user(user.userId); auto userObj = m_connection->user(user.userId);
@@ -165,6 +165,8 @@ QVariant UserDirectoryListModel::data(const QModelIndex &index, int role) const
return QVariant::fromValue(directChatsForUser); return QVariant::fromValue(directChatsForUser);
} }
} }
return QStringList();
} }
return {}; return {};

View File

@@ -33,7 +33,6 @@ Name[ro]=NeoChat
Name[ru]=NeoChat Name[ru]=NeoChat
Name[sk]=NeoChat Name[sk]=NeoChat
Name[sl]=NeoChat Name[sl]=NeoChat
Name[sv]=NeoChat
Name[ta]=நியோச்சாட் Name[ta]=நியோச்சாட்
Name[tr]=NeoChat Name[tr]=NeoChat
Name[uk]=NeoChat Name[uk]=NeoChat
@@ -73,7 +72,6 @@ Comment[ro]=Client pentru Matrix, protocolul de comunicare descentralizată
Comment[ru]=Клиент для Matrix — децентрализованного коммуникационного протокола Comment[ru]=Клиент для Matrix — децентрализованного коммуникационного протокола
Comment[sk]=Klient pre matrix, decentralizovaný komunikačný protokol Comment[sk]=Klient pre matrix, decentralizovaný komunikačný protokol
Comment[sl]=Odjemalec za decentralizirani komunikacijski protokol matrix Comment[sl]=Odjemalec za decentralizirani komunikacijski protokol matrix
Comment[sv]=En klient för matrix, det decentraliserade kommunikationsprotokollet
Comment[tr]=Merkezi olmayan iletişim protokolü Matrix için bir istemci Comment[tr]=Merkezi olmayan iletişim protokolü Matrix için bir istemci
Comment[uk]=Клієнт matrix, децентралізованого протоколу обміну даними Comment[uk]=Клієнт matrix, децентралізованого протоколу обміну даними
Comment[x-test]=xxA client for matrix, the decentralized communication protocolxx Comment[x-test]=xxA client for matrix, the decentralized communication protocolxx
@@ -114,7 +112,6 @@ Name[ro]=Mesaj nou
Name[ru]=Новое сообщение Name[ru]=Новое сообщение
Name[sk]=Nová správa Name[sk]=Nová správa
Name[sl]=Novo sporočilo Name[sl]=Novo sporočilo
Name[sv]=Nytt meddelande
Name[ta]=புதிய செய்தி Name[ta]=புதிய செய்தி
Name[tr]=Yeni ileti Name[tr]=Yeni ileti
Name[uk]=Нове повідомлення Name[uk]=Нове повідомлення
@@ -152,7 +149,6 @@ Comment[ro]=Este un mesaj nou
Comment[ru]=Доступно новое сообщение Comment[ru]=Доступно новое сообщение
Comment[sk]=Je nová správa Comment[sk]=Je nová správa
Comment[sl]=Prišlo je novo sporočilo Comment[sl]=Prišlo je novo sporočilo
Comment[sv]=Det finns ett nytt meddelande
Comment[ta]=ஒரு புதிய செய்தி உள்ளது Comment[ta]=ஒரு புதிய செய்தி உள்ளது
Comment[tr]=Yeni bir ileti var Comment[tr]=Yeni bir ileti var
Comment[uk]=Надійшло нове повідомлення Comment[uk]=Надійшло нове повідомлення
@@ -190,7 +186,6 @@ Name[pt]=Novo Convite
Name[pt_BR]=Novo convite Name[pt_BR]=Novo convite
Name[ru]=Новое приглашение Name[ru]=Новое приглашение
Name[sl]=Novo povabilo Name[sl]=Novo povabilo
Name[sv]=Ny inbjudan
Name[ta]=புதிய அழைப்பிதழ் Name[ta]=புதிய அழைப்பிதழ்
Name[tr]=Yeni Davet Name[tr]=Yeni Davet
Name[uk]=Нове запрошення Name[uk]=Нове запрошення
@@ -224,7 +219,6 @@ Comment[pt]=Existe um novo convite para uma sala
Comment[pt_BR]=Existe um novo convite para uma sala Comment[pt_BR]=Existe um novo convite para uma sala
Comment[ru]=Доступно новое приглашение в комнату Comment[ru]=Доступно новое приглашение в комнату
Comment[sl]=Tam je novo povabilo v sobo Comment[sl]=Tam je novo povabilo v sobo
Comment[sv]=Det finns en ny inbjudan till ett rum
Comment[ta]=ஓர் அரங்கிற்கான புதிய அழைப்பிதழ் உள்ளது Comment[ta]=ஓர் அரங்கிற்கான புதிய அழைப்பிதழ் உள்ளது
Comment[tr]=Bir odaya yeni bir davetiye var Comment[tr]=Bir odaya yeni bir davetiye var
Comment[uk]=У кімнаті нове запрошення Comment[uk]=У кімнаті нове запрошення

View File

@@ -993,7 +993,7 @@ void NeoChatRoom::deleteMessagesByUser(const QString &user, const QString &reaso
QString NeoChatRoom::joinRule() const QString NeoChatRoom::joinRule() const
{ {
auto joinRulesEvent = currentState().get<JoinRulesEvent>(); auto joinRulesEvent = currentState().get<JoinRulesEvent>();
if (joinRulesEvent) { if (!joinRulesEvent) {
return {}; return {};
} }
return joinRulesEvent->joinRule(); return joinRulesEvent->joinRule();
@@ -1941,7 +1941,7 @@ QByteArray NeoChatRoom::roomAcountDataJson(const QString &eventType)
QUrl NeoChatRoom::avatarForMember(NeoChatUser *user) const QUrl NeoChatRoom::avatarForMember(NeoChatUser *user) const
{ {
const auto &url = memberAvatarUrl(user->id()); const auto &url = memberAvatarUrl(user->id());
if (url.isEmpty()) { if (url.isEmpty() || url.scheme() != "mxc"_ls) {
return {}; return {};
} }
auto avatar = connection()->makeMediaUrl(url); auto avatar = connection()->makeMediaUrl(url);

View File

@@ -11,6 +11,7 @@
#include <KNotification> #include <KNotification>
#include <KNotificationReplyAction> #include <KNotificationReplyAction>
#include <QPainter>
#include <Quotient/accountregistry.h> #include <Quotient/accountregistry.h>
#include <Quotient/connection.h> #include <Quotient/connection.h>
#include <Quotient/csapi/pushrules.h> #include <Quotient/csapi/pushrules.h>
@@ -203,7 +204,7 @@ void NotificationsManager::postNotification(NeoChatRoom *room,
} }
notification->setText(notification->text() + '\n' + entry); notification->setText(notification->text() + '\n' + entry);
notification->setPixmap(QPixmap::fromImage(icon)); notification->setPixmap(createNotificationImage(icon, room));
notification->setDefaultAction(i18n("Open NeoChat in this room")); notification->setDefaultAction(i18n("Open NeoChat in this room"));
connect(notification, &KNotification::defaultActivated, this, [notification, room]() { connect(notification, &KNotification::defaultActivated, this, [notification, room]() {
@@ -239,7 +240,7 @@ void NotificationsManager::postInviteNotification(NeoChatRoom *room, const QStri
KNotification *notification = new KNotification("invite"); KNotification *notification = new KNotification("invite");
notification->setText(i18n("%1 invited you to a room", sender)); notification->setText(i18n("%1 invited you to a room", sender));
notification->setTitle(title); notification->setTitle(title);
notification->setPixmap(img); notification->setPixmap(createNotificationImage(icon, nullptr));
notification->setFlags(KNotification::Persistent); notification->setFlags(KNotification::Persistent);
notification->setDefaultAction(i18n("Open this invitation in NeoChat")); notification->setDefaultAction(i18n("Open this invitation in NeoChat"));
connect(notification, &KNotification::defaultActivated, this, [notification, room]() { connect(notification, &KNotification::defaultActivated, this, [notification, room]() {
@@ -282,4 +283,33 @@ void NotificationsManager::clearInvitationNotification(const QString &roomId)
} }
} }
QPixmap NotificationsManager::createNotificationImage(const QImage &icon, NeoChatRoom *room)
{
// Handle avatars that are lopsided in one dimension
const int biggestDimension = std::max(icon.width(), icon.height());
const QRect imageRect{0, 0, biggestDimension, biggestDimension};
QImage roundedImage(imageRect.size(), QImage::Format_ARGB32);
roundedImage.fill(Qt::transparent);
QPainter painter(&roundedImage);
painter.setRenderHint(QPainter::Antialiasing);
QBrush brush(icon.scaledToHeight(biggestDimension));
painter.setBrush(brush);
painter.drawRoundedRect(imageRect, imageRect.width(), imageRect.height());
if (room != nullptr) {
const QImage roomAvatar = room->avatar(imageRect.width(), imageRect.height());
if (icon != roomAvatar) {
const QRect lowerQuarter{imageRect.center(), imageRect.size() / 2};
painter.setBrush(roomAvatar.scaled(lowerQuarter.size()));
painter.drawRoundedRect(lowerQuarter, lowerQuarter.width(), lowerQuarter.height());
}
}
return QPixmap::fromImage(roundedImage);
}
#include "moc_notificationsmanager.cpp" #include "moc_notificationsmanager.cpp"

View File

@@ -97,4 +97,7 @@ private:
private Q_SLOTS: private Q_SLOTS:
void processNotificationJob(QPointer<Quotient::Connection> connection, Quotient::GetNotificationsJob *job, bool initialization); void processNotificationJob(QPointer<Quotient::Connection> connection, Quotient::GetNotificationsJob *job, bool initialization);
private:
QPixmap createNotificationImage(const QImage &icon, NeoChatRoom *room);
}; };

View File

@@ -34,7 +34,6 @@ Name[ro]=NeoChat
Name[ru]=NeoChat Name[ru]=NeoChat
Name[sk]=NeoChat Name[sk]=NeoChat
Name[sl]=NeoChat Name[sl]=NeoChat
Name[sv]=NeoChat
Name[ta]=நியோச்சாட் Name[ta]=நியோச்சாட்
Name[tr]=NeoChat Name[tr]=NeoChat
Name[uk]=NeoChat Name[uk]=NeoChat
@@ -67,7 +66,6 @@ Comment[pt]=Procurar salas no NeoChat
Comment[pt_BR]=Encontrar salas no NeoChat Comment[pt_BR]=Encontrar salas no NeoChat
Comment[ru]=Поиск комнат NeoChat Comment[ru]=Поиск комнат NeoChat
Comment[sl]=Najdi sobe v NeoChatu Comment[sl]=Najdi sobe v NeoChatu
Comment[sv]=Sök efter rum i NeoChat
Comment[ta]=நியோச்சாட்டில் அரங்குகளை கண்டுபிடிக்கும் Comment[ta]=நியோச்சாட்டில் அரங்குகளை கண்டுபிடிக்கும்
Comment[tr]=NeoChat'te odalar bulun Comment[tr]=NeoChat'te odalar bulun
Comment[uk]=Пошук кімнат у NeoChat Comment[uk]=Пошук кімнат у NeoChat

View File

@@ -6,185 +6,33 @@ import QtQuick 2.15
import QtQuick.Layouts 1.15 import QtQuick.Layouts 1.15
import QtQuick.Controls 2.15 as QQC2 import QtQuick.Controls 2.15 as QQC2
import QtQuick.Templates 2.15 as T import QtQuick.Templates 2.15 as T
import org.kde.kirigami 2.19 as Kirigami import org.kde.kirigami 2.20 as Kirigami
import org.kde.kirigamiaddons.delegates 1.0 as Delegates
import org.kde.kirigamiaddons.labs.components 1.0 as KirigamiComponents
T.TabButton { Delegates.RoundedItemDelegate {
id: control id: root
/** required property url source
* @brief This property specifies the index of this tab within the tab bar.
*/ signal contextMenuRequested()
readonly property int tabIndex: {
let tabIdx = 0 padding: Kirigami.Units.largeSpacing
for (let i = 0; i < parent.children.length; ++i) {
if (parent.children[i] === this) { QQC2.ToolTip.visible: hovered
return tabIdx QQC2.ToolTip.text: text
} QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
// Checking for AbstractButtons because any AbstractButton can act as a tab
if (parent.children[i] instanceof T.AbstractButton) { onPressAndHold: root.contextMenuRequested()
++tabIdx
} TapHandler {
} acceptedButtons: Qt.RightButton
return -1 acceptedDevices: PointerDevice.Mouse
onTapped: root.contextMenuRequested()
} }
/** contentItem: KirigamiComponents.Avatar {
* @brief This property sets whether the icon colors should be masked with a single color. source: root.source
* name: root.text
* default: ``true``
*
* @since KDE Frameworks 5.96
*/
property bool recolorIcon: true
property color foregroundColor: Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.85)
property color highlightForegroundColor: Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.85)
property color highlightBarColor: Kirigami.Theme.highlightColor
property color pressedColor: Qt.rgba(highlightBarColor.r, highlightBarColor.g, highlightBarColor.b, 0.3)
property color hoverSelectColor: Qt.rgba(highlightBarColor.r, highlightBarColor.g, highlightBarColor.b, 0.2)
property color checkedBorderColor: Qt.rgba(highlightBarColor.r, highlightBarColor.g, highlightBarColor.b, 0.7)
property color pressedBorderColor: Qt.rgba(highlightBarColor.r, highlightBarColor.g, highlightBarColor.b, 0.9)
property url source
property string name
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
implicitContentWidth + leftPadding + rightPadding)
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
implicitContentHeight + topPadding + bottomPadding)
display: T.AbstractButton.TextUnderIcon
Kirigami.Theme.colorSet: Kirigami.Theme.Window
Kirigami.Theme.inherit: false
// not using the hover handler built into control, since it seems to misbehave and
// permanently report hovered after a touch event
HoverHandler {
id: hoverHandler
}
padding: Kirigami.Units.smallSpacing
spacing: Kirigami.Units.smallSpacing
icon.height: control.display === T.AbstractButton.TextBesideIcon ? Kirigami.Units.iconSizes.small : Kirigami.Units.iconSizes.smallMedium
icon.width: control.display === T.AbstractButton.TextBesideIcon ? Kirigami.Units.iconSizes.small : Kirigami.Units.iconSizes.smallMedium
icon.color: control.checked ? control.highlightForegroundColor : control.foregroundColor
background: Rectangle {
Kirigami.Theme.colorSet: Kirigami.Theme.Button
Kirigami.Theme.inherit: false
implicitHeight: (control.display === T.AbstractButton.TextBesideIcon) ? 0 : (Kirigami.Units.gridUnit * 3 + Kirigami.Units.smallSpacing * 2)
color: "transparent"
Rectangle {
width: parent.width - Kirigami.Units.largeSpacing
height: parent.height - Kirigami.Units.largeSpacing
anchors.centerIn: parent
radius: Kirigami.Units.smallSpacing
color: control.down ? pressedColor : (control.checked || hoverHandler.hovered ? hoverSelectColor : "transparent")
border.color: control.checked ? checkedBorderColor : (control.down ? pressedBorderColor : color)
border.width: 1
Behavior on color { ColorAnimation { duration: Kirigami.Units.shortDuration } }
Behavior on border.color { ColorAnimation { duration: Kirigami.Units.shortDuration } }
}
}
contentItem: GridLayout {
id: gridLayout
columnSpacing: 0
rowSpacing: (label.visible && label.lineCount > 1) ? 0 : control.spacing
// if this is a row or a column
columns: control.display !== T.AbstractButton.TextBesideIcon ? 1 : 2
property real verticalMargins: (control.display === T.AbstractButton.TextBesideIcon) ? Kirigami.Units.largeSpacing : 0
Kirigami.Avatar {
id: icon
source: control.source
name: control.name
Layout.topMargin: gridLayout.verticalMargins
Layout.bottomMargin: gridLayout.verticalMargins
Layout.leftMargin: (control.display === T.AbstractButton.TextBesideIcon) ? Kirigami.Units.gridUnit : 0
Layout.rightMargin: (control.display === T.AbstractButton.TextBesideIcon) ? Kirigami.Units.gridUnit : 0
Layout.alignment: {
if (control.display === T.AbstractButton.TextBesideIcon) {
// row layout
return Qt.AlignVCenter | Qt.AlignRight;
} else {
// column layout
return Qt.AlignHCenter | ((!label.visible || label.lineCount > 1) ? Qt.AlignVCenter : Qt.AlignBottom);
}
}
Layout.preferredWidth: Kirigami.Units.iconSizes.medium
Layout.preferredHeight: Kirigami.Units.iconSizes.medium
}
QQC2.Label {
id: label
Kirigami.MnemonicData.enabled: control.enabled && control.visible
Kirigami.MnemonicData.controlType: Kirigami.MnemonicData.MenuItem
Kirigami.MnemonicData.label: control.text
text: Kirigami.MnemonicData.richTextLabel
horizontalAlignment: (control.display === T.AbstractButton.TextBesideIcon) ? Text.AlignLeft : Text.AlignHCenter
visible: control.display !== T.AbstractButton.IconOnly
wrapMode: Text.Wrap
elide: Text.ElideMiddle
color: control.checked ? control.highlightForegroundColor : control.foregroundColor
font.bold: control.checked
font.family: Kirigami.Theme.smallFont.family
font.pointSize: {
if (control.display === T.AbstractButton.TextBesideIcon) {
// row layout
return Kirigami.Theme.defaultFont.pointSize;
} else {
// column layout
return icon.visible ? Kirigami.Theme.smallFont.pointSize : Kirigami.Theme.defaultFont.pointSize * 1.20; // 1.20 is equivalent to level 2 heading
}
}
Behavior on color { ColorAnimation {} }
Behavior on opacity { NumberAnimation {} }
Layout.topMargin: gridLayout.verticalMargins
Layout.bottomMargin: gridLayout.verticalMargins
Layout.alignment: {
if (control.display === T.AbstractButton.TextBesideIcon) {
// row layout
return Qt.AlignVCenter | Qt.AlignLeft;
} else {
// column layout
return icon.visible ? Qt.AlignHCenter | Qt.AlignTop : Qt.AlignCenter;
}
}
// Work around bold text changing implicit size
Layout.preferredWidth: boldMetrics.implicitWidth
Layout.preferredHeight: boldMetrics.implicitHeight * label.lineCount
Layout.fillWidth: true
QQC2.Label {
id: boldMetrics
visible: false
text: parent.text
font.bold: true
font.family: Kirigami.Theme.smallFont.family
font.pointSize: Kirigami.Theme.smallFont.pointSize
horizontalAlignment: Text.AlignHCenter
wrapMode: QQC2.Label.Wrap
elide: Text.ElideMiddle
}
}
} }
} }

View File

@@ -56,15 +56,6 @@ ColumnLayout {
Kirigami.Theme.colorSet: Kirigami.Theme.View Kirigami.Theme.colorSet: Kirigami.Theme.View
Kirigami.Theme.inherit: false Kirigami.Theme.inherit: false
Kirigami.InlineMessage {
Layout.fillWidth: true
Layout.leftMargin: 1 // So we can see the border
Layout.rightMargin: 1 // So we can see the border
text: i18n("NeoChat is offline. Please check your network connection.")
visible: !Controller.isOnline
}
Kirigami.Separator { Kirigami.Separator {
Layout.fillWidth: true Layout.fillWidth: true
} }

View File

@@ -8,6 +8,8 @@ import QtQuick.Controls 2.15 as QQC2
import Qt.labs.qmlmodels 1.0 import Qt.labs.qmlmodels 1.0
import org.kde.kirigami 2.15 as Kirigami import org.kde.kirigami 2.15 as Kirigami
import org.kde.kirigamiaddons.delegates 1.0 as Delegates
import org.kde.kirigamiaddons.labs.components 1.0 as KirigamiComponents
import org.kde.neochat 1.0 import org.kde.neochat 1.0
@@ -43,6 +45,7 @@ QQC2.Popup {
rightPadding: 0 rightPadding: 0
topPadding: 0 topPadding: 0
bottomPadding: 0 bottomPadding: 0
implicitHeight: Math.min(completions.contentHeight, Kirigami.Units.gridUnit * 10) implicitHeight: Math.min(completions.contentHeight, Kirigami.Units.gridUnit * 10)
contentItem: ListView { contentItem: ListView {
@@ -53,23 +56,35 @@ QQC2.Popup {
currentIndex: 0 currentIndex: 0
keyNavigationWraps: true keyNavigationWraps: true
highlightMoveDuration: 100 highlightMoveDuration: 100
delegate: Kirigami.BasicListItem { delegate: Delegates.RoundedItemDelegate {
text: model.text id: completionDelegate
subtitle: model.subtitle ?? ""
labelItem.textFormat: Text.PlainText required property int index
subtitleItem.textFormat: Text.PlainText required property string displayName
leading: RowLayout { required property string subtitle
Kirigami.Avatar { required property string iconName
visible: model.icon !== "invalid"
Layout.preferredWidth: height text: displayName
Layout.fillHeight: true
source: model.icon === "invalid" ? "" : ("image://mxc/" + model.icon) contentItem: RowLayout {
name: model.text KirigamiComponents.Avatar {
visible: completionDelegate.iconName !== "invalid"
Layout.preferredWidth: Kirigami.Units.iconSizes.medium
Layout.preferredHeight: Kirigami.Units.iconSizes.medium
source: completionDelegate.iconName === "invalid" ? "" : ("image://" + completionDelegate.iconName)
name: completionDelegate.text
}
Delegates.SubtitleContentItem {
itemDelegate: completionDelegate
labelItem.textFormat: Text.PlainText
subtitle: completionDelegate.subtitle ?? ""
subtitleItem.textFormat: Text.PlainText
} }
} }
onClicked: completionMenu.chatDocumentHandler.complete(model.index) onClicked: completionMenu.chatDocumentHandler.complete(completionDelegate.index)
} }
} }
background: Rectangle { background: Rectangle {
color: Kirigami.Theme.backgroundColor color: Kirigami.Theme.backgroundColor
} }

View File

@@ -6,7 +6,8 @@ import QtQuick 2.15
import QtQuick.Layouts 1.15 import QtQuick.Layouts 1.15
import QtQuick.Controls 2.15 as QQC2 import QtQuick.Controls 2.15 as QQC2
import org.kde.kirigami 2.14 as Kirigami import org.kde.kirigami 2.15 as Kirigami
import org.kde.kirigamiaddons.labs.components 1.0 as KirigamiComponents
import org.kde.neochat 1.0 import org.kde.neochat 1.0
@@ -40,7 +41,7 @@ GridLayout {
implicitWidth: Kirigami.Units.smallSpacing implicitWidth: Kirigami.Units.smallSpacing
color: userColor color: userColor
} }
Kirigami.Avatar { KirigamiComponents.Avatar {
id: replyAvatar id: replyAvatar
implicitWidth: Kirigami.Units.iconSizes.small implicitWidth: Kirigami.Units.iconSizes.small

View File

@@ -9,6 +9,7 @@ import QtLocation 5.15
import QtPositioning 5.15 import QtPositioning 5.15
import org.kde.kirigami 2.15 as Kirigami import org.kde.kirigami 2.15 as Kirigami
import org.kde.kirigamiaddons.labs.components 1.0 as KirigamiComponents
import org.kde.neochat 1.0 import org.kde.neochat 1.0
@@ -44,7 +45,7 @@ MapQuickItem {
isMask: true isMask: true
color: parent.color color: parent.color
} }
Kirigami.Avatar { KirigamiComponents.Avatar {
anchors.centerIn: parent anchors.centerIn: parent
anchors.verticalCenterOffset: -parent.height / 8 anchors.verticalCenterOffset: -parent.height / 8
visible: root.asset === "m.self" visible: root.asset === "m.self"

View File

@@ -56,7 +56,7 @@ Components.AlbumMaximizeComponent {
} }
leading: RowLayout { leading: RowLayout {
Kirigami.Avatar { Components.Avatar {
id: userAvatar id: userAvatar
implicitWidth: Kirigami.Units.iconSizes.medium implicitWidth: Kirigami.Units.iconSizes.medium
implicitHeight: Kirigami.Units.iconSizes.medium implicitHeight: Kirigami.Units.iconSizes.medium

View File

@@ -6,9 +6,11 @@ import QtQuick.Controls 2.15 as QQC2
import QtQuick.Layouts 1.15 import QtQuick.Layouts 1.15
import org.kde.kirigami 2.20 as Kirigami import org.kde.kirigami 2.20 as Kirigami
import org.kde.kirigamiaddons.delegates 1.0 as Delegates
import org.kde.kitemmodels 1.0 import org.kde.kitemmodels 1.0
import org.kde.neochat 1.0 import org.kde.neochat 1.0
import './RoomList' as RoomList
QQC2.Dialog { QQC2.Dialog {
id: root id: root
@@ -86,48 +88,23 @@ QQC2.Dialog {
connection: Controller.activeConnection connection: Controller.activeConnection
} }
} }
delegate: Kirigami.BasicListItem {
id: roomListItem
required property NeoChatRoom currentRoom delegate: RoomList.RoomDelegate {
required property string displayName filterText: searchField.text
required property int index
required property int notificationCount
required property string subtitleText
required property string avatar
topPadding: Kirigami.Units.largeSpacing
bottomPadding: Kirigami.Units.largeSpacing
highlighted: roomList.currentIndex === roomListItem.index
focus: true
icon: undefined
onClicked: { onClicked: {
RoomManager.enterRoom(roomListItem.currentRoom); RoomManager.enterRoom(currentRoom);
root.close() root.close()
} }
Keys.onEnterPressed: { Keys.onEnterPressed: {
RoomManager.enterRoom(roomListItem.currentRoom); RoomManager.enterRoom(currentRoom);
root.close(); root.close();
} }
Keys.onReturnPressed: {
RoomManager.enterRoom(roomListItem.currentRoom);
root.close();
}
@BASICLISTITEM_BOLD@: roomListItem.notificationCount > 0
label: roomListItem.displayName ?? ""
labelItem.textFormat: Text.PlainText
subtitle: roomListItem.subtitleText
subtitleItem.textFormat: Text.PlainText
onPressAndHold: {
createRoomListContextMenu()
}
leading: Kirigami.Avatar { Keys.onReturnPressed: {
source: roomListItem.avatar ? "image://mxc/" + roomListItem.avatar : "" RoomManager.enterRoom(currentRoom);
name: roomListItem.displayName root.close();
implicitWidth: height
sourceSize.width: Kirigami.Units.gridUnit + Kirigami.Units.largeSpacing * 2
sourceSize.height: Kirigami.Units.gridUnit + Kirigami.Units.largeSpacing * 2
} }
} }
} }

View File

@@ -5,6 +5,7 @@ import QtQuick 2.15
import QtQuick.Controls 2.15 as QQC2 import QtQuick.Controls 2.15 as QQC2
import org.kde.kirigami 2.15 as Kirigami import org.kde.kirigami 2.15 as Kirigami
import org.kde.kirigamiaddons.labs.components 1.0 as KirigamiComponents
Flow { Flow {
id: root id: root
@@ -17,11 +18,11 @@ Flow {
spacing: -avatarSize / 2 spacing: -avatarSize / 2
Repeater { Repeater {
id: avatarFlowRepeater id: avatarFlowRepeater
delegate: Kirigami.Avatar { delegate: KirigamiComponents.Avatar {
topInset: Kirigami.Units.smallSpacing / 2 required property var modelData
topPadding: Kirigami.Units.smallSpacing / 2
implicitWidth: avatarSize implicitWidth: root.avatarSize
implicitHeight: avatarSize + Kirigami.Units.smallSpacing / 2 implicitHeight: root.avatarSize
name: modelData.displayName name: modelData.displayName
source: modelData.avatarSource source: modelData.avatarSource

View File

@@ -7,6 +7,7 @@ import QtQuick.Controls 2.15 as QQC2
import QtQuick.Layouts 1.15 import QtQuick.Layouts 1.15
import org.kde.kirigami 2.15 as Kirigami import org.kde.kirigami 2.15 as Kirigami
import org.kde.kirigamiaddons.labs.components 1.0 as KirigamiComponents
import org.kde.neochat 1.0 import org.kde.neochat 1.0
@@ -93,7 +94,7 @@ Item {
implicitWidth: Kirigami.Units.smallSpacing implicitWidth: Kirigami.Units.smallSpacing
color: root.author.color color: root.author.color
} }
Kirigami.Avatar { KirigamiComponents.Avatar {
id: replyAvatar id: replyAvatar
implicitWidth: Kirigami.Units.iconSizes.small implicitWidth: Kirigami.Units.iconSizes.small

View File

@@ -6,6 +6,7 @@ import QtQuick.Controls 2.15 as QQC2
import QtQuick.Layouts 1.15 import QtQuick.Layouts 1.15
import org.kde.kirigami 2.15 as Kirigami import org.kde.kirigami 2.15 as Kirigami
import org.kde.kirigamiaddons.labs.components 1.0 as KirigamiComponents
import org.kde.neochat 1.0 import org.kde.neochat 1.0
@@ -21,14 +22,23 @@ RowLayout {
implicitHeight: Math.max(label.contentHeight, stateAvatar.implicitHeight) implicitHeight: Math.max(label.contentHeight, stateAvatar.implicitHeight)
Kirigami.Avatar { KirigamiComponents.Avatar {
id: stateAvatar id: stateAvatar
Layout.preferredWidth: Kirigami.Units.iconSizes.small Layout.preferredWidth: Kirigami.Units.iconSizes.small
Layout.preferredHeight: Kirigami.Units.iconSizes.small Layout.preferredHeight: Kirigami.Units.iconSizes.small
name: root.name name: root.name
color: root.color color: root.color
Rectangle {
radius: height
height: 4
width: 4
color: root.color
anchors.centerIn: parent
}
MouseArea { MouseArea {
anchors.fill: parent anchors.fill: parent
cursorShape: Qt.PointingHandCursor cursorShape: Qt.PointingHandCursor

View File

@@ -6,6 +6,7 @@ import QtQuick.Controls 2.15 as QQC2
import QtQuick.Layouts 1.15 import QtQuick.Layouts 1.15
import org.kde.kirigami 2.15 as Kirigami import org.kde.kirigami 2.15 as Kirigami
import org.kde.kirigamiaddons.labs.components 1.0 as KirigamiComponents
import org.kde.neochat 1.0 import org.kde.neochat 1.0
@@ -71,34 +72,61 @@ QQC2.Control {
Flow { Flow {
visible: columnLayout.folded visible: columnLayout.folded
spacing: -Kirigami.Units.iconSizes.small / 2 spacing: -Kirigami.Units.iconSizes.small / 2
Repeater { Repeater {
model: authorList model: authorList
delegate: Kirigami.Avatar { delegate: Item {
topInset: Kirigami.Units.smallSpacing / 2 id: avatarDelegate
topPadding: Kirigami.Units.smallSpacing / 2
required property var modelData
implicitWidth: Kirigami.Units.iconSizes.small implicitWidth: Kirigami.Units.iconSizes.small
implicitHeight: Kirigami.Units.iconSizes.small + Kirigami.Units.smallSpacing / 2 implicitHeight: Kirigami.Units.iconSizes.small + Kirigami.Units.smallSpacing / 2
name: modelData.displayName KirigamiComponents.Avatar {
source: modelData.avatarSource y: Kirigami.Units.smallSpacing / 2
color: modelData.color
implicitWidth: Kirigami.Units.iconSizes.small
implicitHeight: Kirigami.Units.iconSizes.small
name: parent.modelData.displayName
source: parent.modelData.avatarSource
color: parent.modelData.color
Rectangle {
radius: height
height: 4
width: 4
color: avatarDelegate.modelData.color
anchors.centerIn: parent
}
}
} }
} }
QQC2.Label { QQC2.Label {
id: excessAuthorsLabel id: excessAuthorsLabel
text: model.excessAuthors text: model.excessAuthors
visible: model.excessAuthors !== "" visible: model.excessAuthors !== ""
color: Kirigami.Theme.textColor color: Kirigami.Theme.textColor
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
background: Kirigami.ShadowedRectangle { background: Kirigami.ShadowedRectangle {
color: Kirigami.Theme.backgroundColor
Kirigami.Theme.inherit: false Kirigami.Theme.inherit: false
Kirigami.Theme.colorSet: Kirigami.Theme.View Kirigami.Theme.colorSet: Kirigami.Theme.View
color: Kirigami.Theme.backgroundColor
radius: height / 2 radius: height / 2
shadow.size: Kirigami.Units.smallSpacing
shadow.color: Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.10) shadow {
border.color: Kirigami.ColorUtils.tintWithAlpha(color, Kirigami.Theme.textColor, 0.15) size: Kirigami.Units.smallSpacing
border.width: 1 color: Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.10)
}
border {
color: Kirigami.ColorUtils.tintWithAlpha(color, Kirigami.Theme.textColor, 0.15)
width: 1
}
} }
height: Kirigami.Units.iconSizes.small + Kirigami.Units.smallSpacing height: Kirigami.Units.iconSizes.small + Kirigami.Units.smallSpacing
@@ -125,13 +153,13 @@ QQC2.Control {
visible: !columnLayout.folded visible: !columnLayout.folded
} }
QQC2.ToolButton { QQC2.ToolButton {
icon.name: (!columnLayout.folded ? "go-up" : "go-down") icon {
icon.width: Kirigami.Units.iconSizes.small name: (!columnLayout.folded ? "go-up" : "go-down")
icon.height: Kirigami.Units.iconSizes.small width: Kirigami.Units.iconSizes.small
height: Kirigami.Units.iconSizes.small
onClicked: {
columnLayout.toggleFolded()
} }
onClicked: columnLayout.toggleFolded()
} }
} }
Repeater { Repeater {

View File

@@ -6,6 +6,7 @@ import QtQuick.Controls 2.15 as QQC2
import QtQuick.Layouts 1.15 import QtQuick.Layouts 1.15
import org.kde.kirigami 2.15 as Kirigami import org.kde.kirigami 2.15 as Kirigami
import org.kde.kirigamiaddons.labs.components 1.0 as KirigamiComponents
import org.kde.neochat 1.0 import org.kde.neochat 1.0
@@ -353,18 +354,15 @@ ColumnLayout {
} }
} }
Kirigami.Avatar { KirigamiComponents.Avatar {
id: avatar id: avatar
width: visible || Config.showAvatarInTimeline ? Kirigami.Units.gridUnit * 2 + Kirigami.Units.smallSpacing * 2 : 0 width: visible || Config.showAvatarInTimeline ? Kirigami.Units.gridUnit + Kirigami.Units.largeSpacing * 2: 0
height: width height: width
padding: Kirigami.Units.smallSpacing
topInset: Kirigami.Units.smallSpacing
bottomInset: Kirigami.Units.smallSpacing
leftInset: Kirigami.Units.smallSpacing
rightInset: Kirigami.Units.smallSpacing
anchors { anchors {
left: parent.left left: parent.left
leftMargin: Kirigami.Units.smallSpacing leftMargin: Kirigami.Units.smallSpacing
top: parent.top
topMargin: Kirigami.Units.smallSpacing
} }
visible: root.showAuthor && visible: root.showAuthor &&
@@ -395,7 +393,8 @@ ColumnLayout {
hoverEnabled: true hoverEnabled: true
anchors { anchors {
leftMargin: Kirigami.Units.smallSpacing left: avatar.right
leftMargin: Kirigami.Units.largeSpacing
rightMargin: Kirigami.Units.largeSpacing rightMargin: Kirigami.Units.largeSpacing
} }
// HACK: anchoring didn't reset anchors.right when switching from parent.right to undefined reliably // HACK: anchoring didn't reset anchors.right when switching from parent.right to undefined reliably
@@ -519,14 +518,12 @@ ColumnLayout {
visible: cardBackground && !Config.compactLayout visible: cardBackground && !Config.compactLayout
anchors.fill: parent anchors.fill: parent
Kirigami.Theme.colorSet: Kirigami.Theme.View Kirigami.Theme.colorSet: Kirigami.Theme.View
color: { color: if (root.author.isLocalUser) {
if (root.author.isLocalUser) { return Kirigami.ColorUtils.tintWithAlpha(Kirigami.Theme.backgroundColor, Kirigami.Theme.highlightColor, 0.15)
return Kirigami.ColorUtils.tintWithAlpha(Kirigami.Theme.backgroundColor, Kirigami.Theme.highlightColor, 0.15) } else if (root.showHighlight) {
} else if (root.showHighlight) { return Kirigami.Theme.positiveBackgroundColor
return Kirigami.Theme.positiveBackgroundColor } else {
} else { return Kirigami.Theme.backgroundColor
return Kirigami.Theme.backgroundColor
}
} }
radius: Kirigami.Units.smallSpacing radius: Kirigami.Units.smallSpacing
shadow.size: Kirigami.Units.smallSpacing shadow.size: Kirigami.Units.smallSpacing

View File

@@ -308,7 +308,7 @@ QQC2.ScrollView {
x: delegate ? delegate.x + delegate.bubbleX : 0 x: delegate ? delegate.x + delegate.bubbleX : 0
y: delegate ? delegate.mapToItem(parent, 0, 0).y + delegate.bubbleY - height + Kirigami.Units.smallSpacing : 0 y: delegate ? delegate.mapToItem(parent, 0, 0).y + delegate.bubbleY - height + Kirigami.Units.smallSpacing : 0
width: delegate.bubbleWidth width: delegate ? delegate.bubbleWidth : Kirigami.Units.gridUnit * 4
showActions: delegate && delegate.hovered showActions: delegate && delegate.hovered
verified: delegate && delegate.verified verified: delegate && delegate.verified
@@ -420,13 +420,6 @@ QQC2.ScrollView {
popup.open() popup.open()
} }
function showUserDetail(user) {
userDetailDialog.createObject(QQC2.ApplicationWindow.overlay, {
room: root.currentRoom,
user: root.currentRoom.getUser(user.id),
}).open();
}
function goToLastMessage() { function goToLastMessage() {
root.currentRoom.markAllMessagesAsRead() root.currentRoom.markAllMessagesAsRead()
// scroll to the very end, i.e to messageListView.YEnd // scroll to the very end, i.e to messageListView.YEnd
@@ -496,4 +489,11 @@ QQC2.ScrollView {
function positionViewAtBeginning() { function positionViewAtBeginning() {
messageListView.positionViewAtBeginning() messageListView.positionViewAtBeginning()
} }
function showUserDetail(user) {
userDetailDialog.createObject(QQC2.ApplicationWindow.overlay, {
room: root.currentRoom,
user: root.currentRoom.getUser(user.id),
}).open();
}
} }

View File

@@ -7,6 +7,7 @@ import QtQuick.Controls 2.15 as QQC2
import QtQuick.Layouts 1.15 import QtQuick.Layouts 1.15
import org.kde.kirigami 2.20 as Kirigami import org.kde.kirigami 2.20 as Kirigami
import org.kde.kirigamiaddons.labs.components 1.0 as KirigamiComponents
import org.kde.neochat 1.0 import org.kde.neochat 1.0
@@ -37,7 +38,7 @@ Kirigami.OverlaySheet {
Layout.bottomMargin: Kirigami.Units.largeSpacing Layout.bottomMargin: Kirigami.Units.largeSpacing
spacing: Kirigami.Units.largeSpacing spacing: Kirigami.Units.largeSpacing
Kirigami.Avatar { KirigamiComponents.Avatar {
Layout.preferredWidth: Kirigami.Units.iconSizes.huge Layout.preferredWidth: Kirigami.Units.iconSizes.huge
Layout.preferredHeight: Kirigami.Units.iconSizes.huge Layout.preferredHeight: Kirigami.Units.iconSizes.huge

View File

@@ -6,6 +6,7 @@ import QtQuick 2.15
import QtQuick.Controls 2.15 as QQC2 import QtQuick.Controls 2.15 as QQC2
import QtQuick.Layouts 1.15 import QtQuick.Layouts 1.15
import org.kde.kirigami 2.15 as Kirigami import org.kde.kirigami 2.15 as Kirigami
import org.kde.kirigamiaddons.labs.components 1.0 as KirigamiComponents
import org.kde.neochat 1.0 import org.kde.neochat 1.0
@@ -222,11 +223,11 @@ Loader {
Layout.fillWidth: true Layout.fillWidth: true
Layout.margins: Kirigami.Units.largeSpacing Layout.margins: Kirigami.Units.largeSpacing
spacing: Kirigami.Units.largeSpacing spacing: Kirigami.Units.largeSpacing
Kirigami.Avatar { KirigamiComponents.Avatar {
id: avatar id: avatar
source: author.avatarSource source: author.avatarSource
Layout.preferredWidth: Kirigami.Units.gridUnit * 3 Layout.preferredWidth: Kirigami.Units.gridUnit * 2
Layout.preferredHeight: Kirigami.Units.gridUnit * 3 Layout.preferredHeight: Kirigami.Units.gridUnit * 2
Layout.alignment: Qt.AlignTop Layout.alignment: Qt.AlignTop
} }
ColumnLayout { ColumnLayout {

View File

@@ -7,6 +7,7 @@ import QtQuick.Layouts 1.15
import Qt.labs.platform 1.1 as Platform import Qt.labs.platform 1.1 as Platform
import org.kde.kirigami 2.15 as Kirigami import org.kde.kirigami 2.15 as Kirigami
import org.kde.kirigamiaddons.labs.components 1.0 as KirigamiComponents
import org.kde.kquickimageeditor 1.0 as KQuickImageEditor import org.kde.kquickimageeditor 1.0 as KQuickImageEditor
Kirigami.Page { Kirigami.Page {
@@ -170,7 +171,7 @@ Kirigami.Page {
} }
} }
footer: Kirigami.InlineMessage { footer: KirigamiComponents.Banner {
id: msg id: msg
type: Kirigami.MessageType.Error type: Kirigami.MessageType.Error
showCloseButton: true showCloseButton: true

View File

@@ -6,6 +6,8 @@ import QtQuick.Controls 2.15 as QQC2
import QtQuick.Layouts 1.15 import QtQuick.Layouts 1.15
import org.kde.kirigami 2.15 as Kirigami import org.kde.kirigami 2.15 as Kirigami
import org.kde.kirigamiaddons.delegates 1.0 as Delegates
import org.kde.kirigamiaddons.labs.components 1.0 as KirigamiComponents
import org.kde.neochat 1.0 import org.kde.neochat 1.0
@@ -68,38 +70,51 @@ Kirigami.ScrollablePage {
text: i18n("No users available") text: i18n("No users available")
} }
delegate: Kirigami.BasicListItem { delegate: Delegates.RoundedItemDelegate {
id: delegate id: delegate
required property string userID
required property string name
required property string avatar
property bool inRoom: room && room.containsUser(userID) property bool inRoom: room && room.containsUser(userID)
label: model.name text: name
subtitle: model.userID
leading: Kirigami.Avatar { contentItem: RowLayout {
implicitWidth: height KirigamiComponents.Avatar {
source: model.avatar ? ("image://mxc/" + model.avatar) : "" Layout.preferredWidth: Kirigami.Units.iconSizes.medium
name: model.name Layout.preferredHeight: Kirigami.Units.iconSizes.medium
} source: delegate.avatar ? ("image://mxc/" + delegate.avatar) : ""
trailing: QQC2.ToolButton { name: delegate.name
id: inviteButton
icon.name: "document-send"
text: i18n("Send invitation")
checkable: true
checked: inRoom
opacity: inRoom ? 0.5 : 1
onToggled: {
if (inRoom) {
checked = true
} else {
room.inviteToRoom(model.userID);
applicationWindow().pageStack.layers.pop();
}
} }
QQC2.ToolTip.text: !inRoom ? text : i18n("User is either already a member or has been invited") Delegates.SubtitleContentItem {
QQC2.ToolTip.visible: inviteButton.hovered itemDelegate: delegate
QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay subtitle: delegate.userID
}
QQC2.ToolButton {
id: inviteButton
icon.name: "document-send"
text: i18n("Send invitation")
checkable: true
checked: inRoom
opacity: inRoom ? 0.5 : 1
onToggled: {
if (inRoom) {
checked = true
} else {
room.inviteToRoom(delegate.userID);
applicationWindow().pageStack.layers.pop();
}
}
QQC2.ToolTip.text: !inRoom ? text : i18n("User is either already a member or has been invited")
QQC2.ToolTip.visible: inviteButton.hovered
QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
}
} }
} }
} }

View File

@@ -8,6 +8,7 @@ import QtQuick.Layouts 1.15
import Qt.labs.qmlmodels 1.0 import Qt.labs.qmlmodels 1.0
import org.kde.kirigami 2.15 as Kirigami import org.kde.kirigami 2.15 as Kirigami
import org.kde.kirigamiaddons.labs.components 1.0 as KirigamiComponents
import org.kde.neochat 1.0 import org.kde.neochat 1.0
@@ -202,7 +203,7 @@ Kirigami.ScrollablePage {
applicationWindow().pageStack.layers.pop(); applicationWindow().pageStack.layers.pop();
} }
contentItem: RowLayout { contentItem: RowLayout {
Kirigami.Avatar { KirigamiComponents.Avatar {
Layout.preferredWidth: Kirigami.Units.gridUnit * 2 Layout.preferredWidth: Kirigami.Units.gridUnit * 2
Layout.preferredHeight: Kirigami.Units.gridUnit * 2 Layout.preferredHeight: Kirigami.Units.gridUnit * 2

View File

@@ -7,6 +7,7 @@ import QtQuick.Layouts 1.15
import QtQml.Models 2.15 import QtQml.Models 2.15
import org.kde.kirigami 2.15 as Kirigami import org.kde.kirigami 2.15 as Kirigami
import org.kde.kirigamiaddons.labs.components 1.0 as KirigamiComponents
import org.kde.kitemmodels 1.0 import org.kde.kitemmodels 1.0
import org.kde.neochat 1.0 import org.kde.neochat 1.0
@@ -32,7 +33,7 @@ QQC2.ItemDelegate {
visible: root.categoryVisible || filterText.length > 0 || Config.mergeRoomList visible: root.categoryVisible || filterText.length > 0 || Config.mergeRoomList
contentItem: Kirigami.Avatar { contentItem: KirigamiComponents.Avatar {
source: root.avatar ? `image://mxc/${root.avatar}` : "" source: root.avatar ? `image://mxc/${root.avatar}` : ""
name: root.displayName name: root.displayName

View File

@@ -7,6 +7,7 @@ import QtQuick.Controls 2.15 as QQC2
import QtQuick.Layouts 1.15 import QtQuick.Layouts 1.15
import org.kde.kirigami 2.19 as Kirigami import org.kde.kirigami 2.19 as Kirigami
import org.kde.kirigamiaddons.labs.components 1.0 as KirigamiComponents
import org.kde.neochat 1.0 import org.kde.neochat 1.0
@@ -157,7 +158,7 @@ Loader {
Layout.fillWidth: true Layout.fillWidth: true
Layout.margins: Kirigami.Units.largeSpacing Layout.margins: Kirigami.Units.largeSpacing
spacing: Kirigami.Units.largeSpacing spacing: Kirigami.Units.largeSpacing
Kirigami.Avatar { KirigamiComponents.Avatar {
id: avatar id: avatar
source: room.avatarMediaId ? ("image://mxc/" + room.avatarMediaId) : "" source: room.avatarMediaId ? ("image://mxc/" + room.avatarMediaId) : ""
name: room.displayName name: room.displayName

View File

@@ -240,6 +240,15 @@ Kirigami.Page {
RoomList.RoomDelegate { RoomList.RoomDelegate {
filterText: sortFilterRoomListModel.filterText filterText: sortFilterRoomListModel.filterText
height: visible ? implicitHeight : 0
visible: categoryVisible || filterText.length > 0 || Config.mergeRoomList
onClicked: RoomManager.enterRoom(currentRoom)
Keys.onEnterPressed: RoomManager.enterRoom(currentRoom)
Keys.onReturnPressed: RoomManager.enterRoom(currentRoom)
} }
} }
} }

View File

@@ -7,13 +7,15 @@ import QtQuick.Layouts 1.15
import QtQml.Models 2.15 import QtQml.Models 2.15
import org.kde.kirigami 2.15 as Kirigami import org.kde.kirigami 2.15 as Kirigami
import org.kde.kirigamiaddons.delegates 1.0 as Delegates
import org.kde.kirigamiaddons.labs.components 1.0 as Components
import org.kde.kitemmodels 1.0 import org.kde.kitemmodels 1.0
import org.kde.neochat 1.0 import org.kde.neochat 1.0
import './' as RoomList import './' as RoomList
Kirigami.BasicListItem { Delegates.RoundedItemDelegate {
id: root id: root
required property int index required property int index
@@ -29,48 +31,60 @@ Kirigami.BasicListItem {
readonly property bool hasNotifications: notificationCount > 0 readonly property bool hasNotifications: notificationCount > 0
topPadding: Kirigami.Units.largeSpacing
bottomPadding: Kirigami.Units.largeSpacing
visible: root.categoryVisible || root.filterText.length > 0 || Config.mergeRoomList
highlighted: ListView.view.currentIndex === index
focus: true
icon: undefined
@BASICLISTITEM_BOLD@: root.hasNotifications
label: root.displayName
labelItem.textFormat: Text.PlainText
subtitle: root.subtitleText
subtitleItem {
textFormat: Text.PlainText
visible: !Config.compactRoomList
}
onClicked: RoomManager.enterRoom(root.currentRoom)
onPressAndHold: createRoomListContextMenu() onPressAndHold: createRoomListContextMenu()
Keys.onEnterPressed: RoomManager.enterRoom(root.currentRoom)
Keys.onReturnPressed: RoomManager.enterRoom(root.currentRoom)
TapHandler { TapHandler {
acceptedButtons: Qt.RightButton acceptedButtons: Qt.RightButton
acceptedDevices: PointerDevice.Mouse acceptedDevices: PointerDevice.Mouse
onTapped: createRoomListContextMenu() onTapped: createRoomListContextMenu()
} }
leading: Kirigami.Avatar { contentItem: RowLayout {
source: root.avatar ? `image://mxc/${root.avatar}` : "" spacing: Kirigami.Units.largeSpacing
name: root.displayName
implicitWidth: visible ? height : 0 Components.Avatar {
visible: Config.showAvatarInRoomDrawer source: root.avatar ? "image://mxc/" + root.avatar : ""
sourceSize { name: root.displayName
width: Kirigami.Units.gridUnit + Kirigami.Units.largeSpacing * 2 visible: Config.showAvatarInRoomDrawer
height: Kirigami.Units.gridUnit + Kirigami.Units.largeSpacing * 2 implicitHeight: Kirigami.Units.gridUnit + Kirigami.Units.largeSpacing * 2
} implicitWidth: visible ? implicitHeight : 0
}
Layout.fillHeight: true
Layout.preferredWidth: height
}
ColumnLayout {
spacing: 0
Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter
QQC2.Label {
id: label
text: root.displayName
elide: Text.ElideRight
font.weight: root.hasNotifications ? Font.Bold : Font.Normal
Layout.fillWidth: true
Layout.alignment: subtitle.visible ? Qt.AlignLeft | Qt.AlignBottom : Qt.AlignLeft | Qt.AlignVCenter
}
QQC2.Label {
id: subtitle
text: root.subtitleText
elide: Text.ElideRight
font: Kirigami.Theme.smallFont
opacity: root.hasNotifications ? 0.9 : 0.7
visible: !Config.compactRoomList
textFormat: Text.PlainText
Layout.fillWidth: true
Layout.alignment: visible ? Qt.AlignLeft | Qt.AlignTop : Qt.AlignLeft | Qt.AlignVCenter
}
}
trailing: RowLayout {
Kirigami.Icon { Kirigami.Icon {
source: "notifications-disabled" source: "notifications-disabled"
enabled: false enabled: false
@@ -80,10 +94,12 @@ Kirigami.BasicListItem {
Accessible.name: i18n("Muted room") Accessible.name: i18n("Muted room")
Layout.rightMargin: Kirigami.Units.smallSpacing Layout.rightMargin: Kirigami.Units.smallSpacing
} }
QQC2.Label { QQC2.Label {
id: notificationCountLabel id: notificationCountLabel
text: notificationCount
visible: hasNotifications text: root.notificationCount
visible: root.hasNotifications
color: Kirigami.Theme.textColor color: Kirigami.Theme.textColor
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
background: Rectangle { background: Rectangle {
@@ -103,6 +119,7 @@ Kirigami.BasicListItem {
text: notificationCountLabel.text text: notificationCountLabel.text
} }
} }
QQC2.Button { QQC2.Button {
id: configButton id: configButton
visible: root.hovered && !Kirigami.Settings.isMobile && !Config.compactRoomList visible: root.hovered && !Kirigami.Settings.isMobile && !Config.compactRoomList

View File

@@ -7,6 +7,7 @@ import QtQuick.Controls 2.15 as QQC2
import QtQuick.Layouts 1.15 import QtQuick.Layouts 1.15
import org.kde.kirigami 2.20 as Kirigami import org.kde.kirigami 2.20 as Kirigami
import org.kde.kirigamiaddons.delegates 1.0 as Delegates
import '.' import '.'
import org.kde.neochat 1.0 import org.kde.neochat 1.0
@@ -15,12 +16,8 @@ QQC2.Control {
id: root id: root
readonly property real pinnedWidth: Kirigami.Units.gridUnit * 6 readonly property real pinnedWidth: Kirigami.Units.gridUnit * 6
readonly property int buttonDisplayMode: Kirigami.NavigationTabButton.IconOnly
property bool drawerEnabled: true property bool drawerEnabled: true
Kirigami.Theme.colorSet: Kirigami.Theme.Window
Kirigami.Theme.inherit: false
leftPadding: 0 leftPadding: 0
rightPadding: 0 rightPadding: 0
topPadding: 0 topPadding: 0
@@ -28,12 +25,6 @@ QQC2.Control {
property string selectedSpaceId property string selectedSpaceId
background: Rectangle {
color: Kirigami.Theme.backgroundColor
Kirigami.Theme.colorSet: Kirigami.Theme.View
Kirigami.Theme.inherit: false
}
contentItem: Loader { contentItem: Loader {
id: sidebarColumn id: sidebarColumn
active: root.drawerEnabled active: root.drawerEnabled
@@ -56,17 +47,23 @@ QQC2.Control {
width: scrollView.width width: scrollView.width
spacing: 0 spacing: 0
Kirigami.NavigationTabButton { AvatarTabButton {
id: allRoomButton
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: width Layout.preferredHeight: width - Kirigami.Units.smallSpacing
display: Kirigami.NavigationTabButton.IconOnly Layout.maximumHeight: width - Kirigami.Units.smallSpacing
Layout.topMargin: Kirigami.Units.smallSpacing
text: i18n("All Rooms") text: i18n("All Rooms")
icon.name: "globe" source: "globe"
checked: true
contentItem: Kirigami.Icon {
source: "globe"
}
checked: root.selectedSpaceId === ""
onClicked: root.selectedSpaceId = "" onClicked: root.selectedSpaceId = ""
QQC2.ToolTip.visible: hovered
QQC2.ToolTip.text: text
QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
} }
Repeater { Repeater {
@@ -79,23 +76,23 @@ QQC2.Control {
Component.onCompleted: root.enabled = count > 0 Component.onCompleted: root.enabled = count > 0
delegate: AvatarTabButton { delegate: AvatarTabButton {
Layout.fillWidth: true id: spaceDelegate
Layout.preferredHeight: width
display: Kirigami.NavigationTabButton.IconOnly
text: model.displayName
source: model.avatar ? ("image://mxc/" + model.avatar) : ""
name: model.displayName
onClicked: root.selectedSpaceId = model.id
QQC2.ToolTip.visible: hovered
QQC2.ToolTip.text: text
QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
onPressAndHold: root.createContextMenu(model.currentRoom)
TapHandler { required property string displayName
acceptedButtons: Qt.RightButton required property string avatar
acceptedDevices: PointerDevice.Mouse required property string roomId
onTapped: root.createContextMenu(model.currentRoom) required property var currentRoom
}
Layout.fillWidth: true
Layout.preferredHeight: width - Kirigami.Units.smallSpacing
Layout.maximumHeight: width - Kirigami.Units.smallSpacing
text: displayName
source: avatar ? ("image://mxc/" + avatar) : ""
onClicked: root.selectedSpaceId = roomId
checked: root.selectedSpaceId === roomId
onContextMenuRequested: root.createContextMenu(currentRoom)
} }
} }
} }

View File

@@ -7,6 +7,7 @@ import QtQuick.Controls 2.15 as QQC2
import QtQuick.Layouts 1.15 import QtQuick.Layouts 1.15
import org.kde.kirigami 2.19 as Kirigami import org.kde.kirigami 2.19 as Kirigami
import org.kde.kirigamiaddons.labs.components 1.0 as KirigamiComponents
import org.kde.neochat 1.0 import org.kde.neochat 1.0
@@ -78,7 +79,7 @@ Loader {
Layout.fillWidth: true Layout.fillWidth: true
Layout.margins: Kirigami.Units.largeSpacing Layout.margins: Kirigami.Units.largeSpacing
spacing: Kirigami.Units.largeSpacing spacing: Kirigami.Units.largeSpacing
Kirigami.Avatar { KirigamiComponents.Avatar {
id: avatar id: avatar
source: room.avatarMediaId ? ("image://mxc/" + room.avatarMediaId) : "" source: room.avatarMediaId ? ("image://mxc/" + room.avatarMediaId) : ""
Layout.preferredWidth: Kirigami.Units.gridUnit * 3 Layout.preferredWidth: Kirigami.Units.gridUnit * 3

View File

@@ -5,6 +5,8 @@ import QtQuick 2.15
import QtQuick.Controls 2.15 as QQC2 import QtQuick.Controls 2.15 as QQC2
import QtQuick.Layouts 1.15 import QtQuick.Layouts 1.15
import org.kde.kirigami 2.20 as Kirigami import org.kde.kirigami 2.20 as Kirigami
import org.kde.kirigamiaddons.labs.components 1.0 as KirigamiComponents
import org.kde.kirigamiaddons.delegates 1.0 as Delegates
import org.kde.neochat 1.0 import org.kde.neochat 1.0
@@ -27,34 +29,28 @@ QQC2.ToolBar {
header: Kirigami.Separator {} header: Kirigami.Separator {}
footer: Kirigami.BasicListItem { footer: Delegates.RoundedItemDelegate {
id: addButton
width: parent.width width: parent.width
highlighted: focus highlighted: focus || (addAccount.highlighted || addAccount.ListView.isCurrentItem) && !addAccount.pressed
background: Rectangle {
id: background
color: addAccount.backgroundColor
Rectangle {
anchors.fill: parent
visible: !Kirigami.Settings.tabletMode && addAccount.hoverEnabled
color: addAccount.activeBackgroundColor
opacity: {
if ((addAccount.highlighted || addAccount.ListView.isCurrentItem) && !addAccount.pressed) {
return .6
} else if (addAccount.hovered && !addAccount.pressed) {
return .3
} else {
return 0
}
}
}
}
Component.onCompleted: userInfo.addAccount = this Component.onCompleted: userInfo.addAccount = this
icon: "list-add" icon {
name: "list-add"
width: Kirigami.Units.iconSizes.smallMedium
height: Kirigami.Units.iconSizes.smallMedium
}
text: i18n("Add Account") text: i18n("Add Account")
subtitle: i18n("Log in to an existing account") contentItem: Delegates.SubtitleContentItem {
itemDelegate: parent
subtitle: i18n("Log in to an existing account")
labelItem.textFormat: Text.PlainText
subtitleItem.textFormat: Text.PlainText
}
onClicked: { onClicked: {
pageStack.pushDialogLayer("qrc:/WelcomePage.qml", {}, {title: i18nc("@title:window", "Login")}) pageStack.pushDialogLayer("qrc:/WelcomePage.qml", {}, {
title: i18nc("@title:window", "Login"),
});
if (switchUserButton.checked) { if (switchUserButton.checked) {
switchUserButton.checked = false switchUserButton.checked = false
} }
@@ -101,26 +97,36 @@ QQC2.ToolBar {
width: parent.width width: parent.width
Layout.preferredHeight: contentHeight Layout.preferredHeight: contentHeight
delegate: Kirigami.BasicListItem { delegate: Delegates.RoundedItemDelegate {
leftPadding: topPadding id: userDelegate
leading: Kirigami.Avatar {
implicitWidth: Kirigami.Units.gridUnit + Kirigami.Units.largeSpacing required property var connection
implicitHeight: Kirigami.Units.gridUnit + Kirigami.Units.largeSpacing
sourceSize {
width: Kirigami.Units.gridUnit + Kirigami.Units.largeSpacing
height: Kirigami.Units.gridUnit + Kirigami.Units.largeSpacing
}
source: model.connection.localUser.avatarMediaId ? ("image://mxc/" + model.connection.localUser.avatarMediaId) : ""
name: model.connection.localUser.displayName ?? model.connection.localUser.id
}
width: parent.width width: parent.width
text: model.connection.localUser.displayName text: connection.localUser.displayName
labelItem.textFormat: Text.PlainText
subtitleItem.textFormat: Text.PlainText contentItem: RowLayout {
subtitle: model.connection.localUser.id KirigamiComponents.Avatar {
implicitWidth: Kirigami.Units.gridUnit + Kirigami.Units.largeSpacing
implicitHeight: Kirigami.Units.gridUnit + Kirigami.Units.largeSpacing
sourceSize {
width: Kirigami.Units.gridUnit + Kirigami.Units.largeSpacing
height: Kirigami.Units.gridUnit + Kirigami.Units.largeSpacing
}
source: userDelegate.connection.localUser.avatarMediaId ? ("image://mxc/" + userDelegate.connection.localUser.avatarMediaId) : ""
name: userDelegate.connection.localUser.displayName ?? userDelegate.connection.localUser.id
}
Delegates.SubtitleContentItem {
itemDelegate: userDelegate
subtitle: userDelegate.connection.localUser.id
labelItem.textFormat: Text.PlainText
subtitleItem.textFormat: Text.PlainText
}
}
onClicked: { onClicked: {
Controller.activeConnection = model.connection Controller.activeConnection = userDelegate.connection
if (switchUserButton.checked) { if (switchUserButton.checked) {
switchUserButton.checked = false switchUserButton.checked = false
} }
@@ -139,29 +145,31 @@ QQC2.ToolBar {
Layout.bottomMargin: Kirigami.Units.smallSpacing Layout.bottomMargin: Kirigami.Units.smallSpacing
Layout.minimumHeight: Kirigami.Units.gridUnit * 2 - 2 // HACK: -2 here is to ensure the ChatBox and the UserInfo have the same height Layout.minimumHeight: Kirigami.Units.gridUnit * 2 - 2 // HACK: -2 here is to ensure the ChatBox and the UserInfo have the same height
Kirigami.Avatar { QQC2.AbstractButton {
readonly property string mediaId: Controller.activeConnection.localUser.avatarMediaId
Layout.preferredWidth: Kirigami.Units.gridUnit + Kirigami.Units.largeSpacing Layout.preferredWidth: Kirigami.Units.gridUnit + Kirigami.Units.largeSpacing
Layout.preferredHeight: Kirigami.Units.gridUnit + Kirigami.Units.largeSpacing Layout.preferredHeight: Kirigami.Units.gridUnit + Kirigami.Units.largeSpacing
Layout.leftMargin: Kirigami.Units.largeSpacing Layout.leftMargin: Kirigami.Units.largeSpacing
source: mediaId ? ("image://mxc/" + mediaId) : ""
name: Controller.activeConnection.localUser.displayName ?? Controller.activeConnection.localUser.id
actions.main: Kirigami.Action {
text: i18n("Edit this account")
icon.name: "document-edit"
onTriggered: pageStack.pushDialogLayer(Qt.resolvedUrl('qrc:/AccountEditorPage.qml'), {
connection: Controller.activeConnection
}, {
title: i18n("Account editor")
});
}
TapHandler { TapHandler {
acceptedButtons: Qt.RightButton acceptedButtons: Qt.RightButton
acceptedDevices: PointerDevice.Mouse acceptedDevices: PointerDevice.Mouse
onTapped: accountMenu.open() onTapped: accountMenu.open()
} }
text: i18n("Edit this account")
onClicked: pageStack.pushDialogLayer(Qt.resolvedUrl('qrc:/AccountEditorPage.qml'), {
connection: Controller.activeConnection
}, {
title: i18n("Account editor")
});
contentItem: KirigamiComponents.Avatar {
readonly property string mediaId: Controller.activeConnection.localUser.avatarMediaId
source: mediaId ? ("image://mxc/" + mediaId) : ""
name: Controller.activeConnection.localUser.displayName ?? Controller.activeConnection.localUser.id
}
} }
ColumnLayout { ColumnLayout {
@@ -220,7 +228,7 @@ QQC2.ToolBar {
Layout.minimumWidth: Layout.preferredWidth Layout.minimumWidth: Layout.preferredWidth
Layout.alignment: Qt.AlignRight Layout.alignment: Qt.AlignRight
Layout.rightMargin: Kirigami.Units.largeSpacing Layout.rightMargin: Kirigami.Units.largeSpacing
QQC2.ToolTip.text: parent.text QQC2.ToolTip.text: text
QQC2.ToolTip.visible: hovered QQC2.ToolTip.visible: hovered
QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
} }

View File

@@ -7,6 +7,7 @@ import QtQuick.Controls 2.15 as QQC2
import QtQuick.Layouts 1.15 import QtQuick.Layouts 1.15
import QtQuick.Window 2.15 import QtQuick.Window 2.15
import org.kde.kirigamiaddons.labs.components 1.0 as KirigamiComponents
import org.kde.kirigami 2.19 as Kirigami import org.kde.kirigami 2.19 as Kirigami
import org.kde.kitemmodels 1.0 import org.kde.kitemmodels 1.0
@@ -42,16 +43,26 @@ Kirigami.Page {
} }
} }
header: QQC2.Control { Connections {
height: visible ? implicitHeight : 0 target: Controller
visible: false function onIsOnlineChanged() {
padding: Kirigami.Units.smallSpacing if (true || !Controller.isOnline) {
contentItem: Kirigami.InlineMessage { banner.text = i18n("NeoChat is offline. Please check your network connection.");
showCloseButton: true banner.visible = true;
visible: true banner.type = Kirigami.MessageType.Error;
} else {
banner.visible = false;
}
} }
} }
header: KirigamiComponents.Banner {
id: banner
showCloseButton: true
visible: false
}
Loader { Loader {
id: timelineViewLoader id: timelineViewLoader
anchors.fill: parent anchors.fill: parent
@@ -166,15 +177,19 @@ Kirigami.Page {
Connections { Connections {
target: currentRoom target: currentRoom
function onShowMessage(messageType, message) { function onShowMessage(messageType, message) {
root.header.contentItem.text = message; banner.text = message;
root.header.contentItem.type = messageType === ActionsHandler.Error ? Kirigami.MessageType.Error : messageType === ActionsHandler.Positive ? Kirigami.MessageType.Positive : Kirigami.MessageType.Information; banner.type = messageType === ActionsHandler.Error ? Kirigami.MessageType.Error : messageType === ActionsHandler.Positive ? Kirigami.MessageType.Positive : Kirigami.MessageType.Information;
root.header.visible = true; banner.visible = true;
} }
} }
function warning(title, message) { function warning(title, message) {
root.header.contentItem.text = `${title}<br />${message}`; banner.text = `${title}<br />${message}`;
root.header.contentItem.type = Kirigami.MessageType.Warning; banner.type = Kirigami.MessageType.Warning;
root.header.visible = true; banner.visible = true;
}
function showUserDetail(user) {
timelineViewLoader.item.showUserDetail(user)
} }
} }

View File

@@ -7,6 +7,8 @@ import QtQuick.Controls 2.15 as QQC2
import QtQuick.Layouts 1.15 import QtQuick.Layouts 1.15
import org.kde.kirigami 2.15 as Kirigami import org.kde.kirigami 2.15 as Kirigami
import org.kde.kirigamiaddons.delegates 1.0 as Delegates
import org.kde.kirigamiaddons.labs.components 1.0 as KirigamiComponents
import org.kde.neochat 1.0 import org.kde.neochat 1.0
@@ -60,69 +62,68 @@ Kirigami.ScrollablePage {
keyword: identifierField.text keyword: identifierField.text
} }
delegate: Kirigami.AbstractListItem { delegate: Delegates.RoundedItemDelegate {
width: userDictListView.width id: delegate
required property string userID
required property string avatar
required property string name
required property var directChats
text: name
contentItem: RowLayout { contentItem: RowLayout {
spacing: Kirigami.Units.largeSpacing KirigamiComponents.Avatar {
Layout.preferredWidth: Kirigami.Units.iconSizes.medium
Kirigami.Avatar { Layout.preferredHeight: Kirigami.Units.iconSizes.medium
Layout.preferredWidth: height source: delegate.avatar ? ("image://mxc/" + delegate.avatar) : ""
Layout.fillHeight: true name: delegate.name
source: model.avatar ? ("image://mxc/" + model.avatar) : ""
name: model.name
} }
ColumnLayout { Delegates.SubtitleContentItem {
itemDelegate: delegate
subtitle: delegate.userID
Layout.fillWidth: true Layout.fillWidth: true
Layout.fillHeight: true
spacing: 0
Kirigami.Heading {
Layout.fillWidth: true
Layout.fillHeight: true
text: name
textFormat: Text.PlainText
elide: Text.ElideRight
wrapMode: Text.NoWrap
}
QQC2.Label {
Layout.fillWidth: true
Layout.fillHeight: true
text: userID
textFormat: Text.PlainText
elide: Text.ElideRight
wrapMode: Text.NoWrap
}
} }
QQC2.Button { QQC2.Button {
id: joinChatButton id: joinChatButton
Layout.alignment: Qt.AlignRight
visible: directChats && directChats.length > 0 visible: delegate.directChats && delegate.directChats.length > 0
text: i18n("Join existing chat")
display: QQC2.Button.IconOnly
icon.name: "document-send" icon.name: "document-send"
onClicked: { onClicked: {
connection.requestDirectChat(userID); connection.requestDirectChat(delegate.userID);
applicationWindow().pageStack.layers.pop(); applicationWindow().pageStack.layers.pop();
} }
Layout.alignment: Qt.AlignRight
QQC2.ToolTip.text: text
QQC2.ToolTip.visible: hovered
QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
} }
QQC2.Button { QQC2.Button {
Layout.alignment: Qt.AlignRight
icon.name: "irc-join-channel" icon.name: "irc-join-channel"
// We wants to make sure an user can't start more than one // We wants to make sure an user can't start more than one
// chat with someone. // chat with someone.
visible: !joinChatButton.visible visible: !joinChatButton.visible
text: i18n("Create new chat")
display: QQC2.Button.IconOnly
onClicked: { onClicked: {
connection.requestDirectChat(userID); connection.requestDirectChat(delegate.userID);
applicationWindow().pageStack.layers.pop(); applicationWindow().pageStack.layers.pop();
} }
Layout.alignment: Qt.AlignRight
QQC2.ToolTip.text: text
QQC2.ToolTip.visible: hovered
QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
} }
} }
} }

View File

@@ -6,6 +6,7 @@ import QtQuick 2.15
import QtQuick.Controls 2.15 as QQC2 import QtQuick.Controls 2.15 as QQC2
import QtQuick.Layouts 1.15 import QtQuick.Layouts 1.15
import org.kde.kirigami 2.15 as Kirigami import org.kde.kirigami 2.15 as Kirigami
import org.kde.kirigamiaddons.labs.components 1.0 as KirigamiComponents
import org.kde.neochat 1.0 import org.kde.neochat 1.0
@@ -18,43 +19,45 @@ ColumnLayout {
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: Kirigami.Units.largeSpacing * 2 Layout.preferredHeight: Kirigami.Units.largeSpacing * 2
} }
Kirigami.Avatar {
QQC2.AbstractButton {
Layout.preferredWidth: Math.round(Kirigami.Units.gridUnit * 3.5) Layout.preferredWidth: Math.round(Kirigami.Units.gridUnit * 3.5)
Layout.preferredHeight: Math.round(Kirigami.Units.gridUnit * 3.5) Layout.preferredHeight: Math.round(Kirigami.Units.gridUnit * 3.5)
Layout.alignment: Qt.AlignHCenter Layout.alignment: Qt.AlignHCenter
name: room ? room.displayName : "" onClicked: {
source: room ? ("image://mxc/" + room.avatarMediaId) : "" const popup = userDetailDialog.createObject(QQC2.ApplicationWindow.overlay, {
room: room,
Rectangle { user: room.getUser(room.directChatRemoteUser.id),
visible: room.usesEncryption })
color: Kirigami.Theme.backgroundColor popup.closed.connect(() => {
userListItem.highlighted = false
width: Kirigami.Units.gridUnit })
height: Kirigami.Units.gridUnit if (roomDrawer.modal) {
anchors.bottom: parent.bottom roomDrawer.close()
anchors.right: parent.right
radius: Math.round(width / 2)
Kirigami.Icon {
source: "channel-secure-symbolic"
anchors.fill: parent
} }
popup.open()
} }
actions.main: Kirigami.Action {
onTriggered: { contentItem: KirigamiComponents.Avatar {
const popup = userDetailDialog.createObject(QQC2.ApplicationWindow.overlay, { name: room ? room.displayName : ""
room: room, source: room ? ("image://mxc/" + room.avatarMediaId) : ""
user: room.getUser(room.directChatRemoteUser.id),
}) Rectangle {
popup.closed.connect(() => { visible: room.usesEncryption
userListItem.highlighted = false color: Kirigami.Theme.backgroundColor
})
if (roomDrawer.modal) { width: Kirigami.Units.gridUnit
roomDrawer.close() height: Kirigami.Units.gridUnit
anchors.bottom: parent.bottom
anchors.right: parent.right
radius: Math.round(width / 2)
Kirigami.Icon {
source: "channel-secure-symbolic"
anchors.fill: parent
} }
popup.open()
} }
} }
} }

View File

@@ -6,6 +6,7 @@ import QtQuick 2.15
import QtQuick.Controls 2.15 as QQC2 import QtQuick.Controls 2.15 as QQC2
import QtQuick.Layouts 1.15 import QtQuick.Layouts 1.15
import org.kde.kirigami 2.20 as Kirigami import org.kde.kirigami 2.20 as Kirigami
import org.kde.kirigamiaddons.labs.components 1.0 as KirigamiComponents
import org.kde.neochat 1.0 import org.kde.neochat 1.0
@@ -17,11 +18,14 @@ ColumnLayout {
RowLayout { RowLayout {
Layout.fillWidth: true Layout.fillWidth: true
Layout.leftMargin: Kirigami.Units.largeSpacing Layout.leftMargin: Kirigami.Units.largeSpacing
Layout.topMargin: Kirigami.Units.largeSpacing
Layout.bottomMargin: Kirigami.Units.largeSpacing
spacing: Kirigami.Units.largeSpacing spacing: Kirigami.Units.largeSpacing
Kirigami.Avatar { KirigamiComponents.Avatar {
Layout.preferredWidth: Kirigami.Units.gridUnit * 3.5 Layout.preferredWidth: Kirigami.Units.iconSizes.large
Layout.preferredHeight: Kirigami.Units.gridUnit * 3.5 Layout.preferredHeight: Kirigami.Units.iconSizes.large
name: room ? room.displayName : "" name: room ? room.displayName : ""
source: room && room.avatarMediaId ? ("image://mxc/" + room.avatarMediaId) : "" source: room && room.avatarMediaId ? ("image://mxc/" + room.avatarMediaId) : ""
@@ -47,6 +51,7 @@ ColumnLayout {
} }
} }
ColumnLayout { ColumnLayout {
Layout.fillWidth: true Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter Layout.alignment: Qt.AlignVCenter
@@ -54,14 +59,13 @@ ColumnLayout {
Kirigami.Heading { Kirigami.Heading {
Layout.fillWidth: true Layout.fillWidth: true
type: Kirigami.Heading.Type.Primary
wrapMode: QQC2.Label.Wrap
text: room ? room.displayName : i18n("No name") text: room ? room.displayName : i18n("No name")
textFormat: Text.PlainText textFormat: Text.PlainText
} }
Kirigami.SelectableLabel { Kirigami.SelectableLabel {
Layout.fillWidth: true Layout.fillWidth: true
font: Kirigami.Theme.smallFont
textFormat: TextEdit.PlainText textFormat: TextEdit.PlainText
text: room && room.canonicalAlias ? room.canonicalAlias : i18n("No Canonical Alias") text: room && room.canonicalAlias ? room.canonicalAlias : i18n("No Canonical Alias")
} }

View File

@@ -7,6 +7,8 @@ import QtQuick.Controls 2.15 as QQC2
import QtQuick.Layouts 1.15 import QtQuick.Layouts 1.15
import org.kde.kirigami 2.20 as Kirigami import org.kde.kirigami 2.20 as Kirigami
import org.kde.kirigamiaddons.delegates 1.0 as Delegates
import org.kde.kirigamiaddons.labs.components 1.0 as KirigamiComponents
import org.kde.kitemmodels 1.0 import org.kde.kitemmodels 1.0
import org.kde.neochat 1.0 import org.kde.neochat 1.0
@@ -73,11 +75,15 @@ Kirigami.OverlayDrawer {
active: roomDrawer.drawerOpen active: roomDrawer.drawerOpen
sourceComponent: ColumnLayout { sourceComponent: ColumnLayout {
readonly property string userSearchText: userListView.headerItem.userListSearchField.text readonly property string userSearchText: userListView.headerItem ? userListView.headerItem.userListSearchField.text : ''
property alias highlightedUser: userListView.currentIndex property alias highlightedUser: userListView.currentIndex
spacing: 0 spacing: 0
function clearSearch() {
userListView.headerItem.userListSearchField.text = ""
}
QQC2.ToolBar { QQC2.ToolBar {
Layout.fillWidth: true Layout.fillWidth: true
@@ -120,7 +126,7 @@ Kirigami.OverlayDrawer {
property alias userListSearchField: userListSearchField property alias userListSearchField: userListSearchField
spacing: Kirigami.Units.largeSpacing spacing: 0
width: userListView.width width: userListView.width
Loader { Loader {
@@ -128,31 +134,41 @@ Kirigami.OverlayDrawer {
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: Kirigami.Units.smallSpacing Layout.topMargin: Kirigami.Units.smallSpacing
sourceComponent: room.isDirectChat() ? directChatDrawerHeader : groupChatDrawerHeader sourceComponent: room.isDirectChat() ? directChatDrawerHeader : groupChatDrawerHeader
onItemChanged: if (item) {
userListView.positionViewAtBeginning();
}
} }
Kirigami.ListSectionHeader { Kirigami.ListSectionHeader {
label: i18n("Options") label: i18n("Options")
activeFocusOnTab: false activeFocusOnTab: false
Layout.fillWidth: true
} }
Kirigami.BasicListItem { Delegates.RoundedItemDelegate {
id: devtoolsButton id: devtoolsButton
icon: "tools" icon.name: "tools"
text: i18n("Open developer tools") text: i18n("Open developer tools")
visible: Config.developerTools visible: Config.developerTools
Layout.fillWidth: true
onClicked: { onClicked: {
applicationWindow().pageStack.layers.push("qrc:/DevtoolsPage.qml", {room: room}, {title: i18n("Developer Tools")}) applicationWindow().pageStack.layers.push("qrc:/DevtoolsPage.qml", {room: room}, {title: i18n("Developer Tools")})
roomDrawer.close(); roomDrawer.close();
} }
} }
Kirigami.BasicListItem {
Delegates.RoundedItemDelegate {
id: searchButton id: searchButton
icon: "search" icon.name: "search"
text: i18n("Search in this room") text: i18n("Search in this room")
Layout.fillWidth: true
onClicked: { onClicked: {
pageStack.pushDialogLayer("qrc:/SearchPage.qml", { pageStack.pushDialogLayer("qrc:/SearchPage.qml", {
currentRoom: room currentRoom: room
@@ -161,19 +177,22 @@ Kirigami.OverlayDrawer {
}) })
} }
} }
Kirigami.BasicListItem {
Delegates.RoundedItemDelegate {
id: favouriteButton id: favouriteButton
icon: room && room.isFavourite ? "rating" : "rating-unrated" icon.name: room && room.isFavourite ? "rating" : "rating-unrated"
text: room && room.isFavourite ? i18n("Remove room from favorites") : i18n("Make room favorite") text: room && room.isFavourite ? i18n("Remove room from favorites") : i18n("Make room favorite")
onClicked: room.isFavourite ? room.removeTag("m.favourite") : room.addTag("m.favourite", 1.0) onClicked: room.isFavourite ? room.removeTag("m.favourite") : room.addTag("m.favourite", 1.0)
Layout.fillWidth: true
} }
Kirigami.BasicListItem { Delegates.RoundedItemDelegate {
id: locationsButton id: locationsButton
icon: "map-flat" icon.name: "map-flat"
text: i18n("Show locations for this room") text: i18n("Show locations for this room")
onClicked: pageStack.pushDialogLayer("qrc:/LocationsPage.qml", { onClicked: pageStack.pushDialogLayer("qrc:/LocationsPage.qml", {
@@ -181,6 +200,8 @@ Kirigami.OverlayDrawer {
}, { }, {
title: i18nc("Locations on a map", "Locations") title: i18nc("Locations on a map", "Locations")
}) })
Layout.fillWidth: true
} }
Kirigami.ListSectionHeader { Kirigami.ListSectionHeader {
@@ -189,6 +210,8 @@ Kirigami.OverlayDrawer {
spacing: 0 spacing: 0
visible: !room.isDirectChat() visible: !room.isDirectChat()
Layout.fillWidth: true
QQC2.ToolButton { QQC2.ToolButton {
id: memberSearchToggle id: memberSearchToggle
checkable: true checkable: true
@@ -255,44 +278,62 @@ Kirigami.OverlayDrawer {
clip: true clip: true
activeFocusOnTab: true activeFocusOnTab: true
delegate: Kirigami.BasicListItem { delegate: Delegates.RoundedItemDelegate {
id: userListItem id: userDelegate
required property string name
required property string userId
required property string avatar
required property int powerLevel
required property string powerLevelString
implicitHeight: Kirigami.Units.gridUnit * 2 implicitHeight: Kirigami.Units.gridUnit * 2
leftPadding: Kirigami.Units.largeSpacing + Kirigami.Units.smallSpacing
label: name text: name
labelItem.textFormat: Text.PlainText
onClicked: { onClicked: {
userDelegate.highlighted = true;
const popup = userDetailDialog.createObject(QQC2.ApplicationWindow.overlay, { const popup = userDetailDialog.createObject(QQC2.ApplicationWindow.overlay, {
room: room, room: room,
user: room.getUser(user.id) user: room.getUser(userDelegate.userId)
}) });
popup.closed.connect(function() { popup.closed.connect(() => {
userListItem.highlighted = false userDelegate.highlighted = false;
}) });
if (roomDrawer.modal) { if (roomDrawer.modal) {
roomDrawer.close() roomDrawer.close();
} }
popup.open() popup.open();
} }
leading: Kirigami.Avatar { contentItem: RowLayout {
implicitWidth: height KirigamiComponents.Avatar {
sourceSize.height: Kirigami.Units.gridUnit + Kirigami.Units.smallSpacing * 2.5 implicitWidth: height
sourceSize.width: Kirigami.Units.gridUnit + Kirigami.Units.smallSpacing * 2.5 sourceSize {
source: avatar height: Kirigami.Units.gridUnit + Kirigami.Units.smallSpacing * 2.5
name: model.userId width: Kirigami.Units.gridUnit + Kirigami.Units.smallSpacing * 2.5
} }
source: userDelegate.avatar
name: userDelegate.userId
trailing: QQC2.Label { Layout.fillHeight: true
visible: powerLevel > 0 }
text: powerLevelString QQC2.Label {
color: Kirigami.Theme.disabledTextColor text: userDelegate.name
textFormat: Text.PlainText textFormat: Text.PlainText
wrapMode: Text.NoWrap elide: Text.ElideRight
Layout.fillWidth: true
}
QQC2.Label {
visible: userDelegate.powerLevel > 0
text: userDelegate.powerLevelString
color: Kirigami.Theme.disabledTextColor
textFormat: Text.PlainText
}
} }
} }
} }
@@ -302,7 +343,7 @@ Kirigami.OverlayDrawer {
onRoomChanged: { onRoomChanged: {
if (loader.active) { if (loader.active) {
loader.item.userSearchText = "" loader.item.clearSearch()
loader.item.highlightedUser = -1 loader.item.highlightedUser = -1
} }
if (room == null) { if (room == null) {

View File

@@ -9,6 +9,7 @@ import QtQuick.Window 2.15
import org.kde.kirigami 2.15 as Kirigami import org.kde.kirigami 2.15 as Kirigami
import org.kde.kirigamiaddons.labs.mobileform 0.1 as MobileForm import org.kde.kirigamiaddons.labs.mobileform 0.1 as MobileForm
import org.kde.kirigamiaddons.labs.components 1.0 as KirigamiComponents
import org.kde.neochat 1.0 import org.kde.neochat 1.0
@@ -38,11 +39,13 @@ Kirigami.ScrollablePage {
Item { Item {
Layout.fillWidth: true Layout.fillWidth: true
} }
Kirigami.Avatar { KirigamiComponents.Avatar {
id: avatar id: avatar
Layout.alignment: Qt.AlignRight Layout.alignment: Qt.AlignRight
name: room.name name: room.name
source: room.avatarMediaId ? ("image://mxc/" + room.avatarMediaId) : "" source: room.avatarMediaId ? ("image://mxc/" + room.avatarMediaId) : ""
implicitWidth: Kirigami.Units.iconSizes.medium
implicitHeight: Kirigami.Units.iconSizes.medium
} }
QQC2.Button { QQC2.Button {
Layout.alignment: Qt.AlignLeft Layout.alignment: Qt.AlignLeft

View File

@@ -7,6 +7,8 @@ import QtQuick.Layouts 1.15
import org.kde.kirigami 2.15 as Kirigami import org.kde.kirigami 2.15 as Kirigami
import org.kde.kirigamiaddons.labs.mobileform 0.1 as MobileForm import org.kde.kirigamiaddons.labs.mobileform 0.1 as MobileForm
import org.kde.kirigamiaddons.delegates 1.0 as Delegates
import org.kde.kirigamiaddons.labs.components 1.0 as KirigamiComponents
import org.kde.kitemmodels 1.0 import org.kde.kitemmodels 1.0
import org.kde.neochat 1.0 import org.kde.neochat 1.0
@@ -93,17 +95,19 @@ Kirigami.ScrollablePage {
visible: room.canSendState("m.room.power_levels") visible: room.canSendState("m.room.power_levels")
contentItem: Kirigami.SearchField { contentItem: Kirigami.SearchField {
id: userListSearchField id: userListSearchField
Layout.fillWidth: true
autoAccept: false
Keys.onUpPressed: userListView.decrementCurrentIndex() autoAccept: false
Keys.onDownPressed: userListView.incrementCurrentIndex()
onAccepted: { Layout.fillWidth: true
let currentUser = userListView.itemAtIndex(userListView.currentIndex);
currentUser.action.trigger(); Keys.onUpPressed: userListView.decrementCurrentIndex()
} Keys.onDownPressed: userListView.incrementCurrentIndex()
onAccepted: {
let currentUser = userListView.itemAtIndex(userListView.currentIndex);
currentUser.action.trigger();
}
} }
QQC2.Popup { QQC2.Popup {
id: userListSearchPopup id: userListSearchPopup
@@ -119,21 +123,31 @@ Kirigami.ScrollablePage {
return Math.max(Math.min(filterContentHeight, maxHeight), minHeight); return Math.max(Math.min(filterContentHeight, maxHeight), minHeight);
} }
padding: Kirigami.Units.smallSpacing padding: Kirigami.Units.smallSpacing
leftPadding: Kirigami.Units.smallSpacing / 2
rightPadding: Kirigami.Units.smallSpacing / 2
modal: false modal: false
onClosed: userListSearchField.text = "" onClosed: userListSearchField.text = ""
background: Kirigami.ShadowedRectangle { background: Kirigami.ShadowedRectangle {
property color borderColor: Kirigami.Theme.textColor
Kirigami.Theme.colorSet: Kirigami.Theme.View
Kirigami.Theme.inherit: false
radius: 4 radius: 4
color: Kirigami.Theme.backgroundColor color: Kirigami.Theme.backgroundColor
property color borderColor: Kirigami.Theme.textColor border {
border.color: Qt.rgba(borderColor.r, borderColor.g, borderColor.b, 0.3) color: Qt.rgba(borderColor.r, borderColor.g, borderColor.b, 0.3)
border.width: 1 width: 1
}
shadow.xOffset: 0 shadow {
shadow.yOffset: 4 xOffset: 0
shadow.color: Qt.rgba(0, 0, 0, 0.3) yOffset: 4
shadow.size: 8 color: Qt.rgba(0, 0, 0, 0.3)
size: 8
}
} }
contentItem: QQC2.ScrollView { contentItem: QQC2.ScrollView {
@@ -158,16 +172,42 @@ Kirigami.ScrollablePage {
} }
} }
delegate: Kirigami.BasicListItem { delegate: Delegates.RoundedItemDelegate {
id: userListItem id: userListItem
implicitHeight: Kirigami.Units.gridUnit * 2 required property string userId
leftPadding: Kirigami.Units.largeSpacing + Kirigami.Units.smallSpacing required property string avatar
required property string name
required property int powerLevel
required property string powerLevelString
label: name text: name
labelItem.textFormat: Text.PlainText
subtitle: userId contentItem: RowLayout {
subtitleItem.textFormat: Text.PlainText KirigamiComponents.Avatar {
Layout.preferredWidth: Kirigami.Units.iconSizes.medium
Layout.preferredHeight: Kirigami.Units.iconSizes.medium
source: userListItem.avatar ? ("image://" + userListItem.avatar) : ""
name: userListItem.name
}
Delegates.SubtitleContentItem {
itemDelegate: userListItem
subtitle: userListItem.userId
labelItem.textFormat: Text.PlainText
subtitleItem.textFormat: Text.PlainText
Layout.fillWidth: true
}
QQC2.Label {
visible: userListItem.powerLevel > 0
text: userListItem.powerLevelString
color: Kirigami.Theme.disabledTextColor
textFormat: Text.PlainText
wrapMode: Text.NoWrap
}
}
action: Kirigami.Action { action: Kirigami.Action {
id: editPowerLevelAction id: editPowerLevelAction
@@ -175,30 +215,13 @@ Kirigami.ScrollablePage {
userListSearchPopup.close() userListSearchPopup.close()
let dialog = powerLevelDialog.createObject(applicationWindow().overlay, { let dialog = powerLevelDialog.createObject(applicationWindow().overlay, {
room: root.room, room: root.room,
userId: model.userId, userId: userListItem.userId,
powerLevel: model.powerLevel powerLevel: userListItem.powerLevel
}); });
dialog.open(); dialog.open();
} }
} }
leading: Kirigami.Avatar {
implicitWidth: height
sourceSize.height: Kirigami.Units.gridUnit + Kirigami.Units.smallSpacing * 2.5
sourceSize.width: Kirigami.Units.gridUnit + Kirigami.Units.smallSpacing * 2.5
source: avatar ? ("image://mxc/" + avatar) : ""
name: model.userId
}
trailing: QQC2.Label {
visible: powerLevel > 0
text: powerLevelString
color: Kirigami.Theme.disabledTextColor
textFormat: Text.PlainText
wrapMode: Text.NoWrap
}
Component { Component {
id: powerLevelDialog id: powerLevelDialog
PowerLevelDialog { PowerLevelDialog {

View File

@@ -10,6 +10,7 @@ import QtQuick.Window 2.15
import org.kde.kirigami 2.15 as Kirigami import org.kde.kirigami 2.15 as Kirigami
import org.kde.kirigamiaddons.labs.mobileform 0.1 as MobileForm import org.kde.kirigamiaddons.labs.mobileform 0.1 as MobileForm
import org.kde.kirigamiaddons.labs.components 1.0 as KirigamiComponents
import org.kde.neochat 1.0 import org.kde.neochat 1.0
Kirigami.ScrollablePage { Kirigami.ScrollablePage {
@@ -24,6 +25,78 @@ Kirigami.ScrollablePage {
rightPadding: 0 rightPadding: 0
ColumnLayout { ColumnLayout {
spacing: 0 spacing: 0
QQC2.RoundButton {
property var fileDialog: null;
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
Layout.topMargin: Kirigami.Units.largeSpacing
// Square button
implicitWidth: Kirigami.Units.gridUnit * 5
implicitHeight: implicitWidth
padding: 0
contentItem: KirigamiComponents.Avatar {
id: avatar
source: root.connection && root.connection.localUser.avatarMediaId ? ("image://mxc/" + root.connection.localUser.avatarMediaId) : ""
name: root.connection.localUser.displayName
}
onClicked: {
if (fileDialog != null) {
return;
}
fileDialog = openFileDialog.createObject(QQC2.ApplicationWindow.Overlay)
fileDialog.chosen.connect(function(receivedSource) {
if (!receivedSource) {
return;
}
avatar.source = receivedSource;
});
fileDialog.onRejected.connect(function() {
mouseArea.fileDialog = null;
});
fileDialog.open();
}
QQC2.Button {
anchors {
bottom: parent.bottom
right: parent.right
}
visible: avatar.source.toString().length === 0
icon.name: "cloud-upload"
text: i18n("Upload new avatar")
display: QQC2.AbstractButton.IconOnly
onClicked: parent.onClicked()
QQC2.ToolTip.text: text
QQC2.ToolTip.visible: hovered
QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
}
QQC2.Button {
anchors {
bottom: parent.bottom
right: parent.right
}
visible: avatar.source.toString().length !== 0
icon.name: "edit-clear"
text: i18n("Remove current avatar")
display: QQC2.AbstractButton.IconOnly
onClicked: avatar.source = ""
QQC2.ToolTip.text: text
QQC2.ToolTip.visible: hovered
QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
}
}
MobileForm.FormHeader { MobileForm.FormHeader {
Layout.fillWidth: true Layout.fillWidth: true
title: i18n("User information") title: i18n("User information")
@@ -32,73 +105,22 @@ Kirigami.ScrollablePage {
Layout.fillWidth: true Layout.fillWidth: true
contentItem: ColumnLayout { contentItem: ColumnLayout {
spacing: 0 spacing: 0
MobileForm.AbstractFormDelegate {
Layout.fillWidth: true
background: Item {}
contentItem: RowLayout {
Item {
Layout.fillWidth: true
}
Kirigami.Avatar {
id: avatar
Layout.alignment: Qt.AlignRight
source: root.connection && root.connection.localUser.avatarMediaId ? ("image://mxc/" + root.connection.localUser.avatarMediaId) : ""
name: root.connection.localUser.displayName
MouseArea {
id: mouseArea
anchors.fill: parent
property var fileDialog: null;
onClicked: {
if (fileDialog != null) {
return;
}
fileDialog = openFileDialog.createObject(QQC2.ApplicationWindow.Overlay)
fileDialog.chosen.connect(function(receivedSource) {
mouseArea.fileDialog = null;
if (!receivedSource) {
return;
}
parent.source = receivedSource;
});
fileDialog.onRejected.connect(function() {
mouseArea.fileDialog = null;
});
fileDialog.open();
}
}
}
QQC2.Button {
Layout.alignment: Qt.AlignLeft
visible: avatar.source.toString().length !== 0
icon.name: "edit-clear"
text: i18n("Remove current avatar")
display: QQC2.AbstractButton.IconOnly
onClicked: avatar.source = ""
QQC2.ToolTip.text: text
QQC2.ToolTip.visible: hovered
}
Item {
Layout.fillWidth: true
}
}
}
MobileForm.FormTextFieldDelegate { MobileForm.FormTextFieldDelegate {
id: name id: name
label: i18n("Name:") label: i18n("Name:")
text: root.connection ? root.connection.localUser.displayName : "" text: root.connection ? root.connection.localUser.displayName : ""
} }
MobileForm.FormDelegateSeparator {}
MobileForm.FormTextFieldDelegate { MobileForm.FormTextFieldDelegate {
id: accountLabel id: accountLabel
label: i18n("Label:") label: i18n("Label:")
text: root.connection ? Controller.activeAccountLabel : "" text: root.connection ? Controller.activeAccountLabel : ""
} }
MobileForm.FormDelegateSeparator {}
MobileForm.AbstractFormDelegate { MobileForm.AbstractFormDelegate {
Layout.fillWidth: true Layout.fillWidth: true
background: Item {} background: null
padding: Kirigami.Units.smallSpacing
contentItem: RowLayout { contentItem: RowLayout {
Item { Item {
Layout.fillWidth: true Layout.fillWidth: true
@@ -136,18 +158,21 @@ Kirigami.ScrollablePage {
visible: root.connection !== undefined && root.connection.canChangePassword === false visible: root.connection !== undefined && root.connection.canChangePassword === false
text: i18n("Your server doesn't support changing your password") text: i18n("Your server doesn't support changing your password")
} }
MobileForm.FormDelegateSeparator { visible: root.connection !== undefined && root.connection.canChangePassword === false }
MobileForm.FormTextFieldDelegate { MobileForm.FormTextFieldDelegate {
id: currentPassword id: currentPassword
label: i18n("Current Password:") label: i18n("Current Password:")
enabled: root.connection !== undefined && root.connection.canChangePassword !== false enabled: root.connection !== undefined && root.connection.canChangePassword !== false
echoMode: TextInput.Password echoMode: TextInput.Password
} }
MobileForm.FormDelegateSeparator {}
MobileForm.FormTextFieldDelegate { MobileForm.FormTextFieldDelegate {
id: newPassword id: newPassword
label: i18n("New Password:") label: i18n("New Password:")
enabled: root.connection !== undefined && root.connection.canChangePassword !== false enabled: root.connection !== undefined && root.connection.canChangePassword !== false
echoMode: TextInput.Password echoMode: TextInput.Password
} }
MobileForm.FormDelegateSeparator {}
MobileForm.FormTextFieldDelegate { MobileForm.FormTextFieldDelegate {
id: confirmPassword id: confirmPassword
label: i18n("Confirm new Password:") label: i18n("Confirm new Password:")
@@ -161,9 +186,10 @@ Kirigami.ScrollablePage {
confirmPassword.statusMessage = ''; confirmPassword.statusMessage = '';
} }
} }
MobileForm.FormDelegateSeparator {}
MobileForm.AbstractFormDelegate { MobileForm.AbstractFormDelegate {
Layout.fillWidth: true Layout.fillWidth: true
background: Item {} background: null
contentItem: RowLayout { contentItem: RowLayout {
Item { Item {
Layout.fillWidth: true Layout.fillWidth: true

View File

@@ -8,6 +8,7 @@ import Qt.labs.platform 1.1
import org.kde.kirigami 2.19 as Kirigami import org.kde.kirigami 2.19 as Kirigami
import org.kde.kirigamiaddons.labs.mobileform 0.1 as MobileForm import org.kde.kirigamiaddons.labs.mobileform 0.1 as MobileForm
import org.kde.kirigamiaddons.labs.components 1.0 as KirigamiComponents
import org.kde.neochat 1.0 import org.kde.neochat 1.0
@@ -38,7 +39,7 @@ Kirigami.ScrollablePage {
}) })
contentItem: RowLayout { contentItem: RowLayout {
Kirigami.Avatar { KirigamiComponents.Avatar {
name: model.connection.localUser.displayName name: model.connection.localUser.displayName
source: model.connection.localUser.avatarMediaId ? ("image://mxc/" + model.connection.localUser.avatarMediaId) : "" source: model.connection.localUser.avatarMediaId ? ("image://mxc/" + model.connection.localUser.avatarMediaId) : ""

View File

@@ -8,6 +8,7 @@ import QtQuick.Layouts 1.15
import org.kde.kirigami 2.15 as Kirigami import org.kde.kirigami 2.15 as Kirigami
import org.kde.kirigamiaddons.labs.mobileform 0.1 as MobileForm import org.kde.kirigamiaddons.labs.mobileform 0.1 as MobileForm
import org.kde.kirigamiaddons.labs.components 1.0 as KirigamiComponents
import org.kde.neochat 1.0 import org.kde.neochat 1.0
@@ -42,7 +43,7 @@ Kirigami.ScrollablePage {
innerObject: [ innerObject: [
RowLayout { RowLayout {
Layout.fillWidth: true Layout.fillWidth: true
Kirigami.Avatar { KirigamiComponents.Avatar {
color: "#4a5bcc" color: "#4a5bcc"
Layout.alignment: Qt.AlignTop Layout.alignment: Qt.AlignTop
visible: Config.showAvatarInTimeline visible: Config.showAvatarInTimeline
@@ -79,7 +80,7 @@ Kirigami.ScrollablePage {
}, },
RowLayout { RowLayout {
Layout.fillWidth: true Layout.fillWidth: true
Kirigami.Avatar { KirigamiComponents.Avatar {
color: "#9f244b" color: "#9f244b"
Layout.alignment: Qt.AlignTop Layout.alignment: Qt.AlignTop
visible: Config.showAvatarInTimeline visible: Config.showAvatarInTimeline
@@ -132,7 +133,7 @@ Kirigami.ScrollablePage {
innerObject: [ innerObject: [
RowLayout { RowLayout {
Layout.fillWidth: true Layout.fillWidth: true
Kirigami.Avatar { KirigamiComponents.Avatar {
color: "#4a5bcc" color: "#4a5bcc"
Layout.alignment: Qt.AlignTop Layout.alignment: Qt.AlignTop
visible: Config.showAvatarInTimeline visible: Config.showAvatarInTimeline
@@ -159,7 +160,7 @@ Kirigami.ScrollablePage {
}, },
RowLayout { RowLayout {
Layout.fillWidth: true Layout.fillWidth: true
Kirigami.Avatar { KirigamiComponents.Avatar {
color: "#9f244b" color: "#9f244b"
Layout.alignment: Qt.AlignTop Layout.alignment: Qt.AlignTop
visible: Config.showAvatarInTimeline visible: Config.showAvatarInTimeline

View File

@@ -61,7 +61,7 @@ RemoteMatches Runner::Match(const QString &searchTerm)
const QString name = m_model.data(m_model.index(i, 0), RoomListModel::DisplayNameRole).toString(); const QString name = m_model.data(m_model.index(i, 0), RoomListModel::DisplayNameRole).toString();
match.iconName = QStringLiteral("org.kde.neochat"); match.iconName = QStringLiteral("org.kde.neochat");
match.id = m_model.data(m_model.index(i, 0), RoomListModel::IdRole).toString(); match.id = m_model.data(m_model.index(i, 0), RoomListModel::RoomIdRole).toString();
match.text = name; match.text = name;
match.relevance = 1; match.relevance = 1;
const RemoteImage remoteImage = serializeImage(m_model.data(m_model.index(i, 0), RoomListModel::AvatarImageRole).value<QImage>()); const RemoteImage remoteImage = serializeImage(m_model.data(m_model.index(i, 0), RoomListModel::AvatarImageRole).value<QImage>());