1
0
mirror of https://github.com/vector-im/riotX-android synced 2025-10-06 00:02:48 +02:00

Compare commits

...

344 Commits

Author SHA1 Message Date
Benoit Marty
ce6d4c4a64 Merge branch 'release/1.0.15' 2021-02-03 17:08:27 +01:00
Benoit Marty
061f3c6919 Prepare release 1.0.15 2021-02-03 17:07:49 +01:00
Benoit Marty
9b13381938 Merge pull request #2762 from vector-im/feature/bma/track
Improvements
2021-02-03 17:02:25 +01:00
Benoit Marty
bc22647b48 Merge pull request #2753 from vector-im/feature/bca/sso_reauth
Feature/bca/sso reauth
2021-02-03 16:12:54 +01:00
Valere
73fccdd6de fix test compilation 2021-02-03 15:38:16 +01:00
Benoit Marty
ad9873c565 Some cleanup 2021-02-03 14:52:58 +01:00
Valere
e976100f1a Fix test compilation error 2021-02-03 14:48:43 +01:00
Valere
289a3ab21f remove dev id for now 2021-02-03 14:36:38 +01:00
Valere
286f00396d Removed unused var 2021-02-03 14:20:58 +01:00
Valere
2a12cf22f5 fix code quality, line too long 2021-02-03 09:39:26 +01:00
Valere
97daf57b0a cleaning 2021-02-03 09:32:51 +01:00
Valere
697b551b9b Cleaning / Code review 2021-02-02 23:10:14 +01:00
Valere
0211197c47 SSO UIA for add 3pid + refactoring move RegistrationFlow to api 2021-02-02 22:25:49 +01:00
Benoit Marty
6ac2717d8b Merge pull request #2760 from vector-im/feature/fga/fix_multiple_task
Fix multiple tasks
2021-02-02 17:55:19 +01:00
ganfra
49aed39711 Fix multiple tasks 2021-02-02 17:11:45 +01:00
Benoit Marty
a820443c56 Fix copyright 2021-02-02 13:05:39 +01:00
Benoit Marty
67aa239398 Merge pull request #2755 from vector-im/feature/bma/big_e2e_rooms_2
Data for Worker overload (#2721)
2021-02-02 13:04:33 +01:00
Valere
2a3962265b SSO UIA for deactivate account 2021-02-02 12:30:46 +01:00
Benoit Marty
e6fc605b08 Data for Worker overload (#2721) 2021-02-02 11:40:52 +01:00
Valere
8129cd0cd3 Cleaning + changelog 2021-02-02 09:32:04 +01:00
Valere
0bc203e0d5 Setup cross signing after initial sync if not yet done
Use grace period if available, if not fail silently
2021-02-02 09:02:10 +01:00
Valere
6c9b16088f Secure secrets passed to intent 2021-02-02 08:59:28 +01:00
Valere
76b425ee8a Cleaning 2021-02-01 16:39:14 +01:00
Valere
5b8215a356 Support SSO provider brand + UI fixes 2021-02-01 16:39:14 +01:00
Valere
9c7df25862 Relax rule for e2e by default 2021-02-01 16:39:14 +01:00
Valere
da16ec0af3 UIA fixes + better error support 2021-02-01 16:39:14 +01:00
Valere
1244d00b31 SSO UIA 2021-02-01 16:39:14 +01:00
Onuray Sahin
98054815a4 Merge pull request #2749 from vector-im/feature/ons/fix_replace_matrix_widget_id
Support $matrix_widget_id parameter.
2021-02-01 18:38:52 +03:00
Onuray Sahin
06be3e691d Support $matrix_widget_id parameter. 2021-02-01 18:13:26 +03:00
Benoit Marty
c794843bb2 Inject the context in the constructor 2021-01-26 17:16:55 +01:00
Benoit Marty
afa3149504 Use lifecycleScope rather than an Empty ViewModel 2021-01-25 23:09:14 +01:00
Benoit Marty
f2f4d325eb Bugfix: remove duplicate "More" section 2021-01-25 20:57:38 +01:00
Benoit Marty
fef0404ac7 Merge pull request #2706 from vector-im/feature/ons/fix_url_preview_on_edit
Update url preview when the event is edited.
2021-01-25 18:06:04 +01:00
Benoit Marty
d6a5b9fb48 fulfill assertion about eventId 2021-01-25 16:42:53 +01:00
Benoit Marty
57dba2f29a Merge branch 'develop' into feature/ons/fix_url_preview_on_edit 2021-01-25 16:05:26 +01:00
Benoit Marty
f64db7f5f3 Fix test compilation 2021-01-25 16:03:31 +01:00
Benoit Marty
128d3845b9 Small rework 2021-01-25 15:19:01 +01:00
Benoit Marty
602ea3327b URL preview: improve fix regarding message edition 2021-01-25 15:11:42 +01:00
Benoit Marty
e55178612c Merge pull request #2665 from vector-im/feature/bca/dendrite_sync_fix
Fix Dendrite sync response support
2021-01-25 14:23:13 +01:00
Benoit Marty
5a0d62db6f Cleanup (PR review)
Also add some doc and add missing `internal` keyword
2021-01-25 12:42:39 +01:00
Benoit Marty
ed62e6a390 Merge pull request #2715 from vector-im/gradlew-update-6.8.1
Update Gradle Wrapper from 6.8 to 6.8.1
2021-01-25 09:55:03 +01:00
Benoit Marty
25a6b0ddfb Merge pull request #2714 from vector-im/feature/bma/bulk_clean
Feature/bma/bulk clean
2021-01-25 09:54:46 +01:00
gradle-update-robot
89cf1f3237 Update Gradle Wrapper from 6.8 to 6.8.1.
Signed-off-by: gradle-update-robot <gradle-update-robot@regolo.cc>
2021-01-23 01:32:49 +00:00
Benoit Marty
b65fc4f46b rename val 2021-01-22 17:59:56 +01:00
Benoit Marty
401b5e2b7a Move private fun 2021-01-22 17:48:13 +01:00
Benoit Marty
a44d00a31c Create data class. 2021-01-22 17:44:24 +01:00
Benoit Marty
267ae457ee Use const 2021-01-22 17:38:17 +01:00
Benoit Marty
887da0a3d6 Improve code #2 2021-01-22 17:37:25 +01:00
Benoit Marty
07ffd3ded3 Improve code 2021-01-22 17:32:00 +01:00
Benoit Marty
25dbb3e9ea Fix bad copy/paste 2021-01-22 17:26:10 +01:00
Benoit Marty
68177a02e1 Merge pull request #2709 from AndrewFerr/develop
Identity: Recompute hashes after M_INVALID_PEPPER
2021-01-22 17:20:43 +01:00
Benoit Marty
0a96841336 Merge branch 'develop' into develop 2021-01-22 17:20:36 +01:00
Benoit Marty
4dcd7846b0 Merge pull request #2616 from vector-im/feature/ons/android_11_migration
Migrate to Android 11, API 30.
2021-01-22 17:17:04 +01:00
Benoit Marty
dc48cd4d16 Merge pull request #2712 from vector-im/feature/ons/fix_viewbinding_crashes
Fix viewbinding NPE crashes
2021-01-22 16:53:56 +01:00
Onuray Sahin
883a7cecf0 Fix viewbinding npe crashes. 2021-01-22 15:34:40 +03:00
Andrew Ferrazzutti
daf019b288 Identity: Recompute hashes after M_INVALID_PEPPER
When a new pepper is retrieved after an M_INVALID_PEPPER response,
recompute hashes with that pepper, and send those new hashes in the next
lookup attempt instead of reusing the original hashes.

Signed-off-by: Andrew Ferrazzutti <fair@miscworks.net>
2021-01-21 21:52:19 -05:00
Onuray Sahin
5eeb545ae2 Update url preview when the event is edited. 2021-01-21 15:20:19 +03:00
Benoit Marty
618d1f5de6 Merge pull request #2701 from vector-im/feature/bma/fix_clear_cache
Fix clear cache issue: sometimes, after a clear cache, there is still a token, so the init sync service is not started.
2021-01-20 17:15:12 +01:00
Benoit Marty
277fc4bf61 Merge branch 'develop' into feature/bma/fix_clear_cache 2021-01-20 17:15:02 +01:00
Benoit Marty
c75eb050df Cleanup and fix test compilation 2021-01-20 16:32:41 +01:00
Benoit Marty
304b489470 Merge pull request #2699 from vector-im/feature/ons/fix_navigation_drawer_max_width
Drawer layout width limit for landscape and tablets
2021-01-20 15:37:46 +01:00
Benoit Marty
4709002429 Fix clear cache issue: sometimes, after a clear cache, there is still a token, so the init sync service is not started.
Migratiing to supend methods fixes the problem, I'm not sure why...
2021-01-20 15:19:48 +01:00
Onuray Sahin
f36bab0a7a Limit drawer layout with max width. 2021-01-19 15:33:35 +03:00
Benoit Marty
68f422e498 Merge pull request #2680 from vector-im/feature/dfa/dagger_update
Dagger: update to 2.31 and use new AssistedInject
2021-01-15 15:57:44 +01:00
ganfra
2c0b7ce0f4 Dagger: update to 2.31 and use new AssistedInject 2021-01-15 15:23:24 +01:00
Benoit Marty
72ee1ace48 Version++ 2021-01-15 11:14:59 +01:00
Benoit Marty
7c013de7b9 Merge branch 'release/1.0.14' 2021-01-15 11:13:49 +01:00
Benoit Marty
979ffcf227 Merge branch 'release/1.0.14' into develop 2021-01-15 11:13:47 +01:00
Benoit Marty
f0f0aafa1b Prepare release 1.0.14 2021-01-15 11:13:36 +01:00
Benoit Marty
c2d5ded335 Merge pull request #2673 from vector-im/feature/bma/fix_weblate
Fix issue coming from Weblate and ensure Hebrew is taken into account in the internal language screen setting
2021-01-14 17:09:26 +01:00
Benoit Marty
1a5291537d Correct support for Hebrew 2021-01-14 14:27:22 +01:00
Benoit Marty
d6ef3ea08e Fix lint issues 2021-01-14 14:08:08 +01:00
Benoit Marty
fac9a65f54 Merge pull request #2670 from RiotTranslateBot/weblate-element-android-element-app
Translations update from Weblate
2021-01-14 11:28:13 +01:00
Weblate
93fc64ff33 Merge branch 'origin/develop' into Weblate. 2021-01-14 09:57:30 +00:00
Flat Earth Israel Association
e097c92458 Translated using Weblate (Hebrew)
Currently translated at 54.2% (1114 of 2055 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/he/
2021-01-14 09:57:18 +00:00
Jeff Huang
e91dbfbf2c Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (7 of 7 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/zh_Hant/
2021-01-14 09:57:14 +00:00
Jeff Huang
801f2860e2 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (2055 of 2055 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/zh_Hant/
2021-01-14 09:57:14 +00:00
Benoit Marty
1ffc3a4f53 Merge pull request #2621 from vector-im/feature/bca/crypto_store_outbound
Persist outbound group session
2021-01-14 10:44:08 +01:00
Benoit Marty
844fe2c4cd Merge branch 'develop' into feature/bca/crypto_store_outbound 2021-01-14 10:43:38 +01:00
Benoit Marty
69efb45fb7 Merge pull request #2659 from vector-im/feature/bma/fix_init_sync
Fix issue with delay set to 0
2021-01-14 10:41:10 +01:00
Benoit Marty
1103d7c112 Merge pull request #2637 from vector-im/feature/bma/investigation
Fix switch theme issue
2021-01-14 10:39:13 +01:00
Benoit Marty
c88072e55f Merge branch 'develop' into feature/bma/investigation 2021-01-14 10:38:56 +01:00
Benoit Marty
e041d404f3 Merge pull request #2664 from vector-im/feature/ons/emoji_keyboard_settings
Option to hide emoji keyboard.
2021-01-14 10:17:33 +01:00
Benoit Marty
5b07af2c12 Merge pull request #2666 from RiotTranslateBot/weblate-element-android-element-app
Translations update from Weblate
2021-01-13 23:54:12 +01:00
Weblate
de73539d2b Merge branch 'origin/develop' into Weblate. 2021-01-13 15:00:03 +00:00
argaman
f7ed94c6e9 Translated using Weblate (Hebrew)
Currently translated at 52.1% (1052 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/he/
2021-01-13 14:59:56 +00:00
Valere
36b1a1471a Fix Dendrite sync response support 2021-01-13 14:23:45 +01:00
Onuray Sahin
1f1eeccc32 Option to hide emoji keyboard is added. 2021-01-13 13:28:46 +03:00
Benoit Marty
1d449c84fe Merge pull request #2661 from vector-im/feature/bma/fix_join
Fix request too large Uri error when joining a room
2021-01-13 09:29:04 +01:00
argaman
0750c7763c Translated using Weblate (Hebrew)
Currently translated at 52.1% (1052 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/he/
2021-01-12 21:37:23 +00:00
אבי טייב
dbaaa07dad Translated using Weblate (Hebrew)
Currently translated at 52.1% (1052 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/he/
2021-01-12 21:37:23 +00:00
Benoit Marty
7446b12827 Fix request too large Uri error when joining a room 2021-01-12 18:16:35 +01:00
Benoit Marty
d4c8f56c6e More renaming 2021-01-12 16:29:05 +01:00
Benoit Marty
2ea45185d4 Ensure the service is restarted with the correct intent 2021-01-12 16:26:52 +01:00
Benoit Marty
50ba131350 More renaming 2021-01-12 16:18:29 +01:00
Benoit Marty
b2df107f17 Remove unused params 2021-01-12 16:11:22 +01:00
Benoit Marty
2b60affd9a Remove useless param 2021-01-12 16:07:49 +01:00
Benoit Marty
e771b21ea3 Rename parameters for clarity 2021-01-12 16:07:49 +01:00
Benoit Marty
b20bbc1295 When network is back, do an immediate sync 2021-01-12 16:07:49 +01:00
Benoit Marty
609ceb7fa4 Avoid Magic numbers 2021-01-12 16:07:49 +01:00
Benoit Marty
aac3f379a7 Add a log 2021-01-12 16:07:49 +01:00
Benoit Marty
d46ae83dc4 Define constant for keys 2021-01-12 16:07:49 +01:00
Benoit Marty
561b89830a Avoid default value for param 2021-01-12 16:07:49 +01:00
Benoit Marty
b69d8ad71a Code cleanup, fix crash if appContext !is HasVectorInjector 2021-01-12 16:07:49 +01:00
Benoit Marty
ec0a04e893 timeout -> restart without delay 2021-01-12 16:07:49 +01:00
Benoit Marty
8307245120 Fix issue with delay set to 0 2021-01-12 16:07:49 +01:00
Benoit Marty
5431584b3c Merge pull request #2627 from vector-im/feature/bma/edit_power_level
Edit power level
2021-01-12 10:31:17 +01:00
Valere
426782a001 remember groupId in session cache 2021-01-12 09:48:02 +01:00
Valere
7eb9941f8c Code review 2021-01-12 09:14:30 +01:00
Benoit Marty
f585deb1d7 Merge pull request #2643 from EdGeraghty/patch-1
Update CHANGES.md
2021-01-11 19:08:21 +01:00
Benoit Marty
26c4c7e467 split long line 2021-01-11 17:10:08 +01:00
Benoit Marty
b2b1bebc32 Merge pull request #2645 from vector-im/gradlew-update-6.8
Update Gradle Wrapper from 6.7.1 to 6.8
2021-01-11 17:03:08 +01:00
gkkulik
793c0ababb Translated using Weblate (Silesian)
Currently translated at 3.1% (63 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/szl/
2021-01-11 09:36:30 +00:00
Ahrale
cf1628228a Translated using Weblate (Hebrew)
Currently translated at 50.4% (1018 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/he/
2021-01-11 09:36:27 +00:00
Flat Earth Israel Association
7f433ac4a0 Translated using Weblate (Hebrew)
Currently translated at 50.4% (1018 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/he/
2021-01-11 09:36:26 +00:00
אבי טייב
48f03c0953 Translated using Weblate (Hebrew)
Currently translated at 50.4% (1018 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/he/
2021-01-11 09:36:03 +00:00
linsui
e75d25f00c Translated using Weblate (Chinese (Simplified))
Currently translated at 95.9% (1936 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/zh_Hans/
2021-01-11 09:35:48 +00:00
Ihor Hordiichuk
e22e70c5ba Translated using Weblate (Ukrainian)
Currently translated at 61.5% (1242 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/uk/
2021-01-11 09:35:46 +00:00
Andreas Kelemen
a8e4be9146 Translated using Weblate (Greek)
Currently translated at 24.2% (490 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/el/
2021-01-11 09:35:44 +00:00
Constantinos Miltiadis
a9ee94e3f0 Translated using Weblate (Greek)
Currently translated at 24.2% (490 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/el/
2021-01-11 09:35:44 +00:00
kojid
cdaddb15af Translated using Weblate (German)
Currently translated at 100.0% (2018 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/de/
2021-01-11 09:35:43 +00:00
Ludwig Bald
a724f844f7 Translated using Weblate (German)
Currently translated at 100.0% (2018 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/de/
2021-01-09 20:53:49 +00:00
kojid
2546061933 Translated using Weblate (German)
Currently translated at 100.0% (2018 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/de/
2021-01-09 20:53:45 +00:00
gradle-update-robot
f4db593009 Update Gradle Wrapper from 6.7.1 to 6.8.
Signed-off-by: gradle-update-robot <gradle-update-robot@regolo.cc>
2021-01-09 01:14:35 +00:00
Ed Geraghty
ce92533525 Update CHANGES.md
No need to gender users :)
2021-01-09 00:39:24 +00:00
gkkulik
6d5e1b2285 Added translation using Weblate (Silesian) 2021-01-08 22:30:19 +00:00
gkkulik
6388d6b91b Added translation using Weblate (Silesian) 2021-01-08 22:25:16 +00:00
Andreas Kelemen
54e501127c Translated using Weblate (Greek)
Currently translated at 23.1% (468 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/el/
2021-01-08 21:21:50 +00:00
Constantinos Miltiadis
6bcd96d629 Translated using Weblate (Greek)
Currently translated at 23.1% (468 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/el/
2021-01-08 21:21:50 +00:00
Constantinos Miltiadis
996fe71de9 Translated using Weblate (Greek)
Currently translated at 22.8% (462 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/el/
2021-01-08 21:08:40 +00:00
Andreas Kelemen
08b38cd6ad Translated using Weblate (Greek)
Currently translated at 22.8% (462 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/el/
2021-01-08 21:08:39 +00:00
אבי טייב
d649cb4aa5 Translated using Weblate (Ukrainian)
Currently translated at 60.5% (1222 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/uk/
2021-01-08 20:33:17 +00:00
John
61be2dd3df Translated using Weblate (Greek)
Currently translated at 21.7% (439 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/el/
2021-01-08 20:32:19 +00:00
Petros Koutsolampros
b6dda73cb1 Translated using Weblate (Greek)
Currently translated at 21.7% (439 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/el/
2021-01-08 20:32:19 +00:00
Constantinos Miltiadis
0c77f49ffd Translated using Weblate (Greek)
Currently translated at 21.7% (439 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/el/
2021-01-08 20:32:13 +00:00
Andreas Kelemen
76f4a1b4f1 Translated using Weblate (Greek)
Currently translated at 21.7% (439 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/el/
2021-01-08 20:32:11 +00:00
Benoit Marty
466f9bd532 Merge pull request #2629 from vector-im/feature/ons/fix_show_sending_image
Sent image not displayed when opened immediately after sending
2021-01-08 17:39:27 +01:00
Benoit Marty
992edb2ee2 Merge branch 'develop' into feature/ons/fix_show_sending_image 2021-01-08 17:38:59 +01:00
Benoit Marty
8de4b0bb20 Small formatting 2021-01-08 15:55:32 +01:00
Benoit Marty
e21c8792e6 Fix switch theme issue, and white field issue (#2599, #2528)
Remove some workarounds. I cannot reproduce the bug of signout which does not destroy the HomeActivityViewModel...
2021-01-08 15:55:32 +01:00
Benoit Marty
54f6440bcf super.onClear() called at the end 2021-01-08 15:54:51 +01:00
Flat Earth Israel Association
819f0c021e Translated using Weblate (Hebrew)
Currently translated at 18.1% (367 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/he/
2021-01-08 14:36:32 +00:00
אבי טייב
bc2f49fa31 Translated using Weblate (Hebrew)
Currently translated at 18.1% (367 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/he/
2021-01-08 14:36:32 +00:00
Ahrale
d3a3ba8079 Translated using Weblate (Hebrew)
Currently translated at 18.1% (367 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/he/
2021-01-08 14:36:26 +00:00
Benoit Marty
1540f13444 Merge pull request #2633 from vector-im/feature/fix_initial_sync_retry
Sync: fix initial sync retry
2021-01-08 14:50:22 +01:00
Flat Earth Israel Association
245d580825 Translated using Weblate (Hebrew)
Currently translated at 14.0% (283 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/he/
2021-01-08 13:50:08 +00:00
אבי טייב
2578423c91 Translated using Weblate (Hebrew)
Currently translated at 14.0% (283 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/he/
2021-01-08 13:50:08 +00:00
Flat Earth Israel Association
1762451bc0 Translated using Weblate (Hebrew)
Currently translated at 9.2% (187 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/he/
2021-01-08 13:31:53 +00:00
אבי טייב
38e4984a4a Translated using Weblate (Hebrew)
Currently translated at 9.2% (187 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/he/
2021-01-08 13:31:50 +00:00
אבי טייב
9d7c49306a Translated using Weblate (Hebrew)
Currently translated at 7.4% (150 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/he/
2021-01-08 13:23:59 +00:00
Flat Earth Israel Association
6b605b2e98 Translated using Weblate (Hebrew)
Currently translated at 7.4% (150 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/he/
2021-01-08 13:23:58 +00:00
Flat Earth Israel Association
cf0242f23a Translated using Weblate (Hebrew)
Currently translated at 6.4% (130 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/he/
2021-01-08 13:20:04 +00:00
אבי טייב
56e8325efe Translated using Weblate (Hebrew)
Currently translated at 6.4% (130 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/he/
2021-01-08 13:20:02 +00:00
ganfra
d91ed2985d Sync: fix initial sync is not retried correctly when there is some network error. [#2632] 2021-01-08 12:42:36 +01:00
Benoit Marty
5f9f69b4dc Simplify signatures 2021-01-08 12:27:40 +01:00
Benoit Marty
da33cbedda Introduce LocalFilesHelper to avoid using the Context directly 2021-01-08 12:23:02 +01:00
Benoit Marty
2d91865277 Merge pull request #2624 from vector-im/feature/bma/avoidEventBus2
Remove dependency to org.greenrobot.eventbus library
2021-01-08 10:04:38 +01:00
Flat Earth Israel Association
003f5fab1f Added translation using Weblate (Hebrew) 2021-01-07 19:44:32 +00:00
Benoit Marty
2a365d6776 Move interface to correct location 2021-01-07 18:28:05 +01:00
Onuray Sahin
55f5f90c45 Use ContentResolver and DocumentFile instead of legacy File.
Fixes #409.
2021-01-07 19:32:04 +03:00
Benoit Marty
bd3bdd6996 Merge pull request #2594 from vector-im/feature/ons/fix_room_topic_scroll
Disable scroll effect when click to a link in the topic.
2021-01-07 15:20:47 +01:00
Benoit Marty
0cf485d873 Merge pull request #2622 from vector-im/feature/bma/leave_private
Warn user when he is leaving a not public room (#1460)
2021-01-07 15:18:35 +01:00
Benoit Marty
75e06d43c5 Cover room settings screens by the sanity unit test 2021-01-07 12:29:34 +01:00
Valere
afa1cf7d6c Cleaning 2021-01-07 11:18:05 +01:00
Benoit Marty
a6f909b942 Add Javadoc 2021-01-07 11:04:11 +01:00
Benoit Marty
ae55ee82a7 Cleanup 2021-01-07 00:07:40 +01:00
Benoit Marty
037e53f385 Split permissions between useful ones and the others 2021-01-06 23:24:25 +01:00
Benoit Marty
a28dfdc48e Improve UI and UX when permission are not editable 2021-01-06 23:03:09 +01:00
Benoit Marty
81bdf506bc Fix Int type issue when sending PowerLevelsContent to the server 2021-01-06 22:53:51 +01:00
Benoit Marty
f253aa6b37 Remove unused field 2021-01-06 18:45:24 +01:00
Benoit Marty
0702eee179 Improve code 2021-01-06 18:38:06 +01:00
Benoit Marty
c4a019f0d3 Edit room permissions (#2471) 2021-01-06 17:42:28 +01:00
Onuray Sahin
e948e9d85a Lint fixes. 2021-01-06 16:28:45 +03:00
Benoit Marty
22c10f5ada Prefer immutable type 2021-01-06 12:24:47 +01:00
Onuray Sahin
869eb262f3 Lint fixes. 2021-01-06 12:49:11 +03:00
Benoit Marty
7249c7d25a Merge pull request #2625 from yquemener/patch-1
Typo in the set-up instructions for the test homeserver
2021-01-06 09:36:40 +01:00
Yves Quemener
6e8d93bc6f Fix in the test homeserver set-up instruction
I think I removed a typo. You probably don't want a new virtualenv every time you start a homeserver?
2021-01-06 11:22:25 +09:00
Benoit Marty
963c30a275 Remove dependency to org.greenrobot.eventbus library 2021-01-05 18:56:24 +01:00
Onuray Sahin
474ade01cf Merge branch 'develop' into feature/ons/fix_room_topic_scroll 2021-01-05 15:08:15 +03:00
Onuray Sahin
18d4b66c97 Fix copy topic on long click. 2021-01-05 15:06:50 +03:00
Onuray Sahin
fa311f4ce2 Fix bug reporter progress. 2021-01-05 14:44:02 +03:00
Benoit Marty
3a9b80127f Warn user when he is leaving a not public room (#1460) 2021-01-05 11:46:59 +01:00
Benoit Marty
78c1a0acf4 Merge pull request #2617 from vector-im/feature/bma/malformed
Tapping drawer having more than 1 room in notifications gives "malformed link" error (#2605)
2021-01-05 10:37:11 +01:00
Valere
4ee34126bd Persist outbound group session 2021-01-05 10:04:34 +01:00
Benoit Marty
4f59ec37ca Tapping drawer having more than 1 room in notifications gives "malformed link" error (#2605) 2021-01-04 18:18:34 +01:00
Benoit Marty
c34fea2932 Do not defien Element Stuff in the SDK 2021-01-04 18:16:12 +01:00
Benoit Marty
c11a50f7ff Malformed matrix.to link: display a dialog instead of a toast 2021-01-04 18:07:47 +01:00
Onuray Sahin
23623b8895 Migrate to Android 11, API 30. 2021-01-04 17:12:49 +03:00
Benoit Marty
b475f36b5a Merge pull request #2615 from vector-im/feature/bma/fix_attachmentViewer
Fix crash in AttachmentViewerActivity (after ViewBindings)
2021-01-04 15:06:57 +01:00
Benoit Marty
11367488e6 Fix crash in AttachmentViewerActivity (after ViewBindings)
And improve code a bit
2021-01-04 14:21:57 +01:00
Benoit Marty
a7d8e74468 Merge pull request #2604 from vector-im/feature/ons/fix_hide_member_events
Feature/ons/fix hide member events
2021-01-04 10:48:22 +01:00
Benoit Marty
a25b93197d Merge pull request #2601 from vector-im/feature/bma/sticker
Unspecced msgType field in m.sticker (#2580)
2021-01-04 10:17:08 +01:00
Danial Behzadi
83f2ff5d82 Translated using Weblate (Persian)
Currently translated at 87.7% (193 of 220 strings)

Translation: Element Android/Element Android Sdk
Translate-URL: https://translate.element.io/projects/element-android/element-sdk/fa/
2021-01-03 12:35:41 +00:00
Danial Behzadi
868c056ddd Translated using Weblate (Persian)
Currently translated at 100.0% (2018 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/fa/
2021-01-03 12:35:41 +00:00
Ngô Ngọc Đức Huy
0106adf36c Translated using Weblate (Vietnamese)
Currently translated at 13.0% (263 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/vi/
2021-01-02 03:35:43 +00:00
Dat Ng
b6a93be611 Translated using Weblate (Vietnamese)
Currently translated at 13.0% (263 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/vi/
2021-01-02 03:35:43 +00:00
sr093906
61291f7337 Translated using Weblate (Chinese (Simplified))
Currently translated at 95.0% (1919 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/zh_Hans/
2021-01-02 03:35:40 +00:00
Onuray Sahin
05013d2559 Fix changelog. 2020-12-30 12:17:25 +03:00
Onuray Sahin
3240cadb94 Fix membership event visibility condition. 2020-12-30 12:08:27 +03:00
LinAGKar
594ee61a99 Translated using Weblate (Swedish)
Currently translated at 100.0% (220 of 220 strings)

Translation: Element Android/Element Android Sdk
Translate-URL: https://translate.element.io/projects/element-android/element-sdk/sv/
2020-12-29 22:35:44 +00:00
zeritti
c85b0124e3 Translated using Weblate (Czech)
Currently translated at 100.0% (220 of 220 strings)

Translation: Element Android/Element Android Sdk
Translate-URL: https://translate.element.io/projects/element-android/element-sdk/cs/
2020-12-29 22:35:44 +00:00
LinAGKar
61bc19fc96 Translated using Weblate (Swedish)
Currently translated at 100.0% (2018 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/sv/
2020-12-29 22:35:43 +00:00
Benoit Marty
3ea3d0fc91 Unspecced msgType field in m.sticker (#2580) 2020-12-29 15:42:12 +01:00
Benoit Marty
f1f1613f00 Cleanup and format 2020-12-29 09:56:15 +01:00
Benoit Marty
68dd206140 Merge pull request #2592 from vector-im/feature/bma/fix_viwe_bindings
Fix crash after migration to view bindings
2020-12-29 09:49:49 +01:00
Benoit Marty
17e8581ef0 Merge pull request #2597 from Tigermouthbear/develop
Add System theme option and set as default
2020-12-29 09:47:58 +01:00
Benoit Marty
7ff45738e0 Merge pull request #2543 from vector-im/feature/ons/wait_members_before_sending_event
Make sure to load all members in the room before sending the event
2020-12-29 09:31:30 +01:00
Tigermouthbear
c9eacec449 Fix formatting in ThemeUtils 2020-12-29 00:22:12 -05:00
Tigermouthbear
3e78098c43 Add System theme option and set as default; closes #904, closes #2387 2020-12-28 23:32:06 -05:00
Onuray Sahin
cbdacc199a Disable scroll effect when click to a link in the topic. 2020-12-28 17:17:01 +03:00
Benoit Marty
cc01f25d8f Revert status to RoomMembersLoadStatusType.NONE) in case of failure 2020-12-28 14:52:49 +01:00
Benoit Marty
9f3176c49c Fix code quality 2020-12-28 14:41:23 +01:00
Benoit Marty
7ae2b34a9e Merge pull request #2568 from vector-im/feature/bma/sso_sdk
Let the SDK compute the URLs
2020-12-28 14:20:21 +01:00
Benoit Marty
d1bec21759 Fix crash after migration to view bindings
Also rename some layouts to follow convention
2020-12-28 12:23:06 +01:00
Benoit Marty
073e6227d6 Correct Copyright mention 2020-12-28 10:59:50 +01:00
Ngô Ngọc Đức Huy
761d8d89b0 Translated using Weblate (Vietnamese)
Currently translated at 10.8% (218 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/vi/
2020-12-27 22:35:44 +00:00
Marcelo Filho
f203fa5c58 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (220 of 220 strings)

Translation: Element Android/Element Android Sdk
Translate-URL: https://translate.element.io/projects/element-android/element-sdk/pt_BR/
2020-12-27 22:35:39 +00:00
Marcelo Filho
9ccb22015a Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (2018 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/pt_BR/
2020-12-27 22:35:39 +00:00
Ngô Ngọc Đức Huy
6d1c53c7ed Translated using Weblate (Vietnamese)
Currently translated at 7.2% (147 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/vi/
2020-12-26 11:35:47 +00:00
Ngô Ngọc Đức Huy
855e7e02ce Translated using Weblate (Vietnamese)
Currently translated at 60.0% (3 of 5 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/vi/
2020-12-26 11:35:38 +00:00
Thomas Jensen
df3bb5b212 Translated using Weblate (Norwegian Bokmål)
Currently translated at 53.2% (1075 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/nb_NO/
2020-12-26 11:35:38 +00:00
Ngô Ngọc Đức Huy
5768e45809 Added translation using Weblate (Vietnamese) 2020-12-25 10:31:01 +00:00
Ngô Ngọc Đức Huy
83584fab44 Added translation using Weblate (Vietnamese) 2020-12-25 10:30:07 +00:00
Thomas Jensen
c234e12302 Translated using Weblate (Norwegian Bokmål)
Currently translated at 3.6% (8 of 220 strings)

Translation: Element Android/Element Android Sdk
Translate-URL: https://translate.element.io/projects/element-android/element-sdk/nb/
2020-12-24 19:35:58 +00:00
Thomas Jensen
4645a8c633 Translated using Weblate (Norwegian Bokmål)
Currently translated at 80.0% (4 of 5 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/nb_NO/
2020-12-24 19:35:58 +00:00
LinAGKar
cfb54f7608 Translated using Weblate (Swedish)
Currently translated at 100.0% (5 of 5 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/sv/
2020-12-24 19:35:58 +00:00
Peter Vágner
7195ee9a69 Translated using Weblate (Slovak)
Currently translated at 80.0% (176 of 220 strings)

Translation: Element Android/Element Android Sdk
Translate-URL: https://translate.element.io/projects/element-android/element-sdk/sk/
2020-12-24 19:35:58 +00:00
LinAGKar
ba6dffc0bf Translated using Weblate (Swedish)
Currently translated at 95.8% (1934 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/sv/
2020-12-24 19:35:58 +00:00
eman luff
d3acf7e862 Translated using Weblate (Polish)
Currently translated at 98.5% (1988 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/pl/
2020-12-24 19:35:57 +00:00
Thomas Jensen
5c6d710f2d Translated using Weblate (Norwegian Bokmål)
Currently translated at 52.5% (1061 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/nb_NO/
2020-12-24 19:35:50 +00:00
Thomas Jensen
fa22a4a747 Added translation using Weblate (Norwegian Bokmål) 2020-12-23 14:04:57 +00:00
reg4xp
94aa0a02fe Translated using Weblate (Persian)
Currently translated at 100.0% (5 of 5 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/fa/
2020-12-22 10:36:04 +00:00
Rachida S
ab23d9b715 Translated using Weblate (Kabyle)
Currently translated at 96.8% (1955 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/kab/
2020-12-22 10:36:04 +00:00
Ihor Hordiichuk
c5ce208d07 Translated using Weblate (Ukrainian)
Currently translated at 35.0% (77 of 220 strings)

Translation: Element Android/Element Android Sdk
Translate-URL: https://translate.element.io/projects/element-android/element-sdk/uk/
2020-12-22 10:35:59 +00:00
aka. nils on element-translations
e7f7c0ba78 Translated using Weblate (Norwegian Nynorsk)
Currently translated at 28.1% (62 of 220 strings)

Translation: Element Android/Element Android Sdk
Translate-URL: https://translate.element.io/projects/element-android/element-sdk/nn/
2020-12-22 10:35:59 +00:00
Ihor Hordiichuk
b082a009a7 Translated using Weblate (Ukrainian)
Currently translated at 48.4% (977 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/uk/
2020-12-22 10:35:59 +00:00
eman luff
cdeb2663fe Translated using Weblate (Polish)
Currently translated at 92.6% (1869 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/pl/
2020-12-22 10:35:57 +00:00
aka. nils on element-translations
a5e979b763 Translated using Weblate (Norwegian Nynorsk)
Currently translated at 43.3% (874 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/nn/
2020-12-22 10:35:39 +00:00
reg4xp
be0cadb3c7 Translated using Weblate (Persian)
Currently translated at 99.7% (2013 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/fa/
2020-12-22 10:35:37 +00:00
Benoit Marty
6c4836e27e Move file to internal 2020-12-21 12:18:32 +01:00
Benoit Marty
36a553a886 Let the Matrix SDK compute the Fallback urls 2020-12-21 12:08:49 +01:00
Benoit Marty
13938f2ab3 Let the Matrix SDK compute the SSO url 2020-12-21 11:26:57 +01:00
Onuray Sahin
a755536a2f Merge branch 'develop' into feature/ons/wait_members_before_sending_event 2020-12-21 12:41:24 +03:00
Benoit Marty
4a5dbde8d3 Merge pull request #2558 from aqulu/fix/bottomsheet-viewbinding
Release VectorBaseBottomSheetDialogFragment bindings when view destroyed
2020-12-20 20:44:37 +01:00
Benoit Marty
5744939c05 Merge pull request #2561 from SpiritCroc/url_preview_visibility
Properly hide preview URLs for messages that don't support previews
2020-12-20 20:40:19 +01:00
reg4xp
8c68126ed9 Translated using Weblate (Persian)
Currently translated at 100.0% (5 of 5 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/fa/
2020-12-20 19:35:43 +00:00
notramo
3c37d4c1b0 Translated using Weblate (Hungarian)
Currently translated at 100.0% (5 of 5 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/hu/
2020-12-20 19:35:42 +00:00
The one with the braid
a9316b2f7e Translated using Weblate (German)
Currently translated at 100.0% (5 of 5 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/de/
2020-12-20 19:35:42 +00:00
Rachida S
3e420033c5 Translated using Weblate (Kabyle)
Currently translated at 91.6% (1849 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/kab/
2020-12-20 19:35:42 +00:00
Priit Jõerüüt
571f05bcfb Translated using Weblate (Estonian)
Currently translated at 100.0% (220 of 220 strings)

Translation: Element Android/Element Android Sdk
Translate-URL: https://translate.element.io/projects/element-android/element-sdk/et/
2020-12-20 19:35:41 +00:00
strix aluco
4e73705378 Translated using Weblate (Ukrainian)
Currently translated at 47.7% (963 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/uk/
2020-12-20 19:35:41 +00:00
Nikita Epifanov
611e1185c8 Translated using Weblate (Russian)
Currently translated at 100.0% (2018 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/ru/
2020-12-20 19:35:41 +00:00
Nils Haugen
b90d8e6238 Translated using Weblate (Norwegian Nynorsk)
Currently translated at 40.8% (824 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/nn/
2020-12-20 19:35:41 +00:00
notramo
ad3573226c Translated using Weblate (Hungarian)
Currently translated at 92.3% (1864 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/hu/
2020-12-20 19:35:40 +00:00
reg4xp
1cc0825b54 Translated using Weblate (Persian)
Currently translated at 99.2% (2002 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/fa/
2020-12-20 19:35:38 +00:00
Priit Jõerüüt
87ac4ec5d4 Translated using Weblate (Estonian)
Currently translated at 100.0% (2018 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/et/
2020-12-20 19:35:37 +00:00
The one with the braid
8344506b05 Translated using Weblate (German)
Currently translated at 97.0% (1958 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/de/
2020-12-20 19:35:36 +00:00
Benoit Marty
9da3eec64f Fix small formatting issue 2020-12-20 20:28:40 +01:00
Benoit Marty
621c6c8773 Merge pull request #2562 from SpiritCroc/notice_preview
Enable URL-previews for notices
2020-12-20 20:26:18 +01:00
SpiritCroc
d5e76c515e Enable URL-previews for notices
Desktop has those too.
2020-12-20 09:10:37 +01:00
SpiritCroc
9fcf7263b5 Properly hide preview URLs for messages that don't support previews
Notices and formatted messages don't have imageContentRenderer and
previewUrlRetriever set.
Accordingly, when recycling messages that previously had an URL preview,
we do not want to keep that preview, but actually hide it, instead of
returning early (without rendering any update).
2020-12-20 09:05:15 +01:00
aqulu
0059fdf174 Release VectorBaseBottomSheetDialogFragment bindings when view destroyed
Signed-off-by: aqulu <dev@aqu.lu>
2020-12-20 13:55:32 +09:00
Benoit Marty
3d291c04c9 const -> companion 2020-12-18 16:53:26 +01:00
Benoit Marty
ca4b91a98f Use the new RoomMembersLoadStatusType.LOADING value 2020-12-18 16:52:39 +01:00
Benoit Marty
b0ba62aa31 Use const 2020-12-18 16:12:01 +01:00
Benoit Marty
abf763f454 Convert to internal Kotlin class 2020-12-18 16:10:36 +01:00
Benoit Marty
15597eb041 Rename .java to .kt 2020-12-18 16:10:36 +01:00
Benoit Marty
00b16db7cc Simplification of code 2020-12-18 16:06:30 +01:00
Benoit Marty
ff8a208012 Change to immutable list 2020-12-18 16:04:46 +01:00
Benoit Marty
7732bd47ce Update Changelog after release 2020-12-18 16:01:39 +01:00
Onuray Sahin
42a5680374 Fix copyright. 2020-12-18 16:00:32 +01:00
Onuray Sahin
5d8f365520 Load room members seamlessly when timeline is starting. 2020-12-18 16:00:32 +01:00
Onuray Sahin
938cd32ddd Do not load room members if there is an ongoing request. 2020-12-18 16:00:32 +01:00
Onuray Sahin
80396fcd39 Changelog added. 2020-12-18 16:00:32 +01:00
Onuray Sahin
7b97981bb5 Make sure to load all members in the room before sending the event. 2020-12-18 16:00:32 +01:00
Onuray Sahin
b263273c87 Improve test with detailed CryptoError message. 2020-12-18 16:00:32 +01:00
Onuray Sahin
427dc784fe Support testing a room with many members. 2020-12-18 16:00:32 +01:00
Onuray Sahin
7e4725c091 Update CryptoTestData to handle more than 3 sessions. 2020-12-18 16:00:32 +01:00
Onuray Sahin
9b332f7a32 Test message decryption in a room with 3 members. 2020-12-18 16:00:32 +01:00
Benoit Marty
2b780a8b76 Merge pull request #2542 from vector-im/feature/bma/view_bindings
View bindings
2020-12-18 15:57:34 +01:00
Benoit Marty
0518e5f18d Version++ 2020-12-18 11:03:01 +01:00
Benoit Marty
0412b87ad1 Merge branch 'release/1.0.13' 2020-12-18 10:59:54 +01:00
Benoit Marty
2fe7caa580 Merge branch 'release/1.0.13' into develop 2020-12-18 10:59:53 +01:00
Benoit Marty
d53650c8ae Prepare release 1.0.13 2020-12-18 10:59:43 +01:00
Benoit Marty
930b8da3b3 Typo in comment 2020-12-18 09:53:59 +01:00
Benoit Marty
c48f153b0d Merge pull request #2550 from vector-im/feature/bma/unstable_prefix
MSC2858 unstable prefix
2020-12-17 19:09:12 +01:00
Benoit Marty
68cd06f1fb Improve redirect url, which can be visible to the user: "element://element" -> "element://connect" 2020-12-17 12:11:30 +01:00
Benoit Marty
c7afcf4ff2 Fix compilation issue 2020-12-17 12:10:55 +01:00
Travis Ralston
3491774e7b Add changelog 2020-12-17 12:09:53 +01:00
Travis Ralston
ea6fde3ed0 Make MSC2858 implementation match the unstable policy of the spec
See https://github.com/matrix-org/matrix-doc/pull/2858/files#r543567196
2020-12-17 12:09:34 +01:00
Benoit Marty
267a7a36ff Translated using Weblate (Slovenian)
Currently translated at 0.3% (7 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/sl/
2020-12-17 06:35:49 +00:00
Jeff Huang
9a69bb9656 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (5 of 5 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/zh_Hant/
2020-12-17 06:35:49 +00:00
random
28aef1067b Translated using Weblate (Italian)
Currently translated at 100.0% (5 of 5 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/it/
2020-12-17 06:35:49 +00:00
Ihor Hordiichuk
690a9eaa21 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (5 of 5 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/uk/
2020-12-17 06:35:48 +00:00
Marcelo Filho
24d76b1d32 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (5 of 5 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/pt_BR/
2020-12-17 06:35:48 +00:00
Tuomas Hietala
173458ed6c Translated using Weblate (Finnish)
Currently translated at 100.0% (5 of 5 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/fi/
2020-12-17 06:35:48 +00:00
Jeff Huang
cebef970d3 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (220 of 220 strings)

Translation: Element Android/Element Android Sdk
Translate-URL: https://translate.element.io/projects/element-android/element-sdk/zh_Hant/
2020-12-17 06:35:48 +00:00
Besnik Bleta
4aa349ddd6 Translated using Weblate (Albanian)
Currently translated at 98.1% (216 of 220 strings)

Translation: Element Android/Element Android Sdk
Translate-URL: https://translate.element.io/projects/element-android/element-sdk/sq/
2020-12-17 06:35:48 +00:00
Nikita Epifanov
a918d28ded Translated using Weblate (Russian)
Currently translated at 100.0% (220 of 220 strings)

Translation: Element Android/Element Android Sdk
Translate-URL: https://translate.element.io/projects/element-android/element-sdk/ru/
2020-12-17 06:35:48 +00:00
Marcelo Filho
b1660c077e Translated using Weblate (Portuguese (Brazil))
Currently translated at 98.1% (216 of 220 strings)

Translation: Element Android/Element Android Sdk
Translate-URL: https://translate.element.io/projects/element-android/element-sdk/pt_BR/
2020-12-17 06:35:47 +00:00
Oskars G
38075b4e8d Translated using Weblate (Latvian)
Currently translated at 35.0% (77 of 220 strings)

Translation: Element Android/Element Android Sdk
Translate-URL: https://translate.element.io/projects/element-android/element-sdk/lv/
2020-12-17 06:35:47 +00:00
random
174ecb10d9 Translated using Weblate (Italian)
Currently translated at 100.0% (220 of 220 strings)

Translation: Element Android/Element Android Sdk
Translate-URL: https://translate.element.io/projects/element-android/element-sdk/it/
2020-12-17 06:35:47 +00:00
Priit Jõerüüt
5ef1fd62a7 Translated using Weblate (Estonian)
Currently translated at 100.0% (220 of 220 strings)

Translation: Element Android/Element Android Sdk
Translate-URL: https://translate.element.io/projects/element-android/element-sdk/et/
2020-12-17 06:35:46 +00:00
Jeff Huang
d095784bfc Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (2018 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/zh_Hant/
2020-12-17 06:35:46 +00:00
Ihor Hordiichuk
1ac1d32b3a Translated using Weblate (Ukrainian)
Currently translated at 47.7% (963 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/uk/
2020-12-17 06:35:44 +00:00
Besnik Bleta
518b207f63 Translated using Weblate (Albanian)
Currently translated at 99.6% (2010 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/sq/
2020-12-17 06:35:44 +00:00
Nikita Epifanov
16ba5d2416 Translated using Weblate (Russian)
Currently translated at 100.0% (2018 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/ru/
2020-12-17 06:35:42 +00:00
Marcelo Filho
ac6e7652bd Translated using Weblate (Portuguese (Brazil))
Currently translated at 99.1% (2000 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/pt_BR/
2020-12-17 06:35:40 +00:00
random
cc3e090855 Translated using Weblate (Italian)
Currently translated at 100.0% (2018 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/it/
2020-12-17 06:35:39 +00:00
Priit Jõerüüt
30e4fdebd7 Translated using Weblate (Estonian)
Currently translated at 100.0% (2018 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/et/
2020-12-17 06:35:37 +00:00
Benoit Marty
27e5626fcf Test has been passed! 2020-12-16 16:07:18 +01:00
Benoit Marty
8878cb41ee Fix issue with not clickable item 2020-12-16 16:04:57 +01:00
Benoit Marty
10575698de Avoid blink effect 2020-12-16 15:51:30 +01:00
Benoit Marty
451750f08a Improve code (items still not clickable) 2020-12-16 15:48:39 +01:00
Benoit Marty
6f04f4109d It seems we need to use findViewById sometimes 2020-12-16 14:35:30 +01:00
Benoit Marty
929d711149 Split long lines and cleanup 2020-12-16 14:33:44 +01:00
Benoit Marty
b52f8b1dbf Fix crash 2020-12-16 14:31:14 +01:00
Benoit Marty
aa0a851b35 Restore waiting view management 2020-12-16 13:32:49 +01:00
Benoit Marty
4ddc8e706d Fix issue with coordinator Layout 2020-12-16 13:23:42 +01:00
Benoit Marty
da2a0abf45 Provide CoordinatorLayout when available 2020-12-16 12:39:22 +01:00
Benoit Marty
53a0e0ce10 Remove useless @Inject 2020-12-16 12:22:28 +01:00
Benoit Marty
7f02c0596e Fix strange crash 2020-12-16 12:21:25 +01:00
Benoit Marty
e081c3b249 Add TODO 2020-12-16 12:09:23 +01:00
Benoit Marty
8db4da5473 Fix crash 2020-12-16 11:45:06 +01:00
Benoit Marty
d389581d96 Better binding 2020-12-16 11:18:25 +01:00
Benoit Marty
018574a21e Rename some view ids 2020-12-16 11:10:49 +01:00
Benoit Marty
9e3eb993ee Fix some crashes 2020-12-16 10:36:33 +01:00
Benoit Marty
6c64fb2169 Fix some crashes 2020-12-16 10:16:33 +01:00
Benoit Marty
2e70808bbd Fix some crashes 2020-12-16 04:16:34 +01:00
Benoit Marty
18bf9856fe Migrate to ViewBindings (#1072) - WIP 2020-12-16 03:57:19 +01:00
Benoit Marty
f09ee5016a Migrate to ViewBindings (#1072) - WIP 2020-12-16 03:41:02 +01:00
Benoit Marty
4d3c4b5afc Migrate to ViewBindings (#1072) - WIP 2020-12-16 03:38:07 +01:00
Benoit Marty
7de2494af2 Migrate to ViewBindings (#1072) - WIP 2020-12-16 03:25:17 +01:00
Benoit Marty
409d7e50bb Migrate to ViewBindings (#1072) - WIP 2020-12-16 02:59:03 +01:00
Benoit Marty
c1222737d6 Migrate to ViewBindings (#1072) - WIP 2020-12-16 02:49:22 +01:00
Benoit Marty
d02da1b97e Migrate to ViewBindings (#1072) - WIP 2020-12-16 02:39:58 +01:00
Benoit Marty
a8c6b1cdf7 Migrate to ViewBindings (#1072) - WIP 2020-12-16 02:33:52 +01:00
Benoit Marty
dba65dcd22 Migrate to ViewBindings (#1072) - WIP 2020-12-16 02:05:38 +01:00
Benoit Marty
706736273c Migrate to ViewBindings (#1072) - WIP 2020-12-16 00:46:52 +01:00
Benoit Marty
838340bbc8 Remove dependency to Butterknife 2020-12-15 20:33:55 +01:00
Benoit Marty
75ec9ba3d9 Reduce dependency on Butterknife: remove usage of @BindView 2020-12-15 20:32:26 +01:00
Benoit Marty
876359539f Reduce dependency on Butterknife: remove usage of @OnClick and @OnTextChange 2020-12-15 18:52:36 +01:00
Benoit Marty
6cdb192955 Version++ 2020-12-15 14:18:35 +01:00
Benoit Marty
2927f1ff1c Merge branch 'release/1.0.12' into develop 2020-12-15 14:16:15 +01:00
719 changed files with 15530 additions and 6969 deletions

View File

@@ -1,3 +1,73 @@
Changes in Element 1.0.15 (2020-02-03)
===================================================
Features ✨:
- Social Login support
Improvements 🙌:
- SSO support for cross signing (#1062)
- Deactivate account when logged in with SSO (#1264)
- SSO UIA doesn't work (#2754)
Bugfix 🐛:
- Fix clear cache issue: sometimes, after a clear cache, there is still a token, so the init sync service is not started.
- Sidebar too large in horizontal orientation or tablets (#475)
- UrlPreview should be updated when the url is edited and changed (#2678)
- When receiving a new pepper from identity server, use it on the next hash lookup (#2708)
- Crashes reported by PlayStore (new in 1.0.14) (#2707)
- Widgets: Support $matrix_widget_id parameter (#2748)
- Data for Worker overload (#2721)
- Fix multiple tasks
SDK API changes ⚠️:
- Increase targetSdkVersion to 30 (#2600)
Build 🧱:
- Compile with Android SDK 30 (Android 11)
Other changes:
- Update Dagger to 2.31 version so we can use the embedded AssistedInject feature
Changes in Element 1.0.14 (2020-01-15)
===================================================
Features ✨:
- Enable url previews for notices (#2562)
- Edit room permissions (#2471)
Improvements 🙌:
- Add System theme option and set as default (#904, #2387)
- Store megolm outbound session to improve send time of first message after app launch.
- Warn user when they are leaving a not public room (#1460)
- Option to disable emoji keyboard (#2563)
Bugfix 🐛:
- Unspecced msgType field in m.sticker (#2580)
- Wait for all room members to be known before sending a message to a e2e room (#2518)
- Url previews sometimes attached to wrong message (#2561)
- Room Topic not displayed correctly after visiting a link (#2551)
- Hiding membership events works the exact opposite (#2603)
- Tapping drawer having more than 1 room in notifications gives "malformed link" error (#2605)
- Sent image not displayed when opened immediately after sending (#409)
- Initial sync is not retried correctly when there is some network error. (#2632)
- Fix switch theme issue, and white field issue (#2599, #2528)
- Fix request too large Uri error when joining a room
Translations 🗣:
- New language supported: Hebrew
Build 🧱:
- Remove dependency to org.greenrobot.eventbus library
Other changes:
- Migrate to ViewBindings (#1072)
Changes in Element 1.0.13 (2020-12-18)
===================================================
Bugfix 🐛:
- Fix MSC2858 implementation details (#2540)
Changes in Element 1.0.12 (2020-12-15)
===================================================

View File

@@ -16,7 +16,6 @@
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
buildscript {
repositories {
@@ -33,11 +32,11 @@ buildscript {
}
android {
compileSdkVersion 29
compileSdkVersion 30
defaultConfig {
minSdkVersion 21
targetSdkVersion 29
targetSdkVersion 30
versionCode 1
versionName "1.0"
}
@@ -55,6 +54,10 @@ android {
kotlinOptions {
jvmTarget = '1.8'
}
buildFeatures {
viewBinding true
}
}
dependencies {

View File

@@ -17,19 +17,17 @@
package im.vector.lib.attachmentviewer
import android.view.View
import android.widget.ImageView
import android.widget.ProgressBar
import im.vector.lib.attachmentviewer.databinding.ItemAnimatedImageAttachmentBinding
class AnimatedImageViewHolder constructor(itemView: View) :
BaseViewHolder(itemView) {
val touchImageView: ImageView = itemView.findViewById(R.id.imageView)
val imageLoaderProgress: ProgressBar = itemView.findViewById(R.id.imageLoaderProgress)
val views = ItemAnimatedImageAttachmentBinding.bind(itemView)
internal val target = DefaultImageLoaderTarget(this, this.touchImageView)
internal val target = DefaultImageLoaderTarget(this, views.imageView)
override fun onRecycled() {
super.onRecycled()
touchImageView.setImageDrawable(null)
views.imageView.setImageDrawable(null)
}
}

View File

@@ -18,58 +18,70 @@
package im.vector.lib.attachmentviewer
import android.graphics.Color
import android.os.Build
import android.os.Bundle
import android.view.GestureDetector
import android.view.MotionEvent
import android.view.ScaleGestureDetector
import android.view.View
import android.view.ViewGroup
import android.view.WindowInsets
import android.view.WindowInsetsController
import android.view.WindowManager
import android.widget.ImageView
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.core.view.GestureDetectorCompat
import androidx.core.view.ViewCompat
import androidx.core.view.isVisible
import androidx.core.view.updatePadding
import androidx.transition.TransitionManager
import androidx.viewpager2.widget.ViewPager2
import kotlinx.android.synthetic.main.activity_attachment_viewer.*
import im.vector.lib.attachmentviewer.databinding.ActivityAttachmentViewerBinding
import java.lang.ref.WeakReference
import kotlin.math.abs
abstract class AttachmentViewerActivity : AppCompatActivity(), AttachmentEventListener {
lateinit var pager2: ViewPager2
lateinit var imageTransitionView: ImageView
lateinit var transitionImageContainer: ViewGroup
protected val pager2: ViewPager2
get() = views.attachmentPager
protected val imageTransitionView: ImageView
get() = views.transitionImageView
protected val transitionImageContainer: ViewGroup
get() = views.transitionImageContainer
var topInset = 0
var bottomInset = 0
var systemUiVisibility = true
private var topInset = 0
private var bottomInset = 0
private var systemUiVisibility = true
private var overlayView: View? = null
set(value) {
if (value == overlayView) return
overlayView?.let { rootContainer.removeView(it) }
rootContainer.addView(value)
overlayView?.let { views.rootContainer.removeView(it) }
views.rootContainer.addView(value)
value?.updatePadding(top = topInset, bottom = bottomInset)
field = value
}
private lateinit var views: ActivityAttachmentViewerBinding
private lateinit var swipeDismissHandler: SwipeToDismissHandler
private lateinit var directionDetector: SwipeDirectionDetector
private lateinit var scaleDetector: ScaleGestureDetector
private lateinit var gestureDetector: GestureDetectorCompat
var currentPosition = 0
private set
private var swipeDirection: SwipeDirection? = null
private fun isScaled() = attachmentsAdapter.isScaled(currentPosition)
private val attachmentsAdapter = AttachmentsAdapter()
private var wasScaled: Boolean = false
private var isSwipeToDismissAllowed: Boolean = true
private lateinit var attachmentsAdapter: AttachmentsAdapter
private var isOverlayWasClicked = false
// private val shouldDismissToBottom: Boolean
@@ -86,26 +98,16 @@ abstract class AttachmentViewerActivity : AppCompatActivity(), AttachmentEventLi
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// This is important for the dispatchTouchEvent, if not we must correct
// the touch coordinates
window.decorView.systemUiVisibility = (
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
or View.SYSTEM_UI_FLAG_IMMERSIVE)
window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION)
setDecorViewFullScreen()
setContentView(R.layout.activity_attachment_viewer)
attachmentPager.orientation = ViewPager2.ORIENTATION_HORIZONTAL
attachmentsAdapter = AttachmentsAdapter()
attachmentPager.adapter = attachmentsAdapter
imageTransitionView = transitionImageView
transitionImageContainer = findViewById(R.id.transitionImageContainer)
pager2 = attachmentPager
views = ActivityAttachmentViewerBinding.inflate(layoutInflater)
setContentView(views.root)
views.attachmentPager.orientation = ViewPager2.ORIENTATION_HORIZONTAL
views.attachmentPager.adapter = attachmentsAdapter
directionDetector = createSwipeDirectionDetector()
gestureDetector = createGestureDetector()
attachmentPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
views.attachmentPager.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
override fun onPageScrollStateChanged(state: Int) {
isImagePagerIdle = state == ViewPager2.SCROLL_STATE_IDLE
}
@@ -116,12 +118,12 @@ abstract class AttachmentViewerActivity : AppCompatActivity(), AttachmentEventLi
})
swipeDismissHandler = createSwipeToDismissHandler()
rootContainer.setOnTouchListener(swipeDismissHandler)
rootContainer.viewTreeObserver.addOnGlobalLayoutListener { swipeDismissHandler.translationLimit = dismissContainer.height / 4 }
views.rootContainer.setOnTouchListener(swipeDismissHandler)
views.rootContainer.viewTreeObserver.addOnGlobalLayoutListener { swipeDismissHandler.translationLimit = views.dismissContainer.height / 4 }
scaleDetector = createScaleGestureDetector()
ViewCompat.setOnApplyWindowInsetsListener(rootContainer) { _, insets ->
ViewCompat.setOnApplyWindowInsetsListener(views.rootContainer) { _, insets ->
overlayView?.updatePadding(top = insets.systemWindowInsetTop, bottom = insets.systemWindowInsetBottom)
topInset = insets.systemWindowInsetTop
bottomInset = insets.systemWindowInsetBottom
@@ -129,6 +131,29 @@ abstract class AttachmentViewerActivity : AppCompatActivity(), AttachmentEventLi
}
}
@Suppress("DEPRECATION")
private fun setDecorViewFullScreen() {
// This is important for the dispatchTouchEvent, if not we must correct
// the touch coordinates
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
// New API instead of SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN and SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
window.setDecorFitsSystemWindows(false)
// New API instead of SYSTEM_UI_FLAG_IMMERSIVE
window.decorView.windowInsetsController?.systemBarsBehavior = WindowInsetsController.BEHAVIOR_SHOW_BARS_BY_SWIPE
// New API instead of FLAG_TRANSLUCENT_STATUS
window.statusBarColor = ContextCompat.getColor(this, R.color.half_transparent_status_bar)
// new API instead of FLAG_TRANSLUCENT_NAVIGATION
window.navigationBarColor = ContextCompat.getColor(this, R.color.half_transparent_status_bar)
} else {
window.decorView.systemUiVisibility = (
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
or View.SYSTEM_UI_FLAG_IMMERSIVE)
window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION)
}
}
fun onSelectedPositionChanged(position: Int) {
attachmentsAdapter.recyclerView?.findViewHolderForAdapterPosition(currentPosition)?.let {
(it as? BaseViewHolder)?.onSelected(false)
@@ -170,7 +195,7 @@ abstract class AttachmentViewerActivity : AppCompatActivity(), AttachmentEventLi
if (swipeDirection == null && (scaleDetector.isInProgress || ev.pointerCount > 1 || wasScaled)) {
wasScaled = true
// Log.v("ATTACHEMENTS", "dispatch to pager")
return attachmentPager.dispatchTouchEvent(ev)
return views.attachmentPager.dispatchTouchEvent(ev)
}
// Log.v("ATTACHEMENTS", "is current item scaled ${isScaled()}")
@@ -196,16 +221,16 @@ abstract class AttachmentViewerActivity : AppCompatActivity(), AttachmentEventLi
private fun handleEventActionDown(event: MotionEvent) {
swipeDirection = null
wasScaled = false
attachmentPager.dispatchTouchEvent(event)
views.attachmentPager.dispatchTouchEvent(event)
swipeDismissHandler.onTouch(rootContainer, event)
swipeDismissHandler.onTouch(views.rootContainer, event)
isOverlayWasClicked = dispatchOverlayTouch(event)
}
private fun handleEventActionUp(event: MotionEvent) {
// wasDoubleTapped = false
swipeDismissHandler.onTouch(rootContainer, event)
attachmentPager.dispatchTouchEvent(event)
swipeDismissHandler.onTouch(views.rootContainer, event)
views.attachmentPager.dispatchTouchEvent(event)
isOverlayWasClicked = dispatchOverlayTouch(event)
}
@@ -220,12 +245,12 @@ abstract class AttachmentViewerActivity : AppCompatActivity(), AttachmentEventLi
private fun toggleOverlayViewVisibility() {
if (systemUiVisibility) {
// we hide
TransitionManager.beginDelayedTransition(rootContainer)
TransitionManager.beginDelayedTransition(views.rootContainer)
hideSystemUI()
overlayView?.isVisible = false
} else {
// we show
TransitionManager.beginDelayedTransition(rootContainer)
TransitionManager.beginDelayedTransition(views.rootContainer)
showSystemUI()
overlayView?.isVisible = true
}
@@ -238,11 +263,11 @@ abstract class AttachmentViewerActivity : AppCompatActivity(), AttachmentEventLi
return when (swipeDirection) {
SwipeDirection.Up, SwipeDirection.Down -> {
if (isSwipeToDismissAllowed && !wasScaled && isImagePagerIdle) {
swipeDismissHandler.onTouch(rootContainer, event)
swipeDismissHandler.onTouch(views.rootContainer, event)
} else true
}
SwipeDirection.Left, SwipeDirection.Right -> {
attachmentPager.dispatchTouchEvent(event)
views.attachmentPager.dispatchTouchEvent(event)
}
else -> true
}
@@ -250,8 +275,8 @@ abstract class AttachmentViewerActivity : AppCompatActivity(), AttachmentEventLi
private fun handleSwipeViewMove(translationY: Float, translationLimit: Int) {
val alpha = calculateTranslationAlpha(translationY, translationLimit)
backgroundView.alpha = alpha
dismissContainer.alpha = alpha
views.backgroundView.alpha = alpha
views.dismissContainer.alpha = alpha
overlayView?.alpha = alpha
}
@@ -265,7 +290,7 @@ abstract class AttachmentViewerActivity : AppCompatActivity(), AttachmentEventLi
private fun createSwipeToDismissHandler()
: SwipeToDismissHandler = SwipeToDismissHandler(
swipeView = dismissContainer,
swipeView = views.dismissContainer,
shouldAnimateDismiss = { shouldAnimateDismiss() },
onDismiss = { animateClose() },
onSwipeViewMove = ::handleSwipeViewMove)
@@ -308,28 +333,48 @@ abstract class AttachmentViewerActivity : AppCompatActivity(), AttachmentEventLi
?.handleCommand(commands)
}
@Suppress("DEPRECATION")
private fun hideSystemUI() {
systemUiVisibility = false
// Enables regular immersive mode.
// For "lean back" mode, remove SYSTEM_UI_FLAG_IMMERSIVE.
// Or for "sticky immersive," replace it with SYSTEM_UI_FLAG_IMMERSIVE_STICKY
window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_IMMERSIVE
// Set the content to appear under the system bars so that the
// content doesn't resize when the system bars hide and show.
or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
// Hide the nav bar and status bar
or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_FULLSCREEN)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
// New API instead of SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN and SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
window.setDecorFitsSystemWindows(false)
// new API instead of SYSTEM_UI_FLAG_HIDE_NAVIGATION
window.decorView.windowInsetsController?.hide(WindowInsets.Type.navigationBars())
// New API instead of SYSTEM_UI_FLAG_IMMERSIVE
window.decorView.windowInsetsController?.systemBarsBehavior = WindowInsetsController.BEHAVIOR_SHOW_BARS_BY_SWIPE
// New API instead of FLAG_TRANSLUCENT_STATUS
window.statusBarColor = ContextCompat.getColor(this, R.color.half_transparent_status_bar)
// New API instead of FLAG_TRANSLUCENT_NAVIGATION
window.navigationBarColor = ContextCompat.getColor(this, R.color.half_transparent_status_bar)
} else {
window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_IMMERSIVE
// Set the content to appear under the system bars so that the
// content doesn't resize when the system bars hide and show.
or View.SYSTEM_UI_FLAG_LAYOUT_STABLE
or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
// Hide the nav bar and status bar
or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_FULLSCREEN)
}
}
// Shows the system bars by removing all the flags
// except for the ones that make the content appear under the system bars.
@Suppress("DEPRECATION")
private fun showSystemUI() {
systemUiVisibility = true
window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE
or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
// New API instead of SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN and SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
window.setDecorFitsSystemWindows(false)
} else {
window.decorView.systemUiVisibility = (View.SYSTEM_UI_FLAG_LAYOUT_STABLE
or View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN)
}
}
}

View File

@@ -98,7 +98,7 @@ class AttachmentsAdapter : RecyclerView.Adapter<BaseViewHolder>() {
fun isScaled(position: Int): Boolean {
val holder = recyclerView?.findViewHolderForAdapterPosition(position)
if (holder is ZoomableImageViewHolder) {
return holder.touchImageView.attacher.scale > 1f
return holder.views.touchImageView.attacher.scale > 1f
}
return false
}

View File

@@ -44,29 +44,29 @@ internal class DefaultImageLoaderTarget(val holder: AnimatedImageViewHolder, pri
override fun onResourceLoading(uid: String, placeholder: Drawable?) {
if (holder.boundResourceUid != uid) return
holder.imageLoaderProgress.isVisible = true
holder.views.imageLoaderProgress.isVisible = true
}
override fun onLoadFailed(uid: String, errorDrawable: Drawable?) {
if (holder.boundResourceUid != uid) return
holder.imageLoaderProgress.isVisible = false
holder.touchImageView.setImageDrawable(errorDrawable)
holder.views.imageLoaderProgress.isVisible = false
holder.views.imageView.setImageDrawable(errorDrawable)
}
override fun onResourceCleared(uid: String, placeholder: Drawable?) {
if (holder.boundResourceUid != uid) return
holder.touchImageView.setImageDrawable(placeholder)
holder.views.imageView.setImageDrawable(placeholder)
}
override fun onResourceReady(uid: String, resource: Drawable) {
if (holder.boundResourceUid != uid) return
holder.imageLoaderProgress.isVisible = false
holder.views.imageLoaderProgress.isVisible = false
// Glide mess up the view size :/
holder.touchImageView.updateLayoutParams {
holder.views.imageView.updateLayoutParams {
width = LinearLayout.LayoutParams.MATCH_PARENT
height = LinearLayout.LayoutParams.MATCH_PARENT
}
holder.touchImageView.setImageDrawable(resource)
holder.views.imageView.setImageDrawable(resource)
if (resource is Animatable) {
resource.start()
}
@@ -77,30 +77,30 @@ internal class DefaultImageLoaderTarget(val holder: AnimatedImageViewHolder, pri
override fun onResourceLoading(uid: String, placeholder: Drawable?) {
if (holder.boundResourceUid != uid) return
holder.imageLoaderProgress.isVisible = true
holder.touchImageView.setImageDrawable(placeholder)
holder.views.imageLoaderProgress.isVisible = true
holder.views.touchImageView.setImageDrawable(placeholder)
}
override fun onLoadFailed(uid: String, errorDrawable: Drawable?) {
if (holder.boundResourceUid != uid) return
holder.imageLoaderProgress.isVisible = false
holder.touchImageView.setImageDrawable(errorDrawable)
holder.views.imageLoaderProgress.isVisible = false
holder.views.touchImageView.setImageDrawable(errorDrawable)
}
override fun onResourceCleared(uid: String, placeholder: Drawable?) {
if (holder.boundResourceUid != uid) return
holder.touchImageView.setImageDrawable(placeholder)
holder.views.touchImageView.setImageDrawable(placeholder)
}
override fun onResourceReady(uid: String, resource: Drawable) {
if (holder.boundResourceUid != uid) return
holder.imageLoaderProgress.isVisible = false
holder.views.imageLoaderProgress.isVisible = false
// Glide mess up the view size :/
holder.touchImageView.updateLayoutParams {
holder.views.touchImageView.updateLayoutParams {
width = LinearLayout.LayoutParams.MATCH_PARENT
height = LinearLayout.LayoutParams.MATCH_PARENT
}
holder.touchImageView.setImageDrawable(resource)
holder.views.touchImageView.setImageDrawable(resource)
}
}
}

View File

@@ -49,19 +49,19 @@ internal class DefaultVideoLoaderTarget(val holder: VideoViewHolder, private val
override fun onThumbnailResourceCleared(uid: String, placeholder: Drawable?) {
if (holder.boundResourceUid != uid) return
holder.thumbnailImage.setImageDrawable(placeholder)
holder.views.videoThumbnailImage.setImageDrawable(placeholder)
}
override fun onThumbnailResourceReady(uid: String, resource: Drawable) {
if (holder.boundResourceUid != uid) return
holder.thumbnailImage.setImageDrawable(resource)
holder.views.videoThumbnailImage.setImageDrawable(resource)
}
override fun onVideoFileLoading(uid: String) {
if (holder.boundResourceUid != uid) return
holder.thumbnailImage.isVisible = true
holder.loaderProgressBar.isVisible = true
holder.videoView.isVisible = false
holder.views.videoThumbnailImage.isVisible = true
holder.views.videoLoaderProgress.isVisible = true
holder.views.videoView.isVisible = false
}
override fun onVideoFileLoadFailed(uid: String) {
@@ -82,8 +82,8 @@ internal class DefaultVideoLoaderTarget(val holder: VideoViewHolder, private val
}
private fun arrangeForVideoReady() {
holder.thumbnailImage.isVisible = false
holder.loaderProgressBar.isVisible = false
holder.videoView.isVisible = true
holder.views.videoThumbnailImage.isVisible = false
holder.views.videoLoaderProgress.isVisible = false
holder.views.videoView.isVisible = true
}
}

View File

@@ -18,11 +18,8 @@ package im.vector.lib.attachmentviewer
import android.util.Log
import android.view.View
import android.widget.ImageView
import android.widget.ProgressBar
import android.widget.TextView
import android.widget.VideoView
import androidx.core.view.isVisible
import im.vector.lib.attachmentviewer.databinding.ItemVideoAttachmentBinding
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
@@ -44,13 +41,9 @@ class VideoViewHolder constructor(itemView: View) :
var eventListener: WeakReference<AttachmentEventListener>? = null
val thumbnailImage: ImageView = itemView.findViewById(R.id.videoThumbnailImage)
val videoView: VideoView = itemView.findViewById(R.id.videoView)
val loaderProgressBar: ProgressBar = itemView.findViewById(R.id.videoLoaderProgress)
val videoControlIcon: ImageView = itemView.findViewById(R.id.videoControlIcon)
val errorTextView: TextView = itemView.findViewById(R.id.videoMediaViewerErrorView)
val views = ItemVideoAttachmentBinding.bind(itemView)
internal val target = DefaultVideoLoaderTarget(this, thumbnailImage)
internal val target = DefaultVideoLoaderTarget(this, views.videoThumbnailImage)
override fun onRecycled() {
super.onRecycled()
@@ -77,12 +70,12 @@ class VideoViewHolder constructor(itemView: View) :
}
override fun entersBackground() {
if (videoView.isPlaying) {
progress = videoView.currentPosition
if (views.videoView.isPlaying) {
progress = views.videoView.currentPosition
progressDisposable?.dispose()
progressDisposable = null
videoView.stopPlayback()
videoView.pause()
views.videoView.stopPlayback()
views.videoView.pause()
}
}
@@ -92,9 +85,9 @@ class VideoViewHolder constructor(itemView: View) :
override fun onSelected(selected: Boolean) {
if (!selected) {
if (videoView.isPlaying) {
progress = videoView.currentPosition
videoView.stopPlayback()
if (views.videoView.isPlaying) {
progress = views.videoView.currentPosition
views.videoView.stopPlayback()
} else {
progress = 0
}
@@ -109,34 +102,34 @@ class VideoViewHolder constructor(itemView: View) :
}
private fun startPlaying() {
thumbnailImage.isVisible = false
loaderProgressBar.isVisible = false
videoView.isVisible = true
views.videoThumbnailImage.isVisible = false
views.videoLoaderProgress.isVisible = false
views.videoView.isVisible = true
videoView.setOnPreparedListener {
views.videoView.setOnPreparedListener {
progressDisposable?.dispose()
progressDisposable = Observable.interval(100, TimeUnit.MILLISECONDS)
.timeInterval()
.observeOn(AndroidSchedulers.mainThread())
.subscribe {
val duration = videoView.duration
val progress = videoView.currentPosition
val isPlaying = videoView.isPlaying
val duration = views.videoView.duration
val progress = views.videoView.currentPosition
val isPlaying = views.videoView.isPlaying
// Log.v("FOO", "isPlaying $isPlaying $progress/$duration")
eventListener?.get()?.onEvent(AttachmentEvents.VideoEvent(isPlaying, progress, duration))
}
}
try {
videoView.setVideoPath(mVideoPath)
views.videoView.setVideoPath(mVideoPath)
} catch (failure: Throwable) {
// Couldn't open
Log.v(VideoViewHolder::class.java.name, "Failed to start video")
}
if (!wasPaused) {
videoView.start()
views.videoView.start()
if (progress > 0) {
videoView.seekTo(progress)
views.videoView.seekTo(progress)
}
}
}
@@ -146,17 +139,17 @@ class VideoViewHolder constructor(itemView: View) :
when (commands) {
AttachmentCommands.StartVideo -> {
wasPaused = false
videoView.start()
views.videoView.start()
}
AttachmentCommands.PauseVideo -> {
wasPaused = true
videoView.pause()
views.videoView.pause()
}
is AttachmentCommands.SeekTo -> {
val duration = videoView.duration
val duration = views.videoView.duration
if (duration > 0) {
val seekDuration = duration * (commands.percentProgress / 100f)
videoView.seekTo(seekDuration.toInt())
views.videoView.seekTo(seekDuration.toInt())
}
}
}

View File

@@ -17,31 +17,29 @@
package im.vector.lib.attachmentviewer
import android.view.View
import android.widget.ProgressBar
import com.github.chrisbanes.photoview.PhotoView
import im.vector.lib.attachmentviewer.databinding.ItemImageAttachmentBinding
class ZoomableImageViewHolder constructor(itemView: View) :
BaseViewHolder(itemView) {
val touchImageView: PhotoView = itemView.findViewById(R.id.touchImageView)
val imageLoaderProgress: ProgressBar = itemView.findViewById(R.id.imageLoaderProgress)
val views = ItemImageAttachmentBinding.bind(itemView)
init {
touchImageView.setAllowParentInterceptOnEdge(false)
touchImageView.setOnScaleChangeListener { scaleFactor, _, _ ->
views.touchImageView.setAllowParentInterceptOnEdge(false)
views.touchImageView.setOnScaleChangeListener { scaleFactor, _, _ ->
// Log.v("ATTACHEMENTS", "scaleFactor $scaleFactor")
// It's a bit annoying but when you pitch down the scaling
// is not exactly one :/
touchImageView.setAllowParentInterceptOnEdge(scaleFactor <= 1.0008f)
views.touchImageView.setAllowParentInterceptOnEdge(scaleFactor <= 1.0008f)
}
touchImageView.setScale(1.0f, true)
touchImageView.setAllowParentInterceptOnEdge(true)
views.touchImageView.setScale(1.0f, true)
views.touchImageView.setAllowParentInterceptOnEdge(true)
}
internal val target = DefaultImageLoaderTarget.ZoomableImageTarget(this, touchImageView)
internal val target = DefaultImageLoaderTarget.ZoomableImageTarget(this, views.touchImageView)
override fun onRecycled() {
super.onRecycled()
touchImageView.setImageDrawable(null)
views.touchImageView.setImageDrawable(null)
}
}

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<resources>
<color name="half_transparent_status_bar">#80000000</color>
</resources>

View File

@@ -165,7 +165,7 @@ In this case, the user can click on "Sign in with SSO" and the native web browse
> https://homeserver.with.sso/_matrix/client/r0/login/sso/redirect?redirectUrl=element%3A%2F%element
The parameter `redirectUrl` is set to `element://element`.
The parameter `redirectUrl` is set to `element://connect`.
ChromeCustomTabs are an intermediate way to display a WebPage, between a WebView and using the external browser. More info can be found [here](https://developer.chrome.com/multidevice/android/customtabs)
@@ -175,7 +175,7 @@ During the process, user may be asked to validate an email by clicking on a link
Once the process is finished, the web page will call the `redirectUrl` with an extra parameter `loginToken`
> element://element?loginToken=MDAxOWxvY2F0aW9uIG1vemlsbGEub3JnCjAwMTNpZGVudGlmaWVy
> element://connect?loginToken=MDAxOWxvY2F0aW9uIG1vemlsbGEub3JnCjAwMTNpZGVudGlmaWVy
This navigation is intercepted by Element by the `LoginActivity`, which will then ask the homeserver to convert this `loginToken` to an access token

View File

@@ -27,7 +27,6 @@ $ source env/bin/activate
Every time you want to launch these test homeservers, type:
```shell script
$ virtualenv -p python3 env
$ source env/bin/activate
(env) $ demo/start.sh --no-rate-limit
```

View File

@@ -1 +1,2 @@
// TODO
Diese neue Version enthält hauptsächlich Fehlerkorrekturen und Verbesserungen. Nachrichten verschicken geht jetzt viel schneller.
Vollständige Versionshinweise: https://github.com/vector-im/element-android/releases/tag/v1.0.10

View File

@@ -0,0 +1,2 @@
Diese neue Version enthält hauptsächlich Verbesserungen der Benutzer*innenoberfläche und der Handhabung. Du kannst jetzt ganz schnell Freund*innen einladen und DMs erstellen, indem du schlicht einen QR-Code scannst.
Vollständige Versionshinweise: https://github.com/vector-im/element-android/releases/tag/v1.0.11

View File

@@ -0,0 +1,2 @@
Main changes in this version: URL Preview, new Emoji keyboard, new room settings capabilities, and snow for Christmas!
Full changelog: https://github.com/vector-im/element-android/releases/tag/v1.0.13

View File

@@ -0,0 +1,2 @@
Main changes in this version: Edit room permissions, automatic light/dark theme, and a bunch of bug fixes.
Full changelog: https://github.com/vector-im/element-android/releases/tag/v1.0.14

View File

@@ -0,0 +1,2 @@
Main changes in this version: Social Login support.
Full changelog: https://github.com/vector-im/element-android/releases/tag/v1.0.15

View File

@@ -0,0 +1,2 @@
Selles uues versioonis leidub põhiliselt veaparandusi ja pisikohendusi. Sõnumite saatmine on nüüd märkatavalt kiirem.
Kogu ingliskeelne muudatuste logi: https://github.com/vector-im/element-android/releases/tag/v1.0.10

View File

@@ -0,0 +1,2 @@
Uues versioonis leidub põhiliselt kasutajaliidese ning kasutajakogemuse parandusi. Nüüd saad sõpradele kutseid saata ning otsevestlusi alustada QR-koodi lugemise abil.
Kõik muudatused: https://github.com/vector-im/element-android/releases/tag/v1.0.11

View File

@@ -1 +1,2 @@
// برای انجام
این نگارش جدید به طور عمده شامل رفع اشکال‌ها و بهبودها است. ارسال پیام اکنون بسیار سریعتر است.
گزارش دگرگونی کامل: https://github.com/vector-im/element-android/releases/tag/v1.0.10

View File

@@ -0,0 +1,2 @@
این نگارش جدید به طور عمده شامل رابط کاربری و بهبود تجربه کاربر است. اکنون می‌توانید با پویش کدهای QR دوستانتان را دعوت کرده و بسیار سریع پیام مستقیم ایجاد کنید.
گزارش دگرگونی کامل: https://github.com/vector-im/element-android/releases/tag/v1.0.11

View File

@@ -1 +1 @@
گپ و تماس نامتمرکز امن. داده‌هایتان را از شرکت‌ها امن نگه دارید.
گپ و تماس نامتمرکز امن. داده‌هایتان را از اشخاص سوم امن نگه دارید.

View File

@@ -1 +1 @@
المنت (ریوت سابق)
Element (پیشتر Riot.im)

View File

@@ -0,0 +1,2 @@
Tämä versio sisältää pääosin käyttöliittymä- ja käyttökokemusparannuksia. Voit nyt kutsua kavereita ja luoda yksityisviestejä nopeasti QR-koodeja lukemalla.
Täysi muutosloki: https://github.com/vector-im/element-android/releases/tag/v1.0.11

View File

@@ -1,30 +1,30 @@
Element on uudenlainen viestinsovellus, joka:
1. Antaa sinun päättää yksityisyydestäsi.
1. Antaa sinun päättää yksityisyydestäsi
2. Antaa sinun kommunikoida kenen tahansa kanssa Matrix-verkossa ja jopa sen ulkopuolella siltaamalla sovelluksiin, kuten Slack
3. Suojaa sinua mainonnalta, tietojen keräämiseltä ja suljetuilta alustoilta
4. Suojaa sinut päästä päähän -salauksella sekä ristiin varmentamisella muiden todentamiseksi
Element eroaa täysin muista viestintäsovelluksista, koska se on hajautettu ja avointa lähdekoodia.
Element antaa sinun isännöidä itse - valita isännän - jotta sinulla on yksityisyys ja voit hallita tietojasi sekä keskustelujasi. Se antaa sinulle pääsyn avoimeen verkkoon; joten et ole jumissa Elementin käyttäjissä.
Element antaa sinun isännöidä itse - tai valita palveluntarjoajan - jotta sinulla on yksityisyys ja voit hallita tietojasi sekä keskustelujasi. Se antaa sinulle pääsyn avoimeen verkkoon, joten et jää juttelemaan vain toisten Elementin käyttäjien kanssa. Se on myös hyvin turvallinen.
Element pystyy tekemään kaiken tämän, koska se toimii Matrixilla - avoimella, hajautetun viestinnän standardilla.
Element antaa sinulle hallinnan antamalla sinun valita, kuka isännöi keskustelujasi. Element-sovelluksessa voit valita isännän eri tavoin:
Element antaa sinulle päätösvallan antamalla sinun valita, kuka isännöi keskustelujasi. Element-sovelluksessa voit valita isännän eri tavoin:
1. Hanki ilmainen tili Matrix-kehittäjien ylläpitämällä matrix.org-palvelimella tai valitse tuhansista vapaaehtoisten ylläpitämistä julkisista palvelimista.
2. Isännöi tiliäsi itse suorittamalla palvelinta omalla laitteellasi
3. Luo tili mukautetulla palvelimella yksinkertaisesti tilaamalla Element Matrix Services -palvelu
2. Isännöi tiliäsi itse ylläpitämällä palvelinta omalla laitteellasi
3. Luo tili sinua varten tehdyllä palvelimella tilaamalla Element Matrix Services -palvelu
<b>Miksi valita Element?</b>
<b>OMAT TIEDOT</b>: Sinä päätät, missä tietosi ja viestisi säilytetään. Hallitset sitä itse, ei jokin MEGAYHTIÖ, joka tutkii tietojasi tai antaa niitä kolmansille osapuolille.
<b>OMAT TIEDOT</b>: Sinä päätät, missä tietosi ja viestisi säilytetään. Sinä määräät, ei jokin jättiyhtiö, joka tutkii tietojasi tai antaa niitä kolmansille osapuolille.
<b>AVOIN KOMMUNIKOINYI JA YHTEISTYÖ</b>: Voit keskustella kaikkien muiden Matrix-verkon käyttäjien kanssa, riippumatta siitä käyttävätkö he Elementiä tai muuta Matrix-sovellusta, ja vaikka he käyttäisivät eri viestijärjestelmiä, kuten Slack, IRC tai XMPP.
<b>AVOINTA VIESTINTÄÄ JA YHTEISTYÖ</b>: Voit keskustella kaikkien muiden Matrix-verkon käyttäjien kanssa, riippumatta siitä käyttävätkö he Elementiä tai muuta Matrix-sovellusta, ja vaikka he käyttäisivät eri viestijärjestelmiä, kuten Slack, IRC tai XMPP.
<b>ERITTÄIN TURVALLINEN</b>: Vahva päästä päähän -salaus (vain keskustelussa olevat voivat purkaa viestien salauksen), ja ristiin varmentaminen keskustelun osallistujien laitteiden tarkistamiseksi.
<b>TÄYDELLISTÄ VIESTINTÄÄ</b>: Viestit, ääni- ja videopuhelut, tiedostojen jakaminen, näytön jakaminen ja koko joukko integraatioita, botteja ja widgettejä. Rakenna huoneita, yhteisöjä, pidä yhteyttä ja tee asioita.
<b>KATTAVAA VIESTINTÄÄ</b>: Viestit, ääni- ja videopuhelut, tiedostojen jakaminen, näytön jakaminen ja koko joukko integraatioita, botteja ja sovelmia. Rakenna huoneita ja yhteisöjä, pidä yhteyttä ja hoida asiasi.
<b>MISSÄ TAHANSA OLETKIN</b>: Pidä yhteyttä missä tahansa, täysin synkronoidun viestihistorian kautta kaikilla laitteillasi ja verkossa osoitteessa https://app.element.io.

View File

@@ -1 +1 @@
Turvallista, hajautettua, keskusteluja ja VoIP-puheluita. Pidä tietosi turvassa.
Turvallista, hajautettua keskustelua ja VoIP-puheluita. Pidä tietosi turvassa.

View File

@@ -0,0 +1,2 @@
Cette nouvelle version contient principalement des corrections de bogues et des améliorations. Envoyer un message est maintenant plus rapide.
Liste complète des changements : https://github.com/vector-im/element-android/releases/tag/v1.0.10

View File

@@ -0,0 +1,2 @@
Ez az új verzió főképp hibajavításokat, és teljesítménybeli fejlesztéseket tartalmaz. Most már sokkal gyorsabb az üzenetek elküldése.
A változtatások teljes listája itt található: https://github.com/vector-im/element-android/releases/tag/v1.0.10

View File

@@ -0,0 +1,2 @@
Ez az új verzió főleg a felhasználói felülettel és a felhasználói élménnyel kapcsolatos javításokat tartalmaz. Mostantól már sokkal gyorsabban hívhatsz meg új ismerősöket a QR kód beolvasás által.
A változtatások teljes listája itt található: https://github.com/vector-im/element-android/releases/tag/v1.0.11

View File

@@ -17,7 +17,7 @@ Az Element a te kezedbe adja az irányítást azáltal, hogy eldöntheted, ki t
2. A saját számítógépeden is futtathatsz szervert
3. Előfizethetsz egy saját szerverre az Element Matrix Szolgáltatások platformon
<b>Miért válaszd az Element-et?</b>
<b>Miért az Element-et választani?</b>
<b>ADATAID MEGVÉDÉSE</b>: Eldöntheted, hol tárold az adataid és üzeneteid. A te tulajdonodban van, nem valami megacégnél, ami bányássza az adataid, vagy továbbadja másoknak.

View File

@@ -0,0 +1,2 @@
Questa nuova versione contiene principalmente miglioramenti di interfaccia ed esperienza utente. Ora puoi invitare amici e iniziare messaggi diretti rapidamente tramite codici QR.
Cronologia completa: https://github.com/vector-im/element-android/releases/tag/v1.0.11

View File

@@ -0,0 +1,2 @@
Denne nye versjonen inneholder hovedsakelig feilrettinger og forbedringer. Å sende en melding er nå mye raskere.
Full endringslogg: https://github.com/vector-im/element-android/releases/tag/v1.0.10

View File

@@ -0,0 +1,2 @@
Denne nye versjonen inneholder hovedsakelig forbedringer av brukergrensesnittet og brukeropplevelsen. Nå kan du invitere venner og opprette DM veldig raskt ved å skanne QR-koder.
Full endringslogg: https://github.com/vector-im/element-android/releases/tag/v1.0.11

View File

@@ -0,0 +1 @@
Sikker desentralisert chat & VoIP. Beskytt dataene dine fra tredjeparter.

View File

@@ -0,0 +1 @@
Element (tidligere Riot.im)

View File

@@ -0,0 +1,2 @@
Esta nova versão contém principalmente melhorias na interface do usuário e na experiência do usuário. Agora você pode convidar amigos e criar conversas rapidamente, digitalizando códigos QR.
Registro completo de alterações: https://github.com/vector-im/element-android/releases/tag/v1.0.11

View File

@@ -0,0 +1,2 @@
Эта новая версия в основном содержит исправления ошибок и улучшения. Отправка сообщения стала намного быстрее.
Полный список изменений: https://github.com/vector-im/element-android/releases/tag/v1.0.10

View File

@@ -0,0 +1,2 @@
Эта новая версия в основном содержит улучшения пользовательского интерфейса и взаимодействия с пользователем. Теперь вы можете приглашать друзей и очень быстро создавать чаты, сканируя QR-коды.
Полный список изменений: https://github.com/vector-im/element-android/releases/tag/v1.0.11

View File

@@ -0,0 +1,2 @@
Táto verzia obsahuje predovšetkým opravy chýb. Odosielanie správ je odteraz omnoho rýchlejšie.
Kompletný zoznam zmien: https://github.com/vector-im/element-android/releases/tag/v1.0.10

View File

@@ -0,0 +1,2 @@
Táto verzia obsahuje najmä vylepšenia používateľského rozhrania. Pozývať priateľov alebo vytvárať priame konverzácie môžete veľmi rýchlo naskenovaním QR kódov.
Kompletný zoznam zmien: https://github.com/vector-im/element-android/releases/tag/v1.0.11

View File

@@ -0,0 +1,2 @@
Den här nya versionen innehåller mest förbättringar för användargränssnittet och användarupplevelsen. Du kan nu bjuda in vänner och skapa direktmeddelanden väldigt snabbt genom att skanna QR-koder.
Full ändringslogg: https://github.com/vector-im/element-android/releases/tag/v1.0.11

View File

@@ -0,0 +1,2 @@
Ця нова версія містить переважно поліпшення інтерфейсу та зручності користування. Тепер ви можете запросити друзів і створити прямі повідомлення дуже швидко, скануючи QR-коди.
Повний перелік змін: https://github.com/vector-im/element-android/releases/tag/v1.0.11

View File

@@ -0,0 +1,2 @@
Phiên bản mới này chủ yếu bao gồm sửa lỗi và một số cải thiện. Gửi tin nhắn trở nên nhanh chóng hơn trước.
Danh sách đầy đủ các thay đổi: https://github.com/vector-im/element-android/releases/tag/v1.0.10

View File

@@ -0,0 +1,2 @@
Phiên bản mới này chủ yếu bao gồm các cải thiện về giao diện và trải nghiệm người dùng. Bây giờ bạn có thể mời bạn bè và bắt đầu nói chuyện nhanh chóng bằng cách quét mã QR.
Danh sách đầy đủ các thay đổi: https://github.com/vector-im/element-android/releases/tag/v1.0.11

View File

@@ -0,0 +1 @@
Ứng dụng chat và gọi phân tán bảo mật. Bảo vệ dữ liệu của bạn khỏi bên thứ ba.

View File

@@ -0,0 +1 @@
Element (trước là Riot.im)

View File

@@ -0,0 +1,2 @@
這個新版本主要包含使用者介面與使用者體驗改善。現在您可以邀請朋友,並透過掃描 QR code 來快速建立直接訊息了。
完整變更紀錄https://github.com/vector-im/element-android/releases/tag/v1.0.11

View File

@@ -0,0 +1,2 @@
此版本中的主要變更URL 預覽、新的表情符號鍵盤、新的聊天室設定功能以及聖誕節降雪!
完整變更紀錄https://github.com/vector-im/element-android/releases/tag/v1.0.12

View File

@@ -0,0 +1,2 @@
此版本中的主要變更URL 預覽、新的表情符號鍵盤、新的聊天室設定功能以及聖誕節降雪!
完整變更紀錄https://github.com/vector-im/element-android/releases/tag/v1.0.12

View File

@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionSha256Sum=22449f5231796abd892c98b2a07c9ceebe4688d192cd2d6763f8e3bf8acbedeb
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-all.zip
distributionSha256Sum=3db89524a3981819ff28c3f979236c1274a726e146ced0c8a2020417f9bc0782
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.1-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

View File

@@ -3,11 +3,11 @@ apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
android {
compileSdkVersion 29
compileSdkVersion 30
defaultConfig {
minSdkVersion 21
targetSdkVersion 29
targetSdkVersion 30
versionCode 1
versionName "1.0"

View File

@@ -1,7 +1,7 @@
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-parcelize'
apply plugin: 'realm-android'
buildscript {
@@ -13,17 +13,13 @@ buildscript {
}
}
androidExtensions {
experimental = true
}
android {
compileSdkVersion 29
compileSdkVersion 30
testOptions.unitTests.includeAndroidResources = true
defaultConfig {
minSdkVersion 21
targetSdkVersion 29
targetSdkVersion 30
versionCode 1
versionName "0.0.1"
// Multidex is useful for tests
@@ -116,7 +112,7 @@ dependencies {
def lifecycle_version = '2.2.0'
def arch_version = '2.1.0'
def markwon_version = '3.1.0'
def daggerVersion = '2.29.1'
def daggerVersion = '2.31'
def work_version = '2.4.0'
def retrofit_version = '2.6.2'
@@ -164,16 +160,11 @@ dependencies {
// DI
implementation "com.google.dagger:dagger:$daggerVersion"
kapt "com.google.dagger:dagger-compiler:$daggerVersion"
compileOnly 'com.squareup.inject:assisted-inject-annotations-dagger2:0.5.0'
kapt 'com.squareup.inject:assisted-inject-processor-dagger2:0.5.0'
// Logging
implementation 'com.jakewharton.timber:timber:4.7.1'
implementation 'com.facebook.stetho:stetho-okhttp3:1.5.1'
// Bus
implementation 'org.greenrobot:eventbus:3.1.1'
// Phone number https://github.com/google/libphonenumber
implementation 'com.googlecode.libphonenumber:libphonenumber:8.10.23'

View File

@@ -20,14 +20,8 @@
# hide the original source file name.
#-renamesourcefileattribute SourceFile
### EVENT BUS ###
# BMA: Not sure I can delete this one without side effect
-keepattributes *Annotation*
-keepclassmembers class * {
@org.greenrobot.eventbus.Subscribe <methods>;
}
-keep enum org.greenrobot.eventbus.ThreadMode { *; }
### MOSHI ###

View File

@@ -16,8 +16,18 @@
package org.matrix.android.sdk.account
import org.junit.Assert.assertTrue
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
import org.junit.runners.MethodSorters
import org.matrix.android.sdk.InstrumentedTest
import org.matrix.android.sdk.api.auth.UIABaseAuth
import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor
import org.matrix.android.sdk.api.auth.UserPasswordAuth
import org.matrix.android.sdk.api.auth.data.LoginFlowResult
import org.matrix.android.sdk.api.auth.registration.RegistrationFlowResponse
import org.matrix.android.sdk.api.auth.registration.RegistrationResult
import org.matrix.android.sdk.api.failure.Failure
import org.matrix.android.sdk.api.failure.MatrixError
@@ -25,12 +35,8 @@ import org.matrix.android.sdk.common.CommonTestHelper
import org.matrix.android.sdk.common.SessionTestParams
import org.matrix.android.sdk.common.TestConstants
import org.matrix.android.sdk.common.TestMatrixCallback
import org.junit.Assert.assertTrue
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
import org.junit.runners.MethodSorters
import kotlin.coroutines.Continuation
import kotlin.coroutines.resume
@RunWith(JUnit4::class)
@FixMethodOrder(MethodSorters.JVM)
@@ -44,7 +50,18 @@ class DeactivateAccountTest : InstrumentedTest {
// Deactivate the account
commonTestHelper.runBlockingTest {
session.deactivateAccount(TestConstants.PASSWORD, false)
session.deactivateAccount(
object : UserInteractiveAuthInterceptor {
override fun performStage(flowResponse: RegistrationFlowResponse, errCode: String?, promise: Continuation<UIABaseAuth>) {
promise.resume(
UserPasswordAuth(
user = session.myUserId,
password = TestConstants.PASSWORD,
session = flowResponse.session
)
)
}
}, false)
}
// Try to login on the previous account, it will fail (M_USER_DEACTIVATED)

View File

@@ -86,7 +86,7 @@ class CommonTestHelper(context: Context) {
*
* @param session the session to sync
*/
fun syncSession(session: Session) {
fun syncSession(session: Session, timeout: Long = TestConstants.timeOutMillis) {
val lock = CountDownLatch(1)
val job = GlobalScope.launch(Dispatchers.Main) {
@@ -109,7 +109,7 @@ class CommonTestHelper(context: Context) {
}
GlobalScope.launch(Dispatchers.Main) { syncLiveData.observeForever(syncObserver) }
await(lock)
await(lock, timeout)
}
/**
@@ -119,7 +119,7 @@ class CommonTestHelper(context: Context) {
* @param message the message to send
* @param nbOfMessages the number of time the message will be sent
*/
fun sendTextMessage(room: Room, message: String, nbOfMessages: Int): List<TimelineEvent> {
fun sendTextMessage(room: Room, message: String, nbOfMessages: Int, timeout: Long = TestConstants.timeOutMillis): List<TimelineEvent> {
val timeline = room.createTimeline(null, TimelineSettings(10))
val sentEvents = ArrayList<TimelineEvent>(nbOfMessages)
val latch = CountDownLatch(1)
@@ -151,7 +151,7 @@ class CommonTestHelper(context: Context) {
room.sendTextMessage(message + " #" + (i + 1))
}
// Wait 3 second more per message
await(latch, timeout = TestConstants.timeOutMillis + 3_000L * nbOfMessages)
await(latch, timeout = timeout + 3_000L * nbOfMessages)
timeline.dispose()
// Check that all events has been created
@@ -215,14 +215,14 @@ class CommonTestHelper(context: Context) {
.getLoginFlow(hs, it)
}
doSync<RegistrationResult> {
doSync<RegistrationResult>(timeout = 60_000) {
matrix.authenticationService
.getRegistrationWizard()
.createAccount(userName, password, null, it)
}
// Perform dummy step
val registrationResult = doSync<RegistrationResult> {
val registrationResult = doSync<RegistrationResult>(timeout = 60_000) {
matrix.authenticationService
.getRegistrationWizard()
.dummy(it)
@@ -231,7 +231,7 @@ class CommonTestHelper(context: Context) {
assertTrue(registrationResult is RegistrationResult.Success)
val session = (registrationResult as RegistrationResult.Success).session
if (sessionTestParams.withInitialSync) {
syncSession(session)
syncSession(session, 60_000)
}
return session
@@ -378,7 +378,9 @@ class CommonTestHelper(context: Context) {
fun Iterable<Session>.signOutAndClose() = forEach { signOutAndClose(it) }
fun signOutAndClose(session: Session) {
doSync<Unit>(60_000) { session.signOut(true, it) }
runBlockingTest(timeout = 60_000) {
session.signOut(true)
}
// no need signout will close
// session.close()
}

View File

@@ -18,14 +18,21 @@ package org.matrix.android.sdk.common
import org.matrix.android.sdk.api.session.Session
data class CryptoTestData(val firstSession: Session,
val roomId: String,
val secondSession: Session? = null,
val thirdSession: Session? = null) {
data class CryptoTestData(val roomId: String,
val sessions: List<Session>) {
val firstSession: Session
get() = sessions.first()
val secondSession: Session?
get() = sessions.getOrNull(1)
val thirdSession: Session?
get() = sessions.getOrNull(2)
fun cleanUp(testHelper: CommonTestHelper) {
testHelper.signOutAndClose(firstSession)
secondSession?.let { testHelper.signOutAndClose(it) }
thirdSession?.let { testHelper.signOutAndClose(it) }
sessions.forEach {
testHelper.signOutAndClose(it)
}
}
}

View File

@@ -19,6 +19,18 @@ package org.matrix.android.sdk.common
import android.os.SystemClock
import android.util.Log
import androidx.lifecycle.Observer
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertNull
import org.junit.Assert.assertTrue
import org.matrix.android.sdk.api.auth.UIABaseAuth
import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor
import org.matrix.android.sdk.api.auth.UserPasswordAuth
import org.matrix.android.sdk.api.auth.registration.RegistrationFlowResponse
import org.matrix.android.sdk.api.session.Session
import org.matrix.android.sdk.api.session.crypto.verification.IncomingSasVerificationTransaction
import org.matrix.android.sdk.api.session.crypto.verification.OutgoingSasVerificationTransaction
@@ -36,17 +48,10 @@ import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM
import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM_BACKUP
import org.matrix.android.sdk.internal.crypto.keysbackup.model.MegolmBackupAuthData
import org.matrix.android.sdk.internal.crypto.keysbackup.model.MegolmBackupCreationInfo
import org.matrix.android.sdk.internal.crypto.model.rest.UserPasswordAuth
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotNull
import org.junit.Assert.assertNull
import org.junit.Assert.assertTrue
import java.util.UUID
import java.util.concurrent.CountDownLatch
import kotlin.coroutines.Continuation
import kotlin.coroutines.resume
class CryptoTestHelper(private val mTestHelper: CommonTestHelper) {
@@ -73,7 +78,7 @@ class CryptoTestHelper(private val mTestHelper: CommonTestHelper) {
}
}
return CryptoTestData(aliceSession, roomId)
return CryptoTestData(roomId, listOf(aliceSession))
}
/**
@@ -139,7 +144,7 @@ class CryptoTestHelper(private val mTestHelper: CommonTestHelper) {
// assertNotNull(roomFromBobPOV.powerLevels)
// assertTrue(roomFromBobPOV.powerLevels.maySendMessage(bobSession.myUserId))
return CryptoTestData(aliceSession, aliceRoomId, bobSession)
return CryptoTestData(aliceRoomId, listOf(aliceSession, bobSession))
}
/**
@@ -157,7 +162,7 @@ class CryptoTestHelper(private val mTestHelper: CommonTestHelper) {
// wait the initial sync
SystemClock.sleep(1000)
return CryptoTestData(aliceSession, aliceRoomId, cryptoTestData.secondSession, samSession)
return CryptoTestData(aliceRoomId, listOf(aliceSession, cryptoTestData.secondSession!!, samSession))
}
/**
@@ -304,10 +309,18 @@ class CryptoTestHelper(private val mTestHelper: CommonTestHelper) {
fun initializeCrossSigning(session: Session) {
mTestHelper.doSync<Unit> {
session.cryptoService().crossSigningService()
.initializeCrossSigning(UserPasswordAuth(
user = session.myUserId,
password = TestConstants.PASSWORD
), it)
.initializeCrossSigning(
object : UserInteractiveAuthInterceptor {
override fun performStage(flowResponse: RegistrationFlowResponse, errCode: String?, promise: Continuation<UIABaseAuth>) {
promise.resume(
UserPasswordAuth(
user = session.myUserId,
password = TestConstants.PASSWORD,
session = flowResponse.session
)
)
}
}, it)
}
}
@@ -381,4 +394,30 @@ class CryptoTestHelper(private val mTestHelper: CommonTestHelper) {
}
}
}
fun doE2ETestWithManyMembers(numberOfMembers: Int): CryptoTestData {
val aliceSession = mTestHelper.createAccount(TestConstants.USER_ALICE, defaultSessionParams)
aliceSession.cryptoService().setWarnOnUnknownDevices(false)
val roomId = mTestHelper.doSync<String> {
aliceSession.createRoom(CreateRoomParams().apply { name = "MyRoom" }, it)
}
val room = aliceSession.getRoom(roomId)!!
mTestHelper.runBlockingTest {
room.enableEncryption()
}
val sessions = mutableListOf(aliceSession)
for (index in 1 until numberOfMembers) {
val session = mTestHelper.createAccount("User_$index", defaultSessionParams)
mTestHelper.doSync<Unit>(timeout = 600_000) { room.invite(session.myUserId, null, it) }
println("TEST -> " + session.myUserId + " invited")
mTestHelper.doSync<Unit> { session.joinRoom(room.roomId, null, emptyList(), it) }
println("TEST -> " + session.myUserId + " joined")
sessions.add(session)
}
return CryptoTestData(roomId, sessions)
}
}

View File

@@ -17,7 +17,18 @@
package org.matrix.android.sdk.internal.crypto
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.amshove.kluent.shouldBe
import org.junit.Assert
import org.junit.Before
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
import org.matrix.android.sdk.InstrumentedTest
import org.matrix.android.sdk.api.auth.UIABaseAuth
import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor
import org.matrix.android.sdk.api.auth.UserPasswordAuth
import org.matrix.android.sdk.api.auth.registration.RegistrationFlowResponse
import org.matrix.android.sdk.api.extensions.tryOrNull
import org.matrix.android.sdk.api.session.crypto.MXCryptoError
import org.matrix.android.sdk.api.session.events.model.EventType
@@ -30,19 +41,13 @@ import org.matrix.android.sdk.common.CryptoTestHelper
import org.matrix.android.sdk.common.TestConstants
import org.matrix.android.sdk.internal.crypto.model.OlmSessionWrapper
import org.matrix.android.sdk.internal.crypto.model.event.EncryptedEventContent
import org.matrix.android.sdk.internal.crypto.model.rest.UserPasswordAuth
import org.matrix.android.sdk.internal.crypto.store.db.deserializeFromRealm
import org.matrix.android.sdk.internal.crypto.store.db.serializeForRealm
import org.amshove.kluent.shouldBe
import org.junit.Assert
import org.junit.Before
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
import org.matrix.olm.OlmSession
import timber.log.Timber
import java.util.concurrent.CountDownLatch
import kotlin.coroutines.Continuation
import kotlin.coroutines.resume
/**
* Ref:
@@ -202,10 +207,18 @@ class UnwedgingTest : InstrumentedTest {
// It's a trick to force key request on fail to decrypt
mTestHelper.doSync<Unit> {
bobSession.cryptoService().crossSigningService()
.initializeCrossSigning(UserPasswordAuth(
user = bobSession.myUserId,
password = TestConstants.PASSWORD
), it)
.initializeCrossSigning(
object : UserInteractiveAuthInterceptor {
override fun performStage(flowResponse: RegistrationFlowResponse, errCode: String?, promise: Continuation<UIABaseAuth>) {
promise.resume(
UserPasswordAuth(
user = bobSession.myUserId,
password = TestConstants.PASSWORD,
session = flowResponse.session
)
)
}
}, it)
}
// Wait until we received back the key

View File

@@ -17,14 +17,6 @@
package org.matrix.android.sdk.internal.crypto.crosssigning
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.matrix.android.sdk.InstrumentedTest
import org.matrix.android.sdk.common.CommonTestHelper
import org.matrix.android.sdk.common.CryptoTestHelper
import org.matrix.android.sdk.common.SessionTestParams
import org.matrix.android.sdk.common.TestConstants
import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo
import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap
import org.matrix.android.sdk.internal.crypto.model.rest.UserPasswordAuth
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertNotNull
@@ -35,6 +27,19 @@ import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
import org.matrix.android.sdk.InstrumentedTest
import org.matrix.android.sdk.api.auth.UIABaseAuth
import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor
import org.matrix.android.sdk.api.auth.UserPasswordAuth
import org.matrix.android.sdk.api.auth.registration.RegistrationFlowResponse
import org.matrix.android.sdk.common.CommonTestHelper
import org.matrix.android.sdk.common.CryptoTestHelper
import org.matrix.android.sdk.common.SessionTestParams
import org.matrix.android.sdk.common.TestConstants
import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo
import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap
import kotlin.coroutines.Continuation
import kotlin.coroutines.resume
@RunWith(AndroidJUnit4::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@@ -49,10 +54,17 @@ class XSigningTest : InstrumentedTest {
mTestHelper.doSync<Unit> {
aliceSession.cryptoService().crossSigningService()
.initializeCrossSigning(UserPasswordAuth(
user = aliceSession.myUserId,
password = TestConstants.PASSWORD
), it)
.initializeCrossSigning(object : UserInteractiveAuthInterceptor {
override fun performStage(flowResponse: RegistrationFlowResponse, errCode: String?, promise: Continuation<UIABaseAuth>) {
promise.resume(
UserPasswordAuth(
user = aliceSession.myUserId,
password = TestConstants.PASSWORD,
session = flowResponse.session
)
)
}
}, it)
}
val myCrossSigningKeys = aliceSession.cryptoService().crossSigningService().getMyCrossSigningKeys()
@@ -86,8 +98,18 @@ class XSigningTest : InstrumentedTest {
password = TestConstants.PASSWORD
)
mTestHelper.doSync<Unit> { aliceSession.cryptoService().crossSigningService().initializeCrossSigning(aliceAuthParams, it) }
mTestHelper.doSync<Unit> { bobSession.cryptoService().crossSigningService().initializeCrossSigning(bobAuthParams, it) }
mTestHelper.doSync<Unit> {
aliceSession.cryptoService().crossSigningService().initializeCrossSigning(object : UserInteractiveAuthInterceptor {
override fun performStage(flowResponse: RegistrationFlowResponse, errCode: String?, promise: Continuation<UIABaseAuth>) {
promise.resume(aliceAuthParams)
}
}, it)
}
mTestHelper.doSync<Unit> { bobSession.cryptoService().crossSigningService().initializeCrossSigning(object : UserInteractiveAuthInterceptor {
override fun performStage(flowResponse: RegistrationFlowResponse, errCode: String?, promise: Continuation<UIABaseAuth>) {
promise.resume(bobAuthParams)
}
}, it) }
// Check that alice can see bob keys
mTestHelper.doSync<MXUsersDevicesMap<CryptoDeviceInfo>> { aliceSession.cryptoService().downloadKeys(listOf(bobSession.myUserId), true, it) }
@@ -122,8 +144,16 @@ class XSigningTest : InstrumentedTest {
password = TestConstants.PASSWORD
)
mTestHelper.doSync<Unit> { aliceSession.cryptoService().crossSigningService().initializeCrossSigning(aliceAuthParams, it) }
mTestHelper.doSync<Unit> { bobSession.cryptoService().crossSigningService().initializeCrossSigning(bobAuthParams, it) }
mTestHelper.doSync<Unit> { aliceSession.cryptoService().crossSigningService().initializeCrossSigning(object : UserInteractiveAuthInterceptor {
override fun performStage(flowResponse: RegistrationFlowResponse, errCode: String?, promise: Continuation<UIABaseAuth>) {
promise.resume(aliceAuthParams)
}
}, it) }
mTestHelper.doSync<Unit> { bobSession.cryptoService().crossSigningService().initializeCrossSigning(object : UserInteractiveAuthInterceptor {
override fun performStage(flowResponse: RegistrationFlowResponse, errCode: String?, promise: Continuation<UIABaseAuth>) {
promise.resume(bobAuthParams)
}
}, it) }
// Check that alice can see bob keys
val bobUserId = bobSession.myUserId

View File

@@ -18,7 +18,21 @@ package org.matrix.android.sdk.internal.crypto.gossiping
import android.util.Log
import androidx.test.ext.junit.runners.AndroidJUnit4
import junit.framework.TestCase.assertEquals
import junit.framework.TestCase.assertNotNull
import junit.framework.TestCase.assertTrue
import junit.framework.TestCase.fail
import org.junit.Assert
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
import org.matrix.android.sdk.InstrumentedTest
import org.matrix.android.sdk.api.auth.UIABaseAuth
import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor
import org.matrix.android.sdk.api.auth.UserPasswordAuth
import org.matrix.android.sdk.api.auth.registration.RegistrationFlowResponse
import org.matrix.android.sdk.api.extensions.tryOrNull
import org.matrix.android.sdk.api.session.crypto.verification.IncomingSasVerificationTransaction
import org.matrix.android.sdk.api.session.crypto.verification.SasVerificationTransaction
import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod
@@ -28,6 +42,7 @@ import org.matrix.android.sdk.api.session.crypto.verification.VerificationTxStat
import org.matrix.android.sdk.api.session.events.model.toModel
import org.matrix.android.sdk.api.session.room.model.RoomDirectoryVisibility
import org.matrix.android.sdk.api.session.room.model.create.CreateRoomParams
import org.matrix.android.sdk.api.session.room.model.message.MessageContent
import org.matrix.android.sdk.common.CommonTestHelper
import org.matrix.android.sdk.common.CryptoTestHelper
import org.matrix.android.sdk.common.SessionTestParams
@@ -40,17 +55,9 @@ import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersion
import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo
import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap
import org.matrix.android.sdk.internal.crypto.model.event.EncryptedEventContent
import org.matrix.android.sdk.internal.crypto.model.rest.UserPasswordAuth
import junit.framework.TestCase.assertEquals
import junit.framework.TestCase.assertNotNull
import junit.framework.TestCase.assertTrue
import junit.framework.TestCase.fail
import org.junit.Assert
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
import java.util.concurrent.CountDownLatch
import kotlin.coroutines.Continuation
import kotlin.coroutines.resume
@RunWith(AndroidJUnit4::class)
@FixMethodOrder(MethodSorters.JVM)
@@ -198,10 +205,17 @@ class KeyShareTests : InstrumentedTest {
mTestHelper.doSync<Unit> {
aliceSession1.cryptoService().crossSigningService()
.initializeCrossSigning(UserPasswordAuth(
user = aliceSession1.myUserId,
password = TestConstants.PASSWORD
), it)
.initializeCrossSigning(
object : UserInteractiveAuthInterceptor {
override fun performStage(flowResponse: RegistrationFlowResponse, errCode: String?, promise: Continuation<UIABaseAuth>) {
promise.resume(
UserPasswordAuth(
user = aliceSession1.myUserId,
password = TestConstants.PASSWORD
)
)
}
}, it)
}
// Also bootstrap keybackup on first session
@@ -296,4 +310,93 @@ class KeyShareTests : InstrumentedTest {
mTestHelper.signOutAndClose(aliceSession1)
mTestHelper.signOutAndClose(aliceSession2)
}
@Test
fun test_ImproperKeyShareBug() {
val aliceSession = mTestHelper.createAccount(TestConstants.USER_ALICE, SessionTestParams(true))
mTestHelper.doSync<Unit> {
aliceSession.cryptoService().crossSigningService()
.initializeCrossSigning(
object : UserInteractiveAuthInterceptor {
override fun performStage(flowResponse: RegistrationFlowResponse, errCode: String?, promise: Continuation<UIABaseAuth>) {
promise.resume(
UserPasswordAuth(
user = aliceSession.myUserId,
password = TestConstants.PASSWORD,
session = flowResponse.session
)
)
}
}, it)
}
// Create an encrypted room and send a couple of messages
val roomId = mTestHelper.doSync<String> {
aliceSession.createRoom(
CreateRoomParams().apply {
visibility = RoomDirectoryVisibility.PRIVATE
enableEncryption()
},
it
)
}
val roomAlicePov = aliceSession.getRoom(roomId)
assertNotNull(roomAlicePov)
Thread.sleep(1_000)
assertTrue(roomAlicePov?.isEncrypted() == true)
val secondEventId = mTestHelper.sendTextMessage(roomAlicePov!!, "Message", 3)[1].eventId
// Create bob session
val bobSession = mTestHelper.createAccount(TestConstants.USER_BOB, SessionTestParams(true))
mTestHelper.doSync<Unit> {
bobSession.cryptoService().crossSigningService()
.initializeCrossSigning(
object : UserInteractiveAuthInterceptor {
override fun performStage(flowResponse: RegistrationFlowResponse, errCode: String?, promise: Continuation<UIABaseAuth>) {
promise.resume(
UserPasswordAuth(
user = bobSession.myUserId,
password = TestConstants.PASSWORD,
session = flowResponse.session
)
)
}
}, it)
}
// Let alice invite bob
mTestHelper.doSync<Unit> {
roomAlicePov.invite(bobSession.myUserId, null, it)
}
mTestHelper.doSync<Unit> {
bobSession.joinRoom(roomAlicePov.roomId, null, emptyList(), it)
}
// we want to discard alice outbound session
aliceSession.cryptoService().discardOutboundSession(roomAlicePov.roomId)
// and now resend a new message to reset index to 0
mTestHelper.sendTextMessage(roomAlicePov, "After", 1)
val roomRoomBobPov = aliceSession.getRoom(roomId)
val beforeJoin = roomRoomBobPov!!.getTimeLineEvent(secondEventId)
var dRes = tryOrNull { bobSession.cryptoService().decryptEvent(beforeJoin!!.root, "") }
assert(dRes == null)
// Try to re-ask the keys
bobSession.cryptoService().reRequestRoomKeyForEvent(beforeJoin!!.root)
Thread.sleep(3_000)
// With the bug the first session would have improperly reshare that key :/
dRes = tryOrNull { bobSession.cryptoService().decryptEvent(beforeJoin.root, "") }
Log.d("#TEST", "KS: sgould not decrypt that ${beforeJoin.root.getClearContent().toModel<MessageContent>()?.body}")
assert(dRes?.clearEvent == null)
}
}

View File

@@ -17,20 +17,25 @@
package org.matrix.android.sdk.internal.crypto.verification.qrcode
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.matrix.android.sdk.InstrumentedTest
import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod
import org.matrix.android.sdk.api.session.crypto.verification.VerificationService
import org.matrix.android.sdk.common.CommonTestHelper
import org.matrix.android.sdk.common.CryptoTestHelper
import org.matrix.android.sdk.common.TestConstants
import org.matrix.android.sdk.internal.crypto.model.rest.UserPasswordAuth
import org.matrix.android.sdk.api.session.crypto.verification.PendingVerificationRequest
import org.amshove.kluent.shouldBe
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.MethodSorters
import org.matrix.android.sdk.InstrumentedTest
import org.matrix.android.sdk.api.auth.UIABaseAuth
import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor
import org.matrix.android.sdk.api.auth.UserPasswordAuth
import org.matrix.android.sdk.api.auth.registration.RegistrationFlowResponse
import org.matrix.android.sdk.api.session.crypto.verification.PendingVerificationRequest
import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod
import org.matrix.android.sdk.api.session.crypto.verification.VerificationService
import org.matrix.android.sdk.common.CommonTestHelper
import org.matrix.android.sdk.common.CryptoTestHelper
import org.matrix.android.sdk.common.TestConstants
import java.util.concurrent.CountDownLatch
import kotlin.coroutines.Continuation
import kotlin.coroutines.resume
@RunWith(AndroidJUnit4::class)
@FixMethodOrder(MethodSorters.JVM)
@@ -157,18 +162,34 @@ class VerificationTest : InstrumentedTest {
mTestHelper.doSync<Unit> { callback ->
aliceSession.cryptoService().crossSigningService()
.initializeCrossSigning(UserPasswordAuth(
user = aliceSession.myUserId,
password = TestConstants.PASSWORD
), callback)
.initializeCrossSigning(
object : UserInteractiveAuthInterceptor {
override fun performStage(flowResponse: RegistrationFlowResponse, errCode: String?, promise: Continuation<UIABaseAuth>) {
promise.resume(
UserPasswordAuth(
user = aliceSession.myUserId,
password = TestConstants.PASSWORD,
session = flowResponse.session
)
)
}
}, callback)
}
mTestHelper.doSync<Unit> { callback ->
bobSession.cryptoService().crossSigningService()
.initializeCrossSigning(UserPasswordAuth(
user = bobSession.myUserId,
password = TestConstants.PASSWORD
), callback)
.initializeCrossSigning(
object : UserInteractiveAuthInterceptor {
override fun performStage(flowResponse: RegistrationFlowResponse, errCode: String?, promise: Continuation<UIABaseAuth>) {
promise.resume(
UserPasswordAuth(
user = bobSession.myUserId,
password = TestConstants.PASSWORD,
session = flowResponse.session
)
)
}
}, callback)
}
val aliceVerificationService = aliceSession.cryptoService().verificationService()

View File

@@ -26,6 +26,8 @@ import org.matrix.android.sdk.api.session.events.model.EventType
import org.matrix.android.sdk.api.session.events.model.toContent
import org.matrix.android.sdk.api.session.room.model.message.MessageTextContent
import org.matrix.android.sdk.api.session.room.model.message.MessageType
import org.matrix.android.sdk.api.session.room.sender.SenderInfo
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
@RunWith(AndroidJUnit4::class)
internal class UrlsExtractorTest : InstrumentedTest {
@@ -36,6 +38,7 @@ internal class UrlsExtractorTest : InstrumentedTest {
fun wrongEventTypeTest() {
createEvent(body = "https://matrix.org")
.copy(type = EventType.STATE_ROOM_GUEST_ACCESS)
.toFakeTimelineEvent()
.let { urlsExtractor.extract(it) }
.size shouldBeEqualTo 0
}
@@ -43,6 +46,7 @@ internal class UrlsExtractorTest : InstrumentedTest {
@Test
fun oneUrlTest() {
createEvent(body = "https://matrix.org")
.toFakeTimelineEvent()
.let { urlsExtractor.extract(it) }
.let { result ->
result.size shouldBeEqualTo 1
@@ -53,6 +57,7 @@ internal class UrlsExtractorTest : InstrumentedTest {
@Test
fun withoutProtocolTest() {
createEvent(body = "www.matrix.org")
.toFakeTimelineEvent()
.let { urlsExtractor.extract(it) }
.size shouldBeEqualTo 0
}
@@ -60,6 +65,7 @@ internal class UrlsExtractorTest : InstrumentedTest {
@Test
fun oneUrlWithParamTest() {
createEvent(body = "https://matrix.org?foo=bar")
.toFakeTimelineEvent()
.let { urlsExtractor.extract(it) }
.let { result ->
result.size shouldBeEqualTo 1
@@ -70,6 +76,7 @@ internal class UrlsExtractorTest : InstrumentedTest {
@Test
fun oneUrlWithParamsTest() {
createEvent(body = "https://matrix.org?foo=bar&bar=foo")
.toFakeTimelineEvent()
.let { urlsExtractor.extract(it) }
.let { result ->
result.size shouldBeEqualTo 1
@@ -80,16 +87,18 @@ internal class UrlsExtractorTest : InstrumentedTest {
@Test
fun oneUrlInlinedTest() {
createEvent(body = "Hello https://matrix.org, how are you?")
.toFakeTimelineEvent()
.let { urlsExtractor.extract(it) }
.let { result ->
result.size shouldBeEqualTo 1
result[0] shouldBeEqualTo "https://matrix.org"
result[0] shouldBeEqualTo "https://matrix.org"
}
}
@Test
fun twoUrlsTest() {
createEvent(body = "https://matrix.org https://example.org")
.toFakeTimelineEvent()
.let { urlsExtractor.extract(it) }
.let { result ->
result.size shouldBeEqualTo 2
@@ -99,10 +108,26 @@ internal class UrlsExtractorTest : InstrumentedTest {
}
private fun createEvent(body: String): Event = Event(
eventId = "!fake",
type = EventType.MESSAGE,
content = MessageTextContent(
msgType = MessageType.MSGTYPE_TEXT,
body = body
).toContent()
)
private fun Event.toFakeTimelineEvent(): TimelineEvent {
return TimelineEvent(
root = this,
localId = 0L,
eventId = eventId!!,
displayIndex = 0,
senderInfo = SenderInfo(
userId = "",
displayName = null,
isUniqueDisplayName = true,
avatarUrl = null
)
)
}
}

View File

@@ -66,8 +66,8 @@ class TimelineForwardPaginationTest : InstrumentedTest {
numberOfMessagesToSend)
// Alice clear the cache
commonTestHelper.doSync<Unit> {
aliceSession.clearCache(it)
commonTestHelper.runBlockingTest {
aliceSession.clearCache()
}
// And restarts the sync

View File

@@ -0,0 +1,92 @@
/*
* Copyright 2020 The Matrix.org Foundation C.I.C.
*
* 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 org.matrix.android.sdk.session.room.timeline
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
import org.junit.runners.MethodSorters
import org.matrix.android.sdk.InstrumentedTest
import org.matrix.android.sdk.api.extensions.orFalse
import org.matrix.android.sdk.api.session.events.model.toModel
import org.matrix.android.sdk.api.session.room.model.message.MessageContent
import org.matrix.android.sdk.api.session.room.timeline.TimelineSettings
import org.matrix.android.sdk.common.CommonTestHelper
import org.matrix.android.sdk.common.CryptoTestHelper
import java.util.concurrent.CountDownLatch
import kotlin.test.fail
@RunWith(JUnit4::class)
@FixMethodOrder(MethodSorters.JVM)
class TimelineWithManyMembersTest : InstrumentedTest {
companion object {
private const val NUMBER_OF_MEMBERS = 6
}
private val commonTestHelper = CommonTestHelper(context())
private val cryptoTestHelper = CryptoTestHelper(commonTestHelper)
/**
* Ensures when someone sends a message to a crowded room, everyone can decrypt the message.
*/
@Test
fun everyone_should_decrypt_message_in_a_crowded_room() {
val cryptoTestData = cryptoTestHelper.doE2ETestWithManyMembers(NUMBER_OF_MEMBERS)
val sessionForFirstMember = cryptoTestData.firstSession
val roomForFirstMember = sessionForFirstMember.getRoom(cryptoTestData.roomId)!!
val firstMessage = "First messages from Alice"
commonTestHelper.sendTextMessage(
roomForFirstMember,
firstMessage,
1,
600_000
)
for (index in 1 until cryptoTestData.sessions.size) {
val session = cryptoTestData.sessions[index]
val roomForCurrentMember = session.getRoom(cryptoTestData.roomId)!!
val timelineForCurrentMember = roomForCurrentMember.createTimeline(null, TimelineSettings(30))
timelineForCurrentMember.start()
session.startSync(true)
run {
val lock = CountDownLatch(1)
val eventsListener = commonTestHelper.createEventListener(lock) { snapshot ->
snapshot
.find { it.isEncrypted() }
?.let {
val body = it.root.getClearContent()?.toModel<MessageContent>()?.body
if (body?.startsWith(firstMessage).orFalse()) {
println("User " + session.myUserId + " decrypted as " + body)
return@createEventListener true
} else {
fail("User " + session.myUserId + " decrypted as " + body + " CryptoError: " + it.root.mCryptoError)
}
} ?: return@createEventListener false
}
timelineForCurrentMember.addListener(eventsListener)
commonTestHelper.await(lock, 600_000)
}
session.stopSync()
}
}
}

View File

@@ -41,6 +41,16 @@ interface AuthenticationService {
*/
fun getLoginFlowOfSession(sessionId: String, callback: MatrixCallback<LoginFlowResult>): Cancelable
/**
* Get a SSO url
*/
fun getSsoUrl(redirectUrl: String, deviceId: String?, providerId: String?): String?
/**
* Get the sign in or sign up fallback URL
*/
fun getFallbackUrl(forSignIn: Boolean, deviceId: String?): String?
/**
* Return a LoginWizard, to login to the homeserver. The login flow has to be retrieved first.
*/

View File

@@ -0,0 +1,69 @@
/*
* Copyright 2020 The Matrix.org Foundation C.I.C.
*
* 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 org.matrix.android.sdk.api.auth
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import org.matrix.android.sdk.api.auth.data.LoginFlowTypes
/**
* This class provides the authentication data by using user and password
*/
@JsonClass(generateAdapter = true)
data class TokenBasedAuth(
/**
* This is a session identifier that the client must pass back to the homeserver,
* if one is provided, in subsequent attempts to authenticate in the same API call.
*/
@Json(name = "session")
override val session: String? = null,
/**
* A client may receive a login token via some external service, such as email or SMS.
* Note that a login token is separate from an access token, the latter providing general authentication to various API endpoints.
*/
@Json(name = "token")
val token: String? = null,
/**
* The txn_id should be a random string generated by the client for the request.
* The same txn_id should be used if retrying the request.
* The txn_id may be used by the server to disallow other devices from using the token,
* thus providing "single use" tokens while still allowing the device to retry the request.
* This would be done by tying the token to the txn_id server side, as well as potentially invalidating
* the token completely once the device has successfully logged in
* (e.g. when we receive a request from the newly provisioned access_token).
*/
@Json(name = "txn_id")
val transactionId: String? = null,
// registration information
@Json(name = "type")
val type: String? = LoginFlowTypes.TOKEN
) : UIABaseAuth {
override fun hasAuthInfo() = token != null
override fun copyWithSession(session: String) = this.copy(session = session)
override fun asMap(): Map<String, *> = mapOf(
"session" to session,
"token" to token,
"transactionId" to transactionId,
"type" to type
)
}

View File

@@ -14,18 +14,18 @@
* limitations under the License.
*/
package org.matrix.android.sdk.internal.eventbus
package org.matrix.android.sdk.api.auth
import org.greenrobot.eventbus.Logger
import timber.log.Timber
import java.util.logging.Level
interface UIABaseAuth {
/**
* This is a session identifier that the client must pass back to the homeserver,
* if one is provided, in subsequent attempts to authenticate in the same API call.
*/
val session: String?
class EventBusTimberLogger : Logger {
override fun log(level: Level, msg: String) {
Timber.d(msg)
}
fun hasAuthInfo(): Boolean
override fun log(level: Level, msg: String, th: Throwable) {
Timber.e(th, msg)
}
fun copyWithSession(session: String): UIABaseAuth
fun asMap() : Map<String, *>
}

View File

@@ -0,0 +1,47 @@
/*
* Copyright 2020 The Matrix.org Foundation C.I.C.
*
* 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 org.matrix.android.sdk.api.auth
import org.matrix.android.sdk.api.auth.registration.RegistrationFlowResponse
import kotlin.coroutines.Continuation
/**
* Some API endpoints require authentication that interacts with the user.
* The homeserver may provide many different ways of authenticating, such as user/password auth, login via a social network (OAuth2),
* login by confirming a token sent to their email address, etc.
*
* The process takes the form of one or more 'stages'.
* At each stage the client submits a set of data for a given authentication type and awaits a response from the server,
* which will either be a final success or a request to perform an additional stage.
* This exchange continues until the final success.
*
* For each endpoint, a server offers one or more 'flows' that the client can use to authenticate itself.
* Each flow comprises a series of stages, as described above.
* The client is free to choose which flow it follows, however the flow's stages must be completed in order.
* Failing to follow the flows in order must result in an HTTP 401 response.
* When all stages in a flow are complete, authentication is complete and the API call succeeds.
*/
interface UserInteractiveAuthInterceptor {
/**
* When the API needs additional auth, this will be called.
* Implementation should check the flows from flow response and act accordingly.
* Updated auth should be provided using promise.resume, this allow implementation to perform
* an async operation (prompt for user password, open sso fallback) and then resume initial API call when done.
*/
fun performStage(flowResponse: RegistrationFlowResponse, errCode: String?, promise: Continuation<UIABaseAuth>)
}

View File

@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.matrix.android.sdk.internal.crypto.model.rest
package org.matrix.android.sdk.api.auth
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
@@ -27,7 +27,7 @@ data class UserPasswordAuth(
// device device session id
@Json(name = "session")
val session: String? = null,
override val session: String? = null,
// registration information
@Json(name = "type")
@@ -38,4 +38,16 @@ data class UserPasswordAuth(
@Json(name = "password")
val password: String? = null
)
) : UIABaseAuth {
override fun hasAuthInfo() = password != null
override fun copyWithSession(session: String) = this.copy(session = session)
override fun asMap(): Map<String, *> = mapOf(
"session" to session,
"user" to user,
"password" to password,
"type" to type
)
}

View File

@@ -19,7 +19,7 @@ package org.matrix.android.sdk.api.auth.data
import android.os.Parcelable
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import kotlinx.android.parcel.Parcelize
import kotlinx.parcelize.Parcelize
@JsonClass(generateAdapter = true)
@Parcelize
@@ -38,15 +38,24 @@ data class SsoIdentityProvider(
* If present then it must be an HTTPS URL to an image resource.
* This should be hosted by the homeserver service provider to not leak the client's IP address unnecessarily.
*/
@Json(name = "icon") val iconUrl: String?
@Json(name = "icon") val iconUrl: String?,
/**
* The `brand` field is **optional**. It allows the client to style the login
* button to suit a particular brand. It should be a string matching the
* "Common namespaced identifier grammar" as defined in
* [MSC2758](https://github.com/matrix-org/matrix-doc/pull/2758).
*/
@Json(name = "brand") val brand: String?
) : Parcelable {
companion object {
// Not really defined by the spec, but we may define some ids here
const val ID_GOOGLE = "google"
const val ID_GITHUB = "github"
const val ID_APPLE = "apple"
const val ID_FACEBOOK = "facebook"
const val ID_TWITTER = "twitter"
const val BRAND_GOOGLE = "org.matrix.google"
const val BRAND_GITHUB = "org.matrix.github"
const val BRAND_APPLE = "org.matrix.apple"
const val BRAND_FACEBOOK = "org.matrix.facebook"
const val BRAND_TWITTER = "org.matrix.twitter"
const val BRAND_GITLAB = "org.matrix.gitlab"
}
}

View File

@@ -14,14 +14,11 @@
* limitations under the License.
*/
package org.matrix.android.sdk.internal.auth.registration
package org.matrix.android.sdk.api.auth.registration
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import org.matrix.android.sdk.api.auth.data.LoginFlowTypes
import org.matrix.android.sdk.api.auth.registration.FlowResult
import org.matrix.android.sdk.api.auth.registration.Stage
import org.matrix.android.sdk.api.auth.registration.TermPolicies
import org.matrix.android.sdk.api.util.JsonDict
import org.matrix.android.sdk.internal.auth.data.InteractiveAuthenticationFlow
@@ -109,3 +106,8 @@ fun RegistrationFlowResponse.toFlowResult(): FlowResult {
return FlowResult(missingStage, completedStage)
}
fun RegistrationFlowResponse.nextUncompletedStage(flowIndex: Int = 0): String? {
val completed = completedStages ?: emptyList()
return flows?.getOrNull(flowIndex)?.stages?.firstOrNull { completed.contains(it).not() }
}

View File

@@ -16,8 +16,8 @@
package org.matrix.android.sdk.api.failure
import org.matrix.android.sdk.api.auth.registration.RegistrationFlowResponse
import org.matrix.android.sdk.api.extensions.tryOrNull
import org.matrix.android.sdk.internal.auth.registration.RegistrationFlowResponse
import org.matrix.android.sdk.internal.di.MoshiProvider
import java.io.IOException
import javax.net.ssl.HttpsURLConnection
@@ -43,6 +43,12 @@ fun Throwable.isInvalidPassword(): Boolean {
&& error.message == "Invalid password"
}
fun Throwable.isInvalidUIAAuth(): Boolean {
return this is Failure.ServerError
&& error.code == MatrixError.M_FORBIDDEN
&& error.flows != null
}
/**
* Try to convert to a RegistrationFlowResponse. Return null in the cases it's not possible
*/
@@ -53,6 +59,16 @@ fun Throwable.toRegistrationFlowResponse(): RegistrationFlowResponse? {
.adapter(RegistrationFlowResponse::class.java)
.fromJson(this.errorBody)
}
} else if (this is Failure.ServerError && this.httpCode == 401 && this.error.code == MatrixError.M_FORBIDDEN) {
// This happens when the submission for this stage was bad (like bad password)
if (this.error.session != null && this.error.flows != null) {
RegistrationFlowResponse(
flows = this.error.flows,
session = this.error.session,
completedStages = this.error.completedStages,
params = this.error.params
)
} else null
} else {
null
}

View File

@@ -16,8 +16,8 @@
package org.matrix.android.sdk.api.failure
import org.matrix.android.sdk.api.auth.registration.RegistrationFlowResponse
import org.matrix.android.sdk.api.session.crypto.MXCryptoError
import org.matrix.android.sdk.internal.auth.registration.RegistrationFlowResponse
import org.matrix.android.sdk.internal.network.ssl.Fingerprint
import java.io.IOException

View File

@@ -18,6 +18,8 @@ package org.matrix.android.sdk.api.failure
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import org.matrix.android.sdk.api.util.JsonDict
import org.matrix.android.sdk.internal.auth.data.InteractiveAuthenticationFlow
/**
* This data class holds the error defined by the matrix specifications.
@@ -42,7 +44,17 @@ data class MatrixError(
@Json(name = "soft_logout") val isSoftLogout: Boolean = false,
// For M_INVALID_PEPPER
// {"error": "pepper does not match 'erZvr'", "lookup_pepper": "pQgMS", "algorithm": "sha256", "errcode": "M_INVALID_PEPPER"}
@Json(name = "lookup_pepper") val newLookupPepper: String? = null
@Json(name = "lookup_pepper") val newLookupPepper: String? = null,
// For M_FORBIDDEN UIA
@Json(name = "session")
val session: String? = null,
@Json(name = "completed")
val completedStages: List<String>? = null,
@Json(name = "flows")
val flows: List<InteractiveAuthenticationFlow>? = null,
@Json(name = "params")
val params: JsonDict? = null
) {
companion object {

View File

@@ -37,6 +37,6 @@ class SenderNotificationPermissionCondition(
fun isSatisfied(event: Event, powerLevels: PowerLevelsContent): Boolean {
val powerLevelsHelper = PowerLevelsHelper(powerLevels)
return event.senderId != null && powerLevelsHelper.getUserPowerLevelValue(event.senderId) >= powerLevelsHelper.notificationLevel(key)
return event.senderId != null && powerLevelsHelper.getUserPowerLevelValue(event.senderId) >= powerLevels.notificationLevel(key)
}
}

View File

@@ -245,6 +245,8 @@ interface Session :
val sharedSecretStorageService: SharedSecretStorageService
fun getUiaSsoFallbackUrl(authenticationSessionId: String): String
/**
* Maintenance API, allows to print outs info on DB size to logcat
*/

View File

@@ -16,6 +16,8 @@
package org.matrix.android.sdk.api.session.account
import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor
/**
* This interface defines methods to manage the account. It's implemented at the session level.
*/
@@ -43,5 +45,5 @@ interface AccountService {
* @param eraseAllData set to true to forget all messages that have been sent. Warning: this will cause future users to see
* an incomplete view of conversations
*/
suspend fun deactivateAccount(password: String, eraseAllData: Boolean)
suspend fun deactivateAccount(userInteractiveAuthInterceptor: UserInteractiveAuthInterceptor, eraseAllData: Boolean)
}

View File

@@ -16,8 +16,6 @@
package org.matrix.android.sdk.api.session.cache
import org.matrix.android.sdk.api.MatrixCallback
/**
* This interface defines a method to clear the cache. It's implemented at the session level.
*/
@@ -26,5 +24,5 @@ interface CacheService {
/**
* Clear the whole cached data, except credentials. Once done, the sync has to be restarted by the sdk user.
*/
fun clearCache(callback: MatrixCallback<Unit>)
suspend fun clearCache()
}

View File

@@ -20,7 +20,7 @@ import android.net.Uri
import android.os.Parcelable
import androidx.exifinterface.media.ExifInterface
import com.squareup.moshi.JsonClass
import kotlinx.android.parcel.Parcelize
import kotlinx.parcelize.Parcelize
import org.matrix.android.sdk.api.util.MimeTypes.normalizeMimeType
@Parcelize

View File

@@ -20,6 +20,7 @@ import android.content.Context
import androidx.lifecycle.LiveData
import androidx.paging.PagedList
import org.matrix.android.sdk.api.MatrixCallback
import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor
import org.matrix.android.sdk.api.listeners.ProgressListener
import org.matrix.android.sdk.api.session.crypto.crosssigning.CrossSigningService
import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupService
@@ -53,7 +54,7 @@ interface CryptoService {
fun setDeviceName(deviceId: String, deviceName: String, callback: MatrixCallback<Unit>)
fun deleteDevice(deviceId: String, callback: MatrixCallback<Unit>)
fun deleteDevice(deviceId: String, userInteractiveAuthInterceptor: UserInteractiveAuthInterceptor, callback: MatrixCallback<Unit>)
fun deleteDeviceWithUserPassword(deviceId: String, authSession: String?, password: String, callback: MatrixCallback<Unit>)

View File

@@ -18,10 +18,10 @@ package org.matrix.android.sdk.api.session.crypto.crosssigning
import androidx.lifecycle.LiveData
import org.matrix.android.sdk.api.MatrixCallback
import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor
import org.matrix.android.sdk.api.util.Optional
import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustResult
import org.matrix.android.sdk.internal.crypto.crosssigning.UserTrustResult
import org.matrix.android.sdk.internal.crypto.model.rest.UserPasswordAuth
import org.matrix.android.sdk.internal.crypto.store.PrivateKeysInfo
interface CrossSigningService {
@@ -40,7 +40,7 @@ interface CrossSigningService {
* Initialize cross signing for this user.
* Users needs to enter credentials
*/
fun initializeCrossSigning(authParams: UserPasswordAuth?,
fun initializeCrossSigning(uiaInterceptor: UserInteractiveAuthInterceptor?,
callback: MatrixCallback<Unit>)
fun isCrossSigningInitialized(): Boolean = getMyCrossSigningKeys() != null

View File

@@ -17,15 +17,16 @@
package org.matrix.android.sdk.api.session.media
import org.matrix.android.sdk.api.cache.CacheStrategy
import org.matrix.android.sdk.api.session.events.model.Event
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
import org.matrix.android.sdk.api.util.JsonDict
interface MediaService {
/**
* Extract URLs from an Event.
* @return the list of URLs contains in the body of the Event. It does not mean that URLs in this list have UrlPreview data
* Extract URLs from a TimelineEvent.
* @param event TimelineEvent to extract the URL from.
* @return the list of URLs contains in the body of the TimelineEvent. It does not mean that URLs in this list have UrlPreview data
*/
fun extractUrls(event: Event): List<String>
fun extractUrls(event: TimelineEvent): List<String>
/**
* Get Raw Url Preview data from the homeserver. There is no cache management for this request

View File

@@ -25,7 +25,6 @@ interface PermalinkService {
companion object {
const val MATRIX_TO_URL_BASE = "https://matrix.to/#/"
const val MATRIX_TO_CUSTOM_SCHEME_URL_BASE = "element://"
}
/**

View File

@@ -20,6 +20,7 @@ package org.matrix.android.sdk.api.session.profile
import android.net.Uri
import androidx.lifecycle.LiveData
import org.matrix.android.sdk.api.MatrixCallback
import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor
import org.matrix.android.sdk.api.session.identity.ThreePid
import org.matrix.android.sdk.api.util.Cancelable
import org.matrix.android.sdk.api.util.JsonDict
@@ -107,8 +108,7 @@ interface ProfileService {
* Finalize adding a 3Pids. Call this method once the user has validated that he owns the ThreePid
*/
fun finalizeAddingThreePid(threePid: ThreePid,
uiaSession: String?,
accountPassword: String?,
userInteractiveAuthInterceptor: UserInteractiveAuthInterceptor,
matrixCallback: MatrixCallback<Unit>): Cancelable
/**

View File

@@ -25,28 +25,85 @@ import org.matrix.android.sdk.api.session.room.powerlevels.Role
*/
@JsonClass(generateAdapter = true)
data class PowerLevelsContent(
/**
* The level required to ban a user. Defaults to 50 if unspecified.
*/
@Json(name = "ban") val ban: Int = Role.Moderator.value,
/**
* The level required to kick a user. Defaults to 50 if unspecified.
*/
@Json(name = "kick") val kick: Int = Role.Moderator.value,
/**
* The level required to invite a user. Defaults to 50 if unspecified.
*/
@Json(name = "invite") val invite: Int = Role.Moderator.value,
/**
* The level required to redact an event. Defaults to 50 if unspecified.
*/
@Json(name = "redact") val redact: Int = Role.Moderator.value,
/**
* The default level required to send message events. Can be overridden by the events key. Defaults to 0 if unspecified.
*/
@Json(name = "events_default") val eventsDefault: Int = Role.Default.value,
@Json(name = "events") val events: MutableMap<String, Int> = HashMap(),
/**
* The level required to send specific event types. This is a mapping from event type to power level required.
*/
@Json(name = "events") val events: Map<String, Int> = emptyMap(),
/**
* The default power level for every user in the room, unless their user_id is mentioned in the users key. Defaults to 0 if unspecified.
*/
@Json(name = "users_default") val usersDefault: Int = Role.Default.value,
@Json(name = "users") val users: MutableMap<String, Int> = HashMap(),
/**
* The power levels for specific users. This is a mapping from user_id to power level for that user.
*/
@Json(name = "users") val users: Map<String, Int> = emptyMap(),
/**
* The default level required to send state events. Can be overridden by the events key. Defaults to 50 if unspecified.
*/
@Json(name = "state_default") val stateDefault: Int = Role.Moderator.value,
@Json(name = "notifications") val notifications: Map<String, Any> = HashMap()
/**
* The power level requirements for specific notification types. This is a mapping from key to power level for that notifications key.
*/
@Json(name = "notifications") val notifications: Map<String, Any> = emptyMap()
) {
/**
* Alter this content with a new power level for the specified user
* Return a copy of this content with a new power level for the specified user
*
* @param userId the userId to alter the power level of
* @param powerLevel the new power level, or null to set the default value.
*/
fun setUserPowerLevel(userId: String, powerLevel: Int?) {
if (powerLevel == null || powerLevel == usersDefault) {
users.remove(userId)
} else {
users[userId] = powerLevel
fun setUserPowerLevel(userId: String, powerLevel: Int?): PowerLevelsContent {
return copy(
users = users.toMutableMap().apply {
if (powerLevel == null || powerLevel == usersDefault) {
remove(userId)
} else {
put(userId, powerLevel)
}
}
)
}
/**
* Get the notification level for a dedicated key.
*
* @param key the notification key
* @return the level, default to Moderator if the key is not found
*/
fun notificationLevel(key: String): Int {
return when (val value = notifications[key]) {
// the first implementation was a string value
is String -> value.toInt()
is Double -> value.toInt()
is Int -> value
else -> Role.Moderator.value
}
}
companion object {
/**
* Key to use for content.notifications and get the level required to trigger an @room notification. Defaults to 50 if unspecified.
*/
const val NOTIFICATIONS_ROOM_KEY = "room"
}
}

View File

@@ -27,6 +27,7 @@ data class MessageStickerContent(
/**
* Set in local, not from server
*/
@Transient
override val msgType: String = MessageType.MSGTYPE_STICKER_LOCAL,
/**

View File

@@ -108,19 +108,4 @@ class PowerLevelsHelper(private val powerLevelsContent: PowerLevelsContent) {
val powerLevel = getUserPowerLevelValue(userId)
return powerLevel >= powerLevelsContent.redact
}
/**
* Get the notification level for a dedicated key.
*
* @param key the notification key
* @return the level
*/
fun notificationLevel(key: String): Int {
return when (val value = powerLevelsContent.notifications[key]) {
// the first implementation was a string value
is String -> value.toInt()
is Int -> value
else -> Role.Moderator.value
}
}
}

View File

@@ -0,0 +1,33 @@
/*
* Copyright 2020 The Matrix.org Foundation C.I.C.
*
* 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 org.matrix.android.sdk.api.session.room.state
import org.matrix.android.sdk.api.query.QueryStringValue
import org.matrix.android.sdk.api.session.events.model.EventType
import org.matrix.android.sdk.api.session.events.model.toModel
import org.matrix.android.sdk.api.session.room.model.RoomJoinRules
import org.matrix.android.sdk.api.session.room.model.RoomJoinRulesContent
/**
* Return true if a room can be joined by anyone (RoomJoinRules.PUBLIC)
*/
fun StateService.isPublic(): Boolean {
return getStateEvent(EventType.STATE_ROOM_JOIN_RULES, QueryStringValue.NoCondition)
?.content
?.toModel<RoomJoinRulesContent>()
?.joinRules == RoomJoinRules.PUBLIC
}

View File

@@ -89,6 +89,17 @@ data class TimelineEvent(
*/
fun TimelineEvent.hasBeenEdited() = annotations?.editSummary != null
/**
* Get the latest known eventId for an edited event, or the eventId for an Event which has not been edited
*/
fun TimelineEvent.getLatestEventId(): String {
return annotations
?.editSummary
?.sourceEvents
?.lastOrNull()
?: eventId
}
/**
* Get the relation content if any
*/

View File

@@ -16,9 +16,7 @@
package org.matrix.android.sdk.api.session.signout
import org.matrix.android.sdk.api.MatrixCallback
import org.matrix.android.sdk.api.auth.data.Credentials
import org.matrix.android.sdk.api.util.Cancelable
/**
* This interface defines a method to sign out, or to renew the token. It's implemented at the session level.
@@ -29,19 +27,16 @@ interface SignOutService {
* Ask the homeserver for a new access token.
* The same deviceId will be used
*/
fun signInAgain(password: String,
callback: MatrixCallback<Unit>): Cancelable
suspend fun signInAgain(password: String)
/**
* Update the session with credentials received after SSO
*/
fun updateCredentials(credentials: Credentials,
callback: MatrixCallback<Unit>): Cancelable
suspend fun updateCredentials(credentials: Credentials)
/**
* Sign out, and release the session, clear all the session data, including crypto data
* @param signOutFromHomeserver true if the sign out request has to be done
*/
fun signOut(signOutFromHomeserver: Boolean,
callback: MatrixCallback<Unit>): Cancelable
suspend fun signOut(signOutFromHomeserver: Boolean)
}

View File

@@ -0,0 +1,37 @@
/*
* Copyright 2020 The Matrix.org Foundation C.I.C.
*
* 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 org.matrix.android.sdk.api.util
import java.net.URLEncoder
/**
* Append param and value to a Url, using "?" or "&". Value parameter will be encoded
* Return this for chaining purpose
*/
fun StringBuilder.appendParamToUrl(param: String, value: String): StringBuilder {
if (contains("?")) {
append("&")
} else {
append("?")
}
append(param)
append("=")
append(URLEncoder.encode(value, "utf-8"))
return this
}

View File

@@ -14,24 +14,28 @@
* limitations under the License.
*/
package org.matrix.android.sdk.api.auth
package org.matrix.android.sdk.internal.auth
/**
* Path to use when the client does not supported any or all login flows
* Ref: https://matrix.org/docs/spec/client_server/latest#login-fallback
*/
const val LOGIN_FALLBACK_PATH = "/_matrix/static/client/login/"
internal const val LOGIN_FALLBACK_PATH = "/_matrix/static/client/login/"
/**
* Path to use when the client does not supported any or all registration flows
* Not documented
*/
const val REGISTER_FALLBACK_PATH = "/_matrix/static/client/register/"
internal const val REGISTER_FALLBACK_PATH = "/_matrix/static/client/register/"
/**
* Path to use when the client want to connect using SSO
* Ref: https://matrix.org/docs/spec/client_server/latest#sso-client-login
*/
const val SSO_REDIRECT_PATH = "/_matrix/client/r0/login/sso/redirect"
internal const val SSO_REDIRECT_PATH = "/_matrix/client/r0/login/sso/redirect"
internal const val MSC2858_SSO_REDIRECT_PATH = "/_matrix/client/unstable/org.matrix.msc2858/login/sso/redirect"
const val SSO_REDIRECT_URL_PARAM = "redirectUrl"
internal const val SSO_REDIRECT_URL_PARAM = "redirectUrl"
// Ref: https://matrix.org/docs/spec/client_server/r0.6.1#single-sign-on
internal const val SSO_UIA_FALLBACK_PATH = "/_matrix/client/r0/auth/m.login.sso/fallback/web"

View File

@@ -34,6 +34,7 @@ import org.matrix.android.sdk.api.failure.Failure
import org.matrix.android.sdk.api.session.Session
import org.matrix.android.sdk.api.util.Cancelable
import org.matrix.android.sdk.api.util.NoOpCancellable
import org.matrix.android.sdk.api.util.appendParamToUrl
import org.matrix.android.sdk.internal.SessionManager
import org.matrix.android.sdk.internal.auth.data.LoginFlowResponse
import org.matrix.android.sdk.internal.auth.data.RiotConfig
@@ -99,6 +100,52 @@ internal class DefaultAuthenticationService @Inject constructor(
}
}
override fun getSsoUrl(redirectUrl: String, deviceId: String?, providerId: String?): String? {
val homeServerUrlBase = getHomeServerUrlBase() ?: return null
return buildString {
append(homeServerUrlBase)
if (providerId != null) {
append(MSC2858_SSO_REDIRECT_PATH)
append("/$providerId")
} else {
append(SSO_REDIRECT_PATH)
}
// Set the redirect url
appendParamToUrl(SSO_REDIRECT_URL_PARAM, redirectUrl)
deviceId?.takeIf { it.isNotBlank() }?.let {
// But https://github.com/matrix-org/synapse/issues/5755
appendParamToUrl("device_id", it)
}
}
}
override fun getFallbackUrl(forSignIn: Boolean, deviceId: String?): String? {
val homeServerUrlBase = getHomeServerUrlBase() ?: return null
return buildString {
append(homeServerUrlBase)
if (forSignIn) {
append(LOGIN_FALLBACK_PATH)
deviceId?.takeIf { it.isNotBlank() }?.let {
// But https://github.com/matrix-org/synapse/issues/5755
appendParamToUrl("device_id", it)
}
} else {
// For sign up
append(REGISTER_FALLBACK_PATH)
}
}
}
private fun getHomeServerUrlBase(): String? {
return pendingSessionData
?.homeServerConnectionConfig
?.homeServerUri
?.toString()
?.trim { it == '/' }
}
override fun getLoginFlow(homeServerConnectionConfig: HomeServerConnectionConfig, callback: MatrixCallback<LoginFlowResult>): Cancelable {
pendingSessionData = null

View File

@@ -42,6 +42,7 @@ internal data class LoginFlow(
* the client can show a button for each of the supported providers
* See MSC #2858
*/
@Json(name = "identity_providers")
val ssoIdentityProvider: List<SsoIdentityProvider>?
@Json(name = "org.matrix.msc2858.identity_providers")
val ssoIdentityProvider: List<SsoIdentityProvider>? = null
)

View File

@@ -24,6 +24,7 @@ import org.matrix.android.sdk.api.auth.data.LoginFlowTypes
import org.matrix.android.sdk.api.auth.registration.RegisterThreePid
import org.matrix.android.sdk.api.auth.registration.RegistrationResult
import org.matrix.android.sdk.api.auth.registration.RegistrationWizard
import org.matrix.android.sdk.api.auth.registration.toFlowResult
import org.matrix.android.sdk.api.failure.Failure
import org.matrix.android.sdk.api.failure.Failure.RegistrationFlowError
import org.matrix.android.sdk.api.util.Cancelable

View File

@@ -17,7 +17,7 @@
package org.matrix.android.sdk.internal.auth.registration
import android.os.Parcelable
import kotlinx.android.parcel.Parcelize
import kotlinx.parcelize.Parcelize
/**
* This class represent a localized privacy policy for registration Flow.

View File

@@ -0,0 +1,53 @@
/*
* Copyright 2020 The Matrix.org Foundation C.I.C.
*
* 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 org.matrix.android.sdk.internal.auth.registration
import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor
import org.matrix.android.sdk.api.failure.Failure
import org.matrix.android.sdk.api.failure.toRegistrationFlowResponse
import org.matrix.android.sdk.api.auth.UIABaseAuth
import timber.log.Timber
import kotlin.coroutines.suspendCoroutine
internal suspend fun handleUIA(failure: Throwable, interceptor: UserInteractiveAuthInterceptor, retryBlock: suspend (UIABaseAuth) -> Unit): Boolean {
Timber.d("## UIA: check error ${failure.message}")
val flowResponse = failure.toRegistrationFlowResponse()
?: return false.also {
Timber.d("## UIA: not a UIA error")
}
Timber.d("## UIA: error can be passed to interceptor")
Timber.d("## UIA: type = ${flowResponse.flows}")
Timber.d("## UIA: delegate to interceptor...")
val authUpdate = try {
suspendCoroutine<UIABaseAuth> { continuation ->
interceptor.performStage(flowResponse, (failure as? Failure.ServerError)?.error?.code, continuation)
}
} catch (failure: Throwable) {
Timber.w(failure, "## UIA: failed to participate")
return false
}
Timber.d("## UIA: updated auth $authUpdate")
return try {
retryBlock(authUpdate)
true
} catch (failure: Throwable) {
handleUIA(failure, interceptor, retryBlock)
}
}

View File

@@ -19,7 +19,6 @@ package org.matrix.android.sdk.internal.crypto
import android.content.Context
import androidx.work.WorkerParameters
import com.squareup.moshi.JsonClass
import org.greenrobot.eventbus.EventBus
import org.matrix.android.sdk.api.auth.data.Credentials
import org.matrix.android.sdk.api.failure.shouldBeRetried
import org.matrix.android.sdk.api.session.events.model.Event
@@ -60,7 +59,6 @@ internal class CancelGossipRequestWorker(context: Context,
@Inject lateinit var sendToDeviceTask: SendToDeviceTask
@Inject lateinit var cryptoStore: IMXCryptoStore
@Inject lateinit var eventBus: EventBus
@Inject lateinit var credentials: Credentials
override fun injectWith(injector: SessionComponent) {

View File

@@ -30,6 +30,7 @@ import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext
import org.matrix.android.sdk.api.MatrixCallback
import org.matrix.android.sdk.api.NoOpMatrixCallback
import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor
import org.matrix.android.sdk.api.crypto.MXCryptoConfig
import org.matrix.android.sdk.api.extensions.tryOrNull
import org.matrix.android.sdk.api.failure.Failure
@@ -207,9 +208,9 @@ internal class DefaultCryptoService @Inject constructor(
.executeBy(taskExecutor)
}
override fun deleteDevice(deviceId: String, callback: MatrixCallback<Unit>) {
override fun deleteDevice(deviceId: String, userInteractiveAuthInterceptor: UserInteractiveAuthInterceptor, callback: MatrixCallback<Unit>) {
deleteDeviceTask
.configureWith(DeleteDeviceTask.Params(deviceId)) {
.configureWith(DeleteDeviceTask.Params(deviceId, userInteractiveAuthInterceptor, null)) {
this.executionThread = TaskThread.CRYPTO
this.callback = callback
}

View File

@@ -32,6 +32,7 @@ import org.matrix.android.sdk.internal.crypto.crosssigning.toBase64NoPadding
import org.matrix.android.sdk.internal.crypto.keysbackup.util.extractCurveKeyFromRecoveryKey
import org.matrix.android.sdk.internal.crypto.model.rest.GossipingDefaultContent
import org.matrix.android.sdk.internal.crypto.model.rest.GossipingToDeviceObject
import org.matrix.android.sdk.internal.crypto.model.rest.RoomKeyRequestBody
import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore
import org.matrix.android.sdk.internal.di.SessionId
import org.matrix.android.sdk.internal.session.SessionScope
@@ -206,34 +207,7 @@ internal class IncomingGossipingRequestManager @Inject constructor(
Timber.v("## CRYPTO | GOSSIP processIncomingRoomKeyRequest from $userId:$deviceId for $roomId / ${body.sessionId} id ${request.requestId}")
if (credentials.userId != userId) {
Timber.w("## CRYPTO | GOSSIP processReceivedGossipingRequests() : room key request from other user")
val senderKey = body.senderKey ?: return Unit
.also { Timber.w("missing senderKey") }
.also { cryptoStore.updateGossipingRequestState(request, GossipingRequestState.REJECTED) }
val sessionId = body.sessionId ?: return Unit
.also { Timber.w("missing sessionId") }
.also { cryptoStore.updateGossipingRequestState(request, GossipingRequestState.REJECTED) }
if (alg != MXCRYPTO_ALGORITHM_MEGOLM) {
return Unit
.also { Timber.w("Only megolm is accepted here") }
.also { cryptoStore.updateGossipingRequestState(request, GossipingRequestState.REJECTED) }
}
val roomEncryptor = roomEncryptorsStore.get(roomId) ?: return Unit
.also { Timber.w("no room Encryptor") }
.also { cryptoStore.updateGossipingRequestState(request, GossipingRequestState.REJECTED) }
cryptoCoroutineScope.launch(coroutineDispatchers.crypto) {
val isSuccess = roomEncryptor.reshareKey(sessionId, userId, deviceId, senderKey)
if (isSuccess) {
cryptoStore.updateGossipingRequestState(request, GossipingRequestState.ACCEPTED)
} else {
cryptoStore.updateGossipingRequestState(request, GossipingRequestState.UNABLE_TO_PROCESS)
}
}
cryptoStore.updateGossipingRequestState(request, GossipingRequestState.RE_REQUESTED)
handleKeyRequestFromOtherUser(body, request, alg, roomId, userId, deviceId)
return
}
// TODO: should we queue up requests we don't yet have keys for, in case they turn up later?
@@ -291,6 +265,42 @@ internal class IncomingGossipingRequestManager @Inject constructor(
onRoomKeyRequest(request)
}
private fun handleKeyRequestFromOtherUser(body: RoomKeyRequestBody,
request: IncomingRoomKeyRequest,
alg: String,
roomId: String,
userId: String,
deviceId: String) {
Timber.w("## CRYPTO | GOSSIP processReceivedGossipingRequests() : room key request from other user")
val senderKey = body.senderKey ?: return Unit
.also { Timber.w("missing senderKey") }
.also { cryptoStore.updateGossipingRequestState(request, GossipingRequestState.REJECTED) }
val sessionId = body.sessionId ?: return Unit
.also { Timber.w("missing sessionId") }
.also { cryptoStore.updateGossipingRequestState(request, GossipingRequestState.REJECTED) }
if (alg != MXCRYPTO_ALGORITHM_MEGOLM) {
return Unit
.also { Timber.w("Only megolm is accepted here") }
.also { cryptoStore.updateGossipingRequestState(request, GossipingRequestState.REJECTED) }
}
val roomEncryptor = roomEncryptorsStore.get(roomId) ?: return Unit
.also { Timber.w("no room Encryptor") }
.also { cryptoStore.updateGossipingRequestState(request, GossipingRequestState.REJECTED) }
cryptoCoroutineScope.launch(coroutineDispatchers.crypto) {
val isSuccess = roomEncryptor.reshareKey(sessionId, userId, deviceId, senderKey)
if (isSuccess) {
cryptoStore.updateGossipingRequestState(request, GossipingRequestState.ACCEPTED)
} else {
cryptoStore.updateGossipingRequestState(request, GossipingRequestState.UNABLE_TO_PROCESS)
}
}
cryptoStore.updateGossipingRequestState(request, GossipingRequestState.RE_REQUESTED)
}
private fun processIncomingSecretShareRequest(request: IncomingSecretShareRequest) {
val secretName = request.secretName ?: return Unit.also {
cryptoStore.updateGossipingRequestState(request, GossipingRequestState.REJECTED)

Some files were not shown because too many files have changed in this diff Show More