forked from GitHub-Mirror/riotX-android
Compare commits
526 Commits
feature/fi
...
v0.8.0
Author | SHA1 | Date | |
---|---|---|---|
eb32c5455f | |||
57dcd569f3 | |||
fe17050580 | |||
ec40a8c969 | |||
6b1b3bec85 | |||
6bd6ececb7 | |||
c7db695e67 | |||
4cefdfedce | |||
6ce241163e | |||
79350899c5 | |||
f265724a3c | |||
2e50d2a36e | |||
643c062858 | |||
0e0db67aef | |||
6dc5b126d6 | |||
d2acabddd9 | |||
ec71b53c1e | |||
fc3d4187d1 | |||
a25f309990 | |||
5449592422 | |||
19b415871d | |||
6463f3439f | |||
f2320f9571 | |||
fc91694bdd | |||
dbb41108ef | |||
08c864bad7 | |||
9c5c65a243 | |||
b6199b1f27 | |||
38da54119a | |||
65b09ad4f0 | |||
603b8fae45 | |||
50e2e6a823 | |||
bb237e3bbb | |||
1bd2c0d220 | |||
bcb811a7e8 | |||
ec4d7e29ec | |||
a6df63f6d9 | |||
ea7213a5ae | |||
590a13334d | |||
631448335d | |||
12376368c7 | |||
f17564d743 | |||
a6fcc7dca6 | |||
70bce9e7dd | |||
17f3614288 | |||
238d1d87c6 | |||
82f639b91f | |||
c8bc553caa | |||
fa5d44af65 | |||
cbdbe5033f | |||
61ac250e2b | |||
04f72dfcb8 | |||
10ca5d94ea | |||
c5b8c69ae5 | |||
d3d7f7cc61 | |||
b6bb714264 | |||
a87310ac15 | |||
032e1b3d19 | |||
d9f15c1d21 | |||
99d09f71ad | |||
9c952b6bc8 | |||
fbae3d27c2 | |||
2f7d1f9f01 | |||
114101699d | |||
f5c0dcb5ea | |||
241220ce1f | |||
98d97e574c | |||
96e610970a | |||
2027802f82 | |||
54f93db632 | |||
3af7ca9ab0 | |||
93ef3edab3 | |||
c85852262e | |||
d0c3271628 | |||
ad9a48d5fa | |||
219d1383e5 | |||
8871280fab | |||
fb3e953e28 | |||
10712fd6ab | |||
9d478dbfe2 | |||
3013d67c16 | |||
bee8c2d159 | |||
945e5d5a74 | |||
93df8c56a8 | |||
cd1a964067 | |||
e4b829f0cf | |||
7206d84a6b | |||
b3233d3eb7 | |||
3c4c0ed46a | |||
24f1262005 | |||
86667a6d8a | |||
42e0d0f769 | |||
e976055253 | |||
84d6c8ec16 | |||
9fdfd091ac | |||
e66766f41c | |||
6177e69855 | |||
5c71cabb5f | |||
6ebe5532c5 | |||
8030c44f44 | |||
a85b5af761 | |||
d780c74abf | |||
5d7efa7f8f | |||
7e467443ed | |||
8439c337f7 | |||
151ad01038 | |||
73267442bb | |||
43fd794c96 | |||
36060fe332 | |||
3483debcc1 | |||
4324f6abbd | |||
43f8d8d8aa | |||
fb1ff77ec4 | |||
e355a7f6dd | |||
33e35368fc | |||
0e49a11e5e | |||
d47cf7e932 | |||
101057520b | |||
30b2e53002 | |||
5ab31a0ef5 | |||
b4ae331086 | |||
3f447df13c | |||
3517873156 | |||
118870bc41 | |||
d001ab5bef | |||
7496a88dcd | |||
6567c5e6c7 | |||
361427488f | |||
7272343e6d | |||
f0b3151d71 | |||
035359cb35 | |||
57b640622b | |||
de4c389c76 | |||
199456487c | |||
00ca5dc70a | |||
a04802b238 | |||
cb275aee37 | |||
fbf73c7c8e | |||
0040f8e924 | |||
6cca242f77 | |||
2929b8f617 | |||
8422c6de17 | |||
7c567b04bb | |||
1ac99e92a6 | |||
5ab975cc5c | |||
2cf63ea92a | |||
9e8d8ce878 | |||
b766bce07d | |||
01452efd8d | |||
0a0af221f0 | |||
af08759af6 | |||
e52f0faaa7 | |||
8fa676d034 | |||
b6594599c4 | |||
8be8cc9ef7 | |||
9762d5be40 | |||
b17b54d218 | |||
187e2a26db | |||
2f5fdbb7e2 | |||
8b1411f533 | |||
bdee5e0687 | |||
ce4e244a3b | |||
ff81715783 | |||
3196dcb57e | |||
50bf6df7fe | |||
02914495ce | |||
70a14f6350 | |||
cac5fb725a | |||
dbc17ae515 | |||
1de02c2fbb | |||
6d55c15761 | |||
377a228f88 | |||
2974f8b200 | |||
7388a408b8 | |||
f43dcb1183 | |||
492ed3954a | |||
7890e83204 | |||
00d1a2c380 | |||
78dfd6b3e6 | |||
3abce34484 | |||
4204ab262c | |||
c7a4d34192 | |||
7416fec93e | |||
3c40f64fb7 | |||
b57c71b1c9 | |||
fea54952d3 | |||
3dc5ef54ab | |||
9092b97fb8 | |||
cebd8136da | |||
64b3568d51 | |||
5e4e54153c | |||
d071324694 | |||
2c8cd89533 | |||
11b5c2c3ba | |||
9d7c4abb97 | |||
8e3234d188 | |||
b253722b98 | |||
fce576e3a4 | |||
7ed7b18ccd | |||
053bf7aeac | |||
6ccd083451 | |||
e39c4a7925 | |||
abdb83b9fd | |||
0bcc84cbd6 | |||
b2f6fb8c91 | |||
36042ed145 | |||
6ad1932fe5 | |||
4a6237b50e | |||
a7a19dab11 | |||
8d0aa0437c | |||
0a79b8b315 | |||
1dacfa6744 | |||
723a007c39 | |||
eaa1b04a4a | |||
b1710fde60 | |||
cd0a40c18d | |||
17636019e0 | |||
8078c39d6e | |||
be94b2f90a | |||
eff04be247 | |||
3986839801 | |||
9e436483de | |||
05a069be04 | |||
a1a71e2f1d | |||
203da0f37e | |||
6cd04525aa | |||
3c3c6aeac6 | |||
e71311f576 | |||
e4d0e0b0bf | |||
28e5e42ab1 | |||
b860c3b0e3 | |||
f7f97e2098 | |||
e28e2dadb9 | |||
c28be6adb0 | |||
c57af9cf3e | |||
679b0fff98 | |||
946fc36a26 | |||
13a5f784dc | |||
0ca8696e88 | |||
3622c0ecb4 | |||
116d569fa8 | |||
ee5ebb4b83 | |||
0a0c344bfb | |||
82fc97f619 | |||
20696353b8 | |||
ae5b6bd2b9 | |||
1e11d4492b | |||
6e39164b20 | |||
0a9ebb6bf6 | |||
db009ce683 | |||
55c80d3743 | |||
fbb23dfb66 | |||
e5779d425a | |||
99d9704a50 | |||
3f8ddbe880 | |||
30e43e47cd | |||
15dc4d6369 | |||
dceb5ffd8d | |||
eec470f2ce | |||
68db9c1cc0 | |||
cdfc402599 | |||
72d3f1e909 | |||
255fa11e89 | |||
119e4c0d32 | |||
a9c474105a | |||
6de64cbedd | |||
546c537e3b | |||
36c5f9af13 | |||
c2682c7f4b | |||
3073470c38 | |||
549f749682 | |||
d4dfb76e80 | |||
e80191b2e0 | |||
c62c77f14c | |||
d6e5c5a857 | |||
50a0660ab6 | |||
ecdb3c3326 | |||
2cd1d697fe | |||
3f9b7813bc | |||
f34f28b668 | |||
53572a3be6 | |||
90b6199e10 | |||
0aa299aa37 | |||
d387c310c8 | |||
8bd1fb08f7 | |||
ac6aff9175 | |||
adf0382d28 | |||
51554f7be0 | |||
c1c1c3f999 | |||
8b04fdab77 | |||
f8b665a245 | |||
d68a9a5342 | |||
5d2ff589f8 | |||
e85a0783fc | |||
d6c278288d | |||
4ad86a13a0 | |||
4f7ec91255 | |||
979b42aa30 | |||
fc49de080c | |||
d2b9668d4e | |||
0632870be1 | |||
8e39fd2a70 | |||
abbc62dd35 | |||
77de059dc9 | |||
1931a1a4a4 | |||
9c5987b682 | |||
4e4fb4c565 | |||
0582d0f641 | |||
ef2af14529 | |||
525da17678 | |||
aab41d7358 | |||
5db3c81aa9 | |||
c763635845 | |||
11d72b81f6 | |||
53543453b3 | |||
d4be68191c | |||
7ef471ad0d | |||
73dd735ba6 | |||
2f6d3adb17 | |||
2edfd4e830 | |||
ff7856c535 | |||
650a151b18 | |||
275dd20412 | |||
44f6391cb4 | |||
588e5d6e63 | |||
716999eec6 | |||
42e0a45f3f | |||
31397869b2 | |||
e842bf13b2 | |||
aea34da81e | |||
0814f53fed | |||
b5c6c1af0d | |||
de30e7c1c6 | |||
2d95fe921d | |||
84542326f4 | |||
53b1b89c47 | |||
28315be7b9 | |||
8605095668 | |||
737959f616 | |||
7817f49072 | |||
a060431aaf | |||
a3f561d788 | |||
0ea878af8a | |||
99de40c980 | |||
810a97c639 | |||
f02f16d9c5 | |||
62b7a83a31 | |||
4a80df082c | |||
60f6b3ef02 | |||
a0b1ef3216 | |||
1b66d1f746 | |||
643a2baabf | |||
cd62e87266 | |||
17cba1a432 | |||
f077cc8467 | |||
f3039601bf | |||
4c04014e4d | |||
ae8bceacba | |||
9b91b6ea87 | |||
b24a372262 | |||
63b43de4b8 | |||
d1a61f29e4 | |||
f6373221de | |||
ec0974f72c | |||
b5f2f01c8d | |||
21d808c1ce | |||
1e963bc0dc | |||
0d80750507 | |||
1c9cf7a810 | |||
c6d01fbcf4 | |||
9e1ded941f | |||
af433266c8 | |||
05d09bf950 | |||
6890f83810 | |||
51568c30a6 | |||
cc832633a5 | |||
e019ec6596 | |||
eadea9016b | |||
6422d946c9 | |||
5cc3dc00e3 | |||
5a2a9f908a | |||
c1f2e9f171 | |||
f6d34ec7fd | |||
620ba279d8 | |||
3fcfa33364 | |||
546da0f173 | |||
001711d5a3 | |||
8e1a964679 | |||
b25a130db1 | |||
8a9e6497e8 | |||
47e3797b7e | |||
5cbc90e06a | |||
b6e18e4a8f | |||
7e29665fd0 | |||
e04bf31faa | |||
d25cf79b07 | |||
faa8e6bbb2 | |||
d3d4deb884 | |||
f6b8e0c479 | |||
2a726f54a2 | |||
1197d4021d | |||
03f8120b7d | |||
acd7a709de | |||
5651ea515b | |||
9794b3a49d | |||
b3e1c3969d | |||
90eeb68d36 | |||
d1ff3314a7 | |||
f24bed17a2 | |||
a993a30203 | |||
ea0809ff87 | |||
9668487b6b | |||
91cc78d2ad | |||
562acc9702 | |||
dfab88ed95 | |||
36866dd24e | |||
c728834273 | |||
f5020d0f63 | |||
7da9cafcc2 | |||
6f09eea248 | |||
468bd5bcc9 | |||
3169093c50 | |||
d60d766354 | |||
0ffb5e627e | |||
b4a13f9504 | |||
88fb9667a3 | |||
ffa8b7e73a | |||
528958b3de | |||
3ffe2f7d40 | |||
3066d5f303 | |||
bf42b73713 | |||
ed93f4a6c1 | |||
b3d649a4d9 | |||
3739e50d46 | |||
9bf484cf1e | |||
6c2faff1f0 | |||
07fca0922b | |||
282de21708 | |||
ba9d119892 | |||
4453f0ced9 | |||
77168bfd6a | |||
25e9a179d2 | |||
73ec0f5a83 | |||
993fa74252 | |||
38fc4984fe | |||
695d8cce00 | |||
07e99901e1 | |||
20f53e9a58 | |||
ced72aff4f | |||
fdaaca49c2 | |||
3485f023b0 | |||
384dd100e9 | |||
1ba8a58219 | |||
69fb7bdf95 | |||
c8010561fc | |||
1f127335bc | |||
138a210a73 | |||
ca6bcde82d | |||
6bda437f5d | |||
5d6d0202a9 | |||
3e6b65e174 | |||
137dcab734 | |||
b22b8fba02 | |||
3ccdf4a244 | |||
5fbd271b1c | |||
db8ea0f5e8 | |||
a47a3ead1f | |||
05b2092ffc | |||
f4ab770be9 | |||
6249a59203 | |||
d4111d053d | |||
618e9a4f52 | |||
b8ebe3570b | |||
f2c8d4ad02 | |||
be524472ec | |||
1b82a1a24d | |||
cf0b331c3b | |||
2a92a3dc80 | |||
012840abba | |||
a5975a099e | |||
38da4b9ee5 | |||
242e60fcaa | |||
a23be05cbf | |||
ed39b02924 | |||
fe931b5361 | |||
90d9cd0587 | |||
9cedb18921 | |||
e89ba7b87b | |||
902657c22a | |||
eec2abf164 | |||
6879cc8ca8 | |||
fd6bbbd3b5 | |||
0ff0b014a9 | |||
a89f0ddd1d | |||
fdc9e84dd5 | |||
58f878fca9 | |||
88095e4bd9 | |||
47d22a3d5e | |||
28e82cb8ea | |||
35817245cb | |||
75266f42bb | |||
95c4c9ce56 | |||
ce5570105d | |||
188a9aebfa | |||
c95223f5d2 | |||
ef0362ba9c | |||
ea242f6737 | |||
cbc08d834b | |||
0ab6b33fb6 | |||
1b394527b6 | |||
a8f1388721 | |||
166be4e289 | |||
b49ccefe63 | |||
825760d17e | |||
b5af62c3ea | |||
a51d96bf00 | |||
7e142d201d | |||
2be6058971 | |||
49d73f360e | |||
51a4c93676 | |||
d8f449388c | |||
9cd69d1e33 | |||
456908c851 | |||
215324a03e | |||
02e342849f | |||
df6080b1da |
@ -1,15 +1,38 @@
|
|||||||
# Use Docker file from https://hub.docker.com/r/runmymind/docker-android-sdk
|
# Use Docker file from https://hub.docker.com/r/runmymind/docker-android-sdk
|
||||||
# Last docker plugin version can be found here:
|
# Last docker plugin version can be found here:
|
||||||
# https://github.com/buildkite-plugins/docker-buildkite-plugin/releases
|
# https://github.com/buildkite-plugins/docker-buildkite-plugin/releases
|
||||||
|
# We propagate the environment to the container (sse https://github.com/buildkite-plugins/docker-buildkite-plugin#propagate-environment-optional-boolean)
|
||||||
# Build debug version of the RiotX application, from the develop branch and the features branches
|
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- label: "Assemble GPlay Debug version"
|
- label: "Compile and run Unit tests"
|
||||||
agents:
|
agents:
|
||||||
# We use a medium sized instance instead of the normal small ones because
|
# We use a medium sized instance instead of the normal small ones because
|
||||||
# gradle build is long
|
# gradle build can be memory hungry
|
||||||
queue: "medium"
|
queue: "medium"
|
||||||
|
commands:
|
||||||
|
- "./gradlew clean test --stacktrace"
|
||||||
|
plugins:
|
||||||
|
- docker#v3.1.0:
|
||||||
|
image: "runmymind/docker-android-sdk"
|
||||||
|
propagate-environment: true
|
||||||
|
|
||||||
|
- label: "Compile Android tests"
|
||||||
|
agents:
|
||||||
|
# We use a medium sized instance instead of the normal small ones because
|
||||||
|
# gradle build can be memory hungry
|
||||||
|
queue: "medium"
|
||||||
|
commands:
|
||||||
|
- "./gradlew clean assembleAndroidTest --stacktrace"
|
||||||
|
plugins:
|
||||||
|
- docker#v3.1.0:
|
||||||
|
image: "runmymind/docker-android-sdk"
|
||||||
|
propagate-environment: true
|
||||||
|
|
||||||
|
- label: "Assemble GPlay Debug version"
|
||||||
|
agents:
|
||||||
|
# We use a xlarge sized instance instead of the normal small ones because
|
||||||
|
# gradle build can be memory hungry
|
||||||
|
queue: "xlarge"
|
||||||
commands:
|
commands:
|
||||||
- "./gradlew clean lintGplayRelease assembleGplayDebug --stacktrace"
|
- "./gradlew clean lintGplayRelease assembleGplayDebug --stacktrace"
|
||||||
artifact_paths:
|
artifact_paths:
|
||||||
@ -18,12 +41,13 @@ steps:
|
|||||||
plugins:
|
plugins:
|
||||||
- docker#v3.1.0:
|
- docker#v3.1.0:
|
||||||
image: "runmymind/docker-android-sdk"
|
image: "runmymind/docker-android-sdk"
|
||||||
|
propagate-environment: true
|
||||||
|
|
||||||
- label: "Assemble FDroid Debug version"
|
- label: "Assemble FDroid Debug version"
|
||||||
agents:
|
agents:
|
||||||
# We use a medium sized instance instead of the normal small ones because
|
# We use a xlarge sized instance instead of the normal small ones because
|
||||||
# gradle build is long
|
# gradle build can be memory hungry
|
||||||
queue: "medium"
|
queue: "xlarge"
|
||||||
commands:
|
commands:
|
||||||
- "./gradlew clean lintFdroidRelease assembleFdroidDebug --stacktrace"
|
- "./gradlew clean lintFdroidRelease assembleFdroidDebug --stacktrace"
|
||||||
artifact_paths:
|
artifact_paths:
|
||||||
@ -32,12 +56,13 @@ steps:
|
|||||||
plugins:
|
plugins:
|
||||||
- docker#v3.1.0:
|
- docker#v3.1.0:
|
||||||
image: "runmymind/docker-android-sdk"
|
image: "runmymind/docker-android-sdk"
|
||||||
|
propagate-environment: true
|
||||||
|
|
||||||
- label: "Build Google Play unsigned APK"
|
- label: "Build Google Play unsigned APK"
|
||||||
agents:
|
agents:
|
||||||
# We use a medium sized instance instead of the normal small ones because
|
# We use a xlarge sized instance instead of the normal small ones because
|
||||||
# gradle build is long
|
# gradle build can be memory hungry
|
||||||
queue: "medium"
|
queue: "xlarge"
|
||||||
commands:
|
commands:
|
||||||
- "./gradlew clean assembleGplayRelease --stacktrace"
|
- "./gradlew clean assembleGplayRelease --stacktrace"
|
||||||
artifact_paths:
|
artifact_paths:
|
||||||
@ -46,8 +71,18 @@ steps:
|
|||||||
plugins:
|
plugins:
|
||||||
- docker#v3.1.0:
|
- docker#v3.1.0:
|
||||||
image: "runmymind/docker-android-sdk"
|
image: "runmymind/docker-android-sdk"
|
||||||
|
propagate-environment: true
|
||||||
|
|
||||||
# Code quality
|
# Code quality
|
||||||
|
|
||||||
- label: "Code quality"
|
- label: "Code quality"
|
||||||
command: "./tools/check/check_code_quality.sh"
|
command:
|
||||||
|
- "./tools/check/check_code_quality.sh"
|
||||||
|
|
||||||
|
- label: "ktlint"
|
||||||
|
command:
|
||||||
|
- "curl -sSLO https://github.com/pinterest/ktlint/releases/download/0.34.2/ktlint && chmod a+x ktlint"
|
||||||
|
- "./ktlint --android --experimental -v"
|
||||||
|
plugins:
|
||||||
|
- docker#v3.1.0:
|
||||||
|
image: "openjdk"
|
||||||
|
32
.editorconfig
Normal file
32
.editorconfig
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
# For ktlint configuration. Ref: https://ktlint.github.io/
|
||||||
|
|
||||||
|
[*.{kt,kts}]
|
||||||
|
# possible values: number (e.g. 2), "unset" (makes ktlint ignore indentation completely)
|
||||||
|
indent_size=unset
|
||||||
|
# true (recommended) / false
|
||||||
|
insert_final_newline=true
|
||||||
|
# possible values: number (e.g. 120) (package name, imports & comments are ignored), "off"
|
||||||
|
# it's automatically set to 100 on `ktlint --android ...` (per Android Kotlin Style Guide)
|
||||||
|
max_line_length=off
|
||||||
|
|
||||||
|
# Comma-separated list of rules to disable (Since 0.34.0)
|
||||||
|
# Note that rules in any ruleset other than the standard ruleset will need to be prefixed
|
||||||
|
# by the ruleset identifier.
|
||||||
|
disabled_rules=no-wildcard-imports,no-multi-spaces,colon-spacing,chain-wrapping,import-ordering,experimental:annotation
|
||||||
|
|
||||||
|
# The following (so far identified) rules are kept:
|
||||||
|
# no-blank-line-before-rbrace
|
||||||
|
# final-newline
|
||||||
|
# no-consecutive-blank-lines
|
||||||
|
# comment-spacing
|
||||||
|
# filename
|
||||||
|
# comma-spacing
|
||||||
|
# paren-spacing
|
||||||
|
# op-spacing
|
||||||
|
# string-template
|
||||||
|
# no-unused-imports
|
||||||
|
# curly-spacing
|
||||||
|
# no-semi
|
||||||
|
# no-empty-class-body
|
||||||
|
# experimental:multiline-if-else
|
||||||
|
# experimental:no-empty-first-line-in-method-block
|
14
.gitignore
vendored
14
.gitignore
vendored
@ -1,14 +1,18 @@
|
|||||||
*.iml
|
*.iml
|
||||||
.gradle
|
.gradle
|
||||||
/local.properties
|
/local.properties
|
||||||
.idea/*
|
# idea files: exclude everything except dictionnaries
|
||||||
/.idea/*
|
.idea/caches
|
||||||
/.idea/libraries
|
.idea/codeStyles
|
||||||
/.idea/modules.xml
|
.idea/libraries
|
||||||
/.idea/workspace.xml
|
.idea/*.xml
|
||||||
.DS_Store
|
.DS_Store
|
||||||
/build
|
/build
|
||||||
/captures
|
/captures
|
||||||
.externalNativeBuild
|
.externalNativeBuild
|
||||||
|
|
||||||
/tmp
|
/tmp
|
||||||
|
|
||||||
|
ktlint
|
||||||
|
.idea/copyright/New_vector.xml
|
||||||
|
.idea/copyright/profiles_settings.xml
|
||||||
|
19
.idea/dictionaries/bmarty.xml
generated
Normal file
19
.idea/dictionaries/bmarty.xml
generated
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<component name="ProjectDictionaryState">
|
||||||
|
<dictionary name="bmarty">
|
||||||
|
<words>
|
||||||
|
<w>backstack</w>
|
||||||
|
<w>bytearray</w>
|
||||||
|
<w>ciphertext</w>
|
||||||
|
<w>decryptor</w>
|
||||||
|
<w>emoji</w>
|
||||||
|
<w>emojis</w>
|
||||||
|
<w>hmac</w>
|
||||||
|
<w>ktlint</w>
|
||||||
|
<w>linkified</w>
|
||||||
|
<w>linkify</w>
|
||||||
|
<w>megolm</w>
|
||||||
|
<w>pbkdf</w>
|
||||||
|
<w>pkcs</w>
|
||||||
|
</words>
|
||||||
|
</dictionary>
|
||||||
|
</component>
|
130
CHANGES.md
130
CHANGES.md
@ -1,25 +1,123 @@
|
|||||||
Changes in RiotX 0.4.0 (2019-XX-XX)
|
Changes in RiotX 0.8.0 (2019-11-19)
|
||||||
|
===================================================
|
||||||
|
|
||||||
|
Features ✨:
|
||||||
|
- Handle long click on room in the room list (#395)
|
||||||
|
- Ignore/UnIgnore users, and display list of ignored users (#542, #617)
|
||||||
|
|
||||||
|
Improvements 🙌:
|
||||||
|
- Search reaction by name or keyword in emoji picker
|
||||||
|
- Handle code tags (#567)
|
||||||
|
- Support spoiler messages
|
||||||
|
- Support m.sticker and m.room.join_rules events in timeline
|
||||||
|
|
||||||
|
Other changes:
|
||||||
|
- Markdown set to off by default (#412)
|
||||||
|
- Accessibility improvements to the attachment file type chooser
|
||||||
|
|
||||||
|
Bugfix 🐛:
|
||||||
|
- Fix issues with some member events rendering (#498)
|
||||||
|
- Passphrase does not match (Export room keys) (#644)
|
||||||
|
- Ask for permission to write external storage when uri comes from the keyboard (#658)
|
||||||
|
- Fix issue with english US/GB translation (#671)
|
||||||
|
|
||||||
|
Changes in RiotX 0.7.0 (2019-10-24)
|
||||||
|
===================================================
|
||||||
|
|
||||||
|
Features:
|
||||||
|
- Share elements from other app to RiotX (#58)
|
||||||
|
- Read marker (#84)
|
||||||
|
- Add ability to report content (#515)
|
||||||
|
|
||||||
|
Improvements:
|
||||||
|
- Persist active tab between sessions (#503)
|
||||||
|
- Do not upload file too big for the homeserver (#587)
|
||||||
|
- Attachments: start using system pickers (#52)
|
||||||
|
- Mark all messages as read (#396)
|
||||||
|
|
||||||
|
|
||||||
|
Other changes:
|
||||||
|
- Accessibility improvements to read receipts in the room timeline and reactions emoji chooser
|
||||||
|
|
||||||
|
Bugfix:
|
||||||
|
- Fix issue on upload error in loop (#587)
|
||||||
|
- Fix opening a permalink: the targeted event is displayed twice (#556)
|
||||||
|
- Fix opening a permalink paginates all the history up to the last event (#282)
|
||||||
|
- after login, the icon in the top left is a green 'A' for (all communities) rather than my avatar (#267)
|
||||||
|
- Picture uploads are unreliable, pictures are shown in wrong aspect ratio on desktop client (#517)
|
||||||
|
- Invitation notifications are not dismissed automatically if room is joined from another client (#347)
|
||||||
|
- Opening links from RiotX reuses browser tab (#599)
|
||||||
|
|
||||||
|
Changes in RiotX 0.6.1 (2019-09-24)
|
||||||
|
===================================================
|
||||||
|
|
||||||
|
Bugfix:
|
||||||
|
- Fix crash: MergedHeaderItem was missing dimensionConverter
|
||||||
|
|
||||||
|
Changes in RiotX 0.6.0 (2019-09-24)
|
||||||
|
===================================================
|
||||||
|
|
||||||
|
Features:
|
||||||
|
- Save draft of a message when exiting a room with non empty composer (#329)
|
||||||
|
|
||||||
|
Improvements:
|
||||||
|
- Add unread indent on room list (#485)
|
||||||
|
- Message Editing: Update notifications (#128)
|
||||||
|
- Remove any notification of a redacted event (#563)
|
||||||
|
|
||||||
|
Other changes:
|
||||||
|
- Fix a few accessibility issues
|
||||||
|
|
||||||
|
Bugfix:
|
||||||
|
- Fix characters erased from the Search field when the result are coming (#545)
|
||||||
|
- "No connection" banner was displayed by mistake
|
||||||
|
- Leaving community (from another client) has no effect on RiotX (#497)
|
||||||
|
- Push rules was not retrieved after a clear cache
|
||||||
|
- m.notice messages trigger push notifications (#238)
|
||||||
|
- Embiggen messages with multiple emojis also for edited messages (#458)
|
||||||
|
|
||||||
|
Build:
|
||||||
|
- Fix (again) issue with bad versionCode generated by Buildkite (#553)
|
||||||
|
|
||||||
|
Changes in RiotX 0.5.0 (2019-09-17)
|
||||||
|
===================================================
|
||||||
|
|
||||||
|
Features:
|
||||||
|
- Implementation of login to homeserver with SSO (#557)
|
||||||
|
- Handle M_CONSENT_NOT_GIVEN error (#64)
|
||||||
|
- Auto configure homeserver and identity server URLs of LoginActivity with a magic link
|
||||||
|
|
||||||
|
Improvements:
|
||||||
|
- Reduce default release build log level, and lab option to enable more logs.
|
||||||
|
- Display a no network indicator when there is no network (#559)
|
||||||
|
|
||||||
|
Bugfix:
|
||||||
|
- Fix crash due to missing informationData (#535)
|
||||||
|
- Progress in initial sync dialog is decreasing for a step and should not (#532)
|
||||||
|
- Fix rendering issue of accepted third party invitation event
|
||||||
|
- All current notifications were dismissed by mistake when the app is launched from the launcher
|
||||||
|
|
||||||
|
Build:
|
||||||
|
- Fix issue with version name (#533)
|
||||||
|
- Fix issue with bad versionCode generated by Buildkite (#553)
|
||||||
|
|
||||||
|
Changes in RiotX 0.4.0 (2019-08-30)
|
||||||
===================================================
|
===================================================
|
||||||
|
|
||||||
Features:
|
Features:
|
||||||
- Display read receipts in timeline (#81)
|
- Display read receipts in timeline (#81)
|
||||||
|
|
||||||
Improvements:
|
Improvements:
|
||||||
-
|
- Reactions: Reinstate the ability to react with non-unicode keys (#307)
|
||||||
|
|
||||||
Other changes:
|
|
||||||
-
|
|
||||||
|
|
||||||
Bugfix:
|
Bugfix:
|
||||||
- Fix text diff linebreak display (#441)
|
- Fix text diff linebreak display (#441)
|
||||||
- Date change message repeats for each redaction until a normal message (#358)
|
- Date change message repeats for each redaction until a normal message (#358)
|
||||||
- Slide-in reply icon is distorted (#423)
|
- Slide-in reply icon is distorted (#423)
|
||||||
|
- Regression / e2e replies not encrypted
|
||||||
Translations:
|
- Some video won't play
|
||||||
-
|
- Privacy: remove log of notifiable event (#519)
|
||||||
|
- Fix crash with EmojiCompat (#530)
|
||||||
Build:
|
|
||||||
-
|
|
||||||
|
|
||||||
Changes in RiotX 0.3.0 (2019-08-08)
|
Changes in RiotX 0.3.0 (2019-08-08)
|
||||||
===================================================
|
===================================================
|
||||||
@ -93,21 +191,21 @@ Mode details here: https://medium.com/@RiotChat/introducing-the-riotx-beta-for-a
|
|||||||
Changes in RiotX 0.0.0 (2019-XX-XX)
|
Changes in RiotX 0.0.0 (2019-XX-XX)
|
||||||
===================================================
|
===================================================
|
||||||
|
|
||||||
Features:
|
Features ✨:
|
||||||
-
|
-
|
||||||
|
|
||||||
Improvements:
|
Improvements 🙌:
|
||||||
-
|
-
|
||||||
|
|
||||||
Other changes:
|
Other changes:
|
||||||
-
|
-
|
||||||
|
|
||||||
Bugfix:
|
Bugfix 🐛:
|
||||||
-
|
-
|
||||||
|
|
||||||
Translations:
|
Translations 🗣:
|
||||||
-
|
-
|
||||||
|
|
||||||
Build:
|
Build 🧱:
|
||||||
-
|
-
|
||||||
|
|
||||||
|
@ -40,19 +40,45 @@ Please add a line to the top of the file `CHANGES.md` describing your change.
|
|||||||
|
|
||||||
Make sure the following commands execute without any error:
|
Make sure the following commands execute without any error:
|
||||||
|
|
||||||
> ./tools/check/check_code_quality.sh
|
#### Internal tool
|
||||||
|
|
||||||
> ./gradlew lintGplayRelease
|
<pre>
|
||||||
|
./tools/check/check_code_quality.sh
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
#### ktlint
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
curl -sSLO https://github.com/pinterest/ktlint/releases/download/0.34.2/ktlint && chmod a+x ktlint
|
||||||
|
./ktlint --android --experimental -v
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
Note that you can run
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
./ktlint --android --experimental -v -F
|
||||||
|
</pre>
|
||||||
|
|
||||||
|
For ktlint to fix some detected errors for you (you still have to check and commit the fix of course)
|
||||||
|
|
||||||
|
#### lint
|
||||||
|
|
||||||
|
<pre>
|
||||||
|
./gradlew lintGplayRelease
|
||||||
|
./gradlew lintFdroidRelease
|
||||||
|
</pre>
|
||||||
|
|
||||||
### Unit tests
|
### Unit tests
|
||||||
|
|
||||||
Make sure the following commands execute without any error:
|
Make sure the following commands execute without any error:
|
||||||
|
|
||||||
> ./gradlew testGplayReleaseUnitTest
|
<pre>
|
||||||
|
./gradlew testGplayReleaseUnitTest
|
||||||
|
</pre>
|
||||||
|
|
||||||
### Tests
|
### Tests
|
||||||
|
|
||||||
RiotX is currently supported on Android Jelly Bean (API 16+): please test your change on an Android device (or Android emulator) running with API 16. Many issues can happen (including crashes) on older devices.
|
RiotX is currently supported on Android KitKat (API 19+): please test your change on an Android device (or Android emulator) running with API 19. Many issues can happen (including crashes) on older devices.
|
||||||
Also, if possible, please test your change on a real device. Testing on Android emulator may not be sufficient.
|
Also, if possible, please test your change on a real device. Testing on Android emulator may not be sufficient.
|
||||||
|
|
||||||
### Internationalisation
|
### Internationalisation
|
||||||
@ -60,6 +86,10 @@ Also, if possible, please test your change on a real device. Testing on Android
|
|||||||
When adding new string resources, please only add new entries in file `value/strings.xml`. Translations will be added later by the community of translators with a specific tool named [Weblate](https://translate.riot.im/projects/riot-android/).
|
When adding new string resources, please only add new entries in file `value/strings.xml`. Translations will be added later by the community of translators with a specific tool named [Weblate](https://translate.riot.im/projects/riot-android/).
|
||||||
Do not hesitate to use plurals when appropriate.
|
Do not hesitate to use plurals when appropriate.
|
||||||
|
|
||||||
|
### Accessibility
|
||||||
|
|
||||||
|
Please consider accessibility as an important point. As a minimum requirement, in layout XML files please use attributes such as `android:contentDescription` and `android:importantForAccessibility`, and test with a screen reader if it's working well. You can add new string resources, dedicated to accessibility, in this case, please prefix theirs id with `a11y_`.
|
||||||
|
|
||||||
### Layout
|
### Layout
|
||||||
|
|
||||||
When adding or editing layouts, make sure the layout will render correctly if device uses a RTL (Right To Left) language.
|
When adding or editing layouts, make sure the layout will render correctly if device uses a RTL (Right To Left) language.
|
||||||
|
17
build.gradle
17
build.gradle
@ -1,9 +1,7 @@
|
|||||||
import javax.tools.JavaCompiler
|
|
||||||
|
|
||||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||||
|
|
||||||
buildscript {
|
buildscript {
|
||||||
ext.kotlin_version = '1.3.21'
|
ext.kotlin_version = '1.3.50'
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
jcenter()
|
jcenter()
|
||||||
@ -12,11 +10,11 @@ buildscript {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:3.4.1'
|
classpath 'com.android.tools.build:gradle:3.5.1'
|
||||||
classpath 'com.google.gms:google-services:4.2.0'
|
classpath 'com.google.gms:google-services:4.3.2'
|
||||||
classpath "com.airbnb.okreplay:gradle-plugin:1.4.0"
|
classpath "com.airbnb.okreplay:gradle-plugin:1.5.0"
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||||
classpath 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.6.2'
|
classpath 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.7.1'
|
||||||
classpath 'com.google.android.gms:oss-licenses-plugin:0.9.5'
|
classpath 'com.google.android.gms:oss-licenses-plugin:0.9.5'
|
||||||
|
|
||||||
// NOTE: Do not place your application dependencies here; they belong
|
// NOTE: Do not place your application dependencies here; they belong
|
||||||
@ -61,6 +59,11 @@ allprojects {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
|
||||||
|
// Warnings are potential errors, so stop ignoring them
|
||||||
|
kotlinOptions.allWarningsAsErrors = true
|
||||||
|
}
|
||||||
|
|
||||||
afterEvaluate {
|
afterEvaluate {
|
||||||
extensions.findByName("kapt")?.arguments {
|
extensions.findByName("kapt")?.arguments {
|
||||||
arg("dagger.gradle.incremental", "enabled")
|
arg("dagger.gradle.incremental", "enabled")
|
||||||
|
4
gradle/wrapper/gradle-wrapper.properties
vendored
4
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,6 +1,6 @@
|
|||||||
#Tue Mar 19 09:53:05 CET 2019
|
#Fri Sep 27 10:10:35 CEST 2019
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.2.1-all.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
|
||||||
|
@ -5,16 +5,15 @@ apply plugin: 'kotlin-kapt'
|
|||||||
android {
|
android {
|
||||||
compileSdkVersion 28
|
compileSdkVersion 28
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
minSdkVersion 16
|
minSdkVersion 16
|
||||||
targetSdkVersion 28
|
targetSdkVersion 28
|
||||||
versionCode 1
|
versionCode 1
|
||||||
versionName "1.0"
|
versionName "1.0"
|
||||||
|
|
||||||
|
// Multidex is useful for tests
|
||||||
|
multiDexEnabled true
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
buildTypes {
|
buildTypes {
|
||||||
@ -29,12 +28,14 @@ android {
|
|||||||
targetCompatibility JavaVersion.VERSION_1_8
|
targetCompatibility JavaVersion.VERSION_1_8
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kotlinOptions {
|
||||||
|
jvmTarget = "1.8"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation project(":matrix-sdk-android")
|
implementation project(":matrix-sdk-android")
|
||||||
implementation 'androidx.appcompat:appcompat:1.1.0-beta01'
|
implementation 'androidx.appcompat:appcompat:1.1.0'
|
||||||
implementation 'io.reactivex.rxjava2:rxkotlin:2.3.0'
|
implementation 'io.reactivex.rxjava2:rxkotlin:2.3.0'
|
||||||
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
|
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
|
||||||
// Paging
|
// Paging
|
||||||
|
@ -1,42 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 New Vector Ltd
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package im.vector.matrix.rx;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import androidx.test.InstrumentationRegistry;
|
|
||||||
import androidx.test.runner.AndroidJUnit4;
|
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.junit.runner.RunWith;
|
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Instrumented test, which will execute on an Android device.
|
|
||||||
*
|
|
||||||
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
|
|
||||||
*/
|
|
||||||
@RunWith(AndroidJUnit4.class)
|
|
||||||
public class ExampleInstrumentedTest {
|
|
||||||
@Test
|
|
||||||
public void useAppContext() {
|
|
||||||
// Context of the app under test.
|
|
||||||
Context appContext = InstrumentationRegistry.getTargetContext();
|
|
||||||
|
|
||||||
assertEquals("im.vector.matrix.rx.test", appContext.getPackageName());
|
|
||||||
}
|
|
||||||
}
|
|
@ -20,7 +20,6 @@ import androidx.lifecycle.LiveData
|
|||||||
import androidx.lifecycle.Observer
|
import androidx.lifecycle.Observer
|
||||||
import io.reactivex.Observable
|
import io.reactivex.Observable
|
||||||
import io.reactivex.android.MainThreadDisposable
|
import io.reactivex.android.MainThreadDisposable
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
|
||||||
import io.reactivex.schedulers.Schedulers
|
import io.reactivex.schedulers.Schedulers
|
||||||
|
|
||||||
private class LiveDataObservable<T>(
|
private class LiveDataObservable<T>(
|
||||||
|
@ -19,7 +19,6 @@ package im.vector.matrix.rx
|
|||||||
import im.vector.matrix.android.api.MatrixCallback
|
import im.vector.matrix.android.api.MatrixCallback
|
||||||
import im.vector.matrix.android.api.util.Cancelable
|
import im.vector.matrix.android.api.util.Cancelable
|
||||||
import io.reactivex.CompletableEmitter
|
import io.reactivex.CompletableEmitter
|
||||||
import io.reactivex.SingleEmitter
|
|
||||||
|
|
||||||
internal class MatrixCallbackCompletable<T>(private val completableEmitter: CompletableEmitter) : MatrixCallback<T> {
|
internal class MatrixCallbackCompletable<T>(private val completableEmitter: CompletableEmitter) : MatrixCallback<T> {
|
||||||
|
|
||||||
|
@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package im.vector.matrix.rx
|
||||||
|
|
||||||
|
import im.vector.matrix.android.api.util.Optional
|
||||||
|
import io.reactivex.Observable
|
||||||
|
|
||||||
|
fun <T : Any> Observable<Optional<T>>.unwrap(): Observable<T> {
|
||||||
|
return filter { it.hasValue() }.map { it.get() }
|
||||||
|
}
|
@ -20,26 +20,37 @@ import im.vector.matrix.android.api.session.room.Room
|
|||||||
import im.vector.matrix.android.api.session.room.model.EventAnnotationsSummary
|
import im.vector.matrix.android.api.session.room.model.EventAnnotationsSummary
|
||||||
import im.vector.matrix.android.api.session.room.model.ReadReceipt
|
import im.vector.matrix.android.api.session.room.model.ReadReceipt
|
||||||
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
||||||
|
import im.vector.matrix.android.api.session.room.notification.RoomNotificationState
|
||||||
|
import im.vector.matrix.android.api.session.room.send.UserDraft
|
||||||
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
||||||
|
import im.vector.matrix.android.api.util.Optional
|
||||||
import io.reactivex.Observable
|
import io.reactivex.Observable
|
||||||
import io.reactivex.Single
|
import io.reactivex.Single
|
||||||
|
|
||||||
class RxRoom(private val room: Room) {
|
class RxRoom(private val room: Room) {
|
||||||
|
|
||||||
fun liveRoomSummary(): Observable<RoomSummary> {
|
fun liveRoomSummary(): Observable<Optional<RoomSummary>> {
|
||||||
return room.liveRoomSummary().asObservable()
|
return room.getRoomSummaryLive().asObservable()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun liveRoomMemberIds(): Observable<List<String>> {
|
fun liveRoomMemberIds(): Observable<List<String>> {
|
||||||
return room.getRoomMemberIdsLive().asObservable()
|
return room.getRoomMemberIdsLive().asObservable()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun liveAnnotationSummary(eventId: String): Observable<EventAnnotationsSummary> {
|
fun liveAnnotationSummary(eventId: String): Observable<Optional<EventAnnotationsSummary>> {
|
||||||
return room.getEventSummaryLive(eventId).asObservable()
|
return room.getEventSummaryLive(eventId).asObservable()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun liveTimelineEvent(eventId: String): Observable<TimelineEvent> {
|
fun liveTimelineEvent(eventId: String): Observable<Optional<TimelineEvent>> {
|
||||||
return room.liveTimeLineEvent(eventId).asObservable()
|
return room.getTimeLineEventLive(eventId).asObservable()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun liveReadMarker(): Observable<Optional<String>> {
|
||||||
|
return room.getReadMarkerLive().asObservable()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun liveReadReceipt(): Observable<Optional<String>> {
|
||||||
|
return room.getMyReadReceiptLive().asObservable()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun loadRoomMembersIfNeeded(): Single<Unit> = Single.create {
|
fun loadRoomMembersIfNeeded(): Single<Unit> = Single.create {
|
||||||
@ -54,6 +65,13 @@ class RxRoom(private val room: Room) {
|
|||||||
return room.getEventReadReceiptsLive(eventId).asObservable()
|
return room.getEventReadReceiptsLive(eventId).asObservable()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun liveDrafts(): Observable<List<UserDraft>> {
|
||||||
|
return room.getDraftsLive().asObservable()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun liveNotificationState(): Observable<RoomNotificationState> {
|
||||||
|
return room.getLiveRoomNotificationState().asObservable()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Room.rx(): RxRoom {
|
fun Room.rx(): RxRoom {
|
||||||
|
@ -24,6 +24,7 @@ import im.vector.matrix.android.api.session.room.model.RoomSummary
|
|||||||
import im.vector.matrix.android.api.session.room.model.create.CreateRoomParams
|
import im.vector.matrix.android.api.session.room.model.create.CreateRoomParams
|
||||||
import im.vector.matrix.android.api.session.sync.SyncState
|
import im.vector.matrix.android.api.session.sync.SyncState
|
||||||
import im.vector.matrix.android.api.session.user.model.User
|
import im.vector.matrix.android.api.session.user.model.User
|
||||||
|
import im.vector.matrix.android.api.util.Optional
|
||||||
import io.reactivex.Observable
|
import io.reactivex.Observable
|
||||||
import io.reactivex.Single
|
import io.reactivex.Single
|
||||||
|
|
||||||
@ -45,10 +46,18 @@ class RxSession(private val session: Session) {
|
|||||||
return session.livePushers().asObservable()
|
return session.livePushers().asObservable()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun liveUser(userId: String): Observable<Optional<User>> {
|
||||||
|
return session.liveUser(userId).asObservable().distinctUntilChanged()
|
||||||
|
}
|
||||||
|
|
||||||
fun liveUsers(): Observable<List<User>> {
|
fun liveUsers(): Observable<List<User>> {
|
||||||
return session.liveUsers().asObservable()
|
return session.liveUsers().asObservable()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun liveIgnoredUsers(): Observable<List<User>> {
|
||||||
|
return session.liveIgnoredUsers().asObservable()
|
||||||
|
}
|
||||||
|
|
||||||
fun livePagedUsers(filter: String? = null): Observable<PagedList<User>> {
|
fun livePagedUsers(filter: String? = null): Observable<PagedList<User>> {
|
||||||
return session.livePagedUsers(filter).asObservable()
|
return session.livePagedUsers(filter).asObservable()
|
||||||
}
|
}
|
||||||
@ -66,7 +75,6 @@ class RxSession(private val session: Session) {
|
|||||||
fun joinRoom(roomId: String, viaServers: List<String> = emptyList()): Single<Unit> = Single.create {
|
fun joinRoom(roomId: String, viaServers: List<String> = emptyList()): Single<Unit> = Single.create {
|
||||||
session.joinRoom(roomId, viaServers, MatrixCallbackSingle(it)).toSingle(it)
|
session.joinRoom(roomId, viaServers, MatrixCallbackSingle(it)).toSingle(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Session.rx(): RxSession {
|
fun Session.rx(): RxSession {
|
||||||
|
@ -67,6 +67,10 @@ android {
|
|||||||
sourceCompatibility JavaVersion.VERSION_1_8
|
sourceCompatibility JavaVersion.VERSION_1_8
|
||||||
targetCompatibility JavaVersion.VERSION_1_8
|
targetCompatibility JavaVersion.VERSION_1_8
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kotlinOptions {
|
||||||
|
jvmTarget = "1.8"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static def gitRevision() {
|
static def gitRevision() {
|
||||||
@ -86,41 +90,43 @@ static def gitRevisionDate() {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
|
||||||
def arrow_version = "0.8.0"
|
def arrow_version = "0.8.2"
|
||||||
def support_version = '1.1.0-beta01'
|
|
||||||
def moshi_version = '1.8.0'
|
def moshi_version = '1.8.0'
|
||||||
def lifecycle_version = '2.0.0'
|
def lifecycle_version = '2.1.0'
|
||||||
def coroutines_version = "1.0.1"
|
def coroutines_version = "1.3.2"
|
||||||
def markwon_version = '3.0.0'
|
def markwon_version = '3.1.0'
|
||||||
def daggerVersion = '2.23.1'
|
def daggerVersion = '2.24'
|
||||||
|
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version"
|
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:$coroutines_version"
|
||||||
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version"
|
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version"
|
||||||
|
|
||||||
implementation "androidx.appcompat:appcompat:1.1.0-rc01"
|
implementation "androidx.appcompat:appcompat:1.1.0"
|
||||||
implementation "androidx.recyclerview:recyclerview:1.1.0-beta01"
|
implementation "androidx.recyclerview:recyclerview:1.1.0-beta05"
|
||||||
|
|
||||||
implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
|
implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
|
||||||
kapt "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
|
kapt "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
|
||||||
|
|
||||||
// Network
|
// Network
|
||||||
implementation 'com.squareup.retrofit2:retrofit:2.6.0'
|
implementation 'com.squareup.retrofit2:retrofit:2.6.2'
|
||||||
implementation 'com.squareup.retrofit2:converter-moshi:2.4.0'
|
implementation 'com.squareup.retrofit2:converter-moshi:2.6.2'
|
||||||
implementation 'com.squareup.okhttp3:okhttp:3.14.1'
|
implementation 'com.squareup.okhttp3:okhttp:4.2.2'
|
||||||
implementation 'com.squareup.okhttp3:logging-interceptor:3.10.0'
|
implementation 'com.squareup.okhttp3:logging-interceptor:4.2.2'
|
||||||
implementation 'com.novoda:merlin:1.2.0'
|
implementation 'com.novoda:merlin:1.2.0'
|
||||||
implementation "com.squareup.moshi:moshi-adapters:$moshi_version"
|
implementation "com.squareup.moshi:moshi-adapters:$moshi_version"
|
||||||
kapt "com.squareup.moshi:moshi-kotlin-codegen:$moshi_version"
|
kapt "com.squareup.moshi:moshi-kotlin-codegen:$moshi_version"
|
||||||
|
|
||||||
implementation "ru.noties.markwon:core:$markwon_version"
|
implementation "ru.noties.markwon:core:$markwon_version"
|
||||||
|
|
||||||
|
// Image
|
||||||
|
implementation 'androidx.exifinterface:exifinterface:1.0.0'
|
||||||
|
|
||||||
// Database
|
// Database
|
||||||
implementation 'com.github.Zhuinden:realm-monarchy:0.5.1'
|
implementation 'com.github.Zhuinden:realm-monarchy:0.5.1'
|
||||||
kapt 'dk.ilios:realmfieldnameshelper:1.1.1'
|
kapt 'dk.ilios:realmfieldnameshelper:1.1.1'
|
||||||
|
|
||||||
// Work
|
// Work
|
||||||
implementation "androidx.work:work-runtime-ktx:2.1.0-rc01"
|
implementation "androidx.work:work-runtime-ktx:2.3.0-alpha01"
|
||||||
|
|
||||||
// FP
|
// FP
|
||||||
implementation "io.arrow-kt:arrow-core:$arrow_version"
|
implementation "io.arrow-kt:arrow-core:$arrow_version"
|
||||||
@ -132,21 +138,25 @@ dependencies {
|
|||||||
// DI
|
// DI
|
||||||
implementation "com.google.dagger:dagger:$daggerVersion"
|
implementation "com.google.dagger:dagger:$daggerVersion"
|
||||||
kapt "com.google.dagger:dagger-compiler:$daggerVersion"
|
kapt "com.google.dagger:dagger-compiler:$daggerVersion"
|
||||||
compileOnly 'com.squareup.inject:assisted-inject-annotations-dagger2:0.4.0'
|
compileOnly 'com.squareup.inject:assisted-inject-annotations-dagger2:0.5.0'
|
||||||
kapt 'com.squareup.inject:assisted-inject-processor-dagger2:0.4.0'
|
kapt 'com.squareup.inject:assisted-inject-processor-dagger2:0.5.0'
|
||||||
|
|
||||||
// Logging
|
// Logging
|
||||||
implementation 'com.jakewharton.timber:timber:4.7.1'
|
implementation 'com.jakewharton.timber:timber:4.7.1'
|
||||||
implementation 'com.facebook.stetho:stetho-okhttp3:1.5.0'
|
implementation 'com.facebook.stetho:stetho-okhttp3:1.5.1'
|
||||||
|
|
||||||
debugImplementation 'com.airbnb.okreplay:okreplay:1.4.0'
|
// Bus
|
||||||
releaseImplementation 'com.airbnb.okreplay:noop:1.4.0'
|
implementation 'org.greenrobot:eventbus:3.1.1'
|
||||||
androidTestImplementation 'com.airbnb.okreplay:espresso:1.4.0'
|
|
||||||
|
debugImplementation 'com.airbnb.okreplay:okreplay:1.5.0'
|
||||||
|
releaseImplementation 'com.airbnb.okreplay:noop:1.5.0'
|
||||||
|
androidTestImplementation 'com.airbnb.okreplay:espresso:1.5.0'
|
||||||
|
|
||||||
testImplementation 'junit:junit:4.12'
|
testImplementation 'junit:junit:4.12'
|
||||||
testImplementation 'org.robolectric:robolectric:4.0.2'
|
testImplementation 'org.robolectric:robolectric:4.3'
|
||||||
//testImplementation 'org.robolectric:shadows-support-v4:3.0'
|
//testImplementation 'org.robolectric:shadows-support-v4:3.0'
|
||||||
testImplementation "io.mockk:mockk:1.8.13.kotlin13"
|
// Note: version sticks to 1.9.2 due to https://github.com/mockk/mockk/issues/281
|
||||||
|
testImplementation 'io.mockk:mockk:1.9.2.kotlin12'
|
||||||
testImplementation 'org.amshove.kluent:kluent-android:1.44'
|
testImplementation 'org.amshove.kluent:kluent-android:1.44'
|
||||||
testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version"
|
testImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version"
|
||||||
|
|
||||||
@ -156,7 +166,8 @@ dependencies {
|
|||||||
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
|
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
|
||||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
|
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
|
||||||
androidTestImplementation 'org.amshove.kluent:kluent-android:1.44'
|
androidTestImplementation 'org.amshove.kluent:kluent-android:1.44'
|
||||||
androidTestImplementation "io.mockk:mockk-android:1.8.13.kotlin13"
|
// Note: version sticks to 1.9.2 due to https://github.com/mockk/mockk/issues/281
|
||||||
|
androidTestImplementation 'io.mockk:mockk-android:1.9.2.kotlin12'
|
||||||
androidTestImplementation "androidx.arch.core:core-testing:$lifecycle_version"
|
androidTestImplementation "androidx.arch.core:core-testing:$lifecycle_version"
|
||||||
androidTestImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version"
|
androidTestImplementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$coroutines_version"
|
||||||
|
|
||||||
|
@ -17,12 +17,12 @@
|
|||||||
package im.vector.matrix.android
|
package im.vector.matrix.android
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import androidx.test.InstrumentationRegistry
|
import androidx.test.core.app.ApplicationProvider
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
interface InstrumentedTest {
|
interface InstrumentedTest {
|
||||||
fun context(): Context {
|
fun context(): Context {
|
||||||
return InstrumentationRegistry.getTargetContext()
|
return ApplicationProvider.getApplicationContext()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun cacheDir(): File {
|
fun cacheDir(): File {
|
||||||
|
@ -17,8 +17,8 @@
|
|||||||
package im.vector.matrix.android.auth
|
package im.vector.matrix.android.auth
|
||||||
|
|
||||||
import androidx.test.annotation.UiThreadTest
|
import androidx.test.annotation.UiThreadTest
|
||||||
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
import androidx.test.rule.GrantPermissionRule
|
import androidx.test.rule.GrantPermissionRule
|
||||||
import androidx.test.runner.AndroidJUnit4
|
|
||||||
import im.vector.matrix.android.InstrumentedTest
|
import im.vector.matrix.android.InstrumentedTest
|
||||||
import im.vector.matrix.android.OkReplayRuleChainNoActivity
|
import im.vector.matrix.android.OkReplayRuleChainNoActivity
|
||||||
import im.vector.matrix.android.api.auth.Authenticator
|
import im.vector.matrix.android.api.auth.Authenticator
|
||||||
@ -28,7 +28,6 @@ import org.junit.Rule
|
|||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
|
|
||||||
@RunWith(AndroidJUnit4::class)
|
@RunWith(AndroidJUnit4::class)
|
||||||
internal class AuthenticatorTest : InstrumentedTest {
|
internal class AuthenticatorTest : InstrumentedTest {
|
||||||
|
|
||||||
@ -50,7 +49,6 @@ internal class AuthenticatorTest : InstrumentedTest {
|
|||||||
@UiThreadTest
|
@UiThreadTest
|
||||||
@OkReplay(tape = "auth", mode = TapeMode.READ_WRITE)
|
@OkReplay(tape = "auth", mode = TapeMode.READ_WRITE)
|
||||||
fun auth() {
|
fun auth() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@ -59,6 +57,4 @@ internal class AuthenticatorTest : InstrumentedTest {
|
|||||||
val grantExternalStoragePermissionRule: GrantPermissionRule =
|
val grantExternalStoragePermissionRule: GrantPermissionRule =
|
||||||
GrantPermissionRule.grant(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
GrantPermissionRule.grant(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
@ -21,7 +21,7 @@ import im.vector.matrix.android.internal.crypto.store.IMXCryptoStore
|
|||||||
import im.vector.matrix.android.internal.crypto.store.db.RealmCryptoStore
|
import im.vector.matrix.android.internal.crypto.store.db.RealmCryptoStore
|
||||||
import im.vector.matrix.android.internal.crypto.store.db.RealmCryptoStoreModule
|
import im.vector.matrix.android.internal.crypto.store.db.RealmCryptoStoreModule
|
||||||
import io.realm.RealmConfiguration
|
import io.realm.RealmConfiguration
|
||||||
import java.util.*
|
import kotlin.random.Random
|
||||||
|
|
||||||
internal class CryptoStoreHelper {
|
internal class CryptoStoreHelper {
|
||||||
|
|
||||||
@ -35,7 +35,7 @@ internal class CryptoStoreHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun createCredential() = Credentials(
|
fun createCredential() = Credentials(
|
||||||
userId = "userId_" + Random().nextInt(),
|
userId = "userId_" + Random.nextInt(),
|
||||||
homeServer = "http://matrix.org",
|
homeServer = "http://matrix.org",
|
||||||
accessToken = "access_token",
|
accessToken = "access_token",
|
||||||
refreshToken = null,
|
refreshToken = null,
|
||||||
|
@ -62,8 +62,6 @@ internal class JsonCanonicalizerTest : InstrumentedTest {
|
|||||||
JsonCanonicalizer.canonicalize("{\"a\":\"\\\"\"}"))
|
JsonCanonicalizer.canonicalize("{\"a\":\"\\\"\"}"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* ==========================================================================================
|
/* ==========================================================================================
|
||||||
* Test from https://matrix.org/docs/spec/appendices.html#examples
|
* Test from https://matrix.org/docs/spec/appendices.html#examples
|
||||||
* ========================================================================================== */
|
* ========================================================================================== */
|
||||||
@ -74,7 +72,6 @@ internal class JsonCanonicalizerTest : InstrumentedTest {
|
|||||||
JsonCanonicalizer.canonicalize("""{}"""))
|
JsonCanonicalizer.canonicalize("""{}"""))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun matrixOrg002Test() {
|
fun matrixOrg002Test() {
|
||||||
assertEquals("""{"one":1,"two":"Two"}""",
|
assertEquals("""{"one":1,"two":"Two"}""",
|
||||||
@ -84,7 +81,6 @@ internal class JsonCanonicalizerTest : InstrumentedTest {
|
|||||||
}"""))
|
}"""))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun matrixOrg003Test() {
|
fun matrixOrg003Test() {
|
||||||
assertEquals("""{"a":"1","b":"2"}""",
|
assertEquals("""{"a":"1","b":"2"}""",
|
||||||
@ -94,14 +90,12 @@ internal class JsonCanonicalizerTest : InstrumentedTest {
|
|||||||
}"""))
|
}"""))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun matrixOrg004Test() {
|
fun matrixOrg004Test() {
|
||||||
assertEquals("""{"a":"1","b":"2"}""",
|
assertEquals("""{"a":"1","b":"2"}""",
|
||||||
JsonCanonicalizer.canonicalize("""{"b":"2","a":"1"}"""))
|
JsonCanonicalizer.canonicalize("""{"b":"2","a":"1"}"""))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun matrixOrg005Test() {
|
fun matrixOrg005Test() {
|
||||||
assertEquals("""{"auth":{"mxid":"@john.doe:example.com","profile":{"display_name":"John Doe","three_pids":[{"address":"john.doe@example.org","medium":"email"},{"address":"123456789","medium":"msisdn"}]},"success":true}}""",
|
assertEquals("""{"auth":{"mxid":"@john.doe:example.com","profile":{"display_name":"John Doe","three_pids":[{"address":"john.doe@example.org","medium":"email"},{"address":"123456789","medium":"msisdn"}]},"success":true}}""",
|
||||||
@ -126,7 +120,6 @@ internal class JsonCanonicalizerTest : InstrumentedTest {
|
|||||||
}"""))
|
}"""))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun matrixOrg006Test() {
|
fun matrixOrg006Test() {
|
||||||
assertEquals("""{"a":"日本語"}""",
|
assertEquals("""{"a":"日本語"}""",
|
||||||
@ -135,7 +128,6 @@ internal class JsonCanonicalizerTest : InstrumentedTest {
|
|||||||
}"""))
|
}"""))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun matrixOrg007Test() {
|
fun matrixOrg007Test() {
|
||||||
assertEquals("""{"日":1,"本":2}""",
|
assertEquals("""{"日":1,"本":2}""",
|
||||||
@ -145,7 +137,6 @@ internal class JsonCanonicalizerTest : InstrumentedTest {
|
|||||||
}"""))
|
}"""))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun matrixOrg008Test() {
|
fun matrixOrg008Test() {
|
||||||
assertEquals("""{"a":"日"}""",
|
assertEquals("""{"a":"日"}""",
|
||||||
|
@ -35,7 +35,6 @@ import org.junit.Before
|
|||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
|
|
||||||
@RunWith(AndroidJUnit4::class)
|
@RunWith(AndroidJUnit4::class)
|
||||||
internal class ChunkEntityTest : InstrumentedTest {
|
internal class ChunkEntityTest : InstrumentedTest {
|
||||||
|
|
||||||
@ -48,7 +47,6 @@ internal class ChunkEntityTest : InstrumentedTest {
|
|||||||
monarchy = Monarchy.Builder().setRealmConfiguration(testConfig).build()
|
monarchy = Monarchy.Builder().setRealmConfiguration(testConfig).build()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun add_shouldAdd_whenNotAlreadyIncluded() {
|
fun add_shouldAdd_whenNotAlreadyIncluded() {
|
||||||
monarchy.runTransactionSync { realm ->
|
monarchy.runTransactionSync { realm ->
|
||||||
@ -194,5 +192,4 @@ internal class ChunkEntityTest : InstrumentedTest {
|
|||||||
chunk1.nextToken shouldEqual nextToken
|
chunk1.nextToken shouldEqual nextToken
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -32,6 +32,4 @@ internal class FakeGetContextOfEventTask constructor(private val tokenChunkEvent
|
|||||||
)
|
)
|
||||||
return tokenChunkEventPersistor.insertInDb(tokenChunkEvent, params.roomId, PaginationDirection.BACKWARDS)
|
return tokenChunkEventPersistor.insertInDb(tokenChunkEvent, params.roomId, PaginationDirection.BACKWARDS)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
@ -28,6 +28,4 @@ internal class FakePaginationTask @Inject constructor(private val tokenChunkEven
|
|||||||
val tokenChunkEvent = FakeTokenChunkEvent(params.from, Random.nextLong(System.currentTimeMillis()).toString(), fakeEvents)
|
val tokenChunkEvent = FakeTokenChunkEvent(params.from, Random.nextLong(System.currentTimeMillis()).toString(), fakeEvents)
|
||||||
return tokenChunkEventPersistor.insertInDb(tokenChunkEvent, params.roomId, params.direction)
|
return tokenChunkEventPersistor.insertInDb(tokenChunkEvent, params.roomId, params.direction)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,6 +88,4 @@ object RoomDataHelper {
|
|||||||
roomEntity.addOrUpdate(chunkEntity)
|
roomEntity.addOrUpdate(chunkEntity)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
@ -81,6 +81,4 @@ internal class TimelineTest : InstrumentedTest {
|
|||||||
// timelineEvents.size shouldEqual initialLoad + paginationCount
|
// timelineEvents.size shouldEqual initialLoad + paginationCount
|
||||||
// timeline.dispose()
|
// timeline.dispose()
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
@ -22,6 +22,7 @@ import okhttp3.Interceptor
|
|||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
import okhttp3.logging.HttpLoggingInterceptor
|
import okhttp3.logging.HttpLoggingInterceptor
|
||||||
import okio.Buffer
|
import okio.Buffer
|
||||||
|
import timber.log.Timber
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.nio.charset.Charset
|
import java.nio.charset.Charset
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
@ -51,13 +52,18 @@ internal class CurlLoggingInterceptor @Inject constructor(private val logger: Ht
|
|||||||
var compressed = false
|
var compressed = false
|
||||||
|
|
||||||
var curlCmd = "curl"
|
var curlCmd = "curl"
|
||||||
if (curlOptions != null) {
|
curlOptions?.let {
|
||||||
curlCmd += " " + curlOptions!!
|
curlCmd += " $it"
|
||||||
}
|
}
|
||||||
curlCmd += " -X " + request.method()
|
curlCmd += " -X " + request.method
|
||||||
|
|
||||||
val requestBody = request.body()
|
val requestBody = request.body
|
||||||
if (requestBody != null) {
|
if (requestBody != null) {
|
||||||
|
if (requestBody.contentLength() > 100_000) {
|
||||||
|
Timber.w("Unable to log curl command data, size is too big (${requestBody.contentLength()})")
|
||||||
|
// Ensure the curl command will failed
|
||||||
|
curlCmd += "DATA IS TOO BIG"
|
||||||
|
} else {
|
||||||
val buffer = Buffer()
|
val buffer = Buffer()
|
||||||
requestBody.writeTo(buffer)
|
requestBody.writeTo(buffer)
|
||||||
var charset: Charset? = UTF8
|
var charset: Charset? = UTF8
|
||||||
@ -68,10 +74,11 @@ internal class CurlLoggingInterceptor @Inject constructor(private val logger: Ht
|
|||||||
// try to keep to a single line and use a subshell to preserve any line breaks
|
// try to keep to a single line and use a subshell to preserve any line breaks
|
||||||
curlCmd += " --data $'" + buffer.readString(charset!!).replace("\n", "\\n") + "'"
|
curlCmd += " --data $'" + buffer.readString(charset!!).replace("\n", "\\n") + "'"
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val headers = request.headers()
|
val headers = request.headers
|
||||||
var i = 0
|
var i = 0
|
||||||
val count = headers.size()
|
val count = headers.size
|
||||||
while (i < count) {
|
while (i < count) {
|
||||||
val name = headers.name(i)
|
val name = headers.name(i)
|
||||||
val value = headers.value(i)
|
val value = headers.value(i)
|
||||||
@ -82,7 +89,7 @@ internal class CurlLoggingInterceptor @Inject constructor(private val logger: Ht
|
|||||||
i++
|
i++
|
||||||
}
|
}
|
||||||
|
|
||||||
curlCmd += ((if (compressed) " --compressed " else " ") + "'" + request.url().toString()
|
curlCmd += ((if (compressed) " --compressed " else " ") + "'" + request.url.toString()
|
||||||
// Replace localhost for emulator by localhost for shell
|
// Replace localhost for emulator by localhost for shell
|
||||||
.replace("://10.0.2.2:8080/".toRegex(), "://127.0.0.1:8080/")
|
.replace("://10.0.2.2:8080/".toRegex(), "://127.0.0.1:8080/")
|
||||||
+ "'")
|
+ "'")
|
||||||
@ -90,7 +97,7 @@ internal class CurlLoggingInterceptor @Inject constructor(private val logger: Ht
|
|||||||
// Add Json formatting
|
// Add Json formatting
|
||||||
curlCmd += " | python -m json.tool"
|
curlCmd += " | python -m json.tool"
|
||||||
|
|
||||||
logger.log("--- cURL (" + request.url() + ")")
|
logger.log("--- cURL (" + request.url + ")")
|
||||||
logger.log(curlCmd)
|
logger.log(curlCmd)
|
||||||
|
|
||||||
return chain.proceed(request)
|
return chain.proceed(request)
|
||||||
|
@ -51,7 +51,6 @@ class FormattedJsonHttpLogger : HttpLoggingInterceptor.Logger {
|
|||||||
// Finally this is not a JSON string...
|
// Finally this is not a JSON string...
|
||||||
Timber.e(e)
|
Timber.e(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (message.startsWith("[")) {
|
} else if (message.startsWith("[")) {
|
||||||
// JSON Array detected
|
// JSON Array detected
|
||||||
try {
|
try {
|
||||||
@ -61,7 +60,6 @@ class FormattedJsonHttpLogger : HttpLoggingInterceptor.Logger {
|
|||||||
// Finally not JSON...
|
// Finally not JSON...
|
||||||
Timber.e(e)
|
Timber.e(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
// Else not a json string to log
|
// Else not a json string to log
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,6 @@ data class MatrixConfiguration(
|
|||||||
interface Provider {
|
interface Provider {
|
||||||
fun providesMatrixConfiguration(): MatrixConfiguration
|
fun providesMatrixConfiguration(): MatrixConfiguration
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -98,5 +97,4 @@ class Matrix private constructor(context: Context, matrixConfiguration: MatrixCo
|
|||||||
return BuildConfig.VERSION_NAME + " (" + BuildConfig.GIT_SDK_REVISION + ")"
|
return BuildConfig.VERSION_NAME + " (" + BuildConfig.GIT_SDK_REVISION + ")"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -37,5 +37,4 @@ interface MatrixCallback<in T> {
|
|||||||
fun onFailure(failure: Throwable) {
|
fun onFailure(failure: Throwable) {
|
||||||
// no-op
|
// no-op
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
package im.vector.matrix.android.api
|
package im.vector.matrix.android.api
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class contains pattern to match the different Matrix ids
|
* This class contains pattern to match the different Matrix ids
|
||||||
*/
|
*/
|
||||||
@ -154,6 +153,5 @@ object MatrixPatterns {
|
|||||||
return if (index == -1) {
|
return if (index == -1) {
|
||||||
null
|
null
|
||||||
} else matrixId.substring(index + 1)
|
} else matrixId.substring(index + 1)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,16 +17,23 @@
|
|||||||
package im.vector.matrix.android.api.auth
|
package im.vector.matrix.android.api.auth
|
||||||
|
|
||||||
import im.vector.matrix.android.api.MatrixCallback
|
import im.vector.matrix.android.api.MatrixCallback
|
||||||
|
import im.vector.matrix.android.api.auth.data.Credentials
|
||||||
import im.vector.matrix.android.api.auth.data.HomeServerConnectionConfig
|
import im.vector.matrix.android.api.auth.data.HomeServerConnectionConfig
|
||||||
import im.vector.matrix.android.api.auth.data.SessionParams
|
import im.vector.matrix.android.api.auth.data.SessionParams
|
||||||
import im.vector.matrix.android.api.session.Session
|
import im.vector.matrix.android.api.session.Session
|
||||||
import im.vector.matrix.android.api.util.Cancelable
|
import im.vector.matrix.android.api.util.Cancelable
|
||||||
|
import im.vector.matrix.android.internal.auth.data.LoginFlowResponse
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This interface defines methods to authenticate to a matrix server.
|
* This interface defines methods to authenticate to a matrix server.
|
||||||
*/
|
*/
|
||||||
interface Authenticator {
|
interface Authenticator {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request the supported login flows for this homeserver
|
||||||
|
*/
|
||||||
|
fun getLoginFlow(homeServerConnectionConfig: HomeServerConnectionConfig, callback: MatrixCallback<LoginFlowResponse>): Cancelable
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param homeServerConnectionConfig this param is used to configure the Homeserver
|
* @param homeServerConnectionConfig this param is used to configure the Homeserver
|
||||||
* @param login the login field
|
* @param login the login field
|
||||||
@ -56,4 +63,9 @@ interface Authenticator {
|
|||||||
* @return the associated session if any, or null
|
* @return the associated session if any, or null
|
||||||
*/
|
*/
|
||||||
fun getSession(sessionParams: SessionParams): Session?
|
fun getSession(sessionParams: SessionParams): Session?
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a session after a SSO successful login
|
||||||
|
*/
|
||||||
|
fun createSessionFromSso(credentials: Credentials, homeServerConnectionConfig: HomeServerConnectionConfig, callback: MatrixCallback<Session>): Cancelable
|
||||||
}
|
}
|
@ -253,13 +253,5 @@ data class HomeServerConnectionConfig(
|
|||||||
forceUsageTlsVersions
|
forceUsageTlsVersions
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
package im.vector.matrix.android.api.comparators
|
package im.vector.matrix.android.api.comparators
|
||||||
|
|
||||||
import im.vector.matrix.android.api.interfaces.DatedObject
|
import im.vector.matrix.android.api.interfaces.DatedObject
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
object DatedObjectComparators {
|
object DatedObjectComparators {
|
||||||
|
|
||||||
|
@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package im.vector.matrix.android.api.crypto
|
||||||
|
|
||||||
|
import im.vector.matrix.android.api.session.crypto.sas.EmojiRepresentation
|
||||||
|
import im.vector.matrix.android.internal.crypto.verification.getEmojiForCode
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provide all the emojis used for SAS verification (for debug purpose)
|
||||||
|
*/
|
||||||
|
fun getAllVerificationEmojis(): List<EmojiRepresentation> {
|
||||||
|
return (0..63).map { getEmojiForCode(it) }
|
||||||
|
}
|
@ -19,7 +19,6 @@ package im.vector.matrix.android.api.extensions
|
|||||||
import im.vector.matrix.android.api.comparators.DatedObjectComparators
|
import im.vector.matrix.android.api.comparators.DatedObjectComparators
|
||||||
import im.vector.matrix.android.internal.crypto.model.MXDeviceInfo
|
import im.vector.matrix.android.internal.crypto.model.MXDeviceInfo
|
||||||
import im.vector.matrix.android.internal.crypto.model.rest.DeviceInfo
|
import im.vector.matrix.android.internal.crypto.model.rest.DeviceInfo
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
/* ==========================================================================================
|
/* ==========================================================================================
|
||||||
* MXDeviceInfo
|
* MXDeviceInfo
|
||||||
@ -29,7 +28,6 @@ fun MXDeviceInfo.getFingerprintHumanReadable() = fingerprint()
|
|||||||
?.chunked(4)
|
?.chunked(4)
|
||||||
?.joinToString(separator = " ")
|
?.joinToString(separator = " ")
|
||||||
|
|
||||||
|
fun MutableList<DeviceInfo>.sortByLastSeen() {
|
||||||
fun List<DeviceInfo>.sortByLastSeen() {
|
sortWith(DatedObjectComparators.descComparator)
|
||||||
Collections.sort(this, DatedObjectComparators.descComparator)
|
|
||||||
}
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package im.vector.matrix.android.api.failure
|
||||||
|
|
||||||
|
// This data class will be sent to the bus
|
||||||
|
data class ConsentNotGivenError(
|
||||||
|
val consentUri: String
|
||||||
|
)
|
@ -31,6 +31,7 @@ import java.io.IOException
|
|||||||
*/
|
*/
|
||||||
sealed class Failure(cause: Throwable? = null) : Throwable(cause = cause) {
|
sealed class Failure(cause: Throwable? = null) : Throwable(cause = cause) {
|
||||||
data class Unknown(val throwable: Throwable? = null) : Failure(throwable)
|
data class Unknown(val throwable: Throwable? = null) : Failure(throwable)
|
||||||
|
data class Cancelled(val throwable: Throwable? = null) : Failure(throwable)
|
||||||
data class NetworkConnection(val ioException: IOException? = null) : Failure(ioException)
|
data class NetworkConnection(val ioException: IOException? = null) : Failure(ioException)
|
||||||
data class ServerError(val error: MatrixError, val httpCode: Int) : Failure(RuntimeException(error.toString()))
|
data class ServerError(val error: MatrixError, val httpCode: Int) : Failure(RuntimeException(error.toString()))
|
||||||
// When server send an error, but it cannot be interpreted as a MatrixError
|
// When server send an error, but it cannot be interpreted as a MatrixError
|
||||||
@ -41,5 +42,4 @@ sealed class Failure(cause: Throwable? = null) : Throwable(cause = cause) {
|
|||||||
data class CryptoError(val error: MXCryptoError) : Failure(error)
|
data class CryptoError(val error: MXCryptoError) : Failure(error)
|
||||||
|
|
||||||
abstract class FeatureFailure : Failure()
|
abstract class FeatureFailure : Failure()
|
||||||
|
|
||||||
}
|
}
|
@ -33,7 +33,6 @@ data class MatrixError(
|
|||||||
@Json(name = "limit_type") val limitType: String? = null,
|
@Json(name = "limit_type") val limitType: String? = null,
|
||||||
@Json(name = "admin_contact") val adminUri: String? = null) {
|
@Json(name = "admin_contact") val adminUri: String? = null) {
|
||||||
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val FORBIDDEN = "M_FORBIDDEN"
|
const val FORBIDDEN = "M_FORBIDDEN"
|
||||||
const val UNKNOWN = "M_UNKNOWN"
|
const val UNKNOWN = "M_UNKNOWN"
|
||||||
|
@ -30,9 +30,9 @@ object MatrixLinkify {
|
|||||||
*
|
*
|
||||||
* @param spannable the text in which the matrix items has to be clickable.
|
* @param spannable the text in which the matrix items has to be clickable.
|
||||||
*/
|
*/
|
||||||
fun addLinks(spannable: Spannable?, callback: MatrixPermalinkSpan.Callback?): Boolean {
|
fun addLinks(spannable: Spannable, callback: MatrixPermalinkSpan.Callback?): Boolean {
|
||||||
// sanity checks
|
// sanity checks
|
||||||
if (spannable.isNullOrEmpty()) {
|
if (spannable.isEmpty()) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
val text = spannable.toString()
|
val text = spannable.toString()
|
||||||
@ -51,5 +51,4 @@ object MatrixLinkify {
|
|||||||
}
|
}
|
||||||
return hasMatch
|
return hasMatch
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -35,6 +35,4 @@ class MatrixPermalinkSpan(private val url: String,
|
|||||||
override fun onClick(widget: View) {
|
override fun onClick(widget: View) {
|
||||||
callback?.onUrlClicked(url)
|
callback?.onUrlClicked(url)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
@ -33,5 +33,4 @@ sealed class PermalinkData {
|
|||||||
data class GroupLink(val groupId: String) : PermalinkData()
|
data class GroupLink(val groupId: String) : PermalinkData()
|
||||||
|
|
||||||
data class FallbackLink(val uri: Uri) : PermalinkData()
|
data class FallbackLink(val uri: Uri) : PermalinkData()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
package im.vector.matrix.android.api.permalinks
|
package im.vector.matrix.android.api.permalinks
|
||||||
|
|
||||||
import android.text.TextUtils
|
|
||||||
import im.vector.matrix.android.api.session.events.model.Event
|
import im.vector.matrix.android.api.session.events.model.Event
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -48,10 +47,9 @@ object PermalinkFactory {
|
|||||||
* @return the permalink, or null in case of error
|
* @return the permalink, or null in case of error
|
||||||
*/
|
*/
|
||||||
fun createPermalink(id: String): String? {
|
fun createPermalink(id: String): String? {
|
||||||
return if (TextUtils.isEmpty(id)) {
|
return if (id.isEmpty()) {
|
||||||
null
|
null
|
||||||
} else MATRIX_TO_URL_BASE + escape(id)
|
} else MATRIX_TO_URL_BASE + escape(id)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -72,16 +70,14 @@ object PermalinkFactory {
|
|||||||
* @param url the universal link, Ex: "https://matrix.to/#/@benoit:matrix.org"
|
* @param url the universal link, Ex: "https://matrix.to/#/@benoit:matrix.org"
|
||||||
* @return the id from the url, ex: "@benoit:matrix.org", or null if the url is not a permalink
|
* @return the id from the url, ex: "@benoit:matrix.org", or null if the url is not a permalink
|
||||||
*/
|
*/
|
||||||
fun getLinkedId(url: String?): String? {
|
fun getLinkedId(url: String): String? {
|
||||||
val isSupported = url != null && url.startsWith(MATRIX_TO_URL_BASE)
|
val isSupported = url.startsWith(MATRIX_TO_URL_BASE)
|
||||||
|
|
||||||
return if (isSupported) {
|
return if (isSupported) {
|
||||||
url!!.substring(MATRIX_TO_URL_BASE.length)
|
url.substring(MATRIX_TO_URL_BASE.length)
|
||||||
} else null
|
} else null
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Escape '/' in id, because it is used as a separator
|
* Escape '/' in id, because it is used as a separator
|
||||||
*
|
*
|
||||||
@ -89,6 +85,6 @@ object PermalinkFactory {
|
|||||||
* @return the escaped id
|
* @return the escaped id
|
||||||
*/
|
*/
|
||||||
private fun escape(id: String): String {
|
private fun escape(id: String): String {
|
||||||
return id.replace("/".toRegex(), "%2F")
|
return id.replace("/", "%2F")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -72,5 +72,4 @@ object PermalinkParser {
|
|||||||
else -> PermalinkData.FallbackLink(uri)
|
else -> PermalinkData.FallbackLink(uri)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -18,78 +18,111 @@ package im.vector.matrix.android.api.pushrules
|
|||||||
import im.vector.matrix.android.api.pushrules.rest.PushRule
|
import im.vector.matrix.android.api.pushrules.rest.PushRule
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
|
|
||||||
|
sealed class Action {
|
||||||
|
object Notify : Action()
|
||||||
|
object DoNotNotify : Action()
|
||||||
|
data class Sound(val sound: String = ACTION_OBJECT_VALUE_VALUE_DEFAULT) : Action()
|
||||||
|
data class Highlight(val highlight: Boolean) : Action()
|
||||||
|
}
|
||||||
|
|
||||||
class Action(val type: Type) {
|
private const val ACTION_NOTIFY = "notify"
|
||||||
|
private const val ACTION_DONT_NOTIFY = "dont_notify"
|
||||||
|
private const val ACTION_COALESCE = "coalesce"
|
||||||
|
|
||||||
enum class Type(val value: String) {
|
// Ref: https://matrix.org/docs/spec/client_server/latest#tweaks
|
||||||
NOTIFY("notify"),
|
private const val ACTION_OBJECT_SET_TWEAK_KEY = "set_tweak"
|
||||||
DONT_NOTIFY("dont_notify"),
|
|
||||||
COALESCE("coalesce"),
|
|
||||||
SET_TWEAK("set_tweak");
|
|
||||||
|
|
||||||
companion object {
|
private const val ACTION_OBJECT_SET_TWEAK_VALUE_SOUND = "sound"
|
||||||
|
private const val ACTION_OBJECT_SET_TWEAK_VALUE_HIGHLIGHT = "highlight"
|
||||||
|
|
||||||
fun safeValueOf(value: String): Type? {
|
private const val ACTION_OBJECT_VALUE_KEY = "value"
|
||||||
try {
|
private const val ACTION_OBJECT_VALUE_VALUE_DEFAULT = "default"
|
||||||
return valueOf(value)
|
|
||||||
} catch (e: IllegalArgumentException) {
|
/**
|
||||||
return null
|
* Ref: https://matrix.org/docs/spec/client_server/latest#actions
|
||||||
|
*
|
||||||
|
* Convert
|
||||||
|
* <pre>
|
||||||
|
* "actions": [
|
||||||
|
* "notify",
|
||||||
|
* {
|
||||||
|
* "set_tweak": "sound",
|
||||||
|
* "value": "default"
|
||||||
|
* },
|
||||||
|
* {
|
||||||
|
* "set_tweak": "highlight"
|
||||||
|
* }
|
||||||
|
* ]
|
||||||
|
*
|
||||||
|
* To
|
||||||
|
* [
|
||||||
|
* Action.Notify,
|
||||||
|
* Action.Sound("default"),
|
||||||
|
* Action.Highlight(true)
|
||||||
|
* ]
|
||||||
|
*
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Suppress("IMPLICIT_CAST_TO_ANY")
|
||||||
|
fun List<Action>.toJson(): List<Any> {
|
||||||
|
return map { action ->
|
||||||
|
when (action) {
|
||||||
|
is Action.Notify -> ACTION_NOTIFY
|
||||||
|
is Action.DoNotNotify -> ACTION_DONT_NOTIFY
|
||||||
|
is Action.Sound -> {
|
||||||
|
mapOf(
|
||||||
|
ACTION_OBJECT_SET_TWEAK_KEY to ACTION_OBJECT_SET_TWEAK_VALUE_SOUND,
|
||||||
|
ACTION_OBJECT_VALUE_KEY to action.sound
|
||||||
|
)
|
||||||
|
}
|
||||||
|
is Action.Highlight -> {
|
||||||
|
mapOf(
|
||||||
|
ACTION_OBJECT_SET_TWEAK_KEY to ACTION_OBJECT_SET_TWEAK_VALUE_HIGHLIGHT,
|
||||||
|
ACTION_OBJECT_VALUE_KEY to action.highlight
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var tweak_action: String? = null
|
fun PushRule.getActions(): List<Action> {
|
||||||
var stringValue: String? = null
|
val result = ArrayList<Action>()
|
||||||
var boolValue: Boolean? = null
|
|
||||||
|
|
||||||
companion object {
|
actions.forEach { actionStrOrObj ->
|
||||||
fun mapFrom(pushRule: PushRule): List<Action>? {
|
|
||||||
val actions = ArrayList<Action>()
|
|
||||||
pushRule.actions.forEach { actionStrOrObj ->
|
|
||||||
if (actionStrOrObj is String) {
|
|
||||||
when (actionStrOrObj) {
|
when (actionStrOrObj) {
|
||||||
Action.Type.NOTIFY.value -> Action(Action.Type.NOTIFY)
|
ACTION_NOTIFY -> Action.Notify
|
||||||
Action.Type.DONT_NOTIFY.value -> Action(Action.Type.DONT_NOTIFY)
|
ACTION_DONT_NOTIFY -> Action.DoNotNotify
|
||||||
|
is Map<*, *> -> {
|
||||||
|
when (actionStrOrObj[ACTION_OBJECT_SET_TWEAK_KEY]) {
|
||||||
|
ACTION_OBJECT_SET_TWEAK_VALUE_SOUND -> {
|
||||||
|
(actionStrOrObj[ACTION_OBJECT_VALUE_KEY] as? String)?.let { stringValue ->
|
||||||
|
Action.Sound(stringValue)
|
||||||
|
}
|
||||||
|
// When the value is not there, default sound (not specified by the spec)
|
||||||
|
?: Action.Sound(ACTION_OBJECT_VALUE_VALUE_DEFAULT)
|
||||||
|
}
|
||||||
|
ACTION_OBJECT_SET_TWEAK_VALUE_HIGHLIGHT -> {
|
||||||
|
(actionStrOrObj[ACTION_OBJECT_VALUE_KEY] as? Boolean)?.let { boolValue ->
|
||||||
|
Action.Highlight(boolValue)
|
||||||
|
}
|
||||||
|
// When the value is not there, default is true, says the spec
|
||||||
|
?: Action.Highlight(true)
|
||||||
|
}
|
||||||
else -> {
|
else -> {
|
||||||
Timber.w("Unsupported action type ${actionStrOrObj}")
|
Timber.w("Unsupported set_tweak value ${actionStrOrObj[ACTION_OBJECT_SET_TWEAK_KEY]}")
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
Timber.w("Unsupported action type $actionStrOrObj")
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
}?.let {
|
}?.let {
|
||||||
actions.add(it)
|
result.add(it)
|
||||||
}
|
|
||||||
} else if (actionStrOrObj is Map<*, *>) {
|
|
||||||
val tweakAction = actionStrOrObj["set_tweak"] as? String
|
|
||||||
when (tweakAction) {
|
|
||||||
"sound" -> {
|
|
||||||
(actionStrOrObj["value"] as? String)?.let { stringValue ->
|
|
||||||
Action(Action.Type.SET_TWEAK).also {
|
|
||||||
it.tweak_action = "sound"
|
|
||||||
it.stringValue = stringValue
|
|
||||||
actions.add(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"highlight" -> {
|
|
||||||
(actionStrOrObj["value"] as? Boolean)?.let { boolValue ->
|
|
||||||
Action(Action.Type.SET_TWEAK).also {
|
|
||||||
it.tweak_action = "highlight"
|
|
||||||
it.boolValue = boolValue
|
|
||||||
actions.add(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
Timber.w("Unsupported action type ${actionStrOrObj}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Timber.w("Unsupported action type ${actionStrOrObj}")
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return if (actions.isEmpty()) null else actions
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
@ -35,9 +35,7 @@ abstract class Condition(val kind: Kind) {
|
|||||||
else -> UNRECOGNIZE
|
else -> UNRECOGNIZE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract fun isSatisfied(conditionResolver: ConditionResolver): Boolean
|
abstract fun isSatisfied(conditionResolver: ConditionResolver): Boolean
|
||||||
|
@ -15,13 +15,11 @@
|
|||||||
*/
|
*/
|
||||||
package im.vector.matrix.android.api.pushrules
|
package im.vector.matrix.android.api.pushrules
|
||||||
|
|
||||||
import android.text.TextUtils
|
|
||||||
import im.vector.matrix.android.api.session.events.model.Event
|
import im.vector.matrix.android.api.session.events.model.Event
|
||||||
import im.vector.matrix.android.api.session.events.model.EventType
|
import im.vector.matrix.android.api.session.events.model.EventType
|
||||||
import im.vector.matrix.android.api.session.events.model.toModel
|
import im.vector.matrix.android.api.session.events.model.toModel
|
||||||
import im.vector.matrix.android.api.session.room.model.message.MessageContent
|
import im.vector.matrix.android.api.session.room.model.message.MessageContent
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.util.regex.Pattern
|
|
||||||
|
|
||||||
class ContainsDisplayNameCondition : Condition(Kind.contains_display_name) {
|
class ContainsDisplayNameCondition : Condition(Kind.contains_display_name) {
|
||||||
|
|
||||||
@ -34,7 +32,7 @@ class ContainsDisplayNameCondition : Condition(Kind.contains_display_name) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun isSatisfied(event: Event, displayName: String): Boolean {
|
fun isSatisfied(event: Event, displayName: String): Boolean {
|
||||||
var message = when (event.type) {
|
val message = when (event.type) {
|
||||||
EventType.MESSAGE -> {
|
EventType.MESSAGE -> {
|
||||||
event.content.toModel<MessageContent>()
|
event.content.toModel<MessageContent>()
|
||||||
}
|
}
|
||||||
@ -49,7 +47,6 @@ class ContainsDisplayNameCondition : Condition(Kind.contains_display_name) {
|
|||||||
return caseInsensitiveFind(displayName, message.body)
|
return caseInsensitiveFind(displayName, message.body)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
/**
|
/**
|
||||||
* Returns whether a string contains an occurrence of another, as a standalone word, regardless of case.
|
* Returns whether a string contains an occurrence of another, as a standalone word, regardless of case.
|
||||||
@ -60,20 +57,18 @@ class ContainsDisplayNameCondition : Condition(Kind.contains_display_name) {
|
|||||||
*/
|
*/
|
||||||
fun caseInsensitiveFind(subString: String, longString: String): Boolean {
|
fun caseInsensitiveFind(subString: String, longString: String): Boolean {
|
||||||
// add sanity checks
|
// add sanity checks
|
||||||
if (TextUtils.isEmpty(subString) || TextUtils.isEmpty(longString)) {
|
if (subString.isEmpty() || longString.isEmpty()) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
var res = false
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
val pattern = Pattern.compile("(\\W|^)" + Pattern.quote(subString) + "(\\W|$)", Pattern.CASE_INSENSITIVE)
|
val regex = Regex("(\\W|^)" + Regex.escape(subString) + "(\\W|$)", RegexOption.IGNORE_CASE)
|
||||||
res = pattern.matcher(longString).find()
|
return regex.containsMatchIn(longString)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Timber.e(e, "## caseInsensitiveFind() : failed")
|
Timber.e(e, "## caseInsensitiveFind() : failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
return res
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -29,7 +29,6 @@ class EventMatchCondition(val key: String, val pattern: String) : Condition(Kind
|
|||||||
return "'$key' Matches '$pattern'"
|
return "'$key' Matches '$pattern'"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun isSatisfied(event: Event): Boolean {
|
fun isSatisfied(event: Event): Boolean {
|
||||||
// TODO encrypted events?
|
// TODO encrypted events?
|
||||||
val rawJson = MoshiProvider.providesMoshi().adapter(Event::class.java).toJsonValue(event) as? Map<*, *>
|
val rawJson = MoshiProvider.providesMoshi().adapter(Event::class.java).toJsonValue(event) as? Map<*, *>
|
||||||
@ -47,10 +46,8 @@ class EventMatchCondition(val key: String, val pattern: String) : Condition(Kind
|
|||||||
Timber.e(e, "Failed to evaluate push condition")
|
Timber.e(e, "Failed to evaluate push condition")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun extractField(jsonObject: Map<*, *>, fieldPath: String): String? {
|
private fun extractField(jsonObject: Map<*, *>, fieldPath: String): String? {
|
||||||
val fieldParts = fieldPath.split(".")
|
val fieldParts = fieldPath.split(".")
|
||||||
if (fieldParts.isEmpty()) return null
|
if (fieldParts.isEmpty()) return null
|
||||||
|
@ -25,14 +25,18 @@ interface PushRuleService {
|
|||||||
/**
|
/**
|
||||||
* Fetch the push rules from the server
|
* Fetch the push rules from the server
|
||||||
*/
|
*/
|
||||||
fun fetchPushRules(scope: String = "global")
|
fun fetchPushRules(scope: String = RuleScope.GLOBAL)
|
||||||
|
|
||||||
// TODO get push rule set
|
// TODO get push rule set
|
||||||
fun getPushRules(scope: String = "global"): List<PushRule>
|
fun getPushRules(scope: String = RuleScope.GLOBAL): List<PushRule>
|
||||||
|
|
||||||
// TODO update rule
|
// TODO update rule
|
||||||
|
|
||||||
fun updatePushRuleEnableStatus(kind: String, pushRule: PushRule, enabled: Boolean, callback: MatrixCallback<Unit>): Cancelable
|
fun updatePushRuleEnableStatus(kind: RuleKind, pushRule: PushRule, enabled: Boolean, callback: MatrixCallback<Unit>): Cancelable
|
||||||
|
|
||||||
|
fun addPushRule(kind: RuleKind, pushRule: PushRule, callback: MatrixCallback<Unit>): Cancelable
|
||||||
|
|
||||||
|
fun removePushRule(kind: RuleKind, pushRule: PushRule, callback: MatrixCallback<Unit>): Cancelable
|
||||||
|
|
||||||
fun addPushRuleListener(listener: PushRuleListener)
|
fun addPushRuleListener(listener: PushRuleListener)
|
||||||
|
|
||||||
@ -42,7 +46,9 @@ interface PushRuleService {
|
|||||||
|
|
||||||
interface PushRuleListener {
|
interface PushRuleListener {
|
||||||
fun onMatchRule(event: Event, actions: List<Action>)
|
fun onMatchRule(event: Event, actions: List<Action>)
|
||||||
|
fun onRoomJoined(roomId: String)
|
||||||
fun onRoomLeft(roomId: String)
|
fun onRoomLeft(roomId: String)
|
||||||
|
fun onEventRedacted(redactedEventId: String)
|
||||||
fun batchFinish()
|
fun batchFinish()
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -18,18 +18,17 @@ package im.vector.matrix.android.api.pushrules
|
|||||||
import im.vector.matrix.android.api.session.events.model.Event
|
import im.vector.matrix.android.api.session.events.model.Event
|
||||||
import im.vector.matrix.android.api.session.room.RoomService
|
import im.vector.matrix.android.api.session.room.RoomService
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.util.regex.Pattern
|
|
||||||
|
|
||||||
private val regex = Pattern.compile("^(==|<=|>=|<|>)?(\\d*)$")
|
private val regex = Regex("^(==|<=|>=|<|>)?(\\d*)$")
|
||||||
|
|
||||||
class RoomMemberCountCondition(val `is`: String) : Condition(Kind.room_member_count) {
|
class RoomMemberCountCondition(val iz: String) : Condition(Kind.room_member_count) {
|
||||||
|
|
||||||
override fun isSatisfied(conditionResolver: ConditionResolver): Boolean {
|
override fun isSatisfied(conditionResolver: ConditionResolver): Boolean {
|
||||||
return conditionResolver.resolveRoomMemberCountCondition(this)
|
return conditionResolver.resolveRoomMemberCountCondition(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun technicalDescription(): String {
|
override fun technicalDescription(): String {
|
||||||
return "Room member count is $`is`"
|
return "Room member count is $iz"
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isSatisfied(event: Event, session: RoomService?): Boolean {
|
fun isSatisfied(event: Event, session: RoomService?): Boolean {
|
||||||
@ -56,16 +55,12 @@ class RoomMemberCountCondition(val `is`: String) : Condition(Kind.room_member_co
|
|||||||
*/
|
*/
|
||||||
private fun parseIsField(): Pair<String?, Int>? {
|
private fun parseIsField(): Pair<String?, Int>? {
|
||||||
try {
|
try {
|
||||||
val match = regex.matcher(`is`)
|
val match = regex.find(iz) ?: return null
|
||||||
if (match.find()) {
|
val (prefix, count) = match.destructured
|
||||||
val prefix = match.group(1)
|
return prefix to count.toInt()
|
||||||
val count = match.group(2).toInt()
|
|
||||||
return prefix to count
|
|
||||||
}
|
|
||||||
} catch (t: Throwable) {
|
} catch (t: Throwable) {
|
||||||
Timber.d(t)
|
Timber.d(t)
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -37,7 +37,7 @@ object RuleIds {
|
|||||||
|
|
||||||
// Default Underride Rules
|
// Default Underride Rules
|
||||||
const val RULE_ID_CALL = ".m.rule.call"
|
const val RULE_ID_CALL = ".m.rule.call"
|
||||||
const val RULE_ID_one_to_one_encrypted_room = ".m.rule.encrypted_room_one_to_one"
|
const val RULE_ID_ONE_TO_ONE_ENCRYPTED_ROOM = ".m.rule.encrypted_room_one_to_one"
|
||||||
const val RULE_ID_ONE_TO_ONE_ROOM = ".m.rule.room_one_to_one"
|
const val RULE_ID_ONE_TO_ONE_ROOM = ".m.rule.room_one_to_one"
|
||||||
const val RULE_ID_ALL_OTHER_MESSAGES_ROOMS = ".m.rule.message"
|
const val RULE_ID_ALL_OTHER_MESSAGES_ROOMS = ".m.rule.message"
|
||||||
const val RULE_ID_ENCRYPTED = ".m.rule.encrypted"
|
const val RULE_ID_ENCRYPTED = ".m.rule.encrypted"
|
||||||
|
@ -15,12 +15,6 @@
|
|||||||
*/
|
*/
|
||||||
package im.vector.matrix.android.api.pushrules
|
package im.vector.matrix.android.api.pushrules
|
||||||
|
|
||||||
|
object RuleScope {
|
||||||
enum class RulesetKey(val value: String) {
|
const val GLOBAL = "global"
|
||||||
CONTENT("content"),
|
|
||||||
OVERRIDE("override"),
|
|
||||||
ROOM("room"),
|
|
||||||
SENDER("sender"),
|
|
||||||
UNDERRIDE("underride"),
|
|
||||||
UNKNOWN("")
|
|
||||||
}
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package im.vector.matrix.android.api.pushrules
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ref: https://matrix.org/docs/spec/client_server/latest#get-matrix-client-r0-pushrules
|
||||||
|
*/
|
||||||
|
enum class RuleSetKey(val value: String) {
|
||||||
|
CONTENT("content"),
|
||||||
|
OVERRIDE("override"),
|
||||||
|
ROOM("room"),
|
||||||
|
SENDER("sender"),
|
||||||
|
UNDERRIDE("underride")
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ref: https://matrix.org/docs/spec/client_server/latest#get-matrix-client-r0-pushrules-scope-kind-ruleid
|
||||||
|
*/
|
||||||
|
typealias RuleKind = RuleSetKey
|
@ -18,7 +18,6 @@ package im.vector.matrix.android.api.pushrules
|
|||||||
import im.vector.matrix.android.api.session.events.model.Event
|
import im.vector.matrix.android.api.session.events.model.Event
|
||||||
import im.vector.matrix.android.api.session.room.model.PowerLevels
|
import im.vector.matrix.android.api.session.room.model.PowerLevels
|
||||||
|
|
||||||
|
|
||||||
class SenderNotificationPermissionCondition(val key: String) : Condition(Kind.sender_notification_permission) {
|
class SenderNotificationPermissionCondition(val key: String) : Condition(Kind.sender_notification_permission) {
|
||||||
|
|
||||||
override fun isSatisfied(conditionResolver: ConditionResolver): Boolean {
|
override fun isSatisfied(conditionResolver: ConditionResolver): Boolean {
|
||||||
@ -29,7 +28,6 @@ class SenderNotificationPermissionCondition(val key: String) : Condition(Kind.se
|
|||||||
return "User power level <$key>"
|
return "User power level <$key>"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun isSatisfied(event: Event, powerLevels: PowerLevels): Boolean {
|
fun isSatisfied(event: Event, powerLevels: PowerLevels): Boolean {
|
||||||
return event.senderId != null && powerLevels.getUserPowerLevel(event.senderId) >= powerLevels.notificationLevel(key)
|
return event.senderId != null && powerLevels.getUserPowerLevel(event.senderId) >= powerLevels.notificationLevel(key)
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,7 @@ data class PushCondition(
|
|||||||
this.key?.let { SenderNotificationPermissionCondition(it) }
|
this.key?.let { SenderNotificationPermissionCondition(it) }
|
||||||
}
|
}
|
||||||
Condition.Kind.UNRECOGNIZE -> {
|
Condition.Kind.UNRECOGNIZE -> {
|
||||||
Timber.e("Unknwon kind $kind")
|
Timber.e("Unknown kind $kind")
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,6 @@ package im.vector.matrix.android.api.pushrules.rest
|
|||||||
import com.squareup.moshi.Json
|
import com.squareup.moshi.Json
|
||||||
import com.squareup.moshi.JsonClass
|
import com.squareup.moshi.JsonClass
|
||||||
|
|
||||||
|
|
||||||
@JsonClass(generateAdapter = true)
|
@JsonClass(generateAdapter = true)
|
||||||
data class PushRule(
|
data class PushRule(
|
||||||
/**
|
/**
|
||||||
@ -47,4 +46,3 @@ data class PushRule(
|
|||||||
*/
|
*/
|
||||||
val pattern: String? = null
|
val pattern: String? = null
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -20,10 +20,10 @@ import androidx.lifecycle.LiveData
|
|||||||
|
|
||||||
interface InitialSyncProgressService {
|
interface InitialSyncProgressService {
|
||||||
|
|
||||||
fun getLiveStatus() : LiveData<Status?>
|
fun getInitialSyncProgressStatus() : LiveData<Status?>
|
||||||
|
|
||||||
data class Status(
|
data class Status(
|
||||||
@StringRes val statusText: Int?,
|
@StringRes val statusText: Int,
|
||||||
val percentProgress: Int = 0
|
val percentProgress: Int = 0
|
||||||
)
|
)
|
||||||
}
|
}
|
@ -19,6 +19,7 @@ package im.vector.matrix.android.api.session
|
|||||||
import androidx.annotation.MainThread
|
import androidx.annotation.MainThread
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import im.vector.matrix.android.api.auth.data.SessionParams
|
import im.vector.matrix.android.api.auth.data.SessionParams
|
||||||
|
import im.vector.matrix.android.api.failure.ConsentNotGivenError
|
||||||
import im.vector.matrix.android.api.pushrules.PushRuleService
|
import im.vector.matrix.android.api.pushrules.PushRuleService
|
||||||
import im.vector.matrix.android.api.session.cache.CacheService
|
import im.vector.matrix.android.api.session.cache.CacheService
|
||||||
import im.vector.matrix.android.api.session.content.ContentUploadStateTracker
|
import im.vector.matrix.android.api.session.content.ContentUploadStateTracker
|
||||||
@ -26,9 +27,11 @@ import im.vector.matrix.android.api.session.content.ContentUrlResolver
|
|||||||
import im.vector.matrix.android.api.session.crypto.CryptoService
|
import im.vector.matrix.android.api.session.crypto.CryptoService
|
||||||
import im.vector.matrix.android.api.session.file.FileService
|
import im.vector.matrix.android.api.session.file.FileService
|
||||||
import im.vector.matrix.android.api.session.group.GroupService
|
import im.vector.matrix.android.api.session.group.GroupService
|
||||||
|
import im.vector.matrix.android.api.session.homeserver.HomeServerCapabilitiesService
|
||||||
import im.vector.matrix.android.api.session.pushers.PushersService
|
import im.vector.matrix.android.api.session.pushers.PushersService
|
||||||
import im.vector.matrix.android.api.session.room.RoomDirectoryService
|
import im.vector.matrix.android.api.session.room.RoomDirectoryService
|
||||||
import im.vector.matrix.android.api.session.room.RoomService
|
import im.vector.matrix.android.api.session.room.RoomService
|
||||||
|
import im.vector.matrix.android.api.session.securestorage.SecureStorageService
|
||||||
import im.vector.matrix.android.api.session.signout.SignOutService
|
import im.vector.matrix.android.api.session.signout.SignOutService
|
||||||
import im.vector.matrix.android.api.session.sync.FilterService
|
import im.vector.matrix.android.api.session.sync.FilterService
|
||||||
import im.vector.matrix.android.api.session.sync.SyncState
|
import im.vector.matrix.android.api.session.sync.SyncState
|
||||||
@ -50,7 +53,9 @@ interface Session :
|
|||||||
FileService,
|
FileService,
|
||||||
PushRuleService,
|
PushRuleService,
|
||||||
PushersService,
|
PushersService,
|
||||||
InitialSyncProgressService {
|
InitialSyncProgressService,
|
||||||
|
HomeServerCapabilitiesService,
|
||||||
|
SecureStorageService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The params associated to the session
|
* The params associated to the session
|
||||||
@ -63,7 +68,6 @@ interface Session :
|
|||||||
val myUserId: String
|
val myUserId: String
|
||||||
get() = sessionParams.credentials.userId
|
get() = sessionParams.credentials.userId
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method allow to open a session. It does start some service on the background.
|
* This method allow to open a session. It does start some service on the background.
|
||||||
*/
|
*/
|
||||||
@ -136,6 +140,9 @@ interface Session :
|
|||||||
*/
|
*/
|
||||||
fun onInvalidToken()
|
fun onInvalidToken()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A M_CONSENT_NOT_GIVEN error has been received from the homeserver
|
||||||
|
*/
|
||||||
|
fun onConsentNotGivenError(consentNotGivenError: ConsentNotGivenError)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -19,7 +19,7 @@ package im.vector.matrix.android.api.session.cache
|
|||||||
import im.vector.matrix.android.api.MatrixCallback
|
import im.vector.matrix.android.api.MatrixCallback
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This interface defines a method to sign out. It's implemented at the session level.
|
* This interface defines a method to clear the cache. It's implemented at the session level.
|
||||||
*/
|
*/
|
||||||
interface CacheService {
|
interface CacheService {
|
||||||
|
|
||||||
@ -27,5 +27,4 @@ interface CacheService {
|
|||||||
* Clear the whole cached data, except credentials. Once done, the session is closed and has to be opened again
|
* Clear the whole cached data, except credentials. Once done, the session is closed and has to be opened again
|
||||||
*/
|
*/
|
||||||
fun clearCache(callback: MatrixCallback<Unit>)
|
fun clearCache(callback: MatrixCallback<Unit>)
|
||||||
|
|
||||||
}
|
}
|
@ -17,6 +17,7 @@
|
|||||||
package im.vector.matrix.android.api.session.content
|
package im.vector.matrix.android.api.session.content
|
||||||
|
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
|
import androidx.exifinterface.media.ExifInterface
|
||||||
import kotlinx.android.parcel.Parcelize
|
import kotlinx.android.parcel.Parcelize
|
||||||
|
|
||||||
@Parcelize
|
@Parcelize
|
||||||
@ -26,6 +27,7 @@ data class ContentAttachmentData(
|
|||||||
val date: Long = 0,
|
val date: Long = 0,
|
||||||
val height: Long? = 0,
|
val height: Long? = 0,
|
||||||
val width: Long? = 0,
|
val width: Long? = 0,
|
||||||
|
val exifOrientation: Int = ExifInterface.ORIENTATION_UNDEFINED,
|
||||||
val name: String? = null,
|
val name: String? = null,
|
||||||
val path: String,
|
val path: String,
|
||||||
val mimeType: String,
|
val mimeType: String,
|
||||||
@ -38,5 +40,4 @@ data class ContentAttachmentData(
|
|||||||
AUDIO,
|
AUDIO,
|
||||||
VIDEO
|
VIDEO
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -109,10 +109,7 @@ interface CryptoService {
|
|||||||
|
|
||||||
fun downloadKeys(userIds: List<String>, forceDownload: Boolean, callback: MatrixCallback<MXUsersDevicesMap<MXDeviceInfo>>)
|
fun downloadKeys(userIds: List<String>, forceDownload: Boolean, callback: MatrixCallback<MXUsersDevicesMap<MXDeviceInfo>>)
|
||||||
|
|
||||||
fun clearCryptoCache(callback: MatrixCallback<Unit>)
|
|
||||||
|
|
||||||
fun addNewSessionListener(newSessionListener: NewSessionListener)
|
fun addNewSessionListener(newSessionListener: NewSessionListener)
|
||||||
|
|
||||||
fun removeSessionListener(listener: NewSessionListener)
|
fun removeSessionListener(listener: NewSessionListener)
|
||||||
|
|
||||||
}
|
}
|
@ -210,5 +210,4 @@ interface KeysBackupService {
|
|||||||
val isEnabled: Boolean
|
val isEnabled: Boolean
|
||||||
val isStucked: Boolean
|
val isStucked: Boolean
|
||||||
val state: KeysBackupState
|
val state: KeysBackupState
|
||||||
|
|
||||||
}
|
}
|
@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
package im.vector.matrix.android.api.session.events.model
|
package im.vector.matrix.android.api.session.events.model
|
||||||
|
|
||||||
import android.text.TextUtils
|
|
||||||
import com.squareup.moshi.Json
|
import com.squareup.moshi.Json
|
||||||
import com.squareup.moshi.JsonClass
|
import com.squareup.moshi.JsonClass
|
||||||
import im.vector.matrix.android.api.session.crypto.MXCryptoError
|
import im.vector.matrix.android.api.session.crypto.MXCryptoError
|
||||||
@ -35,11 +34,10 @@ typealias Content = JsonDict
|
|||||||
* This methods is a facility method to map a json content to a model.
|
* This methods is a facility method to map a json content to a model.
|
||||||
*/
|
*/
|
||||||
inline fun <reified T> Content?.toModel(catchError: Boolean = true): T? {
|
inline fun <reified T> Content?.toModel(catchError: Boolean = true): T? {
|
||||||
return this?.let {
|
|
||||||
val moshi = MoshiProvider.providesMoshi()
|
val moshi = MoshiProvider.providesMoshi()
|
||||||
val moshiAdapter = moshi.adapter(T::class.java)
|
val moshiAdapter = moshi.adapter(T::class.java)
|
||||||
return try {
|
return try {
|
||||||
moshiAdapter.fromJsonValue(it)
|
moshiAdapter.fromJsonValue(this)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
if (catchError) {
|
if (catchError) {
|
||||||
Timber.e(e, "To model failed : $e")
|
Timber.e(e, "To model failed : $e")
|
||||||
@ -49,18 +47,15 @@ inline fun <reified T> Content?.toModel(catchError: Boolean = true): T? {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This methods is a facility method to map a model to a json Content
|
* This methods is a facility method to map a model to a json Content
|
||||||
*/
|
*/
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
inline fun <reified T> T?.toContent(): Content? {
|
inline fun <reified T> T.toContent(): Content {
|
||||||
return this?.let {
|
|
||||||
val moshi = MoshiProvider.providesMoshi()
|
val moshi = MoshiProvider.providesMoshi()
|
||||||
val moshiAdapter = moshi.adapter(T::class.java)
|
val moshiAdapter = moshi.adapter(T::class.java)
|
||||||
return moshiAdapter.toJsonValue(it) as Content
|
return moshiAdapter.toJsonValue(this) as Content
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -81,7 +76,6 @@ data class Event(
|
|||||||
@Json(name = "redacts") val redacts: String? = null
|
@Json(name = "redacts") val redacts: String? = null
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
|
||||||
@Transient
|
@Transient
|
||||||
var mxDecryptionResult: OlmDecryptionResult? = null
|
var mxDecryptionResult: OlmDecryptionResult? = null
|
||||||
|
|
||||||
@ -91,7 +85,6 @@ data class Event(
|
|||||||
@Transient
|
@Transient
|
||||||
var sendState: SendState = SendState.UNKNOWN
|
var sendState: SendState = SendState.UNKNOWN
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if event is a state event.
|
* Check if event is a state event.
|
||||||
* @return true if event is state event.
|
* @return true if event is state event.
|
||||||
@ -108,7 +101,7 @@ data class Event(
|
|||||||
* @return true if this event is encrypted.
|
* @return true if this event is encrypted.
|
||||||
*/
|
*/
|
||||||
fun isEncrypted(): Boolean {
|
fun isEncrypted(): Boolean {
|
||||||
return TextUtils.equals(type, EventType.ENCRYPTED)
|
return type == EventType.ENCRYPTED
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -136,11 +129,12 @@ data class Event(
|
|||||||
* @return the event content
|
* @return the event content
|
||||||
*/
|
*/
|
||||||
fun getClearContent(): Content? {
|
fun getClearContent(): Content? {
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
return mxDecryptionResult?.payload?.get("content") as? Content ?: content
|
return mxDecryptionResult?.payload?.get("content") as? Content ?: content
|
||||||
}
|
}
|
||||||
|
|
||||||
fun toContentStringWithIndent(): String {
|
fun toContentStringWithIndent(): String {
|
||||||
val contentMap = toContent()?.toMutableMap() ?: HashMap()
|
val contentMap = toContent().toMutableMap()
|
||||||
return JSONObject(contentMap).toString(4)
|
return JSONObject(contentMap).toString(4)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,10 +188,8 @@ data class Event(
|
|||||||
result = 31 * result + sendState.hashCode()
|
result = 31 * result + sendState.hashCode()
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun Event.isTextMessage(): Boolean {
|
fun Event.isTextMessage(): Boolean {
|
||||||
return getClearType() == EventType.MESSAGE
|
return getClearType() == EventType.MESSAGE
|
||||||
&& when (getClearContent()?.toModel<MessageContent>()?.type) {
|
&& when (getClearContent()?.toModel<MessageContent>()?.type) {
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
|
|
||||||
package im.vector.matrix.android.api.session.events.model
|
package im.vector.matrix.android.api.session.events.model
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constants defining known event types from Matrix specifications.
|
* Constants defining known event types from Matrix specifications.
|
||||||
*/
|
*/
|
||||||
@ -93,7 +92,6 @@ object EventType {
|
|||||||
STATE_PINNED_EVENT
|
STATE_PINNED_EVENT
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
fun isStateEvent(type: String): Boolean {
|
fun isStateEvent(type: String): Boolean {
|
||||||
return STATE_EVENTS.contains(type)
|
return STATE_EVENTS.contains(type)
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package im.vector.matrix.android.api.session.events.model
|
||||||
|
|
||||||
|
import java.util.UUID
|
||||||
|
|
||||||
|
object LocalEcho {
|
||||||
|
|
||||||
|
private const val PREFIX = "local."
|
||||||
|
|
||||||
|
fun isLocalEchoId(eventId: String) = eventId.startsWith(PREFIX)
|
||||||
|
|
||||||
|
fun createLocalEchoId() = "${PREFIX}${UUID.randomUUID()}"
|
||||||
|
}
|
@ -15,7 +15,6 @@
|
|||||||
*/
|
*/
|
||||||
package im.vector.matrix.android.api.session.events.model
|
package im.vector.matrix.android.api.session.events.model
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constants defining known event relation types from Matrix specifications
|
* Constants defining known event relation types from Matrix specifications
|
||||||
*/
|
*/
|
||||||
@ -27,5 +26,4 @@ object RelationType {
|
|||||||
const val REPLACE = "m.replace"
|
const val REPLACE = "m.replace"
|
||||||
/** Lets you define an event which references an existing event.*/
|
/** Lets you define an event which references an existing event.*/
|
||||||
const val REFERENCE = "m.reference"
|
const val REFERENCE = "m.reference"
|
||||||
|
|
||||||
}
|
}
|
@ -15,7 +15,6 @@
|
|||||||
*/
|
*/
|
||||||
package im.vector.matrix.android.api.session.events.model
|
package im.vector.matrix.android.api.session.events.model
|
||||||
|
|
||||||
|
|
||||||
interface UnsignedRelationInfo {
|
interface UnsignedRelationInfo {
|
||||||
val limited : Boolean?
|
val limited : Boolean?
|
||||||
val count: Int?
|
val count: Int?
|
||||||
|
@ -20,7 +20,6 @@ import im.vector.matrix.android.api.MatrixCallback
|
|||||||
import im.vector.matrix.android.internal.crypto.attachments.ElementToDecrypt
|
import im.vector.matrix.android.internal.crypto.attachments.ElementToDecrypt
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This interface defines methods to get files.
|
* This interface defines methods to get files.
|
||||||
*/
|
*/
|
||||||
|
@ -19,7 +19,6 @@ package im.vector.matrix.android.api.session.group
|
|||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import im.vector.matrix.android.api.session.group.model.GroupSummary
|
import im.vector.matrix.android.api.session.group.model.GroupSummary
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This interface defines methods to get groups. It's implemented at the session level.
|
* This interface defines methods to get groups. It's implemented at the session level.
|
||||||
*/
|
*/
|
||||||
|
@ -16,12 +16,15 @@
|
|||||||
|
|
||||||
package im.vector.matrix.android.api.session.group.model
|
package im.vector.matrix.android.api.session.group.model
|
||||||
|
|
||||||
|
import im.vector.matrix.android.api.session.room.model.Membership
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class holds some data of a group.
|
* This class holds some data of a group.
|
||||||
* It can be retrieved through [im.vector.matrix.android.api.session.group.GroupService]
|
* It can be retrieved through [im.vector.matrix.android.api.session.group.GroupService]
|
||||||
*/
|
*/
|
||||||
data class GroupSummary(
|
data class GroupSummary(
|
||||||
val groupId: String,
|
val groupId: String,
|
||||||
|
val membership: Membership,
|
||||||
val displayName: String = "",
|
val displayName: String = "",
|
||||||
val shortDescription: String = "",
|
val shortDescription: String = "",
|
||||||
val avatarUrl: String = "",
|
val avatarUrl: String = "",
|
||||||
|
@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package im.vector.matrix.android.api.session.homeserver
|
||||||
|
|
||||||
|
data class HomeServerCapabilities(
|
||||||
|
/**
|
||||||
|
* Max size of file which can be uploaded to the homeserver in bytes. [MAX_UPLOAD_FILE_SIZE_UNKNOWN] if unknown or not retrieved yet
|
||||||
|
*/
|
||||||
|
val maxUploadFileSize: Long = MAX_UPLOAD_FILE_SIZE_UNKNOWN
|
||||||
|
) {
|
||||||
|
companion object {
|
||||||
|
const val MAX_UPLOAD_FILE_SIZE_UNKNOWN = -1L
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package im.vector.matrix.android.api.session.homeserver
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This interface defines a method to retrieve the homeserver capabilities.
|
||||||
|
*/
|
||||||
|
interface HomeServerCapabilitiesService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the HomeServer capabilities
|
||||||
|
*/
|
||||||
|
fun getHomeServerCapabilities(): HomeServerCapabilities
|
||||||
|
}
|
@ -16,9 +16,6 @@
|
|||||||
package im.vector.matrix.android.api.session.pushers
|
package im.vector.matrix.android.api.session.pushers
|
||||||
|
|
||||||
data class Pusher(
|
data class Pusher(
|
||||||
|
|
||||||
val userId: String,
|
|
||||||
|
|
||||||
val pushKey: String,
|
val pushKey: String,
|
||||||
val kind: String,
|
val kind: String,
|
||||||
val appId: String,
|
val appId: String,
|
||||||
|
@ -17,8 +17,7 @@ package im.vector.matrix.android.api.session.pushers
|
|||||||
|
|
||||||
import androidx.lifecycle.LiveData
|
import androidx.lifecycle.LiveData
|
||||||
import im.vector.matrix.android.api.MatrixCallback
|
import im.vector.matrix.android.api.MatrixCallback
|
||||||
import java.util.*
|
import java.util.UUID
|
||||||
|
|
||||||
|
|
||||||
interface PushersService {
|
interface PushersService {
|
||||||
|
|
||||||
@ -53,7 +52,6 @@ interface PushersService {
|
|||||||
append: Boolean,
|
append: Boolean,
|
||||||
withEventIdOnly: Boolean): UUID
|
withEventIdOnly: Boolean): UUID
|
||||||
|
|
||||||
|
|
||||||
fun removeHttpPusher(pushkey: String, appId: String, callback: MatrixCallback<Unit>)
|
fun removeHttpPusher(pushkey: String, appId: String, callback: MatrixCallback<Unit>)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
@ -21,10 +21,14 @@ import im.vector.matrix.android.api.session.room.crypto.RoomCryptoService
|
|||||||
import im.vector.matrix.android.api.session.room.members.MembershipService
|
import im.vector.matrix.android.api.session.room.members.MembershipService
|
||||||
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
import im.vector.matrix.android.api.session.room.model.RoomSummary
|
||||||
import im.vector.matrix.android.api.session.room.model.relation.RelationService
|
import im.vector.matrix.android.api.session.room.model.relation.RelationService
|
||||||
|
import im.vector.matrix.android.api.session.room.notification.RoomPushRuleService
|
||||||
|
import im.vector.matrix.android.api.session.room.reporting.ReportingService
|
||||||
import im.vector.matrix.android.api.session.room.read.ReadService
|
import im.vector.matrix.android.api.session.room.read.ReadService
|
||||||
|
import im.vector.matrix.android.api.session.room.send.DraftService
|
||||||
import im.vector.matrix.android.api.session.room.send.SendService
|
import im.vector.matrix.android.api.session.room.send.SendService
|
||||||
import im.vector.matrix.android.api.session.room.state.StateService
|
import im.vector.matrix.android.api.session.room.state.StateService
|
||||||
import im.vector.matrix.android.api.session.room.timeline.TimelineService
|
import im.vector.matrix.android.api.session.room.timeline.TimelineService
|
||||||
|
import im.vector.matrix.android.api.util.Optional
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This interface defines methods to interact within a room.
|
* This interface defines methods to interact within a room.
|
||||||
@ -32,11 +36,14 @@ import im.vector.matrix.android.api.session.room.timeline.TimelineService
|
|||||||
interface Room :
|
interface Room :
|
||||||
TimelineService,
|
TimelineService,
|
||||||
SendService,
|
SendService,
|
||||||
|
DraftService,
|
||||||
ReadService,
|
ReadService,
|
||||||
MembershipService,
|
MembershipService,
|
||||||
StateService,
|
StateService,
|
||||||
|
ReportingService,
|
||||||
RelationService,
|
RelationService,
|
||||||
RoomCryptoService {
|
RoomCryptoService,
|
||||||
|
RoomPushRuleService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The roomId of this room
|
* The roomId of this room
|
||||||
@ -47,8 +54,7 @@ interface Room :
|
|||||||
* A live [RoomSummary] associated with the room
|
* A live [RoomSummary] associated with the room
|
||||||
* You can observe this summary to get dynamic data from this room.
|
* You can observe this summary to get dynamic data from this room.
|
||||||
*/
|
*/
|
||||||
fun liveRoomSummary(): LiveData<RoomSummary>
|
fun getRoomSummaryLive(): LiveData<Optional<RoomSummary>>
|
||||||
|
|
||||||
fun roomSummary(): RoomSummary?
|
fun roomSummary(): RoomSummary?
|
||||||
|
|
||||||
}
|
}
|
@ -42,5 +42,4 @@ interface RoomDirectoryService {
|
|||||||
* Includes both the available protocols and all fields required for queries against each protocol.
|
* Includes both the available protocols and all fields required for queries against each protocol.
|
||||||
*/
|
*/
|
||||||
fun getThirdPartyProtocol(callback: MatrixCallback<Map<String, ThirdPartyProtocol>>): Cancelable
|
fun getThirdPartyProtocol(callback: MatrixCallback<Map<String, ThirdPartyProtocol>>): Cancelable
|
||||||
|
|
||||||
}
|
}
|
@ -54,4 +54,8 @@ interface RoomService {
|
|||||||
*/
|
*/
|
||||||
fun liveRoomSummaries(): LiveData<List<RoomSummary>>
|
fun liveRoomSummaries(): LiveData<List<RoomSummary>>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark all rooms as read
|
||||||
|
*/
|
||||||
|
fun markAllAsRead(roomIds: List<String>, callback: MatrixCallback<Unit>): Cancelable
|
||||||
}
|
}
|
@ -21,5 +21,4 @@ import im.vector.matrix.android.api.failure.Failure
|
|||||||
sealed class CreateRoomFailure : Failure.FeatureFailure() {
|
sealed class CreateRoomFailure : Failure.FeatureFailure() {
|
||||||
|
|
||||||
object CreatedWithTimeout: CreateRoomFailure()
|
object CreatedWithTimeout: CreateRoomFailure()
|
||||||
|
|
||||||
}
|
}
|
@ -21,5 +21,4 @@ import im.vector.matrix.android.api.failure.Failure
|
|||||||
sealed class JoinRoomFailure : Failure.FeatureFailure() {
|
sealed class JoinRoomFailure : Failure.FeatureFailure() {
|
||||||
|
|
||||||
object JoinedWithTimeout : JoinRoomFailure()
|
object JoinedWithTimeout : JoinRoomFailure()
|
||||||
|
|
||||||
}
|
}
|
@ -64,5 +64,4 @@ interface MembershipService {
|
|||||||
* Leave the room, or reject an invitation.
|
* Leave the room, or reject an invitation.
|
||||||
*/
|
*/
|
||||||
fun leave(callback: MatrixCallback<Unit>): Cancelable
|
fun leave(callback: MatrixCallback<Unit>): Cancelable
|
||||||
|
|
||||||
}
|
}
|
@ -43,5 +43,4 @@ enum class Membership(val value: String) {
|
|||||||
fun isLeft(): Boolean {
|
fun isLeft(): Boolean {
|
||||||
return this == KNOCK || this == LEAVE || this == BAN
|
return this == KNOCK || this == LEAVE || this == BAN
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -16,11 +16,9 @@
|
|||||||
|
|
||||||
package im.vector.matrix.android.api.session.room.model
|
package im.vector.matrix.android.api.session.room.model
|
||||||
|
|
||||||
import android.text.TextUtils
|
|
||||||
import com.squareup.moshi.Json
|
import com.squareup.moshi.Json
|
||||||
import com.squareup.moshi.JsonClass
|
import com.squareup.moshi.JsonClass
|
||||||
import im.vector.matrix.android.api.session.events.model.EventType
|
import im.vector.matrix.android.api.session.events.model.EventType
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class representing the EventType.EVENT_TYPE_STATE_ROOM_POWER_LEVELS state event content.
|
* Class representing the EventType.EVENT_TYPE_STATE_ROOM_POWER_LEVELS state event content.
|
||||||
@ -46,13 +44,7 @@ data class PowerLevels(
|
|||||||
* @return the power level
|
* @return the power level
|
||||||
*/
|
*/
|
||||||
fun getUserPowerLevel(userId: String): Int {
|
fun getUserPowerLevel(userId: String): Int {
|
||||||
// sanity check
|
return users.getOrElse(userId) { usersDefault }
|
||||||
if (!TextUtils.isEmpty(userId)) {
|
|
||||||
val powerLevel = users[userId]
|
|
||||||
return powerLevel ?: usersDefault
|
|
||||||
}
|
|
||||||
|
|
||||||
return usersDefault
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -61,10 +53,8 @@ data class PowerLevels(
|
|||||||
* @param userId the user
|
* @param userId the user
|
||||||
* @param powerLevel the new power level
|
* @param powerLevel the new power level
|
||||||
*/
|
*/
|
||||||
fun setUserPowerLevel(userId: String?, powerLevel: Int) {
|
fun setUserPowerLevel(userId: String, powerLevel: Int) {
|
||||||
if (null != userId) {
|
users[userId] = powerLevel
|
||||||
users[userId] = Integer.valueOf(powerLevel)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -75,10 +65,9 @@ data class PowerLevels(
|
|||||||
* @return true if the user can send the event
|
* @return true if the user can send the event
|
||||||
*/
|
*/
|
||||||
fun maySendEventOfType(eventTypeString: String, userId: String): Boolean {
|
fun maySendEventOfType(eventTypeString: String, userId: String): Boolean {
|
||||||
return if (!TextUtils.isEmpty(eventTypeString) && !TextUtils.isEmpty(userId)) {
|
return if (eventTypeString.isNotEmpty() && userId.isNotEmpty()) {
|
||||||
getUserPowerLevel(userId) >= minimumPowerLevelForSendingEventAsMessage(eventTypeString)
|
getUserPowerLevel(userId) >= minimumPowerLevelForSendingEventAsMessage(eventTypeString)
|
||||||
} else false
|
} else false
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -113,25 +102,20 @@ data class PowerLevels(
|
|||||||
return events[eventTypeString] ?: stateDefault
|
return events[eventTypeString] ?: stateDefault
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the notification level for a dedicated key.
|
* Get the notification level for a dedicated key.
|
||||||
*
|
*
|
||||||
* @param key the notification key
|
* @param key the notification key
|
||||||
* @return the level
|
* @return the level
|
||||||
*/
|
*/
|
||||||
fun notificationLevel(key: String?): Int {
|
fun notificationLevel(key: String): Int {
|
||||||
if (null != key && notifications.containsKey(key)) {
|
val valAsVoid = notifications[key] ?: return 50
|
||||||
val valAsVoid = notifications[key]
|
|
||||||
|
|
||||||
// the first implementation was a string value
|
// the first implementation was a string value
|
||||||
return if (valAsVoid is String) {
|
return if (valAsVoid is String) {
|
||||||
Integer.parseInt(valAsVoid)
|
valAsVoid.toInt()
|
||||||
} else {
|
} else {
|
||||||
valAsVoid as Int
|
valAsVoid as Int
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 50
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package im.vector.matrix.android.api.session.room.model
|
||||||
|
|
||||||
|
import com.squareup.moshi.Json
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enum for [RoomJoinRulesContent] : https://matrix.org/docs/spec/client_server/r0.4.0#m-room-join-rules
|
||||||
|
*/
|
||||||
|
enum class RoomJoinRules(val value: String) {
|
||||||
|
|
||||||
|
@Json(name = "public")
|
||||||
|
PUBLIC("public"),
|
||||||
|
|
||||||
|
@Json(name = "invite")
|
||||||
|
INVITE("invite"),
|
||||||
|
|
||||||
|
@Json(name = "knock")
|
||||||
|
KNOCK("knock"),
|
||||||
|
|
||||||
|
@Json(name = "private")
|
||||||
|
PRIVATE("private")
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package im.vector.matrix.android.api.session.room.model
|
||||||
|
|
||||||
|
import com.squareup.moshi.Json
|
||||||
|
import com.squareup.moshi.JsonClass
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class representing the EventType.STATE_ROOM_JOIN_RULES state event content
|
||||||
|
*/
|
||||||
|
@JsonClass(generateAdapter = true)
|
||||||
|
data class RoomJoinRulesContent(
|
||||||
|
@Json(name = "join_rule") val joinRules: RoomJoinRules? = null
|
||||||
|
)
|
@ -17,6 +17,7 @@
|
|||||||
package im.vector.matrix.android.api.session.room.model
|
package im.vector.matrix.android.api.session.room.model
|
||||||
|
|
||||||
import im.vector.matrix.android.api.session.room.model.tag.RoomTag
|
import im.vector.matrix.android.api.session.room.model.tag.RoomTag
|
||||||
|
import im.vector.matrix.android.api.session.room.send.UserDraft
|
||||||
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -29,15 +30,21 @@ data class RoomSummary(
|
|||||||
val topic: String = "",
|
val topic: String = "",
|
||||||
val avatarUrl: String = "",
|
val avatarUrl: String = "",
|
||||||
val isDirect: Boolean = false,
|
val isDirect: Boolean = false,
|
||||||
val latestEvent: TimelineEvent? = null,
|
val latestPreviewableEvent: TimelineEvent? = null,
|
||||||
val otherMemberIds: List<String> = emptyList(),
|
val otherMemberIds: List<String> = emptyList(),
|
||||||
val notificationCount: Int = 0,
|
val notificationCount: Int = 0,
|
||||||
val highlightCount: Int = 0,
|
val highlightCount: Int = 0,
|
||||||
|
val hasUnreadMessages: Boolean = false,
|
||||||
val tags: List<RoomTag> = emptyList(),
|
val tags: List<RoomTag> = emptyList(),
|
||||||
val membership: Membership = Membership.NONE,
|
val membership: Membership = Membership.NONE,
|
||||||
val versioningState: VersioningState = VersioningState.NONE
|
val versioningState: VersioningState = VersioningState.NONE,
|
||||||
|
val readMarkerId: String? = null,
|
||||||
|
val userDrafts: List<UserDraft> = emptyList()
|
||||||
) {
|
) {
|
||||||
|
|
||||||
val isVersioned: Boolean
|
val isVersioned: Boolean
|
||||||
get() = versioningState != VersioningState.NONE
|
get() = versioningState != VersioningState.NONE
|
||||||
|
|
||||||
|
val hasNewMessages: Boolean
|
||||||
|
get() = notificationCount != 0
|
||||||
}
|
}
|
@ -31,5 +31,4 @@ data class CallAnswerContent(
|
|||||||
@Json(name = "type") val type: String,
|
@Json(name = "type") val type: String,
|
||||||
@Json(name = "sdp") val sdp: String
|
@Json(name = "sdp") val sdp: String
|
||||||
)
|
)
|
||||||
|
|
||||||
}
|
}
|
@ -32,5 +32,4 @@ data class CallCandidatesContent(
|
|||||||
@Json(name = "sdpMLineIndex") val sdpMLineIndex: String,
|
@Json(name = "sdpMLineIndex") val sdpMLineIndex: String,
|
||||||
@Json(name = "candidate") val candidate: String
|
@Json(name = "candidate") val candidate: String
|
||||||
)
|
)
|
||||||
|
|
||||||
}
|
}
|
@ -37,6 +37,5 @@ data class CallInviteContent(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun isVideo(): Boolean = offer.sdp.contains(Offer.SDP_VIDEO)
|
fun isVideo(): Boolean = offer.sdp.contains(Offer.SDP_VIDEO)
|
||||||
}
|
}
|
@ -20,7 +20,6 @@ import android.util.Patterns
|
|||||||
import com.squareup.moshi.Json
|
import com.squareup.moshi.Json
|
||||||
import com.squareup.moshi.JsonClass
|
import com.squareup.moshi.JsonClass
|
||||||
import im.vector.matrix.android.api.MatrixPatterns.isUserId
|
import im.vector.matrix.android.api.MatrixPatterns.isUserId
|
||||||
import im.vector.matrix.android.api.auth.data.Credentials
|
|
||||||
import im.vector.matrix.android.api.auth.data.HomeServerConnectionConfig
|
import im.vector.matrix.android.api.auth.data.HomeServerConnectionConfig
|
||||||
import im.vector.matrix.android.api.session.events.model.Event
|
import im.vector.matrix.android.api.session.events.model.Event
|
||||||
import im.vector.matrix.android.api.session.events.model.EventType
|
import im.vector.matrix.android.api.session.events.model.EventType
|
||||||
@ -29,7 +28,6 @@ import im.vector.matrix.android.api.session.room.model.PowerLevels
|
|||||||
import im.vector.matrix.android.api.session.room.model.RoomDirectoryVisibility
|
import im.vector.matrix.android.api.session.room.model.RoomDirectoryVisibility
|
||||||
import im.vector.matrix.android.api.session.room.model.RoomHistoryVisibility
|
import im.vector.matrix.android.api.session.room.model.RoomHistoryVisibility
|
||||||
import im.vector.matrix.android.internal.auth.data.ThreePidMedium
|
import im.vector.matrix.android.internal.auth.data.ThreePidMedium
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parameter to create a room, with facilities functions to configure it
|
* Parameter to create a room, with facilities functions to configure it
|
||||||
@ -133,7 +131,7 @@ class CreateRoomParams {
|
|||||||
)
|
)
|
||||||
|
|
||||||
if (null == initialStates) {
|
if (null == initialStates) {
|
||||||
initialStates = Arrays.asList<Event>(algoEvent)
|
initialStates = mutableListOf(algoEvent)
|
||||||
} else {
|
} else {
|
||||||
initialStates!!.add(algoEvent)
|
initialStates!!.add(algoEvent)
|
||||||
}
|
}
|
||||||
@ -147,15 +145,7 @@ class CreateRoomParams {
|
|||||||
*/
|
*/
|
||||||
fun setHistoryVisibility(historyVisibility: RoomHistoryVisibility?) {
|
fun setHistoryVisibility(historyVisibility: RoomHistoryVisibility?) {
|
||||||
// Remove the existing value if any.
|
// Remove the existing value if any.
|
||||||
if (initialStates != null && !initialStates!!.isEmpty()) {
|
initialStates?.removeAll { it.getClearType() == EventType.STATE_HISTORY_VISIBILITY }
|
||||||
val newInitialStates = ArrayList<Event>()
|
|
||||||
for (event in initialStates!!) {
|
|
||||||
if (event.getClearType() != EventType.STATE_HISTORY_VISIBILITY) {
|
|
||||||
newInitialStates.add(event)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
initialStates = newInitialStates
|
|
||||||
}
|
|
||||||
|
|
||||||
if (historyVisibility != null) {
|
if (historyVisibility != null) {
|
||||||
val contentMap = HashMap<String, RoomHistoryVisibility>()
|
val contentMap = HashMap<String, RoomHistoryVisibility>()
|
||||||
@ -166,7 +156,7 @@ class CreateRoomParams {
|
|||||||
content = contentMap.toContent())
|
content = contentMap.toContent())
|
||||||
|
|
||||||
if (null == initialStates) {
|
if (null == initialStates) {
|
||||||
initialStates = Arrays.asList<Event>(historyVisibilityEvent)
|
initialStates = mutableListOf(historyVisibilityEvent)
|
||||||
} else {
|
} else {
|
||||||
initialStates!!.add(historyVisibilityEvent)
|
initialStates!!.add(historyVisibilityEvent)
|
||||||
}
|
}
|
||||||
@ -220,7 +210,7 @@ class CreateRoomParams {
|
|||||||
* @param ids the participant ids to add.
|
* @param ids the participant ids to add.
|
||||||
*/
|
*/
|
||||||
fun addParticipantIds(hsConfig: HomeServerConnectionConfig,
|
fun addParticipantIds(hsConfig: HomeServerConnectionConfig,
|
||||||
credentials: Credentials,
|
userId: String,
|
||||||
ids: List<String>) {
|
ids: List<String>) {
|
||||||
for (id in ids) {
|
for (id in ids) {
|
||||||
if (Patterns.EMAIL_ADDRESS.matcher(id).matches() && hsConfig.identityServerUri != null) {
|
if (Patterns.EMAIL_ADDRESS.matcher(id).matches() && hsConfig.identityServerUri != null) {
|
||||||
@ -234,7 +224,7 @@ class CreateRoomParams {
|
|||||||
invite3pids!!.add(pid)
|
invite3pids!!.add(pid)
|
||||||
} else if (isUserId(id)) {
|
} else if (isUserId(id)) {
|
||||||
// do not invite oneself
|
// do not invite oneself
|
||||||
if (credentials.userId != id) {
|
if (userId != id) {
|
||||||
if (null == invitedUserIds) {
|
if (null == invitedUserIds) {
|
||||||
invitedUserIds = ArrayList()
|
invitedUserIds = ArrayList()
|
||||||
}
|
}
|
||||||
|
@ -28,5 +28,3 @@ data class RoomCreateContent(
|
|||||||
@Json(name = "room_version") val roomVersion: String? = null,
|
@Json(name = "room_version") val roomVersion: String? = null,
|
||||||
@Json(name = "predecessor") val predecessor: Predecessor? = null
|
@Json(name = "predecessor") val predecessor: Predecessor? = null
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -42,16 +42,6 @@ data class ImageInfo(
|
|||||||
*/
|
*/
|
||||||
@Json(name = "size") val size: Int = 0,
|
@Json(name = "size") val size: Int = 0,
|
||||||
|
|
||||||
/**
|
|
||||||
* Not documented
|
|
||||||
*/
|
|
||||||
@Json(name = "rotation") val rotation: Int = 0,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Not documented
|
|
||||||
*/
|
|
||||||
@Json(name = "orientation") val orientation: Int = 0,
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Metadata about the image referred to in thumbnail_url.
|
* Metadata about the image referred to in thumbnail_url.
|
||||||
*/
|
*/
|
||||||
|
@ -19,7 +19,6 @@ package im.vector.matrix.android.api.session.room.model.message
|
|||||||
import im.vector.matrix.android.api.session.events.model.Content
|
import im.vector.matrix.android.api.session.events.model.Content
|
||||||
import im.vector.matrix.android.api.session.room.model.relation.RelationDefaultContent
|
import im.vector.matrix.android.api.session.room.model.relation.RelationDefaultContent
|
||||||
|
|
||||||
|
|
||||||
interface MessageContent {
|
interface MessageContent {
|
||||||
val type: String
|
val type: String
|
||||||
val body: String
|
val body: String
|
||||||
@ -27,7 +26,6 @@ interface MessageContent {
|
|||||||
val newContent: Content?
|
val newContent: Content?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun MessageContent?.isReply(): Boolean {
|
fun MessageContent?.isReply(): Boolean {
|
||||||
return this?.relatesTo?.inReplyTo?.eventId != null
|
return this?.relatesTo?.inReplyTo?.eventId != null
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,6 @@ package im.vector.matrix.android.api.session.room.model.message
|
|||||||
|
|
||||||
import im.vector.matrix.android.internal.crypto.model.rest.EncryptedFileInfo
|
import im.vector.matrix.android.internal.crypto.model.rest.EncryptedFileInfo
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for message which can contains an encrypted file
|
* Interface for message which can contains an encrypted file
|
||||||
*/
|
*/
|
||||||
|
@ -38,7 +38,7 @@ data class MessageImageContent(
|
|||||||
/**
|
/**
|
||||||
* Metadata about the image referred to in url.
|
* Metadata about the image referred to in url.
|
||||||
*/
|
*/
|
||||||
@Json(name = "info") val info: ImageInfo? = null,
|
@Json(name = "info") override val info: ImageInfo? = null,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Required. Required if the file is unencrypted. The URL (typically MXC URI) to the image.
|
* Required. Required if the file is unencrypted. The URL (typically MXC URI) to the image.
|
||||||
@ -52,4 +52,4 @@ data class MessageImageContent(
|
|||||||
* Required if the file is encrypted. Information on the encrypted file, as specified in End-to-end encryption.
|
* Required if the file is encrypted. Information on the encrypted file, as specified in End-to-end encryption.
|
||||||
*/
|
*/
|
||||||
@Json(name = "file") override val encryptedFileInfo: EncryptedFileInfo? = null
|
@Json(name = "file") override val encryptedFileInfo: EncryptedFileInfo? = null
|
||||||
) : MessageEncryptedContent
|
) : MessageImageInfoContent
|
||||||
|
@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package im.vector.matrix.android.api.session.room.model.message
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A content with image information
|
||||||
|
*/
|
||||||
|
interface MessageImageInfoContent : MessageEncryptedContent {
|
||||||
|
val info: ImageInfo?
|
||||||
|
}
|
@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
package im.vector.matrix.android.api.session.room.model.message
|
||||||
|
|
||||||
|
import com.squareup.moshi.Json
|
||||||
|
import com.squareup.moshi.JsonClass
|
||||||
|
import im.vector.matrix.android.api.session.events.model.Content
|
||||||
|
import im.vector.matrix.android.api.session.room.model.relation.RelationDefaultContent
|
||||||
|
import im.vector.matrix.android.internal.crypto.model.rest.EncryptedFileInfo
|
||||||
|
|
||||||
|
@JsonClass(generateAdapter = true)
|
||||||
|
data class MessageStickerContent(
|
||||||
|
/**
|
||||||
|
* Set in local, not from server
|
||||||
|
*/
|
||||||
|
override val type: String = MessageType.MSGTYPE_STICKER_LOCAL,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Required. A textual representation of the image. This could be the alt text of the image, the filename of the image,
|
||||||
|
* or some kind of content description for accessibility e.g. 'image attachment'.
|
||||||
|
*/
|
||||||
|
@Json(name = "body") override val body: String,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Metadata about the image referred to in url.
|
||||||
|
*/
|
||||||
|
@Json(name = "info") override val info: ImageInfo? = null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Required. Required if the file is unencrypted. The URL (typically MXC URI) to the image.
|
||||||
|
*/
|
||||||
|
@Json(name = "url") override val url: String? = null,
|
||||||
|
|
||||||
|
@Json(name = "m.relates_to") override val relatesTo: RelationDefaultContent? = null,
|
||||||
|
@Json(name = "m.new_content") override val newContent: Content? = null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Required if the file is encrypted. Information on the encrypted file, as specified in End-to-end encryption.
|
||||||
|
*/
|
||||||
|
@Json(name = "file") override val encryptedFileInfo: EncryptedFileInfo? = null
|
||||||
|
) : MessageImageInfoContent
|
@ -21,6 +21,7 @@ import im.vector.matrix.android.api.session.events.model.Event
|
|||||||
import im.vector.matrix.android.api.session.room.model.EventAnnotationsSummary
|
import im.vector.matrix.android.api.session.room.model.EventAnnotationsSummary
|
||||||
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
import im.vector.matrix.android.api.session.room.timeline.TimelineEvent
|
||||||
import im.vector.matrix.android.api.util.Cancelable
|
import im.vector.matrix.android.api.util.Cancelable
|
||||||
|
import im.vector.matrix.android.api.util.Optional
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* In some cases, events may wish to reference other events.
|
* In some cases, events may wish to reference other events.
|
||||||
@ -47,26 +48,21 @@ import im.vector.matrix.android.api.util.Cancelable
|
|||||||
*/
|
*/
|
||||||
interface RelationService {
|
interface RelationService {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends a reaction (emoji) to the targetedEvent.
|
* Sends a reaction (emoji) to the targetedEvent.
|
||||||
* @param reaction the reaction (preferably emoji)
|
|
||||||
* @param targetEventId the id of the event being reacted
|
* @param targetEventId the id of the event being reacted
|
||||||
|
* @param reaction the reaction (preferably emoji)
|
||||||
*/
|
*/
|
||||||
fun sendReaction(reaction: String,
|
fun sendReaction(targetEventId: String,
|
||||||
targetEventId: String): Cancelable
|
reaction: String): Cancelable
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Undo a reaction (emoji) to the targetedEvent.
|
* Undo a reaction (emoji) to the targetedEvent.
|
||||||
* @param reaction the reaction (preferably emoji)
|
|
||||||
* @param targetEventId the id of the event being reacted
|
* @param targetEventId the id of the event being reacted
|
||||||
* @param myUserId used to know if a reaction event was made by the user
|
* @param reaction the reaction (preferably emoji)
|
||||||
*/
|
*/
|
||||||
fun undoReaction(reaction: String,
|
fun undoReaction(targetEventId: String,
|
||||||
targetEventId: String,
|
reaction: String): Cancelable
|
||||||
myUserId: String)//: Cancelable
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Edit a text message body. Limited to "m.text" contentType
|
* Edit a text message body. Limited to "m.text" contentType
|
||||||
@ -80,7 +76,6 @@ interface RelationService {
|
|||||||
newBodyAutoMarkdown: Boolean,
|
newBodyAutoMarkdown: Boolean,
|
||||||
compatibilityBodyText: String = "* $newBodyText"): Cancelable
|
compatibilityBodyText: String = "* $newBodyText"): Cancelable
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Edit a reply. This is a special case because replies contains fallback text as a prefix.
|
* Edit a reply. This is a special case because replies contains fallback text as a prefix.
|
||||||
* This method will take the new body (stripped from fallbacks) and re-add them before sending.
|
* This method will take the new body (stripped from fallbacks) and re-add them before sending.
|
||||||
@ -95,11 +90,10 @@ interface RelationService {
|
|||||||
compatibilityBodyText: String = "* $newBodyText"): Cancelable
|
compatibilityBodyText: String = "* $newBodyText"): Cancelable
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get's the edit history of the given event
|
* Get the edit history of the given event
|
||||||
*/
|
*/
|
||||||
fun fetchEditHistory(eventId: String, callback: MatrixCallback<List<Event>>)
|
fun fetchEditHistory(eventId: String, callback: MatrixCallback<List<Event>>)
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reply to an event in the timeline (must be in same room)
|
* Reply to an event in the timeline (must be in same room)
|
||||||
* https://matrix.org/docs/spec/client_server/r0.4.0.html#id350
|
* https://matrix.org/docs/spec/client_server/r0.4.0.html#id350
|
||||||
@ -111,7 +105,5 @@ interface RelationService {
|
|||||||
replyText: String,
|
replyText: String,
|
||||||
autoMarkdown: Boolean = false): Cancelable?
|
autoMarkdown: Boolean = false): Cancelable?
|
||||||
|
|
||||||
fun getEventSummaryLive(eventId: String): LiveData<EventAnnotationsSummary>
|
fun getEventSummaryLive(eventId: String): LiveData<Optional<EventAnnotationsSummary>>
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
@ -27,5 +27,4 @@ data class RoomTag(
|
|||||||
val ROOM_TAG_NO_TAG = "m.recent"
|
val ROOM_TAG_NO_TAG = "m.recent"
|
||||||
val ROOM_TAG_SERVER_NOTICE = "m.server_notice"
|
val ROOM_TAG_SERVER_NOTICE = "m.server_notice"
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -51,5 +51,4 @@ data class RoomDirectoryData(
|
|||||||
companion object {
|
companion object {
|
||||||
const val DEFAULT_HOME_SERVER_NAME = "Matrix"
|
const val DEFAULT_HOME_SERVER_NAME = "Matrix"
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -51,7 +51,6 @@ data class ThirdPartyProtocolInstance(
|
|||||||
@Json(name = "instance_id")
|
@Json(name = "instance_id")
|
||||||
var instanceId: String? = null,
|
var instanceId: String? = null,
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* FIXDOC Not documented on matrix.org doc
|
* FIXDOC Not documented on matrix.org doc
|
||||||
*/
|
*/
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user