Compare commits
1261 Commits
v23.03.90
...
work/tobia
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
666cd3c81f | ||
|
|
dc5366e924 | ||
|
|
f21b3bb0e4 | ||
|
|
4ebcc36fb3 | ||
|
|
292cfb0d3d | ||
|
|
1b59917f16 | ||
|
|
fcf64a7e1b | ||
|
|
b598584aea | ||
|
|
0ebcacce69 | ||
|
|
33c38288a3 | ||
|
|
f00e3ded45 | ||
|
|
250483fbe7 | ||
|
|
755a060e12 | ||
|
|
6d3839dd42 | ||
|
|
15084459bb | ||
|
|
7150445f8e | ||
|
|
b02bdd22dd | ||
|
|
8755cd9d61 | ||
|
|
2c4c07dc81 | ||
|
|
645771c03d | ||
|
|
b2af69fd92 | ||
|
|
ca57732871 | ||
|
|
cd9e98f24b | ||
|
|
136da65381 | ||
|
|
b909cb2db8 | ||
|
|
3a4b531edf | ||
|
|
413453dd85 | ||
|
|
fe52d26f05 | ||
|
|
6029c0d0b3 | ||
|
|
12bfe9d6ca | ||
|
|
dd910f2856 | ||
|
|
b4e0d9e996 | ||
|
|
d3f691548c | ||
|
|
367131d64c | ||
|
|
2895b7bc21 | ||
|
|
f9cdd55a4d | ||
|
|
1854373dd6 | ||
|
|
00a621a5f7 | ||
|
|
f047bd797e | ||
|
|
777f8b4276 | ||
|
|
0992b7fc93 | ||
|
|
b7d6208869 | ||
|
|
da4ce27168 | ||
|
|
4746401bec | ||
|
|
79cf399bf5 | ||
|
|
563323f241 | ||
|
|
e2048dfa1c | ||
|
|
c986c63b84 | ||
|
|
0b3426a9b2 | ||
|
|
173e507ebf | ||
|
|
fb3b1490a9 | ||
|
|
48502480df | ||
|
|
efb3b8f38c | ||
|
|
f185b1773c | ||
|
|
95fff4c9f7 | ||
|
|
27662f9a4a | ||
|
|
f9f678a801 | ||
|
|
8e07e7553a | ||
|
|
bb566e3c7b | ||
|
|
35c68a6de1 | ||
|
|
7fd8394253 | ||
|
|
c54a447caf | ||
|
|
61b009422d | ||
|
|
5a8b0184ea | ||
|
|
f48c2a21d9 | ||
|
|
538cfbee8d | ||
|
|
7666f1c362 | ||
|
|
4b5d828bf8 | ||
|
|
4bd160cceb | ||
|
|
5f56fc1156 | ||
|
|
72a2a74395 | ||
|
|
f6a5cc7c25 | ||
|
|
80f3bd64b6 | ||
|
|
1f69a96766 | ||
|
|
f963e06983 | ||
|
|
e6980e2370 | ||
|
|
8e8105d04d | ||
|
|
21d9e69712 | ||
|
|
e0783a3c6e | ||
|
|
3b9337d2a8 | ||
|
|
85cda8ffa7 | ||
|
|
f1efc1f17d | ||
|
|
0486fa61cd | ||
|
|
2247a2a7af | ||
|
|
08a0fbfd6b | ||
|
|
898b993b94 | ||
|
|
77e366b179 | ||
|
|
981edc9cf7 | ||
|
|
d45aa14348 | ||
|
|
4926488d49 | ||
|
|
dcc1935150 | ||
|
|
55364a8eb8 | ||
|
|
70bb06715f | ||
|
|
ec4aa73e37 | ||
|
|
c1d122a717 | ||
|
|
f75c194e7c | ||
|
|
ecf93de006 | ||
|
|
7feb02c7d8 | ||
|
|
0764fe0dd9 | ||
|
|
50a7138633 | ||
|
|
96a477f91c | ||
|
|
5a6b0f756d | ||
|
|
dbbf975f7a | ||
|
|
e06c2d2f93 | ||
|
|
5dea17b616 | ||
|
|
63b6d7ebe0 | ||
|
|
652106e6a1 | ||
|
|
3e158b3e60 | ||
|
|
b9ec33dd94 | ||
|
|
69bd1202ba | ||
|
|
f75c09e130 | ||
|
|
683d216f44 | ||
|
|
c10bcf1764 | ||
|
|
9e2bf0da26 | ||
|
|
51f7de117d | ||
|
|
f361f4e2d8 | ||
|
|
acfb5ab834 | ||
|
|
8bc4500ce1 | ||
|
|
b96d3dde46 | ||
|
|
fad381c36f | ||
|
|
ad083f64b1 | ||
|
|
5c78b23cc2 | ||
|
|
2202063641 | ||
|
|
5be15ffa6a | ||
|
|
a0bafe53a0 | ||
|
|
1a39ce9585 | ||
|
|
4a809d57f7 | ||
|
|
c01e42c972 | ||
|
|
6c56f7f4ef | ||
|
|
6d8d5a82c2 | ||
|
|
daa27b0333 | ||
|
|
f6edf0e4cc | ||
|
|
356e8eefe0 | ||
|
|
7ad362225f | ||
|
|
d623a8c826 | ||
|
|
b3f0d110d9 | ||
|
|
612b5d7f47 | ||
|
|
7e9f206348 | ||
|
|
d5f4a3dd64 | ||
|
|
e807ad9908 | ||
|
|
2d8ad834a7 | ||
|
|
d82dfc7a5b | ||
|
|
1e1e54d4bd | ||
|
|
9043b1c7a1 | ||
|
|
0739f4c661 | ||
|
|
29321aeaf3 | ||
|
|
9fe44515a7 | ||
|
|
4c3d7ab011 | ||
|
|
d02eee6daa | ||
|
|
a613baa148 | ||
|
|
4e141e05f0 | ||
|
|
134f1d2ae5 | ||
|
|
9ec3e5b2cc | ||
|
|
15d066b3ed | ||
|
|
7694f6c464 | ||
|
|
46da4f9777 | ||
|
|
44e0ef43ac | ||
|
|
5b79371c0a | ||
|
|
3caa5ad2ed | ||
|
|
a74d78439c | ||
|
|
0b82aeb5cc | ||
|
|
bc7aa4e272 | ||
|
|
d1f421994d | ||
|
|
b043cbedc9 | ||
|
|
5a469ed126 | ||
|
|
8d209a5424 | ||
|
|
a0937bdcac | ||
|
|
df4eba0191 | ||
|
|
9f83cf1c52 | ||
|
|
ddc0bfe786 | ||
|
|
09796b6e0b | ||
|
|
73c34c68b7 | ||
|
|
76ab96ef3e | ||
|
|
5a580dd16c | ||
|
|
918887525b | ||
|
|
500ebbecbf | ||
|
|
8062dface6 | ||
|
|
8d717b78ac | ||
|
|
4751ac6acc | ||
|
|
1d8ffb22ee | ||
|
|
a035d6542d | ||
|
|
d7230022f6 | ||
|
|
d25340bc31 | ||
|
|
c396024a26 | ||
|
|
65b94890ab | ||
|
|
682004d9a2 | ||
|
|
decf797180 | ||
|
|
552b6dd913 | ||
|
|
e6358eca16 | ||
|
|
f3bacad460 | ||
|
|
862f4363a9 | ||
|
|
9b3a3dc562 | ||
|
|
c2641a5fc2 | ||
|
|
1213ba5916 | ||
|
|
0521ff2c4d | ||
|
|
65c892787e | ||
|
|
7541c192bf | ||
|
|
c692d7e679 | ||
|
|
44a9a491af | ||
|
|
f8cae7c143 | ||
|
|
4f2b559126 | ||
|
|
46fd288a95 | ||
|
|
3a1cac6c99 | ||
|
|
225092a193 | ||
|
|
2fcb17621c | ||
|
|
69e3ee862f | ||
|
|
47c12cb582 | ||
|
|
94cf75af68 | ||
|
|
259b9884c7 | ||
|
|
2980dc49e4 | ||
|
|
5e12f50899 | ||
|
|
79940f707f | ||
|
|
e7024a270c | ||
|
|
1a561f6649 | ||
|
|
2cbb6ed65c | ||
|
|
ab4639926a | ||
|
|
89b6c54f25 | ||
|
|
27c9c62564 | ||
|
|
bb8ffb02d1 | ||
|
|
201aa82c04 | ||
|
|
704430db7a | ||
|
|
dcbbbd9296 | ||
|
|
410258c478 | ||
|
|
6baf2e4888 | ||
|
|
dd6eaac556 | ||
|
|
840903128c | ||
|
|
68f0ca96da | ||
|
|
faf7af06fe | ||
|
|
4ef67c3e0d | ||
|
|
5efd17d370 | ||
|
|
0dbef58ff2 | ||
|
|
6a3df8baf4 | ||
|
|
2fc973f218 | ||
|
|
7d16999c44 | ||
|
|
f9ba31f2dc | ||
|
|
d4ad773ff1 | ||
|
|
822a4dc500 | ||
|
|
bfd1d431c1 | ||
|
|
94bf2481f0 | ||
|
|
5c32520c35 | ||
|
|
de47597f6e | ||
|
|
7780a72888 | ||
|
|
1f8c07fedf | ||
|
|
877575b4d3 | ||
|
|
1181df4db2 | ||
|
|
5be2113b32 | ||
|
|
7ad7af56e8 | ||
|
|
d3148f8c8b | ||
|
|
100f595026 | ||
|
|
15ba6d58e2 | ||
|
|
61ad892732 | ||
|
|
2a3e1dfcd7 | ||
|
|
d1dc6fc4ed | ||
|
|
6dc30a9ca7 | ||
|
|
ae0c5ffaef | ||
|
|
fc546d4a43 | ||
|
|
96e62e3ebe | ||
|
|
d979cd2fbc | ||
|
|
22298181cb | ||
|
|
1312fde470 | ||
|
|
7fe2feb1e4 | ||
|
|
67fb5d0824 | ||
|
|
359114bd3d | ||
|
|
3db9f1198b | ||
|
|
2435a6b953 | ||
|
|
e6c8b3fa4b | ||
|
|
2d55dca508 | ||
|
|
bbb0bc3092 | ||
|
|
4065aa6a2e | ||
|
|
5942eac5ed | ||
|
|
85c2b7dada | ||
|
|
86ef921cdb | ||
|
|
aab69c5bae | ||
|
|
624578ec77 | ||
|
|
197ff984fd | ||
|
|
a26337d5f4 | ||
|
|
31b4eefadd | ||
|
|
b8e592f8ba | ||
|
|
555d23863e | ||
|
|
ffa2d5dc0e | ||
|
|
9987edbaf2 | ||
|
|
d90298392d | ||
|
|
600dbd0603 | ||
|
|
2179e2cc35 | ||
|
|
8119ea3ccb | ||
|
|
3fc125a798 | ||
|
|
99f6778df4 | ||
|
|
f7bd24db34 | ||
|
|
41c2f9c4d5 | ||
|
|
56d5f3036b | ||
|
|
21bb7dce21 | ||
|
|
11081719a7 | ||
|
|
980de7d85d | ||
|
|
7735313b0c | ||
|
|
1a3055df86 | ||
|
|
84cad630cd | ||
|
|
0beb5df08d | ||
|
|
4ef44b8e93 | ||
|
|
59153be006 | ||
|
|
50be96f762 | ||
|
|
819d88e18c | ||
|
|
dbbad2cf13 | ||
|
|
08b84c6592 | ||
|
|
b8abf0540d | ||
|
|
7f9e709559 | ||
|
|
c4f6abee9d | ||
|
|
1a4947b98a | ||
|
|
6ba2b715c3 | ||
|
|
e9e1e223f7 | ||
|
|
006da1fb16 | ||
|
|
3aff1795c8 | ||
|
|
576b1f928f | ||
|
|
fc3ab50701 | ||
|
|
e7fa3ad524 | ||
|
|
5adffddbd8 | ||
|
|
1d95d5aa15 | ||
|
|
dabd6291a5 | ||
|
|
0e55c3b38f | ||
|
|
ff4cf86ea5 | ||
|
|
f4d5ccbf12 | ||
|
|
192601d358 | ||
|
|
d7c432119e | ||
|
|
eddb2b73c2 | ||
|
|
0c60bfdb83 | ||
|
|
2bfb2fa1f9 | ||
|
|
d1aac971bf | ||
|
|
284cadf305 | ||
|
|
4697b7fcf1 | ||
|
|
9f356912c9 | ||
|
|
1cf891f845 | ||
|
|
52e2d636b9 | ||
|
|
dc6b539ddf | ||
|
|
e3cf85aa8c | ||
|
|
2065eb6684 | ||
|
|
9cac2a8abd | ||
|
|
feb87e6f70 | ||
|
|
a0057b8a49 | ||
|
|
dbb0269354 | ||
|
|
7fdb617b33 | ||
|
|
d798b0dec9 | ||
|
|
95cf23eb5b | ||
|
|
7e3db20229 | ||
|
|
12689babfb | ||
|
|
211407da44 | ||
|
|
400a84e48d | ||
|
|
7a45640e5e | ||
|
|
8af20885ab | ||
|
|
4033f07272 | ||
|
|
5df4fa297d | ||
|
|
33c5b418d2 | ||
|
|
69d378a17b | ||
|
|
f1b1b8ce53 | ||
|
|
526d4748e0 | ||
|
|
c5f93adbf4 | ||
|
|
61630cbe90 | ||
|
|
8c435e9d6d | ||
|
|
57978b1a6e | ||
|
|
f3c4d9449a | ||
|
|
9b37777f20 | ||
|
|
d6d6c161db | ||
|
|
772bca5ba6 | ||
|
|
036a60a095 | ||
|
|
b3315e1ed4 | ||
|
|
d300e9cf52 | ||
|
|
1f4bcd150f | ||
|
|
9ad8894983 | ||
|
|
9e63ca5eb7 | ||
|
|
ade66242bb | ||
|
|
2c6932b4cb | ||
|
|
5cce9e7205 | ||
|
|
7dd3ad9548 | ||
|
|
f690b76efa | ||
|
|
87b8d6710e | ||
|
|
965b890346 | ||
|
|
02b4e5cc70 | ||
|
|
410add04fb | ||
|
|
b575b1e700 | ||
|
|
5828ee1ada | ||
|
|
a64c80109e | ||
|
|
de47f7f2fa | ||
|
|
19adc7b9e5 | ||
|
|
23f60a59fe | ||
|
|
946ba2e56d | ||
|
|
9dcb7b49fa | ||
|
|
52f5901642 | ||
|
|
d4b4a7e1ff | ||
|
|
4449678b74 | ||
|
|
19e197e0ec | ||
|
|
cfc5202645 | ||
|
|
9b80d9e7aa | ||
|
|
dc409387bd | ||
|
|
1e73a7bda4 | ||
|
|
ef1d62d45c | ||
|
|
c2d82750b1 | ||
|
|
c97d276b36 | ||
|
|
681a0b1e93 | ||
|
|
39556f45ab | ||
|
|
3c7774800a | ||
|
|
bc7530eaa1 | ||
|
|
82d11f79d6 | ||
|
|
25d0368d41 | ||
|
|
83b7e7d121 | ||
|
|
26fd26f9fd | ||
|
|
0029567c3a | ||
|
|
c7614caf41 | ||
|
|
6571dbe554 | ||
|
|
b3a29068cc | ||
|
|
5adda55a85 | ||
|
|
d56f0d6086 | ||
|
|
60772be391 | ||
|
|
27f1679741 | ||
|
|
838596c3ae | ||
|
|
a57744891a | ||
|
|
f5417a6227 | ||
|
|
ac6f9ea219 | ||
|
|
4b49559d39 | ||
|
|
baa33f1843 | ||
|
|
dae5718c6c | ||
|
|
60260cff3b | ||
|
|
2df9a26cdc | ||
|
|
b16cd12b33 | ||
|
|
6a3b22ef2d | ||
|
|
b28a85ff05 | ||
|
|
e480299563 | ||
|
|
fe70e2773f | ||
|
|
e78ea4721a | ||
|
|
1699dcf0c4 | ||
|
|
9d6aef6c2b | ||
|
|
a9c2428498 | ||
|
|
0730f15e2b | ||
|
|
136856f3c3 | ||
|
|
763b6af076 | ||
|
|
ac231320a3 | ||
|
|
87aee162f1 | ||
|
|
0899db31af | ||
|
|
b4198bc13b | ||
|
|
c6bfe73d26 | ||
|
|
d490dffa36 | ||
|
|
43b2b71b73 | ||
|
|
39a51d1f35 | ||
|
|
2eb26ffbb3 | ||
|
|
87ef55215f | ||
|
|
f6186aad2e | ||
|
|
2251edbf86 | ||
|
|
1c55649740 | ||
|
|
aa0b6613de | ||
|
|
f948e813b6 | ||
|
|
b5c6411aad | ||
|
|
b1daa76d9f | ||
|
|
7180fa022b | ||
|
|
17bc08270d | ||
|
|
d4cb27eca4 | ||
|
|
541350e678 | ||
|
|
843deefaf8 | ||
|
|
070d579bc2 | ||
|
|
add283c9fb | ||
|
|
fe4230b5fd | ||
|
|
e8f40d98de | ||
|
|
eba62103a4 | ||
|
|
925393deab | ||
|
|
abe881caf7 | ||
|
|
237a3c9dfb | ||
|
|
9715440854 | ||
|
|
ecdad9f965 | ||
|
|
08711fc927 | ||
|
|
e44cd405b7 | ||
|
|
8945e004e2 | ||
|
|
c04d8d6f59 | ||
|
|
58a73c0208 | ||
|
|
852110debd | ||
|
|
6b71d3c78d | ||
|
|
f3a0adee39 | ||
|
|
6e7b6c9ce0 | ||
|
|
f67cd7deb5 | ||
|
|
931b4b1f9a | ||
|
|
167ed4eca3 | ||
|
|
7d5b2c1b6a | ||
|
|
be7b1e49b4 | ||
|
|
957419070a | ||
|
|
f22107c8ab | ||
|
|
3a4f71de7f | ||
|
|
4ed4f3f628 | ||
|
|
ba24f1272f | ||
|
|
443661d113 | ||
|
|
091c8806db | ||
|
|
041c719a2e | ||
|
|
83a9bfa974 | ||
|
|
e35a6f7257 | ||
|
|
6d56251f6f | ||
|
|
486fae9c10 | ||
|
|
1c26d9b811 | ||
|
|
6d7ae99c94 | ||
|
|
442a343097 | ||
|
|
f0a7216b4b | ||
|
|
e926b22524 | ||
|
|
69087c2117 | ||
|
|
4d2104b54b | ||
|
|
3f85a359e1 | ||
|
|
3084913940 | ||
|
|
e2670cd6ba | ||
|
|
1b6fc3dde5 | ||
|
|
69a19effa2 | ||
|
|
4abdf1f920 | ||
|
|
0b1a6a3f6b | ||
|
|
45544c79bb | ||
|
|
c4dddf6e02 | ||
|
|
7f3f628b7d | ||
|
|
6bf552398e | ||
|
|
78f676d71a | ||
|
|
33c0cae64c | ||
|
|
14cdd096cf | ||
|
|
c04ddfde26 | ||
|
|
ec4c156a8c | ||
|
|
17ff5b4c56 | ||
|
|
0e2275e415 | ||
|
|
12fd1875b5 | ||
|
|
10e50804c7 | ||
|
|
c01c638a49 | ||
|
|
399151eb1d | ||
|
|
5e80715898 | ||
|
|
6439fa48f9 | ||
|
|
823f3cdd4e | ||
|
|
f542d0b9fd | ||
|
|
a43990559b | ||
|
|
feb2dbc9fb | ||
|
|
f299d5a245 | ||
|
|
d69b8fbf8c | ||
|
|
234e5c49c4 | ||
|
|
cee72b6d48 | ||
|
|
539fdcaf2e | ||
|
|
32b3861c3e | ||
|
|
f1076a5ced | ||
|
|
bf8f5705d0 | ||
|
|
2656a93ee7 | ||
|
|
cbab810a2e | ||
|
|
e78dfaec34 | ||
|
|
3cfa773820 | ||
|
|
94c0e8b6cd | ||
|
|
35b1f24cb7 | ||
|
|
de3072125e | ||
|
|
f7d2ffac66 | ||
|
|
ff0990bb7c | ||
|
|
8285961c42 | ||
|
|
cd39d5b129 | ||
|
|
83b3fefbf5 | ||
|
|
3718bd716a | ||
|
|
a18257ee17 | ||
|
|
def46d90a8 | ||
|
|
8afd7b2892 | ||
|
|
deb11367cb | ||
|
|
ffd1b06a82 | ||
|
|
2597f0aec9 | ||
|
|
33ca72efd9 | ||
|
|
2fbf659eb4 | ||
|
|
763198b2c3 | ||
|
|
50551541ed | ||
|
|
323cd4962e | ||
|
|
b2f592afeb | ||
|
|
f7f98c43e2 | ||
|
|
06134f96eb | ||
|
|
bb62849a19 | ||
|
|
d05385caed | ||
|
|
209ca747b5 | ||
|
|
2c6ab498ac | ||
|
|
597633f824 | ||
|
|
65da416b8e | ||
|
|
c528929b30 | ||
|
|
8650ce1755 | ||
|
|
8936b23da9 | ||
|
|
cf72fbea2e | ||
|
|
0d5929b4bc | ||
|
|
d43cc9a044 | ||
|
|
682e3967ba | ||
|
|
ceebee3a56 | ||
|
|
52ab052aef | ||
|
|
e6a2b2d125 | ||
|
|
92dadc2cc9 | ||
|
|
6ca9380a51 | ||
|
|
51d41ab5bf | ||
|
|
f1047fa474 | ||
|
|
011b11681f | ||
|
|
8baeb236bc | ||
|
|
b9d173d0b5 | ||
|
|
3790955c56 | ||
|
|
199772a013 | ||
|
|
54cc3ac761 | ||
|
|
1675c14c92 | ||
|
|
56f5ef2611 | ||
|
|
7ba63eb680 | ||
|
|
ddd690f6d5 | ||
|
|
d9dc5f48bc | ||
|
|
a3b40a5e6d | ||
|
|
be71a4349b | ||
|
|
ede2707767 | ||
|
|
5871903529 | ||
|
|
87745c360d | ||
|
|
40d2eb5aba | ||
|
|
cfd9f36a97 | ||
|
|
48f7e06c01 | ||
|
|
43ecd188f1 | ||
|
|
063056bebd | ||
|
|
dfba655527 | ||
|
|
23178b6224 | ||
|
|
a9a6e31b8c | ||
|
|
0afd74d96a | ||
|
|
c5501f2b5d | ||
|
|
68602fc177 | ||
|
|
8ce5a57499 | ||
|
|
bf3c5708c7 | ||
|
|
8359c1fe90 | ||
|
|
774121ea8c | ||
|
|
370bbf8a4b | ||
|
|
4fd36fb221 | ||
|
|
167349b9d2 | ||
|
|
296aa9ddad | ||
|
|
94c1b67ec9 | ||
|
|
a9965acdd3 | ||
|
|
35313271a3 | ||
|
|
e40179f641 | ||
|
|
dacf3ff8a0 | ||
|
|
0274d70f71 | ||
|
|
0c19052f32 | ||
|
|
a3423e5724 | ||
|
|
e09f31f891 | ||
|
|
e05e0f5489 | ||
|
|
002961f638 | ||
|
|
e28419ef88 | ||
|
|
0e4df58fc9 | ||
|
|
21a55885b3 | ||
|
|
6a8ac8f6e5 | ||
|
|
9fcfad7058 | ||
|
|
cfcc1756dd | ||
|
|
e15bec2295 | ||
|
|
9071cf827f | ||
|
|
c7deaaba84 | ||
|
|
414035de8b | ||
|
|
442612d31d | ||
|
|
59164d3bb2 | ||
|
|
cc60dde62d | ||
|
|
cbed8148a3 | ||
|
|
50e8b9ebf6 | ||
|
|
f5ad2ad162 | ||
|
|
d11d6c74b3 | ||
|
|
63ed69a5d4 | ||
|
|
a8aa775575 | ||
|
|
6305359b3c | ||
|
|
7e859364af | ||
|
|
8abd0db012 | ||
|
|
dbc10685f0 | ||
|
|
96582a12bc | ||
|
|
0ac61854bd | ||
|
|
68298f038d | ||
|
|
405fd5841a | ||
|
|
5da9bba844 | ||
|
|
84373712ef | ||
|
|
50f4f96341 | ||
|
|
1b27b1a4e2 | ||
|
|
33811a4c49 | ||
|
|
43715486e5 | ||
|
|
5c72bd4ab7 | ||
|
|
092f1be99b | ||
|
|
550d55cb1a | ||
|
|
e9edb61245 | ||
|
|
89aae665b1 | ||
|
|
1e3c3dd1f4 | ||
|
|
6f4d2c0216 | ||
|
|
803cd2b4e4 | ||
|
|
9f3012061d | ||
|
|
c1604a9c4f | ||
|
|
3c7fcee244 | ||
|
|
d33a50a00d | ||
|
|
ed033a1c5e | ||
|
|
2b961703ae | ||
|
|
0539665779 | ||
|
|
df127b88e6 | ||
|
|
27c4b57f0f | ||
|
|
f875a23e83 | ||
|
|
7f5cfbf21c | ||
|
|
f7c7643c1c | ||
|
|
692edf52f1 | ||
|
|
e48cfaa41f | ||
|
|
ba116460d5 | ||
|
|
c71672dab3 | ||
|
|
932ef72311 | ||
|
|
7e53a2234f | ||
|
|
a0499e5140 | ||
|
|
093ef0a18c | ||
|
|
36bf862ab9 | ||
|
|
6d8c1d0780 | ||
|
|
7fe85066a4 | ||
|
|
1fefa228e6 | ||
|
|
4104e10d95 | ||
|
|
05f3c3ee0a | ||
|
|
0a1c489401 | ||
|
|
e53d63ad8b | ||
|
|
78541b32f0 | ||
|
|
3bd93996c0 | ||
|
|
61968aa475 | ||
|
|
24d0082048 | ||
|
|
2980af11b0 | ||
|
|
91d9406c38 | ||
|
|
280d1e38e2 | ||
|
|
7b520da4b4 | ||
|
|
419b4cea98 | ||
|
|
38824f30ac | ||
|
|
9c4d8ef823 | ||
|
|
fe3bf3a638 | ||
|
|
d678a446e2 | ||
|
|
6df60a39b0 | ||
|
|
6f9fa76ab7 | ||
|
|
6e8b0f001f | ||
|
|
0bfad95d8b | ||
|
|
1b43846196 | ||
|
|
4ea183b139 | ||
|
|
22fd24549b | ||
|
|
af793fb865 | ||
|
|
13414b5834 | ||
|
|
65a1df4a75 | ||
|
|
d15157703a | ||
|
|
2d21330a36 | ||
|
|
fbc4611d02 | ||
|
|
e257865b19 | ||
|
|
018154f555 | ||
|
|
80a5daa1f7 | ||
|
|
bf5ce049d9 | ||
|
|
58213ee3e6 | ||
|
|
2d1862a637 | ||
|
|
67453d9fb8 | ||
|
|
3ab04583ae | ||
|
|
794683b5d2 | ||
|
|
9f7f5409bd | ||
|
|
7d7b9d7ae0 | ||
|
|
c7c892c51c | ||
|
|
97903a7cb0 | ||
|
|
0c8f488ac4 | ||
|
|
88368cefaa | ||
|
|
ab4bb41979 | ||
|
|
c2398b19dc | ||
|
|
4b3dac025f | ||
|
|
9eeff06328 | ||
|
|
657a8291d0 | ||
|
|
bc4431462a | ||
|
|
fdd8a62873 | ||
|
|
c164228894 | ||
|
|
7d418f0883 | ||
|
|
e90aecbead | ||
|
|
221c27fbbe | ||
|
|
1907404124 | ||
|
|
81e953dd8c | ||
|
|
9311052e39 | ||
|
|
648fff20f2 | ||
|
|
980211f36a | ||
|
|
25e0e3fa8e | ||
|
|
403c1ed391 | ||
|
|
c2f76612cf | ||
|
|
2a651b8946 | ||
|
|
00c0d1c276 | ||
|
|
0162d91b60 | ||
|
|
5f41b7b4c1 | ||
|
|
d9691bac7c | ||
|
|
719b916837 | ||
|
|
f9514fe925 | ||
|
|
399b9e6944 | ||
|
|
00cf5c8a5b | ||
|
|
02f26424e2 | ||
|
|
3bd639775a | ||
|
|
163c1ef407 | ||
|
|
9997b1074a | ||
|
|
f52a25717b | ||
|
|
5746c24b73 | ||
|
|
dca1b22521 | ||
|
|
b15f1461d8 | ||
|
|
24fd7a0f5b | ||
|
|
0ac3932303 | ||
|
|
807a9ee779 | ||
|
|
4f32a168cd | ||
|
|
45d2da56c7 | ||
|
|
d794e26d62 | ||
|
|
42cc42642d | ||
|
|
ffd6205bd1 | ||
|
|
9ba6b2f0a5 | ||
|
|
f8d3e25f8e | ||
|
|
75cd77facb | ||
|
|
8546d76a54 | ||
|
|
00b7f68a03 | ||
|
|
b486cb905c | ||
|
|
cdd5c9f484 | ||
|
|
3e6c426397 | ||
|
|
847f41e1ad | ||
|
|
ed5bb270ff | ||
|
|
c8b4da2b96 | ||
|
|
ba5445e135 | ||
|
|
1cca39e105 | ||
|
|
dbf67b984e | ||
|
|
c9126cf38e | ||
|
|
13988da4fc | ||
|
|
0847839abc | ||
|
|
6b55e502a0 | ||
|
|
8f81629ac1 | ||
|
|
7f459cb90f | ||
|
|
420e195313 | ||
|
|
3263a69880 | ||
|
|
b060881f06 | ||
|
|
701e786c1f | ||
|
|
646c8ba8fe | ||
|
|
9b31fdea10 | ||
|
|
ce5dfdee16 | ||
|
|
918e805718 | ||
|
|
7debf47833 | ||
|
|
2c142c36e6 | ||
|
|
3279142498 | ||
|
|
0e08a1aa7e | ||
|
|
3855922ad2 | ||
|
|
89a094ce8f | ||
|
|
d4421aaecf | ||
|
|
80b451c27b | ||
|
|
32ff22ba89 | ||
|
|
b990e3fbcb | ||
|
|
8d1baab89f | ||
|
|
62ecbc8d6b | ||
|
|
0e1c7f8c47 | ||
|
|
c963966f1d | ||
|
|
8db2526153 | ||
|
|
7587a1a418 | ||
|
|
294812956a | ||
|
|
d01aac6fa3 | ||
|
|
5cda1ca3ce | ||
|
|
bf26a463e0 | ||
|
|
30180c1ac8 | ||
|
|
41c296061c | ||
|
|
461420af0a | ||
|
|
052a7ed571 | ||
|
|
98e86f887b | ||
|
|
63a17b5985 | ||
|
|
025b367a7e | ||
|
|
a8536b0634 | ||
|
|
0c43d3eeee | ||
|
|
bf1614256b | ||
|
|
99614d1b27 | ||
|
|
e1e57ef27a | ||
|
|
6d45d126f8 | ||
|
|
732b43cbd6 | ||
|
|
a5da17b000 | ||
|
|
10a294f99e | ||
|
|
882a0d4901 | ||
|
|
506d31f53f | ||
|
|
110f007b41 | ||
|
|
a90943d9ac | ||
|
|
cbe7d8c2c2 | ||
|
|
ae4943dd71 | ||
|
|
7bd84bf51e | ||
|
|
a6ce44eb24 | ||
|
|
b1c42c3d3d | ||
|
|
213aaf3ac4 | ||
|
|
c55b40c9c6 | ||
|
|
81928d8b93 | ||
|
|
b7bddba053 | ||
|
|
307a9370db | ||
|
|
2f65cbeb36 | ||
|
|
e0c0b1f0e8 | ||
|
|
74f767aa82 | ||
|
|
7176dd4476 | ||
|
|
f75fe31571 | ||
|
|
61bdb1ed5f | ||
|
|
527e9d93a5 | ||
|
|
7d22b30217 | ||
|
|
c0d2333a3d | ||
|
|
4a7e1d058c | ||
|
|
66974615f6 | ||
|
|
116c888686 | ||
|
|
f6d6a804d2 | ||
|
|
6d6d702b97 | ||
|
|
9be04c1272 | ||
|
|
6f5d88cf63 | ||
|
|
1103e80191 | ||
|
|
a5320397c2 | ||
|
|
53719b971d | ||
|
|
64a1316f9b | ||
|
|
a3b8168744 | ||
|
|
c06e69931a | ||
|
|
30f8573dfc | ||
|
|
7f067b698e | ||
|
|
b56ebdf149 | ||
|
|
a02dd4ab87 | ||
|
|
898f0c962a | ||
|
|
5b4ae764cf | ||
|
|
d14db326bb | ||
|
|
5c51e0d0fc | ||
|
|
f78b4af692 | ||
|
|
bd5ed0f46c | ||
|
|
529cfa8f7d | ||
|
|
5552cd60f6 | ||
|
|
c51a1f4851 | ||
|
|
a27f4765e4 | ||
|
|
402f99923c | ||
|
|
2afda78912 | ||
|
|
25f9c7e125 | ||
|
|
05082cb2bb | ||
|
|
59495a1452 | ||
|
|
d10460c45b | ||
|
|
b968c85de2 | ||
|
|
13efc08b07 | ||
|
|
718060c757 | ||
|
|
4092cd8b6a | ||
|
|
ea99c26556 | ||
|
|
7527fd47cd | ||
|
|
c72c9c5cba | ||
|
|
09ded20409 | ||
|
|
0fd3de6215 | ||
|
|
1de160cb19 | ||
|
|
921abac3c1 | ||
|
|
7c75a2fd06 | ||
|
|
105be518c7 | ||
|
|
9425f24315 | ||
|
|
47c28ce9a2 | ||
|
|
72c85af407 | ||
|
|
22694fe5e4 | ||
|
|
a02232dc19 | ||
|
|
252e099e75 | ||
|
|
76a697c3f6 | ||
|
|
5b23593fd2 | ||
|
|
c2580c1d2d | ||
|
|
3303d2c7db | ||
|
|
22107fc598 | ||
|
|
bc4c4f8519 | ||
|
|
16c63dbe93 | ||
|
|
9e78ab3328 | ||
|
|
e6dc1f54b3 | ||
|
|
09025fa16d | ||
|
|
357b148944 | ||
|
|
8b71e56a5f | ||
|
|
f5aa5ac7f4 | ||
|
|
075d2fda4d | ||
|
|
b5c781212c | ||
|
|
af136943c3 | ||
|
|
b2a29c8d45 | ||
|
|
5d16d78914 | ||
|
|
94e970e15a | ||
|
|
1f4b984664 | ||
|
|
a2a27e78d1 | ||
|
|
915a5c188f | ||
|
|
e8f0420ad5 | ||
|
|
7a01b3ea28 | ||
|
|
7cff2aaa97 | ||
|
|
9588c7d8ef | ||
|
|
d5a6c7683e | ||
|
|
1de4e2ecd3 | ||
|
|
fa37f28c94 | ||
|
|
f1be509d13 | ||
|
|
fed528c6d8 | ||
|
|
d09cd5d71b | ||
|
|
4e40f5c7d9 | ||
|
|
3b5bb06b4a | ||
|
|
8f4e5a41c5 | ||
|
|
9b1005efc3 | ||
|
|
e1d4b66479 | ||
|
|
f2aa375b43 | ||
|
|
ee53793a6d | ||
|
|
528d46be9f | ||
|
|
cc80e69644 | ||
|
|
09ced090f2 | ||
|
|
8ad23e7a40 | ||
|
|
a94f46f904 | ||
|
|
41a5d2557e | ||
|
|
0b36db0ecc | ||
|
|
aae5519bed | ||
|
|
df849accfa | ||
|
|
b098937d1b | ||
|
|
fbe4fc49e1 | ||
|
|
8741fd8fed | ||
|
|
ccc952b65e | ||
|
|
6a68375b10 | ||
|
|
4dcb19edb7 | ||
|
|
838abc9af3 | ||
|
|
7283b2dd4d | ||
|
|
2c1f00da03 | ||
|
|
c7caec894e | ||
|
|
b254b4aa9b | ||
|
|
67107959e4 | ||
|
|
26d3e16e6d | ||
|
|
bb8ee4ef44 | ||
|
|
ee65ad22e6 | ||
|
|
b823f2c6b9 | ||
|
|
0901c59de9 | ||
|
|
69bfa1394c | ||
|
|
5b69a3e07c | ||
|
|
37220ab872 | ||
|
|
9dd7ceb966 | ||
|
|
ae6056615d | ||
|
|
d74253d149 | ||
|
|
805332c599 | ||
|
|
e42c1c1f69 | ||
|
|
f7881d0661 | ||
|
|
5eb86bbc88 | ||
|
|
53dc32fac1 | ||
|
|
a5a2c0b03e | ||
|
|
4d2e64cb80 | ||
|
|
dee064a758 | ||
|
|
5bdd67dcc1 | ||
|
|
2ff92bea70 | ||
|
|
0fbb070bf2 | ||
|
|
1a1c7ef23e | ||
|
|
fabd3da5a7 | ||
|
|
6f90d33f3a | ||
|
|
3bb0ee17cd | ||
|
|
fa8164cdba | ||
|
|
c63f1f0452 | ||
|
|
e0df447998 | ||
|
|
a64d4d0989 | ||
|
|
4c575f18d1 | ||
|
|
b629961a70 | ||
|
|
571d9780b1 | ||
|
|
df2ed04f16 | ||
|
|
3d687a283e | ||
|
|
99479b3896 | ||
|
|
7fca14bce1 | ||
|
|
afb51497cd | ||
|
|
88fada89ea | ||
|
|
023c51ac62 | ||
|
|
c37fa92559 | ||
|
|
9dabb890dc | ||
|
|
e40c3b4c03 | ||
|
|
5be7105bb8 | ||
|
|
8dc9541d95 | ||
|
|
6e5b71888d | ||
|
|
b362365609 | ||
|
|
1db2e4a333 | ||
|
|
6e8e40c22f | ||
|
|
cc21f8cca9 | ||
|
|
b545a27bc6 | ||
|
|
c9d863335e | ||
|
|
334e3ac6b4 | ||
|
|
d424aba0bc | ||
|
|
8802753de1 | ||
|
|
40edfef046 | ||
|
|
11343e6bdf | ||
|
|
30c7d86045 | ||
|
|
58b7b46828 | ||
|
|
3d0c0e3ed5 | ||
|
|
77d8ec04ca | ||
|
|
72de7c6cfb | ||
|
|
b82d3ab5ad | ||
|
|
20443ba59f | ||
|
|
bfdca9ca9e | ||
|
|
a12a44b722 | ||
|
|
8d45d4404e | ||
|
|
42ca128d7f | ||
|
|
7cd8e70d55 | ||
|
|
2982d2526a | ||
|
|
d33a0c6644 | ||
|
|
4a29e0d0e1 | ||
|
|
a89e04b92f | ||
|
|
4b993775c6 | ||
|
|
e0983fcc8c | ||
|
|
c9ddf2f04a | ||
|
|
b5764c4d04 | ||
|
|
5f41d275e4 | ||
|
|
7f707ae042 | ||
|
|
270a1e3a96 | ||
|
|
65d919876c | ||
|
|
049ae3602f | ||
|
|
d4c8e558e0 | ||
|
|
0e4d87824e | ||
|
|
cd7f6d52dd | ||
|
|
96c1b98d02 | ||
|
|
443d709eb8 | ||
|
|
5107f0e79e | ||
|
|
5567f94535 | ||
|
|
8e566e7326 | ||
|
|
43c6172482 | ||
|
|
f453334f63 | ||
|
|
ac24e06ae2 | ||
|
|
eab5abec2f | ||
|
|
0fc962b147 | ||
|
|
10794628ed | ||
|
|
a6f108d3b8 | ||
|
|
c4e80c1d1c | ||
|
|
6f231fa916 | ||
|
|
5d5f5c4ab7 | ||
|
|
034453636d | ||
|
|
8e4da42a64 | ||
|
|
7156bf0711 | ||
|
|
bc317514e6 | ||
|
|
26b2380bb7 | ||
|
|
685b2a68ba | ||
|
|
9936c7a8b6 | ||
|
|
83da52582b | ||
|
|
fbf918c7d0 | ||
|
|
2281fe6f8a | ||
|
|
1bb03e115e | ||
|
|
9d6ebf53a9 | ||
|
|
9e780b8eb2 | ||
|
|
01b34c5b8c | ||
|
|
11233bee3a | ||
|
|
e94b3caf51 | ||
|
|
e8166f3433 | ||
|
|
d844945453 | ||
|
|
85b40ca536 | ||
|
|
ca805917de | ||
|
|
014185c4c9 | ||
|
|
2b06679be6 | ||
|
|
7d2edc7c52 | ||
|
|
224bc9441b | ||
|
|
5a7b17a31e | ||
|
|
eea8950afb | ||
|
|
9f15c7fc53 | ||
|
|
4b879be4ea | ||
|
|
af078f03d0 | ||
|
|
cdf2c390ca | ||
|
|
77b2186cb6 | ||
|
|
0664ef8ccb | ||
|
|
4af7537764 | ||
|
|
f47e7531fc | ||
|
|
e484a08e8d | ||
|
|
56f3d0e0d6 | ||
|
|
3797854b0c | ||
|
|
931e91ddba | ||
|
|
25754bbe22 | ||
|
|
53884949d1 | ||
|
|
abb2a340e2 | ||
|
|
ed874ed00a | ||
|
|
a8aec35884 | ||
|
|
0496f6552a | ||
|
|
970cd5cf7a | ||
|
|
2fb4fdd18f | ||
|
|
fc1dc5c1d6 | ||
|
|
800194c6f5 | ||
|
|
0cab7b1c85 | ||
|
|
983d4c9db2 | ||
|
|
88dfacbbb3 | ||
|
|
3f572c79fa | ||
|
|
a7ee1fac3c | ||
|
|
068bfc948b | ||
|
|
47470f5a6d | ||
|
|
144dc1f8f4 | ||
|
|
4002bb804c | ||
|
|
760ed24b37 | ||
|
|
489979af43 | ||
|
|
e482e12826 | ||
|
|
fa7b9d54e2 | ||
|
|
f60114c7f6 | ||
|
|
de55253e54 | ||
|
|
8479e51051 | ||
|
|
bb2fd7c9c4 | ||
|
|
a0b0a5d47f | ||
|
|
10bdc1d3d1 | ||
|
|
6ec7d8d6b4 | ||
|
|
0dca9588ff | ||
|
|
ca03c530b2 | ||
|
|
973ec24674 | ||
|
|
1da767ff0a | ||
|
|
89127876f9 | ||
|
|
47a738a703 | ||
|
|
516b1cff88 | ||
|
|
6438977964 | ||
|
|
d750263d39 | ||
|
|
3ed952db9e | ||
|
|
f8040a1bf6 | ||
|
|
d83b31fd86 | ||
|
|
e0dbb657f6 | ||
|
|
a807cc6143 | ||
|
|
fe064c0ef8 | ||
|
|
6cc773426f | ||
|
|
db94408ba6 | ||
|
|
333bd3cdb9 | ||
|
|
9a0d82eb31 | ||
|
|
0990c0507c | ||
|
|
9f76ce22c1 | ||
|
|
6acd6075ff | ||
|
|
57b6f00d8e | ||
|
|
280c9327cb | ||
|
|
05bcbb695f | ||
|
|
552f4e8f13 | ||
|
|
1223c5348d | ||
|
|
3ccff4f337 | ||
|
|
a67f3334ea | ||
|
|
52dafbb6c8 | ||
|
|
4341cc437d | ||
|
|
7bb7dd7bbb | ||
|
|
b4090d9671 | ||
|
|
3d2bcce99a | ||
|
|
f3a04635cf | ||
|
|
419cb07557 | ||
|
|
57fccaa076 | ||
|
|
4bf65339f8 | ||
|
|
e5f2e209a2 | ||
|
|
be3b5cdb8a | ||
|
|
abd56baa51 | ||
|
|
ff27a1d0bb | ||
|
|
8af2d4d273 | ||
|
|
f64c8e28da | ||
|
|
4570d6350b | ||
|
|
6dd51a35c5 | ||
|
|
2470990d75 | ||
|
|
1a87e605d6 | ||
|
|
e995740790 | ||
|
|
0fb8b740a4 | ||
|
|
5087161e4b | ||
|
|
918e9e492a | ||
|
|
f10805dddb | ||
|
|
55e4d03dfe | ||
|
|
9f9086b4b0 | ||
|
|
e00ce79d26 | ||
|
|
a13b2e6bd2 | ||
|
|
cefe5acdaa | ||
|
|
1438aea965 | ||
|
|
1b60e24c64 | ||
|
|
4f1c8f6f35 | ||
|
|
882945260a | ||
|
|
3677088104 | ||
|
|
8f141cd88d | ||
|
|
0d1b35b610 | ||
|
|
87c20bf03c | ||
|
|
77479ca22d | ||
|
|
34ad743e98 | ||
|
|
493e27622f | ||
|
|
b1b6c7ceed | ||
|
|
d0b1610a9f | ||
|
|
dcf520a7a9 | ||
|
|
a0ae8b28b2 | ||
|
|
78a6179a11 | ||
|
|
9c91557d8f | ||
|
|
fb24ffd20d | ||
|
|
0c985a0af1 | ||
|
|
787dc5ab66 | ||
|
|
f11abdeebd | ||
|
|
89141dddf2 | ||
|
|
69f08de0ff | ||
|
|
925e20ebb8 | ||
|
|
ee254a286d | ||
|
|
3cc8d32dd3 | ||
|
|
50cf6d9750 | ||
|
|
cedbb64932 | ||
|
|
b45898a5b6 | ||
|
|
ccb1748ab3 | ||
|
|
11e9af15f7 | ||
|
|
8ad41fec92 | ||
|
|
ac5212ebb2 | ||
|
|
4e16b91f54 | ||
|
|
343f4965ed | ||
|
|
ac775c5aaf | ||
|
|
db17888d42 | ||
|
|
f12d10baa6 | ||
|
|
4289c1345f | ||
|
|
0d6a83b063 | ||
|
|
76b04dcba9 | ||
|
|
64dee7eb12 | ||
|
|
bc84ad8d56 | ||
|
|
afe8a2a5e4 | ||
|
|
87213dc9dd | ||
|
|
300d2428eb | ||
|
|
abe7d70822 | ||
|
|
d8bf26158a | ||
|
|
741cb57105 | ||
|
|
81c73037ca | ||
|
|
f6ba4f2ecd | ||
|
|
23303c0483 | ||
|
|
5a02448326 | ||
|
|
411ae25e80 | ||
|
|
6e1b3fe860 | ||
|
|
4a38d83a68 |
7
.craft.ini
Normal file
7
.craft.ini
Normal file
@@ -0,0 +1,7 @@
|
||||
; SPDX-FileCopyrightText: None
|
||||
; SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
[BlueprintSettings]
|
||||
kde/frameworks/extra-cmake-modules.version=master
|
||||
kde/unreleased/kirigami-addons.version=master
|
||||
libs/qt.qtMajorVersion=6
|
||||
@@ -2,7 +2,7 @@
|
||||
"id": "org.kde.neochat",
|
||||
"branch": "master",
|
||||
"runtime": "org.kde.Platform",
|
||||
"runtime-version": "5.15-22.08",
|
||||
"runtime-version": "6.6-kf6preview",
|
||||
"sdk": "org.kde.Sdk",
|
||||
"command": "neochat",
|
||||
"tags": [
|
||||
@@ -12,13 +12,14 @@
|
||||
"finish-args": [
|
||||
"--share=network",
|
||||
"--share=ipc",
|
||||
"--socket=x11",
|
||||
"--socket=fallback-x11",
|
||||
"--socket=wayland",
|
||||
"--device=dri",
|
||||
"--filesystem=xdg-download",
|
||||
"--talk-name=org.freedesktop.Notifications",
|
||||
"--talk-name=org.kde.kwalletd5",
|
||||
"--talk-name=org.kde.StatusNotifierWatcher",
|
||||
"--talk-name=org.freedesktop.secrets",
|
||||
"--own-name=org.kde.StatusNotifierItem-2-2"
|
||||
],
|
||||
"modules": [
|
||||
@@ -30,6 +31,7 @@
|
||||
},
|
||||
{
|
||||
"name": "kquickimageeditor",
|
||||
"config-opts": [ "-DBUILD_WITH_QT6=ON" ],
|
||||
"buildsystem": "cmake-ninja",
|
||||
"sources": [
|
||||
{
|
||||
@@ -41,6 +43,7 @@
|
||||
{
|
||||
"name": "olm",
|
||||
"buildsystem": "cmake-ninja",
|
||||
"config-opts": [ "-DOLM_TESTS=OFF" ],
|
||||
"sources": [
|
||||
{
|
||||
"type": "git",
|
||||
@@ -83,8 +86,8 @@
|
||||
"sources": [
|
||||
{
|
||||
"type": "archive",
|
||||
"url": "https://github.com/frankosterfeld/qtkeychain/archive/v0.13.2.tar.gz",
|
||||
"sha256": "20beeb32de7c4eb0af9039b21e18370faf847ac8697ab3045906076afbc4caa5",
|
||||
"url": "https://github.com/frankosterfeld/qtkeychain/archive/0.14.2.tar.gz",
|
||||
"sha256": "cf2e972b783ba66334a79a30f6b3a1ea794a1dc574d6c3bebae5ffd2f0399571",
|
||||
"x-checker-data": {
|
||||
"type": "anitya",
|
||||
"project-id": 4138,
|
||||
@@ -94,6 +97,7 @@
|
||||
}
|
||||
],
|
||||
"config-opts": [
|
||||
"-DBUILD_WITH_QT6=ON",
|
||||
"-DCMAKE_INSTALL_LIBDIR=/app/lib",
|
||||
"-DLIB_INSTALL_DIR=/app/lib",
|
||||
"-DBUILD_TRANSLATIONS=NO"
|
||||
@@ -111,12 +115,15 @@
|
||||
}
|
||||
],
|
||||
"config-opts": [
|
||||
"-DQuotient_ENABLE_E2EE=ON"
|
||||
"-DBUILD_WITH_QT6=ON",
|
||||
"-DQuotient_ENABLE_E2EE=ON",
|
||||
"-DBUILD_TESTING=OFF"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "cmark",
|
||||
"buildsystem": "cmake-ninja",
|
||||
"config-opts": [ "-DCMARK_TESTS=OFF" ],
|
||||
"sources": [
|
||||
{
|
||||
"type": "git",
|
||||
@@ -133,6 +140,7 @@
|
||||
{
|
||||
"name": "qcoro",
|
||||
"buildsystem": "cmake-ninja",
|
||||
"config-opts": [ "-DQCORO_BUILD_EXAMPLES=OFF", "-DBUILD_TESTING=OFF" ],
|
||||
"sources": [
|
||||
{
|
||||
"type": "archive",
|
||||
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -1,4 +1,4 @@
|
||||
build
|
||||
build*
|
||||
.clang-format
|
||||
.DS_Store
|
||||
.kdev4/
|
||||
@@ -10,3 +10,5 @@ kate.project.ctags.*
|
||||
*.user
|
||||
.flatpak-builder/
|
||||
.idea/
|
||||
cmake-build-*
|
||||
src/res.generated.qrc
|
||||
|
||||
@@ -2,13 +2,14 @@
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
include:
|
||||
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/reuse-lint.yml
|
||||
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/android.yml
|
||||
# - https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/android-qt6.yml
|
||||
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/linux.yml
|
||||
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/linux-qt6.yml
|
||||
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/windows.yml
|
||||
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/windows-qt6.yml
|
||||
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/freebsd.yml
|
||||
# - https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/freebsd-qt6.yml
|
||||
- https://invent.kde.org/sysadmin/ci-utilities/raw/master/gitlab-templates/flatpak.yml
|
||||
- project: sysadmin/ci-utilities
|
||||
file:
|
||||
- /gitlab-templates/reuse-lint.yml
|
||||
- /gitlab-templates/android-qt6.yml
|
||||
- /gitlab-templates/linux-qt6.yml
|
||||
- /gitlab-templates/windows-qt6.yml
|
||||
- /gitlab-templates/freebsd-qt6.yml
|
||||
- /gitlab-templates/flatpak.yml
|
||||
- /gitlab-templates/craft-android-qt6-apks.yml
|
||||
- /gitlab-templates/craft-appimage-qt6.yml
|
||||
- /gitlab-templates/craft-windows-x86-64-qt6.yml
|
||||
|
||||
45
.kde-ci.yml
45
.kde-ci.yml
@@ -2,34 +2,7 @@
|
||||
# SPDX-License-Identifier: BSD-2-Clause
|
||||
|
||||
Dependencies:
|
||||
- 'on': ['Linux/Qt5', 'Android/Qt5', 'FreeBSD/Qt5', 'Windows/Qt5']
|
||||
'require':
|
||||
'frameworks/extra-cmake-modules': '@stable'
|
||||
'frameworks/kcoreaddons': '@stable'
|
||||
'frameworks/kirigami': '@stable'
|
||||
'frameworks/ki18n': '@stable'
|
||||
'frameworks/kconfig': '@stable'
|
||||
'frameworks/syntax-highlighting': '@stable'
|
||||
'frameworks/kitemmodels': '@stable'
|
||||
'frameworks/knotifications': '@stable'
|
||||
'libraries/kquickimageeditor': '@stable'
|
||||
'frameworks/sonnet': '@stable'
|
||||
'libraries/kirigami-addons': '@latest'
|
||||
'third-party/libquotient': '@latest'
|
||||
'third-party/qtkeychain': '@latest'
|
||||
'third-party/cmark': '@latest'
|
||||
'third-party/qcoro': '@latest'
|
||||
- 'on': ['Windows/Qt5', 'Linux/Qt5', 'FreeBSD/Qt5']
|
||||
'require':
|
||||
'frameworks/qqc2-desktop-style': '@stable'
|
||||
'frameworks/kio': '@stable'
|
||||
'frameworks/kwindowsystem': '@stable'
|
||||
'frameworks/kconfigwidgets': '@stable'
|
||||
- 'on': ['Linux/Qt5', 'FreeBSD/Qt5']
|
||||
'require':
|
||||
'frameworks/kdbusaddons': '@stable'
|
||||
|
||||
- 'on': ['Linux/Qt6', 'Android/Qt6', 'FreeBSD/Qt6', 'Windows/Qt6']
|
||||
- 'on': ['Linux', 'Android', 'FreeBSD', 'Windows']
|
||||
'require':
|
||||
'frameworks/extra-cmake-modules': '@latest-kf6'
|
||||
'frameworks/kcoreaddons': '@latest-kf6'
|
||||
@@ -38,23 +11,31 @@ Dependencies:
|
||||
'frameworks/kconfig': '@latest-kf6'
|
||||
'frameworks/syntax-highlighting': '@latest-kf6'
|
||||
'frameworks/kitemmodels': '@latest-kf6'
|
||||
'frameworks/kquickcharts': '@latest-kf6'
|
||||
'frameworks/knotifications': '@latest-kf6'
|
||||
'frameworks/kcolorscheme': '@latest-kf6'
|
||||
'libraries/kquickimageeditor': '@latest-kf6'
|
||||
'frameworks/sonnet': '@latest-kf6'
|
||||
'frameworks/prison': '@latest-kf6'
|
||||
'libraries/kirigami-addons': '@latest-kf6'
|
||||
'third-party/libquotient': '@latest'
|
||||
'third-party/qtkeychain': '@latest'
|
||||
'third-party/cmark': '@latest'
|
||||
'third-party/qcoro': '@latest'
|
||||
- 'on': ['Windows/Qt6', 'Linux/Qt6', 'FreeBSD/Qt6']
|
||||
- 'on': ['Windows', 'Linux', 'FreeBSD']
|
||||
'require':
|
||||
'frameworks/qqc2-desktop-style': '@latest-kf6'
|
||||
'frameworks/kio': '@latest-kf6'
|
||||
'frameworks/kwindowsystem': '@latest-kf6'
|
||||
'frameworks/kconfigwidgets': '@latest-kf6'
|
||||
- 'on': ['Linux/Qt6', 'FreeBSD/Qt6']
|
||||
'frameworks/kstatusnotifieritem': '@latest-kf6'
|
||||
- 'on': ['Linux', 'FreeBSD']
|
||||
'require':
|
||||
'frameworks/kdbusaddons': '@latest-kf6'
|
||||
|
||||
- 'on': ['Linux']
|
||||
'require':
|
||||
'sdk/selenium-webdriver-at-spi': '@latest-kf6'
|
||||
|
||||
Options:
|
||||
require-passing-tests-on: [ 'Linux/Qt5', 'FreeBSD', 'Windows' ]
|
||||
per-test-timeout: 90
|
||||
require-passing-tests-on: [ '@all' ]
|
||||
|
||||
10
.reuse/dep5
10
.reuse/dep5
@@ -34,10 +34,18 @@ Files: src/neochat.notifyrc
|
||||
Copyright: 2020 Tobias Fella <tobias.fella@kde.org>
|
||||
License: BSD-2-Clause
|
||||
|
||||
Files: src/qml/Component/confetti.png src/qml/Component/glowdot.png
|
||||
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
|
||||
|
||||
@@ -7,18 +7,15 @@
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
# KDE Applications version, managed by release script.
|
||||
set(RELEASE_SERVICE_VERSION_MAJOR "23")
|
||||
set(RELEASE_SERVICE_VERSION_MINOR "03")
|
||||
set(RELEASE_SERVICE_VERSION_MAJOR "24")
|
||||
set(RELEASE_SERVICE_VERSION_MINOR "04")
|
||||
set(RELEASE_SERVICE_VERSION_MICRO "70")
|
||||
set(RELEASE_SERVICE_VERSION "${RELEASE_SERVICE_VERSION_MAJOR}.${RELEASE_SERVICE_VERSION_MINOR}.${RELEASE_SERVICE_VERSION_MICRO}")
|
||||
|
||||
project(NeoChat VERSION ${RELEASE_SERVICE_VERSION})
|
||||
|
||||
set(KF_MIN_VERSION "5.91.0")
|
||||
set(QT_MIN_VERSION "5.15.2")
|
||||
if (ANDROID)
|
||||
set(QT_MIN_VERSION "5.15.8")
|
||||
endif()
|
||||
set(KF_MIN_VERSION "5.240.0")
|
||||
set(QT_MIN_VERSION "6.5")
|
||||
|
||||
find_package(ECM ${KF_MIN_VERSION} REQUIRED NO_MODULE)
|
||||
|
||||
@@ -27,7 +24,7 @@ set(CMAKE_MODULE_PATH ${ECM_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake)
|
||||
set(CMAKE_CXX_STANDARD 20)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
set(KDE_COMPILERSETTINGS_LEVEL 5.84)
|
||||
set(KDE_COMPILERSETTINGS_LEVEL 5.105)
|
||||
|
||||
include(FeatureSummary)
|
||||
include(ECMSetupVersion)
|
||||
@@ -39,6 +36,8 @@ include(KDECompilerSettings NO_POLICY_SCOPE)
|
||||
include(ECMAddAppIcon)
|
||||
include(KDEGitCommitHooks)
|
||||
include(ECMCheckOutboundLicense)
|
||||
include(ECMQtDeclareLoggingCategory)
|
||||
include(ECMAddAndroidApk)
|
||||
if (NOT ANDROID)
|
||||
include(KDEClangFormat)
|
||||
endif()
|
||||
@@ -47,32 +46,28 @@ if(NEOCHAT_FLATPAK)
|
||||
include(cmake/Flatpak.cmake)
|
||||
endif()
|
||||
|
||||
set(QUOTIENT_FORCE_NAMESPACED_INCLUDES TRUE)
|
||||
|
||||
ecm_setup_version(${PROJECT_VERSION}
|
||||
VARIABLE_PREFIX NEOCHAT
|
||||
VERSION_HEADER ${CMAKE_CURRENT_BINARY_DIR}/neochat-version.h
|
||||
)
|
||||
|
||||
find_package(Qt${QT_MAJOR_VERSION} ${QT_MIN_VERSION} NO_MODULE COMPONENTS Core Quick Gui QuickControls2 Multimedia Svg)
|
||||
set_package_properties(Qt${QT_MAJOR_VERSION} PROPERTIES
|
||||
find_package(Qt6 ${QT_MIN_VERSION} NO_MODULE COMPONENTS Core Quick Gui QuickControls2 Multimedia Svg WebView)
|
||||
set_package_properties(Qt6 PROPERTIES
|
||||
TYPE REQUIRED
|
||||
PURPOSE "Basic application components"
|
||||
)
|
||||
find_package(KF${QT_MAJOR_VERSION} ${KF_MIN_VERSION} COMPONENTS Kirigami2 I18n Notifications Config CoreAddons Sonnet ItemModels)
|
||||
set_package_properties(KF${QT_MAJOR_VERSION} PROPERTIES
|
||||
find_package(KF6 ${KF_MIN_VERSION} COMPONENTS Kirigami I18n Notifications Config CoreAddons Sonnet ItemModels ColorScheme)
|
||||
set_package_properties(KF6 PROPERTIES
|
||||
TYPE REQUIRED
|
||||
PURPOSE "Basic application components"
|
||||
)
|
||||
set_package_properties(KF${QT_MAJOR_VERSION}Kirigami2 PROPERTIES
|
||||
TYPE REQUIRED
|
||||
PURPOSE "Kirigami application UI framework"
|
||||
)
|
||||
find_package(KF${QT_MAJOR_VERSION}KirigamiAddons 0.7.2 REQUIRED)
|
||||
|
||||
find_package(Qt${QT_MAJOR_VERSION}Keychain)
|
||||
set_package_properties(Qt${QT_MAJOR_VERSION}Keychain PROPERTIES
|
||||
set_package_properties(KF6Kirigami PROPERTIES
|
||||
TYPE REQUIRED
|
||||
PURPOSE "Secure storage of account secrets"
|
||||
PURPOSE "Kirigami application UI framework"
|
||||
)
|
||||
find_package(KF6KirigamiAddons 0.7.2 REQUIRED)
|
||||
|
||||
if(ANDROID)
|
||||
find_package(OpenSSL)
|
||||
@@ -81,26 +76,37 @@ if(ANDROID)
|
||||
PURPOSE "Encrypted communications"
|
||||
)
|
||||
else()
|
||||
find_package(Qt${QT_MAJOR_VERSION} ${QT_MIN_VERSION} COMPONENTS Widgets)
|
||||
find_package(KF${QT_MAJOR_VERSION} ${KF_MIN_VERSION} REQUIRED COMPONENTS QQC2DesktopStyle ConfigWidgets KIO WindowSystem)
|
||||
set_package_properties(KF${QT_MAJOR_VERSION}QQC2DesktopStyle PROPERTIES
|
||||
find_package(Qt6 ${QT_MIN_VERSION} COMPONENTS Widgets)
|
||||
find_package(KF6 ${KF_MIN_VERSION} REQUIRED COMPONENTS QQC2DesktopStyle KIO WindowSystem StatusNotifierItem)
|
||||
set_package_properties(KF6QQC2DesktopStyle PROPERTIES
|
||||
TYPE RUNTIME
|
||||
)
|
||||
ecm_find_qmlmodule(org.kde.syntaxhighlighting 1.0)
|
||||
|
||||
find_package(ICU 61.0 COMPONENTS uc)
|
||||
set_package_properties(ICU PROPERTIES
|
||||
TYPE REQUIRED
|
||||
PURPOSE "Unicode library"
|
||||
)
|
||||
endif()
|
||||
|
||||
if (NOT ANDROID AND NOT WIN32 AND NOT APPLE)
|
||||
find_package(KF${QT_MAJOR_VERSION}DBusAddons ${KF_MIN_VERSION} REQUIRED)
|
||||
find_package(KF6DBusAddons ${KF_MIN_VERSION} REQUIRED)
|
||||
endif()
|
||||
|
||||
find_package(Quotient 0.6)
|
||||
set_package_properties(Quotient PROPERTIES
|
||||
find_package(QuotientQt6 0.7)
|
||||
set_package_properties(QuotientQt6 PROPERTIES
|
||||
TYPE REQUIRED
|
||||
DESCRIPTION "Qt wrapper around Matrix API"
|
||||
URL "https://github.com/quotient-im/libQuotient/"
|
||||
PURPOSE "Talk with matrix server"
|
||||
)
|
||||
|
||||
if (NOT TARGET Olm::Olm)
|
||||
message(FATAL_ERROR "NeoChat requires Quotient with the E2EE feature enabled")
|
||||
endif()
|
||||
|
||||
|
||||
find_package(cmark)
|
||||
set_package_properties(cmark PROPERTIES
|
||||
TYPE REQUIRED
|
||||
@@ -111,6 +117,9 @@ set_package_properties(cmark PROPERTIES
|
||||
|
||||
ecm_find_qmlmodule(org.kde.kquickimageeditor 1.0)
|
||||
ecm_find_qmlmodule(org.kde.kitemmodels 1.0)
|
||||
ecm_find_qmlmodule(org.kde.quickcharts 1.0)
|
||||
ecm_find_qmlmodule(QtLocation)
|
||||
ecm_find_qmlmodule(org.kde.prison)
|
||||
|
||||
find_package(KQuickImageEditor COMPONENTS)
|
||||
set_package_properties(KQuickImageEditor PROPERTIES
|
||||
@@ -120,23 +129,25 @@ set_package_properties(KQuickImageEditor PROPERTIES
|
||||
PURPOSE "Add image editing capability to image attachments"
|
||||
)
|
||||
|
||||
find_package(QCoro${QT_MAJOR_VERSION} 0.4 COMPONENTS Core REQUIRED)
|
||||
find_package(QCoro6 0.4 COMPONENTS Core Network REQUIRED)
|
||||
|
||||
qcoro_enable_coroutines()
|
||||
|
||||
find_package(KF${QT_MAJOR_VERSION}DocTools ${KF_MIN_VERSION})
|
||||
set_package_properties(KF${QT_MAJOR_VERSION}DocTools PROPERTIES DESCRIPTION
|
||||
find_package(KF6DocTools ${KF_MIN_VERSION})
|
||||
set_package_properties(KF6DocTools PROPERTIES DESCRIPTION
|
||||
"Tools to generate documentation"
|
||||
TYPE OPTIONAL
|
||||
)
|
||||
|
||||
find_package(Sqlite3)
|
||||
|
||||
if(NOT Quotient_VERSION_MINOR GREATER 6)
|
||||
cmake_policy(SET CMP0063 OLD)
|
||||
endif()
|
||||
find_package(KUnifiedPush QUIET)
|
||||
set_package_properties(KUnifiedPush PROPERTIES
|
||||
TYPE OPTIONAL
|
||||
PURPOSE "Push notification support"
|
||||
URL "https://invent.kde.org/libraries/kunifiedpush"
|
||||
)
|
||||
|
||||
if(ANDROID)
|
||||
find_package(Sqlite3)
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/android/version.gradle.in ${CMAKE_BINARY_DIR}/version.gradle)
|
||||
endif()
|
||||
|
||||
@@ -150,12 +161,14 @@ install(FILES org.kde.neochat.tray.svg DESTINATION ${KDE_INSTALL_FULL_ICONDIR}/h
|
||||
add_definitions(-DQT_NO_FOREACH)
|
||||
|
||||
add_subdirectory(src)
|
||||
if (BUILD_TESTING AND Quotient_VERSION_MINOR GREATER 6)
|
||||
find_package(Qt${QT_MAJOR_VERSION} ${QT_MIN_VERSION} NO_MODULE COMPONENTS Test)
|
||||
|
||||
if (BUILD_TESTING)
|
||||
find_package(Qt6 ${QT_MIN_VERSION} NO_MODULE COMPONENTS Test)
|
||||
add_subdirectory(autotests)
|
||||
add_subdirectory(appiumtests)
|
||||
endif()
|
||||
|
||||
if(KF${QT_MAJOR_VERSION}DocTools_FOUND)
|
||||
if(KF6DocTools_FOUND)
|
||||
kdoctools_install(po)
|
||||
add_subdirectory(doc)
|
||||
endif()
|
||||
@@ -173,3 +186,9 @@ file(GLOB_RECURSE ALL_SOURCE_FILES *.cpp *.h *.qml)
|
||||
# Fixes the test by excluding this directory
|
||||
list(FILTER ALL_SOURCE_FILES EXCLUDE REGEX [[_(install|build)/.*]])
|
||||
ecm_check_outbound_license(LICENSES GPL-3.0-only FILES ${ALL_SOURCE_FILES})
|
||||
|
||||
ecm_qt_install_logging_categories(
|
||||
EXPORT NEOCHAT
|
||||
FILE neochat.categories
|
||||
DESTINATION ${KDE_INSTALL_LOGGINGCATEGORIESDIR}
|
||||
)
|
||||
|
||||
101
README.md
101
README.md
@@ -1,24 +1,52 @@
|
||||
<!--
|
||||
SPDX-FileCopyrightText: 2020-2021 Carl Schwan <carlschwan@kde.org>
|
||||
SPDX-FileCopyrightText: 2020-2021 Tobias Fella <tobias.fella@kde.org>
|
||||
SPDX-FileCopyrightText: 2023 James Graham <james.h.graham@protonmail.com>
|
||||
SPDX-License-Identifier: CC0-1.0
|
||||
-->
|
||||
|
||||
# NeoChat
|
||||
|
||||
NeoChat is a client for Matrix, the decentralized communication protocol for instant
|
||||
messaging. It is a fork of Spectral, using KDE frameworks, most notably Kirigami,
|
||||
KConfig and KI18n.
|
||||
A Qt/QML based Matrix client.
|
||||
|
||||
<a href='https://matrix.org'><img src='https://matrix.org/docs/legacy/made-for-matrix.png' alt='Made for Matrix' height=64 target=_blank /></a>
|
||||
<a href='https://flathub.org/apps/details/org.kde.neochat'><img width='190px' alt='Download on Flathub' src='https://flathub.org/assets/badges/flathub-badge-i-en.png'/></a>
|
||||
<a href='https://snapcraft.io/neochat'><img width='190px' alt='Download on the Snap Store' src='https://snapcraft.io/static/images/badges/en/snap-store-black.svg'/></a>
|
||||
|
||||
## Introduction
|
||||
|
||||
NeoChat is a client for [Matrix](https://matrix.org), the decentralized communication protocol for instant
|
||||
messaging. It is a fork of Spectral, using KDE frameworks, most notably [Kirigami](https://invent.kde.org/frameworks/kirigami)
|
||||
to provide a convergent experience across multiple platforms.
|
||||
|
||||
NeoChat also make use of other KDE Frameworks as well as [libQuotient](https://github.com/quotient-im/libQuotient), a
|
||||
Qt-based SDK for the [Matrix Protocol](https://spec.matrix.org/).
|
||||
|
||||

|
||||
|
||||
## Features
|
||||
|
||||
NeoChat aims to be a fully featured application for the Matrix specification. As such everything in the current stable specification with the notable exceptions
|
||||
of VoIP, threads and some aspects of End-to-End Encryption are supported. There are a few other smaller omissions due to the fact that the Matrix spec is constantly
|
||||
evolving but the aim remains to provide eventual support for the entire spec.
|
||||
|
||||
Due to the nature of the Matrix specification development NeoChat also supports numerous unstable features. Currently these are:
|
||||
- Polls - MSC3381
|
||||
- Sticker Packs - MSC2545
|
||||
- Location Events - MSC3488
|
||||
|
||||
## Get it
|
||||
|
||||
A stable release [is available](https://apps.kde.org/neochat) for download for Linux distributions.
|
||||
Details where to find stable releases for NeoChat can be found on its [homepage](https://apps.kde.org/neochat).
|
||||
|
||||
In addition to the stable builds, unstable nightly builds are available for all platforms. These can be downloaded
|
||||
from the [binary factory](https://binary-factory.kde.org/). There are unstable versions for the following platforms
|
||||
in addition to stable ones:
|
||||
- Android
|
||||
- MacOS
|
||||
- Windows
|
||||
|
||||
Along with the stable release, a Flatpak version is available for the nightly
|
||||
version:
|
||||
Additionally the nightly Flatpak version can be obtained from the nightly Flatpak repo using the following commands in your terminal:
|
||||
|
||||
```
|
||||
flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
|
||||
@@ -26,42 +54,53 @@ flatpak remote-add --if-not-exists kdeapps --from https://distribute.kde.org/kde
|
||||
flatpak install kdeapps org.kde.neochat
|
||||
```
|
||||
|
||||
A nightly build is also available for Android in the [KDE nightly F-Droid repo](https://community.kde.org/Android/FDroid)
|
||||
and can also directly be downloaded from the [binary factory](https://binary-factory.kde.org/view/Android/job/NeoChat_Nightly_android-arm64/).
|
||||
The unstable Android version can also be obtained from the [KDE nightly F-Droid repo](https://community.kde.org/Android/FDroid).
|
||||
|
||||
Nightly builds for [Windows](https://binary-factory.kde.org/job/NeoChat_Nightly_win64/), [MacOS](https://binary-factory.kde.org/job/NeoChat_Nightly_macos/) and [AppImages](https://binary-factory.kde.org/job/NeoChat_Nightly_appimage/) can also be downloaded from the [binary factory](https://binary-factory.kde.org/search/?q=neochat).
|
||||
## Running
|
||||
|
||||

|
||||
Just start the executable in your preferred way - either from the build directory or from the installed location.
|
||||
|
||||
## Features
|
||||
## Building NeoChat
|
||||
|
||||
* Sending messages
|
||||
* Sending files from clipboard and filesystem
|
||||
* Reply to message (right-click on a message to access menu)
|
||||
* Start a private chat (but not encrypted)
|
||||
* Show notifications, for the moment there is only a global switch
|
||||
to disable it. We plan to implement the configuration part of the
|
||||
specification soon.
|
||||
* Autocompletion of usernames in chat
|
||||
* Emoji picker
|
||||
* Basic room setting page
|
||||
* Send and accept invitations
|
||||
* /rainbow <message> (very important)
|
||||
* /me <message>
|
||||
The best way to build KDE apps during development is to use `kdesrc-build`. The full instructions for this can be found on
|
||||
the KDE community website's get involved section under [development](https://community.kde.org/Get_Involved/development). This
|
||||
is primarily aimed at Linux development.
|
||||
|
||||
NeoChat is still missing a few features to become a full-featured
|
||||
Matrix client (most notably encryption support and video chat support).
|
||||
We welcome contributions in this direction.
|
||||
For Windows and Android [Craft](https://invent.kde.org/packaging/craft) is the primary choice. There are guides for setting up
|
||||
development environments for [Windows](https://community.kde.org/Get_Involved/development/Windows) and [Android](https://develop.kde.org/docs/packaging/android/building_applications/).
|
||||
|
||||
## Tests
|
||||
|
||||
Tests are in the repository under [autotests](autotests) and should all pass for any contribution.
|
||||
|
||||
The project has CI setup to test new commits to the repository. All tests are expected to pass for a merge request to
|
||||
be complete.
|
||||
|
||||
Current build status
|
||||
|
||||

|
||||
|
||||
Currently the number of tests is limited, but growing. If anyone wants to help improve this, those
|
||||
contributions would be especially welcome.
|
||||
|
||||
## Contributing
|
||||
|
||||
As is the case throughout the KDE ecosystem contributions are welcome from all. The code base is managed in the
|
||||
[NeoChat repository](https://invent.kde.org/network/neochat) of the KDE Gitlab instance.
|
||||
|
||||
- [Code of Conduct](https://kde.org/code-of-conduct)
|
||||
- [Report a Bug](https://bugs.kde.org/enter_bug.cgi?format=guided&product=neochat)
|
||||
- [Feature Request](https://community.kde.org/Infrastructure/GitLab#Submitting_a_merge_request)
|
||||
- [Create a Merge Request](https://community.kde.org/Infrastructure/GitLab#Submitting_a_merge_request)
|
||||
- [Translation](https://community.kde.org/Get_Involved/translation)
|
||||
|
||||
## Contact
|
||||
|
||||
You can reach the maintainers at [#neochat:kde.org](https://matrix.to/#/#neochat:kde.org), if you are already on Matrix.
|
||||
Development happens in http://invent.kde.org/network/neochat (not in GitHub).
|
||||
The best place to reach the maintainers is on the KDE Matrix instance in the NeoChat channel, [#neochat:kde.org](https://go.kde.org/matrix/#/#neochat:kde.org). See [Matrix](https://community.kde.org/Matrix) for more details.
|
||||
|
||||
## Acknowledgement
|
||||
|
||||
This program utilizes [libQuotient](https://github.com/quotient-im/libQuotient/)
|
||||
library and some C++ models from [Quaternion](https://github.com/quotient-im/Quaternion/).
|
||||
This program utilizes [libQuotient](https://github.com/quotient-im/libQuotient/) as its Matrix SDK.
|
||||
|
||||
This program is a fork of [Spectral](https://gitlab.com/spectral-im/spectral/).
|
||||
|
||||
|
||||
@@ -9,9 +9,9 @@
|
||||
android:versionName="${versionName}"
|
||||
android:versionCode="${versionCode}"
|
||||
android:installLocation="auto">
|
||||
<application android:name="org.qtproject.qt5.android.bindings.QtApplication" android:label="NeoChat" android:icon="@drawable/neochat">
|
||||
<application android:name="org.qtproject.qt.android.bindings.QtApplication" android:label="NeoChat" android:icon="@drawable/neochat" android:usesCleartextTraffic="true">
|
||||
<activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|layoutDirection|locale|fontScale|keyboard|keyboardHidden|navigation"
|
||||
android:name="org.qtproject.qt5.android.bindings.QtActivity"
|
||||
android:name="org.qtproject.qt.android.bindings.QtActivity"
|
||||
android:label="NeoChat"
|
||||
android:windowSoftInputMode="adjustResize"
|
||||
android:launchMode="singleTop"
|
||||
|
||||
@@ -12,7 +12,7 @@ buildscript {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:7.0.2'
|
||||
classpath 'com.android.tools.build:gradle:7.4.1'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,7 +35,7 @@ android {
|
||||
* The following variables:
|
||||
* - androidBuildToolsVersion,
|
||||
* - androidCompileSdkVersion
|
||||
* - qt5AndroidDir - holds the path to qt android files
|
||||
* - qtAndroidDir - holds the path to qt android files
|
||||
* needed to build any Qt application
|
||||
* on Android.
|
||||
*
|
||||
@@ -44,16 +44,20 @@ android {
|
||||
* Changing them manually might break the compilation!
|
||||
*******************************************************/
|
||||
|
||||
compileSdkVersion androidCompileSdkVersion.toInteger()
|
||||
|
||||
compileSdkVersion androidCompileSdkVersion
|
||||
buildToolsVersion androidBuildToolsVersion
|
||||
ndkVersion androidNdkVersion
|
||||
|
||||
// Extract native libraries from the APK
|
||||
packagingOptions.jniLibs.useLegacyPackaging true
|
||||
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
manifest.srcFile 'AndroidManifest.xml'
|
||||
java.srcDirs = [qt5AndroidDir + '/src', 'src', 'java']
|
||||
aidl.srcDirs = [qt5AndroidDir + '/src', 'src', 'aidl']
|
||||
res.srcDirs = [qt5AndroidDir + '/res', 'res']
|
||||
java.srcDirs = [qtAndroidDir + '/src', 'src', 'java']
|
||||
aidl.srcDirs = [qtAndroidDir + '/src', 'src', 'aidl']
|
||||
res.srcDirs = [qtAndroidDir + '/res', 'res']
|
||||
resources.srcDirs = ['src']
|
||||
renderscript.srcDirs = ['src']
|
||||
assets.srcDirs = ['assets']
|
||||
@@ -88,6 +92,7 @@ android {
|
||||
exclude 'lib/*/*_imageformats_qtga_*'
|
||||
exclude 'lib/*/*_imageformats_qtiff_*'
|
||||
exclude 'lib/*/*_qmltooling_*'
|
||||
exclude 'lib/*/*_multimedia_ffmpeg*' // temporary qt6 android fix
|
||||
}
|
||||
|
||||
aaptOptions {
|
||||
|
||||
28
appiumtests/CMakeLists.txt
Normal file
28
appiumtests/CMakeLists.txt
Normal file
@@ -0,0 +1,28 @@
|
||||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
# SPDX-FileCopyrightText: 2022 Harald Sitter <sitter@kde.org>
|
||||
|
||||
|
||||
if(NOT BUILD_TESTING OR NOT CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
return()
|
||||
endif()
|
||||
|
||||
find_package(SeleniumWebDriverATSPI)
|
||||
set_package_properties(SeleniumWebDriverATSPI PROPERTIES
|
||||
DESCRIPTION "Server component for selenium tests using Linux accessibility infrastructure"
|
||||
PURPOSE "Needed for GUI tests"
|
||||
URL "https://invent.kde.org/sdk/selenium-webdriver-at-spi"
|
||||
TYPE OPTIONAL
|
||||
)
|
||||
if(NOT SeleniumWebDriverATSPI_FOUND)
|
||||
return()
|
||||
endif()
|
||||
|
||||
add_test(
|
||||
NAME logintest
|
||||
COMMAND selenium-webdriver-at-spi-run ${CMAKE_CURRENT_SOURCE_DIR}/logintest.py
|
||||
)
|
||||
|
||||
add_test(
|
||||
NAME openuserdetailstest
|
||||
COMMAND selenium-webdriver-at-spi-run ${CMAKE_CURRENT_SOURCE_DIR}/openuserdetailstest.py
|
||||
)
|
||||
3
appiumtests/data/sync_response_no_rooms.json
Normal file
3
appiumtests/data/sync_response_no_rooms.json
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"next_batch": "batch1234"
|
||||
}
|
||||
50
appiumtests/data/sync_response_rooms.json
Normal file
50
appiumtests/data/sync_response_rooms.json
Normal file
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"next_batch": "batch1234",
|
||||
"rooms": {
|
||||
"join": {
|
||||
"!room_id_1234:localhost:1234": {
|
||||
"state": {
|
||||
"events": [
|
||||
{
|
||||
"type": "m.room.member",
|
||||
"state_key": "@user:localhost:1234",
|
||||
"sender": "@user:localhost:1234",
|
||||
"origin_server_ts": 1432735824653,
|
||||
"event_id": "$event_id_1234_0:localhost:1234",
|
||||
"room_id": "!room_id_1234:localhost:1234",
|
||||
"content": {
|
||||
"avatar_url": "",
|
||||
"displayname": "A Display Name",
|
||||
"membership": "join",
|
||||
"reason": "Nothing"
|
||||
},
|
||||
"unsigned": {
|
||||
"age": 1234
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"timeline": {
|
||||
"events": [
|
||||
{
|
||||
"type": "m.room.message",
|
||||
"sender": "@user:localhost:1234",
|
||||
"origin_server_ts": 1432735824653,
|
||||
"event_id": "$event_id_1234_1:localhost:1234",
|
||||
"room_id": "!room_id_1234:localhost:1234",
|
||||
"content": {
|
||||
"body": "This is a message",
|
||||
"format": "org.matrix.custom.html",
|
||||
"formatted_body": "<a href=\"https://matrix.to/#/@user:localhost:1234\">User</a>:",
|
||||
"msgtype": "m.text"
|
||||
},
|
||||
"unsigned": {
|
||||
"age": 1234
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
70
appiumtests/login-server.py
Normal file
70
appiumtests/login-server.py
Normal file
@@ -0,0 +1,70 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
# SPDX-FileCopyrightText: 2023 Tobias Fella <tobias.fella@kde.org>
|
||||
|
||||
import json
|
||||
from flask import Flask, request, abort
|
||||
import os
|
||||
app = Flask(__name__)
|
||||
|
||||
|
||||
@app.route("/_matrix/client/v3/login", methods=["GET"])
|
||||
def login_get():
|
||||
result = dict()
|
||||
result["flows"] = [dict()]
|
||||
result["flows"][0]["type"] = "m.login.password"
|
||||
return result
|
||||
|
||||
@app.route("/_matrix/client/v3/account/whoami", methods=["GET"])
|
||||
def whoami():
|
||||
result = dict()
|
||||
result["device_id"] = "device_id_1234"
|
||||
result["user_id"] = "@user:localhost:1234"
|
||||
return result
|
||||
|
||||
@app.route("/_matrix/client/v3/login", methods=["POST"])
|
||||
def login_post():
|
||||
data = request.get_json()
|
||||
if data["identifier"]["user"] != "user" or data["password"] != "1234":
|
||||
abort(403)
|
||||
print(data)
|
||||
result = dict()
|
||||
result["access_token"] = "token_login"
|
||||
result["device_id"] = "device_1234"
|
||||
result["user_id"] = "@user:localhost:1234"
|
||||
return result
|
||||
|
||||
def load_json(name):
|
||||
parts = __file__.split("/")
|
||||
parts.pop()
|
||||
datadir = "/".join(parts)
|
||||
return json.loads(open(f"{datadir}/data/{name}.json").read())
|
||||
|
||||
|
||||
@app.route("/_matrix/client/r0/sync")
|
||||
def sync():
|
||||
|
||||
result = load_json("sync_response_no_rooms") if ("login" in request.headers.get("Authorization")) else load_json("sync_response_rooms")
|
||||
return result
|
||||
|
||||
@app.route("/.well-known/matrix/client")
|
||||
def well_known():
|
||||
reply = dict()
|
||||
reply["m.homeserver"] = dict()
|
||||
reply["m.homeserver"]["base_url"] = "https://localhost:1234"
|
||||
return reply
|
||||
|
||||
@app.route("/_matrix/client/v3/profile/<id>")
|
||||
def profile(id):
|
||||
reply = dict()
|
||||
reply["avatar_url"] = "mxc://localhost:1234/asdf1234"
|
||||
reply["displayname"] = "User123"
|
||||
return reply
|
||||
|
||||
@app.route("/_matrix/client/v3/keys/upload", methods=["POST"])
|
||||
def upload_keys():
|
||||
reply = dict()
|
||||
return reply
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run(ssl_context='adhoc', port=1234)
|
||||
51
appiumtests/logintest.py
Executable file
51
appiumtests/logintest.py
Executable file
@@ -0,0 +1,51 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# SPDX-License-Identifier: MIT
|
||||
# SPDX-FileCopyrightText: 2021-2022 Harald Sitter <sitter@kde.org>
|
||||
# SPDX-FileCopyrightText: 2023 Tobias Fella <tobias.fella@kde.org>
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from appium import webdriver
|
||||
from appium.options.common.base import AppiumOptions
|
||||
from appium.webdriver.common.appiumby import AppiumBy
|
||||
|
||||
|
||||
class LoginTest(unittest.TestCase):
|
||||
|
||||
mockServerProcess: subprocess.Popen
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
options = AppiumOptions()
|
||||
options.set_capability("app", "neochat --ignore-ssl-errors")
|
||||
cls.driver = webdriver.Remote(command_executor='http://127.0.0.1:4723', options=options)
|
||||
cls.mockServerProcess = subprocess.Popen([sys.executable, os.path.join(os.path.dirname(__file__), "login-server.py")])
|
||||
|
||||
def setUp(self):
|
||||
pass
|
||||
|
||||
def tearDown(self):
|
||||
if not self._outcome.result.wasSuccessful():
|
||||
self.driver.get_screenshot_as_file("failed_test_shot_{}.png".format(self.id()))
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(self):
|
||||
self.mockServerProcess.terminate()
|
||||
self.driver.quit()
|
||||
|
||||
def test_login(self):
|
||||
self.driver.find_element(by=AppiumBy.NAME, value="Login").click()
|
||||
|
||||
self.driver.find_element(by=AppiumBy.NAME, value="Matrix ID").send_keys("@user:localhost:1234")
|
||||
self.driver.find_element(by=AppiumBy.NAME, value="Continue").click()
|
||||
self.driver.find_element(by=AppiumBy.NAME, value="Password").send_keys("1234")
|
||||
self.driver.find_element(by=AppiumBy.NAME, value="Login").click()
|
||||
self.driver.find_element(by=AppiumBy.NAME, value="Join some rooms to get started").click()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
48
appiumtests/openuserdetailstest.py
Executable file
48
appiumtests/openuserdetailstest.py
Executable file
@@ -0,0 +1,48 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# SPDX-License-Identifier: MIT
|
||||
# SPDX-FileCopyrightText: 2021-2022 Harald Sitter <sitter@kde.org>
|
||||
# SPDX-FileCopyrightText: 2023 Tobias Fella <tobias.fella@kde.org>
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from appium import webdriver
|
||||
from appium.options.common.base import AppiumOptions
|
||||
from appium.webdriver.common.appiumby import AppiumBy
|
||||
|
||||
|
||||
class OpenUserDetailsTest(unittest.TestCase):
|
||||
|
||||
mockServerProcess: subprocess.Popen
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cls.mockServerProcess = subprocess.Popen([sys.executable, os.path.join(os.path.dirname(__file__), "login-server.py")])
|
||||
options = AppiumOptions()
|
||||
options.set_capability("app", "neochat --ignore-ssl-errors --test")
|
||||
cls.driver = webdriver.Remote(command_executor='http://127.0.0.1:4723', options=options)
|
||||
|
||||
def setUp(self):
|
||||
pass
|
||||
|
||||
def tearDown(self):
|
||||
if not self._outcome.result.wasSuccessful():
|
||||
self.driver.get_screenshot_as_file("failed_test_shot_{}.png".format(self.id()))
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(self):
|
||||
self.mockServerProcess.terminate()
|
||||
self.driver.quit()
|
||||
|
||||
def test_open_sheet(self):
|
||||
self.driver.find_element(by=AppiumBy.NAME, value="@user:localhost:1234").click()
|
||||
self.driver.find_element(by=AppiumBy.NAME, value="Empty room (!room_id_1234:localhost:1234)").click()
|
||||
self.driver.find_element(by=AppiumBy.NAME, value="A Display Name").click()
|
||||
self.driver.find_element(by=AppiumBy.NAME, value="Account Details")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -3,8 +3,82 @@
|
||||
|
||||
enable_testing()
|
||||
|
||||
add_definitions(-DDATA_DIR="${CMAKE_CURRENT_SOURCE_DIR}/data" )
|
||||
|
||||
ecm_add_test(
|
||||
neochatroomtest.cpp
|
||||
LINK_LIBRARIES neochat Qt::Test Quotient
|
||||
LINK_LIBRARIES neochat Qt::Test
|
||||
TEST_NAME neochatroomtest
|
||||
)
|
||||
|
||||
ecm_add_test(
|
||||
texthandlertest.cpp
|
||||
LINK_LIBRARIES neochat Qt::Test
|
||||
TEST_NAME texthandlertest
|
||||
)
|
||||
|
||||
ecm_add_test(
|
||||
delegatesizehelpertest.cpp
|
||||
LINK_LIBRARIES neochat Qt::Test
|
||||
TEST_NAME delegatesizehelpertest
|
||||
)
|
||||
|
||||
ecm_add_test(
|
||||
mediasizehelpertest.cpp
|
||||
LINK_LIBRARIES neochat Qt::Test
|
||||
TEST_NAME mediasizehelpertest
|
||||
)
|
||||
|
||||
ecm_add_test(
|
||||
eventhandlertest.cpp
|
||||
LINK_LIBRARIES neochat Qt::Test
|
||||
TEST_NAME eventhandlertest
|
||||
)
|
||||
|
||||
ecm_add_test(
|
||||
chatbarcachetest.cpp
|
||||
LINK_LIBRARIES neochat Qt::Test
|
||||
TEST_NAME chatbarcachetest
|
||||
)
|
||||
|
||||
ecm_add_test(
|
||||
chatdocumenthandlertest.cpp
|
||||
LINK_LIBRARIES neochat Qt::Test
|
||||
TEST_NAME chatdocumenthandlertest
|
||||
)
|
||||
|
||||
ecm_add_test(
|
||||
messageeventmodeltest.cpp
|
||||
LINK_LIBRARIES neochat Qt::Test
|
||||
TEST_NAME messageeventmodeltest
|
||||
)
|
||||
|
||||
ecm_add_test(
|
||||
actionshandlertest.cpp
|
||||
LINK_LIBRARIES neochat Qt::Test
|
||||
TEST_NAME actionshandlertest
|
||||
)
|
||||
|
||||
ecm_add_test(
|
||||
windowcontrollertest.cpp
|
||||
LINK_LIBRARIES neochat Qt::Test
|
||||
TEST_NAME windowcontrollertest
|
||||
)
|
||||
|
||||
ecm_add_test(
|
||||
pollhandlertest.cpp
|
||||
LINK_LIBRARIES neochat Qt::Test
|
||||
TEST_NAME pollhandlertest
|
||||
)
|
||||
|
||||
ecm_add_test(
|
||||
reactionmodeltest.cpp
|
||||
LINK_LIBRARIES neochat Qt::Test
|
||||
TEST_NAME reactionmodeltest
|
||||
)
|
||||
|
||||
ecm_add_test(
|
||||
linkpreviewertest.cpp
|
||||
LINK_LIBRARIES neochat Qt::Test
|
||||
TEST_NAME linkpreviewertest
|
||||
)
|
||||
|
||||
43
autotests/actionshandlertest.cpp
Normal file
43
autotests/actionshandlertest.cpp
Normal file
@@ -0,0 +1,43 @@
|
||||
// SPDX-FileCopyrightText: 2023 James Graham <james.h.graham@protonmail.com>
|
||||
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||
|
||||
#include <QTest>
|
||||
|
||||
#include "actionshandler.h"
|
||||
#include "chatbarcache.h"
|
||||
|
||||
#include "testutils.h"
|
||||
|
||||
class ActionsHandlerTest : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
Quotient::Connection *connection = Quotient::Connection::makeMockConnection(QStringLiteral("@bob:kde.org"));
|
||||
ActionsHandler *actionsHandler = new ActionsHandler(this);
|
||||
|
||||
private Q_SLOTS:
|
||||
void nullObject();
|
||||
};
|
||||
|
||||
void ActionsHandlerTest::nullObject()
|
||||
{
|
||||
QTest::ignoreMessage(QtWarningMsg, "ActionsHandler::handleMessageEvent - called with m_room and/or chatBarCache set to nullptr.");
|
||||
actionsHandler->handleMessageEvent(nullptr);
|
||||
|
||||
auto chatBarCache = new ChatBarCache(this);
|
||||
QTest::ignoreMessage(QtWarningMsg, "ActionsHandler::handleMessageEvent - called with m_room and/or chatBarCache set to nullptr.");
|
||||
actionsHandler->handleMessageEvent(chatBarCache);
|
||||
|
||||
auto room = new TestUtils::TestRoom(connection, QStringLiteral("#myroom:kde.org"));
|
||||
actionsHandler->setRoom(room);
|
||||
QTest::ignoreMessage(QtWarningMsg, "ActionsHandler::handleMessageEvent - called with m_room and/or chatBarCache set to nullptr.");
|
||||
actionsHandler->handleMessageEvent(nullptr);
|
||||
|
||||
// The final one should throw no warning so we make sure.
|
||||
QTest::failOnWarning("ActionsHandler::handleMessageEvent - called with m_room and/or chatBarCache set to nullptr.");
|
||||
actionsHandler->handleMessageEvent(chatBarCache);
|
||||
}
|
||||
|
||||
QTEST_GUILESS_MAIN(ActionsHandlerTest)
|
||||
#include "actionshandlertest.moc"
|
||||
141
autotests/chatbarcachetest.cpp
Normal file
141
autotests/chatbarcachetest.cpp
Normal file
@@ -0,0 +1,141 @@
|
||||
// SPDX-FileCopyrightText: 2023 James Graham <james.h.graham@protonmail.com>
|
||||
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QObject>
|
||||
#include <QTest>
|
||||
|
||||
#include <Quotient/syncdata.h>
|
||||
#include <qtestcase.h>
|
||||
|
||||
#include "chatbarcache.h"
|
||||
#include "neochatroom.h"
|
||||
|
||||
#include "testutils.h"
|
||||
|
||||
using namespace Quotient;
|
||||
|
||||
class ChatBarCacheTest : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
Connection *connection = nullptr;
|
||||
TestUtils::TestRoom *room = nullptr;
|
||||
|
||||
private Q_SLOTS:
|
||||
void initTestCase();
|
||||
|
||||
void empty();
|
||||
void noRoom();
|
||||
void badParent();
|
||||
void reply();
|
||||
void edit();
|
||||
void attachment();
|
||||
};
|
||||
|
||||
void ChatBarCacheTest::initTestCase()
|
||||
{
|
||||
connection = Connection::makeMockConnection(QStringLiteral("@bob:kde.org"));
|
||||
room = new TestUtils::TestRoom(connection, QStringLiteral("#myroom:kde.org"), QLatin1String("test-min-sync.json"));
|
||||
}
|
||||
|
||||
void ChatBarCacheTest::empty()
|
||||
{
|
||||
QScopedPointer<ChatBarCache> chatBarCache(new ChatBarCache(room));
|
||||
|
||||
QCOMPARE(chatBarCache->text(), QString());
|
||||
QCOMPARE(chatBarCache->isReplying(), false);
|
||||
QCOMPARE(chatBarCache->replyId(), QString());
|
||||
QCOMPARE(chatBarCache->isEditing(), false);
|
||||
QCOMPARE(chatBarCache->editId(), QString());
|
||||
QCOMPARE(chatBarCache->relationUser(), room->getUser(nullptr));
|
||||
QCOMPARE(chatBarCache->relationMessage(), QString());
|
||||
QCOMPARE(chatBarCache->attachmentPath(), QString());
|
||||
}
|
||||
|
||||
void ChatBarCacheTest::noRoom()
|
||||
{
|
||||
QScopedPointer<ChatBarCache> chatBarCache(new ChatBarCache());
|
||||
chatBarCache->setReplyId(QLatin1String("$153456789:example.org"));
|
||||
|
||||
// These should return empty even though a reply ID has been set because the
|
||||
// ChatBarCache has no parent.
|
||||
|
||||
QTest::ignoreMessage(QtWarningMsg, "ChatBarCache created with no parent, a NeoChatRoom must be set as the parent on creation.");
|
||||
QCOMPARE(chatBarCache->relationUser(), QVariantMap());
|
||||
|
||||
QTest::ignoreMessage(QtWarningMsg, "ChatBarCache created with no parent, a NeoChatRoom must be set as the parent on creation.");
|
||||
QCOMPARE(chatBarCache->relationMessage(), QString());
|
||||
}
|
||||
|
||||
void ChatBarCacheTest::badParent()
|
||||
{
|
||||
QScopedPointer<QObject> badParent(new QObject());
|
||||
QScopedPointer<ChatBarCache> chatBarCache(new ChatBarCache(badParent.get()));
|
||||
chatBarCache->setReplyId(QLatin1String("$153456789:example.org"));
|
||||
|
||||
// These should return empty even though a reply ID has been set because the
|
||||
// ChatBarCache has no parent.
|
||||
|
||||
QTest::ignoreMessage(QtWarningMsg, "ChatBarCache created with incorrect parent, a NeoChatRoom must be set as the parent on creation.");
|
||||
QCOMPARE(chatBarCache->relationUser(), QVariantMap());
|
||||
|
||||
QTest::ignoreMessage(QtWarningMsg, "ChatBarCache created with incorrect parent, a NeoChatRoom must be set as the parent on creation.");
|
||||
QCOMPARE(chatBarCache->relationMessage(), QString());
|
||||
}
|
||||
|
||||
void ChatBarCacheTest::reply()
|
||||
{
|
||||
QScopedPointer<ChatBarCache> chatBarCache(new ChatBarCache(room));
|
||||
chatBarCache->setText(QLatin1String("some text"));
|
||||
chatBarCache->setAttachmentPath(QLatin1String("some/path"));
|
||||
chatBarCache->setReplyId(QLatin1String("$153456789:example.org"));
|
||||
|
||||
QCOMPARE(chatBarCache->text(), QLatin1String("some text"));
|
||||
QCOMPARE(chatBarCache->isReplying(), true);
|
||||
QCOMPARE(chatBarCache->replyId(), QLatin1String("$153456789:example.org"));
|
||||
QCOMPARE(chatBarCache->isEditing(), false);
|
||||
QCOMPARE(chatBarCache->editId(), QString());
|
||||
QCOMPARE(chatBarCache->relationUser(), room->getUser(room->user(QLatin1String("@example:example.org"))));
|
||||
QCOMPARE(chatBarCache->relationMessage(), QLatin1String("This is an example\ntext message"));
|
||||
QCOMPARE(chatBarCache->attachmentPath(), QString());
|
||||
}
|
||||
|
||||
void ChatBarCacheTest::edit()
|
||||
{
|
||||
QScopedPointer<ChatBarCache> chatBarCache(new ChatBarCache(room));
|
||||
chatBarCache->setText(QLatin1String("some text"));
|
||||
chatBarCache->setAttachmentPath(QLatin1String("some/path"));
|
||||
chatBarCache->setEditId(QLatin1String("$153456789:example.org"));
|
||||
|
||||
QCOMPARE(chatBarCache->text(), QLatin1String("some text"));
|
||||
QCOMPARE(chatBarCache->isReplying(), false);
|
||||
QCOMPARE(chatBarCache->replyId(), QString());
|
||||
QCOMPARE(chatBarCache->isEditing(), true);
|
||||
QCOMPARE(chatBarCache->editId(), QLatin1String("$153456789:example.org"));
|
||||
QCOMPARE(chatBarCache->relationUser(), room->getUser(room->user(QLatin1String("@example:example.org"))));
|
||||
QCOMPARE(chatBarCache->relationMessage(), QLatin1String("This is an example\ntext message"));
|
||||
QCOMPARE(chatBarCache->attachmentPath(), QString());
|
||||
}
|
||||
|
||||
void ChatBarCacheTest::attachment()
|
||||
{
|
||||
QScopedPointer<ChatBarCache> chatBarCache(new ChatBarCache(room));
|
||||
chatBarCache->setText(QLatin1String("some text"));
|
||||
chatBarCache->setEditId(QLatin1String("$153456789:example.org"));
|
||||
chatBarCache->setAttachmentPath(QLatin1String("some/path"));
|
||||
|
||||
QCOMPARE(chatBarCache->text(), QLatin1String("some text"));
|
||||
QCOMPARE(chatBarCache->isReplying(), false);
|
||||
QCOMPARE(chatBarCache->replyId(), QString());
|
||||
QCOMPARE(chatBarCache->isEditing(), false);
|
||||
QCOMPARE(chatBarCache->editId(), QString());
|
||||
QCOMPARE(chatBarCache->relationUser(), room->getUser(nullptr));
|
||||
QCOMPARE(chatBarCache->relationMessage(), QString());
|
||||
QCOMPARE(chatBarCache->attachmentPath(), QLatin1String("some/path"));
|
||||
}
|
||||
|
||||
QTEST_MAIN(ChatBarCacheTest)
|
||||
#include "chatbarcachetest.moc"
|
||||
36
autotests/chatdocumenthandlertest.cpp
Normal file
36
autotests/chatdocumenthandlertest.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
// SPDX-FileCopyrightText: 2023 James Graham <james.h.graham@protonmail.com>
|
||||
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||
|
||||
#include <QObject>
|
||||
#include <QTest>
|
||||
|
||||
#include "chatdocumenthandler.h"
|
||||
#include "neochatconfig.h"
|
||||
|
||||
class ChatDocumentHandlerTest : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
ChatDocumentHandler emptyHandler;
|
||||
|
||||
private Q_SLOTS:
|
||||
void initTestCase();
|
||||
|
||||
void nullComplete();
|
||||
};
|
||||
|
||||
void ChatDocumentHandlerTest::initTestCase()
|
||||
{
|
||||
// HACK: this is to stop KStatusNotifierItem SEGFAULTING on cleanup.
|
||||
NeoChatConfig::self()->setSystemTray(false);
|
||||
}
|
||||
|
||||
void ChatDocumentHandlerTest::nullComplete()
|
||||
{
|
||||
QTest::ignoreMessage(QtWarningMsg, "complete called with m_document set to nullptr.");
|
||||
emptyHandler.complete(0);
|
||||
}
|
||||
|
||||
QTEST_MAIN(ChatDocumentHandlerTest)
|
||||
#include "chatdocumenthandlertest.moc"
|
||||
410
autotests/data/test-eventhandler-sync.json
Normal file
410
autotests/data/test-eventhandler-sync.json
Normal file
@@ -0,0 +1,410 @@
|
||||
{
|
||||
"account_data": {
|
||||
"events": [
|
||||
{
|
||||
"content": {
|
||||
"tags": {
|
||||
"u.work": {
|
||||
"order": 0.9
|
||||
}
|
||||
}
|
||||
},
|
||||
"type": "m.tag"
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"custom_config_key": "custom_config_value"
|
||||
},
|
||||
"type": "org.example.custom.room.config"
|
||||
}
|
||||
]
|
||||
},
|
||||
"ephemeral": {
|
||||
"events": [
|
||||
{
|
||||
"content": {
|
||||
"user_ids": [
|
||||
"@alice:matrix.org",
|
||||
"@bob:example.com"
|
||||
]
|
||||
},
|
||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||
"type": "m.typing"
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"$153456789:example.org": {
|
||||
"m.read": {
|
||||
"@alice:matrix.org": {
|
||||
"ts": 1436451550453
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"type": "m.receipt"
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"$1532735824654:example.org": {
|
||||
"m.read": {
|
||||
"@bob:example.com": {
|
||||
"ts": 1436451550453
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"type": "m.receipt"
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"$1532735824654:example.org": {
|
||||
"m.read": {
|
||||
"@tim:example.com": {
|
||||
"ts": 1436451550454
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"type": "m.receipt"
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"$1532735824654:example.org": {
|
||||
"m.read": {
|
||||
"@jeff:example.com": {
|
||||
"ts": 1436451550455
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"type": "m.receipt"
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"$1532735824654:example.org": {
|
||||
"m.read": {
|
||||
"@tina:example.com": {
|
||||
"ts": 1436451550456
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"type": "m.receipt"
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"$1532735824654:example.org": {
|
||||
"m.read": {
|
||||
"@sally:example.com": {
|
||||
"ts": 1436451550457
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"type": "m.receipt"
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"$1532735824654:example.org": {
|
||||
"m.read": {
|
||||
"@fred:example.com": {
|
||||
"ts": 1436451550458
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"type": "m.receipt"
|
||||
}
|
||||
]
|
||||
},
|
||||
"state": {
|
||||
"events": [
|
||||
{
|
||||
"content": {
|
||||
"avatar_url": "mxc://example.org/SEsfnsuifSDFSSEF",
|
||||
"displayname": "Alice Margatroid",
|
||||
"membership": "join",
|
||||
"reason": "Looking for support"
|
||||
},
|
||||
"event_id": "$143273582443PhrSn:example.org",
|
||||
"origin_server_ts": 1432735824653,
|
||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||
"sender": "@example:example.org",
|
||||
"state_key": "@alice:example.org",
|
||||
"type": "m.room.member",
|
||||
"unsigned": {
|
||||
"age": 1234
|
||||
}
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"displayname": "Look\nat\nme\nI\nput\nnewlines\nin\nmy\ndisplay name",
|
||||
"membership": "join"
|
||||
},
|
||||
"event_id": "$143273582443PhrSh:example.org",
|
||||
"origin_server_ts": 1432735824659,
|
||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||
"sender": "@newline:example.org",
|
||||
"state_key": "@newline:example.org",
|
||||
"type": "m.room.member",
|
||||
"unsigned": {
|
||||
"age": 12345
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"summary": {
|
||||
"m.heroes": [
|
||||
"@alice:example.com",
|
||||
"@bob:example.com"
|
||||
],
|
||||
"m.invited_member_count": 0,
|
||||
"m.joined_member_count": 2
|
||||
},
|
||||
"timeline": {
|
||||
"events": [
|
||||
{
|
||||
"content": {
|
||||
"body": "This is an example\ntext message",
|
||||
"format": "org.matrix.custom.html",
|
||||
"formatted_body": "<b>This is an example<br>text message</b>",
|
||||
"msgtype": "m.text"
|
||||
},
|
||||
"event_id": "$153456789:example.org",
|
||||
"origin_server_ts": 1432735824654,
|
||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||
"sender": "@example:example.org",
|
||||
"type": "m.room.message",
|
||||
"unsigned": {
|
||||
"age": 1232
|
||||
}
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"avatar_url": "mxc://kde.org/123456",
|
||||
"displayname": "after",
|
||||
"membership": "join"
|
||||
},
|
||||
"origin_server_ts": 1690651134736,
|
||||
"sender": "@example:example.org",
|
||||
"state_key": "@example:example.org",
|
||||
"type": "m.room.member",
|
||||
"unsigned": {
|
||||
"replaces_state": "$1234567890:example.org",
|
||||
"prev_content": {
|
||||
"avatar_url": "mxc://kde.org/12345",
|
||||
"displayname": "before",
|
||||
"membership": "join"
|
||||
},
|
||||
"prev_sender": "@example:example.orgg",
|
||||
"age": 1234
|
||||
},
|
||||
"event_id": "$143273583553PhrSn:example.org",
|
||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org"
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"body": "This is a highlight @bob:kde.org and this is a link https://kde.org",
|
||||
"format": "org.matrix.custom.html",
|
||||
"msgtype": "m.text"
|
||||
},
|
||||
"event_id": "$1532735824654:example.org",
|
||||
"origin_server_ts": 1532735824654,
|
||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||
"sender": "@example:example.org",
|
||||
"type": "m.room.message",
|
||||
"unsigned": {
|
||||
"age": 1233
|
||||
}
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"m.relates_to": {
|
||||
"event_id": "$153456789:example.org",
|
||||
"key": "👍",
|
||||
"rel_type": "m.annotation"
|
||||
}
|
||||
},
|
||||
"origin_server_ts": 1690322545182,
|
||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||
"sender": "@alice:matrix.org",
|
||||
"type": "m.reaction",
|
||||
"unsigned": {
|
||||
"age": 390159120
|
||||
},
|
||||
"event_id": "$163456789:example.org",
|
||||
"age": 390159120
|
||||
},
|
||||
{
|
||||
"age": 4926305285,
|
||||
"content": {
|
||||
"body": "video caption",
|
||||
"filename": "video.mp4",
|
||||
"info": {
|
||||
"duration": 10,
|
||||
"h": 1080,
|
||||
"mimetype": "video/mp4",
|
||||
"size": 62650636,
|
||||
"w": 1920,
|
||||
"thumbnail_info": {
|
||||
"h": 450,
|
||||
"mimetype": "image/jpeg",
|
||||
"size": 382249,
|
||||
"w": 800
|
||||
},
|
||||
"thumbnail_url": "mxc://kde.org/2234567"
|
||||
},
|
||||
"msgtype": "m.video",
|
||||
"url": "mxc://kde.org/1234567"
|
||||
},
|
||||
"event_id": "$263456789:example.org",
|
||||
"origin_server_ts": 1685793783330,
|
||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||
"sender": "@example:example.org",
|
||||
"type": "m.room.message",
|
||||
"unsigned": {
|
||||
"age": 4926305285
|
||||
},
|
||||
"user_id": "@example:example.org"
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"body": "> <@example:example.org> This is an example\ntext message\n\nreply",
|
||||
"format": "org.matrix.custom.html",
|
||||
"formatted_body": "<mx-reply><blockquote><a href=\"https://matrix.to/#/!jEsUZKDJdhlrceRyVU:example.org/$153456789:example.org?via=kde.org&via=matrix.org\">In reply to</a> <a href=\"https://matrix.to/#/@example:example.org\">@example:example.org</a><br><b>This is an example<br>text message</b></blockquote></mx-reply>reply",
|
||||
"m.relates_to": {
|
||||
"m.in_reply_to": {
|
||||
"event_id": "$153456789:example.org"
|
||||
}
|
||||
},
|
||||
"msgtype": "m.text"
|
||||
},
|
||||
"origin_server_ts": 1690725965572,
|
||||
"sender": "@alice:matrix.org",
|
||||
"type": "m.room.message",
|
||||
"unsigned": {
|
||||
"age": 98
|
||||
},
|
||||
"event_id": "$154456789:example.org",
|
||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org"
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"body": "> <@example:example.org> video caption\n\nreply",
|
||||
"m.relates_to": {
|
||||
"m.in_reply_to": {
|
||||
"event_id": "$263456789:example.org"
|
||||
}
|
||||
},
|
||||
"msgtype": "m.text"
|
||||
},
|
||||
"origin_server_ts": 1690725965573,
|
||||
"sender": "@alice:matrix.org",
|
||||
"type": "m.room.message",
|
||||
"unsigned": {
|
||||
"age": 98
|
||||
},
|
||||
"event_id": "$154456799:example.org",
|
||||
"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": "$1544567999:example.org",
|
||||
"origin_server_ts": 1690821582876,
|
||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||
"sender": "@example:example.org",
|
||||
"type": "m.room.message",
|
||||
"unsigned": {
|
||||
"age": 96845207
|
||||
}
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"body": "Thread root",
|
||||
"format": "org.matrix.custom.html",
|
||||
"msgtype": "m.text"
|
||||
},
|
||||
"event_id": "$threadroot:example.org",
|
||||
"origin_server_ts": 1690821582879,
|
||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||
"sender": "@example:example.org",
|
||||
"type": "m.room.message",
|
||||
"unsigned": {
|
||||
"age": 1232
|
||||
}
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"body": "Thread message 1",
|
||||
"msgtype": "m.text",
|
||||
"m.relates_to": {
|
||||
"rel_type": "m.thread",
|
||||
"event_id": "$threadroot:example.org",
|
||||
"m.in_reply_to": {
|
||||
"event_id": "$threadroot:example.org"
|
||||
},
|
||||
"is_falling_back": true
|
||||
}
|
||||
},
|
||||
"event_id": "$threadmessage1:example.org",
|
||||
"origin_server_ts": 1690821582890,
|
||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||
"sender": "@example:example.org",
|
||||
"type": "m.room.message",
|
||||
"unsigned": {
|
||||
"age": 1238
|
||||
}
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"body": "Thread message 2",
|
||||
"msgtype": "m.text",
|
||||
"m.relates_to": {
|
||||
"rel_type": "m.thread",
|
||||
"event_id": "$threadroot:example.org",
|
||||
"m.in_reply_to": {
|
||||
"event_id": "$threadmessage1:example.org"
|
||||
},
|
||||
"is_falling_back": true
|
||||
}
|
||||
},
|
||||
"event_id": "$threadmessage2:example.org",
|
||||
"origin_server_ts": 1690821582890,
|
||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||
"sender": "@example:example.org",
|
||||
"type": "m.room.message",
|
||||
"unsigned": {
|
||||
"age": 1238
|
||||
}
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"body": "A message from someone who thought it was a good idea to put newlines in their display name.",
|
||||
"msgtype": "m.text"
|
||||
},
|
||||
"event_id": "$153456889:example.org",
|
||||
"origin_server_ts": 14327358246589,
|
||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||
"sender": "@newline:example.org",
|
||||
"type": "m.room.message",
|
||||
"unsigned": {
|
||||
"age": 1230
|
||||
}
|
||||
}
|
||||
],
|
||||
"limited": true,
|
||||
"prev_batch": "t34-23535_0_0"
|
||||
}
|
||||
}
|
||||
14
autotests/data/test-invalidmatrixtolink-event.json
Normal file
14
autotests/data/test-invalidmatrixtolink-event.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"content": {
|
||||
"body": "https://matrix.to/#/@alice:example.org",
|
||||
"msgtype": "m.text"
|
||||
},
|
||||
"event_id": "$validlink1:example.org",
|
||||
"origin_server_ts": 1432735824654,
|
||||
"room_id": "!test:example.org",
|
||||
"sender": "@example:example.org",
|
||||
"type": "m.room.message",
|
||||
"unsigned": {
|
||||
"age": 1234
|
||||
}
|
||||
}
|
||||
14
autotests/data/test-invalidmxclink-event.json
Normal file
14
autotests/data/test-invalidmxclink-event.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"content": {
|
||||
"body": "mxc://example.org/SEsfnsuifSDFSSEF",
|
||||
"msgtype": "m.text"
|
||||
},
|
||||
"event_id": "$validlink1:example.org",
|
||||
"origin_server_ts": 1432735824654,
|
||||
"room_id": "!test:example.org",
|
||||
"sender": "@example:example.org",
|
||||
"type": "m.room.message",
|
||||
"unsigned": {
|
||||
"age": 1234
|
||||
}
|
||||
}
|
||||
14
autotests/data/test-invalidnospacelink-event.json
Normal file
14
autotests/data/test-invalidnospacelink-event.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"content": {
|
||||
"body": "testhttps://kde.org",
|
||||
"msgtype": "m.text"
|
||||
},
|
||||
"event_id": "$validlink1:example.org",
|
||||
"origin_server_ts": 1432735824654,
|
||||
"room_id": "!test:example.org",
|
||||
"sender": "@example:example.org",
|
||||
"type": "m.room.message",
|
||||
"unsigned": {
|
||||
"age": 1234
|
||||
}
|
||||
}
|
||||
24
autotests/data/test-linkpreviewerintial-sync.json
Normal file
24
autotests/data/test-linkpreviewerintial-sync.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"timeline": {
|
||||
"events": [
|
||||
{
|
||||
"content": {
|
||||
"body": "https://kde.org",
|
||||
"format": "org.matrix.custom.html",
|
||||
"formatted_body": "https://kde.org",
|
||||
"msgtype": "m.text"
|
||||
},
|
||||
"origin_server_ts": 1704648567967,
|
||||
"sender": "@example:example.org",
|
||||
"type": "m.room.message",
|
||||
"unsigned": {
|
||||
"age": 112
|
||||
},
|
||||
"event_id": "$validlink:example.org",
|
||||
"room_id": "!test:example.org"
|
||||
}
|
||||
],
|
||||
"limited": true,
|
||||
"prev_batch": "t34-23535_0_0"
|
||||
}
|
||||
}
|
||||
35
autotests/data/test-linkpreviewerreplace-sync.json
Normal file
35
autotests/data/test-linkpreviewerreplace-sync.json
Normal file
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"timeline": {
|
||||
"events": [
|
||||
{
|
||||
"content": {
|
||||
"body": "* ",
|
||||
"format": "org.matrix.custom.html",
|
||||
"formatted_body": "no link",
|
||||
"m.new_content": {
|
||||
"body": "",
|
||||
"format": "org.matrix.custom.html",
|
||||
"formatted_body": "no link",
|
||||
"msgtype": "m.text"
|
||||
},
|
||||
"m.relates_to": {
|
||||
"event_id": "$validlink:example.org",
|
||||
"rel_type": "m.replace"
|
||||
},
|
||||
"msgtype": "m.text",
|
||||
"type": "m.room.message"
|
||||
},
|
||||
"origin_server_ts": 1704648614969,
|
||||
"sender": "@example:example.org",
|
||||
"type": "m.room.message",
|
||||
"unsigned": {
|
||||
"age": 65
|
||||
},
|
||||
"event_id": "$nolink:example.org",
|
||||
"room_id": "!test:example.org"
|
||||
}
|
||||
],
|
||||
"limited": true,
|
||||
"prev_batch": "t34-23535_0_0"
|
||||
}
|
||||
}
|
||||
105
autotests/data/test-messageventmodel-sync.json
Normal file
105
autotests/data/test-messageventmodel-sync.json
Normal file
@@ -0,0 +1,105 @@
|
||||
{
|
||||
"account_data": {
|
||||
"events": [
|
||||
{
|
||||
"content": {
|
||||
"tags": {
|
||||
"u.work": {
|
||||
"order": 0.9
|
||||
}
|
||||
}
|
||||
},
|
||||
"type": "m.tag"
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"custom_config_key": "custom_config_value"
|
||||
},
|
||||
"type": "org.example.custom.room.config"
|
||||
}
|
||||
]
|
||||
},
|
||||
"ephemeral": {
|
||||
"events": [
|
||||
{
|
||||
"content": {
|
||||
"user_ids": [
|
||||
"@alice:matrix.org",
|
||||
"@bob:example.com"
|
||||
]
|
||||
},
|
||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||
"type": "m.typing"
|
||||
}
|
||||
]
|
||||
},
|
||||
"state": {
|
||||
"events": [
|
||||
{
|
||||
"content": {
|
||||
"displayname": "Example",
|
||||
"membership": "join"
|
||||
},
|
||||
"event_id": "$exampleMember:example.org",
|
||||
"origin_server_ts": 1432735824653,
|
||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||
"sender": "@example:example.org",
|
||||
"state_key": "@example:example.org",
|
||||
"type": "m.room.member",
|
||||
"unsigned": {
|
||||
"age": 1234
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"summary": {
|
||||
"m.heroes": [
|
||||
"@example:example.org"
|
||||
],
|
||||
"m.invited_member_count": 0,
|
||||
"m.joined_member_count": 2
|
||||
},
|
||||
"timeline": {
|
||||
"events": [
|
||||
{
|
||||
"content": {
|
||||
"body": "This is an example\ntext message",
|
||||
"format": "org.matrix.custom.html",
|
||||
"formatted_body": "<b>This is an example<br>text message</b>",
|
||||
"msgtype": "m.text"
|
||||
},
|
||||
"event_id": "$153456789:example.org",
|
||||
"origin_server_ts": 1,
|
||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||
"sender": "@example:example.org",
|
||||
"type": "m.room.message",
|
||||
"unsigned": {
|
||||
"age": 1232
|
||||
}
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"displayname": "Example Changed",
|
||||
"membership": "join"
|
||||
},
|
||||
"event_id": "$exampleMemberChnage:example.org",
|
||||
"origin_server_ts": 2,
|
||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||
"sender": "@example:example.org",
|
||||
"state_key": "@example:example.org",
|
||||
"type": "m.room.member",
|
||||
"unsigned": {
|
||||
"replaces_state": "$exampleMember:example.org",
|
||||
"prev_content": {
|
||||
"displayname": "Example",
|
||||
"membership": "join"
|
||||
},
|
||||
"prev_sender": "@example:example.org",
|
||||
"age": 1234
|
||||
}
|
||||
}
|
||||
],
|
||||
"limited": true,
|
||||
"prev_batch": "t34-23535_0_0"
|
||||
}
|
||||
}
|
||||
87
autotests/data/test-min-sync.json
Normal file
87
autotests/data/test-min-sync.json
Normal file
@@ -0,0 +1,87 @@
|
||||
{
|
||||
"account_data": {
|
||||
"events": [
|
||||
{
|
||||
"content": {
|
||||
"tags": {
|
||||
"u.work": {
|
||||
"order": 0.9
|
||||
}
|
||||
}
|
||||
},
|
||||
"type": "m.tag"
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"custom_config_key": "custom_config_value"
|
||||
},
|
||||
"type": "org.example.custom.room.config"
|
||||
}
|
||||
]
|
||||
},
|
||||
"ephemeral": {
|
||||
"events": [
|
||||
{
|
||||
"content": {
|
||||
"user_ids": [
|
||||
"@alice:matrix.org",
|
||||
"@bob:example.com"
|
||||
]
|
||||
},
|
||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||
"type": "m.typing"
|
||||
}
|
||||
]
|
||||
},
|
||||
"state": {
|
||||
"events": [
|
||||
{
|
||||
"content": {
|
||||
"avatar_url": "mxc://example.org/SEsfnsuifSDFSSEF",
|
||||
"displayname": "Alice Margatroid",
|
||||
"membership": "join",
|
||||
"reason": "Looking for support"
|
||||
},
|
||||
"event_id": "$143273582443PhrSn:example.org",
|
||||
"origin_server_ts": 1432735824653,
|
||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||
"sender": "@example:example.org",
|
||||
"state_key": "@alice:example.org",
|
||||
"type": "m.room.member",
|
||||
"unsigned": {
|
||||
"age": 1234
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"summary": {
|
||||
"m.heroes": [
|
||||
"@alice:example.com",
|
||||
"@bob:example.com"
|
||||
],
|
||||
"m.invited_member_count": 0,
|
||||
"m.joined_member_count": 2
|
||||
},
|
||||
"timeline": {
|
||||
"events": [
|
||||
{
|
||||
"content": {
|
||||
"body": "This is an example\ntext message",
|
||||
"format": "org.matrix.custom.html",
|
||||
"formatted_body": "<b>This is an example<br>text message</b>",
|
||||
"msgtype": "m.text"
|
||||
},
|
||||
"event_id": "$153456789:example.org",
|
||||
"origin_server_ts": 1432735824654,
|
||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||
"sender": "@example:example.org",
|
||||
"type": "m.room.message",
|
||||
"unsigned": {
|
||||
"age": 1232
|
||||
}
|
||||
}
|
||||
],
|
||||
"limited": true,
|
||||
"prev_batch": "t34-23535_0_0"
|
||||
}
|
||||
}
|
||||
14
autotests/data/test-multiplelink-event.json
Normal file
14
autotests/data/test-multiplelink-event.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"content": {
|
||||
"body": "www.example.org https://kde.org",
|
||||
"msgtype": "m.text"
|
||||
},
|
||||
"event_id": "$validlink1:example.org",
|
||||
"origin_server_ts": 1432735824654,
|
||||
"room_id": "!test:example.org",
|
||||
"sender": "@example:example.org",
|
||||
"type": "m.room.message",
|
||||
"unsigned": {
|
||||
"age": 1234
|
||||
}
|
||||
}
|
||||
22
autotests/data/test-pending-sync.json
Normal file
22
autotests/data/test-pending-sync.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"timeline": {
|
||||
"events": [
|
||||
{
|
||||
"content": {
|
||||
"body": "New plain message",
|
||||
"msgtype": "m.text"
|
||||
},
|
||||
"event_id": "$pendingmerge:example.org",
|
||||
"origin_server_ts": 123456,
|
||||
"room_id":"#myroom:kde.org",
|
||||
"sender":"@bob:kde.org",
|
||||
"type":"m.room.message",
|
||||
"unsigned": {
|
||||
"transaction_id": "17017181543521"
|
||||
}
|
||||
}
|
||||
],
|
||||
"limited": true,
|
||||
"prev_batch": "t34-23535_0_0"
|
||||
}
|
||||
}
|
||||
38
autotests/data/test-pollhandlerstart-sync.json
Normal file
38
autotests/data/test-pollhandlerstart-sync.json
Normal file
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"timeline": {
|
||||
"events": [
|
||||
{
|
||||
"content": {
|
||||
"org.matrix.msc1767.text": "test\n1. option1\n2. option 2",
|
||||
"org.matrix.msc3381.poll.start": {
|
||||
"answers": [
|
||||
{
|
||||
"id": "option1",
|
||||
"org.matrix.msc1767.text": "option1"
|
||||
},
|
||||
{
|
||||
"id": "option2",
|
||||
"org.matrix.msc1767.text": "option2"
|
||||
}
|
||||
],
|
||||
"kind": "org.matrix.msc3381.poll.disclosed",
|
||||
"max_selections": 1,
|
||||
"question": {
|
||||
"body": "test",
|
||||
"msgtype": "m.text",
|
||||
"org.matrix.msc1767.text": "test"
|
||||
}
|
||||
}
|
||||
},
|
||||
"event_id": "$153456789:example.org",
|
||||
"origin_server_ts": 1432735824654,
|
||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||
"sender": "@example:example.org",
|
||||
"type": "org.matrix.msc3381.poll.start",
|
||||
"unsigned": {
|
||||
"age": 1232
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
44
autotests/data/test-reactionmodel-extra-sync.json
Normal file
44
autotests/data/test-reactionmodel-extra-sync.json
Normal file
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"timeline": {
|
||||
"events": [
|
||||
{
|
||||
"content": {
|
||||
"m.relates_to": {
|
||||
"event_id": "$153456789:example.org",
|
||||
"key": "👍",
|
||||
"rel_type": "m.annotation"
|
||||
}
|
||||
},
|
||||
"origin_server_ts": 1690322545183,
|
||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||
"sender": "@bob:example.org",
|
||||
"type": "m.reaction",
|
||||
"unsigned": {
|
||||
"age": 390159121
|
||||
},
|
||||
"event_id": "$163456790:example.org",
|
||||
"age": 390159121
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"m.relates_to": {
|
||||
"event_id": "$153456789:example.org",
|
||||
"key": "😆",
|
||||
"rel_type": "m.annotation"
|
||||
}
|
||||
},
|
||||
"origin_server_ts": 1690322545184,
|
||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||
"sender": "@bob:example.org",
|
||||
"type": "m.reaction",
|
||||
"unsigned": {
|
||||
"age": 390159122
|
||||
},
|
||||
"event_id": "$163456791:example.org",
|
||||
"age": 390159122
|
||||
}
|
||||
],
|
||||
"limited": true,
|
||||
"prev_batch": "t34-23535_0_0"
|
||||
}
|
||||
}
|
||||
204
autotests/data/test-reactionmodel-sync.json
Normal file
204
autotests/data/test-reactionmodel-sync.json
Normal file
@@ -0,0 +1,204 @@
|
||||
{
|
||||
"account_data": {
|
||||
"events": [
|
||||
{
|
||||
"content": {
|
||||
"tags": {
|
||||
"u.work": {
|
||||
"order": 0.9
|
||||
}
|
||||
}
|
||||
},
|
||||
"type": "m.tag"
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"custom_config_key": "custom_config_value"
|
||||
},
|
||||
"type": "org.example.custom.room.config"
|
||||
}
|
||||
]
|
||||
},
|
||||
"ephemeral": {
|
||||
"events": [
|
||||
{
|
||||
"content": {
|
||||
"user_ids": [
|
||||
"@alice:matrix.org",
|
||||
"@bob:example.com"
|
||||
]
|
||||
},
|
||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||
"type": "m.typing"
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"$153456789:example.org": {
|
||||
"m.read": {
|
||||
"@alice:matrix.org": {
|
||||
"ts": 1436451550453
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"type": "m.receipt"
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"$1532735824654:example.org": {
|
||||
"m.read": {
|
||||
"@bob:example.com": {
|
||||
"ts": 1436451550453
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"type": "m.receipt"
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"$1532735824654:example.org": {
|
||||
"m.read": {
|
||||
"@tim:example.com": {
|
||||
"ts": 1436451550454
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"type": "m.receipt"
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"$1532735824654:example.org": {
|
||||
"m.read": {
|
||||
"@jeff:example.com": {
|
||||
"ts": 1436451550455
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"type": "m.receipt"
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"$1532735824654:example.org": {
|
||||
"m.read": {
|
||||
"@tina:example.com": {
|
||||
"ts": 1436451550456
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"type": "m.receipt"
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"$1532735824654:example.org": {
|
||||
"m.read": {
|
||||
"@sally:example.com": {
|
||||
"ts": 1436451550457
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"type": "m.receipt"
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"$1532735824654:example.org": {
|
||||
"m.read": {
|
||||
"@fred:example.com": {
|
||||
"ts": 1436451550458
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"type": "m.receipt"
|
||||
}
|
||||
]
|
||||
},
|
||||
"state": {
|
||||
"events": [
|
||||
{
|
||||
"content": {
|
||||
"avatar_url": "mxc://example.org/SEsfnsuifSDFSSEF",
|
||||
"displayname": "Alice Margatroid",
|
||||
"membership": "join",
|
||||
"reason": "Looking for support"
|
||||
},
|
||||
"event_id": "$143273582443PhrSn:example.org",
|
||||
"origin_server_ts": 1432735824653,
|
||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||
"sender": "@example:example.org",
|
||||
"state_key": "@alice:example.org",
|
||||
"type": "m.room.member",
|
||||
"unsigned": {
|
||||
"age": 1234
|
||||
}
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"displayname": "Look\nat\nme\nI\nput\nnewlines\nin\nmy\ndisplay name",
|
||||
"membership": "join"
|
||||
},
|
||||
"event_id": "$143273582443PhrSh:example.org",
|
||||
"origin_server_ts": 1432735824659,
|
||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||
"sender": "@newline:example.org",
|
||||
"state_key": "@newline:example.org",
|
||||
"type": "m.room.member",
|
||||
"unsigned": {
|
||||
"age": 12345
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"summary": {
|
||||
"m.heroes": [
|
||||
"@alice:example.com",
|
||||
"@bob:example.com"
|
||||
],
|
||||
"m.invited_member_count": 0,
|
||||
"m.joined_member_count": 2
|
||||
},
|
||||
"timeline": {
|
||||
"events": [
|
||||
{
|
||||
"content": {
|
||||
"body": "This is an example\ntext message",
|
||||
"format": "org.matrix.custom.html",
|
||||
"formatted_body": "<b>This is an example<br>text message</b>",
|
||||
"msgtype": "m.text"
|
||||
},
|
||||
"event_id": "$153456789:example.org",
|
||||
"origin_server_ts": 1432735824654,
|
||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||
"sender": "@example:example.org",
|
||||
"type": "m.room.message",
|
||||
"unsigned": {
|
||||
"age": 1232
|
||||
}
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"m.relates_to": {
|
||||
"event_id": "$153456789:example.org",
|
||||
"key": "👍",
|
||||
"rel_type": "m.annotation"
|
||||
}
|
||||
},
|
||||
"origin_server_ts": 1690322545182,
|
||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||
"sender": "@alice:matrix.org",
|
||||
"type": "m.reaction",
|
||||
"unsigned": {
|
||||
"age": 390159120
|
||||
},
|
||||
"event_id": "$163456789:example.org",
|
||||
"age": 390159120
|
||||
}
|
||||
],
|
||||
"limited": true,
|
||||
"prev_batch": "t34-23535_0_0"
|
||||
}
|
||||
}
|
||||
124
autotests/data/test-texthandler-sync.json
Normal file
124
autotests/data/test-texthandler-sync.json
Normal file
@@ -0,0 +1,124 @@
|
||||
{
|
||||
"account_data": {
|
||||
"events": [
|
||||
{
|
||||
"content": {
|
||||
"tags": {
|
||||
"u.work": {
|
||||
"order": 0.9
|
||||
}
|
||||
}
|
||||
},
|
||||
"type": "m.tag"
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"custom_config_key": "custom_config_value"
|
||||
},
|
||||
"type": "org.example.custom.room.config"
|
||||
}
|
||||
]
|
||||
},
|
||||
"ephemeral": {
|
||||
"events": [
|
||||
{
|
||||
"content": {
|
||||
"user_ids": [
|
||||
"@alice:matrix.org",
|
||||
"@bob:example.com"
|
||||
]
|
||||
},
|
||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||
"type": "m.typing"
|
||||
}
|
||||
]
|
||||
},
|
||||
"state": {
|
||||
"events": [
|
||||
{
|
||||
"content": {
|
||||
"avatar_url": "mxc://example.org/SEsfnsuifSDFSSEF",
|
||||
"displayname": "Alice Margatroid",
|
||||
"membership": "join",
|
||||
"reason": "Looking for support"
|
||||
},
|
||||
"event_id": "$143273582443PhrSn:example.org",
|
||||
"origin_server_ts": 1432735824653,
|
||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||
"sender": "@example:example.org",
|
||||
"state_key": "@alice:example.org",
|
||||
"type": "m.room.member",
|
||||
"unsigned": {
|
||||
"age": 1234
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"summary": {
|
||||
"m.heroes": [
|
||||
"@alice:example.com",
|
||||
"@bob:example.com"
|
||||
],
|
||||
"m.invited_member_count": 0,
|
||||
"m.joined_member_count": 2
|
||||
},
|
||||
"timeline": {
|
||||
"events": [
|
||||
{
|
||||
"content": {
|
||||
"body": "This is an **example** text message",
|
||||
"format": "org.matrix.custom.html",
|
||||
"formatted_body": "<b>This is an example text message</b>",
|
||||
"msgtype": "m.text"
|
||||
},
|
||||
"event_id": "$143273582443PhrSn:example.org",
|
||||
"origin_server_ts": 1432735824654,
|
||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||
"sender": "@example:example.org",
|
||||
"type": "m.room.message",
|
||||
"unsigned": {
|
||||
"age": 1232
|
||||
}
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"body": "/me This is an emote.",
|
||||
"format": "org.matrix.custom.html",
|
||||
"formatted_body": "This is an emote.",
|
||||
"msgtype": "m.emote"
|
||||
},
|
||||
"event_id": "$153273582443PhrSn:example.org",
|
||||
"origin_server_ts": 1532735824654,
|
||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||
"sender": "@example:example.org",
|
||||
"type": "m.room.message",
|
||||
"unsigned": {
|
||||
"age": 1231
|
||||
}
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"body": "tested",
|
||||
"msgtype": "m.text"
|
||||
},
|
||||
"event_id": "$zrCiBxBnqqTn0Z5FY78qSZAszno_w8nJJXzfBULG-3E",
|
||||
"origin_server_ts": 1680948575928,
|
||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||
"sender": "@example:example.org",
|
||||
"type": "m.room.message",
|
||||
"unsigned": {
|
||||
"age": 1747776,
|
||||
"m.relations": {
|
||||
"m.replace": {
|
||||
"event_id": "$UX0PlpyI7vYO32iHMuuYEP7ECMh4sX3XLGiB2SwM4mQ",
|
||||
"origin_server_ts": 1680948580992,
|
||||
"sender": "@example:example.org"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"limited": true,
|
||||
"prev_batch": "t34-23535_0_0"
|
||||
}
|
||||
}
|
||||
14
autotests/data/test-validplainlink-event.json
Normal file
14
autotests/data/test-validplainlink-event.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"content": {
|
||||
"body": "https://kde.org",
|
||||
"msgtype": "m.text"
|
||||
},
|
||||
"event_id": "$validlink1:example.org",
|
||||
"origin_server_ts": 1432735824654,
|
||||
"room_id": "!test:example.org",
|
||||
"sender": "@example:example.org",
|
||||
"type": "m.room.message",
|
||||
"unsigned": {
|
||||
"age": 1234
|
||||
}
|
||||
}
|
||||
14
autotests/data/test-validplainwwwlink-event.json
Normal file
14
autotests/data/test-validplainwwwlink-event.json
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"content": {
|
||||
"body": "www.example.org",
|
||||
"msgtype": "m.text"
|
||||
},
|
||||
"event_id": "$validlink1:example.org",
|
||||
"origin_server_ts": 1432735824654,
|
||||
"room_id": "!test:example.org",
|
||||
"sender": "@example:example.org",
|
||||
"type": "m.room.message",
|
||||
"unsigned": {
|
||||
"age": 1234
|
||||
}
|
||||
}
|
||||
16
autotests/data/test-validrichlink-event.json
Normal file
16
autotests/data/test-validrichlink-event.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"content": {
|
||||
"body": "[Rich Link](https://kde.org)",
|
||||
"format": "org.matrix.custom.html",
|
||||
"formatted_body": "<a href=\"https://kde.org\">Rich Link</a>",
|
||||
"msgtype": "m.text"
|
||||
},
|
||||
"event_id": "$validlink1:example.org",
|
||||
"origin_server_ts": 1432735824654,
|
||||
"room_id": "!test:example.org",
|
||||
"sender": "@example:example.org",
|
||||
"type": "m.room.message",
|
||||
"unsigned": {
|
||||
"age": 1234
|
||||
}
|
||||
}
|
||||
156
autotests/delegatesizehelpertest.cpp
Normal file
156
autotests/delegatesizehelpertest.cpp
Normal file
@@ -0,0 +1,156 @@
|
||||
// SPDX-FileCopyrightText: 2023 James Graham <james.h.graham@protonmail.com>
|
||||
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||
|
||||
#include <QObject>
|
||||
#include <QTest>
|
||||
|
||||
#include "delegatesizehelper.h"
|
||||
|
||||
class DelegateSizeHelperTest : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private Q_SLOTS:
|
||||
void risingPercentage_data();
|
||||
void risingPercentage();
|
||||
|
||||
void fallingPercentage_data();
|
||||
void fallingPercentage();
|
||||
|
||||
void equalPercentage_data();
|
||||
void equalPercentage();
|
||||
|
||||
void equalBreakpoint_data();
|
||||
void equalBreakpoint();
|
||||
};
|
||||
|
||||
void DelegateSizeHelperTest::risingPercentage_data()
|
||||
{
|
||||
QTest::addColumn<qreal>("parentWidth");
|
||||
QTest::addColumn<int>("currentPercentageWidth");
|
||||
QTest::addColumn<qreal>("currentWidth");
|
||||
|
||||
QTest::newRow("zero") << qreal(0) << 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("two hundred") << qreal(200) << int(100) << qreal(200);
|
||||
QTest::newRow("three hundred") << qreal(300) << int(100) << qreal(300);
|
||||
}
|
||||
|
||||
void DelegateSizeHelperTest::risingPercentage()
|
||||
{
|
||||
QFETCH(qreal, parentWidth);
|
||||
QFETCH(int, currentPercentageWidth);
|
||||
QFETCH(qreal, currentWidth);
|
||||
|
||||
DelegateSizeHelper delegateSizeHelper;
|
||||
delegateSizeHelper.setStartBreakpoint(100);
|
||||
delegateSizeHelper.setEndBreakpoint(200);
|
||||
delegateSizeHelper.setStartPercentWidth(0);
|
||||
delegateSizeHelper.setEndPercentWidth(100);
|
||||
|
||||
delegateSizeHelper.setParentWidth(parentWidth);
|
||||
|
||||
QCOMPARE(delegateSizeHelper.currentPercentageWidth(), currentPercentageWidth);
|
||||
QCOMPARE(delegateSizeHelper.currentWidth(), currentWidth);
|
||||
}
|
||||
|
||||
void DelegateSizeHelperTest::fallingPercentage_data()
|
||||
{
|
||||
QTest::addColumn<qreal>("parentWidth");
|
||||
QTest::addColumn<int>("currentPercentageWidth");
|
||||
QTest::addColumn<qreal>("currentWidth");
|
||||
|
||||
QTest::newRow("zero") << qreal(0) << int(100) << qreal(0);
|
||||
QTest::newRow("one hundred") << qreal(100) << int(100) << qreal(100);
|
||||
QTest::newRow("one fifty") << qreal(150) << int(50) << qreal(75);
|
||||
QTest::newRow("two hundred") << qreal(200) << int(0) << qreal(0);
|
||||
QTest::newRow("three hundred") << qreal(300) << int(0) << qreal(0);
|
||||
}
|
||||
|
||||
void DelegateSizeHelperTest::fallingPercentage()
|
||||
{
|
||||
QFETCH(qreal, parentWidth);
|
||||
QFETCH(int, currentPercentageWidth);
|
||||
QFETCH(qreal, currentWidth);
|
||||
|
||||
DelegateSizeHelper delegateSizeHelper;
|
||||
delegateSizeHelper.setStartBreakpoint(100);
|
||||
delegateSizeHelper.setEndBreakpoint(200);
|
||||
delegateSizeHelper.setStartPercentWidth(100);
|
||||
delegateSizeHelper.setEndPercentWidth(0);
|
||||
|
||||
delegateSizeHelper.setParentWidth(parentWidth);
|
||||
|
||||
QCOMPARE(delegateSizeHelper.currentPercentageWidth(), currentPercentageWidth);
|
||||
QCOMPARE(delegateSizeHelper.currentWidth(), currentWidth);
|
||||
}
|
||||
|
||||
void DelegateSizeHelperTest::equalPercentage_data()
|
||||
{
|
||||
QTest::addColumn<qreal>("parentWidth");
|
||||
QTest::addColumn<int>("currentPercentageWidth");
|
||||
QTest::addColumn<qreal>("currentWidth");
|
||||
|
||||
QTest::newRow("zero") << qreal(0) << int(50) << qreal(0);
|
||||
QTest::newRow("one hundred") << qreal(100) << int(50) << qreal(50);
|
||||
QTest::newRow("one fifty") << qreal(150) << int(50) << qreal(75);
|
||||
QTest::newRow("two hundred") << qreal(200) << int(50) << qreal(100);
|
||||
QTest::newRow("three hundred") << qreal(300) << int(50) << qreal(150);
|
||||
}
|
||||
|
||||
void DelegateSizeHelperTest::equalPercentage()
|
||||
{
|
||||
QFETCH(qreal, parentWidth);
|
||||
QFETCH(int, currentPercentageWidth);
|
||||
QFETCH(qreal, currentWidth);
|
||||
|
||||
DelegateSizeHelper delegateSizeHelper;
|
||||
delegateSizeHelper.setStartBreakpoint(100);
|
||||
delegateSizeHelper.setEndBreakpoint(200);
|
||||
delegateSizeHelper.setStartPercentWidth(50);
|
||||
delegateSizeHelper.setEndPercentWidth(50);
|
||||
|
||||
delegateSizeHelper.setParentWidth(parentWidth);
|
||||
|
||||
QCOMPARE(delegateSizeHelper.currentPercentageWidth(), currentPercentageWidth);
|
||||
QCOMPARE(delegateSizeHelper.currentWidth(), currentWidth);
|
||||
}
|
||||
|
||||
void DelegateSizeHelperTest::equalBreakpoint_data()
|
||||
{
|
||||
QTest::addColumn<int>("startPercentageWidth");
|
||||
QTest::addColumn<int>("endPercentageWidth");
|
||||
QTest::addColumn<int>("currentPercentageWidth");
|
||||
QTest::addColumn<qreal>("currentWidth");
|
||||
|
||||
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("end higher") << int(0) << int(100) << int(-1) << qreal(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* We expect a default return except in the case where the the two percentages are
|
||||
* equal as that case can be calculated without dividing by zero.
|
||||
*/
|
||||
void DelegateSizeHelperTest::equalBreakpoint()
|
||||
{
|
||||
QFETCH(int, startPercentageWidth);
|
||||
QFETCH(int, endPercentageWidth);
|
||||
QFETCH(int, currentPercentageWidth);
|
||||
QFETCH(qreal, currentWidth);
|
||||
|
||||
DelegateSizeHelper delegateSizeHelper;
|
||||
delegateSizeHelper.setStartBreakpoint(100);
|
||||
delegateSizeHelper.setEndBreakpoint(100);
|
||||
delegateSizeHelper.setStartPercentWidth(startPercentageWidth);
|
||||
delegateSizeHelper.setEndPercentWidth(endPercentageWidth);
|
||||
|
||||
delegateSizeHelper.setParentWidth(1000);
|
||||
|
||||
QCOMPARE(delegateSizeHelper.currentPercentageWidth(), currentPercentageWidth);
|
||||
QCOMPARE(delegateSizeHelper.currentWidth(), currentWidth);
|
||||
}
|
||||
|
||||
QTEST_GUILESS_MAIN(DelegateSizeHelperTest)
|
||||
#include "delegatesizehelpertest.moc"
|
||||
565
autotests/eventhandlertest.cpp
Normal file
565
autotests/eventhandlertest.cpp
Normal file
@@ -0,0 +1,565 @@
|
||||
// SPDX-FileCopyrightText: 2023 James Graham <james.h.graham@protonmail.com>
|
||||
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||
|
||||
#include <QObject>
|
||||
#include <QTest>
|
||||
|
||||
#include "eventhandler.h"
|
||||
|
||||
#include <KFormat>
|
||||
|
||||
#include <Quotient/connection.h>
|
||||
#include <Quotient/quotient_common.h>
|
||||
#include <Quotient/syncdata.h>
|
||||
|
||||
#include "linkpreviewer.h"
|
||||
#include "models/reactionmodel.h"
|
||||
#include "neochatroom.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include "testutils.h"
|
||||
|
||||
using namespace Quotient;
|
||||
|
||||
class EventHandlerTest : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
Connection *connection = nullptr;
|
||||
TestUtils::TestRoom *room = nullptr;
|
||||
|
||||
EventHandler emptyHandler = EventHandler(nullptr, nullptr);
|
||||
|
||||
private Q_SLOTS:
|
||||
void initTestCase();
|
||||
|
||||
void eventId();
|
||||
void nullEventId();
|
||||
void author();
|
||||
void nullAuthor();
|
||||
void authorDisplayName();
|
||||
void nullAuthorDisplayName();
|
||||
void singleLineSidplayName();
|
||||
void nullSingleLineDisplayName();
|
||||
void time();
|
||||
void nullTime();
|
||||
void timeString();
|
||||
void nullTimeString();
|
||||
void highlighted();
|
||||
void nullHighlighted();
|
||||
void hidden();
|
||||
void nullHidden();
|
||||
void body();
|
||||
void nullBody();
|
||||
void genericBody_data();
|
||||
void genericBody();
|
||||
void nullGenericBody();
|
||||
void subtitle();
|
||||
void nullSubtitle();
|
||||
void mediaInfo();
|
||||
void nullMediaInfo();
|
||||
void hasReply();
|
||||
void nullHasReply();
|
||||
void replyId();
|
||||
void nullReplyId();
|
||||
void replyAuthor();
|
||||
void nullReplyAuthor();
|
||||
void replyBody();
|
||||
void nullReplyBody();
|
||||
void replyMediaInfo();
|
||||
void nullReplyMediaInfo();
|
||||
void thread();
|
||||
void nullThread();
|
||||
void location();
|
||||
void nullLocation();
|
||||
void readMarkers();
|
||||
void nullReadMarkers();
|
||||
};
|
||||
|
||||
void EventHandlerTest::initTestCase()
|
||||
{
|
||||
connection = Connection::makeMockConnection(QStringLiteral("@bob:kde.org"));
|
||||
room = new TestUtils::TestRoom(connection, QStringLiteral("#myroom:kde.org"), QLatin1String("test-eventhandler-sync.json"));
|
||||
}
|
||||
|
||||
void EventHandlerTest::eventId()
|
||||
{
|
||||
EventHandler eventHandler(room, room->messageEvents().at(0).get());
|
||||
QCOMPARE(eventHandler.getId(), QStringLiteral("$153456789:example.org"));
|
||||
}
|
||||
|
||||
void EventHandlerTest::nullEventId()
|
||||
{
|
||||
EventHandler noEventHandler(room, nullptr);
|
||||
QTest::ignoreMessage(QtWarningMsg, "getId called with m_event set to nullptr.");
|
||||
QCOMPARE(noEventHandler.getId(), QString());
|
||||
}
|
||||
|
||||
void EventHandlerTest::author()
|
||||
{
|
||||
auto event = room->messageEvents().at(0).get();
|
||||
auto author = room->user(event->senderId());
|
||||
EventHandler eventHandler(room, event);
|
||||
|
||||
auto eventHandlerAuthor = eventHandler.getAuthor();
|
||||
|
||||
QCOMPARE(eventHandlerAuthor["isLocalUser"_ls], author->id() == room->localUser()->id());
|
||||
QCOMPARE(eventHandlerAuthor["id"_ls], author->id());
|
||||
QCOMPARE(eventHandlerAuthor["displayName"_ls], author->displayname(room));
|
||||
QCOMPARE(eventHandlerAuthor["avatarSource"_ls], room->avatarForMember(author));
|
||||
QCOMPARE(eventHandlerAuthor["avatarMediaId"_ls], author->avatarMediaId(room));
|
||||
QCOMPARE(eventHandlerAuthor["color"_ls], Utils::getUserColor(author->hueF()));
|
||||
QCOMPARE(eventHandlerAuthor["object"_ls], QVariant::fromValue(author));
|
||||
}
|
||||
|
||||
void EventHandlerTest::nullAuthor()
|
||||
{
|
||||
QTest::ignoreMessage(QtWarningMsg, "getAuthor called with m_room set to nullptr.");
|
||||
QCOMPARE(emptyHandler.getAuthor(), QVariantMap());
|
||||
|
||||
EventHandler noEventHandler(room, nullptr);
|
||||
QTest::ignoreMessage(QtWarningMsg, "getAuthor called with m_event set to nullptr. Returning empty user.");
|
||||
QCOMPARE(noEventHandler.getAuthor(), room->getUser(nullptr));
|
||||
}
|
||||
|
||||
void EventHandlerTest::authorDisplayName()
|
||||
{
|
||||
EventHandler eventHandler(room, room->messageEvents().at(1).get());
|
||||
QCOMPARE(eventHandler.getAuthorDisplayName(), QStringLiteral("before"));
|
||||
}
|
||||
|
||||
void EventHandlerTest::nullAuthorDisplayName()
|
||||
{
|
||||
QTest::ignoreMessage(QtWarningMsg, "getAuthorDisplayName called with m_room set to nullptr.");
|
||||
QCOMPARE(emptyHandler.getAuthorDisplayName(), QString());
|
||||
|
||||
EventHandler noEventHandler(room, nullptr);
|
||||
QTest::ignoreMessage(QtWarningMsg, "getAuthorDisplayName called with m_event set to nullptr.");
|
||||
QCOMPARE(noEventHandler.getAuthorDisplayName(), QString());
|
||||
}
|
||||
|
||||
void EventHandlerTest::singleLineSidplayName()
|
||||
{
|
||||
EventHandler eventHandler(room, room->messageEvents().at(11).get());
|
||||
QCOMPARE(eventHandler.singleLineAuthorDisplayname(), QStringLiteral("Look at me I put newlines in my display name"));
|
||||
}
|
||||
|
||||
void EventHandlerTest::nullSingleLineDisplayName()
|
||||
{
|
||||
QTest::ignoreMessage(QtWarningMsg, "getAuthorDisplayName called with m_room set to nullptr.");
|
||||
QCOMPARE(emptyHandler.singleLineAuthorDisplayname(), QString());
|
||||
|
||||
EventHandler noEventHandler(room, nullptr);
|
||||
QTest::ignoreMessage(QtWarningMsg, "getAuthorDisplayName called with m_event set to nullptr.");
|
||||
QCOMPARE(noEventHandler.singleLineAuthorDisplayname(), QString());
|
||||
}
|
||||
|
||||
void EventHandlerTest::time()
|
||||
{
|
||||
EventHandler eventHandler(room, room->messageEvents().at(0).get());
|
||||
|
||||
QCOMPARE(eventHandler.getTime(), QDateTime::fromMSecsSinceEpoch(1432735824654, Qt::UTC));
|
||||
QCOMPARE(eventHandler.getTime(true, QDateTime::fromMSecsSinceEpoch(1234, Qt::UTC)), QDateTime::fromMSecsSinceEpoch(1234, Qt::UTC));
|
||||
}
|
||||
|
||||
void EventHandlerTest::nullTime()
|
||||
{
|
||||
EventHandler noEventHandler(room, nullptr);
|
||||
QTest::ignoreMessage(QtWarningMsg, "getTime called with m_event set to nullptr.");
|
||||
QCOMPARE(noEventHandler.getTime(), QDateTime());
|
||||
|
||||
EventHandler eventHandler(room, room->messageEvents().at(0).get());
|
||||
QTest::ignoreMessage(QtWarningMsg, "a value must be provided for lastUpdated for a pending event.");
|
||||
QCOMPARE(eventHandler.getTime(true), QDateTime());
|
||||
}
|
||||
|
||||
void EventHandlerTest::timeString()
|
||||
{
|
||||
EventHandler eventHandler(room, room->messageEvents().at(0).get());
|
||||
|
||||
KFormat format;
|
||||
|
||||
QCOMPARE(eventHandler.getTimeString(false),
|
||||
QLocale().toString(QDateTime::fromMSecsSinceEpoch(1432735824654, Qt::UTC).toLocalTime().time(), QLocale::ShortFormat));
|
||||
QCOMPARE(eventHandler.getTimeString(true),
|
||||
format.formatRelativeDate(QDateTime::fromMSecsSinceEpoch(1432735824654, Qt::UTC).toLocalTime().date(), QLocale::ShortFormat));
|
||||
QCOMPARE(eventHandler.getTimeString(false, QLocale::ShortFormat, true, QDateTime::fromMSecsSinceEpoch(1690699214545, Qt::UTC)),
|
||||
QLocale().toString(QDateTime::fromMSecsSinceEpoch(1690699214545, Qt::UTC).toLocalTime().time(), QLocale::ShortFormat));
|
||||
QCOMPARE(eventHandler.getTimeString(true, QLocale::ShortFormat, true, QDateTime::fromMSecsSinceEpoch(1690699214545, Qt::UTC)),
|
||||
format.formatRelativeDate(QDateTime::fromMSecsSinceEpoch(1690699214545, Qt::UTC).toLocalTime().date(), QLocale::ShortFormat));
|
||||
QCOMPARE(eventHandler.getTimeString(false, QLocale::LongFormat, true, QDateTime::fromMSecsSinceEpoch(1690699214545, Qt::UTC)),
|
||||
QLocale().toString(QDateTime::fromMSecsSinceEpoch(1690699214545, Qt::UTC).toLocalTime().time(), QLocale::LongFormat));
|
||||
QCOMPARE(eventHandler.getTimeString(true, QLocale::LongFormat, true, QDateTime::fromMSecsSinceEpoch(1690699214545, Qt::UTC)),
|
||||
format.formatRelativeDate(QDateTime::fromMSecsSinceEpoch(1690699214545, Qt::UTC).toLocalTime().date(), QLocale::LongFormat));
|
||||
}
|
||||
|
||||
void EventHandlerTest::nullTimeString()
|
||||
{
|
||||
EventHandler noEventHandler(room, nullptr);
|
||||
QTest::ignoreMessage(QtWarningMsg, "getTimeString called with m_event set to nullptr.");
|
||||
QCOMPARE(noEventHandler.getTimeString(false), QString());
|
||||
|
||||
EventHandler eventHandler(room, room->messageEvents().at(0).get());
|
||||
QTest::ignoreMessage(QtWarningMsg, "a value must be provided for lastUpdated for a pending event.");
|
||||
QCOMPARE(eventHandler.getTimeString(false, QLocale::ShortFormat, true), QString());
|
||||
}
|
||||
|
||||
void EventHandlerTest::highlighted()
|
||||
{
|
||||
EventHandler eventHandlerHighlight(room, room->messageEvents().at(2).get());
|
||||
QCOMPARE(eventHandlerHighlight.isHighlighted(), true);
|
||||
|
||||
EventHandler eventHandlerNoHighlight(room, room->messageEvents().at(0).get());
|
||||
QCOMPARE(eventHandlerNoHighlight.isHighlighted(), false);
|
||||
}
|
||||
|
||||
void EventHandlerTest::nullHighlighted()
|
||||
{
|
||||
QTest::ignoreMessage(QtWarningMsg, "isHighlighted called with m_room set to nullptr.");
|
||||
QCOMPARE(emptyHandler.isHighlighted(), false);
|
||||
|
||||
EventHandler noEventHandler(room, nullptr);
|
||||
QTest::ignoreMessage(QtWarningMsg, "isHighlighted called with m_event set to nullptr.");
|
||||
QCOMPARE(noEventHandler.isHighlighted(), false);
|
||||
}
|
||||
|
||||
void EventHandlerTest::hidden()
|
||||
{
|
||||
EventHandler eventHandlerHidden(room, room->messageEvents().at(3).get());
|
||||
QCOMPARE(eventHandlerHidden.isHidden(), true);
|
||||
|
||||
EventHandler eventHandlerNoHidden(room, room->messageEvents().at(0).get());
|
||||
QCOMPARE(eventHandlerNoHidden.isHidden(), false);
|
||||
}
|
||||
|
||||
void EventHandlerTest::nullHidden()
|
||||
{
|
||||
QTest::ignoreMessage(QtWarningMsg, "isHidden called with m_room set to nullptr.");
|
||||
QCOMPARE(emptyHandler.isHidden(), false);
|
||||
|
||||
EventHandler noEventHandler(room, nullptr);
|
||||
QTest::ignoreMessage(QtWarningMsg, "isHidden called with m_event set to nullptr.");
|
||||
QCOMPARE(noEventHandler.isHidden(), false);
|
||||
}
|
||||
|
||||
void EventHandlerTest::body()
|
||||
{
|
||||
EventHandler eventHandler(room, room->messageEvents().at(0).get());
|
||||
|
||||
QCOMPARE(eventHandler.getRichBody(), QStringLiteral("<b>This is an example<br>text message</b>"));
|
||||
QCOMPARE(eventHandler.getRichBody(true), QStringLiteral("<b>This is an example text message</b>"));
|
||||
QCOMPARE(eventHandler.getPlainBody(), QStringLiteral("This is an example\ntext message"));
|
||||
QCOMPARE(eventHandler.getPlainBody(true), QStringLiteral("This is an example text message"));
|
||||
}
|
||||
|
||||
void EventHandlerTest::nullBody()
|
||||
{
|
||||
EventHandler noEventHandler(room, nullptr);
|
||||
|
||||
QTest::ignoreMessage(QtWarningMsg, "getRichBody called with m_event set to nullptr.");
|
||||
QCOMPARE(noEventHandler.getRichBody(), QString());
|
||||
|
||||
QTest::ignoreMessage(QtWarningMsg, "getPlainBody called with m_event set to nullptr.");
|
||||
QCOMPARE(noEventHandler.getPlainBody(), QString());
|
||||
}
|
||||
|
||||
void EventHandlerTest::genericBody_data()
|
||||
{
|
||||
QTest::addColumn<int>("eventNum");
|
||||
QTest::addColumn<QString>("output");
|
||||
|
||||
QTest::newRow("message") << 0 << QStringLiteral("sent a message");
|
||||
QTest::newRow("member") << 1 << QStringLiteral("changed their display name and updated their avatar");
|
||||
QTest::newRow("message 2") << 2 << QStringLiteral("sent a message");
|
||||
QTest::newRow("reaction") << 3 << QStringLiteral("Unknown event");
|
||||
QTest::newRow("video") << 4 << QStringLiteral("sent a message");
|
||||
}
|
||||
|
||||
void EventHandlerTest::genericBody()
|
||||
{
|
||||
QFETCH(int, eventNum);
|
||||
QFETCH(QString, output);
|
||||
|
||||
EventHandler eventHandler(room, room->messageEvents().at(eventNum).get());
|
||||
|
||||
QCOMPARE(eventHandler.getGenericBody(), output);
|
||||
}
|
||||
|
||||
void EventHandlerTest::nullGenericBody()
|
||||
{
|
||||
EventHandler noEventHandler(room, nullptr);
|
||||
QTest::ignoreMessage(QtWarningMsg, "getGenericBody called with m_event set to nullptr.");
|
||||
QCOMPARE(noEventHandler.getGenericBody(), QString());
|
||||
}
|
||||
|
||||
void EventHandlerTest::subtitle()
|
||||
{
|
||||
EventHandler eventHandler(room, room->messageEvents().at(0).get());
|
||||
QCOMPARE(eventHandler.subtitleText(), QStringLiteral("after: This is an example text message"));
|
||||
|
||||
EventHandler eventHandler2(room, room->messageEvents().at(2).get());
|
||||
QCOMPARE(eventHandler2.subtitleText(), QStringLiteral("after: This is a highlight @bob:kde.org and this is a link https://kde.org"));
|
||||
}
|
||||
|
||||
void EventHandlerTest::nullSubtitle()
|
||||
{
|
||||
EventHandler noEventHandler(room, nullptr);
|
||||
QTest::ignoreMessage(QtWarningMsg, "subtitleText called with m_event set to nullptr.");
|
||||
QCOMPARE(noEventHandler.subtitleText(), QString());
|
||||
}
|
||||
|
||||
void EventHandlerTest::mediaInfo()
|
||||
{
|
||||
auto event = room->messageEvents().at(4).get();
|
||||
EventHandler eventHandler(room, event);
|
||||
|
||||
auto mediaInfo = eventHandler.getMediaInfo();
|
||||
auto thumbnailInfo = mediaInfo["tempInfo"_ls].toMap();
|
||||
|
||||
QCOMPARE(mediaInfo["source"_ls], room->makeMediaUrl(event->id(), QUrl("mxc://kde.org/1234567"_ls)));
|
||||
QCOMPARE(mediaInfo["mimeType"_ls], QStringLiteral("video/mp4"));
|
||||
QCOMPARE(mediaInfo["mimeIcon"_ls], QStringLiteral("video-mp4"));
|
||||
QCOMPARE(mediaInfo["size"_ls], 62650636);
|
||||
QCOMPARE(mediaInfo["duration"_ls], 10);
|
||||
QCOMPARE(mediaInfo["width"_ls], 1920);
|
||||
QCOMPARE(mediaInfo["height"_ls], 1080);
|
||||
QCOMPARE(thumbnailInfo["source"_ls], room->makeMediaUrl(event->id(), QUrl("mxc://kde.org/2234567"_ls)));
|
||||
QCOMPARE(thumbnailInfo["mimeType"_ls], QStringLiteral("image/jpeg"));
|
||||
QCOMPARE(thumbnailInfo["mimeIcon"_ls], QStringLiteral("image-jpeg"));
|
||||
QCOMPARE(thumbnailInfo["size"_ls], 382249);
|
||||
QCOMPARE(thumbnailInfo["width"_ls], 800);
|
||||
QCOMPARE(thumbnailInfo["height"_ls], 450);
|
||||
}
|
||||
|
||||
void EventHandlerTest::nullMediaInfo()
|
||||
{
|
||||
QTest::ignoreMessage(QtWarningMsg, "getMediaInfo called with m_room set to nullptr.");
|
||||
QCOMPARE(emptyHandler.getMediaInfo(), QVariantMap());
|
||||
|
||||
EventHandler noEventHandler(room, nullptr);
|
||||
QTest::ignoreMessage(QtWarningMsg, "getMediaInfo called with m_event set to nullptr.");
|
||||
QCOMPARE(noEventHandler.getMediaInfo(), QVariantMap());
|
||||
}
|
||||
|
||||
void EventHandlerTest::hasReply()
|
||||
{
|
||||
EventHandler eventHandlerReply(room, room->messageEvents().at(5).get());
|
||||
QCOMPARE(eventHandlerReply.hasReply(), true);
|
||||
|
||||
EventHandler eventHandlerNoReply(room, room->messageEvents().at(0).get());
|
||||
QCOMPARE(eventHandlerNoReply.hasReply(), false);
|
||||
}
|
||||
|
||||
void EventHandlerTest::nullHasReply()
|
||||
{
|
||||
EventHandler noEventHandler(room, nullptr);
|
||||
QTest::ignoreMessage(QtWarningMsg, "hasReply called with m_event set to nullptr.");
|
||||
QCOMPARE(noEventHandler.hasReply(), false);
|
||||
}
|
||||
|
||||
void EventHandlerTest::replyId()
|
||||
{
|
||||
EventHandler eventHandlerReply(room, room->messageEvents().at(5).get());
|
||||
QCOMPARE(eventHandlerReply.getReplyId(), QStringLiteral("$153456789:example.org"));
|
||||
|
||||
EventHandler eventHandlerNoReply(room, room->messageEvents().at(0).get());
|
||||
QCOMPARE(eventHandlerNoReply.getReplyId(), QStringLiteral(""));
|
||||
}
|
||||
|
||||
void EventHandlerTest::nullReplyId()
|
||||
{
|
||||
EventHandler noEventHandler(room, nullptr);
|
||||
QTest::ignoreMessage(QtWarningMsg, "getReplyId called with m_event set to nullptr.");
|
||||
QCOMPARE(noEventHandler.getReplyId(), QString());
|
||||
}
|
||||
|
||||
void EventHandlerTest::replyAuthor()
|
||||
{
|
||||
auto replyEvent = room->messageEvents().at(0).get();
|
||||
auto replyAuthor = room->user(replyEvent->senderId());
|
||||
EventHandler eventHandler(room, room->messageEvents().at(5).get());
|
||||
|
||||
auto eventHandlerReplyAuthor = eventHandler.getReplyAuthor();
|
||||
|
||||
QCOMPARE(eventHandlerReplyAuthor["isLocalUser"_ls], replyAuthor->id() == room->localUser()->id());
|
||||
QCOMPARE(eventHandlerReplyAuthor["id"_ls], replyAuthor->id());
|
||||
QCOMPARE(eventHandlerReplyAuthor["displayName"_ls], replyAuthor->displayname(room));
|
||||
QCOMPARE(eventHandlerReplyAuthor["avatarSource"_ls], room->avatarForMember(replyAuthor));
|
||||
QCOMPARE(eventHandlerReplyAuthor["avatarMediaId"_ls], replyAuthor->avatarMediaId(room));
|
||||
QCOMPARE(eventHandlerReplyAuthor["color"_ls], Utils::getUserColor(replyAuthor->hueF()));
|
||||
QCOMPARE(eventHandlerReplyAuthor["object"_ls], QVariant::fromValue(replyAuthor));
|
||||
|
||||
EventHandler eventHandlerNoAuthor(room, room->messageEvents().at(0).get());
|
||||
QCOMPARE(eventHandlerNoAuthor.getReplyAuthor(), room->getUser(nullptr));
|
||||
}
|
||||
|
||||
void EventHandlerTest::nullReplyAuthor()
|
||||
{
|
||||
QTest::ignoreMessage(QtWarningMsg, "getReplyAuthor called with m_room set to nullptr.");
|
||||
QCOMPARE(emptyHandler.getReplyAuthor(), QVariantMap());
|
||||
|
||||
EventHandler noEventHandler(room, nullptr);
|
||||
QTest::ignoreMessage(QtWarningMsg, "getReplyAuthor called with m_event set to nullptr. Returning empty user.");
|
||||
QCOMPARE(noEventHandler.getReplyAuthor(), room->getUser(nullptr));
|
||||
}
|
||||
|
||||
void EventHandlerTest::replyBody()
|
||||
{
|
||||
EventHandler eventHandler(room, room->messageEvents().at(5).get());
|
||||
|
||||
QCOMPARE(eventHandler.getReplyRichBody(), QStringLiteral("<b>This is an example<br>text message</b>"));
|
||||
QCOMPARE(eventHandler.getReplyRichBody(true), QStringLiteral("<b>This is an example text message</b>"));
|
||||
QCOMPARE(eventHandler.getReplyPlainBody(), QStringLiteral("This is an example\ntext message"));
|
||||
QCOMPARE(eventHandler.getReplyPlainBody(true), QStringLiteral("This is an example text message"));
|
||||
}
|
||||
|
||||
void EventHandlerTest::nullReplyBody()
|
||||
{
|
||||
EventHandler noEventHandler(room, nullptr);
|
||||
|
||||
QTest::ignoreMessage(QtWarningMsg, "getReplyRichBody called with m_event set to nullptr.");
|
||||
QCOMPARE(noEventHandler.getReplyRichBody(), QString());
|
||||
|
||||
QTest::ignoreMessage(QtWarningMsg, "getReplyPlainBody called with m_event set to nullptr.");
|
||||
QCOMPARE(noEventHandler.getReplyPlainBody(), QString());
|
||||
}
|
||||
|
||||
void EventHandlerTest::replyMediaInfo()
|
||||
{
|
||||
auto event = room->messageEvents().at(6).get();
|
||||
auto replyEvent = room->messageEvents().at(4).get();
|
||||
EventHandler eventHandler(room, event);
|
||||
|
||||
auto mediaInfo = eventHandler.getReplyMediaInfo();
|
||||
auto thumbnailInfo = mediaInfo["tempInfo"_ls].toMap();
|
||||
|
||||
QCOMPARE(mediaInfo["source"_ls], room->makeMediaUrl(replyEvent->id(), QUrl("mxc://kde.org/1234567"_ls)));
|
||||
QCOMPARE(mediaInfo["mimeType"_ls], QStringLiteral("video/mp4"));
|
||||
QCOMPARE(mediaInfo["mimeIcon"_ls], QStringLiteral("video-mp4"));
|
||||
QCOMPARE(mediaInfo["size"_ls], 62650636);
|
||||
QCOMPARE(mediaInfo["duration"_ls], 10);
|
||||
QCOMPARE(mediaInfo["width"_ls], 1920);
|
||||
QCOMPARE(mediaInfo["height"_ls], 1080);
|
||||
QCOMPARE(thumbnailInfo["source"_ls], room->makeMediaUrl(replyEvent->id(), QUrl("mxc://kde.org/2234567"_ls)));
|
||||
QCOMPARE(thumbnailInfo["mimeType"_ls], QStringLiteral("image/jpeg"));
|
||||
QCOMPARE(thumbnailInfo["mimeIcon"_ls], QStringLiteral("image-jpeg"));
|
||||
QCOMPARE(thumbnailInfo["size"_ls], 382249);
|
||||
QCOMPARE(thumbnailInfo["width"_ls], 800);
|
||||
QCOMPARE(thumbnailInfo["height"_ls], 450);
|
||||
}
|
||||
|
||||
void EventHandlerTest::nullReplyMediaInfo()
|
||||
{
|
||||
QTest::ignoreMessage(QtWarningMsg, "getReplyMediaInfo called with m_room set to nullptr.");
|
||||
QCOMPARE(emptyHandler.getReplyMediaInfo(), QVariantMap());
|
||||
|
||||
EventHandler noEventHandler(room, nullptr);
|
||||
QTest::ignoreMessage(QtWarningMsg, "getReplyMediaInfo called with m_event set to nullptr.");
|
||||
QCOMPARE(noEventHandler.getReplyMediaInfo(), QVariantMap());
|
||||
}
|
||||
|
||||
void EventHandlerTest::thread()
|
||||
{
|
||||
EventHandler eventHandlerNoThread(room, room->messageEvents().at(0).get());
|
||||
QCOMPARE(eventHandlerNoThread.isThreaded(), false);
|
||||
QCOMPARE(eventHandlerNoThread.threadRoot(), QString());
|
||||
|
||||
EventHandler eventHandlerThreadRoot(room, room->messageEvents().at(9).get());
|
||||
QCOMPARE(eventHandlerThreadRoot.isThreaded(), true);
|
||||
QCOMPARE(eventHandlerThreadRoot.threadRoot(), QStringLiteral("$threadroot:example.org"));
|
||||
QCOMPARE(eventHandlerThreadRoot.getReplyId(), QStringLiteral("$threadroot:example.org"));
|
||||
|
||||
EventHandler eventHandlerThreadReply(room, room->messageEvents().at(10).get());
|
||||
QCOMPARE(eventHandlerThreadReply.isThreaded(), true);
|
||||
QCOMPARE(eventHandlerThreadReply.threadRoot(), QStringLiteral("$threadroot:example.org"));
|
||||
QCOMPARE(eventHandlerThreadReply.getReplyId(), QStringLiteral("$threadmessage1:example.org"));
|
||||
}
|
||||
|
||||
void EventHandlerTest::nullThread()
|
||||
{
|
||||
QTest::ignoreMessage(QtWarningMsg, "isThreaded called with m_event set to nullptr.");
|
||||
QCOMPARE(emptyHandler.isThreaded(), false);
|
||||
|
||||
EventHandler noEventHandler(room, nullptr);
|
||||
QTest::ignoreMessage(QtWarningMsg, "threadRoot called with m_event set to nullptr.");
|
||||
QCOMPARE(noEventHandler.threadRoot(), QString());
|
||||
}
|
||||
|
||||
void EventHandlerTest::location()
|
||||
{
|
||||
EventHandler eventHandler(room, room->messageEvents().at(7).get());
|
||||
|
||||
QCOMPARE(eventHandler.getLatitude(), QStringLiteral("51.7035").toFloat());
|
||||
QCOMPARE(eventHandler.getLongitude(), QStringLiteral("-1.14394").toFloat());
|
||||
QCOMPARE(eventHandler.getLocationAssetType(), QStringLiteral("m.pin"));
|
||||
}
|
||||
|
||||
void EventHandlerTest::nullLocation()
|
||||
{
|
||||
QTest::ignoreMessage(QtWarningMsg, "getLatitude called with m_event set to nullptr.");
|
||||
QCOMPARE(emptyHandler.getLatitude(), -100.0);
|
||||
|
||||
QTest::ignoreMessage(QtWarningMsg, "getLongitude called with m_event set to nullptr.");
|
||||
QCOMPARE(emptyHandler.getLongitude(), -200.0);
|
||||
|
||||
QTest::ignoreMessage(QtWarningMsg, "getLocationAssetType called with m_event set to nullptr.");
|
||||
QCOMPARE(emptyHandler.getLocationAssetType(), QString());
|
||||
}
|
||||
|
||||
void EventHandlerTest::readMarkers()
|
||||
{
|
||||
EventHandler eventHandler(room, room->messageEvents().at(0).get());
|
||||
QCOMPARE(eventHandler.hasReadMarkers(), true);
|
||||
|
||||
auto readMarkers = eventHandler.getReadMarkers();
|
||||
|
||||
QCOMPARE(readMarkers.size(), 1);
|
||||
QCOMPARE(readMarkers[0].toMap()["id"_ls], QStringLiteral("@alice:matrix.org"));
|
||||
|
||||
QCOMPARE(eventHandler.getNumberExcessReadMarkers(), QString());
|
||||
QCOMPARE(eventHandler.getReadMarkersString(), QStringLiteral("1 user: @alice:matrix.org"));
|
||||
|
||||
EventHandler eventHandler2(room, room->messageEvents().at(2).get());
|
||||
QCOMPARE(eventHandler2.hasReadMarkers(), true);
|
||||
|
||||
readMarkers = eventHandler2.getReadMarkers();
|
||||
|
||||
QCOMPARE(readMarkers.size(), 5);
|
||||
|
||||
QCOMPARE(eventHandler2.getNumberExcessReadMarkers(), QStringLiteral("+ 1"));
|
||||
// There are no guarantees on the order of the users it will be different every time so don't match the whole string.
|
||||
QCOMPARE(eventHandler2.getReadMarkersString().startsWith(QStringLiteral("6 users:")), true);
|
||||
}
|
||||
|
||||
void EventHandlerTest::nullReadMarkers()
|
||||
{
|
||||
QTest::ignoreMessage(QtWarningMsg, "hasReadMarkers called with m_room set to nullptr.");
|
||||
QCOMPARE(emptyHandler.hasReadMarkers(), false);
|
||||
|
||||
QTest::ignoreMessage(QtWarningMsg, "getReadMarkers called with m_room set to nullptr.");
|
||||
QCOMPARE(emptyHandler.getReadMarkers(), QVariantList());
|
||||
|
||||
QTest::ignoreMessage(QtWarningMsg, "getNumberExcessReadMarkers called with m_room set to nullptr.");
|
||||
QCOMPARE(emptyHandler.getNumberExcessReadMarkers(), QString());
|
||||
|
||||
QTest::ignoreMessage(QtWarningMsg, "getReadMarkersString called with m_room set to nullptr.");
|
||||
QCOMPARE(emptyHandler.getReadMarkersString(), QString());
|
||||
|
||||
EventHandler noEventHandler(room, nullptr);
|
||||
|
||||
QTest::ignoreMessage(QtWarningMsg, "hasReadMarkers called with m_event set to nullptr.");
|
||||
QCOMPARE(noEventHandler.hasReadMarkers(), false);
|
||||
|
||||
QTest::ignoreMessage(QtWarningMsg, "getReadMarkers called with m_event set to nullptr.");
|
||||
QCOMPARE(noEventHandler.getReadMarkers(), QVariantList());
|
||||
|
||||
QTest::ignoreMessage(QtWarningMsg, "getNumberExcessReadMarkers called with m_event set to nullptr.");
|
||||
QCOMPARE(noEventHandler.getNumberExcessReadMarkers(), QString());
|
||||
|
||||
QTest::ignoreMessage(QtWarningMsg, "getReadMarkersString called with m_event set to nullptr.");
|
||||
QCOMPARE(noEventHandler.getReadMarkersString(), QString());
|
||||
}
|
||||
|
||||
QTEST_MAIN(EventHandlerTest)
|
||||
#include "eventhandlertest.moc"
|
||||
104
autotests/linkpreviewertest.cpp
Normal file
104
autotests/linkpreviewertest.cpp
Normal file
@@ -0,0 +1,104 @@
|
||||
// SPDX-FileCopyrightText: 2023 James Graham <james.h.graham@protonmail.com>
|
||||
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||
|
||||
#include <QObject>
|
||||
#include <QTest>
|
||||
|
||||
#include "linkpreviewer.h"
|
||||
|
||||
#include <Quotient/events/roommessageevent.h>
|
||||
#include <Quotient/quotient_common.h>
|
||||
#include <Quotient/syncdata.h>
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
#include "testutils.h"
|
||||
|
||||
using namespace Quotient;
|
||||
|
||||
class LinkPreviewerTest : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
Connection *connection = nullptr;
|
||||
TestUtils::TestRoom *room = nullptr;
|
||||
|
||||
private Q_SLOTS:
|
||||
void initTestCase();
|
||||
|
||||
void linkPreviewsMatch_data();
|
||||
void linkPreviewsMatch();
|
||||
|
||||
void linkPreviewsReject_data();
|
||||
void linkPreviewsReject();
|
||||
|
||||
void editedLink();
|
||||
};
|
||||
|
||||
void LinkPreviewerTest::initTestCase()
|
||||
{
|
||||
connection = Connection::makeMockConnection(QStringLiteral("@bob:example.org"));
|
||||
room = new TestUtils::TestRoom(connection, QStringLiteral("!test:example.org"));
|
||||
}
|
||||
|
||||
void LinkPreviewerTest::linkPreviewsMatch_data()
|
||||
{
|
||||
QTest::addColumn<QString>("eventSource");
|
||||
QTest::addColumn<QUrl>("testOutputLink");
|
||||
|
||||
QTest::newRow("plainHttps") << QStringLiteral("test-validplainlink-event.json") << QUrl("https://kde.org"_ls);
|
||||
QTest::newRow("richHttps") << QStringLiteral("test-validrichlink-event.json") << QUrl("https://kde.org"_ls);
|
||||
QTest::newRow("plainWww") << QStringLiteral("test-validplainwwwlink-event.json") << QUrl("www.example.org"_ls);
|
||||
QTest::newRow("multipleHttps") << QStringLiteral("test-multiplelink-event.json") << QUrl("www.example.org"_ls);
|
||||
}
|
||||
|
||||
void LinkPreviewerTest::linkPreviewsMatch()
|
||||
{
|
||||
QFETCH(QString, eventSource);
|
||||
QFETCH(QUrl, testOutputLink);
|
||||
|
||||
auto event = TestUtils::loadEventFromFile<RoomMessageEvent>(eventSource);
|
||||
auto linkPreviewer = LinkPreviewer(room, event.get());
|
||||
|
||||
QCOMPARE(linkPreviewer.empty(), false);
|
||||
QCOMPARE(linkPreviewer.url(), testOutputLink);
|
||||
}
|
||||
|
||||
void LinkPreviewerTest::linkPreviewsReject_data()
|
||||
{
|
||||
QTest::addColumn<QString>("eventSource");
|
||||
|
||||
QTest::newRow("mxc") << QStringLiteral("test-invalidmxclink-event.json");
|
||||
QTest::newRow("matrixTo") << QStringLiteral("test-invalidmatrixtolink-event.json");
|
||||
QTest::newRow("noSpace") << QStringLiteral("test-invalidnospacelink-event.json");
|
||||
}
|
||||
|
||||
void LinkPreviewerTest::linkPreviewsReject()
|
||||
{
|
||||
QFETCH(QString, eventSource);
|
||||
|
||||
auto event = TestUtils::loadEventFromFile<RoomMessageEvent>(eventSource);
|
||||
auto linkPreviewer = LinkPreviewer(room, event.get());
|
||||
|
||||
QCOMPARE(linkPreviewer.empty(), true);
|
||||
QCOMPARE(linkPreviewer.url(), QUrl());
|
||||
}
|
||||
|
||||
void LinkPreviewerTest::editedLink()
|
||||
{
|
||||
room->syncNewEvents(QStringLiteral("test-linkpreviewerintial-sync.json"));
|
||||
auto event = eventCast<const RoomMessageEvent>(room->messageEvents().at(0).get());
|
||||
auto linkPreviewer = LinkPreviewer(room, event);
|
||||
|
||||
QCOMPARE(linkPreviewer.empty(), false);
|
||||
QCOMPARE(linkPreviewer.url(), QUrl("https://kde.org"_ls));
|
||||
|
||||
room->syncNewEvents(QStringLiteral("test-linkpreviewerreplace-sync.json"));
|
||||
|
||||
QCOMPARE(linkPreviewer.empty(), true);
|
||||
QCOMPARE(linkPreviewer.url(), QUrl());
|
||||
}
|
||||
|
||||
QTEST_MAIN(LinkPreviewerTest)
|
||||
#include "linkpreviewertest.moc"
|
||||
72
autotests/mediasizehelpertest.cpp
Normal file
72
autotests/mediasizehelpertest.cpp
Normal file
@@ -0,0 +1,72 @@
|
||||
// SPDX-FileCopyrightText: 2023 James Graham <james.h.graham@protonmail.com>
|
||||
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||
|
||||
#include <QObject>
|
||||
#include <QTest>
|
||||
#include <qglobal.h>
|
||||
#include <qtestcase.h>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include "mediasizehelper.h"
|
||||
#include "neochatconfig.h"
|
||||
|
||||
class MediaSizeHelperTest : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private Q_SLOTS:
|
||||
void uninitialized();
|
||||
|
||||
void limits_data();
|
||||
void limits();
|
||||
};
|
||||
|
||||
void MediaSizeHelperTest::uninitialized()
|
||||
{
|
||||
MediaSizeHelper mediasizehelper;
|
||||
QCOMPARE(mediasizehelper.currentSize(), QSize(540, qRound(qreal(NeoChatConfig::self()->mediaMaxWidth()) / qreal(16.0) * qreal(9.0))));
|
||||
}
|
||||
|
||||
void MediaSizeHelperTest::limits_data()
|
||||
{
|
||||
QTest::addColumn<qreal>("mediaWidth");
|
||||
QTest::addColumn<qreal>("mediaHeight");
|
||||
QTest::addColumn<qreal>("contentMaxWidth");
|
||||
QTest::addColumn<qreal>("contentMaxHeight");
|
||||
QTest::addColumn<QSize>("currentSize");
|
||||
|
||||
QTest::newRow("media smaller than content limits") << qreal(200) << qreal(150) << qreal(400) << qreal(900) << QSize(200, 150);
|
||||
QTest::newRow("media smaller than max limits") << qreal(200) << qreal(150) << qreal(-1) << qreal(-1) << QSize(200, 150);
|
||||
|
||||
QTest::newRow("limit by max width") << qreal(600) << qreal(50) << qreal(-1) << qreal(-1) << QSize(540, qRound(qreal(540) / (qreal(600) / qreal(50))));
|
||||
QTest::newRow("limit by max height") << qreal(50) << qreal(600) << qreal(-1) << qreal(-1) << QSize(qRound(qreal(540) * (qreal(50) / qreal(600))), 540);
|
||||
|
||||
QTest::newRow("limit by content width") << qreal(600) << qreal(50) << qreal(300) << qreal(-1) << QSize(300, qRound(qreal(300) / (qreal(600) / qreal(50))));
|
||||
QTest::newRow("limit by content height") << qreal(50) << qreal(600) << qreal(-1) << qreal(300) << QSize(qRound(qreal(300) * (qreal(50) / qreal(600))), 300);
|
||||
|
||||
QTest::newRow("limit by content width tall media")
|
||||
<< qreal(400) << qreal(600) << qreal(100) << qreal(400) << QSize(100, qRound(qreal(100) / (qreal(400) / qreal(600))));
|
||||
QTest::newRow("limit by content height wide media")
|
||||
<< qreal(1000) << qreal(600) << qreal(400) << qreal(100) << QSize(qRound(qreal(100) * (qreal(1000) / qreal(600))), 100);
|
||||
}
|
||||
|
||||
void MediaSizeHelperTest::limits()
|
||||
{
|
||||
QFETCH(qreal, mediaWidth);
|
||||
QFETCH(qreal, mediaHeight);
|
||||
QFETCH(qreal, contentMaxWidth);
|
||||
QFETCH(qreal, contentMaxHeight);
|
||||
QFETCH(QSize, currentSize);
|
||||
|
||||
MediaSizeHelper mediasizehelper;
|
||||
mediasizehelper.setMediaWidth(mediaWidth);
|
||||
mediasizehelper.setMediaHeight(mediaHeight);
|
||||
mediasizehelper.setContentMaxWidth(contentMaxWidth);
|
||||
mediasizehelper.setContentMaxHeight(contentMaxHeight);
|
||||
|
||||
QCOMPARE(mediasizehelper.currentSize(), currentSize);
|
||||
}
|
||||
|
||||
QTEST_GUILESS_MAIN(MediaSizeHelperTest)
|
||||
#include "mediasizehelpertest.moc"
|
||||
214
autotests/messageeventmodeltest.cpp
Normal file
214
autotests/messageeventmodeltest.cpp
Normal file
@@ -0,0 +1,214 @@
|
||||
// SPDX-FileCopyrightText: 2023 James Graham <james.h.graham@protonmail.com>
|
||||
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||
|
||||
#include <QObject>
|
||||
#include <QSignalSpy>
|
||||
#include <QTest>
|
||||
|
||||
#include <Quotient/connection.h>
|
||||
#include <Quotient/quotient_common.h>
|
||||
#include <Quotient/syncdata.h>
|
||||
|
||||
#include "enums/delegatetype.h"
|
||||
#include "models/messageeventmodel.h"
|
||||
#include "neochatroom.h"
|
||||
|
||||
#include "testutils.h"
|
||||
|
||||
using namespace Quotient;
|
||||
|
||||
class MessageEventModelTest : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
Connection *connection = nullptr;
|
||||
MessageEventModel *model = nullptr;
|
||||
|
||||
private Q_SLOTS:
|
||||
void initTestCase();
|
||||
void init();
|
||||
|
||||
void switchEmptyRoom();
|
||||
void switchSyncedRoom();
|
||||
void simpleTimeline();
|
||||
void syncNewEvents();
|
||||
void pendingEvent();
|
||||
void disconnect();
|
||||
void idToRow();
|
||||
|
||||
void cleanup();
|
||||
};
|
||||
|
||||
void MessageEventModelTest::initTestCase()
|
||||
{
|
||||
connection = Connection::makeMockConnection(QStringLiteral("@bob:kde.org"));
|
||||
}
|
||||
|
||||
void MessageEventModelTest::init()
|
||||
{
|
||||
QCOMPARE(model, nullptr);
|
||||
model = new MessageEventModel;
|
||||
}
|
||||
|
||||
// Make sure that basic empty rooms can be switched without crashing.
|
||||
void MessageEventModelTest::switchEmptyRoom()
|
||||
{
|
||||
auto firstRoom = new TestUtils::TestRoom(connection, QStringLiteral("#firstRoom:kde.org"));
|
||||
auto secondRoom = new TestUtils::TestRoom(connection, QStringLiteral("#secondRoom:kde.org"));
|
||||
|
||||
QSignalSpy spy(model, SIGNAL(roomChanged()));
|
||||
|
||||
QCOMPARE(model->room(), nullptr);
|
||||
model->setRoom(firstRoom);
|
||||
QCOMPARE(spy.count(), 1);
|
||||
QCOMPARE(model->room()->id(), QStringLiteral("#firstRoom:kde.org"));
|
||||
model->setRoom(secondRoom);
|
||||
QCOMPARE(spy.count(), 2);
|
||||
QCOMPARE(model->room()->id(), QStringLiteral("#secondRoom:kde.org"));
|
||||
model->setRoom(nullptr);
|
||||
QCOMPARE(spy.count(), 3);
|
||||
QCOMPARE(model->room(), nullptr);
|
||||
}
|
||||
|
||||
// Make sure that rooms with some events can be switched without crashing
|
||||
void MessageEventModelTest::switchSyncedRoom()
|
||||
{
|
||||
auto firstRoom = new TestUtils::TestRoom(connection, QStringLiteral("#firstRoom:kde.org"), QLatin1String("test-messageventmodel-sync.json"));
|
||||
auto secondRoom = new TestUtils::TestRoom(connection, QStringLiteral("#secondRoom:kde.org"), QLatin1String("test-messageventmodel-sync.json"));
|
||||
|
||||
QSignalSpy spy(model, SIGNAL(roomChanged()));
|
||||
|
||||
QCOMPARE(model->room(), nullptr);
|
||||
model->setRoom(firstRoom);
|
||||
QCOMPARE(spy.count(), 1);
|
||||
QCOMPARE(model->room()->id(), QStringLiteral("#firstRoom:kde.org"));
|
||||
model->setRoom(secondRoom);
|
||||
QCOMPARE(spy.count(), 2);
|
||||
QCOMPARE(model->room()->id(), QStringLiteral("#secondRoom:kde.org"));
|
||||
model->setRoom(nullptr);
|
||||
QCOMPARE(spy.count(), 3);
|
||||
QCOMPARE(model->room(), nullptr);
|
||||
}
|
||||
|
||||
void MessageEventModelTest::simpleTimeline()
|
||||
{
|
||||
auto room = new TestUtils::TestRoom(connection, QStringLiteral("#myroom:kde.org"), QLatin1String("test-messageventmodel-sync.json"));
|
||||
|
||||
model->setRoom(room);
|
||||
QCOMPARE(model->rowCount(), 2);
|
||||
|
||||
QCOMPARE(model->data(model->index(0), MessageEventModel::DelegateTypeRole), DelegateType::State);
|
||||
QCOMPARE(model->data(model->index(0)), QStringLiteral("changed their display name to Example Changed"));
|
||||
|
||||
QCOMPARE(model->data(model->index(1)), QStringLiteral("<b>This is an example<br>text message</b>"));
|
||||
QCOMPARE(model->data(model->index(1), MessageEventModel::DelegateTypeRole), DelegateType::Message);
|
||||
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)");
|
||||
QCOMPARE(model->data(model->index(-1)), QVariant());
|
||||
QTest::ignoreMessage(QtWarningMsg, "Index QModelIndex(-1,-1,0x0,QObject(0x0)) is not valid (expected valid)");
|
||||
QCOMPARE(model->data(model->index(model->rowCount())), QVariant());
|
||||
}
|
||||
|
||||
// Sync some events into the MessageEventModel's current room and don't crash.
|
||||
void MessageEventModelTest::syncNewEvents()
|
||||
{
|
||||
auto room = new TestUtils::TestRoom(connection, QStringLiteral("#myroom:kde.org"));
|
||||
QSignalSpy spy(room, SIGNAL(aboutToAddNewMessages(Quotient::RoomEventsRange)));
|
||||
|
||||
model->setRoom(room);
|
||||
QCOMPARE(model->rowCount(), 0);
|
||||
|
||||
room->syncNewEvents(QLatin1String("test-messageventmodel-sync.json"));
|
||||
|
||||
QCOMPARE(model->rowCount(), 2);
|
||||
QCOMPARE(spy.count(), 1);
|
||||
}
|
||||
|
||||
// Check the adding of pending events to the room doesn't cause any issues in the model.
|
||||
void MessageEventModelTest::pendingEvent()
|
||||
{
|
||||
QSignalSpy spyInsert(model, SIGNAL(rowsInserted(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> &)));
|
||||
|
||||
auto room = new TestUtils::TestRoom(connection, QStringLiteral("#myroom:kde.org"));
|
||||
model->setRoom(room);
|
||||
QCOMPARE(model->rowCount(), 0);
|
||||
|
||||
auto txnId = room->postPlainText("New plain message"_ls);
|
||||
QCOMPARE(model->rowCount(), 1);
|
||||
QCOMPARE(spyInsert.count(), 1);
|
||||
|
||||
room->discardMessage(txnId);
|
||||
QCOMPARE(model->rowCount(), 0);
|
||||
QCOMPARE(spyRemove.count(), 1);
|
||||
|
||||
txnId = room->postPlainText("New plain message"_ls);
|
||||
QCOMPARE(model->rowCount(), 1);
|
||||
QCOMPARE(spyInsert.count(), 2);
|
||||
|
||||
// We need to manually set the transaction ID of the new message as it will be
|
||||
// different every time.
|
||||
QFile testSyncFile;
|
||||
testSyncFile.setFileName(QLatin1String(DATA_DIR) + u'/' + QLatin1String("test-pending-sync.json"));
|
||||
testSyncFile.open(QIODevice::ReadOnly);
|
||||
auto testSyncJson = QJsonDocument::fromJson(testSyncFile.readAll());
|
||||
auto root = testSyncJson.object();
|
||||
auto timeline = root["timeline"_ls].toObject();
|
||||
auto events = timeline["events"_ls].toArray();
|
||||
auto firstEvent = events[0].toObject();
|
||||
firstEvent.insert(QLatin1String("unsigned"), QJsonObject{{QLatin1String("transaction_id"), txnId}});
|
||||
events[0] = firstEvent;
|
||||
timeline.insert("events"_ls, events);
|
||||
root.insert("timeline"_ls, timeline);
|
||||
testSyncJson.setObject(root);
|
||||
SyncRoomData roomData(QStringLiteral("@bob:kde.org"), JoinState::Join, testSyncJson.object());
|
||||
room->update(std::move(roomData));
|
||||
|
||||
QCOMPARE(model->rowCount(), 1);
|
||||
// The model will throw multiple data changed signals we need the one that refreshes
|
||||
// the IsPendingRole.
|
||||
QCOMPARE(spyChanged.count() > 0, true);
|
||||
auto isPendingChanged = false;
|
||||
for (auto signal : spyChanged) {
|
||||
auto roles = signal.at(2).toList();
|
||||
if (roles.contains(MessageEventModel::IsPendingRole)) {
|
||||
isPendingChanged = true;
|
||||
}
|
||||
}
|
||||
QCOMPARE(isPendingChanged, true);
|
||||
}
|
||||
|
||||
// Make sure that the signals are disconnecting correctly when a room is switched.
|
||||
void MessageEventModelTest::disconnect()
|
||||
{
|
||||
auto room = new TestUtils::TestRoom(connection, QStringLiteral("#myroom:kde.org"));
|
||||
model->setRoom(room);
|
||||
|
||||
QSignalSpy spy(model, SIGNAL(rowsInserted(const QModelIndex &, int, int)));
|
||||
|
||||
model->setRoom(nullptr);
|
||||
room->syncNewEvents(QLatin1String("test-messageventmodel-sync.json"));
|
||||
|
||||
QCOMPARE(spy.count(), 0);
|
||||
}
|
||||
|
||||
void MessageEventModelTest::idToRow()
|
||||
{
|
||||
auto room = new TestUtils::TestRoom(connection, QStringLiteral("#myroom:kde.org"), QLatin1String("test-min-sync.json"));
|
||||
model->setRoom(room);
|
||||
|
||||
QCOMPARE(model->eventIdToRow(QStringLiteral("$153456789:example.org")), 0);
|
||||
}
|
||||
|
||||
void MessageEventModelTest::cleanup()
|
||||
{
|
||||
delete model;
|
||||
model = nullptr;
|
||||
QCOMPARE(model, nullptr);
|
||||
}
|
||||
|
||||
QTEST_MAIN(MessageEventModelTest)
|
||||
#include "messageeventmodeltest.moc"
|
||||
@@ -5,138 +5,30 @@
|
||||
#include <QSignalSpy>
|
||||
#include <QTest>
|
||||
|
||||
#include "neochatroom.h"
|
||||
#include <Quotient/connection.h>
|
||||
#include <Quotient/quotient_common.h>
|
||||
#include <Quotient/syncdata.h>
|
||||
|
||||
#include <connection.h>
|
||||
#include <quotient_common.h>
|
||||
#include <syncdata.h>
|
||||
#include "testutils.h"
|
||||
|
||||
using namespace Quotient;
|
||||
|
||||
class TestRoom : public NeoChatRoom
|
||||
{
|
||||
public:
|
||||
using NeoChatRoom::NeoChatRoom;
|
||||
|
||||
void update(SyncRoomData &&data, bool fromCache = false)
|
||||
{
|
||||
Room::updateData(std::move(data), fromCache);
|
||||
}
|
||||
};
|
||||
|
||||
class NeoChatRoomTest : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
Connection *connection = nullptr;
|
||||
TestRoom *room = nullptr;
|
||||
TestUtils::TestRoom *room = nullptr;
|
||||
|
||||
private Q_SLOTS:
|
||||
void initTestCase();
|
||||
void subtitleTextTest();
|
||||
void eventTest();
|
||||
};
|
||||
|
||||
void NeoChatRoomTest::initTestCase()
|
||||
{
|
||||
connection = Connection::makeMockConnection(QStringLiteral("@bob:kde.org"));
|
||||
room = new TestRoom(connection, QStringLiteral("#myroom:kde.org"), JoinState::Join);
|
||||
|
||||
auto json = QJsonDocument::fromJson(R"EVENT({
|
||||
"account_data": {
|
||||
"events": [
|
||||
{
|
||||
"content": {
|
||||
"tags": {
|
||||
"u.work": {
|
||||
"order": 0.9
|
||||
}
|
||||
}
|
||||
},
|
||||
"type": "m.tag"
|
||||
},
|
||||
{
|
||||
"content": {
|
||||
"custom_config_key": "custom_config_value"
|
||||
},
|
||||
"type": "org.example.custom.room.config"
|
||||
}
|
||||
]
|
||||
},
|
||||
"ephemeral": {
|
||||
"events": [
|
||||
{
|
||||
"content": {
|
||||
"user_ids": [
|
||||
"@alice:matrix.org",
|
||||
"@bob:example.com"
|
||||
]
|
||||
},
|
||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||
"type": "m.typing"
|
||||
}
|
||||
]
|
||||
},
|
||||
"state": {
|
||||
"events": [
|
||||
{
|
||||
"content": {
|
||||
"avatar_url": "mxc://example.org/SEsfnsuifSDFSSEF",
|
||||
"displayname": "Alice Margatroid",
|
||||
"membership": "join",
|
||||
"reason": "Looking for support"
|
||||
},
|
||||
"event_id": "$143273582443PhrSn:example.org",
|
||||
"origin_server_ts": 1432735824653,
|
||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||
"sender": "@example:example.org",
|
||||
"state_key": "@alice:example.org",
|
||||
"type": "m.room.member",
|
||||
"unsigned": {
|
||||
"age": 1234
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
"summary": {
|
||||
"m.heroes": [
|
||||
"@alice:example.com",
|
||||
"@bob:example.com"
|
||||
],
|
||||
"m.invited_member_count": 0,
|
||||
"m.joined_member_count": 2
|
||||
},
|
||||
"timeline": {
|
||||
"events": [
|
||||
{
|
||||
"content": {
|
||||
"body": "This is an **example** text message",
|
||||
"format": "org.matrix.custom.html",
|
||||
"formatted_body": "<b>This is an example text message</b>",
|
||||
"msgtype": "m.text"
|
||||
},
|
||||
"event_id": "$143273582443PhrSn:example.org",
|
||||
"origin_server_ts": 1432735824654,
|
||||
"room_id": "!jEsUZKDJdhlrceRyVU:example.org",
|
||||
"sender": "@example:example.org",
|
||||
"type": "m.room.message",
|
||||
"unsigned": {
|
||||
"age": 1235
|
||||
}
|
||||
}
|
||||
],
|
||||
"limited": true,
|
||||
"prev_batch": "t34-23535_0_0"
|
||||
}
|
||||
})EVENT");
|
||||
SyncRoomData roomData(QStringLiteral("@bob:kde.org"), JoinState::Join, json.object());
|
||||
room->update(std::move(roomData));
|
||||
}
|
||||
|
||||
void NeoChatRoomTest::subtitleTextTest()
|
||||
{
|
||||
QCOMPARE(room->timelineSize(), 1);
|
||||
QCOMPARE(room->subtitleText(), QStringLiteral("@example:example.org: This is an example text message"));
|
||||
room = new TestUtils::TestRoom(connection, QStringLiteral("#myroom:kde.org"), "test-min-sync.json"_ls);
|
||||
}
|
||||
|
||||
void NeoChatRoomTest::eventTest()
|
||||
@@ -144,5 +36,5 @@ void NeoChatRoomTest::eventTest()
|
||||
QCOMPARE(room->timelineSize(), 1);
|
||||
}
|
||||
|
||||
QTEST_MAIN(NeoChatRoomTest)
|
||||
QTEST_GUILESS_MAIN(NeoChatRoomTest)
|
||||
#include "neochatroomtest.moc"
|
||||
|
||||
70
autotests/pollhandlertest.cpp
Normal file
70
autotests/pollhandlertest.cpp
Normal file
@@ -0,0 +1,70 @@
|
||||
// SPDX-FileCopyrightText: 2023 James Graham <james.h.graham@protonmail.com>
|
||||
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||
|
||||
#include <QObject>
|
||||
#include <QSignalSpy>
|
||||
#include <QTest>
|
||||
|
||||
#include <Quotient/connection.h>
|
||||
#include <Quotient/quotient_common.h>
|
||||
#include <Quotient/syncdata.h>
|
||||
|
||||
#include "events/pollevent.h"
|
||||
#include "pollhandler.h"
|
||||
#include "testutils.h"
|
||||
|
||||
using namespace Quotient;
|
||||
|
||||
class PollHandlerTest : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
Connection *connection = nullptr;
|
||||
TestUtils::TestRoom *room = nullptr;
|
||||
|
||||
private Q_SLOTS:
|
||||
void initTestCase();
|
||||
void nullObject();
|
||||
void poll();
|
||||
};
|
||||
|
||||
void PollHandlerTest::initTestCase()
|
||||
{
|
||||
connection = Connection::makeMockConnection(QStringLiteral("@bob:kde.org"));
|
||||
room = new TestUtils::TestRoom(connection, QStringLiteral("#myroom:kde.org"), "test-pollhandlerstart-sync.json"_ls);
|
||||
}
|
||||
|
||||
// Basically don't crash.
|
||||
void PollHandlerTest::nullObject()
|
||||
{
|
||||
auto pollHandler = PollHandler();
|
||||
|
||||
QCOMPARE(pollHandler.hasEnded(), false);
|
||||
QCOMPARE(pollHandler.answerCount(), 0);
|
||||
QCOMPARE(pollHandler.question(), QString());
|
||||
QCOMPARE(pollHandler.options(), QJsonArray());
|
||||
QCOMPARE(pollHandler.answers(), QJsonObject());
|
||||
QCOMPARE(pollHandler.counts(), QJsonObject());
|
||||
QCOMPARE(pollHandler.kind(), QString());
|
||||
}
|
||||
|
||||
void PollHandlerTest::poll()
|
||||
{
|
||||
auto startEvent = eventCast<const PollStartEvent>(room->messageEvents().at(0).get());
|
||||
auto pollHandler = PollHandler(room, startEvent);
|
||||
|
||||
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}}};
|
||||
|
||||
QCOMPARE(pollHandler.hasEnded(), false);
|
||||
QCOMPARE(pollHandler.answerCount(), 0);
|
||||
QCOMPARE(pollHandler.question(), QStringLiteral("test"));
|
||||
QCOMPARE(pollHandler.options(), options);
|
||||
QCOMPARE(pollHandler.answers(), QJsonObject());
|
||||
QCOMPARE(pollHandler.counts(), QJsonObject());
|
||||
QCOMPARE(pollHandler.kind(), QStringLiteral("org.matrix.msc3381.poll.disclosed"));
|
||||
}
|
||||
|
||||
QTEST_GUILESS_MAIN(PollHandlerTest)
|
||||
#include "pollhandlertest.moc"
|
||||
83
autotests/reactionmodeltest.cpp
Normal file
83
autotests/reactionmodeltest.cpp
Normal file
@@ -0,0 +1,83 @@
|
||||
// SPDX-FileCopyrightText: 2023 James Graham <james.h.graham@protonmail.com>
|
||||
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||
|
||||
#include <QObject>
|
||||
#include <QSignalSpy>
|
||||
#include <QTest>
|
||||
|
||||
#include "models/reactionmodel.h"
|
||||
|
||||
#include <Quotient/events/roommessageevent.h>
|
||||
|
||||
#include "testutils.h"
|
||||
|
||||
using namespace Quotient;
|
||||
|
||||
class ReactionModelTest : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
Connection *connection = nullptr;
|
||||
TestUtils::TestRoom *room = nullptr;
|
||||
|
||||
private Q_SLOTS:
|
||||
void initTestCase();
|
||||
|
||||
void nullModel();
|
||||
void basicReaction();
|
||||
void newReaction();
|
||||
};
|
||||
|
||||
void ReactionModelTest::initTestCase()
|
||||
{
|
||||
connection = Connection::makeMockConnection(QStringLiteral("@bob:kde.org"));
|
||||
room = new TestUtils::TestRoom(connection, QStringLiteral("#myroom:kde.org"), QLatin1String("test-reactionmodel-sync.json"));
|
||||
}
|
||||
|
||||
void ReactionModelTest::nullModel()
|
||||
{
|
||||
auto model = ReactionModel(nullptr, nullptr);
|
||||
|
||||
QCOMPARE(model.rowCount(), 0);
|
||||
QCOMPARE(model.data(model.index(0), ReactionModel::TextContentRole), QVariant());
|
||||
}
|
||||
|
||||
void ReactionModelTest::basicReaction()
|
||||
{
|
||||
auto event = eventCast<const RoomMessageEvent>(room->messageEvents().at(0).get());
|
||||
auto model = ReactionModel(event, room);
|
||||
|
||||
QCOMPARE(model.rowCount(), 1);
|
||||
QCOMPARE(model.data(model.index(0), ReactionModel::TextContentRole), QStringLiteral("<span style=\"font-family: 'emoji';\">👍</span>"));
|
||||
QCOMPARE(model.data(model.index(0), ReactionModel::ReactionRole), QStringLiteral("👍"));
|
||||
QCOMPARE(model.data(model.index(0), ReactionModel::ToolTipRole),
|
||||
QStringLiteral("@alice:matrix.org reacted with <span style=\"font-family: 'emoji';\">👍</span>"));
|
||||
auto authorList = QVariantList{room->getUser(room->user(QStringLiteral("@alice:matrix.org")))};
|
||||
QCOMPARE(model.data(model.index(0), ReactionModel::AuthorsRole), authorList);
|
||||
QCOMPARE(model.data(model.index(0), ReactionModel::HasLocalUser), false);
|
||||
}
|
||||
|
||||
void ReactionModelTest::newReaction()
|
||||
{
|
||||
auto event = eventCast<const RoomMessageEvent>(room->messageEvents().at(0).get());
|
||||
auto model = new ReactionModel(event, room);
|
||||
|
||||
QCOMPARE(model->rowCount(), 1);
|
||||
QCOMPARE(model->data(model->index(0), ReactionModel::ToolTipRole),
|
||||
QStringLiteral("@alice:matrix.org reacted with <span style=\"font-family: 'emoji';\">👍</span>"));
|
||||
|
||||
QSignalSpy spy(model, SIGNAL(modelReset()));
|
||||
|
||||
room->syncNewEvents(QLatin1String("test-reactionmodel-extra-sync.json"));
|
||||
QCOMPARE(model->rowCount(), 2);
|
||||
QCOMPARE(spy.count(), 2); // Once for each of the 2 new reactions.
|
||||
QCOMPARE(model->data(model->index(1), ReactionModel::ReactionRole), QStringLiteral("😆"));
|
||||
QCOMPARE(model->data(model->index(0), ReactionModel::ToolTipRole),
|
||||
QStringLiteral("@alice:matrix.org and @bob:example.org reacted with <span style=\"font-family: 'emoji';\">👍</span>"));
|
||||
|
||||
delete model;
|
||||
}
|
||||
|
||||
QTEST_MAIN(ReactionModelTest)
|
||||
#include "reactionmodeltest.moc"
|
||||
55
autotests/testutils.h
Normal file
55
autotests/testutils.h
Normal file
@@ -0,0 +1,55 @@
|
||||
// SPDX-FileCopyrightText: 2023 James Graham <james.h.graham@protonmail.com>
|
||||
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||
|
||||
#include <Quotient/events/event.h>
|
||||
#include <Quotient/syncdata.h>
|
||||
|
||||
#include "neochatroom.h"
|
||||
|
||||
namespace Quotient
|
||||
{
|
||||
class Connection;
|
||||
}
|
||||
|
||||
namespace TestUtils
|
||||
{
|
||||
class TestRoom : public NeoChatRoom
|
||||
{
|
||||
public:
|
||||
TestRoom(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(QLatin1String(DATA_DIR) + u'/' + syncFileName);
|
||||
testSyncFile.open(QIODevice::ReadOnly);
|
||||
const auto testSyncJson = QJsonDocument::fromJson(testSyncFile.readAll());
|
||||
Quotient::SyncRoomData roomData(id(), Quotient::JoinState::Join, testSyncJson.object());
|
||||
update(std::move(roomData));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<Quotient::EventClass EventT>
|
||||
inline Quotient::event_ptr_tt<EventT> loadEventFromFile(const QString &eventFileName)
|
||||
{
|
||||
if (!eventFileName.isEmpty()) {
|
||||
QFile testEventFile;
|
||||
testEventFile.setFileName(QLatin1String(DATA_DIR) + u'/' + eventFileName);
|
||||
testEventFile.open(QIODevice::ReadOnly);
|
||||
auto testSyncJson = QJsonDocument::fromJson(testEventFile.readAll()).object();
|
||||
return Quotient::loadEvent<EventT>(testSyncJson);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
530
autotests/texthandlertest.cpp
Normal file
530
autotests/texthandlertest.cpp
Normal file
@@ -0,0 +1,530 @@
|
||||
// SPDX-FileCopyrightText: 2023 James Graham <james.h.graham@protonmail.com>
|
||||
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||
|
||||
#include <QObject>
|
||||
#include <QTest>
|
||||
|
||||
#include "texthandler.h"
|
||||
|
||||
#include <Quotient/quotient_common.h>
|
||||
#include <Quotient/syncdata.h>
|
||||
#include <qnamespace.h>
|
||||
|
||||
#include "models/customemojimodel.h"
|
||||
#include "neochatconnection.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include "testutils.h"
|
||||
|
||||
using namespace Quotient;
|
||||
|
||||
class TextHandlerTest : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
Connection *connection = nullptr;
|
||||
TestUtils::TestRoom *room = nullptr;
|
||||
|
||||
private Q_SLOTS:
|
||||
void initTestCase();
|
||||
|
||||
void allowedAttributes();
|
||||
void stripDisallowedTags();
|
||||
void stripDisallowedAttributes();
|
||||
void emptyCodeTags();
|
||||
void formatBlockQuote();
|
||||
|
||||
void sendSimpleStringCase();
|
||||
void sendSingleParaMarkup();
|
||||
void sendMultipleSectionMarkup();
|
||||
void sendBadLinks();
|
||||
void sendEscapeCode();
|
||||
void sendCodeClass();
|
||||
void sendCustomEmoji();
|
||||
void sendCustomEmojiCode_data();
|
||||
void sendCustomEmojiCode();
|
||||
|
||||
void receiveStripReply();
|
||||
void receivePlainTextIn();
|
||||
|
||||
void receiveRichInPlainOut_data();
|
||||
void receiveRichInPlainOut();
|
||||
void receivePlainStripHtml();
|
||||
void receivePlainStripMarkup();
|
||||
void receiveStripNewlines();
|
||||
|
||||
void receiveRichUserPill();
|
||||
void receiveRichStrikethrough();
|
||||
void receiveRichtextIn();
|
||||
void receiveRichMxcUrl();
|
||||
void receiveRichPlainUrl();
|
||||
void receiveRichEmote();
|
||||
void receiveRichEdited_data();
|
||||
void receiveRichEdited();
|
||||
void receiveLineSeparator();
|
||||
void receiveRichCodeUrl();
|
||||
};
|
||||
|
||||
void TextHandlerTest::initTestCase()
|
||||
{
|
||||
connection = Connection::makeMockConnection(QStringLiteral("@bob:kde.org"));
|
||||
connection->setAccountData("im.ponies.user_emotes"_ls,
|
||||
QJsonObject{{"images"_ls,
|
||||
QJsonObject{{"test"_ls,
|
||||
QJsonObject{{"body"_ls, "Test custom emoji"_ls},
|
||||
{"url"_ls, "mxc://example.org/test"_ls},
|
||||
{"usage"_ls, QJsonArray{"emoticon"_ls}}}}}}});
|
||||
CustomEmojiModel::instance().setConnection(static_cast<NeoChatConnection *>(connection));
|
||||
|
||||
room = new TestUtils::TestRoom(connection, QStringLiteral("#myroom:kde.org"), QLatin1String("test-texthandler-sync.json"));
|
||||
}
|
||||
|
||||
void TextHandlerTest::allowedAttributes()
|
||||
{
|
||||
const QString testInputString1 = QStringLiteral("<p><span data-mx-spoiler><font color=#FFFFFF>Test</font><span></p>");
|
||||
const QString testOutputString1 = QStringLiteral("<p><span data-mx-spoiler><font color=#FFFFFF>Test</font><span></p>");
|
||||
// Handle urls where the href has either single (') or double (") quotes.
|
||||
const QString testInputString2 = QStringLiteral("<p><a href=\"https://kde.org\">link</a><a href='https://kde.org'>link</a></p>");
|
||||
const QString testOutputString2 = QStringLiteral("<p><a href=\"https://kde.org\">link</a><a href='https://kde.org'>link</a></p>");
|
||||
|
||||
TextHandler testTextHandler;
|
||||
testTextHandler.setData(testInputString1);
|
||||
|
||||
QCOMPARE(testTextHandler.handleSendText(), testOutputString1);
|
||||
QCOMPARE(testTextHandler.handleRecieveRichText(), testOutputString1);
|
||||
|
||||
testTextHandler.setData(testInputString2);
|
||||
QCOMPARE(testTextHandler.handleSendText(), testOutputString2);
|
||||
QCOMPARE(testTextHandler.handleRecieveRichText(), testOutputString2);
|
||||
}
|
||||
|
||||
void TextHandlerTest::stripDisallowedTags()
|
||||
{
|
||||
const QString testInputString = QStringLiteral("<p>Allowed</p> <span>Allowed</span> <body>Disallowed</body>");
|
||||
const QString testOutputString = QStringLiteral("<p>Allowed</p> <span>Allowed</span> Disallowed");
|
||||
|
||||
TextHandler testTextHandler;
|
||||
testTextHandler.setData(testInputString);
|
||||
|
||||
QCOMPARE(testTextHandler.handleSendText(), testOutputString);
|
||||
QCOMPARE(testTextHandler.handleRecieveRichText(), testOutputString);
|
||||
}
|
||||
|
||||
void TextHandlerTest::stripDisallowedAttributes()
|
||||
{
|
||||
const QString testInputString = QStringLiteral("<p style=\"font-size:50px;\" color=#FFFFFF>Test</p>");
|
||||
const QString testOutputString = QStringLiteral("<p>Test</p>");
|
||||
|
||||
TextHandler testTextHandler;
|
||||
testTextHandler.setData(testInputString);
|
||||
|
||||
QCOMPARE(testTextHandler.handleSendText(), testOutputString);
|
||||
QCOMPARE(testTextHandler.handleRecieveRichText(), testOutputString);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make sure that empty code tags are handled.
|
||||
* (this was a bug during development hence the test)
|
||||
*/
|
||||
void TextHandlerTest::emptyCodeTags()
|
||||
{
|
||||
const QString testInputString = QStringLiteral("<pre><code></code></pre>");
|
||||
const QString testOutputString = QStringLiteral("<pre><code></code></pre>");
|
||||
|
||||
TextHandler testTextHandler;
|
||||
testTextHandler.setData(testInputString);
|
||||
|
||||
QCOMPARE(testTextHandler.handleSendText(), testOutputString);
|
||||
QCOMPARE(testTextHandler.handleRecieveRichText(), testOutputString);
|
||||
}
|
||||
|
||||
void TextHandlerTest::formatBlockQuote()
|
||||
{
|
||||
auto input = QStringLiteral("<blockquote>\n<p>Lorem Ispum</p>\n</blockquote>");
|
||||
auto expectedOutput = QStringLiteral("<blockquote><table><tr><td>\u201CLorem Ispum\u201D</td></tr></table></blockquote>");
|
||||
|
||||
TextHandler testTextHandler;
|
||||
testTextHandler.setData(input);
|
||||
QCOMPARE(testTextHandler.handleRecieveRichText(), expectedOutput);
|
||||
}
|
||||
|
||||
void TextHandlerTest::sendSimpleStringCase()
|
||||
{
|
||||
const QString testInputString = QStringLiteral("This data should just be put in a paragraph.");
|
||||
const QString testOutputString = QStringLiteral("<p>This data should just be put in a paragraph.</p>");
|
||||
|
||||
TextHandler testTextHandler;
|
||||
testTextHandler.setData(testInputString);
|
||||
|
||||
QCOMPARE(testTextHandler.handleSendText(), testOutputString);
|
||||
}
|
||||
|
||||
void TextHandlerTest::sendSingleParaMarkup()
|
||||
{
|
||||
const QString testInputString = QStringLiteral(
|
||||
"Text para with **bold**, *italic*, [link](https://kde.org), , `inline code`.");
|
||||
const QString testOutputString = QStringLiteral(
|
||||
"<p>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>.</p>");
|
||||
|
||||
TextHandler testTextHandler;
|
||||
testTextHandler.setData(testInputString);
|
||||
|
||||
QCOMPARE(testTextHandler.handleSendText(), testOutputString);
|
||||
}
|
||||
|
||||
void TextHandlerTest::sendMultipleSectionMarkup()
|
||||
{
|
||||
const QString testInputString =
|
||||
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 = QStringLiteral(
|
||||
"<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;
|
||||
testTextHandler.setData(testInputString);
|
||||
|
||||
QCOMPARE(testTextHandler.handleSendText(), testOutputString);
|
||||
}
|
||||
|
||||
void TextHandlerTest::sendBadLinks()
|
||||
{
|
||||
const QString testInputString = QStringLiteral("[link](kde.org), ");
|
||||
const QString testOutputString = QStringLiteral("<p><a>link</a>, <img alt=\"image\"></p>");
|
||||
|
||||
TextHandler testTextHandler;
|
||||
testTextHandler.setData(testInputString);
|
||||
|
||||
QCOMPARE(testTextHandler.handleSendText(), testOutputString);
|
||||
}
|
||||
|
||||
/**
|
||||
* All text between code tags is treated as plain so it should get escaped.
|
||||
*/
|
||||
void TextHandlerTest::sendEscapeCode()
|
||||
{
|
||||
const QString testInputString = QStringLiteral("```\n<p>Test <span style=\"font-size:50px;\">some</span> code</p>\n```");
|
||||
const QString testOutputString =
|
||||
QStringLiteral("<pre><code><p>Test <span style="font-size:50px;">some</span> code</p>\n</code></pre>");
|
||||
|
||||
TextHandler testTextHandler;
|
||||
testTextHandler.setData(testInputString);
|
||||
|
||||
QCOMPARE(testTextHandler.handleSendText(), testOutputString);
|
||||
}
|
||||
|
||||
void TextHandlerTest::sendCodeClass()
|
||||
{
|
||||
const QString testInputString = QStringLiteral("```html\nsome code\n```\n<pre><code class=\"code-underline\">some more code</code></pre>");
|
||||
const QString testOutputString = QStringLiteral("<pre><code class=\"language-html\">some code\n</code></pre>\n<pre><code>some more code</code></pre>");
|
||||
|
||||
TextHandler testTextHandler;
|
||||
testTextHandler.setData(testInputString);
|
||||
|
||||
QCOMPARE(testTextHandler.handleSendText(), testOutputString);
|
||||
}
|
||||
|
||||
void TextHandlerTest::sendCustomEmoji()
|
||||
{
|
||||
const QString testInputString = QStringLiteral(":test:");
|
||||
const QString testOutputString = QStringLiteral(
|
||||
"<p><img data-mx-emoticon=\"\" src=\"mxc://example.org/test\" alt=\":test:\" title=\":test:\" height=\"32\" vertical-align=\"middle\" /></p>");
|
||||
|
||||
TextHandler testTextHandler;
|
||||
testTextHandler.setData(testInputString);
|
||||
|
||||
QCOMPARE(testTextHandler.handleSendText(), testOutputString);
|
||||
}
|
||||
|
||||
void TextHandlerTest::sendCustomEmojiCode_data()
|
||||
{
|
||||
QTest::addColumn<QString>("testInputString");
|
||||
QTest::addColumn<QString>("testOutputString");
|
||||
|
||||
QTest::newRow("inline") << QStringLiteral("`:test:`") << QStringLiteral("<p><code>:test:</code></p>");
|
||||
QTest::newRow("block") << QStringLiteral("```\n:test:\n```") << QStringLiteral("<pre><code>:test:\n</code></pre>");
|
||||
}
|
||||
|
||||
// Custom emojis in code blocks should be left alone.
|
||||
void TextHandlerTest::sendCustomEmojiCode()
|
||||
{
|
||||
QFETCH(QString, testInputString);
|
||||
QFETCH(QString, testOutputString);
|
||||
|
||||
TextHandler testTextHandler;
|
||||
testTextHandler.setData(testInputString);
|
||||
|
||||
QCOMPARE(testTextHandler.handleSendText(), testOutputString);
|
||||
}
|
||||
|
||||
void TextHandlerTest::receiveStripReply()
|
||||
{
|
||||
const QString testInputString = QStringLiteral(
|
||||
"<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.");
|
||||
const QString testOutputString = QStringLiteral("Reply message.");
|
||||
|
||||
TextHandler testTextHandler;
|
||||
testTextHandler.setData(testInputString);
|
||||
|
||||
QCOMPARE(testTextHandler.handleRecieveRichText(), testOutputString);
|
||||
QCOMPARE(testTextHandler.handleRecievePlainText(), testOutputString);
|
||||
}
|
||||
|
||||
void TextHandlerTest::receiveRichInPlainOut_data()
|
||||
{
|
||||
QTest::addColumn<QString>("testInputString");
|
||||
QTest::addColumn<QString>("testOutputString");
|
||||
|
||||
QTest::newRow("ampersand") << QStringLiteral("a & b") << QStringLiteral("a & b");
|
||||
QTest::newRow("quote") << QStringLiteral(""a and b"") << QStringLiteral("\"a and b\"");
|
||||
QTest::newRow("new line") << QStringLiteral("new<br>line") << QStringLiteral("new\nline");
|
||||
}
|
||||
|
||||
void TextHandlerTest::receiveRichInPlainOut()
|
||||
{
|
||||
QFETCH(QString, testInputString);
|
||||
QFETCH(QString, testOutputString);
|
||||
|
||||
TextHandler testTextHandler;
|
||||
testTextHandler.setData(testInputString);
|
||||
|
||||
QCOMPARE(testTextHandler.handleRecievePlainText(Qt::RichText), testOutputString);
|
||||
}
|
||||
|
||||
void TextHandlerTest::receivePlainTextIn()
|
||||
{
|
||||
const QString testInputString = QStringLiteral("<plain text in tag bracket>\nTest link https://kde.org.");
|
||||
const QString testOutputStringRich = QStringLiteral("<plain text in tag bracket><br>Test link <a href=\"https://kde.org\">https://kde.org</a>.");
|
||||
QString testOutputStringPlain = QStringLiteral("<plain text in tag bracket>\nTest link https://kde.org.");
|
||||
|
||||
// Make sure quotes are maintained in a plain string.
|
||||
const QString testInputString2 = QStringLiteral("last line is \"Time to switch to a new topic.\"");
|
||||
const QString testOutputString2 = QStringLiteral("last line is \"Time to switch to a new topic.\"");
|
||||
|
||||
TextHandler testTextHandler;
|
||||
testTextHandler.setData(testInputString);
|
||||
|
||||
QCOMPARE(testTextHandler.handleRecieveRichText(Qt::PlainText), testOutputStringRich);
|
||||
QCOMPARE(testTextHandler.handleRecievePlainText(), testOutputStringPlain);
|
||||
|
||||
testTextHandler.setData(testInputString2);
|
||||
QCOMPARE(testTextHandler.handleRecieveRichText(Qt::PlainText), testOutputString2);
|
||||
QCOMPARE(testTextHandler.handleRecievePlainText(), testOutputString2);
|
||||
}
|
||||
|
||||
void TextHandlerTest::receiveStripNewlines()
|
||||
{
|
||||
const QString testInputStringPlain = QStringLiteral("Test\nmany\nnew\nlines.");
|
||||
const QString testInputStringRich = QStringLiteral("Test<br>many<br />new<br>lines.");
|
||||
const QString testOutputString = QStringLiteral("Test many new lines.");
|
||||
|
||||
const QString testInputStringPlain2 = QStringLiteral("* List\n* Items");
|
||||
const QString testOutputString2 = QStringLiteral("List Items");
|
||||
|
||||
TextHandler testTextHandler;
|
||||
testTextHandler.setData(testInputStringPlain);
|
||||
|
||||
QCOMPARE(testTextHandler.handleRecievePlainText(Qt::PlainText, true), testOutputString);
|
||||
QCOMPARE(testTextHandler.handleRecieveRichText(Qt::PlainText, nullptr, nullptr, true), testOutputString);
|
||||
|
||||
testTextHandler.setData(testInputStringRich);
|
||||
QCOMPARE(testTextHandler.handleRecievePlainText(Qt::RichText, true), testOutputString);
|
||||
QCOMPARE(testTextHandler.handleRecieveRichText(Qt::RichText, nullptr, nullptr, true), testOutputString);
|
||||
|
||||
testTextHandler.setData(testInputStringPlain2);
|
||||
QCOMPARE(testTextHandler.handleRecievePlainText(Qt::RichText, true), testOutputString2);
|
||||
}
|
||||
|
||||
/**
|
||||
* For a plain text output of a received string all html is stripped except for
|
||||
* code which is unescaped if it's html.
|
||||
*/
|
||||
void TextHandlerTest::receivePlainStripHtml()
|
||||
{
|
||||
const QString testInputString = QStringLiteral("<p>Test</p> <pre><code>Some code <strong>with tags</strong></code></pre>");
|
||||
const QString testOutputString = QStringLiteral("Test Some code <strong>with tags</strong>");
|
||||
|
||||
TextHandler testTextHandler;
|
||||
testTextHandler.setData(testInputString);
|
||||
|
||||
QCOMPARE(testTextHandler.handleRecievePlainText(Qt::RichText), testOutputString);
|
||||
}
|
||||
|
||||
void TextHandlerTest::receivePlainStripMarkup()
|
||||
{
|
||||
const QString testInputString = QStringLiteral("**bold** `<p>inline code</p>` *italic*");
|
||||
const QString testOutputString = QStringLiteral("bold <p>inline code</p> italic");
|
||||
|
||||
TextHandler testTextHandler;
|
||||
testTextHandler.setData(testInputString);
|
||||
|
||||
QCOMPARE(testTextHandler.handleRecievePlainText(), testOutputString);
|
||||
}
|
||||
|
||||
void TextHandlerTest::receiveRichUserPill()
|
||||
{
|
||||
const QString testInputString = QStringLiteral("<p><a href=\"https://matrix.to/#/@alice:example.org\">@alice:example.org</a></p>");
|
||||
const QString testOutputString = QStringLiteral("<p><b><a href=\"https://matrix.to/#/@alice:example.org\">@alice:example.org</a></b></p>");
|
||||
|
||||
TextHandler testTextHandler;
|
||||
testTextHandler.setData(testInputString);
|
||||
|
||||
QCOMPARE(testTextHandler.handleRecieveRichText(), testOutputString);
|
||||
}
|
||||
|
||||
void TextHandlerTest::receiveRichStrikethrough()
|
||||
{
|
||||
const QString testInputString = QStringLiteral("<p><del>Test</del></p>");
|
||||
const QString testOutputString = QStringLiteral("<p><s>Test</s></p>");
|
||||
|
||||
TextHandler testTextHandler;
|
||||
testTextHandler.setData(testInputString);
|
||||
|
||||
QCOMPARE(testTextHandler.handleRecieveRichText(), testOutputString);
|
||||
}
|
||||
|
||||
void TextHandlerTest::receiveRichtextIn()
|
||||
{
|
||||
const QString testInputString = QStringLiteral("<p>Test</p> <pre><code>Some code <strong>with tags</strong></code></pre>");
|
||||
const QString testOutputString = QStringLiteral("<p>Test</p> <pre><code>Some code <strong>with tags</strong></code></pre>");
|
||||
|
||||
TextHandler testTextHandler;
|
||||
testTextHandler.setData(testInputString);
|
||||
|
||||
QCOMPARE(testTextHandler.handleRecieveRichText(), testOutputString);
|
||||
}
|
||||
|
||||
void TextHandlerTest::receiveRichMxcUrl()
|
||||
{
|
||||
const QString testInputString = QStringLiteral(
|
||||
"<img src=\"mxc://kde.org/aebd3ffd40503e1ef0525bf8f0d60282fec6183e\" alt=\"image\"><img src=\"mxc://kde.org/34c3464b3a1bd7f55af2d559e07d2c773c430e73\" "
|
||||
"alt=\"image\">");
|
||||
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;
|
||||
testTextHandler.setData(testInputString);
|
||||
|
||||
QCOMPARE(testTextHandler.handleRecieveRichText(Qt::RichText, room, room->messageEvents().at(0).get()), testOutputString);
|
||||
}
|
||||
|
||||
/**
|
||||
* For when your rich input string has a plain text url left in.
|
||||
*
|
||||
* This test is to show that a url that is already rich will be left alone but a
|
||||
* plain one will be linkified.
|
||||
*/
|
||||
void TextHandlerTest::receiveRichPlainUrl()
|
||||
{
|
||||
// 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.
|
||||
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>");
|
||||
|
||||
TextHandler testTextHandler;
|
||||
testTextHandler.setData(testInputStringLink1);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
// Test that user pill is add to an emote message.
|
||||
// N.B. The second message in the test timeline is marked as an emote.
|
||||
void TextHandlerTest::receiveRichEmote()
|
||||
{
|
||||
auto event = room->messageEvents().at(1).get();
|
||||
auto author = room->user(event->senderId());
|
||||
const QString testInputString = QStringLiteral("This is an emote.");
|
||||
const QString testOutputString = QStringLiteral("* <a href=\"https://matrix.to/#/@example:example.org\" style=\"color:")
|
||||
+ Utils::getUserColor(author->hueF()).name() + QStringLiteral("\">@example:example.org</a> This is an emote.");
|
||||
|
||||
TextHandler testTextHandler;
|
||||
testTextHandler.setData(testInputString);
|
||||
|
||||
QCOMPARE(testTextHandler.handleRecieveRichText(Qt::RichText, room, event), testOutputString);
|
||||
}
|
||||
|
||||
void TextHandlerTest::receiveRichEdited_data()
|
||||
{
|
||||
QTest::addColumn<QString>("testInputString");
|
||||
QTest::addColumn<QString>("testOutputString");
|
||||
|
||||
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>")
|
||||
<< QStringLiteral("<p>Edited</p>\n<p>Edited <span style=\"color:#000000\">(edited)</span></p>");
|
||||
QTest::newRow("blockquote")
|
||||
<< QStringLiteral("<blockquote>Edited</blockquote>")
|
||||
<< QStringLiteral("<blockquote><table><tr><td>\u201CEdited\u201D</td></tr></table></blockquote><p> <span style=\"color:#000000\">(edited)</span></p>");
|
||||
}
|
||||
|
||||
void TextHandlerTest::receiveRichEdited()
|
||||
{
|
||||
QFETCH(QString, testInputString);
|
||||
QFETCH(QString, testOutputString);
|
||||
|
||||
TextHandler testTextHandler;
|
||||
testTextHandler.setData(testInputString);
|
||||
|
||||
QCOMPARE(testTextHandler.handleRecieveRichText(Qt::RichText, room, room->messageEvents().at(2).get()), testOutputString);
|
||||
}
|
||||
|
||||
void TextHandlerTest::receiveLineSeparator()
|
||||
{
|
||||
auto text = QStringLiteral("foo\u2028bar");
|
||||
TextHandler textHandler;
|
||||
textHandler.setData(text);
|
||||
QCOMPARE(textHandler.handleRecievePlainText(Qt::PlainText, true), QStringLiteral("foo bar"));
|
||||
}
|
||||
|
||||
void TextHandlerTest::receiveRichCodeUrl()
|
||||
{
|
||||
auto input = QStringLiteral("<code>https://kde.org</code>");
|
||||
TextHandler testTextHandler;
|
||||
testTextHandler.setData(input);
|
||||
QCOMPARE(testTextHandler.handleRecieveRichText(), input);
|
||||
}
|
||||
|
||||
QTEST_MAIN(TextHandlerTest)
|
||||
#include "texthandlertest.moc"
|
||||
102
autotests/windowcontrollertest.cpp
Normal file
102
autotests/windowcontrollertest.cpp
Normal file
@@ -0,0 +1,102 @@
|
||||
// SPDX-FileCopyrightText: 2023 James Graham <james.h.graham@protonmail.com>
|
||||
// SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||
|
||||
#include <QQmlApplicationEngine>
|
||||
#include <QTest>
|
||||
#include <QWindow>
|
||||
|
||||
#include <KConfig>
|
||||
#include <KSharedConfig>
|
||||
#include <KWindowConfig>
|
||||
|
||||
#include "windowcontroller.h"
|
||||
|
||||
class WindowControllerTest : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private Q_SLOTS:
|
||||
void nullWindow();
|
||||
void geometry();
|
||||
void showAndRaise();
|
||||
void toggle();
|
||||
|
||||
void cleanup();
|
||||
};
|
||||
|
||||
// Basically don't crash when no window is set.
|
||||
void WindowControllerTest::nullWindow()
|
||||
{
|
||||
auto &instance = WindowController::instance();
|
||||
QCOMPARE(instance.window(), nullptr);
|
||||
|
||||
instance.restoreGeometry();
|
||||
instance.saveGeometry();
|
||||
instance.showAndRaiseWindow({});
|
||||
instance.toggleWindow();
|
||||
}
|
||||
|
||||
void WindowControllerTest::geometry()
|
||||
{
|
||||
auto &instance = WindowController::instance();
|
||||
|
||||
QWindow window;
|
||||
window.setGeometry(0, 0, 200, 200);
|
||||
instance.setWindow(&window);
|
||||
QCOMPARE(instance.window(), &window);
|
||||
|
||||
instance.saveGeometry();
|
||||
const auto stateConfig = KSharedConfig::openStateConfig();
|
||||
KConfigGroup windowGroup = stateConfig->group(QStringLiteral("Window"));
|
||||
QCOMPARE(KWindowConfig::hasSavedWindowSize(windowGroup), true);
|
||||
|
||||
window.setGeometry(0, 0, 400, 400);
|
||||
QCOMPARE(window.geometry(), QRect(0, 0, 400, 400));
|
||||
instance.restoreGeometry();
|
||||
QCOMPARE(window.geometry(), QRect(0, 0, 200, 200));
|
||||
}
|
||||
|
||||
void WindowControllerTest::showAndRaise()
|
||||
{
|
||||
auto &instance = WindowController::instance();
|
||||
QWindow window;
|
||||
instance.setWindow(&window);
|
||||
QCOMPARE(window.isVisible(), false);
|
||||
|
||||
instance.showAndRaiseWindow({});
|
||||
QCOMPARE(window.isVisible(), true);
|
||||
}
|
||||
|
||||
void WindowControllerTest::cleanup()
|
||||
{
|
||||
auto &instance = WindowController::instance();
|
||||
instance.setWindow(nullptr);
|
||||
QCOMPARE(instance.window(), nullptr);
|
||||
}
|
||||
|
||||
void WindowControllerTest::toggle()
|
||||
{
|
||||
auto &instance = WindowController::instance();
|
||||
QWindow window;
|
||||
instance.setWindow(&window);
|
||||
QCOMPARE(window.isVisible(), false);
|
||||
instance.toggleWindow();
|
||||
QCOMPARE(window.isVisible(), true);
|
||||
instance.toggleWindow();
|
||||
QCOMPARE(window.isVisible(), false);
|
||||
|
||||
// A window is classed as visible by qt when minimized but to the user this is not visible.
|
||||
// So in this case we expect to show it even though visibility is technically true.
|
||||
window.setVisibility(QWindow::Minimized);
|
||||
QCOMPARE(window.windowState(), Qt::WindowMinimized);
|
||||
QCOMPARE(window.isVisible(), true);
|
||||
instance.toggleWindow();
|
||||
QCOMPARE(window.windowState(), Qt::WindowNoState);
|
||||
QCOMPARE(window.isVisible(), true);
|
||||
instance.toggleWindow();
|
||||
QCOMPARE(window.windowState(), Qt::WindowNoState);
|
||||
QCOMPARE(window.isVisible(), false);
|
||||
}
|
||||
|
||||
QTEST_MAIN(WindowControllerTest)
|
||||
#include "windowcontrollertest.moc"
|
||||
@@ -2,4 +2,4 @@
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
kdoctools_create_manpage(man-neochat.1.docbook 1 INSTALL_DESTINATION ${MAN_INSTALL_DIR})
|
||||
kdoctools_create_manpage(man-neochat.1.docbook 1 INSTALL_DESTINATION ${KDE_INSTALL_MANDIR})
|
||||
|
||||
BIN
icons/300-apps-neochat.png
Normal file
BIN
icons/300-apps-neochat.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
BIN
icons/windows/promoimage-1920x1080.png
Normal file
BIN
icons/windows/promoimage-1920x1080.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 68 KiB |
BIN
icons/windows/storelogo-1080x1080.png
Normal file
BIN
icons/windows/storelogo-1080x1080.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 67 KiB |
BIN
icons/windows/storelogo-720x1080.png
Normal file
BIN
icons/windows/storelogo-720x1080.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 36 KiB |
@@ -11,6 +11,7 @@
|
||||
</provides>
|
||||
<name>NeoChat</name>
|
||||
<name xml:lang="ar">نيوتشات</name>
|
||||
<name xml:lang="ast">NeoChat</name>
|
||||
<name xml:lang="az">NeoChat</name>
|
||||
<name xml:lang="ca">NeoChat</name>
|
||||
<name xml:lang="ca-valencia">NeoChat</name>
|
||||
@@ -18,10 +19,12 @@
|
||||
<name xml:lang="de">NeoChat</name>
|
||||
<name xml:lang="el">NeoChat</name>
|
||||
<name xml:lang="en-GB">NeoChat</name>
|
||||
<name xml:lang="eo">NeoChat</name>
|
||||
<name xml:lang="es">NeoChat</name>
|
||||
<name xml:lang="eu">NeoChat</name>
|
||||
<name xml:lang="fi">NeoChat</name>
|
||||
<name xml:lang="fr">NeoChat</name>
|
||||
<name xml:lang="gl">NeoChat</name>
|
||||
<name xml:lang="hu">NeoChat</name>
|
||||
<name xml:lang="ia">Neochat</name>
|
||||
<name xml:lang="id">NeoChat</name>
|
||||
@@ -44,179 +47,213 @@
|
||||
<name xml:lang="uk">NeoChat</name>
|
||||
<name xml:lang="x-test">xxNeoChatxx</name>
|
||||
<name xml:lang="zh-CN">NeoChat</name>
|
||||
<summary>A client for matrix, the decentralized communication protocol</summary>
|
||||
<summary xml:lang="ar">عميل لماتركس، ميفاق الاتصال اللامركزي</summary>
|
||||
<summary xml:lang="az">Matrix üçün müştəri, mərkəzləşməmiş kommunikasiya protokolu</summary>
|
||||
<summary xml:lang="ca">Un client per al Matrix, el protocol de comunicacions descentralitzat</summary>
|
||||
<summary xml:lang="ca-valencia">Un client per a Matrix, el protocol de comunicacions descentralitzat</summary>
|
||||
<summary xml:lang="cs">Klient pro decentralizovaný komunikační protokol matrix</summary>
|
||||
<summary xml:lang="de">Ein Programm für Matrix, das dezentrale Kommunikationsprotokoll</summary>
|
||||
<summary xml:lang="el">Ένας πελάτης για το Matrix, το αποκεντρωμένο πρωτόκολλο επικοινωνίας</summary>
|
||||
<summary xml:lang="en-GB">A client for matrix, the decentralised communication protocol</summary>
|
||||
<summary xml:lang="es">Un cliente para Matrix, el protocolo de comunicaciones descentralizado</summary>
|
||||
<summary xml:lang="eu">Matrix, deszentralizatutako komunikazio protokolorako bezero bat</summary>
|
||||
<summary xml:lang="fi">Asiakas Matrixille, hajautetulle viestintäyhteyskäytännölle</summary>
|
||||
<summary xml:lang="fr">Un client pour « Matrix », le protocole décentralisé de communications.</summary>
|
||||
<summary xml:lang="hu">Kliens a matrixhoz, a decentralizált kommunikációs protokollhoz</summary>
|
||||
<summary xml:lang="ia">Un cliente per Matrix, le protocollo de communication decentralisate</summary>
|
||||
<summary xml:lang="id">Klien untuk matrix, protokol komunikasi terdesentralisasi</summary>
|
||||
<summary xml:lang="ie">Un cliente de Matrix, li protocol de communication decentralisat</summary>
|
||||
<summary xml:lang="it">Un client per matrix, il protocollo di comunicazione decentralizzato</summary>
|
||||
<summary xml:lang="ka">კლიენტი Matrix-სთვის, დეცენტრალიზებული კომუნიკაციის პროტოკოლისთვის</summary>
|
||||
<summary xml:lang="ko">Matrix, 분산 대화 프로토콜 클라이언트</summary>
|
||||
<summary xml:lang="nl">Een client voor matrix, het gedecentraliseerde communicatieprotocol</summary>
|
||||
<summary xml:lang="nn">Ein klient for Matrix, den desentraliserte lynmeldingsprotokollen</summary>
|
||||
<summary xml:lang="pa">ਮੈਟਰਿਕਸ, ਸਰਬ-ਸਾਂਝੇ ਸੰਚਾਰ ਪਰੋਟੋਕਾਲ, ਲਈ ਕਲਾਈਂਟ ਹੈ</summary>
|
||||
<summary xml:lang="pl">Program do obsługi matriksa, rozproszonego protokołu porozumiewania się</summary>
|
||||
<summary xml:lang="pt">Um cliente para o Matrix, o protocolo de comunicação descentralizado</summary>
|
||||
<summary xml:lang="pt-BR">Um cliente do Matrix, o protocolo de comunicação descentralizado</summary>
|
||||
<summary xml:lang="ru">Клиент для Matrix — децентрализованного коммуникационного протокола</summary>
|
||||
<summary xml:lang="sk">Klient pre matrix, decentralizovaný komunikačný protokol</summary>
|
||||
<summary xml:lang="sl">Odjemalec za matrix, decentralizirani komunikacijski protokol</summary>
|
||||
<summary xml:lang="sv">En klient för Matrix, det decentraliserade kommunikationsprotokollet</summary>
|
||||
<summary xml:lang="tr">Merkezi olmayan iletişim protokolü Matrix için bir istemci</summary>
|
||||
<summary xml:lang="uk">Клієнт matrix, децентралізованого протоколу обміну даними</summary>
|
||||
<summary xml:lang="x-test">xxA client for matrix, the decentralized communication protocolxx</summary>
|
||||
<summary xml:lang="zh-CN">分布式通讯协议 Matrix 的客户端</summary>
|
||||
<name xml:lang="zh-TW">NeoChat</name>
|
||||
<summary>Chat with your friends on matrix</summary>
|
||||
<summary xml:lang="ar">دردش مع أصدقائك على ماتركس</summary>
|
||||
<summary xml:lang="ca">Xategeu amb els vostres amics a Matrix</summary>
|
||||
<summary xml:lang="ca-valencia">Xategeu amb els vostres amics a Matrix</summary>
|
||||
<summary xml:lang="cs">Mluvte se svými přáteli na Matrixu</summary>
|
||||
<summary xml:lang="eo">Babilu kun viaj amikoj sur matrix</summary>
|
||||
<summary xml:lang="es">Charle con sus amigos en matrix</summary>
|
||||
<summary xml:lang="eu">Berriketan jardun zure lagunekin «Matrix»en</summary>
|
||||
<summary xml:lang="fi">Keskustelu ystäviesi kanssa Matrixissa</summary>
|
||||
<summary xml:lang="fr">Discuter avec vos ami(e)s sur le réseau Matrix</summary>
|
||||
<summary xml:lang="gl">Charle coas súas amizades en Matrix.</summary>
|
||||
<summary xml:lang="ia">Starta Conversation conntu amicos sur matrix</summary>
|
||||
<summary xml:lang="it">Conversa con i tuoi contatti su matrix</summary>
|
||||
<summary xml:lang="ka">ესაუბრეთ მეგობრებს Matrix-ზე</summary>
|
||||
<summary xml:lang="ko">Matrix를 사용하여 친구들과 대화하기</summary>
|
||||
<summary xml:lang="nl">Met uw vrienden chatten op matrix</summary>
|
||||
<summary xml:lang="nn">Prat med vennar på Matrix</summary>
|
||||
<summary xml:lang="pl">Rozmawiaj ze swoimi znajomymi w Matriksie</summary>
|
||||
<summary xml:lang="sl">Klepet z vašimi prijatelji na matrixu</summary>
|
||||
<summary xml:lang="sv">Chatta med dina vänner på Matrix</summary>
|
||||
<summary xml:lang="ta">மேட்ரிக்ஸு மூலம் உங்கள் நண்பர்களிடம் பேசலாம்</summary>
|
||||
<summary xml:lang="tr">Matrix'te arkadaşlarınızla sohbet edin</summary>
|
||||
<summary xml:lang="uk">Спілкуйтеся з вашими друзями у matrix</summary>
|
||||
<summary xml:lang="x-test">xxChat with your friends on matrixxx</summary>
|
||||
<summary xml:lang="zh-CN">在 Matrix 上与朋友聊天</summary>
|
||||
<summary xml:lang="zh-TW">在 Matrix 上與您的朋友聊天</summary>
|
||||
<description>
|
||||
<p>NeoChat is a Matrix client. It allows you to send text messages, videos and audio files to your family, colleagues and friends using the Matrix protocol.</p>
|
||||
<p xml:lang="ar">نيوتشات هو عميل ماتركس Matrix. يتيح لك إرسال رسائل نصية ومقاطع فيديو وملفات صوتية إلى عائلتك وزملائك وأصدقائك باستخدام بروتوكول ماتركس</p>
|
||||
<p xml:lang="az">NeoChat Mtrix müştərisidir. O, Matrix protokolundan istifadə edərək, ailənizə, dostlarınıza, iş yoldaşlarınıza mətn, səsli və görüntülü ismarıclar göndərməyə imkan verir.</p>
|
||||
<p xml:lang="ca">El NeoChat és un client de Matrix. Permet enviar missatges de text, fitxers de vídeo i d'àudio a la família, col·legues i amics usant el protocol Matrix.</p>
|
||||
<p xml:lang="ca-valencia">NeoChat és un client de Matrix. Permet enviar missatges de text, fitxers de vídeo i d'àudio a la família, col·legues i amics utilitzant el protocol Matrix.</p>
|
||||
<p xml:lang="de">NeoChat ist ein Matrix-Client. Er ermöglicht Ihnen das Senden von Textnachrichten, Videos und Audiodateien an Ihre Familie, Kollegen und Freunde unter Verwendung des Matrix-Protokolls.</p>
|
||||
<p xml:lang="el">Το NeoChat είναι μια εφαρμογή του Matrix. Σας επιτρέπει να στέλνετε μηνύματα κειμένου, βίντεο και ήχο στην οικογένειά σας, σε συναδέλφους και φίλους με το πρωτόκολλο Matrix.</p>
|
||||
<p xml:lang="en-GB">NeoChat is a Matrix client. It allows you to send text messages, videos and audio files to your family, colleagues and friends using the Matrix protocol.</p>
|
||||
<p xml:lang="es">NeoChat es un cliente para Matrix. Le permite enviar mensajes de texto, vídeos y archivos de sonido a su familia, compañeros de trabajo y amigos usando el protocolo Matrix.</p>
|
||||
<p xml:lang="eu">NeoChat Matrix bezero bat da. Familiari, lankideei eta lagunei testu-mezuak, bideoak eta audio-fitxategiak bidaltzeko aukera ematen du, Matrix protokoloa erabiliz.</p>
|
||||
<p xml:lang="fi">NeoChat on Matrix-asiakas. Sillä voi lähettää perheelle, tuttaville ja kavereille tekstiviestejä sekä video- ja äänitiedostoja Matrix-yhteyskäytännöllä.</p>
|
||||
<p xml:lang="fr">NeoChat est un client Matrix. Il vous permet d'envoyer des messages de texte, des vidéos et des fichiers audio à votre famille, vos collègues et vos amis en utilisant le protocole Matrix.</p>
|
||||
<p xml:lang="hu">A NeoChat egy Matrix kliens. Szöveges üzeneteket, videókat ésaudio fájlokat küldhet családjának, kollégáinak és barátainak a Matrix protokoll használatával.</p>
|
||||
<p xml:lang="ia">NeoChat es un cliente de Matrix. Illo te permitte inviar messager de texto, files de video e audio a tu familia, collegas e amicos usante le protocollo de Matrix.</p>
|
||||
<p xml:lang="id">NeoChat adalah sebuah klien Matrix. Memungkinkan Anda untuk mengirim pesan teks, file video dan audio ke keluarga, kolega dan teman Anda menggunakan protokol Matrix.</p>
|
||||
<p xml:lang="ie">NeoChat es un cliente de Matrix. On posse usar it por inviar missages textual, video- e audiofiles a su familie, colegos e amics med li protocol Matrix.</p>
|
||||
<p xml:lang="it">NeoChat è un client Matrix. Ti consente di inviare messaggi di testo, file video e audio a familiari, colleghi e amici utilizzando il protocollo Matrix.</p>
|
||||
<p>NeoChat is a client for Matrix, the decentralized communication protocol for instant messaging. It allows you to send text messages, videos and audio files to your family, colleagues and friends. It uses KDE frameworks and most notably Kirigami
|
||||
to provide a convergent experience across multiple platforms.</p>
|
||||
<p xml:lang="ar">نيوتشات هو عميل ماتركس Matrix، (ميفاق الاتصال اللامركزي للمراسلة الفورية). يتيح لك نيوتشات إرسال رسائل نصية ومقاطع فيديو وملفات صوتية إلى عائلتك وزملائك وأصدقائك. يستخدم أطر عمل كيدي وأبرزها Kirigami لتوفير تجربة متقاربة عبر منصات متعددة.</p>
|
||||
<p xml:lang="ca">El NeoChat és un client de Matrix, el protocol descentralitzat de comunicacions de missatgeria instantània. Permet enviar missatges de text, fitxers de vídeo i d'àudio a la família, col·legues i amics. Fa servir els Frameworks de KDE i, sobretot, el Kirigami per a proporcionar una experiència convergent a través de diverses plataformes.</p>
|
||||
<p xml:lang="ca-valencia">NeoChat és un client de Matrix, el protocol descentralitzat de comunicacions de missatgeria instantània. Permet enviar missatges de text, fitxers de vídeo i d'àudio a la família, col·legues i amics. Utilitza els Frameworks de KDE i, sobretot, Kirigami per a proporcionar una experiència convergent a través de diverses plataformes.</p>
|
||||
<p xml:lang="en-GB">NeoChat is a client for Matrix, the decentralised communication protocol for instant messaging. It allows you to send text messages, videos and audio files to your family, colleagues and friends. It uses KDE frameworks and most notably Kirigami to provide a convergent experience across multiple platforms.</p>
|
||||
<p xml:lang="eo">NeoChat estas kliento por Matrix, la malcentra komunikoprotokolo por tuja mesaĝado. Ĝi ebligas al vi sendi tekstmesaĝojn, filmetojn kaj sondosierojn al via familio, kolegoj kaj amikoj. Ĝi uzas KDE-framojn kaj precipe Kirigami por disponigi konverĝan sperton tra pluraj platformoj.</p>
|
||||
<p xml:lang="es">NeoChat es un cliente para Matrix, el protocolo de comunicaciones descentralizado para mensajería instantánea. Le permite enviar mensajes de texto, vídeos y archivos de sonido a su familia, compañeros de trabajo y amigos. Usa la infraestructura de KDE y, en particular, Kirigami para proporcionar una experiencia convergente en muchas plataformas.</p>
|
||||
<p xml:lang="eu">NeoChat «Matrix»erako, bat-bateko mezularitzarako komunikazio deszentralizatuko protokolorako, bezero bat da. Zure sendiari, kide eta lagunei testu mezuak, bideo eta audio fitxategiak bidaltzeko aukera ematen dizu. «KDE Frameworks» eta bereziki «Kirigami» erabiltzen ditu plataforma anitzen artean esperientzia konbergente bat eskaintzeko.</p>
|
||||
<p xml:lang="fi">NeoChat on asiakassovellus Matrixille, hajautetulle pikaviestinyhteyskäytännölle. Sillä voi lähettää teksti-, video- ja ääniviestejä perheelle, tutuille ja ystäville. Se käyttää KDE-kehystä ja erityisesti Kirigamia tuottaakseen mukautuvan monialustaisen käyttökokemuksen.</p>
|
||||
<p xml:lang="fr">NeoChat est un client pour le protocole Matrix, un protocole décentralisé de communications pour messagerie instantané. Il vous permet d'envoyer des messages de texte, des vidéos et des fichiers audio à votre famille, vos collègues et vos amis. Il utilise les environnements de développement et plus précisément Kirigami pour fournir une expérience convergente sur plusieurs plate-formes. </p>
|
||||
<p xml:lang="gl">NeoChat é un cliente para Matrix, o protocolo de comunicación descentralizada para mensaxaría instantánea. Podes enviar mensaxes de texto, vídeos e ficheiros de son á túa familia, colegas e amizades. Usas infraestruturas de KDE e principalmente Kirigami para proporcionar unha experiencia de uso converxente para varias plataformas.</p>
|
||||
<p xml:lang="hu">A NeoChat egy kliens a Matrixhoz, az azonnali üzenetküldés decentralizált komunikációs protokolljához.. Szöveges üzeneteket, videókat és hangfájlokat küldhet családjának, kollégáinak és barátainak. A KDE keretrendszert használja, a Kirigaminak köszönhetően konvergens élményt nyújt több platformon is.</p>
|
||||
<p xml:lang="ia">NeoChat es un cliente per Matrix, le protocollo de communication decentralisate per messager instantanee. Illo te permitte inviar messager de texto, files de video e audio a tu familia, collegas e amicos usante. Illo usa KDE frameworks e super toto Kirigamii forni un experientia convergente trans platteforme multiple.</p>
|
||||
<p xml:lang="it">NeoChat è un client per Matrix, il protocollo di comunicazione decentralizzato per la messaggistica istantanea. Ti consente di inviare messaggi di testo, video e file audio a familiari, colleghi e amici. Utilizza i framework KDE e in particolare Kirigami per fornire un'esperienza convergente su più piattaforme.</p>
|
||||
<p xml:lang="ka">NeoChat არის Matrix კლიენტი. ის საშუალებას გაძლევთ გაგზავნოთ ტექსტური შეტყობინებები, ვიდეოები და აუდიო ფაილები თქვენს ოჯახს, კოლეგებსა და მეგობრებს მატრიქსის პროტოკოლის გამოყენებით.</p>
|
||||
<p xml:lang="ko">NeoChat은 Matrix 클라이언트입니다. Matrix 프로토콜을 사용하여 가족, 동료, 친구에게 텍스트 메시지, 동영상, 오디오 파일을 전송할 수 있습니다.</p>
|
||||
<p xml:lang="nl">NeoChat is een Matrix-client. Het biedt u het verzenden van tekstberichten, video's en geluidsbestanden naar uw familie, collega's en vrienden met het Matrix-protocol.</p>
|
||||
<p xml:lang="pl">NeoChat jest programem do Matrisa. Umożliwia wysyłanie wiadomości tekstowych, filmów oraz dźwięku do twojej rodziny, znajomych oraz przyjaciół poprzez protokół Matriksa.</p>
|
||||
<p xml:lang="pt">O NeoChat é um cliente do Matrix. O mesmo permite-lhe enviar mensagens de texto, ficheiros de vídeo e áudio para a sua família, colegas e amigos com o protocolo Matrix.</p>
|
||||
<p xml:lang="pt-BR">O NeoChat é um cliente Matrix. Ele permite a você enviar mensagens de texto, arquivos de vídeo e áudio para seus familiares, colegas e amigos usando o protocolo Matrix.</p>
|
||||
<p xml:lang="ru">NeoChat — это клиент, поддерживающий работу с протоколом Matrix. Он позволяет отправлять текстовые сообщения, видео и аудиофайлы.</p>
|
||||
<p xml:lang="sk">NeoChat je Matrix klient. Umožňuje vám posielať textové správy, videá a zvukové súbory rodine, kolegom a priateľom pomocou protokolu Matrix.</p>
|
||||
<p xml:lang="sl">NeoChat je odjemalec Matrixa. Dovoljuje vam pošiljanje besedilnih sporočil, videoposnetkov in zvočnih datotek vaši družini, kolegom in prijateljem z uporabo protokola Matrix.</p>
|
||||
<p xml:lang="sv">NeoChat är en Matrix-klient. Den låter dig skicka textmeddelanden, videor och ljudfiler till din familj, kollegor och vänner med användning av Matrix-protokollet.</p>
|
||||
<p xml:lang="tr">NeoChat, bir Matrix istemcisidir. Matrix protokolünü kullanarak ailenize, iş arkadaşlarınıza, arkadaşlarınıza ve başkalarına metin iletileri, video ve ses dosyaların göndermenize olanak verir.</p>
|
||||
<p xml:lang="uk">NeoChat — клієнт мережі обміну повідомленнями Matrix. За допомогою цієї програми ви зможете надсилати текстові повідомлення, відео та звукові файли вашій родині, колегам та друзям за допомогою протоколу Matrix.</p>
|
||||
<p xml:lang="x-test">xxNeoChat is a Matrix client. It allows you to send text messages, videos and audio files to your family, colleagues and friends using the Matrix protocol.xx</p>
|
||||
<p xml:lang="zh-CN">NeoChat 是一个 Matrix 客户端。 它允许您使用 Matrix 协议向您的家人、同事和朋友发送文本消息、视频和音频文件。</p>
|
||||
<p>Matrix is a decentralized communication protocol, putting the user back in control. Currently NeoChat implements large part of the protocol with the exception of encrypted chats and video chat.</p>
|
||||
<p xml:lang="ar">ماتريكس هو بروتوكول اتصال لامركزي ، يعيد المستخدم إلى السيطرة. يطبق نيوتشات حاليًا جزءًا كبيرًا من الميفاق باستثناء الدردشات المشفرة ودردشة الفيديو.</p>
|
||||
<p xml:lang="az">Matrix, istifadəçini nəzarətdə saxlayan, mərkəzləşməmişi rabitə protokoludur. NeoChat, söhbətin və video əlaqəsinin şifrələnməsindən başqa bir çox protokolları həyata keçirə bilir.</p>
|
||||
<p xml:lang="ca">Matrix és un protocol de comunicacions descentralitzat, que retorna el control a l'usuari. Actualment el NeoChat implementa una gran part del protocol amb l'excepció dels xats encriptats i els xats de vídeo.</p>
|
||||
<p xml:lang="ca-valencia">Matrix és un protocol de comunicacions descentralitzat, que retorna el control a l'usuari. Actualment NeoChat implementa una gran part del protocol amb l'excepció dels xats encriptats i els xats de vídeo.</p>
|
||||
<p xml:lang="de">Matrix ist ein dezentralisiertes Kommunikationsprotokoll, das dem Benutzer wieder die Kontrolle zurückgibt. Derzeit implementiert NeoChat einen großen Teil des Protokolls mit der Ausnahme von verschlüsselten Chats und Video-Chat.</p>
|
||||
<p xml:lang="el">Το Matrix είναι ένα αποκεντρωμένο πρωτόκολλο επικοινωνίας, δίνοντας πίσω στον χρήστη τον έλεγχο. Προς το παρόν το NeoChat υλοποιεί ένα μεγάλο μέρος του πρωτοκόλλου με εξαίρεση τις κρυπτογραφημένες συνομιλίες και τη συνομιλία με βίντεο.</p>
|
||||
<p xml:lang="en-GB">Matrix is a decentralised communication protocol, putting the user back in control. Currently NeoChat implements large part of the protocol with the exception of encrypted chats and video chat.</p>
|
||||
<p xml:lang="es">Matrix es un protocolo de comunicaciones descentralizado, que devuelve el control al usuario. En la actualidad, NeoChat implementa gran parte del protocolo con la excepción de chats cifrados y chats de vídeo.</p>
|
||||
<p xml:lang="eu">Matrix komunikazio-protokolo deszentralizatu bat da, erabiltzaileari kontrola itzultzen diona. Gaur egun, NeoChat-ek protokoloaren zati handi bat inplementatzen du, berriketa zifratuak eta bideo berriketak izan ezik.</p>
|
||||
<p xml:lang="fi">Matrix on hajautettu viestintäyhteyskäytäntö, joka antaa hallinnan takaisin käyttäjille. NeoChat tarjoaa nykyisellään valtaosan yhteyskäytännöstä salattuja keskustelu- ja videokeskusteluja lukuun ottamatta.</p>
|
||||
<p xml:lang="fr">Matrix est un protocole de communication décentralisé, donnant le contrôle à l'utilisateur. Actuellement, NeoChat met en œuvre une grande partie du protocole, à l'exception des discussions chiffrées et du chat vidéo.</p>
|
||||
<p xml:lang="hu">A Matrix egy decentralizált kommunikációs protokoll, amely a felhasználók kezébe adja az irányítást.</p>
|
||||
<p xml:lang="ia">Matrix es un protocollo de communication decentrate, ponente le usator in le controlo. Currentemente NeoChat implementa un grande parte del protocollo con le exception de conversationes cryptate e conversationes video.</p>
|
||||
<p xml:lang="id">Matrix adalah protokol komunikasi terdesentralisasi, menempatkan pengguna kembali dalam kendali. Saat ini NeoChat mengimplementasikan sebagian besar protokol dengan pengecualian obrolan terenkripsi dan obrolan video.</p>
|
||||
<p xml:lang="ie">Matrix es un decentralisat protocol de communication quel retroda li control a un usator. Actualmen, NeoChat implementa un grand parte del protocol except ciffrat conversationes e videotelefonada.</p>
|
||||
<p xml:lang="it">Matrix è un protocollo di comunicazione decentralizzato, che restituisce all'utente il controllo. Attualmente NeoChat implementa gran parte del protocollo ad eccezione delle chat cifrate e delle chat video.</p>
|
||||
<p xml:lang="ka">Matrix -ი დეცენტრალიზებული კომუნიკაციის პროტოკოლია, რომელიც მომხმარებელს კონტროლის უფლებას უბრუნებს. ამჟამად NeoChat-ს პროტოკოლის ძირითადი ნაწილის მხარდაჭერა გააჩნია, დაშიფვრისა და ვიდეოჩატის გამოკლებით.</p>
|
||||
<p xml:lang="ko">Matrix는 사용자에게 제어권을 돌려 주는 분산 통신 프로토콜입니다. NeoChat은 암호화된 대화 및 영상 통화를 제외한 프로토콜의 대부분 기능을 구현합니다.</p>
|
||||
<p xml:lang="nl">Matrix is een gedecentraliseerd communicatieprotocol, dat de gebruiker de controle teruggeeft. Op dit moment implementeert NeoChat grote delen van het protocol met de uitzondering van versleutelde chats en video-chat.</p>
|
||||
<p xml:lang="pl">Matrix jest protokołem rozproszonego porozumiewania się oddający użytkownikowi jego władzę. Obecnie NeoChat obsługuje dużą część protokołu poza szyfrowanymi rozmowami tekstowymi i z obrazem.</p>
|
||||
<p xml:lang="pt">O Matrix é um protocolo de comunicações descentralizado, colocando de novo o utilizador no poder. De momento, o NeoChat implementa uma boa parte do protocolo, com a excepção das conversas encriptadas e as conversas de vídeo.</p>
|
||||
<p xml:lang="pt-BR">O Matrix é um protocolo de comunicação descentralizado, colocando o usuário de volta no controle. Atualmente o NeoChat implementa grande parte do protocolo com a exceção de bate-papos criptografados e bate-papo por vídeo.</p>
|
||||
<p xml:lang="ru">Matrix — это децентрализованный коммуникационный протокол, возвращающий пользователю контроль над своими данными. В настоящее время в приложении NeoChat реализована поддержка большей части протокола, за исключением зашифрованных чатов и видеочата.</p>
|
||||
<p xml:lang="sk">Matrix je decentralizovaný komunikačný protokol, ktorý používateľovi vracia kontrolu. V súčasnosti NeoChat implementuje veľkú časť protokolu s výnimkou šifrovaných chatov a videohovorov.</p>
|
||||
<p xml:lang="sl">Matrix je decentraliziran komunikacijski protokol, kjer ima uporabnik uporabnik kontrolo rabe. Trenutno ima NeoChat izveden velik del protokola z izjemo šifriranih klepetov in video klepetov.</p>
|
||||
<p xml:lang="sv">Matrix är ett decentraliserat kommunikationsprotokoll, som ger tillbaka kontrollen till användaren. För närvarande implementerar NeoChat en stor del av protokollet, med undantag för krypterad chatt och videochatt.</p>
|
||||
<p xml:lang="tr">Matrix; tam denetimi kullanıcıya bırakan, merkezi olmayan bir iletişim protokolüdür. Şu anda NeoChat, uçtan uca şifrelenmiş metin ve video sohbetleri dışında protokolün büyük bir bölümünü bünyesinde bulundurur.</p>
|
||||
<p xml:lang="uk">Matrix — протокол децентралізованого спілкування, який передає контроль над даними користувачеві. У поточній версії NeoChat реалізовано більшу частину протоколу, окрім зашифрованого спілкування та відеоспілкування.</p>
|
||||
<p xml:lang="x-test">xxMatrix is a decentralized communication protocol, putting the user back in control. Currently NeoChat implements large part of the protocol with the exception of encrypted chats and video chat.xx</p>
|
||||
<p xml:lang="zh-CN">Matrix 是一个分布式通讯协议,使用户重新得到控制权。 目前,NeoChat 实现了协议的大部分,除了加密聊天和视频聊天。</p>
|
||||
<p>NeoChat works both on mobile and desktop while providing a consistent user experience.</p>
|
||||
<p xml:lang="ar">يعمل نيوتشات على كل من الأجهزة المحمولة وسطح المكتب مع توفير تجربة مستخدم متسقة.</p>
|
||||
<p xml:lang="az">Vahid istifadəçi interfeysi ilə təmin olunan NeoChat, həm mobil telefonda həm də kompyuterlərdə işləyir.</p>
|
||||
<p xml:lang="ca">El NeoChat funciona en els mòbils i a l'escriptori, proporcionant una experiència d'usuari coherent.</p>
|
||||
<p xml:lang="ca-valencia">NeoChat funciona en els mòbils i en l'escriptori, proporcionant una experiència d'usuari coherent.</p>
|
||||
<p xml:lang="de">NeoChat funktioniert sowohl auf Mobilgeräten als auch auf dem PC und bietet ein einheitliches Benutzererlebnis.</p>
|
||||
<p xml:lang="el">Το NeoChat λειτουργεί και στα κινητά και στους υπολογιστές γραφείου παρέχοντας μια αδιάλειπτη εμπειρία χρήσης.</p>
|
||||
<p xml:lang="en-GB">NeoChat works both on mobile and desktop while providing a consistent user experience.</p>
|
||||
<p xml:lang="es">NeoChat funciona en móviles y en el escritorio a la vez que proporciona una experiencia de usuario consistente.</p>
|
||||
<p xml:lang="eu">NeoChat mugikorretan eta mahaigainean dabil, erabiltzaile esperientzia koherentea eskainiz.</p>
|
||||
<p xml:lang="fi">NeoChat toimii sekä mobiili- että työpöytäalustoilla tarjoten yhdenmukaisen käyttökokemuksen.</p>
|
||||
<p xml:lang="fr">NeoChat fonctionne aussi bien sur les mobiles que sur les ordinateurs de bureau, tout en offrant une expérience utilisateur cohérente.</p>
|
||||
<p xml:lang="hu">A NeoChat mobilon és asztali számítógépen is működik, egységes felhasználói élményt nyújtva.</p>
|
||||
<p xml:lang="ia">NeoChat functiona sia sur mobile que ur scriptorio durante que forni un experientia de usator consistente.</p>
|
||||
<p xml:lang="id">NeoChat berfungsi baik di ponsel dan desktop sambil memberikan pengalaman pengguna yang konsisten.</p>
|
||||
<p xml:lang="ie">NeoChat supporta amb computatores e aparates mobil, ancor providente un consistent experientie de usator.</p>
|
||||
<p xml:lang="it">NeoChat funziona sia su dispositivi mobili che desktop, fornendo un'esperienza utente coerente.</p>
|
||||
<p xml:lang="ka">NeoChat მუშაობს როგორც მობილურ, ისე ჩვეულებრივ კომპიუტერებზე იმ დროს, როცა მომხმარებლის ინტერფეისი არ იცვლება.</p>
|
||||
<p xml:lang="ko">NeoChat은 모바일과 데스크톱 모두에서 일관된 사용자 경험을 제공합니다.</p>
|
||||
<p xml:lang="nl">NeoChat werkt zowel op de mobiel en het bureaublad met het leveren van een consistente gebruikerservaring.</p>
|
||||
<p xml:lang="pl">NeoChat działa zarówno na urządzeniach przenośnych jak i biurkowych, zapewniając spójne wrażenia użytkownika</p>
|
||||
<p xml:lang="pt">O NeoChat funciona tanto em dispositivos móveis como no computador, fornecendo uma experiência de utilizador consistente.</p>
|
||||
<p xml:lang="pt-BR">O NeoChat funciona tanto no celular como no computador enquanto fornece uma experiência consistente ao usuário.</p>
|
||||
<p xml:lang="ru">NeoChat работает как на мобильных устройствах, так и на настольных компьютерах, обеспечивая единый пользовательский интерфейс.</p>
|
||||
<p xml:lang="sk">NeoChat funguje na mobilných aj stolových počítačoch a poskytuje konzistentný používateľský zážitok.</p>
|
||||
<p xml:lang="sl">NeoChat deluje tako na mobilnih kot na namiznih platformah z zagotavljanjem konsistentne uporabniške izkušnje.</p>
|
||||
<p xml:lang="sv">NeoChat fungerar både på mobil och skrivbord och tillhandahåller en konsekvent användarupplevelse.</p>
|
||||
<p xml:lang="tr">NeoChat, hem masaüstü hem de taşınabilir ortamlarda çalışarak tutarlı bir kullanıcı deneyimi sunar.</p>
|
||||
<p xml:lang="uk">NeoChat працює на мобільних пристроях та звичайних комп'ютерах, маючи однорідний інтерфейс на усіх підтримуваних пристроях.</p>
|
||||
<p xml:lang="x-test">xxNeoChat works both on mobile and desktop while providing a consistent user experience.xx</p>
|
||||
<p xml:lang="zh-CN">NeoChat 在移动设备和桌面上均可用,并提供一致的用户体验。</p>
|
||||
<p xml:lang="ko">NeoChat은 분산형 인스턴트 메시징 통신 프로토콜인 Matrix 클라이언트입니다. 가족, 동료, 친구에게 텍스트 메시지, 동영상, 오디오 파일을 전송할 수 있습니다. KDE 프레임워크와 Kirigami를 사용하여 다양한 플랫폼에서 일관적인 사용자 경험을 제공합니다.</p>
|
||||
<p xml:lang="nl">NeoChat is een client voor Matrix, het gedecentraliseerde communicatieprotocol voor instant messages. Het biedt u het verzenden van tekstberichten, video's en geluidsbestanden naar uw familie, collega's en vrienden. Het gebruik KDE frameworks en het meest opmerkelijk Kirigami om een convergente ervaring te leveren op meerdere platforms.</p>
|
||||
<p xml:lang="nn">NeoChat er ein klient for Matrix, ein protokoll for desentralisert kommunikasjon. Du kan utveksla tekst, lyd og videoar med kollegaar, vennar og familie. Programmet brukar KDE Frameworks og Kirigami for å gje ei brukarflate tilpassa ulike plattformer.</p>
|
||||
<p xml:lang="pl">NeoChat jest programem do Matriksa, protokołu rozproszonego porozumiewania się w czasie rzeczywistym. Umożliwia wysyłanie wiadomości tekstowych, filmów oraz dźwięku do twojej rodziny, znajomych oraz przyjaciół. Używa szkieletów KDE i głównie Kirigami, aby zapewnić spójne wrażenia na wielu platformach</p>
|
||||
<p xml:lang="pt">O NeoChat é um cliente do Matrix. O mesmo permite-lhe enviar mensagens de texto, ficheiros de vídeo e áudio para a sua família, colegas e amigos com o protocolo Matrix. Usa as plataformas do KDE, e principalmente o Kirigami, para oferecer uma experiência convergente entre várias plataformas.</p>
|
||||
<p xml:lang="sl">Neochat je odjemalec za Matrix, decentralizirani komunikacijski protokol za takojšnje sporočanje. Omogoča vam pošiljanje besedilnih sporočil, videoposnetkov in zvočnih datotek svoji družini, sodelavcem in prijateljem. Uporablja okvire ogrodje KDE frameworks in predvsem Kirigami za zagotavljanje konvergentne izkušnje na več platformah.</p>
|
||||
<p xml:lang="sv">NeoChat är en klient för Matrix, det decentraliserade kommunikationsprotokollet för direktmeddelanden. Den låter dig skicka textmeddelanden, videor och ljudfiler till din familj, kollegor och vänner. Den använder KDE Ramverk, i synnerhet Kirigami, för att tillhandahålla en konvergent upplevelse på flera plattformar.</p>
|
||||
<p xml:lang="tr">NeoChat, anlık iletileşme için merkezi olmayan iletişim protokolü olan Matrix için bir istemcidir. Ailenize, iş arkadaşlarınıza ve arkadaşlarınıza metin iletiler, videolar ve ses dosyaları göndermenize olanak tanır. Birden çok platformda yakınsak bir deneyim sağlamak için KDE Frameworks ve en önemlilerinden Kirigami'yi kullanır.</p>
|
||||
<p xml:lang="uk">NeoChat — клієнт Matrix, децентралізованого протоколу спілкування для миттєвого обміну повідомленнями. За його допомогою ви можете надсилати текстові повідомлення, відео та звукові файли вашій родин, колегами та друзям. У програмі використано бібліотеки KDE, зокрема Kirigami, для надання однорідного середовища на декількох програмних та апаратних платформах.</p>
|
||||
<p xml:lang="x-test">xxNeoChat is a client for Matrix, the decentralized communication protocol for instant messaging. It allows you to send text messages, videos and audio files to your family, colleagues and friends. It uses KDE frameworks and most notably Kirigami to provide a convergent experience across multiple platforms.xx</p>
|
||||
<p xml:lang="zh-TW">NeoChat 是去中心化即時通訊協定 Matrix 的一個用戶端。它讓您可以傳送文字訊息、影片、音訊檔案給您的家人、同事或朋友。NeoChat 使用 KDE frameworks,尤其是 Kirigami,來提供跨平台的響應式體驗。</p>
|
||||
<p>NeoChat aims to be a fully featured application for the Matrix specification. As such everything in the current stable specification with the notable exceptions of VoIP, threads and some aspects of End-to-End Encryption are supported. There are a few other smaller omissions due to the fact that the Matrix spec is constantly evolving but the aim remains to provide eventual support for the entire spec.</p>
|
||||
<p xml:lang="ar">يهدف نيوتشات إلى أن يكون تطبيقًا كامل الميزات لمواصفات ماتركس. على هذا النحو يتم دعم كل شيء في المواصفات المستقرة الحالية مع الاستثناءات الملحوظة لـ VoIP والخيوط وبعض جوانب التشفير من طرف إلى طرف. هناك عدد قليل من الإغفالات الصغيرة الأخرى بسبب حقيقة أن مواصفات ماتركس تتطور باستمرار ، ولكن يبقى الهدف توفير الدعم النهائي للمواصفات بأكملها.</p>
|
||||
<p xml:lang="ca">NeoChat pretén ser una aplicació amb totes les característiques per a l'especificació de Matrix. Com a tal, s'ha implementat tota l'especificació actual estable amb les notables excepcions de la VoIP, fils i alguns aspectes de l'encriptatge d'extrem a extrem. Hi ha algunes altres omissions més petites a causa del fet que l'especificació de Matrix està evolucionant constantment, però l'objectiu segueix sent proporcionar suport eventual per a tota l'especificació.</p>
|
||||
<p xml:lang="ca-valencia">NeoChat pretén ser una aplicació amb totes les característiques per a l'especificació de Matrix. Com a tal, s'ha implementat tota l'especificació actual estable amb les notables excepcions de la VoIP, fils i alguns aspectes de l'encriptació d'extrem a extrem. Hi ha algunes altres omissions més xicotetes a causa del fet que l'especificació de Matrix està evolucionant constantment, però l'objectiu seguix sent proporcionar suport eventual per a tota l'especificació.</p>
|
||||
<p xml:lang="en-GB">NeoChat aims to be a fully featured application for the Matrix specification. As such everything in the current stable specification with the notable exceptions of VoIP, threads and some aspects of End-to-End Encryption are supported. There are a few other smaller omissions due to the fact that the Matrix spec is constantly evolving but the aim remains to provide eventual support for the entire spec.</p>
|
||||
<p xml:lang="eo">NeoChat celas esti plene kapabla aplikaĵo por la Matrix-specifo. Kiel tia, ĉio en la nuna stabila specifo kun la rimarkindaj esceptoj de VoIP, fadenoj kaj kelkaj aspektoj de Fin-al-Fina Ĉifrado estas subtenataj. Estas kelkaj aliaj pli malgrandaj preterlasoj pro la fakto, ke la Matrix-speco konstante evoluas, sed la celo restas provizi finfine subtenon por la tuta specifaĵo.</p>
|
||||
<p xml:lang="es">NeoChat pretende ser una aplicación con todas las funciones para la especificación de Matrix. Como tal, admite todo en la especificación estable actual, con las notables excepciones de VoIP, subprocesos y algunas funciones de cifrado de extremo a extremo. Existen algunas omisiones menos importantes debido al hecho de que la especificación de Matrix está en constante evolución, pero el objetivo sigue siendo brindar compatibilidad final con toda la especificación.</p>
|
||||
<p xml:lang="eu">«NeoChat»ek «Matrix» zehaztapenaren ezaugarri guztiak eskaintzen dituen aplikazio bat izan nahi du. Beraz, egungo zehaztapen egonkorrean dagoen guztiaren euskarria du, VoIP, hariak eta muturren artean zifratzeko salbuespen nabarmenekin. Badira beste ez-betetze txikiago batzuk, «Matrix»en zehaztapena etengabe eboluzioan dagoelako, baina azken helburua zehaztapen osoaren euskarria ematea izaten jarraitzen du.</p>
|
||||
<p xml:lang="fi">NeoChat pyrkii olemaan Matrix-määritelmän täysominaisuuksinen sovellus, joten se tukee kaikkea nykyisessä vakaassa määritelmässä muutamaa huomattavaa poikkeusta lukuun ottamatta (VoIP, säikeet ja jotkin piirteet päästä päähän -salauksessa). Joitakin pienempiäkin puutteita on Matrix-määritelmän jatkuvan kehityksen vuoksi, mutta lopputavoitteena on tarjota määritelmän täysi tuki.</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 é implementar a especificación completa.</p>
|
||||
<p xml:lang="ia">NeoChat aspira a esser un application plenemente eminente per le specification de Matrix. Tal como omne cosas in le specification currentemente stabile con le exceptiones notabile de VOIP, threads e alcun aspectos del cryptation End-to-End es supportate. Il ha ltere pauc omissiones, debite al facto que le specification de Matrix es in evolution constante ma le aspiration remane a fornir supporto eventual per le integre specification.</p>
|
||||
<p xml:lang="it">NeoChat mira ad essere un'applicazione completa per le specifiche Matrix. Pertanto, sono supportati tutti gli elementi dell'attuale specifica stabile con le notevoli eccezioni di VoIP, conversazioni e alcuni aspetti della cifratura end-to-end. Ci sono alcune altre piccole omissioni dovute al fatto che le specifiche Matrix sono in continua evoluzione, ma l'obiettivo rimane quello di fornire un eventuale supporto per l'intera specifica.</p>
|
||||
<p xml:lang="ka">NeoChat-ი მიზნად ისახავს Matrix სპეციფიკაციის სრული განხორციელება ჰქონდეს. როგორც ასეთი, ყველაფერი მიმდინარე სპეციფიკაციიდან, VoIP-ის, ძაფებისა და გამჭოლი დაშიფვრის ზოგიერთი ასპექტის გარდა, მხარდაჭერილია. შეძლება ასევე იყოს მცირე ლაფსუსებიც იმის გამო, რომ Matrix-ის სპეციფიკაცია მუდმივად ვითარგდება, მაგრამ ჩვენი მიზანი მისი სრული მხარდაჭერაა.</p>
|
||||
<p xml:lang="ko">NeoChat은 Matrix 표준을 따르는 프로그램을 목표로 합니다. 현재 안정 버전의 표준에서 제공하는 기능의 대부분을 지원하며, VoIP, 스레드, 일부 종단간 암호화와 같은 기능은 아직 지원하지 않습니다. Matrix 표준은 계속하여 진화 중이기 때문에 일부 기능이 빠져 있을 수도 있지만 장기적으로는 전체 표준을 지원하는 것이 목표입니다.</p>
|
||||
<p xml:lang="nl">NeoChat richt zich op het volledig bieden van alle mogelijkheden van de Matrix-specificatie. Alles in de huidige stabiele specificatie met merkbare uitzondering van VoIP, gekoppelde discussies en sommige aspecten van eind-tot-eind versleuteling worden ondersteund. Er zijn een paar andere kleinere omissies vanwege het feit dat de Matrix specificatie constant evolueert maar het doel blijft het eventueel bieden van ondersteuning van de gehele specificatie.</p>
|
||||
<p xml:lang="nn">NeoChat har som mål å støtta all funksjonalitet i Matrix-spesifikasjonen. Førebels er alt i den gjeldande stabile spesifikasjonen støtta, med unntak av VoIP, trådar og nokre delar av ende-til-kryptering. Det finst òg andre småting som ikkje er støtta, sidan Matrix-spesifikasjon er i stadig endring, men målet er altså støtte for alt.</p>
|
||||
<p xml:lang="pl">NeoChat w zamyśle ma być pełnowartościową aplikacją wg wytycznych Matriksa. Z tego powodu, wszystko, co jest obecnie w stabilnych wytycznych z pominięciem VoIP, wątków i niektórych części szyfrowania Użytkownik-do-Użytkownika są obecnie obsługiwane. Pominięto też kilka mniejszych rzeczy ze względu na ciągły rozwój wytycznych Matriksa, lecz celem nadal jest zapewnienie obsługi wszystkich wytycznych.</p>
|
||||
<p xml:lang="pt">O NeoChat pretende ser uma aplicação completa para a especificação do Matrix. Como tal, tudo o que existe na especificação estável actual, com as notáveis excepções do VoIP, tópicos e alguns aspectos da Encriptação Ponto-a-Ponto, são suportados. Existem mais algumas omissões, devido ao facto que a norma do Matrix está em constante evolução, mas o objectivo continua a ser oferecer o suporte eventual para a norma por inteiro.</p>
|
||||
<p xml:lang="sl">Neochat cilja, da bi bila popolna aplikacija po specifikaciji Matrixa. Kot takšna vsebuje vse v trenutni stabilni specifikaciji z pomembnimi izjemami pri VoIP, nitih in nekaterih vidikov šifriranja od konca do konca. Obstaja nekaj drugih manjših opustitev zaradi dejstva, da se specifikacija Matrix nenehno razvija, vendar cilj ostaja zagotoviti morebitno podporo celotni specifikaciji.</p>
|
||||
<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="uk">Метою створення NeoChat є повноцінна реалізація програми для специфікації Matrix. Як наслідок, реалізовано усе у поточній стабільній специфікації, окрім голосового інтернет-зв'язку, потоків та деяких аспектів міжвузлового шифрування. Є також декілька інших незначних прогалин через те, що специфікація Matrix постійно змінюється, але метою лишається повна підтримка специфікації.</p>
|
||||
<p xml:lang="x-test">xxNeoChat aims to be a fully featured application for the Matrix specification. As such everything in the current stable specification with the notable exceptions of VoIP, threads and some aspects of End-to-End Encryption are supported. There are a few other smaller omissions due to the fact that the Matrix spec is constantly evolving but the aim remains to provide eventual support for the entire spec.xx</p>
|
||||
<p xml:lang="zh-TW">NeoChat 以完整支援 Matrix 標準為目標,因此目前穩定版標準除了 VoIP、對話串與端對端加密的某些部分以外的所有部分都有支援。其他部分還有一些較小的不支援的部分,這是因為 Matrix 標準隨時都在改進,但目標仍然時最終提供整個標準的完整支援。</p>
|
||||
<p>Due to the nature of the Matrix specification development NeoChat also supports numerous unstable features. Currently these are:</p>
|
||||
<p xml:lang="ar">نظرًا لطبيعة تطوير مواصفات ماتركس، يدعم نيوتشات أيضًا العديد من الميزات غير المستقرة وهي:</p>
|
||||
<p xml:lang="ca">A causa de la naturalesa del desenvolupament de l'especificació de Matrix, el NeoChat també implementa nombroses característiques inestables. Actualment són:</p>
|
||||
<p xml:lang="ca-valencia">A causa de la naturalea del desenvolupament de l'especificació de Matrix, NeoChat també implementa nombroses característiques inestables. Actualment són:</p>
|
||||
<p xml:lang="en-GB">Due to the nature of the Matrix specification development NeoChat also supports numerous unstable features. Currently these are:</p>
|
||||
<p xml:lang="eo">Pro la naturo de la Matrix-specifevoluo NeoChat ankaŭ subtenas multajn malstabilajn funkciojn. Nuntempe ĉi tiuj estas:</p>
|
||||
<p xml:lang="es">Debido a la naturaleza del desarrollo de la especificación de Matrix, NeoChat también permite numerosas funciones no estables, como:</p>
|
||||
<p xml:lang="eu">«Matrix» zehaztapenaren garapenaren izaeragatik, «Neo¢hat»ek ezaugarri ezegonkor ugari ere onartzen ditu. Gaur egun hauek:</p>
|
||||
<p xml:lang="fi">Matrix-määritelmän kehittyessä NeoChat tukee myös monia epävakaita ominaisuuksia. Tällä hetkellä näitä ovat:</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="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="ka">Matrix-ის სპეციფიკაციის განვითარების ბუნების გამო NeoChat-ს ასევე აქვს უამრავი არასტაბილური ფუნქციაც. ახლა ისინია:</p>
|
||||
<p xml:lang="ko">Matrix 표준 개발의 특징으로 인하여 NeoChat은 일부 실험적인 기능을 지원합니다. 현재 지원하는 기능은 다음과 같습니다.</p>
|
||||
<p xml:lang="nl">Vanwege de aard van de ontwikkeling van de Matrix specificatie ondersteunt NeoChat ook talloze onstabiele mogelijkheden. Dit zijn nu:</p>
|
||||
<p xml:lang="nn">På grunn av måten Matrix-spesifikasjonen vert utvikla på, støttar NeoChat òg nokre uferdige funksjonar:</p>
|
||||
<p xml:lang="pl">Ze względu na sposób rozwoju Matriksa, NeoChat obsługuje także kilka niestabilnych możliwości. Obecnie są to:</p>
|
||||
<p xml:lang="pt">Devido à natureza do desenvolvimento da especificação do Matrix, o NeoChat também suporta diversas funcionalidades instáveis. De momento são:</p>
|
||||
<p xml:lang="sl">Zaradi narave razvoja specifikacije Matrixa NeoChat podpira tudi številne nestabilne zmožnosti. Trenutno so to:</p>
|
||||
<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="tr">NeoChat, Matrix belirtimi geliştirmesinin doğası gereği çok sayıda kararsız özelliği de destekler. Şu anda bunlar:</p>
|
||||
<p xml:lang="uk">Через природу розробки специфікації Matrix, у NeoChat також передбачено підтримку численних нестабільних можливостей. У поточній версії цими можливостями є:</p>
|
||||
<p xml:lang="x-test">xxDue to the nature of the Matrix specification development NeoChat also supports numerous unstable features. Currently these are:xx</p>
|
||||
<p xml:lang="zh-TW">由於 Matrix 標準的開發流程的緣故,NeoChat 也支援數個非穩定版的功能。目前這些功能是:</p>
|
||||
<ul>
|
||||
<li>Polls - MSC3381</li>
|
||||
<li xml:lang="ar">التصويت - MSC3381</li>
|
||||
<li xml:lang="ca">Enquestes - MSC3381</li>
|
||||
<li xml:lang="ca-valencia">Enquestes - MSC3381</li>
|
||||
<li xml:lang="en-GB">Polls - MSC3381</li>
|
||||
<li xml:lang="eo">Enketoj - MSC3381</li>
|
||||
<li xml:lang="es">Encuestas - MSC3381</li>
|
||||
<li xml:lang="eu">Polls - MSC3381</li>
|
||||
<li xml:lang="fi">Kyselyt – MSC3381</li>
|
||||
<li xml:lang="fr">Sondages - MSC3381</li>
|
||||
<li xml:lang="gl">Enquisas — MSC3381</li>
|
||||
<li xml:lang="ia">Inquestas - MSC3381</li>
|
||||
<li xml:lang="it">Sondaggi - MSC3381</li>
|
||||
<li xml:lang="ka">Polls - MSC3381</li>
|
||||
<li xml:lang="ko">투표 - MSC3381</li>
|
||||
<li xml:lang="nl">Polls - MSC3381</li>
|
||||
<li xml:lang="nn">Avstemmingar – MSC3381</li>
|
||||
<li xml:lang="pl">Ankiety - MSC3381</li>
|
||||
<li xml:lang="pt">Inquéritos - MSC3381</li>
|
||||
<li xml:lang="sl">Polls - MSC3381</li>
|
||||
<li xml:lang="sv">Polls - MSC3381</li>
|
||||
<li xml:lang="ta">வாக்கெடுப்புகள் - MSC3381</li>
|
||||
<li xml:lang="tr">Anketler - MSC3381</li>
|
||||
<li xml:lang="uk">Опитування - MSC3381</li>
|
||||
<li xml:lang="x-test">xxPolls - MSC3381xx</li>
|
||||
<li xml:lang="zh-TW">投票 - MSC3381</li>
|
||||
<li>Sticker Packs - MSC2545</li>
|
||||
<li xml:lang="ar">حزم الملصقات - MSC2545</li>
|
||||
<li xml:lang="ca">Paquets d'adhesius - MSC2545</li>
|
||||
<li xml:lang="ca-valencia">Paquets d'adhesius - MSC2545</li>
|
||||
<li xml:lang="en-GB">Sticker Packs - MSC2545</li>
|
||||
<li xml:lang="eo">Glumark-Pakoj - MSC2545</li>
|
||||
<li xml:lang="es">Paquetes de pegatinas - MSC2545</li>
|
||||
<li xml:lang="eu">Eranskailu paketeak - MSC2545</li>
|
||||
<li xml:lang="fi">Tarrapakkaukset – MSC2545</li>
|
||||
<li xml:lang="fr">Paquets d'auto-collants - MSC2545</li>
|
||||
<li xml:lang="gl">Paquetes de adhesivos — MSC2545</li>
|
||||
<li xml:lang="ia">Etiquetta gummate (sticker) -MSC2545</li>
|
||||
<li xml:lang="it">Pacchetti di adesivi - MSC2545</li>
|
||||
<li xml:lang="ka">სტიკერების პაკეტები - MSC2545</li>
|
||||
<li xml:lang="ko">스티커 팩 - MSC2545</li>
|
||||
<li xml:lang="nl">Sticker Packs - MSC2545</li>
|
||||
<li xml:lang="nn">Klistremerke-pakkar – MSC2545</li>
|
||||
<li xml:lang="pl">Paczki naklejek - MSC2545</li>
|
||||
<li xml:lang="pt">Pacotes de Autocolantes - MSC2545</li>
|
||||
<li xml:lang="sl">Sticker Packs - MSC2545</li>
|
||||
<li xml:lang="sv">Sticker Packs - MSC2545</li>
|
||||
<li xml:lang="ta">ஒட்டி தொகுப்புகள் - MSC2545</li>
|
||||
<li xml:lang="tr">Yapışkan Paketleri - MSC2545</li>
|
||||
<li xml:lang="uk">Пакунки наліпок - MSC2545</li>
|
||||
<li xml:lang="x-test">xxSticker Packs - MSC2545xx</li>
|
||||
<li xml:lang="zh-TW">貼圖包 - MSC2545</li>
|
||||
<li>Location Events - MSC3488</li>
|
||||
<li xml:lang="ar">موقع الأحداث - MSC3488</li>
|
||||
<li xml:lang="ca">Esdeveniments d'ubicació - MSC3488</li>
|
||||
<li xml:lang="ca-valencia">Esdeveniments d'ubicació - MSC3488</li>
|
||||
<li xml:lang="en-GB">Location Events - MSC3488</li>
|
||||
<li xml:lang="eo">Lokaj Eventoj - MSC3488</li>
|
||||
<li xml:lang="es">Eventos de ubicación - MSC3488</li>
|
||||
<li xml:lang="eu">Kokaleku-gertaerak - MSC3488</li>
|
||||
<li xml:lang="fi">Sijaintitapahtumat – 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="ia">Eventos de Location - MSC3488</li>
|
||||
<li xml:lang="it">Località eventi - MSC3488</li>
|
||||
<li xml:lang="ka">მდებარეობის მოვლენები - MSC3488</li>
|
||||
<li xml:lang="ko">위치 이벤트 - MSC3488</li>
|
||||
<li xml:lang="nl">Locatie gebeurtenissen - MSC3488</li>
|
||||
<li xml:lang="nn">Posisjonshendingar – MSC3488</li>
|
||||
<li xml:lang="pl">Wydarzenia w miejscach - MSC3488</li>
|
||||
<li xml:lang="pt">Eventos com Localizações - MSC3488</li>
|
||||
<li xml:lang="sl">Location Events - MSC3488</li>
|
||||
<li xml:lang="sv">Location Events - MSC3488</li>
|
||||
<li xml:lang="ta">இட நிகழ்வுகள் - MSC3488</li>
|
||||
<li xml:lang="tr">Konum Etkinlikleri - MSC3488</li>
|
||||
<li xml:lang="uk">Місцеві зустрічі - MSC3488</li>
|
||||
<li xml:lang="x-test">xxLocation Events - MSC3488xx</li>
|
||||
<li xml:lang="zh-TW">位置事件 - MSC3488</li>
|
||||
</ul>
|
||||
</description>
|
||||
<url type="homepage">https://apps.kde.org/neochat/</url>
|
||||
<url type="bugtracker">https://bugs.kde.org/buglist.cgi?component=General&product=NeoChat</url>
|
||||
<url type="homepage">https://apps.kde.org/neochat</url>
|
||||
<url type="bugtracker">https://bugs.kde.org/enter_bug.cgi?product=NeoChat</url>
|
||||
<categories>
|
||||
<category>Network</category>
|
||||
</categories>
|
||||
<developer_name>The KDE Community</developer_name>
|
||||
<developer_name xml:lang="ar">مجتمع كِيدِي</developer_name>
|
||||
<developer_name xml:lang="az">KDE Cəmiyyəti</developer_name>
|
||||
<developer_name xml:lang="ca">La comunitat KDE</developer_name>
|
||||
<developer_name xml:lang="ca-valencia">La comunitat KDE</developer_name>
|
||||
<developer_name xml:lang="cs">Komunita KDE</developer_name>
|
||||
<developer_name xml:lang="de">Die KDE-Gemeinschaft</developer_name>
|
||||
<developer_name xml:lang="el">Η Κοινότητα του KDE</developer_name>
|
||||
<developer_name xml:lang="en-GB">The KDE Community</developer_name>
|
||||
<developer_name xml:lang="es">La comunidad KDE</developer_name>
|
||||
<developer_name xml:lang="eu">KDE komunitatea</developer_name>
|
||||
<developer_name xml:lang="fi">KDE-yhteisö</developer_name>
|
||||
<developer_name xml:lang="fr">La communauté de KDE</developer_name>
|
||||
<developer_name xml:lang="hu">A KDE Közösség</developer_name>
|
||||
<developer_name xml:lang="ia">Le communitate de KDE</developer_name>
|
||||
<developer_name xml:lang="id">Komunitas KDE</developer_name>
|
||||
<developer_name xml:lang="ie">Li comunité de KDE</developer_name>
|
||||
<developer_name xml:lang="it">La comunità KDE</developer_name>
|
||||
<developer_name xml:lang="ka">KDE-ის საზოგადოება</developer_name>
|
||||
<developer_name xml:lang="ko">KDE 커뮤니티</developer_name>
|
||||
<developer_name xml:lang="nl">De KDE gemeenschap</developer_name>
|
||||
<developer_name xml:lang="nn">KDE-fellesskapet</developer_name>
|
||||
<developer_name xml:lang="pa">ਕੇਡੀਈ ਕਮਿਊਨਟੀ</developer_name>
|
||||
<developer_name xml:lang="pl">Społeczność KDE</developer_name>
|
||||
<developer_name xml:lang="pt">A Comunidade do KDE</developer_name>
|
||||
<developer_name xml:lang="pt-BR">A comunidade KDE</developer_name>
|
||||
<developer_name xml:lang="ru">Сообщество KDE</developer_name>
|
||||
<developer_name xml:lang="sk">KDE Komunita</developer_name>
|
||||
<developer_name xml:lang="sl">Skupnost KDE</developer_name>
|
||||
<developer_name xml:lang="sv">KDE-gemenskapen</developer_name>
|
||||
<developer_name xml:lang="tr">KDE Topluluğu</developer_name>
|
||||
<developer_name xml:lang="uk">Спільнота KDE</developer_name>
|
||||
<developer_name xml:lang="x-test">xxThe KDE Communityxx</developer_name>
|
||||
<developer_name xml:lang="zh-CN">KDE 社区</developer_name>
|
||||
<developer>
|
||||
<id>kde.org</id>
|
||||
<name>The KDE Community</name>
|
||||
<url>https://kde.org</url>
|
||||
</developer>
|
||||
<metadata_license>CC0-1.0</metadata_license>
|
||||
<project_license>GPL-3.0</project_license>
|
||||
<custom>
|
||||
<value key="KDE::matrix">#neochat:kde.org</value>
|
||||
<value key="KDE::windows_store">https://www.microsoft.com/store/apps/9PNXWVNRC29H</value>
|
||||
<value key="KDE::mastodon">https://kde.social/@neochat</value>
|
||||
<value key="KDE::windows_store::StoreLogo9x16">https://invent.kde.org/network/neochat/-/raw/master/icons/windows/storelogo-720x1080.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::PromotionalArt16x9">https://invent.kde.org/network/neochat/-/raw/master/icons/windows/promoimage-1920x1080.png</value>
|
||||
</custom>
|
||||
<launchable type="desktop-id">org.kde.neochat.desktop</launchable>
|
||||
<screenshots>
|
||||
@@ -226,11 +263,113 @@
|
||||
<screenshot type="default">
|
||||
<image>https://cdn.kde.org/screenshots/neochat/application.png</image>
|
||||
</screenshot>
|
||||
<screenshot environment="windows">
|
||||
<image>https://cdn.kde.org/screenshots/neochat/NeoChat-Windows-Timeline.png</image>
|
||||
<caption>Main view with room list, chat, and room information</caption>
|
||||
<caption xml:lang="ar">العرض الرئيسة مع قائمة الغرف والدردشات و معلومات الغرفة</caption>
|
||||
<caption xml:lang="ca">Vista principal amb la llista de sales, xats i informació de les sales</caption>
|
||||
<caption xml:lang="ca-valencia">Vista principal amb la llista de sales, xats i informació de les sales</caption>
|
||||
<caption xml:lang="eo">Ĉefa vido kun ĉambra listo, babilejo kaj ĉambra informo</caption>
|
||||
<caption xml:lang="es">Vista principal con la lista de salas, chat e información de la sala</caption>
|
||||
<caption xml:lang="eu">Ikuspegi nagusia gela-zerrenda, berriketa, eta gelako informazioarekin</caption>
|
||||
<caption xml:lang="fi">Päänäkymä, jossa huoneluettelo, keskustelu ja huoneen tiedot</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="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="ka">მთავარი ხედი სურათების სიით, ჩატით და ოთახის ინფორმაციით</caption>
|
||||
<caption xml:lang="ko">대화방 목록, 채팅, 대화방 정보가 표시된 주 보기</caption>
|
||||
<caption xml:lang="nl">Hoofdweergave met lijst met rooms, chat en roominformatie</caption>
|
||||
<caption xml:lang="nn">Hovudvising med romliste, pratevindauge og rominformasjon</caption>
|
||||
<caption xml:lang="pl">Główny widok z wykazem pokojów, rozmowami i szczegółami pokojów</caption>
|
||||
<caption xml:lang="pt">A área principal com a lista de salas e com informações sobre a conversa e a sala</caption>
|
||||
<caption xml:lang="sl">Glavni pogled s seznamom sob, klepetom in informacijami o sobah</caption>
|
||||
<caption xml:lang="sv">Huvudvy med rumslista, chatt, och rumsinformation</caption>
|
||||
<caption xml:lang="ta">அரங்குப்பட்டியல், உரையாடல், மற்றும் அரங்குவிவரங்களைக் கொண்டுள்ள பிரதான காட்சி</caption>
|
||||
<caption xml:lang="tr">Oda listesini, sohbet penceresini ve oda bilgisini gösteren ana görünüm</caption>
|
||||
<caption xml:lang="uk">Головна панель із списком кімнат, спілкуванням та даними щодо кімнати</caption>
|
||||
<caption xml:lang="x-test">xxMain view with room list, chat, and room informationxx</caption>
|
||||
<caption xml:lang="zh-TW">主頁面,包含聊天室列表、聊天內容,與聊天室資訊</caption>
|
||||
</screenshot>
|
||||
<screenshot environment="windows">
|
||||
<image>https://cdn.kde.org/screenshots/neochat/NeoChat-Windows-Login.png</image>
|
||||
<caption>Login screen</caption>
|
||||
<caption xml:lang="ar">شاشة الدخول</caption>
|
||||
<caption xml:lang="ca">Pantalla d'inici de sessió</caption>
|
||||
<caption xml:lang="ca-valencia">Pantalla d'inici de sessió</caption>
|
||||
<caption xml:lang="cs">Přihlašovací obrazovka</caption>
|
||||
<caption xml:lang="eo">Ensaluta ekrano</caption>
|
||||
<caption xml:lang="es">Pantalla de inicio de sesión</caption>
|
||||
<caption xml:lang="eu">Saio-hasteko pantaila</caption>
|
||||
<caption xml:lang="fi">Kirjautumisnäkymä</caption>
|
||||
<caption xml:lang="fr">Écran de connexion</caption>
|
||||
<caption xml:lang="gl">Pantalla de identificación.</caption>
|
||||
<caption xml:lang="ia">Schermo de accesso</caption>
|
||||
<caption xml:lang="it">Schermata di accesso</caption>
|
||||
<caption xml:lang="ka">შესვლის ეკრანი</caption>
|
||||
<caption xml:lang="ko">로그인 화면</caption>
|
||||
<caption xml:lang="nl">Aanmeldscherm</caption>
|
||||
<caption xml:lang="nn">Innloggingsbilete</caption>
|
||||
<caption xml:lang="pl">Ekran logowania</caption>
|
||||
<caption xml:lang="pt">Ecrã de autenticação</caption>
|
||||
<caption xml:lang="sl">Prijavni zaslon</caption>
|
||||
<caption xml:lang="sv">Inloggningsfönster</caption>
|
||||
<caption xml:lang="ta">நுழைவுத் திரை</caption>
|
||||
<caption xml:lang="tr">Oturum açma ekranı</caption>
|
||||
<caption xml:lang="uk">Вікно входу</caption>
|
||||
<caption xml:lang="x-test">xxLogin screenxx</caption>
|
||||
<caption xml:lang="zh-TW">登入畫面</caption>
|
||||
</screenshot>
|
||||
</screenshots>
|
||||
<content_rating type="oars-1.1">
|
||||
<content_attribute id="social-chat">intense</content_attribute>
|
||||
</content_rating>
|
||||
<releases>
|
||||
<release version="24.02.0" date="2024-02-28">
|
||||
<url>https://kde.org/announcements/megarelease/6/#neochat</url>
|
||||
<description>
|
||||
<p>In the newest version, when launching the app, you will get a welcome page that lets you choose which account you want to use and lets you log in to other accounts. The welcome screen will also warn you when NeoChat cannot load an account.</p>
|
||||
<p>NeoChat will also let you register a new account directly from the app itself. Deactivating your Matrix account is also possible from within NeoChat.</p>
|
||||
<p>Spaces are a relatively new feature of Matrix that let you group chat channels together. This is used to improve the discoverability of rooms, manage large communities, or just tidy all the channels you are in. You can now do all this without leaving NeoChat.</p>
|
||||
<p>NeoChat won't let you miss any new notifications anymore. We added a new page that includes all your recent notifications and when NeoChat is closed, you will still be able to receive push notifications. The main timeline will let you know when more messages are loading and when you reach the end of it.</p>
|
||||
<p>More NeoChat Goodies</p>
|
||||
<ul>
|
||||
<li>QR Codes to share contacts</li>
|
||||
<li>Improved room upgrades</li>
|
||||
<li>Added button to reject invitation and ignore user</li>
|
||||
<li>Display device security details</li>
|
||||
<li>Added room security settings</li>
|
||||
</ul>
|
||||
</description>
|
||||
</release>
|
||||
<release version="23.08.5" date="2024-02-15"/>
|
||||
<release version="23.08.4" date="2023-12-07"/>
|
||||
<release version="23.08.3" date="2023-11-09"/>
|
||||
<release version="23.08.2" date="2023-10-12"/>
|
||||
<release version="23.08.0" date="2023-08-24">
|
||||
<url>https://kde.org/announcements/gear/23.08.0/#neochathttpsappskdeorgneochat</url>
|
||||
<description>
|
||||
<p>Apart from a visual overhaul, NeoChat can now display location events and also a map with the location of all the users currently broadcasting their location using Itineray's Matrix integration. Great for locating where your friends are.</p>
|
||||
</description>
|
||||
</release>
|
||||
<release version="23.04.3" date="2023-07-06"/>
|
||||
<release version="23.04.2" date="2023-06-08"/>
|
||||
<release version="23.04.1" date="2023-05-11"/>
|
||||
<release version="23.04.0" date="2023-04-20">
|
||||
<url>https://kde.org/announcements/gear/23.04.0/#neochathttpsappskdeorgneochat</url>
|
||||
<description>
|
||||
<p>NeoChat improves its design with tweaks that provide a more compact layout and a simpler menu which works better for the collapsed room list.</p>
|
||||
<p>We have also improved the video controls, added a new command /knock <room-id> to send a knock event to a room, and you can now edit a prior message inline, within the chat pane.</p>
|
||||
<p>Other usability improvements include an overhaul of the keyboard navigation and shortcuts like Ctrl+PgUp/PgDn that allow you to skip from room to room.</p>
|
||||
</description>
|
||||
<artifacts>
|
||||
<artifact type="binary" platform="x86_64-windows-msvc">
|
||||
<location>https://download.kde.org/stable/release-service/23.04.0/windows/neochat-23.04.0-512-windows-cl-msvc2019-x86_64.exe</location>
|
||||
<checksum type="sha256">85e17fdd9b128bfdd171a93b11f7a95febeff0a00df9261df11f6ff67637686d</checksum>
|
||||
<size type="download">58032464</size>
|
||||
</artifact>
|
||||
</artifacts>
|
||||
</release>
|
||||
<release version="23.01" date="2023-01-30">
|
||||
<url>https://plasma-mobile.org/2023/01/30/january-blog-post/</url>
|
||||
<description>
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
Version=1.5
|
||||
Name=NeoChat
|
||||
Name[ar]=نيوتشات
|
||||
Name[ast]=NeoChat
|
||||
Name[az]=NeoChat
|
||||
Name[ca]=NeoChat
|
||||
Name[ca@valencia]=NeoChat
|
||||
@@ -11,10 +12,12 @@ Name[cs]=NeoChat
|
||||
Name[de]=NeoChat
|
||||
Name[el]=NeoChat
|
||||
Name[en_GB]=NeoChat
|
||||
Name[eo]=NeoChat
|
||||
Name[es]=NeoChat
|
||||
Name[eu]=NeoChat
|
||||
Name[fi]=NeoChat
|
||||
Name[fr]=NeoChat
|
||||
Name[gl]=NeoChat
|
||||
Name[hu]=NeoChat
|
||||
Name[ia]=Neochat
|
||||
Name[id]=NeoChat
|
||||
@@ -39,6 +42,7 @@ Name[tr]=NeoChat
|
||||
Name[uk]=NeoChat
|
||||
Name[x-test]=xxNeoChatxx
|
||||
Name[zh_CN]=NeoChat
|
||||
Name[zh_TW]=NeoChat
|
||||
GenericName=Matrix Client
|
||||
GenericName[ar]=عميل ماتركس
|
||||
GenericName[az]=Matrix Müştərisi
|
||||
@@ -48,10 +52,12 @@ GenericName[cs]=Klient protokolu Matrix
|
||||
GenericName[de]=Matrix-Programm
|
||||
GenericName[el]=Εφαρμογή του Matrix
|
||||
GenericName[en_GB]=Matrix Client
|
||||
GenericName[eo]=Matrix-Kliento
|
||||
GenericName[es]=Cliente para Matrix
|
||||
GenericName[eu]=Matrix bezeroa
|
||||
GenericName[fi]=Matrix-asiakas
|
||||
GenericName[fr]=Client « Matrix »
|
||||
GenericName[gl]=Cliente de Matrix
|
||||
GenericName[hu]=Matrix kliens
|
||||
GenericName[ia]=Cliente de Matrice
|
||||
GenericName[id]=Klien Matrix
|
||||
@@ -59,7 +65,7 @@ GenericName[ie]=Cliente de Matrix
|
||||
GenericName[it]=Client Matrix
|
||||
GenericName[ka]=Matrix -ის კლიენტი
|
||||
GenericName[ko]=Matrix 클라이언트
|
||||
GenericName[lt]=Matrix kliento programą
|
||||
GenericName[lt]=Matrix kliento programa
|
||||
GenericName[nl]=Matrix-client
|
||||
GenericName[nn]=Matrix-klient
|
||||
GenericName[pa]=ਮੈਟਰਿਕਸ ਕਲਾਈਂਟ
|
||||
@@ -76,6 +82,7 @@ GenericName[tr]=Matrix İstemcisi
|
||||
GenericName[uk]=Клієнт Matrix
|
||||
GenericName[x-test]=xxMatrix Clientxx
|
||||
GenericName[zh_CN]=Matrix 客户端
|
||||
GenericName[zh_TW]=Matrix 用戶端
|
||||
Comment=Client for the Matrix protocol
|
||||
Comment[ar]=عميل لميفاق ماتركس
|
||||
Comment[az]=Matrix protokolu üçün müştəri
|
||||
@@ -84,10 +91,12 @@ Comment[ca@valencia]=Client per al protocol Matrix
|
||||
Comment[de]=Programm für das Matrix-Protokoll
|
||||
Comment[el]=Πελάτης για το πρωτόκολλο Matrix
|
||||
Comment[en_GB]=Client for the Matrix protocol
|
||||
Comment[eo]=Kliento por la Matrix-protokolo
|
||||
Comment[es]=Cliente para el protocolo Matrix
|
||||
Comment[eu]=Matrix protokolorako bezeroa
|
||||
Comment[fi]=Asiakas Matrix-yhteyskäytännölle
|
||||
Comment[fr]=Client pour le protocole « Matrix »
|
||||
Comment[gl]=Cliente para o protocolo Matrix.
|
||||
Comment[hu]=Kliens a Matrix protokollhoz
|
||||
Comment[ia]=Cliente per le protocollo de Matrix
|
||||
Comment[id]=Klien untuk protokol Matrix
|
||||
@@ -97,7 +106,7 @@ Comment[ka]=კლიენტი Matrix-ის პროტოკოლის
|
||||
Comment[ko]=Matrix 프로토콜용 클라이언트
|
||||
Comment[lt]=Matrix protokolo kliento programa
|
||||
Comment[nl]=Client voor het Matrix-protocol
|
||||
Comment[nn]=Lynmeldingsklient for Matrix-protokollen
|
||||
Comment[nn]=Klient for Matrix-protokollen
|
||||
Comment[pa]=ਮੈਟਰਿਕਸ ਪਰੋਟੋਕਾਲ ਲਈ ਕਲਾਈਂਟ ਹੈ
|
||||
Comment[pl]=Program obsługi protokołu Matriksa
|
||||
Comment[pt]=Cliente para o protocolo Matrix
|
||||
@@ -112,6 +121,7 @@ Comment[tr]=Matrix protokolü için istemci
|
||||
Comment[uk]=Клієнт протоколу Matrix
|
||||
Comment[x-test]=xxClient for the Matrix protocolxx
|
||||
Comment[zh_CN]=为 Matrix 协议打造的客户端
|
||||
Comment[zh_TW]=Matrix 通訊協定的用戶端
|
||||
MimeType=x-scheme-handler/matrix;
|
||||
Exec=neochat %u
|
||||
Terminal=false
|
||||
|
||||
@@ -1 +1,8 @@
|
||||
<svg width="22" height="22" fill="none" version="1.1" id="svg13" xmlns="http://www.w3.org/2000/svg"><style type="text/css" id="current-color-scheme">.ColorScheme-Text{color:#232629}</style><path class="ColorScheme-Text" style="fill:currentColor;fill-opacity:1;stroke:none" fill-rule="evenodd" clip-rule="evenodd" d="M2 4h18v11H6.681L3 18.067V15H2zm1 10h1v1.933L6.319 14H19V5H3z" id="path3"/><path class="ColorScheme-Text" style="fill:currentColor;fill-opacity:1;stroke:none" id="rect5" d="M4 7h9v1H4z"/><path class="ColorScheme-Text" style="fill:currentColor;fill-opacity:1;stroke:none" id="rect7" d="M4 9h7v1H4z"/><path class="ColorScheme-Text" style="fill:currentColor;fill-opacity:1;stroke:none" id="rect9" d="M4 11h5v1H4z"/><path class="ColorScheme-Text" style="fill:currentColor;fill-opacity:1;stroke:none" fill-rule="evenodd" clip-rule="evenodd" d="m16 15.293-1.147-1.146-.707.707 2.853 2.853V14.5h-1z" id="path11"/></svg>
|
||||
<svg width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<style type="text/css" id="current-color-scheme">.ColorScheme-Text{color:#232629}</style>
|
||||
<path class="ColorScheme-Text" fill-rule="evenodd" clip-rule="evenodd" d="M3 3H19V14H8.68787L4 18.1019V14H3V3ZM4 13H5V15.8981L8.31213 13H18V4H4V13Z" fill="currentColor"/>
|
||||
<path class="ColorScheme-Text" fill-rule="evenodd" clip-rule="evenodd" d="M17 15.2929L14.8536 13.1465L14.1465 13.8536L18 17.7071V13.5H17V15.2929Z" fill="currentColor"/>
|
||||
<path class="ColorScheme-Text" d="M5 6H15V7H5V6Z" fill="currentColor"/>
|
||||
<path class="ColorScheme-Text" d="M5 8H13V9H5V8Z" fill="currentColor"/>
|
||||
<path class="ColorScheme-Text" d="M5 10H11V11H5V10Z" fill="currentColor"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 928 B After Width: | Height: | Size: 752 B |
7194
po/ar/neochat.po
7194
po/ar/neochat.po
File diff suppressed because it is too large
Load Diff
4678
po/ast/neochat.po
Normal file
4678
po/ast/neochat.po
Normal file
File diff suppressed because it is too large
Load Diff
7635
po/az/neochat.po
7635
po/az/neochat.po
File diff suppressed because it is too large
Load Diff
@@ -97,7 +97,7 @@ SPDX-License-Identifier: CC-BY-SA-4.0
|
||||
>Vegeu també</title>
|
||||
<simplelist>
|
||||
<member
|
||||
>Una llista de les preguntes més freqüents quan a Matrix <ulink url="https://matrix.org/faq/"
|
||||
>Una llista de les preguntes més freqüents quant a Matrix <ulink url="https://matrix.org/faq/"
|
||||
>https://matrix.org/faq/</ulink
|
||||
> </member>
|
||||
<member
|
||||
|
||||
6188
po/ca/neochat.po
6188
po/ca/neochat.po
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
6823
po/cs/neochat.po
6823
po/cs/neochat.po
File diff suppressed because it is too large
Load Diff
6891
po/da/neochat.po
6891
po/da/neochat.po
File diff suppressed because it is too large
Load Diff
6670
po/de/neochat.po
6670
po/de/neochat.po
File diff suppressed because it is too large
Load Diff
6940
po/el/neochat.po
6940
po/el/neochat.po
File diff suppressed because it is too large
Load Diff
7596
po/en_GB/neochat.po
7596
po/en_GB/neochat.po
File diff suppressed because it is too large
Load Diff
4738
po/eo/neochat.po
Normal file
4738
po/eo/neochat.po
Normal file
File diff suppressed because it is too large
Load Diff
6376
po/es/neochat.po
6376
po/es/neochat.po
File diff suppressed because it is too large
Load Diff
7098
po/eu/neochat.po
7098
po/eu/neochat.po
File diff suppressed because it is too large
Load Diff
7264
po/fi/neochat.po
7264
po/fi/neochat.po
File diff suppressed because it is too large
Load Diff
6591
po/fr/neochat.po
6591
po/fr/neochat.po
File diff suppressed because it is too large
Load Diff
7733
po/hu/neochat.po
7733
po/hu/neochat.po
File diff suppressed because it is too large
Load Diff
7401
po/ia/neochat.po
7401
po/ia/neochat.po
File diff suppressed because it is too large
Load Diff
6709
po/id/neochat.po
6709
po/id/neochat.po
File diff suppressed because it is too large
Load Diff
7110
po/ie/neochat.po
7110
po/ie/neochat.po
File diff suppressed because it is too large
Load Diff
6400
po/it/neochat.po
6400
po/it/neochat.po
File diff suppressed because it is too large
Load Diff
6461
po/ja/neochat.po
6461
po/ja/neochat.po
File diff suppressed because it is too large
Load Diff
6345
po/ka/neochat.po
6345
po/ka/neochat.po
File diff suppressed because it is too large
Load Diff
7199
po/ko/neochat.po
7199
po/ko/neochat.po
File diff suppressed because it is too large
Load Diff
6657
po/lt/neochat.po
6657
po/lt/neochat.po
File diff suppressed because it is too large
Load Diff
6372
po/nl/neochat.po
6372
po/nl/neochat.po
File diff suppressed because it is too large
Load Diff
7144
po/nn/neochat.po
7144
po/nn/neochat.po
File diff suppressed because it is too large
Load Diff
7510
po/pa/neochat.po
7510
po/pa/neochat.po
File diff suppressed because it is too large
Load Diff
6642
po/pl/neochat.po
6642
po/pl/neochat.po
File diff suppressed because it is too large
Load Diff
6517
po/pt/neochat.po
6517
po/pt/neochat.po
File diff suppressed because it is too large
Load Diff
7562
po/pt_BR/neochat.po
7562
po/pt_BR/neochat.po
File diff suppressed because it is too large
Load Diff
6932
po/ru/neochat.po
6932
po/ru/neochat.po
File diff suppressed because it is too large
Load Diff
7463
po/sk/neochat.po
7463
po/sk/neochat.po
File diff suppressed because it is too large
Load Diff
6601
po/sl/neochat.po
6601
po/sl/neochat.po
File diff suppressed because it is too large
Load Diff
122
po/sv/docs/neochat/man-neochat.1.docbook
Normal file
122
po/sv/docs/neochat/man-neochat.1.docbook
Normal file
@@ -0,0 +1,122 @@
|
||||
<?xml version="1.0" ?>
|
||||
<!DOCTYPE refentry PUBLIC "-//KDE//DTD DocBook XML V4.5-Based Variant V1.1//EN" "dtd/kdedbx45.dtd" [
|
||||
<!ENTITY % Swedish "INCLUDE">
|
||||
]>
|
||||
<!--
|
||||
SPDX-FileCopyrightText: 2022 Carl Schwan <carl@carlschwan.eu>
|
||||
SPDX-License-Identifier: CC-BY-SA-4.0
|
||||
-->
|
||||
|
||||
<refentry lang="&language;">
|
||||
<refentryinfo>
|
||||
<title
|
||||
>NeoChat användarmanual</title>
|
||||
<author
|
||||
><firstname
|
||||
>Carl</firstname
|
||||
><surname
|
||||
>Schwan</surname
|
||||
> <contrib
|
||||
>NeoChat manualsida.</contrib
|
||||
> <email
|
||||
>carl@carlschwan.eu</email
|
||||
></author>
|
||||
<date
|
||||
>2022-11-01</date>
|
||||
<releaseinfo
|
||||
>22.09</releaseinfo>
|
||||
<productname
|
||||
>NeoChat</productname>
|
||||
</refentryinfo>
|
||||
|
||||
<refmeta>
|
||||
<refentrytitle>
|
||||
<command
|
||||
>neochat</command>
|
||||
</refentrytitle>
|
||||
<manvolnum
|
||||
>1</manvolnum>
|
||||
</refmeta>
|
||||
|
||||
<refnamediv>
|
||||
<refname
|
||||
>neochat</refname>
|
||||
<refpurpose
|
||||
>Klient för att interagera med meddelandeprotokollet matrix</refpurpose>
|
||||
</refnamediv>
|
||||
<!-- body begins here -->
|
||||
<refsynopsisdiv id='synopsis'>
|
||||
<cmdsynopsis
|
||||
><command
|
||||
>neochat</command
|
||||
> <arg choice="opt"
|
||||
><replaceable
|
||||
>URI</replaceable
|
||||
></arg
|
||||
> </cmdsynopsis>
|
||||
</refsynopsisdiv>
|
||||
|
||||
|
||||
<refsect1 id="description">
|
||||
<title
|
||||
>Beskrivning</title>
|
||||
<para
|
||||
><command
|
||||
>neochat</command
|
||||
> är ett chattprogram för protokollet matrix som fungerar både på skrivbord och mobil. </para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1 id="options"
|
||||
><title
|
||||
>Väljare</title>
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term
|
||||
><option
|
||||
>URI</option
|
||||
></term>
|
||||
<listitem>
|
||||
<para
|
||||
>Matrix webbadress för en användare eller ett rum, t.ex. matrix:u/användare:exempel.org. Det gör att NeoChat försöker öppna det angivna rummet eller konversationen. </para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
<refsect1 id="bug">
|
||||
<title
|
||||
>Rapportera fel</title>
|
||||
<para
|
||||
>Rapportera fel och funktionsönskemål på <ulink url="https://bugs.kde.org/enter_bug.cgi?product=NeoChat&component=General"
|
||||
>https://bugs.kde.org/enter_bug.cgi?product=NeoChat&component=General</ulink
|
||||
></para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title
|
||||
>Se också</title>
|
||||
<simplelist>
|
||||
<member
|
||||
>En lista över vanliga frågor om Matrix <ulink url="https://matrix.org/faq/"
|
||||
>https://matrix.org/faq/</ulink
|
||||
> </member>
|
||||
<member
|
||||
>kf5options(7)</member>
|
||||
<member
|
||||
>qt5options(7)</member>
|
||||
</simplelist>
|
||||
</refsect1>
|
||||
|
||||
<refsect1 id="copyright"
|
||||
><title
|
||||
>Copyright</title>
|
||||
<para
|
||||
>Copyright © 2020-2022 Tobias Fella </para>
|
||||
<para
|
||||
>Copyright © 2020-2022 Carl Schwan </para>
|
||||
<para
|
||||
>Licens: GNU General Public Version 3 eller senare <<ulink url="https://wwwgnuorg/licenses/gpl-html"
|
||||
>http://www.gnu.org/licenses/gpl-3.0.html</ulink
|
||||
>></para>
|
||||
</refsect1>
|
||||
</refentry>
|
||||
7162
po/sv/neochat.po
7162
po/sv/neochat.po
File diff suppressed because it is too large
Load Diff
6642
po/ta/neochat.po
6642
po/ta/neochat.po
File diff suppressed because it is too large
Load Diff
7036
po/tok/neochat.po
7036
po/tok/neochat.po
File diff suppressed because it is too large
Load Diff
@@ -77,7 +77,7 @@ SPDX-License-Identifier: CC-BY-SA-4.0
|
||||
></term>
|
||||
<listitem>
|
||||
<para
|
||||
>Bir kullanıcı veya oda için matrix URI'si; örneğin, matrix:u/kullanıcı:örnek.org ve matrix:r/kök:örnek.org. Bu, NeoChat'in verilen odayı veya konuşmayı açmayı denemesini sağlar. </para>
|
||||
>Bir kullanıcı veya oda için matrix URI’si; örneğin, matrix:u/kullanıcı:örnek.org ve matrix:r/kök:örnek.org. Bu, NeoChat’in verilen odayı veya konuşmayı açmayı denemesini sağlar. </para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
|
||||
6481
po/tr/neochat.po
6481
po/tr/neochat.po
File diff suppressed because it is too large
Load Diff
6784
po/uk/neochat.po
6784
po/uk/neochat.po
File diff suppressed because it is too large
Load Diff
6344
po/zh_CN/neochat.po
6344
po/zh_CN/neochat.po
File diff suppressed because it is too large
Load Diff
6994
po/zh_TW/neochat.po
6994
po/zh_TW/neochat.po
File diff suppressed because it is too large
Load Diff
@@ -5,96 +5,420 @@
|
||||
|
||||
add_library(neochat STATIC
|
||||
controller.cpp
|
||||
controller.h
|
||||
actionshandler.cpp
|
||||
actionshandler.h
|
||||
models/emojimodel.cpp
|
||||
models/emojimodel.h
|
||||
emojitones.cpp
|
||||
emojitones.h
|
||||
models/customemojimodel.cpp
|
||||
models/customemojimodel.h
|
||||
clipboard.cpp
|
||||
clipboard.h
|
||||
matriximageprovider.cpp
|
||||
matriximageprovider.h
|
||||
models/messageeventmodel.cpp
|
||||
models/messageeventmodel.h
|
||||
models/messagefiltermodel.cpp
|
||||
models/messagefiltermodel.h
|
||||
models/roomlistmodel.cpp
|
||||
models/roomlistmodel.h
|
||||
models/sortfilterspacelistmodel.cpp
|
||||
models/sortfilterspacelistmodel.h
|
||||
models/accountemoticonmodel.cpp
|
||||
models/accountemoticonmodel.h
|
||||
spacehierarchycache.cpp
|
||||
spacehierarchycache.h
|
||||
roommanager.cpp
|
||||
roommanager.h
|
||||
neochatroom.cpp
|
||||
neochatuser.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/keywordnotificationrulemodel.cpp
|
||||
utils.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
|
||||
chatdocumenthandler.cpp
|
||||
chatdocumenthandler.h
|
||||
models/devicesmodel.cpp
|
||||
filetypesingleton.cpp
|
||||
models/devicesmodel.h
|
||||
models/devicesproxymodel.cpp
|
||||
filetype.cpp
|
||||
filetype.h
|
||||
login.cpp
|
||||
stickerevent.cpp
|
||||
login.h
|
||||
models/webshortcutmodel.cpp
|
||||
models/webshortcutmodel.h
|
||||
blurhash.cpp
|
||||
blurhash.h
|
||||
blurhashimageprovider.cpp
|
||||
joinrulesevent.cpp
|
||||
models/collapsestateproxymodel.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
|
||||
registration.cpp
|
||||
neochatconnection.cpp
|
||||
neochatconnection.h
|
||||
jobs/neochatdeactivateaccountjob.cpp
|
||||
jobs/neochatdeactivateaccountjob.h
|
||||
jobs/neochatdeletedevicejob.cpp
|
||||
jobs/neochatdeletedevicejob.h
|
||||
jobs/neochatchangepasswordjob.cpp
|
||||
jobs/neochatchangepasswordjob.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/serveraclevent.h
|
||||
events/widgetevent.h
|
||||
enums/messagecomponenttype.h
|
||||
models/messagecontentmodel.cpp
|
||||
models/messagecontentmodel.h
|
||||
)
|
||||
|
||||
qt_add_qml_module(neochat URI org.kde.neochat NO_PLUGIN
|
||||
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/RoomWindow.qml
|
||||
qml/ExploreRoomsPage.qml
|
||||
qml/ManualRoomDialog.qml
|
||||
qml/ExplorerDelegate.qml
|
||||
qml/InviteUserPage.qml
|
||||
qml/ImageEditorPage.qml
|
||||
qml/WelcomePage.qml
|
||||
qml/General.qml
|
||||
qml/RoomSecurity.qml
|
||||
qml/PushNotification.qml
|
||||
qml/Categories.qml
|
||||
qml/Permissions.qml
|
||||
qml/NeochatMaximizeComponent.qml
|
||||
qml/FancyEffectsContainer.qml
|
||||
qml/TypingPane.qml
|
||||
qml/QuickSwitcher.qml
|
||||
qml/HoverActions.qml
|
||||
qml/ChatBar.qml
|
||||
qml/AttachmentPane.qml
|
||||
qml/ReplyPane.qml
|
||||
qml/CompletionMenu.qml
|
||||
qml/PieProgressBar.qml
|
||||
qml/QuickFormatBar.qml
|
||||
qml/RoomData.qml
|
||||
qml/ServerData.qml
|
||||
qml/EmojiPicker.qml
|
||||
qml/TimelineDelegate.qml
|
||||
qml/ReplyComponent.qml
|
||||
qml/StateDelegate.qml
|
||||
qml/MessageDelegate.qml
|
||||
qml/Bubble.qml
|
||||
qml/SectionDelegate.qml
|
||||
qml/ReactionDelegate.qml
|
||||
qml/EventDelegate.qml
|
||||
qml/ReadMarkerDelegate.qml
|
||||
qml/MimeComponent.qml
|
||||
qml/StateComponent.qml
|
||||
qml/MessageEditComponent.qml
|
||||
qml/AvatarFlow.qml
|
||||
qml/LoginStep.qml
|
||||
qml/Login.qml
|
||||
qml/Homeserver.qml
|
||||
qml/Username.qml
|
||||
qml/RegisterPassword.qml
|
||||
qml/Captcha.qml
|
||||
qml/Terms.qml
|
||||
qml/Email.qml
|
||||
qml/Password.qml
|
||||
qml/LoginRegister.qml
|
||||
qml/Loading.qml
|
||||
qml/LoginMethod.qml
|
||||
qml/Sso.qml
|
||||
qml/UserDetailDialog.qml
|
||||
qml/CreateRoomDialog.qml
|
||||
qml/EmojiDialog.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/GlobalMenu.qml
|
||||
qml/EditMenu.qml
|
||||
qml/MessageDelegateContextMenu.qml
|
||||
qml/FileDelegateContextMenu.qml
|
||||
qml/MessageSourceSheet.qml
|
||||
qml/ReportSheet.qml
|
||||
qml/SettingsPage.qml
|
||||
qml/ThemeRadioButton.qml
|
||||
qml/ColorScheme.qml
|
||||
qml/GeneralSettingsPage.qml
|
||||
qml/EmoticonsPage.qml
|
||||
qml/EmoticonEditorPage.qml
|
||||
qml/EmoticonFormCard.qml
|
||||
qml/GlobalNotificationsPage.qml
|
||||
qml/NotificationRuleItem.qml
|
||||
qml/AppearanceSettingsPage.qml
|
||||
qml/AccountsPage.qml
|
||||
qml/AccountEditorPage.qml
|
||||
qml/DevicesPage.qml
|
||||
qml/DeviceDelegate.qml
|
||||
qml/DevicesCard.qml
|
||||
qml/About.qml
|
||||
qml/AboutKDE.qml
|
||||
qml/SonnetConfigPage.qml
|
||||
qml/NetworkProxyPage.qml
|
||||
qml/DevtoolsPage.qml
|
||||
qml/ConfirmEncryptionDialog.qml
|
||||
qml/RemoveSheet.qml
|
||||
qml/BanSheet.qml
|
||||
qml/EmojiTonesPicker.qml
|
||||
qml/EmojiDelegate.qml
|
||||
qml/EmojiGrid.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/ShareAction.qml
|
||||
qml/SpaceHomePage.qml
|
||||
qml/SpaceHierarchyDelegate.qml
|
||||
qml/RemoveChildDialog.qml
|
||||
qml/SelectParentDialog.qml
|
||||
qml/Security.qml
|
||||
qml/QrCodeMaximizeComponent.qml
|
||||
qml/SelectSpacesDialog.qml
|
||||
qml/AttachDialog.qml
|
||||
qml/NotificationsView.qml
|
||||
qml/LoadingDelegate.qml
|
||||
qml/TimelineEndDelegate.qml
|
||||
qml/SearchPage.qml
|
||||
qml/ServerComboBox.qml
|
||||
qml/UserSearchPage.qml
|
||||
qml/ManualUserDialog.qml
|
||||
qml/MessageComponentChooser.qml
|
||||
qml/TextComponent.qml
|
||||
qml/ImageComponent.qml
|
||||
qml/VideoComponent.qml
|
||||
qml/AudioComponent.qml
|
||||
qml/EncryptedComponent.qml
|
||||
qml/FileComponent.qml
|
||||
qml/LocationComponent.qml
|
||||
qml/LiveLocationComponent.qml
|
||||
qml/PollComponent.qml
|
||||
qml/LinkPreviewComponent.qml
|
||||
qml/LoadComponent.qml
|
||||
qml/RecommendedSpaceDialog.qml
|
||||
RESOURCES
|
||||
qml/confetti.png
|
||||
qml/glowdot.png
|
||||
)
|
||||
|
||||
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
|
||||
res.qrc
|
||||
)
|
||||
|
||||
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
|
||||
)
|
||||
|
||||
if(Quotient_VERSION_MINOR GREATER 6)
|
||||
target_compile_definitions(neochat PUBLIC QUOTIENT_07)
|
||||
target_sources(neochat PRIVATE pollevent.cpp pollhandler.cpp)
|
||||
else()
|
||||
target_compile_definitions(neochat PUBLIC QUOTIENT_VERSION=\"${Quotient_VERSION}\")
|
||||
target_sources(neochat PRIVATE neochataccountregistry.cpp)
|
||||
endif()
|
||||
|
||||
ecm_add_app_icon(NEOCHAT_ICON ICONS ${CMAKE_SOURCE_DIR}/128-logo.png)
|
||||
|
||||
target_sources(neochat-app PRIVATE ${NEOCHAT_ICON})
|
||||
|
||||
if(NOT ANDROID)
|
||||
target_sources(neochat PRIVATE colorschemer.cpp)
|
||||
if (NOT WIN32 AND NOT APPLE)
|
||||
target_sources(neochat PRIVATE trayicon_sni.cpp)
|
||||
target_sources(neochat PRIVATE trayicon_sni.cpp trayicon_sni.h)
|
||||
target_link_libraries(neochat PRIVATE KF6::StatusNotifierItem)
|
||||
else()
|
||||
target_sources(neochat PRIVATE trayicon.cpp)
|
||||
target_sources(neochat PRIVATE trayicon.cpp trayicon.h)
|
||||
endif()
|
||||
target_link_libraries(neochat PUBLIC KF${QT_MAJOR_VERSION}::ConfigWidgets KF${QT_MAJOR_VERSION}::WindowSystem)
|
||||
target_compile_definitions(neochat PUBLIC -DHAVE_COLORSCHEME)
|
||||
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)
|
||||
target_sources(neochat-app PRIVATE res_desktop.qrc)
|
||||
target_compile_definitions(neochat PUBLIC -DHAVE_RUNNER)
|
||||
target_compile_definitions(neochat PUBLIC -DHAVE_X11)
|
||||
target_sources(neochat PRIVATE runner.cpp)
|
||||
else()
|
||||
target_sources(neochat-app PRIVATE res_android.qrc)
|
||||
endif()
|
||||
|
||||
target_include_directories(neochat PRIVATE ${CMAKE_BINARY_DIR})
|
||||
target_link_libraries(neochat PUBLIC Qt::Core Qt::Quick Qt::Qml Qt::Gui Qt::Multimedia Qt::Network Qt::QuickControls2 KF${QT_MAJOR_VERSION}::I18n KF${QT_MAJOR_VERSION}::Kirigami2 KF${QT_MAJOR_VERSION}::Notifications KF${QT_MAJOR_VERSION}::ConfigCore KF${QT_MAJOR_VERSION}::ConfigGui KF${QT_MAJOR_VERSION}::CoreAddons KF${QT_MAJOR_VERSION}::SonnetCore KF${QT_MAJOR_VERSION}::ItemModels Quotient cmark::cmark ${QTKEYCHAIN_LIBRARIES} QCoro::Core)
|
||||
target_include_directories(neochat PRIVATE ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/models ${CMAKE_CURRENT_SOURCE_DIR}/enums)
|
||||
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::ColorScheme
|
||||
KF6::ItemModels
|
||||
QuotientQt6
|
||||
cmark::cmark
|
||||
QCoro::Core
|
||||
QCoro::Network
|
||||
)
|
||||
|
||||
kconfig_add_kcfg_files(neochat GENERATE_MOC neochatconfig.kcfgc)
|
||||
|
||||
if(NEOCHAT_FLATPAK)
|
||||
@@ -175,9 +499,29 @@ if(ANDROID)
|
||||
"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-low"
|
||||
"security-low-symbolic"
|
||||
"kde"
|
||||
"list-remove-symbolic"
|
||||
"edit-delete"
|
||||
)
|
||||
ecm_add_android_apk(neochat-app ANDROID_DIR ${CMAKE_SOURCE_DIR}/android)
|
||||
else()
|
||||
target_link_libraries(neochat PUBLIC Qt::Widgets KF${QT_MAJOR_VERSION}::KIOWidgets)
|
||||
target_link_libraries(neochat PUBLIC Qt::Widgets KF6::KIOWidgets)
|
||||
install(FILES neochat.notifyrc DESTINATION ${KDE_INSTALL_KNOTIFYRCDIR})
|
||||
endif()
|
||||
|
||||
@@ -185,18 +529,27 @@ if(NOT ANDROID)
|
||||
set_target_properties(neochat-app PROPERTIES OUTPUT_NAME "neochat")
|
||||
endif()
|
||||
|
||||
if(TARGET KF${QT_MAJOR_VERSION}::DBusAddons)
|
||||
target_link_libraries(neochat PUBLIC KF${QT_MAJOR_VERSION}::DBusAddons)
|
||||
if(TARGET KF6::DBusAddons)
|
||||
target_link_libraries(neochat PUBLIC KF6::DBusAddons)
|
||||
target_compile_definitions(neochat PUBLIC -DHAVE_KDBUSADDONS)
|
||||
endif()
|
||||
|
||||
if (TARGET KF${QT_MAJOR_VERSION}::KIOWidgets)
|
||||
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()
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user