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

Compare commits

...

384 Commits

Author SHA1 Message Date
Onuray Sahin
6c91fa54e7 Merge branch 'develop' into feature/fix_draw_large_bitmap 2021-01-06 13:08:33 +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
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
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
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
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
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
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
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
Onuray Sahin
526320f4e3 Fix typo. 2020-12-21 11:58:38 +03:00
Onuray Sahin
5c67b3b216 Merge branch 'develop' into feature/fix_draw_large_bitmap 2020-12-21 11:56:02 +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
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
Onuray Sahin
d03521d153 Set image width as maximum as possible. 2020-12-18 16:24:52 +03:00
Onuray Sahin
d520f7a5d4 Merge branch 'develop' into feature/fix_draw_large_bitmap
* develop: (1406 commits)
  Version++
  Prepare release 1.0.13
  Typo in comment
  Improve redirect url, which can be visible to the user: "element://element" -> "element://connect"
  Fix compilation issue
  Add changelog
  Make MSC2858 implementation match the unstable policy of the spec
  Version++
  Prepare release 1.0.12
  /confetti /snow commands: send emote if text is blank (iso Element Web)
  Import SAS strings
  Ensure the message is understood as a debug indication (#2509)
  Add /snow command
  PR Review
  Chat Effects
  Remove bad translation
  Translated using Weblate (French)
  Translated using Weblate (Albanian)
  Translated using Weblate (Ukrainian)
  Translated using Weblate (Albanian)
  ...

# Conflicts:
#	CHANGES.md
2020-12-18 14:49:47 +03:00
Benoit Marty
0518e5f18d Version++ 2020-12-18 11:03:01 +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
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
Benoit Marty
e230cd8ee3 Prepare release 1.0.12 2020-12-15 14:16:08 +01:00
Benoit Marty
45225e883e Merge pull request #2539 from vector-im/feature/bma/cleanup
Small cleanup before the release
2020-12-15 14:11:31 +01:00
Benoit Marty
bb9a08d429 /confetti /snow commands: send emote if text is blank (iso Element Web) 2020-12-15 12:19:31 +01:00
Benoit Marty
6ddcd046d4 Import SAS strings 2020-12-15 12:19:31 +01:00
Benoit Marty
88a4dfd094 Ensure the message is understood as a debug indication (#2509) 2020-12-15 12:19:31 +01:00
Benoit Marty
7828e3f501 Merge pull request #2485 from vector-im/feature/ons/fix_hide_state_events
Fix UTD when hiding member state events.
2020-12-15 12:16:27 +01:00
Benoit Marty
b4b302c1f2 Merge pull request #2535 from vector-im/feature/bca/confetti
Chat Effects XMAS PR ❄️ 🎉
2020-12-15 11:41:29 +01:00
Benoit Marty
487ef870f9 Add /snow command 2020-12-15 10:56:05 +01:00
Benoit Marty
6957768567 PR Review 2020-12-15 10:21:12 +01:00
Valere
7da8b13cde Chat Effects 2020-12-15 09:39:16 +01:00
Benoit Marty
a027ef29e5 Merge pull request #2484 from vector-im/feature/bca/social_login
Social Login
2020-12-14 18:19:23 +01:00
Benoit Marty
211c158e23 Remove bad translation 2020-12-14 17:42:52 +01:00
Benoit Marty
338650cea7 Merge pull request #2537 from RiotTranslateBot/weblate-element-android-element-app
Translations update from Weblate
2020-12-14 17:37:51 +01:00
Benoit Marty
2d4eeb64c5 Translated using Weblate (French)
Currently translated at 98.2% (1982 of 2018 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/fr/
2020-12-14 16:37:12 +00:00
Benoit Marty
4f98031c6d Merge pull request #2536 from RiotTranslateBot/weblate-element-android-element-app
Translations update from Weblate
2020-12-14 17:27:10 +01:00
Weblate
3813f6d659 Merge branch 'origin/develop' into Weblate. 2020-12-14 15:45:20 +00:00
Besnik Bleta
6687a74f5c Translated using Weblate (Albanian)
Currently translated at 98.0% (206 of 210 strings)

Translation: Element Android/Element Android Sdk
Translate-URL: https://translate.element.io/projects/element-android/element-sdk/sq/
2020-12-14 15:35:36 +00:00
Ihor Hordiichuk
545e13c843 Translated using Weblate (Ukrainian)
Currently translated at 48.0% (955 of 1986 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/uk/
2020-12-14 15:35:35 +00:00
Besnik Bleta
995ec25990 Translated using Weblate (Albanian)
Currently translated at 99.4% (1975 of 1986 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/sq/
2020-12-14 15:35:35 +00:00
Benoit Marty
09040b7095 Clear history (#1933) 2020-12-14 16:22:22 +01:00
Benoit Marty
5a69b33600 Move style for social login to a dedicated file 2020-12-14 15:53:16 +01:00
Benoit Marty
c8c4e10822 Cleanup layout 2020-12-14 15:46:31 +01:00
Benoit Marty
2f616cb6c5 Add some constants 2020-12-14 15:41:33 +01:00
Benoit Marty
776d7699bc Do not modify the DB in debug mode, and add to history only if valid 2020-12-14 15:33:32 +01:00
Benoit Marty
f3578e2538 Cleanup 2020-12-14 15:17:07 +01:00
Benoit Marty
8022430f0d Remove useless override 2020-12-14 15:14:46 +01:00
Benoit Marty
eb72d0c6d3 Revert formatting change 2020-12-14 15:13:08 +01:00
Benoit Marty
ae29cbdc34 Better name 2020-12-14 15:11:02 +01:00
Benoit Marty
cf59c7db95 Cleanup 2020-12-14 15:09:10 +01:00
Benoit Marty
924fac84b2 Move HomeServerHistoryService binding to AuthModule 2020-12-14 15:08:09 +01:00
Benoit Marty
db0a958708 Fix crash in Realm migration 2020-12-14 14:53:29 +01:00
Benoit Marty
b31dfcfe4f IdentityProvider -> SsoIdentityProvider 2020-12-14 14:32:20 +01:00
Benoit Marty
bba2daf0fc Capital H for GitHub 2020-12-14 14:13:50 +01:00
Benoit Marty
23e05200b5 Social login: cleanup 2020-12-14 14:13:36 +01:00
Valere
0fd8641cf6 Fix copyright + lint 2020-12-14 14:05:57 +01:00
Valere
26c01d46a7 Code review + Completion layout res 2020-12-14 14:05:57 +01:00
Valere
42d1bf57f6 Refactor + fix sso in LoginFragment 2020-12-14 14:05:57 +01:00
Valere
351793d456 Fix / support sso_with_password flow when no providers 2020-12-14 14:05:57 +01:00
Valere
03428ea9f5 Social Login
And new custom homeserver completion (and remember history)
2020-12-14 14:05:57 +01:00
Onuray Sahin
b321838502 Merge branch 'develop' into feature/ons/fix_hide_state_events 2020-12-14 12:03:49 +03:00
Ihor Hordiichuk
b915c91c86 Translated using Weblate (Ukrainian)
Currently translated at 28.0% (59 of 210 strings)

Translation: Element Android/Element Android Sdk
Translate-URL: https://translate.element.io/projects/element-android/element-sdk/uk/
2020-12-13 14:35:36 +00:00
strix aluco
f83b478008 Translated using Weblate (Ukrainian)
Currently translated at 48.0% (955 of 1986 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/uk/
2020-12-13 14:35:36 +00:00
Ihor Hordiichuk
2bdb425085 Translated using Weblate (Ukrainian)
Currently translated at 48.0% (955 of 1986 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/uk/
2020-12-13 14:35:36 +00:00
Nikita Epifanov
45a0586329 Translated using Weblate (Russian)
Currently translated at 100.0% (1986 of 1986 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/ru/
2020-12-13 14:35:33 +00:00
Ihor Hordiichuk
74283e7d50 Translated using Weblate (Ukrainian)
Currently translated at 45.7% (908 of 1986 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/uk/
2020-12-13 00:55:11 +00:00
AlexanderLevchenkoTechs
6f4c307854 Translated using Weblate (Ukrainian)
Currently translated at 45.2% (898 of 1986 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/uk/
2020-12-13 00:34:33 +00:00
Ihor Hordiichuk
69cd0e3ea2 Translated using Weblate (Ukrainian)
Currently translated at 45.2% (898 of 1986 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/uk/
2020-12-13 00:34:31 +00:00
AlexanderLevchenkoTechs
a5094f97d5 Translated using Weblate (Ukrainian)
Currently translated at 43.1% (857 of 1986 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/uk/
2020-12-11 22:07:47 +00:00
Benoit Marty
163c05d5cf Merge pull request #2526 from vector-im/feature/bca/fix_mxto
element:// support + basic peeking + fix join via server
2020-12-11 21:44:06 +01:00
Benoit Marty
903936368d Merge branch 'develop' into feature/bca/fix_mxto 2020-12-11 21:43:56 +01:00
Benoit Marty
3eba43f3fa Merge pull request #2500 from aqulu/feature/state_service_coroutines
Convert StateService to suspend functions
2020-12-11 18:04:25 +01:00
Valere
d8a1939c69 Fix number of enum 2020-12-11 17:50:59 +01:00
Benoit Marty
5b74eb3bca Merge branch 'develop' into feature/state_service_coroutines 2020-12-11 16:54:41 +01:00
Benoit Marty
071611b81c We are not supposed to fallback on alternative alias 2020-12-11 16:38:22 +01:00
Benoit Marty
5461fd4060 Some cleanup up 2020-12-11 16:35:04 +01:00
Benoit Marty
5203d15409 Merge pull request #2490 from vector-im/feature/bma/url_preview
Url preview
2020-12-11 15:39:58 +01:00
Benoit Marty
989f1c6268 Merge branch 'develop' into feature/bma/url_preview 2020-12-11 15:39:20 +01:00
Valere
544345bbf3 Update change log 2020-12-11 15:16:10 +01:00
Valere
bd9da8eaa6 element:// support + basic peeking + fix join via server 2020-12-11 15:06:39 +01:00
Benoit Marty
68a5ba9a01 Merge pull request #2524 from vector-im/feature/bma/fix_rtl
Fix rtl
2020-12-11 14:06:33 +01:00
Benoit Marty
ed9ae07e52 Merge pull request #2475 from vector-im/feature/bma/gif_from_keyboard_preview
Feature/bma/gif from keyboard preview
2020-12-11 14:05:13 +01:00
Benoit Marty
9b0c2e420d Reorder Views (no other change) 2020-12-11 13:18:22 +01:00
Onuray Sahin
60aaa2a39c Code review fixes. 2020-12-11 15:08:32 +03:00
Benoit Marty
8d30658fa5 Bigger touch area for the other buttons 2020-12-11 12:46:44 +01:00
Benoit Marty
32fd3be732 Better alignment of button and animation, bigger touch area for send button 2020-12-11 12:41:35 +01:00
Benoit Marty
705b6176f1 Fix Layout issue (visible only on RTL) (#2523) 2020-12-11 12:17:23 +01:00
Benoit Marty
d996c77c03 Fix typo 2020-12-11 12:09:08 +01:00
Benoit Marty
49cad8feec Rename files. 2020-12-11 11:49:46 +01:00
Benoit Marty
ca75eae0aa Create MimeTypes object 2020-12-11 11:24:42 +01:00
Benoit Marty
21271b6510 Do not compress GIFs (#1616, #1254) 2020-12-11 11:22:36 +01:00
Benoit Marty
439029467a Attachment preview also for Gif files 2020-12-11 11:22:36 +01:00
Benoit Marty
eb30b9fae9 Show preview when sending attachment from the keyboard (#2440)
It's actually a revert of a3b205b310
2020-12-11 11:22:36 +01:00
Benoit Marty
38843f74ab No need for WRITE_EXTERNAL permission to send attachment to the app (anymore?) 2020-12-11 11:21:49 +01:00
Benoit Marty
91c86c1a45 Merge branch 'develop' into feature/bma/url_preview 2020-12-11 09:47:57 +01:00
Benoit Marty
5541c2e190 Merge pull request #2512 from vector-im/feature/bma/fix_span
Improve management of files
2020-12-11 09:46:44 +01:00
Benoit Marty
f2ba236130 Merge branch 'develop' into feature/bma/fix_span 2020-12-11 09:46:36 +01:00
Jadran Prodan
4cb7754b77 Translated using Weblate (Slovenian)
Currently translated at 0.3% (7 of 1986 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/sl/
2020-12-11 07:35:34 +00:00
Nikita Epifanov
3473a7ef5e Translated using Weblate (Russian)
Currently translated at 100.0% (210 of 210 strings)

Translation: Element Android/Element Android Sdk
Translate-URL: https://translate.element.io/projects/element-android/element-sdk/ru/
2020-12-11 07:35:33 +00:00
Nikita Epifanov
c9535509e8 Translated using Weblate (Russian)
Currently translated at 100.0% (1986 of 1986 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/ru/
2020-12-11 07:35:33 +00:00
Hivaa
3d578c147c Translated using Weblate (Persian)
Currently translated at 100.0% (1986 of 1986 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/fa/
2020-12-11 07:35:33 +00:00
Benoit Marty
43ac66feb3 Merge pull request #2514 from vector-im/feature/ons/emoji_keyboard
Emoji Keyboard
2020-12-10 17:13:43 +01:00
Benoit Marty
5e2f091ec1 Remove useless parameter id 2020-12-10 13:36:00 +01:00
Onuray Sahin
752bde413d Fix copyright. 2020-12-10 13:47:23 +03:00
Jadran Prodan
e6949c85fb Added translation using Weblate (Slovenian) 2020-12-10 10:28:31 +00:00
Onuray Sahin
c1cb23d728 Fix ripple effect of the send button. 2020-12-10 13:12:19 +03:00
Onuray Sahin
4007982db6 Changelog added. 2020-12-10 12:59:09 +03:00
Onuray Sahin
a9f5ed3869 Add emoji license. 2020-12-10 12:56:09 +03:00
Onuray Sahin
08964d8548 Fix emoji keyboard orientation bug. 2020-12-10 12:51:15 +03:00
Mitja Sorsa
5186ee6e43 Translated using Weblate (Finnish)
Currently translated at 100.0% (4 of 4 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/fi/
2020-12-09 16:15:50 +00:00
Mitja Sorsa
c2fc9fe0ee Translated using Weblate (Finnish)
Currently translated at 73.8% (155 of 210 strings)

Translation: Element Android/Element Android Sdk
Translate-URL: https://translate.element.io/projects/element-android/element-sdk/fi/
2020-12-09 16:15:49 +00:00
Uumas
280d3f22a7 Translated using Weblate (Finnish)
Currently translated at 80.2% (1593 of 1986 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/fi/
2020-12-09 16:15:48 +00:00
Mitja Sorsa
a19ca8a820 Translated using Weblate (Finnish)
Currently translated at 80.2% (1593 of 1986 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/fi/
2020-12-09 16:15:48 +00:00
@a2sc:matrix.org
7ba1116349 Translated using Weblate (German)
Currently translated at 98.1% (1949 of 1986 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/de/
2020-12-09 16:15:47 +00:00
Onuray Sahin
e8862b3aaa Add emoji keyboard, remove profile picture from composer. 2020-12-09 18:48:14 +03:00
Onuray Sahin
a96cc19eb6 Update composer layout by adding emoji icon. 2020-12-09 18:47:34 +03:00
Onuray Sahin
3d975b7fba Update composer icons. 2020-12-09 18:46:33 +03:00
Onuray Sahin
d54571d0a6 Emoji library added with Google style. 2020-12-09 18:45:33 +03:00
Benoit Marty
75071cf1d9 Cleanup 2020-12-09 13:50:14 +01:00
Benoit Marty
4bd538e448 Changelog and update comment 2020-12-09 12:49:25 +01:00
Benoit Marty
0956baecf9 Delete unencrypted files each time the app is started 2020-12-09 12:27:37 +01:00
Benoit Marty
e4968c4119 Doc and internal 2020-12-09 12:27:03 +01:00
Benoit Marty
283e10dfef Use filename if available 2020-12-09 12:26:49 +01:00
Benoit Marty
1c43f92e49 DefaultFileService: store just sent file 2020-12-09 12:26:27 +01:00
Benoit Marty
ca7796114c DefaultFileService: better management of the files and the filenames 2020-12-09 10:50:21 +01:00
aqulu
ed822becc6 Fix try-catch behavior of sendStateEvent actions
Signed-off-by: aqulu <dev@aqu.lu>
2020-12-09 08:39:00 +09:00
Benoit Marty
7057b2970b Improve FileService API: add facility methods to deal with MessageWithAttachment object 2020-12-08 19:31:29 +01:00
Benoit Marty
62791e4b36 Encrypted files: store decrypted file in a dedicated folder 2020-12-08 18:35:17 +01:00
Benoit Marty
237cb63fc2 Small formatting 2020-12-08 18:04:42 +01:00
Benoit Marty
42ab7f1b4f Add space between image and text
And remove useless `apply` block
2020-12-08 17:42:42 +01:00
Benoit Marty
8e11ba21ed Glide: No Disk cache for encrypted images 2020-12-08 17:37:24 +01:00
Benoit Marty
24a9ddaa5e FileService: remove useless FileService.DownloadMode 2020-12-08 17:25:37 +01:00
random
6190fb3511 Translated using Weblate (Italian)
Currently translated at 100.0% (210 of 210 strings)

Translation: Element Android/Element Android Sdk
Translate-URL: https://translate.element.io/projects/element-android/element-sdk/it/
2020-12-08 15:50:10 +00:00
Kaede
2d9043fbed Translated using Weblate (Japanese)
Currently translated at 50.1% (996 of 1986 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/
2020-12-08 15:50:10 +00:00
random
682dff9c1c Translated using Weblate (Italian)
Currently translated at 100.0% (1986 of 1986 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/it/
2020-12-08 15:50:09 +00:00
Jeanne Lavoie
9339b7e31d Translated using Weblate (French)
Currently translated at 100.0% (1986 of 1986 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/fr/
2020-12-08 15:50:09 +00:00
OLIVIER Thomas
7667ef686d Translated using Weblate (French)
Currently translated at 100.0% (1986 of 1986 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/fr/
2020-12-08 15:50:07 +00:00
Uumas
4d4fe687ac Translated using Weblate (Finnish)
Currently translated at 79.9% (1587 of 1986 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/fi/
2020-12-08 15:50:07 +00:00
Benoit Marty
7152dead1d Rename method 2020-12-08 16:47:29 +01:00
aqulu
40b9f03132 Remove explicit coroutine context changes
Signed-off-by: aqulu <dev@aqu.lu>
2020-12-08 22:25:28 +09:00
aqulu
19d421df84 Remove coroutine context change for sendStateEvent
Signed-off-by: aqulu <dev@aqu.lu>
2020-12-08 22:25:28 +09:00
aqulu
c889deaab1 Remove unused imports
Signed-off-by: aqulu <dev@aqu.lu>
2020-12-08 22:25:28 +09:00
aqulu
416f57b1d7 Fix failing test compilation
Signed-off-by: aqulu <dev@aqu.lu>
2020-12-08 22:25:19 +09:00
Benoit Marty
dda2685bd8 Upgrade Realm dependency to 10.1.2 2020-12-08 13:45:30 +01:00
Benoit Marty
b43f3b3b6a Log some details about the request which has failed 2020-12-08 13:44:42 +01:00
Benoit Marty
a0c8a8e97c Log HTTP requests and responses in production (level BASIC, i.e. without any private data) 2020-12-08 13:44:42 +01:00
Benoit Marty
28bfea6af0 This code is for debug build (see the path), so no need to check again 2020-12-08 13:44:42 +01:00
Benoit Marty
f3bc39a0c5 Cleanup 2020-12-08 13:44:42 +01:00
aqulu
c7efd1feb9 Convert StateService to suspend functions
Signed-off-by: aqulu <dev@aqu.lu>
2020-12-08 19:21:10 +09:00
Benoit Marty
c31d368d0d Merge pull request #2468 from vector-im/feature/bma/fix_cancel
Fix cancellation of event sending not always working
2020-12-07 12:41:48 +01:00
Benoit Marty
5237eb0638 Merge branch 'develop' into feature/bma/fix_cancel 2020-12-07 12:41:37 +01:00
Benoit Marty
7869d731d4 Fix the rotate screen issue 2020-12-07 10:38:34 +01:00
Benoit Marty
c603ec0b38 Format files 2020-12-07 09:55:11 +01:00
random
555bf1f0ae Translated using Weblate (Italian)
Currently translated at 100.0% (4 of 4 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/it/
2020-12-06 14:50:09 +00:00
zeritti
8bdf384563 Translated using Weblate (Czech)
Currently translated at 100.0% (210 of 210 strings)

Translation: Element Android/Element Android Sdk
Translate-URL: https://translate.element.io/projects/element-android/element-sdk/cs/
2020-12-06 14:50:08 +00:00
random
19524eaa82 Translated using Weblate (Italian)
Currently translated at 100.0% (1986 of 1986 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/it/
2020-12-06 14:50:08 +00:00
Hivaa
9bbae825e2 Translated using Weblate (Persian)
Currently translated at 100.0% (1986 of 1986 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/fa/
2020-12-06 14:50:05 +00:00
@a2sc:matrix.org
3e9cb987a1 Translated using Weblate (German)
Currently translated at 90.4% (190 of 210 strings)

Translation: Element Android/Element Android Sdk
Translate-URL: https://translate.element.io/projects/element-android/element-sdk/de/
2020-12-04 17:50:05 +00:00
Nikita Epifanov
dacb9cd86c Translated using Weblate (Russian)
Currently translated at 99.8% (1983 of 1986 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/ru/
2020-12-04 17:50:05 +00:00
Hivaa
b9d7333998 Translated using Weblate (Persian)
Currently translated at 100.0% (1986 of 1986 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/fa/
2020-12-04 17:50:04 +00:00
@a2sc:matrix.org
e14b507b27 Translated using Weblate (German)
Currently translated at 97.3% (1933 of 1986 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/de/
2020-12-04 17:50:04 +00:00
Benoit Marty
431ac5aa2d Fix layout issue 2020-12-04 15:23:59 +01:00
Benoit Marty
78fe7e5c16 No need to create a Set to remove an item from it 2020-12-04 14:56:26 +01:00
Benoit Marty
c2c9e37a36 PreviewUrl: fix layout issue and add more tests 2020-12-04 14:36:11 +01:00
Benoit Marty
5d3682cd44 More cleanup 2020-12-04 14:19:36 +01:00
Benoit Marty
2a19726e49 Cleanup and changelog 2020-12-04 14:19:24 +01:00
Benoit Marty
c08c652080 PreviewUrl: handle close (in memory) 2020-12-04 12:41:26 +01:00
Benoit Marty
9089c54990 Ripple effect 2020-12-04 11:53:37 +01:00
Benoit Marty
679d9bae1c Fix bad image rendering 2020-12-04 11:45:05 +01:00
Benoit Marty
19315fc65e PreviewUrl: handle click 2020-12-04 11:08:06 +01:00
Benoit Marty
770041eceb PreviewUrl: setting and e2e room 2020-12-04 09:48:48 +01:00
Benoit Marty
1161dcb299 PreviewUrl: protocol is mandatory (exclude rstp://) 2020-12-04 08:31:14 +01:00
Benoit Marty
fa7b0a24a7 PreviewUrl: Application part - bugfix 2020-12-04 08:01:00 +01:00
Benoit Marty
48354c7793 PreviewUrl: Application part - WIP 2020-12-04 07:46:09 +01:00
Benoit Marty
fcd9fe7d5a PreviewUrl: layout for a single PreviewUrl 2020-12-03 19:32:49 +01:00
Benoit Marty
a36d5684b8 Create extension for androidx.collection.LruCache 2020-12-03 19:09:33 +01:00
Benoit Marty
be20f9b455 PreviewUrl: extract url from Content 2020-12-03 19:09:33 +01:00
Benoit Marty
dd150c6d7e Remove unnecessary non-null assertion 2020-12-03 19:09:33 +01:00
Benoit Marty
bd5ac514ef PreviewUrl: create the task and the service 2020-12-03 19:09:33 +01:00
LinAGKar
bd926fa74b Translated using Weblate (Swedish)
Currently translated at 100.0% (4 of 4 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/sv/
2020-12-03 14:50:05 +00:00
Hivaa
167144b504 Translated using Weblate (Persian)
Currently translated at 91.9% (193 of 210 strings)

Translation: Element Android/Element Android Sdk
Translate-URL: https://translate.element.io/projects/element-android/element-sdk/fa/
2020-12-03 14:50:05 +00:00
LinAGKar
5faaabf2f4 Translated using Weblate (Swedish)
Currently translated at 97.3% (1933 of 1986 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/sv/
2020-12-03 14:50:05 +00:00
Keij0
1933fc948c Translated using Weblate (Polish)
Currently translated at 76.8% (1526 of 1986 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/pl/
2020-12-03 14:50:04 +00:00
quidje
83df430d17 Translated using Weblate (Dutch)
Currently translated at 55.6% (1106 of 1986 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/nl/
2020-12-03 14:50:04 +00:00
Hivaa
ec60d7d0b6 Translated using Weblate (Persian)
Currently translated at 100.0% (1986 of 1986 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/fa/
2020-12-03 14:50:04 +00:00
Benoit Marty
f9ccb0e8de Translated using Weblate (Spanish)
Currently translated at 97.2% (1932 of 1986 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/es/
2020-12-03 14:50:04 +00:00
Benoit Marty
1109d9f88a PreviewUrl create DB object and handle migration 2020-12-03 14:45:20 +01:00
Onuray Sahin
32b7cc64fb Changelog added.
Fixes #2486
2020-12-03 16:19:37 +03:00
Onuray Sahin
a6724b5f75 EventTypeFilter implementation to allow hiding member events. 2020-12-03 16:10:50 +03:00
Benoit Marty
8a35bfcc31 Rework: rename files using the interface name and not the implementation name 2020-12-03 13:57:47 +01:00
Benoit Marty
0c037184f8 Create a MediaService to handle UrlPreview request - WIP 2020-12-03 13:46:25 +01:00
Benoit Marty
3e563a37a2 Rework: Make RawCacheStrategy class more generic, to use it for other SDK API 2020-12-03 13:43:04 +01:00
Hivaa
e5cbf9e3a3 Translated using Weblate (Persian)
Currently translated at 100.0% (1986 of 1986 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/fa/
2020-12-03 11:10:27 +00:00
Benoit Marty
cafe86e675 Rework: create a MediaModule 2020-12-03 09:56:26 +01:00
Benoit Marty
a911492a9e Merge pull request #2481 from vector-im/feature/bma/upgrade
Upgrade of some library + cleanup
2020-12-03 09:50:43 +01:00
Benoit Marty
d889598b20 Fix DefaultLocale lint issue 2020-12-02 17:04:54 +01:00
Benoit Marty
c4577f28b2 Remove unnecessary dependency (we have -ktx dependency) 2020-12-02 16:43:52 +01:00
Benoit Marty
f5af15454e Create a generic class for ViewModel 2020-12-02 15:47:21 +01:00
Benoit Marty
ee96d5c68f Remove useless Factories 2020-12-02 15:41:31 +01:00
Benoit Marty
6c56b5f45b Fix warnings after library upgrade 2020-12-02 14:39:33 +01:00
Benoit Marty
1058bfecf4 Kotlinification 2020-12-02 13:54:59 +01:00
Benoit Marty
f0afd5ceea Update deprecated code 2020-12-02 13:49:07 +01:00
Benoit Marty
9881c9f61c Fix compilation issue after library upgrade 2020-12-02 13:34:34 +01:00
Benoit Marty
89a7ec6d4b Use fragment-ktx and preference-ktx dependencies (fix lint issue KtxExtensionAvailable) 2020-12-02 12:46:15 +01:00
Benoit Marty
c426364618 Remove unused dependencies 2020-12-02 12:45:31 +01:00
Benoit Marty
cc5264a587 Try to clarify the code 2020-12-02 12:38:07 +01:00
Benoit Marty
42bc4d2445 Upgrade some dependencies and Kotlin version 2020-12-02 12:09:56 +01:00
Benoit Marty
2cc5d46cd3 Merge pull request #2474 from vector-im/feature/bma/remove_status_theme
Remove Status theme
2020-12-02 11:43:23 +01:00
Benoit Marty
3feb67ad32 Merge pull request #2470 from vector-im/feature/ons/fix_text_input_cursor
Move cursor to the end to fix the jumping cursor bug.
2020-12-02 11:23:53 +01:00
Benoit Marty
aa6c7afbbd Remove Status theme and handle migration or current status theme to light theme (#2424) 2020-12-01 16:20:11 +01:00
Benoit Marty
c6ba296028 Create an extension to apply the fix at several places 2020-12-01 14:50:13 +01:00
Benoit Marty
51b86e21f6 Merge pull request #2458 from vector-im/feature/bma/room_history_join_rule
Room setting: improve room history and add join rule
2020-12-01 14:18:52 +01:00
Jeff Huang
04914be442 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (4 of 4 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/zh_Hant/
2020-12-01 12:50:16 +00:00
strix aluco
3133935063 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (4 of 4 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/uk/
2020-12-01 12:50:15 +00:00
Jeff Huang
088608011b Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (210 of 210 strings)

Translation: Element Android/Element Android Sdk
Translate-URL: https://translate.element.io/projects/element-android/element-sdk/zh_Hant/
2020-12-01 12:50:15 +00:00
Nikita Epifanov
6d0f9baba4 Translated using Weblate (Russian)
Currently translated at 92.8% (195 of 210 strings)

Translation: Element Android/Element Android Sdk
Translate-URL: https://translate.element.io/projects/element-android/element-sdk/ru/
2020-12-01 12:50:15 +00:00
Jeff Huang
3b21400bb8 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (1986 of 1986 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/zh_Hant/
2020-12-01 12:50:15 +00:00
sr093906
1c3a279b8a Translated using Weblate (Chinese (Simplified))
Currently translated at 96.7% (1921 of 1986 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/zh_Hans/
2020-12-01 12:50:12 +00:00
HolgerHuo
6236b01189 Translated using Weblate (Chinese (Simplified))
Currently translated at 96.7% (1921 of 1986 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/zh_Hans/
2020-12-01 12:50:12 +00:00
Nikita Epifanov
e42906f08a Translated using Weblate (Russian)
Currently translated at 99.3% (1973 of 1986 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/ru/
2020-12-01 12:50:11 +00:00
Kaede
b53ba2b98e Translated using Weblate (Japanese)
Currently translated at 49.8% (991 of 1986 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/ja/
2020-12-01 12:50:09 +00:00
Danial Behzadi
7bd8d54d5c Translated using Weblate (Persian)
Currently translated at 99.4% (1976 of 1986 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/fa/
2020-12-01 12:50:07 +00:00
Benoit Marty
c785ea63e7 Update Change after release 2020-11-30 17:53:31 +01:00
Benoit Marty
b78f1dbb93 Hide the icon area if there is no icon to display 2020-11-30 17:52:16 +01:00
Benoit Marty
056b9df65e Add title to the new two bottom sheets 2020-11-30 17:52:16 +01:00
Benoit Marty
589c301606 Fix bad copyright 2020-11-30 17:52:16 +01:00
Benoit Marty
476f721f5e Cleanup 2020-11-30 17:52:16 +01:00
Benoit Marty
a813610c04 Room setting: update join rules and guest access (#2442) 2020-11-30 17:52:16 +01:00
Benoit Marty
41dd67f1c1 Renaming 2020-11-30 17:47:54 +01:00
Benoit Marty
63b068f426 Reorder iso Element Web 2020-11-30 17:46:14 +01:00
Benoit Marty
637c54073a Room history visibility: Use correct wording for the setting. 2020-11-30 17:46:14 +01:00
Benoit Marty
4171311095 Room history visibility: from ugly dialog to nice bottom sheet.
Including a reusable bottom sheet pattern, for future join rules setting bottom sheet
2020-11-30 17:46:14 +01:00
Benoit Marty
bb5d5ffc92 Improve room history visibility setting UX (#1579)
And observe correctly the state event
2020-11-30 17:43:28 +01:00
Benoit Marty
d07a95204b Better name 2020-11-30 17:41:55 +01:00
Onuray Sahin
2736247d09 Move cursor to the end to fix the jumping cursor bug.
Fixes #2469
2020-11-30 18:12:26 +03:00
Benoit Marty
93ffb116b7 Merge pull request #2439 from vector-im/feature/bma/alias
Add room alias management
2020-11-30 14:59:21 +01:00
Benoit Marty
396dd5e36e Merge pull request #2463 from vector-im/feature/ons/change_pin
Change PIN
2020-11-30 13:45:09 +01:00
Benoit Marty
096abd7ebf Fix IllegalStateException: focus search returned a view that wasn't able to take focus!
And no multiline input for room alias
2020-11-30 13:33:41 +01:00
Onuray Sahin
694397efc1 Create a new pin mode for changing pin code. 2020-11-30 13:51:40 +03:00
Onuray Sahin
ffe9a03d3e Merge branch 'develop' into feature/ons/change_pin
* develop:
  Format source
  Fix / double bottomsheet effect
  Version**
  Ensure the Activity is destroyed, it seems that the intent flags are not enough now. - finish all
  Ensure the Activity is destroyed, it seems that the intent flags are not enough now.
  Remove redundant returns
  Prepare version 1.0.11
  Fix issue when there is no display name
  Cleanup
  Fix issue with too big icons
  Use style instead of duplicating the whole layout file
  Try other asset strategy as lint not happy
  Convert TermsService to suspend functions
  Convert UploadsService to suspend functions
  Convert IntegrationManagerService to suspend functions
  update change log
  Home empty screen design update
2020-11-30 13:14:13 +03:00
Benoit Marty
b2556cb293 Update change after release 2020-11-30 11:00:58 +01:00
Benoit Marty
c029564590 Rename method and class for more clarity 2020-11-30 10:59:07 +01:00
Benoit Marty
0cfea40b24 Use when statement and modify the case to simplify the code 2020-11-30 10:59:07 +01:00
Benoit Marty
9c53f0f881 Clarify aliasLocalPart 2020-11-30 10:59:07 +01:00
Benoit Marty
50ddd3cf31 Small cleanup, handle case of no local alias, handle unpublish of canonical alias 2020-11-30 10:59:07 +01:00
Benoit Marty
6c7eb6ea8c Small wording change 2020-11-30 10:59:07 +01:00
Benoit Marty
412fc78c9a Cleanup 2020-11-30 10:59:07 +01:00
Benoit Marty
0da0857970 Cleanup 2020-11-30 10:59:07 +01:00
Benoit Marty
90e0006cae Room directory visibility management 2020-11-30 10:59:07 +01:00
Benoit Marty
a570528f6c More fixes 2020-11-30 10:59:07 +01:00
Benoit Marty
2d4cbde72c Render canonical alias 2020-11-30 10:59:07 +01:00
Benoit Marty
f5ae95d7f1 Close form only if necessary 2020-11-30 10:59:07 +01:00
Benoit Marty
c5e6e004dd Room alias detail 2020-11-30 10:59:07 +01:00
Benoit Marty
d9c209aa87 Cleanup 2020-11-30 10:59:07 +01:00
Benoit Marty
8f80f375f0 Prepare alias bottom sheet 2020-11-30 10:59:07 +01:00
Benoit Marty
2cf2233643 Naming convention 2020-11-30 10:59:07 +01:00
Benoit Marty
36564f0c75 copy/paste error 2020-11-30 10:59:07 +01:00
Benoit Marty
8dbb984ead Sort the aliases 2020-11-30 10:59:07 +01:00
Benoit Marty
74ffbd4679 Ensure the forms are displayable 2020-11-30 10:59:07 +01:00
Benoit Marty
82b23d9a13 Ensure we push only clean m.room.canonical_alias event 2020-11-30 10:59:07 +01:00
Benoit Marty
0a9b234272 Renaming 2020-11-30 10:59:07 +01:00
Benoit Marty
3a06ef3959 Improve form UX + local echo in case of success 2020-11-30 10:59:07 +01:00
Benoit Marty
ed4676bb6c Cleanup and avoid duplicate 2020-11-30 10:59:07 +01:00
Benoit Marty
893ebd9690 Fix UI error 2020-11-30 10:59:07 +01:00
Benoit Marty
3c069f8b79 Add published aliases 2020-11-30 10:59:07 +01:00
Benoit Marty
93580c902f Prepare to update canonical alias state 2020-11-30 10:59:07 +01:00
Benoit Marty
e1abd5a051 Fix layout issue 2020-11-30 10:59:07 +01:00
Benoit Marty
27fc5f265f Add/Remove local alias (#2428) 2020-11-30 10:59:07 +01:00
Benoit Marty
5b618ba1f3 Create RoomDirectoryAPI, and handle deletion of alias 2020-11-30 10:59:07 +01:00
Benoit Marty
a6f56ace24 Create a dedicated screen to manage room alias (#2428) - WIP 2020-11-30 10:59:07 +01:00
Benoit Marty
0d93105bcd Rended m.room.canonical_alias event in the timeline, considering alt_aliases (#2428) 2020-11-30 10:59:07 +01:00
Benoit Marty
7c2fea8623 Typo 2020-11-30 10:59:07 +01:00
Benoit Marty
e2a89c22da Do not show m.room.aliases event in the timeline (#2428) 2020-11-30 10:59:07 +01:00
Benoit Marty
03715e0939 Do not use m.room.aliases event to compute a room name (#2428) 2020-11-30 10:59:07 +01:00
Benoit Marty
4d9b9cb959 Deprecated event m.room.aliases 2020-11-30 10:59:07 +01:00
Benoit Marty
d759636d95 Merge pull request #2465 from vector-im/feature/bca/fix_verifypassphrase_bottomsheet
Fix / double bottomsheet effect
2020-11-30 10:58:15 +01:00
Benoit Marty
c8a8e0f2da Format source 2020-11-30 10:54:22 +01:00
Benoit Marty
b004dfbdf2 Merge pull request #2457 from Dominaezzz/suspend_functions_2
Convert IntegrationManagerService to suspend functions
2020-11-30 10:49:46 +01:00
Benoit Marty
40ea91cce4 Merge pull request #2459 from Dominaezzz/suspend_functions_3
Convert UploadsService to suspend functions
2020-11-30 10:48:44 +01:00
Benoit Marty
abcb02d4aa Merge pull request #2460 from Dominaezzz/suspend_functions
Convert TermsService to suspend functions
2020-11-30 10:47:55 +01:00
Benoit Marty
cd983de058 Fix cancellation of sending event (#2438) 2020-11-30 10:08:31 +01:00
Benoit Marty
f6cc05634f Send task: small rework and cleanup 2020-11-30 10:08:05 +01:00
Marcelo Filho
f14b390849 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (4 of 4 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/pt_BR/
2020-11-28 17:50:18 +00:00
Besnik Bleta
431f5d76ce Translated using Weblate (Albanian)
Currently translated at 95.2% (200 of 210 strings)

Translation: Element Android/Element Android Sdk
Translate-URL: https://translate.element.io/projects/element-android/element-sdk/sq/
2020-11-28 17:50:18 +00:00
Marcelo Filho
dd50399a21 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (210 of 210 strings)

Translation: Element Android/Element Android Sdk
Translate-URL: https://translate.element.io/projects/element-android/element-sdk/pt_BR/
2020-11-28 17:50:18 +00:00
sblondon
eb17463b68 Translated using Weblate (French)
Currently translated at 100.0% (210 of 210 strings)

Translation: Element Android/Element Android Sdk
Translate-URL: https://translate.element.io/projects/element-android/element-sdk/fr/
2020-11-28 17:50:17 +00:00
Priit Jõerüüt
88e05ffd05 Translated using Weblate (Estonian)
Currently translated at 100.0% (210 of 210 strings)

Translation: Element Android/Element Android Sdk
Translate-URL: https://translate.element.io/projects/element-android/element-sdk/et/
2020-11-28 17:50:17 +00:00
Besnik Bleta
a5079f5243 Translated using Weblate (Albanian)
Currently translated at 99.3% (1973 of 1986 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/sq/
2020-11-28 17:50:17 +00:00
krikra01
422c681e55 Translated using Weblate (Russian)
Currently translated at 97.1% (1930 of 1986 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/ru/
2020-11-28 17:50:14 +00:00
Marcelo Filho
9531a38486 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (1986 of 1986 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/pt_BR/
2020-11-28 17:50:13 +00:00
sblondon
493cd2a0e3 Translated using Weblate (French)
Currently translated at 98.8% (1963 of 1986 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/fr/
2020-11-28 17:50:10 +00:00
Priit Jõerüüt
f7f7e808f2 Translated using Weblate (Estonian)
Currently translated at 100.0% (1986 of 1986 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/et/
2020-11-28 17:50:08 +00:00
zeritti
217c88f342 Translated using Weblate (Czech)
Currently translated at 100.0% (1986 of 1986 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/cs/
2020-11-28 17:50:05 +00:00
Valere
cf70916764 Fix / double bottomsheet effect 2020-11-28 00:41:29 +01:00
Benoit Marty
b84d7f0834 Version** 2020-11-27 20:42:02 +01:00
Benoit Marty
11deaa049e Merge branch 'release/1.0.11' into develop 2020-11-27 20:40:01 +01:00
Onuray Sahin
245aa6e9e7 Create a new pin when tap on change pin item. 2020-11-27 17:17:24 +03:00
Dominic Fischer
33a5cc1488 Remove redundant returns
Signed-off-by: Dominic Fischer <dominicfischer7@gmail.com>
2020-11-27 13:18:07 +00:00
Onuray Sahin
89e7e28bfa Add settings item to change pin. 2020-11-27 15:22:31 +03:00
Onuray Sahin
221eddd995 Add changelog. 2020-11-27 15:02:08 +03:00
Dominic Fischer
27050b911b Convert TermsService to suspend functions
Signed-off-by: Dominic Fischer <dominicfischer7@gmail.com>
2020-11-26 21:53:22 +00:00
Dominic Fischer
a3a2c0a9a8 Convert UploadsService to suspend functions
Signed-off-by: Dominic Fischer <dominicfischer7@gmail.com>
2020-11-26 21:51:58 +00:00
Dominic Fischer
92ceb0e8fb Convert IntegrationManagerService to suspend functions
Signed-off-by: Dominic Fischer <dominicfischer7@gmail.com>
2020-11-26 21:17:58 +00:00
Onuray Sahin
cfe7852ffd Let Glide reduce image size if it is too large.
Fixes #1951
2020-08-18 13:49:11 +03:00
630 changed files with 13540 additions and 5960 deletions

View File

@@ -24,6 +24,8 @@
<w>pbkdf</w>
<w>pids</w>
<w>pkcs</w>
<w>previewable</w>
<w>previewables</w>
<w>riotx</w>
<w>signin</w>
<w>signout</w>
@@ -31,6 +33,7 @@
<w>ssss</w>
<w>sygnal</w>
<w>threepid</w>
<w>unpublish</w>
<w>unwedging</w>
</words>
</dictionary>

View File

@@ -1,3 +1,83 @@
Changes in Element 1.0.14 (2020-XX-XX)
===================================================
Features ✨:
- Enable url previews for notices (#2562)
Improvements 🙌:
- Add System theme option and set as default (#904) (#2387)
Bugfix 🐛:
- Fix Canvas: trying to draw too large bitmap (#1951)
- Url previews sometimes attached to wrong message (#2561)
- 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)
- Hiding membership events works the exact opposite (#2603)
- Tapping drawer having more than 1 room in notifications gives "malformed link" error (#2605)
Translations 🗣:
-
SDK API changes ⚠️:
-
Build 🧱:
-
Test:
-
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)
===================================================
Features ✨:
- Add room aliases management, and room directory visibility management in a dedicated screen (#1579, #2428)
- Room setting: update join rules and guest access (#2442)
- Url preview (#481)
- Store encrypted file in cache and cleanup decrypted file at each app start (#2512)
- Emoji Keyboard (#2520)
- Social login (#2452)
- Support for chat effects in timeline (confetti, snow) (#2535)
Improvements 🙌:
- Add Setting Item to Change PIN (#2462)
- Improve room history visibility setting UX (#1579)
- Matrix.to deeplink custom scheme support
- Homeserver history (#1933)
Bugfix 🐛:
- Fix cancellation of sending event (#2438)
- Double bottomsheet effect after verify with passphrase
- EditText cursor jumps to the start while typing fast (#2469)
- UTD for events before invitation if member state events are hidden (#2486)
- No known servers error is given when joining rooms on new Gitter bridge (#2516)
- Show preview when sending attachment from the keyboard (#2440)
- Do not compress GIFs (#1616, #1254)
SDK API changes ⚠️:
- StateService now exposes suspendable function instead of using MatrixCallback.
- RawCacheStrategy has been moved and renamed to CacheStrategy
- FileService: remove useless FileService.DownloadMode
Build 🧱:
- Upgrade some dependencies and Kotlin version
- Use fragment-ktx and preference-ktx dependencies (fix lint issue KtxExtensionAvailable)
- Upgrade Realm dependency to 10.1.2
Other changes:
- Remove "Status.im" theme #2424
- Log HTTP requests and responses in production (level BASIC, i.e. without any private data)
Changes in Element 1.0.11 (2020-11-27)
===================================================

View File

@@ -16,7 +16,6 @@
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
buildscript {
repositories {
@@ -55,6 +54,10 @@ android {
kotlinOptions {
jvmTarget = '1.8'
}
buildFeatures {
viewBinding true
}
}
dependencies {
@@ -66,7 +69,6 @@ dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.3.2'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation "androidx.fragment:fragment:1.3.0-beta01"
implementation "androidx.recyclerview:recyclerview:1.1.0"
implementation 'com.google.android.material:material:1.2.1'

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

@@ -33,43 +33,51 @@ 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
@@ -95,17 +103,14 @@ abstract class AttachmentViewerActivity : AppCompatActivity(), AttachmentEventLi
window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS)
window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION, WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION)
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 +121,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
@@ -170,7 +175,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 +201,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 +225,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 +243,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 +255,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 +270,7 @@ abstract class AttachmentViewerActivity : AppCompatActivity(), AttachmentEventLi
private fun createSwipeToDismissHandler()
: SwipeToDismissHandler = SwipeToDismissHandler(
swipeView = dismissContainer,
swipeView = views.dismissContainer,
shouldAnimateDismiss = { shouldAnimateDismiss() },
onDismiss = { animateClose() },
onSwipeViewMove = ::handleSwipeViewMove)

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

@@ -2,8 +2,8 @@
buildscript {
// Ref: https://kotlinlang.org/releases.html
ext.kotlin_version = '1.4.10'
ext.kotlin_coroutines_version = "1.3.9"
ext.kotlin_version = '1.4.20'
ext.kotlin_coroutines_version = "1.4.1"
repositories {
google()
jcenter()
@@ -12,7 +12,7 @@ buildscript {
}
}
dependencies {
classpath 'com.android.tools.build:gradle:4.1.0'
classpath 'com.android.tools.build:gradle:4.1.1'
classpath 'com.google.gms:google-services:4.3.4'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.7.1'
@@ -43,6 +43,10 @@ allprojects {
includeGroupByRegex 'com\\.github\\.chrisbanes'
// PFLockScreen-Android
includeGroupByRegex 'com\\.github\\.vector-im'
//Chat effects
includeGroupByRegex 'com\\.github\\.jetradarmobile'
includeGroupByRegex 'nl\\.dionsegijn'
}
}
maven {

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

@@ -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.12

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.12

View File

@@ -0,0 +1,2 @@
Tämä versio sisältää virheenkorjauksia ja muita parannuksia. Viestien lähettäminen on nyt paljon nopeampaa.
Täysi muutosloki: https://github.com/vector-im/element-android/releases/tag/v1.0.10

View File

@@ -0,0 +1,30 @@
Element on uudenlainen viestinsovellus, joka:
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 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:
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
<b>Miksi valita Element?</b>
<b>OMAT TIEDOT</b>: Sinä päätät, missä tietosi ja viestisi säilytetään. Hallitset sitä itse, eikä jokin MEGAYHTIÖ, 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>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>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 keskustelua ja VoIP-puheluita. Pidä tietosi turvassa.
Turvallista, hajautettua, keskusteluja ja VoIP-puheluita. Pidä tietosi turvassa.

View File

@@ -1 +1,2 @@
// DA FARE
Questa nuova versione contiene soprattutto correzioni di errori e miglioramenti. L'invio di messaggi ora è molto più veloce.
Cronologia completa: https://github.com/vector-im/element-android/releases/tag/v1.0.10

View File

@@ -1 +1,2 @@
// A FAZER
Esta nova versão contém principalmente correções de erros e melhorias. Enviar mensagens agora é muito mais rápido.
Registro de todas as alterações: https://github.com/vector-im/element-android/releases/tag/v1.0.10

View File

@@ -1 +1,2 @@
// ATT GÖRA
Den här nya versionen innehåller mest buggfixar och förbättringar. Det går nu mycket snabbare att skicka meddelanden.
Full ändringslogg: https://github.com/vector-im/element-android/releases/tag/v1.0.10

View File

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

View File

@@ -7,7 +7,7 @@ Element — це застосунок для спілкування та спі
Element ґрунтовно відрізняється від інших застосунків для спілкування та співпраці тому що він є децентралізованим та відкритоджерельним.
Element дозволяє вам розміщувати сервер в себе або обирати будь-якого з надавачів послуг, таким чином забезпечуючи вам конфіденційність і можливість володіти власними даними й бесідами та контролювати їх. Він надає вам доступ до відкритої мережі, тож ви не є обмеженими спілкуванням виключно з користувачами Element. І він є дуже надійним та безпечним.
Element дозволяє вам розміщувати сервер в себе або обирати будь-якого з надавачів послуг, таким чином забезпечуючи вам конфіденційність і можливість володіти власними даними й бесідами та контролювати їх. Він надає вам доступ до відкритої мережі, тож ви не є обмеженими спілкуванням виключно з користувачами Element. І він є дуже надійним та безпечним.
Element здатен забезпечити усе це завдяки тому, що він заснований на протоколі Matrix — стандарті для відкритого та децентралізованого спілкування.

View File

@@ -1 +1,2 @@
// 待辦事項
這個新版本主要包含錯誤修復與改善。傳送訊息更快了。
完整的變更紀錄請見https://github.com/vector-im/element-android/releases/tag/v1.0.10

View File

@@ -18,7 +18,7 @@ org.gradle.jvmargs=-Xmx2048m
org.gradle.vfs.watch=true
vector.debugPrivateData=false
vector.httpLogLevel=NONE
vector.httpLogLevel=BASIC
# Note: to debug, you can put and uncomment the following lines in the file ~/.gradle/gradle.properties to override the value above
#vector.debugPrivateData=true

View File

@@ -36,9 +36,10 @@ android {
dependencies {
implementation project(":matrix-sdk-android")
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation "androidx.fragment:fragment:1.3.0-beta01"
implementation 'io.reactivex.rxjava2:rxkotlin:2.3.0'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-rx2:$kotlin_coroutines_version"
// Paging
implementation "androidx.paging:paging-runtime-ktx:2.1.2"

View File

@@ -21,34 +21,36 @@ import org.matrix.android.sdk.api.util.Cancelable
import io.reactivex.Completable
import io.reactivex.Single
fun <T> singleBuilder(builder: (callback: MatrixCallback<T>) -> Cancelable): Single<T> = Single.create {
val callback: MatrixCallback<T> = object : MatrixCallback<T> {
fun <T> singleBuilder(builder: (MatrixCallback<T>) -> Cancelable): Single<T> = Single.create { emitter ->
val callback = object : MatrixCallback<T> {
override fun onSuccess(data: T) {
it.onSuccess(data)
// Add `!!` to fix the warning:
// "Type mismatch: type parameter with nullable bounds is used T is used where T was expected. This warning will become an error soon"
emitter.onSuccess(data!!)
}
override fun onFailure(failure: Throwable) {
it.tryOnError(failure)
emitter.tryOnError(failure)
}
}
val cancelable = builder(callback)
it.setCancellable {
emitter.setCancellable {
cancelable.cancel()
}
}
fun <T> completableBuilder(builder: (callback: MatrixCallback<T>) -> Cancelable): Completable = Completable.create {
val callback: MatrixCallback<T> = object : MatrixCallback<T> {
fun <T> completableBuilder(builder: (MatrixCallback<T>) -> Cancelable): Completable = Completable.create { emitter ->
val callback = object : MatrixCallback<T> {
override fun onSuccess(data: T) {
it.onComplete()
emitter.onComplete()
}
override fun onFailure(failure: Throwable) {
it.tryOnError(failure)
emitter.tryOnError(failure)
}
}
val cancelable = builder(callback)
it.setCancellable {
emitter.setCancellable {
cancelable.cancel()
}
}

View File

@@ -17,14 +17,20 @@
package org.matrix.android.sdk.rx
import android.net.Uri
import io.reactivex.Completable
import io.reactivex.Observable
import io.reactivex.Single
import kotlinx.coroutines.rx2.rxCompletable
import org.matrix.android.sdk.api.query.QueryStringValue
import org.matrix.android.sdk.api.session.events.model.Event
import org.matrix.android.sdk.api.session.identity.ThreePid
import org.matrix.android.sdk.api.session.room.Room
import org.matrix.android.sdk.api.session.room.members.RoomMemberQueryParams
import org.matrix.android.sdk.api.session.room.model.EventAnnotationsSummary
import org.matrix.android.sdk.api.session.room.model.GuestAccess
import org.matrix.android.sdk.api.session.room.model.ReadReceipt
import org.matrix.android.sdk.api.session.room.model.RoomHistoryVisibility
import org.matrix.android.sdk.api.session.room.model.RoomJoinRules
import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary
import org.matrix.android.sdk.api.session.room.model.RoomSummary
import org.matrix.android.sdk.api.session.room.notification.RoomNotificationState
@@ -32,9 +38,6 @@ import org.matrix.android.sdk.api.session.room.send.UserDraft
import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent
import org.matrix.android.sdk.api.util.Optional
import org.matrix.android.sdk.api.util.toOptional
import io.reactivex.Completable
import io.reactivex.Observable
import io.reactivex.Single
class RxRoom(private val room: Room) {
@@ -119,32 +122,28 @@ class RxRoom(private val room: Room) {
room.invite3pid(threePid, it)
}
fun updateTopic(topic: String): Completable = completableBuilder<Unit> {
room.updateTopic(topic, it)
fun updateTopic(topic: String): Completable = rxCompletable {
room.updateTopic(topic)
}
fun updateName(name: String): Completable = completableBuilder<Unit> {
room.updateName(name, it)
fun updateName(name: String): Completable = rxCompletable {
room.updateName(name)
}
fun addRoomAlias(alias: String): Completable = completableBuilder<Unit> {
room.addRoomAlias(alias, it)
fun updateHistoryReadability(readability: RoomHistoryVisibility): Completable = rxCompletable {
room.updateHistoryReadability(readability)
}
fun updateCanonicalAlias(alias: String): Completable = completableBuilder<Unit> {
room.updateCanonicalAlias(alias, it)
fun updateJoinRule(joinRules: RoomJoinRules?, guestAccess: GuestAccess?): Completable = rxCompletable {
room.updateJoinRule(joinRules, guestAccess)
}
fun updateHistoryReadability(readability: RoomHistoryVisibility): Completable = completableBuilder<Unit> {
room.updateHistoryReadability(readability, it)
fun updateAvatar(avatarUri: Uri, fileName: String): Completable = rxCompletable {
room.updateAvatar(avatarUri, fileName)
}
fun updateAvatar(avatarUri: Uri, fileName: String): Completable = completableBuilder<Unit> {
room.updateAvatar(avatarUri, fileName, it)
}
fun deleteAvatar(): Completable = completableBuilder<Unit> {
room.deleteAvatar(it)
fun deleteAvatar(): Completable = rxCompletable {
room.deleteAvatar()
}
}

View File

@@ -47,6 +47,7 @@ import org.matrix.android.sdk.api.util.toOptional
import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo
import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo
import org.matrix.android.sdk.internal.crypto.store.PrivateKeysInfo
import org.matrix.android.sdk.internal.session.room.alias.RoomAliasDescription
class RxSession(private val session: Session) {
@@ -139,7 +140,7 @@ class RxSession(private val session: Session) {
}
fun getRoomIdByAlias(roomAlias: String,
searchOnServer: Boolean): Single<Optional<String>> = singleBuilder {
searchOnServer: Boolean): Single<Optional<RoomAliasDescription>> = singleBuilder {
session.getRoomIdByAlias(roomAlias, searchOnServer, it)
}

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 {
@@ -9,14 +9,10 @@ buildscript {
jcenter()
}
dependencies {
classpath "io.realm:realm-gradle-plugin:10.0.0"
classpath "io.realm:realm-gradle-plugin:10.1.2"
}
}
androidExtensions {
experimental = true
}
android {
compileSdkVersion 29
testOptions.unitTests.includeAndroidResources = true
@@ -63,7 +59,7 @@ android {
release {
buildConfigField "boolean", "LOG_PRIVATE_DATA", "false"
buildConfigField "okhttp3.logging.HttpLoggingInterceptor.Level", "OKHTTP_LOGGING_LEVEL", "okhttp3.logging.HttpLoggingInterceptor.Level.NONE"
buildConfigField "okhttp3.logging.HttpLoggingInterceptor.Level", "OKHTTP_LOGGING_LEVEL", "okhttp3.logging.HttpLoggingInterceptor.Level.BASIC"
}
}
@@ -125,7 +121,6 @@ dependencies {
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlin_coroutines_version"
implementation "androidx.appcompat:appcompat:1.2.0"
implementation "androidx.fragment:fragment:1.3.0-beta01"
implementation "androidx.core:core-ktx:1.3.2"
implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"
@@ -146,7 +141,7 @@ dependencies {
implementation "ru.noties.markwon:core:$markwon_version"
// Image
implementation 'androidx.exifinterface:exifinterface:1.3.0'
implementation 'androidx.exifinterface:exifinterface:1.3.1'
// Database
implementation 'com.github.Zhuinden:realm-monarchy:0.7.1'

View File

@@ -25,6 +25,7 @@ import androidx.work.WorkManager
import com.zhuinden.monarchy.Monarchy
import org.matrix.android.sdk.BuildConfig
import org.matrix.android.sdk.api.auth.AuthenticationService
import org.matrix.android.sdk.api.auth.HomeServerHistoryService
import org.matrix.android.sdk.api.legacy.LegacySessionImporter
import org.matrix.android.sdk.api.raw.RawService
import org.matrix.android.sdk.common.DaggerTestMatrixComponent
@@ -49,6 +50,7 @@ class Matrix private constructor(context: Context, matrixConfiguration: MatrixCo
@Inject internal lateinit var backgroundDetectionObserver: BackgroundDetectionObserver
@Inject internal lateinit var olmManager: OlmManager
@Inject internal lateinit var sessionManager: SessionManager
@Inject internal lateinit var homeServerHistoryService: HomeServerHistoryService
private val uiHandler = Handler(Looper.getMainLooper())
@@ -71,6 +73,8 @@ class Matrix private constructor(context: Context, matrixConfiguration: MatrixCo
fun rawService() = rawService
fun homeServerHistoryService() = homeServerHistoryService
fun legacySessionImporter(): LegacySessionImporter {
return legacySessionImporter
}

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

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

@@ -73,7 +73,7 @@ class CryptoTestHelper(private val mTestHelper: CommonTestHelper) {
}
}
return CryptoTestData(aliceSession, roomId)
return CryptoTestData(roomId, listOf(aliceSession))
}
/**
@@ -139,7 +139,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 +157,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))
}
/**
@@ -381,4 +381,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,13 +17,13 @@
package org.matrix.android.sdk.internal.crypto.encryption
import androidx.test.ext.junit.runners.AndroidJUnit4
import kotlinx.coroutines.runBlocking
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.NoOpMatrixCallback
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.Room
@@ -57,13 +57,14 @@ class EncryptionTest : InstrumentedTest {
@Test
fun test_EncryptionStateEvent() {
performTest(roomShouldBeEncrypted = true) { room ->
// Send an encryption Event as a State Event
room.sendStateEvent(
eventType = EventType.STATE_ROOM_ENCRYPTION,
stateKey = null,
body = EncryptionEventContent(algorithm = MXCRYPTO_ALGORITHM_MEGOLM).toContent(),
callback = NoOpMatrixCallback()
)
runBlocking {
// Send an encryption Event as a State Event
room.sendStateEvent(
eventType = EventType.STATE_ROOM_ENCRYPTION,
stateKey = null,
body = EncryptionEventContent(algorithm = MXCRYPTO_ALGORITHM_MEGOLM).toContent()
)
}
}
}

View File

@@ -264,7 +264,7 @@ class KeysBackupTest : InstrumentedTest {
assertNotNull(decryption)
// - Check decryptKeyBackupData() returns stg
val sessionData = keysBackup
.decryptKeyBackupData(keyBackupData!!,
.decryptKeyBackupData(keyBackupData,
session.olmInboundGroupSession!!.sessionIdentifier(),
cryptoTestData.roomId,
decryption!!)

View File

@@ -111,7 +111,7 @@ class KeysBackupTestHelper(
Assert.assertTrue(keysBackup.isEnabled)
stateObserver.stopAndCheckStates(null)
return PrepareKeysBackupDataResult(megolmBackupCreationInfo, keysVersion.version!!)
return PrepareKeysBackupDataResult(megolmBackupCreationInfo, keysVersion.version)
}
/**

View File

@@ -0,0 +1,108 @@
/*
* 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.session.media
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.amshove.kluent.shouldBeEqualTo
import org.junit.Test
import org.junit.runner.RunWith
import org.matrix.android.sdk.InstrumentedTest
import org.matrix.android.sdk.api.session.events.model.Event
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
@RunWith(AndroidJUnit4::class)
internal class UrlsExtractorTest : InstrumentedTest {
private val urlsExtractor = UrlsExtractor()
@Test
fun wrongEventTypeTest() {
createEvent(body = "https://matrix.org")
.copy(type = EventType.STATE_ROOM_GUEST_ACCESS)
.let { urlsExtractor.extract(it) }
.size shouldBeEqualTo 0
}
@Test
fun oneUrlTest() {
createEvent(body = "https://matrix.org")
.let { urlsExtractor.extract(it) }
.let { result ->
result.size shouldBeEqualTo 1
result[0] shouldBeEqualTo "https://matrix.org"
}
}
@Test
fun withoutProtocolTest() {
createEvent(body = "www.matrix.org")
.let { urlsExtractor.extract(it) }
.size shouldBeEqualTo 0
}
@Test
fun oneUrlWithParamTest() {
createEvent(body = "https://matrix.org?foo=bar")
.let { urlsExtractor.extract(it) }
.let { result ->
result.size shouldBeEqualTo 1
result[0] shouldBeEqualTo "https://matrix.org?foo=bar"
}
}
@Test
fun oneUrlWithParamsTest() {
createEvent(body = "https://matrix.org?foo=bar&bar=foo")
.let { urlsExtractor.extract(it) }
.let { result ->
result.size shouldBeEqualTo 1
result[0] shouldBeEqualTo "https://matrix.org?foo=bar&bar=foo"
}
}
@Test
fun oneUrlInlinedTest() {
createEvent(body = "Hello https://matrix.org, how are you?")
.let { urlsExtractor.extract(it) }
.let { result ->
result.size shouldBeEqualTo 1
result[0] shouldBeEqualTo "https://matrix.org"
}
}
@Test
fun twoUrlsTest() {
createEvent(body = "https://matrix.org https://example.org")
.let { urlsExtractor.extract(it) }
.let { result ->
result.size shouldBeEqualTo 2
result[0] shouldBeEqualTo "https://matrix.org"
result[1] shouldBeEqualTo "https://example.org"
}
}
private fun createEvent(body: String): Event = Event(
type = EventType.MESSAGE,
content = MessageTextContent(
msgType = MessageType.MSGTYPE_TEXT,
body = body
).toContent()
)
}

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

@@ -17,7 +17,6 @@
package org.matrix.android.sdk.internal.network.interceptors
import androidx.annotation.NonNull
import org.matrix.android.sdk.BuildConfig
import okhttp3.logging.HttpLoggingInterceptor
import org.json.JSONArray
import org.json.JSONException
@@ -38,31 +37,28 @@ class FormattedJsonHttpLogger : HttpLoggingInterceptor.Logger {
*/
@Synchronized
override fun log(@NonNull message: String) {
// In RELEASE there is no log, but for sure, test again BuildConfig.DEBUG
if (BuildConfig.DEBUG) {
Timber.v(message)
Timber.v(message)
if (message.startsWith("{")) {
// JSON Detected
try {
val o = JSONObject(message)
logJson(o.toString(INDENT_SPACE))
} catch (e: JSONException) {
// Finally this is not a JSON string...
Timber.e(e)
}
} else if (message.startsWith("[")) {
// JSON Array detected
try {
val o = JSONArray(message)
logJson(o.toString(INDENT_SPACE))
} catch (e: JSONException) {
// Finally not JSON...
Timber.e(e)
}
if (message.startsWith("{")) {
// JSON Detected
try {
val o = JSONObject(message)
logJson(o.toString(INDENT_SPACE))
} catch (e: JSONException) {
// Finally this is not a JSON string...
Timber.e(e)
}
} else if (message.startsWith("[")) {
// JSON Array detected
try {
val o = JSONArray(message)
logJson(o.toString(INDENT_SPACE))
} catch (e: JSONException) {
// Finally not JSON...
Timber.e(e)
}
// Else not a json string to log
}
// Else not a json string to log
}
private fun logJson(formattedJson: String) {

View File

@@ -23,6 +23,7 @@ import androidx.work.WorkManager
import com.zhuinden.monarchy.Monarchy
import org.matrix.android.sdk.BuildConfig
import org.matrix.android.sdk.api.auth.AuthenticationService
import org.matrix.android.sdk.api.auth.HomeServerHistoryService
import org.matrix.android.sdk.api.legacy.LegacySessionImporter
import org.matrix.android.sdk.api.raw.RawService
import org.matrix.android.sdk.internal.SessionManager
@@ -47,6 +48,7 @@ class Matrix private constructor(context: Context, matrixConfiguration: MatrixCo
@Inject internal lateinit var backgroundDetectionObserver: BackgroundDetectionObserver
@Inject internal lateinit var olmManager: OlmManager
@Inject internal lateinit var sessionManager: SessionManager
@Inject internal lateinit var homeServerHistoryService: HomeServerHistoryService
init {
Monarchy.init(context)
@@ -65,6 +67,8 @@ class Matrix private constructor(context: Context, matrixConfiguration: MatrixCo
fun rawService() = rawService
fun homeServerHistoryService() = homeServerHistoryService
fun legacySessionImporter(): LegacySessionImporter {
return legacySessionImporter
}

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,29 @@
/*
* 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
/**
* A simple service to remember homeservers you already connected to.
*/
interface HomeServerHistoryService {
fun getKnownServersUrls(): List<String>
fun addHomeServerToHistory(url: String)
fun clearHistory()
}

View File

@@ -19,6 +19,7 @@ package org.matrix.android.sdk.api.auth.data
sealed class LoginFlowResult {
data class Success(
val supportedLoginTypes: List<String>,
val ssoIdentityProviders: List<SsoIdentityProvider>?,
val isLoginAndRegistrationSupported: Boolean,
val homeServerUrl: String,
val isOutdatedHomeserver: Boolean

View File

@@ -0,0 +1,52 @@
/*
* 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.data
import android.os.Parcelable
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import kotlinx.parcelize.Parcelize
@JsonClass(generateAdapter = true)
@Parcelize
data class SsoIdentityProvider(
/**
* The id field would be opaque with the accepted characters matching unreserved URI characters as defined in RFC3986
* - this was chosen to avoid having to encode special characters in the URL. Max length 128.
*/
@Json(name = "id") val id: String,
/**
* The name field should be the human readable string intended for printing by the client.
*/
@Json(name = "name") val name: String?,
/**
* The icon field is the only optional field and should point to an icon representing the IdP.
* 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?
) : 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"
}
}

View File

@@ -14,16 +14,16 @@
* limitations under the License.
*/
package org.matrix.android.sdk.api.raw
package org.matrix.android.sdk.api.cache
sealed class RawCacheStrategy {
sealed class CacheStrategy {
// Data is always fetched from the server
object NoCache : RawCacheStrategy()
object NoCache : CacheStrategy()
// Once data is retrieved, it is stored for the provided amount of time.
// In case of error, and if strict is set to false, the cache can be returned if available
data class TtlCache(val validityDurationInMillis: Long, val strict: Boolean) : RawCacheStrategy()
data class TtlCache(val validityDurationInMillis: Long, val strict: Boolean) : CacheStrategy()
// Once retrieved, the data is stored in cache and will be always get from the cache
object InfiniteCache : RawCacheStrategy()
object InfiniteCache : CacheStrategy()
}

View File

@@ -16,6 +16,8 @@
package org.matrix.android.sdk.api.raw
import org.matrix.android.sdk.api.cache.CacheStrategy
/**
* Useful methods to fetch raw data from the server. The access token will not be used to fetched the data
*/
@@ -23,7 +25,7 @@ interface RawService {
/**
* Get a URL, either from cache or from the remote server, depending on the cache strategy
*/
suspend fun getUrl(url: String, rawCacheStrategy: RawCacheStrategy): String
suspend fun getUrl(url: String, cacheStrategy: CacheStrategy): String
/**
* Specific case for the well-known file. Cache validity is 8 hours

View File

@@ -35,6 +35,7 @@ import org.matrix.android.sdk.api.session.group.GroupService
import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilitiesService
import org.matrix.android.sdk.api.session.identity.IdentityService
import org.matrix.android.sdk.api.session.integrationmanager.IntegrationManagerService
import org.matrix.android.sdk.api.session.media.MediaService
import org.matrix.android.sdk.api.session.permalinks.PermalinkService
import org.matrix.android.sdk.api.session.profile.ProfileService
import org.matrix.android.sdk.api.session.pushers.PushersService
@@ -181,6 +182,11 @@ interface Session :
*/
fun widgetService(): WidgetService
/**
* Returns the media service associated with the session
*/
fun mediaService(): MediaService
/**
* Returns the integration manager service associated with the session
*/

View File

@@ -36,7 +36,7 @@ sealed class CallState {
* Connected. Incoming/Outgoing call, ice layer connecting or connected
* Notice that the PeerState failed is not always final, if you switch network, new ice candidtates
* could be exchanged, and the connection could go back to connected
* */
*/
data class Connected(val iceConnectionState: PeerConnection.PeerConnectionState) : CallState()
/** Terminated. Incoming/Outgoing call, the call is terminated */

View File

@@ -20,7 +20,8 @@ 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
@JsonClass(generateAdapter = true)
@@ -45,5 +46,5 @@ data class ContentAttachmentData(
VIDEO
}
fun getSafeMimeType() = if (mimeType == "image/jpg") "image/jpeg" else mimeType
fun getSafeMimeType() = mimeType?.normalizeMimeType()
}

View File

@@ -49,6 +49,12 @@ object EventType {
const val STATE_ROOM_JOIN_RULES = "m.room.join_rules"
const val STATE_ROOM_GUEST_ACCESS = "m.room.guest_access"
const val STATE_ROOM_POWER_LEVELS = "m.room.power_levels"
/**
* Note that this Event has been deprecated, see
* - https://matrix.org/docs/spec/client_server/r0.6.1#historical-events
* - https://github.com/matrix-org/matrix-doc/pull/2432
*/
const val STATE_ROOM_ALIASES = "m.room.aliases"
const val STATE_ROOM_TOMBSTONE = "m.room.tombstone"
const val STATE_ROOM_CANONICAL_ALIAS = "m.room.canonical_alias"

View File

@@ -18,8 +18,12 @@ package org.matrix.android.sdk.api.session.file
import android.net.Uri
import org.matrix.android.sdk.api.MatrixCallback
import org.matrix.android.sdk.api.session.room.model.message.MessageWithAttachmentContent
import org.matrix.android.sdk.api.session.room.model.message.getFileName
import org.matrix.android.sdk.api.session.room.model.message.getFileUrl
import org.matrix.android.sdk.api.util.Cancelable
import org.matrix.android.sdk.internal.crypto.attachments.ElementToDecrypt
import org.matrix.android.sdk.internal.crypto.attachments.toElementToDecrypt
import java.io.File
/**
@@ -27,23 +31,6 @@ import java.io.File
*/
interface FileService {
enum class DownloadMode {
/**
* Download file in external storage
*/
TO_EXPORT,
/**
* Download file in cache
*/
FOR_INTERNAL_USE,
/**
* Download file in file provider path
*/
FOR_EXTERNAL_SHARE
}
enum class FileState {
IN_CACHE,
DOWNLOADING,
@@ -54,34 +41,79 @@ interface FileService {
* Download a file.
* Result will be a decrypted file, stored in the cache folder. url parameter will be used to create unique filename to avoid name collision.
*/
fun downloadFile(
downloadMode: DownloadMode,
id: String,
fileName: String,
mimeType: String?,
url: String?,
elementToDecrypt: ElementToDecrypt?,
callback: MatrixCallback<File>): Cancelable
fun downloadFile(fileName: String,
mimeType: String?,
url: String?,
elementToDecrypt: ElementToDecrypt?,
callback: MatrixCallback<File>): Cancelable
fun isFileInCache(mxcUrl: String, mimeType: String?): Boolean
fun downloadFile(messageContent: MessageWithAttachmentContent,
callback: MatrixCallback<File>): Cancelable =
downloadFile(
fileName = messageContent.getFileName(),
mimeType = messageContent.mimeType,
url = messageContent.getFileUrl(),
elementToDecrypt = messageContent.encryptedFileInfo?.toElementToDecrypt(),
callback = callback
)
fun isFileInCache(mxcUrl: String?,
fileName: String,
mimeType: String?,
elementToDecrypt: ElementToDecrypt?
): Boolean
fun isFileInCache(messageContent: MessageWithAttachmentContent) =
isFileInCache(
mxcUrl = messageContent.getFileUrl(),
fileName = messageContent.getFileName(),
mimeType = messageContent.mimeType,
elementToDecrypt = messageContent.encryptedFileInfo?.toElementToDecrypt())
/**
* Use this URI and pass it to intent using flag Intent.FLAG_GRANT_READ_URI_PERMISSION
* (if not other app won't be able to access it)
*/
fun getTemporarySharableURI(mxcUrl: String, mimeType: String?): Uri?
fun getTemporarySharableURI(mxcUrl: String?,
fileName: String,
mimeType: String?,
elementToDecrypt: ElementToDecrypt?): Uri?
fun getTemporarySharableURI(messageContent: MessageWithAttachmentContent): Uri? =
getTemporarySharableURI(
mxcUrl = messageContent.getFileUrl(),
fileName = messageContent.getFileName(),
mimeType = messageContent.mimeType,
elementToDecrypt = messageContent.encryptedFileInfo?.toElementToDecrypt()
)
/**
* Get information on the given file.
* Mimetype should be the same one as passed to downloadFile (limitation for now)
*/
fun fileState(mxcUrl: String, mimeType: String?): FileState
fun fileState(mxcUrl: String?,
fileName: String,
mimeType: String?,
elementToDecrypt: ElementToDecrypt?): FileState
fun fileState(messageContent: MessageWithAttachmentContent): FileState =
fileState(
mxcUrl = messageContent.getFileUrl(),
fileName = messageContent.getFileName(),
mimeType = messageContent.mimeType,
elementToDecrypt = messageContent.encryptedFileInfo?.toElementToDecrypt()
)
/**
* Clears all the files downloaded by the service
* Clears all the files downloaded by the service, including decrypted files
*/
fun clearCache()
/**
* Clears all the decrypted files by the service
*/
fun clearDecryptedCache()
/**
* Get size of cached files
*/

View File

@@ -16,9 +16,6 @@
package org.matrix.android.sdk.api.session.integrationmanager
import org.matrix.android.sdk.api.MatrixCallback
import org.matrix.android.sdk.api.util.Cancelable
/**
* This is the entry point to manage integration. You can grab an instance of this service through an active session.
*/
@@ -80,19 +77,17 @@ interface IntegrationManagerService {
/**
* Offers to enable or disable the integration.
* @param enable the param to change
* @param callback the matrix callback to listen for result.
* @return Cancelable
*/
fun setIntegrationEnabled(enable: Boolean, callback: MatrixCallback<Unit>): Cancelable
suspend fun setIntegrationEnabled(enable: Boolean)
/**
* Offers to allow or disallow a widget.
* @param stateEventId the eventId of the state event defining the widget.
* @param allowed the param to change
* @param callback the matrix callback to listen for result.
* @return Cancelable
*/
fun setWidgetAllowed(stateEventId: String, allowed: Boolean, callback: MatrixCallback<Unit>): Cancelable
suspend fun setWidgetAllowed(stateEventId: String, allowed: Boolean)
/**
* Returns true if the widget is allowed, false otherwise.
@@ -105,7 +100,7 @@ interface IntegrationManagerService {
* @param widgetType the widget type to check for
* @param domain the domain to check for
*/
fun setNativeWidgetDomainAllowed(widgetType: String, domain: String, allowed: Boolean, callback: MatrixCallback<Unit>): Cancelable
suspend fun setNativeWidgetDomainAllowed(widgetType: String, domain: String, allowed: Boolean)
/**
* Returns true if the widget domain is allowed, false otherwise.

View File

@@ -0,0 +1,50 @@
/*
* 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.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.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
*/
fun extractUrls(event: Event): List<String>
/**
* Get Raw Url Preview data from the homeserver. There is no cache management for this request
* @param url The url to get the preview data from
* @param timestamp The optional timestamp
*/
suspend fun getRawPreviewUrl(url: String, timestamp: Long?): JsonDict
/**
* Get Url Preview data from the homeserver, or from cache, depending on the cache strategy
* @param url The url to get the preview data from
* @param timestamp The optional timestamp. Note that this parameter is not taken into account
* if the data is already in cache and the cache strategy allow to use it
* @param cacheStrategy the cache strategy, see the type for more details
*/
suspend fun getPreviewUrl(url: String, timestamp: Long?, cacheStrategy: CacheStrategy): PreviewUrlData
/**
* Clear the cache of all retrieved UrlPreview data
*/
suspend fun clearCache()
}

View File

@@ -0,0 +1,51 @@
/*
* 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.media
/**
* Facility data class to get the common field of a PreviewUrl response form the server
*
* Example of return data for the url `https://matrix.org`:
* <pre>
* {
* "matrix:image:size": 112805,
* "og:description": "Matrix is an open standard for interoperable, decentralised, real-time communication",
* "og:image": "mxc://matrix.org/2020-12-03_uFqjagCCTJbaaJxb",
* "og:image:alt": "Matrix is an open standard for interoperable, decentralised, real-time communication",
* "og:image:height": 467,
* "og:image:type": "image/jpeg",
* "og:image:width": 911,
* "og:locale": "en_US",
* "og:site_name": "Matrix.org",
* "og:title": "Matrix.org",
* "og:type": "website",
* "og:url": "https://matrix.org"
* }
* </pre>
*/
data class PreviewUrlData(
// Value of field "og:url". If not provided, this is the value passed in parameter
val url: String,
// Value of field "og:site_name"
val siteName: String?,
// Value of field "og:title"
val title: String?,
// Value of field "og:description"
val description: String?,
// Value of field "og:image"
val mxcUrl: String?
)

View File

@@ -18,6 +18,7 @@ package org.matrix.android.sdk.api.session.room
import androidx.lifecycle.LiveData
import org.matrix.android.sdk.api.MatrixCallback
import org.matrix.android.sdk.api.session.room.alias.AliasService
import org.matrix.android.sdk.api.session.room.call.RoomCallService
import org.matrix.android.sdk.api.session.room.crypto.RoomCryptoService
import org.matrix.android.sdk.api.session.room.members.MembershipService
@@ -46,6 +47,7 @@ interface Room :
DraftService,
ReadService,
TypingService,
AliasService,
TagsService,
MembershipService,
StateService,

View File

@@ -17,6 +17,7 @@
package org.matrix.android.sdk.api.session.room
import org.matrix.android.sdk.api.MatrixCallback
import org.matrix.android.sdk.api.session.room.model.RoomDirectoryVisibility
import org.matrix.android.sdk.api.session.room.model.roomdirectory.PublicRoomsParams
import org.matrix.android.sdk.api.session.room.model.roomdirectory.PublicRoomsResponse
import org.matrix.android.sdk.api.session.room.model.thirdparty.ThirdPartyProtocol
@@ -39,4 +40,14 @@ interface RoomDirectoryService {
* Includes both the available protocols and all fields required for queries against each protocol.
*/
fun getThirdPartyProtocol(callback: MatrixCallback<Map<String, ThirdPartyProtocol>>): Cancelable
/**
* Get the visibility of a room in the directory
*/
suspend fun getRoomDirectoryVisibility(roomId: String): RoomDirectoryVisibility
/**
* Set the visibility of a room in the directory
*/
suspend fun setRoomDirectoryVisibility(roomId: String, roomDirectoryVisibility: RoomDirectoryVisibility)
}

View File

@@ -18,12 +18,15 @@ package org.matrix.android.sdk.api.session.room
import androidx.lifecycle.LiveData
import org.matrix.android.sdk.api.MatrixCallback
import org.matrix.android.sdk.api.session.events.model.Event
import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState
import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary
import org.matrix.android.sdk.api.session.room.model.RoomSummary
import org.matrix.android.sdk.api.session.room.model.create.CreateRoomParams
import org.matrix.android.sdk.api.session.room.peeking.PeekResult
import org.matrix.android.sdk.api.util.Cancelable
import org.matrix.android.sdk.api.util.Optional
import org.matrix.android.sdk.internal.session.room.alias.RoomAliasDescription
/**
* This interface defines methods to get rooms. It's implemented at the session level.
@@ -120,7 +123,12 @@ interface RoomService {
*/
fun getRoomIdByAlias(roomAlias: String,
searchOnServer: Boolean,
callback: MatrixCallback<Optional<String>>): Cancelable
callback: MatrixCallback<Optional<RoomAliasDescription>>): Cancelable
/**
* Delete a room alias
*/
suspend fun deleteRoomAlias(roomAlias: String)
/**
* Return a live data of all local changes membership that happened since the session has been opened.
@@ -158,4 +166,16 @@ interface RoomService {
* @return a LiveData of the optional found room member
*/
fun getRoomMemberLive(userId: String, roomId: String): LiveData<Optional<RoomMemberSummary>>
/**
* Get some state events about a room
*/
fun getRoomState(roomId: String, callback: MatrixCallback<List<Event>>)
/**
* Use this if you want to get information from a room that you are not yet in (or invited)
* It might be possible to get some information on this room if it is public or if guest access is allowed
* This call will try to gather some information on this room, but it could fail and get nothing more
*/
fun peekRoom(roomIdOrAlias: String, callback: MatrixCallback<PeekResult>)
}

View File

@@ -0,0 +1,32 @@
/*
* 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.alias
interface AliasService {
/**
* Get list of local alias of the room
* @return the list of the aliases (full aliases, not only the local part)
*/
suspend fun getRoomAliases(): List<String>
/**
* Add local alias to the room
* @param aliasLocalPart the local part of the alias.
* Ex: for the alias "#my_alias:example.org", the local part is "my_alias"
*/
suspend fun addAlias(aliasLocalPart: String)
}

View File

@@ -0,0 +1,23 @@
/*
* 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.alias
sealed class RoomAliasError : Throwable() {
object AliasEmpty : RoomAliasError()
object AliasNotAvailable : RoomAliasError()
object AliasInvalid : RoomAliasError()
}

View File

@@ -18,13 +18,10 @@ package org.matrix.android.sdk.api.session.room.failure
import org.matrix.android.sdk.api.failure.Failure
import org.matrix.android.sdk.api.failure.MatrixError
import org.matrix.android.sdk.api.session.room.alias.RoomAliasError
sealed class CreateRoomFailure : Failure.FeatureFailure() {
object CreatedWithTimeout : CreateRoomFailure()
data class CreatedWithFederationFailure(val matrixError: MatrixError) : CreateRoomFailure()
sealed class RoomAliasError : CreateRoomFailure() {
object AliasEmpty : RoomAliasError()
object AliasNotAvailable : RoomAliasError()
object AliasInvalid : RoomAliasError()
}
data class AliasError(val aliasError: RoomAliasError) : CreateRoomFailure()
}

View File

@@ -21,6 +21,9 @@ import com.squareup.moshi.JsonClass
/**
* Class representing the EventType.STATE_ROOM_ALIASES state event content
* Note that this Event has been deprecated, see
* - https://matrix.org/docs/spec/client_server/r0.6.1#historical-events
* - https://github.com/matrix-org/matrix-doc/pull/2432
*/
@JsonClass(generateAdapter = true)
data class RoomAliasesContent(

View File

@@ -24,5 +24,14 @@ import com.squareup.moshi.JsonClass
*/
@JsonClass(generateAdapter = true)
data class RoomCanonicalAliasContent(
@Json(name = "alias") val canonicalAlias: String? = null
/**
* The canonical alias for the room. If not present, null, or empty the room should be considered to have no canonical alias.
*/
@Json(name = "alias") val canonicalAlias: String? = null,
/**
* Alternative aliases the room advertises.
* This list can have aliases despite the alias field being null, empty, or otherwise not present.
*/
@Json(name = "alt_aliases") val alternativeAliases: List<String>? = null
)

View File

@@ -20,6 +20,7 @@ import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import org.matrix.android.sdk.api.session.events.model.Content
import org.matrix.android.sdk.api.session.room.model.relation.RelationDefaultContent
import org.matrix.android.sdk.api.util.MimeTypes
import org.matrix.android.sdk.internal.crypto.model.rest.EncryptedFileInfo
@JsonClass(generateAdapter = true)
@@ -54,5 +55,5 @@ data class MessageImageContent(
@Json(name = "file") override val encryptedFileInfo: EncryptedFileInfo? = null
) : MessageImageInfoContent {
override val mimeType: String?
get() = encryptedFileInfo?.mimetype ?: info?.mimeType ?: "image/*"
get() = encryptedFileInfo?.mimetype ?: info?.mimeType ?: MimeTypes.Images
}

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

@@ -33,4 +33,7 @@ object MessageType {
// Add, in local, a fake message type in order to StickerMessage can inherit Message class
// Because sticker isn't a message type but a event type without msgtype field
const val MSGTYPE_STICKER_LOCAL = "org.matrix.android.sdk.sticker"
const val MSGTYPE_CONFETTI = "nic.custom.confetti"
const val MSGTYPE_SNOW = "nic.custom.snow"
}

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.session.room.peeking
sealed class PeekResult {
data class Success(
val roomId: String,
val alias: String?,
val name: String?,
val topic: String?,
val avatarUrl: String?,
val numJoinedMembers: Int?,
val viaServers: List<String>
) : PeekResult()
data class PeekingNotAllowed(
val roomId: String,
val alias: String?,
val viaServers: List<String>
) : PeekResult()
object UnknownAlias : PeekResult()
}

View File

@@ -18,11 +18,11 @@ package org.matrix.android.sdk.api.session.room.state
import android.net.Uri
import androidx.lifecycle.LiveData
import org.matrix.android.sdk.api.MatrixCallback
import org.matrix.android.sdk.api.query.QueryStringValue
import org.matrix.android.sdk.api.session.events.model.Event
import org.matrix.android.sdk.api.session.room.model.GuestAccess
import org.matrix.android.sdk.api.session.room.model.RoomHistoryVisibility
import org.matrix.android.sdk.api.util.Cancelable
import org.matrix.android.sdk.api.session.room.model.RoomJoinRules
import org.matrix.android.sdk.api.util.JsonDict
import org.matrix.android.sdk.api.util.Optional
@@ -31,39 +31,41 @@ interface StateService {
/**
* Update the topic of the room
*/
fun updateTopic(topic: String, callback: MatrixCallback<Unit>): Cancelable
suspend fun updateTopic(topic: String)
/**
* Update the name of the room
*/
fun updateName(name: String, callback: MatrixCallback<Unit>): Cancelable
/**
* Add new alias to the room.
*/
fun addRoomAlias(roomAlias: String, callback: MatrixCallback<Unit>): Cancelable
suspend fun updateName(name: String)
/**
* Update the canonical alias of the room
* @param alias the canonical alias, or null to reset the canonical alias of this room
* @param altAliases the alternative aliases for this room. It should include the canonical alias if any.
*/
fun updateCanonicalAlias(alias: String, callback: MatrixCallback<Unit>): Cancelable
suspend fun updateCanonicalAlias(alias: String?, altAliases: List<String>)
/**
* Update the history readability of the room
*/
fun updateHistoryReadability(readability: RoomHistoryVisibility, callback: MatrixCallback<Unit>): Cancelable
suspend fun updateHistoryReadability(readability: RoomHistoryVisibility)
/**
* Update the join rule and/or the guest access
*/
suspend fun updateJoinRule(joinRules: RoomJoinRules?, guestAccess: GuestAccess?)
/**
* Update the avatar of the room
*/
fun updateAvatar(avatarUri: Uri, fileName: String, callback: MatrixCallback<Unit>): Cancelable
suspend fun updateAvatar(avatarUri: Uri, fileName: String)
/**
* Delete the avatar of the room
*/
fun deleteAvatar(callback: MatrixCallback<Unit>): Cancelable
suspend fun deleteAvatar()
fun sendStateEvent(eventType: String, stateKey: String?, body: JsonDict, callback: MatrixCallback<Unit>): Cancelable
suspend fun sendStateEvent(eventType: String, stateKey: String?, body: JsonDict)
fun getStateEvent(eventType: String, stateKey: QueryStringValue = QueryStringValue.NoCondition): Event?

View File

@@ -0,0 +1,29 @@
/*
* 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.timeline
data class EventTypeFilter(
/**
* Allowed event type.
*/
val eventType: String,
/**
* Allowed state key. Set null if you want to allow all events,
* otherwise allowed events will be filtered according to the given stateKey.
*/
val stateKey: String?
)

View File

@@ -36,5 +36,5 @@ data class TimelineEventFilters(
/**
* If [filterTypes] is true, the list of types allowed by the list.
*/
val allowedTypes: List<String> = emptyList()
val allowedTypes: List<EventTypeFilter> = emptyList()
)

View File

@@ -16,9 +16,6 @@
package org.matrix.android.sdk.api.session.room.uploads
import org.matrix.android.sdk.api.MatrixCallback
import org.matrix.android.sdk.api.util.Cancelable
/**
* This interface defines methods to get event with uploads (= attachments) sent to a room. It's implemented at the room level.
*/
@@ -29,7 +26,5 @@ interface UploadsService {
* @param numberOfEvents the expected number of events to retrieve. The result can contain less events.
* @param since token to get next page, or null to get the first page
*/
fun getUploads(numberOfEvents: Int,
since: String?,
callback: MatrixCallback<GetUploadsResult>): Cancelable
suspend fun getUploads(numberOfEvents: Int, since: String?): GetUploadsResult
}

View File

@@ -16,22 +16,16 @@
package org.matrix.android.sdk.api.session.terms
import org.matrix.android.sdk.api.MatrixCallback
import org.matrix.android.sdk.api.util.Cancelable
interface TermsService {
enum class ServiceType {
IntegrationManager,
IdentityService
}
fun getTerms(serviceType: ServiceType,
baseUrl: String,
callback: MatrixCallback<GetTermsResponse>): Cancelable
suspend fun getTerms(serviceType: ServiceType, baseUrl: String): GetTermsResponse
fun agreeToTerms(serviceType: ServiceType,
baseUrl: String,
agreedUrls: List<String>,
token: String?,
callback: MatrixCallback<Unit>): Cancelable
suspend fun agreeToTerms(serviceType: ServiceType,
baseUrl: String,
agreedUrls: List<String>,
token: String?)
}

View File

@@ -0,0 +1,38 @@
/*
* 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 org.matrix.android.sdk.api.extensions.orFalse
// The Android SDK does not provide constant for mime type, add some of them here
object MimeTypes {
const val Any: String = "*/*"
const val OctetStream = "application/octet-stream"
const val Images = "image/*"
const val Png = "image/png"
const val BadJpg = "image/jpg"
const val Jpeg = "image/jpeg"
const val Gif = "image/gif"
fun String?.normalizeMimeType() = if (this == BadJpg) Jpeg else this
fun String?.isMimeTypeImage() = this?.startsWith("image/").orFalse()
fun String?.isMimeTypeVideo() = this?.startsWith("video/").orFalse()
fun String?.isMimeTypeAudio() = this?.startsWith("audio/").orFalse()
}

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

@@ -33,6 +33,7 @@ import org.matrix.android.sdk.internal.di.AuthDatabase
import org.matrix.android.sdk.internal.legacy.DefaultLegacySessionImporter
import org.matrix.android.sdk.internal.wellknown.WellknownModule
import io.realm.RealmConfiguration
import org.matrix.android.sdk.api.auth.HomeServerHistoryService
import java.io.File
@Module(includes = [WellknownModule::class])
@@ -80,4 +81,7 @@ internal abstract class AuthModule {
@Binds
abstract fun bindDirectLoginTask(task: DefaultDirectLoginTask): DirectLoginTask
@Binds
abstract fun bindHomeServerHistoryService(service: DefaultHomeServerHistoryService): HomeServerHistoryService
}

View File

@@ -14,24 +14,25 @@
* 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"

View File

@@ -26,6 +26,7 @@ import org.matrix.android.sdk.api.auth.AuthenticationService
import org.matrix.android.sdk.api.auth.data.Credentials
import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig
import org.matrix.android.sdk.api.auth.data.LoginFlowResult
import org.matrix.android.sdk.api.auth.data.LoginFlowTypes
import org.matrix.android.sdk.api.auth.login.LoginWizard
import org.matrix.android.sdk.api.auth.registration.RegistrationWizard
import org.matrix.android.sdk.api.auth.wellknown.WellknownResult
@@ -33,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
@@ -98,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
@@ -278,6 +326,7 @@ internal class DefaultAuthenticationService @Inject constructor(
}
return LoginFlowResult.Success(
loginFlowResponse.flows.orEmpty().mapNotNull { it.type },
loginFlowResponse.flows.orEmpty().firstOrNull { it.type == LoginFlowTypes.SSO }?.ssoIdentityProvider,
versions.isLoginAndRegistrationSupportedBySdk(),
homeServerUrl,
!versions.isSupportedBySdk()

View File

@@ -0,0 +1,50 @@
/*
* 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
import com.zhuinden.monarchy.Monarchy
import io.realm.kotlin.where
import org.matrix.android.sdk.api.auth.HomeServerHistoryService
import org.matrix.android.sdk.internal.database.model.KnownServerUrlEntity
import org.matrix.android.sdk.internal.di.GlobalDatabase
import javax.inject.Inject
class DefaultHomeServerHistoryService @Inject constructor(
@GlobalDatabase private val monarchy: Monarchy
) : HomeServerHistoryService {
override fun getKnownServersUrls(): List<String> {
return monarchy.fetchAllMappedSync(
{ realm ->
realm.where<KnownServerUrlEntity>()
},
{ it.url }
)
}
override fun addHomeServerToHistory(url: String) {
monarchy.writeAsync { realm ->
KnownServerUrlEntity(url).let {
realm.insertOrUpdate(it)
}
}
}
override fun clearHistory() {
monarchy.runTransactionSync { it.where<KnownServerUrlEntity>().findAll().deleteAllFromRealm() }
}
}

View File

@@ -18,6 +18,7 @@ package org.matrix.android.sdk.internal.auth.data
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import org.matrix.android.sdk.api.auth.data.SsoIdentityProvider
@JsonClass(generateAdapter = true)
internal data class LoginFlowResponse(
@@ -34,5 +35,13 @@ internal data class LoginFlow(
* The login type. This is supplied as the type when logging in.
*/
@Json(name = "type")
val type: String?
val type: String?,
/**
* Augments m.login.sso flow discovery definition to include metadata on the supported IDPs
* the client can show a button for each of the supported providers
* See MSC #2858
*/
@Json(name = "org.matrix.msc2858.identity_providers")
val ssoIdentityProvider: List<SsoIdentityProvider>?
)

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

@@ -51,6 +51,18 @@ data class RegistrationFlowResponse(
* The information that the client will need to know in order to use a given type of authentication.
* For each login stage type presented, that type may be present as a key in this dictionary.
* For example, the public key of reCAPTCHA stage could be given here.
* other example
* "params": {
* "m.login.sso": {
* "identity_providers": [
* {
* "id": "google",
* "name": "Google",
* "icon": "https://..."
* }
* ]
* }
* }
*/
@Json(name = "params")
val params: JsonDict? = null

View File

@@ -18,7 +18,7 @@ package org.matrix.android.sdk.internal.crypto.attachments
import android.os.Parcelable
import org.matrix.android.sdk.internal.crypto.model.rest.EncryptedFileInfo
import kotlinx.android.parcel.Parcelize
import kotlinx.parcelize.Parcelize
fun EncryptedFileInfo.toElementToDecrypt(): ElementToDecrypt? {
// Check the validity of some fields

View File

@@ -20,6 +20,7 @@ import org.matrix.android.sdk.api.session.events.model.Event
import org.matrix.android.sdk.api.session.room.send.SendState
import org.matrix.android.sdk.internal.network.executeRequest
import org.matrix.android.sdk.internal.session.room.RoomAPI
import org.matrix.android.sdk.internal.session.room.membership.LoadRoomMembersTask
import org.matrix.android.sdk.internal.session.room.send.LocalEchoRepository
import org.matrix.android.sdk.internal.session.room.send.SendResponse
import org.matrix.android.sdk.internal.task.Task
@@ -35,11 +36,19 @@ internal interface SendEventTask : Task<SendEventTask.Params, String> {
internal class DefaultSendEventTask @Inject constructor(
private val localEchoRepository: LocalEchoRepository,
private val encryptEventTask: DefaultEncryptEventTask,
private val loadRoomMembersTask: LoadRoomMembersTask,
private val roomAPI: RoomAPI,
private val eventBus: EventBus) : SendEventTask {
override suspend fun execute(params: SendEventTask.Params): String {
try {
// Make sure to load all members in the room before sending the event.
params.event.roomId
?.takeIf { params.encrypt }
?.let { roomId ->
loadRoomMembersTask.execute(LoadRoomMembersTask.Params(roomId))
}
val event = handleEncryption(params)
val localId = event.eventId!!

View File

@@ -31,6 +31,7 @@ import org.matrix.android.sdk.internal.extensions.toUnsignedInt
import org.matrix.olm.OlmSAS
import org.matrix.olm.OlmUtility
import timber.log.Timber
import java.util.Locale
/**
* Represents an ongoing short code interactive key verification between two devices.
@@ -344,7 +345,7 @@ internal abstract class SASDefaultVerificationTransaction(
}
protected fun hashUsingAgreedHashMethod(toHash: String): String? {
if ("sha256".toLowerCase() == accepted?.hash?.toLowerCase()) {
if ("sha256" == accepted?.hash?.toLowerCase(Locale.ROOT)) {
val olmUtil = OlmUtility()
val hashBytes = olmUtil.sha256(toHash)
olmUtil.releaseUtility()
@@ -354,12 +355,11 @@ internal abstract class SASDefaultVerificationTransaction(
}
private fun macUsingAgreedMethod(message: String, info: String): String? {
if (SAS_MAC_SHA256_LONGKDF.toLowerCase() == accepted?.messageAuthenticationCode?.toLowerCase()) {
return getSAS().calculateMacLongKdf(message, info)
} else if (SAS_MAC_SHA256.toLowerCase() == accepted?.messageAuthenticationCode?.toLowerCase()) {
return getSAS().calculateMac(message, info)
return when (accepted?.messageAuthenticationCode?.toLowerCase(Locale.ROOT)) {
SAS_MAC_SHA256_LONGKDF -> getSAS().calculateMacLongKdf(message, info)
SAS_MAC_SHA256 -> getSAS().calculateMac(message, info)
else -> null
}
return null
}
override fun getDecimalCodeRepresentation(): String {

View File

@@ -20,6 +20,9 @@ import io.realm.DynamicRealm
import io.realm.RealmMigration
import org.matrix.android.sdk.internal.database.model.HomeServerCapabilitiesEntityFields
import org.matrix.android.sdk.internal.database.model.PendingThreePidEntityFields
import org.matrix.android.sdk.internal.database.model.PreviewUrlCacheEntityFields
import org.matrix.android.sdk.internal.database.model.RoomEntityFields
import org.matrix.android.sdk.internal.database.model.RoomMembersLoadStatusType
import org.matrix.android.sdk.internal.database.model.RoomSummaryEntityFields
import timber.log.Timber
import javax.inject.Inject
@@ -27,7 +30,7 @@ import javax.inject.Inject
class RealmSessionStoreMigration @Inject constructor() : RealmMigration {
companion object {
const val SESSION_STORE_SCHEMA_VERSION = 5L
const val SESSION_STORE_SCHEMA_VERSION = 7L
}
override fun migrate(realm: DynamicRealm, oldVersion: Long, newVersion: Long) {
@@ -38,6 +41,8 @@ class RealmSessionStoreMigration @Inject constructor() : RealmMigration {
if (oldVersion <= 2) migrateTo3(realm)
if (oldVersion <= 3) migrateTo4(realm)
if (oldVersion <= 4) migrateTo5(realm)
if (oldVersion <= 5) migrateTo6(realm)
if (oldVersion <= 6) migrateTo7(realm)
}
private fun migrateTo1(realm: DynamicRealm) {
@@ -89,4 +94,32 @@ class RealmSessionStoreMigration @Inject constructor() : RealmMigration {
?.removeField("adminE2EByDefault")
?.removeField("preferredJitsiDomain")
}
private fun migrateTo6(realm: DynamicRealm) {
Timber.d("Step 5 -> 6")
realm.schema.create("PreviewUrlCacheEntity")
.addField(PreviewUrlCacheEntityFields.URL, String::class.java)
.setRequired(PreviewUrlCacheEntityFields.URL, true)
.addPrimaryKey(PreviewUrlCacheEntityFields.URL)
.addField(PreviewUrlCacheEntityFields.URL_FROM_SERVER, String::class.java)
.addField(PreviewUrlCacheEntityFields.SITE_NAME, String::class.java)
.addField(PreviewUrlCacheEntityFields.TITLE, String::class.java)
.addField(PreviewUrlCacheEntityFields.DESCRIPTION, String::class.java)
.addField(PreviewUrlCacheEntityFields.MXC_URL, String::class.java)
.addField(PreviewUrlCacheEntityFields.LAST_UPDATED_TIMESTAMP, Long::class.java)
}
private fun migrateTo7(realm: DynamicRealm) {
Timber.d("Step 6 -> 7")
realm.schema.get("RoomEntity")
?.addField(RoomEntityFields.MEMBERS_LOAD_STATUS_STR, String::class.java)
?.transform { obj ->
if (obj.getBoolean("areAllMembersLoaded")) {
obj.setString("membersLoadStatusStr", RoomMembersLoadStatusType.LOADED.name)
} else {
obj.setString("membersLoadStatusStr", RoomMembersLoadStatusType.NONE.name)
}
}
?.removeField("areAllMembersLoaded")
}
}

View File

@@ -0,0 +1,27 @@
/*
* 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.database.model
import io.realm.RealmObject
import io.realm.annotations.PrimaryKey
internal open class KnownServerUrlEntity(
@PrimaryKey
var url: String = ""
) : RealmObject() {
companion object
}

View File

@@ -0,0 +1,36 @@
/*
* 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.database.model
import io.realm.RealmObject
import io.realm.annotations.PrimaryKey
internal open class PreviewUrlCacheEntity(
@PrimaryKey
var url: String = "",
var urlFromServer: String? = null,
var siteName: String? = null,
var title: String? = null,
var description: String? = null,
var mxcUrl: String? = null,
var lastUpdatedTimestamp: Long = 0L
) : RealmObject() {
companion object
}

View File

@@ -23,8 +23,7 @@ import io.realm.annotations.PrimaryKey
internal open class RoomEntity(@PrimaryKey var roomId: String = "",
var chunks: RealmList<ChunkEntity> = RealmList(),
var sendingTimelineEvents: RealmList<TimelineEventEntity> = RealmList(),
var areAllMembersLoaded: Boolean = false
var sendingTimelineEvents: RealmList<TimelineEventEntity> = RealmList()
) : RealmObject() {
private var membershipStr: String = Membership.NONE.name
@@ -36,5 +35,14 @@ internal open class RoomEntity(@PrimaryKey var roomId: String = "",
membershipStr = value.name
}
private var membersLoadStatusStr: String = RoomMembersLoadStatusType.NONE.name
var membersLoadStatus: RoomMembersLoadStatusType
get() {
return RoomMembersLoadStatusType.valueOf(membersLoadStatusStr)
}
set(value) {
membersLoadStatusStr = value.name
}
companion object
}

View File

@@ -0,0 +1,23 @@
/*
* 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.database.model
internal enum class RoomMembersLoadStatusType {
NONE,
LOADING,
LOADED
}

View File

@@ -48,6 +48,7 @@ import io.realm.annotations.RealmModule
PushRulesEntity::class,
PushRuleEntity::class,
PushConditionEntity::class,
PreviewUrlCacheEntity::class,
PusherEntity::class,
PusherDataEntity::class,
ReadReceiptsSummaryEntity::class,

View File

@@ -0,0 +1,39 @@
/*
* 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.database.query
import io.realm.Realm
import io.realm.kotlin.createObject
import io.realm.kotlin.where
import org.matrix.android.sdk.internal.database.model.PreviewUrlCacheEntity
import org.matrix.android.sdk.internal.database.model.PreviewUrlCacheEntityFields
/**
* Get the current PreviewUrlCacheEntity, return null if it does not exist
*/
internal fun PreviewUrlCacheEntity.Companion.get(realm: Realm, url: String): PreviewUrlCacheEntity? {
return realm.where<PreviewUrlCacheEntity>()
.equalTo(PreviewUrlCacheEntityFields.URL, url)
.findFirst()
}
/**
* Get the current PreviewUrlCacheEntity, create one if it does not exist
*/
internal fun PreviewUrlCacheEntity.Companion.getOrCreate(realm: Realm, url: String): PreviewUrlCacheEntity {
return get(realm, url) ?: realm.createObject(url)
}

View File

@@ -71,8 +71,23 @@ internal fun TimelineEventEntity.Companion.latestEvent(realm: Realm,
}
internal fun RealmQuery<TimelineEventEntity>.filterEvents(filters: TimelineEventFilters): RealmQuery<TimelineEventEntity> {
if (filters.filterTypes) {
`in`(TimelineEventEntityFields.ROOT.TYPE, filters.allowedTypes.toTypedArray())
if (filters.filterTypes && filters.allowedTypes.isNotEmpty()) {
beginGroup()
filters.allowedTypes.forEachIndexed { index, filter ->
if (filter.stateKey == null) {
equalTo(TimelineEventEntityFields.ROOT.TYPE, filter.eventType)
} else {
beginGroup()
equalTo(TimelineEventEntityFields.ROOT.TYPE, filter.eventType)
and()
equalTo(TimelineEventEntityFields.ROOT.STATE_KEY, filter.stateKey)
endGroup()
}
if (index != filters.allowedTypes.size - 1) {
or()
}
}
endGroup()
}
if (filters.filterUseless) {
not()

View File

@@ -25,6 +25,7 @@ import okhttp3.OkHttpClient
import org.matrix.android.sdk.api.Matrix
import org.matrix.android.sdk.api.MatrixConfiguration
import org.matrix.android.sdk.api.auth.AuthenticationService
import org.matrix.android.sdk.api.auth.HomeServerHistoryService
import org.matrix.android.sdk.api.raw.RawService
import org.matrix.android.sdk.internal.SessionManager
import org.matrix.android.sdk.internal.auth.AuthModule
@@ -62,6 +63,8 @@ internal interface MatrixComponent {
fun rawService(): RawService
fun homeServerHistoryService(): HomeServerHistoryService
fun context(): Context
fun matrixConfiguration(): MatrixConfiguration
@@ -71,9 +74,6 @@ internal interface MatrixComponent {
@CacheDirectory
fun cacheDir(): File
@ExternalFilesDirectory
fun externalFilesDir(): File?
fun olmManager(): OlmManager
fun taskExecutor(): TaskExecutor

View File

@@ -57,13 +57,6 @@ internal object MatrixModule {
return context.cacheDir
}
@JvmStatic
@Provides
@ExternalFilesDirectory
fun providesExternalFilesDir(context: Context): File? {
return context.getExternalFilesDir(null)
}
@JvmStatic
@Provides
@MatrixScope

View File

@@ -16,14 +16,15 @@
package org.matrix.android.sdk.internal.network
import org.matrix.android.sdk.api.failure.Failure
import org.matrix.android.sdk.api.failure.shouldBeRetried
import org.matrix.android.sdk.internal.network.ssl.CertUtil
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.delay
import org.greenrobot.eventbus.EventBus
import org.matrix.android.sdk.api.failure.Failure
import org.matrix.android.sdk.api.failure.shouldBeRetried
import org.matrix.android.sdk.internal.network.ssl.CertUtil
import retrofit2.Call
import retrofit2.awaitResponse
import timber.log.Timber
import java.io.IOException
internal suspend inline fun <DATA : Any> executeRequest(eventBus: EventBus?,
@@ -49,6 +50,9 @@ internal class Request<DATA : Any>(private val eventBus: EventBus?) {
throw response.toFailure(eventBus)
}
} catch (exception: Throwable) {
// Log some details about the request which has failed
Timber.e("Exception when executing request ${apiCall.request().method} ${apiCall.request().url.toString().substringBefore("?")}")
// Check if this is a certificateException
CertUtil.getCertificateException(exception)
// TODO Support certificate error once logged

View File

@@ -16,7 +16,7 @@
package org.matrix.android.sdk.internal.raw
import org.matrix.android.sdk.api.raw.RawCacheStrategy
import org.matrix.android.sdk.api.cache.CacheStrategy
import org.matrix.android.sdk.api.raw.RawService
import java.util.concurrent.TimeUnit
import javax.inject.Inject
@@ -25,15 +25,15 @@ internal class DefaultRawService @Inject constructor(
private val getUrlTask: GetUrlTask,
private val cleanRawCacheTask: CleanRawCacheTask
) : RawService {
override suspend fun getUrl(url: String, rawCacheStrategy: RawCacheStrategy): String {
return getUrlTask.execute(GetUrlTask.Params(url, rawCacheStrategy))
override suspend fun getUrl(url: String, cacheStrategy: CacheStrategy): String {
return getUrlTask.execute(GetUrlTask.Params(url, cacheStrategy))
}
override suspend fun getWellknown(userId: String): String {
val homeServerDomain = userId.substringAfter(":")
return getUrl(
"https://$homeServerDomain/.well-known/matrix/client",
RawCacheStrategy.TtlCache(TimeUnit.HOURS.toMillis(8), false)
CacheStrategy.TtlCache(TimeUnit.HOURS.toMillis(8), false)
)
}

View File

@@ -18,7 +18,7 @@ package org.matrix.android.sdk.internal.raw
import com.zhuinden.monarchy.Monarchy
import okhttp3.ResponseBody
import org.matrix.android.sdk.api.raw.RawCacheStrategy
import org.matrix.android.sdk.api.cache.CacheStrategy
import org.matrix.android.sdk.internal.database.model.RawCacheEntity
import org.matrix.android.sdk.internal.database.query.get
import org.matrix.android.sdk.internal.database.query.getOrCreate
@@ -32,7 +32,7 @@ import javax.inject.Inject
internal interface GetUrlTask : Task<GetUrlTask.Params, String> {
data class Params(
val url: String,
val rawCacheStrategy: RawCacheStrategy
val cacheStrategy: CacheStrategy
)
}
@@ -42,14 +42,14 @@ internal class DefaultGetUrlTask @Inject constructor(
) : GetUrlTask {
override suspend fun execute(params: GetUrlTask.Params): String {
return when (params.rawCacheStrategy) {
RawCacheStrategy.NoCache -> doRequest(params.url)
is RawCacheStrategy.TtlCache -> doRequestWithCache(
return when (params.cacheStrategy) {
CacheStrategy.NoCache -> doRequest(params.url)
is CacheStrategy.TtlCache -> doRequestWithCache(
params.url,
params.rawCacheStrategy.validityDurationInMillis,
params.rawCacheStrategy.strict
params.cacheStrategy.validityDurationInMillis,
params.cacheStrategy.strict
)
RawCacheStrategy.InfiniteCache -> doRequestWithCache(
CacheStrategy.InfiniteCache -> doRequestWithCache(
params.url,
Long.MAX_VALUE,
true

View File

@@ -0,0 +1,41 @@
/*
* 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.raw
import io.realm.DynamicRealm
import io.realm.RealmMigration
import org.matrix.android.sdk.internal.database.model.KnownServerUrlEntityFields
import timber.log.Timber
internal object GlobalRealmMigration : RealmMigration {
// Current schema version
const val SCHEMA_VERSION = 1L
override fun migrate(realm: DynamicRealm, oldVersion: Long, newVersion: Long) {
Timber.d("Migrating Auth Realm from $oldVersion to $newVersion")
if (oldVersion <= 0) migrateTo1(realm)
}
private fun migrateTo1(realm: DynamicRealm) {
realm.schema.create("KnownServerUrlEntity")
.addField(KnownServerUrlEntityFields.URL, String::class.java)
.addPrimaryKey(KnownServerUrlEntityFields.URL)
.setRequired(KnownServerUrlEntityFields.URL, true)
}
}

View File

@@ -17,6 +17,7 @@
package org.matrix.android.sdk.internal.raw
import io.realm.annotations.RealmModule
import org.matrix.android.sdk.internal.database.model.KnownServerUrlEntity
import org.matrix.android.sdk.internal.database.model.RawCacheEntity
/**
@@ -24,6 +25,7 @@ import org.matrix.android.sdk.internal.database.model.RawCacheEntity
*/
@RealmModule(library = true,
classes = [
RawCacheEntity::class
RawCacheEntity::class,
KnownServerUrlEntity::class
])
internal class GlobalRealmModule

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