Compare commits
120 Commits
work/tobia
...
v24.04.80
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eeddf99ca5 | ||
|
|
09a35b1a7e | ||
|
|
533182ec55 | ||
|
|
70a8842f00 | ||
|
|
ab33d1ca88 | ||
|
|
9e45f22e09 | ||
|
|
6a627dfff0 | ||
|
|
a9f05a7f63 | ||
|
|
4dfd4b68eb | ||
|
|
3786710d81 | ||
|
|
3967b27352 | ||
|
|
714ea8413c | ||
|
|
4097addae9 | ||
|
|
e9ac9deb40 | ||
|
|
3b858ab7d5 | ||
|
|
08807797a5 | ||
|
|
923839d6c7 | ||
|
|
3d4a1d22b0 | ||
|
|
5aa7f499c0 | ||
|
|
40c3519737 | ||
|
|
6ec9cc2475 | ||
|
|
eba34b19ad | ||
|
|
8517636485 | ||
|
|
4a96dae57d | ||
|
|
09f433be45 | ||
|
|
b9901a9167 | ||
|
|
8b27d99d82 | ||
|
|
6b53c4d7b1 | ||
|
|
bd28a7f66d | ||
|
|
0d1c09696d | ||
|
|
aeb4013d26 | ||
|
|
08a7e324aa | ||
|
|
9202a4525f | ||
|
|
bfc756fb35 | ||
|
|
2a735ff1cc | ||
|
|
551092a1b4 | ||
|
|
ddd12688aa | ||
|
|
71767c4172 | ||
|
|
ee405fbff6 | ||
|
|
c87c6fbabb | ||
|
|
096b36b89b | ||
|
|
c3db90d2e3 | ||
|
|
b7df10aa45 | ||
|
|
fea5e02e7d | ||
|
|
cb94261727 | ||
|
|
efac7e4860 | ||
|
|
0f6fd3adee | ||
|
|
e5e0405401 | ||
|
|
bb35e9ce15 | ||
|
|
5881db4e55 | ||
|
|
89f7167b08 | ||
|
|
3b39fcff84 | ||
|
|
0daf45a465 | ||
|
|
c0d7b96e79 | ||
|
|
a247e40865 | ||
|
|
c3e7a99bca | ||
|
|
9080d8be6a | ||
|
|
b7ee83f6b6 | ||
|
|
1e24bde9a9 | ||
|
|
ba82df1152 | ||
|
|
8980fe7838 | ||
|
|
ef34ed7c20 | ||
|
|
17d60b79ca | ||
|
|
ab0a32c339 | ||
|
|
697778df8d | ||
|
|
55caf84b94 | ||
|
|
335c012f1b | ||
|
|
3c4c538de8 | ||
|
|
c344a3ee55 | ||
|
|
d2695947ed | ||
|
|
21beeef920 | ||
|
|
a4630a53fa | ||
|
|
f5aef8d0c3 | ||
|
|
e044e66030 | ||
|
|
88bfacd386 | ||
|
|
c61c73088f | ||
|
|
2887263f26 | ||
|
|
72b90bdf5c | ||
|
|
163b02f023 | ||
|
|
1a96899336 | ||
|
|
554c086aba | ||
|
|
1fad9bf7db | ||
|
|
22d922e451 | ||
|
|
70bff21632 | ||
|
|
f58c390a47 | ||
|
|
089a9abcb4 | ||
|
|
bf1c76d0a6 | ||
|
|
879da627b1 | ||
|
|
9b93eb44d5 | ||
|
|
b30220eca9 | ||
|
|
d270d4e5e1 | ||
|
|
21da6cb0f4 | ||
|
|
6ac75df935 | ||
|
|
f29781349c | ||
|
|
bb776d5c2b | ||
|
|
6cfab9e3ea | ||
|
|
6373186c15 | ||
|
|
e342de3bc1 | ||
|
|
4cd7b69ea5 | ||
|
|
988e8529da | ||
|
|
6a32d1e961 | ||
|
|
0552c798fb | ||
|
|
a53ad41879 | ||
|
|
92351edcd0 | ||
|
|
878eb48cb0 | ||
|
|
053ca6bed8 | ||
|
|
78ae14ab2f | ||
|
|
5fdc2ad765 | ||
|
|
b75dbe8d5c | ||
|
|
eaf4663c84 | ||
|
|
64b8cd5bcc | ||
|
|
482d61ee47 | ||
|
|
276dcce95e | ||
|
|
217f9e2e02 | ||
|
|
f40a0a6f5f | ||
|
|
9bd67acc2f | ||
|
|
e87da0feb0 | ||
|
|
2608d879fa | ||
|
|
6ab61fd41f | ||
|
|
30dd6297ee |
@@ -110,7 +110,7 @@
|
|||||||
{
|
{
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/quotient-im/libQuotient.git",
|
"url": "https://github.com/quotient-im/libQuotient.git",
|
||||||
"branch": "dev",
|
"branch": "0.8.x",
|
||||||
"disable-submodules": true
|
"disable-submodules": true
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -12,3 +12,4 @@ kate.project.ctags.*
|
|||||||
.idea/
|
.idea/
|
||||||
cmake-build-*
|
cmake-build-*
|
||||||
src/res.generated.qrc
|
src/res.generated.qrc
|
||||||
|
.qmlls.ini
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ Dependencies:
|
|||||||
'frameworks/kio': '@latest-kf6'
|
'frameworks/kio': '@latest-kf6'
|
||||||
'frameworks/kwindowsystem': '@latest-kf6'
|
'frameworks/kwindowsystem': '@latest-kf6'
|
||||||
'frameworks/kstatusnotifieritem': '@latest-kf6'
|
'frameworks/kstatusnotifieritem': '@latest-kf6'
|
||||||
|
'frameworks/kcrash': '@latest-kf6'
|
||||||
- 'on': ['Linux', 'FreeBSD']
|
- 'on': ['Linux', 'FreeBSD']
|
||||||
'require':
|
'require':
|
||||||
'frameworks/kdbusaddons': '@latest-kf6'
|
'frameworks/kdbusaddons': '@latest-kf6'
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ cmake_minimum_required(VERSION 3.16)
|
|||||||
# KDE Applications version, managed by release script.
|
# KDE Applications version, managed by release script.
|
||||||
set(RELEASE_SERVICE_VERSION_MAJOR "24")
|
set(RELEASE_SERVICE_VERSION_MAJOR "24")
|
||||||
set(RELEASE_SERVICE_VERSION_MINOR "04")
|
set(RELEASE_SERVICE_VERSION_MINOR "04")
|
||||||
set(RELEASE_SERVICE_VERSION_MICRO "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})
|
||||||
@@ -84,7 +84,7 @@ if(ANDROID)
|
|||||||
)
|
)
|
||||||
else()
|
else()
|
||||||
find_package(Qt6 ${QT_MIN_VERSION} COMPONENTS Widgets)
|
find_package(Qt6 ${QT_MIN_VERSION} COMPONENTS Widgets)
|
||||||
find_package(KF6 ${KF_MIN_VERSION} REQUIRED COMPONENTS QQC2DesktopStyle KIO WindowSystem StatusNotifierItem)
|
find_package(KF6 ${KF_MIN_VERSION} REQUIRED COMPONENTS QQC2DesktopStyle KIO WindowSystem StatusNotifierItem Crash)
|
||||||
find_package(KF6SyntaxHighlighting ${KF_MIN_VERSION} REQUIRED)
|
find_package(KF6SyntaxHighlighting ${KF_MIN_VERSION} REQUIRED)
|
||||||
set_package_properties(KF6QQC2DesktopStyle PROPERTIES
|
set_package_properties(KF6QQC2DesktopStyle PROPERTIES
|
||||||
TYPE RUNTIME
|
TYPE RUNTIME
|
||||||
|
|||||||
48
README.md
48
README.md
@@ -1,6 +1,6 @@
|
|||||||
<!--
|
<!--
|
||||||
SPDX-FileCopyrightText: 2020-2021 Carl Schwan <carlschwan@kde.org>
|
SPDX-FileCopyrightText: 2020-2021 Carl Schwan <carlschwan@kde.org>
|
||||||
SPDX-FileCopyrightText: 2020-2021 Tobias Fella <tobias.fella@kde.org>
|
SPDX-FileCopyrightText: 2020-2024 Tobias Fella <tobias.fella@kde.org>
|
||||||
SPDX-FileCopyrightText: 2023 James Graham <james.h.graham@protonmail.com>
|
SPDX-FileCopyrightText: 2023 James Graham <james.h.graham@protonmail.com>
|
||||||
SPDX-License-Identifier: CC0-1.0
|
SPDX-License-Identifier: CC0-1.0
|
||||||
-->
|
-->
|
||||||
@@ -16,19 +16,18 @@ A Qt/QML based Matrix client.
|
|||||||
## Introduction
|
## Introduction
|
||||||
|
|
||||||
NeoChat is a client for [Matrix](https://matrix.org), the decentralized communication protocol for instant
|
NeoChat is a client for [Matrix](https://matrix.org), the decentralized communication protocol for instant
|
||||||
messaging. It is a fork of Spectral, using KDE frameworks, most notably [Kirigami](https://invent.kde.org/frameworks/kirigami)
|
messaging.
|
||||||
to provide a convergent experience across multiple platforms.
|
|
||||||
|
|
||||||
NeoChat also make use of other KDE Frameworks as well as [libQuotient](https://github.com/quotient-im/libQuotient), a
|
NeoChat is based on KDE frameworks and as [libQuotient](https://github.com/quotient-im/libQuotient), a
|
||||||
Qt-based SDK for the [Matrix Protocol](https://spec.matrix.org/).
|
Qt-based SDK for the [Matrix Protocol](https://spec.matrix.org/).
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
NeoChat aims to be a fully featured application for the Matrix specification. As such everything in the current stable specification with the notable exceptions
|
NeoChat aims to be a fully featured application for the Matrix specification. As such most parts of the current specification are supported, with the notable exceptions
|
||||||
of VoIP, threads and some aspects of End-to-End Encryption are supported. There are a few other smaller omissions due to the fact that the Matrix spec is constantly
|
of VoIP, threads, and some aspects of End-to-End Encryption. There are a few other smaller omissions due to the fact that the Matrix spec is constantly
|
||||||
evolving but the aim remains to provide eventual support for the entire spec.
|
evolving, but the aim remains to provide eventual support for the entire spec.
|
||||||
|
|
||||||
Due to the nature of the Matrix specification development NeoChat also supports numerous unstable features. Currently these are:
|
Due to the nature of the Matrix specification development NeoChat also supports numerous unstable features. Currently these are:
|
||||||
- Polls - MSC3381
|
- Polls - MSC3381
|
||||||
@@ -39,26 +38,9 @@ Due to the nature of the Matrix specification development NeoChat also supports
|
|||||||
|
|
||||||
Details where to find stable releases for NeoChat can be found on its [homepage](https://apps.kde.org/neochat).
|
Details where to find stable releases for NeoChat can be found on its [homepage](https://apps.kde.org/neochat).
|
||||||
|
|
||||||
In addition to the stable builds, unstable nightly builds are available for all platforms. These can be downloaded
|
Nightly builds for linux and windows can be downloaded from [cdn.kde.org](https://cdn.kde.org/ci-builds/network/neochat/).
|
||||||
from the [binary factory](https://binary-factory.kde.org/). There are unstable versions for the following platforms
|
Nightly builds for android are available from [KDE's nightly F-Droid repository](https://community.kde.org/Android/F-Droid).
|
||||||
in addition to stable ones:
|
Nightly Flatpaks are available from [KDE's nightly Flatpak repository](https://userbase.kde.org/Tutorials/Flatpak).
|
||||||
- Android
|
|
||||||
- MacOS
|
|
||||||
- Windows
|
|
||||||
|
|
||||||
Additionally the nightly Flatpak version can be obtained from the nightly Flatpak repo using the following commands in your terminal:
|
|
||||||
|
|
||||||
```
|
|
||||||
flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
|
|
||||||
flatpak remote-add --if-not-exists kdeapps --from https://distribute.kde.org/kdeapps.flatpakrepo
|
|
||||||
flatpak install kdeapps org.kde.neochat
|
|
||||||
```
|
|
||||||
|
|
||||||
The unstable Android version can also be obtained from the [KDE nightly F-Droid repo](https://community.kde.org/Android/FDroid).
|
|
||||||
|
|
||||||
## Running
|
|
||||||
|
|
||||||
Just start the executable in your preferred way - either from the build directory or from the installed location.
|
|
||||||
|
|
||||||
## Building NeoChat
|
## Building NeoChat
|
||||||
|
|
||||||
@@ -69,14 +51,18 @@ is primarily aimed at Linux development.
|
|||||||
For Windows and Android [Craft](https://invent.kde.org/packaging/craft) is the primary choice. There are guides for setting up
|
For Windows and Android [Craft](https://invent.kde.org/packaging/craft) is the primary choice. There are guides for setting up
|
||||||
development environments for [Windows](https://community.kde.org/Get_Involved/development/Windows) and [Android](https://develop.kde.org/docs/packaging/android/building_applications/).
|
development environments for [Windows](https://community.kde.org/Get_Involved/development/Windows) and [Android](https://develop.kde.org/docs/packaging/android/building_applications/).
|
||||||
|
|
||||||
|
## Running
|
||||||
|
|
||||||
|
Just start the executable in your preferred way - either from the build directory or from the installed location.
|
||||||
|
|
||||||
## Tests
|
## Tests
|
||||||
|
|
||||||
Tests are in the repository under [autotests](autotests) and should all pass for any contribution.
|
Tests are in the repository under [autotests](autotests) and [appiumtests](appiumtests).
|
||||||
|
|
||||||
The project has CI setup to test new commits to the repository. All tests are expected to pass for a merge request to
|
The project has CI setup to test new commits to the repository. All tests are expected to pass for a merge request to
|
||||||
be complete.
|
be complete.
|
||||||
|
|
||||||
Current build status
|
## Current build status
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@@ -100,9 +86,9 @@ The best place to reach the maintainers is on the KDE Matrix instance in the Neo
|
|||||||
|
|
||||||
## Acknowledgement
|
## Acknowledgement
|
||||||
|
|
||||||
This program utilizes [libQuotient](https://github.com/quotient-im/libQuotient/) as its Matrix SDK.
|
NeoChat utilizes [libQuotient](https://github.com/quotient-im/libQuotient/) as its Matrix SDK.
|
||||||
|
|
||||||
This program is a fork of [Spectral](https://gitlab.com/spectral-im/spectral/).
|
NeoChat is a fork of [Spectral](https://gitlab.com/spectral-im/spectral/).
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
|||||||
@@ -39,6 +39,10 @@ class OpenUserDetailsTest(unittest.TestCase):
|
|||||||
|
|
||||||
def test_open_sheet(self):
|
def test_open_sheet(self):
|
||||||
self.driver.find_element(by=AppiumBy.NAME, value="@user:localhost:1234").click()
|
self.driver.find_element(by=AppiumBy.NAME, value="@user:localhost:1234").click()
|
||||||
|
try:
|
||||||
|
self.driver.find_element(by=AppiumBy.NAME, value="Expand Normal").click()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
self.driver.find_element(by=AppiumBy.NAME, value="Empty room (!room_id_1234:localhost:1234)").click()
|
self.driver.find_element(by=AppiumBy.NAME, value="Empty room (!room_id_1234:localhost:1234)").click()
|
||||||
self.driver.find_element(by=AppiumBy.NAME, value="A Display Name").click()
|
self.driver.find_element(by=AppiumBy.NAME, value="A Display Name").click()
|
||||||
self.driver.find_element(by=AppiumBy.NAME, value="Account Details")
|
self.driver.find_element(by=AppiumBy.NAME, value="Account Details")
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ void DelegateSizeHelperTest::equalBreakpoint_data()
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We expect a default return except in the case where the the two percentages are
|
* We expect a default return except in the case where the two percentages are
|
||||||
* equal as that case can be calculated without dividing by zero.
|
* equal as that case can be calculated without dividing by zero.
|
||||||
*/
|
*/
|
||||||
void DelegateSizeHelperTest::equalBreakpoint()
|
void DelegateSizeHelperTest::equalBreakpoint()
|
||||||
|
|||||||
@@ -32,8 +32,6 @@ private Q_SLOTS:
|
|||||||
|
|
||||||
void linkPreviewsReject_data();
|
void linkPreviewsReject_data();
|
||||||
void linkPreviewsReject();
|
void linkPreviewsReject();
|
||||||
|
|
||||||
void editedLink();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void LinkPreviewerTest::initTestCase()
|
void LinkPreviewerTest::initTestCase()
|
||||||
@@ -59,7 +57,7 @@ void LinkPreviewerTest::linkPreviewsMatch()
|
|||||||
QFETCH(QUrl, testOutputLink);
|
QFETCH(QUrl, testOutputLink);
|
||||||
|
|
||||||
auto event = TestUtils::loadEventFromFile<RoomMessageEvent>(eventSource);
|
auto event = TestUtils::loadEventFromFile<RoomMessageEvent>(eventSource);
|
||||||
auto linkPreviewer = LinkPreviewer(room, event.get());
|
auto linkPreviewer = LinkPreviewer(LinkPreviewer::linkPreview(event.get()), connection);
|
||||||
|
|
||||||
QCOMPARE(linkPreviewer.empty(), false);
|
QCOMPARE(linkPreviewer.empty(), false);
|
||||||
QCOMPARE(linkPreviewer.url(), testOutputLink);
|
QCOMPARE(linkPreviewer.url(), testOutputLink);
|
||||||
@@ -79,22 +77,7 @@ void LinkPreviewerTest::linkPreviewsReject()
|
|||||||
QFETCH(QString, eventSource);
|
QFETCH(QString, eventSource);
|
||||||
|
|
||||||
auto event = TestUtils::loadEventFromFile<RoomMessageEvent>(eventSource);
|
auto event = TestUtils::loadEventFromFile<RoomMessageEvent>(eventSource);
|
||||||
auto linkPreviewer = LinkPreviewer(room, event.get());
|
auto linkPreviewer = LinkPreviewer(LinkPreviewer::linkPreview(event.get()), connection);
|
||||||
|
|
||||||
QCOMPARE(linkPreviewer.empty(), true);
|
|
||||||
QCOMPARE(linkPreviewer.url(), QUrl());
|
|
||||||
}
|
|
||||||
|
|
||||||
void LinkPreviewerTest::editedLink()
|
|
||||||
{
|
|
||||||
room->syncNewEvents(QStringLiteral("test-linkpreviewerintial-sync.json"));
|
|
||||||
auto event = eventCast<const RoomMessageEvent>(room->messageEvents().at(0).get());
|
|
||||||
auto linkPreviewer = LinkPreviewer(room, event);
|
|
||||||
|
|
||||||
QCOMPARE(linkPreviewer.empty(), false);
|
|
||||||
QCOMPARE(linkPreviewer.url(), QUrl("https://kde.org"_ls));
|
|
||||||
|
|
||||||
room->syncNewEvents(QStringLiteral("test-linkpreviewerreplace-sync.json"));
|
|
||||||
|
|
||||||
QCOMPARE(linkPreviewer.empty(), true);
|
QCOMPARE(linkPreviewer.empty(), true);
|
||||||
QCOMPARE(linkPreviewer.url(), QUrl());
|
QCOMPARE(linkPreviewer.url(), QUrl());
|
||||||
|
|||||||
@@ -394,6 +394,7 @@
|
|||||||
<content_attribute id="social-chat">intense</content_attribute>
|
<content_attribute id="social-chat">intense</content_attribute>
|
||||||
</content_rating>
|
</content_rating>
|
||||||
<releases>
|
<releases>
|
||||||
|
<release version="24.02.2" date="2024-04-11"/>
|
||||||
<release version="24.02.1" date="2024-03-21"/>
|
<release version="24.02.1" date="2024-03-21"/>
|
||||||
<release version="24.02.0" date="2024-02-28">
|
<release version="24.02.0" date="2024-02-28">
|
||||||
<url>https://kde.org/announcements/megarelease/6/#neochat</url>
|
<url>https://kde.org/announcements/megarelease/6/#neochat</url>
|
||||||
|
|||||||
1686
po/ar/neochat.po
1686
po/ar/neochat.po
File diff suppressed because it is too large
Load Diff
1568
po/ast/neochat.po
1568
po/ast/neochat.po
File diff suppressed because it is too large
Load Diff
1702
po/az/neochat.po
1702
po/az/neochat.po
File diff suppressed because it is too large
Load Diff
1643
po/ca/neochat.po
1643
po/ca/neochat.po
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
1663
po/cs/neochat.po
1663
po/cs/neochat.po
File diff suppressed because it is too large
Load Diff
1665
po/da/neochat.po
1665
po/da/neochat.po
File diff suppressed because it is too large
Load Diff
1673
po/de/neochat.po
1673
po/de/neochat.po
File diff suppressed because it is too large
Load Diff
1679
po/el/neochat.po
1679
po/el/neochat.po
File diff suppressed because it is too large
Load Diff
1672
po/en_GB/neochat.po
1672
po/en_GB/neochat.po
File diff suppressed because it is too large
Load Diff
1660
po/eo/neochat.po
1660
po/eo/neochat.po
File diff suppressed because it is too large
Load Diff
1645
po/es/neochat.po
1645
po/es/neochat.po
File diff suppressed because it is too large
Load Diff
1663
po/eu/neochat.po
1663
po/eu/neochat.po
File diff suppressed because it is too large
Load Diff
1667
po/fi/neochat.po
1667
po/fi/neochat.po
File diff suppressed because it is too large
Load Diff
1633
po/fr/neochat.po
1633
po/fr/neochat.po
File diff suppressed because it is too large
Load Diff
1658
po/hu/neochat.po
1658
po/hu/neochat.po
File diff suppressed because it is too large
Load Diff
1660
po/ia/neochat.po
1660
po/ia/neochat.po
File diff suppressed because it is too large
Load Diff
1672
po/id/neochat.po
1672
po/id/neochat.po
File diff suppressed because it is too large
Load Diff
1629
po/ie/neochat.po
1629
po/ie/neochat.po
File diff suppressed because it is too large
Load Diff
1664
po/it/neochat.po
1664
po/it/neochat.po
File diff suppressed because it is too large
Load Diff
1564
po/ja/neochat.po
1564
po/ja/neochat.po
File diff suppressed because it is too large
Load Diff
1656
po/ka/neochat.po
1656
po/ka/neochat.po
File diff suppressed because it is too large
Load Diff
1662
po/ko/neochat.po
1662
po/ko/neochat.po
File diff suppressed because it is too large
Load Diff
1576
po/lt/neochat.po
1576
po/lt/neochat.po
File diff suppressed because it is too large
Load Diff
1656
po/lv/neochat.po
1656
po/lv/neochat.po
File diff suppressed because it is too large
Load Diff
1659
po/nl/neochat.po
1659
po/nl/neochat.po
File diff suppressed because it is too large
Load Diff
1652
po/nn/neochat.po
1652
po/nn/neochat.po
File diff suppressed because it is too large
Load Diff
1707
po/pa/neochat.po
1707
po/pa/neochat.po
File diff suppressed because it is too large
Load Diff
1689
po/pl/neochat.po
1689
po/pl/neochat.po
File diff suppressed because it is too large
Load Diff
1670
po/pt/neochat.po
1670
po/pt/neochat.po
File diff suppressed because it is too large
Load Diff
1703
po/pt_BR/neochat.po
1703
po/pt_BR/neochat.po
File diff suppressed because it is too large
Load Diff
1664
po/ru/neochat.po
1664
po/ru/neochat.po
File diff suppressed because it is too large
Load Diff
1704
po/sk/neochat.po
1704
po/sk/neochat.po
File diff suppressed because it is too large
Load Diff
1650
po/sl/neochat.po
1650
po/sl/neochat.po
File diff suppressed because it is too large
Load Diff
1654
po/sv/neochat.po
1654
po/sv/neochat.po
File diff suppressed because it is too large
Load Diff
1663
po/ta/neochat.po
1663
po/ta/neochat.po
File diff suppressed because it is too large
Load Diff
1646
po/tok/neochat.po
1646
po/tok/neochat.po
File diff suppressed because it is too large
Load Diff
1651
po/tr/neochat.po
1651
po/tr/neochat.po
File diff suppressed because it is too large
Load Diff
1667
po/uk/neochat.po
1667
po/uk/neochat.po
File diff suppressed because it is too large
Load Diff
1736
po/zh_CN/neochat.po
1736
po/zh_CN/neochat.po
File diff suppressed because it is too large
Load Diff
1695
po/zh_TW/neochat.po
1695
po/zh_TW/neochat.po
File diff suppressed because it is too large
Load Diff
@@ -172,11 +172,21 @@ add_library(neochat STATIC
|
|||||||
models/statekeysmodel.h
|
models/statekeysmodel.h
|
||||||
sharehandler.cpp
|
sharehandler.cpp
|
||||||
sharehandler.h
|
sharehandler.h
|
||||||
|
models/roomtreeitem.cpp
|
||||||
|
models/roomtreeitem.h
|
||||||
|
foreigntypes.h
|
||||||
|
models/threepidmodel.cpp
|
||||||
|
models/threepidmodel.h
|
||||||
|
)
|
||||||
|
|
||||||
|
set_source_files_properties(qml/OsmLocationPlugin.qml PROPERTIES
|
||||||
|
QT_QML_SINGLETON_TYPE TRUE
|
||||||
)
|
)
|
||||||
|
|
||||||
qt_add_qml_module(neochat URI org.kde.neochat NO_PLUGIN
|
qt_add_qml_module(neochat URI org.kde.neochat NO_PLUGIN
|
||||||
|
OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/src/org/kde/neochat
|
||||||
QML_FILES
|
QML_FILES
|
||||||
qml/main.qml
|
qml/Main.qml
|
||||||
qml/AccountMenu.qml
|
qml/AccountMenu.qml
|
||||||
qml/ExploreComponent.qml
|
qml/ExploreComponent.qml
|
||||||
qml/ExploreComponentMobile.qml
|
qml/ExploreComponentMobile.qml
|
||||||
@@ -193,9 +203,7 @@ qt_add_qml_module(neochat URI org.kde.neochat NO_PLUGIN
|
|||||||
qml/ExplorerDelegate.qml
|
qml/ExplorerDelegate.qml
|
||||||
qml/InviteUserPage.qml
|
qml/InviteUserPage.qml
|
||||||
qml/ImageEditorPage.qml
|
qml/ImageEditorPage.qml
|
||||||
qml/WelcomePage.qml
|
|
||||||
qml/NeochatMaximizeComponent.qml
|
qml/NeochatMaximizeComponent.qml
|
||||||
qml/FancyEffectsContainer.qml
|
|
||||||
qml/TypingPane.qml
|
qml/TypingPane.qml
|
||||||
qml/QuickSwitcher.qml
|
qml/QuickSwitcher.qml
|
||||||
qml/HoverActions.qml
|
qml/HoverActions.qml
|
||||||
@@ -205,22 +213,7 @@ qt_add_qml_module(neochat URI org.kde.neochat NO_PLUGIN
|
|||||||
qml/CompletionMenu.qml
|
qml/CompletionMenu.qml
|
||||||
qml/PieProgressBar.qml
|
qml/PieProgressBar.qml
|
||||||
qml/QuickFormatBar.qml
|
qml/QuickFormatBar.qml
|
||||||
qml/RoomData.qml
|
|
||||||
qml/ServerData.qml
|
|
||||||
qml/EmojiPicker.qml
|
qml/EmojiPicker.qml
|
||||||
qml/LoginStep.qml
|
|
||||||
qml/Login.qml
|
|
||||||
qml/Homeserver.qml
|
|
||||||
qml/Username.qml
|
|
||||||
qml/RegisterPassword.qml
|
|
||||||
qml/Captcha.qml
|
|
||||||
qml/Terms.qml
|
|
||||||
qml/Email.qml
|
|
||||||
qml/Password.qml
|
|
||||||
qml/LoginRegister.qml
|
|
||||||
qml/Loading.qml
|
|
||||||
qml/LoginMethod.qml
|
|
||||||
qml/Sso.qml
|
|
||||||
qml/UserDetailDialog.qml
|
qml/UserDetailDialog.qml
|
||||||
qml/CreateRoomDialog.qml
|
qml/CreateRoomDialog.qml
|
||||||
qml/EmojiDialog.qml
|
qml/EmojiDialog.qml
|
||||||
@@ -240,7 +233,6 @@ qt_add_qml_module(neochat URI org.kde.neochat NO_PLUGIN
|
|||||||
qml/FileDelegateContextMenu.qml
|
qml/FileDelegateContextMenu.qml
|
||||||
qml/MessageSourceSheet.qml
|
qml/MessageSourceSheet.qml
|
||||||
qml/ReportSheet.qml
|
qml/ReportSheet.qml
|
||||||
qml/DevtoolsPage.qml
|
|
||||||
qml/ConfirmEncryptionDialog.qml
|
qml/ConfirmEncryptionDialog.qml
|
||||||
qml/RemoveSheet.qml
|
qml/RemoveSheet.qml
|
||||||
qml/BanSheet.qml
|
qml/BanSheet.qml
|
||||||
@@ -280,21 +272,20 @@ qt_add_qml_module(neochat URI org.kde.neochat NO_PLUGIN
|
|||||||
qml/RoomTreeSection.qml
|
qml/RoomTreeSection.qml
|
||||||
qml/DelegateContextMenu.qml
|
qml/DelegateContextMenu.qml
|
||||||
qml/ShareDialog.qml
|
qml/ShareDialog.qml
|
||||||
qml/FeatureFlagPage.qml
|
|
||||||
qml/AccountData.qml
|
|
||||||
qml/StateKeys.qml
|
|
||||||
qml/UnlockSSSSDialog.qml
|
qml/UnlockSSSSDialog.qml
|
||||||
qml/QrScannerPage.qml
|
qml/QrScannerPage.qml
|
||||||
qml/JoinRoomDialog.qml
|
qml/JoinRoomDialog.qml
|
||||||
qml/ConfirmUrlDialog.qml
|
qml/ConfirmUrlDialog.qml
|
||||||
qml/AccountSwitchDialog.qml
|
qml/AccountSwitchDialog.qml
|
||||||
RESOURCES
|
qml/ConfirmLeaveDialog.qml
|
||||||
qml/confetti.png
|
qml/CodeMaximizeComponent.qml
|
||||||
qml/glowdot.png
|
qml/EditStateDialog.qml
|
||||||
)
|
)
|
||||||
|
|
||||||
add_subdirectory(settings)
|
add_subdirectory(settings)
|
||||||
add_subdirectory(timeline)
|
add_subdirectory(timeline)
|
||||||
|
add_subdirectory(devtools)
|
||||||
|
add_subdirectory(login)
|
||||||
|
|
||||||
if(UNIX)
|
if(UNIX)
|
||||||
qt_target_qml_sources(neochat QML_FILES qml/ShareAction.qml)
|
qt_target_qml_sources(neochat QML_FILES qml/ShareAction.qml)
|
||||||
@@ -386,7 +377,7 @@ if (NOT ANDROID AND NOT WIN32 AND NOT APPLE)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
target_include_directories(neochat PRIVATE ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/models ${CMAKE_CURRENT_SOURCE_DIR}/enums)
|
target_include_directories(neochat PRIVATE ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/models ${CMAKE_CURRENT_SOURCE_DIR}/enums)
|
||||||
target_link_libraries(neochat PRIVATE settingsplugin timelineplugin)
|
target_link_libraries(neochat PRIVATE settingsplugin timelineplugin devtoolsplugin loginplugin)
|
||||||
target_link_libraries(neochat PUBLIC
|
target_link_libraries(neochat PUBLIC
|
||||||
Qt::Core
|
Qt::Core
|
||||||
Qt::Quick
|
Qt::Quick
|
||||||
@@ -410,6 +401,10 @@ target_link_libraries(neochat PUBLIC
|
|||||||
QCoro::Network
|
QCoro::Network
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (TARGET KF6::Crash)
|
||||||
|
target_link_libraries(neochat PUBLIC KF6::Crash)
|
||||||
|
endif()
|
||||||
|
|
||||||
kconfig_add_kcfg_files(neochat GENERATE_MOC neochatconfig.kcfgc)
|
kconfig_add_kcfg_files(neochat GENERATE_MOC neochatconfig.kcfgc)
|
||||||
|
|
||||||
if(NEOCHAT_FLATPAK)
|
if(NEOCHAT_FLATPAK)
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
#include "models/actionsmodel.h"
|
#include "models/actionsmodel.h"
|
||||||
#include "neochatconfig.h"
|
#include "neochatconfig.h"
|
||||||
#include "texthandler.h"
|
#include "texthandler.h"
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
using namespace Quotient;
|
using namespace Quotient;
|
||||||
|
|
||||||
@@ -145,6 +146,26 @@ void ActionsHandler::handleMessage(const QString &text, QString handledText, Cha
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We want to add back the <mx-reply> if it's in the original message but not in the edit, to preserve the reply.
|
||||||
|
for (auto it = m_room->messageEvents().crbegin(); it != m_room->messageEvents().crend(); it++) {
|
||||||
|
if (const auto event = eventCast<const RoomMessageEvent>(&**it)) {
|
||||||
|
if (event->senderId() == m_room->localUser()->id() && event->hasTextContent()) {
|
||||||
|
QString originalString;
|
||||||
|
if (event->content()) {
|
||||||
|
originalString = static_cast<const Quotient::EventContent::TextContent *>(event->content())->body;
|
||||||
|
} else {
|
||||||
|
originalString = event->plainBody();
|
||||||
|
}
|
||||||
|
|
||||||
|
const QRegularExpression exp(TextRegex::removeRichReply);
|
||||||
|
const auto match = exp.match(originalString);
|
||||||
|
if (match.hasCaptured(0) && !handledText.contains(TextRegex::removeRichReply)) {
|
||||||
|
handledText.prepend(match.captured(0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
m_room->postMessage(text, handledText, messageType, chatBarCache->replyId(), chatBarCache->editId(), chatBarCache->threadId());
|
m_room->postMessage(text, handledText, messageType, chatBarCache->replyId(), chatBarCache->editId(), chatBarCache->threadId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ class ChatDocumentHandler : public QObject
|
|||||||
Q_PROPERTY(CompletionModel *completionModel READ completionModel CONSTANT)
|
Q_PROPERTY(CompletionModel *completionModel READ completionModel CONSTANT)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief The current room that the the text document is being handled for.
|
* @brief The current room that the text document is being handled for.
|
||||||
*/
|
*/
|
||||||
Q_PROPERTY(NeoChatRoom *room READ room WRITE setRoom NOTIFY roomChanged)
|
Q_PROPERTY(NeoChatRoom *room READ room WRITE setRoom NOTIFY roomChanged)
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,6 @@
|
|||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
|
||||||
#include <Quotient/accountregistry.h>
|
#include <Quotient/accountregistry.h>
|
||||||
#include <Quotient/connection.h>
|
|
||||||
#include <Quotient/csapi/logout.h>
|
#include <Quotient/csapi/logout.h>
|
||||||
#include <Quotient/csapi/notifications.h>
|
#include <Quotient/csapi/notifications.h>
|
||||||
#include <Quotient/eventstats.h>
|
#include <Quotient/eventstats.h>
|
||||||
@@ -157,7 +156,7 @@ void Controller::addConnection(NeoChatConnection *c)
|
|||||||
});
|
});
|
||||||
connect(c, &NeoChatConnection::loggedOut, this, [this, c] {
|
connect(c, &NeoChatConnection::loggedOut, this, [this, c] {
|
||||||
if (accounts().count() > 1) {
|
if (accounts().count() > 1) {
|
||||||
// Only set the connection if the the account being logged out is currently active
|
// Only set the connection if the account being logged out is currently active
|
||||||
if (c == activeConnection()) {
|
if (c == activeConnection()) {
|
||||||
setActiveConnection(dynamic_cast<NeoChatConnection *>(accounts().accounts()[0]));
|
setActiveConnection(dynamic_cast<NeoChatConnection *>(accounts().accounts()[0]));
|
||||||
}
|
}
|
||||||
@@ -318,7 +317,7 @@ void Controller::setActiveConnection(NeoChatConnection *connection)
|
|||||||
updateBadgeNotificationCount(m_connection, m_connection->badgeNotificationCount());
|
updateBadgeNotificationCount(m_connection, m_connection->badgeNotificationCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_EMIT activeConnectionChanged();
|
Q_EMIT activeConnectionChanged(m_connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller::listenForNotifications()
|
void Controller::listenForNotifications()
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ private:
|
|||||||
|
|
||||||
Quotient::AccountRegistry m_accountRegistry;
|
Quotient::AccountRegistry m_accountRegistry;
|
||||||
QStringList m_accountsLoading;
|
QStringList m_accountsLoading;
|
||||||
QMap<QString, QPointer<Quotient::Connection>> m_connectionsLoading;
|
QMap<QString, QPointer<NeoChatConnection>> m_connectionsLoading;
|
||||||
QString m_endpoint;
|
QString m_endpoint;
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
@@ -129,6 +129,6 @@ Q_SIGNALS:
|
|||||||
void errorOccured(const QString &error, const QString &detail);
|
void errorOccured(const QString &error, const QString &detail);
|
||||||
void connectionAdded(NeoChatConnection *connection);
|
void connectionAdded(NeoChatConnection *connection);
|
||||||
void connectionDropped(NeoChatConnection *connection);
|
void connectionDropped(NeoChatConnection *connection);
|
||||||
void activeConnectionChanged();
|
void activeConnectionChanged(NeoChatConnection *connection);
|
||||||
void accountsLoadingChanged();
|
void accountsLoadingChanged();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ ColumnLayout {
|
|||||||
model: root.connection.accountDataEventTypes
|
model: root.connection.accountDataEventTypes
|
||||||
delegate: FormCard.FormButtonDelegate {
|
delegate: FormCard.FormButtonDelegate {
|
||||||
text: modelData
|
text: modelData
|
||||||
onClicked: applicationWindow().pageStack.pushDialogLayer(Qt.createComponent('org.kde.neochat', 'MessageSourceSheet.qml'), {
|
onClicked: applicationWindow().pageStack.pushDialogLayer(Qt.createComponent('org.kde.neochat', 'MessageSourceSheet'), {
|
||||||
sourceText: root.connection.accountDataJsonString(modelData)
|
sourceText: root.connection.accountDataJsonString(modelData)
|
||||||
}, {
|
}, {
|
||||||
title: i18nc("@title:window", "Event Source"),
|
title: i18nc("@title:window", "Event Source"),
|
||||||
16
src/devtools/CMakeLists.txt
Normal file
16
src/devtools/CMakeLists.txt
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
# SPDX-FileCopyrightText: 2024 James Graham <james.h.graham@protonmail.com>
|
||||||
|
# SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
|
qt_add_library(devtools STATIC)
|
||||||
|
qt_add_qml_module(devtools
|
||||||
|
URI org.kde.neochat.devtools
|
||||||
|
OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/src/org/kde/neochat/devtools
|
||||||
|
QML_FILES
|
||||||
|
DevtoolsPage.qml
|
||||||
|
AccountData.qml
|
||||||
|
DebugOptions.qml
|
||||||
|
FeatureFlagPage.qml
|
||||||
|
RoomData.qml
|
||||||
|
ServerData.qml
|
||||||
|
StateKeys.qml
|
||||||
|
)
|
||||||
42
src/devtools/DebugOptions.qml
Normal file
42
src/devtools/DebugOptions.qml
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
// SPDX-FileCopyrightText: 2024 James Graham <james.h.graham@protonmail.com>
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||||
|
|
||||||
|
import QtQuick
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
import org.kde.kirigami as Kirigami
|
||||||
|
import org.kde.kirigamiaddons.formcard as FormCard
|
||||||
|
|
||||||
|
import org.kde.neochat
|
||||||
|
|
||||||
|
FormCard.FormCardPage {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
FormCard.FormCard {
|
||||||
|
Layout.topMargin: Kirigami.Units.largeSpacing
|
||||||
|
|
||||||
|
FormCard.FormCheckDelegate {
|
||||||
|
text: i18nc("@option:check", "Show hidden events in the timeline")
|
||||||
|
checked: Config.showAllEvents
|
||||||
|
|
||||||
|
onToggled: Config.showAllEvents = checked
|
||||||
|
}
|
||||||
|
FormCard.FormCheckDelegate {
|
||||||
|
id: roomAccountDataVisibleCheck
|
||||||
|
text: i18nc("@option:check Enable the matrix 'threads' feature", "Always allow device verification")
|
||||||
|
description: i18n("Allow the user to start a verification session with devices that were already verified")
|
||||||
|
checked: Config.alwaysVerifyDevice
|
||||||
|
|
||||||
|
onToggled: Config.alwaysVerifyDevice = checked
|
||||||
|
}
|
||||||
|
FormCard.FormCheckDelegate {
|
||||||
|
text: i18nc("@option:check", "Show focus in window header")
|
||||||
|
checked: Config.windowTitleFocus
|
||||||
|
|
||||||
|
onToggled: {
|
||||||
|
Config.windowTitleFocus = checked;
|
||||||
|
Config.save();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -25,6 +25,11 @@ FormCard.FormCardPage {
|
|||||||
|
|
||||||
readonly property real tabWidth: tabBar.width / tabBar.count
|
readonly property real tabWidth: tabBar.width / tabBar.count
|
||||||
|
|
||||||
|
QQC2.TabButton {
|
||||||
|
text: i18nc("@title:tab", "Debug Options")
|
||||||
|
|
||||||
|
implicitWidth: tabBar.tabWidth
|
||||||
|
}
|
||||||
QQC2.TabButton {
|
QQC2.TabButton {
|
||||||
text: qsTr("Room Data")
|
text: qsTr("Room Data")
|
||||||
|
|
||||||
@@ -52,6 +57,7 @@ FormCard.FormCardPage {
|
|||||||
|
|
||||||
currentIndex: tabBar.currentIndex
|
currentIndex: tabBar.currentIndex
|
||||||
|
|
||||||
|
DebugOptions {}
|
||||||
RoomData {
|
RoomData {
|
||||||
room: root.room
|
room: root.room
|
||||||
connection: root.connection
|
connection: root.connection
|
||||||
@@ -8,7 +8,6 @@ import org.kde.kirigami as Kirigami
|
|||||||
import org.kde.kirigamiaddons.formcard as FormCard
|
import org.kde.kirigamiaddons.formcard as FormCard
|
||||||
|
|
||||||
import org.kde.neochat
|
import org.kde.neochat
|
||||||
import org.kde.neochat.config
|
|
||||||
|
|
||||||
FormCard.FormCardPage {
|
FormCard.FormCardPage {
|
||||||
id: root
|
id: root
|
||||||
@@ -25,14 +25,12 @@ ColumnLayout {
|
|||||||
text: i18n("Room")
|
text: i18n("Room")
|
||||||
textRole: "escapedDisplayName"
|
textRole: "escapedDisplayName"
|
||||||
valueRole: "roomId"
|
valueRole: "roomId"
|
||||||
displayText: roomListModel.data(roomListModel.index(currentIndex, 0), RoomListModel.DisplayNameRole)
|
displayText: RoomManager.roomListModel.data(RoomManager.roomListModel.index(currentIndex, 0), RoomListModel.EscapedDisplayNameRole)
|
||||||
model: RoomListModel {
|
model: RoomManager.roomListModel
|
||||||
id: roomListModel
|
|
||||||
connection: root.connection
|
|
||||||
}
|
|
||||||
currentIndex: 0
|
currentIndex: 0
|
||||||
Component.onCompleted: currentIndex = roomListModel.rowForRoom(root.room)
|
displayMode: FormCard.FormComboBoxDelegate.Page
|
||||||
onCurrentValueChanged: root.room = roomListModel.roomByAliasOrId(roomComboBox.currentValue)
|
Component.onCompleted: currentIndex = RoomManager.roomListModel.rowForRoom(root.room)
|
||||||
|
onCurrentValueChanged: root.room = RoomManager.roomListModel.roomByAliasOrId(roomComboBox.currentValue)
|
||||||
}
|
}
|
||||||
FormCard.FormTextDelegate {
|
FormCard.FormTextDelegate {
|
||||||
text: i18n("Room Id: %1", root.room.id)
|
text: i18n("Room Id: %1", root.room.id)
|
||||||
@@ -49,7 +47,7 @@ ColumnLayout {
|
|||||||
model: root.room.accountDataEventTypes
|
model: root.room.accountDataEventTypes
|
||||||
delegate: FormCard.FormButtonDelegate {
|
delegate: FormCard.FormButtonDelegate {
|
||||||
text: modelData
|
text: modelData
|
||||||
onClicked: applicationWindow().pageStack.pushDialogLayer(Qt.createComponent('org.kde.neochat', 'MessageSourceSheet.qml'), {
|
onClicked: applicationWindow().pageStack.pushDialogLayer(Qt.createComponent('org.kde.neochat', 'MessageSourceSheet'), {
|
||||||
sourceText: root.room.roomAcountDataJson(text)
|
sourceText: root.room.roomAcountDataJson(text)
|
||||||
}, {
|
}, {
|
||||||
title: i18n("Event Source"),
|
title: i18n("Event Source"),
|
||||||
@@ -77,14 +75,9 @@ ColumnLayout {
|
|||||||
description: i18ncp("'Event' being some JSON data, not something physically happening.", "%1 event of this type", "%1 events of this type", model.eventCount)
|
description: i18ncp("'Event' being some JSON data, not something physically happening.", "%1 event of this type", "%1 events of this type", model.eventCount)
|
||||||
onClicked: {
|
onClicked: {
|
||||||
if (model.eventCount === 1) {
|
if (model.eventCount === 1) {
|
||||||
onClicked: applicationWindow().pageStack.pushDialogLayer(Qt.createComponent('org.kde.neochat', 'MessageSourceSheet.qml'), {
|
openEventSource(model.type, model.stateKey);
|
||||||
sourceText: stateModel.stateEventJson(stateModel.index(model.index, 0))
|
|
||||||
}, {
|
|
||||||
title: i18n("Event Source"),
|
|
||||||
width: Kirigami.Units.gridUnit * 25
|
|
||||||
})
|
|
||||||
} else {
|
} else {
|
||||||
pageStack.pushDialogLayer(stateKeysComponent, {
|
pageStack.pushDialogLayer(Qt.createComponent('org.kde.neochat.devtools', 'StateKeys'), {
|
||||||
room: root.room,
|
room: root.room,
|
||||||
eventType: model.type
|
eventType: model.type
|
||||||
}, {
|
}, {
|
||||||
@@ -94,9 +87,17 @@ ColumnLayout {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Component {
|
}
|
||||||
id: stateKeysComponent
|
function openEventSource(type: string, stateKey: string): void {
|
||||||
StateKeys {}
|
onClicked: applicationWindow().pageStack.pushDialogLayer(Qt.createComponent('org.kde.neochat', 'MessageSourceSheet'), {
|
||||||
}
|
model: stateModel,
|
||||||
|
allowEdit: true,
|
||||||
|
room: root.room,
|
||||||
|
type: type,
|
||||||
|
stateKey: stateKey,
|
||||||
|
}, {
|
||||||
|
title: i18n("Event Source"),
|
||||||
|
width: Kirigami.Units.gridUnit * 25
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -31,13 +31,21 @@ FormCard.FormCardPage {
|
|||||||
|
|
||||||
delegate: FormCard.FormButtonDelegate {
|
delegate: FormCard.FormButtonDelegate {
|
||||||
text: model.stateKey
|
text: model.stateKey
|
||||||
onClicked: applicationWindow().pageStack.pushDialogLayer(Qt.createComponent('org.kde.neochat', 'MessageSourceSheet.qml'), {
|
onClicked: openEventSource(model.stateKey)
|
||||||
sourceText: stateKeysModel.stateEventJson(stateKeysModel.index(model.index, 0))
|
|
||||||
}, {
|
|
||||||
title: i18nc("@title:window", "Event Source"),
|
|
||||||
width: Kirigami.Units.gridUnit * 25
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function openEventSource(stateKey: string): void {
|
||||||
|
applicationWindow().pageStack.pushDialogLayer(Qt.createComponent('org.kde.neochat', 'MessageSourceSheet'), {
|
||||||
|
model: stateKeysModel,
|
||||||
|
allowEdit: true,
|
||||||
|
room: root.room,
|
||||||
|
type: root.eventType,
|
||||||
|
stateKey: stateKey
|
||||||
|
}, {
|
||||||
|
title: i18nc("@title:window", "Event Source"),
|
||||||
|
width: Kirigami.Units.gridUnit * 25
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -21,7 +21,6 @@ public:
|
|||||||
* @brief Defines the room list categories a room can be assigned.
|
* @brief Defines the room list categories a room can be assigned.
|
||||||
*/
|
*/
|
||||||
enum Types {
|
enum Types {
|
||||||
Search = 0, /**< So we can show a search delegate if needed, e.g. collapsed mode. */
|
|
||||||
Invited, /**< The user has been invited to the room. */
|
Invited, /**< The user has been invited to the room. */
|
||||||
Favorite, /**< The room is set as a favourite. */
|
Favorite, /**< The room is set as a favourite. */
|
||||||
Direct, /**< The room is a direct chat. */
|
Direct, /**< The room is a direct chat. */
|
||||||
@@ -29,6 +28,7 @@ public:
|
|||||||
Deprioritized, /**< The room is set as low priority. */
|
Deprioritized, /**< The room is set as low priority. */
|
||||||
Space, /**< The room is a space. */
|
Space, /**< The room is a space. */
|
||||||
AddDirect, /**< So we can show the add friend delegate. */
|
AddDirect, /**< So we can show the add friend delegate. */
|
||||||
|
TypesCount, /**< Number of different types (this should always be last). */
|
||||||
};
|
};
|
||||||
Q_ENUM(Types);
|
Q_ENUM(Types);
|
||||||
|
|
||||||
@@ -67,8 +67,6 @@ public:
|
|||||||
return i18n("Low priority");
|
return i18n("Low priority");
|
||||||
case NeoChatRoomType::Space:
|
case NeoChatRoomType::Space:
|
||||||
return i18n("Spaces");
|
return i18n("Spaces");
|
||||||
case NeoChatRoomType::Search:
|
|
||||||
return i18n("Search");
|
|
||||||
default:
|
default:
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@@ -88,8 +86,6 @@ public:
|
|||||||
return QStringLiteral("object-order-lower");
|
return QStringLiteral("object-order-lower");
|
||||||
case NeoChatRoomType::Space:
|
case NeoChatRoomType::Space:
|
||||||
return QStringLiteral("group");
|
return QStringLiteral("group");
|
||||||
case NeoChatRoomType::Search:
|
|
||||||
return QStringLiteral("search");
|
|
||||||
default:
|
default:
|
||||||
return QStringLiteral("tools-report-bug");
|
return QStringLiteral("tools-report-bug");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,6 +74,9 @@ void ImagePackEventContent::fillJson(QJsonObject *o) const
|
|||||||
}
|
}
|
||||||
imageJson["usage"_ls] = usageJson;
|
imageJson["usage"_ls] = usageJson;
|
||||||
}
|
}
|
||||||
|
if (image.info.has_value()) {
|
||||||
|
imageJson["info"_ls] = Quotient::EventContent::toInfoJson(*image.info);
|
||||||
|
}
|
||||||
imagesJson[image.shortcode] = imageJson;
|
imagesJson[image.shortcode] = imageJson;
|
||||||
}
|
}
|
||||||
(*o)["images"_ls] = imagesJson;
|
(*o)["images"_ls] = imagesJson;
|
||||||
|
|||||||
@@ -89,6 +89,4 @@ public:
|
|||||||
QUO_EVENT(ImagePackEvent, "im.ponies.room_emotes")
|
QUO_EVENT(ImagePackEvent, "im.ponies.room_emotes")
|
||||||
using KeyedStateEventBase::KeyedStateEventBase;
|
using KeyedStateEventBase::KeyedStateEventBase;
|
||||||
};
|
};
|
||||||
|
|
||||||
REGISTER_EVENT_TYPE(ImagePackEvent)
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,5 +40,4 @@ public:
|
|||||||
*/
|
*/
|
||||||
QJsonArray allow() const;
|
QJsonArray allow() const;
|
||||||
};
|
};
|
||||||
REGISTER_EVENT_TYPE(JoinRulesEvent)
|
|
||||||
}
|
}
|
||||||
|
|||||||
56
src/foreigntypes.h
Normal file
56
src/foreigntypes.h
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
// SPDX-FileCopyrightText: 2024 Tobias Fella <tobias.fella@kde.org>
|
||||||
|
// SPDX-License-Identifier: LGPL-2.0-or-later
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <QQmlEngine>
|
||||||
|
|
||||||
|
#include <Quotient/accountregistry.h>
|
||||||
|
#include <Quotient/keyverificationsession.h>
|
||||||
|
#if __has_include("Quotient/e2ee/sssshandler.h")
|
||||||
|
#include <Quotient/e2ee/sssshandler.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "controller.h"
|
||||||
|
#include "neochatconfig.h"
|
||||||
|
|
||||||
|
struct ForeignConfig {
|
||||||
|
Q_GADGET
|
||||||
|
QML_FOREIGN(NeoChatConfig)
|
||||||
|
QML_NAMED_ELEMENT(Config)
|
||||||
|
QML_SINGLETON
|
||||||
|
public:
|
||||||
|
static NeoChatConfig *create(QQmlEngine *, QJSEngine *)
|
||||||
|
{
|
||||||
|
QQmlEngine::setObjectOwnership(NeoChatConfig::self(), QQmlEngine::CppOwnership);
|
||||||
|
return NeoChatConfig::self();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ForeignAccountRegistry {
|
||||||
|
Q_GADGET
|
||||||
|
QML_FOREIGN(Quotient::AccountRegistry)
|
||||||
|
QML_NAMED_ELEMENT(AccountRegistry)
|
||||||
|
QML_SINGLETON
|
||||||
|
public:
|
||||||
|
static Quotient::AccountRegistry *create(QQmlEngine *, QJSEngine *)
|
||||||
|
{
|
||||||
|
QQmlEngine::setObjectOwnership(&Controller::instance().accounts(), QQmlEngine::CppOwnership);
|
||||||
|
return &Controller::instance().accounts();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ForeignKeyVerificationSession {
|
||||||
|
Q_GADGET
|
||||||
|
QML_FOREIGN(Quotient::KeyVerificationSession)
|
||||||
|
QML_NAMED_ELEMENT(KeyVerificationSession)
|
||||||
|
QML_UNCREATABLE("")
|
||||||
|
};
|
||||||
|
|
||||||
|
#if __has_include("Quotient/e2ee/sssshandler.h")
|
||||||
|
struct ForeignSSSSHandler {
|
||||||
|
Q_GADGET
|
||||||
|
QML_FOREIGN(Quotient::SSSSHandler)
|
||||||
|
QML_NAMED_ELEMENT(SSSSHandler)
|
||||||
|
};
|
||||||
|
#endif
|
||||||
@@ -8,34 +8,22 @@
|
|||||||
#include <Quotient/events/roommessageevent.h>
|
#include <Quotient/events/roommessageevent.h>
|
||||||
|
|
||||||
#include "neochatconfig.h"
|
#include "neochatconfig.h"
|
||||||
#include "neochatroom.h"
|
#include "neochatconnection.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
using namespace Quotient;
|
using namespace Quotient;
|
||||||
|
|
||||||
LinkPreviewer::LinkPreviewer(const NeoChatRoom *room, const Quotient::RoomMessageEvent *event, QObject *parent)
|
LinkPreviewer::LinkPreviewer(const QUrl &url, QObject *parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
, m_currentRoom(room)
|
|
||||||
, m_event(event)
|
|
||||||
, m_loaded(false)
|
, m_loaded(false)
|
||||||
, m_url(linkPreview(event))
|
, m_url(url)
|
||||||
{
|
{
|
||||||
connect(this, &LinkPreviewer::urlChanged, this, &LinkPreviewer::emptyChanged);
|
Q_ASSERT(dynamic_cast<Connection *>(this->parent()));
|
||||||
|
|
||||||
if (m_event != nullptr && m_currentRoom != nullptr) {
|
connect(this, &LinkPreviewer::urlChanged, this, &LinkPreviewer::emptyChanged);
|
||||||
loadUrlPreview();
|
|
||||||
connect(m_currentRoom, &NeoChatRoom::urlPreviewEnabledChanged, this, &LinkPreviewer::loadUrlPreview);
|
|
||||||
// Make sure that we react to edits
|
|
||||||
connect(m_currentRoom, &NeoChatRoom::replacedEvent, this, [this](const Quotient::RoomEvent *newEvent) {
|
|
||||||
if (m_event->id() == newEvent->id()) {
|
|
||||||
m_event = eventCast<const Quotient::RoomMessageEvent>(newEvent);
|
|
||||||
m_url = linkPreview(m_event);
|
|
||||||
Q_EMIT urlChanged();
|
|
||||||
loadUrlPreview();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
connect(NeoChatConfig::self(), &NeoChatConfig::ShowLinkPreviewChanged, this, &LinkPreviewer::loadUrlPreview);
|
connect(NeoChatConfig::self(), &NeoChatConfig::ShowLinkPreviewChanged, this, &LinkPreviewer::loadUrlPreview);
|
||||||
|
|
||||||
|
loadUrlPreview();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LinkPreviewer::loaded() const
|
bool LinkPreviewer::loaded() const
|
||||||
@@ -65,14 +53,14 @@ QUrl LinkPreviewer::url() const
|
|||||||
|
|
||||||
void LinkPreviewer::loadUrlPreview()
|
void LinkPreviewer::loadUrlPreview()
|
||||||
{
|
{
|
||||||
if (!m_currentRoom || !NeoChatConfig::showLinkPreview() || !m_currentRoom->urlPreviewEnabled()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (m_url.scheme() == QStringLiteral("https")) {
|
if (m_url.scheme() == QStringLiteral("https")) {
|
||||||
m_loaded = false;
|
m_loaded = false;
|
||||||
Q_EMIT loadedChanged();
|
Q_EMIT loadedChanged();
|
||||||
|
|
||||||
auto conn = m_currentRoom->connection();
|
auto conn = dynamic_cast<Connection *>(this->parent());
|
||||||
|
if (conn == nullptr) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
GetUrlPreviewJob *job = conn->callApi<GetUrlPreviewJob>(m_url);
|
GetUrlPreviewJob *job = conn->callApi<GetUrlPreviewJob>(m_url);
|
||||||
|
|
||||||
connect(job, &BaseJob::success, this, [this, job, conn]() {
|
connect(job, &BaseJob::success, this, [this, job, conn]() {
|
||||||
|
|||||||
@@ -53,14 +53,15 @@ class LinkPreviewer : public QObject
|
|||||||
Q_PROPERTY(QUrl imageSource READ imageSource NOTIFY imageSourceChanged)
|
Q_PROPERTY(QUrl imageSource READ imageSource NOTIFY imageSourceChanged)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Whether the there is a link to preview.
|
* @brief Whether there is a link to preview.
|
||||||
*
|
*
|
||||||
* A linkPreviwer is empty if the URL is empty.
|
* A linkPreviwer is empty if the URL is empty.
|
||||||
*/
|
*/
|
||||||
Q_PROPERTY(bool empty READ empty NOTIFY emptyChanged)
|
Q_PROPERTY(bool empty READ empty NOTIFY emptyChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit LinkPreviewer(const NeoChatRoom *room = nullptr, const Quotient::RoomMessageEvent *event = nullptr, QObject *parent = nullptr);
|
LinkPreviewer() = default;
|
||||||
|
explicit LinkPreviewer(const QUrl &url, QObject *parent = nullptr);
|
||||||
|
|
||||||
[[nodiscard]] QUrl url() const;
|
[[nodiscard]] QUrl url() const;
|
||||||
[[nodiscard]] bool loaded() const;
|
[[nodiscard]] bool loaded() const;
|
||||||
@@ -76,18 +77,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
static bool hasPreviewableLinks(const Quotient::RoomMessageEvent *event);
|
static bool hasPreviewableLinks(const Quotient::RoomMessageEvent *event);
|
||||||
|
|
||||||
private:
|
|
||||||
const NeoChatRoom *m_currentRoom;
|
|
||||||
const Quotient::RoomMessageEvent *m_event;
|
|
||||||
|
|
||||||
bool m_loaded;
|
|
||||||
QString m_title = QString();
|
|
||||||
QString m_description = QString();
|
|
||||||
QUrl m_imageSource = QUrl();
|
|
||||||
QUrl m_url;
|
|
||||||
|
|
||||||
void loadUrlPreview();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Return the link to be previewed from the given event.
|
* @brief Return the link to be previewed from the given event.
|
||||||
*
|
*
|
||||||
@@ -96,6 +85,15 @@ private:
|
|||||||
*/
|
*/
|
||||||
static QUrl linkPreview(const Quotient::RoomMessageEvent *event);
|
static QUrl linkPreview(const Quotient::RoomMessageEvent *event);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool m_loaded;
|
||||||
|
QString m_title = QString();
|
||||||
|
QString m_description = QString();
|
||||||
|
QUrl m_imageSource = QUrl();
|
||||||
|
QUrl m_url;
|
||||||
|
|
||||||
|
void loadUrlPreview();
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void loadedChanged();
|
void loadedChanged();
|
||||||
void titleChanged();
|
void titleChanged();
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
#include "login.h"
|
#include "login.h"
|
||||||
|
|
||||||
#include <Quotient/accountregistry.h>
|
#include <Quotient/accountregistry.h>
|
||||||
#include <Quotient/connection.h>
|
|
||||||
#include <Quotient/qt_connection_util.h>
|
#include <Quotient/qt_connection_util.h>
|
||||||
|
|
||||||
#include "controller.h"
|
#include "controller.h"
|
||||||
@@ -54,7 +53,7 @@ void LoginHelper::init()
|
|||||||
m_connection = new NeoChatConnection();
|
m_connection = new NeoChatConnection();
|
||||||
}
|
}
|
||||||
m_connection->resolveServer(m_matrixId);
|
m_connection->resolveServer(m_matrixId);
|
||||||
connectSingleShot(m_connection, &Connection::loginFlowsChanged, this, [this]() {
|
connectSingleShot(m_connection.get(), &Connection::loginFlowsChanged, this, [this]() {
|
||||||
setHomeserverReachable(true);
|
setHomeserverReachable(true);
|
||||||
m_testing = false;
|
m_testing = false;
|
||||||
Q_EMIT testingChanged();
|
Q_EMIT testingChanged();
|
||||||
@@ -100,7 +99,7 @@ void LoginHelper::init()
|
|||||||
Q_EMIT Controller::instance().errorOccured(i18n("Network Error"), std::move(error));
|
Q_EMIT Controller::instance().errorOccured(i18n("Network Error"), std::move(error));
|
||||||
});
|
});
|
||||||
|
|
||||||
connectSingleShot(m_connection, &Connection::syncDone, this, [this]() {
|
connectSingleShot(m_connection.get(), &Connection::syncDone, this, [this]() {
|
||||||
Q_EMIT loaded();
|
Q_EMIT loaded();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -182,7 +181,7 @@ QUrl LoginHelper::ssoUrl() const
|
|||||||
void LoginHelper::loginWithSso()
|
void LoginHelper::loginWithSso()
|
||||||
{
|
{
|
||||||
m_connection->resolveServer(m_matrixId);
|
m_connection->resolveServer(m_matrixId);
|
||||||
connectSingleShot(m_connection, &Connection::loginFlowsChanged, this, [this]() {
|
connectSingleShot(m_connection.get(), &Connection::loginFlowsChanged, this, [this]() {
|
||||||
SsoSession *session = m_connection->prepareForSso(m_deviceName);
|
SsoSession *session = m_connection->prepareForSso(m_deviceName);
|
||||||
m_ssoUrl = session->ssoUrl();
|
m_ssoUrl = session->ssoUrl();
|
||||||
Q_EMIT ssoUrlChanged();
|
Q_EMIT ssoUrlChanged();
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ private:
|
|||||||
QString m_deviceName;
|
QString m_deviceName;
|
||||||
bool m_supportsSso = false;
|
bool m_supportsSso = false;
|
||||||
bool m_supportsPassword = false;
|
bool m_supportsPassword = false;
|
||||||
NeoChatConnection *m_connection = nullptr;
|
QPointer<NeoChatConnection> m_connection;
|
||||||
QUrl m_ssoUrl;
|
QUrl m_ssoUrl;
|
||||||
bool m_testing = false;
|
bool m_testing = false;
|
||||||
bool m_isLoggingIn = false;
|
bool m_isLoggingIn = false;
|
||||||
|
|||||||
23
src/login/CMakeLists.txt
Normal file
23
src/login/CMakeLists.txt
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
# SPDX-FileCopyrightText: 2024 James Graham <james.h.graham@protonmail.com>
|
||||||
|
# SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
|
qt_add_library(login STATIC)
|
||||||
|
qt_add_qml_module(login
|
||||||
|
URI org.kde.neochat.login
|
||||||
|
OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/src/org/kde/neochat/login
|
||||||
|
QML_FILES
|
||||||
|
WelcomePage.qml
|
||||||
|
LoginStep.qml
|
||||||
|
Captcha.qml
|
||||||
|
Email.qml
|
||||||
|
Homeserver.qml
|
||||||
|
Loading.qml
|
||||||
|
Login.qml
|
||||||
|
LoginMethod.qml
|
||||||
|
LoginRegister.qml
|
||||||
|
Password.qml
|
||||||
|
RegisterPassword.qml
|
||||||
|
Sso.qml
|
||||||
|
Terms.qml
|
||||||
|
Username.qml
|
||||||
|
)
|
||||||
@@ -43,6 +43,6 @@ LoginStep {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
previousAction: Kirigami.Action {
|
previousAction: Kirigami.Action {
|
||||||
onTriggered: root.processed("Username.qml")
|
onTriggered: root.processed("Username")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -55,6 +55,6 @@ LoginStep {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
previousAction: Kirigami.Action {
|
previousAction: Kirigami.Action {
|
||||||
onTriggered: root.processed("Username.qml")
|
onTriggered: root.processed("Username")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -40,9 +40,9 @@ LoginStep {
|
|||||||
nextAction: Kirigami.Action {
|
nextAction: Kirigami.Action {
|
||||||
text: Registration.testing ? i18n("Loading") : null
|
text: Registration.testing ? i18n("Loading") : null
|
||||||
enabled: Registration.status > Registration.ServerNoRegistration
|
enabled: Registration.status > Registration.ServerNoRegistration
|
||||||
onTriggered: root.processed("Username.qml")
|
onTriggered: root.processed("Username")
|
||||||
}
|
}
|
||||||
previousAction: Kirigami.Action {
|
previousAction: Kirigami.Action {
|
||||||
onTriggered: root.processed("LoginRegister.qml")
|
onTriggered: root.processed("LoginRegister")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -38,18 +38,18 @@ LoginStep {
|
|||||||
text: LoginHelper.isLoggedIn ? i18n("Already logged in") : (LoginHelper.testing && matrixIdField.acceptableInput) ? i18n("Loading…") : i18nc("@action:button", "Continue")
|
text: LoginHelper.isLoggedIn ? i18n("Already logged in") : (LoginHelper.testing && matrixIdField.acceptableInput) ? i18n("Loading…") : i18nc("@action:button", "Continue")
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
if (LoginHelper.supportsSso && LoginHelper.supportsPassword) {
|
if (LoginHelper.supportsSso && LoginHelper.supportsPassword) {
|
||||||
processed("LoginMethod.qml");
|
processed("LoginMethod");
|
||||||
} else if (LoginHelper.supportsSso) {
|
} else if (LoginHelper.supportsSso) {
|
||||||
processed("Sso.qml");
|
processed("Sso");
|
||||||
} else {
|
} else {
|
||||||
processed("Password.qml");
|
processed("Password");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
enabled: LoginHelper.homeserverReachable
|
enabled: LoginHelper.homeserverReachable
|
||||||
}
|
}
|
||||||
previousAction: Kirigami.Action {
|
previousAction: Kirigami.Action {
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
root.processed("LoginRegister.qml");
|
root.processed("LoginRegister");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -18,12 +18,12 @@ LoginStep {
|
|||||||
FormCard.FormButtonDelegate {
|
FormCard.FormButtonDelegate {
|
||||||
id: loginPasswordButton
|
id: loginPasswordButton
|
||||||
text: i18nc("@action:button", "Login with password")
|
text: i18nc("@action:button", "Login with password")
|
||||||
onClicked: processed("Password.qml")
|
onClicked: processed("Password")
|
||||||
}
|
}
|
||||||
|
|
||||||
FormCard.FormButtonDelegate {
|
FormCard.FormButtonDelegate {
|
||||||
id: loginSsoButton
|
id: loginSsoButton
|
||||||
text: i18nc("@action:button", "Login with single sign-on")
|
text: i18nc("@action:button", "Login with single sign-on")
|
||||||
onClicked: processed("Sso.qml")
|
onClicked: processed("Sso")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -22,13 +22,13 @@ LoginStep {
|
|||||||
FormCard.FormButtonDelegate {
|
FormCard.FormButtonDelegate {
|
||||||
id: loginButton
|
id: loginButton
|
||||||
text: i18nc("@action:button", "Login")
|
text: i18nc("@action:button", "Login")
|
||||||
onClicked: root.processed("Login.qml")
|
onClicked: root.processed("Login")
|
||||||
}
|
}
|
||||||
|
|
||||||
FormCard.FormDelegateSeparator {}
|
FormCard.FormDelegateSeparator {}
|
||||||
|
|
||||||
FormCard.FormButtonDelegate {
|
FormCard.FormButtonDelegate {
|
||||||
text: i18nc("@action:button", "Register")
|
text: i18nc("@action:button", "Register")
|
||||||
onClicked: root.processed("Homeserver.qml")
|
onClicked: root.processed("Homeserver")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -15,7 +15,7 @@ LoginStep {
|
|||||||
Connections {
|
Connections {
|
||||||
target: LoginHelper
|
target: LoginHelper
|
||||||
function onConnected() {
|
function onConnected() {
|
||||||
processed("Loading.qml");
|
processed("Loading");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,6 +46,6 @@ LoginStep {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
previousAction: Kirigami.Action {
|
previousAction: Kirigami.Action {
|
||||||
onTriggered: processed("Login.qml")
|
onTriggered: processed("Login")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -47,6 +47,6 @@ LoginStep {
|
|||||||
}
|
}
|
||||||
|
|
||||||
previousAction: Kirigami.Action {
|
previousAction: Kirigami.Action {
|
||||||
onTriggered: root.processed("Username.qml")
|
onTriggered: root.processed("Username")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -22,7 +22,7 @@ LoginStep {
|
|||||||
UrlHelper.openUrl(LoginHelper.ssoUrl);
|
UrlHelper.openUrl(LoginHelper.ssoUrl);
|
||||||
}
|
}
|
||||||
function onConnected() {
|
function onConnected() {
|
||||||
processed("Loading.qml");
|
processed("Loading");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@ LoginStep {
|
|||||||
}
|
}
|
||||||
|
|
||||||
previousAction: Kirigami.Action {
|
previousAction: Kirigami.Action {
|
||||||
onTriggered: processed("Login.qml")
|
onTriggered: processed("Login")
|
||||||
}
|
}
|
||||||
|
|
||||||
nextAction: Kirigami.Action {
|
nextAction: Kirigami.Action {
|
||||||
@@ -33,6 +33,6 @@ LoginStep {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
previousAction: Kirigami.Action {
|
previousAction: Kirigami.Action {
|
||||||
onTriggered: root.processed("Username.qml")
|
onTriggered: root.processed("Username")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -37,11 +37,11 @@ LoginStep {
|
|||||||
nextAction: Kirigami.Action {
|
nextAction: Kirigami.Action {
|
||||||
text: Registration.status === Registration.TestingUsername ? i18n("Loading") : null
|
text: Registration.status === Registration.TestingUsername ? i18n("Loading") : null
|
||||||
|
|
||||||
onTriggered: root.processed("RegisterPassword.qml")
|
onTriggered: root.processed("RegisterPassword")
|
||||||
enabled: Registration.status === Registration.Ready
|
enabled: Registration.status === Registration.Ready
|
||||||
}
|
}
|
||||||
|
|
||||||
previousAction: Kirigami.Action {
|
previousAction: Kirigami.Action {
|
||||||
onTriggered: root.processed("Homeserver.qml")
|
onTriggered: root.processed("Homeserver")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -10,7 +10,6 @@ import org.kde.kirigamiaddons.formcard as FormCard
|
|||||||
|
|
||||||
import org.kde.neochat
|
import org.kde.neochat
|
||||||
import org.kde.neochat.settings
|
import org.kde.neochat.settings
|
||||||
import org.kde.neochat.accounts
|
|
||||||
|
|
||||||
FormCard.FormCardPage {
|
FormCard.FormCardPage {
|
||||||
id: root
|
id: root
|
||||||
@@ -19,7 +18,7 @@ FormCard.FormCardPage {
|
|||||||
property bool _showExisting: showExisting && root.currentStepString === root.initialStep
|
property bool _showExisting: showExisting && root.currentStepString === root.initialStep
|
||||||
property alias currentStep: module.item
|
property alias currentStep: module.item
|
||||||
property string currentStepString: initialStep
|
property string currentStepString: initialStep
|
||||||
property string initialStep: "LoginRegister.qml"
|
property string initialStep: "LoginRegister"
|
||||||
|
|
||||||
signal connectionChosen
|
signal connectionChosen
|
||||||
|
|
||||||
@@ -129,14 +128,14 @@ FormCard.FormCardPage {
|
|||||||
Loader {
|
Loader {
|
||||||
id: module
|
id: module
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
sourceComponent: Qt.createComponent('org.kde.neochat', root.initialStep)
|
sourceComponent: Qt.createComponent('org.kde.neochat.login', root.initialStep)
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
id: stepConnections
|
id: stepConnections
|
||||||
target: currentStep
|
target: currentStep
|
||||||
|
|
||||||
function onProcessed(nextStep: string): void {
|
function onProcessed(nextStep: string): void {
|
||||||
module.source = nextStep;
|
module.source = nextStep + ".qml";
|
||||||
root.currentStepString = nextStep;
|
root.currentStepString = nextStep;
|
||||||
headerMessage.text = "";
|
headerMessage.text = "";
|
||||||
headerMessage.visible = false;
|
headerMessage.visible = false;
|
||||||
@@ -167,16 +166,16 @@ FormCard.FormCardPage {
|
|||||||
target: Registration
|
target: Registration
|
||||||
function onNextStepChanged() {
|
function onNextStepChanged() {
|
||||||
if (Registration.nextStep === "m.login.recaptcha") {
|
if (Registration.nextStep === "m.login.recaptcha") {
|
||||||
stepConnections.onProcessed("Captcha.qml");
|
stepConnections.onProcessed("Captcha");
|
||||||
}
|
}
|
||||||
if (Registration.nextStep === "m.login.terms") {
|
if (Registration.nextStep === "m.login.terms") {
|
||||||
stepConnections.onProcessed("Terms.qml");
|
stepConnections.onProcessed("Terms");
|
||||||
}
|
}
|
||||||
if (Registration.nextStep === "m.login.email.identity") {
|
if (Registration.nextStep === "m.login.email.identity") {
|
||||||
stepConnections.onProcessed("Email.qml");
|
stepConnections.onProcessed("Email");
|
||||||
}
|
}
|
||||||
if (Registration.nextStep === "loading") {
|
if (Registration.nextStep === "loading") {
|
||||||
stepConnections.onProcessed("Loading.qml");
|
stepConnections.onProcessed("Loading");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -217,7 +216,7 @@ FormCard.FormCardPage {
|
|||||||
FormCard.FormButtonDelegate {
|
FormCard.FormButtonDelegate {
|
||||||
text: i18nc("@action:button", "Open proxy settings")
|
text: i18nc("@action:button", "Open proxy settings")
|
||||||
icon.name: "settings-configure"
|
icon.name: "settings-configure"
|
||||||
onClicked: pageStack.pushDialogLayer(Qt.createComponent("org.kde.neochat.settings", "NetworkProxyPage.qml"), {}, {
|
onClicked: pageStack.pushDialogLayer(Qt.createComponent("org.kde.neochat.settings", "NetworkProxyPage"), {}, {
|
||||||
title: i18nc("@title:window", "Proxy Settings")
|
title: i18nc("@title:window", "Proxy Settings")
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
25
src/main.cpp
25
src/main.cpp
@@ -30,16 +30,16 @@
|
|||||||
#ifdef HAVE_WINDOWSYSTEM
|
#ifdef HAVE_WINDOWSYSTEM
|
||||||
#include <KWindowSystem>
|
#include <KWindowSystem>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if __has_include("KCrash")
|
||||||
|
#include <KCrash>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <KLocalizedContext>
|
#include <KLocalizedContext>
|
||||||
#include <KLocalizedString>
|
#include <KLocalizedString>
|
||||||
|
|
||||||
#include "neochat-version.h"
|
#include "neochat-version.h"
|
||||||
|
|
||||||
#include <Quotient/accountregistry.h>
|
|
||||||
#if __has_include("Quotient/e2ee/sssshandler.h")
|
|
||||||
#include <Quotient/e2ee/sssshandler.h>
|
|
||||||
#endif
|
|
||||||
#include <Quotient/keyverificationsession.h>
|
|
||||||
#include <Quotient/networkaccessmanager.h>
|
#include <Quotient/networkaccessmanager.h>
|
||||||
|
|
||||||
#include "blurhashimageprovider.h"
|
#include "blurhashimageprovider.h"
|
||||||
@@ -167,6 +167,10 @@ int main(int argc, char *argv[])
|
|||||||
KAboutData::setApplicationData(about);
|
KAboutData::setApplicationData(about);
|
||||||
QGuiApplication::setWindowIcon(QIcon::fromTheme(QStringLiteral("org.kde.neochat")));
|
QGuiApplication::setWindowIcon(QIcon::fromTheme(QStringLiteral("org.kde.neochat")));
|
||||||
|
|
||||||
|
#if __has_include("KCrash")
|
||||||
|
KCrash::initialize();
|
||||||
|
#endif
|
||||||
|
|
||||||
initLogging();
|
initLogging();
|
||||||
|
|
||||||
Connection::setEncryptionDefault(true);
|
Connection::setEncryptionDefault(true);
|
||||||
@@ -230,15 +234,10 @@ int main(int argc, char *argv[])
|
|||||||
|
|
||||||
Q_IMPORT_QML_PLUGIN(org_kde_neochat_settingsPlugin)
|
Q_IMPORT_QML_PLUGIN(org_kde_neochat_settingsPlugin)
|
||||||
Q_IMPORT_QML_PLUGIN(org_kde_neochat_timelinePlugin)
|
Q_IMPORT_QML_PLUGIN(org_kde_neochat_timelinePlugin)
|
||||||
|
Q_IMPORT_QML_PLUGIN(org_kde_neochat_devtoolsPlugin)
|
||||||
|
Q_IMPORT_QML_PLUGIN(org_kde_neochat_loginPlugin)
|
||||||
|
|
||||||
qml_register_types_org_kde_neochat();
|
qml_register_types_org_kde_neochat();
|
||||||
qmlRegisterSingletonInstance("org.kde.neochat.config", 1, 0, "Config", NeoChatConfig::self());
|
|
||||||
qmlRegisterSingletonInstance("org.kde.neochat.accounts", 1, 0, "AccountRegistry", &Controller::instance().accounts());
|
|
||||||
|
|
||||||
qmlRegisterUncreatableType<KeyVerificationSession>("com.github.quotient_im.libquotient", 1, 0, "KeyVerificationSession", {});
|
|
||||||
#if __has_include("Quotient/e2ee/sssshandler.h")
|
|
||||||
qmlRegisterType<SSSSHandler>("com.github.quotient_im.libquotient", 1, 0, "SSSSHandler");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
QQmlApplicationEngine engine;
|
QQmlApplicationEngine engine;
|
||||||
|
|
||||||
@@ -289,7 +288,7 @@ int main(int argc, char *argv[])
|
|||||||
engine.addImageProvider(QLatin1String("mxc"), MatrixImageProvider::create(&engine, &engine));
|
engine.addImageProvider(QLatin1String("mxc"), MatrixImageProvider::create(&engine, &engine));
|
||||||
engine.addImageProvider(QLatin1String("blurhash"), new BlurhashImageProvider);
|
engine.addImageProvider(QLatin1String("blurhash"), new BlurhashImageProvider);
|
||||||
|
|
||||||
engine.load(QUrl(QStringLiteral("qrc:/qt/qml/org/kde/neochat/qml/main.qml")));
|
engine.loadFromModule("org.kde.neochat", "Main");
|
||||||
if (engine.rootObjects().isEmpty()) {
|
if (engine.rootObjects().isEmpty()) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,8 +14,6 @@
|
|||||||
|
|
||||||
#include "neochatconnection.h"
|
#include "neochatconnection.h"
|
||||||
|
|
||||||
#include <Quotient/connection.h>
|
|
||||||
|
|
||||||
using namespace Quotient;
|
using namespace Quotient;
|
||||||
|
|
||||||
ThumbnailResponse::ThumbnailResponse(QString id, QSize size, NeoChatConnection *connection)
|
ThumbnailResponse::ThumbnailResponse(QString id, QSize size, NeoChatConnection *connection)
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ private:
|
|||||||
QSize requestedSize;
|
QSize requestedSize;
|
||||||
const QString localFile;
|
const QString localFile;
|
||||||
Quotient::MediaThumbnailJob *job = nullptr;
|
Quotient::MediaThumbnailJob *job = nullptr;
|
||||||
NeoChatConnection *m_connection;
|
QPointer<NeoChatConnection> m_connection;
|
||||||
|
|
||||||
QImage image;
|
QImage image;
|
||||||
QString errorStr;
|
QString errorStr;
|
||||||
@@ -75,6 +75,6 @@ public:
|
|||||||
QQuickImageResponse *requestImageResponse(const QString &id, const QSize &requestedSize) override;
|
QQuickImageResponse *requestImageResponse(const QString &id, const QSize &requestedSize) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
NeoChatConnection *m_connection = nullptr;
|
QPointer<NeoChatConnection> m_connection;
|
||||||
MatrixImageProvider() = default;
|
MatrixImageProvider() = default;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -7,3 +7,5 @@ void MediaManager::startPlayback()
|
|||||||
{
|
{
|
||||||
Q_EMIT playbackStarted();
|
Q_EMIT playbackStarted();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include "moc_mediamanager.cpp"
|
||||||
|
|||||||
@@ -3,9 +3,15 @@
|
|||||||
|
|
||||||
#include "accountemoticonmodel.h"
|
#include "accountemoticonmodel.h"
|
||||||
|
|
||||||
|
#include <QImage>
|
||||||
|
#include <QMimeDatabase>
|
||||||
|
|
||||||
#include <Quotient/csapi/content-repo.h>
|
#include <Quotient/csapi/content-repo.h>
|
||||||
|
#include <Quotient/events/eventcontent.h>
|
||||||
#include <qcoro/qcorosignal.h>
|
#include <qcoro/qcorosignal.h>
|
||||||
|
|
||||||
|
#include "neochatconnection.h"
|
||||||
|
|
||||||
using namespace Quotient;
|
using namespace Quotient;
|
||||||
|
|
||||||
AccountEmoticonModel::AccountEmoticonModel(QObject *parent)
|
AccountEmoticonModel::AccountEmoticonModel(QObject *parent)
|
||||||
@@ -73,12 +79,12 @@ QHash<int, QByteArray> AccountEmoticonModel::roleNames() const
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
Connection *AccountEmoticonModel::connection() const
|
NeoChatConnection *AccountEmoticonModel::connection() const
|
||||||
{
|
{
|
||||||
return m_connection;
|
return m_connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AccountEmoticonModel::setConnection(Connection *connection)
|
void AccountEmoticonModel::setConnection(NeoChatConnection *connection)
|
||||||
{
|
{
|
||||||
if (m_connection) {
|
if (m_connection) {
|
||||||
disconnect(m_connection, nullptr, this, nullptr);
|
disconnect(m_connection, nullptr, this, nullptr);
|
||||||
@@ -162,7 +168,15 @@ QCoro::Task<void> AccountEmoticonModel::doSetEmoticonImage(int index, QUrl sourc
|
|||||||
co_return;
|
co_return;
|
||||||
}
|
}
|
||||||
m_images->images[index].url = job->contentUri();
|
m_images->images[index].url = job->contentUri();
|
||||||
m_images->images[index].info = none;
|
auto mime = QMimeDatabase().mimeTypeForUrl(source);
|
||||||
|
source.setScheme("file"_ls);
|
||||||
|
QFileInfo fileInfo(source.isLocalFile() ? source.toLocalFile() : source.toString());
|
||||||
|
EventContent::ImageInfo info;
|
||||||
|
if (mime.name().startsWith("image/"_ls)) {
|
||||||
|
QImage image(source.toLocalFile());
|
||||||
|
info = EventContent::ImageInfo(source, fileInfo.size(), mime, image.size(), fileInfo.fileName());
|
||||||
|
}
|
||||||
|
m_images->images[index].info = info;
|
||||||
QJsonObject data;
|
QJsonObject data;
|
||||||
m_images->fillJson(&data);
|
m_images->fillJson(&data);
|
||||||
m_connection->setAccountData("im.ponies.user_emotes"_ls, data);
|
m_connection->setAccountData("im.ponies.user_emotes"_ls, data);
|
||||||
@@ -175,11 +189,21 @@ QCoro::Task<void> AccountEmoticonModel::doAddEmoticon(QUrl source, QString short
|
|||||||
if (job->error() != BaseJob::NoError) {
|
if (job->error() != BaseJob::NoError) {
|
||||||
co_return;
|
co_return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto mime = QMimeDatabase().mimeTypeForUrl(source);
|
||||||
|
source.setScheme("file"_ls);
|
||||||
|
QFileInfo fileInfo(source.isLocalFile() ? source.toLocalFile() : source.toString());
|
||||||
|
EventContent::ImageInfo info;
|
||||||
|
if (mime.name().startsWith("image/"_ls)) {
|
||||||
|
QImage image(source.toLocalFile());
|
||||||
|
info = EventContent::ImageInfo(source, fileInfo.size(), mime, image.size(), fileInfo.fileName());
|
||||||
|
}
|
||||||
|
|
||||||
m_images->images.append(ImagePackEventContent::ImagePackImage{
|
m_images->images.append(ImagePackEventContent::ImagePackImage{
|
||||||
shortcode,
|
shortcode,
|
||||||
job->contentUri(),
|
job->contentUri(),
|
||||||
description,
|
description,
|
||||||
none,
|
info,
|
||||||
QStringList{type},
|
QStringList{type},
|
||||||
});
|
});
|
||||||
QJsonObject data;
|
QJsonObject data;
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
#include <QPointer>
|
#include <QPointer>
|
||||||
#include <QQmlEngine>
|
#include <QQmlEngine>
|
||||||
|
|
||||||
#include <Quotient/connection.h>
|
class NeoChatConnection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @class AccountEmoticonModel
|
* @class AccountEmoticonModel
|
||||||
@@ -29,7 +29,7 @@ class AccountEmoticonModel : public QAbstractListModel
|
|||||||
/**
|
/**
|
||||||
* @brief The connection to get emoticons from.
|
* @brief The connection to get emoticons from.
|
||||||
*/
|
*/
|
||||||
Q_PROPERTY(Quotient::Connection *connection READ connection WRITE setConnection NOTIFY connectionChanged)
|
Q_PROPERTY(NeoChatConnection *connection READ connection WRITE setConnection NOTIFY connectionChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum Roles {
|
enum Roles {
|
||||||
@@ -63,8 +63,8 @@ public:
|
|||||||
*/
|
*/
|
||||||
[[nodiscard]] QHash<int, QByteArray> roleNames() const override;
|
[[nodiscard]] QHash<int, QByteArray> roleNames() const override;
|
||||||
|
|
||||||
[[nodiscard]] Quotient::Connection *connection() const;
|
[[nodiscard]] NeoChatConnection *connection() const;
|
||||||
void setConnection(Quotient::Connection *connection);
|
void setConnection(NeoChatConnection *connection);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Deletes the emoticon at the given index.
|
* @brief Deletes the emoticon at the given index.
|
||||||
@@ -96,7 +96,7 @@ Q_SIGNALS:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
std::optional<Quotient::ImagePackEventContent> m_images;
|
std::optional<Quotient::ImagePackEventContent> m_images;
|
||||||
QPointer<Quotient::Connection> m_connection;
|
QPointer<NeoChatConnection> m_connection;
|
||||||
QCoro::Task<void> doSetEmoticonImage(int index, QUrl source);
|
QCoro::Task<void> doSetEmoticonImage(int index, QUrl source);
|
||||||
QCoro::Task<void> doAddEmoticon(QUrl source, QString shortcode, QString description, QString type);
|
QCoro::Task<void> doAddEmoticon(QUrl source, QString shortcode, QString description, QString type);
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include "actionsmodel.h"
|
#include "actionsmodel.h"
|
||||||
|
|
||||||
#include "chatbarcache.h"
|
#include "chatbarcache.h"
|
||||||
|
#include "neochatconnection.h"
|
||||||
#include "neochatroom.h"
|
#include "neochatroom.h"
|
||||||
#include "roommanager.h"
|
#include "roommanager.h"
|
||||||
#include <Quotient/events/roommemberevent.h>
|
#include <Quotient/events/roommemberevent.h>
|
||||||
@@ -260,7 +261,7 @@ QList<ActionsModel::Action> actions{
|
|||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
Q_EMIT room->showMessage(NeoChatRoom::Info, i18nc("Knocking room <roomname>.", "Knocking room %1.", text));
|
Q_EMIT room->showMessage(NeoChatRoom::Info, i18nc("Knocking room <roomname>.", "Knocking room %1.", text));
|
||||||
auto connection = room->connection();
|
auto connection = dynamic_cast<NeoChatConnection *>(room->connection());
|
||||||
const auto knownServer = roomName.mid(roomName.indexOf(":"_ls) + 1);
|
const auto knownServer = roomName.mid(roomName.indexOf(":"_ls) + 1);
|
||||||
if (parts.length() >= 2) {
|
if (parts.length() >= 2) {
|
||||||
RoomManager::instance().knockRoom(connection, roomName, parts[1], QStringList{knownServer});
|
RoomManager::instance().knockRoom(connection, roomName, parts[1], QStringList{knownServer});
|
||||||
|
|||||||
@@ -161,7 +161,7 @@ QVariant CustomEmojiModel::data(const QModelIndex &idx, int role) const
|
|||||||
case Roles::ImageURL:
|
case Roles::ImageURL:
|
||||||
return QUrl(QStringLiteral("image://mxc/") + data.url.mid(6));
|
return QUrl(QStringLiteral("image://mxc/") + data.url.mid(6));
|
||||||
case Roles::MxcUrl:
|
case Roles::MxcUrl:
|
||||||
return data.url.mid(6);
|
return m_connection->makeMediaUrl(QUrl(data.url));
|
||||||
default:
|
default:
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ Q_SIGNALS:
|
|||||||
private:
|
private:
|
||||||
explicit CustomEmojiModel(QObject *parent = nullptr);
|
explicit CustomEmojiModel(QObject *parent = nullptr);
|
||||||
QList<CustomEmoji> m_emojis;
|
QList<CustomEmoji> m_emojis;
|
||||||
NeoChatConnection *m_connection = nullptr;
|
QPointer<NeoChatConnection> m_connection;
|
||||||
|
|
||||||
void fetchEmojis();
|
void fetchEmojis();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,7 +5,8 @@
|
|||||||
|
|
||||||
#include "customemojimodel.h"
|
#include "customemojimodel.h"
|
||||||
#include <QRegularExpression>
|
#include <QRegularExpression>
|
||||||
#include <connection.h>
|
|
||||||
|
class NeoChatConnection;
|
||||||
|
|
||||||
struct CustomEmoji {
|
struct CustomEmoji {
|
||||||
QString name; // with :semicolons:
|
QString name; // with :semicolons:
|
||||||
@@ -14,6 +15,6 @@ struct CustomEmoji {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct CustomEmojiModel::Private {
|
struct CustomEmojiModel::Private {
|
||||||
Quotient::Connection *conn = nullptr;
|
QPointer<NeoChatConnection> connection;
|
||||||
QList<CustomEmoji> emojies;
|
QList<CustomEmoji> emojies;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -11,14 +11,24 @@
|
|||||||
#include <KLocalizedString>
|
#include <KLocalizedString>
|
||||||
|
|
||||||
#include <Quotient/csapi/device_management.h>
|
#include <Quotient/csapi/device_management.h>
|
||||||
#include <Quotient/connection.h>
|
|
||||||
#include <Quotient/user.h>
|
#include <Quotient/user.h>
|
||||||
|
|
||||||
|
#include "neochatconnection.h"
|
||||||
|
|
||||||
using namespace Quotient;
|
using namespace Quotient;
|
||||||
|
|
||||||
DevicesModel::DevicesModel(QObject *parent)
|
DevicesModel::DevicesModel(QObject *parent)
|
||||||
: QAbstractListModel(parent)
|
: QAbstractListModel(parent)
|
||||||
{
|
{
|
||||||
|
connect(m_connection, &Connection::sessionVerified, this, [this](const QString &, const QString &deviceId) {
|
||||||
|
const auto it = std::find_if(m_devices.begin(), m_devices.end(), [deviceId](const Quotient::Device &device) {
|
||||||
|
return device.deviceId == deviceId;
|
||||||
|
});
|
||||||
|
if (it != m_devices.end()) {
|
||||||
|
const auto index = this->index(it - m_devices.begin());
|
||||||
|
Q_EMIT dataChanged(index, index, {Type});
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void DevicesModel::fetchDevices()
|
void DevicesModel::fetchDevices()
|
||||||
@@ -143,12 +153,12 @@ void DevicesModel::setName(const QString &deviceId, const QString &name)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Connection *DevicesModel::connection() const
|
NeoChatConnection *DevicesModel::connection() const
|
||||||
{
|
{
|
||||||
return m_connection;
|
return m_connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DevicesModel::setConnection(Connection *connection)
|
void DevicesModel::setConnection(NeoChatConnection *connection)
|
||||||
{
|
{
|
||||||
if (m_connection) {
|
if (m_connection) {
|
||||||
disconnect(m_connection, nullptr, this, nullptr);
|
disconnect(m_connection, nullptr, this, nullptr);
|
||||||
|
|||||||
@@ -9,10 +9,7 @@
|
|||||||
|
|
||||||
#include <Quotient/csapi/definitions/client_device.h>
|
#include <Quotient/csapi/definitions/client_device.h>
|
||||||
|
|
||||||
namespace Quotient
|
class NeoChatConnection;
|
||||||
{
|
|
||||||
class Connection;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @class DevicesModel
|
* @class DevicesModel
|
||||||
@@ -31,7 +28,7 @@ class DevicesModel : public QAbstractListModel
|
|||||||
/**
|
/**
|
||||||
* @brief The current connection that the model is getting its devices from.
|
* @brief The current connection that the model is getting its devices from.
|
||||||
*/
|
*/
|
||||||
Q_PROPERTY(Quotient::Connection *connection READ connection WRITE setConnection NOTIFY connectionChanged REQUIRED)
|
Q_PROPERTY(NeoChatConnection *connection READ connection WRITE setConnection NOTIFY connectionChanged REQUIRED)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
@@ -88,9 +85,8 @@ public:
|
|||||||
|
|
||||||
explicit DevicesModel(QObject *parent = nullptr);
|
explicit DevicesModel(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
[[nodiscard]] NeoChatConnection *connection() const;
|
||||||
[[nodiscard]] Quotient::Connection *connection() const;
|
void setConnection(NeoChatConnection *connection);
|
||||||
void setConnection(Quotient::Connection *connection);
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void connectionChanged();
|
void connectionChanged();
|
||||||
@@ -99,5 +95,5 @@ Q_SIGNALS:
|
|||||||
private:
|
private:
|
||||||
void fetchDevices();
|
void fetchDevices();
|
||||||
QList<Quotient::Device> m_devices;
|
QList<Quotient::Device> m_devices;
|
||||||
QPointer<Quotient::Connection> m_connection;
|
QPointer<NeoChatConnection> m_connection;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -208,3 +208,5 @@ void ItineraryModel::sendToItinerary()
|
|||||||
job->start();
|
job->start();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include "moc_itinerarymodel.cpp"
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user