Compare commits
179 Commits
work/redst
...
release/24
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cedbbd6c56 | ||
|
|
3215224528 | ||
|
|
2f6d7308c5 | ||
|
|
6450f0dbe8 | ||
|
|
3d7a964889 | ||
|
|
2ab2570d94 | ||
|
|
bf81e743f4 | ||
|
|
a85af258fe | ||
|
|
063e7393ac | ||
|
|
dafd02790f | ||
|
|
29dd6b12ec | ||
|
|
9c7a49bf62 | ||
|
|
e3cb592cd1 | ||
|
|
2dc54441ac | ||
|
|
9259e7bb52 | ||
|
|
9212cf3f45 | ||
|
|
49a99058b7 | ||
|
|
b7c9ec9bd2 | ||
|
|
683d1f3487 | ||
|
|
e7563870bf | ||
|
|
59a865e1d3 | ||
|
|
75b6444c1e | ||
|
|
180e927f82 | ||
|
|
fcb32b1974 | ||
|
|
bf9d1e5261 | ||
|
|
d6eb91c476 | ||
|
|
96b03082e3 | ||
|
|
962063e58a | ||
|
|
06a09700a0 | ||
|
|
12657abd03 | ||
|
|
3752c3b872 | ||
|
|
acf3f7030d | ||
|
|
63ed48f283 | ||
|
|
25f2693710 | ||
|
|
2efcc1041b | ||
|
|
1f5823cec0 | ||
|
|
efd18fa2d6 | ||
|
|
98dc2cf41a | ||
|
|
97f27a1ae0 | ||
|
|
46b9566242 | ||
|
|
70ab0374ec | ||
|
|
2b2e991bb8 | ||
|
|
fbf4dfbe35 | ||
|
|
1344e46201 | ||
|
|
728d133b7c | ||
|
|
a41be9e19b | ||
|
|
aa5ece8bfb | ||
|
|
21f5ee74ba | ||
|
|
2e6cf03c15 | ||
|
|
9332910bcb | ||
|
|
157c098af3 | ||
|
|
9fe134e7f0 | ||
|
|
46aaab3fb0 | ||
|
|
a5b37a78a0 | ||
|
|
59699abb94 | ||
|
|
3cc0d89ee5 | ||
|
|
96e83fc71b | ||
|
|
d89019d752 | ||
|
|
51565dfdd2 | ||
|
|
e1d09171d5 | ||
|
|
f86572f880 | ||
|
|
d7451834f3 | ||
|
|
a4767cea7d | ||
|
|
4c43869fd4 | ||
|
|
e603664521 | ||
|
|
369242ab31 | ||
|
|
013773d465 | ||
|
|
20b17a58d3 | ||
|
|
1c4bb79347 | ||
|
|
6d2b49f3eb | ||
|
|
e3d5867da6 | ||
|
|
a046e3ed27 | ||
|
|
5b935c1d33 | ||
|
|
fe6bc5a36e | ||
|
|
c085be4f6e | ||
|
|
1f73a9dc90 | ||
|
|
63206ef1dd | ||
|
|
0d286db0c2 | ||
|
|
7d3f478a74 | ||
|
|
6df2ebd1eb | ||
|
|
252fb6eb21 | ||
|
|
5873092356 | ||
|
|
30822003d1 | ||
|
|
52ae237eb7 | ||
|
|
ee02abfe37 | ||
|
|
f0de235f37 | ||
|
|
9e9fe6d275 | ||
|
|
f4ca5f0f34 | ||
|
|
5f240fa05c | ||
|
|
1e29eca59a | ||
|
|
1f71ec3bf8 | ||
|
|
64c5ad88f6 | ||
|
|
fb5a3c1c5c | ||
|
|
4a5a83f94a | ||
|
|
133edc249f | ||
|
|
da30e66127 | ||
|
|
4516e1e0f4 | ||
|
|
bd80f65163 | ||
|
|
f828ecf282 | ||
|
|
a0483167c5 | ||
|
|
87288f508c | ||
|
|
dc184ed2fd | ||
|
|
49e1bf9ab1 | ||
|
|
74acf3f9dc | ||
|
|
38205d2791 | ||
|
|
81da926d4f | ||
|
|
1018fe5d3f | ||
|
|
58b32dd50f | ||
|
|
82184b895a | ||
|
|
da0f6f78a4 | ||
|
|
cfd06d064c | ||
|
|
a90e9ae92a | ||
|
|
8ab0002057 | ||
|
|
e1840be234 | ||
|
|
d6ecaaa344 | ||
|
|
0c08c2ab89 | ||
|
|
39ff11e059 | ||
|
|
93254431c5 | ||
|
|
fc14a8eac8 | ||
|
|
50759bb3ca | ||
|
|
23134d8e72 | ||
|
|
7cd095f76a | ||
|
|
d5c3054da4 | ||
|
|
ae12c838bd | ||
|
|
51727dd345 | ||
|
|
5611b000fb | ||
|
|
461896e228 | ||
|
|
e388536a03 | ||
|
|
61f22edd86 | ||
|
|
9e368691d6 | ||
|
|
dad2b3ec8f | ||
|
|
8821c37ff8 | ||
|
|
c105170eca | ||
|
|
b07c04eddc | ||
|
|
7aa0f68b10 | ||
|
|
cbdae4c312 | ||
|
|
9210940556 | ||
|
|
d8489527b4 | ||
|
|
64c9cd97de | ||
|
|
119a9890b1 | ||
|
|
69be6b5939 | ||
|
|
112152f2df | ||
|
|
2ef634a6cb | ||
|
|
fd31b4fb74 | ||
|
|
3b12520fa2 | ||
|
|
24718a5f72 | ||
|
|
db62bacc7e | ||
|
|
6500669b67 | ||
|
|
557d151ed4 | ||
|
|
95ffd485b4 | ||
|
|
ebd38fb435 | ||
|
|
a5b999e682 | ||
|
|
41d34fc0e4 | ||
|
|
b51194f90f | ||
|
|
80ac9e1ba7 | ||
|
|
e3874c824a | ||
|
|
6599c6b609 | ||
|
|
13d522221c | ||
|
|
dd8f926f32 | ||
|
|
258312e798 | ||
|
|
43d40c7e75 | ||
|
|
cbcc9a6514 | ||
|
|
625048610b | ||
|
|
fa47b67e3d | ||
|
|
9347a66acf | ||
|
|
317df56ffa | ||
|
|
fed9197716 | ||
|
|
1e892599e9 | ||
|
|
b7229ca0cf | ||
|
|
953b711823 | ||
|
|
01d903efd3 | ||
|
|
241dd81932 | ||
|
|
f6dfe0cbcf | ||
|
|
f10b97139c | ||
|
|
385c5b3405 | ||
|
|
7bc6f906f8 | ||
|
|
b8b1434a95 | ||
|
|
85c7a4bcb3 | ||
|
|
84b698a7e8 |
@@ -2,7 +2,7 @@
|
|||||||
"id": "org.kde.neochat",
|
"id": "org.kde.neochat",
|
||||||
"branch": "master",
|
"branch": "master",
|
||||||
"runtime": "org.kde.Platform",
|
"runtime": "org.kde.Platform",
|
||||||
"runtime-version": "6.9",
|
"runtime-version": "6.7",
|
||||||
"sdk": "org.kde.Sdk",
|
"sdk": "org.kde.Sdk",
|
||||||
"command": "neochat",
|
"command": "neochat",
|
||||||
"tags": [
|
"tags": [
|
||||||
@@ -25,23 +25,13 @@
|
|||||||
"modules": [
|
"modules": [
|
||||||
{
|
{
|
||||||
"name": "kirigamiaddons",
|
"name": "kirigamiaddons",
|
||||||
"config-opts": [
|
"config-opts": [ "-DBUILD_TESTING=OFF" ],
|
||||||
"-DBUILD_TESTING=OFF"
|
|
||||||
],
|
|
||||||
"buildsystem": "cmake-ninja",
|
"buildsystem": "cmake-ninja",
|
||||||
"sources": [
|
"sources": [ { "type": "git", "url": "https://invent.kde.org/libraries/kirigami-addons.git", "commit": "34d311219e8b7209746a98b3a29b91ded05ff936" } ]
|
||||||
{
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://invent.kde.org/libraries/kirigami-addons.git"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "kquickimageeditor",
|
"name": "kquickimageeditor",
|
||||||
"config-opts": [
|
"config-opts": [ "-DBUILD_WITH_QT6=ON" ],
|
||||||
"-DBUILD_WITH_QT6=ON",
|
|
||||||
"-DBUILD_TESTING=OFF"
|
|
||||||
],
|
|
||||||
"buildsystem": "cmake-ninja",
|
"buildsystem": "cmake-ninja",
|
||||||
"sources": [
|
"sources": [
|
||||||
{
|
{
|
||||||
@@ -53,19 +43,17 @@
|
|||||||
{
|
{
|
||||||
"name": "olm",
|
"name": "olm",
|
||||||
"buildsystem": "cmake-ninja",
|
"buildsystem": "cmake-ninja",
|
||||||
"config-opts": [
|
"config-opts": [ "-DOLM_TESTS=OFF" ],
|
||||||
"-DOLM_TESTS=OFF"
|
|
||||||
],
|
|
||||||
"sources": [
|
"sources": [
|
||||||
{
|
{
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://gitlab.matrix.org/matrix-org/olm.git",
|
"url": "https://gitlab.matrix.org/matrix-org/olm.git",
|
||||||
"tag": "3.2.16",
|
"tag": "3.2.10",
|
||||||
"x-checker-data": {
|
"x-checker-data": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"tag-pattern": "^([\\d.]+)$"
|
"tag-pattern": "^([\\d.]+)$"
|
||||||
},
|
},
|
||||||
"commit": "7e0c8277032e40308987257b711b38af8d77cc69"
|
"commit": "9908862979147a71dc6abaecd521be526ae77be1"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -77,13 +65,13 @@
|
|||||||
"-Dvapi=false",
|
"-Dvapi=false",
|
||||||
"-Dgtk_doc=false",
|
"-Dgtk_doc=false",
|
||||||
"-Dintrospection=false",
|
"-Dintrospection=false",
|
||||||
"-Dcrypto=disabled"
|
"-Dgcrypt=false"
|
||||||
],
|
],
|
||||||
"sources": [
|
"sources": [
|
||||||
{
|
{
|
||||||
"type": "archive",
|
"type": "archive",
|
||||||
"url": "https://download.gnome.org/sources/libsecret/0.21/libsecret-0.21.6.tar.xz",
|
"url": "https://download.gnome.org/sources/libsecret/0.20/libsecret-0.20.5.tar.xz",
|
||||||
"sha256": "747b8c175be108c880d3adfb9c3537ea66e520e4ad2dccf5dce58003aeeca090",
|
"sha256": "3fb3ce340fcd7db54d87c893e69bfc2b1f6e4d4b279065ffe66dac9f0fd12b4d",
|
||||||
"x-checker-data": {
|
"x-checker-data": {
|
||||||
"type": "gnome",
|
"type": "gnome",
|
||||||
"name": "libsecret",
|
"name": "libsecret",
|
||||||
@@ -98,13 +86,13 @@
|
|||||||
"sources": [
|
"sources": [
|
||||||
{
|
{
|
||||||
"type": "archive",
|
"type": "archive",
|
||||||
"url": "https://github.com/frankosterfeld/qtkeychain/archive/refs/tags/0.15.0.tar.gz",
|
"url": "https://github.com/frankosterfeld/qtkeychain/archive/0.14.2.tar.gz",
|
||||||
"sha256": "f4254dc8f0933b06d90672d683eab08ef770acd8336e44dfa030ce041dc2ca22",
|
"sha256": "cf2e972b783ba66334a79a30f6b3a1ea794a1dc574d6c3bebae5ffd2f0399571",
|
||||||
"x-checker-data": {
|
"x-checker-data": {
|
||||||
"type": "anitya",
|
"type": "anitya",
|
||||||
"project-id": 4138,
|
"project-id": 4138,
|
||||||
"stable-only": true,
|
"stable-only": true,
|
||||||
"url-template": "https://github.com/frankosterfeld/qtkeychain/archive/refs/tags/$version.tar.gz"
|
"url-template": "https://github.com/frankosterfeld/qtkeychain/archive/v$version.tar.gz"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -112,8 +100,7 @@
|
|||||||
"-DBUILD_WITH_QT6=ON",
|
"-DBUILD_WITH_QT6=ON",
|
||||||
"-DCMAKE_INSTALL_LIBDIR=/app/lib",
|
"-DCMAKE_INSTALL_LIBDIR=/app/lib",
|
||||||
"-DLIB_INSTALL_DIR=/app/lib",
|
"-DLIB_INSTALL_DIR=/app/lib",
|
||||||
"-DBUILD_TRANSLATIONS=NO",
|
"-DBUILD_TRANSLATIONS=NO"
|
||||||
"-DBUILD_TESTING=OFF"
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -123,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",
|
"tag": "0.9.2",
|
||||||
"disable-submodules": true
|
"disable-submodules": true
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -136,33 +123,34 @@
|
|||||||
{
|
{
|
||||||
"name": "cmark",
|
"name": "cmark",
|
||||||
"buildsystem": "cmake-ninja",
|
"buildsystem": "cmake-ninja",
|
||||||
"config-opts": [
|
"config-opts": [ "-DCMARK_TESTS=OFF" ],
|
||||||
"-DCMARK_TESTS=OFF",
|
|
||||||
"-DCMAKE_BUILD_TYPE=Release",
|
|
||||||
"-DCMAKE_INSTALL_PREFIX=/app"
|
|
||||||
],
|
|
||||||
"sources": [
|
"sources": [
|
||||||
{
|
{
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/commonmark/cmark.git"
|
"url": "https://github.com/commonmark/cmark.git"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"config-opts": [
|
||||||
|
"-DCMARK_TESTS=OFF",
|
||||||
|
"-DCMAKE_BUILD_TYPE=Release",
|
||||||
|
"-DCMAKE_INSTALL_PREFIX=/app"
|
||||||
|
],
|
||||||
"builddir": true
|
"builddir": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "kunifiedpush",
|
"name": "qcoro",
|
||||||
"buildsystem": "cmake-ninja",
|
"buildsystem": "cmake-ninja",
|
||||||
"builddir": true,
|
"config-opts": [ "-DQCORO_BUILD_EXAMPLES=OFF", "-DBUILD_TESTING=OFF" ],
|
||||||
"sources": [
|
"sources": [
|
||||||
{
|
{
|
||||||
"type": "archive",
|
"type": "archive",
|
||||||
"url": "https://download.kde.org/stable/kunifiedpush/kunifiedpush-1.0.0.tar.xz",
|
"url": "https://github.com/danvratil/qcoro/archive/refs/tags/v0.7.0.tar.gz",
|
||||||
"sha256": "2ddeba21306d0307114ec50a2c38159ec62359f9fc6cdd58da30a369fbd550cf",
|
"sha256": "23ef0217926e67c8d2eb861cf91617da2f7d8d5a9ae6c62321b21448b1669210",
|
||||||
"x-checker-data": {
|
"x-checker-data": {
|
||||||
"type": "anitya",
|
"type": "anitya",
|
||||||
"project-id": 375055,
|
"project-id": 236236,
|
||||||
"stable-only": true,
|
"stable-only": true,
|
||||||
"url-template": "https://download.kde.org/stable/kunifiedpush/kunifiedpush-$version.tar.xz"
|
"url-template": "https://github.com/danvratil/qcoro/archive/refs/tags/v$version.tar.gz"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -170,15 +158,14 @@
|
|||||||
{
|
{
|
||||||
"name": "neochat",
|
"name": "neochat",
|
||||||
"buildsystem": "cmake-ninja",
|
"buildsystem": "cmake-ninja",
|
||||||
"config-opts": [
|
|
||||||
"-DBUILD_TESTING=OFF",
|
|
||||||
"-DNEOCHAT_FLATPAK=ON"
|
|
||||||
],
|
|
||||||
"sources": [
|
"sources": [
|
||||||
{
|
{
|
||||||
"type": "dir",
|
"type": "dir",
|
||||||
"path": "."
|
"path": "."
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
"config-opts": [
|
||||||
|
"-DNEOCHAT_FLATPAK=ON"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -5,14 +5,10 @@ include:
|
|||||||
- project: sysadmin/ci-utilities
|
- project: sysadmin/ci-utilities
|
||||||
file:
|
file:
|
||||||
- /gitlab-templates/reuse-lint.yml
|
- /gitlab-templates/reuse-lint.yml
|
||||||
- /gitlab-templates/json-validation.yml
|
|
||||||
- /gitlab-templates/xml-lint.yml
|
|
||||||
- /gitlab-templates/yaml-lint.yml
|
|
||||||
- /gitlab-templates/android-qt6.yml
|
- /gitlab-templates/android-qt6.yml
|
||||||
- /gitlab-templates/linux-qt6.yml
|
- /gitlab-templates/linux-qt6.yml
|
||||||
- /gitlab-templates/linux-qt6-next.yml
|
|
||||||
- /gitlab-templates/windows-qt6.yml
|
- /gitlab-templates/windows-qt6.yml
|
||||||
- /gitlab-templates/freebsd-qt6.yml
|
# - /gitlab-templates/freebsd-qt6.yml
|
||||||
- /gitlab-templates/flatpak.yml
|
- /gitlab-templates/flatpak.yml
|
||||||
- /gitlab-templates/snap-snapcraft-lxd.yml
|
- /gitlab-templates/snap-snapcraft-lxd.yml
|
||||||
- /gitlab-templates/craft-android-qt6-apks.yml
|
- /gitlab-templates/craft-android-qt6-apks.yml
|
||||||
|
|||||||
73
.kde-ci.yml
73
.kde-ci.yml
@@ -2,44 +2,43 @@
|
|||||||
# SPDX-License-Identifier: BSD-2-Clause
|
# SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
Dependencies:
|
Dependencies:
|
||||||
- 'on': ['Linux', 'Android', 'FreeBSD', 'Windows']
|
- 'on': ['Linux', 'Android', 'FreeBSD', 'Windows']
|
||||||
'require':
|
'require':
|
||||||
'frameworks/extra-cmake-modules': '@latest-kf6'
|
'frameworks/extra-cmake-modules': '@latest-kf6'
|
||||||
'frameworks/kcoreaddons': '@latest-kf6'
|
'frameworks/kcoreaddons': '@latest-kf6'
|
||||||
'frameworks/kirigami': '@latest-kf6'
|
'frameworks/kirigami': '@latest-kf6'
|
||||||
'frameworks/ki18n': '@latest-kf6'
|
'frameworks/ki18n': '@latest-kf6'
|
||||||
'frameworks/kconfig': '@latest-kf6'
|
'frameworks/kconfig': '@latest-kf6'
|
||||||
'frameworks/syntax-highlighting': '@latest-kf6'
|
'frameworks/syntax-highlighting': '@latest-kf6'
|
||||||
'frameworks/kitemmodels': '@latest-kf6'
|
'frameworks/kitemmodels': '@latest-kf6'
|
||||||
'frameworks/kquickcharts': '@latest-kf6'
|
'frameworks/kquickcharts': '@latest-kf6'
|
||||||
'frameworks/knotifications': '@latest-kf6'
|
'frameworks/knotifications': '@latest-kf6'
|
||||||
'frameworks/kcolorscheme': '@latest-kf6'
|
'frameworks/kcolorscheme': '@latest-kf6'
|
||||||
'frameworks/kiconthemes': '@latest-kf6'
|
'frameworks/kiconthemes': '@latest-kf6'
|
||||||
'libraries/kquickimageeditor': '@latest-kf6'
|
'libraries/kquickimageeditor': '@latest-kf6'
|
||||||
'frameworks/sonnet': '@latest-kf6'
|
'frameworks/sonnet': '@latest-kf6'
|
||||||
'frameworks/prison': '@latest-kf6'
|
'frameworks/prison': '@latest-kf6'
|
||||||
'libraries/kirigami-addons': '@latest-kf6'
|
'libraries/kirigami-addons': '@latest-kf6'
|
||||||
'third-party/libquotient': '@latest'
|
'third-party/libquotient': '@latest'
|
||||||
'third-party/qtkeychain': '@latest'
|
'third-party/qtkeychain': '@latest'
|
||||||
'third-party/cmark': '@latest'
|
'third-party/cmark': '@latest'
|
||||||
'third-party/qcoro': '@latest'
|
'third-party/qcoro': '@latest'
|
||||||
- 'on': ['Windows', 'Linux', 'FreeBSD']
|
- 'on': ['Windows', 'Linux', 'FreeBSD']
|
||||||
'require':
|
'require':
|
||||||
'frameworks/qqc2-desktop-style': '@latest-kf6'
|
'frameworks/qqc2-desktop-style': '@latest-kf6'
|
||||||
'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'
|
'frameworks/kcrash': '@latest-kf6'
|
||||||
- 'on': ['Linux', 'FreeBSD']
|
- 'on': ['Linux', 'FreeBSD']
|
||||||
'require':
|
'require':
|
||||||
'frameworks/kdbusaddons': '@latest-kf6'
|
'frameworks/kdbusaddons': '@latest-kf6'
|
||||||
'frameworks/purpose': '@latest-kf6'
|
'frameworks/purpose': '@latest-kf6'
|
||||||
'libraries/kunifiedpush': '@latest-kf6'
|
|
||||||
|
|
||||||
- 'on': ['Linux']
|
- 'on': ['Linux']
|
||||||
'require':
|
'require':
|
||||||
'sdk/selenium-webdriver-at-spi': '@latest-kf6'
|
'sdk/selenium-webdriver-at-spi': '@latest-kf6'
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
per-test-timeout: 90
|
per-test-timeout: 90
|
||||||
require-passing-tests-on: ['Linux', 'Android', 'FreeBSD', 'Windows']
|
require-passing-tests-on: [ 'Linux', 'Android', 'FreeBSD' ]
|
||||||
|
|||||||
55
.reuse/dep5
Normal file
55
.reuse/dep5
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||||
|
Upstream-Name: NeoChat
|
||||||
|
Upstream-Contact: Carl Schwan <carlschwan@kde.org>
|
||||||
|
|
||||||
|
Files: 128-logo.png icons/* logo.png org.kde.neochat.svg org.kde.neochat.tray.svg android/res/drawable/neochat.png
|
||||||
|
Copyright: 2020 Carson Black <uhhadd@gmail.com>
|
||||||
|
License: LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
|
||||||
|
|
||||||
|
Files: android/res/drawable/splash.xml
|
||||||
|
Copyright: 2020 Tobias Fella <tobias.fella@kde.org>
|
||||||
|
License: BSD-2-Clause
|
||||||
|
|
||||||
|
Files: .gitignore
|
||||||
|
Copyright: None
|
||||||
|
License: CC0-1.0
|
||||||
|
|
||||||
|
Files: .gitlab/issue_templates/bug.md
|
||||||
|
Copyright: 2021 Carl Schwan <carlschwan@kde.org>
|
||||||
|
License: CC0-1.0
|
||||||
|
|
||||||
|
Files: src/res.qrc src/res_android.qrc src/res_desktop.qrc
|
||||||
|
Copyright: None
|
||||||
|
License: CC0-1.0
|
||||||
|
|
||||||
|
Files: cmake/Flatpak/99-noto-mono-color-emoji.conf
|
||||||
|
Copyright: 2021 Carl Schwan <carlschwan@kde.org>
|
||||||
|
License: BSD-2-Clause
|
||||||
|
|
||||||
|
Files: src/neochatconfig.kcfg
|
||||||
|
Copyright: 2020-2021 Carl Schwan <carlschwan@kde.org>, Tobias Fella <tobias.fella@kde.org>
|
||||||
|
License: BSD-2-Clause
|
||||||
|
|
||||||
|
Files: src/neochat.notifyrc
|
||||||
|
Copyright: 2020 Tobias Fella <tobias.fella@kde.org>
|
||||||
|
License: BSD-2-Clause
|
||||||
|
|
||||||
|
Files: src/qml/confetti.png src/qml/glowdot.png
|
||||||
|
Copyright: 2021 Alexey Andreyev <aa13q@ya.ru>
|
||||||
|
License: CC0-1.0
|
||||||
|
|
||||||
|
Files: .flatpak-manifest.json
|
||||||
|
Copyright: 2020-2022 Tobias Fella <tobias.fella@kde.org>
|
||||||
|
License: BSD-2-Clause
|
||||||
|
|
||||||
|
Files: autotests/data/*
|
||||||
|
Copyright: none
|
||||||
|
License: CC0-1.0
|
||||||
|
|
||||||
|
Files: appiumtests/data/*
|
||||||
|
Copyright: 2023 Tobias Fella <tobias.fella@kde.org>
|
||||||
|
License: CC0-1.0
|
||||||
|
|
||||||
|
Files: src/purpose/purposeplugin.json
|
||||||
|
Copyright: 2023 Tobias Fella <tobias.fella@kde.org>
|
||||||
|
License: BSD-2-Clause
|
||||||
@@ -7,14 +7,14 @@
|
|||||||
cmake_minimum_required(VERSION 3.16)
|
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 "25")
|
set(RELEASE_SERVICE_VERSION_MAJOR "24")
|
||||||
set(RELEASE_SERVICE_VERSION_MINOR "11")
|
set(RELEASE_SERVICE_VERSION_MINOR "12")
|
||||||
set(RELEASE_SERVICE_VERSION_MICRO "70")
|
set(RELEASE_SERVICE_VERSION_MICRO "3")
|
||||||
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})
|
||||||
|
|
||||||
set(KF_MIN_VERSION "6.12")
|
set(KF_MIN_VERSION "6.6")
|
||||||
set(QT_MIN_VERSION "6.5")
|
set(QT_MIN_VERSION "6.5")
|
||||||
|
|
||||||
find_package(ECM ${KF_MIN_VERSION} REQUIRED NO_MODULE)
|
find_package(ECM ${KF_MIN_VERSION} REQUIRED NO_MODULE)
|
||||||
@@ -56,7 +56,7 @@ ecm_setup_version(${PROJECT_VERSION}
|
|||||||
VERSION_HEADER ${CMAKE_CURRENT_BINARY_DIR}/neochat-version.h
|
VERSION_HEADER ${CMAKE_CURRENT_BINARY_DIR}/neochat-version.h
|
||||||
)
|
)
|
||||||
|
|
||||||
find_package(Qt6 ${QT_MIN_VERSION} NO_MODULE COMPONENTS Core Quick Gui QuickControls2 Multimedia Svg TextToSpeech WebView)
|
find_package(Qt6 ${QT_MIN_VERSION} NO_MODULE COMPONENTS Core Quick Gui QuickControls2 Multimedia Svg WebView)
|
||||||
set_package_properties(Qt6 PROPERTIES
|
set_package_properties(Qt6 PROPERTIES
|
||||||
TYPE REQUIRED
|
TYPE REQUIRED
|
||||||
PURPOSE "Basic application components"
|
PURPOSE "Basic application components"
|
||||||
@@ -75,7 +75,7 @@ set_package_properties(KF6Kirigami PROPERTIES
|
|||||||
TYPE REQUIRED
|
TYPE REQUIRED
|
||||||
PURPOSE "Kirigami application UI framework"
|
PURPOSE "Kirigami application UI framework"
|
||||||
)
|
)
|
||||||
find_package(KF6KirigamiAddons 1.6.0 REQUIRED)
|
find_package(KF6KirigamiAddons 0.7.2 REQUIRED)
|
||||||
|
|
||||||
if (UNIX AND NOT APPLE AND NOT ANDROID AND NOT NEOCHAT_FLATPAK AND NOT NEOCHAT_APPIMAGE)
|
if (UNIX AND NOT APPLE AND NOT ANDROID AND NOT NEOCHAT_FLATPAK AND NOT NEOCHAT_APPIMAGE)
|
||||||
find_package(KF6 ${KF_MIN_VERSION} REQUIRED COMPONENTS Purpose)
|
find_package(KF6 ${KF_MIN_VERSION} REQUIRED COMPONENTS Purpose)
|
||||||
@@ -107,7 +107,7 @@ if (NOT ANDROID AND NOT WIN32 AND NOT APPLE AND NOT HAIKU)
|
|||||||
find_package(KF6DBusAddons ${KF_MIN_VERSION} REQUIRED)
|
find_package(KF6DBusAddons ${KF_MIN_VERSION} REQUIRED)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
find_package(QuotientQt6 0.9.1)
|
find_package(QuotientQt6 0.9)
|
||||||
set_package_properties(QuotientQt6 PROPERTIES
|
set_package_properties(QuotientQt6 PROPERTIES
|
||||||
TYPE REQUIRED
|
TYPE REQUIRED
|
||||||
DESCRIPTION "Qt wrapper around Matrix API"
|
DESCRIPTION "Qt wrapper around Matrix API"
|
||||||
@@ -147,24 +147,16 @@ set_package_properties(KF6DocTools PROPERTIES DESCRIPTION
|
|||||||
TYPE OPTIONAL
|
TYPE OPTIONAL
|
||||||
)
|
)
|
||||||
|
|
||||||
option(WITH_UNIFIEDPUSH "Build with KUnifiedPush support" ON)
|
find_package(KUnifiedPush QUIET)
|
||||||
|
set_package_properties(KUnifiedPush PROPERTIES
|
||||||
if (ANDROID OR APPLE OR WIN32 OR HAIKU)
|
TYPE OPTIONAL
|
||||||
set(WITH_UNIFIEDPUSH OFF)
|
PURPOSE "Push notification support"
|
||||||
endif()
|
URL "https://invent.kde.org/libraries/kunifiedpush"
|
||||||
|
)
|
||||||
if (WITH_UNIFIEDPUSH)
|
|
||||||
find_package(KUnifiedPush)
|
|
||||||
set_package_properties(KUnifiedPush PROPERTIES
|
|
||||||
TYPE REQUIRED
|
|
||||||
PURPOSE "Push notification support"
|
|
||||||
URL "https://invent.kde.org/libraries/kunifiedpush"
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(ANDROID)
|
if(ANDROID)
|
||||||
find_package(Sqlite3)
|
find_package(Sqlite3)
|
||||||
set(BUILD_TESTING FALSE)
|
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/android/version.gradle.in ${CMAKE_BINARY_DIR}/version.gradle)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
ki18n_install(po)
|
ki18n_install(po)
|
||||||
@@ -179,12 +171,9 @@ add_definitions(-DQT_NO_FOREACH)
|
|||||||
add_subdirectory(src)
|
add_subdirectory(src)
|
||||||
|
|
||||||
if (BUILD_TESTING)
|
if (BUILD_TESTING)
|
||||||
find_package(Qt6 ${QT_MIN_VERSION} NO_MODULE COMPONENTS Test HttpServer)
|
find_package(Qt6 ${QT_MIN_VERSION} NO_MODULE COMPONENTS Test)
|
||||||
add_subdirectory(autotests)
|
add_subdirectory(autotests)
|
||||||
# add_subdirectory(appiumtests)
|
add_subdirectory(appiumtests)
|
||||||
if (NOT ANDROID)
|
|
||||||
add_subdirectory(memorytests)
|
|
||||||
endif()
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(KF6DocTools_FOUND)
|
if(KF6DocTools_FOUND)
|
||||||
@@ -192,7 +181,7 @@ if(KF6DocTools_FOUND)
|
|||||||
add_subdirectory(doc)
|
add_subdirectory(doc)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES)
|
feature_summary(WHAT ALL INCLUDE_QUIET_PACKAGES FATAL_ON_MISSING_REQUIRED_PACKAGES)
|
||||||
|
|
||||||
if (NOT ANDROID)
|
if (NOT ANDROID)
|
||||||
file(GLOB_RECURSE ALL_CLANG_FORMAT_SOURCE_FILES src/*.cpp src/*.h)
|
file(GLOB_RECURSE ALL_CLANG_FORMAT_SOURCE_FILES src/*.cpp src/*.h)
|
||||||
|
|||||||
90
REUSE.toml
90
REUSE.toml
@@ -1,90 +0,0 @@
|
|||||||
# SPDX-FileCopyrightText: none
|
|
||||||
# SPDX-License-Identifier: CC0-1.0
|
|
||||||
|
|
||||||
version = 1
|
|
||||||
SPDX-PackageName = "NeoChat"
|
|
||||||
SPDX-PackageSupplier = "Carl Schwan <carlschwan@kde.org>"
|
|
||||||
|
|
||||||
[[annotations]]
|
|
||||||
path = ["128-logo.png", "icons/**", "logo.png", "org.kde.neochat.svg", "org.kde.neochat.tray.svg", "android/res/drawable/neochat.png", "android/neochat-playstore.png"]
|
|
||||||
precedence = "aggregate"
|
|
||||||
SPDX-FileCopyrightText = "2020 Carson Black <uhhadd@gmail.com>"
|
|
||||||
SPDX-License-Identifier = "LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL"
|
|
||||||
|
|
||||||
[[annotations]]
|
|
||||||
path = "android/res/drawable/splash.xml"
|
|
||||||
precedence = "aggregate"
|
|
||||||
SPDX-FileCopyrightText = "2020 Tobias Fella <tobias.fella@kde.org>"
|
|
||||||
SPDX-License-Identifier = "BSD-2-Clause"
|
|
||||||
|
|
||||||
[[annotations]]
|
|
||||||
path = ".gitignore"
|
|
||||||
precedence = "aggregate"
|
|
||||||
SPDX-FileCopyrightText = "None"
|
|
||||||
SPDX-License-Identifier = "CC0-1.0"
|
|
||||||
|
|
||||||
[[annotations]]
|
|
||||||
path = ".gitlab/issue_templates/bug.md"
|
|
||||||
precedence = "aggregate"
|
|
||||||
SPDX-FileCopyrightText = "2021 Carl Schwan <carlschwan@kde.org>"
|
|
||||||
SPDX-License-Identifier = "CC0-1.0"
|
|
||||||
|
|
||||||
[[annotations]]
|
|
||||||
path = ["src/res.qrc", "src/res_android.qrc", "src/res_desktop.qrc"]
|
|
||||||
precedence = "aggregate"
|
|
||||||
SPDX-FileCopyrightText = "None"
|
|
||||||
SPDX-License-Identifier = "CC0-1.0"
|
|
||||||
|
|
||||||
[[annotations]]
|
|
||||||
path = "cmake/Flatpak/99-noto-mono-color-emoji.conf"
|
|
||||||
precedence = "aggregate"
|
|
||||||
SPDX-FileCopyrightText = "2021 Carl Schwan <carlschwan@kde.org>"
|
|
||||||
SPDX-License-Identifier = "BSD-2-Clause"
|
|
||||||
|
|
||||||
[[annotations]]
|
|
||||||
path = "src/app/neochatconfig.kcfg"
|
|
||||||
precedence = "aggregate"
|
|
||||||
SPDX-FileCopyrightText = "2020-2021 Carl Schwan <carlschwan@kde.org>, Tobias Fella <tobias.fella@kde.org>"
|
|
||||||
SPDX-License-Identifier = "BSD-2-Clause"
|
|
||||||
|
|
||||||
[[annotations]]
|
|
||||||
path = "src/app/neochat.notifyrc"
|
|
||||||
precedence = "aggregate"
|
|
||||||
SPDX-FileCopyrightText = "2020 Tobias Fella <tobias.fella@kde.org>"
|
|
||||||
SPDX-License-Identifier = "BSD-2-Clause"
|
|
||||||
|
|
||||||
[[annotations]]
|
|
||||||
path = ["src/qml/confetti.png", "src/qml/glowdot.png"]
|
|
||||||
precedence = "aggregate"
|
|
||||||
SPDX-FileCopyrightText = "2021 Alexey Andreyev <aa13q@ya.ru>"
|
|
||||||
SPDX-License-Identifier = "CC0-1.0"
|
|
||||||
|
|
||||||
[[annotations]]
|
|
||||||
path = ".flatpak-manifest.json"
|
|
||||||
precedence = "aggregate"
|
|
||||||
SPDX-FileCopyrightText = "2020-2022 Tobias Fella <tobias.fella@kde.org>"
|
|
||||||
SPDX-License-Identifier = "BSD-2-Clause"
|
|
||||||
|
|
||||||
[[annotations]]
|
|
||||||
path = "autotests/data/**"
|
|
||||||
precedence = "aggregate"
|
|
||||||
SPDX-FileCopyrightText = "none"
|
|
||||||
SPDX-License-Identifier = "CC0-1.0"
|
|
||||||
|
|
||||||
[[annotations]]
|
|
||||||
path = "appiumtests/data/**"
|
|
||||||
precedence = "aggregate"
|
|
||||||
SPDX-FileCopyrightText = "2023 Tobias Fella <tobias.fella@kde.org>"
|
|
||||||
SPDX-License-Identifier = "CC0-1.0"
|
|
||||||
|
|
||||||
[[annotations]]
|
|
||||||
path = "src/purpose/purposeplugin.json"
|
|
||||||
precedence = "aggregate"
|
|
||||||
SPDX-FileCopyrightText = "2023 Tobias Fella <tobias.fella@kde.org>"
|
|
||||||
SPDX-License-Identifier = "BSD-2-Clause"
|
|
||||||
|
|
||||||
[[annotations]]
|
|
||||||
path = "memorytests/memtest-sync.json"
|
|
||||||
precedence = "aggregate"
|
|
||||||
SPDX-FileCopyrightText = "2024 James Graham <james.h.graham@protonmail.com>"
|
|
||||||
SPDX-License-Identifier = "BSD-2-Clause"
|
|
||||||
@@ -23,7 +23,8 @@ repositories {
|
|||||||
|
|
||||||
|
|
||||||
apply plugin: 'com.android.application'
|
apply plugin: 'com.android.application'
|
||||||
apply from: '../ecm-version.gradle'
|
apply from: '../version.gradle'
|
||||||
|
def timestamp = (int)(new Date().getTime()/1000)
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
|
implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
|
||||||
@@ -78,9 +79,9 @@ android {
|
|||||||
targetSdkVersion qtTargetSdkVersion
|
targetSdkVersion qtTargetSdkVersion
|
||||||
applicationId "org.kde.neochat"
|
applicationId "org.kde.neochat"
|
||||||
namespace "org.kde.neochat"
|
namespace "org.kde.neochat"
|
||||||
versionCode ecmVersionCode
|
versionCode timestamp
|
||||||
versionName ecmVersionName
|
versionName projectVersionFull
|
||||||
manifestPlaceholders = [versionName: ecmVersionName, versionCode: ecmVersionCode]
|
manifestPlaceholders = [versionName: projectVersionFull, versionCode: timestamp]
|
||||||
}
|
}
|
||||||
|
|
||||||
packagingOptions {
|
packagingOptions {
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 23 KiB |
6
android/version.gradle.in
Normal file
6
android/version.gradle.in
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
// SPDX-FileCopyrightText: 2021 Volker Krause <vkrause@kde.org>
|
||||||
|
// SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
|
||||||
|
ext {
|
||||||
|
projectVersionFull = "@NEOCHAT_VERSION@"
|
||||||
|
}
|
||||||
@@ -83,15 +83,6 @@ def create_room():
|
|||||||
next_sync_payload = "sync_response_new_room"
|
next_sync_payload = "sync_response_new_room"
|
||||||
return response
|
return response
|
||||||
|
|
||||||
@app.route("/_matrix/client/v3/publicRooms", methods=["POST"])
|
|
||||||
def public_rooms():
|
|
||||||
if request.get_json()["filter"]["generic_search_term"] == "forbidden":
|
|
||||||
data = dict()
|
|
||||||
data["errcode"] = "M_FORBIDDEN"
|
|
||||||
data["error"] = "You are not allowed to search for this. Go to https://wikipedia.org for more information"
|
|
||||||
return data, 403
|
|
||||||
return dict()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
@@ -3,10 +3,6 @@
|
|||||||
|
|
||||||
enable_testing()
|
enable_testing()
|
||||||
|
|
||||||
add_library(neochat_server STATIC server.cpp)
|
|
||||||
|
|
||||||
target_link_libraries(neochat_server PUBLIC Qt::HttpServer QuotientQt6)
|
|
||||||
|
|
||||||
add_definitions(-DDATA_DIR="${CMAKE_CURRENT_SOURCE_DIR}/data" )
|
add_definitions(-DDATA_DIR="${CMAKE_CURRENT_SOURCE_DIR}/data" )
|
||||||
|
|
||||||
ecm_add_test(
|
ecm_add_test(
|
||||||
@@ -15,11 +11,11 @@ ecm_add_test(
|
|||||||
TEST_NAME neochatroomtest
|
TEST_NAME neochatroomtest
|
||||||
)
|
)
|
||||||
|
|
||||||
ecm_add_test(
|
# ecm_add_test(
|
||||||
texthandlertest.cpp
|
# texthandlertest.cpp
|
||||||
LINK_LIBRARIES neochat Qt::Test
|
# LINK_LIBRARIES neochat Qt::Test
|
||||||
TEST_NAME texthandlertest
|
# TEST_NAME texthandlertest
|
||||||
)
|
# )
|
||||||
|
|
||||||
ecm_add_test(
|
ecm_add_test(
|
||||||
delegatesizehelpertest.cpp
|
delegatesizehelpertest.cpp
|
||||||
@@ -52,9 +48,9 @@ ecm_add_test(
|
|||||||
)
|
)
|
||||||
|
|
||||||
ecm_add_test(
|
ecm_add_test(
|
||||||
timelinemessagemodeltest.cpp
|
messageeventmodeltest.cpp
|
||||||
LINK_LIBRARIES neochat Qt::Test
|
LINK_LIBRARIES neochat Qt::Test
|
||||||
TEST_NAME timelinemessagemodeltest
|
TEST_NAME messageeventmodeltest
|
||||||
)
|
)
|
||||||
|
|
||||||
ecm_add_test(
|
ecm_add_test(
|
||||||
@@ -86,9 +82,3 @@ ecm_add_test(
|
|||||||
LINK_LIBRARIES neochat Qt::Test
|
LINK_LIBRARIES neochat Qt::Test
|
||||||
TEST_NAME messagecontentmodeltest
|
TEST_NAME messagecontentmodeltest
|
||||||
)
|
)
|
||||||
|
|
||||||
ecm_add_test(
|
|
||||||
actionstest.cpp
|
|
||||||
LINK_LIBRARIES neochat Qt::Test neochat_server
|
|
||||||
TEST_NAME actionstest
|
|
||||||
)
|
|
||||||
|
|||||||
@@ -1,151 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: 2024 Tobias Fella <tobias.fella@kde.org>
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <QTest>
|
|
||||||
#include <QSignalSpy>
|
|
||||||
#include <QVariantList>
|
|
||||||
|
|
||||||
#include "accountmanager.h"
|
|
||||||
#include "chatbarcache.h"
|
|
||||||
#include "models/actionsmodel.h"
|
|
||||||
|
|
||||||
#include "server.h"
|
|
||||||
#include "testutils.h"
|
|
||||||
|
|
||||||
using namespace Quotient;
|
|
||||||
|
|
||||||
//TODO: rainbow, rainbowme, plain, spoiler, me, join, knock, j, part, leave, nick, roomnick, myroomnick, ignore, unignore, react, ban, unban, kick
|
|
||||||
|
|
||||||
class ActionsTest : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
private:
|
|
||||||
Connection *connection = nullptr;
|
|
||||||
NeoChatRoom *room = nullptr;
|
|
||||||
|
|
||||||
void expectMessage(const QString &actionName, const QString &args, MessageType::Type type, const QString &message);
|
|
||||||
|
|
||||||
Server server;
|
|
||||||
|
|
||||||
private Q_SLOTS:
|
|
||||||
void initTestCase();
|
|
||||||
void testActions();
|
|
||||||
void testActions_data();
|
|
||||||
void testInvite();
|
|
||||||
};
|
|
||||||
|
|
||||||
void ActionsTest::initTestCase()
|
|
||||||
{
|
|
||||||
Connection::setRoomType<NeoChatRoom>();
|
|
||||||
server.start();
|
|
||||||
KLocalizedString::setApplicationDomain(QByteArrayLiteral("neochat"));
|
|
||||||
auto accountManager = new AccountManager(true);
|
|
||||||
QSignalSpy spy(accountManager, &AccountManager::connectionAdded);
|
|
||||||
connection = accountManager->accounts()->front();
|
|
||||||
auto roomId = server.createRoom(u"@user:localhost:1234"_s);
|
|
||||||
server.inviteUser(roomId, u"@invited:example.com"_s);
|
|
||||||
server.banUser(roomId, u"@banned:example.com"_s);
|
|
||||||
server.joinUser(roomId, u"@example:example.com"_s);
|
|
||||||
|
|
||||||
QSignalSpy syncSpy(connection, &Connection::syncDone);
|
|
||||||
// We need to wait for two syncs, as the next one won't have the changes yet
|
|
||||||
QVERIFY(syncSpy.wait());
|
|
||||||
QVERIFY(syncSpy.wait());
|
|
||||||
room = dynamic_cast<NeoChatRoom *>(connection->room(roomId));
|
|
||||||
QVERIFY(room);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionsTest::testActions_data()
|
|
||||||
{
|
|
||||||
QTest::addColumn<QString>("command");
|
|
||||||
QTest::addColumn<std::optional<QString>>("resultText");
|
|
||||||
QTest::addColumn<std::optional<Quotient::RoomMessageEvent::MsgType>>("type");
|
|
||||||
|
|
||||||
QTest::newRow("shrug") << u"/shrug Hello"_s << std::make_optional(u"¯\\\\_(ツ)_/¯ Hello"_s)
|
|
||||||
<< std::make_optional(Quotient::RoomMessageEvent::MsgType::Text);
|
|
||||||
QTest::newRow("lenny") << u"/lenny Hello"_s << std::make_optional(u"( ͡° ͜ʖ ͡°) Hello"_s) << std::make_optional(Quotient::RoomMessageEvent::MsgType::Text);
|
|
||||||
QTest::newRow("tableflip") << u"/tableflip Hello"_s << std::make_optional(u"(╯°□°)╯︵ ┻━┻ Hello"_s)
|
|
||||||
<< std::make_optional(Quotient::RoomMessageEvent::MsgType::Text);
|
|
||||||
QTest::newRow("unflip") << u"/unflip Hello"_s << std::make_optional(u"┬──┬ ノ( ゜-゜ノ) Hello"_s)
|
|
||||||
<< std::make_optional(Quotient::RoomMessageEvent::MsgType::Text);
|
|
||||||
QTest::newRow("rainbow") << u"/rainbow Hello"_s << std::optional<QString>() << std::optional<Quotient::RoomMessageEvent::MsgType>();
|
|
||||||
QTest::newRow("rainbowme") << u"/rainbowme Hello"_s << std::optional<QString>() << std::optional<Quotient::RoomMessageEvent::MsgType>();
|
|
||||||
QTest::newRow("plain") << u"/plain <b>Hello</b>"_s << std::optional<QString>() << std::optional<Quotient::RoomMessageEvent::MsgType>();
|
|
||||||
QTest::newRow("spoiler") << u"/spoiler Hello"_s << std::optional<QString>() << std::optional<Quotient::RoomMessageEvent::MsgType>();
|
|
||||||
QTest::newRow("me") << u"/me Hello"_s << std::make_optional(u"Hello"_s) << std::make_optional(Quotient::RoomMessageEvent::MsgType::Emote);
|
|
||||||
QTest::newRow("notice") << u"/notice Hello"_s << std::make_optional(u"Hello"_s) << std::make_optional(Quotient::RoomMessageEvent::MsgType::Notice);
|
|
||||||
QTest::newRow("message") << u"Hello"_s << std::make_optional(u"Hello"_s) << std::make_optional(Quotient::RoomMessageEvent::MsgType::Text);
|
|
||||||
QTest::newRow("invite") << u"/invite @foo:example.com"_s << std::optional<QString>() << std::optional<Quotient::RoomMessageEvent::MsgType>();
|
|
||||||
|
|
||||||
//TODO: join, knock, j, part, leave, nick, roomnick, myroomnick, ignore, unignore, react, ban, unban, kick
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionsTest::testActions()
|
|
||||||
{
|
|
||||||
QFETCH(QString, command);
|
|
||||||
QFETCH(std::optional<QString>, resultText);
|
|
||||||
QFETCH(std::optional<Quotient::RoomMessageEvent::MsgType>, type);
|
|
||||||
|
|
||||||
auto cache = new ChatBarCache();
|
|
||||||
cache->setText(command);
|
|
||||||
auto result = ActionsModel::handleAction(room, cache);
|
|
||||||
QCOMPARE(resultText, std::get<std::optional<QString>>(result));
|
|
||||||
QCOMPARE(type, std::get<std::optional<Quotient::RoomMessageEvent::MsgType>>(result));
|
|
||||||
}
|
|
||||||
|
|
||||||
static ActionsModel::Action findAction(const QString &name)
|
|
||||||
{
|
|
||||||
for (const auto &action : ActionsModel::allActions()) {
|
|
||||||
if (action.prefix == name) {
|
|
||||||
return action;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionsTest::expectMessage(const QString &actionName, const QString &args, MessageType::Type type, const QString &message)
|
|
||||||
{
|
|
||||||
auto action = findAction(actionName);
|
|
||||||
QSignalSpy spy(room, &NeoChatRoom::showMessage);
|
|
||||||
auto result = action.handle(args, room, nullptr);
|
|
||||||
auto expected = QVariantList {type, message};
|
|
||||||
auto signal = spy.takeFirst();
|
|
||||||
QCOMPARE(signal, expected);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionsTest::testInvite()
|
|
||||||
{
|
|
||||||
expectMessage(u"invite"_s, u"foo"_s, MessageType::Error, u"'foo' does not look like a matrix id."_s);
|
|
||||||
expectMessage(u"invite"_s, u"@invited:example.com"_s, MessageType::Information, u"@invited:example.com is already invited to this room."_s);
|
|
||||||
QCOMPARE(room->memberState(u"@invited:example.com"_s), Membership::Invite);
|
|
||||||
expectMessage(u"invite"_s, u"@banned:example.com"_s, MessageType::Information, u"@banned:example.com is banned from this room."_s);
|
|
||||||
QCOMPARE(room->memberState(u"@banned:example.com"_s), Membership::Ban);
|
|
||||||
expectMessage(u"invite"_s, connection->userId(), MessageType::Positive, u"You are already in this room."_s);
|
|
||||||
QCOMPARE(room->memberState(connection->userId()), Membership::Join);
|
|
||||||
expectMessage(u"invite"_s, u"@example:example.com"_s, MessageType::Information, u"@example:example.com is already in this room."_s);
|
|
||||||
QCOMPARE(room->memberState(u"@example:example.com"_s), Membership::Join);
|
|
||||||
|
|
||||||
QCOMPARE(room->memberState(u"@user:example.com"_s), Membership::Leave);
|
|
||||||
expectMessage(u"invite"_s, u"@user:example.com"_s, MessageType::Positive, u"@user:example.com was invited into this room."_s);
|
|
||||||
|
|
||||||
QSignalSpy spy(room, &NeoChatRoom::changed);
|
|
||||||
QVERIFY(spy.wait());
|
|
||||||
|
|
||||||
auto tries = 0;
|
|
||||||
|
|
||||||
while (room->memberState(u"@user:example.com"_s) != Membership::Invite) {
|
|
||||||
QVERIFY(spy.wait());
|
|
||||||
tries += 1;
|
|
||||||
if (tries > 3) {
|
|
||||||
QVERIFY(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QCOMPARE(room->memberState(u"@user:example.com"_s), Membership::Invite);
|
|
||||||
}
|
|
||||||
|
|
||||||
QTEST_MAIN(ActionsTest)
|
|
||||||
#include "actionstest.moc"
|
|
||||||
@@ -38,8 +38,8 @@ private Q_SLOTS:
|
|||||||
|
|
||||||
void ChatBarCacheTest::initTestCase()
|
void ChatBarCacheTest::initTestCase()
|
||||||
{
|
{
|
||||||
connection = Connection::makeMockConnection(u"@bob:kde.org"_s);
|
connection = Connection::makeMockConnection(QStringLiteral("@bob:kde.org"));
|
||||||
room = new TestUtils::TestRoom(connection, u"#myroom:kde.org"_s, "test-min-sync.json"_L1);
|
room = new TestUtils::TestRoom(connection, QStringLiteral("#myroom:kde.org"), QLatin1String("test-min-sync.json"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatBarCacheTest::empty()
|
void ChatBarCacheTest::empty()
|
||||||
@@ -59,7 +59,7 @@ void ChatBarCacheTest::empty()
|
|||||||
void ChatBarCacheTest::noRoom()
|
void ChatBarCacheTest::noRoom()
|
||||||
{
|
{
|
||||||
QScopedPointer<ChatBarCache> chatBarCache(new ChatBarCache());
|
QScopedPointer<ChatBarCache> chatBarCache(new ChatBarCache());
|
||||||
chatBarCache->setReplyId(u"$153456789:example.org"_s);
|
chatBarCache->setReplyId(QLatin1String("$153456789:example.org"));
|
||||||
|
|
||||||
// These should return empty even though a reply ID has been set because the
|
// These should return empty even though a reply ID has been set because the
|
||||||
// ChatBarCache has no parent.
|
// ChatBarCache has no parent.
|
||||||
@@ -75,7 +75,7 @@ void ChatBarCacheTest::badParent()
|
|||||||
{
|
{
|
||||||
QScopedPointer<QObject> badParent(new QObject());
|
QScopedPointer<QObject> badParent(new QObject());
|
||||||
QScopedPointer<ChatBarCache> chatBarCache(new ChatBarCache(badParent.get()));
|
QScopedPointer<ChatBarCache> chatBarCache(new ChatBarCache(badParent.get()));
|
||||||
chatBarCache->setReplyId(u"$153456789:example.org"_s);
|
chatBarCache->setReplyId(QLatin1String("$153456789:example.org"));
|
||||||
|
|
||||||
// These should return empty even though a reply ID has been set because the
|
// These should return empty even though a reply ID has been set because the
|
||||||
// ChatBarCache has no parent.
|
// ChatBarCache has no parent.
|
||||||
@@ -90,17 +90,17 @@ void ChatBarCacheTest::badParent()
|
|||||||
void ChatBarCacheTest::reply()
|
void ChatBarCacheTest::reply()
|
||||||
{
|
{
|
||||||
QScopedPointer<ChatBarCache> chatBarCache(new ChatBarCache(room));
|
QScopedPointer<ChatBarCache> chatBarCache(new ChatBarCache(room));
|
||||||
chatBarCache->setText(u"some text"_s);
|
chatBarCache->setText(QLatin1String("some text"));
|
||||||
chatBarCache->setAttachmentPath(u"some/path"_s);
|
chatBarCache->setAttachmentPath(QLatin1String("some/path"));
|
||||||
chatBarCache->setReplyId(u"$153456789:example.org"_s);
|
chatBarCache->setReplyId(QLatin1String("$153456789:example.org"));
|
||||||
|
|
||||||
QCOMPARE(chatBarCache->text(), u"some text"_s);
|
QCOMPARE(chatBarCache->text(), QLatin1String("some text"));
|
||||||
QCOMPARE(chatBarCache->isReplying(), true);
|
QCOMPARE(chatBarCache->isReplying(), true);
|
||||||
QCOMPARE(chatBarCache->replyId(), u"$153456789:example.org"_s);
|
QCOMPARE(chatBarCache->replyId(), QLatin1String("$153456789:example.org"));
|
||||||
QCOMPARE(chatBarCache->isEditing(), false);
|
QCOMPARE(chatBarCache->isEditing(), false);
|
||||||
QCOMPARE(chatBarCache->editId(), QString());
|
QCOMPARE(chatBarCache->editId(), QString());
|
||||||
QCOMPARE(chatBarCache->relationAuthor(), room->member(u"@example:example.org"_s));
|
QCOMPARE(chatBarCache->relationAuthor(), room->member(QLatin1String("@example:example.org")));
|
||||||
QCOMPARE(chatBarCache->relationMessage(), u"This is an example\ntext message"_s);
|
QCOMPARE(chatBarCache->relationMessage(), QLatin1String("This is an example\ntext message"));
|
||||||
QCOMPARE(chatBarCache->attachmentPath(), QString());
|
QCOMPARE(chatBarCache->attachmentPath(), QString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,39 +108,39 @@ void ChatBarCacheTest::edit()
|
|||||||
{
|
{
|
||||||
QScopedPointer<ChatBarCache> chatBarCache(new ChatBarCache(room));
|
QScopedPointer<ChatBarCache> chatBarCache(new ChatBarCache(room));
|
||||||
|
|
||||||
chatBarCache->setText(u"some text"_s);
|
chatBarCache->setText(QLatin1String("some text"));
|
||||||
chatBarCache->setAttachmentPath(u"some/path"_s);
|
chatBarCache->setAttachmentPath(QLatin1String("some/path"));
|
||||||
connect(chatBarCache.get(), &ChatBarCache::relationIdChanged, this, [](const QString &oldEventId, const QString &newEventId) {
|
connect(chatBarCache.get(), &ChatBarCache::relationIdChanged, this, [](const QString &oldEventId, const QString &newEventId) {
|
||||||
QCOMPARE(oldEventId, QString());
|
QCOMPARE(oldEventId, QString());
|
||||||
QCOMPARE(newEventId, QString(u"$153456789:example.org"_s));
|
QCOMPARE(newEventId, QString(QLatin1String("$153456789:example.org")));
|
||||||
});
|
});
|
||||||
chatBarCache->setEditId(u"$153456789:example.org"_s);
|
chatBarCache->setEditId(QLatin1String("$153456789:example.org"));
|
||||||
|
|
||||||
QCOMPARE(chatBarCache->text(), u"some text"_s);
|
QCOMPARE(chatBarCache->text(), QLatin1String("some text"));
|
||||||
QCOMPARE(chatBarCache->isReplying(), false);
|
QCOMPARE(chatBarCache->isReplying(), false);
|
||||||
QCOMPARE(chatBarCache->replyId(), QString());
|
QCOMPARE(chatBarCache->replyId(), QString());
|
||||||
QCOMPARE(chatBarCache->isEditing(), true);
|
QCOMPARE(chatBarCache->isEditing(), true);
|
||||||
QCOMPARE(chatBarCache->editId(), u"$153456789:example.org"_s);
|
QCOMPARE(chatBarCache->editId(), QLatin1String("$153456789:example.org"));
|
||||||
QCOMPARE(chatBarCache->relationAuthor(), room->member(u"@example:example.org"_s));
|
QCOMPARE(chatBarCache->relationAuthor(), room->member(QLatin1String("@example:example.org")));
|
||||||
QCOMPARE(chatBarCache->relationMessage(), u"This is an example\ntext message"_s);
|
QCOMPARE(chatBarCache->relationMessage(), QLatin1String("This is an example\ntext message"));
|
||||||
QCOMPARE(chatBarCache->attachmentPath(), QString());
|
QCOMPARE(chatBarCache->attachmentPath(), QString());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatBarCacheTest::attachment()
|
void ChatBarCacheTest::attachment()
|
||||||
{
|
{
|
||||||
QScopedPointer<ChatBarCache> chatBarCache(new ChatBarCache(room));
|
QScopedPointer<ChatBarCache> chatBarCache(new ChatBarCache(room));
|
||||||
chatBarCache->setText(u"some text"_s);
|
chatBarCache->setText(QLatin1String("some text"));
|
||||||
chatBarCache->setEditId(u"$153456789:example.org"_s);
|
chatBarCache->setEditId(QLatin1String("$153456789:example.org"));
|
||||||
chatBarCache->setAttachmentPath(u"some/path"_s);
|
chatBarCache->setAttachmentPath(QLatin1String("some/path"));
|
||||||
|
|
||||||
QCOMPARE(chatBarCache->text(), u"some text"_s);
|
QCOMPARE(chatBarCache->text(), QLatin1String("some text"));
|
||||||
QCOMPARE(chatBarCache->isReplying(), false);
|
QCOMPARE(chatBarCache->isReplying(), false);
|
||||||
QCOMPARE(chatBarCache->replyId(), QString());
|
QCOMPARE(chatBarCache->replyId(), QString());
|
||||||
QCOMPARE(chatBarCache->isEditing(), false);
|
QCOMPARE(chatBarCache->isEditing(), false);
|
||||||
QCOMPARE(chatBarCache->editId(), QString());
|
QCOMPARE(chatBarCache->editId(), QString());
|
||||||
QCOMPARE(chatBarCache->relationAuthor(), room->member(QString()));
|
QCOMPARE(chatBarCache->relationAuthor(), room->member(QString()));
|
||||||
QCOMPARE(chatBarCache->relationMessage(), QString());
|
QCOMPARE(chatBarCache->relationMessage(), QString());
|
||||||
QCOMPARE(chatBarCache->attachmentPath(), u"some/path"_s);
|
QCOMPARE(chatBarCache->attachmentPath(), QLatin1String("some/path"));
|
||||||
}
|
}
|
||||||
|
|
||||||
QTEST_MAIN(ChatBarCacheTest)
|
QTEST_MAIN(ChatBarCacheTest)
|
||||||
|
|||||||
@@ -1,20 +0,0 @@
|
|||||||
-----BEGIN CERTIFICATE-----
|
|
||||||
MIIDNTCCAh2gAwIBAgIUXbyWfTfcvVLrVB1qx36pW/7IkwMwDQYJKoZIhvcNAQEL
|
|
||||||
BQAwQjELMAkGA1UEBhMCWFgxFTATBgNVBAcMDERlZmF1bHQgQ2l0eTEcMBoGA1UE
|
|
||||||
CgwTRGVmYXVsdCBDb21wYW55IEx0ZDAgFw0yNDEyMjQxNTAxMDNaGA8yNTcyMDcy
|
|
||||||
NDE1MDEwM1owQjELMAkGA1UEBhMCWFgxFTATBgNVBAcMDERlZmF1bHQgQ2l0eTEc
|
|
||||||
MBoGA1UECgwTRGVmYXVsdCBDb21wYW55IEx0ZDCCASIwDQYJKoZIhvcNAQEBBQAD
|
|
||||||
ggEPADCCAQoCggEBAKlxZ540TQ1uUDAR7ZJ9ue0PzcD2dPmblIIddyekvZS59V7X
|
|
||||||
drhamclXpHE2EelR87Sexst0BaHH/jmrHwxCtwbeXHZ8ueJHkGHJ5DLZCCiwfG+Q
|
|
||||||
gml7wlSXxXz37vie2tdlZh2yJSM8yvLAYceHb2zOskaGvul7ZITIS0JrPc3o6VZk
|
|
||||||
+MYGkYtA2JfUsv3jH4oQbxOf7RXqhWNAXbB+3hlwRBwMIdyoBNK6YS9QSrTeS9jj
|
|
||||||
UqgO5QmaQZOVvpaPf1Y/rHHLd2Qa6+a/cCJ1sr2biagb75AihpQFsK/oy6D1PP70
|
|
||||||
zTe7hPWn/efEpmtCV7CQ8ti4cRu0Kjy0T8grtCsCAwEAAaMhMB8wHQYDVR0OBBYE
|
|
||||||
FIFlylzwADNLfgTDNkhFeFelaEDxMA0GCSqGSIb3DQEBCwUAA4IBAQBQ2rw4GLIU
|
|
||||||
v+GY7Qru9LttkrQPd2bZXKxDMd/jT+wjmMVtqS4MAsCuDYwaYLjU1aWyqy0mN+lY
|
|
||||||
A17kD0VjBNBy45sYqkZveY0ks8mCScBemtrIDmjz2tiueecBIEASwEPBOZgv5/MV
|
|
||||||
cz864FiChF+2r8Zl8bhycGy9DEpRjzYKvIQWSDHQ3zpuh3iBnjfoieLHWX2kKCpk
|
|
||||||
ouS3V6485rHNCWsZT5IcCwfBFQkOuWRJpIazpz4AfwZh1TK9+bgiKA5EyZjSNrKw
|
|
||||||
xGQSpMSTRQMB0/FOCL/AixhN9unVFUViqUcdtSfoHE1VyBHv9kDT/cYms/Xl4B0t
|
|
||||||
/ZSQJ/D/Km1+
|
|
||||||
-----END CERTIFICATE-----
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
-----BEGIN PRIVATE KEY-----
|
|
||||||
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCpcWeeNE0NblAw
|
|
||||||
Ee2SfbntD83A9nT5m5SCHXcnpL2UufVe13a4WpnJV6RxNhHpUfO0nsbLdAWhx/45
|
|
||||||
qx8MQrcG3lx2fLniR5BhyeQy2QgosHxvkIJpe8JUl8V89+74ntrXZWYdsiUjPMry
|
|
||||||
wGHHh29szrJGhr7pe2SEyEtCaz3N6OlWZPjGBpGLQNiX1LL94x+KEG8Tn+0V6oVj
|
|
||||||
QF2wft4ZcEQcDCHcqATSumEvUEq03kvY41KoDuUJmkGTlb6Wj39WP6xxy3dkGuvm
|
|
||||||
v3AidbK9m4moG++QIoaUBbCv6Mug9Tz+9M03u4T1p/3nxKZrQlewkPLYuHEbtCo8
|
|
||||||
tE/IK7QrAgMBAAECggEAH9qmeKrra2F4KLlOGNKS//qPGz4Z+ozhi95/NpA1Zb7Z
|
|
||||||
3pUSCBFcROo5i2D3WA4kiymoRLpQjrv60puVcCggoWVvK4VCKsR6Y6/hOx/q9T9M
|
|
||||||
fWrE4ZC3FVEc+uPfZJT0nja9TkrdyXSV0LITD8Ap1eI7yJ9vR5R/bqj64QcpLMrU
|
|
||||||
QeoQIy1oTMR+qdjj33duyRwBZU3Yf8FRB2iW6OILZ8hzFo1jngec7dph9a1RK4e0
|
|
||||||
mEPdc9ywsKlDM7P0Y7zdmjar5XtQn87GiwNhz23f1fzCC2axLtOW0Xm4e4Qumehb
|
|
||||||
WrIi6Vfq8IWMglU7QrBJ7iR0Ls+XoKA5GxomV2IJZQKBgQDoIkOl5YGPQ3iGR+WK
|
|
||||||
e5/2Ml4G/uURzYiOlzSsyfoPXyO4EI2BJd5HkH+EvfgRx4xKkxUZRJdzR7llYPl8
|
|
||||||
BFYcFitvhO8SbD0mNAB5YW7f+3v1pgEN2umzoKd389Zx5WqTZ7YB1VG5RN/Q1JJL
|
|
||||||
2JM0Xgamq2vNtx3roRPxDBeW7QKBgQC63R/bmACJbgIzfaVBX4Zie3NQG0/Hf+gF
|
|
||||||
LnBwUmQDZOR7MY+kSiIUVMn3NuZRiCSCFBVwApruyK8r535JCibTVm5PWjvhFddY
|
|
||||||
LgaPOCKGlm9TLScjoH1pErYgG3uJ4nXeRfXhg4mco6EkrC7RzQywrd0VDoqpuc1Y
|
|
||||||
EKfEsYk8dwKBgE+mSh3nNOBKX1V73+f3aTiZqaeu2DyWkG+UtE9BclrJ40Cp9VPG
|
|
||||||
AZH+o7KRWEgJdzqzYv7riSfWCWgesRv7hOxYMwktzLY+i3DLUQpVAy05ZhwwnJX7
|
|
||||||
ckrfKfc/pGoqNLplUI8qecMfPciy14vMwR2r0Y5orTHFzi9mcqg35PQ1AoGAW2LX
|
|
||||||
OLq+0HdHhk0Va8I+450CSRQCUUvhed87SANTPEG0Z/dWC3/h6NWKrGdh/k+5oxAV
|
|
||||||
Z+EuSkdFPBCLt0bKtCKZ8h7sF+lplotz08kdQXsC2MfFU2wiySdIgK1QHp/tCxZl
|
|
||||||
6LM+sqdnoJrAjwRcB3AQJkMlV1ox7ba/hbdZqYMCgYBS6+JUXSSASpm5ZHd32a8m
|
|
||||||
xwryEZ7H6Hek6lvMHdxmwoKat5dCavxw64nrtyeeGZpg1W3zLLyamF9x/8kMyr6y
|
|
||||||
KKvtBfJ5sCvAbt80o9Pbs6R3yDB3AKiD3s3PQK7lol1nhE/8IbsF2r8JEQVcYd/k
|
|
||||||
oBzkl7MrMyLhhaCqSxwqQQ==
|
|
||||||
-----END PRIVATE KEY-----
|
|
||||||
@@ -49,51 +49,6 @@
|
|||||||
"unsigned": {
|
"unsigned": {
|
||||||
"age": 1234
|
"age": 1234
|
||||||
}
|
}
|
||||||
},
|
|
||||||
{
|
|
||||||
"content": {
|
|
||||||
"displayname": "Bob",
|
|
||||||
"membership": "join"
|
|
||||||
},
|
|
||||||
"event_id": "$143273blorb3PhrSn:example.org",
|
|
||||||
"origin_server_ts": 1432735824653,
|
|
||||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
|
||||||
"sender": "@bob:kde.org",
|
|
||||||
"state_key": "@bob:kde.org",
|
|
||||||
"type": "m.room.member",
|
|
||||||
"unsigned": {
|
|
||||||
"age": 1234
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"content": {
|
|
||||||
"displayname": "Invited",
|
|
||||||
"membership": "invite"
|
|
||||||
},
|
|
||||||
"event_id": "$asdfpj443PhrSn:example.org",
|
|
||||||
"origin_server_ts": 1432735824653,
|
|
||||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
|
||||||
"sender": "@example:example.org",
|
|
||||||
"state_key": "@invited:example.com",
|
|
||||||
"type": "m.room.member",
|
|
||||||
"unsigned": {
|
|
||||||
"age": 1234
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"content": {
|
|
||||||
"displayname": "Banned",
|
|
||||||
"membership": "ban"
|
|
||||||
},
|
|
||||||
"event_id": "$asdfpj443PhrSnasfd:example.org",
|
|
||||||
"origin_server_ts": 1432735824653,
|
|
||||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
|
||||||
"sender": "@banned:example.com",
|
|
||||||
"state_key": "@banned:example.com",
|
|
||||||
"type": "m.room.member",
|
|
||||||
"unsigned": {
|
|
||||||
"age": 1234
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -102,7 +57,7 @@
|
|||||||
"@alice:example.com",
|
"@alice:example.com",
|
||||||
"@bob:example.com"
|
"@bob:example.com"
|
||||||
],
|
],
|
||||||
"m.invited_member_count": 1,
|
"m.invited_member_count": 0,
|
||||||
"m.joined_member_count": 2
|
"m.joined_member_count": 2
|
||||||
},
|
},
|
||||||
"timeline": {
|
"timeline": {
|
||||||
|
|||||||
@@ -8,14 +8,14 @@
|
|||||||
"answers": [
|
"answers": [
|
||||||
{
|
{
|
||||||
"id": "option1",
|
"id": "option1",
|
||||||
"org.matrix.msc1767.text": "option1text"
|
"org.matrix.msc1767.text": "option1"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "option2",
|
"id": "option2",
|
||||||
"org.matrix.msc1767.text": "option2text"
|
"org.matrix.msc1767.text": "option2"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"kind": "org.matrix.msc3381.poll.undisclosed",
|
"kind": "org.matrix.msc3381.poll.disclosed",
|
||||||
"max_selections": 1,
|
"max_selections": 1,
|
||||||
"question": {
|
"question": {
|
||||||
"body": "test",
|
"body": "test",
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QQuickItem>
|
|
||||||
#include <QTest>
|
#include <QTest>
|
||||||
|
|
||||||
#include "delegatesizehelper.h"
|
#include "delegatesizehelper.h"
|
||||||
@@ -31,7 +30,7 @@ void DelegateSizeHelperTest::risingPercentage_data()
|
|||||||
QTest::addColumn<int>("currentPercentageWidth");
|
QTest::addColumn<int>("currentPercentageWidth");
|
||||||
QTest::addColumn<qreal>("currentWidth");
|
QTest::addColumn<qreal>("currentWidth");
|
||||||
|
|
||||||
QTest::newRow("zero") << qreal(0) << int(100) << qreal(0);
|
QTest::newRow("zero") << qreal(0) << int(0) << qreal(0);
|
||||||
QTest::newRow("one hundred") << qreal(100) << int(0) << qreal(0);
|
QTest::newRow("one hundred") << qreal(100) << int(0) << qreal(0);
|
||||||
QTest::newRow("one fifty") << qreal(150) << int(50) << qreal(75);
|
QTest::newRow("one fifty") << qreal(150) << int(50) << qreal(75);
|
||||||
QTest::newRow("two hundred") << qreal(200) << int(100) << qreal(200);
|
QTest::newRow("two hundred") << qreal(200) << int(100) << qreal(200);
|
||||||
@@ -44,18 +43,16 @@ void DelegateSizeHelperTest::risingPercentage()
|
|||||||
QFETCH(int, currentPercentageWidth);
|
QFETCH(int, currentPercentageWidth);
|
||||||
QFETCH(qreal, currentWidth);
|
QFETCH(qreal, currentWidth);
|
||||||
|
|
||||||
auto item = QQuickItem();
|
|
||||||
item.setWidth(parentWidth);
|
|
||||||
|
|
||||||
DelegateSizeHelper delegateSizeHelper;
|
DelegateSizeHelper delegateSizeHelper;
|
||||||
delegateSizeHelper.setParentItem(&item);
|
|
||||||
delegateSizeHelper.setStartBreakpoint(100);
|
delegateSizeHelper.setStartBreakpoint(100);
|
||||||
delegateSizeHelper.setEndBreakpoint(200);
|
delegateSizeHelper.setEndBreakpoint(200);
|
||||||
delegateSizeHelper.setStartPercentWidth(0);
|
delegateSizeHelper.setStartPercentWidth(0);
|
||||||
delegateSizeHelper.setEndPercentWidth(100);
|
delegateSizeHelper.setEndPercentWidth(100);
|
||||||
|
|
||||||
QCOMPARE(delegateSizeHelper.availablePercentageWidth(), currentPercentageWidth);
|
delegateSizeHelper.setParentWidth(parentWidth);
|
||||||
QCOMPARE(delegateSizeHelper.availableWidth(), currentWidth);
|
|
||||||
|
QCOMPARE(delegateSizeHelper.currentPercentageWidth(), currentPercentageWidth);
|
||||||
|
QCOMPARE(delegateSizeHelper.currentWidth(), currentWidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DelegateSizeHelperTest::fallingPercentage_data()
|
void DelegateSizeHelperTest::fallingPercentage_data()
|
||||||
@@ -77,18 +74,16 @@ void DelegateSizeHelperTest::fallingPercentage()
|
|||||||
QFETCH(int, currentPercentageWidth);
|
QFETCH(int, currentPercentageWidth);
|
||||||
QFETCH(qreal, currentWidth);
|
QFETCH(qreal, currentWidth);
|
||||||
|
|
||||||
auto item = QQuickItem();
|
|
||||||
item.setWidth(parentWidth);
|
|
||||||
|
|
||||||
DelegateSizeHelper delegateSizeHelper;
|
DelegateSizeHelper delegateSizeHelper;
|
||||||
delegateSizeHelper.setParentItem(&item);
|
|
||||||
delegateSizeHelper.setStartBreakpoint(100);
|
delegateSizeHelper.setStartBreakpoint(100);
|
||||||
delegateSizeHelper.setEndBreakpoint(200);
|
delegateSizeHelper.setEndBreakpoint(200);
|
||||||
delegateSizeHelper.setStartPercentWidth(100);
|
delegateSizeHelper.setStartPercentWidth(100);
|
||||||
delegateSizeHelper.setEndPercentWidth(0);
|
delegateSizeHelper.setEndPercentWidth(0);
|
||||||
|
|
||||||
QCOMPARE(delegateSizeHelper.availablePercentageWidth(), currentPercentageWidth);
|
delegateSizeHelper.setParentWidth(parentWidth);
|
||||||
QCOMPARE(delegateSizeHelper.availableWidth(), currentWidth);
|
|
||||||
|
QCOMPARE(delegateSizeHelper.currentPercentageWidth(), currentPercentageWidth);
|
||||||
|
QCOMPARE(delegateSizeHelper.currentWidth(), currentWidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DelegateSizeHelperTest::equalPercentage_data()
|
void DelegateSizeHelperTest::equalPercentage_data()
|
||||||
@@ -110,18 +105,16 @@ void DelegateSizeHelperTest::equalPercentage()
|
|||||||
QFETCH(int, currentPercentageWidth);
|
QFETCH(int, currentPercentageWidth);
|
||||||
QFETCH(qreal, currentWidth);
|
QFETCH(qreal, currentWidth);
|
||||||
|
|
||||||
auto item = QQuickItem();
|
|
||||||
item.setWidth(parentWidth);
|
|
||||||
|
|
||||||
DelegateSizeHelper delegateSizeHelper;
|
DelegateSizeHelper delegateSizeHelper;
|
||||||
delegateSizeHelper.setParentItem(&item);
|
|
||||||
delegateSizeHelper.setStartBreakpoint(100);
|
delegateSizeHelper.setStartBreakpoint(100);
|
||||||
delegateSizeHelper.setEndBreakpoint(200);
|
delegateSizeHelper.setEndBreakpoint(200);
|
||||||
delegateSizeHelper.setStartPercentWidth(50);
|
delegateSizeHelper.setStartPercentWidth(50);
|
||||||
delegateSizeHelper.setEndPercentWidth(50);
|
delegateSizeHelper.setEndPercentWidth(50);
|
||||||
|
|
||||||
QCOMPARE(delegateSizeHelper.availablePercentageWidth(), currentPercentageWidth);
|
delegateSizeHelper.setParentWidth(parentWidth);
|
||||||
QCOMPARE(delegateSizeHelper.availableWidth(), currentWidth);
|
|
||||||
|
QCOMPARE(delegateSizeHelper.currentPercentageWidth(), currentPercentageWidth);
|
||||||
|
QCOMPARE(delegateSizeHelper.currentWidth(), currentWidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DelegateSizeHelperTest::equalBreakpoint_data()
|
void DelegateSizeHelperTest::equalBreakpoint_data()
|
||||||
@@ -131,9 +124,9 @@ void DelegateSizeHelperTest::equalBreakpoint_data()
|
|||||||
QTest::addColumn<int>("currentPercentageWidth");
|
QTest::addColumn<int>("currentPercentageWidth");
|
||||||
QTest::addColumn<qreal>("currentWidth");
|
QTest::addColumn<qreal>("currentWidth");
|
||||||
|
|
||||||
QTest::newRow("start higher") << int(100) << int(0) << int(100) << qreal(1000);
|
QTest::newRow("start higher") << int(100) << int(0) << int(-1) << qreal(0);
|
||||||
QTest::newRow("equal") << int(50) << int(50) << int(50) << qreal(500);
|
QTest::newRow("equal") << int(50) << int(50) << int(50) << qreal(500);
|
||||||
QTest::newRow("end higher") << int(0) << int(100) << int(100) << qreal(1000);
|
QTest::newRow("end higher") << int(0) << int(100) << int(-1) << qreal(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -147,18 +140,16 @@ void DelegateSizeHelperTest::equalBreakpoint()
|
|||||||
QFETCH(int, currentPercentageWidth);
|
QFETCH(int, currentPercentageWidth);
|
||||||
QFETCH(qreal, currentWidth);
|
QFETCH(qreal, currentWidth);
|
||||||
|
|
||||||
auto item = QQuickItem();
|
|
||||||
item.setWidth(1000);
|
|
||||||
|
|
||||||
DelegateSizeHelper delegateSizeHelper;
|
DelegateSizeHelper delegateSizeHelper;
|
||||||
delegateSizeHelper.setParentItem(&item);
|
|
||||||
delegateSizeHelper.setStartBreakpoint(100);
|
delegateSizeHelper.setStartBreakpoint(100);
|
||||||
delegateSizeHelper.setEndBreakpoint(100);
|
delegateSizeHelper.setEndBreakpoint(100);
|
||||||
delegateSizeHelper.setStartPercentWidth(startPercentageWidth);
|
delegateSizeHelper.setStartPercentWidth(startPercentageWidth);
|
||||||
delegateSizeHelper.setEndPercentWidth(endPercentageWidth);
|
delegateSizeHelper.setEndPercentWidth(endPercentageWidth);
|
||||||
|
|
||||||
QCOMPARE(delegateSizeHelper.availablePercentageWidth(), currentPercentageWidth);
|
delegateSizeHelper.setParentWidth(1000);
|
||||||
QCOMPARE(delegateSizeHelper.availableWidth(), currentWidth);
|
|
||||||
|
QCOMPARE(delegateSizeHelper.currentPercentageWidth(), currentPercentageWidth);
|
||||||
|
QCOMPARE(delegateSizeHelper.currentWidth(), currentWidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
QTEST_GUILESS_MAIN(DelegateSizeHelperTest)
|
QTEST_GUILESS_MAIN(DelegateSizeHelperTest)
|
||||||
|
|||||||
@@ -11,8 +11,6 @@
|
|||||||
#include <Quotient/connection.h>
|
#include <Quotient/connection.h>
|
||||||
#include <Quotient/quotient_common.h>
|
#include <Quotient/quotient_common.h>
|
||||||
#include <Quotient/syncdata.h>
|
#include <Quotient/syncdata.h>
|
||||||
#include <qcbormap.h>
|
|
||||||
#include <qtestcase.h>
|
|
||||||
|
|
||||||
#include "linkpreviewer.h"
|
#include "linkpreviewer.h"
|
||||||
#include "models/reactionmodel.h"
|
#include "models/reactionmodel.h"
|
||||||
@@ -34,6 +32,8 @@ private:
|
|||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void initTestCase();
|
void initTestCase();
|
||||||
|
|
||||||
|
void eventId();
|
||||||
|
void nullEventId();
|
||||||
void authorDisplayName();
|
void authorDisplayName();
|
||||||
void nullAuthorDisplayName();
|
void nullAuthorDisplayName();
|
||||||
void singleLineSidplayName();
|
void singleLineSidplayName();
|
||||||
@@ -56,21 +56,38 @@ private Q_SLOTS:
|
|||||||
void nullSubtitle();
|
void nullSubtitle();
|
||||||
void mediaInfo();
|
void mediaInfo();
|
||||||
void nullMediaInfo();
|
void nullMediaInfo();
|
||||||
|
void hasReply();
|
||||||
|
void nullHasReply();
|
||||||
|
void replyId();
|
||||||
|
void nullReplyId();
|
||||||
void replyAuthor();
|
void replyAuthor();
|
||||||
void nullReplyAuthor();
|
void nullReplyAuthor();
|
||||||
|
void thread();
|
||||||
|
void nullThread();
|
||||||
void location();
|
void location();
|
||||||
void nullLocation();
|
void nullLocation();
|
||||||
};
|
};
|
||||||
|
|
||||||
void EventHandlerTest::initTestCase()
|
void EventHandlerTest::initTestCase()
|
||||||
{
|
{
|
||||||
connection = Connection::makeMockConnection(u"@bob:kde.org"_s);
|
connection = Connection::makeMockConnection(QStringLiteral("@bob:kde.org"));
|
||||||
room = new TestUtils::TestRoom(connection, u"#myroom:kde.org"_s, u"test-eventhandler-sync.json"_s);
|
room = new TestUtils::TestRoom(connection, QStringLiteral("#myroom:kde.org"), QLatin1String("test-eventhandler-sync.json"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void EventHandlerTest::eventId()
|
||||||
|
{
|
||||||
|
QCOMPARE(EventHandler::id(room->messageEvents().at(0).get()), QStringLiteral("$153456789:example.org"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void EventHandlerTest::nullEventId()
|
||||||
|
{
|
||||||
|
QTest::ignoreMessage(QtWarningMsg, "id called with event set to nullptr.");
|
||||||
|
QCOMPARE(EventHandler::id(nullptr), QString());
|
||||||
}
|
}
|
||||||
|
|
||||||
void EventHandlerTest::authorDisplayName()
|
void EventHandlerTest::authorDisplayName()
|
||||||
{
|
{
|
||||||
QCOMPARE(EventHandler::authorDisplayName(room, room->messageEvents().at(1).get()), u"before"_s);
|
QCOMPARE(EventHandler::authorDisplayName(room, room->messageEvents().at(1).get()), QStringLiteral("before"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EventHandlerTest::nullAuthorDisplayName()
|
void EventHandlerTest::nullAuthorDisplayName()
|
||||||
@@ -84,7 +101,8 @@ void EventHandlerTest::nullAuthorDisplayName()
|
|||||||
|
|
||||||
void EventHandlerTest::singleLineSidplayName()
|
void EventHandlerTest::singleLineSidplayName()
|
||||||
{
|
{
|
||||||
QCOMPARE(EventHandler::singleLineAuthorDisplayname(room, room->messageEvents().at(11).get()), "Look at me I put newlines in my display name"_L1);
|
QCOMPARE(EventHandler::singleLineAuthorDisplayname(room, room->messageEvents().at(11).get()),
|
||||||
|
QStringLiteral("Look at me I put newlines in my display name"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EventHandlerTest::nullSingleLineDisplayName()
|
void EventHandlerTest::nullSingleLineDisplayName()
|
||||||
@@ -100,24 +118,17 @@ void EventHandlerTest::time()
|
|||||||
{
|
{
|
||||||
const auto event = room->messageEvents().at(0).get();
|
const auto event = room->messageEvents().at(0).get();
|
||||||
|
|
||||||
QCOMPARE(EventHandler::time(room, event), QDateTime::fromMSecsSinceEpoch(1432735824654, QTimeZone(QTimeZone::UTC)));
|
QCOMPARE(EventHandler::time(event), QDateTime::fromMSecsSinceEpoch(1432735824654, Qt::UTC));
|
||||||
|
QCOMPARE(EventHandler::time(event, true, QDateTime::fromMSecsSinceEpoch(1234, Qt::UTC)), QDateTime::fromMSecsSinceEpoch(1234, Qt::UTC));
|
||||||
const auto txID = room->postJson("m.room.message"_L1, event->fullJson());
|
|
||||||
QCOMPARE(room->pendingEvents().size(), 1);
|
|
||||||
const auto pendingIt = room->findPendingEvent(txID);
|
|
||||||
QCOMPARE(EventHandler::time(room, pendingIt->event(), true), pendingIt->lastUpdated());
|
|
||||||
|
|
||||||
room->discardMessage(txID);
|
|
||||||
QCOMPARE(room->pendingEvents().size(), 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EventHandlerTest::nullTime()
|
void EventHandlerTest::nullTime()
|
||||||
{
|
{
|
||||||
QTest::ignoreMessage(QtWarningMsg, "time called with room set to nullptr.");
|
|
||||||
QCOMPARE(EventHandler::time(nullptr, nullptr), QDateTime());
|
|
||||||
|
|
||||||
QTest::ignoreMessage(QtWarningMsg, "time called with event set to nullptr.");
|
QTest::ignoreMessage(QtWarningMsg, "time called with event set to nullptr.");
|
||||||
QCOMPARE(EventHandler::time(room, nullptr), QDateTime());
|
QCOMPARE(EventHandler::time(nullptr), QDateTime());
|
||||||
|
|
||||||
|
QTest::ignoreMessage(QtWarningMsg, "a value must be provided for lastUpdated for a pending event.");
|
||||||
|
QCOMPARE(EventHandler::time(room->messageEvents().at(0).get(), true), QDateTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
void EventHandlerTest::timeString()
|
void EventHandlerTest::timeString()
|
||||||
@@ -126,27 +137,20 @@ void EventHandlerTest::timeString()
|
|||||||
|
|
||||||
KFormat format;
|
KFormat format;
|
||||||
|
|
||||||
QCOMPARE(EventHandler::timeString(room, event, false),
|
QCOMPARE(EventHandler::timeString(event, false),
|
||||||
QLocale().toString(QDateTime::fromMSecsSinceEpoch(1432735824654, QTimeZone(QTimeZone::UTC)).toLocalTime().time(), QLocale::ShortFormat));
|
QLocale().toString(QDateTime::fromMSecsSinceEpoch(1432735824654, Qt::UTC).toLocalTime().time(), QLocale::ShortFormat));
|
||||||
QCOMPARE(EventHandler::timeString(room, event, true),
|
QCOMPARE(EventHandler::timeString(event, true),
|
||||||
format.formatRelativeDate(QDateTime::fromMSecsSinceEpoch(1432735824654, QTimeZone(QTimeZone::UTC)).toLocalTime().date(), QLocale::ShortFormat));
|
format.formatRelativeDate(QDateTime::fromMSecsSinceEpoch(1432735824654, Qt::UTC).toLocalTime().date(), QLocale::ShortFormat));
|
||||||
QCOMPARE(EventHandler::timeString(room, event, u"hh:mm"_s), QDateTime::fromMSecsSinceEpoch(1432735824654, QTimeZone(QTimeZone::UTC)).toString(u"hh:mm"_s));
|
QCOMPARE(EventHandler::timeString(event, false, QLocale::ShortFormat, true, QDateTime::fromMSecsSinceEpoch(1690699214545, Qt::UTC)),
|
||||||
|
QLocale().toString(QDateTime::fromMSecsSinceEpoch(1690699214545, Qt::UTC).toLocalTime().time(), QLocale::ShortFormat));
|
||||||
const auto txID = room->postJson("m.room.message"_L1, event->fullJson());
|
QCOMPARE(EventHandler::timeString(event, true, QLocale::ShortFormat, true, QDateTime::fromMSecsSinceEpoch(1690699214545, Qt::UTC)),
|
||||||
QCOMPARE(room->pendingEvents().size(), 1);
|
format.formatRelativeDate(QDateTime::fromMSecsSinceEpoch(1690699214545, Qt::UTC).toLocalTime().date(), QLocale::ShortFormat));
|
||||||
const auto pendingIt = room->findPendingEvent(txID);
|
QCOMPARE(EventHandler::timeString(event, false, QLocale::LongFormat, true, QDateTime::fromMSecsSinceEpoch(1690699214545, Qt::UTC)),
|
||||||
|
QLocale().toString(QDateTime::fromMSecsSinceEpoch(1690699214545, Qt::UTC).toLocalTime().time(), QLocale::LongFormat));
|
||||||
QCOMPARE(EventHandler::timeString(room, pendingIt->event(), false, QLocale::ShortFormat, true),
|
QCOMPARE(EventHandler::timeString(event, true, QLocale::LongFormat, true, QDateTime::fromMSecsSinceEpoch(1690699214545, Qt::UTC)),
|
||||||
QLocale().toString(pendingIt->lastUpdated().toLocalTime().time(), QLocale::ShortFormat));
|
format.formatRelativeDate(QDateTime::fromMSecsSinceEpoch(1690699214545, Qt::UTC).toLocalTime().date(), QLocale::LongFormat));
|
||||||
QCOMPARE(EventHandler::timeString(room, pendingIt->event(), true, QLocale::ShortFormat, true),
|
QCOMPARE(EventHandler::timeString(event, QStringLiteral("hh:mm")),
|
||||||
format.formatRelativeDate(pendingIt->lastUpdated().toLocalTime().date(), QLocale::ShortFormat));
|
QDateTime::fromMSecsSinceEpoch(1432735824654, Qt::UTC).toString(QStringLiteral("hh:mm")));
|
||||||
QCOMPARE(EventHandler::timeString(room, pendingIt->event(), false, QLocale::LongFormat, true),
|
|
||||||
QLocale().toString(pendingIt->lastUpdated().toLocalTime().time(), QLocale::LongFormat));
|
|
||||||
QCOMPARE(EventHandler::timeString(room, pendingIt->event(), true, QLocale::LongFormat, true),
|
|
||||||
format.formatRelativeDate(pendingIt->lastUpdated().toLocalTime().date(), QLocale::LongFormat));
|
|
||||||
|
|
||||||
room->discardMessage(txID);
|
|
||||||
QCOMPARE(room->pendingEvents().size(), 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EventHandlerTest::highlighted()
|
void EventHandlerTest::highlighted()
|
||||||
@@ -183,10 +187,10 @@ void EventHandlerTest::body()
|
|||||||
{
|
{
|
||||||
const auto event = room->messageEvents().at(0).get();
|
const auto event = room->messageEvents().at(0).get();
|
||||||
|
|
||||||
QCOMPARE(EventHandler::richBody(room, event), u"<b>This is an example<br>text message</b>"_s);
|
QCOMPARE(EventHandler::richBody(room, event), QStringLiteral("<b>This is an example<br>text message</b>"));
|
||||||
QCOMPARE(EventHandler::richBody(room, event, true), u"<b>This is an example text message</b>"_s);
|
QCOMPARE(EventHandler::richBody(room, event, true), QStringLiteral("<b>This is an example text message</b>"));
|
||||||
QCOMPARE(EventHandler::plainBody(room, event), u"This is an example\ntext message"_s);
|
QCOMPARE(EventHandler::plainBody(room, event), QStringLiteral("This is an example\ntext message"));
|
||||||
QCOMPARE(EventHandler::plainBody(room, event, true), u"This is an example text message"_s);
|
QCOMPARE(EventHandler::plainBody(room, event, true), QStringLiteral("This is an example text message"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EventHandlerTest::nullBody()
|
void EventHandlerTest::nullBody()
|
||||||
@@ -209,11 +213,13 @@ void EventHandlerTest::genericBody_data()
|
|||||||
QTest::addColumn<int>("eventNum");
|
QTest::addColumn<int>("eventNum");
|
||||||
QTest::addColumn<QString>("output");
|
QTest::addColumn<QString>("output");
|
||||||
|
|
||||||
QTest::newRow("message") << 0 << u"<a href=\"https://matrix.to/#/@example:example.org\">after</a> sent a message"_s;
|
QTest::newRow("message") << 0 << QStringLiteral("<a href=\"https://matrix.to/#/@example:example.org\">after</a> sent a message");
|
||||||
QTest::newRow("member") << 1 << u"<a href=\"https://matrix.to/#/@example:example.org\">after</a> changed their display name and updated their avatar"_s;
|
QTest::newRow("member") << 1
|
||||||
QTest::newRow("message 2") << 2 << u"<a href=\"https://matrix.to/#/@example:example.org\">after</a> sent a message"_s;
|
<< QStringLiteral(
|
||||||
QTest::newRow("reaction") << 3 << u"Unknown event"_s;
|
"<a href=\"https://matrix.to/#/@example:example.org\">after</a> changed their display name and updated their avatar");
|
||||||
QTest::newRow("video") << 4 << u"<a href=\"https://matrix.to/#/@example:example.org\">after</a> sent a message"_s;
|
QTest::newRow("message 2") << 2 << QStringLiteral("<a href=\"https://matrix.to/#/@example:example.org\">after</a> sent a message");
|
||||||
|
QTest::newRow("reaction") << 3 << QStringLiteral("Unknown event");
|
||||||
|
QTest::newRow("video") << 4 << QStringLiteral("<a href=\"https://matrix.to/#/@example:example.org\">after</a> sent a message");
|
||||||
}
|
}
|
||||||
|
|
||||||
void EventHandlerTest::genericBody()
|
void EventHandlerTest::genericBody()
|
||||||
@@ -235,19 +241,19 @@ void EventHandlerTest::nullGenericBody()
|
|||||||
|
|
||||||
void EventHandlerTest::markdownBody()
|
void EventHandlerTest::markdownBody()
|
||||||
{
|
{
|
||||||
QCOMPARE(EventHandler::markdownBody(room->messageEvents().at(0).get()), u"This is an example\ntext message"_s);
|
QCOMPARE(EventHandler::markdownBody(room->messageEvents().at(0).get()), QStringLiteral("This is an example\ntext message"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EventHandlerTest::markdownBodyReply()
|
void EventHandlerTest::markdownBodyReply()
|
||||||
{
|
{
|
||||||
QCOMPARE(EventHandler::markdownBody(room->messageEvents().at(5).get()), u"reply"_s);
|
QCOMPARE(EventHandler::markdownBody(room->messageEvents().at(5).get()), QStringLiteral("reply"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EventHandlerTest::subtitle()
|
void EventHandlerTest::subtitle()
|
||||||
{
|
{
|
||||||
QCOMPARE(EventHandler::subtitleText(room, room->messageEvents().at(0).get()), u"after: This is an example text message"_s);
|
QCOMPARE(EventHandler::subtitleText(room, room->messageEvents().at(0).get()), QStringLiteral("after: This is an example text message"));
|
||||||
QCOMPARE(EventHandler::subtitleText(room, room->messageEvents().at(2).get()),
|
QCOMPARE(EventHandler::subtitleText(room, room->messageEvents().at(2).get()),
|
||||||
u"after: This is a highlight @bob:kde.org and this is a link https://kde.org"_s);
|
QStringLiteral("after: This is a highlight @bob:kde.org and this is a link https://kde.org"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EventHandlerTest::nullSubtitle()
|
void EventHandlerTest::nullSubtitle()
|
||||||
@@ -263,21 +269,21 @@ void EventHandlerTest::mediaInfo()
|
|||||||
{
|
{
|
||||||
auto event = room->messageEvents().at(4).get();
|
auto event = room->messageEvents().at(4).get();
|
||||||
auto mediaInfo = EventHandler::mediaInfo(room, event);
|
auto mediaInfo = EventHandler::mediaInfo(room, event);
|
||||||
auto thumbnailInfo = mediaInfo["tempInfo"_L1].toMap();
|
auto thumbnailInfo = mediaInfo["tempInfo"_ls].toMap();
|
||||||
|
|
||||||
QCOMPARE(mediaInfo["source"_L1], room->makeMediaUrl(event->id(), QUrl("mxc://kde.org/1234567"_L1)));
|
QCOMPARE(mediaInfo["source"_ls], room->makeMediaUrl(event->id(), QUrl("mxc://kde.org/1234567"_ls)));
|
||||||
QCOMPARE(mediaInfo["mimeType"_L1], u"video/mp4"_s);
|
QCOMPARE(mediaInfo["mimeType"_ls], QStringLiteral("video/mp4"));
|
||||||
QCOMPARE(mediaInfo["mimeIcon"_L1], u"video-mp4"_s);
|
QCOMPARE(mediaInfo["mimeIcon"_ls], QStringLiteral("video-mp4"));
|
||||||
QCOMPARE(mediaInfo["size"_L1], 62650636);
|
QCOMPARE(mediaInfo["size"_ls], 62650636);
|
||||||
QCOMPARE(mediaInfo["duration"_L1], 10);
|
QCOMPARE(mediaInfo["duration"_ls], 10);
|
||||||
QCOMPARE(mediaInfo["width"_L1], 1920);
|
QCOMPARE(mediaInfo["width"_ls], 1920);
|
||||||
QCOMPARE(mediaInfo["height"_L1], 1080);
|
QCOMPARE(mediaInfo["height"_ls], 1080);
|
||||||
QCOMPARE(thumbnailInfo["source"_L1], room->makeMediaUrl(event->id(), QUrl("mxc://kde.org/2234567"_L1)));
|
QCOMPARE(thumbnailInfo["source"_ls], room->makeMediaUrl(event->id(), QUrl("mxc://kde.org/2234567"_ls)));
|
||||||
QCOMPARE(thumbnailInfo["mimeType"_L1], u"image/jpeg"_s);
|
QCOMPARE(thumbnailInfo["mimeType"_ls], QStringLiteral("image/jpeg"));
|
||||||
QCOMPARE(thumbnailInfo["mimeIcon"_L1], u"image-jpeg"_s);
|
QCOMPARE(thumbnailInfo["mimeIcon"_ls], QStringLiteral("image-jpeg"));
|
||||||
QCOMPARE(thumbnailInfo["size"_L1], 382249);
|
QCOMPARE(thumbnailInfo["size"_ls], 382249);
|
||||||
QCOMPARE(thumbnailInfo["width"_L1], 800);
|
QCOMPARE(thumbnailInfo["width"_ls], 800);
|
||||||
QCOMPARE(thumbnailInfo["height"_L1], 450);
|
QCOMPARE(thumbnailInfo["height"_ls], 450);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EventHandlerTest::nullMediaInfo()
|
void EventHandlerTest::nullMediaInfo()
|
||||||
@@ -289,6 +295,30 @@ void EventHandlerTest::nullMediaInfo()
|
|||||||
QCOMPARE(EventHandler::mediaInfo(room, nullptr), QVariantMap());
|
QCOMPARE(EventHandler::mediaInfo(room, nullptr), QVariantMap());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EventHandlerTest::hasReply()
|
||||||
|
{
|
||||||
|
QCOMPARE(EventHandler::hasReply(room->messageEvents().at(5).get()), true);
|
||||||
|
QCOMPARE(EventHandler::hasReply(room->messageEvents().at(0).get()), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EventHandlerTest::nullHasReply()
|
||||||
|
{
|
||||||
|
QTest::ignoreMessage(QtWarningMsg, "hasReply called with event set to nullptr.");
|
||||||
|
QCOMPARE(EventHandler::hasReply(nullptr), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EventHandlerTest::replyId()
|
||||||
|
{
|
||||||
|
QCOMPARE(EventHandler::replyId(room->messageEvents().at(5).get()), QStringLiteral("$153456789:example.org"));
|
||||||
|
QCOMPARE(EventHandler::replyId(room->messageEvents().at(0).get()), QStringLiteral(""));
|
||||||
|
}
|
||||||
|
|
||||||
|
void EventHandlerTest::nullReplyId()
|
||||||
|
{
|
||||||
|
QTest::ignoreMessage(QtWarningMsg, "replyId called with event set to nullptr.");
|
||||||
|
QCOMPARE(EventHandler::replyId(nullptr), QString());
|
||||||
|
}
|
||||||
|
|
||||||
void EventHandlerTest::replyAuthor()
|
void EventHandlerTest::replyAuthor()
|
||||||
{
|
{
|
||||||
auto replyEvent = room->messageEvents().at(0).get();
|
auto replyEvent = room->messageEvents().at(0).get();
|
||||||
@@ -314,11 +344,34 @@ void EventHandlerTest::nullReplyAuthor()
|
|||||||
QCOMPARE(EventHandler::replyAuthor(room, nullptr), RoomMember());
|
QCOMPARE(EventHandler::replyAuthor(room, nullptr), RoomMember());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EventHandlerTest::thread()
|
||||||
|
{
|
||||||
|
QCOMPARE(EventHandler::isThreaded(room->messageEvents().at(0).get()), false);
|
||||||
|
QCOMPARE(EventHandler::threadRoot(room->messageEvents().at(0).get()), QString());
|
||||||
|
|
||||||
|
QCOMPARE(EventHandler::isThreaded(room->messageEvents().at(9).get()), true);
|
||||||
|
QCOMPARE(EventHandler::threadRoot(room->messageEvents().at(9).get()), QStringLiteral("$threadroot:example.org"));
|
||||||
|
QCOMPARE(EventHandler::replyId(room->messageEvents().at(9).get()), QStringLiteral("$threadroot:example.org"));
|
||||||
|
|
||||||
|
QCOMPARE(EventHandler::isThreaded(room->messageEvents().at(10).get()), true);
|
||||||
|
QCOMPARE(EventHandler::threadRoot(room->messageEvents().at(10).get()), QStringLiteral("$threadroot:example.org"));
|
||||||
|
QCOMPARE(EventHandler::replyId(room->messageEvents().at(10).get()), QStringLiteral("$threadmessage1:example.org"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void EventHandlerTest::nullThread()
|
||||||
|
{
|
||||||
|
QTest::ignoreMessage(QtWarningMsg, "isThreaded called with event set to nullptr.");
|
||||||
|
QCOMPARE(EventHandler::isThreaded(nullptr), false);
|
||||||
|
|
||||||
|
QTest::ignoreMessage(QtWarningMsg, "threadRoot called with event set to nullptr.");
|
||||||
|
QCOMPARE(EventHandler::threadRoot(nullptr), QString());
|
||||||
|
}
|
||||||
|
|
||||||
void EventHandlerTest::location()
|
void EventHandlerTest::location()
|
||||||
{
|
{
|
||||||
QCOMPARE(EventHandler::latitude(room->messageEvents().at(7).get()), u"51.7035"_s.toFloat());
|
QCOMPARE(EventHandler::latitude(room->messageEvents().at(7).get()), QStringLiteral("51.7035").toFloat());
|
||||||
QCOMPARE(EventHandler::longitude(room->messageEvents().at(7).get()), u"-1.14394"_s.toFloat());
|
QCOMPARE(EventHandler::longitude(room->messageEvents().at(7).get()), QStringLiteral("-1.14394").toFloat());
|
||||||
QCOMPARE(EventHandler::locationAssetType(room->messageEvents().at(7).get()), u"m.pin"_s);
|
QCOMPARE(EventHandler::locationAssetType(room->messageEvents().at(7).get()), QStringLiteral("m.pin"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void EventHandlerTest::nullLocation()
|
void EventHandlerTest::nullLocation()
|
||||||
|
|||||||
@@ -38,8 +38,8 @@ private Q_SLOTS:
|
|||||||
|
|
||||||
void LinkPreviewerTest::initTestCase()
|
void LinkPreviewerTest::initTestCase()
|
||||||
{
|
{
|
||||||
connection = Connection::makeMockConnection(u"@bob:example.org"_s);
|
connection = Connection::makeMockConnection(QStringLiteral("@bob:example.org"));
|
||||||
room = new TestUtils::TestRoom(connection, u"!test:example.org"_s);
|
room = new TestUtils::TestRoom(connection, QStringLiteral("!test:example.org"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void LinkPreviewerTest::linkPreviewsMatch_data()
|
void LinkPreviewerTest::linkPreviewsMatch_data()
|
||||||
@@ -47,9 +47,9 @@ void LinkPreviewerTest::linkPreviewsMatch_data()
|
|||||||
QTest::addColumn<QString>("inputString");
|
QTest::addColumn<QString>("inputString");
|
||||||
QTest::addColumn<QUrl>("testOutputLink");
|
QTest::addColumn<QUrl>("testOutputLink");
|
||||||
|
|
||||||
QTest::newRow("plainHttps") << u"https://kde.org"_s << QUrl(u"https://kde.org"_s);
|
QTest::newRow("plainHttps") << QStringLiteral("https://kde.org") << QUrl("https://kde.org"_ls);
|
||||||
QTest::newRow("richHttps") << u"<a href=\"https://kde.org\">Rich Link</a>"_s << QUrl(u"https://kde.org"_s);
|
QTest::newRow("richHttps") << QStringLiteral("<a href=\"https://kde.org\">Rich Link</a>") << QUrl("https://kde.org"_ls);
|
||||||
QTest::newRow("richHttpsLinkDescription") << u"<a href=\"https://kde.org\">https://kde.org</a>"_s << QUrl(u"https://kde.org"_s);
|
QTest::newRow("richHttpsLinkDescription") << QStringLiteral("<a href=\"https://kde.org\">https://kde.org</a>") << QUrl("https://kde.org"_ls);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LinkPreviewerTest::linkPreviewsMatch()
|
void LinkPreviewerTest::linkPreviewsMatch()
|
||||||
@@ -67,8 +67,8 @@ void LinkPreviewerTest::multipleLinkPreviewsMatch_data()
|
|||||||
QTest::addColumn<QString>("inputString");
|
QTest::addColumn<QString>("inputString");
|
||||||
QTest::addColumn<QList<QUrl>>("testOutputLinks");
|
QTest::addColumn<QList<QUrl>>("testOutputLinks");
|
||||||
|
|
||||||
QTest::newRow("multipleHttps") << u"www.example.org https://kde.org"_s << QList{QUrl(u"www.example.org"_s), QUrl(u"https://kde.org"_s)};
|
QTest::newRow("multipleHttps") << QStringLiteral("www.example.org https://kde.org") << QList{QUrl("www.example.org"_ls), QUrl("https://kde.org"_ls)};
|
||||||
QTest::newRow("multipleHttps1Invalid") << u"www.example.org mxc://example.org/SEsfnsuifSDFSSEF"_s << QList{QUrl(u"www.example.org"_s)};
|
QTest::newRow("multipleHttps1Invalid") << QStringLiteral("www.example.org mxc://example.org/SEsfnsuifSDFSSEF") << QList{QUrl("www.example.org"_ls)};
|
||||||
}
|
}
|
||||||
|
|
||||||
void LinkPreviewerTest::multipleLinkPreviewsMatch()
|
void LinkPreviewerTest::multipleLinkPreviewsMatch()
|
||||||
@@ -85,9 +85,9 @@ void LinkPreviewerTest::linkPreviewsReject_data()
|
|||||||
{
|
{
|
||||||
QTest::addColumn<QString>("inputString");
|
QTest::addColumn<QString>("inputString");
|
||||||
|
|
||||||
QTest::newRow("mxc") << u"mxc://example.org/SEsfnsuifSDFSSEF"_s;
|
QTest::newRow("mxc") << QStringLiteral("mxc://example.org/SEsfnsuifSDFSSEF");
|
||||||
QTest::newRow("matrixTo") << u"https://matrix.to/#/@alice:example.org"_s;
|
QTest::newRow("matrixTo") << QStringLiteral("https://matrix.to/#/@alice:example.org");
|
||||||
QTest::newRow("noSpace") << u"testhttps://kde.org"_s;
|
QTest::newRow("noSpace") << QStringLiteral("testhttps://kde.org");
|
||||||
}
|
}
|
||||||
|
|
||||||
void LinkPreviewerTest::linkPreviewsReject()
|
void LinkPreviewerTest::linkPreviewsReject()
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ private Q_SLOTS:
|
|||||||
void MediaSizeHelperTest::uninitialized()
|
void MediaSizeHelperTest::uninitialized()
|
||||||
{
|
{
|
||||||
MediaSizeHelper mediasizehelper;
|
MediaSizeHelper mediasizehelper;
|
||||||
mediasizehelper.setMaxSize(540, 540);
|
|
||||||
QCOMPARE(mediasizehelper.currentSize(), QSize(540, qRound(qreal(NeoChatConfig::self()->mediaMaxWidth()) / qreal(16.0) * qreal(9.0))));
|
QCOMPARE(mediasizehelper.currentSize(), QSize(540, qRound(qreal(NeoChatConfig::self()->mediaMaxWidth()) / qreal(16.0) * qreal(9.0))));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,7 +60,6 @@ void MediaSizeHelperTest::limits()
|
|||||||
QFETCH(QSize, currentSize);
|
QFETCH(QSize, currentSize);
|
||||||
|
|
||||||
MediaSizeHelper mediasizehelper;
|
MediaSizeHelper mediasizehelper;
|
||||||
mediasizehelper.setMaxSize(540, 540);
|
|
||||||
mediasizehelper.setMediaWidth(mediaWidth);
|
mediasizehelper.setMediaWidth(mediaWidth);
|
||||||
mediasizehelper.setMediaHeight(mediaHeight);
|
mediasizehelper.setMediaHeight(mediaHeight);
|
||||||
mediasizehelper.setContentMaxWidth(contentMaxWidth);
|
mediasizehelper.setContentMaxWidth(contentMaxWidth);
|
||||||
|
|||||||
@@ -12,7 +12,6 @@
|
|||||||
|
|
||||||
#include "models/messagecontentmodel.h"
|
#include "models/messagecontentmodel.h"
|
||||||
|
|
||||||
#include "neochatconnection.h"
|
|
||||||
#include "testutils.h"
|
#include "testutils.h"
|
||||||
|
|
||||||
using namespace Quotient;
|
using namespace Quotient;
|
||||||
@@ -33,25 +32,25 @@ private Q_SLOTS:
|
|||||||
|
|
||||||
void MessageContentModelTest::initTestCase()
|
void MessageContentModelTest::initTestCase()
|
||||||
{
|
{
|
||||||
connection = new NeoChatConnection;
|
connection = Connection::makeMockConnection(QStringLiteral("@bob:kde.org"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageContentModelTest::missingEvent()
|
void MessageContentModelTest::missingEvent()
|
||||||
{
|
{
|
||||||
auto room = new TestUtils::TestRoom(connection, u"#firstRoom:kde.org"_s);
|
auto room = new TestUtils::TestRoom(connection, QStringLiteral("#firstRoom:kde.org"));
|
||||||
auto model1 = MessageContentModel(room, u"$153456789:example.org"_s);
|
auto model1 = MessageContentModel(room, "$153456789:example.org"_L1);
|
||||||
|
|
||||||
QCOMPARE(model1.rowCount(), 1);
|
QCOMPARE(model1.rowCount(), 1);
|
||||||
QCOMPARE(model1.data(model1.index(0), MessageContentModel::ComponentTypeRole), MessageComponentType::Loading);
|
QCOMPARE(model1.data(model1.index(0), MessageContentModel::ComponentTypeRole), MessageComponentType::Loading);
|
||||||
QCOMPARE(model1.data(model1.index(0), MessageContentModel::DisplayRole), u"Loading"_s);
|
QCOMPARE(model1.data(model1.index(0), MessageContentModel::DisplayRole), "Loading"_L1);
|
||||||
|
|
||||||
auto model2 = MessageContentModel(room, u"$153456789:example.org"_s, true);
|
auto model2 = MessageContentModel(room, "$153456789:example.org"_L1, true);
|
||||||
|
|
||||||
QCOMPARE(model2.rowCount(), 1);
|
QCOMPARE(model2.rowCount(), 1);
|
||||||
QCOMPARE(model2.data(model2.index(0), MessageContentModel::ComponentTypeRole), MessageComponentType::Loading);
|
QCOMPARE(model2.data(model2.index(0), MessageContentModel::ComponentTypeRole), MessageComponentType::Loading);
|
||||||
QCOMPARE(model2.data(model2.index(0), MessageContentModel::DisplayRole), u"Loading reply"_s);
|
QCOMPARE(model2.data(model2.index(0), MessageContentModel::DisplayRole), "Loading reply"_L1);
|
||||||
|
|
||||||
room->syncNewEvents(u"test-min-sync.json"_s);
|
room->syncNewEvents(QLatin1String("test-min-sync.json"));
|
||||||
QCOMPARE(model1.rowCount(), 2);
|
QCOMPARE(model1.rowCount(), 2);
|
||||||
QCOMPARE(model1.data(model1.index(0), MessageContentModel::ComponentTypeRole), MessageComponentType::Author);
|
QCOMPARE(model1.data(model1.index(0), MessageContentModel::ComponentTypeRole), MessageComponentType::Author);
|
||||||
QCOMPARE(model1.data(model1.index(1), MessageContentModel::ComponentTypeRole), MessageComponentType::Text);
|
QCOMPARE(model1.data(model1.index(1), MessageContentModel::ComponentTypeRole), MessageComponentType::Text);
|
||||||
|
|||||||
@@ -10,20 +10,20 @@
|
|||||||
#include <Quotient/syncdata.h>
|
#include <Quotient/syncdata.h>
|
||||||
|
|
||||||
#include "enums/delegatetype.h"
|
#include "enums/delegatetype.h"
|
||||||
#include "models/timelinemessagemodel.h"
|
#include "models/messageeventmodel.h"
|
||||||
#include "neochatroom.h"
|
#include "neochatroom.h"
|
||||||
|
|
||||||
#include "testutils.h"
|
#include "testutils.h"
|
||||||
|
|
||||||
using namespace Quotient;
|
using namespace Quotient;
|
||||||
|
|
||||||
class TimelineMessageModelTest : public QObject
|
class MessageEventModelTest : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Connection *connection = nullptr;
|
Connection *connection = nullptr;
|
||||||
TimelineMessageModel *model = nullptr;
|
MessageEventModel *model = nullptr;
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void initTestCase();
|
void initTestCase();
|
||||||
@@ -40,70 +40,70 @@ private Q_SLOTS:
|
|||||||
void cleanup();
|
void cleanup();
|
||||||
};
|
};
|
||||||
|
|
||||||
void TimelineMessageModelTest::initTestCase()
|
void MessageEventModelTest::initTestCase()
|
||||||
{
|
{
|
||||||
connection = Connection::makeMockConnection(u"@bob:kde.org"_s);
|
connection = Connection::makeMockConnection(QStringLiteral("@bob:kde.org"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TimelineMessageModelTest::init()
|
void MessageEventModelTest::init()
|
||||||
{
|
{
|
||||||
QCOMPARE(model, nullptr);
|
QCOMPARE(model, nullptr);
|
||||||
model = new TimelineMessageModel;
|
model = new MessageEventModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure that basic empty rooms can be switched without crashing.
|
// Make sure that basic empty rooms can be switched without crashing.
|
||||||
void TimelineMessageModelTest::switchEmptyRoom()
|
void MessageEventModelTest::switchEmptyRoom()
|
||||||
{
|
{
|
||||||
auto firstRoom = new TestUtils::TestRoom(connection, u"#firstRoom:kde.org"_s);
|
auto firstRoom = new TestUtils::TestRoom(connection, QStringLiteral("#firstRoom:kde.org"));
|
||||||
auto secondRoom = new TestUtils::TestRoom(connection, u"#secondRoom:kde.org"_s);
|
auto secondRoom = new TestUtils::TestRoom(connection, QStringLiteral("#secondRoom:kde.org"));
|
||||||
|
|
||||||
QSignalSpy spy(model, SIGNAL(roomChanged(NeoChatRoom *, NeoChatRoom *)));
|
QSignalSpy spy(model, SIGNAL(roomChanged()));
|
||||||
|
|
||||||
QCOMPARE(model->room(), nullptr);
|
QCOMPARE(model->room(), nullptr);
|
||||||
model->setRoom(firstRoom);
|
model->setRoom(firstRoom);
|
||||||
QCOMPARE(spy.count(), 1);
|
QCOMPARE(spy.count(), 1);
|
||||||
QCOMPARE(model->room()->id(), u"#firstRoom:kde.org"_s);
|
QCOMPARE(model->room()->id(), QStringLiteral("#firstRoom:kde.org"));
|
||||||
model->setRoom(secondRoom);
|
model->setRoom(secondRoom);
|
||||||
QCOMPARE(spy.count(), 2);
|
QCOMPARE(spy.count(), 2);
|
||||||
QCOMPARE(model->room()->id(), u"#secondRoom:kde.org"_s);
|
QCOMPARE(model->room()->id(), QStringLiteral("#secondRoom:kde.org"));
|
||||||
model->setRoom(nullptr);
|
model->setRoom(nullptr);
|
||||||
QCOMPARE(spy.count(), 3);
|
QCOMPARE(spy.count(), 3);
|
||||||
QCOMPARE(model->room(), nullptr);
|
QCOMPARE(model->room(), nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure that rooms with some events can be switched without crashing
|
// Make sure that rooms with some events can be switched without crashing
|
||||||
void TimelineMessageModelTest::switchSyncedRoom()
|
void MessageEventModelTest::switchSyncedRoom()
|
||||||
{
|
{
|
||||||
auto firstRoom = new TestUtils::TestRoom(connection, u"#firstRoom:kde.org"_s, u"test-messageventmodel-sync.json"_s);
|
auto firstRoom = new TestUtils::TestRoom(connection, QStringLiteral("#firstRoom:kde.org"), QLatin1String("test-messageventmodel-sync.json"));
|
||||||
auto secondRoom = new TestUtils::TestRoom(connection, u"#secondRoom:kde.org"_s, u"test-messageventmodel-sync.json"_s);
|
auto secondRoom = new TestUtils::TestRoom(connection, QStringLiteral("#secondRoom:kde.org"), QLatin1String("test-messageventmodel-sync.json"));
|
||||||
|
|
||||||
QSignalSpy spy(model, SIGNAL(roomChanged(NeoChatRoom *, NeoChatRoom *)));
|
QSignalSpy spy(model, SIGNAL(roomChanged()));
|
||||||
|
|
||||||
QCOMPARE(model->room(), nullptr);
|
QCOMPARE(model->room(), nullptr);
|
||||||
model->setRoom(firstRoom);
|
model->setRoom(firstRoom);
|
||||||
QCOMPARE(spy.count(), 1);
|
QCOMPARE(spy.count(), 1);
|
||||||
QCOMPARE(model->room()->id(), u"#firstRoom:kde.org"_s);
|
QCOMPARE(model->room()->id(), QStringLiteral("#firstRoom:kde.org"));
|
||||||
model->setRoom(secondRoom);
|
model->setRoom(secondRoom);
|
||||||
QCOMPARE(spy.count(), 2);
|
QCOMPARE(spy.count(), 2);
|
||||||
QCOMPARE(model->room()->id(), u"#secondRoom:kde.org"_s);
|
QCOMPARE(model->room()->id(), QStringLiteral("#secondRoom:kde.org"));
|
||||||
model->setRoom(nullptr);
|
model->setRoom(nullptr);
|
||||||
QCOMPARE(spy.count(), 3);
|
QCOMPARE(spy.count(), 3);
|
||||||
QCOMPARE(model->room(), nullptr);
|
QCOMPARE(model->room(), nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TimelineMessageModelTest::simpleTimeline()
|
void MessageEventModelTest::simpleTimeline()
|
||||||
{
|
{
|
||||||
auto room = new TestUtils::TestRoom(connection, u"#myroom:kde.org"_s, u"test-messageventmodel-sync.json"_s);
|
auto room = new TestUtils::TestRoom(connection, QStringLiteral("#myroom:kde.org"), QLatin1String("test-messageventmodel-sync.json"));
|
||||||
|
|
||||||
model->setRoom(room);
|
model->setRoom(room);
|
||||||
QCOMPARE(model->rowCount(), 2);
|
QCOMPARE(model->rowCount(), 2);
|
||||||
|
|
||||||
QCOMPARE(model->data(model->index(0), TimelineMessageModel::DelegateTypeRole), DelegateType::State);
|
QCOMPARE(model->data(model->index(0), MessageEventModel::DelegateTypeRole), DelegateType::State);
|
||||||
QCOMPARE(model->data(model->index(0)), u"changed their display name to Example Changed"_s);
|
QCOMPARE(model->data(model->index(0)), QStringLiteral("changed their display name to Example Changed"));
|
||||||
|
|
||||||
QCOMPARE(model->data(model->index(1)), u"<b>This is an example<br>text message</b>"_s);
|
QCOMPARE(model->data(model->index(1)), QStringLiteral("<b>This is an example<br>text message</b>"));
|
||||||
QCOMPARE(model->data(model->index(1), TimelineMessageModel::DelegateTypeRole), DelegateType::Message);
|
QCOMPARE(model->data(model->index(1), MessageEventModel::DelegateTypeRole), DelegateType::Message);
|
||||||
QCOMPARE(model->data(model->index(1), TimelineMessageModel::EventIdRole), u"$153456789:example.org"_s);
|
QCOMPARE(model->data(model->index(1), MessageEventModel::EventIdRole), QStringLiteral("$153456789:example.org"));
|
||||||
|
|
||||||
QTest::ignoreMessage(QtWarningMsg, "Index QModelIndex(-1,-1,0x0,QObject(0x0)) is not valid (expected valid)");
|
QTest::ignoreMessage(QtWarningMsg, "Index QModelIndex(-1,-1,0x0,QObject(0x0)) is not valid (expected valid)");
|
||||||
QCOMPARE(model->data(model->index(-1)), QVariant());
|
QCOMPARE(model->data(model->index(-1)), QVariant());
|
||||||
@@ -111,37 +111,33 @@ void TimelineMessageModelTest::simpleTimeline()
|
|||||||
QCOMPARE(model->data(model->index(model->rowCount())), QVariant());
|
QCOMPARE(model->data(model->index(model->rowCount())), QVariant());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sync some events into the TimelineMessageModel's current room and don't crash.
|
// Sync some events into the MessageEventModel's current room and don't crash.
|
||||||
void TimelineMessageModelTest::syncNewEvents()
|
void MessageEventModelTest::syncNewEvents()
|
||||||
{
|
{
|
||||||
auto room = new TestUtils::TestRoom(connection, u"#myroom:kde.org"_s);
|
auto room = new TestUtils::TestRoom(connection, QStringLiteral("#myroom:kde.org"));
|
||||||
QSignalSpy spy(room, SIGNAL(aboutToAddNewMessages(Quotient::RoomEventsRange)));
|
QSignalSpy spy(room, SIGNAL(aboutToAddNewMessages(Quotient::RoomEventsRange)));
|
||||||
|
|
||||||
model->setRoom(room);
|
model->setRoom(room);
|
||||||
QCOMPARE(model->rowCount(), 0);
|
QCOMPARE(model->rowCount(), 0);
|
||||||
|
|
||||||
room->syncNewEvents(u"test-messageventmodel-sync.json"_s);
|
room->syncNewEvents(QLatin1String("test-messageventmodel-sync.json"));
|
||||||
|
|
||||||
QCOMPARE(model->rowCount(), 2);
|
QCOMPARE(model->rowCount(), 2);
|
||||||
QCOMPARE(spy.count(), 1);
|
QCOMPARE(spy.count(), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check the adding of pending events to the room doesn't cause any issues in the model.
|
// Check the adding of pending events to the room doesn't cause any issues in the model.
|
||||||
void TimelineMessageModelTest::pendingEvent()
|
void MessageEventModelTest::pendingEvent()
|
||||||
{
|
{
|
||||||
QSignalSpy spyInsert(model, SIGNAL(rowsInserted(const QModelIndex &, int, int)));
|
QSignalSpy spyInsert(model, SIGNAL(rowsInserted(const QModelIndex &, int, int)));
|
||||||
QSignalSpy spyRemove(model, SIGNAL(rowsRemoved(const QModelIndex &, int, int)));
|
QSignalSpy spyRemove(model, SIGNAL(rowsRemoved(const QModelIndex &, int, int)));
|
||||||
QSignalSpy spyChanged(model, SIGNAL(dataChanged(const QModelIndex, const QModelIndex, const QList<int> &)));
|
QSignalSpy spyChanged(model, SIGNAL(dataChanged(const QModelIndex, const QModelIndex, const QList<int> &)));
|
||||||
|
|
||||||
auto room = new TestUtils::TestRoom(connection, u"#myroom:kde.org"_s);
|
auto room = new TestUtils::TestRoom(connection, QStringLiteral("#myroom:kde.org"));
|
||||||
model->setRoom(room);
|
model->setRoom(room);
|
||||||
QCOMPARE(model->rowCount(), 0);
|
QCOMPARE(model->rowCount(), 0);
|
||||||
|
|
||||||
#if Quotient_VERSION_MINOR > 9
|
auto txnId = room->postPlainText("New plain message"_ls);
|
||||||
auto txnId = room->postText("New plain message"_L1);
|
|
||||||
#else
|
|
||||||
auto txnId = room->postPlainText("New plain message"_L1);
|
|
||||||
#endif
|
|
||||||
QCOMPARE(model->rowCount(), 1);
|
QCOMPARE(model->rowCount(), 1);
|
||||||
QCOMPARE(spyInsert.count(), 1);
|
QCOMPARE(spyInsert.count(), 1);
|
||||||
|
|
||||||
@@ -149,30 +145,26 @@ void TimelineMessageModelTest::pendingEvent()
|
|||||||
QCOMPARE(model->rowCount(), 0);
|
QCOMPARE(model->rowCount(), 0);
|
||||||
QCOMPARE(spyRemove.count(), 1);
|
QCOMPARE(spyRemove.count(), 1);
|
||||||
|
|
||||||
#if Quotient_VERSION_MINOR > 9
|
txnId = room->postPlainText("New plain message"_ls);
|
||||||
txnId = room->postText("New plain message"_L1);
|
|
||||||
#else
|
|
||||||
txnId = room->postPlainText("New plain message"_L1);
|
|
||||||
#endif
|
|
||||||
QCOMPARE(model->rowCount(), 1);
|
QCOMPARE(model->rowCount(), 1);
|
||||||
QCOMPARE(spyInsert.count(), 2);
|
QCOMPARE(spyInsert.count(), 2);
|
||||||
|
|
||||||
// We need to manually set the transaction ID of the new message as it will be
|
// We need to manually set the transaction ID of the new message as it will be
|
||||||
// different every time.
|
// different every time.
|
||||||
QFile testSyncFile;
|
QFile testSyncFile;
|
||||||
testSyncFile.setFileName(QStringLiteral(DATA_DIR) + u'/' + u"test-pending-sync.json"_s);
|
testSyncFile.setFileName(QLatin1String(DATA_DIR) + u'/' + QLatin1String("test-pending-sync.json"));
|
||||||
testSyncFile.open(QIODevice::ReadOnly);
|
testSyncFile.open(QIODevice::ReadOnly);
|
||||||
auto testSyncJson = QJsonDocument::fromJson(testSyncFile.readAll());
|
auto testSyncJson = QJsonDocument::fromJson(testSyncFile.readAll());
|
||||||
auto root = testSyncJson.object();
|
auto root = testSyncJson.object();
|
||||||
auto timeline = root["timeline"_L1].toObject();
|
auto timeline = root["timeline"_ls].toObject();
|
||||||
auto events = timeline["events"_L1].toArray();
|
auto events = timeline["events"_ls].toArray();
|
||||||
auto firstEvent = events[0].toObject();
|
auto firstEvent = events[0].toObject();
|
||||||
firstEvent.insert("unsigned"_L1, QJsonObject{{"transaction_id"_L1, txnId}});
|
firstEvent.insert(QLatin1String("unsigned"), QJsonObject{{QLatin1String("transaction_id"), txnId}});
|
||||||
events[0] = firstEvent;
|
events[0] = firstEvent;
|
||||||
timeline.insert("events"_L1, events);
|
timeline.insert("events"_ls, events);
|
||||||
root.insert("timeline"_L1, timeline);
|
root.insert("timeline"_ls, timeline);
|
||||||
testSyncJson.setObject(root);
|
testSyncJson.setObject(root);
|
||||||
SyncRoomData roomData(u"@bob:kde.org"_s, JoinState::Join, testSyncJson.object());
|
SyncRoomData roomData(QStringLiteral("@bob:kde.org"), JoinState::Join, testSyncJson.object());
|
||||||
room->update(std::move(roomData));
|
room->update(std::move(roomData));
|
||||||
|
|
||||||
QCOMPARE(model->rowCount(), 1);
|
QCOMPARE(model->rowCount(), 1);
|
||||||
@@ -182,7 +174,7 @@ void TimelineMessageModelTest::pendingEvent()
|
|||||||
auto isPendingChanged = false;
|
auto isPendingChanged = false;
|
||||||
for (auto signal : spyChanged) {
|
for (auto signal : spyChanged) {
|
||||||
auto roles = signal.at(2).toList();
|
auto roles = signal.at(2).toList();
|
||||||
if (roles.contains(TimelineMessageModel::IsPendingRole)) {
|
if (roles.contains(MessageEventModel::IsPendingRole)) {
|
||||||
isPendingChanged = true;
|
isPendingChanged = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -190,33 +182,33 @@ void TimelineMessageModelTest::pendingEvent()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Make sure that the signals are disconnecting correctly when a room is switched.
|
// Make sure that the signals are disconnecting correctly when a room is switched.
|
||||||
void TimelineMessageModelTest::disconnect()
|
void MessageEventModelTest::disconnect()
|
||||||
{
|
{
|
||||||
auto room = new TestUtils::TestRoom(connection, u"#myroom:kde.org"_s);
|
auto room = new TestUtils::TestRoom(connection, QStringLiteral("#myroom:kde.org"));
|
||||||
model->setRoom(room);
|
model->setRoom(room);
|
||||||
|
|
||||||
QSignalSpy spy(model, SIGNAL(rowsInserted(const QModelIndex &, int, int)));
|
QSignalSpy spy(model, SIGNAL(rowsInserted(const QModelIndex &, int, int)));
|
||||||
|
|
||||||
model->setRoom(nullptr);
|
model->setRoom(nullptr);
|
||||||
room->syncNewEvents(u"test-messageventmodel-sync.json"_s);
|
room->syncNewEvents(QLatin1String("test-messageventmodel-sync.json"));
|
||||||
|
|
||||||
QCOMPARE(spy.count(), 0);
|
QCOMPARE(spy.count(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TimelineMessageModelTest::idToRow()
|
void MessageEventModelTest::idToRow()
|
||||||
{
|
{
|
||||||
auto room = new TestUtils::TestRoom(connection, u"#myroom:kde.org"_s, u"test-min-sync.json"_s);
|
auto room = new TestUtils::TestRoom(connection, QStringLiteral("#myroom:kde.org"), QLatin1String("test-min-sync.json"));
|
||||||
model->setRoom(room);
|
model->setRoom(room);
|
||||||
|
|
||||||
QCOMPARE(model->indexforEventId(u"$153456789:example.org"_s).row(), 0);
|
QCOMPARE(model->eventIdToRow(QStringLiteral("$153456789:example.org")), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TimelineMessageModelTest::cleanup()
|
void MessageEventModelTest::cleanup()
|
||||||
{
|
{
|
||||||
delete model;
|
delete model;
|
||||||
model = nullptr;
|
model = nullptr;
|
||||||
QCOMPARE(model, nullptr);
|
QCOMPARE(model, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
QTEST_MAIN(TimelineMessageModelTest)
|
QTEST_MAIN(MessageEventModelTest)
|
||||||
#include "timelinemessagemodeltest.moc"
|
#include "messageeventmodeltest.moc"
|
||||||
@@ -27,8 +27,8 @@ private Q_SLOTS:
|
|||||||
|
|
||||||
void NeoChatRoomTest::initTestCase()
|
void NeoChatRoomTest::initTestCase()
|
||||||
{
|
{
|
||||||
connection = Connection::makeMockConnection(u"@bob:kde.org"_s);
|
connection = Connection::makeMockConnection(QStringLiteral("@bob:kde.org"));
|
||||||
room = new TestUtils::TestRoom(connection, u"#myroom:kde.org"_s, u"test-min-sync.json"_s);
|
room = new TestUtils::TestRoom(connection, QStringLiteral("#myroom:kde.org"), "test-min-sync.json"_ls);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NeoChatRoomTest::eventTest()
|
void NeoChatRoomTest::eventTest()
|
||||||
|
|||||||
@@ -31,8 +31,8 @@ private Q_SLOTS:
|
|||||||
|
|
||||||
void PollHandlerTest::initTestCase()
|
void PollHandlerTest::initTestCase()
|
||||||
{
|
{
|
||||||
connection = Connection::makeMockConnection(u"@bob:kde.org"_s);
|
connection = Connection::makeMockConnection(QStringLiteral("@bob:kde.org"));
|
||||||
room = new TestUtils::TestRoom(connection, u"#myroom:kde.org"_s, u"test-pollhandlerstart-sync.json"_s);
|
room = new TestUtils::TestRoom(connection, QStringLiteral("#myroom:kde.org"), "test-pollhandlerstart-sync.json"_ls);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Basically don't crash.
|
// Basically don't crash.
|
||||||
@@ -41,32 +41,29 @@ void PollHandlerTest::nullObject()
|
|||||||
auto pollHandler = PollHandler();
|
auto pollHandler = PollHandler();
|
||||||
|
|
||||||
QCOMPARE(pollHandler.hasEnded(), false);
|
QCOMPARE(pollHandler.hasEnded(), false);
|
||||||
QCOMPARE(pollHandler.numAnswers(), 0);
|
QCOMPARE(pollHandler.answerCount(), 0);
|
||||||
QCOMPARE(pollHandler.question(), QString());
|
QCOMPARE(pollHandler.question(), QString());
|
||||||
QCOMPARE(pollHandler.kind(), PollKind::Disclosed);
|
QCOMPARE(pollHandler.options(), QJsonArray());
|
||||||
|
QCOMPARE(pollHandler.answers(), QJsonObject());
|
||||||
|
QCOMPARE(pollHandler.counts(), QJsonObject());
|
||||||
|
QCOMPARE(pollHandler.kind(), QString());
|
||||||
}
|
}
|
||||||
|
|
||||||
void PollHandlerTest::poll()
|
void PollHandlerTest::poll()
|
||||||
{
|
{
|
||||||
auto startEvent = eventCast<const PollStartEvent>(room->messageEvents().at(0).get());
|
auto startEvent = eventCast<const PollStartEvent>(room->messageEvents().at(0).get());
|
||||||
auto pollHandler = PollHandler(room, startEvent->id());
|
auto pollHandler = PollHandler(room, startEvent);
|
||||||
|
|
||||||
QList<Quotient::EventContent::Answer> options = {EventContent::Answer{"option1"_L1, "option1"_L1}, EventContent::Answer{"option2"_L1, "option2"_L1}};
|
auto options = QJsonArray{QJsonObject{{"id"_ls, "option1"_ls}, {"org.matrix.msc1767.text"_ls, "option1"_ls}},
|
||||||
|
QJsonObject{{"id"_ls, "option2"_ls}, {"org.matrix.msc1767.text"_ls, "option2"_ls}}};
|
||||||
|
|
||||||
const auto answer0 = pollHandler.answerAtRow(0);
|
|
||||||
const auto answer1 = pollHandler.answerAtRow(1);
|
|
||||||
QCOMPARE(pollHandler.hasEnded(), false);
|
QCOMPARE(pollHandler.hasEnded(), false);
|
||||||
QCOMPARE(pollHandler.numAnswers(), 2);
|
QCOMPARE(pollHandler.answerCount(), 0);
|
||||||
QCOMPARE(pollHandler.question(), u"test"_s);
|
QCOMPARE(pollHandler.question(), QStringLiteral("test"));
|
||||||
QCOMPARE(answer0.id, "option1"_L1);
|
QCOMPARE(pollHandler.options(), options);
|
||||||
QCOMPARE(answer1.id, "option2"_L1);
|
QCOMPARE(pollHandler.answers(), QJsonObject());
|
||||||
QCOMPARE(answer0.text, "option1text"_L1);
|
QCOMPARE(pollHandler.counts(), QJsonObject());
|
||||||
QCOMPARE(answer1.text, "option2text"_L1);
|
QCOMPARE(pollHandler.kind(), QStringLiteral("org.matrix.msc3381.poll.disclosed"));
|
||||||
QCOMPARE(pollHandler.answerCountAtId(answer0.id), 0);
|
|
||||||
QCOMPARE(pollHandler.answerCountAtId(answer1.id), 0);
|
|
||||||
QCOMPARE(pollHandler.checkMemberSelectedId(connection->userId(), answer0.id), false);
|
|
||||||
QCOMPARE(pollHandler.checkMemberSelectedId(connection->userId(), answer1.id), false);
|
|
||||||
QCOMPARE(pollHandler.kind(), PollKind::Undisclosed);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QTEST_GUILESS_MAIN(PollHandlerTest)
|
QTEST_GUILESS_MAIN(PollHandlerTest)
|
||||||
|
|||||||
@@ -9,7 +9,6 @@
|
|||||||
|
|
||||||
#include <Quotient/events/roommessageevent.h>
|
#include <Quotient/events/roommessageevent.h>
|
||||||
|
|
||||||
#include "models/messagecontentmodel.h"
|
|
||||||
#include "testutils.h"
|
#include "testutils.h"
|
||||||
|
|
||||||
using namespace Quotient;
|
using namespace Quotient;
|
||||||
@@ -21,50 +20,59 @@ class ReactionModelTest : public QObject
|
|||||||
private:
|
private:
|
||||||
Connection *connection = nullptr;
|
Connection *connection = nullptr;
|
||||||
TestUtils::TestRoom *room = nullptr;
|
TestUtils::TestRoom *room = nullptr;
|
||||||
MessageContentModel *parentModel;
|
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void initTestCase();
|
void initTestCase();
|
||||||
|
|
||||||
|
void nullModel();
|
||||||
void basicReaction();
|
void basicReaction();
|
||||||
void newReaction();
|
void newReaction();
|
||||||
};
|
};
|
||||||
|
|
||||||
void ReactionModelTest::initTestCase()
|
void ReactionModelTest::initTestCase()
|
||||||
{
|
{
|
||||||
connection = Connection::makeMockConnection(u"@bob:kde.org"_s);
|
connection = Connection::makeMockConnection(QStringLiteral("@bob:kde.org"));
|
||||||
room = new TestUtils::TestRoom(connection, u"#myroom:kde.org"_s, u"test-reactionmodel-sync.json"_s);
|
room = new TestUtils::TestRoom(connection, QStringLiteral("#myroom:kde.org"), QLatin1String("test-reactionmodel-sync.json"));
|
||||||
parentModel = new MessageContentModel(room, "123456"_L1);
|
}
|
||||||
|
|
||||||
|
void ReactionModelTest::nullModel()
|
||||||
|
{
|
||||||
|
auto model = ReactionModel(nullptr, nullptr);
|
||||||
|
|
||||||
|
QCOMPARE(model.rowCount(), 0);
|
||||||
|
QCOMPARE(model.data(model.index(0), ReactionModel::TextContentRole), QVariant());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReactionModelTest::basicReaction()
|
void ReactionModelTest::basicReaction()
|
||||||
{
|
{
|
||||||
auto event = eventCast<const RoomMessageEvent>(room->messageEvents().at(0).get());
|
auto event = eventCast<const RoomMessageEvent>(room->messageEvents().at(0).get());
|
||||||
auto model = ReactionModel(parentModel, event->id(), room);
|
auto model = ReactionModel(event, room);
|
||||||
|
|
||||||
QCOMPARE(model.rowCount(), 1);
|
QCOMPARE(model.rowCount(), 1);
|
||||||
QCOMPARE(model.data(model.index(0), ReactionModel::TextContentRole), u"<span style=\"font-family: 'emoji';\">👍</span>"_s);
|
QCOMPARE(model.data(model.index(0), ReactionModel::TextContentRole), QStringLiteral("<span style=\"font-family: 'emoji';\">👍</span>"));
|
||||||
QCOMPARE(model.data(model.index(0), ReactionModel::ReactionRole), u"👍"_s);
|
QCOMPARE(model.data(model.index(0), ReactionModel::ReactionRole), QStringLiteral("👍"));
|
||||||
QCOMPARE(model.data(model.index(0), ReactionModel::ToolTipRole), u"Alice Margatroid reacted with <span style=\"font-family: 'emoji';\">👍</span>"_s);
|
QCOMPARE(model.data(model.index(0), ReactionModel::ToolTipRole),
|
||||||
|
QStringLiteral("Alice Margatroid reacted with <span style=\"font-family: 'emoji';\">👍</span>"));
|
||||||
QCOMPARE(model.data(model.index(0), ReactionModel::HasLocalMember), false);
|
QCOMPARE(model.data(model.index(0), ReactionModel::HasLocalMember), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ReactionModelTest::newReaction()
|
void ReactionModelTest::newReaction()
|
||||||
{
|
{
|
||||||
auto event = eventCast<const RoomMessageEvent>(room->messageEvents().at(0).get());
|
auto event = eventCast<const RoomMessageEvent>(room->messageEvents().at(0).get());
|
||||||
auto model = new ReactionModel(parentModel, event->id(), room);
|
auto model = new ReactionModel(event, room);
|
||||||
|
|
||||||
QCOMPARE(model->rowCount(), 1);
|
QCOMPARE(model->rowCount(), 1);
|
||||||
QCOMPARE(model->data(model->index(0), ReactionModel::ToolTipRole), u"Alice Margatroid reacted with <span style=\"font-family: 'emoji';\">👍</span>"_s);
|
QCOMPARE(model->data(model->index(0), ReactionModel::ToolTipRole),
|
||||||
|
QStringLiteral("Alice Margatroid reacted with <span style=\"font-family: 'emoji';\">👍</span>"));
|
||||||
|
|
||||||
QSignalSpy spy(model, SIGNAL(modelReset()));
|
QSignalSpy spy(model, SIGNAL(modelReset()));
|
||||||
|
|
||||||
room->syncNewEvents(u"test-reactionmodel-extra-sync.json"_s);
|
room->syncNewEvents(QLatin1String("test-reactionmodel-extra-sync.json"));
|
||||||
QCOMPARE(model->rowCount(), 2);
|
QCOMPARE(model->rowCount(), 2);
|
||||||
QCOMPARE(spy.count(), 2); // Once for each of the 2 new reactions.
|
QCOMPARE(spy.count(), 2); // Once for each of the 2 new reactions.
|
||||||
QCOMPARE(model->data(model->index(1), ReactionModel::ReactionRole), u"😆"_s);
|
QCOMPARE(model->data(model->index(1), ReactionModel::ReactionRole), QStringLiteral("😆"));
|
||||||
QCOMPARE(model->data(model->index(0), ReactionModel::ToolTipRole),
|
QCOMPARE(model->data(model->index(0), ReactionModel::ToolTipRole),
|
||||||
u"Alice Margatroid and Bob reacted with <span style=\"font-family: 'emoji';\">👍</span>"_s);
|
QStringLiteral("Alice Margatroid and Bob reacted with <span style=\"font-family: 'emoji';\">👍</span>"));
|
||||||
|
|
||||||
delete model;
|
delete model;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,235 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: 2025 Tobias Fella <tobias.fella@kde.org>
|
|
||||||
// SPDX-License-Identifier: LGPL-2.0-or-later
|
|
||||||
|
|
||||||
#include "server.h"
|
|
||||||
|
|
||||||
#include <QFile>
|
|
||||||
#include <QHttpServer>
|
|
||||||
#include <QHttpServerResponder>
|
|
||||||
#include <QJsonArray>
|
|
||||||
#include <QJsonDocument>
|
|
||||||
#include <QJsonObject>
|
|
||||||
#include <QNetworkReply>
|
|
||||||
#include <QSslCertificate>
|
|
||||||
#include <QSslKey>
|
|
||||||
#include <QSslServer>
|
|
||||||
#include <QUuid>
|
|
||||||
|
|
||||||
#include <Quotient/networkaccessmanager.h>
|
|
||||||
|
|
||||||
using namespace Qt::Literals::StringLiterals;
|
|
||||||
|
|
||||||
QString generateEventId()
|
|
||||||
{
|
|
||||||
return u"$"_s + QString::fromLatin1(QCryptographicHash::hash(QUuid::createUuid().toString().toLatin1(), QCryptographicHash::Sha1).toBase64());
|
|
||||||
}
|
|
||||||
|
|
||||||
QString generateRoomId()
|
|
||||||
{
|
|
||||||
return u"!%1:localhost:1234"_s
|
|
||||||
.arg(QString::fromLatin1(QCryptographicHash::hash(QUuid::createUuid().toString().toLatin1(), QCryptographicHash::Sha1).toBase64()))
|
|
||||||
.replace(u'/', QChar());
|
|
||||||
}
|
|
||||||
|
|
||||||
Server::Server()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void Server::start()
|
|
||||||
{
|
|
||||||
QObject::connect(Quotient::NetworkAccessManager::instance(),
|
|
||||||
&QNetworkAccessManager::sslErrors,
|
|
||||||
Quotient::NetworkAccessManager::instance(),
|
|
||||||
[](QNetworkReply *reply) {
|
|
||||||
reply->ignoreSslErrors();
|
|
||||||
});
|
|
||||||
m_server.route(u"/.well-known/matrix/client"_s, QHttpServerRequest::Method::Get, [](QHttpServerResponder &responder) {
|
|
||||||
responder.write(QJsonDocument(QJsonObject{
|
|
||||||
{u"m.homeserver"_s, QJsonObject{{u"base_url"_s, u"https://localhost:1234"_s}}},
|
|
||||||
}),
|
|
||||||
QHttpServerResponder::StatusCode::Ok);
|
|
||||||
});
|
|
||||||
m_server.route(u"/_matrix/client/versions"_s, QHttpServerRequest::Method::Get, [](QHttpServerResponder &responder) {
|
|
||||||
responder.write(QJsonDocument(QJsonObject{
|
|
||||||
{u"versions"_s,
|
|
||||||
QJsonArray{
|
|
||||||
u"v1.0"_s,
|
|
||||||
u"v1.1"_s,
|
|
||||||
u"v1.2"_s,
|
|
||||||
u"v1.3"_s,
|
|
||||||
u"v1.4"_s,
|
|
||||||
u"v1.5"_s,
|
|
||||||
u"v1.6"_s,
|
|
||||||
u"v1.7"_s,
|
|
||||||
u"v1.8"_s,
|
|
||||||
u"v1.9"_s,
|
|
||||||
u"v1.10"_s,
|
|
||||||
u"v1.11"_s,
|
|
||||||
u"v1.12"_s,
|
|
||||||
u"v1.13"_s,
|
|
||||||
}},
|
|
||||||
}),
|
|
||||||
QHttpServerResponder::StatusCode::Ok);
|
|
||||||
});
|
|
||||||
m_server.route(u"/_matrix/client/v3/capabilities"_s, QHttpServerRequest::Method::Get, [](QHttpServerResponder &responder) {
|
|
||||||
responder.write(
|
|
||||||
QJsonDocument(QJsonObject{{u"capabilities"_s,
|
|
||||||
QJsonObject{
|
|
||||||
{u"m.room_versions"_s, QJsonObject{{u"m.available"_s, QJsonObject{{u"1"_s, u"stable"_s}}}, {u"default"_s, u"1"_s}}},
|
|
||||||
}}}),
|
|
||||||
QHttpServerResponder::StatusCode::Ok);
|
|
||||||
});
|
|
||||||
m_server.route(u"/_matrix/client/v3/account/whoami"_s, QHttpServerRequest::Method::Get, [](QHttpServerResponder &responder) {
|
|
||||||
responder.write(QJsonDocument(QJsonObject{
|
|
||||||
{u"device_id"_s, u"device_id_1234"_s},
|
|
||||||
{u"user_id"_s, u"@user:localhost:1234"_s},
|
|
||||||
}),
|
|
||||||
QHttpServerResponder::StatusCode::Ok);
|
|
||||||
});
|
|
||||||
|
|
||||||
m_server.route(u"/_matrix/client/v3/login"_s, QHttpServerRequest::Method::Post, [](QHttpServerResponder &responder) {
|
|
||||||
// TODO
|
|
||||||
// if data["identifier"]["user"] != "user" or data["password"] != "1234":
|
|
||||||
// abort(403)
|
|
||||||
responder.write(QJsonDocument(QJsonObject{
|
|
||||||
{u"access_token"_s, u"token_login"_s},
|
|
||||||
{u"device_id"_s, u"device_1234"_s},
|
|
||||||
{u"user_id"_s, u"@user:localhost:1234"_s},
|
|
||||||
}),
|
|
||||||
QHttpServerResponder::StatusCode::Ok);
|
|
||||||
});
|
|
||||||
|
|
||||||
m_server.route(u"/_matrix/client/v3/login"_s, QHttpServerRequest::Method::Get, [](QHttpServerResponder &responder) {
|
|
||||||
responder.write(QJsonDocument(QJsonObject{
|
|
||||||
{u"flows"_s, QJsonArray{QJsonObject{{u"type"_s, u"m.login.password"_s}}}},
|
|
||||||
}),
|
|
||||||
QHttpServerResponder::StatusCode::Ok);
|
|
||||||
});
|
|
||||||
|
|
||||||
m_server.route(u"/_matrix/client/v3/rooms/<arg>/invite"_s,
|
|
||||||
QHttpServerRequest::Method::Post,
|
|
||||||
[this](const QString &roomId, QHttpServerResponder &responder, const QHttpServerRequest &request) {
|
|
||||||
m_invitedUsers[roomId] += QJsonDocument::fromJson(request.body()).object()[u"user_id"_s].toString();
|
|
||||||
responder.write(QJsonDocument(QJsonObject{}), QHttpServerResponder::StatusCode::Ok);
|
|
||||||
});
|
|
||||||
|
|
||||||
m_server.route(u"/_matrix/client/r0/sync"_s, QHttpServerRequest::Method::Get, [this](QHttpServerResponder &responder) {
|
|
||||||
QMap<QString, QJsonArray> stateEvents;
|
|
||||||
|
|
||||||
for (const auto &[roomId, matrixId] : m_roomsToCreate) {
|
|
||||||
stateEvents[roomId] += QJsonObject{
|
|
||||||
{u"content"_s, QJsonObject{{u"room_version"_s, u"11"_s}}},
|
|
||||||
{u"event_id"_s, generateEventId()},
|
|
||||||
{u"origin_server_ts"_s, QDateTime::currentMSecsSinceEpoch()},
|
|
||||||
{u"room_id"_s, roomId},
|
|
||||||
{u"sender"_s, matrixId},
|
|
||||||
{u"state_key"_s, QString()},
|
|
||||||
{u"type"_s, u"m.room.create"_s},
|
|
||||||
{u"unsigned"_s, QJsonObject{{u"age"_s, 1234}}},
|
|
||||||
};
|
|
||||||
stateEvents[roomId] += QJsonObject{
|
|
||||||
{u"content"_s, QJsonObject{{u"displayname"_s, u"User"_s}, {u"membership"_s, u"join"_s}}},
|
|
||||||
{u"event_id"_s, generateEventId()},
|
|
||||||
{u"origin_server_ts"_s, QDateTime::currentMSecsSinceEpoch()},
|
|
||||||
{u"room_id"_s, roomId},
|
|
||||||
{u"sender"_s, matrixId},
|
|
||||||
{u"state_key"_s, matrixId},
|
|
||||||
{u"type"_s, u"m.room.member"_s},
|
|
||||||
{u"unsigned"_s, QJsonObject{{u"age"_s, 1234}}},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
m_roomsToCreate.clear();
|
|
||||||
for (const auto &roomId : m_invitedUsers.keys()) {
|
|
||||||
const auto &values = m_invitedUsers[roomId];
|
|
||||||
for (const auto &value : values) {
|
|
||||||
stateEvents[roomId] += QJsonObject{
|
|
||||||
{u"content"_s, QJsonObject{{u"displayname"_s, u"User"_s}, {u"membership"_s, u"invite"_s}}},
|
|
||||||
{u"event_id"_s, generateEventId()},
|
|
||||||
{u"origin_server_ts"_s, QDateTime::currentMSecsSinceEpoch()},
|
|
||||||
{u"room_id"_s, roomId},
|
|
||||||
{u"sender"_s, u"@user:localhost:1234"_s},
|
|
||||||
{u"state_key"_s, value},
|
|
||||||
{u"type"_s, u"m.room.member"_s},
|
|
||||||
{u"unsigned"_s, QJsonObject{{u"age"_s, 1234}}},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_invitedUsers.clear();
|
|
||||||
|
|
||||||
for (const auto &roomId : m_bannedUsers.keys()) {
|
|
||||||
const auto &values = m_bannedUsers[roomId];
|
|
||||||
for (const auto &value : values) {
|
|
||||||
stateEvents[roomId] += QJsonObject{
|
|
||||||
{u"content"_s, QJsonObject{{u"displayname"_s, u"User"_s}, {u"membership"_s, u"ban"_s}}},
|
|
||||||
{u"event_id"_s, generateEventId()},
|
|
||||||
{u"origin_server_ts"_s, QDateTime::currentMSecsSinceEpoch()},
|
|
||||||
{u"room_id"_s, roomId},
|
|
||||||
{u"sender"_s, u"@user:localhost:1234"_s},
|
|
||||||
{u"state_key"_s, value},
|
|
||||||
{u"type"_s, u"m.room.member"_s},
|
|
||||||
{u"unsigned"_s, QJsonObject{{u"age"_s, 1234}}},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_bannedUsers.clear();
|
|
||||||
|
|
||||||
for (const auto &roomId : m_joinedUsers.keys()) {
|
|
||||||
const auto &values = m_joinedUsers[roomId];
|
|
||||||
for (const auto &value : values) {
|
|
||||||
stateEvents[roomId] += QJsonObject{
|
|
||||||
{u"content"_s, QJsonObject{{u"displayname"_s, u"User"_s}, {u"membership"_s, u"join"_s}}},
|
|
||||||
{u"event_id"_s, generateEventId()},
|
|
||||||
{u"origin_server_ts"_s, QDateTime::currentMSecsSinceEpoch()},
|
|
||||||
{u"room_id"_s, roomId},
|
|
||||||
{u"sender"_s, u"@user:localhost:1234"_s},
|
|
||||||
{u"state_key"_s, value},
|
|
||||||
{u"type"_s, u"m.room.member"_s},
|
|
||||||
{u"unsigned"_s, QJsonObject{{u"age"_s, 1234}}},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_joinedUsers.clear();
|
|
||||||
|
|
||||||
QJsonObject rooms;
|
|
||||||
for (const auto &roomId : stateEvents.keys()) {
|
|
||||||
rooms[roomId] = QJsonObject{{u"state"_s, QJsonObject{{u"events"_s, stateEvents[roomId]}}}};
|
|
||||||
}
|
|
||||||
|
|
||||||
responder.write(QJsonDocument(QJsonObject{{u"rooms"_s, QJsonObject{{u"join"_s, rooms}}}}), QHttpServerResponder::StatusCode::Ok);
|
|
||||||
});
|
|
||||||
|
|
||||||
QSslConfiguration config;
|
|
||||||
QFile key(QStringLiteral(DATA_DIR) + u"/localhost.key"_s);
|
|
||||||
key.open(QFile::ReadOnly);
|
|
||||||
config.setPrivateKey(QSslKey(&key, QSsl::Rsa));
|
|
||||||
config.setLocalCertificate(QSslCertificate::fromPath(QStringLiteral(DATA_DIR) + u"/localhost.crt"_s).front());
|
|
||||||
m_sslServer.setSslConfiguration(config);
|
|
||||||
if (!m_sslServer.listen(QHostAddress::LocalHost, 1234) || !m_server.bind(&m_sslServer)) {
|
|
||||||
qFatal() << "Server failed to listen on a port.";
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
qWarning() << "Server listening";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QString Server::createRoom(const QString &matrixId)
|
|
||||||
{
|
|
||||||
auto roomId = generateRoomId();
|
|
||||||
m_roomsToCreate += {roomId, matrixId};
|
|
||||||
return roomId;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Server::inviteUser(const QString &roomId, const QString &matrixId)
|
|
||||||
{
|
|
||||||
m_invitedUsers[roomId] += matrixId;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Server::banUser(const QString &roomId, const QString &matrixId)
|
|
||||||
{
|
|
||||||
m_bannedUsers[roomId] += matrixId;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Server::joinUser(const QString &roomId, const QString &matrixId)
|
|
||||||
{
|
|
||||||
m_joinedUsers[roomId] += matrixId;
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: 2025 Tobias Fella <tobias.fella@kde.org>
|
|
||||||
// SPDX-License-Identifier: LGPL-2.0-or-later
|
|
||||||
|
|
||||||
#include <QHttpServer>
|
|
||||||
#include <QSslServer>
|
|
||||||
|
|
||||||
class Server
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Server();
|
|
||||||
|
|
||||||
void start();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a room and place the user with id matrixId in it.
|
|
||||||
* Returns the room's id
|
|
||||||
*/
|
|
||||||
QString createRoom(const QString &matrixId);
|
|
||||||
|
|
||||||
void inviteUser(const QString &roomId, const QString &matrixId);
|
|
||||||
void banUser(const QString &roomId, const QString &matrixId);
|
|
||||||
void joinUser(const QString &roomId, const QString &matrixId);
|
|
||||||
|
|
||||||
private:
|
|
||||||
QHttpServer m_server;
|
|
||||||
QSslServer m_sslServer;
|
|
||||||
|
|
||||||
QHash<QString, QList<QString>> m_invitedUsers;
|
|
||||||
QHash<QString, QList<QString>> m_bannedUsers;
|
|
||||||
QHash<QString, QList<QString>> m_joinedUsers;
|
|
||||||
|
|
||||||
QList<std::pair<QString, QString>> m_roomsToCreate;
|
|
||||||
};
|
|
||||||
@@ -31,7 +31,7 @@ public:
|
|||||||
{
|
{
|
||||||
if (!syncFileName.isEmpty()) {
|
if (!syncFileName.isEmpty()) {
|
||||||
QFile testSyncFile;
|
QFile testSyncFile;
|
||||||
testSyncFile.setFileName(QStringLiteral(DATA_DIR) + u'/' + syncFileName);
|
testSyncFile.setFileName(QLatin1String(DATA_DIR) + u'/' + syncFileName);
|
||||||
testSyncFile.open(QIODevice::ReadOnly);
|
testSyncFile.open(QIODevice::ReadOnly);
|
||||||
const auto testSyncJson = QJsonDocument::fromJson(testSyncFile.readAll());
|
const auto testSyncJson = QJsonDocument::fromJson(testSyncFile.readAll());
|
||||||
Quotient::SyncRoomData roomData(id(), Quotient::JoinState::Join, testSyncJson.object());
|
Quotient::SyncRoomData roomData(id(), Quotient::JoinState::Join, testSyncJson.object());
|
||||||
@@ -45,7 +45,7 @@ inline Quotient::event_ptr_tt<EventT> loadEventFromFile(const QString &eventFile
|
|||||||
{
|
{
|
||||||
if (!eventFileName.isEmpty()) {
|
if (!eventFileName.isEmpty()) {
|
||||||
QFile testEventFile;
|
QFile testEventFile;
|
||||||
testEventFile.setFileName(QStringLiteral(DATA_DIR) + u'/' + eventFileName);
|
testEventFile.setFileName(QLatin1String(DATA_DIR) + u'/' + eventFileName);
|
||||||
testEventFile.open(QIODevice::ReadOnly);
|
testEventFile.open(QIODevice::ReadOnly);
|
||||||
auto testSyncJson = QJsonDocument::fromJson(testEventFile.readAll()).object();
|
auto testSyncJson = QJsonDocument::fromJson(testEventFile.readAll()).object();
|
||||||
return Quotient::loadEvent<EventT>(testSyncJson);
|
return Quotient::loadEvent<EventT>(testSyncJson);
|
||||||
|
|||||||
@@ -8,8 +8,7 @@
|
|||||||
|
|
||||||
#include <Quotient/quotient_common.h>
|
#include <Quotient/quotient_common.h>
|
||||||
#include <Quotient/syncdata.h>
|
#include <Quotient/syncdata.h>
|
||||||
|
#include <qnamespace.h>
|
||||||
#include <Kirigami/Platform/PlatformTheme>
|
|
||||||
|
|
||||||
#include "enums/messagecomponenttype.h"
|
#include "enums/messagecomponenttype.h"
|
||||||
#include "models/customemojimodel.h"
|
#include "models/customemojimodel.h"
|
||||||
@@ -44,8 +43,6 @@ private Q_SLOTS:
|
|||||||
void sendCustomEmoji();
|
void sendCustomEmoji();
|
||||||
void sendCustomEmojiCode_data();
|
void sendCustomEmojiCode_data();
|
||||||
void sendCustomEmojiCode();
|
void sendCustomEmojiCode();
|
||||||
void sendCustomTags_data();
|
|
||||||
void sendCustomTags();
|
|
||||||
|
|
||||||
void receiveSpacelessSelfClosingTag();
|
void receiveSpacelessSelfClosingTag();
|
||||||
void receiveStripReply();
|
void receiveStripReply();
|
||||||
@@ -61,7 +58,6 @@ private Q_SLOTS:
|
|||||||
void receiveRichStrikethrough();
|
void receiveRichStrikethrough();
|
||||||
void receiveRichtextIn();
|
void receiveRichtextIn();
|
||||||
void receiveRichMxcUrl();
|
void receiveRichMxcUrl();
|
||||||
void receiveRichPlainUrl_data();
|
|
||||||
void receiveRichPlainUrl();
|
void receiveRichPlainUrl();
|
||||||
void receiveRichEdited_data();
|
void receiveRichEdited_data();
|
||||||
void receiveRichEdited();
|
void receiveRichEdited();
|
||||||
@@ -75,25 +71,25 @@ private Q_SLOTS:
|
|||||||
|
|
||||||
void TextHandlerTest::initTestCase()
|
void TextHandlerTest::initTestCase()
|
||||||
{
|
{
|
||||||
connection = Connection::makeMockConnection(u"@bob:kde.org"_s);
|
connection = Connection::makeMockConnection(QStringLiteral("@bob:kde.org"));
|
||||||
connection->setAccountData(u"im.ponies.user_emotes"_s,
|
connection->setAccountData("im.ponies.user_emotes"_ls,
|
||||||
QJsonObject{{"images"_L1,
|
QJsonObject{{"images"_ls,
|
||||||
QJsonObject{{"test"_L1,
|
QJsonObject{{"test"_ls,
|
||||||
QJsonObject{{"body"_L1, "Test custom emoji"_L1},
|
QJsonObject{{"body"_ls, "Test custom emoji"_ls},
|
||||||
{"url"_L1, "mxc://example.org/test"_L1},
|
{"url"_ls, "mxc://example.org/test"_ls},
|
||||||
{"usage"_L1, QJsonArray{"emoticon"_L1}}}}}}});
|
{"usage"_ls, QJsonArray{"emoticon"_ls}}}}}}});
|
||||||
CustomEmojiModel::instance().setConnection(static_cast<NeoChatConnection *>(connection));
|
CustomEmojiModel::instance().setConnection(static_cast<NeoChatConnection *>(connection));
|
||||||
|
|
||||||
room = new TestUtils::TestRoom(connection, u"#myroom:kde.org"_s, u"test-texthandler-sync.json"_s);
|
room = new TestUtils::TestRoom(connection, QStringLiteral("#myroom:kde.org"), QLatin1String("test-texthandler-sync.json"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextHandlerTest::allowedAttributes()
|
void TextHandlerTest::allowedAttributes()
|
||||||
{
|
{
|
||||||
const QString testInputString1 = u"<span data-mx-spoiler><font color=#FFFFFF>Test</font><span>"_s;
|
const QString testInputString1 = QStringLiteral("<span data-mx-spoiler><font color=#FFFFFF>Test</font><span>");
|
||||||
const QString testOutputString1 = u"<span data-mx-spoiler><font color=#FFFFFF>Test</font><span>"_s;
|
const QString testOutputString1 = QStringLiteral("<span data-mx-spoiler><font color=#FFFFFF>Test</font><span>");
|
||||||
// Handle urls where the href has either single (') or double (") quotes.
|
// Handle urls where the href has either single (') or double (") quotes.
|
||||||
const QString testInputString2 = u"<a href=\"https://kde.org\">link</a><a href='https://kde.org'>link</a>"_s;
|
const QString testInputString2 = QStringLiteral("<a href=\"https://kde.org\">link</a><a href='https://kde.org'>link</a>");
|
||||||
const QString testOutputString2 = u"<a href=\"https://kde.org\">link</a><a href='https://kde.org'>link</a>"_s;
|
const QString testOutputString2 = QStringLiteral("<a href=\"https://kde.org\">link</a><a href='https://kde.org'>link</a>");
|
||||||
|
|
||||||
TextHandler testTextHandler;
|
TextHandler testTextHandler;
|
||||||
testTextHandler.setData(testInputString1);
|
testTextHandler.setData(testInputString1);
|
||||||
@@ -108,8 +104,8 @@ void TextHandlerTest::allowedAttributes()
|
|||||||
|
|
||||||
void TextHandlerTest::stripDisallowedTags()
|
void TextHandlerTest::stripDisallowedTags()
|
||||||
{
|
{
|
||||||
const QString testInputString = u"<p>Allowed</p> <span>Allowed</span> <body>Disallowed</body>"_s;
|
const QString testInputString = QStringLiteral("<p>Allowed</p> <span>Allowed</span> <body>Disallowed</body>");
|
||||||
const QString testOutputString = u"<p>Allowed</p> <span>Allowed</span> Disallowed"_s;
|
const QString testOutputString = QStringLiteral("<p>Allowed</p> <span>Allowed</span> Disallowed");
|
||||||
|
|
||||||
TextHandler testTextHandler;
|
TextHandler testTextHandler;
|
||||||
testTextHandler.setData(testInputString);
|
testTextHandler.setData(testInputString);
|
||||||
@@ -120,8 +116,8 @@ void TextHandlerTest::stripDisallowedTags()
|
|||||||
|
|
||||||
void TextHandlerTest::stripDisallowedAttributes()
|
void TextHandlerTest::stripDisallowedAttributes()
|
||||||
{
|
{
|
||||||
const QString testInputString = u"<p style=\"font-size:50px;\" color=#FFFFFF>Test</p>"_s;
|
const QString testInputString = QStringLiteral("<p style=\"font-size:50px;\" color=#FFFFFF>Test</p>");
|
||||||
const QString testOutputString = u"Test"_s;
|
const QString testOutputString = QStringLiteral("Test");
|
||||||
|
|
||||||
TextHandler testTextHandler;
|
TextHandler testTextHandler;
|
||||||
testTextHandler.setData(testInputString);
|
testTextHandler.setData(testInputString);
|
||||||
@@ -136,8 +132,8 @@ void TextHandlerTest::stripDisallowedAttributes()
|
|||||||
*/
|
*/
|
||||||
void TextHandlerTest::emptyCodeTags()
|
void TextHandlerTest::emptyCodeTags()
|
||||||
{
|
{
|
||||||
const QString testInputString = u"<pre><code></code></pre>"_s;
|
const QString testInputString = QStringLiteral("<pre><code></code></pre>");
|
||||||
const QString testOutputString = u"<pre><code></code></pre>"_s;
|
const QString testOutputString = QStringLiteral("<pre><code></code></pre>");
|
||||||
|
|
||||||
TextHandler testTextHandler;
|
TextHandler testTextHandler;
|
||||||
testTextHandler.setData(testInputString);
|
testTextHandler.setData(testInputString);
|
||||||
@@ -148,8 +144,8 @@ void TextHandlerTest::emptyCodeTags()
|
|||||||
|
|
||||||
void TextHandlerTest::sendSimpleStringCase()
|
void TextHandlerTest::sendSimpleStringCase()
|
||||||
{
|
{
|
||||||
const QString testInputString = u"This data should just be left alone."_s;
|
const QString testInputString = QStringLiteral("This data should just be left alone.");
|
||||||
const QString testOutputString = u"This data should just be left alone."_s;
|
const QString testOutputString = QStringLiteral("This data should just be left alone.");
|
||||||
|
|
||||||
TextHandler testTextHandler;
|
TextHandler testTextHandler;
|
||||||
testTextHandler.setData(testInputString);
|
testTextHandler.setData(testInputString);
|
||||||
@@ -159,10 +155,11 @@ void TextHandlerTest::sendSimpleStringCase()
|
|||||||
|
|
||||||
void TextHandlerTest::sendSingleParaMarkup()
|
void TextHandlerTest::sendSingleParaMarkup()
|
||||||
{
|
{
|
||||||
const QString testInputString =
|
const QString testInputString = QStringLiteral(
|
||||||
u"Text para with **bold**, *italic*, [link](https://kde.org), , `inline code`."_s;
|
"Text para with **bold**, *italic*, [link](https://kde.org), , `inline code`.");
|
||||||
const QString testOutputString =
|
const QString testOutputString = QStringLiteral(
|
||||||
u"Text para with <strong>bold</strong>, <em>italic</em>, <a href=\"https://kde.org\">link</a>, <img src=\"mxc://kde.org/aebd3ffd40503e1ef0525bf8f0d60282fec6183e\" alt=\"image\">, <code>inline code</code>."_s;
|
"Text para with <strong>bold</strong>, <em>italic</em>, <a href=\"https://kde.org\">link</a>, <img "
|
||||||
|
"src=\"mxc://kde.org/aebd3ffd40503e1ef0525bf8f0d60282fec6183e\" alt=\"image\">, <code>inline code</code>.");
|
||||||
|
|
||||||
TextHandler testTextHandler;
|
TextHandler testTextHandler;
|
||||||
testTextHandler.setData(testInputString);
|
testTextHandler.setData(testInputString);
|
||||||
@@ -173,9 +170,11 @@ void TextHandlerTest::sendSingleParaMarkup()
|
|||||||
void TextHandlerTest::sendMultipleSectionMarkup()
|
void TextHandlerTest::sendMultipleSectionMarkup()
|
||||||
{
|
{
|
||||||
const QString testInputString =
|
const QString testInputString =
|
||||||
u"Text para\n> blockquote\n* List 1\n* List 2\n1. one\n2. two\n# Heading 1\n## Heading 2\nhorizontal rule\n\n---\n```\ncodeblock\n```"_s;
|
QStringLiteral("Text para\n> blockquote\n* List 1\n* List 2\n1. one\n2. two\n# Heading 1\n## Heading 2\nhorizontal rule\n\n---\n```\ncodeblock\n```");
|
||||||
const QString testOutputString =
|
const QString testOutputString = QStringLiteral(
|
||||||
u"<p>Text para</p>\n<blockquote>\n<p>blockquote</p>\n</blockquote>\n<ul>\n<li>List 1</li>\n<li>List 2</li>\n</ul>\n<ol>\n<li>one</li>\n<li>two</li>\n</ol>\n<h1>Heading 1</h1>\n<h2>Heading 2</h2>\n<p>horizontal rule</p>\n<hr>\n<pre><code>codeblock\n</code></pre>"_s;
|
"<p>Text para</p>\n<blockquote>\n<p>blockquote</p>\n</blockquote>\n<ul>\n<li>List 1</li>\n<li>List "
|
||||||
|
"2</li>\n</ul>\n<ol>\n<li>one</li>\n<li>two</li>\n</ol>\n<h1>Heading 1</h1>\n<h2>Heading 2</h2>\n<p>horizontal "
|
||||||
|
"rule</p>\n<hr>\n<pre><code>codeblock\n</code></pre>");
|
||||||
|
|
||||||
TextHandler testTextHandler;
|
TextHandler testTextHandler;
|
||||||
testTextHandler.setData(testInputString);
|
testTextHandler.setData(testInputString);
|
||||||
@@ -185,8 +184,8 @@ void TextHandlerTest::sendMultipleSectionMarkup()
|
|||||||
|
|
||||||
void TextHandlerTest::sendBadLinks()
|
void TextHandlerTest::sendBadLinks()
|
||||||
{
|
{
|
||||||
const QString testInputString = u"[link](kde.org), "_s;
|
const QString testInputString = QStringLiteral("[link](kde.org), ");
|
||||||
const QString testOutputString = u"<a>link</a>, <img alt=\"image\">"_s;
|
const QString testOutputString = QStringLiteral("<a>link</a>, <img alt=\"image\">");
|
||||||
|
|
||||||
TextHandler testTextHandler;
|
TextHandler testTextHandler;
|
||||||
testTextHandler.setData(testInputString);
|
testTextHandler.setData(testInputString);
|
||||||
@@ -199,9 +198,9 @@ void TextHandlerTest::sendBadLinks()
|
|||||||
*/
|
*/
|
||||||
void TextHandlerTest::sendEscapeCode()
|
void TextHandlerTest::sendEscapeCode()
|
||||||
{
|
{
|
||||||
const QString testInputString = u"```\n<p>Test <span style=\"font-size:50px;\">some</span> code</p>\n```"_s;
|
const QString testInputString = QStringLiteral("```\n<p>Test <span style=\"font-size:50px;\">some</span> code</p>\n```");
|
||||||
const QString testOutputString =
|
const QString testOutputString =
|
||||||
u"<pre><code><p>Test <span style="font-size:50px;">some</span> code</p>\n</code></pre>"_s;
|
QStringLiteral("<pre><code><p>Test <span style="font-size:50px;">some</span> code</p>\n</code></pre>");
|
||||||
|
|
||||||
TextHandler testTextHandler;
|
TextHandler testTextHandler;
|
||||||
testTextHandler.setData(testInputString);
|
testTextHandler.setData(testInputString);
|
||||||
@@ -211,8 +210,8 @@ void TextHandlerTest::sendEscapeCode()
|
|||||||
|
|
||||||
void TextHandlerTest::sendCodeClass()
|
void TextHandlerTest::sendCodeClass()
|
||||||
{
|
{
|
||||||
const QString testInputString = u"```html\nsome code\n```\n<pre><code class=\"code-underline\">some more code</code></pre>"_s;
|
const QString testInputString = QStringLiteral("```html\nsome code\n```\n<pre><code class=\"code-underline\">some more code</code></pre>");
|
||||||
const QString testOutputString = u"<pre><code class=\"language-html\">some code\n</code></pre>\n<pre><code>some more code</code></pre>"_s;
|
const QString testOutputString = QStringLiteral("<pre><code class=\"language-html\">some code\n</code></pre>\n<pre><code>some more code</code></pre>");
|
||||||
|
|
||||||
TextHandler testTextHandler;
|
TextHandler testTextHandler;
|
||||||
testTextHandler.setData(testInputString);
|
testTextHandler.setData(testInputString);
|
||||||
@@ -222,9 +221,9 @@ void TextHandlerTest::sendCodeClass()
|
|||||||
|
|
||||||
void TextHandlerTest::sendCustomEmoji()
|
void TextHandlerTest::sendCustomEmoji()
|
||||||
{
|
{
|
||||||
const QString testInputString = u":test:"_s;
|
const QString testInputString = QStringLiteral(":test:");
|
||||||
const QString testOutputString =
|
const QString testOutputString =
|
||||||
u"<img data-mx-emoticon=\"\" src=\"mxc://example.org/test\" alt=\":test:\" title=\":test:\" height=\"32\" vertical-align=\"middle\" />"_s;
|
QStringLiteral("<img data-mx-emoticon=\"\" src=\"mxc://example.org/test\" alt=\":test:\" title=\":test:\" height=\"32\" vertical-align=\"middle\" />");
|
||||||
|
|
||||||
TextHandler testTextHandler;
|
TextHandler testTextHandler;
|
||||||
testTextHandler.setData(testInputString);
|
testTextHandler.setData(testInputString);
|
||||||
@@ -237,8 +236,8 @@ void TextHandlerTest::sendCustomEmojiCode_data()
|
|||||||
QTest::addColumn<QString>("testInputString");
|
QTest::addColumn<QString>("testInputString");
|
||||||
QTest::addColumn<QString>("testOutputString");
|
QTest::addColumn<QString>("testOutputString");
|
||||||
|
|
||||||
QTest::newRow("inline") << u"`:test:`"_s << u"<code>:test:</code>"_s;
|
QTest::newRow("inline") << QStringLiteral("`:test:`") << QStringLiteral("<code>:test:</code>");
|
||||||
QTest::newRow("block") << u"```\n:test:\n```"_s << u"<pre><code>:test:\n</code></pre>"_s;
|
QTest::newRow("block") << QStringLiteral("```\n:test:\n```") << QStringLiteral("<pre><code>:test:\n</code></pre>");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Custom emojis in code blocks should be left alone.
|
// Custom emojis in code blocks should be left alone.
|
||||||
@@ -253,45 +252,11 @@ void TextHandlerTest::sendCustomEmojiCode()
|
|||||||
QCOMPARE(testTextHandler.handleSendText(), testOutputString);
|
QCOMPARE(testTextHandler.handleSendText(), testOutputString);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextHandlerTest::sendCustomTags_data()
|
|
||||||
{
|
|
||||||
QTest::addColumn<QString>("testInputString");
|
|
||||||
QTest::addColumn<QString>("testOutputString");
|
|
||||||
|
|
||||||
// spoiler
|
|
||||||
QTest::newRow("incomplete spoiler") << u"||test"_s << u"||test"_s;
|
|
||||||
QTest::newRow("complete spoiler") << u"||test||"_s << u"<span data-mx-spoiler>test</span>"_s;
|
|
||||||
QTest::newRow("multiple spoiler") << u"||apple||banana||pear||"_s << u"<span data-mx-spoiler>apple</span>banana<span data-mx-spoiler>pear</span>"_s;
|
|
||||||
QTest::newRow("inside code block spoiler") << u"```||apple||```"_s << u"<code>||apple||</code>"_s;
|
|
||||||
QTest::newRow("outside code block spoiler") << u"||apple|| ```||banana||``` ||pear||"_s
|
|
||||||
<< u"<span data-mx-spoiler>apple</span> <code>||banana||</code> <span data-mx-spoiler>pear</span>"_s;
|
|
||||||
QTest::newRow("complex spoiler") << u"Between `formFactor == Horizontal||Vertical` and `location == top||left||bottom||right`"_s
|
|
||||||
<< u"Between <code>formFactor == Horizontal||Vertical</code> and <code>location == top||left||bottom||right</code>"_s;
|
|
||||||
|
|
||||||
// strikethrough
|
|
||||||
QTest::newRow("incomplete strikethrough") << u"~~test"_s << u"~~test"_s;
|
|
||||||
QTest::newRow("complete strikethrough") << u"~~test~~"_s << u"<del>test</del>"_s;
|
|
||||||
QTest::newRow("inside code block strikethrough") << u"```~~apple~~```"_s << u"<code>~~apple~~</code>"_s;
|
|
||||||
QTest::newRow("outside code block strikethrough") << u"~~apple~~ ```~~banana~~``` ~~pear~~"_s
|
|
||||||
<< u"<del>apple</del> <code>~~banana~~</code> <del>pear</del>"_s;
|
|
||||||
}
|
|
||||||
|
|
||||||
void TextHandlerTest::sendCustomTags()
|
|
||||||
{
|
|
||||||
QFETCH(QString, testInputString);
|
|
||||||
QFETCH(QString, testOutputString);
|
|
||||||
|
|
||||||
TextHandler testTextHandler;
|
|
||||||
testTextHandler.setData(testInputString);
|
|
||||||
|
|
||||||
QCOMPARE(testTextHandler.handleSendText(), testOutputString);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TextHandlerTest::receiveSpacelessSelfClosingTag()
|
void TextHandlerTest::receiveSpacelessSelfClosingTag()
|
||||||
{
|
{
|
||||||
const QString testInputString = u"Test...<br/>...ing"_s;
|
const QString testInputString = QStringLiteral("Test...<br/>...ing");
|
||||||
const QString testRichOutputString = u"Test...<br/>...ing"_s;
|
const QString testRichOutputString = QStringLiteral("Test...<br/>...ing");
|
||||||
const QString testPlainOutputString = u"Test...\n...ing"_s;
|
const QString testPlainOutputString = QStringLiteral("Test...\n...ing");
|
||||||
|
|
||||||
TextHandler testTextHandler;
|
TextHandler testTextHandler;
|
||||||
testTextHandler.setData(testInputString);
|
testTextHandler.setData(testInputString);
|
||||||
@@ -302,9 +267,10 @@ void TextHandlerTest::receiveSpacelessSelfClosingTag()
|
|||||||
|
|
||||||
void TextHandlerTest::receiveStripReply()
|
void TextHandlerTest::receiveStripReply()
|
||||||
{
|
{
|
||||||
const QString testInputString =
|
const QString testInputString = QStringLiteral(
|
||||||
u"<mx-reply><blockquote><a href=\"https://matrix.to/#/!somewhere:example.org/$event:example.org\">In reply to</a><a href=\"https://matrix.to/#/@alice:example.org\">@alice:example.org</a><br />Message replied to.</blockquote></mx-reply>Reply message."_s;
|
"<mx-reply><blockquote><a href=\"https://matrix.to/#/!somewhere:example.org/$event:example.org\">In reply to</a><a "
|
||||||
const QString testOutputString = u"Reply message."_s;
|
"href=\"https://matrix.to/#/@alice:example.org\">@alice:example.org</a><br />Message replied to.</blockquote></mx-reply>Reply message.");
|
||||||
|
const QString testOutputString = QStringLiteral("Reply message.");
|
||||||
|
|
||||||
TextHandler testTextHandler;
|
TextHandler testTextHandler;
|
||||||
testTextHandler.setData(testInputString);
|
testTextHandler.setData(testInputString);
|
||||||
@@ -318,10 +284,10 @@ void TextHandlerTest::receiveRichInPlainOut_data()
|
|||||||
QTest::addColumn<QString>("testInputString");
|
QTest::addColumn<QString>("testInputString");
|
||||||
QTest::addColumn<QString>("testOutputString");
|
QTest::addColumn<QString>("testOutputString");
|
||||||
|
|
||||||
QTest::newRow("ampersand") << u"a & b"_s << u"a & b"_s;
|
QTest::newRow("ampersand") << QStringLiteral("a & b") << QStringLiteral("a & b");
|
||||||
QTest::newRow("quote") << u""a and b""_s << u"\"a and b\""_s;
|
QTest::newRow("quote") << QStringLiteral(""a and b"") << QStringLiteral("\"a and b\"");
|
||||||
QTest::newRow("new line") << u"new<br>line"_s << u"new\nline"_s;
|
QTest::newRow("new line") << QStringLiteral("new<br>line") << QStringLiteral("new\nline");
|
||||||
QTest::newRow("unescape") << u"can't"_s << u"can't"_s;
|
QTest::newRow("unescape") << QStringLiteral("can't") << QStringLiteral("can't");
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextHandlerTest::receiveRichInPlainOut()
|
void TextHandlerTest::receiveRichInPlainOut()
|
||||||
@@ -337,13 +303,13 @@ void TextHandlerTest::receiveRichInPlainOut()
|
|||||||
|
|
||||||
void TextHandlerTest::receivePlainTextIn()
|
void TextHandlerTest::receivePlainTextIn()
|
||||||
{
|
{
|
||||||
const QString testInputString = u"<plain text in tag bracket>\nTest link https://kde.org."_s;
|
const QString testInputString = QStringLiteral("<plain text in tag bracket>\nTest link https://kde.org.");
|
||||||
const QString testOutputStringRich = u"<plain text in tag bracket><br>Test link <a href=\"https://kde.org\">https://kde.org</a>."_s;
|
const QString testOutputStringRich = QStringLiteral("<plain text in tag bracket><br>Test link <a href=\"https://kde.org\">https://kde.org</a>.");
|
||||||
QString testOutputStringPlain = u"<plain text in tag bracket>\nTest link https://kde.org."_s;
|
QString testOutputStringPlain = QStringLiteral("<plain text in tag bracket>\nTest link https://kde.org.");
|
||||||
|
|
||||||
// Make sure quotes are maintained in a plain string.
|
// Make sure quotes are maintained in a plain string.
|
||||||
const QString testInputString2 = u"last line is \"Time to switch to a new topic.\""_s;
|
const QString testInputString2 = QStringLiteral("last line is \"Time to switch to a new topic.\"");
|
||||||
const QString testOutputString2 = u"last line is \"Time to switch to a new topic.\""_s;
|
const QString testOutputString2 = QStringLiteral("last line is \"Time to switch to a new topic.\"");
|
||||||
|
|
||||||
TextHandler testTextHandler;
|
TextHandler testTextHandler;
|
||||||
testTextHandler.setData(testInputString);
|
testTextHandler.setData(testInputString);
|
||||||
@@ -358,12 +324,12 @@ void TextHandlerTest::receivePlainTextIn()
|
|||||||
|
|
||||||
void TextHandlerTest::receiveStripNewlines()
|
void TextHandlerTest::receiveStripNewlines()
|
||||||
{
|
{
|
||||||
const QString testInputStringPlain = u"Test\nmany\nnew\nlines."_s;
|
const QString testInputStringPlain = QStringLiteral("Test\nmany\nnew\nlines.");
|
||||||
const QString testInputStringRich = u"Test<br>many<br />new<br>lines."_s;
|
const QString testInputStringRich = QStringLiteral("Test<br>many<br />new<br>lines.");
|
||||||
const QString testOutputString = u"Test many new lines."_s;
|
const QString testOutputString = QStringLiteral("Test many new lines.");
|
||||||
|
|
||||||
const QString testInputStringPlain2 = u"* List\n* Items"_s;
|
const QString testInputStringPlain2 = QStringLiteral("* List\n* Items");
|
||||||
const QString testOutputString2 = u"List Items"_s;
|
const QString testOutputString2 = QStringLiteral("List Items");
|
||||||
|
|
||||||
TextHandler testTextHandler;
|
TextHandler testTextHandler;
|
||||||
testTextHandler.setData(testInputStringPlain);
|
testTextHandler.setData(testInputStringPlain);
|
||||||
@@ -385,8 +351,8 @@ void TextHandlerTest::receiveStripNewlines()
|
|||||||
*/
|
*/
|
||||||
void TextHandlerTest::receivePlainStripHtml()
|
void TextHandlerTest::receivePlainStripHtml()
|
||||||
{
|
{
|
||||||
const QString testInputString = u"<p>Test</p> <pre><code>Some code <strong>with tags</strong></code></pre>"_s;
|
const QString testInputString = QStringLiteral("<p>Test</p> <pre><code>Some code <strong>with tags</strong></code></pre>");
|
||||||
const QString testOutputString = u"Test Some code <strong>with tags</strong>"_s;
|
const QString testOutputString = QStringLiteral("Test Some code <strong>with tags</strong>");
|
||||||
|
|
||||||
TextHandler testTextHandler;
|
TextHandler testTextHandler;
|
||||||
testTextHandler.setData(testInputString);
|
testTextHandler.setData(testInputString);
|
||||||
@@ -396,8 +362,8 @@ void TextHandlerTest::receivePlainStripHtml()
|
|||||||
|
|
||||||
void TextHandlerTest::receivePlainStripMarkup()
|
void TextHandlerTest::receivePlainStripMarkup()
|
||||||
{
|
{
|
||||||
const QString testInputString = u"**bold** `<p>inline code</p>` *italic*"_s;
|
const QString testInputString = QStringLiteral("**bold** `<p>inline code</p>` *italic*");
|
||||||
const QString testOutputString = u"bold <p>inline code</p> italic"_s;
|
const QString testOutputString = QStringLiteral("bold <p>inline code</p> italic");
|
||||||
|
|
||||||
TextHandler testTextHandler;
|
TextHandler testTextHandler;
|
||||||
testTextHandler.setData(testInputString);
|
testTextHandler.setData(testInputString);
|
||||||
@@ -407,8 +373,8 @@ void TextHandlerTest::receivePlainStripMarkup()
|
|||||||
|
|
||||||
void TextHandlerTest::receiveRichUserPill()
|
void TextHandlerTest::receiveRichUserPill()
|
||||||
{
|
{
|
||||||
const QString testInputString = u"<p><a href=\"https://matrix.to/#/@alice:example.org\">@alice:example.org</a></p>"_s;
|
const QString testInputString = QStringLiteral("<p><a href=\"https://matrix.to/#/@alice:example.org\">@alice:example.org</a></p>");
|
||||||
const QString testOutputString = u"<b><a href=\"https://matrix.to/#/@alice:example.org\">@alice:example.org</a></b>"_s;
|
const QString testOutputString = QStringLiteral("<b><a href=\"https://matrix.to/#/@alice:example.org\">@alice:example.org</a></b>");
|
||||||
|
|
||||||
TextHandler testTextHandler;
|
TextHandler testTextHandler;
|
||||||
testTextHandler.setData(testInputString);
|
testTextHandler.setData(testInputString);
|
||||||
@@ -418,8 +384,8 @@ void TextHandlerTest::receiveRichUserPill()
|
|||||||
|
|
||||||
void TextHandlerTest::receiveRichStrikethrough()
|
void TextHandlerTest::receiveRichStrikethrough()
|
||||||
{
|
{
|
||||||
const QString testInputString = u"<p><del>Test</del></p>"_s;
|
const QString testInputString = QStringLiteral("<p><del>Test</del></p>");
|
||||||
const QString testOutputString = u"<s>Test</s>"_s;
|
const QString testOutputString = QStringLiteral("<s>Test</s>");
|
||||||
|
|
||||||
TextHandler testTextHandler;
|
TextHandler testTextHandler;
|
||||||
testTextHandler.setData(testInputString);
|
testTextHandler.setData(testInputString);
|
||||||
@@ -429,8 +395,8 @@ void TextHandlerTest::receiveRichStrikethrough()
|
|||||||
|
|
||||||
void TextHandlerTest::receiveRichtextIn()
|
void TextHandlerTest::receiveRichtextIn()
|
||||||
{
|
{
|
||||||
const QString testInputString = u"<p>Test</p> <pre><code>Some code <strong>with tags</strong></code></pre>"_s;
|
const QString testInputString = QStringLiteral("<p>Test</p> <pre><code>Some code <strong>with tags</strong></code></pre>");
|
||||||
const QString testOutputString = u"<p>Test</p> <pre><code>Some code <strong>with tags</strong></code></pre>"_s;
|
const QString testOutputString = QStringLiteral("<p>Test</p> <pre><code>Some code <strong>with tags</strong></code></pre>");
|
||||||
|
|
||||||
TextHandler testTextHandler;
|
TextHandler testTextHandler;
|
||||||
testTextHandler.setData(testInputString);
|
testTextHandler.setData(testInputString);
|
||||||
@@ -440,10 +406,15 @@ void TextHandlerTest::receiveRichtextIn()
|
|||||||
|
|
||||||
void TextHandlerTest::receiveRichMxcUrl()
|
void TextHandlerTest::receiveRichMxcUrl()
|
||||||
{
|
{
|
||||||
const QString testInputString =
|
const QString testInputString = QStringLiteral(
|
||||||
u"<img src=\"mxc://kde.org/aebd3ffd40503e1ef0525bf8f0d60282fec6183e\" alt=\"image\"><img src=\"mxc://kde.org/34c3464b3a1bd7f55af2d559e07d2c773c430e73\" alt=\"image\">"_s;
|
"<img src=\"mxc://kde.org/aebd3ffd40503e1ef0525bf8f0d60282fec6183e\" alt=\"image\"><img src=\"mxc://kde.org/34c3464b3a1bd7f55af2d559e07d2c773c430e73\" "
|
||||||
const QString testOutputString =
|
"alt=\"image\">");
|
||||||
u"<img src=\"mxc://kde.org/aebd3ffd40503e1ef0525bf8f0d60282fec6183e?user_id=@bob:kde.org&room_id=%23myroom:kde.org&event_id=$143273582443PhrSn:example.org\" alt=\"image\"><img src=\"mxc://kde.org/34c3464b3a1bd7f55af2d559e07d2c773c430e73?user_id=@bob:kde.org&room_id=%23myroom:kde.org&event_id=$143273582443PhrSn:example.org\" alt=\"image\">"_s;
|
const QString testOutputString = QStringLiteral(
|
||||||
|
"<img "
|
||||||
|
"src=\"mxc://kde.org/aebd3ffd40503e1ef0525bf8f0d60282fec6183e?user_id=@bob:kde.org&room_id=%23myroom:kde.org&event_id=$143273582443PhrSn:example.org\" "
|
||||||
|
"alt=\"image\"><img "
|
||||||
|
"src=\"mxc://kde.org/34c3464b3a1bd7f55af2d559e07d2c773c430e73?user_id=@bob:kde.org&room_id=%23myroom:kde.org&event_id=$143273582443PhrSn:example.org\" "
|
||||||
|
"alt=\"image\">");
|
||||||
|
|
||||||
TextHandler testTextHandler;
|
TextHandler testTextHandler;
|
||||||
testTextHandler.setData(testInputString);
|
testTextHandler.setData(testInputString);
|
||||||
@@ -451,32 +422,6 @@ void TextHandlerTest::receiveRichMxcUrl()
|
|||||||
QCOMPARE(testTextHandler.handleRecieveRichText(Qt::RichText, room, room->messageEvents().at(0).get()), testOutputString);
|
QCOMPARE(testTextHandler.handleRecieveRichText(Qt::RichText, room, room->messageEvents().at(0).get()), testOutputString);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextHandlerTest::receiveRichPlainUrl_data()
|
|
||||||
{
|
|
||||||
QTest::addColumn<QString>("input");
|
|
||||||
QTest::addColumn<QString>("output");
|
|
||||||
|
|
||||||
// This is an actual link that caused trouble which is why it's so long. Keeping
|
|
||||||
// so we can confirm consistent behaviour for complex urls.
|
|
||||||
QTest::addRow("link 1")
|
|
||||||
<< u"https://matrix.to/#/!RvzunyTWZGfNxJVQqv:matrix.org/$-9TJVTh5PvW6MvIhFDwteiyLBVGriinueO5eeIazQS8?via=libera.chat&via=matrix.org&via=fedora.im <a href=\"https://matrix.to/#/!RvzunyTWZGfNxJVQqv:matrix.org/$-9TJVTh5PvW6MvIhFDwteiyLBVGriinueO5eeIazQS8?via=libera.chat&via=matrix.org&via=fedora.im\">Link already rich</a>"_s
|
|
||||||
<< u"<a href=\"https://matrix.to/#/!RvzunyTWZGfNxJVQqv:matrix.org/$-9TJVTh5PvW6MvIhFDwteiyLBVGriinueO5eeIazQS8?via=libera.chat&via=matrix.org&via=fedora.im\">https://matrix.to/#/!RvzunyTWZGfNxJVQqv:matrix.org/$-9TJVTh5PvW6MvIhFDwteiyLBVGriinueO5eeIazQS8?via=libera.chat&via=matrix.org&via=fedora.im</a> <a href=\"https://matrix.to/#/!RvzunyTWZGfNxJVQqv:matrix.org/$-9TJVTh5PvW6MvIhFDwteiyLBVGriinueO5eeIazQS8?via=libera.chat&via=matrix.org&via=fedora.im\">Link already rich</a>"_s;
|
|
||||||
|
|
||||||
// Another real case. The linkification wasn't handling it when a single link
|
|
||||||
// contains what looks like and email. It was broken into 3 but needs to
|
|
||||||
// be just single link.
|
|
||||||
QTest::addRow("link 2")
|
|
||||||
<< u"https://lore.kernel.org/lkml/CAHk-=wio46vC4t6xXD-sFqjoPwFm_u515jm3suzmkGxQTeA1_A@mail.gmail.com/"_s
|
|
||||||
<< u"<a href=\"https://lore.kernel.org/lkml/CAHk-=wio46vC4t6xXD-sFqjoPwFm_u515jm3suzmkGxQTeA1_A@mail.gmail.com/\">https://lore.kernel.org/lkml/CAHk-=wio46vC4t6xXD-sFqjoPwFm_u515jm3suzmkGxQTeA1_A@mail.gmail.com/</a>"_s;
|
|
||||||
|
|
||||||
QTest::addRow("email") << uR"(email@example.com <a href="mailto:email@example.com">Link already rich</a>)"_s
|
|
||||||
<< uR"(<a href="mailto:email@example.com">email@example.com</a> <a href="mailto:email@example.com">Link already rich</a>)"_s;
|
|
||||||
QTest::addRow("mxid")
|
|
||||||
<< u"@user:kde.org <a href=\"https://matrix.to/#/@user:kde.org\">Link already rich</a>"_s
|
|
||||||
<< u"<b><a href=\"https://matrix.to/#/@user:kde.org\">@user:kde.org</a></b> <b><a href=\"https://matrix.to/#/@user:kde.org\">Link already rich</a></b>"_s;
|
|
||||||
QTest::addRow("mxid with prefix") << u"a @user:kde.org b"_s << u"a <b><a href=\"https://matrix.to/#/@user:kde.org\">@user:kde.org</a></b> b"_s;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For when your rich input string has a plain text url left in.
|
* For when your rich input string has a plain text url left in.
|
||||||
*
|
*
|
||||||
@@ -485,13 +430,57 @@ void TextHandlerTest::receiveRichPlainUrl_data()
|
|||||||
*/
|
*/
|
||||||
void TextHandlerTest::receiveRichPlainUrl()
|
void TextHandlerTest::receiveRichPlainUrl()
|
||||||
{
|
{
|
||||||
QFETCH(QString, input);
|
// This is an actual link that caused trouble which is why it's so long. Keeping
|
||||||
QFETCH(QString, output);
|
// so we can confirm consistent behaviour for complex urls.
|
||||||
|
const QString testInputStringLink1 = QStringLiteral(
|
||||||
|
"https://matrix.to/#/!RvzunyTWZGfNxJVQqv:matrix.org/$-9TJVTh5PvW6MvIhFDwteiyLBVGriinueO5eeIazQS8?via=libera.chat&via=matrix.org&via=fedora.im "
|
||||||
|
"<a "
|
||||||
|
"href=\"https://matrix.to/#/!RvzunyTWZGfNxJVQqv:matrix.org/"
|
||||||
|
"$-9TJVTh5PvW6MvIhFDwteiyLBVGriinueO5eeIazQS8?via=libera.chat&via=matrix.org&via=fedora.im\">Link already rich</a>");
|
||||||
|
const QString testOutputStringLink1 = QStringLiteral(
|
||||||
|
"<a "
|
||||||
|
"href=\"https://matrix.to/#/!RvzunyTWZGfNxJVQqv:matrix.org/"
|
||||||
|
"$-9TJVTh5PvW6MvIhFDwteiyLBVGriinueO5eeIazQS8?via=libera.chat&via=matrix.org&via=fedora.im\">https://matrix.to/#/"
|
||||||
|
"!RvzunyTWZGfNxJVQqv:matrix.org/$-9TJVTh5PvW6MvIhFDwteiyLBVGriinueO5eeIazQS8?via=libera.chat&via=matrix.org&via=fedora.im</a> <a "
|
||||||
|
"href=\"https://matrix.to/#/!RvzunyTWZGfNxJVQqv:matrix.org/"
|
||||||
|
"$-9TJVTh5PvW6MvIhFDwteiyLBVGriinueO5eeIazQS8?via=libera.chat&via=matrix.org&via=fedora.im\">Link already rich</a>");
|
||||||
|
|
||||||
|
// Another real case. The linkification wasn't handling it when a single link
|
||||||
|
// contains what looks like and email. It was been broken into 3 but needs to
|
||||||
|
// be just single link.
|
||||||
|
const QString testInputStringLink2 = QStringLiteral("https://lore.kernel.org/lkml/CAHk-=wio46vC4t6xXD-sFqjoPwFm_u515jm3suzmkGxQTeA1_A@mail.gmail.com/");
|
||||||
|
const QString testOutputStringLink2 = QStringLiteral(
|
||||||
|
"<a "
|
||||||
|
"href=\"https://lore.kernel.org/lkml/CAHk-=wio46vC4t6xXD-sFqjoPwFm_u515jm3suzmkGxQTeA1_A@mail.gmail.com/\">https://lore.kernel.org/lkml/"
|
||||||
|
"CAHk-=wio46vC4t6xXD-sFqjoPwFm_u515jm3suzmkGxQTeA1_A@mail.gmail.com/</a>");
|
||||||
|
|
||||||
|
QString testInputStringEmail = QStringLiteral(R"(email@example.com <a href="mailto:email@example.com">Link already rich</a>)");
|
||||||
|
QString testOutputStringEmail =
|
||||||
|
QStringLiteral(R"(<a href="mailto:email@example.com">email@example.com</a> <a href="mailto:email@example.com">Link already rich</a>)");
|
||||||
|
|
||||||
|
QString testInputStringMxId = QStringLiteral("@user:kde.org <a href=\"https://matrix.to/#/@user:kde.org\">Link already rich</a>");
|
||||||
|
QString testOutputStringMxId = QStringLiteral(
|
||||||
|
"<b><a href=\"https://matrix.to/#/@user:kde.org\">@user:kde.org</a></b> <b><a href=\"https://matrix.to/#/@user:kde.org\">Link already rich</a></b>");
|
||||||
|
|
||||||
|
QString testInputStringMxIdWithPrefix = QStringLiteral("a @user:kde.org b");
|
||||||
|
QString testOutputStringMxIdWithPrefix = QStringLiteral("a <b><a href=\"https://matrix.to/#/@user:kde.org\">@user:kde.org</a></b> b");
|
||||||
|
|
||||||
TextHandler testTextHandler;
|
TextHandler testTextHandler;
|
||||||
testTextHandler.setData(input);
|
testTextHandler.setData(testInputStringLink1);
|
||||||
|
|
||||||
QCOMPARE(testTextHandler.handleRecieveRichText(Qt::RichText), output);
|
QCOMPARE(testTextHandler.handleRecieveRichText(Qt::RichText), testOutputStringLink1);
|
||||||
|
|
||||||
|
testTextHandler.setData(testInputStringLink2);
|
||||||
|
QCOMPARE(testTextHandler.handleRecieveRichText(Qt::RichText), testOutputStringLink2);
|
||||||
|
|
||||||
|
testTextHandler.setData(testInputStringEmail);
|
||||||
|
QCOMPARE(testTextHandler.handleRecieveRichText(Qt::RichText), testOutputStringEmail);
|
||||||
|
|
||||||
|
testTextHandler.setData(testInputStringMxId);
|
||||||
|
QCOMPARE(testTextHandler.handleRecieveRichText(Qt::RichText), testOutputStringMxId);
|
||||||
|
|
||||||
|
testTextHandler.setData(testInputStringMxIdWithPrefix);
|
||||||
|
QCOMPARE(testTextHandler.handleRecieveRichText(Qt::RichText), testOutputStringMxIdWithPrefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextHandlerTest::receiveRichEdited_data()
|
void TextHandlerTest::receiveRichEdited_data()
|
||||||
@@ -499,12 +488,9 @@ void TextHandlerTest::receiveRichEdited_data()
|
|||||||
QTest::addColumn<QString>("testInputString");
|
QTest::addColumn<QString>("testInputString");
|
||||||
QTest::addColumn<QString>("testOutputString");
|
QTest::addColumn<QString>("testOutputString");
|
||||||
|
|
||||||
auto theme = static_cast<Kirigami::Platform::PlatformTheme *>(qmlAttachedPropertiesObject<Kirigami::Platform::PlatformTheme>(this, true));
|
QTest::newRow("basic") << QStringLiteral("Edited") << QStringLiteral("Edited <span style=\"color:#000000\">(edited)</span>");
|
||||||
|
QTest::newRow("multiple paragraphs") << QStringLiteral("<p>Edited</p>\n<p>Edited</p>")
|
||||||
QTest::newRow("basic") << u"Edited"_s << u"Edited <span style=\"color:%1\">(edited)</span>"_s.arg(theme ? theme->disabledTextColor().name() : u"#000000"_s);
|
<< QStringLiteral("<p>Edited</p>\n<p>Edited <span style=\"color:#000000\">(edited)</span></p>");
|
||||||
QTest::newRow("multiple paragraphs") << u"<p>Edited</p>\n<p>Edited</p>"_s
|
|
||||||
<< u"<p>Edited</p>\n<p>Edited <span style=\"color:%1\">(edited)</span></p>"_s.arg(
|
|
||||||
theme ? theme->disabledTextColor().name() : u"#000000"_s);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextHandlerTest::receiveRichEdited()
|
void TextHandlerTest::receiveRichEdited()
|
||||||
@@ -521,15 +507,15 @@ void TextHandlerTest::receiveRichEdited()
|
|||||||
|
|
||||||
void TextHandlerTest::receiveLineSeparator()
|
void TextHandlerTest::receiveLineSeparator()
|
||||||
{
|
{
|
||||||
auto text = u"foo\u2028bar"_s;
|
auto text = QStringLiteral("foo\u2028bar");
|
||||||
TextHandler textHandler;
|
TextHandler textHandler;
|
||||||
textHandler.setData(text);
|
textHandler.setData(text);
|
||||||
QCOMPARE(textHandler.handleRecievePlainText(Qt::PlainText, true), u"foo bar"_s);
|
QCOMPARE(textHandler.handleRecievePlainText(Qt::PlainText, true), QStringLiteral("foo bar"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextHandlerTest::receiveRichCodeUrl()
|
void TextHandlerTest::receiveRichCodeUrl()
|
||||||
{
|
{
|
||||||
auto input = u"<code>https://kde.org</code>"_s;
|
auto input = QStringLiteral("<code>https://kde.org</code>");
|
||||||
TextHandler testTextHandler;
|
TextHandler testTextHandler;
|
||||||
testTextHandler.setData(input);
|
testTextHandler.setData(input);
|
||||||
QCOMPARE(testTextHandler.handleRecieveRichText(), input);
|
QCOMPARE(testTextHandler.handleRecieveRichText(), input);
|
||||||
@@ -537,14 +523,20 @@ void TextHandlerTest::receiveRichCodeUrl()
|
|||||||
|
|
||||||
void TextHandlerTest::receiveRichColor()
|
void TextHandlerTest::receiveRichColor()
|
||||||
{
|
{
|
||||||
const QString testInputString =
|
const QString testInputString = QStringLiteral(
|
||||||
u"<span data-mx-color=\"#ff00be\">¯</span><span data-mx-color=\"#ff3b1d\">\\</span><span data-mx-color=\"#ffa600\">_</span><span data-mx-color=\"#64d200\">(</span><span data-mx-color=\"#00e261\">ツ</span><span data-mx-color=\"#00e7ff\">)</span><span data-mx-color=\"#00e1ff\">_</span><span data-mx-color=\"#00bdff\">/</span><span data-mx-color=\"#ff60ff\">¯</span>"_s;
|
"<span data-mx-color=\"#ff00be\">¯</span><span data-mx-color=\"#ff3b1d\">\\</span><span data-mx-color=\"#ffa600\">_</span><span "
|
||||||
const QString testOutputString =
|
"data-mx-color=\"#64d200\">(</span><span data-mx-color=\"#00e261\">ツ</span><span data-mx-color=\"#00e7ff\">)</span><span "
|
||||||
u"<span style=\"color: #ff00be;\">¯</span><span style=\"color: #ff3b1d;\">\\</span><span style=\"color: #ffa600;\">_</span><span style=\"color: #64d200;\">(</span><span style=\"color: #00e261;\">ツ</span><span style=\"color: #00e7ff;\">)</span><span style=\"color: #00e1ff;\">_</span><span style=\"color: #00bdff;\">/</span><span style=\"color: #ff60ff;\">¯</span>"_s;
|
"data-mx-color=\"#00e1ff\">_</span><span data-mx-color=\"#00bdff\">/</span><span data-mx-color=\"#ff60ff\">¯</span>");
|
||||||
|
const QString testOutputString = QStringLiteral(
|
||||||
|
"<span style=\"color: #ff00be;\">¯</span><span style=\"color: #ff3b1d;\">\\</span><span style=\"color: #ffa600;\">_</span><span style=\"color: "
|
||||||
|
"#64d200;\">(</span><span style=\"color: #00e261;\">ツ</span><span style=\"color: #00e7ff;\">)</span><span style=\"color: #00e1ff;\">_</span><span "
|
||||||
|
"style=\"color: #00bdff;\">/</span><span style=\"color: #ff60ff;\">¯</span>");
|
||||||
|
|
||||||
TextHandler testTextHandler;
|
TextHandler testTextHandler;
|
||||||
testTextHandler.setData(testInputString);
|
testTextHandler.setData(testInputString);
|
||||||
|
|
||||||
|
qInfo() << testTextHandler.handleRecieveRichText();
|
||||||
|
|
||||||
QCOMPARE(testTextHandler.handleRecieveRichText(), testOutputString);
|
QCOMPARE(testTextHandler.handleRecieveRichText(), testOutputString);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -553,38 +545,42 @@ void TextHandlerTest::componentOutput_data()
|
|||||||
QTest::addColumn<QString>("testInputString");
|
QTest::addColumn<QString>("testInputString");
|
||||||
QTest::addColumn<QList<MessageComponent>>("testOutputComponents");
|
QTest::addColumn<QList<MessageComponent>>("testOutputComponents");
|
||||||
|
|
||||||
QTest::newRow("multiple paragraphs") << u"<p>Text</p>\n<p>Text</p>"_s
|
QTest::newRow("multiple paragraphs") << QStringLiteral("<p>Text</p>\n<p>Text</p>")
|
||||||
<< QList<MessageComponent>{MessageComponent{MessageComponentType::Text, u"Text"_s, {}},
|
<< QList<MessageComponent>{MessageComponent{MessageComponentType::Text, QStringLiteral("Text"), {}},
|
||||||
MessageComponent{MessageComponentType::Text, u"Text"_s, {}}};
|
MessageComponent{MessageComponentType::Text, QStringLiteral("Text"), {}}};
|
||||||
QTest::newRow("code") << u"<p>Text</p>\n<pre><code class=\"language-html\">Some code\n</code></pre>"_s
|
QTest::newRow("code") << QStringLiteral("<p>Text</p>\n<pre><code class=\"language-html\">Some code\n</code></pre>")
|
||||||
<< QList<MessageComponent>{MessageComponent{MessageComponentType::Text, u"Text"_s, {}},
|
<< QList<MessageComponent>{MessageComponent{MessageComponentType::Text, QStringLiteral("Text"), {}},
|
||||||
MessageComponent{MessageComponentType::Code, u"Some code"_s, QVariantMap{{u"class"_s, u"html"_s}}}};
|
MessageComponent{MessageComponentType::Code,
|
||||||
QTest::newRow("quote") << u"<p>Text</p>\n<blockquote>\n<p>blockquote</p>\n</blockquote>"_s
|
QStringLiteral("Some code"),
|
||||||
<< QList<MessageComponent>{MessageComponent{MessageComponentType::Text, u"Text"_s, {}},
|
QVariantMap{{QStringLiteral("class"), QStringLiteral("html")}}}};
|
||||||
MessageComponent{MessageComponentType::Quote, u"“blockquote”"_s, {}}};
|
QTest::newRow("quote") << QStringLiteral("<p>Text</p>\n<blockquote>\n<p>blockquote</p>\n</blockquote>")
|
||||||
QTest::newRow("multiple paragraph quote") << u"<blockquote>\n<p>blockquote</p>\n<p>next paragraph</p>\n</blockquote>"_s
|
<< QList<MessageComponent>{MessageComponent{MessageComponentType::Text, QStringLiteral("Text"), {}},
|
||||||
|
MessageComponent{MessageComponentType::Quote, QStringLiteral("“blockquote”"), {}}};
|
||||||
|
QTest::newRow("no tag first paragraph") << QStringLiteral("Text\n<p>Text</p>")
|
||||||
|
<< QList<MessageComponent>{MessageComponent{MessageComponentType::Text, QStringLiteral("Text"), {}},
|
||||||
|
MessageComponent{MessageComponentType::Text, QStringLiteral("Text"), {}}};
|
||||||
|
QTest::newRow("no tag last paragraph") << QStringLiteral("<p>Text</p>\nText")
|
||||||
|
<< QList<MessageComponent>{MessageComponent{MessageComponentType::Text, QStringLiteral("Text"), {}},
|
||||||
|
MessageComponent{MessageComponentType::Text, QStringLiteral("Text"), {}}};
|
||||||
|
QTest::newRow("inline code") << QStringLiteral("<p><code>https://kde.org</code></p>\n<p>Text</p>")
|
||||||
|
<< QList<MessageComponent>{MessageComponent{MessageComponentType::Text, QStringLiteral("<code>https://kde.org</code>"), {}},
|
||||||
|
MessageComponent{MessageComponentType::Text, QStringLiteral("Text"), {}}};
|
||||||
|
QTest::newRow("inline code single block") << QStringLiteral("<code>https://kde.org</code>")
|
||||||
<< QList<MessageComponent>{
|
<< QList<MessageComponent>{
|
||||||
MessageComponent{MessageComponentType::Quote, u"<p>“blockquote</p>\n<p>next paragraph”</p>"_s, {}}};
|
MessageComponent{MessageComponentType::Text, QStringLiteral("<code>https://kde.org</code>"), {}}};
|
||||||
QTest::newRow("no tag first paragraph") << u"Text\n<p>Text</p>"_s
|
|
||||||
<< QList<MessageComponent>{MessageComponent{MessageComponentType::Text, u"Text"_s, {}},
|
|
||||||
MessageComponent{MessageComponentType::Text, u"Text"_s, {}}};
|
|
||||||
QTest::newRow("no tag last paragraph") << u"<p>Text</p>\nText"_s
|
|
||||||
<< QList<MessageComponent>{MessageComponent{MessageComponentType::Text, u"Text"_s, {}},
|
|
||||||
MessageComponent{MessageComponentType::Text, u"Text"_s, {}}};
|
|
||||||
QTest::newRow("inline code") << u"<p><code>https://kde.org</code></p>\n<p>Text</p>"_s
|
|
||||||
<< QList<MessageComponent>{MessageComponent{MessageComponentType::Text, u"<code>https://kde.org</code>"_s, {}},
|
|
||||||
MessageComponent{MessageComponentType::Text, u"Text"_s, {}}};
|
|
||||||
QTest::newRow("inline code single block") << u"<code>https://kde.org</code>"_s
|
|
||||||
<< QList<MessageComponent>{MessageComponent{MessageComponentType::Text, u"<code>https://kde.org</code>"_s, {}}};
|
|
||||||
QTest::newRow("long start tag")
|
QTest::newRow("long start tag")
|
||||||
<< u"Ah, you mean something like<br/><pre data-md=\"```\"><code class=\"language-qml\"># main.qml\nimport CustomQml\n...\nControls.TextField { id: someField }\nCustomQml {\n someTextProperty: someField.text\n}\n</code></pre>Sure you can, it's still local to the same file where you defined the id"_s
|
<< QStringLiteral(
|
||||||
|
"Ah, you mean something like<br/><pre data-md=\"```\"><code class=\"language-qml\"># main.qml\nimport CustomQml\n...\nControls.TextField { id: "
|
||||||
|
"someField }\nCustomQml {\n someTextProperty: someField.text\n}\n</code></pre>Sure you can, it's still local to the same file where you "
|
||||||
|
"defined the id")
|
||||||
<< QList<MessageComponent>{
|
<< QList<MessageComponent>{
|
||||||
MessageComponent{MessageComponentType::Text, u"Ah, you mean something like<br/>"_s, {}},
|
MessageComponent{MessageComponentType::Text, QStringLiteral("Ah, you mean something like<br/>"), {}},
|
||||||
MessageComponent{
|
MessageComponent{
|
||||||
MessageComponentType::Code,
|
MessageComponentType::Code,
|
||||||
u"# main.qml\nimport CustomQml\n...\nControls.TextField { id: someField }\nCustomQml {\n someTextProperty: someField.text\n}"_s,
|
QStringLiteral(
|
||||||
QVariantMap{{u"class"_s, u"qml"_s}}},
|
"# main.qml\nimport CustomQml\n...\nControls.TextField { id: someField }\nCustomQml {\n someTextProperty: someField.text\n}"),
|
||||||
MessageComponent{MessageComponentType::Text, u"Sure you can, it's still local to the same file where you defined the id"_s, {}}};
|
QVariantMap{{QStringLiteral("class"), QStringLiteral("qml")}}},
|
||||||
|
MessageComponent{MessageComponentType::Text, QStringLiteral("Sure you can, it's still local to the same file where you defined the id"), {}}};
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextHandlerTest::componentOutput()
|
void TextHandlerTest::componentOutput()
|
||||||
|
|||||||
@@ -1,37 +0,0 @@
|
|||||||
# SPDX-FileCopyrightText: 2024 James Graham <james.h.graham@protonmail.com>
|
|
||||||
# SPDX-License-Identifier: BSD-2-Clause
|
|
||||||
|
|
||||||
add_definitions(-DDATA_DIR="${CMAKE_CURRENT_SOURCE_DIR}" )
|
|
||||||
|
|
||||||
qt_add_executable(timeline-memtest
|
|
||||||
main.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
target_link_libraries(timeline-memtest PRIVATE neochatplugin Timelineplugin)
|
|
||||||
target_link_libraries(timeline-memtest PUBLIC
|
|
||||||
Qt::Core
|
|
||||||
Qt::Quick
|
|
||||||
Qt::Qml
|
|
||||||
Qt::Gui
|
|
||||||
Qt::QuickControls2
|
|
||||||
Qt::Widgets
|
|
||||||
KF6::I18nQml
|
|
||||||
KF6::Kirigami
|
|
||||||
QuotientQt6
|
|
||||||
LibNeoChat
|
|
||||||
Timeline
|
|
||||||
)
|
|
||||||
|
|
||||||
ecm_add_qml_module(timeline-memtest URI org.kde.neochat.timeline-memtest GENERATE_PLUGIN_SOURCE
|
|
||||||
OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/src/org/kde/timeline-memtest
|
|
||||||
QML_FILES
|
|
||||||
Main.qml
|
|
||||||
SOURCES
|
|
||||||
memtesttimelinemodel.cpp
|
|
||||||
memtesttimelinemodel.h
|
|
||||||
DEPENDENCIES
|
|
||||||
QtCore
|
|
||||||
QtQuick
|
|
||||||
IMPORTS
|
|
||||||
org.kde.neochat.timeline
|
|
||||||
)
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
// 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.Controls as QQC2
|
|
||||||
|
|
||||||
import org.kde.kirigami as Kirigami
|
|
||||||
|
|
||||||
import org.kde.neochat
|
|
||||||
|
|
||||||
QQC2.ApplicationWindow {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
title: "Timeline Memory Test"
|
|
||||||
|
|
||||||
minimumWidth: Kirigami.Units.gridUnit * 30
|
|
||||||
minimumHeight: Kirigami.Units.gridUnit * 30
|
|
||||||
|
|
||||||
visible: true
|
|
||||||
|
|
||||||
QQC2.ScrollView {
|
|
||||||
width: root.width
|
|
||||||
height: root.height
|
|
||||||
|
|
||||||
contentItem: ListView {
|
|
||||||
cacheBuffer: 1000000
|
|
||||||
model: messageFilterModel
|
|
||||||
|
|
||||||
delegate: EventDelegate {
|
|
||||||
room: memTestTimelineModel.room
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
// 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
|
|
||||||
|
|
||||||
#include <QApplication>
|
|
||||||
#include <QQmlApplicationEngine>
|
|
||||||
#include <QQmlContext>
|
|
||||||
|
|
||||||
#include <KLocalizedQmlContext>
|
|
||||||
#include <KLocalizedString>
|
|
||||||
|
|
||||||
#include "memtesttimelinemodel.h"
|
|
||||||
#include "models/messagefiltermodel.h"
|
|
||||||
|
|
||||||
using namespace Qt::StringLiterals;
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
QApplication app(argc, argv);
|
|
||||||
|
|
||||||
KLocalizedString::setApplicationDomain(QByteArrayLiteral("neochat"));
|
|
||||||
|
|
||||||
QQmlApplicationEngine engine;
|
|
||||||
|
|
||||||
KLocalization::setupLocalizedContext(&engine);
|
|
||||||
|
|
||||||
MemTestTimelineModel *memTestTimelineModel = new MemTestTimelineModel;
|
|
||||||
MessageFilterModel *messageFilterModel = new MessageFilterModel(nullptr, memTestTimelineModel);
|
|
||||||
engine.rootContext()->setContextProperty(u"memTestTimelineModel"_s, memTestTimelineModel);
|
|
||||||
engine.rootContext()->setContextProperty(u"messageFilterModel"_s, messageFilterModel);
|
|
||||||
|
|
||||||
engine.loadFromModule("org.kde.neochat.timeline-memtest", "Main");
|
|
||||||
|
|
||||||
return app.exec();
|
|
||||||
}
|
|
||||||
@@ -1,379 +0,0 @@
|
|||||||
{
|
|
||||||
"ephemeral": {
|
|
||||||
"events": [
|
|
||||||
{
|
|
||||||
"content": {
|
|
||||||
"$1000000000000:example.org": {
|
|
||||||
"m.read": {
|
|
||||||
"@alice:example.org": {
|
|
||||||
"ts": 1000000000000
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"type": "m.receipt"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"content": {
|
|
||||||
"$1000000000000:example.org": {
|
|
||||||
"m.read": {
|
|
||||||
"@bob:example.org": {
|
|
||||||
"ts": 1000000000000
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"type": "m.receipt"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"content": {
|
|
||||||
"$1000000000003:example.org": {
|
|
||||||
"m.read": {
|
|
||||||
"@tim:example.org": {
|
|
||||||
"ts": 1000000000000
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"type": "m.receipt"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"content": {
|
|
||||||
"$1000000000003:example.org": {
|
|
||||||
"m.read": {
|
|
||||||
"@example:example.org": {
|
|
||||||
"ts": 1000000000000
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"type": "m.receipt"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"content": {
|
|
||||||
"$1000000000003:example.org": {
|
|
||||||
"m.read": {
|
|
||||||
"@jeff:example.org": {
|
|
||||||
"ts": 1000000000000
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"type": "m.receipt"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"content": {
|
|
||||||
"$1000000000003:example.org": {
|
|
||||||
"m.read": {
|
|
||||||
"@tina:example.org": {
|
|
||||||
"ts": 1000000000000
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"type": "m.receipt"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"content": {
|
|
||||||
"$1000000000003:example.org": {
|
|
||||||
"m.read": {
|
|
||||||
"@sally:example.org": {
|
|
||||||
"ts": 1000000000000
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"type": "m.receipt"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"content": {
|
|
||||||
"$1000000000003:example.org": {
|
|
||||||
"m.read": {
|
|
||||||
"@fred:example.org": {
|
|
||||||
"ts": 1000000000000
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"type": "m.receipt"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"state": {
|
|
||||||
"events": [
|
|
||||||
{
|
|
||||||
"content": {
|
|
||||||
"avatar_url": "mxc://example.org/SEsfnsuifSDFSSEF",
|
|
||||||
"displayname": "Example",
|
|
||||||
"membership": "join"
|
|
||||||
},
|
|
||||||
"event_id": "$143273582555PhrSn:example.org",
|
|
||||||
"origin_server_ts": 1000000000000,
|
|
||||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
|
||||||
"sender": "example:example.org",
|
|
||||||
"state_key": "@example:example.org",
|
|
||||||
"type": "m.room.member",
|
|
||||||
"unsigned": {
|
|
||||||
"age": 1234
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"content": {
|
|
||||||
"avatar_url": "mxc://example.org/SEsfnsuifSDFSSEF",
|
|
||||||
"displayname": "Alice",
|
|
||||||
"membership": "join",
|
|
||||||
"reason": "Looking for support"
|
|
||||||
},
|
|
||||||
"event_id": "$143273582443PhrSn:example.org",
|
|
||||||
"origin_server_ts": 1000000000000,
|
|
||||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
|
||||||
"sender": "alice:example.org",
|
|
||||||
"state_key": "@alice:example.org",
|
|
||||||
"type": "m.room.member",
|
|
||||||
"unsigned": {
|
|
||||||
"age": 1234
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"content": {
|
|
||||||
"avatar_url": "mxc://example.org/SEsfnsuifSDFSSEF",
|
|
||||||
"displayname": "Bob",
|
|
||||||
"membership": "join"
|
|
||||||
},
|
|
||||||
"event_id": "$143273582443PhrSn:example.org",
|
|
||||||
"origin_server_ts": 1000000000000,
|
|
||||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
|
||||||
"sender": "bob:example.org",
|
|
||||||
"state_key": "@bob:example.org",
|
|
||||||
"type": "m.room.member",
|
|
||||||
"unsigned": {
|
|
||||||
"age": 1234
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"content": {
|
|
||||||
"avatar_url": "mxc://example.org/SEsfnsuifSDFSSEF",
|
|
||||||
"displayname": "Tim",
|
|
||||||
"membership": "join"
|
|
||||||
},
|
|
||||||
"event_id": "$143273582443PhrSn:example.org",
|
|
||||||
"origin_server_ts": 1000000000000,
|
|
||||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
|
||||||
"sender": "tim:example.org",
|
|
||||||
"state_key": "@tim:example.org",
|
|
||||||
"type": "m.room.member",
|
|
||||||
"unsigned": {
|
|
||||||
"age": 1234
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"content": {
|
|
||||||
"avatar_url": "mxc://example.org/SEsfnsuifSDFSSEF",
|
|
||||||
"displayname": "Jeff",
|
|
||||||
"membership": "join"
|
|
||||||
},
|
|
||||||
"event_id": "$143273582443PhrSn:example.org",
|
|
||||||
"origin_server_ts": 1000000000000,
|
|
||||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
|
||||||
"sender": "jeff:example.org",
|
|
||||||
"state_key": "@jeff:example.org",
|
|
||||||
"type": "m.room.member",
|
|
||||||
"unsigned": {
|
|
||||||
"age": 1234
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"content": {
|
|
||||||
"avatar_url": "mxc://example.org/SEsfnsuifSDFSSEF",
|
|
||||||
"displayname": "Tina",
|
|
||||||
"membership": "join"
|
|
||||||
},
|
|
||||||
"event_id": "$143273582443PhrSn:example.org",
|
|
||||||
"origin_server_ts": 1000000000000,
|
|
||||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
|
||||||
"sender": "tina:example.org",
|
|
||||||
"state_key": "@tina:example.org",
|
|
||||||
"type": "m.room.member",
|
|
||||||
"unsigned": {
|
|
||||||
"age": 1234
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"content": {
|
|
||||||
"avatar_url": "mxc://example.org/SEsfnsuifSDFSSEF",
|
|
||||||
"displayname": "Sally",
|
|
||||||
"membership": "join"
|
|
||||||
},
|
|
||||||
"event_id": "$143273582443PhrSn:example.org",
|
|
||||||
"origin_server_ts": 1000000000000,
|
|
||||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
|
||||||
"sender": "sally:example.org",
|
|
||||||
"state_key": "@sally:example.org",
|
|
||||||
"type": "m.room.member",
|
|
||||||
"unsigned": {
|
|
||||||
"age": 1234
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"content": {
|
|
||||||
"avatar_url": "mxc://example.org/SEsfnsuifSDFSSEF",
|
|
||||||
"displayname": "Fred",
|
|
||||||
"membership": "join"
|
|
||||||
},
|
|
||||||
"event_id": "$143273582443PhrSn:example.org",
|
|
||||||
"origin_server_ts": 1000000000000,
|
|
||||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
|
||||||
"sender": "fred:example.org",
|
|
||||||
"state_key": "@fred:example.org",
|
|
||||||
"type": "m.room.member",
|
|
||||||
"unsigned": {
|
|
||||||
"age": 1234
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"timeline": {
|
|
||||||
"events": [
|
|
||||||
{
|
|
||||||
"content": {
|
|
||||||
"body": "This is an example text message",
|
|
||||||
"format": "org.matrix.custom.html",
|
|
||||||
"formatted_body": "This is an example<br>text message",
|
|
||||||
"msgtype": "m.text"
|
|
||||||
},
|
|
||||||
"event_id": 0,
|
|
||||||
"origin_server_ts": 1000000000000,
|
|
||||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
|
||||||
"sender": "@example:example.org",
|
|
||||||
"type": "m.room.message",
|
|
||||||
"unsigned": {
|
|
||||||
"age": 1232
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"content": {
|
|
||||||
"body": "This is a highlight @bob:example.org",
|
|
||||||
"msgtype": "m.text"
|
|
||||||
},
|
|
||||||
"event_id": 1,
|
|
||||||
"origin_server_ts": 1000000000001,
|
|
||||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
|
||||||
"sender": "@example:example.org",
|
|
||||||
"type": "m.room.message",
|
|
||||||
"unsigned": {
|
|
||||||
"age": 1233
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"content": {
|
|
||||||
"m.relates_to": {
|
|
||||||
"event_id": 1,
|
|
||||||
"key": "👍",
|
|
||||||
"rel_type": "m.annotation"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"origin_server_ts": 1000000000002,
|
|
||||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
|
||||||
"sender": "@alice:example.org",
|
|
||||||
"type": "m.reaction",
|
|
||||||
"unsigned": {
|
|
||||||
"age": 390159120
|
|
||||||
},
|
|
||||||
"event_id": 2,
|
|
||||||
"age": 390159120
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"content": {
|
|
||||||
"body": "reply",
|
|
||||||
"format": "org.matrix.custom.html",
|
|
||||||
"formatted_body": "reply",
|
|
||||||
"m.relates_to": {
|
|
||||||
"m.in_reply_to": {
|
|
||||||
"event_id": 0
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"msgtype": "m.text"
|
|
||||||
},
|
|
||||||
"origin_server_ts": 1000000000003,
|
|
||||||
"sender": "@alice:example.org",
|
|
||||||
"type": "m.room.message",
|
|
||||||
"unsigned": {
|
|
||||||
"age": 98
|
|
||||||
},
|
|
||||||
"event_id": 3,
|
|
||||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"age": 96845207,
|
|
||||||
"content": {
|
|
||||||
"body": "Lat: 51.7035, Lon: -1.14394",
|
|
||||||
"geo_uri": "geo:51.7035,-1.14394",
|
|
||||||
"msgtype": "m.location",
|
|
||||||
"org.matrix.msc1767.text": "Lat: 51.7035, Lon: -1.14394",
|
|
||||||
"org.matrix.msc3488.asset": {
|
|
||||||
"type": "m.pin"
|
|
||||||
},
|
|
||||||
"org.matrix.msc3488.location": {
|
|
||||||
"uri": "geo:51.7035,-1.14394"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"event_id": 4,
|
|
||||||
"origin_server_ts": 1000000000004,
|
|
||||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
|
||||||
"sender": "@example:example.org",
|
|
||||||
"type": "m.room.message",
|
|
||||||
"unsigned": {
|
|
||||||
"age": 96845207
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"content": {
|
|
||||||
"body": "```cpp\nint main(int argc, char **argv)\n{\n QApplication app(argc, argv);\n\n KLocalizedString::setApplicationDomain(QByteArrayLiteral(\"neochat\"));\n\n QQmlApplicationEngine engine;\n engine.loadFromModule(\"org.kde.neochat.timeline-memtest\", \"Main\");\n\n return app.exec();\n}\n```",
|
|
||||||
"format": "org.matrix.custom.html",
|
|
||||||
"formatted_body": "<pre><code class=\"language-cpp\">int main(int argc, char **argv)\n{\n QApplication app(argc, argv);\n\n KLocalizedString::setApplicationDomain(QByteArrayLiteral("neochat"));\n\n QQmlApplicationEngine engine;\n engine.loadFromModule("org.kde.neochat.timeline-memtest", "Main");\n\n return app.exec();\n}\n</code></pre>",
|
|
||||||
"msgtype": "m.text"
|
|
||||||
},
|
|
||||||
"event_id": 5,
|
|
||||||
"origin_server_ts": 1000000000005,
|
|
||||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
|
||||||
"sender": "@bob:example.org",
|
|
||||||
"type": "m.room.message",
|
|
||||||
"unsigned": {
|
|
||||||
"age": 1233
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"content": {
|
|
||||||
"body": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam sed fringilla risus, eget lacinia risus. Suspendisse at magna id justo sagittis suscipit. Maecenas eros quam, pulvinar a consequat sed, varius vitae risus. Cras congue est eget felis porttitor lobortis. Nam cursus, nulla ut finibus suscipit, tellus eros tincidunt ante, a volutpat velit lectus sit amet turpis. Morbi leo justo, fringilla sed rutrum a, suscipit a quam. Proin rhoncus neque eget ligula ullamcorper pellentesque. Mauris volutpat malesuada nunc. Nullam finibus enim eu nibh placerat imperdiet. Nullam in mi in diam luctus scelerisque dignissim non erat. ",
|
|
||||||
"msgtype": "m.text"
|
|
||||||
},
|
|
||||||
"event_id": 6,
|
|
||||||
"origin_server_ts": 1000000000006,
|
|
||||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
|
||||||
"sender": "@example:example.org",
|
|
||||||
"type": "m.room.message",
|
|
||||||
"unsigned": {
|
|
||||||
"age": 1232
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"content": {
|
|
||||||
"body": "> Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam sed fringilla risus, eget lacinia risus. Suspendisse at magna id justo sagittis suscipit. Maecenas eros quam, pulvinar a consequat sed, varius vitae risus. Cras congue est eget felis porttitor lobortis. Nam cursus, nulla ut finibus suscipit, tellus eros tincidunt ante, a volutpat velit lectus sit amet turpis. Morbi leo justo, fringilla sed rutrum a, suscipit a quam. Proin rhoncus neque eget ligula ullamcorper pellentesque. Mauris volutpat malesuada nunc. Nullam finibus enim eu nibh placerat imperdiet. Nullam in mi in diam luctus scelerisque dignissim non erat. ",
|
|
||||||
"format": "org.matrix.custom.html",
|
|
||||||
"formatted_body": "<blockquote>\n<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam sed fringilla risus, eget lacinia risus. Suspendisse at magna id justo sagittis suscipit. Maecenas eros quam, pulvinar a consequat sed, varius vitae risus. Cras congue est eget felis porttitor lobortis. Nam cursus, nulla ut finibus suscipit, tellus eros tincidunt ante, a volutpat velit lectus sit amet turpis. Morbi leo justo, fringilla sed rutrum a, suscipit a quam. Proin rhoncus neque eget ligula ullamcorper pellentesque. Mauris volutpat malesuada nunc. Nullam finibus enim eu nibh placerat imperdiet. Nullam in mi in diam luctus scelerisque dignissim non erat.</p>\n</blockquote>",
|
|
||||||
"msgtype": "m.text"
|
|
||||||
},
|
|
||||||
"event_id": 7,
|
|
||||||
"origin_server_ts": 1000000000007,
|
|
||||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
|
||||||
"sender": "@example:example.org",
|
|
||||||
"type": "m.room.message",
|
|
||||||
"unsigned": {
|
|
||||||
"age": 1232
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"limited": true,
|
|
||||||
"prev_batch": "t34-23535_0_0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
// 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
|
|
||||||
|
|
||||||
#include "memtesttimelinemodel.h"
|
|
||||||
|
|
||||||
#include <Quotient/events/eventcontent.h>
|
|
||||||
#include <Quotient/events/roommessageevent.h>
|
|
||||||
|
|
||||||
using namespace Quotient;
|
|
||||||
|
|
||||||
MemTestTimelineModel::MemTestTimelineModel(QObject *parent)
|
|
||||||
: MessageModel(parent)
|
|
||||||
{
|
|
||||||
beginResetModel();
|
|
||||||
m_connection = Connection::makeMockConnection(u"@bob:example.org"_s);
|
|
||||||
m_room = new MemTestRoom(m_connection, u"#memtestroom:example.org"_s, u"memtest-sync.json"_s);
|
|
||||||
|
|
||||||
for (const auto &eventIt : m_room->messageEvents()) {
|
|
||||||
Q_EMIT newEventAdded(eventIt.event());
|
|
||||||
}
|
|
||||||
|
|
||||||
endResetModel();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::optional<std::reference_wrapper<const RoomEvent>> MemTestTimelineModel::getEventForIndex(QModelIndex index) const
|
|
||||||
{
|
|
||||||
return *m_room->messageEvents().at(index.row()).event();
|
|
||||||
}
|
|
||||||
|
|
||||||
int MemTestTimelineModel::rowCount(const QModelIndex &parent) const
|
|
||||||
{
|
|
||||||
Q_UNUSED(parent);
|
|
||||||
return m_room->messageEvents().size();
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "moc_memtesttimelinemodel.cpp"
|
|
||||||
@@ -1,117 +0,0 @@
|
|||||||
// 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
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QAbstractListModel>
|
|
||||||
#include <QQmlEngine>
|
|
||||||
|
|
||||||
#include <Quotient/events/roomevent.h>
|
|
||||||
#include <Quotient/syncdata.h>
|
|
||||||
|
|
||||||
#include "models/messagemodel.h"
|
|
||||||
|
|
||||||
namespace Quotient
|
|
||||||
{
|
|
||||||
class Connection;
|
|
||||||
}
|
|
||||||
|
|
||||||
class NeoChatRoom;
|
|
||||||
|
|
||||||
class MemTestRoom : public NeoChatRoom
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
MemTestRoom(Quotient::Connection *connection, const QString &roomName, const QString &syncFileName = {})
|
|
||||||
: NeoChatRoom(connection, roomName, Quotient::JoinState::Join)
|
|
||||||
{
|
|
||||||
syncNewEvents(syncFileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
void update(Quotient::SyncRoomData &&data, bool fromCache = false)
|
|
||||||
{
|
|
||||||
Room::updateData(std::move(data), fromCache);
|
|
||||||
}
|
|
||||||
|
|
||||||
void syncNewEvents(const QString &syncFileName)
|
|
||||||
{
|
|
||||||
if (!syncFileName.isEmpty()) {
|
|
||||||
QFile testSyncFile;
|
|
||||||
testSyncFile.setFileName(QStringLiteral(DATA_DIR) + u'/' + syncFileName);
|
|
||||||
testSyncFile.open(QIODevice::ReadOnly);
|
|
||||||
auto testSyncJson = QJsonDocument::fromJson(testSyncFile.readAll()).object();
|
|
||||||
auto timelineJson = testSyncJson["timeline"_L1].toObject();
|
|
||||||
timelineJson["events"_L1] = multiplyEvents(timelineJson["events"_L1].toArray(), 100);
|
|
||||||
testSyncJson["timeline"_L1] = timelineJson;
|
|
||||||
Quotient::SyncRoomData roomData(id(), Quotient::JoinState::Join, testSyncJson);
|
|
||||||
update(std::move(roomData));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QJsonArray multiplyEvents(QJsonArray events, int factor)
|
|
||||||
{
|
|
||||||
QJsonArray newArray;
|
|
||||||
int eventNum = 0;
|
|
||||||
int ts = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < factor; ++i) {
|
|
||||||
for (const auto &event : events) {
|
|
||||||
auto eventObject = event.toObject();
|
|
||||||
auto contentJson = eventObject["content"_L1].toObject();
|
|
||||||
if (contentJson.contains("m.relates_to"_L1)) {
|
|
||||||
auto relatesToJson = contentJson["m.relates_to"_L1].toObject();
|
|
||||||
if (relatesToJson.contains("m.in_reply_to"_L1)) {
|
|
||||||
auto replyJson = relatesToJson["m.in_reply_to"_L1].toObject();
|
|
||||||
const auto currentId = eventObject["event_id"_L1].toInt();
|
|
||||||
const auto currentReplyId = replyJson["event_id"_L1].toInt();
|
|
||||||
replyJson["event_id"_L1] = "$%1:example.org"_L1.arg(QString::number(eventNum - (currentId - currentReplyId)));
|
|
||||||
relatesToJson["m.in_reply_to"_L1] = replyJson;
|
|
||||||
} else if (relatesToJson.contains("event_id"_L1)) {
|
|
||||||
const auto currentId = eventObject["event_id"_L1].toInt();
|
|
||||||
const auto currentRelationId = relatesToJson["event_id"_L1].toInt();
|
|
||||||
relatesToJson["event_id"_L1] = "$%1:example.org"_L1.arg(QString::number(eventNum - (currentId - currentRelationId)));
|
|
||||||
}
|
|
||||||
contentJson["m.relates_to"_L1] = relatesToJson;
|
|
||||||
eventObject["content"_L1] = contentJson;
|
|
||||||
}
|
|
||||||
eventObject["event_id"_L1] = "$%1:example.org"_L1.arg(QString::number(eventNum));
|
|
||||||
eventObject["origin_server_ts"_L1] = ts;
|
|
||||||
auto unsignedJson = eventObject["unsigned"_L1].toObject();
|
|
||||||
unsignedJson["age"_L1] = ts;
|
|
||||||
eventObject["unsigned"_L1] = unsignedJson;
|
|
||||||
newArray.append(eventObject);
|
|
||||||
++eventNum;
|
|
||||||
++ts;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return newArray;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @class MemTestTimelineModel
|
|
||||||
*
|
|
||||||
* This is a special version of the MessageModel design to load an unchanging set
|
|
||||||
* of events from a json file so that timeline memory optimisations can be measured.
|
|
||||||
*/
|
|
||||||
class MemTestTimelineModel : public MessageModel
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
QML_ELEMENT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit MemTestTimelineModel(QObject *parent = nullptr);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Number of rows in the model.
|
|
||||||
*
|
|
||||||
* @sa QAbstractItemModel::rowCount
|
|
||||||
*/
|
|
||||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
QPointer<Quotient::Connection> m_connection;
|
|
||||||
|
|
||||||
std::vector<Quotient::RoomEventPtr> m_events;
|
|
||||||
|
|
||||||
std::optional<std::reference_wrapper<const Quotient::RoomEvent>> getEventForIndex(QModelIndex index) const override;
|
|
||||||
};
|
|
||||||
@@ -26,7 +26,6 @@
|
|||||||
<name xml:lang="fr">NeoChat</name>
|
<name xml:lang="fr">NeoChat</name>
|
||||||
<name xml:lang="gl">NeoChat</name>
|
<name xml:lang="gl">NeoChat</name>
|
||||||
<name xml:lang="he">NeoChat</name>
|
<name xml:lang="he">NeoChat</name>
|
||||||
<name xml:lang="hi">नियोचैट</name>
|
|
||||||
<name xml:lang="hu">NeoChat</name>
|
<name xml:lang="hu">NeoChat</name>
|
||||||
<name xml:lang="ia">Neochat</name>
|
<name xml:lang="ia">Neochat</name>
|
||||||
<name xml:lang="id">NeoChat</name>
|
<name xml:lang="id">NeoChat</name>
|
||||||
@@ -42,7 +41,6 @@
|
|||||||
<name xml:lang="pt">NeoChat</name>
|
<name xml:lang="pt">NeoChat</name>
|
||||||
<name xml:lang="pt-BR">NeoChat</name>
|
<name xml:lang="pt-BR">NeoChat</name>
|
||||||
<name xml:lang="ru">NeoChat</name>
|
<name xml:lang="ru">NeoChat</name>
|
||||||
<name xml:lang="sa">नवचैट्</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="sv">NeoChat</name>
|
||||||
@@ -65,18 +63,13 @@
|
|||||||
<summary xml:lang="fr">Discuter sur Matrix</summary>
|
<summary xml:lang="fr">Discuter sur Matrix</summary>
|
||||||
<summary xml:lang="gl">Charlar en Matrix</summary>
|
<summary xml:lang="gl">Charlar en Matrix</summary>
|
||||||
<summary xml:lang="he">התכתבות דרך Matrix</summary>
|
<summary xml:lang="he">התכתבות דרך Matrix</summary>
|
||||||
<summary xml:lang="hi">मैट्रिक्स पर चैट करें</summary>
|
|
||||||
<summary xml:lang="hu">Csevegés Matrixon</summary>
|
<summary xml:lang="hu">Csevegés Matrixon</summary>
|
||||||
<summary xml:lang="ia">Conversation en ditecto sur Matrix</summary>
|
<summary xml:lang="ia">Conversation en ditecto sur Matrix</summary>
|
||||||
<summary xml:lang="it">Chat su Matrix</summary>
|
<summary xml:lang="it">Chat su Matrix</summary>
|
||||||
<summary xml:lang="ka">ისაუბრეთ Matrix-ზე</summary>
|
<summary xml:lang="ka">ისაუბრეთ Matrix-ზე</summary>
|
||||||
<summary xml:lang="ko">Matrix에서 대화하기</summary>
|
|
||||||
<summary xml:lang="lv">Tērzējiet „Matrix“ tīklā</summary>
|
|
||||||
<summary xml:lang="nl">Chat op Matrix</summary>
|
<summary xml:lang="nl">Chat op Matrix</summary>
|
||||||
<summary xml:lang="nn">Prat med via Matrix</summary>
|
<summary xml:lang="nn">Prat med via Matrix</summary>
|
||||||
<summary xml:lang="pl">Rozmawiaj na Matriksie</summary>
|
<summary xml:lang="pl">Rozmawiaj na Matriksie</summary>
|
||||||
<summary xml:lang="ru">Общение в Matrix</summary>
|
|
||||||
<summary xml:lang="sa">Matrix इत्यत्र गपशपं कुर्वन्तु</summary>
|
|
||||||
<summary xml:lang="sl">Klepet na Matrixu</summary>
|
<summary xml:lang="sl">Klepet na Matrixu</summary>
|
||||||
<summary xml:lang="sv">Chatta på Matrix</summary>
|
<summary xml:lang="sv">Chatta på Matrix</summary>
|
||||||
<summary xml:lang="ta">மேட்ரிக்ஸுக்கான உரையாடல் செயலி</summary>
|
<summary xml:lang="ta">மேட்ரிக்ஸுக்கான உரையாடல் செயலி</summary>
|
||||||
@@ -99,18 +92,15 @@
|
|||||||
<p xml:lang="fr">NeoChat est une application de discussions vous permettant de profiter pleinement du réseau Matrix. Elle vous offre un moyen sécurisé d'envoyer des messages de texte, des vidéos et des fichiers audio à votre famille, vos collègues et vos ami(e)s.</p>
|
<p xml:lang="fr">NeoChat est une application de discussions vous permettant de profiter pleinement du réseau Matrix. Elle vous offre un moyen sécurisé d'envoyer des messages de texte, des vidéos et des fichiers audio à votre famille, vos collègues et vos ami(e)s.</p>
|
||||||
<p xml:lang="gl">NeoChat é unha aplicación de conversa que lle permite usar todas as funcionalidades da rede Matrix. Fornece unha forma segura de enviar mensaxes de texto e ficheiros de vídeo e son a familiares, amizades ou no traballo.</p>
|
<p xml:lang="gl">NeoChat é unha aplicación de conversa que lle permite usar todas as funcionalidades da rede Matrix. Fornece unha forma segura de enviar mensaxes de texto e ficheiros de vídeo e son a familiares, amizades ou no traballo.</p>
|
||||||
<p xml:lang="he">NeoChat הוא יישום התכתבות שמאפשר לך לנצל את רשת Matrix במלואה. הוא מספק דרך מאובטחת לשליחת הודעות כתובות, סרטונים וקובצי שמע למשפחה, לעמיתים לעבודה ולחברים.</p>
|
<p xml:lang="he">NeoChat הוא יישום התכתבות שמאפשר לך לנצל את רשת Matrix במלואה. הוא מספק דרך מאובטחת לשליחת הודעות כתובות, סרטונים וקובצי שמע למשפחה, לעמיתים לעבודה ולחברים.</p>
|
||||||
<p xml:lang="hi">नियोचैट एक चैट ऐप है जो आपको मैट्रिक्स नेटवर्क का पूरा लाभ उठाने देता है। यह आपको अपने परिवार, सहकर्मियों और दोस्तों को टेक्स्ट संदेश, वीडियो और ऑडियो फ़ाइलें भेजने का एक सुरक्षित तरीका प्रदान करता है।</p>
|
|
||||||
<p xml:lang="hu">A NeoChat egy olyan csevegőalkalmazás, amellyel teljes mértékben kihasználhatja a Matrix hálózatot. Biztonságos módot biztosít szöveges üzenetek, videók és hangfájlok küldéséhez családtagjainak, kollégáinak és barátainak.</p>
|
<p xml:lang="hu">A NeoChat egy olyan csevegőalkalmazás, amellyel teljes mértékben kihasználhatja a Matrix hálózatot. Biztonságos módot biztosít szöveges üzenetek, videók és hangfájlok küldéséhez családtagjainak, kollégáinak és barátainak.</p>
|
||||||
<p xml:lang="ia">NeoChat es un app de conversation que te permitte prender avantage plen del rete Matrix. Il te forni un modo secur de inviar messages de texto, videos e files audio a tui familia, collegas e amicos.</p>
|
<p xml:lang="ia">NeoChat es un app de conversation que te permitte prender avantage plen del rete Matrix. Il te forni un modo secur de inviar messages de texto, videos e files audio a tui familia, collegas e amicos.</p>
|
||||||
<p xml:lang="it">NeoChat è un'applicazione di chat che ti consente di sfruttare appieno la rete Matrix. Ti fornisce un modo sicuro per inviare messaggi di testo, video e file audio a familiari, colleghi e amici.</p>
|
<p xml:lang="it">NeoChat è un'applicazione di chat che ti consente di sfruttare appieno la rete Matrix. Ti fornisce un modo sicuro per inviare messaggi di testo, video e file audio a familiari, colleghi e amici.</p>
|
||||||
<p xml:lang="ka">NeoChat ჩატის აპია, რომელიც საშუალება გაძლევთ, Matrix-ის ქსელის საშუალებები ბოლომდე გამოიყენოთ. ის გაძლევთ უსაფრთხო გზას, გააგზავნოთ ტექსტური შეტყობინებები, ვიდეოებ და აუდიოფაილები თქვენს ოჯახთან, კოლეგებთან და მეგობრებთან.</p>
|
<p xml:lang="ka">NeoChat ჩატის აპია, რომელიც საშუალება გაძლევთ, Matrix-ის ქსელის საშუალებები ბოლომდე გამოიყენოთ. ის გაძლევთ უსაფრთხო გზას, გააგზავნოთ ტექსტური შეტყობინებები, ვიდეოებ და აუდიოფაილები თქვენს ოჯახთან, კოლეგებთან და მეგობრებთან.</p>
|
||||||
<p xml:lang="ko">NeoChat은 Matrix 네트워크를 사용하는 채팅 앱입니다. 텍스트 메시지, 동영상, 오디오 파일을 가족, 친구, 동료와 안전하게 공유할 수 있습니다.</p>
|
|
||||||
<p xml:lang="lv">„NeoChat“ ir tērzēšanas programma, kas ļauj pilnvērtīgi izmantot „Matrix“ tīklu. Tā sniedz drošu veidu teksta ziņu, video un audio sūtīšanai ģimenes locekļiem, kolēģiem un draugiem.</p>
|
<p xml:lang="lv">„NeoChat“ ir tērzēšanas programma, kas ļauj pilnvērtīgi izmantot „Matrix“ tīklu. Tā sniedz drošu veidu teksta ziņu, video un audio sūtīšanai ģimenes locekļiem, kolēģiem un draugiem.</p>
|
||||||
<p xml:lang="nl">NeoChat is een chat-toepassing die u het volledige voordeel van het Matrix-netwerk laat genieten. Het levert u op een veilige manier tekstberichten, video's en geluidsbestanden naar uw familie, collega's en vrienden te verzenden.</p>
|
<p xml:lang="nl">NeoChat is een chat-toepassing die u het volledige voordeel van het Matrix-netwerk laat genieten. Het levert u op een veilige manier tekstberichten, video's en geluidsbestanden naar uw familie, collega's en vrienden te verzenden.</p>
|
||||||
<p xml:lang="nn">NeoChat er ein prateapp som lèt deg bruka all funksjonalitet i Matrix-nettverket. Du kan utveksla tekst, lyd og videoar med vennar, familie og kollegaar på ein trygg måte.</p>
|
<p xml:lang="nn">NeoChat er ein prateapp som lèt deg bruka all funksjonalitet i Matrix-nettverket. Du kan utveksla tekst, lyd og videoar med vennar, familie og kollegaar på ein trygg måte.</p>
|
||||||
<p xml:lang="pl">NoeChat to aplikacja do rozmów, która umożliwia wykorzystanie wszystkich możliwości Matriksa. Umożliwia wysyłanie wiadomości tekstowych, filmów i dźwięków w bezpieczny sposób do twojej rodziny, kolegów i przyjaciół.</p>
|
<p xml:lang="pl">NoeChat to aplikacja do rozmów, która umożliwia wykorzystanie wszystkich możliwości Matriksa. Umożliwia wysyłanie wiadomości tekstowych, filmów i dźwięków w bezpieczny sposób do twojej rodziny, kolegów i przyjaciół.</p>
|
||||||
<p xml:lang="ru">NeoChat — приложение для общения, предоставляющее все преимущества сети Matrix. С его помощью можно безопасно отправлять текстовые сообщения, видеозаписи и звуковые файлы родственникам, коллегам и друзьям.</p>
|
<p xml:lang="ru">NeoChat — приложение для общения, предоставляющее все преимущества сети Matrix. С его помощью можно безопасно отправлять текстовые сообщения, видеозаписи и звуковые файлы родственникам, коллегам и друзьям.</p>
|
||||||
<p xml:lang="sa">NeoChat इति एकं गपशप-अनुप्रयोगं यत् भवान् Matrix-जालस्य पूर्णं लाभं ग्रहीतुं शक्नोति । एतत् भवन्तं भवतः परिवाराय, सहकारिभ्यः, मित्रेभ्यः च पाठसन्देशान्, भिडियो, श्रव्यसञ्चिकाः च प्रेषयितुं सुरक्षितं मार्गं प्रदाति ।</p>
|
|
||||||
<p xml:lang="sl">NeoChat je aplikacija za klepet, ki vam omogoča, da v celoti izkoristite omrežje Matrix. Zagotavlja vam varen način za pošiljanje besedilnih sporočil, videoposnetkov in zvočnih datotek vaši družini, sodelavcem in prijateljem.</p>
|
<p xml:lang="sl">NeoChat je aplikacija za klepet, ki vam omogoča, da v celoti izkoristite omrežje Matrix. Zagotavlja vam varen način za pošiljanje besedilnih sporočil, videoposnetkov in zvočnih datotek vaši družini, sodelavcem in prijateljem.</p>
|
||||||
<p xml:lang="sv">NeoChat är ett chattprogram som låter dig dra full nytta av Matrix-nätverket. Det ger dig ett säkert sätt att skicka textmeddelanden, videor och ljudfiler till din familj, kollegor och vänner.</p>
|
<p xml:lang="sv">NeoChat är ett chattprogram som låter dig dra full nytta av Matrix-nätverket. Det ger dig ett säkert sätt att skicka textmeddelanden, videor och ljudfiler till din familj, kollegor och vänner.</p>
|
||||||
<p xml:lang="tr">NeoChat, Matrix ağının tüm özelliklerini kullanan bir sohbet uygulamasıdır. Ailenize, arkadaşlarınıza ve iş arkadaşlarınıza metin iletileri, ses ve video dosyaları göndermenin kolay bir yolunu sunar.</p>
|
<p xml:lang="tr">NeoChat, Matrix ağının tüm özelliklerini kullanan bir sohbet uygulamasıdır. Ailenize, arkadaşlarınıza ve iş arkadaşlarınıza metin iletileri, ses ve video dosyaları göndermenin kolay bir yolunu sunar.</p>
|
||||||
@@ -131,7 +121,6 @@
|
|||||||
<p xml:lang="fr">L'objectif de NeoChat est d'être une application complète pour le protocole Matrix. En tant que tel, tout dans la spécification stable actuelle avec les exceptions notables de VoIP, les processus et certains aspects du chiffrement de bout en bout sont pris en charge. Il y a quelques autres petites omissions en raison du fait que la spécification du protocole Matrix est en constante évolution. Cependant, l'objectif reste de fournir un soutien éventuel pour l'ensemble de la spécification.</p>
|
<p xml:lang="fr">L'objectif de NeoChat est d'être une application complète pour le protocole Matrix. En tant que tel, tout dans la spécification stable actuelle avec les exceptions notables de VoIP, les processus et certains aspects du chiffrement de bout en bout sont pris en charge. Il y a quelques autres petites omissions en raison du fait que la spécification du protocole Matrix est en constante évolution. Cependant, l'objectif reste de fournir un soutien éventuel pour l'ensemble de la spécification.</p>
|
||||||
<p xml:lang="gl">NeoChat pretende ser unha aplicación completa para a especificación de Matrix. Coas excepcións de VoIP, conversas fiadas e algúns aspectos da cifraxe de extremo a extremo, a versión estábel segue as especificacións. Existen algunhas outras pequenas omisións debido ao feito de que Matrix está en continua evolución pero a intención é fornecer compatibilidade coa especificación completa.</p>
|
<p xml:lang="gl">NeoChat pretende ser unha aplicación completa para a especificación de Matrix. Coas excepcións de VoIP, conversas fiadas e algúns aspectos da cifraxe de extremo a extremo, a versión estábel segue as especificacións. Existen algunhas outras pequenas omisións debido ao feito de que Matrix está en continua evolución pero a intención é fornecer compatibilidade coa especificación completa.</p>
|
||||||
<p xml:lang="he">NeoChat מתיימר להיות יישום עתיר יכולות לפי מפרט Matrix. כיוון שזה ייעודו, כל מה שבמפרט היציב עם חריגות משמעותיות כגון VoIP, שרשורים ועוד מגוון היבטים של הצפנה מקצה לקצה נתמכים גם הם. יש מספר השמטות קטן עקב העובדה שהמפרט של Matrix ממשיך להתפתח אך המטרה היא להמשיך לספק תמיכה בסופו של דבר לכל המפרט.</p>
|
<p xml:lang="he">NeoChat מתיימר להיות יישום עתיר יכולות לפי מפרט Matrix. כיוון שזה ייעודו, כל מה שבמפרט היציב עם חריגות משמעותיות כגון VoIP, שרשורים ועוד מגוון היבטים של הצפנה מקצה לקצה נתמכים גם הם. יש מספר השמטות קטן עקב העובדה שהמפרט של Matrix ממשיך להתפתח אך המטרה היא להמשיך לספק תמיכה בסופו של דבר לכל המפרט.</p>
|
||||||
<p xml:lang="hi">नियोचैट का लक्ष्य मैट्रिक्स विनिर्देश के लिए एक पूर्ण विशेषताओं वाला अनुप्रयोग बनना है। इस प्रकार वर्तमान स्थिर विनिर्देश में वीओआईपी, थ्रेड्स और एंड-टू-एंड एन्क्रिप्शन के कुछ पहलुओं के उल्लेखनीय अपवादों के साथ सब कुछ समर्थित है। मैट्रिक्स विनिर्देश लगातार विकसित हो रहा है, इस तथ्य के कारण कुछ अन्य छोटी चूकें हैं, लेकिन उद्देश्य पूरे विनिर्देश के लिए अंतिम समर्थन प्रदान करना है।</p>
|
|
||||||
<p xml:lang="hu">A NeoChat célja, hogy a Matrix specifikációnak megfelelő teljes funkcionalitású alkalmazás legyen. Mint ilyen, a jelenlegi stabil specifikáció támogatott a VoIP, a szálak és a végpontok közötti titkosítás egyes elemeinek kivételével. Van még néhány kisebb hiányosság annak köszönhetően, hogy a Matrix specifikáció folyamatosan fejlődik, de végső cél a teljes specifikáció megvalósítása.</p>
|
<p xml:lang="hu">A NeoChat célja, hogy a Matrix specifikációnak megfelelő teljes funkcionalitású alkalmazás legyen. Mint ilyen, a jelenlegi stabil specifikáció támogatott a VoIP, a szálak és a végpontok közötti titkosítás egyes elemeinek kivételével. Van még néhány kisebb hiányosság annak köszönhetően, hogy a Matrix specifikáció folyamatosan fejlődik, de végső cél a teljes specifikáció megvalósítása.</p>
|
||||||
<p xml:lang="ia">NeoChat aspira a esser un application plenmente 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 plenmente 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>
|
||||||
@@ -143,7 +132,6 @@
|
|||||||
<p xml:lang="pl">NeoChat w zamyśle ma być pełnowartościową aplikacją wg wytycznych Matriksa. Z tego powodu, wszystko, co jest obecnie w stabilnych wytycznych z pominięciem VoIP, wątków i niektórych części szyfrowania Użytkownik-do-Użytkownika są obecnie obsługiwane. Pominięto też kilka mniejszych rzeczy ze względu na ciągły rozwój wytycznych Matriksa, lecz celem nadal jest zapewnienie obsługi wszystkich wytycznych.</p>
|
<p xml:lang="pl">NeoChat w zamyśle ma być pełnowartościową aplikacją wg wytycznych Matriksa. Z tego powodu, wszystko, co jest obecnie w stabilnych wytycznych z pominięciem VoIP, wątków i niektórych części szyfrowania Użytkownik-do-Użytkownika są obecnie obsługiwane. Pominięto też kilka mniejszych rzeczy ze względu na ciągły rozwój wytycznych Matriksa, lecz celem nadal jest zapewnienie obsługi wszystkich wytycznych.</p>
|
||||||
<p xml:lang="pt">O NeoChat pretende ser uma aplicação completa para a especificação do Matrix. Como tal, tudo o que existe na especificação estável actual, com as notáveis excepções do VoIP, tópicos e alguns aspectos da Encriptação Ponto-a-Ponto, são suportados. Existem mais algumas omissões, devido ao facto que a norma do Matrix está em constante evolução, mas o objectivo continua a ser oferecer o suporte eventual para a norma por inteiro.</p>
|
<p xml:lang="pt">O NeoChat pretende ser uma aplicação completa para a especificação do Matrix. Como tal, tudo o que existe na especificação estável actual, com as notáveis excepções do VoIP, tópicos e alguns aspectos da Encriptação Ponto-a-Ponto, são suportados. Existem mais algumas omissões, devido ao facto que a norma do Matrix está em constante evolução, mas o objectivo continua a ser oferecer o suporte eventual para a norma por inteiro.</p>
|
||||||
<p xml:lang="ru">Целью создания NeoChat является полноценная реализация программы для спецификации Matrix. Как следствие, реализовано всё в текущей стабильной спецификации (за исключением голосовой интернет-связи, потоков и некоторых аспектов сквозного шифрования). Есть также несколько других незначительных пробелов, обусловленных постоянными изменениями спецификации Matrix. Тем не менее, стоит задача в итоге предоставить полную поддержку спецификации.</p>
|
<p xml:lang="ru">Целью создания NeoChat является полноценная реализация программы для спецификации Matrix. Как следствие, реализовано всё в текущей стабильной спецификации (за исключением голосовой интернет-связи, потоков и некоторых аспектов сквозного шифрования). Есть также несколько других незначительных пробелов, обусловленных постоянными изменениями спецификации Matrix. Тем не менее, стоит задача в итоге предоставить полную поддержку спецификации.</p>
|
||||||
<p xml:lang="sa">NeoChat इत्यस्य उद्देश्यं Matrix विनिर्देशस्य कृते पूर्णतया विशेषतायुक्तः अनुप्रयोगः भवितुम् अस्ति । यथा तथा वर्तमानस्थिरविनिर्देशे सर्वं VoIP इत्यस्य उल्लेखनीयअपवादैः सह, थ्रेड्स तथा च End-to-End Encryption इत्यस्य केचन पक्षाः समर्थिताः सन्ति । अन्ये कतिचन लघु लोपाः सन्ति यतोहि Matrix spec निरन्तरं विकसितः अस्ति परन्तु उद्देश्यं सम्पूर्ण spec कृते अन्ततः समर्थनं प्रदातुं अवशिष्टम् अस्ति</p>
|
|
||||||
<p xml:lang="sl">Neochat cilja, da bi bila popolna aplikacija po specifikaciji Matrixa. Kot takšna vsebuje vse v trenutni stabilni specifikaciji z pomembnimi izjemami pri VoIP, nitih in nekaterih vidikov šifriranja od konca do konca. Obstaja nekaj drugih manjših opustitev zaradi dejstva, da se specifikacija Matrix nenehno razvija, vendar cilj ostaja zagotoviti morebitno podporo celotni specifikaciji.</p>
|
<p xml:lang="sl">Neochat cilja, da bi bila popolna aplikacija po specifikaciji Matrixa. Kot takšna vsebuje vse v trenutni stabilni specifikaciji z pomembnimi izjemami pri VoIP, nitih in nekaterih vidikov šifriranja od konca do konca. Obstaja nekaj drugih manjših opustitev zaradi dejstva, da se specifikacija Matrix nenehno razvija, vendar cilj ostaja zagotoviti morebitno podporo celotni specifikaciji.</p>
|
||||||
<p xml:lang="sv">NeoChat har som mål att vara ett fullständigt program enligt Matrix-specifikationen. Som sådant stöds allt i den nuvarande stabila specifikationen, med de nämnvärda undantagen VoIP, trådar och några aspekter av kryptering hela vägen. Det finns några ytterligare utelämnanden på grund av att Matrix-specifikationen hela tiden utvecklas, men målet förblir att till slut erbjuda stöd för hela specifikationen.</p>
|
<p xml:lang="sv">NeoChat har som mål att vara ett fullständigt program enligt Matrix-specifikationen. Som sådant stöds allt i den nuvarande stabila specifikationen, med de nämnvärda undantagen VoIP, trådar och några aspekter av kryptering hela vägen. Det finns några ytterligare utelämnanden på grund av att Matrix-specifikationen hela tiden utvecklas, men målet förblir att till slut erbjuda stöd för hela specifikationen.</p>
|
||||||
<p xml:lang="tr">NeoChat, Matrix belirtimi için tam özellikli bir uygulama olmayı hedefler. Bu nedenle; VoIP, ileti zincirleri ve Uçtan Uca Şifreleme’nin bazı yönleri gibi dikkate değer istisnalar dışında var olan kararlı belirtimdeki her şey desteklenir. Matrix belirtiminin sürekli gelişmesi nedeniyle birkaç küçük eksiklik daha var; ancak amaç tüm belirtim için nihai destek sağlamak olmayı sürdürüyor.</p>
|
<p xml:lang="tr">NeoChat, Matrix belirtimi için tam özellikli bir uygulama olmayı hedefler. Bu nedenle; VoIP, ileti zincirleri ve Uçtan Uca Şifreleme’nin bazı yönleri gibi dikkate değer istisnalar dışında var olan kararlı belirtimdeki her şey desteklenir. Matrix belirtiminin sürekli gelişmesi nedeniyle birkaç küçük eksiklik daha var; ancak amaç tüm belirtim için nihai destek sağlamak olmayı sürdürüyor.</p>
|
||||||
@@ -164,7 +152,6 @@
|
|||||||
<p xml:lang="fr">En raison de la nature du développement des spécifications du protocole Matrix, NeoChat prend également en charge de nombreuses fonctionnalités instables. Actuellement, ce sont :</p>
|
<p xml:lang="fr">En raison de la nature du développement des spécifications du protocole Matrix, NeoChat prend également en charge de nombreuses fonctionnalités instables. Actuellement, ce sont :</p>
|
||||||
<p xml:lang="gl">Debido á natureza do desenvolvemento da especificación de Matrix, NeoChat tamén inclúe varias funcionalidades non estábeis:</p>
|
<p xml:lang="gl">Debido á natureza do desenvolvemento da especificación de Matrix, NeoChat tamén inclúe varias funcionalidades non estábeis:</p>
|
||||||
<p xml:lang="he">מטבע הדברים, הפיתוח של NeoChat תומך במגוון יכולות מפוקפקות כתלות בהתפתחות המפרט הטכני של Matrix. היכולות האלה הן:</p>
|
<p xml:lang="he">מטבע הדברים, הפיתוח של NeoChat תומך במגוון יכולות מפוקפקות כתלות בהתפתחות המפרט הטכני של Matrix. היכולות האלה הן:</p>
|
||||||
<p xml:lang="hi">मैट्रिक्स विनिर्देश विकास की प्रकृति के कारण नियोचैट कई अस्थिर सुविधाओं का भी समर्थन करता है। वर्तमान में ये हैं:</p>
|
|
||||||
<p xml:lang="hu">A Matrix specifikáció fejlesztésének jellegéből adódóan a NeoChat számos instabil funkciót is támogat. Jelenleg a következőket:</p>
|
<p xml:lang="hu">A Matrix specifikáció fejlesztésének jellegéből adódóan a NeoChat számos instabil funkciót is támogat. Jelenleg a következőket:</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>
|
||||||
@@ -176,7 +163,6 @@
|
|||||||
<p xml:lang="pl">Ze względu na sposób rozwoju Matriksa, NeoChat obsługuje także kilka niestabilnych możliwości. Obecnie są to:</p>
|
<p xml:lang="pl">Ze względu na sposób rozwoju Matriksa, NeoChat obsługuje także kilka niestabilnych możliwości. Obecnie są to:</p>
|
||||||
<p xml:lang="pt">Devido à natureza do desenvolvimento da especificação do Matrix, o NeoChat também suporta diversas funcionalidades instáveis. De momento são:</p>
|
<p xml:lang="pt">Devido à natureza do desenvolvimento da especificação do Matrix, o NeoChat também suporta diversas funcionalidades instáveis. De momento são:</p>
|
||||||
<p xml:lang="ru">В силу природы разработки спецификации Matrix в NeoChat тоже предусмотрена поддержка многочисленных нестабильных возможностей. В текущей версии это следующие возможности:</p>
|
<p xml:lang="ru">В силу природы разработки спецификации Matrix в NeoChat тоже предусмотрена поддержка многочисленных нестабильных возможностей. В текущей версии это следующие возможности:</p>
|
||||||
<p xml:lang="sa">Matrix विनिर्देशविकासस्य प्रकृतेः कारणात् NeoChat अपि अनेकानाम् अस्थिरविशेषतानां समर्थनं करोति । सम्प्रति एते सन्ति :</p>
|
|
||||||
<p xml:lang="sl">Zaradi narave razvoja specifikacije Matrixa NeoChat podpira tudi številne nestabilne zmožnosti. Trenutno so to:</p>
|
<p xml:lang="sl">Zaradi narave razvoja specifikacije Matrixa NeoChat podpira tudi številne nestabilne zmožnosti. Trenutno so to:</p>
|
||||||
<p xml:lang="sv">På grund av sättet Matrix-specifikationens utvecklas, stöder NeoChat också ett stor antal instabila funktioner. För närvarande är de:</p>
|
<p xml:lang="sv">På grund av sättet Matrix-specifikationens utvecklas, stöder NeoChat också ett stor antal instabila funktioner. För närvarande är de:</p>
|
||||||
<p xml:lang="ta">மேட்ரிக்ஸு நெறிமுறை வரையறுக்கப்படும் விதத்தின் காரணமாக, பல நிலையற்ற அம்சங்களையும் நியோச்சாட் ஆதரிக்கிறது. தற்போது ஆதரிக்கப்படுபவை:</p>
|
<p xml:lang="ta">மேட்ரிக்ஸு நெறிமுறை வரையறுக்கப்படும் விதத்தின் காரணமாக, பல நிலையற்ற அம்சங்களையும் நியோச்சாட் ஆதரிக்கிறது. தற்போது ஆதரிக்கப்படுபவை:</p>
|
||||||
@@ -198,7 +184,6 @@
|
|||||||
<li xml:lang="fr">Sondages - MSC3381</li>
|
<li xml:lang="fr">Sondages - MSC3381</li>
|
||||||
<li xml:lang="gl">Enquisas — MSC3381</li>
|
<li xml:lang="gl">Enquisas — MSC3381</li>
|
||||||
<li xml:lang="he">סקרים - MSC3381</li>
|
<li xml:lang="he">סקרים - MSC3381</li>
|
||||||
<li xml:lang="hi">पोल - MSC3381</li>
|
|
||||||
<li xml:lang="hu">Szavazások - MSC3381</li>
|
<li xml:lang="hu">Szavazások - MSC3381</li>
|
||||||
<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>
|
||||||
@@ -210,7 +195,6 @@
|
|||||||
<li xml:lang="pl">Ankiety - MSC3381</li>
|
<li xml:lang="pl">Ankiety - MSC3381</li>
|
||||||
<li xml:lang="pt">Inquéritos - MSC3381</li>
|
<li xml:lang="pt">Inquéritos - MSC3381</li>
|
||||||
<li xml:lang="ru">Голосования — MSC3381</li>
|
<li xml:lang="ru">Голосования — MSC3381</li>
|
||||||
<li xml:lang="sa">मतदान - MSC3381</li>
|
|
||||||
<li xml:lang="sl">Polls - MSC3381</li>
|
<li xml:lang="sl">Polls - MSC3381</li>
|
||||||
<li xml:lang="sv">Polls - MSC3381</li>
|
<li xml:lang="sv">Polls - MSC3381</li>
|
||||||
<li xml:lang="ta">வாக்கெடுப்புகள் - MSC3381</li>
|
<li xml:lang="ta">வாக்கெடுப்புகள் - MSC3381</li>
|
||||||
@@ -231,7 +215,6 @@
|
|||||||
<li xml:lang="fr">Paquets d'auto-collants - MSC2545</li>
|
<li xml:lang="fr">Paquets d'auto-collants - MSC2545</li>
|
||||||
<li xml:lang="gl">Paquetes de adhesivos — MSC2545</li>
|
<li xml:lang="gl">Paquetes de adhesivos — MSC2545</li>
|
||||||
<li xml:lang="he">חבילות מדבקות - MSC2545</li>
|
<li xml:lang="he">חבילות מדבקות - MSC2545</li>
|
||||||
<li xml:lang="hi">स्टिकर पैक - MSC2545</li>
|
|
||||||
<li xml:lang="hu">Matricacsomagok - MSC2545</li>
|
<li xml:lang="hu">Matricacsomagok - MSC2545</li>
|
||||||
<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>
|
||||||
@@ -243,7 +226,6 @@
|
|||||||
<li xml:lang="pl">Paczki naklejek - MSC2545</li>
|
<li xml:lang="pl">Paczki naklejek - MSC2545</li>
|
||||||
<li xml:lang="pt">Pacotes de Autocolantes - MSC2545</li>
|
<li xml:lang="pt">Pacotes de Autocolantes - MSC2545</li>
|
||||||
<li xml:lang="ru">Наборы стикеров — MSC2545</li>
|
<li xml:lang="ru">Наборы стикеров — MSC2545</li>
|
||||||
<li xml:lang="sa">स्टिकर पैक - MSC2545</li>
|
|
||||||
<li xml:lang="sl">Sticker Packs - MSC2545</li>
|
<li xml:lang="sl">Sticker Packs - MSC2545</li>
|
||||||
<li xml:lang="sv">Sticker Packs - MSC2545</li>
|
<li xml:lang="sv">Sticker Packs - MSC2545</li>
|
||||||
<li xml:lang="ta">ஒட்டி தொகுப்புகள் - MSC2545</li>
|
<li xml:lang="ta">ஒட்டி தொகுப்புகள் - MSC2545</li>
|
||||||
@@ -264,7 +246,6 @@
|
|||||||
<li xml:lang="fr">Événements de lieu - MSC3488</li>
|
<li xml:lang="fr">Événements de lieu - MSC3488</li>
|
||||||
<li xml:lang="gl">Localización de eventos — MSC3488</li>
|
<li xml:lang="gl">Localización de eventos — MSC3488</li>
|
||||||
<li xml:lang="he">אירועי מקום - MSC3488</li>
|
<li xml:lang="he">אירועי מקום - MSC3488</li>
|
||||||
<li xml:lang="hi">स्थान घटनाएँ - MSC3488</li>
|
|
||||||
<li xml:lang="hu">Események helyadatai - MSC3488</li>
|
<li xml:lang="hu">Események helyadatai - MSC3488</li>
|
||||||
<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>
|
||||||
@@ -276,7 +257,6 @@
|
|||||||
<li xml:lang="pl">Wydarzenia w miejscach - MSC3488</li>
|
<li xml:lang="pl">Wydarzenia w miejscach - MSC3488</li>
|
||||||
<li xml:lang="pt">Eventos com Localizações - MSC3488</li>
|
<li xml:lang="pt">Eventos com Localizações - MSC3488</li>
|
||||||
<li xml:lang="ru">События местоположения — MSC3488</li>
|
<li xml:lang="ru">События местоположения — MSC3488</li>
|
||||||
<li xml:lang="sa">स्थान घटनाएँ - MSC3488</li>
|
|
||||||
<li xml:lang="sl">Location Events - MSC3488</li>
|
<li xml:lang="sl">Location Events - MSC3488</li>
|
||||||
<li xml:lang="sv">Location Events - MSC3488</li>
|
<li xml:lang="sv">Location Events - MSC3488</li>
|
||||||
<li xml:lang="ta">இட நிகழ்வுகள் - MSC3488</li>
|
<li xml:lang="ta">இட நிகழ்வுகள் - MSC3488</li>
|
||||||
@@ -313,7 +293,6 @@
|
|||||||
<value key="KDE::windows_store::StoreLogoSquare">https://invent.kde.org/network/neochat/-/raw/master/icons/windows/storelogo-1080x1080.png</value>
|
<value key="KDE::windows_store::StoreLogoSquare">https://invent.kde.org/network/neochat/-/raw/master/icons/windows/storelogo-1080x1080.png</value>
|
||||||
<value key="KDE::windows_store::Icon">https://invent.kde.org/network/neochat/-/raw/master/icons/300-apps-neochat.png</value>
|
<value key="KDE::windows_store::Icon">https://invent.kde.org/network/neochat/-/raw/master/icons/300-apps-neochat.png</value>
|
||||||
<value key="KDE::windows_store::PromotionalArt16x9">https://invent.kde.org/network/neochat/-/raw/master/icons/windows/promoimage-1920x1080.png</value>
|
<value key="KDE::windows_store::PromotionalArt16x9">https://invent.kde.org/network/neochat/-/raw/master/icons/windows/promoimage-1920x1080.png</value>
|
||||||
<value key="KDE::supporters">Tanguy Fardet;[dabe](https://freeradical.zone/@dabe);[lengau](https://mastodon.world/@lengau);Joshua Strobl;Stuart Turton</value>
|
|
||||||
</custom>
|
</custom>
|
||||||
<launchable type="desktop-id">org.kde.neochat.desktop</launchable>
|
<launchable type="desktop-id">org.kde.neochat.desktop</launchable>
|
||||||
<screenshots>
|
<screenshots>
|
||||||
@@ -333,7 +312,6 @@
|
|||||||
<caption xml:lang="fr">Vue principale avec la liste des salons ainsi que des informations sur les salons et forums de discussions</caption>
|
<caption xml:lang="fr">Vue principale avec la liste des salons ainsi que des informations sur les salons et forums de discussions</caption>
|
||||||
<caption xml:lang="gl">Vista principal coa lista de salas, a charla, e información da sala.</caption>
|
<caption xml:lang="gl">Vista principal coa lista de salas, a charla, e información da sala.</caption>
|
||||||
<caption xml:lang="he">תצוגה ראשית עם רשימת חדרים, צ׳אט ופרטי חדר</caption>
|
<caption xml:lang="he">תצוגה ראשית עם רשימת חדרים, צ׳אט ופרטי חדר</caption>
|
||||||
<caption xml:lang="hi">कमरे की सूची, चैट और कमरे की जानकारी के साथ मुख्य दृश्य</caption>
|
|
||||||
<caption xml:lang="hu">A fő nézet a szobalistával, csevegéssel és szobainformációkkal</caption>
|
<caption xml:lang="hu">A fő nézet a szobalistával, csevegéssel és szobainformációkkal</caption>
|
||||||
<caption xml:lang="ia">Vista principal con lista de sala, chat e information de sala</caption>
|
<caption xml:lang="ia">Vista principal con lista de sala, chat e information de sala</caption>
|
||||||
<caption xml:lang="it">Vista principale con elenco delle stanze, chat e informazioni sulla stanza</caption>
|
<caption xml:lang="it">Vista principale con elenco delle stanze, chat e informazioni sulla stanza</caption>
|
||||||
@@ -345,7 +323,6 @@
|
|||||||
<caption xml:lang="pl">Główny widok z wykazem pokojów, rozmowami i szczegółami pokojów</caption>
|
<caption xml:lang="pl">Główny widok z wykazem pokojów, rozmowami i szczegółami pokojów</caption>
|
||||||
<caption xml:lang="pt">A área principal com a lista de salas e com informações sobre a conversa e a sala</caption>
|
<caption xml:lang="pt">A área principal com a lista de salas e com informações sobre a conversa e a sala</caption>
|
||||||
<caption xml:lang="ru">Главное окно со списком комнат, чатом и информацией о комнате</caption>
|
<caption xml:lang="ru">Главное окно со списком комнат, чатом и информацией о комнате</caption>
|
||||||
<caption xml:lang="sa">कक्षसूची, गपशपः, कक्षसूचना च सह मुख्यदृश्यम्</caption>
|
|
||||||
<caption xml:lang="sl">Glavni pogled s seznamom sob, klepetom in informacijami o sobah</caption>
|
<caption xml:lang="sl">Glavni pogled s seznamom sob, klepetom in informacijami o sobah</caption>
|
||||||
<caption xml:lang="sv">Huvudvy med rumslista, chatt, och rumsinformation</caption>
|
<caption xml:lang="sv">Huvudvy med rumslista, chatt, och rumsinformation</caption>
|
||||||
<caption xml:lang="ta">அரங்குப்பட்டியல், உரையாடல், மற்றும் அரங்குவிவரங்களைக் கொண்டுள்ள பிரதான காட்சி</caption>
|
<caption xml:lang="ta">அரங்குப்பட்டியல், உரையாடல், மற்றும் அரங்குவிவரங்களைக் கொண்டுள்ள பிரதான காட்சி</caption>
|
||||||
@@ -370,18 +347,15 @@
|
|||||||
<caption xml:lang="fr">Découvrez de nouvelles communautés avec les espaces sous Matrix</caption>
|
<caption xml:lang="fr">Découvrez de nouvelles communautés avec les espaces sous Matrix</caption>
|
||||||
<caption xml:lang="gl">Descubra novas comunidades dos espazos de Matrix.</caption>
|
<caption xml:lang="gl">Descubra novas comunidades dos espazos de Matrix.</caption>
|
||||||
<caption xml:lang="he">אפשר להיחשף לקהילות חדשות דרך Matrix Spaces</caption>
|
<caption xml:lang="he">אפשר להיחשף לקהילות חדשות דרך Matrix Spaces</caption>
|
||||||
<caption xml:lang="hi">मैट्रिक्स स्पेस के साथ नए समुदायों की खोज करें</caption>
|
|
||||||
<caption xml:lang="hu">Fedezzen fel új közösségeket a Matrix Terek segítségével</caption>
|
<caption xml:lang="hu">Fedezzen fel új közösségeket a Matrix Terek segítségével</caption>
|
||||||
<caption xml:lang="ia">Discoperi nove communitate con Matrix Spaces (Spatios de Matrix)</caption>
|
<caption xml:lang="ia">Discoperi nove communitate con Matrix Spaces (Spatios de Matrix)</caption>
|
||||||
<caption xml:lang="it">Scopri nuove comunità con Matrix Spaces</caption>
|
<caption xml:lang="it">Scopri nuove comunità con Matrix Spaces</caption>
|
||||||
<caption xml:lang="ka">აღმოაჩინეთ ახალი საზოგადოებები Matrix Spaces-თან ერთად</caption>
|
<caption xml:lang="ka">აღმოაჩინეთ ახალი საზოგადოებები Matrix Spaces-თან ერთად</caption>
|
||||||
<caption xml:lang="ko">Matrix 스페이스에서 새로운 커뮤니티 탐험</caption>
|
|
||||||
<caption xml:lang="lv">Atklājiet jaunas kopienas ar „Matrix“ telpām</caption>
|
<caption xml:lang="lv">Atklājiet jaunas kopienas ar „Matrix“ telpām</caption>
|
||||||
<caption xml:lang="nl">Ontdek nieuwe gemeenschappen met Matrix-ruimten</caption>
|
<caption xml:lang="nl">Ontdek nieuwe gemeenschappen met Matrix-ruimten</caption>
|
||||||
<caption xml:lang="nn">Oppdag nye fellesskap med Matrix Spaces</caption>
|
<caption xml:lang="nn">Oppdag nye fellesskap med Matrix Spaces</caption>
|
||||||
<caption xml:lang="pl">Odkrywaj nowe społeczności w Przestrzeniach Matriksa</caption>
|
<caption xml:lang="pl">Odkrywaj nowe społeczności w Przestrzeniach Matriksa</caption>
|
||||||
<caption xml:lang="ru">Поиск новых сообществ с помощью Matrix Spaces</caption>
|
<caption xml:lang="ru">Поиск новых сообществ с помощью Matrix Spaces</caption>
|
||||||
<caption xml:lang="sa">Matrix Spaces इत्यनेन सह नूतनानां समुदायानाम् अन्वेषणं कुर्वन्तु</caption>
|
|
||||||
<caption xml:lang="sl">Odkrijte nove skupnosti z Matrix Spaces</caption>
|
<caption xml:lang="sl">Odkrijte nove skupnosti z Matrix Spaces</caption>
|
||||||
<caption xml:lang="sv">Upptäck nya gemenskaper med Matrix Spaces</caption>
|
<caption xml:lang="sv">Upptäck nya gemenskaper med Matrix Spaces</caption>
|
||||||
<caption xml:lang="ta">மேட்ரிக்ஸு இடங்களின் மூலம் புதிய சமூகங்களைக் கண்டுபிடிக்கலாம்</caption>
|
<caption xml:lang="ta">மேட்ரிக்ஸு இடங்களின் மூலம் புதிய சமூகங்களைக் கண்டுபிடிக்கலாம்</caption>
|
||||||
@@ -413,7 +387,6 @@
|
|||||||
<caption xml:lang="fr">Vue principale avec la liste des salons ainsi que des informations sur les salons et forums de discussions</caption>
|
<caption xml:lang="fr">Vue principale avec la liste des salons ainsi que des informations sur les salons et forums de discussions</caption>
|
||||||
<caption xml:lang="gl">Vista principal coa lista de salas, a charla, e información da sala.</caption>
|
<caption xml:lang="gl">Vista principal coa lista de salas, a charla, e información da sala.</caption>
|
||||||
<caption xml:lang="he">תצוגה ראשית עם רשימת חדרים, צ׳אט ופרטי חדר</caption>
|
<caption xml:lang="he">תצוגה ראשית עם רשימת חדרים, צ׳אט ופרטי חדר</caption>
|
||||||
<caption xml:lang="hi">कमरे की सूची, चैट और कमरे की जानकारी के साथ मुख्य दृश्य</caption>
|
|
||||||
<caption xml:lang="hu">A fő nézet a szobalistával, csevegéssel és szobainformációkkal</caption>
|
<caption xml:lang="hu">A fő nézet a szobalistával, csevegéssel és szobainformációkkal</caption>
|
||||||
<caption xml:lang="ia">Vista principal con lista de sala, chat e information de sala</caption>
|
<caption xml:lang="ia">Vista principal con lista de sala, chat e information de sala</caption>
|
||||||
<caption xml:lang="it">Vista principale con elenco delle stanze, chat e informazioni sulla stanza</caption>
|
<caption xml:lang="it">Vista principale con elenco delle stanze, chat e informazioni sulla stanza</caption>
|
||||||
@@ -425,7 +398,6 @@
|
|||||||
<caption xml:lang="pl">Główny widok z wykazem pokojów, rozmowami i szczegółami pokojów</caption>
|
<caption xml:lang="pl">Główny widok z wykazem pokojów, rozmowami i szczegółami pokojów</caption>
|
||||||
<caption xml:lang="pt">A área principal com a lista de salas e com informações sobre a conversa e a sala</caption>
|
<caption xml:lang="pt">A área principal com a lista de salas e com informações sobre a conversa e a sala</caption>
|
||||||
<caption xml:lang="ru">Главное окно со списком комнат, чатом и информацией о комнате</caption>
|
<caption xml:lang="ru">Главное окно со списком комнат, чатом и информацией о комнате</caption>
|
||||||
<caption xml:lang="sa">कक्षसूची, गपशपः, कक्षसूचना च सह मुख्यदृश्यम्</caption>
|
|
||||||
<caption xml:lang="sl">Glavni pogled s seznamom sob, klepetom in informacijami o sobah</caption>
|
<caption xml:lang="sl">Glavni pogled s seznamom sob, klepetom in informacijami o sobah</caption>
|
||||||
<caption xml:lang="sv">Huvudvy med rumslista, chatt, och rumsinformation</caption>
|
<caption xml:lang="sv">Huvudvy med rumslista, chatt, och rumsinformation</caption>
|
||||||
<caption xml:lang="ta">அரங்குப்பட்டியல், உரையாடல், மற்றும் அரங்குவிவரங்களைக் கொண்டுள்ள பிரதான காட்சி</caption>
|
<caption xml:lang="ta">அரங்குப்பட்டியல், உரையாடல், மற்றும் அரங்குவிவரங்களைக் கொண்டுள்ள பிரதான காட்சி</caption>
|
||||||
@@ -451,7 +423,6 @@
|
|||||||
<caption xml:lang="fr">Écran de connexion</caption>
|
<caption xml:lang="fr">Écran de connexion</caption>
|
||||||
<caption xml:lang="gl">Pantalla de identificación.</caption>
|
<caption xml:lang="gl">Pantalla de identificación.</caption>
|
||||||
<caption xml:lang="he">מסך כניסה</caption>
|
<caption xml:lang="he">מסך כניסה</caption>
|
||||||
<caption xml:lang="hi">लॉगिन स्क्रीन</caption>
|
|
||||||
<caption xml:lang="hu">Bejelentkező képernyő</caption>
|
<caption xml:lang="hu">Bejelentkező képernyő</caption>
|
||||||
<caption xml:lang="ia">Schermo de accesso</caption>
|
<caption xml:lang="ia">Schermo de accesso</caption>
|
||||||
<caption xml:lang="it">Schermata di accesso</caption>
|
<caption xml:lang="it">Schermata di accesso</caption>
|
||||||
@@ -463,7 +434,6 @@
|
|||||||
<caption xml:lang="pl">Ekran logowania</caption>
|
<caption xml:lang="pl">Ekran logowania</caption>
|
||||||
<caption xml:lang="pt">Ecrã de autenticação</caption>
|
<caption xml:lang="pt">Ecrã de autenticação</caption>
|
||||||
<caption xml:lang="ru">Окно входа</caption>
|
<caption xml:lang="ru">Окно входа</caption>
|
||||||
<caption xml:lang="sa">लॉगिन् स्क्रीन</caption>
|
|
||||||
<caption xml:lang="sl">Prijavni zaslon</caption>
|
<caption xml:lang="sl">Prijavni zaslon</caption>
|
||||||
<caption xml:lang="sv">Inloggningsfönster</caption>
|
<caption xml:lang="sv">Inloggningsfönster</caption>
|
||||||
<caption xml:lang="ta">நுழைவுத் திரை</caption>
|
<caption xml:lang="ta">நுழைவுத் திரை</caption>
|
||||||
@@ -477,10 +447,6 @@
|
|||||||
<content_attribute id="social-chat">intense</content_attribute>
|
<content_attribute id="social-chat">intense</content_attribute>
|
||||||
</content_rating>
|
</content_rating>
|
||||||
<releases>
|
<releases>
|
||||||
<release version="25.04.3" date="2025-07-03"/>
|
|
||||||
<release version="25.04.2" date="2025-06-05"/>
|
|
||||||
<release version="25.04.1" date="2025-05-08"/>
|
|
||||||
<release version="25.04.0" date="2025-04-17"/>
|
|
||||||
<release version="24.12.3" date="2025-03-06"/>
|
<release version="24.12.3" date="2025-03-06"/>
|
||||||
<release version="24.12.2" date="2025-02-06"/>
|
<release version="24.12.2" date="2025-02-06"/>
|
||||||
<release version="24.12.1" date="2025-01-09"/>
|
<release version="24.12.1" date="2025-01-09"/>
|
||||||
@@ -659,9 +625,6 @@
|
|||||||
<url>https://carlschwan.eu/2020/12/23/announcing-neochat-1.0-the-kde-matrix-client/</url>
|
<url>https://carlschwan.eu/2020/12/23/announcing-neochat-1.0-the-kde-matrix-client/</url>
|
||||||
</release>
|
</release>
|
||||||
</releases>
|
</releases>
|
||||||
<requires>
|
|
||||||
<display_length compare="ge">360</display_length>
|
|
||||||
</requires>
|
|
||||||
<branding>
|
<branding>
|
||||||
<color type="primary" scheme_preference="light">#a6e4f3</color>
|
<color type="primary" scheme_preference="light">#a6e4f3</color>
|
||||||
<color type="primary" scheme_preference="dark">#235670</color>
|
<color type="primary" scheme_preference="dark">#235670</color>
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ Name[fi]=NeoChat
|
|||||||
Name[fr]=NeoChat
|
Name[fr]=NeoChat
|
||||||
Name[gl]=NeoChat
|
Name[gl]=NeoChat
|
||||||
Name[he]=NeoChat
|
Name[he]=NeoChat
|
||||||
Name[hi]=नियोचैट
|
|
||||||
Name[hu]=NeoChat
|
Name[hu]=NeoChat
|
||||||
Name[ia]=Neochat
|
Name[ia]=Neochat
|
||||||
Name[id]=NeoChat
|
Name[id]=NeoChat
|
||||||
@@ -37,7 +36,6 @@ Name[pt]=NeoChat
|
|||||||
Name[pt_BR]=NeoChat
|
Name[pt_BR]=NeoChat
|
||||||
Name[ro]=NeoChat
|
Name[ro]=NeoChat
|
||||||
Name[ru]=NeoChat
|
Name[ru]=NeoChat
|
||||||
Name[sa]=नवचैट्
|
|
||||||
Name[sk]=NeoChat
|
Name[sk]=NeoChat
|
||||||
Name[sl]=NeoChat
|
Name[sl]=NeoChat
|
||||||
Name[sv]=NeoChat
|
Name[sv]=NeoChat
|
||||||
@@ -63,7 +61,6 @@ GenericName[fi]=Matrix-asiakas
|
|||||||
GenericName[fr]=Client « Matrix »
|
GenericName[fr]=Client « Matrix »
|
||||||
GenericName[gl]=Cliente de Matrix
|
GenericName[gl]=Cliente de Matrix
|
||||||
GenericName[he]=לקוח Matrix
|
GenericName[he]=לקוח Matrix
|
||||||
GenericName[hi]=मैट्रिक्स क्लाइंट
|
|
||||||
GenericName[hu]=Matrix kliens
|
GenericName[hu]=Matrix kliens
|
||||||
GenericName[ia]=Cliente de Matrice
|
GenericName[ia]=Cliente de Matrice
|
||||||
GenericName[id]=Klien Matrix
|
GenericName[id]=Klien Matrix
|
||||||
@@ -81,7 +78,6 @@ GenericName[pt]=Cliente de Matrix
|
|||||||
GenericName[pt_BR]=Cliente Matrix
|
GenericName[pt_BR]=Cliente Matrix
|
||||||
GenericName[ro]=Client Matrix
|
GenericName[ro]=Client Matrix
|
||||||
GenericName[ru]=Клиент Matrix
|
GenericName[ru]=Клиент Matrix
|
||||||
GenericName[sa]=मैट्रिक्स क्लाइंट
|
|
||||||
GenericName[sk]=Matrix Client
|
GenericName[sk]=Matrix Client
|
||||||
GenericName[sl]=Odjemalec Matrix
|
GenericName[sl]=Odjemalec Matrix
|
||||||
GenericName[sv]=Matrix-klient
|
GenericName[sv]=Matrix-klient
|
||||||
@@ -104,24 +100,18 @@ Comment[fi]=Keskustele Matrixissä
|
|||||||
Comment[fr]=Clavarder sur Matrix
|
Comment[fr]=Clavarder sur Matrix
|
||||||
Comment[gl]=Charle en Matrix
|
Comment[gl]=Charle en Matrix
|
||||||
Comment[he]=התכתבות דרך Matrix
|
Comment[he]=התכתבות דרך Matrix
|
||||||
Comment[hi]=मैट्रिक्स पर चैट करें
|
|
||||||
Comment[hu]=Csevegés Matrixon
|
Comment[hu]=Csevegés Matrixon
|
||||||
Comment[ia]=Conversation en ditecto sur Matrix
|
Comment[ia]=Conversation en ditecto sur Matrix
|
||||||
Comment[it]= su Matrix
|
Comment[it]= su Matrix
|
||||||
Comment[ka]=ჩატი Matrix-ზე
|
Comment[ka]=საუბარი Matrix-ზე
|
||||||
Comment[ko]=Matrix에서 대화하기
|
|
||||||
Comment[lv]=Tērzējiet „Matrix“ tīklā
|
|
||||||
Comment[nl]=Chat op Matrix
|
Comment[nl]=Chat op Matrix
|
||||||
Comment[pl]=Rozmawiaj na Matriksie
|
Comment[pl]=Rozmawiaj na Matriksie
|
||||||
Comment[pt_BR]=Bate papo na Matrix
|
Comment[pt_BR]=Bate papo na Matrix
|
||||||
Comment[ru]=Общение в Matrix
|
|
||||||
Comment[sa]=Matrix इत्यत्र गपशपं कुर्वन्तु
|
|
||||||
Comment[sl]=Klepet na Matrixu
|
Comment[sl]=Klepet na Matrixu
|
||||||
Comment[sv]=Chatta på Matrix
|
Comment[sv]=Chatta på Matrix
|
||||||
Comment[ta]=மேட்ரிக்ஸில் உரையாட உதவும்
|
Comment[ta]=மேட்ரிக்ஸில் உரையாட உதவும்
|
||||||
Comment[tr]=Matrix üzerinde sohbet edin
|
Comment[tr]=Matrix üzerinde sohbet edin
|
||||||
Comment[uk]=Спілкування у Matrix
|
Comment[uk]=Спілкування у Matrix
|
||||||
Comment[x-test]=xxChat on Matrixxx
|
|
||||||
Comment[zh_CN]=在 Matrix 上聊天
|
Comment[zh_CN]=在 Matrix 上聊天
|
||||||
Comment[zh_TW]=在 Matrix 上聊天
|
Comment[zh_TW]=在 Matrix 上聊天
|
||||||
MimeType=x-scheme-handler/matrix;
|
MimeType=x-scheme-handler/matrix;
|
||||||
|
|||||||
7775
po/ar/neochat.po
7775
po/ar/neochat.po
File diff suppressed because it is too large
Load Diff
7327
po/ast/neochat.po
7327
po/ast/neochat.po
File diff suppressed because it is too large
Load Diff
8570
po/az/neochat.po
8570
po/az/neochat.po
File diff suppressed because it is too large
Load Diff
7710
po/ca/neochat.po
7710
po/ca/neochat.po
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
7761
po/cs/neochat.po
7761
po/cs/neochat.po
File diff suppressed because it is too large
Load Diff
8170
po/da/neochat.po
8170
po/da/neochat.po
File diff suppressed because it is too large
Load Diff
8191
po/de/neochat.po
8191
po/de/neochat.po
File diff suppressed because it is too large
Load Diff
8417
po/el/neochat.po
8417
po/el/neochat.po
File diff suppressed because it is too large
Load Diff
8254
po/en_GB/neochat.po
8254
po/en_GB/neochat.po
File diff suppressed because it is too large
Load Diff
7910
po/eo/neochat.po
7910
po/eo/neochat.po
File diff suppressed because it is too large
Load Diff
8447
po/es/neochat.po
8447
po/es/neochat.po
File diff suppressed because it is too large
Load Diff
7877
po/eu/neochat.po
7877
po/eu/neochat.po
File diff suppressed because it is too large
Load Diff
7836
po/fi/neochat.po
7836
po/fi/neochat.po
File diff suppressed because it is too large
Load Diff
7969
po/fr/neochat.po
7969
po/fr/neochat.po
File diff suppressed because it is too large
Load Diff
7916
po/gl/neochat.po
7916
po/gl/neochat.po
File diff suppressed because it is too large
Load Diff
6690
po/he/neochat.po
6690
po/he/neochat.po
File diff suppressed because it is too large
Load Diff
6896
po/hi/neochat.po
6896
po/hi/neochat.po
File diff suppressed because it is too large
Load Diff
7997
po/hu/neochat.po
7997
po/hu/neochat.po
File diff suppressed because it is too large
Load Diff
7902
po/ia/neochat.po
7902
po/ia/neochat.po
File diff suppressed because it is too large
Load Diff
8708
po/id/neochat.po
8708
po/id/neochat.po
File diff suppressed because it is too large
Load Diff
8266
po/ie/neochat.po
8266
po/ie/neochat.po
File diff suppressed because it is too large
Load Diff
7893
po/it/neochat.po
7893
po/it/neochat.po
File diff suppressed because it is too large
Load Diff
7316
po/ja/neochat.po
7316
po/ja/neochat.po
File diff suppressed because it is too large
Load Diff
7800
po/ka/neochat.po
7800
po/ka/neochat.po
File diff suppressed because it is too large
Load Diff
8640
po/ko/neochat.po
8640
po/ko/neochat.po
File diff suppressed because it is too large
Load Diff
7339
po/lt/neochat.po
7339
po/lt/neochat.po
File diff suppressed because it is too large
Load Diff
7834
po/lv/neochat.po
7834
po/lv/neochat.po
File diff suppressed because it is too large
Load Diff
7878
po/nl/neochat.po
7878
po/nl/neochat.po
File diff suppressed because it is too large
Load Diff
7927
po/nn/neochat.po
7927
po/nn/neochat.po
File diff suppressed because it is too large
Load Diff
8541
po/pa/neochat.po
8541
po/pa/neochat.po
File diff suppressed because it is too large
Load Diff
8019
po/pl/neochat.po
8019
po/pl/neochat.po
File diff suppressed because it is too large
Load Diff
8725
po/pt/neochat.po
8725
po/pt/neochat.po
File diff suppressed because it is too large
Load Diff
8561
po/pt_BR/neochat.po
8561
po/pt_BR/neochat.po
File diff suppressed because it is too large
Load Diff
8411
po/ru/neochat.po
8411
po/ru/neochat.po
File diff suppressed because it is too large
Load Diff
6869
po/sa/neochat.po
6869
po/sa/neochat.po
File diff suppressed because it is too large
Load Diff
8905
po/sk/neochat.po
8905
po/sk/neochat.po
File diff suppressed because it is too large
Load Diff
7803
po/sl/neochat.po
7803
po/sl/neochat.po
File diff suppressed because it is too large
Load Diff
7848
po/sv/neochat.po
7848
po/sv/neochat.po
File diff suppressed because it is too large
Load Diff
7936
po/ta/neochat.po
7936
po/ta/neochat.po
File diff suppressed because it is too large
Load Diff
8084
po/tok/neochat.po
8084
po/tok/neochat.po
File diff suppressed because it is too large
Load Diff
7753
po/tr/neochat.po
7753
po/tr/neochat.po
File diff suppressed because it is too large
Load Diff
7872
po/uk/neochat.po
7872
po/uk/neochat.po
File diff suppressed because it is too large
Load Diff
7577
po/zh_CN/neochat.po
7577
po/zh_CN/neochat.po
File diff suppressed because it is too large
Load Diff
7707
po/zh_TW/neochat.po
7707
po/zh_TW/neochat.po
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,4 @@
|
|||||||
# SPDX-FileCopyrightText: 2024-2025 Scarlett Moore <sgmoore@kde.org>
|
# SPDX-FileCopyrightText: 2024 Scarlett Moore <sgmoore@kde.org>
|
||||||
#
|
#
|
||||||
# SPDX-License-Identifier: CC0-1.0
|
# SPDX-License-Identifier: CC0-1.0
|
||||||
---
|
---
|
||||||
@@ -24,15 +24,12 @@ apps:
|
|||||||
- network-manager-observe
|
- network-manager-observe
|
||||||
- password-manager-service
|
- password-manager-service
|
||||||
- accounts-service
|
- accounts-service
|
||||||
environment:
|
|
||||||
QT_PLUGIN_PATH: "$SNAP/usr/lib/$CRAFT_ARCH_TRIPLET/plugins/snap/kf6-core24/current/usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/plugins"
|
|
||||||
QML_IMPORT_PATH: "$SNAP/usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/qml:/snap/kf6-core24/current/usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/qml"
|
|
||||||
|
|
||||||
compression: lzo
|
compression: lzo
|
||||||
|
|
||||||
package-repositories:
|
package-repositories:
|
||||||
- type: apt
|
- type: apt
|
||||||
ppa: ubuntu-toolchain-r/test
|
ppa: ubuntu-toolchain-r/test
|
||||||
|
|
||||||
slots:
|
slots:
|
||||||
session-dbus-interface:
|
session-dbus-interface:
|
||||||
@@ -44,12 +41,11 @@ parts:
|
|||||||
olm:
|
olm:
|
||||||
source: https://gitlab.matrix.org/matrix-org/olm.git
|
source: https://gitlab.matrix.org/matrix-org/olm.git
|
||||||
source-depth: 1
|
source-depth: 1
|
||||||
source-tag: '3.2.16'
|
source-tag: '3.2.12'
|
||||||
plugin: cmake
|
plugin: cmake
|
||||||
cmake-parameters:
|
cmake-parameters:
|
||||||
- -DCMAKE_BUILD_TYPE=Release
|
- -DCMAKE_BUILD_TYPE=Release
|
||||||
- -DCMAKE_INSTALL_PREFIX=/usr
|
- -DCMAKE_INSTALL_PREFIX=/usr
|
||||||
- -DCMAKE_POLICY_VERSION_MINIMUM=3.5
|
|
||||||
prime:
|
prime:
|
||||||
- -usr/include
|
- -usr/include
|
||||||
- -usr/lib/*/pkgconfig
|
- -usr/lib/*/pkgconfig
|
||||||
@@ -85,7 +81,7 @@ parts:
|
|||||||
plugin: cmake
|
plugin: cmake
|
||||||
build-environment:
|
build-environment:
|
||||||
- PATH: /snap/bin:${PATH}
|
- PATH: /snap/bin:${PATH}
|
||||||
- PKG_CONFIG_PATH: "$CRAFT_STAGE/usr/lib/$CRAFT_ARCH_TRIPLET/pkgconfig:$PKG_CONFIG_PATH"
|
- PKG_CONFIG_PATH: $CRAFT_STAGE/usr/lib/$CRAFT_ARCH_TRIPLET/pkgconfig:$PKG_CONFIG_PATH
|
||||||
cmake-parameters:
|
cmake-parameters:
|
||||||
- -DCMAKE_INSTALL_PREFIX=/usr
|
- -DCMAKE_INSTALL_PREFIX=/usr
|
||||||
- -DCMAKE_BUILD_TYPE=Release
|
- -DCMAKE_BUILD_TYPE=Release
|
||||||
@@ -101,7 +97,7 @@ parts:
|
|||||||
- olm
|
- olm
|
||||||
- qtkeychain
|
- qtkeychain
|
||||||
source: https://github.com/quotient-im/libQuotient.git
|
source: https://github.com/quotient-im/libQuotient.git
|
||||||
source-tag: 0.9.2
|
source-tag: 0.9.1
|
||||||
source-depth: 1
|
source-depth: 1
|
||||||
plugin: cmake
|
plugin: cmake
|
||||||
build-environment:
|
build-environment:
|
||||||
@@ -140,24 +136,11 @@ parts:
|
|||||||
- -usr/lib/*/pkgconfig
|
- -usr/lib/*/pkgconfig
|
||||||
- -usr/lib/*/cmake
|
- -usr/lib/*/cmake
|
||||||
|
|
||||||
kunifiedpush:
|
|
||||||
source: https://invent.kde.org/libraries/kunifiedpush.git
|
|
||||||
plugin: cmake
|
|
||||||
build-environment:
|
|
||||||
- PATH: /snap/bin:${PATH}
|
|
||||||
- PYTHONPATH: ${CRAFT_STAGE}/lib/python3.12/site-packages:${CRAFT_STAGE}/usr/lib/python3/dist-packages
|
|
||||||
- LD_LIBRARY_PATH: "/snap/mesa-2404/current/usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR:$CRAFT_STAGE/usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR:/snap/kde-qt6-core24-sdk/current/usr/lib/$CRAFT_ARCH_TRIPLET_BUILD_FOR/libproxy:$LD_LIBRARY_PATH"
|
|
||||||
cmake-parameters:
|
|
||||||
- -DCMAKE_INSTALL_PREFIX=/usr
|
|
||||||
- -DCMAKE_BUILD_TYPE=Release
|
|
||||||
- -DBUILD_TESTING=OFF
|
|
||||||
|
|
||||||
neochat:
|
neochat:
|
||||||
after:
|
after:
|
||||||
- qtkeychain
|
- qtkeychain
|
||||||
- libquotient
|
- libquotient
|
||||||
- kquickimageeditor
|
- kquickimageeditor
|
||||||
- kunifiedpush
|
|
||||||
parse-info:
|
parse-info:
|
||||||
- usr/share/metainfo/org.kde.neochat.appdata.xml
|
- usr/share/metainfo/org.kde.neochat.appdata.xml
|
||||||
source: .
|
source: .
|
||||||
|
|||||||
@@ -1,18 +1,574 @@
|
|||||||
# SPDX-FileCopyrightText: 2025 James Graham <james.h.graham@protonmail.com>
|
# SPDX-FileCopyrightText: 2020-2021 Carl Schwan <carl@carlschwan.eu>
|
||||||
|
# SPDX-FileCopyrightText: 2020-2021 Nicolas Fella <nicolas.fella@gmx.de>
|
||||||
|
# SPDX-FileCopyrightText: 2020-2021 Tobias Fella <tobias.fella@kde.org>
|
||||||
# SPDX-License-Identifier: BSD-2-Clause
|
# SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
if (NOT ANDROID AND NOT WIN32 AND NOT APPLE AND NOT NEOCHAT_FLATPAK AND NOT NEOCHAT_APPIMAGE)
|
if (NOT ANDROID AND NOT WIN32 AND NOT APPLE AND NOT NEOCHAT_FLATPAK AND NOT NEOCHAT_APPIMAGE)
|
||||||
add_subdirectory(purpose)
|
add_subdirectory(purpose)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_subdirectory(libneochat)
|
add_library(neochat STATIC
|
||||||
add_subdirectory(login)
|
controller.cpp
|
||||||
add_subdirectory(rooms)
|
controller.h
|
||||||
add_subdirectory(roominfo)
|
models/emojimodel.cpp
|
||||||
add_subdirectory(messagecontent)
|
models/emojimodel.h
|
||||||
add_subdirectory(timeline)
|
emojitones.cpp
|
||||||
add_subdirectory(spaces)
|
emojitones.h
|
||||||
add_subdirectory(chatbar)
|
models/customemojimodel.cpp
|
||||||
|
models/customemojimodel.h
|
||||||
|
clipboard.cpp
|
||||||
|
clipboard.h
|
||||||
|
models/messageeventmodel.cpp
|
||||||
|
models/messageeventmodel.h
|
||||||
|
models/messagefiltermodel.cpp
|
||||||
|
models/messagefiltermodel.h
|
||||||
|
models/roomlistmodel.cpp
|
||||||
|
models/roomlistmodel.h
|
||||||
|
models/sortfilterspacelistmodel.cpp
|
||||||
|
models/sortfilterspacelistmodel.h
|
||||||
|
models/accountemoticonmodel.cpp
|
||||||
|
models/accountemoticonmodel.h
|
||||||
|
spacehierarchycache.cpp
|
||||||
|
spacehierarchycache.h
|
||||||
|
roommanager.cpp
|
||||||
|
roommanager.h
|
||||||
|
neochatroom.cpp
|
||||||
|
neochatroom.h
|
||||||
|
models/userlistmodel.cpp
|
||||||
|
models/userlistmodel.h
|
||||||
|
models/userfiltermodel.cpp
|
||||||
|
models/userfiltermodel.h
|
||||||
|
models/publicroomlistmodel.cpp
|
||||||
|
models/publicroomlistmodel.h
|
||||||
|
models/spacechildrenmodel.cpp
|
||||||
|
models/spacechildrenmodel.h
|
||||||
|
models/spacechildsortfiltermodel.cpp
|
||||||
|
models/spacechildsortfiltermodel.h
|
||||||
|
models/spacetreeitem.cpp
|
||||||
|
models/spacetreeitem.h
|
||||||
|
models/userdirectorylistmodel.cpp
|
||||||
|
models/userdirectorylistmodel.h
|
||||||
|
models/pushrulemodel.cpp
|
||||||
|
models/pushrulemodel.h
|
||||||
|
models/emoticonfiltermodel.cpp
|
||||||
|
models/emoticonfiltermodel.h
|
||||||
|
notificationsmanager.cpp
|
||||||
|
notificationsmanager.h
|
||||||
|
models/sortfilterroomlistmodel.cpp
|
||||||
|
models/sortfilterroomlistmodel.h
|
||||||
|
models/roomtreemodel.cpp
|
||||||
|
models/roomtreemodel.h
|
||||||
|
chatdocumenthandler.cpp
|
||||||
|
chatdocumenthandler.h
|
||||||
|
models/devicesmodel.cpp
|
||||||
|
models/devicesmodel.h
|
||||||
|
models/devicesproxymodel.cpp
|
||||||
|
filetype.cpp
|
||||||
|
filetype.h
|
||||||
|
login.cpp
|
||||||
|
login.h
|
||||||
|
models/webshortcutmodel.cpp
|
||||||
|
models/webshortcutmodel.h
|
||||||
|
blurhash.cpp
|
||||||
|
blurhash.h
|
||||||
|
blurhashimageprovider.cpp
|
||||||
|
blurhashimageprovider.h
|
||||||
|
models/mediamessagefiltermodel.cpp
|
||||||
|
models/mediamessagefiltermodel.h
|
||||||
|
urlhelper.cpp
|
||||||
|
urlhelper.h
|
||||||
|
windowcontroller.cpp
|
||||||
|
windowcontroller.h
|
||||||
|
linkpreviewer.cpp
|
||||||
|
linkpreviewer.h
|
||||||
|
models/completionmodel.cpp
|
||||||
|
models/completionmodel.h
|
||||||
|
models/completionproxymodel.cpp
|
||||||
|
models/completionproxymodel.h
|
||||||
|
models/actionsmodel.cpp
|
||||||
|
models/actionsmodel.h
|
||||||
|
models/serverlistmodel.cpp
|
||||||
|
models/serverlistmodel.h
|
||||||
|
models/statemodel.cpp
|
||||||
|
models/statemodel.h
|
||||||
|
models/statefiltermodel.cpp
|
||||||
|
models/statefiltermodel.h
|
||||||
|
filetransferpseudojob.cpp
|
||||||
|
filetransferpseudojob.h
|
||||||
|
models/searchmodel.cpp
|
||||||
|
models/searchmodel.h
|
||||||
|
texthandler.cpp
|
||||||
|
texthandler.h
|
||||||
|
logger.cpp
|
||||||
|
logger.h
|
||||||
|
models/stickermodel.cpp
|
||||||
|
models/stickermodel.h
|
||||||
|
models/imagepacksmodel.cpp
|
||||||
|
models/imagepacksmodel.h
|
||||||
|
events/imagepackevent.cpp
|
||||||
|
events/imagepackevent.h
|
||||||
|
events/joinrulesevent.cpp
|
||||||
|
events/joinrulesevent.h
|
||||||
|
models/reactionmodel.cpp
|
||||||
|
models/reactionmodel.h
|
||||||
|
delegatesizehelper.cpp
|
||||||
|
delegatesizehelper.h
|
||||||
|
models/livelocationsmodel.cpp
|
||||||
|
models/livelocationsmodel.h
|
||||||
|
models/locationsmodel.cpp
|
||||||
|
models/locationsmodel.h
|
||||||
|
locationhelper.cpp
|
||||||
|
locationhelper.h
|
||||||
|
events/pollevent.cpp
|
||||||
|
pollhandler.cpp
|
||||||
|
utils.h
|
||||||
|
utils.cpp
|
||||||
|
registration.cpp
|
||||||
|
neochatconnection.cpp
|
||||||
|
neochatconnection.h
|
||||||
|
jobs/neochatdeactivateaccountjob.cpp
|
||||||
|
jobs/neochatdeactivateaccountjob.h
|
||||||
|
jobs/neochatdeletedevicejob.cpp
|
||||||
|
jobs/neochatdeletedevicejob.h
|
||||||
|
jobs/neochatchangepasswordjob.cpp
|
||||||
|
jobs/neochatchangepasswordjob.h
|
||||||
|
jobs/neochatgetcommonroomsjob.cpp
|
||||||
|
jobs/neochatgetcommonroomsjob.h
|
||||||
|
mediasizehelper.cpp
|
||||||
|
mediasizehelper.h
|
||||||
|
eventhandler.cpp
|
||||||
|
enums/delegatetype.h
|
||||||
|
roomlastmessageprovider.cpp
|
||||||
|
roomlastmessageprovider.h
|
||||||
|
chatbarcache.cpp
|
||||||
|
chatbarcache.h
|
||||||
|
colorschemer.cpp
|
||||||
|
colorschemer.h
|
||||||
|
models/notificationsmodel.cpp
|
||||||
|
models/notificationsmodel.h
|
||||||
|
models/timelinemodel.cpp
|
||||||
|
models/timelinemodel.h
|
||||||
|
enums/pushrule.h
|
||||||
|
models/itinerarymodel.cpp
|
||||||
|
models/itinerarymodel.h
|
||||||
|
proxycontroller.cpp
|
||||||
|
proxycontroller.h
|
||||||
|
models/linemodel.cpp
|
||||||
|
models/linemodel.h
|
||||||
|
events/locationbeaconevent.h
|
||||||
|
events/widgetevent.h
|
||||||
|
enums/messagecomponenttype.h
|
||||||
|
models/messagecontentmodel.cpp
|
||||||
|
models/messagecontentmodel.h
|
||||||
|
enums/neochatroomtype.h
|
||||||
|
models/sortfilterroomtreemodel.cpp
|
||||||
|
models/sortfilterroomtreemodel.h
|
||||||
|
mediamanager.cpp
|
||||||
|
mediamanager.h
|
||||||
|
models/statekeysmodel.cpp
|
||||||
|
models/statekeysmodel.h
|
||||||
|
sharehandler.cpp
|
||||||
|
sharehandler.h
|
||||||
|
models/roomtreeitem.cpp
|
||||||
|
models/roomtreeitem.h
|
||||||
|
foreigntypes.h
|
||||||
|
models/threepidmodel.cpp
|
||||||
|
models/threepidmodel.h
|
||||||
|
threepidaddhelper.cpp
|
||||||
|
threepidaddhelper.h
|
||||||
|
jobs/neochatadd3pidjob.cpp
|
||||||
|
jobs/neochatadd3pidjob.h
|
||||||
|
identityserverhelper.cpp
|
||||||
|
identityserverhelper.h
|
||||||
|
enums/powerlevel.cpp
|
||||||
|
enums/powerlevel.h
|
||||||
|
models/permissionsmodel.cpp
|
||||||
|
models/permissionsmodel.h
|
||||||
|
threepidbindhelper.cpp
|
||||||
|
threepidbindhelper.h
|
||||||
|
models/readmarkermodel.cpp
|
||||||
|
models/readmarkermodel.h
|
||||||
|
neochatroommember.cpp
|
||||||
|
neochatroommember.h
|
||||||
|
models/threadmodel.cpp
|
||||||
|
models/threadmodel.h
|
||||||
|
enums/messagetype.h
|
||||||
|
messagecomponent.h
|
||||||
|
)
|
||||||
|
|
||||||
|
set_source_files_properties(qml/OsmLocationPlugin.qml PROPERTIES
|
||||||
|
QT_QML_SINGLETON_TYPE TRUE
|
||||||
|
)
|
||||||
|
|
||||||
|
if(ANDROID OR WIN32)
|
||||||
|
set_source_files_properties(qml/ShareActionStub.qml PROPERTIES
|
||||||
|
QT_QML_SOURCE_TYPENAME ShareAction
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
ecm_add_qml_module(neochat URI org.kde.neochat GENERATE_PLUGIN_SOURCE
|
||||||
|
OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/src/org/kde/neochat
|
||||||
|
QML_FILES
|
||||||
|
qml/Main.qml
|
||||||
|
qml/AccountMenu.qml
|
||||||
|
qml/ExploreComponent.qml
|
||||||
|
qml/ExploreComponentMobile.qml
|
||||||
|
qml/ContextMenu.qml
|
||||||
|
qml/CollapsedRoomDelegate.qml
|
||||||
|
qml/RoomDelegate.qml
|
||||||
|
qml/RoomListPage.qml
|
||||||
|
qml/SpaceListContextMenu.qml
|
||||||
|
qml/UserInfo.qml
|
||||||
|
qml/UserInfoDesktop.qml
|
||||||
|
qml/RoomPage.qml
|
||||||
|
qml/ExploreRoomsPage.qml
|
||||||
|
qml/ManualRoomDialog.qml
|
||||||
|
qml/ExplorerDelegate.qml
|
||||||
|
qml/InviteUserPage.qml
|
||||||
|
qml/ImageEditorPage.qml
|
||||||
|
qml/NeochatMaximizeComponent.qml
|
||||||
|
qml/TypingPane.qml
|
||||||
|
qml/QuickSwitcher.qml
|
||||||
|
qml/HoverActions.qml
|
||||||
|
qml/AttachmentPane.qml
|
||||||
|
qml/QuickFormatBar.qml
|
||||||
|
qml/UserDetailDialog.qml
|
||||||
|
qml/CreateRoomDialog.qml
|
||||||
|
qml/OpenFileDialog.qml
|
||||||
|
qml/KeyVerificationDialog.qml
|
||||||
|
qml/ConfirmLogoutDialog.qml
|
||||||
|
qml/PowerLevelDialog.qml
|
||||||
|
qml/Message.qml
|
||||||
|
qml/EmojiItem.qml
|
||||||
|
qml/EmojiRow.qml
|
||||||
|
qml/EmojiSas.qml
|
||||||
|
qml/ConfirmDeactivateAccountDialog.qml
|
||||||
|
qml/VerificationCanceled.qml
|
||||||
|
qml/MessageDelegateContextMenu.qml
|
||||||
|
qml/FileDelegateContextMenu.qml
|
||||||
|
qml/MessageSourceSheet.qml
|
||||||
|
qml/ConfirmEncryptionDialog.qml
|
||||||
|
qml/RoomSearchPage.qml
|
||||||
|
qml/LocationChooser.qml
|
||||||
|
qml/TimelineView.qml
|
||||||
|
qml/InvitationView.qml
|
||||||
|
qml/AvatarTabButton.qml
|
||||||
|
qml/SpaceDrawer.qml
|
||||||
|
qml/OsmLocationPlugin.qml
|
||||||
|
qml/FullScreenMap.qml
|
||||||
|
qml/LocationsPage.qml
|
||||||
|
qml/LocationMapItem.qml
|
||||||
|
qml/RoomDrawer.qml
|
||||||
|
qml/RoomDrawerPage.qml
|
||||||
|
qml/DirectChatDrawerHeader.qml
|
||||||
|
qml/GroupChatDrawerHeader.qml
|
||||||
|
qml/RoomInformation.qml
|
||||||
|
qml/RoomMedia.qml
|
||||||
|
qml/ChooseRoomDialog.qml
|
||||||
|
qml/SpaceHomePage.qml
|
||||||
|
qml/SpaceHierarchyDelegate.qml
|
||||||
|
qml/RemoveChildDialog.qml
|
||||||
|
qml/SelectParentDialog.qml
|
||||||
|
qml/QrCodeMaximizeComponent.qml
|
||||||
|
qml/SelectSpacesDialog.qml
|
||||||
|
qml/NotificationsView.qml
|
||||||
|
qml/SearchPage.qml
|
||||||
|
qml/ServerComboBox.qml
|
||||||
|
qml/UserSearchPage.qml
|
||||||
|
qml/ManualUserDialog.qml
|
||||||
|
qml/RecommendedSpaceDialog.qml
|
||||||
|
qml/RoomTreeSection.qml
|
||||||
|
qml/DelegateContextMenu.qml
|
||||||
|
qml/ShareDialog.qml
|
||||||
|
qml/UnlockSSSSDialog.qml
|
||||||
|
qml/QrScannerPage.qml
|
||||||
|
qml/JoinRoomDialog.qml
|
||||||
|
qml/ConfirmUrlDialog.qml
|
||||||
|
qml/AccountSwitchDialog.qml
|
||||||
|
qml/ConfirmLeaveDialog.qml
|
||||||
|
qml/CodeMaximizeComponent.qml
|
||||||
|
qml/EditStateDialog.qml
|
||||||
|
qml/ConsentDialog.qml
|
||||||
|
qml/AskDirectChatConfirmation.qml
|
||||||
|
qml/HoverLinkIndicator.qml
|
||||||
|
qml/AvatarNotification.qml
|
||||||
|
qml/ReasonDialog.qml
|
||||||
|
DEPENDENCIES
|
||||||
|
QtCore
|
||||||
|
QtQuick
|
||||||
|
IMPORTS
|
||||||
|
org.kde.neochat.timeline
|
||||||
|
org.kde.neochat.settings
|
||||||
|
org.kde.neochat.devtools
|
||||||
|
org.kde.neochat.login
|
||||||
|
org.kde.neochat.chatbar
|
||||||
|
)
|
||||||
|
|
||||||
add_subdirectory(settings)
|
add_subdirectory(settings)
|
||||||
|
add_subdirectory(timeline)
|
||||||
add_subdirectory(devtools)
|
add_subdirectory(devtools)
|
||||||
add_subdirectory(app)
|
add_subdirectory(login)
|
||||||
|
add_subdirectory(chatbar)
|
||||||
|
|
||||||
|
if(NOT ANDROID AND NOT WIN32)
|
||||||
|
qt_target_qml_sources(neochat QML_FILES
|
||||||
|
qml/ShareAction.qml
|
||||||
|
qml/GlobalMenu.qml
|
||||||
|
qml/EditMenu.qml
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
qt_target_qml_sources(neochat QML_FILES qml/ShareActionStub.qml)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
configure_file(config-neochat.h.in ${CMAKE_CURRENT_BINARY_DIR}/config-neochat.h)
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
set_target_properties(neochat PROPERTIES OUTPUT_NAME "neochatlib")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
ecm_qt_declare_logging_category(neochat
|
||||||
|
HEADER "messageeventmodel_logging.h"
|
||||||
|
IDENTIFIER "MessageEvent"
|
||||||
|
CATEGORY_NAME "org.kde.neochat.messageeventmodel"
|
||||||
|
DESCRIPTION "Neochat: messageeventmodel"
|
||||||
|
DEFAULT_SEVERITY Info
|
||||||
|
EXPORT NEOCHAT
|
||||||
|
)
|
||||||
|
|
||||||
|
ecm_qt_declare_logging_category(neochat
|
||||||
|
HEADER "publicroomlist_logging.h"
|
||||||
|
IDENTIFIER "PublicRoomList"
|
||||||
|
CATEGORY_NAME "org.kde.neochat.publicroomlistmodel"
|
||||||
|
DESCRIPTION "Neochat: publicroomlistmodel"
|
||||||
|
DEFAULT_SEVERITY Info
|
||||||
|
EXPORT NEOCHAT
|
||||||
|
)
|
||||||
|
|
||||||
|
ecm_qt_declare_logging_category(neochat
|
||||||
|
HEADER "eventhandler_logging.h"
|
||||||
|
IDENTIFIER "EventHandling"
|
||||||
|
CATEGORY_NAME "org.kde.neochat.eventhandler"
|
||||||
|
DEFAULT_SEVERITY Info
|
||||||
|
)
|
||||||
|
|
||||||
|
ecm_qt_declare_logging_category(neochat
|
||||||
|
HEADER "chatdocumenthandler_logging.h"
|
||||||
|
IDENTIFIER "ChatDocumentHandling"
|
||||||
|
CATEGORY_NAME "org.kde.neochat.chatdocumenthandler"
|
||||||
|
DEFAULT_SEVERITY Info
|
||||||
|
)
|
||||||
|
|
||||||
|
add_executable(neochat-app
|
||||||
|
main.cpp
|
||||||
|
)
|
||||||
|
|
||||||
|
if(TARGET Qt::WebView)
|
||||||
|
target_link_libraries(neochat-app PUBLIC Qt::WebView)
|
||||||
|
target_compile_definitions(neochat-app PUBLIC -DHAVE_WEBVIEW)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
target_include_directories(neochat-app PRIVATE ${CMAKE_BINARY_DIR})
|
||||||
|
|
||||||
|
target_link_libraries(neochat-app PRIVATE
|
||||||
|
neochat
|
||||||
|
)
|
||||||
|
|
||||||
|
ecm_add_app_icon(NEOCHAT_ICON ICONS ${CMAKE_SOURCE_DIR}/128-logo.png)
|
||||||
|
|
||||||
|
target_sources(neochat-app PRIVATE ${NEOCHAT_ICON})
|
||||||
|
|
||||||
|
if(NOT ANDROID)
|
||||||
|
if (NOT WIN32 AND NOT APPLE)
|
||||||
|
target_sources(neochat PRIVATE trayicon_sni.cpp trayicon_sni.h)
|
||||||
|
target_link_libraries(neochat PRIVATE KF6::StatusNotifierItem)
|
||||||
|
else()
|
||||||
|
target_sources(neochat PRIVATE trayicon.cpp trayicon.h)
|
||||||
|
endif()
|
||||||
|
target_link_libraries(neochat PUBLIC KF6::WindowSystem ICU::uc)
|
||||||
|
target_compile_definitions(neochat PUBLIC -DHAVE_WINDOWSYSTEM)
|
||||||
|
target_compile_definitions(neochat PUBLIC -DHAVE_ICU)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (NOT ANDROID AND NOT WIN32 AND NOT APPLE AND NOT HAIKU)
|
||||||
|
target_compile_definitions(neochat PUBLIC -DHAVE_RUNNER)
|
||||||
|
target_compile_definitions(neochat PUBLIC -DHAVE_X11=1)
|
||||||
|
target_sources(neochat PRIVATE runner.cpp)
|
||||||
|
|
||||||
|
if (TARGET KUnifiedPush)
|
||||||
|
target_sources(neochat PRIVATE fakerunner.cpp)
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
target_compile_definitions(neochat PUBLIC -DHAVE_X11=0)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
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 devtoolsplugin loginplugin chatbarplugin)
|
||||||
|
target_link_libraries(neochat PUBLIC
|
||||||
|
Qt::Core
|
||||||
|
Qt::Quick
|
||||||
|
Qt::Qml
|
||||||
|
Qt::Gui
|
||||||
|
Qt::Multimedia
|
||||||
|
Qt::Network
|
||||||
|
Qt::QuickControls2
|
||||||
|
KF6::I18n
|
||||||
|
KF6::Kirigami
|
||||||
|
KF6::Notifications
|
||||||
|
KF6::ConfigCore
|
||||||
|
KF6::ConfigGui
|
||||||
|
KF6::CoreAddons
|
||||||
|
KF6::SonnetCore
|
||||||
|
KF6::IconThemes
|
||||||
|
KF6::ColorScheme
|
||||||
|
KF6::ItemModels
|
||||||
|
QuotientQt6
|
||||||
|
cmark::cmark
|
||||||
|
QCoro::Core
|
||||||
|
QCoro::Network
|
||||||
|
)
|
||||||
|
|
||||||
|
if (TARGET KF6::Crash)
|
||||||
|
target_link_libraries(neochat PUBLIC KF6::Crash)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
kconfig_target_kcfg_file(neochat FILE neochatconfig.kcfg CLASS_NAME NeoChatConfig MUTATORS GENERATE_PROPERTIES DEFAULT_VALUE_GETTERS PARENT_IN_CONSTRUCTOR SINGLETON GENERATE_MOC QML_REGISTRATION)
|
||||||
|
|
||||||
|
if(NEOCHAT_FLATPAK)
|
||||||
|
target_compile_definitions(neochat PUBLIC NEOCHAT_FLATPAK)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(ANDROID)
|
||||||
|
target_sources(neochat PRIVATE notifyrc.qrc)
|
||||||
|
target_link_libraries(neochat PRIVATE Qt::Svg OpenSSL::SSL)
|
||||||
|
if(SQLite3_FOUND)
|
||||||
|
target_link_libraries(neochat-app PRIVATE SQLite::SQLite3)
|
||||||
|
endif()
|
||||||
|
target_sources(neochat-app PRIVATE notifyrc.qrc)
|
||||||
|
target_link_libraries(neochat PUBLIC Qt::Svg OpenSSL::SSL)
|
||||||
|
kirigami_package_breeze_icons(ICONS
|
||||||
|
"arrow-down-symbolic"
|
||||||
|
"arrow-up-symbolic"
|
||||||
|
"arrow-up-double-symbolic"
|
||||||
|
"arrow-left-symbolic"
|
||||||
|
"arrow-right-symbolic"
|
||||||
|
"checkmark"
|
||||||
|
"help-about"
|
||||||
|
"im-user"
|
||||||
|
"im-invisible-user"
|
||||||
|
"im-kick-user"
|
||||||
|
"mail-attachment"
|
||||||
|
"dialog-cancel"
|
||||||
|
"preferences-desktop-emoticons"
|
||||||
|
"preferences-security"
|
||||||
|
"document-open"
|
||||||
|
"document-save"
|
||||||
|
"document-send"
|
||||||
|
"dialog-close"
|
||||||
|
"edit-delete-remove"
|
||||||
|
"code-context"
|
||||||
|
"document-edit"
|
||||||
|
"list-user-add"
|
||||||
|
"list-add-user"
|
||||||
|
"user-others"
|
||||||
|
"media-playback-pause"
|
||||||
|
"media-playback-start"
|
||||||
|
"media-playback-stop"
|
||||||
|
"go-previous"
|
||||||
|
"go-up"
|
||||||
|
"go-down"
|
||||||
|
"list-add"
|
||||||
|
"irc-join-channel"
|
||||||
|
"settings-configure"
|
||||||
|
"configure"
|
||||||
|
"rating"
|
||||||
|
"rating-unrated"
|
||||||
|
"search"
|
||||||
|
"mail-replied-symbolic"
|
||||||
|
"edit-clear"
|
||||||
|
"edit-copy"
|
||||||
|
"gtk-quit"
|
||||||
|
"compass"
|
||||||
|
"computer"
|
||||||
|
"network-connect"
|
||||||
|
"list-remove-user"
|
||||||
|
"org.kde.neochat"
|
||||||
|
"org.kde.neochat.tray"
|
||||||
|
"preferences-system-users"
|
||||||
|
"preferences-desktop-theme-global"
|
||||||
|
"notifications"
|
||||||
|
"notifications-disabled"
|
||||||
|
"audio-volume-high"
|
||||||
|
"audio-volume-muted"
|
||||||
|
"draw-highlight"
|
||||||
|
"zoom-in"
|
||||||
|
"zoom-out"
|
||||||
|
"image-rotate-left-symbolic"
|
||||||
|
"image-rotate-right-symbolic"
|
||||||
|
"channel-secure-symbolic"
|
||||||
|
"download"
|
||||||
|
"smiley"
|
||||||
|
"tools-check-spelling"
|
||||||
|
"username-copy"
|
||||||
|
"system-switch-user"
|
||||||
|
"bookmark-new"
|
||||||
|
"bookmark-remove"
|
||||||
|
"favorite"
|
||||||
|
"window-new"
|
||||||
|
"globe"
|
||||||
|
"visibility"
|
||||||
|
"home"
|
||||||
|
"preferences-desktop-notification"
|
||||||
|
"computer-symbolic"
|
||||||
|
"gps"
|
||||||
|
"system-users-symbolic"
|
||||||
|
"map-flat"
|
||||||
|
"documentinfo"
|
||||||
|
"view-list-details"
|
||||||
|
"go-previous"
|
||||||
|
"mail-forward-symbolic"
|
||||||
|
"dialog-warning-symbolic"
|
||||||
|
"object-rotate-left"
|
||||||
|
"object-rotate-right"
|
||||||
|
"add-subtitle"
|
||||||
|
"security-high"
|
||||||
|
"security-low"
|
||||||
|
"security-low-symbolic"
|
||||||
|
"kde"
|
||||||
|
"list-remove-symbolic"
|
||||||
|
"edit-delete"
|
||||||
|
"user-home-symbolic"
|
||||||
|
)
|
||||||
|
ecm_add_android_apk(neochat-app ANDROID_DIR ${CMAKE_SOURCE_DIR}/android)
|
||||||
|
else()
|
||||||
|
target_link_libraries(neochat PUBLIC Qt::Widgets KF6::KIOWidgets KF6::SyntaxHighlighting)
|
||||||
|
install(FILES neochat.notifyrc DESTINATION ${KDE_INSTALL_KNOTIFYRCDIR})
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT ANDROID)
|
||||||
|
set_target_properties(neochat-app PROPERTIES OUTPUT_NAME "neochat")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(TARGET KF6::DBusAddons AND NOT WIN32)
|
||||||
|
target_link_libraries(neochat PUBLIC KF6::DBusAddons)
|
||||||
|
target_compile_definitions(neochat PUBLIC -DHAVE_KDBUSADDONS)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (TARGET KF6::KIOWidgets)
|
||||||
|
target_compile_definitions(neochat PUBLIC -DHAVE_KIO)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (TARGET KUnifiedPush)
|
||||||
|
target_compile_definitions(neochat PUBLIC -DHAVE_KUNIFIEDPUSH)
|
||||||
|
target_link_libraries(neochat PUBLIC KUnifiedPush)
|
||||||
|
|
||||||
|
if (NOT ANDROID)
|
||||||
|
configure_file(org.kde.neochat.service.in ${CMAKE_CURRENT_BINARY_DIR}/org.kde.neochat.service)
|
||||||
|
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/org.kde.neochat.service DESTINATION ${KDE_INSTALL_DBUSSERVICEDIR})
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
install(TARGETS neochat-app ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})
|
||||||
|
|
||||||
|
if (NOT ANDROID AND NOT WIN32 AND NOT APPLE)
|
||||||
|
install(FILES plasma-runner-neochat.desktop DESTINATION ${KDE_INSTALL_DATAROOTDIR}/krunner/dbusplugins)
|
||||||
|
endif()
|
||||||
|
|||||||
@@ -1,366 +0,0 @@
|
|||||||
# SPDX-FileCopyrightText: 2020-2021 Carl Schwan <carl@carlschwan.eu>
|
|
||||||
# SPDX-FileCopyrightText: 2020-2021 Nicolas Fella <nicolas.fella@gmx.de>
|
|
||||||
# SPDX-FileCopyrightText: 2020-2021 Tobias Fella <tobias.fella@kde.org>
|
|
||||||
# SPDX-License-Identifier: BSD-2-Clause
|
|
||||||
|
|
||||||
add_library(neochat STATIC
|
|
||||||
controller.cpp
|
|
||||||
controller.h
|
|
||||||
roommanager.cpp
|
|
||||||
roommanager.h
|
|
||||||
models/userdirectorylistmodel.cpp
|
|
||||||
models/userdirectorylistmodel.h
|
|
||||||
notificationsmanager.cpp
|
|
||||||
notificationsmanager.h
|
|
||||||
blurhash.cpp
|
|
||||||
blurhash.h
|
|
||||||
blurhashimageprovider.cpp
|
|
||||||
blurhashimageprovider.h
|
|
||||||
windowcontroller.cpp
|
|
||||||
windowcontroller.h
|
|
||||||
models/serverlistmodel.cpp
|
|
||||||
models/serverlistmodel.h
|
|
||||||
models/notificationsmodel.cpp
|
|
||||||
models/notificationsmodel.h
|
|
||||||
proxycontroller.cpp
|
|
||||||
proxycontroller.h
|
|
||||||
mediamanager.cpp
|
|
||||||
mediamanager.h
|
|
||||||
sharehandler.cpp
|
|
||||||
sharehandler.h
|
|
||||||
foreigntypes.h
|
|
||||||
identityserverhelper.cpp
|
|
||||||
identityserverhelper.h
|
|
||||||
models/commonroomsmodel.cpp
|
|
||||||
models/commonroomsmodel.h
|
|
||||||
texttospeechhelper.h
|
|
||||||
texttospeechhelper.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
set_source_files_properties(qml/OsmLocationPlugin.qml PROPERTIES
|
|
||||||
QT_QML_SINGLETON_TYPE TRUE
|
|
||||||
)
|
|
||||||
|
|
||||||
if(ANDROID OR WIN32)
|
|
||||||
set_source_files_properties(qml/ShareActionStub.qml PROPERTIES
|
|
||||||
QT_QML_SOURCE_TYPENAME ShareAction
|
|
||||||
)
|
|
||||||
set_source_files_properties(qml/GlobalMenuStub.qml PROPERTIES
|
|
||||||
QT_QML_SOURCE_TYPENAME GlobalMenu
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
ecm_add_qml_module(neochat URI org.kde.neochat GENERATE_PLUGIN_SOURCE
|
|
||||||
OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/src/org/kde/neochat
|
|
||||||
QML_FILES
|
|
||||||
qml/Main.qml
|
|
||||||
qml/AccountMenu.qml
|
|
||||||
qml/CollapsedRoomDelegate.qml
|
|
||||||
qml/RoomPage.qml
|
|
||||||
qml/ManualRoomDialog.qml
|
|
||||||
qml/ExplorerDelegate.qml
|
|
||||||
qml/NeochatMaximizeComponent.qml
|
|
||||||
qml/QuickSwitcher.qml
|
|
||||||
qml/AttachmentPane.qml
|
|
||||||
qml/QuickFormatBar.qml
|
|
||||||
qml/UserDetailDialog.qml
|
|
||||||
qml/OpenFileDialog.qml
|
|
||||||
qml/KeyVerificationDialog.qml
|
|
||||||
qml/ConfirmLogoutDialog.qml
|
|
||||||
qml/VerificationMessage.qml
|
|
||||||
qml/EmojiItem.qml
|
|
||||||
qml/EmojiRow.qml
|
|
||||||
qml/EmojiSas.qml
|
|
||||||
qml/VerificationCanceled.qml
|
|
||||||
qml/MessageSourceSheet.qml
|
|
||||||
qml/LocationChooser.qml
|
|
||||||
qml/InvitationView.qml
|
|
||||||
qml/AvatarTabButton.qml
|
|
||||||
qml/OsmLocationPlugin.qml
|
|
||||||
qml/FullScreenMap.qml
|
|
||||||
qml/ChooseRoomDialog.qml
|
|
||||||
qml/QrCodeMaximizeComponent.qml
|
|
||||||
qml/NotificationsView.qml
|
|
||||||
qml/ServerComboBox.qml
|
|
||||||
qml/UserSearchPage.qml
|
|
||||||
qml/ManualUserDialog.qml
|
|
||||||
qml/RecommendedSpaceDialog.qml
|
|
||||||
qml/ShareDialog.qml
|
|
||||||
qml/UnlockSSSSDialog.qml
|
|
||||||
qml/QrScannerPage.qml
|
|
||||||
qml/JoinRoomDialog.qml
|
|
||||||
qml/ConfirmUrlDialog.qml
|
|
||||||
qml/AccountSwitchDialog.qml
|
|
||||||
qml/ConfirmLeaveDialog.qml
|
|
||||||
qml/CodeMaximizeComponent.qml
|
|
||||||
qml/EditStateDialog.qml
|
|
||||||
qml/ConsentDialog.qml
|
|
||||||
qml/AskDirectChatConfirmation.qml
|
|
||||||
qml/HoverLinkIndicator.qml
|
|
||||||
qml/AvatarNotification.qml
|
|
||||||
qml/ReasonDialog.qml
|
|
||||||
qml/NewPollDialog.qml
|
|
||||||
qml/UserMenu.qml
|
|
||||||
DEPENDENCIES
|
|
||||||
QtCore
|
|
||||||
QtQuick
|
|
||||||
IMPORTS
|
|
||||||
org.kde.neochat.libneochat
|
|
||||||
org.kde.neochat.rooms
|
|
||||||
org.kde.neochat.roominfo
|
|
||||||
org.kde.neochat.messagecontent
|
|
||||||
org.kde.neochat.timeline
|
|
||||||
org.kde.neochat.spaces
|
|
||||||
org.kde.neochat.settings
|
|
||||||
org.kde.neochat.devtools
|
|
||||||
org.kde.neochat.login
|
|
||||||
org.kde.neochat.chatbar
|
|
||||||
)
|
|
||||||
|
|
||||||
if(NOT ANDROID AND NOT WIN32)
|
|
||||||
qt_target_qml_sources(neochat QML_FILES
|
|
||||||
qml/ShareAction.qml
|
|
||||||
qml/GlobalMenu.qml
|
|
||||||
qml/EditMenu.qml
|
|
||||||
)
|
|
||||||
else()
|
|
||||||
qt_target_qml_sources(neochat QML_FILES
|
|
||||||
qml/ShareActionStub.qml
|
|
||||||
qml/GlobalMenuStub.qml
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(WIN32)
|
|
||||||
set_target_properties(neochat PROPERTIES OUTPUT_NAME "neochatlib")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_executable(neochat-app
|
|
||||||
main.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
if(TARGET Qt::WebView)
|
|
||||||
target_link_libraries(neochat-app PUBLIC Qt::WebView)
|
|
||||||
target_compile_definitions(neochat-app PUBLIC -DHAVE_WEBVIEW)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
target_include_directories(neochat-app PRIVATE ${CMAKE_BINARY_DIR})
|
|
||||||
|
|
||||||
target_link_libraries(neochat-app PRIVATE
|
|
||||||
neochat
|
|
||||||
)
|
|
||||||
|
|
||||||
ecm_add_app_icon(NEOCHAT_ICON ICONS ${CMAKE_SOURCE_DIR}/128-logo.png)
|
|
||||||
|
|
||||||
target_sources(neochat-app PRIVATE ${NEOCHAT_ICON})
|
|
||||||
|
|
||||||
if(NOT ANDROID)
|
|
||||||
if (NOT WIN32 AND NOT APPLE)
|
|
||||||
target_sources(neochat PRIVATE trayicon_sni.cpp trayicon_sni.h)
|
|
||||||
target_link_libraries(neochat PRIVATE KF6::StatusNotifierItem)
|
|
||||||
else()
|
|
||||||
target_sources(neochat PRIVATE trayicon.cpp trayicon.h)
|
|
||||||
endif()
|
|
||||||
target_link_libraries(neochat PUBLIC KF6::WindowSystem)
|
|
||||||
target_compile_definitions(neochat PUBLIC -DHAVE_WINDOWSYSTEM)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (NOT ANDROID AND NOT WIN32 AND NOT APPLE AND NOT HAIKU)
|
|
||||||
target_compile_definitions(neochat PUBLIC -DHAVE_RUNNER)
|
|
||||||
target_compile_definitions(neochat PUBLIC -DHAVE_X11=1)
|
|
||||||
target_sources(neochat PRIVATE runner.cpp)
|
|
||||||
|
|
||||||
if (TARGET KUnifiedPush)
|
|
||||||
target_sources(neochat PRIVATE fakerunner.cpp)
|
|
||||||
endif()
|
|
||||||
else()
|
|
||||||
target_compile_definitions(neochat PUBLIC -DHAVE_X11=0)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
target_include_directories(neochat PRIVATE ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/models)
|
|
||||||
target_link_libraries(neochat PRIVATE Loginplugin Roomsplugin RoomInfoplugin MessageContentplugin Timelineplugin Spacesplugin Chatbarplugin Settingsplugin Devtoolsplugin)
|
|
||||||
target_link_libraries(neochat PUBLIC
|
|
||||||
LibNeoChat
|
|
||||||
Timeline
|
|
||||||
Settings
|
|
||||||
Qt::Core
|
|
||||||
Qt::Quick
|
|
||||||
Qt::Qml
|
|
||||||
Qt::Gui
|
|
||||||
Qt::Multimedia
|
|
||||||
Qt::Network
|
|
||||||
Qt::QuickControls2
|
|
||||||
Qt::TextToSpeech
|
|
||||||
KF6::I18n
|
|
||||||
KF6::Kirigami
|
|
||||||
KF6::Notifications
|
|
||||||
KF6::ConfigCore
|
|
||||||
KF6::ConfigGui
|
|
||||||
KF6::CoreAddons
|
|
||||||
KF6::SonnetCore
|
|
||||||
KF6::IconThemes
|
|
||||||
KF6::ItemModels
|
|
||||||
QuotientQt6
|
|
||||||
Login
|
|
||||||
Rooms
|
|
||||||
MessageContent
|
|
||||||
Spaces
|
|
||||||
)
|
|
||||||
|
|
||||||
if (TARGET KF6::Crash)
|
|
||||||
target_link_libraries(neochat PUBLIC KF6::Crash)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
kconfig_target_kcfg_file(neochat FILE neochatconfig.kcfg CLASS_NAME NeoChatConfig MUTATORS GENERATE_PROPERTIES DEFAULT_VALUE_GETTERS PARENT_IN_CONSTRUCTOR SINGLETON GENERATE_MOC QML_REGISTRATION)
|
|
||||||
|
|
||||||
if(NEOCHAT_FLATPAK)
|
|
||||||
target_compile_definitions(neochat PUBLIC NEOCHAT_FLATPAK)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(ANDROID)
|
|
||||||
target_sources(neochat PRIVATE notifyrc.qrc)
|
|
||||||
target_link_libraries(neochat PRIVATE Qt::Svg OpenSSL::SSL)
|
|
||||||
if(SQLite3_FOUND)
|
|
||||||
target_link_libraries(neochat-app PRIVATE SQLite::SQLite3)
|
|
||||||
endif()
|
|
||||||
target_sources(neochat-app PRIVATE notifyrc.qrc)
|
|
||||||
target_link_libraries(neochat PUBLIC Qt::Svg OpenSSL::SSL)
|
|
||||||
kirigami_package_breeze_icons(ICONS
|
|
||||||
"arrow-down-symbolic"
|
|
||||||
"arrow-up-symbolic"
|
|
||||||
"arrow-up-double-symbolic"
|
|
||||||
"arrow-left-symbolic"
|
|
||||||
"arrow-right-symbolic"
|
|
||||||
"checkmark"
|
|
||||||
"help-about"
|
|
||||||
"im-user"
|
|
||||||
"im-invisible-user"
|
|
||||||
"im-kick-user"
|
|
||||||
"mail-attachment"
|
|
||||||
"dialog-cancel"
|
|
||||||
"preferences-desktop-emoticons"
|
|
||||||
"preferences-security"
|
|
||||||
"document-open"
|
|
||||||
"document-save"
|
|
||||||
"document-send"
|
|
||||||
"dialog-close"
|
|
||||||
"edit-delete-remove"
|
|
||||||
"code-context"
|
|
||||||
"document-edit"
|
|
||||||
"list-user-add"
|
|
||||||
"list-add-user"
|
|
||||||
"user-others"
|
|
||||||
"media-playback-pause"
|
|
||||||
"media-playback-start"
|
|
||||||
"media-playback-stop"
|
|
||||||
"go-previous"
|
|
||||||
"go-up"
|
|
||||||
"go-down"
|
|
||||||
"list-add"
|
|
||||||
"irc-join-channel"
|
|
||||||
"settings-configure"
|
|
||||||
"configure"
|
|
||||||
"rating"
|
|
||||||
"rating-unrated"
|
|
||||||
"search"
|
|
||||||
"mail-replied-symbolic"
|
|
||||||
"edit-clear"
|
|
||||||
"edit-copy"
|
|
||||||
"gtk-quit"
|
|
||||||
"compass"
|
|
||||||
"computer"
|
|
||||||
"network-connect"
|
|
||||||
"list-remove-user"
|
|
||||||
"org.kde.neochat"
|
|
||||||
"org.kde.neochat.tray"
|
|
||||||
"preferences-system-users"
|
|
||||||
"preferences-desktop-theme-global"
|
|
||||||
"notifications"
|
|
||||||
"notifications-disabled"
|
|
||||||
"audio-volume-high"
|
|
||||||
"audio-volume-muted"
|
|
||||||
"draw-highlight"
|
|
||||||
"zoom-in"
|
|
||||||
"zoom-out"
|
|
||||||
"image-rotate-left-symbolic"
|
|
||||||
"image-rotate-right-symbolic"
|
|
||||||
"channel-secure-symbolic"
|
|
||||||
"download"
|
|
||||||
"smiley"
|
|
||||||
"tools-check-spelling"
|
|
||||||
"username-copy"
|
|
||||||
"system-switch-user"
|
|
||||||
"bookmark-new"
|
|
||||||
"bookmark-remove"
|
|
||||||
"favorite"
|
|
||||||
"window-new"
|
|
||||||
"globe"
|
|
||||||
"visibility"
|
|
||||||
"home"
|
|
||||||
"preferences-desktop-notification"
|
|
||||||
"computer-symbolic"
|
|
||||||
"gps"
|
|
||||||
"system-users-symbolic"
|
|
||||||
"map-flat"
|
|
||||||
"documentinfo"
|
|
||||||
"view-list-details"
|
|
||||||
"go-previous"
|
|
||||||
"mail-forward-symbolic"
|
|
||||||
"dialog-warning-symbolic"
|
|
||||||
"object-rotate-left"
|
|
||||||
"object-rotate-right"
|
|
||||||
"add-subtitle"
|
|
||||||
"security-high"
|
|
||||||
"security-low"
|
|
||||||
"security-low-symbolic"
|
|
||||||
"kde"
|
|
||||||
"list-remove-symbolic"
|
|
||||||
"edit-delete"
|
|
||||||
"user-home-symbolic"
|
|
||||||
"pin-symbolic"
|
|
||||||
"kt-restore-defaults-symbolic"
|
|
||||||
"user-symbolic"
|
|
||||||
"mark-location-symbolic"
|
|
||||||
|
|
||||||
${KIRIGAMI_ADDONS_ICONS}
|
|
||||||
)
|
|
||||||
ecm_add_android_apk(neochat-app ANDROID_DIR ${CMAKE_SOURCE_DIR}/android)
|
|
||||||
else()
|
|
||||||
target_link_libraries(neochat PUBLIC Qt::Widgets KF6::KIOWidgets)
|
|
||||||
install(FILES neochat.notifyrc DESTINATION ${KDE_INSTALL_KNOTIFYRCDIR})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(NOT ANDROID)
|
|
||||||
set_target_properties(neochat-app PROPERTIES OUTPUT_NAME "neochat")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(TARGET KF6::DBusAddons AND NOT WIN32)
|
|
||||||
target_link_libraries(neochat PUBLIC KF6::DBusAddons)
|
|
||||||
target_compile_definitions(neochat PUBLIC -DHAVE_KDBUSADDONS)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (TARGET KF6::KIOWidgets)
|
|
||||||
target_compile_definitions(neochat PUBLIC -DHAVE_KIO)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (TARGET KUnifiedPush)
|
|
||||||
target_compile_definitions(neochat PUBLIC -DHAVE_KUNIFIEDPUSH)
|
|
||||||
target_link_libraries(neochat PUBLIC KUnifiedPush)
|
|
||||||
|
|
||||||
if (NOT ANDROID)
|
|
||||||
configure_file(org.kde.neochat.service.in ${CMAKE_CURRENT_BINARY_DIR}/org.kde.neochat.service)
|
|
||||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/org.kde.neochat.service DESTINATION ${KDE_INSTALL_DBUSSERVICEDIR})
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
install(TARGETS neochat-app ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})
|
|
||||||
|
|
||||||
if (NOT ANDROID AND NOT WIN32 AND NOT APPLE)
|
|
||||||
install(FILES plasma-runner-neochat.desktop DESTINATION ${KDE_INSTALL_DATAROOTDIR}/krunner/dbusplugins)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (APPLE)
|
|
||||||
set_target_properties(neochat-app PROPERTIES MACOSX_BUNDLE_GUI_IDENTIFIER "org.kde.neochat")
|
|
||||||
set_target_properties(neochat-app PROPERTIES MACOSX_BUNDLE_BUNDLE_NAME "NeoChat")
|
|
||||||
set_target_properties(neochat-app PROPERTIES MACOSX_BUNDLE_SHORT_VERSION_STRING ${RELEASE_SERVICE_VERSION})
|
|
||||||
set_target_properties(neochat-app PROPERTIES MACOSX_BUNDLE_BUNDLE_VERSION ${RELEASE_SERVICE_VERSION})
|
|
||||||
endif ()
|
|
||||||
@@ -1,415 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: 2018-2019 Black Hat <bhat@encom.eu.org>
|
|
||||||
// SPDX-FileCopyrightText: 2020 Tobias Fella <tobias.fella@kde.org>
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-only
|
|
||||||
|
|
||||||
#include "controller.h"
|
|
||||||
|
|
||||||
#include <Quotient/connection.h>
|
|
||||||
#include <qt6keychain/keychain.h>
|
|
||||||
|
|
||||||
#include <KLocalizedString>
|
|
||||||
|
|
||||||
#include <QGuiApplication>
|
|
||||||
#include <QTimer>
|
|
||||||
|
|
||||||
#include <signal.h>
|
|
||||||
|
|
||||||
#include <Quotient/csapi/notifications.h>
|
|
||||||
#include <Quotient/events/roommemberevent.h>
|
|
||||||
#include <Quotient/qt_connection_util.h>
|
|
||||||
#include <Quotient/settings.h>
|
|
||||||
|
|
||||||
#include "accountmanager.h"
|
|
||||||
#include "enums/roomsortparameter.h"
|
|
||||||
#include "mediasizehelper.h"
|
|
||||||
#include "models/actionsmodel.h"
|
|
||||||
#include "models/messagemodel.h"
|
|
||||||
#include "models/pushrulemodel.h"
|
|
||||||
#include "models/roomlistmodel.h"
|
|
||||||
#include "models/roomtreemodel.h"
|
|
||||||
#include "neochatconfig.h"
|
|
||||||
#include "neochatconnection.h"
|
|
||||||
#include "neochatroom.h"
|
|
||||||
#include "notificationsmanager.h"
|
|
||||||
#include "proxycontroller.h"
|
|
||||||
#include "roommanager.h"
|
|
||||||
|
|
||||||
#if defined(Q_OS_WIN) || defined(Q_OS_MAC)
|
|
||||||
#include "trayicon.h"
|
|
||||||
#elif !defined(Q_OS_ANDROID)
|
|
||||||
#include "trayicon_sni.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if QT_VERSION < QT_VERSION_CHECK(6, 6, 0)
|
|
||||||
#ifndef Q_OS_ANDROID
|
|
||||||
#include <QDBusConnection>
|
|
||||||
#include <QDBusInterface>
|
|
||||||
#include <QDBusMessage>
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_KUNIFIEDPUSH
|
|
||||||
#include <kunifiedpush/connector.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
using namespace Quotient;
|
|
||||||
|
|
||||||
static std::function<bool(const Quotient::RoomEvent *)> hiddenEventFilter = [](const RoomEvent *event) -> bool {
|
|
||||||
if (event->isStateEvent() && !NeoChatConfig::showStateEvent()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (auto roomMemberEvent = eventCast<const RoomMemberEvent>(event)) {
|
|
||||||
if ((roomMemberEvent->isJoin() || roomMemberEvent->isLeave()) && !NeoChatConfig::showLeaveJoinEvent()) {
|
|
||||||
return true;
|
|
||||||
} else if (roomMemberEvent->isRename() && !roomMemberEvent->isJoin() && !roomMemberEvent->isLeave() && !NeoChatConfig::showRename()) {
|
|
||||||
return true;
|
|
||||||
} else if (roomMemberEvent->isAvatarUpdate() && !roomMemberEvent->isJoin() && !roomMemberEvent->isLeave() && !NeoChatConfig::showAvatarUpdate()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
};
|
|
||||||
|
|
||||||
Controller::Controller(QObject *parent)
|
|
||||||
: QObject(parent)
|
|
||||||
{
|
|
||||||
Connection::setRoomType<NeoChatRoom>();
|
|
||||||
|
|
||||||
Connection::setDirectChatEncryptionDefault(NeoChatConfig::preferUsingEncryption());
|
|
||||||
connect(NeoChatConfig::self(), &NeoChatConfig::PreferUsingEncryptionChanged, this, [] {
|
|
||||||
Connection::setDirectChatEncryptionDefault(NeoChatConfig::preferUsingEncryption());
|
|
||||||
});
|
|
||||||
|
|
||||||
NeoChatConnection::setGlobalUrlPreviewDefault(NeoChatConfig::showLinkPreview());
|
|
||||||
connect(NeoChatConfig::self(), &NeoChatConfig::ShowLinkPreviewChanged, this, [this] {
|
|
||||||
NeoChatConnection::setGlobalUrlPreviewDefault(NeoChatConfig::showLinkPreview());
|
|
||||||
Q_EMIT globalUrlPreviewDefaultChanged();
|
|
||||||
});
|
|
||||||
|
|
||||||
NeoChatConnection::setKeywordPushRuleDefault(static_cast<PushRuleAction::Action>(NeoChatConfig::keywordPushRuleDefault()));
|
|
||||||
connect(NeoChatConfig::self(), &NeoChatConfig::KeywordPushRuleDefaultChanged, this, [] {
|
|
||||||
NeoChatConnection::setKeywordPushRuleDefault(static_cast<PushRuleAction::Action>(NeoChatConfig::keywordPushRuleDefault()));
|
|
||||||
});
|
|
||||||
|
|
||||||
ActionsModel::setAllowQuickEdit(NeoChatConfig::allowQuickEdit());
|
|
||||||
connect(NeoChatConfig::self(), &NeoChatConfig::AllowQuickEditChanged, this, []() {
|
|
||||||
ActionsModel::setAllowQuickEdit(NeoChatConfig::allowQuickEdit());
|
|
||||||
});
|
|
||||||
|
|
||||||
MessageModel::setHiddenFilter(hiddenEventFilter);
|
|
||||||
RoomListModel::setHiddenFilter(hiddenEventFilter);
|
|
||||||
RoomTreeModel::setHiddenFilter(hiddenEventFilter);
|
|
||||||
NeoChatRoom::setHiddenFilter(hiddenEventFilter);
|
|
||||||
|
|
||||||
MediaSizeHelper::setMaxSize(NeoChatConfig::mediaMaxWidth(), NeoChatConfig::mediaMaxHeight());
|
|
||||||
connect(NeoChatConfig::self(), &NeoChatConfig::MediaMaxWidthChanged, this, []() {
|
|
||||||
MediaSizeHelper::setMaxSize(NeoChatConfig::mediaMaxWidth(), NeoChatConfig::mediaMaxHeight());
|
|
||||||
});
|
|
||||||
connect(NeoChatConfig::self(), &NeoChatConfig::MediaMaxHeightChanged, this, []() {
|
|
||||||
MediaSizeHelper::setMaxSize(NeoChatConfig::mediaMaxWidth(), NeoChatConfig::mediaMaxHeight());
|
|
||||||
});
|
|
||||||
|
|
||||||
RoomSortParameter::setSortOrder(static_cast<RoomSortOrder::Order>(NeoChatConfig::sortOrder()));
|
|
||||||
connect(NeoChatConfig::self(), &NeoChatConfig::SortOrderChanged, this, []() {
|
|
||||||
RoomSortParameter::setSortOrder(static_cast<RoomSortOrder::Order>(NeoChatConfig::sortOrder()));
|
|
||||||
});
|
|
||||||
|
|
||||||
QList<RoomSortParameter::Parameter> configParamList;
|
|
||||||
const auto intList = NeoChatConfig::customSortOrder();
|
|
||||||
std::transform(intList.constBegin(), intList.constEnd(), std::back_inserter(configParamList), [](int param) {
|
|
||||||
return static_cast<RoomSortParameter::Parameter>(param);
|
|
||||||
});
|
|
||||||
RoomSortParameter::setCustomSortOrder(configParamList);
|
|
||||||
connect(NeoChatConfig::self(), &NeoChatConfig::CustomSortOrderChanged, this, []() {
|
|
||||||
QList<RoomSortParameter::Parameter> configParamList;
|
|
||||||
const auto intList = NeoChatConfig::customSortOrder();
|
|
||||||
std::transform(intList.constBegin(), intList.constEnd(), std::back_inserter(configParamList), [](int param) {
|
|
||||||
return static_cast<RoomSortParameter::Parameter>(param);
|
|
||||||
});
|
|
||||||
RoomSortParameter::setCustomSortOrder(configParamList);
|
|
||||||
});
|
|
||||||
|
|
||||||
ProxyController::instance().setApplicationProxy();
|
|
||||||
|
|
||||||
#ifndef Q_OS_ANDROID
|
|
||||||
setQuitOnLastWindowClosed();
|
|
||||||
connect(NeoChatConfig::self(), &NeoChatConfig::SystemTrayChanged, this, &Controller::setQuitOnLastWindowClosed);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
QObject::connect(QGuiApplication::instance(), &QCoreApplication::aboutToQuit, QGuiApplication::instance(), [this] {
|
|
||||||
delete m_trayIcon;
|
|
||||||
NeoChatConfig::self()->save();
|
|
||||||
});
|
|
||||||
|
|
||||||
#ifndef Q_OS_WINDOWS
|
|
||||||
const auto unixExitHandler = [](int) -> void {
|
|
||||||
QCoreApplication::quit();
|
|
||||||
};
|
|
||||||
|
|
||||||
const int quitSignals[] = {SIGQUIT, SIGINT, SIGTERM, SIGHUP};
|
|
||||||
|
|
||||||
sigset_t blockingMask;
|
|
||||||
sigemptyset(&blockingMask);
|
|
||||||
for (const auto sig : quitSignals) {
|
|
||||||
sigaddset(&blockingMask, sig);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct sigaction sa;
|
|
||||||
sa.sa_handler = unixExitHandler;
|
|
||||||
sa.sa_mask = blockingMask;
|
|
||||||
sa.sa_flags = 0;
|
|
||||||
|
|
||||||
for (auto sig : quitSignals) {
|
|
||||||
sigaction(sig, &sa, nullptr);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_KUNIFIEDPUSH
|
|
||||||
auto connector = new KUnifiedPush::Connector(u"org.kde.neochat"_s);
|
|
||||||
connect(connector, &KUnifiedPush::Connector::endpointChanged, this, [this](const QString &endpoint) {
|
|
||||||
if (!m_accountManager) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_endpoint = endpoint;
|
|
||||||
for (auto "ientConnection : m_accountManager->accounts()->accounts()) {
|
|
||||||
auto connection = dynamic_cast<NeoChatConnection *>(quotientConnection);
|
|
||||||
connection->setupPushNotifications(endpoint);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
connector->registerClient(
|
|
||||||
i18nc("The reason for using push notifications, as in: '[Push notifications are used for] Receiving notifications for new messages'",
|
|
||||||
"Receiving notifications for new messages"));
|
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
Controller &Controller::instance()
|
|
||||||
{
|
|
||||||
static Controller _instance;
|
|
||||||
return _instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Controller::setAccountManager(AccountManager *manager)
|
|
||||||
{
|
|
||||||
if (manager == m_accountManager) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_accountManager) {
|
|
||||||
m_accountManager->disconnect(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_accountManager = manager;
|
|
||||||
|
|
||||||
if (m_accountManager) {
|
|
||||||
connect(m_accountManager, &AccountManager::errorOccured, this, &Controller::errorOccured);
|
|
||||||
connect(m_accountManager, &AccountManager::accountsLoadingChanged, this, &Controller::accountsLoadingChanged);
|
|
||||||
connect(m_accountManager, &AccountManager::connectionAdded, this, &Controller::initConnection);
|
|
||||||
connect(m_accountManager, &AccountManager::connectionDropped, this, &Controller::teardownConnection);
|
|
||||||
connect(m_accountManager, &AccountManager::activeConnectionChanged, this, &Controller::initActiveConnection);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Controller::initConnection(NeoChatConnection *connection)
|
|
||||||
{
|
|
||||||
if (!connection) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
connect(
|
|
||||||
connection,
|
|
||||||
&NeoChatConnection::syncDone,
|
|
||||||
this,
|
|
||||||
[this, connection] {
|
|
||||||
if (!m_endpoint.isEmpty()) {
|
|
||||||
connection->setupPushNotifications(m_endpoint);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Qt::SingleShotConnection);
|
|
||||||
connect(connection, &NeoChatConnection::syncDone, this, [this, connection]() {
|
|
||||||
m_notificationsManager.handleNotifications(connection);
|
|
||||||
});
|
|
||||||
connect(this, &Controller::globalUrlPreviewDefaultChanged, connection, &NeoChatConnection::globalUrlPreviewEnabledChanged);
|
|
||||||
connect(connection, &NeoChatConnection::roomAboutToBeLeft, &RoomManager::instance(), &RoomManager::roomLeft);
|
|
||||||
Q_EMIT connectionAdded(connection);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Controller::teardownConnection(NeoChatConnection *connection)
|
|
||||||
{
|
|
||||||
if (!connection) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
connection->disconnect(this);
|
|
||||||
Q_EMIT connectionDropped(connection);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Controller::initActiveConnection(NeoChatConnection *oldConnection, NeoChatConnection *newConnection)
|
|
||||||
{
|
|
||||||
if (oldConnection) {
|
|
||||||
oldConnection->disconnect(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (newConnection) {
|
|
||||||
connect(newConnection, &NeoChatConnection::errorOccured, this, &Controller::errorOccured);
|
|
||||||
connect(newConnection, &NeoChatConnection::badgeNotificationCountChanged, this, &Controller::updateBadgeNotificationCount);
|
|
||||||
newConnection->refreshBadgeNotificationCount();
|
|
||||||
}
|
|
||||||
Q_EMIT activeConnectionChanged(newConnection);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Controller::supportSystemTray() const
|
|
||||||
{
|
|
||||||
#ifdef Q_OS_ANDROID
|
|
||||||
return false;
|
|
||||||
#else
|
|
||||||
auto de = QString::fromLatin1(qgetenv("XDG_CURRENT_DESKTOP"));
|
|
||||||
return de != u"GNOME"_s && de != u"Pantheon"_s;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void Controller::setQuitOnLastWindowClosed()
|
|
||||||
{
|
|
||||||
#ifndef Q_OS_ANDROID
|
|
||||||
if (supportSystemTray() && NeoChatConfig::self()->systemTray()) {
|
|
||||||
m_trayIcon = new TrayIcon(this);
|
|
||||||
m_trayIcon->show();
|
|
||||||
} else {
|
|
||||||
if (m_trayIcon) {
|
|
||||||
delete m_trayIcon;
|
|
||||||
m_trayIcon = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
NeoChatConnection *Controller::activeConnection() const
|
|
||||||
{
|
|
||||||
if (!m_accountManager) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
return m_accountManager->activeConnection();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Controller::setActiveConnection(NeoChatConnection *connection)
|
|
||||||
{
|
|
||||||
if (!m_accountManager) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
m_accountManager->setActiveConnection(connection);
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList Controller::accountsLoading() const
|
|
||||||
{
|
|
||||||
if (!m_accountManager) {
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
return m_accountManager->accountsLoading();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Controller::listenForNotifications()
|
|
||||||
{
|
|
||||||
#ifdef HAVE_KUNIFIEDPUSH
|
|
||||||
auto connector = new KUnifiedPush::Connector(u"org.kde.neochat"_s);
|
|
||||||
|
|
||||||
auto timer = new QTimer();
|
|
||||||
connect(timer, &QTimer::timeout, qGuiApp, &QGuiApplication::quit);
|
|
||||||
|
|
||||||
connect(connector, &KUnifiedPush::Connector::messageReceived, [timer](const QByteArray &data) {
|
|
||||||
instance().m_notificationsManager.postPushNotification(data);
|
|
||||||
timer->stop();
|
|
||||||
});
|
|
||||||
|
|
||||||
// Wait five seconds to see if we received any messages or this happened to be an erroneous activation.
|
|
||||||
// Otherwise, messageReceived is never activated, and this daemon could stick around forever.
|
|
||||||
timer->start(5000);
|
|
||||||
|
|
||||||
connector->registerClient(i18n("Receiving push notifications"));
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void Controller::clearInvitationNotification(const QString &roomId)
|
|
||||||
{
|
|
||||||
m_notificationsManager.clearInvitationNotification(roomId);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Controller::updateBadgeNotificationCount(int count)
|
|
||||||
{
|
|
||||||
#if QT_VERSION < QT_VERSION_CHECK(6, 6, 0)
|
|
||||||
#ifndef Q_OS_ANDROID
|
|
||||||
// copied from Telegram desktop
|
|
||||||
const auto launcherUrl = "application://org.kde.neochat.desktop"_L1;
|
|
||||||
// Gnome requires that count is a 64bit integer
|
|
||||||
const qint64 counterSlice = std::min(count, 9999);
|
|
||||||
QVariantMap dbusUnityProperties;
|
|
||||||
|
|
||||||
if (counterSlice > 0) {
|
|
||||||
dbusUnityProperties["count"_L1] = counterSlice;
|
|
||||||
dbusUnityProperties["count-visible"_L1] = true;
|
|
||||||
} else {
|
|
||||||
dbusUnityProperties["count-visible"_L1] = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto signal = QDBusMessage::createSignal("/com/canonical/unity/launcherentry/neochat"_L1, "com.canonical.Unity.LauncherEntry"_L1, "Update"_L1);
|
|
||||||
|
|
||||||
signal.setArguments({launcherUrl, dbusUnityProperties});
|
|
||||||
|
|
||||||
QDBusConnection::sessionBus().send(signal);
|
|
||||||
#endif // Q_OS_ANDROID
|
|
||||||
#else
|
|
||||||
qGuiApp->setBadgeNumber(count);
|
|
||||||
#endif // QT_VERSION_CHECK(6, 6, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Controller::isFlatpak() const
|
|
||||||
{
|
|
||||||
#ifdef NEOCHAT_FLATPAK
|
|
||||||
return true;
|
|
||||||
#else
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
AccountRegistry *Controller::accounts()
|
|
||||||
{
|
|
||||||
return m_accountManager->accounts();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString Controller::loadFileContent(const QString &path) const
|
|
||||||
{
|
|
||||||
QUrl url(path);
|
|
||||||
QFile file(url.isLocalFile() ? url.toLocalFile() : url.toString());
|
|
||||||
file.open(QFile::ReadOnly);
|
|
||||||
return QString::fromLatin1(file.readAll());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Controller::removeConnection(const QString &userId)
|
|
||||||
{
|
|
||||||
m_accountManager->dropConnection(userId);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Controller::revertToDefaultConfig()
|
|
||||||
{
|
|
||||||
const auto config = NeoChatConfig::self();
|
|
||||||
config->setDefaults();
|
|
||||||
config->save();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Controller::isImageShown(const QString &eventId)
|
|
||||||
{
|
|
||||||
return m_shownImages.contains(eventId);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Controller::markImageShown(const QString &eventId)
|
|
||||||
{
|
|
||||||
m_shownImages.append(eventId);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Controller::markImageHidden(const QString &eventId)
|
|
||||||
{
|
|
||||||
m_shownImages.removeAll(eventId);
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "moc_controller.cpp"
|
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: 2025 Joshua Goins <josh@redstrate.com>
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#include "commonroomsmodel.h"
|
|
||||||
#include "jobs/neochatgetcommonroomsjob.h"
|
|
||||||
|
|
||||||
#include <QGuiApplication>
|
|
||||||
|
|
||||||
using namespace Quotient;
|
|
||||||
|
|
||||||
CommonRoomsModel::CommonRoomsModel(QObject *parent)
|
|
||||||
: QAbstractListModel(parent)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
NeoChatConnection *CommonRoomsModel::connection() const
|
|
||||||
{
|
|
||||||
return m_connection;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CommonRoomsModel::setConnection(NeoChatConnection *connection)
|
|
||||||
{
|
|
||||||
m_connection = connection;
|
|
||||||
Q_EMIT connectionChanged();
|
|
||||||
reload();
|
|
||||||
}
|
|
||||||
|
|
||||||
QString CommonRoomsModel::userId() const
|
|
||||||
{
|
|
||||||
return m_userId;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CommonRoomsModel::setUserId(const QString &userId)
|
|
||||||
{
|
|
||||||
m_userId = userId;
|
|
||||||
Q_EMIT userIdChanged();
|
|
||||||
reload();
|
|
||||||
}
|
|
||||||
|
|
||||||
QVariant CommonRoomsModel::data(const QModelIndex &index, int roleName) const
|
|
||||||
{
|
|
||||||
Q_UNUSED(index)
|
|
||||||
Q_UNUSED(roleName)
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
int CommonRoomsModel::rowCount(const QModelIndex &parent) const
|
|
||||||
{
|
|
||||||
Q_UNUSED(parent)
|
|
||||||
return m_commonRooms.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CommonRoomsModel::reload()
|
|
||||||
{
|
|
||||||
if (!m_connection || m_userId.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!m_connection->canCheckMutualRooms()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Checking if you have mutual rooms with yourself doesn't make sense and servers reject it too
|
|
||||||
if (m_connection->userId() == m_userId) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_connection->callApi<NeochatGetCommonRoomsJob>(m_userId).then([this](const auto job) {
|
|
||||||
const auto &replyData = job->jsonData();
|
|
||||||
beginResetModel();
|
|
||||||
for (const auto &roomId : replyData[u"joined"_s].toArray()) {
|
|
||||||
m_commonRooms.push_back(roomId.toString());
|
|
||||||
}
|
|
||||||
endResetModel();
|
|
||||||
Q_EMIT countChanged();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "moc_commonroomsmodel.cpp"
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: 2025 Joshua Goins <josh@redstrate.com>
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QAbstractListModel>
|
|
||||||
#include <QQmlEngine>
|
|
||||||
|
|
||||||
#include "neochatconnection.h"
|
|
||||||
#include "neochatroom.h"
|
|
||||||
|
|
||||||
#include <Quotient/events/roommessageevent.h>
|
|
||||||
#include <Quotient/roommember.h>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Model to show the common or mutual rooms between you and another user.
|
|
||||||
*/
|
|
||||||
class CommonRoomsModel : public QAbstractListModel
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
QML_ELEMENT
|
|
||||||
Q_PROPERTY(NeoChatConnection *connection WRITE setConnection READ connection NOTIFY connectionChanged REQUIRED)
|
|
||||||
Q_PROPERTY(QString userId WRITE setUserId READ userId NOTIFY userIdChanged REQUIRED)
|
|
||||||
Q_PROPERTY(int count READ rowCount NOTIFY countChanged)
|
|
||||||
|
|
||||||
public:
|
|
||||||
enum Roles {
|
|
||||||
TextRole = Qt::DisplayRole,
|
|
||||||
LongitudeRole,
|
|
||||||
LatitudeRole,
|
|
||||||
AssetRole,
|
|
||||||
AuthorRole,
|
|
||||||
};
|
|
||||||
Q_ENUM(Roles)
|
|
||||||
|
|
||||||
explicit CommonRoomsModel(QObject *parent = nullptr);
|
|
||||||
|
|
||||||
[[nodiscard]] NeoChatConnection *connection() const;
|
|
||||||
void setConnection(NeoChatConnection *connection);
|
|
||||||
|
|
||||||
[[nodiscard]] QString userId() const;
|
|
||||||
void setUserId(const QString &userId);
|
|
||||||
|
|
||||||
[[nodiscard]] QVariant data(const QModelIndex &index, int roleName) const override;
|
|
||||||
[[nodiscard]] Q_INVOKABLE int rowCount(const QModelIndex &parent = {}) const override;
|
|
||||||
|
|
||||||
Q_SIGNALS:
|
|
||||||
void connectionChanged();
|
|
||||||
void userIdChanged();
|
|
||||||
void countChanged();
|
|
||||||
|
|
||||||
private:
|
|
||||||
void reload();
|
|
||||||
|
|
||||||
QPointer<NeoChatConnection> m_connection;
|
|
||||||
QString m_userId;
|
|
||||||
QList<QString> m_commonRooms;
|
|
||||||
};
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: 2025 Joshua Goins <josh@redstrate.com
|
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
import QtQuick
|
|
||||||
|
|
||||||
import org.kde.neochat
|
|
||||||
|
|
||||||
Item {
|
|
||||||
required property NeoChatConnection connection
|
|
||||||
}
|
|
||||||
@@ -1,183 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: 2023 Tobias Fella <tobias.fella@kde.org>
|
|
||||||
// SPDX-FileCopyrightText: 2025 Joshua Goins <josh@redstrate.com>
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Controls as QQC2
|
|
||||||
import QtQuick.Layouts
|
|
||||||
|
|
||||||
import org.kde.kirigami as Kirigami
|
|
||||||
import org.kde.kirigamiaddons.components as KirigamiComponents
|
|
||||||
import org.kde.kirigamiaddons.formcard as FormCard
|
|
||||||
|
|
||||||
import org.kde.neochat
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
required property NeoChatRoom currentRoom
|
|
||||||
readonly property var invitingMember: currentRoom.qmlSafeMember(currentRoom.invitingUserId)
|
|
||||||
readonly property string inviteTimestamp: root.currentRoom.inviteTimestamp.toLocaleString(Qt.locale(), Locale.ShortFormat)
|
|
||||||
|
|
||||||
spacing: Kirigami.Units.smallSpacing
|
|
||||||
|
|
||||||
Item {
|
|
||||||
Layout.fillHeight: true
|
|
||||||
}
|
|
||||||
|
|
||||||
KirigamiComponents.Avatar {
|
|
||||||
id: avatar
|
|
||||||
Layout.preferredWidth: Kirigami.Units.iconSizes.huge
|
|
||||||
Layout.preferredHeight: Kirigami.Units.iconSizes.huge
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
name: root.invitingMember.displayName
|
|
||||||
source: NeoChatConfig.hideImages ? undefined : root.invitingMember.avatarUrl
|
|
||||||
color: root.invitingMember.color
|
|
||||||
}
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
active: !root.currentRoom.isDirectChat()
|
|
||||||
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
sourceComponent: ColumnLayout {
|
|
||||||
spacing: Kirigami.Units.smallSpacing
|
|
||||||
|
|
||||||
QQC2.Label {
|
|
||||||
text: i18nc("@info:label 'Username' has invited you to this room at 'timestamp'.", "%1 has invited you to this room at %2.", root.invitingMember.displayName, root.inviteTimestamp)
|
|
||||||
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
Kirigami.Heading {
|
|
||||||
text: root.currentRoom.displayName
|
|
||||||
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Loader {
|
|
||||||
active: root.currentRoom.isDirectChat()
|
|
||||||
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
sourceComponent: ColumnLayout {
|
|
||||||
spacing: Kirigami.Units.smallSpacing
|
|
||||||
|
|
||||||
Kirigami.Heading {
|
|
||||||
text: root.currentRoom.displayName
|
|
||||||
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
}
|
|
||||||
|
|
||||||
QQC2.Label {
|
|
||||||
text: i18nc("@info:label This user invited you to chat at 'timestamp'", "This user invited you to chat at %1.", root.inviteTimestamp)
|
|
||||||
|
|
||||||
Layout.alignment: Qt.AlignHCenter
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FormCard.FormCard {
|
|
||||||
Layout.topMargin: Kirigami.Units.largeSpacing * 4
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
FormCard.FormButtonDelegate {
|
|
||||||
id: acceptInviteDelegate
|
|
||||||
|
|
||||||
icon.name: "dialog-ok-symbolic"
|
|
||||||
text: i18nc("@action:button Accept this invite", "Accept Invite")
|
|
||||||
focus: true
|
|
||||||
|
|
||||||
onClicked: root.currentRoom.acceptInvitation()
|
|
||||||
}
|
|
||||||
|
|
||||||
FormCard.FormDelegateSeparator {
|
|
||||||
above: acceptInviteDelegate
|
|
||||||
below: rejectInviteDelegate
|
|
||||||
}
|
|
||||||
|
|
||||||
FormCard.FormButtonDelegate {
|
|
||||||
id: rejectInviteDelegate
|
|
||||||
|
|
||||||
icon.name: "dialog-cancel-symbolic"
|
|
||||||
text: i18nc("@action:button Reject this invite", "Reject Invite")
|
|
||||||
|
|
||||||
onClicked: root.currentRoom.forget()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
FormCard.FormCard {
|
|
||||||
id: blockUserCard
|
|
||||||
|
|
||||||
Layout.topMargin: Kirigami.Units.largeSpacing
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
FormCard.FormButtonDelegate {
|
|
||||||
icon.name: "list-remove-symbolic"
|
|
||||||
text: i18nc("@action:button Block the user", "Block %1", root.invitingMember.displayName)
|
|
||||||
|
|
||||||
onClicked: {
|
|
||||||
root.currentRoom.forget()
|
|
||||||
root.currentRoom.connection.addToIgnoredUsers(root.currentRoom.invitingUserId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
visible: root.currentRoom.connection.canCheckMutualRooms
|
|
||||||
spacing: 0
|
|
||||||
|
|
||||||
Layout.topMargin: Kirigami.Units.largeSpacing * 2
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
Item {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
}
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
spacing: Kirigami.Units.smallSpacing
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
Item {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
}
|
|
||||||
|
|
||||||
Kirigami.Icon {
|
|
||||||
source: "help-hint-symbolic"
|
|
||||||
color: Kirigami.Theme.disabledTextColor
|
|
||||||
|
|
||||||
Layout.preferredWidth: Kirigami.Units.iconSizes.small
|
|
||||||
Layout.preferredHeight: Kirigami.Units.iconSizes.small
|
|
||||||
}
|
|
||||||
|
|
||||||
QQC2.Label {
|
|
||||||
color: Kirigami.Theme.disabledTextColor
|
|
||||||
text: i18nc("@info:label", "You can reject invitations from unknown users under Security settings.")
|
|
||||||
wrapMode: Text.WordWrap
|
|
||||||
|
|
||||||
// + 5 to prevent it from wrapping unnecessarily
|
|
||||||
Layout.maximumWidth: implicitWidth + 5
|
|
||||||
Layout.fillWidth: true
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Item {
|
|
||||||
Layout.fillHeight: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,156 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: 2025 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.Controls as QQC2
|
|
||||||
import QtQuick.Layouts
|
|
||||||
|
|
||||||
import org.kde.kirigami as Kirigami
|
|
||||||
|
|
||||||
import org.kde.kirigamiaddons.formcard as FormCard
|
|
||||||
import org.kde.kirigamiaddons.labs.components as KirigamiComponents
|
|
||||||
import org.kde.kirigamiaddons.delegates as Delegates
|
|
||||||
|
|
||||||
import Quotient
|
|
||||||
|
|
||||||
import org.kde.neochat
|
|
||||||
|
|
||||||
Kirigami.Dialog {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
required property NeoChatRoom room
|
|
||||||
|
|
||||||
standardButtons: Kirigami.Dialog.Cancel
|
|
||||||
|
|
||||||
customFooterActions: [
|
|
||||||
Kirigami.Action {
|
|
||||||
enabled: optionModel.allValuesSet && questionTextField.text.length > 0
|
|
||||||
text: i18nc("@action:button", "Send")
|
|
||||||
icon.name: "document-send"
|
|
||||||
onTriggered: {
|
|
||||||
root.room.postPoll(pollTypeCombo.currentValue, questionTextField.text, optionModel.values())
|
|
||||||
root.close()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
width: Math.min(applicationWindow().width, Kirigami.Units.gridUnit * 24)
|
|
||||||
title: i18nc("@title: create new poll in the room", "Create Poll")
|
|
||||||
|
|
||||||
contentItem: ColumnLayout {
|
|
||||||
spacing: 0
|
|
||||||
|
|
||||||
FormCard.FormComboBoxDelegate {
|
|
||||||
id: pollTypeCombo
|
|
||||||
|
|
||||||
text: i18n("Poll type:")
|
|
||||||
currentIndex: 0
|
|
||||||
textRole: "text"
|
|
||||||
valueRole: "value"
|
|
||||||
model: [
|
|
||||||
{ value: PollKind.Disclosed, text: i18n("Open poll") },
|
|
||||||
{ value: PollKind.Undisclosed, text: i18n("Closed poll") }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
FormCard.FormTextDelegate {
|
|
||||||
verticalPadding: 0
|
|
||||||
text: pollTypeCombo.currentValue == 0 ? i18n("Voters can see the result as soon as they have voted") : i18n("Results are revealed only after the poll has closed")
|
|
||||||
}
|
|
||||||
FormCard.FormTextFieldDelegate {
|
|
||||||
id: questionTextField
|
|
||||||
label: i18n("Question:")
|
|
||||||
}
|
|
||||||
Repeater {
|
|
||||||
id: optionRepeater
|
|
||||||
|
|
||||||
model: ListModel {
|
|
||||||
id: optionModel
|
|
||||||
|
|
||||||
readonly property bool allValuesSet: {
|
|
||||||
for( var i = 0; i < optionModel.rowCount(); i++ ) {
|
|
||||||
if (optionModel.get(i).optionText.length <= 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
ListElement {
|
|
||||||
optionText: ""
|
|
||||||
}
|
|
||||||
ListElement {
|
|
||||||
optionText: ""
|
|
||||||
}
|
|
||||||
|
|
||||||
function values() {
|
|
||||||
let textValues = []
|
|
||||||
for( var i = 0; i < optionModel.rowCount(); i++ ) {
|
|
||||||
textValues.push(optionModel.get(i).optionText);
|
|
||||||
}
|
|
||||||
return textValues;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
delegate: FormCard.AbstractFormDelegate {
|
|
||||||
id: optionDelegate
|
|
||||||
|
|
||||||
required property int index
|
|
||||||
required property string optionText
|
|
||||||
|
|
||||||
contentItem: ColumnLayout {
|
|
||||||
QQC2.Label {
|
|
||||||
id: optionLabel
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
|
||||||
text: i18nc("As in first answer option to the poll", "Option %1:", optionDelegate.index + 1)
|
|
||||||
elide: Text.ElideRight
|
|
||||||
wrapMode: Text.Wrap
|
|
||||||
Accessible.ignored: true
|
|
||||||
}
|
|
||||||
RowLayout {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
QQC2.TextField {
|
|
||||||
id: textField
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Accessible.name: optionLabel.text
|
|
||||||
onTextChanged: {
|
|
||||||
optionModel.set(optionDelegate.index, {optionText: text})
|
|
||||||
optionModel.allValuesSetChanged()
|
|
||||||
}
|
|
||||||
placeholderText: i18n("Enter option")
|
|
||||||
}
|
|
||||||
QQC2.ToolButton {
|
|
||||||
display: QQC2.AbstractButton.IconOnly
|
|
||||||
action: Kirigami.Action {
|
|
||||||
id: removeOptionAction
|
|
||||||
text: i18nc("@action:button", "Remove option")
|
|
||||||
icon.name: "edit-delete-remove"
|
|
||||||
onTriggered: optionModel.remove(optionDelegate.index)
|
|
||||||
}
|
|
||||||
QQC2.ToolTip {
|
|
||||||
text: removeOptionAction.text
|
|
||||||
delay: Kirigami.Units.toolTipDelay
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
background: null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Delegates.RoundedItemDelegate {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
horizontalPadding: Kirigami.Units.largeSpacing * 2
|
|
||||||
leftInset: Kirigami.Units.largeSpacing + Kirigami.Units.smallSpacing
|
|
||||||
rightInset: Kirigami.Units.largeSpacing + Kirigami.Units.smallSpacing
|
|
||||||
|
|
||||||
highlighted: true
|
|
||||||
|
|
||||||
icon.name: "list-add"
|
|
||||||
text: i18nc("@action:button", "Add option")
|
|
||||||
|
|
||||||
onClicked: optionModel.append({optionText: ""})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: 2025 Joshua Goins <josh@redstrate.com>
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
|
||||||
|
|
||||||
import QtQuick
|
|
||||||
import QtQuick.Controls as QQC2
|
|
||||||
import QtQuick.Layouts
|
|
||||||
|
|
||||||
import org.kde.kirigami as Kirigami
|
|
||||||
import org.kde.kirigamiaddons.components as KirigamiComponents
|
|
||||||
|
|
||||||
import org.kde.neochat
|
|
||||||
import org.kde.neochat.settings
|
|
||||||
import org.kde.neochat.devtools
|
|
||||||
|
|
||||||
KirigamiComponents.ConvergentContextMenu {
|
|
||||||
id: root
|
|
||||||
|
|
||||||
required property Kirigami.ApplicationWindow window
|
|
||||||
required property var author
|
|
||||||
|
|
||||||
headerContentItem: RowLayout {
|
|
||||||
id: detailRow
|
|
||||||
|
|
||||||
spacing: Kirigami.Units.largeSpacing
|
|
||||||
|
|
||||||
KirigamiComponents.Avatar {
|
|
||||||
id: avatar
|
|
||||||
Layout.preferredWidth: Kirigami.Units.iconSizes.medium
|
|
||||||
Layout.preferredHeight: Kirigami.Units.iconSizes.medium
|
|
||||||
|
|
||||||
name: root.author.displayName
|
|
||||||
source: root.author.avatarUrl
|
|
||||||
color: root.author.color
|
|
||||||
}
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
|
|
||||||
spacing: 0
|
|
||||||
|
|
||||||
Kirigami.Heading {
|
|
||||||
level: 1
|
|
||||||
Layout.fillWidth: true
|
|
||||||
font.bold: true
|
|
||||||
|
|
||||||
elide: Text.ElideRight
|
|
||||||
wrapMode: Text.NoWrap
|
|
||||||
text: root.author.displayName
|
|
||||||
textFormat: Text.PlainText
|
|
||||||
}
|
|
||||||
|
|
||||||
QQC2.Label {
|
|
||||||
id: idLabel
|
|
||||||
textFormat: TextEdit.PlainText
|
|
||||||
text: root.author.id
|
|
||||||
elide: Qt.ElideRight
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QQC2.Action {
|
|
||||||
text: i18nc("@action:button", "Open Profile")
|
|
||||||
icon.name: "im-user-symbolic"
|
|
||||||
onTriggered: RoomManager.resolveResource(root.author.uri)
|
|
||||||
}
|
|
||||||
|
|
||||||
QQC2.Action {
|
|
||||||
text: i18nc("@action:button", "Mention")
|
|
||||||
icon.name: "username-copy-symbolic"
|
|
||||||
onTriggered: {
|
|
||||||
RoomManager.currentRoom.mainCache.mentionAdded(root.author.id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: 2025 Ritchie Frodomar <ritchie@kde.org>
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
|
||||||
|
|
||||||
#include "texttospeechhelper.h"
|
|
||||||
|
|
||||||
void TextToSpeechHelper::speak(const QString &textToSpeak)
|
|
||||||
{
|
|
||||||
if (!m_speech) {
|
|
||||||
m_speech = new QTextToSpeech();
|
|
||||||
}
|
|
||||||
|
|
||||||
m_speech->say(textToSpeak);
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "moc_texttospeechhelper.cpp"
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
// SPDX-FileCopyrightText: 2025 Ritchie Frodomar <ritchie@kde.org>
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <QObject>
|
|
||||||
#include <QQmlEngine>
|
|
||||||
#include <QtTextToSpeech>
|
|
||||||
|
|
||||||
class TextToSpeechHelper : public QObject
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
QML_ELEMENT
|
|
||||||
QML_SINGLETON
|
|
||||||
|
|
||||||
public:
|
|
||||||
Q_INVOKABLE void speak(const QString &textToSpeak);
|
|
||||||
|
|
||||||
private:
|
|
||||||
QTextToSpeech *m_speech = nullptr;
|
|
||||||
};
|
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
# SPDX-FileCopyrightText: 2024 Tobias Fella <tobias.fella@kde.org>
|
# SPDX-FileCopyrightText: 2024 Tobias Fella <tobias.fella@kde.org>
|
||||||
# SPDX-License-Identifier: BSD-2-Clause
|
# SPDX-License-Identifier: BSD-2-Clause
|
||||||
|
|
||||||
qt_add_library(Chatbar STATIC)
|
qt_add_library(chatbar STATIC)
|
||||||
ecm_add_qml_module(Chatbar GENERATE_PLUGIN_SOURCE
|
ecm_add_qml_module(chatbar GENERATE_PLUGIN_SOURCE
|
||||||
URI org.kde.neochat.chatbar
|
URI org.kde.neochat.chatbar
|
||||||
OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/src/org/kde/neochat/chatbar
|
OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/src/org/kde/neochat/chatbar
|
||||||
QML_FILES
|
QML_FILES
|
||||||
@@ -15,5 +15,4 @@ ecm_add_qml_module(Chatbar GENERATE_PLUGIN_SOURCE
|
|||||||
EmojiPicker.qml
|
EmojiPicker.qml
|
||||||
EmojiDialog.qml
|
EmojiDialog.qml
|
||||||
EmojiTonesPicker.qml
|
EmojiTonesPicker.qml
|
||||||
ImageEditorPage.qml
|
|
||||||
)
|
)
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user