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

Compare commits

...

249 Commits

Author SHA1 Message Date
Benoit Marty
789746c276 Merge branch 'hotfix/1.5.13' into main 2022-12-19 16:58:28 +01:00
Benoit Marty
241d011d30 Changelog (same than 1.5.13) 2022-12-19 16:56:29 +01:00
Benoit Marty
ed01f32393 Add largeHeap=true in the manifest since we are seeing more crashes (OOM) when handling sync response. 2022-12-19 16:54:15 +01:00
Benoit Marty
ffa49870a9 Version 1.5.13 2022-12-19 16:52:32 +01:00
Benoit Marty
7341e5c47b Merge branch 'release/1.5.12' into main 2022-12-15 10:18:25 +01:00
Benoit Marty
cf1a115c67 Merge branch 'release/1.5.12' into main 2022-12-15 10:16:25 +01:00
Benoit Marty
dd88ac597e Adding fastlane file for version 1.5.12 2022-12-15 10:16:02 +01:00
Benoit Marty
82ad08aced Changelog for version 1.5.12 2022-12-15 10:15:24 +01:00
Nikita Fedrunov
cf3abd6562 thread list loading (#7766) 2022-12-14 18:56:16 +01:00
Yoan Pintas
c74ea2dd16 Merge pull request #7719 from vector-im/feature/fre/voice_broadcast_last_message
Voice Broadcast - Update last message in the room list
2022-12-14 17:39:42 +01:00
Nikita Fedrunov
e0a611a16e changed copy for threads labs flag (#7776) 2022-12-14 15:13:24 +01:00
Maxime NATUREL
fe5e4d6830 Merge pull request #7757 from vector-im/fix/mna/poll-end-not-recognized
[Poll] Poll end event is not recognized (PSG-948 and PSG-949)
2022-12-13 17:08:01 +01:00
Maxime NATUREL
851276978f Remove unused import 2022-12-13 15:47:30 +01:00
Maxime NATUREL
96e29d4d10 Renaming the name of the test file be consistent 2022-12-13 15:46:14 +01:00
Maxime NATUREL
71df1e61d4 Remove non necessary call when getting the targeted event id 2022-12-13 15:45:46 +01:00
Nikita Fedrunov
3dadebe505 threads are enabled by default end forced to enabled for existing users (#7775) 2022-12-13 14:02:45 +01:00
dependabot[bot]
4657729e36 Bump dependency-check-gradle from 7.3.0 to 7.4.1 (#7759)
Bumps dependency-check-gradle from 7.3.0 to 7.4.1.

---
updated-dependencies:
- dependency-name: org.owasp:dependency-check-gradle
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-13 12:41:17 +00:00
Valere
d05e10e10a crypto migration tests (#7645)
Crypto migration tests

Co-authored-by: Benoit Marty <benoitm@matrix.org>
2022-12-13 11:38:49 +01:00
Onuray Sahin
250bd9c620 Merge pull request #7754 from vector-im/feature/ons/remove_client_information_account_data
Delete unused client information from account data (PSG-871)
2022-12-13 11:10:41 +03:00
Nikita Fedrunov
4e0c3a97bd thread message notification should navigate to thread timeline (#7771) 2022-12-12 22:35:09 +01:00
Hugh Nimmo-Smith
34ee399f94 Merge pull request #7737 from vector-im/bugfix/hughns/qr-server-change 2022-12-12 18:21:39 +00:00
Hugh Nimmo-Smith
0ffc2af679 Update test to work with new state 2022-12-12 17:32:28 +00:00
Onuray Sahin
9954045d30 Merge pull request #7740 from vector-im/feature/ons/remove_account_data
Handle account data removal (PSG-865, PSG-867)
2022-12-12 19:31:16 +03:00
Hugh Nimmo-Smith
f111a84e17 More unit test fix 2022-12-12 16:30:35 +00:00
Hugh Nimmo-Smith
096e52612e More fix up of unit tests 2022-12-12 16:30:35 +00:00
Hugh Nimmo-Smith
643b09a77c Fix up unit tests 2022-12-12 16:30:35 +00:00
Hugh Nimmo-Smith
1437f6d41d Remove unused bad function call 2022-12-12 16:30:35 +00:00
Hugh Nimmo-Smith
006e2b5c0d Changelog 2022-12-12 16:30:35 +00:00
Hugh Nimmo-Smith
21cbe52740 Lint 2022-12-12 16:30:34 +00:00
Hugh Nimmo-Smith
1930047ce1 Fix issue of QR not being offered where domain is entered instead of homeserver 2022-12-12 16:30:34 +00:00
Onuray Sahin
8c6c2dd5c2 Code review fixes. 2022-12-12 16:36:40 +03:00
Jorge Martin Espinosa
c523e144b8 Rich text editor: improve performance when changing composer mode (#7691)
* Rich text editor: improve performance when changing composer mode

* Add changelog

* Make `MessageComposerMode.Quote` and `Reply` data classes

* Re-arrange code to fix composer not being emptied when sneding a message
2022-12-12 13:52:17 +01:00
Ekaterina Gerasimova
a12167077f Update project board IDs for automation
"PN-" prefixed IDs are no longer working, update to new IDs
2022-12-12 10:40:49 +00:00
Onuray Sahin
746fb7719a Code review fixes. 2022-12-12 13:39:56 +03:00
Maxime NATUREL
361b0411c7 Merge pull request #7747 from vector-im/fix/mna/verification-request-priority
Verification request is not showing when verify session popup is displayed (PSG-1017)
2022-12-12 09:44:25 +01:00
dependabot[bot]
74d7e60380 Bump fragment from 1.5.4 to 1.5.5 (#7741)
Bumps `fragment` from 1.5.4 to 1.5.5.

Updates `fragment-ktx` from 1.5.4 to 1.5.5

Updates `fragment-testing` from 1.5.4 to 1.5.5

---
updated-dependencies:
- dependency-name: androidx.fragment:fragment-ktx
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: androidx.fragment:fragment-testing
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-12 09:21:24 +01:00
Onuray Sahin
85a6c8c6f2 Write unit tests for the use case. 2022-12-09 19:53:20 +03:00
Maxime NATUREL
dba8aaea16 Merge pull request #7752 from vector-im/fix/mna/wrong-usage-of-stable-fields
Revert usage of stable fields in live location sharing and polls
2022-12-09 17:32:53 +01:00
Maxime NATUREL
bd91db66f8 Fixing retrieve of related event id in the end poll event during aggregation 2022-12-09 14:07:06 +01:00
Onuray Sahin
7a667b513e Execute use case from a better place. 2022-12-09 15:47:28 +03:00
Hugh Nimmo-Smith
a762179c32 Merge pull request #7699 from vector-im/bugfix/hughns/qr-device-race 2022-12-09 12:04:29 +00:00
Onuray Sahin
22cce30e35 Create use case to detect and delete unnecessary account data of client information. 2022-12-09 14:53:27 +03:00
Onuray Sahin
8206b534f9 Create a task to delete an event data with a given type. 2022-12-09 14:52:27 +03:00
Onuray Sahin
3d68233723 Support retrieving account data whose key starts with a string. 2022-12-09 14:51:23 +03:00
Maxime NATUREL
57cedaeb69 Adding changelog entry 2022-12-09 10:10:59 +01:00
Maxime NATUREL
be7b49b707 Merge pull request #7736 from vector-im/fix/mna/session-without-crypto-keys
[Session manager] Sessions without encryption support should not prompt to verify (PSG-1004)
2022-12-09 09:52:39 +01:00
Nikita Fedrunov
cf59c80100 stop listening timeline collection changes when app is not resumed (#7734) 2022-12-09 09:42:45 +01:00
Maxime NATUREL
99942c2714 Adding changelog entry 2022-12-09 09:33:06 +01:00
Maxime NATUREL
220b1d86c0 Reverting usage of some stable fields whereas related MSCs have not landed into the specs yet 2022-12-08 17:42:51 +01:00
Benoit Marty
ee737025f2 Merge pull request #7744 from vector-im/feature/bma/quickCrashFix
Fix crash
2022-12-08 16:01:55 +01:00
Onuray Sahin
b09a00efda Code review fixes. 2022-12-08 17:11:09 +03:00
Maxime NATUREL
63bde230a3 Cancel verification alerts when adding the incoming request alert and when starting the process 2022-12-08 14:40:17 +01:00
Hugh Nimmo-Smith
7bbd91f2a9 Handle error whilst download key for self 2022-12-08 13:27:49 +00:00
Hugh Nimmo-Smith
3a2a916c2f Clarify comment 2022-12-08 13:27:49 +00:00
Hugh Nimmo-Smith
d0b2c0693d Changelog 2022-12-08 13:27:49 +00:00
Hugh Nimmo-Smith
73fd93148a Download device keys for self prior to verification checks
Fixes https://github.com/vector-im/element-android/issues/7676
2022-12-08 13:27:49 +00:00
Maxime NATUREL
df55c84167 Raise priority of incoming verification request alert + cancel existing verification alerts 2022-12-08 14:00:35 +01:00
jonnyandrew
de18f37849 [Rich text editor] Add error tracking for rich text editor (#7695) 2022-12-08 11:43:19 +00:00
Onuray Sahin
d6c20226bb Add changelog. 2022-12-08 13:46:01 +03:00
dependabot[bot]
72ecd1bbc9 Bump kotlin-gradle-plugin from 1.7.21 to 1.7.22 (#7664)
Bumps [kotlin-gradle-plugin](https://github.com/JetBrains/kotlin) from 1.7.21 to 1.7.22.
- [Release notes](https://github.com/JetBrains/kotlin/releases)
- [Changelog](https://github.com/JetBrains/kotlin/blob/master/ChangeLog.md)
- [Commits](https://github.com/JetBrains/kotlin/compare/v1.7.21...v1.7.22)

---
updated-dependencies:
- dependency-name: org.jetbrains.kotlin:kotlin-gradle-plugin
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-08 10:51:20 +01:00
Benoit Marty
b25f185d63 Try to fix issue about danger file not found. 2022-12-08 10:48:17 +01:00
Maxime NATUREL
b49045ff15 Adding changelog entry 2022-12-08 10:37:00 +01:00
Benoit Marty
7034d82259 changelog 2022-12-08 10:36:29 +01:00
Benoit Marty
a5ab1b4a8b Fix crash kotlin.UninitializedPropertyAccessException: lateinit property avatarRenderer has not been initialized. AvatarRenderer is not used here. 2022-12-08 10:34:08 +01:00
ganfra
ceec2018a7 Merge pull request #7686 from vector-im/dependabot/gradle/com.facebook.soloader-soloader-0.10.5
Bump soloader from 0.10.4 to 0.10.5
2022-12-07 20:24:13 +01:00
Onuray Sahin
055bf6d302 Revert unused companion object. 2022-12-07 21:41:22 +03:00
Benoit Marty
7d31cc9f55 Merge pull request #7730 from vector-im/dependabot/gradle/io.element.android-wysiwyg-0.9.0
Bump wysiwyg from 0.8.0 to 0.9.0
2022-12-07 18:14:05 +01:00
Florian Renaud
59859ec02e Prioritize call events against live broadcast 2022-12-07 18:11:52 +01:00
Florian Renaud
bb7323a935 Rename some use cases 2022-12-07 18:11:52 +01:00
Florian Renaud
28c59e3290 Changelog 2022-12-07 18:11:52 +01:00
Florian Renaud
35c528405d Code cleanup 2022-12-07 18:11:52 +01:00
Florian Renaud
7a1dfef6d5 Display a notice in the timeline when a voice broadcast is stopped 2022-12-07 18:11:52 +01:00
Florian Renaud
aa5270760e Hide typing events if there is a live voice broadcast 2022-12-07 18:11:51 +01:00
Florian Renaud
69beef4648 Show voice broadcast events in the room list
fix factory
2022-12-07 18:11:51 +01:00
Florian Renaud
1a3ca7b1a0 Filter event types from decrypted content 2022-12-07 18:11:51 +01:00
Florian Renaud
6e5461f300 Stop filtering events with reference relationship when computing latest previewable event 2022-12-07 18:11:51 +01:00
Florian Renaud
4d6c04baf9 Add provider for custom event types 2022-12-07 18:11:51 +01:00
Florian Renaud
fdb8743ad3 Create provider package 2022-12-07 18:11:51 +01:00
Onuray Sahin
f4429d4c9c Handle sync response to delete user and room account data. 2022-12-07 18:58:14 +03:00
Maxime NATUREL
23c2682f8d Fixing code style issues 2022-12-07 16:39:51 +01:00
Onuray Sahin
765202e05a Add helper functions to delete user and room account data. 2022-12-07 18:17:43 +03:00
Maxime NATUREL
c580090f20 Merge pull request #7707 from vector-im/feature/mna/rename-and-signout-action-current-session
[Session manager] Add actions to rename and signout current session (PSG-885)
2022-12-07 16:16:44 +01:00
Valere
01533db4e0 Merge pull request #7713 from vector-im/feature/bca/to_device_tracing
add to device tracing id
2022-12-07 16:16:20 +01:00
Onuray Sahin
d244f7324c Add api functions to delete account data. 2022-12-07 18:12:25 +03:00
Maxime NATUREL
88f7439880 Updating comment to clarify intention 2022-12-07 16:04:27 +01:00
Benoit Marty
6c94f1cd52 Quick tweak on the release script. 2022-12-07 15:50:26 +01:00
Maxime NATUREL
a44c8dfca3 Renaming a method to avoid confusion 2022-12-07 15:10:21 +01:00
Benoit Marty
d0b1a7bfd1 Merge pull request #7723 from vector-im/feature/bma/disableNightlyPopup
Disable nightly popup
2022-12-07 15:01:09 +01:00
Maxime NATUREL
f014866d06 Handling the case where device has no CryptoDeviceInfo 2022-12-07 14:34:45 +01:00
Benoit Marty
c9c5483d22 Changelog 2022-12-07 14:10:23 +01:00
Benoit Marty
40bfffae9d Merge branch 'hotfix/1.5.11' into main 2022-12-07 14:03:49 +01:00
Benoit Marty
03440307ce Merge branch 'hotfix/1.5.11' into develop 2022-12-07 14:03:48 +01:00
Benoit Marty
242ef518b2 Merge hotfix 1.5.11 into develop (the fix is already on develop) 2022-12-07 14:03:08 +01:00
Benoit Marty
3132a7d463 Towncrier 1.5.11 2022-12-07 13:59:42 +01:00
Benoit Marty
a0bba91d67 Fastlane file for hotfix 1.5.11 2022-12-07 13:58:51 +01:00
Benoit Marty
6c84668611 Hotfix 1.5.11 2022-12-07 13:58:02 +01:00
Benoit Marty
53b703dcaf Changelog 2022-12-07 13:55:42 +01:00
Benoit Marty
1acd8e1049 Do not propagate failure if saving the filter server side fails. This will be retried later. 2022-12-07 13:55:18 +01:00
Benoit Marty
4a5f4849e5 Merge pull request #7725 from vector-im/feature/bma/filterCrash
Do not propagate failure if saving the filter server side fails
2022-12-07 13:54:57 +01:00
Benoit Marty
11dded71ec Changelog 2022-12-07 13:54:20 +01:00
ganfra
440944decb Merge pull request #7669 from vector-im/dependabot/gradle/com.google.devtools.ksp-1.7.22-1.0.8
Bump com.google.devtools.ksp from 1.7.21-1.0.8 to 1.7.22-1.0.8
2022-12-07 11:43:05 +01:00
Maxime NATUREL
041fcef1db Adding changelog entry 2022-12-07 10:30:47 +01:00
dependabot[bot]
9bbecbeed3 Bump wysiwyg from 0.8.0 to 0.9.0
Bumps [wysiwyg](https://github.com/matrix-org/matrix-wysiwyg) from 0.8.0 to 0.9.0.
- [Release notes](https://github.com/matrix-org/matrix-wysiwyg/releases)
- [Changelog](https://github.com/matrix-org/matrix-rich-text-editor/blob/main/CHANGELOG.md)
- [Commits](https://github.com/matrix-org/matrix-wysiwyg/compare/0.8.0...0.9.0)

---
updated-dependencies:
- dependency-name: io.element.android:wysiwyg
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-06 23:02:30 +00:00
Benoit Marty
988afa4ebe Fix FDroid build 2022-12-06 18:21:07 +01:00
dependabot[bot]
a6752a0cf1 Bump com.google.devtools.ksp from 1.7.21-1.0.8 to 1.7.22-1.0.8
Bumps [com.google.devtools.ksp](https://github.com/google/ksp) from 1.7.21-1.0.8 to 1.7.22-1.0.8.
- [Release notes](https://github.com/google/ksp/releases)
- [Commits](https://github.com/google/ksp/compare/1.7.21-1.0.8...1.7.22-1.0.8)

---
updated-dependencies:
- dependency-name: com.google.devtools.ksp
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-06 16:10:25 +00:00
Benoit Marty
b9eb271aff Merge pull request #7712 from vector-im/feature/bma/startServiceApi
Use the latest startForeground API
2022-12-06 17:05:07 +01:00
Florian Renaud
3b3947d046 Merge pull request #7677 from vector-im/dependabot/gradle/com.autonomousapps.dependency-analysis-1.17.0
Bump com.autonomousapps.dependency-analysis from 1.16.0 to 1.17.0
2022-12-06 17:04:58 +01:00
valere
63d2886415 use msgid in logs for consistency 2022-12-06 16:07:24 +01:00
Onuray Sahin
f76a6de10d Merge pull request #7710 from vector-im/feature/ons/fix_unknown_shield_icon_in_room
Fix usage of unknown shield in room summary (PSG-1019)
2022-12-06 17:51:04 +03:00
valere
8646cc441d do not add tracing ids to verification events 2022-12-06 15:30:06 +01:00
Benoit Marty
ae93c07597 Do not propagate failure if saving the filter server side fails. This will be retried later. 2022-12-06 15:01:47 +01:00
Maxime NATUREL
6f0a95b828 Merge pull request #7692 from vector-im/feature/mna/listen-notification-account-data
Update notifications setting when m.local_notification_settings.<device-id> event changes for current device (PSG-874)
2022-12-06 14:12:01 +01:00
Benoit Marty
0d12dbbe7e Disable the Nightly popup, user registration (with updateIfNewReleaseAvailable()) to get upgrade does not work.
Add a nightly build section in the preferences to manually try to upgrade.
2022-12-06 12:51:46 +01:00
Benoit Marty
a65e13970d appdistribution is only for nightly builds, not necessary for gplay (prod) builds. 2022-12-06 12:22:50 +01:00
Onuray Sahin
4cd4cf1c51 Code review fix. 2022-12-06 14:06:14 +03:00
valere
139eb1708c fix uncheck cast warning 2022-12-06 08:17:31 +01:00
valere
2ed212aa11 Fix copyright 2022-12-05 18:30:38 +01:00
valere
f2952f2dee add to device tracing id 2022-12-05 18:15:55 +01:00
Maxime NATUREL
b5f6dc0034 Merge pull request #7696 from vector-im/feature/mna/signout-all-other-sessions
[Session manager] Add action to signout all the other session (PSG-888)
2022-12-05 17:50:14 +01:00
Maxime NATUREL
7b830d1c1a Renaming a use case 2022-12-05 17:40:38 +01:00
Maxime NATUREL
a12c640984 Merge pull request #7630 from vector-im/feature/mna/remote-notification-toggle-account-data
Save m.local_notification_settings.<device-id> event in account_data (PSG-873)
2022-12-05 16:58:51 +01:00
Maxime NATUREL
a2f8fed63c Merge pull request #7675 from vector-im/fix/mna/unified-push-selection
ANR when asking to select the notification method
2022-12-05 16:58:09 +01:00
Benoit Marty
febf01a2e6 Use the API startForeground(int id, @NonNull Notification notification, @ForegroundServiceType int foregroundServiceType) when available.
Add missing android:foregroundServiceType in the manifest
2022-12-05 16:36:31 +01:00
Onuray Sahin
32ded289fc Add changelog. 2022-12-05 18:18:09 +03:00
Onuray Sahin
516103e51b Fix usage of unknown shield in room summary. 2022-12-05 18:10:22 +03:00
Maxime NATUREL
a00508e085 Removing unused import 2022-12-05 14:12:00 +01:00
Maxime NATUREL
57554c5d36 Handling signout current session action 2022-12-05 14:10:56 +01:00
Benoit Marty
201873f5a7 Merge pull request #7700 from RiotTranslateBot/weblate-element-android-element-app
Translations update from Weblate
2022-12-05 14:06:49 +01:00
Benoit Marty
a6904d2604 Merge pull request #7689 from vector-im/feature/bma/pills_color
Fix bad pills color background.
2022-12-05 14:05:44 +01:00
Maxime NATUREL
540758d66b Navigate to rename session screen from current session menu 2022-12-05 10:43:56 +01:00
dependabot[bot]
7e0a597c65 Bump wysiwyg from 0.7.0.1 to 0.8.0 (#7666)
Bumps [wysiwyg](https://github.com/matrix-org/matrix-wysiwyg) from 0.7.0.1 to 0.8.0.
- [Release notes](https://github.com/matrix-org/matrix-wysiwyg/releases)
- [Changelog](https://github.com/matrix-org/matrix-rich-text-editor/blob/main/CHANGELOG.md)
- [Commits](https://github.com/matrix-org/matrix-wysiwyg/commits/0.8.0)

---
updated-dependencies:
- dependency-name: io.element.android:wysiwyg
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-12-05 09:42:20 +00:00
Maxime NATUREL
bbc756136c Adding the rename and signout actions in the menu 2022-12-05 10:26:07 +01:00
dependabot[bot]
b4792c8a59 Bump leakcanary-android from 2.9.1 to 2.10 (#7570) 2022-12-05 10:20:02 +01:00
Benoit Marty
b8023d66de Fix formatting 2022-12-05 09:57:02 +01:00
Maxime NATUREL
c12af5a800 Listening changes on notifications enabled preference to update the UI in settings 2022-12-05 09:46:14 +01:00
Maxime NATUREL
9fbfe82044 Fix observation of the notification status for the current session 2022-12-05 09:46:14 +01:00
Maxime NATUREL
18ab8a1279 Adding changelog entry 2022-12-05 09:46:14 +01:00
Maxime NATUREL
635f975b6c Fix missing unregister of pusher when notifications are disabled 2022-12-05 09:43:57 +01:00
Maxime NATUREL
e09b9a2ce0 Fixing wrong notification status when no registered pusher for the session 2022-12-05 09:43:57 +01:00
Maxime NATUREL
b78de15228 Adding unit tests for new toggle notification for current session use case 2022-12-05 09:43:57 +01:00
Maxime NATUREL
5248a69fe2 Updating existing unit tests 2022-12-05 09:43:57 +01:00
Maxime NATUREL
06681fd115 Removing listening on background sync preference 2022-12-05 09:43:57 +01:00
Maxime NATUREL
3f5147ddce Fixing the toggle notifications use case for current session 2022-12-05 09:43:57 +01:00
Maxime NATUREL
8973f3892a Fixing unit tests after rebase 2022-12-05 09:43:57 +01:00
Maxime NATUREL
9dff4ff949 Fixing import order after rebase 2022-12-05 09:43:57 +01:00
Maxime NATUREL
68d00e00d1 Fix method used to check if background sync is enabled 2022-12-05 09:43:56 +01:00
Maxime NATUREL
a2ae3af69d Removing unused imports 2022-12-05 09:43:56 +01:00
Maxime NATUREL
7c10a4cb21 Adding tests for notifications setting updater 2022-12-05 09:43:56 +01:00
Maxime NATUREL
637961bbb1 Update related account data event on notification method change 2022-12-05 09:43:56 +01:00
Maxime NATUREL
e99dc1d163 Remove unused parameters from some ViewModel 2022-12-05 09:43:56 +01:00
Maxime NATUREL
ab6a6b53c8 Some refactorings + update unit tests 2022-12-05 09:43:56 +01:00
Maxime NATUREL
7c51174d7e Renaming some use cases to be consistent 2022-12-05 09:43:56 +01:00
Maxime NATUREL
14b21dc039 Adding use cases to create and delete notifications settings in account data 2022-12-05 09:43:56 +01:00
Maxime NATUREL
b163b42d3d Use new sub usecase in the TogglePushNotificationUseCase 2022-12-05 09:43:56 +01:00
Maxime NATUREL
81c64503f2 Adding SetNotificationSettingsAccountDataUseCase 2022-12-05 09:43:56 +01:00
Maxime NATUREL
c56eb331db Update use cases to enable/disable push notifications for the current session 2022-12-05 09:43:56 +01:00
Maxime NATUREL
9d684bc021 Check if account data has content to decide if push notifications can be toggled using account data 2022-12-05 09:43:56 +01:00
Maxime NATUREL
0c6781e9ef Adding changelog entry 2022-12-05 09:43:55 +01:00
Maxime NATUREL
f8c59f6b0c Removing unused import 2022-12-05 09:42:03 +01:00
Maxime NATUREL
d31652e910 Adding unit tests for settings ViewModel 2022-12-05 09:42:03 +01:00
Maxime NATUREL
e78e192853 Adding unit tests for FCM token retrieval 2022-12-05 09:42:03 +01:00
Maxime NATUREL
2a8c72bdcf Fixing code style issues 2022-12-05 09:42:03 +01:00
Maxime NATUREL
46ccf4d73f Adding unit tests for register and unregister use cases 2022-12-05 09:42:01 +01:00
Maxime NATUREL
a3815d7012 Update unit tests 2022-12-05 09:41:24 +01:00
Maxime NATUREL
aa3a808d2c Do not ask to select push distributor in home if notifications are disabled 2022-12-05 09:41:24 +01:00
Maxime NATUREL
740ed89638 Removing the old methods from helper 2022-12-05 09:41:24 +01:00
Maxime NATUREL
2673979ef8 Handling change of notification method 2022-12-05 09:41:24 +01:00
Maxime NATUREL
95556d2551 Change the distributor in dialog cancellation only if there is no existing one 2022-12-05 09:41:24 +01:00
Maxime NATUREL
3f944e9d36 Extracting the logic to toggle notifications for device into a ViewModel 2022-12-05 09:41:24 +01:00
Maxime NATUREL
b29191e892 Using use cases inside component for endpoint testing 2022-12-05 09:41:24 +01:00
Maxime NATUREL
58efe90f7d Removing some debug logs 2022-12-05 09:41:23 +01:00
Maxime NATUREL
2890f41f30 Replacing unregister method by usecase 2022-12-05 09:41:23 +01:00
Maxime NATUREL
4dbca7858c Adding new use cases to handle the Unified push registration 2022-12-05 09:41:23 +01:00
Maxime NATUREL
9456789047 Adding changelog entry 2022-12-05 09:41:23 +01:00
Onuray Sahin
34d29dc9d7 Merge pull request #7694 from vector-im/feature/ons/unverified_sessions_alert
Remind unverified sessions with a banner once a week (PSG-892)
2022-12-03 14:23:10 +03:00
Weblate
19982e8d77 Merge branch 'origin/develop' into Weblate. 2022-12-03 06:33:28 +00:00
Linerly
70e9f13ec2 Translated using Weblate (Indonesian)
Currently translated at 100.0% (83 of 83 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/id/
2022-12-03 06:33:27 +00:00
waclaw66
58d10e901e Translated using Weblate (Czech)
Currently translated at 100.0% (83 of 83 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/cs/
2022-12-03 06:33:25 +00:00
Jeff Huang
61eb0d6b44 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (83 of 83 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/zh_Hant/
2022-12-03 06:33:22 +00:00
Priit Jõerüüt
10d03e16af Translated using Weblate (Estonian)
Currently translated at 100.0% (83 of 83 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/et/
2022-12-03 06:33:20 +00:00
Ihor Hordiichuk
873fa2a210 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (83 of 83 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/uk/
2022-12-03 06:33:18 +00:00
Jozef Gaal
098dee1aa7 Translated using Weblate (Slovak)
Currently translated at 100.0% (83 of 83 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/sk/
2022-12-03 06:33:16 +00:00
Vri
6d1f9408c8 Translated using Weblate (German)
Currently translated at 100.0% (83 of 83 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/de/
2022-12-03 06:33:13 +00:00
phardyle
53ef97d949 Translated using Weblate (Chinese (Simplified))
Currently translated at 99.6% (2550 of 2558 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/zh_Hans/
2022-12-03 06:33:11 +00:00
Onuray Sahin
980d59ab58 Fix lint. 2022-12-02 21:21:12 +03:00
Maxime NATUREL
b8ab1b5620 Adding changelog entry 2022-12-02 17:35:13 +01:00
Maxime NATUREL
efc436c3f5 Hide the action when there are no other sessions 2022-12-02 17:17:44 +01:00
Maxime NATUREL
2b8dc13dca Adding listener on the new menu item 2022-12-02 17:11:10 +01:00
Maxime NATUREL
62e2f06e2a Adding menu for current session header 2022-12-02 17:08:29 +01:00
Benoit Marty
ab43f4cf14 Add snapshot test for room item 2022-12-02 17:06:48 +01:00
Onuray Sahin
f576f83339 Add changelog. 2022-12-02 19:02:55 +03:00
Maxime NATUREL
e857407bc1 Adding changelog entry 2022-12-02 16:50:46 +01:00
Benoit Marty
6f934e2d49 Extract paparazzi rule creation 2022-12-02 16:50:45 +01:00
Onuray Sahin
4050975a19 Implement new logic for new login banner. 2022-12-02 18:15:10 +03:00
Benoit Marty
310ea99c44 Fix bad pills color background. For light and dark theme the color is now 61708B (iso EleWeb) 2022-12-02 10:50:08 +01:00
Benoit Marty
75fabb1b0d Merge pull request #7684 from vector-im/feature/bma/fix_onboarding_crash
Fix crash when invalid url is entered #7672
2022-12-02 09:55:19 +01:00
jonnyandrew
20b1eaba9e Fix crash in message composer when room is missing (#7683)
This error was seen before but has been reintroduced during refactoring.
- see https://github.com/vector-im/element-android/pull/6978
2022-12-02 08:41:33 +00:00
Maxime NATUREL
4c58cc877f Merge pull request #7688 from vector-im/dependabot/gradle/flipper-0.176.0
Bump flipper from 0.175.0 to 0.176.0
2022-12-02 09:29:42 +01:00
dependabot[bot]
f0ad75a2b7 Bump flipper from 0.175.0 to 0.176.0
Bumps `flipper` from 0.175.0 to 0.176.0.

Updates `flipper` from 0.175.0 to 0.176.0
- [Release notes](https://github.com/facebook/flipper/releases)
- [Commits](https://github.com/facebook/flipper/compare/v0.175.0...v0.176.0)

Updates `flipper-network-plugin` from 0.175.0 to 0.176.0
- [Release notes](https://github.com/facebook/flipper/releases)
- [Commits](https://github.com/facebook/flipper/compare/v0.175.0...v0.176.0)

---
updated-dependencies:
- dependency-name: com.facebook.flipper:flipper
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: com.facebook.flipper:flipper-network-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-01 23:03:43 +00:00
dependabot[bot]
b70370b217 Bump soloader from 0.10.4 to 0.10.5
Bumps [soloader](https://github.com/facebook/soloader) from 0.10.4 to 0.10.5.
- [Release notes](https://github.com/facebook/soloader/releases)
- [Commits](https://github.com/facebook/soloader/commits)

---
updated-dependencies:
- dependency-name: com.facebook.soloader:soloader
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-01 23:02:57 +00:00
Benoit Marty
ca34b29b20 Merge pull request #7685 from vector-im/chore/move-changelog-entry
Move changelog entry to correct directory
2022-12-01 18:25:19 +01:00
Jonny Andrew
c12906971a Move changelog entry to correct dir 2022-12-01 17:15:23 +00:00
Benoit Marty
b6aae0c7c1 Add unit test for canLoginWithQrCode = true 2022-12-01 17:51:44 +01:00
Benoit Marty
381103383e Fix unit tests. 2022-12-01 17:44:12 +01:00
Benoit Marty
d580d4cdb6 Read sensible data from the env and do not rely to an external script anymore. 2022-12-01 17:17:22 +01:00
Benoit Marty
d96ff6e527 Changelog 2022-12-01 15:38:31 +01:00
Benoit Marty
341967bf3c Fix crash when invalid url is entered #7672 2022-12-01 15:25:54 +01:00
jonnyandrew
da5db0ed15 [Rich text editor] Fix keyboard closing after collapsing rich text editor (#7659) 2022-12-01 13:39:01 +00:00
Florian Renaud
c20500ab7a Merge pull request #7590 from vector-im/dependabot/gradle/com.adevinta.android-barista-4.3.0
Bump barista from 4.2.0 to 4.3.0
2022-12-01 14:34:53 +01:00
Jorge Martin Espinosa
0c11778d33 Rich Text Editor: fix several inset issues in room screen (#7681) 2022-12-01 10:26:55 +00:00
Benoit Marty
c8a73a6ac8 Merge pull request #7477 from vector-im/task/langleyd/migrate-rich-text_label
Add Z-Labs label for rich text editor and migrate to new label naming
2022-12-01 11:13:12 +01:00
Benoit Marty
79e8c5f38c Merge pull request #7649 from vector-im/gradlew-update-7.6
Update Gradle Wrapper from 7.5.1 to 7.6
2022-12-01 11:04:08 +01:00
Weblate
d2ab9a2515 Merge branch 'origin/develop' into Weblate. 2022-12-01 09:52:06 +00:00
Besnik Bleta
56715f13d4 Translated using Weblate (Albanian)
Currently translated at 100.0% (82 of 82 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/sq/
2022-12-01 09:52:06 +00:00
Jeff Huang
a57162cf83 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (2558 of 2558 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/zh_Hant/
2022-12-01 09:52:04 +00:00
Ihor Hordiichuk
571d1a4816 Translated using Weblate (Ukrainian)
Currently translated at 100.0% (2558 of 2558 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/uk/
2022-12-01 09:52:03 +00:00
Besnik Bleta
b759f40c13 Translated using Weblate (Albanian)
Currently translated at 99.3% (2541 of 2558 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/sq/
2022-12-01 09:52:03 +00:00
Jozef Gaal
3d84a999e0 Translated using Weblate (Slovak)
Currently translated at 100.0% (2558 of 2558 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/sk/
2022-12-01 09:52:02 +00:00
random
05e6a59a86 Translated using Weblate (Italian)
Currently translated at 100.0% (2558 of 2558 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/it/
2022-12-01 09:52:02 +00:00
Linerly
ab1db4de68 Translated using Weblate (Indonesian)
Currently translated at 100.0% (2558 of 2558 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/id/
2022-12-01 09:52:01 +00:00
Glandos
1c7f789928 Translated using Weblate (French)
Currently translated at 100.0% (2558 of 2558 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/fr/
2022-12-01 09:52:01 +00:00
Danial Behzadi
27acb198ab Translated using Weblate (Persian)
Currently translated at 99.7% (2551 of 2558 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/fa/
2022-12-01 09:52:01 +00:00
Priit Jõerüüt
c6ed280a6f Translated using Weblate (Estonian)
Currently translated at 99.6% (2550 of 2558 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/et/
2022-12-01 09:52:00 +00:00
Vri
a0528fe0ce Translated using Weblate (German)
Currently translated at 100.0% (2558 of 2558 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/de/
2022-12-01 09:52:00 +00:00
waclaw66
279756bdfb Translated using Weblate (Czech)
Currently translated at 100.0% (2558 of 2558 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/cs/
2022-12-01 09:51:59 +00:00
Maxime NATUREL
d5f279ed8b Merge pull request #7678 from vector-im/dependabot/gradle/flipper-0.175.0
Bump flipper from 0.174.0 to 0.175.0
2022-12-01 10:07:11 +01:00
dependabot[bot]
e4212bd7db Bump flipper from 0.174.0 to 0.175.0
Bumps `flipper` from 0.174.0 to 0.175.0.

Updates `flipper` from 0.174.0 to 0.175.0
- [Release notes](https://github.com/facebook/flipper/releases)
- [Commits](https://github.com/facebook/flipper/compare/v0.174.0...v0.175.0)

Updates `flipper-network-plugin` from 0.174.0 to 0.175.0
- [Release notes](https://github.com/facebook/flipper/releases)
- [Commits](https://github.com/facebook/flipper/compare/v0.174.0...v0.175.0)

---
updated-dependencies:
- dependency-name: com.facebook.flipper:flipper
  dependency-type: direct:production
  update-type: version-update:semver-minor
- dependency-name: com.facebook.flipper:flipper-network-plugin
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-30 23:03:13 +00:00
dependabot[bot]
d1cef1bc5c Bump com.autonomousapps.dependency-analysis from 1.16.0 to 1.17.0
Bumps com.autonomousapps.dependency-analysis from 1.16.0 to 1.17.0.

---
updated-dependencies:
- dependency-name: com.autonomousapps.dependency-analysis
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-30 23:02:20 +00:00
dependabot[bot]
b699e9db3a Bump sentry-android from 6.7.0 to 6.9.0 (#7668)
Bumps [sentry-android](https://github.com/getsentry/sentry-java) from 6.7.0 to 6.9.0.
- [Release notes](https://github.com/getsentry/sentry-java/releases)
- [Changelog](https://github.com/getsentry/sentry-java/blob/6.9.0/CHANGELOG.md)
- [Commits](https://github.com/getsentry/sentry-java/compare/6.7.0...6.9.0)

---
updated-dependencies:
- dependency-name: io.sentry:sentry-android
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-30 13:58:28 +01:00
Benoit Marty
0868686caa Release script: Send message to Android Room 2022-11-30 12:54:48 +01:00
Benoit Marty
714f8b3a75 Release script: Improve release script again. 2022-11-30 12:54:40 +01:00
Benoit Marty
8cf8852aae Release script: Update last part of the script 2022-11-30 12:54:26 +01:00
Benoit Marty
52477aa9d5 version++ 2022-11-30 11:03:58 +01:00
Benoit Marty
02542950c8 Merge branch 'release/1.5.10' into develop 2022-11-30 10:59:48 +01:00
dependabot[bot]
a73fe9585f Bump danger/danger-js from 11.1.4 to 11.2.0 (#7584)
Bumps [danger/danger-js](https://github.com/danger/danger-js) from 11.1.4 to 11.2.0.
- [Release notes](https://github.com/danger/danger-js/releases)
- [Changelog](https://github.com/danger/danger-js/blob/main/CHANGELOG.md)
- [Commits](https://github.com/danger/danger-js/compare/11.1.4...11.2.0)

---
updated-dependencies:
- dependency-name: danger/danger-js
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-30 09:15:18 +00:00
dependabot[bot]
b58050f496 Bump kotlin-reflect from 1.7.21 to 1.7.22 (#7665)
Bumps [kotlin-reflect](https://github.com/JetBrains/kotlin) from 1.7.21 to 1.7.22.
- [Release notes](https://github.com/JetBrains/kotlin/releases)
- [Changelog](https://github.com/JetBrains/kotlin/blob/master/ChangeLog.md)
- [Commits](https://github.com/JetBrains/kotlin/compare/v1.7.21...v1.7.22)

---
updated-dependencies:
- dependency-name: org.jetbrains.kotlin:kotlin-reflect
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-11-30 09:13:47 +00:00
Weblate
60dff395ca Merge branch 'origin/develop' into Weblate. 2022-11-29 21:33:15 +00:00
LinAGKar
4a70ea8518 Translated using Weblate (Swedish)
Currently translated at 100.0% (82 of 82 strings)

Translation: Element Android/Element Android Store
Translate-URL: https://translate.element.io/projects/element-android/element-store/sv/
2022-11-29 21:33:12 +00:00
Ihor Hordiichuk
b3ffc4d76c Translated using Weblate (Ukrainian)
Currently translated at 100.0% (2556 of 2556 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/uk/
2022-11-29 21:33:10 +00:00
LinAGKar
1c0fe56329 Translated using Weblate (Swedish)
Currently translated at 100.0% (2556 of 2556 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/sv/
2022-11-29 21:33:10 +00:00
lvre
c5fe9d4a18 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (2556 of 2556 strings)

Translation: Element Android/Element Android App
Translate-URL: https://translate.element.io/projects/element-android/element-app/pt_BR/
2022-11-29 21:33:09 +00:00
Benoit Marty
d04e2b0f82 Trigger CI 2022-11-28 12:40:17 +01:00
gradle-update-robot
d7dc5c812e Update Gradle Wrapper from 7.5.1 to 7.6.
Signed-off-by: gradle-update-robot <gradle-update-robot@regolo.cc>
2022-11-27 00:26:10 +00:00
Onuray Sahin
8835e4d25e Create use case to decide to show alert. 2022-11-25 14:34:39 +03:00
Onuray Sahin
821a561235 Add timeout preference for alert. 2022-11-25 14:33:41 +03:00
Onuray Sahin
59ac3b4f8b Update new strings of unverified sessions alert. 2022-11-24 15:26:59 +03:00
dependabot[bot]
e4caf7be81 Bump barista from 4.2.0 to 4.3.0
Bumps [barista](https://github.com/AdevintaSpain/Barista) from 4.2.0 to 4.3.0.
- [Release notes](https://github.com/AdevintaSpain/Barista/releases)
- [Commits](https://github.com/AdevintaSpain/Barista/compare/4.2.0...4.3.0)

---
updated-dependencies:
- dependency-name: com.adevinta.android:barista
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-15 23:03:53 +00:00
David Langley
15583a14aa changelog 2022-10-27 14:30:36 +01:00
David Langley
2b7560b1e7 Add Labs-Z label for rich text editor and migrate to new label naming 2022-10-27 14:21:14 +01:00
282 changed files with 5899 additions and 1435 deletions

1
.gitattributes vendored
View File

@@ -1 +1,2 @@
**/snapshots/**/*.png filter=lfs diff=lfs merge=lfs -text
**/src/androidTest/assets/*.realm filter=lfs diff=lfs merge=lfs -text

View File

@@ -11,9 +11,9 @@ jobs:
- run: |
npm install --save-dev @babel/plugin-transform-flow-strip-types
- name: Danger
uses: danger/danger-js@11.1.4
uses: danger/danger-js@11.2.0
with:
args: "--dangerfile tools/danger/dangerfile.js"
args: "--dangerfile ./tools/danger/dangerfile.js"
env:
DANGER_GITHUB_API_TOKEN: ${{ secrets.DANGER_GITHUB_API_TOKEN }}
# Fallback for forks

View File

@@ -66,9 +66,9 @@ jobs:
yarn add danger-plugin-lint-report --dev
- name: Danger lint
if: always()
uses: danger/danger-js@11.1.4
uses: danger/danger-js@11.2.0
with:
args: "--dangerfile tools/danger/dangerfile-lint.js"
args: "--dangerfile ./tools/danger/dangerfile-lint.js"
env:
DANGER_GITHUB_API_TOKEN: ${{ secrets.DANGER_GITHUB_API_TOKEN }}
# Fallback for forks

View File

@@ -17,7 +17,8 @@ jobs:
contains(github.event.issue.labels.*.name, 'Z-IA') ||
contains(github.event.issue.labels.*.name, 'A-Themes-Custom') ||
contains(github.event.issue.labels.*.name, 'A-E2EE-Dehydration') ||
contains(github.event.issue.labels.*.name, 'A-Tags')
contains(github.event.issue.labels.*.name, 'A-Tags') ||
contains(github.event.issue.labels.*.name, 'A-Rich-Text-Editor')
steps:
- uses: actions/github-script@v5
with:
@@ -88,7 +89,7 @@ jobs:
projectid: ${{ env.PROJECT_ID }}
contentid: ${{ github.event.issue.node_id }}
env:
PROJECT_ID: "PN_kwDOAM0swc0sUA"
PROJECT_ID: "PVT_kwDOAM0swc0sUA"
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
add_product_issues:
@@ -112,7 +113,7 @@ jobs:
projectid: ${{ env.PROJECT_ID }}
contentid: ${{ github.event.issue.node_id }}
env:
PROJECT_ID: "PN_kwDOAM0swc4AAg6N"
PROJECT_ID: "PVT_kwDOAM0swc4AAg6N"
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
delight_issues_to_board:
@@ -138,7 +139,7 @@ jobs:
projectid: ${{ env.PROJECT_ID }}
contentid: ${{ github.event.issue.node_id }}
env:
PROJECT_ID: "PN_kwDOAM0swc1HvQ"
PROJECT_ID: "PVT_kwDOAM0swc1HvQ"
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
move_voice-message_issues:
@@ -163,7 +164,7 @@ jobs:
projectid: ${{ env.PROJECT_ID }}
contentid: ${{ github.event.issue.node_id }}
env:
PROJECT_ID: "PN_kwDOAM0swc2KCw"
PROJECT_ID: "PVT_kwDOAM0swc2KCw"
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
move_message_bubbles_issues:
name: A-Message-Bubbles to Message bubbles board
@@ -187,7 +188,7 @@ jobs:
projectid: ${{ env.PROJECT_ID }}
contentid: ${{ github.event.issue.node_id }}
env:
PROJECT_ID: "PN_kwDOAM0swc3m-g"
PROJECT_ID: "PVT_kwDOAM0swc3m-g"
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
move_ftue_issues:
@@ -212,7 +213,7 @@ jobs:
projectid: ${{ env.PROJECT_ID }}
contentid: ${{ github.event.issue.node_id }}
env:
PROJECT_ID: "PN_kwDOAM0swc4AAqVx"
PROJECT_ID: "PVT_kwDOAM0swc4AAqVx"
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
move_WTF_issues:
@@ -237,7 +238,7 @@ jobs:
projectid: ${{ env.PROJECT_ID }}
contentid: ${{ github.event.issue.node_id }}
env:
PROJECT_ID: "PN_kwDOAM0swc4AArk0"
PROJECT_ID: "PVT_kwDOAM0swc4AArk0"
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
move_element_x_issues:
@@ -267,7 +268,7 @@ jobs:
projectid: ${{ env.PROJECT_ID }}
contentid: ${{ github.event.issue.node_id }}
env:
PROJECT_ID: "PN_kwDOAM0swc4ABTXY"
PROJECT_ID: "PVT_kwDOAM0swc4ABTXY"
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
ps_features1:

View File

@@ -69,7 +69,7 @@ jobs:
projectid: ${{ env.PROJECT_ID }}
contentid: ${{ github.event.pull_request.node_id }}
env:
PROJECT_ID: "PN_kwDOAM0swc0sUA"
PROJECT_ID: "PVT_kwDOAM0swc0sUA"
TEAM: "design"
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
@@ -138,6 +138,6 @@ jobs:
projectid: ${{ env.PROJECT_ID }}
contentid: ${{ github.event.pull_request.node_id }}
env:
PROJECT_ID: "PN_kwDOAM0swc4AAg6N"
PROJECT_ID: "PVT_kwDOAM0swc4AAg6N"
TEAM: "product"
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}

View File

@@ -1 +0,0 @@
[Rich text editor] Fix design and spacing of rich text editor

View File

@@ -1,3 +1,70 @@
Changes in Element v1.5.13 (2022-12-19)
=======================================
Bugfixes 🐛
----------
- Add `largeHeap=true` in the manifest since we are seeing more crashes (OOM) when handling sync response.
Changes in Element v1.5.12 (2022-12-15)
=======================================
Features ✨
----------
- [Threads] - Threads Labs Flag is enabled by default and forced to be enabled for existing users, but sill can be disabled manually ([#5503](https://github.com/vector-im/element-android/issues/5503))
- [Session manager] Add action to signout all the other session ([#7693](https://github.com/vector-im/element-android/issues/7693))
- Remind unverified sessions with a banner once a week ([#7694](https://github.com/vector-im/element-android/issues/7694))
- [Session manager] Add actions to rename and signout current session ([#7697](https://github.com/vector-im/element-android/issues/7697))
- Voice Broadcast - Update last message in the room list ([#7719](https://github.com/vector-im/element-android/issues/7719))
- Delete unused client information from account data ([#7754](https://github.com/vector-im/element-android/issues/7754))
Bugfixes 🐛
----------
- Fix bad pills color background. For light and dark theme the color is now 61708B (iso EleWeb) ([#7274](https://github.com/vector-im/element-android/issues/7274))
- [Notifications] Fixed a bug when push notification was automatically dismissed while app is on background ([#7643](https://github.com/vector-im/element-android/issues/7643))
- ANR when asking to select the notification method ([#7653](https://github.com/vector-im/element-android/issues/7653))
- [Rich text editor] Fix design and spacing of rich text editor ([#7658](https://github.com/vector-im/element-android/issues/7658))
- [Rich text editor] Fix keyboard closing after collapsing editor ([#7659](https://github.com/vector-im/element-android/issues/7659))
- Rich Text Editor: fix several issues related to insets:
* Empty space displayed at the bottom when you don't have permissions to send messages into a room.
* Wrong insets being kept when you exit the room screen and the keyboard is displayed, then come back to it. ([#7680](https://github.com/vector-im/element-android/issues/7680))
- Fix crash in message composer when room is missing ([#7683](https://github.com/vector-im/element-android/issues/7683))
- Fix crash when invalid homeserver url is entered. ([#7684](https://github.com/vector-im/element-android/issues/7684))
- Rich Text Editor: improve performance when entering reply/edit/quote mode. ([#7691](https://github.com/vector-im/element-android/issues/7691))
- [Rich text editor] Add error tracking for rich text editor ([#7695](https://github.com/vector-im/element-android/issues/7695))
- Fix E2EE set up failure whilst signing in using QR code ([#7699](https://github.com/vector-im/element-android/issues/7699))
- Fix usage of unknown shield in room summary ([#7710](https://github.com/vector-im/element-android/issues/7710))
- Fix crash when the network is not available. ([#7725](https://github.com/vector-im/element-android/issues/7725))
- [Session manager] Sessions without encryption support should not prompt to verify ([#7733](https://github.com/vector-im/element-android/issues/7733))
- Fix issue of Scan QR code button sometimes not showing when it should be available ([#7737](https://github.com/vector-im/element-android/issues/7737))
- Verification request is not showing when verify session popup is displayed ([#7743](https://github.com/vector-im/element-android/issues/7743))
- Fix crash when inviting by email. ([#7744](https://github.com/vector-im/element-android/issues/7744))
- Revert usage of stable fields in live location sharing and polls ([#7751](https://github.com/vector-im/element-android/issues/7751))
- [Poll] Poll end event is not recognized ([#7753](https://github.com/vector-im/element-android/issues/7753))
- [Push Notifications] When push notification for threaded message is clicked, thread timeline will be opened instead of room's main timeline ([#7770](https://github.com/vector-im/element-android/issues/7770))
Other changes
-------------
- [Threads] - added API to fetch threads list from the server instead of building it locally from events ([#5819](https://github.com/vector-im/element-android/issues/5819))
- Add Z-Labs label for rich text editor and migrate to new label naming. ([#7477](https://github.com/vector-im/element-android/issues/7477))
- Crypto database migration tests ([#7645](https://github.com/vector-im/element-android/issues/7645))
- Add tracing Id for to device messages ([#7708](https://github.com/vector-im/element-android/issues/7708))
- Disable nightly popup and add an entry point in the advanced settings instead. ([#7723](https://github.com/vector-im/element-android/issues/7723))
- Save m.local_notification_settings.<device-id> event in account_data ([#7596](https://github.com/vector-im/element-android/issues/7596))
- Update notifications setting when m.local_notification_settings.<device-id> event changes for current device ([#7632](https://github.com/vector-im/element-android/issues/7632))
SDK API changes ⚠️
------------------
- Handle account data removal ([#7740](https://github.com/vector-im/element-android/issues/7740))
Changes in Element 1.5.11 (2022-12-07)
======================================
Bugfixes 🐛
----------
- Fix crash when the network is not available. ([#7725](https://github.com/vector-im/element-android/issues/7725))
Changes in Element v1.5.10 (2022-11-30)
=======================================

View File

@@ -29,7 +29,7 @@ buildscript {
classpath 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:3.5.0.2730'
classpath 'com.google.android.gms:oss-licenses-plugin:0.10.5'
classpath "com.likethesalad.android:stem-plugin:2.2.3"
classpath 'org.owasp:dependency-check-gradle:7.3.0'
classpath 'org.owasp:dependency-check-gradle:7.4.1'
classpath "org.jetbrains.dokka:dokka-gradle-plugin:1.7.20"
classpath "org.jetbrains.kotlinx:kotlinx-knit:0.4.0"
classpath 'com.jakewharton:butterknife-gradle-plugin:10.2.3'
@@ -45,10 +45,10 @@ plugins {
// Detekt
id "io.gitlab.arturbosch.detekt" version "1.22.0"
// Ksp
id "com.google.devtools.ksp" version "1.7.21-1.0.8"
id "com.google.devtools.ksp" version "1.7.22-1.0.8"
// Dependency Analysis
id 'com.autonomousapps.dependency-analysis' version "1.16.0"
id 'com.autonomousapps.dependency-analysis' version "1.17.0"
// Gradle doctor
id "com.osacky.doctor" version "0.8.1"
}

View File

@@ -8,7 +8,7 @@ ext.versions = [
def gradle = "7.3.1"
// Ref: https://kotlinlang.org/releases.html
def kotlin = "1.7.21"
def kotlin = "1.7.22"
def kotlinCoroutines = "1.6.4"
def dagger = "2.44.2"
def appDistribution = "16.0.0-beta05"
@@ -17,7 +17,7 @@ def markwon = "4.6.2"
def moshi = "1.14.0"
def lifecycle = "2.5.1"
def flowBinding = "1.2.0"
def flipper = "0.174.0"
def flipper = "0.176.0"
def epoxy = "5.0.0"
def mavericks = "3.0.1"
def glide = "4.14.2"
@@ -26,8 +26,8 @@ def jjwt = "0.11.5"
// Temporary version to unblock #6929. Once 0.16.0 is released we should use it, and revert
// the whole commit which set version 0.16.0-SNAPSHOT
def vanniktechEmoji = "0.16.0-SNAPSHOT"
def sentry = "6.7.0"
def fragment = "1.5.4"
def sentry = "6.9.0"
def fragment = "1.5.5"
// Testing
def mockk = "1.12.3" // We need to use 1.12.3 to have mocking in androidTest until a new version is released: https://github.com/mockk/mockk/issues/819
def espresso = "3.4.0"
@@ -98,7 +98,7 @@ ext.libs = [
],
element : [
'opusencoder' : "io.element.android:opusencoder:1.1.0",
'wysiwyg' : "io.element.android:wysiwyg:0.7.0.1"
'wysiwyg' : "io.element.android:wysiwyg:0.9.0"
],
squareup : [
'moshi' : "com.squareup.moshi:moshi:$moshi",

View File

@@ -0,0 +1,55 @@
<!--- TOC -->
* [Testing database migration](#testing-database-migration)
* [Creating a reference database](#creating-a-reference-database)
* [Testing](#testing)
<!--- END -->
## Testing database migration
### Creating a reference database
Databases are encrypted, the key to decrypt is needed to setup the test.
A special build property must be enabled to extract it.
Set `vector.debugPrivateData=true` in `~/.gradle/gradle.properties` (to avoid committing by mistake)
Launch the app in your emulator, login and use the app to fill up the database.
Save the key for the tested database
```
RealmKeysUtils W Database key for alias `session_db_fe9f212a611ccf6dea1141777065ed0a`: 935a6dfa0b0fc5cce1414194ed190....
RealmKeysUtils W Database key for alias `crypto_module_fe9f212a611ccf6dea1141777065ed0a`: 7b9a21a8a311e85d75b069a343.....
```
Use the [Device File Explorer](https://developer.android.com/studio/debug/device-file-explorer) to extrat the database file from the emulator.
Go to `data/data/im.vector.app.debug/files/<hash>/`
Pick the database you want to test (name can be found in SessionRealmConfigurationFactory):
- crypto_store.realm for crypto
- disk_store.realm for session
- etc...
Download the file on your disk
### Testing
Copy the file in `src/AndroidTest/assets`
see `CryptoSanityMigrationTest` or `RealmSessionStoreMigration43Test` for sample tests.
There are already some databases in the assets folder.
The existing test will properly detect schema changes, and fail with such errors if a migration is missing:
```
io.realm.exceptions.RealmMigrationNeededException: Migration is required due to the following errors:
- Property 'CryptoMetadataEntity.foo' has been added.
```
If you want to test properly more complex database migration (dynamic transforms) ensure that the database contains
the entity you want to migrate.
You can explore the database with [realm studio](https://www.mongodb.com/docs/realm/studio/) if needed.

View File

@@ -0,0 +1,2 @@
Hlavní změny v této verzi: Nová implementace celoobrazovkového režimu pro editor formátovaného textu a opravy chyb.
Úplný seznam změn: https://github.com/vector-im/element-android/releases

View File

@@ -0,0 +1,2 @@
Die wichtigsten Änderungen in dieser Version: Der Vollbildmodus des Textverarbeitungseditors wurde neu umgesetzt und es wurden diverse Fehler behoben.
Vollständiges Änderungsprotokoll: https://github.com/vector-im/element-android/releases

View File

@@ -0,0 +1,2 @@
Main changes in this version: New implementation of the full screen mode for the Rich Text Editor and bugfixes.
Full changelog: https://github.com/vector-im/element-android/releases

View File

@@ -0,0 +1,2 @@
Main changes in this version: Thread are now enabled by default.
Full changelog: https://github.com/vector-im/element-android/releases

View File

@@ -0,0 +1,2 @@
Main changes in this version: Thread are now enabled by default.
Full changelog: https://github.com/vector-im/element-android/releases

View File

@@ -0,0 +1,2 @@
Põhilised muutused selles versioonis: tekstitoimeti täisekraanivaade ja erinevate vigade parandused.
Kogu ingliskeelne muudatuste logi: https://github.com/vector-im/element-android/releases

View File

@@ -0,0 +1,2 @@
Perubahan utama dalam versi ini: Penerapan baru mode layar penuh untuk Penyunting Teks Kaya dan perbaikan kutu.
Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases

View File

@@ -0,0 +1,2 @@
Hlavné zmeny v tejto verzii: Nová implementácia celo-obrazovkového režimu pre Rozšírený textový editor a opravy chýb.
Úplný zoznam zmien: https://github.com/vector-im/element-android/releases

View File

@@ -0,0 +1,2 @@
Ndryshimet kryesore në këtë version: ndreqje të metash dhe përmirësime.
Regjistër i plotë ndryshimesh: https://github.com/vector-im/element-android/releases

View File

@@ -0,0 +1,2 @@
Huvudsakliga ändringar i den här versionen: buggfixar och förbättringar.
Full ändringslogg: https://github.com/vector-im/element-android/releases

View File

@@ -0,0 +1,2 @@
Основні зміни в цій версії: Нова реалізація повноекранного режиму для редактора розширеного тексту та виправлення помилок.
Перелік усіх змін: https://github.com/vector-im/element-android/releases

View File

@@ -0,0 +1,2 @@
此版本中的主要變動:格式化文字編輯器的全螢幕模式新實作與臭蟲修復。
完整的變更紀錄https://github.com/vector-im/element-android/releases

Binary file not shown.

View File

@@ -1,6 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionSha256Sum=db9c8211ed63f61f60292c69e80d89196f9eb36665e369e7f00ac4cc841c2219
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-all.zip
distributionSha256Sum=312eb12875e1747e05c2f81a4789902d7e4ec5defbd1eefeaccc08acf096505d
distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-all.zip
networkTimeout=10000
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

12
gradlew vendored
View File

@@ -55,7 +55,7 @@
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
@@ -80,10 +80,10 @@ do
esac
done
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
APP_NAME="Gradle"
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
@@ -143,12 +143,16 @@ fi
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
case $MAX_FD in #(
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
# shellcheck disable=SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac

1
gradlew.bat vendored
View File

@@ -26,6 +26,7 @@ if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%"=="" set DIRNAME=.
@rem This is normally unused
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%

View File

@@ -2789,7 +2789,7 @@
<string name="key_authenticity_not_guaranteed">Pravost této šifrované zprávy nelze v tomto zařízení zaručit.</string>
<string name="settings_security_incognito_keyboard_summary">Požadujte, aby klávesnice neaktualizovala žádné personalizované údaje, jako je historie psaní a slovník, na základě toho, co jste napsali v konverzacích. Upozorňujeme, že některé klávesnice nemusí toto nastavení respektovat.</string>
<string name="settings_security_incognito_keyboard_title">Inkognito klávesnice</string>
<string name="command_description_table_flip">Přidá znaky (╯°□°)╯︵ ┻━┻ před zprávy ve formátu obyčejného textu</string>
<string name="command_description_table_flip">Přidá znaky (╯°□°)╯︵ ┻━┻ před zprávy ve formátu prostého textu</string>
<string name="attachment_type_voice_broadcast">Hlasové vysílání</string>
<string name="command_description_devtools">Otevřít nástroje pro vývojáře</string>
<string name="room_settings_global_block_unverified_info_text">🔒 V nastavení zabezpečení jste povolili šifrování pouze do ověřených relací pro všechny místnosti.</string>
@@ -2824,8 +2824,8 @@
<string name="permissions_rationale_msg_notification">${app_name} potřebuje oprávnění k zobrazování oznámení. Oznámení mohou zobrazovat vaše zprávy, pozvánky atd.
\n
\nPro zobrazování oznámení povolte přístup na dalších vyskakovacích oknech.</string>
<string name="labs_enable_rich_text_editor_summary">Vyzkoušejte rozšířený textový editor (textový režim již brzy)</string>
<string name="labs_enable_rich_text_editor_title">Povolit rozšířený textový editor</string>
<string name="labs_enable_rich_text_editor_summary">Vyzkoušejte editor formátovaného textu (režim prostého textu již brzy)</string>
<string name="labs_enable_rich_text_editor_title">Povolit editor formátovaného textu</string>
<string name="qr_code_login_confirm_security_code_description">Ujistěte se, že znáte původ tohoto kódu. Propojením zařízení poskytnete někomu plný přístup ke svému účtu.</string>
<string name="qr_code_login_confirm_security_code">Potvrdit</string>
<string name="qr_code_login_try_again">Zkuste to znovu</string>
@@ -2868,7 +2868,7 @@
<string name="qr_code_login_header_failed_other_device_already_signed_in_description">Druhé zařízení je již přihlášeno.</string>
<string name="qr_code_login_header_failed_e2ee_security_issue_description">Při nastavování zabezpečeného zasílání zpráv se vyskytl problém se zabezpečením. Může být napadena jedna z následujících věcí: váš domovský server; vaše internetové připojení; vaše zařízení;</string>
<string name="qr_code_login_header_failed_other_description">Žádost se nezdařila.</string>
<string name="a11y_voice_broadcast_buffering">Ukládání do vyrovnávací paměti</string>
<string name="a11y_voice_broadcast_buffering">Ukládání do vyrovnávací paměti</string>
<string name="a11y_pause_voice_broadcast">Pozastavit hlasové vysílání</string>
<string name="a11y_play_voice_broadcast">Přehrát nebo obnovit hlasové vysílání</string>
<string name="a11y_stop_voice_broadcast_record">Ukončit záznam hlasového vysílání</string>
@@ -2922,4 +2922,6 @@
<string name="quoting">Citace</string>
<string name="replying_to">Odpovídám na %s</string>
<string name="editing">Úpravy</string>
<string name="settings_enable_direct_share_summary">Zobrazit poslední chaty v nabídce sdílení systému</string>
<string name="settings_enable_direct_share_title">Povolit přímé sdílení</string>
</resources>

View File

@@ -2815,7 +2815,7 @@
<string name="qr_code_login_header_failed_other_description">Die Anfrage ist fehlgeschlagen.</string>
<string name="a11y_play_voice_broadcast">Abspielen oder fortsetzen der Sprachübertragung</string>
<string name="a11y_resume_voice_broadcast_record">Fortsetzen der Sprachübertragung</string>
<string name="a11y_voice_broadcast_buffering">Puffere</string>
<string name="a11y_voice_broadcast_buffering">Puffere</string>
<string name="a11y_pause_voice_broadcast">Pausiere Sprachübertragung</string>
<string name="a11y_stop_voice_broadcast_record">Stoppe Aufzeichnung der Sprachübertragung</string>
<string name="a11y_pause_voice_broadcast_record">Pausiere Aufzeichnung der Sprachübertragung</string>
@@ -2865,4 +2865,6 @@
<string name="replying_to">%s antworten</string>
<string name="device_manager_other_sessions_hide_ip_address">IP-Adresse ausblenden</string>
<string name="device_manager_other_sessions_show_ip_address">IP-Adresse anzeigen</string>
<string name="settings_enable_direct_share_summary">Kürzliche Unterhaltungen im Teilen-Menü des Systems anzeigen</string>
<string name="settings_enable_direct_share_title">Direktes Teilen aktivieren</string>
</resources>

View File

@@ -2805,7 +2805,7 @@
<string name="qr_code_login_header_failed_other_device_already_signed_in_description">Teine seade on juba võrku loginud.</string>
<string name="qr_code_login_header_failed_e2ee_security_issue_description">Turvalise sõnumivahetuse ülesseadmisel tekkis turvaviga. Üks kolmest võib olla sattunud vale osapoole kontrolli alla: sinu koduserver, sinu internetiühendus või sinu seade;</string>
<string name="qr_code_login_header_failed_other_description">Päring ei õnnestunud.</string>
<string name="a11y_voice_broadcast_buffering">Andmed on puhverdamisel</string>
<string name="a11y_voice_broadcast_buffering">Andmed on puhverdamisel</string>
<string name="a11y_play_voice_broadcast">Alusta või jätka ringhäälingukõne esitamist</string>
<string name="a11y_stop_voice_broadcast_record">Lõpeta ringhäälingukõne salvestamine</string>
<string name="a11y_pause_voice_broadcast_record">Peata ringhäälingukõne salvestamine</string>
@@ -2857,4 +2857,6 @@
<string name="message_reply_to_sender_sent_video">saatis video.</string>
<string name="message_reply_to_sender_sent_sticker">saatis kleepsu.</string>
<string name="message_reply_to_sender_created_poll">koostas küsitluse.</string>
<string name="settings_enable_direct_share_title">Kasuta otsejagamist</string>
<string name="settings_enable_direct_share_summary">Näita viimaseid vestlusi süsteemses jagamisvaates</string>
</resources>

View File

@@ -943,7 +943,7 @@
\n
\nپیامهایتان با قفل‌هایی امن شده‌اند و فقط شما و گیرندگان دیگر، کلیدهای یکتا را برای قفل‌گشاییشان دارید.</string>
<string name="room_profile_section_security">امنیت</string>
<string name="room_profile_section_security_learn_more">بثیش‌تر بدانید</string>
<string name="room_profile_section_security_learn_more">بیش‌تر بدانید</string>
<string name="room_profile_section_more">بیش‌تر</string>
<string name="room_profile_section_admin">کنش‌های مدیر</string>
<string name="room_profile_section_more_settings">تنظمیات اتاق</string>
@@ -2783,7 +2783,7 @@
<string name="attachment_type_selector_poll">نظرسنجی‌ها</string>
<string name="attachment_type_selector_file">پیوست‌ها</string>
<string name="attachment_type_selector_sticker">برچسب‌ها</string>
<string name="a11y_voice_broadcast_buffering">میانگیری</string>
<string name="a11y_voice_broadcast_buffering">میانگیری</string>
<string name="voice_broadcast_live">زنده</string>
<string name="qr_code_login_confirm_security_code">تأیید</string>
<string name="three">۳</string>
@@ -2844,4 +2844,9 @@
<string name="quoting">نقل کردن</string>
<string name="replying_to">پاسخ دادن به %s</string>
<string name="editing">ویرایش کردن</string>
<string name="device_manager_sessions_sign_in_with_qr_code_description">می‌توانید با یک رمز QR از این افزاره برای ورود به افزاره‌ای همراه یا روی وب استفاده کنید. دو راه برای این کار وجود دارد:</string>
<string name="qr_code_login_header_failed_e2ee_security_issue_description">مشکلی امنیتی در برپایی پیام‌رسانی امن وجود داشت. ممکن است یکی از موارد زیر دستکاری شده باشند: کارساز خانیگیتان؛ اتّصال اینترنتیتان؛ افزاره(های)تان؛</string>
<string name="qr_code_login_confirm_security_code_description">لطفاً مطمئن شوید که مبدأ این کد را می‌دانید. با پیوند دادن افزاره‌ها، دسترسی کامل را به حسابتان می‌دهید.</string>
<string name="settings_enable_direct_share_summary">نمایش گپ‌های اخیر در فهرست هم رسانی سامانه</string>
<string name="settings_enable_direct_share_title">به کار انداختن هم‌رسانی مستقیم</string>
</resources>

View File

@@ -2814,7 +2814,7 @@
<string name="device_manager_sessions_sign_in_with_qr_code_description">Vous pouvez utiliser cet appareil pour connecter un appareil mobile ou un client web avec un QR code. Il y a deux façons de le faire :</string>
<string name="device_manager_sessions_sign_in_with_qr_code_title">Se connecter avec un QR code</string>
<string name="login_scan_qr_code">Scanner le QR code</string>
<string name="a11y_voice_broadcast_buffering">Mise en mémoire tampon</string>
<string name="a11y_voice_broadcast_buffering">Mise en mémoire tampon</string>
<string name="a11y_pause_voice_broadcast">Mettre en pause la diffusion audio</string>
<string name="a11y_play_voice_broadcast">Lire ou continuer la diffusion audio</string>
<string name="a11y_stop_voice_broadcast_record">Arrêter lenregistrement de la diffusion audio</string>
@@ -2866,4 +2866,6 @@
<string name="quoting">Citation de</string>
<string name="replying_to">Réponse à %s</string>
<string name="editing">Modification</string>
<string name="settings_enable_direct_share_summary">Affiche les conversations récentes dans le menu de partage du système</string>
<string name="settings_enable_direct_share_title">Activer le partage direct</string>
</resources>

View File

@@ -2762,7 +2762,7 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan.</string>
<string name="qr_code_login_header_failed_other_description">Permintaan gagal.</string>
<string name="labs_enable_voice_broadcast_summary">Memungkinkan untuk merekam dan mengirim siaran suara dalam linimasa ruangan.</string>
<string name="labs_enable_voice_broadcast_title">Aktifkan siaran suara (dalam pengembangan aktif)</string>
<string name="a11y_voice_broadcast_buffering">Memuat</string>
<string name="a11y_voice_broadcast_buffering">Memuat</string>
<string name="a11y_pause_voice_broadcast">Jeda siaran suara</string>
<string name="a11y_play_voice_broadcast">Mainkan atau lanjutkan siaran suara</string>
<string name="a11y_stop_voice_broadcast_record">Hentikan rekaman siaran suara</string>
@@ -2812,4 +2812,6 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan.</string>
<string name="editing">Mengedit</string>
<string name="device_manager_other_sessions_show_ip_address">Tampilkan alamat IP</string>
<string name="replying_to">Membalas ke %s</string>
<string name="settings_enable_direct_share_summary">Tampilkan obrolan terkini dalam menu pembagian sistem</string>
<string name="settings_enable_direct_share_title">Aktifkan pembagian langsung</string>
</resources>

View File

@@ -2805,7 +2805,7 @@
<string name="qr_code_login_header_failed_other_device_already_signed_in_description">L\'altro dispositivo ha già fatto l\'accesso.</string>
<string name="qr_code_login_header_failed_e2ee_security_issue_description">Si è verificato un problema di sicurezza configurando i messaggi sicuri. Una delle seguenti cose potrebbe essere compromessa: il tuo homeserver; la/e connessione/i internet; il/i dispositivo/i;</string>
<string name="qr_code_login_header_failed_other_description">La richiesta è fallita.</string>
<string name="a11y_voice_broadcast_buffering">Buffering</string>
<string name="a11y_voice_broadcast_buffering">Buffer</string>
<string name="a11y_pause_voice_broadcast">Sospendi trasmissione vocale</string>
<string name="a11y_play_voice_broadcast">Avvia o riprendi trasmissione vocale</string>
<string name="a11y_stop_voice_broadcast_record">Ferma registrazione trasmissione vocale</string>
@@ -2857,4 +2857,6 @@
<string name="quoting">Citazione</string>
<string name="replying_to">Risposta a %s</string>
<string name="editing">Modifica</string>
<string name="settings_enable_direct_share_summary">Mostra chat recenti nel menu di condivisione di sistema</string>
<string name="settings_enable_direct_share_title">Attiva condivisione diretta</string>
</resources>

View File

@@ -2723,7 +2723,7 @@
<string name="device_manager_learn_more_sessions_unverified_title">Sessões não-verificadas</string>
<string name="device_manager_learn_more_sessions_inactive">Sessões inativas são sessões que você não tem usado em algum tempo, mas elas continuam a receber chaves de encriptação.
\n
\nRemover sessões inativas melhora segurança e performance, e torna-o mais fácil para você identificar se uma nova sessão é suspeita.</string>
\nRemover sessões inativas melhora segurança e performance, e torna mais fácil para você identificar se uma nova sessão é suspeita.</string>
<string name="device_manager_learn_more_sessions_inactive_title">Sessões inativas</string>
<string name="device_manager_session_rename_warning">Por favor esteja ciente que nomes de sessões também são visíveis a pessoas com quem você se comunica.</string>
<string name="device_manager_session_rename_description">Nomes de sessões personalizadas podem ajudar você a reconhecer seus dispositivos mais facilmente.</string>
@@ -2844,9 +2844,9 @@
<string name="error_voice_broadcast_unauthorized_title">Não dá pra começar um novo broadcast de voz</string>
<string name="a11y_voice_broadcast_fast_forward">Avançar rápido 30 segundos</string>
<string name="a11y_voice_broadcast_fast_backward">Retroceder 30 segundos</string>
<string name="device_manager_learn_more_sessions_verified_description">Sessões verificadas são onde quer que você está usando esta conta depois de entrar sua frasepasse ou confirmar sua identidade com uma outra sessão verificada.
<string name="device_manager_learn_more_sessions_verified_description">Sessões verificadas são onde quer que você esteja usando esta conta depois de entrar sua frasepasse ou confirmar sua identidade com uma outra sessão verificada.
\n
\nIsto significa que você tem todas as chaves necessitadas para destrancar suas mensagens encriptadas e confirmar a outras(os) usuárias(os) que você confia nesta sessão.</string>
\nIsto significa que você tem todas as chaves necessárias para destrancar suas mensagens encriptadas e confirmar a outras(os) usuárias(os) que você confia nesta sessão.</string>
<plurals name="device_manager_other_sessions_multi_signout_all">
<item quantity="one">Fazer signout de %1$d sessão</item>
<item quantity="other">Fazer signout de %1$d sessões</item>

View File

@@ -2868,7 +2868,7 @@
<string name="qr_code_login_header_failed_other_description">Žiadosť zlyhala.</string>
<string name="labs_enable_voice_broadcast_summary">Možnosť nahrávania a odosielania hlasového vysielania v časovej osi miestnosti.</string>
<string name="labs_enable_voice_broadcast_title">Zapnúť hlasové vysielanie (v štádiu aktívneho vývoja)</string>
<string name="a11y_voice_broadcast_buffering">Načítavanie do vyrovnávacej pamäte</string>
<string name="a11y_voice_broadcast_buffering">Načítavanie do vyrovnávacej pamäte</string>
<string name="a11y_pause_voice_broadcast">Pozastaviť hlasové vysielanie</string>
<string name="a11y_play_voice_broadcast">Prehrať alebo pokračovať v nahrávaní hlasového vysielania</string>
<string name="a11y_stop_voice_broadcast_record">Zastaviť nahrávanie hlasového vysielania</string>
@@ -2922,4 +2922,6 @@
<string name="device_manager_other_sessions_show_ip_address">Zobraziť IP adresu</string>
<string name="replying_to">Odpoveď na %s</string>
<string name="editing">Úprava</string>
<string name="settings_enable_direct_share_summary">Zobraziť posledné konverzácie v systémovej ponuke zdieľania</string>
<string name="settings_enable_direct_share_title">Povoliť priame zdieľanie</string>
</resources>

View File

@@ -2659,7 +2659,7 @@
\nKy shërbyes Home mund të mos jetë formësuar të shfaqë harta.</string>
<string name="poll_undisclosed_not_ended">Përfundimet do të jenë të dukshme pasi të ketë përfunduar pyetësori</string>
<string name="labs_enable_msc3061_share_history_desc">Kur bëhet ftesë në një dhomë të fshehtëzuar që ka historik ndarjesh me të tjerët, historiku i fshehtëzuar do të jetë i dukshëm.</string>
<string name="a11y_voice_broadcast_buffering">Përdo</string>
<string name="a11y_voice_broadcast_buffering"></string>
<string name="a11y_pause_voice_broadcast">Ndal transmetim zanor</string>
<string name="a11y_play_voice_broadcast">Luani ose vazhdoni luajtje transmetimi zanor</string>
<string name="a11y_stop_voice_broadcast_record">Ndal incizim transmetimi zanor</string>
@@ -2851,4 +2851,6 @@
<string name="a11y_voice_broadcast_fast_backward">Kthim prapa 30 sekonda</string>
<string name="replying_to">Si përgjigje për %s</string>
<string name="labs_enable_deferred_dm_title">Aktivizo MD të lënë për më vonë</string>
<string name="a11y_collapse_space_children">Tkurr pjella të %s</string>
<string name="a11y_expand_space_children">Zgjero pjella të %s</string>
</resources>

View File

@@ -2852,4 +2852,18 @@
<string name="error_voice_broadcast_unauthorized_title">Kan inte starta en ny röstsändning</string>
<string name="a11y_voice_broadcast_fast_forward">Spola framåt 30 sekunder</string>
<string name="a11y_voice_broadcast_fast_backward">Spola tillbaka 30 sekunder</string>
<string name="message_reply_to_sender_created_poll">skickade en omröstning.</string>
<string name="message_reply_to_sender_sent_sticker">skickade en dekal.</string>
<string name="message_reply_to_sender_sent_video">skickade en video.</string>
<string name="message_reply_to_sender_sent_image">skickade en bild.</string>
<string name="message_reply_to_sender_sent_voice_message">skickade ett röstmeddelande.</string>
<string name="message_reply_to_sender_sent_audio_file">skickade en ljudfil.</string>
<string name="message_reply_to_sender_sent_file">skickade en fil.</string>
<string name="message_reply_to_prefix">Svar på</string>
<string name="device_manager_other_sessions_hide_ip_address">Dölj IP-adress</string>
<string name="device_manager_other_sessions_show_ip_address">Visa IP-adress</string>
<string name="voice_broadcast_recording_time_left">%1$s kvar</string>
<string name="quoting">Citerar</string>
<string name="replying_to">Besvarar %s</string>
<string name="editing">Redigerar</string>
</resources>

View File

@@ -2922,7 +2922,7 @@
<string name="qr_code_login_header_failed_other_description">Запит не виконаний.</string>
<string name="labs_enable_voice_broadcast_summary">Можливість записувати та надсилати голосові трансляції до стрічки кімнати.</string>
<string name="labs_enable_voice_broadcast_title">Увімкнути голосові трансляції (в активній розробці)</string>
<string name="a11y_voice_broadcast_buffering">Буферизація</string>
<string name="a11y_voice_broadcast_buffering">Буферизація</string>
<string name="a11y_pause_voice_broadcast">Призупинити голосову трансляцію</string>
<string name="a11y_play_voice_broadcast">Відтворити або поновити відтворення голосової трансляції</string>
<string name="a11y_stop_voice_broadcast_record">Припинити запис голосової трансляції</string>
@@ -2966,16 +2966,18 @@
<string name="device_manager_other_sessions_multi_signout_selection">Вийти</string>
<string name="voice_broadcast_recording_time_left">Залишилося %1$s</string>
<string name="message_reply_to_sender_sent_audio_file">надсилає аудіофайл.</string>
<string name="message_reply_to_sender_sent_file">відправив файл.</string>
<string name="message_reply_to_sender_sent_file">надсилає файл.</string>
<string name="message_reply_to_prefix">У відповідь на</string>
<string name="device_manager_other_sessions_hide_ip_address">Сховати IP-адресу</string>
<string name="message_reply_to_sender_created_poll">створив голосування.</string>
<string name="message_reply_to_sender_sent_sticker">відправив наліпку.</string>
<string name="message_reply_to_sender_sent_video">відправив відео.</string>
<string name="message_reply_to_sender_sent_image">відправив зображення.</string>
<string name="message_reply_to_sender_sent_voice_message">відправив голосове повідомлення.</string>
<string name="message_reply_to_sender_created_poll">створює опитування.</string>
<string name="message_reply_to_sender_sent_sticker">надсилає наліпку.</string>
<string name="message_reply_to_sender_sent_video">надсилає відео.</string>
<string name="message_reply_to_sender_sent_image">надсилає зображення.</string>
<string name="message_reply_to_sender_sent_voice_message">надсилає голосове повідомлення.</string>
<string name="device_manager_other_sessions_show_ip_address">Показати IP-адресу</string>
<string name="quoting">Цитуючи</string>
<string name="replying_to">У відповідь на %s</string>
<string name="replying_to">У відповідь %s</string>
<string name="editing">Редагування</string>
<string name="settings_enable_direct_share_summary">Показувати останні бесіди в системному меню загального доступу</string>
<string name="settings_enable_direct_share_title">Увімкнути пряме поширення</string>
</resources>

View File

@@ -1007,7 +1007,7 @@
<string name="settings_discovery_disconnect_with_bound_pid">您当前在身份服务器 %1$s 上共享电子邮件地址或电话号码。您需要重新连接到 %2$s 才能停止共享它们。</string>
<string name="settings_agree_to_terms">同意身份服务器 (%s) 服务条款使你可以通过电子邮件地址或电话号码被发现。</string>
<string name="labs_allow_extended_logging">启用详细日志。</string>
<string name="labs_allow_extended_logging_summary">详细日志将通过在您发送 RageShake 时提供更多日志来帮助开发人员。即使启用,应用程序也不会记录消息内容或任何其他私人数据。</string>
<string name="labs_allow_extended_logging_summary">详细日志将通过在您发送愤怒摇动(RageShake时提供更多日志来帮助开发人员。即使启用,应用程序也不会记录消息内容或任何其他私人数据。</string>
<string name="error_terms_not_accepted">接收你的主服务器条款和条件后请重试。</string>
<string name="error_network_timeout">服务器似乎响应时间太长,这可能是由于连接不良或服务器错误引起的。请稍后再试。</string>
<string name="send_attachment">发送附件</string>
@@ -1205,7 +1205,7 @@
<string name="settings_advanced_settings">高级设置</string>
<string name="settings_developer_mode">开发者模式</string>
<string name="settings_developer_mode_summary">开发者模式激活隐藏的功能,也可能使应用不稳定。仅供开发者使用!</string>
<string name="settings_rageshake">摇一摇</string>
<string name="settings_rageshake">愤怒摇动Rageshake</string>
<string name="settings_rageshake_detection_threshold">检测阈值</string>
<string name="settings_rageshake_detection_threshold_summary">摇动手机以测试检测阈值</string>
<string name="rageshake_detected">检测到摇动!</string>
@@ -1213,7 +1213,7 @@
<string name="devices_current_device">当前会话</string>
<string name="devices_other_devices">其它会话</string>
<string name="autocomplete_limited_results">仅显示第一个结果,请输入更多字符…</string>
<string name="settings_developer_mode_fail_fast_title">快速失败</string>
<string name="settings_developer_mode_fail_fast_title">快速失败Fail-fast</string>
<string name="settings_developer_mode_fail_fast_summary">发生意外错误时,${app_name} 可能更经常崩溃</string>
<string name="command_description_shrug">在明文消息前添加 ¯\\_(ツ)_/¯</string>
<string name="create_room_encryption_title">启用加密</string>
@@ -2694,7 +2694,7 @@
<string name="device_manager_verification_status_detail_other_session_unknown">验证您当前的会话以显示此会话的验证状态。</string>
<string name="device_manager_verification_status_unknown">未知的验证状态</string>
<string name="tooltip_attachment_voice_broadcast">开始语音广播</string>
<string name="a11y_voice_broadcast_buffering">缓冲</string>
<string name="a11y_voice_broadcast_buffering">正在缓冲……</string>
<string name="a11y_pause_voice_broadcast">暂停语音广播</string>
<string name="voice_broadcast_live">实时</string>
<string name="action_got_it">知道了</string>
@@ -2789,4 +2789,19 @@
<plurals name="x_selected">
<item quantity="other">已选择 %1$d</item>
</plurals>
<string name="message_reply_to_sender_created_poll">已创建投票。</string>
<string name="message_reply_to_sender_sent_sticker">已发送贴纸。</string>
<string name="message_reply_to_sender_sent_video">已发送视频。</string>
<string name="message_reply_to_sender_sent_image">已发送图片。</string>
<string name="message_reply_to_sender_sent_voice_message">已发送语音消息。</string>
<string name="message_reply_to_sender_sent_audio_file">已发送音频文件。</string>
<string name="message_reply_to_sender_sent_file">已发送文件。</string>
<string name="device_manager_learn_more_sessions_verified_description">已验证的会话是在输入你的口令词组或用另一个已验证的会话确认你的身份之后你使用此账户的任何地方。
\n
\n这意味着你拥有解锁你的已加密消息和向其他用户证明你信任此会话所需的全部密钥。</string>
<plurals name="device_manager_other_sessions_multi_signout_all">
<item quantity="other">登出%1$d个会话</item>
</plurals>
<string name="device_manager_other_sessions_multi_signout_selection">登出</string>
<string name="voice_broadcast_recording_time_left">剩余%1$s</string>
</resources>

View File

@@ -2760,7 +2760,7 @@
<string name="qr_code_login_header_failed_other_description">請求失敗。</string>
<string name="labs_enable_voice_broadcast_summary">可以在聊天室時間軸中錄製並傳送語音廣播。</string>
<string name="labs_enable_voice_broadcast_title">啟用語音廣播(正在積極開發中)</string>
<string name="a11y_voice_broadcast_buffering">正在緩衝</string>
<string name="a11y_voice_broadcast_buffering">正在緩衝……</string>
<string name="a11y_pause_voice_broadcast">暫停語音廣播</string>
<string name="a11y_play_voice_broadcast">播放或繼續語音廣播</string>
<string name="a11y_stop_voice_broadcast_record">停止語音廣播錄製</string>
@@ -2810,4 +2810,6 @@
<string name="quoting">引用</string>
<string name="replying_to">回覆給 %s</string>
<string name="editing">正在編輯</string>
<string name="settings_enable_direct_share_summary">在系統分享選單中顯示最近聊天</string>
<string name="settings_enable_direct_share_title">啟用直接分享</string>
</resources>

View File

@@ -134,6 +134,9 @@
<string name="notice_crypto_unable_to_decrypt">** Unable to decrypt: %s **</string>
<string name="notice_crypto_error_unknown_inbound_session_id">The sender\'s device has not sent us the keys for this message.</string>
<string name="notice_voice_broadcast_ended">%1$s ended a voice broadcast.</string>
<string name="notice_voice_broadcast_ended_by_you">You ended a voice broadcast.</string>
<!-- Messages -->
<!-- Room Screen -->
@@ -2487,6 +2490,9 @@
<string name="settings_key_requests">Key Requests</string>
<string name="settings_export_trail">Export Audit</string>
<string name="settings_nightly_build">Nightly build</string>
<string name="settings_nightly_build_update">Get the latest build (note: you may have trouble to sign in)</string>
<string name="e2e_use_keybackup">Unlock encrypted messages history</string>
<string name="refresh">Refresh</string>
@@ -2649,8 +2655,12 @@
<string name="unencrypted">Unencrypted</string>
<string name="encrypted_unverified">Encrypted by an unverified device</string>
<string name="key_authenticity_not_guaranteed">The authenticity of this encrypted message can\'t be guaranteed on this device.</string>
<string name="review_logins">Review where youre logged in</string>
<string name="verify_other_sessions">Verify all your sessions to ensure your account &amp; messages are safe</string>
<!-- TODO TO BE REMOVED -->
<string name="review_logins" tools:ignore="UnusedResources">Review where youre logged in</string>
<!-- TODO TO BE REMOVED -->
<string name="verify_other_sessions" tools:ignore="UnusedResources">Verify all your sessions to ensure your account &amp; messages are safe</string>
<string name="review_unverified_sessions_title">You have unverified sessions</string>
<string name="review_unverified_sessions_description">Review to ensure your account is safe</string>
<!-- Argument will be replaced by the other session name (e.g, Desktop, mobile) -->
<string name="verify_this_session">Verify the new login accessing your account: %1$s</string>
@@ -3025,7 +3035,7 @@
<string name="labs_auto_report_uisi">Auto Report Decryption Errors.</string>
<string name="labs_auto_report_uisi_desc">Your system will automatically send logs when an unable to decrypt error occurs</string>
<string name="labs_enable_thread_messages">Enable Thread Messages</string>
<string name="labs_enable_thread_messages">Enable threaded messages</string>
<string name="labs_enable_thread_messages_desc">Note: app will be restarted</string>
<string name="settings_show_latest_profile">Show latest user info</string>
<string name="settings_show_latest_profile_description">Show the latest profile info (avatar and display name) for all the messages.</string>
@@ -3094,6 +3104,7 @@
<string name="audio_message_file_size">(%1$s)</string>
<string name="voice_broadcast_live">Live</string>
<string name="voice_broadcast_live_broadcast">Live broadcast</string>
<!-- TODO Rename id to voice_broadcast_buffering -->
<string name="a11y_voice_broadcast_buffering">Buffering…</string>
<string name="a11y_resume_voice_broadcast_record">Resume voice broadcast record</string>
@@ -3301,6 +3312,7 @@
<string name="device_manager_verification_status_detail_current_session_unverified">Verify your current session for enhanced secure messaging.</string>
<string name="device_manager_verification_status_detail_other_session_unverified">Verify or sign out from this session for best security and reliability.</string>
<string name="device_manager_verification_status_detail_other_session_unknown">Verify your current session to reveal this session\'s verification status.</string>
<string name="device_manager_verification_status_detail_session_encryption_not_supported">This session doesn\'t support encryption and thus can\'t be verified.</string>
<string name="device_manager_verify_session">Verify Session</string>
<string name="device_manager_view_details">View Details</string>
<string name="device_manager_other_sessions_view_all">View All (%1$d)</string>
@@ -3359,6 +3371,7 @@
<item quantity="one">Sign out of %1$d session</item>
<item quantity="other">Sign out of %1$d sessions</item>
</plurals>
<string name="device_manager_signout_all_other_sessions">Sign out of all other sessions</string>
<string name="device_manager_other_sessions_show_ip_address">Show IP address</string>
<string name="device_manager_other_sessions_hide_ip_address">Hide IP address</string>
<string name="device_manager_session_overview_signout">Sign out of this session</string>
@@ -3392,6 +3405,7 @@
<!-- TODO TO BE REMOVED -->
<string name="device_manager_learn_more_sessions_verified" tools:ignore="UnusedResources">Verified sessions have logged in with your credentials and then been verified, either using your secure passphrase or by cross-verifying.\n\nThis means they hold encryption keys for your previous messages, and confirm to other users you are communicating with that these sessions are really you.</string>
<string name="device_manager_learn_more_sessions_verified_description">Verified sessions are anywhere you are using this account after entering your passphrase or confirming your identity with another verified session.\n\nThis means that you have all the keys needed to unlock your encrypted messages and confirm to other users that you trust this session.</string>
<string name="device_manager_learn_more_sessions_encryption_not_supported">This session doesn\'t support encryption, so it can\'t be verified.\n\nYou won\'t be able to participate in rooms where encryption is enabled when using this session.\n\nFor best security and privacy, it is recommended to use Matrix clients that support encryption.</string>
<string name="device_manager_learn_more_session_rename_title">Renaming sessions</string>
<string name="device_manager_learn_more_session_rename">Other users in direct messages and rooms that you join are able to view a full list of your sessions.\n\nThis provides them with confidence that they are really speaking to you, but it also means they can see the session name you enter here.</string>
<string name="labs_enable_session_manager_title">Enable new session manager</string>

View File

@@ -44,4 +44,4 @@
<color name="palette_black_800">#15191E</color>
<color name="palette_black_950">#21262C</color>
</resources>
</resources>

View File

@@ -53,7 +53,7 @@
<item name="vctr_list_separator">?vctr_content_quinary</item>
<item name="vctr_list_separator_system">?vctr_system</item>
<item name="vctr_list_separator_on_surface">?vctr_system</item>
<item name="vctr_unread_background">?vctr_content_tertiary</item>
<item name="vctr_unread_background">?vctr_notice_secondary</item>
<!-- Material color -->
<item name="colorPrimary">@color/element_accent_dark</item>

View File

@@ -53,7 +53,7 @@
<item name="vctr_list_separator">?vctr_content_quinary</item>
<item name="vctr_list_separator_system">?vctr_system</item>
<item name="vctr_list_separator_on_surface">?vctr_system</item>
<item name="vctr_unread_background">?vctr_content_tertiary</item>
<item name="vctr_unread_background">?vctr_notice_secondary</item>
<!-- Material color -->
<item name="colorPrimary">@color/element_accent_light</item>

View File

@@ -31,7 +31,6 @@ 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
import org.matrix.android.sdk.api.session.room.send.UserDraft
import org.matrix.android.sdk.api.session.room.threads.model.ThreadSummary
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
@@ -119,13 +118,6 @@ class FlowRoom(private val room: Room) {
return room.roomPushRuleService().getLiveRoomNotificationState().asFlow()
}
fun liveThreadSummaries(): Flow<List<ThreadSummary>> {
return room.threadsService().getAllThreadSummariesLive().asFlow()
.startWith(room.coroutineDispatchers.io) {
room.threadsService().getAllThreadSummaries()
}
}
fun liveThreadList(): Flow<List<ThreadRootEvent>> {
return room.threadsLocalService().getAllThreadsLive().asFlow()
.startWith(room.coroutineDispatchers.io) {

View File

@@ -62,7 +62,7 @@ android {
// that the app's state is completely cleared between tests.
testInstrumentationRunnerArguments clearPackageData: 'true'
buildConfigField "String", "SDK_VERSION", "\"1.5.10\""
buildConfigField "String", "SDK_VERSION", "\"1.5.13\""
buildConfigField "String", "GIT_SDK_REVISION", "\"${gitRevision()}\""
buildConfigField "String", "GIT_SDK_REVISION_UNIX_DATE", "\"${gitRevisionUnixDate()}\""

View File

@@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:a7acd69f37612bab0a1ab7f456656712d7ba19dbb679f81b97b58ef44e239f42
size 8523776

View File

@@ -16,7 +16,7 @@
package org.matrix.android.sdk.common
import org.matrix.android.sdk.api.RoomDisplayNameFallbackProvider
import org.matrix.android.sdk.api.provider.RoomDisplayNameFallbackProvider
class TestRoomDisplayNameFallbackProvider : RoomDisplayNameFallbackProvider {

View File

@@ -0,0 +1,65 @@
/*
* Copyright 2022 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
import android.content.Context
import androidx.test.platform.app.InstrumentationRegistry
import io.realm.Realm
import org.junit.After
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.matrix.android.sdk.internal.crypto.store.db.RealmCryptoStoreMigration
import org.matrix.android.sdk.internal.crypto.store.db.RealmCryptoStoreModule
import org.matrix.android.sdk.internal.util.time.Clock
class CryptoSanityMigrationTest {
@get:Rule val configurationFactory = TestRealmConfigurationFactory()
lateinit var context: Context
var realm: Realm? = null
@Before
fun setUp() {
context = InstrumentationRegistry.getInstrumentation().context
}
@After
fun tearDown() {
realm?.close()
}
@Test
fun cryptoDatabaseShouldMigrateGracefully() {
val realmName = "crypto_store_20.realm"
val migration = RealmCryptoStoreMigration(object : Clock {
override fun epochMillis(): Long {
return 0L
}
})
val realmConfiguration = configurationFactory.createConfiguration(
realmName,
"7b9a21a8a311e85d75b069a343c23fc952fc3fec5e0c83ecfa13f24b787479c487c3ed587db3dd1f5805d52041fc0ac246516e94b27ffa699ff928622e621aca",
RealmCryptoStoreModule(),
migration.schemaVersion,
migration
)
configurationFactory.copyRealmFromAssets(context, realmName, realmName)
realm = Realm.getInstance(realmConfiguration)
}
}

View File

@@ -20,6 +20,9 @@ import okhttp3.ConnectionSpec
import okhttp3.Interceptor
import org.matrix.android.sdk.api.crypto.MXCryptoConfig
import org.matrix.android.sdk.api.metrics.MetricPlugin
import org.matrix.android.sdk.api.provider.CustomEventTypesProvider
import org.matrix.android.sdk.api.provider.MatrixItemDisplayNameFallbackProvider
import org.matrix.android.sdk.api.provider.RoomDisplayNameFallbackProvider
import java.net.Proxy
data class MatrixConfiguration(
@@ -66,7 +69,7 @@ data class MatrixConfiguration(
/**
* Thread messages default enable/disabled value.
*/
val threadMessagesEnabledDefault: Boolean = false,
val threadMessagesEnabledDefault: Boolean = true,
/**
* List of network interceptors, they will be added when building an OkHttp client.
*/
@@ -75,9 +78,12 @@ data class MatrixConfiguration(
* Sync configuration.
*/
val syncConfig: SyncConfig = SyncConfig(),
/**
* Metrics plugin that can be used to capture metrics from matrix-sdk-android.
*/
val metricPlugins: List<MetricPlugin> = emptyList()
val metricPlugins: List<MetricPlugin> = emptyList(),
/**
* CustomEventTypesProvider to provide custom event types to the sdk which should be processed with internal events.
*/
val customEventTypesProvider: CustomEventTypesProvider? = null,
)

View File

@@ -21,5 +21,6 @@ import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = true)
data class LocalNotificationSettingsContent(
@Json(name = "is_silenced") val isSilenced: Boolean = false
@Json(name = "is_silenced")
val isSilenced: Boolean?
)

View File

@@ -125,12 +125,6 @@ interface AuthenticationService {
deviceId: String? = null
): Session
/**
* @param homeServerConnectionConfig the information about the homeserver and other configuration
* Return true if qr code login is supported by the server, false otherwise.
*/
suspend fun isQrLoginSupported(homeServerConnectionConfig: HomeServerConnectionConfig): Boolean
/**
* Authenticate using m.login.token method during sign in with QR code.
* @param homeServerConnectionConfig the information about the homeserver and other configuration

View File

@@ -22,5 +22,6 @@ data class LoginFlowResult(
val isLoginAndRegistrationSupported: Boolean,
val homeServerUrl: String,
val isOutdatedHomeserver: Boolean,
val isLogoutDevicesSupported: Boolean
val isLogoutDevicesSupported: Boolean,
val isLoginWithQrSupported: Boolean,
)

View File

@@ -0,0 +1,30 @@
/*
* Copyright 2022 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.provider
import org.matrix.android.sdk.api.session.room.model.RoomSummary
/**
* Provide custom event types which should be processed with the internal event types.
*/
interface CustomEventTypesProvider {
/**
* Custom event types to include when computing [RoomSummary.latestPreviewableEvent].
*/
val customPreviewableEventTypes: List<String>
}

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.matrix.android.sdk.api
package org.matrix.android.sdk.api.provider
import org.matrix.android.sdk.api.util.MatrixItem

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package org.matrix.android.sdk.api
package org.matrix.android.sdk.api.provider
/**
* This interface exists to let the implementation provide localized room display name fallback.

View File

@@ -35,7 +35,10 @@ import org.matrix.android.sdk.api.session.crypto.crosssigning.KEYBACKUP_SECRET_S
import org.matrix.android.sdk.api.session.crypto.crosssigning.MASTER_KEY_SSSS_NAME
import org.matrix.android.sdk.api.session.crypto.crosssigning.SELF_SIGNING_KEY_SSSS_NAME
import org.matrix.android.sdk.api.session.crypto.crosssigning.USER_SIGNING_KEY_SSSS_NAME
import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo
import org.matrix.android.sdk.api.session.crypto.model.MXUsersDevicesMap
import org.matrix.android.sdk.api.util.MatrixJsonParser
import org.matrix.android.sdk.api.util.awaitCallback
import timber.log.Timber
/**
@@ -147,6 +150,14 @@ class Rendezvous(
val deviceKey = crypto.getMyDevice().fingerprint()
send(Payload(PayloadType.PROGRESS, outcome = Outcome.SUCCESS, deviceId = deviceId, deviceKey = deviceKey))
try {
// explicitly download keys for ourself rather than racing with initial sync which might not complete in time
awaitCallback<MXUsersDevicesMap<CryptoDeviceInfo>> { crypto.downloadKeys(listOf(userId), false, it) }
} catch (e: Throwable) {
// log as warning and continue as initial sync might still complete
Timber.tag(TAG).w(e, "Failed to download keys for self")
}
// await confirmation of verification
val verificationResponse = receive()
if (verificationResponse?.outcome == Outcome.VERIFIED) {

View File

@@ -63,4 +63,17 @@ interface SessionAccountDataService {
* Update the account data with the provided type and the provided account data content.
*/
suspend fun updateUserAccountData(type: String, content: Content)
/**
* Retrieve user account data list whose type starts with the given type.
* @param type the type or the starting part of a type
* @return list of account data whose type starts with the given type
*/
fun getUserAccountDataEventsStartWith(type: String): List<UserAccountDataEvent>
/**
* Deletes user account data of the given type.
* @param type the type to delete from user account data
*/
suspend fun deleteUserAccountData(type: String)
}

View File

@@ -16,6 +16,8 @@
package org.matrix.android.sdk.api.session.events.model
import org.matrix.android.sdk.api.session.room.model.message.MessageType.MSGTYPE_VERIFICATION_REQUEST
/**
* Constants defining known event types from Matrix specifications.
*/
@@ -126,6 +128,7 @@ object EventType {
fun isVerificationEvent(type: String): Boolean {
return when (type) {
MSGTYPE_VERIFICATION_REQUEST,
KEY_VERIFICATION_START,
KEY_VERIFICATION_ACCEPT,
KEY_VERIFICATION_KEY,

View File

@@ -0,0 +1,23 @@
/*
* Copyright 2022 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.threads
sealed class FetchThreadsResult {
data class ShouldFetchMore(val nextBatch: String) : FetchThreadsResult()
object ReachedEnd : FetchThreadsResult()
object Failed : FetchThreadsResult()
}

View File

@@ -0,0 +1,26 @@
/*
* Copyright 2022 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.threads
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
@JsonClass(generateAdapter = false)
enum class ThreadFilter {
@Json(name = "all") ALL,
@Json(name = "participated") PARTICIPATED,
}

View File

@@ -0,0 +1,27 @@
/*
* Copyright (c) 2021 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.threads
import androidx.lifecycle.LiveData
import androidx.paging.PagedList
import org.matrix.android.sdk.api.session.room.ResultBoundaries
import org.matrix.android.sdk.api.session.room.threads.model.ThreadSummary
data class ThreadLivePageResult(
val livePagedList: LiveData<PagedList<ThreadSummary>>,
val liveBoundaries: LiveData<ResultBoundaries>
)

View File

@@ -16,7 +16,7 @@
package org.matrix.android.sdk.api.session.room.threads
import androidx.lifecycle.LiveData
import androidx.paging.PagedList
import org.matrix.android.sdk.api.session.room.threads.model.ThreadSummary
/**
@@ -27,15 +27,14 @@ import org.matrix.android.sdk.api.session.room.threads.model.ThreadSummary
*/
interface ThreadsService {
/**
* Returns a [LiveData] list of all the [ThreadSummary] that exists at the room level.
*/
fun getAllThreadSummariesLive(): LiveData<List<ThreadSummary>>
suspend fun getPagedThreadsList(userParticipating: Boolean, pagedListConfig: PagedList.Config): ThreadLivePageResult
suspend fun fetchThreadList(nextBatchId: String?, limit: Int, filter: ThreadFilter = ThreadFilter.ALL): FetchThreadsResult
/**
* Returns a list of all the [ThreadSummary] that exists at the room level.
*/
fun getAllThreadSummaries(): List<ThreadSummary>
suspend fun getAllThreadSummaries(): List<ThreadSummary>
/**
* Enhance the provided ThreadSummary[List] by adding the latest
@@ -51,9 +50,4 @@ interface ThreadsService {
* @param limit defines the number of max results the api will respond with
*/
suspend fun fetchThreadTimeline(rootThreadEventId: String, from: String, limit: Int)
/**
* Fetch all thread summaries for the current room using the enhanced /messages api.
*/
suspend fun fetchThreadSummaries()
}

View File

@@ -30,7 +30,6 @@ 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
import org.matrix.android.sdk.api.extensions.orFalse
import org.matrix.android.sdk.api.failure.Failure
import org.matrix.android.sdk.api.failure.MatrixIdFailure
import org.matrix.android.sdk.api.session.Session
@@ -299,7 +298,8 @@ internal class DefaultAuthenticationService @Inject constructor(
isLoginAndRegistrationSupported = versions.isLoginAndRegistrationSupportedBySdk(),
homeServerUrl = homeServerUrl,
isOutdatedHomeserver = !versions.isSupportedBySdk(),
isLogoutDevicesSupported = versions.doesServerSupportLogoutDevices()
isLogoutDevicesSupported = versions.doesServerSupportLogoutDevices(),
isLoginWithQrSupported = versions.doesServerSupportQrCodeLogin(),
)
}
@@ -408,20 +408,6 @@ internal class DefaultAuthenticationService @Inject constructor(
)
}
override suspend fun isQrLoginSupported(homeServerConnectionConfig: HomeServerConnectionConfig): Boolean {
val authAPI = buildAuthAPI(homeServerConnectionConfig)
val versions = runCatching {
executeRequest(null) {
authAPI.versions()
}
}
return if (versions.isSuccess) {
versions.getOrNull()?.doesServerSupportQrCodeLogin().orFalse()
} else {
false
}
}
override suspend fun loginUsingQrLoginToken(
homeServerConnectionConfig: HomeServerConnectionConfig,
loginToken: String,

View File

@@ -17,14 +17,22 @@
package org.matrix.android.sdk.internal.crypto.tasks
import org.matrix.android.sdk.api.session.crypto.model.MXUsersDevicesMap
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.internal.crypto.api.CryptoApi
import org.matrix.android.sdk.internal.crypto.model.rest.SendToDeviceBody
import org.matrix.android.sdk.internal.network.GlobalErrorReceiver
import org.matrix.android.sdk.internal.network.executeRequest
import org.matrix.android.sdk.internal.task.Task
import timber.log.Timber
import java.util.UUID
import javax.inject.Inject
const val TO_DEVICE_TRACING_ID_KEY = "org.matrix.msgid"
fun Event.toDeviceTracingId(): String? = content?.get(TO_DEVICE_TRACING_ID_KEY) as? String
internal interface SendToDeviceTask : Task<SendToDeviceTask.Params, Unit> {
data class Params(
// the type of event to send
@@ -32,7 +40,9 @@ internal interface SendToDeviceTask : Task<SendToDeviceTask.Params, Unit> {
// the content to send. Map from user_id to device_id to content dictionary.
val contentMap: MXUsersDevicesMap<Any>,
// the transactionId. If not provided, a transactionId will be created by the task
val transactionId: String? = null
val transactionId: String? = null,
// add tracing id, notice that to device events that do signature on content might be broken by it
val addTracingIds: Boolean = !EventType.isVerificationEvent(eventType),
)
}
@@ -42,15 +52,22 @@ internal class DefaultSendToDeviceTask @Inject constructor(
) : SendToDeviceTask {
override suspend fun execute(params: SendToDeviceTask.Params) {
val sendToDeviceBody = SendToDeviceBody(
messages = params.contentMap.map
)
// If params.transactionId is not provided, we create a unique txnId.
// It's important to do that outside the requestBlock parameter of executeRequest()
// to use the same value if the request is retried
val txnId = params.transactionId ?: createUniqueTxnId()
// add id tracing to debug
val decorated = if (params.addTracingIds) {
decorateWithToDeviceTracingIds(params)
} else {
params.contentMap.map to emptyList()
}
val sendToDeviceBody = SendToDeviceBody(
messages = decorated.first
)
return executeRequest(
globalErrorReceiver,
canRetry = true,
@@ -61,8 +78,35 @@ internal class DefaultSendToDeviceTask @Inject constructor(
transactionId = txnId,
body = sendToDeviceBody
)
Timber.i("Sent to device type=${params.eventType} txnid=$txnId [${decorated.second.joinToString(",")}]")
}
}
/**
* To make it easier to track down where to-device messages are getting lost,
* add a custom property to each one, and that will be logged after sent and on reception. Synapse will also log
* this property.
* @return A pair, first is the decorated content, and second info to log out after sending
*/
private fun decorateWithToDeviceTracingIds(params: SendToDeviceTask.Params): Pair<Map<String, Map<String, Any>>, List<String>> {
val tracingInfo = mutableListOf<String>()
val decoratedContent = params.contentMap.map.map { userToDeviceMap ->
val userId = userToDeviceMap.key
userId to userToDeviceMap.value.map {
val deviceId = it.key
deviceId to it.value.toContent().toMutableMap().apply {
put(
TO_DEVICE_TRACING_ID_KEY,
UUID.randomUUID().toString().also {
tracingInfo.add("$userId/$deviceId (msgid $it)")
}
)
}
}.toMap()
}.toMap()
return decoratedContent to tracingInfo
}
}
internal fun createUniqueTxnId() = UUID.randomUUID().toString()

View File

@@ -62,6 +62,7 @@ import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo042
import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo043
import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo044
import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo045
import org.matrix.android.sdk.internal.database.migration.MigrateSessionTo046
import org.matrix.android.sdk.internal.util.Normalizer
import org.matrix.android.sdk.internal.util.database.MatrixRealmMigration
import javax.inject.Inject
@@ -70,7 +71,7 @@ internal class RealmSessionStoreMigration @Inject constructor(
private val normalizer: Normalizer
) : MatrixRealmMigration(
dbName = "Session",
schemaVersion = 45L,
schemaVersion = 46L,
) {
/**
* Forces all RealmSessionStoreMigration instances to be equal.
@@ -125,5 +126,6 @@ internal class RealmSessionStoreMigration @Inject constructor(
if (oldVersion < 43) MigrateSessionTo043(realm).perform()
if (oldVersion < 44) MigrateSessionTo044(realm).perform()
if (oldVersion < 45) MigrateSessionTo045(realm).perform()
if (oldVersion < 46) MigrateSessionTo046(realm).perform()
}
}

View File

@@ -37,9 +37,11 @@ import org.matrix.android.sdk.internal.database.model.EventEntity
import org.matrix.android.sdk.internal.database.model.EventInsertType
import org.matrix.android.sdk.internal.database.model.RoomEntity
import org.matrix.android.sdk.internal.database.model.TimelineEventEntity
import org.matrix.android.sdk.internal.database.model.threads.ThreadListPageEntity
import org.matrix.android.sdk.internal.database.model.threads.ThreadSummaryEntity
import org.matrix.android.sdk.internal.database.model.threads.ThreadSummaryEntityFields
import org.matrix.android.sdk.internal.database.query.copyToRealmOrIgnore
import org.matrix.android.sdk.internal.database.query.get
import org.matrix.android.sdk.internal.database.query.getOrCreate
import org.matrix.android.sdk.internal.database.query.getOrNull
import org.matrix.android.sdk.internal.database.query.where
@@ -113,16 +115,16 @@ internal fun ThreadSummaryEntity.Companion.createOrUpdate(
userId: String,
cryptoService: CryptoService? = null,
currentTimeMillis: Long,
) {
): ThreadSummaryEntity? {
when (threadSummaryType) {
ThreadSummaryUpdateType.REPLACE -> {
rootThreadEvent?.eventId ?: return
rootThreadEvent.senderId ?: return
rootThreadEvent?.eventId ?: return null
rootThreadEvent.senderId ?: return null
val numberOfThreads = rootThreadEvent.unsignedData?.relations?.latestThread?.count ?: return
val numberOfThreads = rootThreadEvent.unsignedData?.relations?.latestThread?.count ?: return null
// Something is wrong with the server return
if (numberOfThreads <= 0) return
if (numberOfThreads <= 0) return null
val threadSummary = ThreadSummaryEntity.getOrCreate(realm, roomId, rootThreadEvent.eventId).also {
Timber.i("###THREADS ThreadSummaryHelper REPLACE eventId:${it.rootThreadEventId} ")
@@ -153,12 +155,13 @@ internal fun ThreadSummaryEntity.Companion.createOrUpdate(
)
roomEntity.addIfNecessary(threadSummary)
return threadSummary
}
ThreadSummaryUpdateType.ADD -> {
val rootThreadEventId = threadEventEntity?.rootThreadEventId ?: return
val rootThreadEventId = threadEventEntity?.rootThreadEventId ?: return null
Timber.i("###THREADS ThreadSummaryHelper ADD for root eventId:$rootThreadEventId")
val threadSummary = ThreadSummaryEntity.getOrNull(realm, roomId, rootThreadEventId)
var threadSummary = ThreadSummaryEntity.getOrNull(realm, roomId, rootThreadEventId)
if (threadSummary != null) {
// ThreadSummary exists so lets add the latest event
Timber.i("###THREADS ThreadSummaryHelper ADD root eventId:$rootThreadEventId exists, lets update latest thread event.")
@@ -172,7 +175,7 @@ internal fun ThreadSummaryEntity.Companion.createOrUpdate(
Timber.i("###THREADS ThreadSummaryHelper ADD root eventId:$rootThreadEventId do not exists, lets try to create one")
threadEventEntity.findRootThreadEvent()?.let { rootThreadEventEntity ->
// Root thread event entity exists so lets create a new record
ThreadSummaryEntity.getOrCreate(realm, roomId, rootThreadEventEntity.eventId).let {
threadSummary = ThreadSummaryEntity.getOrCreate(realm, roomId, rootThreadEventEntity.eventId).also {
it.updateThreadSummary(
rootThreadEventEntity = rootThreadEventEntity,
numberOfThreads = 1,
@@ -183,7 +186,12 @@ internal fun ThreadSummaryEntity.Companion.createOrUpdate(
roomEntity.addIfNecessary(it)
}
}
threadSummary?.let {
ThreadListPageEntity.get(realm, roomId)?.threadSummaries?.add(it)
}
}
return threadSummary
}
}
}

View File

@@ -0,0 +1,32 @@
/*
* Copyright (c) 2022 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.migration
import io.realm.DynamicRealm
import org.matrix.android.sdk.internal.database.model.threads.ThreadListPageEntityFields
import org.matrix.android.sdk.internal.util.database.RealmMigrator
internal class MigrateSessionTo046(realm: DynamicRealm) : RealmMigrator(realm, 46) {
override fun doMigrate(realm: DynamicRealm) {
realm.schema.create("ThreadListPageEntity")
.addField(ThreadListPageEntityFields.ROOM_ID, String::class.java)
.addPrimaryKey(ThreadListPageEntityFields.ROOM_ID)
.setRequired(ThreadListPageEntityFields.ROOM_ID, true)
.addRealmListField(ThreadListPageEntityFields.THREAD_SUMMARIES.`$`, realm.schema.get("ThreadSummaryEntity")!!)
}
}

View File

@@ -19,6 +19,7 @@ package org.matrix.android.sdk.internal.database.model
import io.realm.annotations.RealmModule
import org.matrix.android.sdk.internal.database.model.livelocation.LiveLocationShareAggregatedSummaryEntity
import org.matrix.android.sdk.internal.database.model.presence.UserPresenceEntity
import org.matrix.android.sdk.internal.database.model.threads.ThreadListPageEntity
import org.matrix.android.sdk.internal.database.model.threads.ThreadSummaryEntity
/**
@@ -72,6 +73,7 @@ import org.matrix.android.sdk.internal.database.model.threads.ThreadSummaryEntit
UserPresenceEntity::class,
ThreadSummaryEntity::class,
SyncFilterParamsEntity::class,
ThreadListPageEntity::class
]
)
internal class SessionRealmModule

View File

@@ -0,0 +1,28 @@
/*
* Copyright 2022 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.threads
import io.realm.RealmList
import io.realm.RealmObject
import io.realm.annotations.PrimaryKey
internal open class ThreadListPageEntity(
@PrimaryKey var roomId: String = "",
var threadSummaries: RealmList<ThreadSummaryEntity> = RealmList()
) : RealmObject() {
companion object
}

View File

@@ -40,5 +40,8 @@ internal open class ThreadSummaryEntity(
@LinkingObjects("threadSummaries")
val room: RealmResults<RoomEntity>? = null
@LinkingObjects("threadSummaries")
val page: RealmResults<ThreadListPageEntity>? = null
companion object
}

View File

@@ -21,6 +21,7 @@ import io.realm.RealmQuery
import io.realm.kotlin.where
import org.matrix.android.sdk.api.session.room.model.Membership
import org.matrix.android.sdk.internal.database.model.EventEntity
import org.matrix.android.sdk.internal.database.model.RoomAccountDataEntityFields
import org.matrix.android.sdk.internal.database.model.RoomEntity
import org.matrix.android.sdk.internal.database.model.RoomEntityFields
@@ -44,3 +45,11 @@ internal fun RoomEntity.Companion.where(realm: Realm, membership: Membership? =
internal fun RoomEntity.fastContains(eventId: String): Boolean {
return EventEntity.where(realm, eventId = eventId).findFirst() != null
}
internal fun RoomEntity.removeAccountData(type: String) {
accountData
.where()
.equalTo(RoomAccountDataEntityFields.TYPE, type)
.findFirst()
?.deleteFromRealm()
}

View File

@@ -0,0 +1,31 @@
/*
* Copyright 2022 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.threads.ThreadListPageEntity
import org.matrix.android.sdk.internal.database.model.threads.ThreadListPageEntityFields
internal fun ThreadListPageEntity.Companion.get(realm: Realm, roomId: String): ThreadListPageEntity? {
return realm.where<ThreadListPageEntity>().equalTo(ThreadListPageEntityFields.ROOM_ID, roomId).findFirst()
}
internal fun ThreadListPageEntity.Companion.getOrCreate(realm: Realm, roomId: String): ThreadListPageEntity {
return get(realm, roomId) ?: realm.createObject(roomId)
}

View File

@@ -22,6 +22,7 @@ import io.realm.RealmQuery
import io.realm.RealmResults
import io.realm.Sort
import io.realm.kotlin.where
import org.matrix.android.sdk.api.session.events.model.EventType
import org.matrix.android.sdk.api.session.room.send.SendState
import org.matrix.android.sdk.api.session.room.timeline.TimelineEventFilters
import org.matrix.android.sdk.internal.database.model.ChunkEntity
@@ -94,14 +95,27 @@ internal fun RealmQuery<TimelineEventEntity>.filterEvents(filters: TimelineEvent
if (filters.filterTypes && filters.allowedTypes.isNotEmpty()) {
beginGroup()
filters.allowedTypes.forEachIndexed { index, filter ->
if (filter.stateKey == null) {
equalTo(TimelineEventEntityFields.ROOT.TYPE, filter.eventType)
if (filter.eventType == EventType.ENCRYPTED) {
val otherTypes = filters.allowedTypes.minus(filter).map { it.eventType }
if (filter.stateKey == null) {
filterEncryptedTypes(otherTypes)
} else {
beginGroup()
filterEncryptedTypes(otherTypes)
and()
equalTo(TimelineEventEntityFields.ROOT.STATE_KEY, filter.stateKey)
endGroup()
}
} else {
beginGroup()
equalTo(TimelineEventEntityFields.ROOT.TYPE, filter.eventType)
and()
equalTo(TimelineEventEntityFields.ROOT.STATE_KEY, filter.stateKey)
endGroup()
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()
@@ -115,7 +129,6 @@ internal fun RealmQuery<TimelineEventEntity>.filterEvents(filters: TimelineEvent
if (filters.filterEdits) {
not().like(TimelineEventEntityFields.ROOT.CONTENT, TimelineEventFilter.Content.EDIT)
not().like(TimelineEventEntityFields.ROOT.CONTENT, TimelineEventFilter.Content.RESPONSE)
not().like(TimelineEventEntityFields.ROOT.CONTENT, TimelineEventFilter.Content.REFERENCE)
}
if (filters.filterRedacted) {
not().like(TimelineEventEntityFields.ROOT.UNSIGNED_DATA, TimelineEventFilter.Unsigned.REDACTED)
@@ -124,6 +137,21 @@ internal fun RealmQuery<TimelineEventEntity>.filterEvents(filters: TimelineEvent
return this
}
internal fun RealmQuery<TimelineEventEntity>.filterEncryptedTypes(allowedTypes: List<String>): RealmQuery<TimelineEventEntity> {
beginGroup()
equalTo(TimelineEventEntityFields.ROOT.TYPE, EventType.ENCRYPTED)
and()
beginGroup()
isNull(TimelineEventEntityFields.ROOT.DECRYPTION_RESULT_JSON)
allowedTypes.forEach { eventType ->
or()
like(TimelineEventEntityFields.ROOT.DECRYPTION_RESULT_JSON, TimelineEventFilter.DecryptedContent.type(eventType))
}
endGroup()
endGroup()
return this
}
internal fun RealmQuery<TimelineEventEntity>.filterTypes(filterTypes: List<String>): RealmQuery<TimelineEventEntity> {
return if (filterTypes.isEmpty()) {
this

View File

@@ -34,6 +34,7 @@ internal object TimelineEventFilter {
*/
internal object DecryptedContent {
internal const val URL = """{*"file":*"url":*}"""
fun type(type: String) = """{*"type":*"$type"*}"""
}
/**

View File

@@ -0,0 +1,33 @@
/*
* Copyright 2022 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.where
import org.matrix.android.sdk.internal.database.model.UserAccountDataEntity
import org.matrix.android.sdk.internal.database.model.UserAccountDataEntityFields
/**
* Delete an account_data event.
*/
internal fun UserAccountDataEntity.Companion.delete(realm: Realm, type: String) {
realm
.where<UserAccountDataEntity>()
.equalTo(UserAccountDataEntityFields.TYPE, type)
.findFirst()
?.deleteFromRealm()
}

View File

@@ -42,7 +42,7 @@ internal class DefaultGetCurrentFilterTask @Inject constructor(
return when (storedFilterBody) {
currentFilterBody -> storedFilterId ?: storedFilterBody
else -> saveFilter(currentFilter)
else -> saveFilter(currentFilter) ?: currentFilterBody
}
}

View File

@@ -16,6 +16,7 @@
package org.matrix.android.sdk.internal.session.filter
import org.matrix.android.sdk.api.extensions.tryOrNull
import org.matrix.android.sdk.internal.di.UserId
import org.matrix.android.sdk.internal.network.GlobalErrorReceiver
import org.matrix.android.sdk.internal.network.executeRequest
@@ -24,8 +25,9 @@ import javax.inject.Inject
/**
* Save a filter, in db and if any changes, upload to the server.
* Return the filterId if uploading to the server is successful, else return null.
*/
internal interface SaveFilterTask : Task<SaveFilterTask.Params, String> {
internal interface SaveFilterTask : Task<SaveFilterTask.Params, String?> {
data class Params(
val filter: Filter
@@ -39,18 +41,20 @@ internal class DefaultSaveFilterTask @Inject constructor(
private val globalErrorReceiver: GlobalErrorReceiver,
) : SaveFilterTask {
override suspend fun execute(params: SaveFilterTask.Params): String {
override suspend fun execute(params: SaveFilterTask.Params): String? {
val filter = params.filter
val filterResponse = executeRequest(globalErrorReceiver) {
// TODO auto retry
filterAPI.uploadFilter(userId, filter)
val filterResponse = tryOrNull {
executeRequest(globalErrorReceiver) {
filterAPI.uploadFilter(userId, filter)
}
}
val filterId = filterResponse?.filterId
filterRepository.storeSyncFilter(
filter = filter,
filterId = filterResponse.filterId,
filterId = filterId.orEmpty(),
roomEventFilter = FilterFactory.createDefaultRoomFilter()
)
return filterResponse.filterId
return filterId
}
}

View File

@@ -35,6 +35,7 @@ import org.matrix.android.sdk.internal.session.room.membership.joining.InviteBod
import org.matrix.android.sdk.internal.session.room.membership.threepid.ThreePidInviteBody
import org.matrix.android.sdk.internal.session.room.read.ReadBody
import org.matrix.android.sdk.internal.session.room.relation.RelationsResponse
import org.matrix.android.sdk.internal.session.room.relation.threads.ThreadSummariesResponse
import org.matrix.android.sdk.internal.session.room.reporting.ReportContentBody
import org.matrix.android.sdk.internal.session.room.send.SendResponse
import org.matrix.android.sdk.internal.session.room.tags.TagBody
@@ -427,6 +428,19 @@ internal interface RoomAPI {
@Body content: JsonDict
)
/**
* Remove an account_data event from the room.
* @param userId the user id
* @param roomId the room id
* @param type the type
*/
@DELETE(NetworkConstants.URI_API_PREFIX_PATH_UNSTABLE + "org.matrix.msc3391/user/{userId}/rooms/{roomId}/account_data/{type}")
suspend fun deleteRoomAccountData(
@Path("userId") userId: String,
@Path("roomId") roomId: String,
@Path("type") type: String
)
/**
* Upgrades the given room to a particular room version.
* Errors:
@@ -451,4 +465,12 @@ internal interface RoomAPI {
@Path("roomIdOrAlias") roomidOrAlias: String,
@Query("via") viaServers: List<String>?
): RoomStrippedState
@GET(NetworkConstants.URI_API_PREFIX_PATH_V1 + "rooms/{roomId}/threads")
suspend fun getThreadsList(
@Path("roomId") roomId: String,
@Query("include") include: String? = "all",
@Query("from") from: String? = null,
@Query("limit") limit: Int? = null
): ThreadSummariesResponse
}

View File

@@ -29,7 +29,6 @@ import org.matrix.android.sdk.api.session.room.getTimelineEvent
import org.matrix.android.sdk.api.session.room.model.PollSummaryContent
import org.matrix.android.sdk.api.session.room.model.VoteInfo
import org.matrix.android.sdk.api.session.room.model.VoteSummary
import org.matrix.android.sdk.api.session.room.model.message.MessageEndPollContent
import org.matrix.android.sdk.api.session.room.model.message.MessagePollContent
import org.matrix.android.sdk.api.session.room.model.message.MessagePollResponseContent
import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper
@@ -78,7 +77,7 @@ class DefaultPollAggregationProcessor @Inject constructor() : PollAggregationPro
val content = event.getClearContent()?.toModel<MessagePollResponseContent>() ?: return false
val roomId = event.roomId ?: return false
val senderId = event.senderId ?: return false
val targetEventId = (event.getRelationContent() ?: content.relatesTo)?.eventId ?: return false
val targetEventId = event.getRelationContent()?.eventId ?: return false
val targetPollContent = getPollContent(session, roomId, targetEventId) ?: return false
val annotationsSummaryEntity = getAnnotationsSummaryEntity(realm, roomId, targetEventId)
@@ -154,9 +153,8 @@ class DefaultPollAggregationProcessor @Inject constructor() : PollAggregationPro
}
override fun handlePollEndEvent(session: Session, powerLevelsHelper: PowerLevelsHelper, realm: Realm, event: Event): Boolean {
val content = event.getClearContent()?.toModel<MessageEndPollContent>() ?: return false
val roomId = event.roomId ?: return false
val pollEventId = content.relatesTo?.eventId ?: return false
val pollEventId = event.getRelationContent()?.eventId ?: return false
val pollOwnerId = getPollEvent(session, roomId, pollEventId)?.root?.senderId
val isPollOwner = pollOwnerId == event.senderId

View File

@@ -46,7 +46,7 @@ internal class DefaultStartLiveLocationShareTask @Inject constructor(
isLive = true,
unstableTimestampMillis = clock.epochMillis()
).toContent()
val eventType = EventType.STATE_ROOM_BEACON_INFO.stable
val eventType = EventType.STATE_ROOM_BEACON_INFO.unstable
val sendStateTaskParams = SendStateTask.Params(
roomId = params.roomId,
stateKey = userId,

View File

@@ -45,7 +45,7 @@ internal class DefaultStopLiveLocationShareTask @Inject constructor(
val sendStateTaskParams = SendStateTask.Params(
roomId = params.roomId,
stateKey = stateKey,
eventType = EventType.STATE_ROOM_BEACON_INFO.stable,
eventType = EventType.STATE_ROOM_BEACON_INFO.unstable,
body = updatedContent
)
return try {

View File

@@ -16,37 +16,38 @@
package org.matrix.android.sdk.internal.session.room.relation.threads
import com.zhuinden.monarchy.Monarchy
import io.realm.RealmList
import org.matrix.android.sdk.api.session.room.model.RoomMemberContent
import org.matrix.android.sdk.api.session.room.threads.FetchThreadsResult
import org.matrix.android.sdk.api.session.room.threads.ThreadFilter
import org.matrix.android.sdk.api.session.room.threads.model.ThreadSummaryUpdateType
import org.matrix.android.sdk.internal.crypto.DefaultCryptoService
import org.matrix.android.sdk.internal.database.helper.createOrUpdate
import org.matrix.android.sdk.internal.database.model.RoomEntity
import org.matrix.android.sdk.internal.database.model.threads.ThreadListPageEntity
import org.matrix.android.sdk.internal.database.model.threads.ThreadSummaryEntity
import org.matrix.android.sdk.internal.database.query.getOrCreate
import org.matrix.android.sdk.internal.database.query.where
import org.matrix.android.sdk.internal.di.SessionDatabase
import org.matrix.android.sdk.internal.di.UserId
import org.matrix.android.sdk.internal.network.GlobalErrorReceiver
import org.matrix.android.sdk.internal.network.executeRequest
import org.matrix.android.sdk.internal.session.filter.FilterFactory
import org.matrix.android.sdk.internal.session.room.RoomAPI
import org.matrix.android.sdk.internal.session.room.timeline.PaginationDirection
import org.matrix.android.sdk.internal.session.room.timeline.PaginationResponse
import org.matrix.android.sdk.internal.task.Task
import org.matrix.android.sdk.internal.util.awaitTransaction
import org.matrix.android.sdk.internal.util.time.Clock
import timber.log.Timber
import javax.inject.Inject
/***
* This class is responsible to Fetch all the thread in the current room,
* To fetch all threads in a room, the /messages API is used with newly added filtering options.
*/
internal interface FetchThreadSummariesTask : Task<FetchThreadSummariesTask.Params, DefaultFetchThreadSummariesTask.Result> {
internal interface FetchThreadSummariesTask : Task<FetchThreadSummariesTask.Params, FetchThreadsResult> {
data class Params(
val roomId: String,
val from: String = "",
val limit: Int = 500,
val isUserParticipating: Boolean = true
val from: String? = null,
val limit: Int = 5,
val filter: ThreadFilter? = null,
)
}
@@ -59,39 +60,43 @@ internal class DefaultFetchThreadSummariesTask @Inject constructor(
private val clock: Clock,
) : FetchThreadSummariesTask {
override suspend fun execute(params: FetchThreadSummariesTask.Params): Result {
val filter = FilterFactory.createThreadsFilter(
numberOfEvents = params.limit,
userId = if (params.isUserParticipating) userId else null
).toJSONString()
val response = executeRequest(
globalErrorReceiver,
canRetry = true
) {
roomAPI.getRoomMessagesFrom(params.roomId, params.from, PaginationDirection.BACKWARDS.value, params.limit, filter)
override suspend fun execute(params: FetchThreadSummariesTask.Params): FetchThreadsResult {
val response = executeRequest(globalErrorReceiver) {
roomAPI.getThreadsList(
roomId = params.roomId,
include = params.filter?.toString()?.lowercase(),
from = params.from,
limit = params.limit
)
}
Timber.i("###THREADS DefaultFetchThreadSummariesTask Fetched size:${response.events.size} nextBatch:${response.end} ")
handleResponse(response, params)
return handleResponse(response, params)
return when {
response.nextBatch != null -> FetchThreadsResult.ShouldFetchMore(response.nextBatch)
else -> FetchThreadsResult.ReachedEnd
}
}
private suspend fun handleResponse(
response: PaginationResponse,
response: ThreadSummariesResponse,
params: FetchThreadSummariesTask.Params
): Result {
val rootThreadList = response.events
) {
val rootThreadList = response.chunk
val threadSummaries = RealmList<ThreadSummaryEntity>()
monarchy.awaitTransaction { realm ->
val roomEntity = RoomEntity.where(realm, roomId = params.roomId).findFirst() ?: return@awaitTransaction
val roomMemberContentsByUser = HashMap<String, RoomMemberContent?>()
for (rootThreadEvent in rootThreadList) {
if (rootThreadEvent.eventId == null || rootThreadEvent.senderId == null || rootThreadEvent.type == null) {
continue
}
ThreadSummaryEntity.createOrUpdate(
val threadSummary = ThreadSummaryEntity.createOrUpdate(
threadSummaryType = ThreadSummaryUpdateType.REPLACE,
realm = realm,
roomId = params.roomId,
@@ -102,14 +107,16 @@ internal class DefaultFetchThreadSummariesTask @Inject constructor(
cryptoService = cryptoService,
currentTimeMillis = clock.epochMillis(),
)
threadSummaries.add(threadSummary)
}
val page = ThreadListPageEntity.getOrCreate(realm, params.roomId)
threadSummaries.forEach {
if (!page.threadSummaries.contains(it)) {
page.threadSummaries.add(it)
}
}
}
return Result.SUCCESS
}
enum class Result {
SHOULD_FETCH_MORE,
REACHED_END,
SUCCESS
}
}

View File

@@ -0,0 +1,27 @@
/*
* Copyright 2022 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.room.relation.threads
import com.squareup.moshi.Json
import com.squareup.moshi.JsonClass
import org.matrix.android.sdk.api.session.events.model.Event
@JsonClass(generateAdapter = true)
internal data class ThreadSummariesResponse(
@Json(name = "chunk") val chunk: List<Event>,
@Json(name = "next_batch") val nextBatch: String?,
@Json(name = "prev_batch") val prevBatch: String?
)

View File

@@ -181,7 +181,7 @@ internal class LocalEchoEventFactory @Inject constructor(
originServerTs = dummyOriginServerTs(),
senderId = userId,
eventId = localId,
type = EventType.POLL_START.stable,
type = EventType.POLL_START.unstable,
content = newContent.toContent().plus(additionalContent.orEmpty())
)
}
@@ -206,7 +206,7 @@ internal class LocalEchoEventFactory @Inject constructor(
originServerTs = dummyOriginServerTs(),
senderId = userId,
eventId = localId,
type = EventType.POLL_RESPONSE.stable,
type = EventType.POLL_RESPONSE.unstable,
content = content.toContent().plus(additionalContent.orEmpty()),
unsignedData = UnsignedData(age = null, transactionId = localId)
)
@@ -226,7 +226,7 @@ internal class LocalEchoEventFactory @Inject constructor(
originServerTs = dummyOriginServerTs(),
senderId = userId,
eventId = localId,
type = EventType.POLL_START.stable,
type = EventType.POLL_START.unstable,
content = content.toContent().plus(additionalContent.orEmpty()),
unsignedData = UnsignedData(age = null, transactionId = localId)
)
@@ -249,7 +249,7 @@ internal class LocalEchoEventFactory @Inject constructor(
originServerTs = dummyOriginServerTs(),
senderId = userId,
eventId = localId,
type = EventType.POLL_END.stable,
type = EventType.POLL_END.unstable,
content = content.toContent().plus(additionalContent.orEmpty()),
unsignedData = UnsignedData(age = null, transactionId = localId)
)
@@ -300,7 +300,7 @@ internal class LocalEchoEventFactory @Inject constructor(
originServerTs = dummyOriginServerTs(),
senderId = userId,
eventId = localId,
type = EventType.BEACON_LOCATION_DATA.stable,
type = EventType.BEACON_LOCATION_DATA.unstable,
content = content.toContent().plus(additionalContent.orEmpty()),
unsignedData = UnsignedData(age = null, transactionId = localId)
)

View File

@@ -17,17 +17,23 @@
package org.matrix.android.sdk.internal.session.room.summary
import io.realm.Realm
import org.matrix.android.sdk.api.MatrixConfiguration
import org.matrix.android.sdk.api.session.room.summary.RoomSummaryConstants
import org.matrix.android.sdk.api.session.room.timeline.EventTypeFilter
import org.matrix.android.sdk.api.session.room.timeline.TimelineEventFilters
import org.matrix.android.sdk.internal.database.model.TimelineEventEntity
import org.matrix.android.sdk.internal.database.query.latestEvent
import javax.inject.Inject
internal object RoomSummaryEventsHelper {
internal class RoomSummaryEventsHelper @Inject constructor(
matrixConfiguration: MatrixConfiguration,
) {
private val previewFilters = TimelineEventFilters(
filterTypes = true,
allowedTypes = RoomSummaryConstants.PREVIEWABLE_TYPES.map { EventTypeFilter(eventType = it, stateKey = null) },
allowedTypes = RoomSummaryConstants.PREVIEWABLE_TYPES
.plus(matrixConfiguration.customEventTypesProvider?.customPreviewableEventTypes.orEmpty())
.map { EventTypeFilter(eventType = it, stateKey = null) },
filterUseless = true,
filterRedacted = false,
filterEdits = true

View File

@@ -78,12 +78,13 @@ internal class RoomSummaryUpdater @Inject constructor(
private val crossSigningService: DefaultCrossSigningService,
private val roomAccountDataDataSource: RoomAccountDataDataSource,
private val homeServerCapabilitiesService: HomeServerCapabilitiesService,
private val roomSummaryEventsHelper: RoomSummaryEventsHelper,
) {
fun refreshLatestPreviewContent(realm: Realm, roomId: String) {
val roomSummaryEntity = RoomSummaryEntity.getOrNull(realm, roomId)
if (roomSummaryEntity != null) {
val latestPreviewableEvent = RoomSummaryEventsHelper.getLatestPreviewableEvent(realm, roomId)
val latestPreviewableEvent = roomSummaryEventsHelper.getLatestPreviewableEvent(realm, roomId)
latestPreviewableEvent?.attemptToDecrypt()
}
}
@@ -145,7 +146,7 @@ internal class RoomSummaryUpdater @Inject constructor(
val encryptionEvent = CurrentStateEventEntity.getOrNull(realm, roomId, type = EventType.STATE_ROOM_ENCRYPTION, stateKey = "")?.root
Timber.d("## CRYPTO: currentEncryptionEvent is $encryptionEvent")
val latestPreviewableEvent = RoomSummaryEventsHelper.getLatestPreviewableEvent(realm, roomId)
val latestPreviewableEvent = roomSummaryEventsHelper.getLatestPreviewableEvent(realm, roomId)
val lastActivityFromEvent = latestPreviewableEvent?.root?.originServerTs
if (lastActivityFromEvent != null) {
@@ -231,7 +232,7 @@ internal class RoomSummaryUpdater @Inject constructor(
fun updateSendingInformation(realm: Realm, roomId: String) {
val roomSummaryEntity = RoomSummaryEntity.getOrCreate(realm, roomId)
roomSummaryEntity.updateHasFailedSending()
roomSummaryEntity.latestPreviewableEvent = RoomSummaryEventsHelper.getLatestPreviewableEvent(realm, roomId)
roomSummaryEntity.latestPreviewableEvent = roomSummaryEventsHelper.getLatestPreviewableEvent(realm, roomId)
}
/**

View File

@@ -16,32 +16,39 @@
package org.matrix.android.sdk.internal.session.room.threads
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.paging.LivePagedListBuilder
import androidx.paging.PagedList
import com.zhuinden.monarchy.Monarchy
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import io.realm.Realm
import io.realm.Sort
import io.realm.kotlin.where
import org.matrix.android.sdk.api.session.room.ResultBoundaries
import org.matrix.android.sdk.api.session.room.threads.FetchThreadsResult
import org.matrix.android.sdk.api.session.room.threads.ThreadFilter
import org.matrix.android.sdk.api.session.room.threads.ThreadLivePageResult
import org.matrix.android.sdk.api.session.room.threads.ThreadsService
import org.matrix.android.sdk.api.session.room.threads.model.ThreadSummary
import org.matrix.android.sdk.internal.database.helper.enhanceWithEditions
import org.matrix.android.sdk.internal.database.helper.findAllThreadsForRoomId
import org.matrix.android.sdk.internal.database.mapper.ThreadSummaryMapper
import org.matrix.android.sdk.internal.database.mapper.TimelineEventMapper
import org.matrix.android.sdk.internal.database.model.threads.ThreadListPageEntity
import org.matrix.android.sdk.internal.database.model.threads.ThreadSummaryEntity
import org.matrix.android.sdk.internal.database.model.threads.ThreadSummaryEntityFields
import org.matrix.android.sdk.internal.di.SessionDatabase
import org.matrix.android.sdk.internal.di.UserId
import org.matrix.android.sdk.internal.session.room.relation.threads.FetchThreadSummariesTask
import org.matrix.android.sdk.internal.session.room.relation.threads.FetchThreadTimelineTask
import org.matrix.android.sdk.internal.util.awaitTransaction
internal class DefaultThreadsService @AssistedInject constructor(
@Assisted private val roomId: String,
@UserId private val userId: String,
private val fetchThreadTimelineTask: FetchThreadTimelineTask,
private val fetchThreadSummariesTask: FetchThreadSummariesTask,
@SessionDatabase private val monarchy: Monarchy,
private val timelineEventMapper: TimelineEventMapper,
private val threadSummaryMapper: ThreadSummaryMapper
private val threadSummaryMapper: ThreadSummaryMapper,
private val fetchThreadSummariesTask: FetchThreadSummariesTask,
) : ThreadsService {
@AssistedFactory
@@ -49,16 +56,58 @@ internal class DefaultThreadsService @AssistedInject constructor(
fun create(roomId: String): DefaultThreadsService
}
override fun getAllThreadSummariesLive(): LiveData<List<ThreadSummary>> {
return monarchy.findAllMappedWithChanges(
{ ThreadSummaryEntity.findAllThreadsForRoomId(it, roomId = roomId) },
{
threadSummaryMapper.map(it)
override suspend fun getPagedThreadsList(userParticipating: Boolean, pagedListConfig: PagedList.Config): ThreadLivePageResult {
monarchy.awaitTransaction { realm ->
realm.where<ThreadListPageEntity>().findAll().deleteAllFromRealm()
}
val realmDataSourceFactory = monarchy.createDataSourceFactory { realm ->
realm
.where<ThreadSummaryEntity>().equalTo(ThreadSummaryEntityFields.PAGE.ROOM_ID, roomId)
.sort(ThreadSummaryEntityFields.LATEST_THREAD_EVENT_ENTITY.ORIGIN_SERVER_TS, Sort.DESCENDING)
}
val dataSourceFactory = realmDataSourceFactory.map {
threadSummaryMapper.map(it)
}
val boundaries = MutableLiveData(ResultBoundaries())
val builder = LivePagedListBuilder(dataSourceFactory, pagedListConfig).also {
it.setBoundaryCallback(object : PagedList.BoundaryCallback<ThreadSummary>() {
override fun onItemAtEndLoaded(itemAtEnd: ThreadSummary) {
boundaries.postValue(boundaries.value?.copy(endLoaded = true))
}
override fun onItemAtFrontLoaded(itemAtFront: ThreadSummary) {
boundaries.postValue(boundaries.value?.copy(frontLoaded = true))
}
override fun onZeroItemsLoaded() {
boundaries.postValue(boundaries.value?.copy(zeroItemLoaded = true))
}
})
}
val livePagedList = monarchy.findAllPagedWithChanges(
realmDataSourceFactory,
builder
)
return ThreadLivePageResult(livePagedList, boundaries)
}
override suspend fun fetchThreadList(nextBatchId: String?, limit: Int, filter: ThreadFilter): FetchThreadsResult {
return fetchThreadSummariesTask.execute(
FetchThreadSummariesTask.Params(
roomId = roomId,
from = nextBatchId,
limit = limit,
filter = filter
)
)
}
override fun getAllThreadSummaries(): List<ThreadSummary> {
override suspend fun getAllThreadSummaries(): List<ThreadSummary> {
return monarchy.fetchAllMappedSync(
{ ThreadSummaryEntity.findAllThreadsForRoomId(it, roomId = roomId) },
{ threadSummaryMapper.map(it) }
@@ -81,12 +130,4 @@ internal class DefaultThreadsService @AssistedInject constructor(
)
)
}
override suspend fun fetchThreadSummaries() {
fetchThreadSummariesTask.execute(
FetchThreadSummariesTask.Params(
roomId = roomId
)
)
}
}

View File

@@ -29,6 +29,7 @@ import org.matrix.android.sdk.api.session.room.model.message.MessageContent
import org.matrix.android.sdk.api.session.sync.model.SyncResponse
import org.matrix.android.sdk.api.session.sync.model.ToDeviceSyncResponse
import org.matrix.android.sdk.internal.crypto.DefaultCryptoService
import org.matrix.android.sdk.internal.crypto.tasks.toDeviceTracingId
import org.matrix.android.sdk.internal.crypto.verification.DefaultVerificationService
import org.matrix.android.sdk.internal.session.sync.ProgressReporter
import timber.log.Timber
@@ -48,12 +49,14 @@ internal class CryptoSyncHandler @Inject constructor(
?.forEachIndexed { index, event ->
progressReporter?.reportProgress(index * 100F / total)
// Decrypt event if necessary
Timber.tag(loggerTag.value).i("To device event from ${event.senderId} of type:${event.type}")
Timber.tag(loggerTag.value).d("To device event msgid:${event.toDeviceTracingId()}")
decryptToDeviceEvent(event, null)
if (event.getClearType() == EventType.MESSAGE &&
event.getClearContent()?.toModel<MessageContent>()?.msgType == "m.bad.encrypted") {
Timber.tag(loggerTag.value).e("handleToDeviceEvent() : Warning: Unable to decrypt to-device event : ${event.content}")
} else {
Timber.tag(loggerTag.value).d("received to-device ${event.getClearType()} from:${event.senderId} msgid:${event.toDeviceTracingId()}")
verificationService.onToDeviceEvent(event)
cryptoService.onToDeviceEvent(event)
}

View File

@@ -45,6 +45,7 @@ import org.matrix.android.sdk.internal.database.model.TimelineEventEntity
import org.matrix.android.sdk.internal.database.model.UserAccountDataEntity
import org.matrix.android.sdk.internal.database.model.UserAccountDataEntityFields
import org.matrix.android.sdk.internal.database.model.deleteOnCascade
import org.matrix.android.sdk.internal.database.query.delete
import org.matrix.android.sdk.internal.database.query.findAllFrom
import org.matrix.android.sdk.internal.database.query.getDirectRooms
import org.matrix.android.sdk.internal.database.query.getOrCreate
@@ -94,7 +95,7 @@ internal class UserAccountDataSyncHandler @Inject constructor(
// If we get some direct chat invites, we synchronize the user account data including those.
suspend fun synchronizeWithServerIfNeeded(invites: Map<String, InvitedRoomSync>) {
if (invites.isNullOrEmpty()) return
if (invites.isEmpty()) return
val directChats = directChatsHelper.getLocalDirectMessages().toMutable()
var hasUpdate = false
monarchy.doWithRealm { realm ->
@@ -252,9 +253,17 @@ internal class UserAccountDataSyncHandler @Inject constructor(
}
fun handleGenericAccountData(realm: Realm, type: String, content: Content?) {
if (content.isNullOrEmpty()) {
// This is a response for a deleted account data according to
// https://github.com/ShadowJonathan/matrix-doc/blob/account-data-delete/proposals/3391-account-data-delete.md#sync
UserAccountDataEntity.delete(realm, type)
return
}
val existing = realm.where<UserAccountDataEntity>()
.equalTo(UserAccountDataEntityFields.TYPE, type)
.findFirst()
if (existing != null) {
// Update current value
existing.contentStr = ContentMapper.map(content)

View File

@@ -27,6 +27,7 @@ import org.matrix.android.sdk.internal.database.model.RoomAccountDataEntity
import org.matrix.android.sdk.internal.database.model.RoomAccountDataEntityFields
import org.matrix.android.sdk.internal.database.model.RoomEntity
import org.matrix.android.sdk.internal.database.query.getOrCreate
import org.matrix.android.sdk.internal.database.query.removeAccountData
import org.matrix.android.sdk.internal.session.room.read.FullyReadContent
import org.matrix.android.sdk.internal.session.sync.handler.room.RoomFullyReadHandler
import org.matrix.android.sdk.internal.session.sync.handler.room.RoomTagHandler
@@ -56,6 +57,13 @@ internal class RoomSyncAccountDataHandler @Inject constructor(
}
private fun handleGeneric(roomEntity: RoomEntity, content: JsonDict?, eventType: String) {
if (content.isNullOrEmpty()) {
// This is a response for a deleted account data according to
// https://github.com/ShadowJonathan/matrix-doc/blob/account-data-delete/proposals/3391-account-data-delete.md#sync
roomEntity.removeAccountData(eventType)
return
}
val existing = roomEntity.accountData.where().equalTo(RoomAccountDataEntityFields.TYPE, eventType).findFirst()
if (existing != null) {
existing.contentStr = ContentMapper.map(content)

View File

@@ -18,13 +18,14 @@ package org.matrix.android.sdk.internal.session.user.accountdata
import org.matrix.android.sdk.internal.network.NetworkConstants
import retrofit2.http.Body
import retrofit2.http.DELETE
import retrofit2.http.PUT
import retrofit2.http.Path
internal interface AccountDataAPI {
/**
* Set some account_data for the client.
* Set some account_data for the user.
*
* @param userId the user id
* @param type the type
@@ -36,4 +37,16 @@ internal interface AccountDataAPI {
@Path("type") type: String,
@Body params: Any
)
/**
* Remove an account_data for the user.
*
* @param userId the user id
* @param type the type
*/
@DELETE(NetworkConstants.URI_API_PREFIX_PATH_UNSTABLE + "org.matrix.msc3391/user/{userId}/account_data/{type}")
suspend fun deleteAccountData(
@Path("userId") userId: String,
@Path("type") type: String
)
}

View File

@@ -42,4 +42,7 @@ internal abstract class AccountDataModule {
@Binds
abstract fun bindUpdateBreadcrumbsTask(task: DefaultUpdateBreadcrumbsTask): UpdateBreadcrumbsTask
@Binds
abstract fun bindDeleteUserAccountDataTask(task: DefaultDeleteUserAccountDataTask): DeleteUserAccountDataTask
}

View File

@@ -34,10 +34,11 @@ import javax.inject.Inject
internal class DefaultSessionAccountDataService @Inject constructor(
@SessionDatabase private val monarchy: Monarchy,
private val updateUserAccountDataTask: UpdateUserAccountDataTask,
private val deleteUserAccountDataTask: DeleteUserAccountDataTask,
private val userAccountDataSyncHandler: UserAccountDataSyncHandler,
private val userAccountDataDataSource: UserAccountDataDataSource,
private val roomAccountDataDataSource: RoomAccountDataDataSource,
private val taskExecutor: TaskExecutor
private val taskExecutor: TaskExecutor,
) : SessionAccountDataService {
override fun getUserAccountDataEvent(type: String): UserAccountDataEvent? {
@@ -78,4 +79,12 @@ internal class DefaultSessionAccountDataService @Inject constructor(
userAccountDataSyncHandler.handleGenericAccountData(realm, type, content)
}
}
override fun getUserAccountDataEventsStartWith(type: String): List<UserAccountDataEvent> {
return userAccountDataDataSource.getAccountDataEventsStartWith(type)
}
override suspend fun deleteUserAccountData(type: String) {
deleteUserAccountDataTask.execute(DeleteUserAccountDataTask.Params(type))
}
}

View File

@@ -0,0 +1,43 @@
/*
* Copyright 2022 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.user.accountdata
import org.matrix.android.sdk.internal.di.UserId
import org.matrix.android.sdk.internal.network.GlobalErrorReceiver
import org.matrix.android.sdk.internal.network.executeRequest
import org.matrix.android.sdk.internal.task.Task
import javax.inject.Inject
internal interface DeleteUserAccountDataTask : Task<DeleteUserAccountDataTask.Params, Unit> {
data class Params(
val type: String,
)
}
internal class DefaultDeleteUserAccountDataTask @Inject constructor(
private val accountDataApi: AccountDataAPI,
@UserId private val userId: String,
private val globalErrorReceiver: GlobalErrorReceiver,
) : DeleteUserAccountDataTask {
override suspend fun execute(params: DeleteUserAccountDataTask.Params) {
return executeRequest(globalErrorReceiver) {
accountDataApi.deleteAccountData(userId, params.type)
}
}
}

View File

@@ -60,6 +60,16 @@ internal class UserAccountDataDataSource @Inject constructor(
)
}
fun getAccountDataEventsStartWith(type: String): List<UserAccountDataEvent> {
return realmSessionProvider.withRealm { realm ->
realm
.where(UserAccountDataEntity::class.java)
.beginsWith(UserAccountDataEntityFields.TYPE, type)
.findAll()
.map(accountDataMapper::map)
}
}
private fun accountDataEventsQuery(realm: Realm, types: Set<String>): RealmQuery<UserAccountDataEntity> {
val query = realm.where(UserAccountDataEntity::class.java)
if (types.isNotEmpty()) {

View File

@@ -0,0 +1,255 @@
/*
* Copyright 2022 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.crypto
import io.mockk.mockk
import kotlinx.coroutines.runBlocking
import org.amshove.kluent.internal.assertEquals
import org.junit.Assert
import org.junit.Test
import org.matrix.android.sdk.api.session.crypto.model.DeviceInfo
import org.matrix.android.sdk.api.session.crypto.model.DevicesListResponse
import org.matrix.android.sdk.api.session.crypto.model.MXUsersDevicesMap
import org.matrix.android.sdk.api.session.events.model.EventType
import org.matrix.android.sdk.api.session.room.model.message.MessageType
import org.matrix.android.sdk.internal.crypto.api.CryptoApi
import org.matrix.android.sdk.internal.crypto.model.rest.DeleteDeviceParams
import org.matrix.android.sdk.internal.crypto.model.rest.DeleteDevicesParams
import org.matrix.android.sdk.internal.crypto.model.rest.KeyChangesResponse
import org.matrix.android.sdk.internal.crypto.model.rest.KeysClaimBody
import org.matrix.android.sdk.internal.crypto.model.rest.KeysClaimResponse
import org.matrix.android.sdk.internal.crypto.model.rest.KeysQueryBody
import org.matrix.android.sdk.internal.crypto.model.rest.KeysQueryResponse
import org.matrix.android.sdk.internal.crypto.model.rest.KeysUploadBody
import org.matrix.android.sdk.internal.crypto.model.rest.KeysUploadResponse
import org.matrix.android.sdk.internal.crypto.model.rest.SendToDeviceBody
import org.matrix.android.sdk.internal.crypto.model.rest.SignatureUploadResponse
import org.matrix.android.sdk.internal.crypto.model.rest.UpdateDeviceInfoBody
import org.matrix.android.sdk.internal.crypto.model.rest.UploadSigningKeysBody
import org.matrix.android.sdk.internal.crypto.tasks.DefaultSendToDeviceTask
import org.matrix.android.sdk.internal.crypto.tasks.SendToDeviceTask
class DefaultSendToDeviceTaskTest {
private val users = listOf(
"@alice:example.com" to listOf("D0", "D1"),
"bob@example.com" to listOf("D2", "D3")
)
private val fakeEncryptedContent = mapOf(
"algorithm" to "m.olm.v1.curve25519-aes-sha2",
"sender_key" to "gMObR+/4dqL5T4DisRRRYBJpn+OjzFnkyCFOktP6Eyw",
"ciphertext" to mapOf(
"tdwXf7006FDgzmufMCVI4rDdVPO51ecRTTT6HkRxUwE" to mapOf(
"type" to 0,
"body" to "AwogCA1ULEc0abGIFxMDIC9iv7ul3jqJSnapTHQ+8JJx"
)
)
)
private val fakeStartVerificationContent = mapOf(
"method" to "m.sas.v1",
"from_device" to "MNQHVEISFQ",
"key_agreement_protocols" to listOf(
"curve25519-hkdf-sha256",
"curve25519"
),
"hashes" to listOf("sha256"),
"message_authentication_codes" to listOf(
"org.matrix.msc3783.hkdf-hmac-sha256",
"hkdf-hmac-sha256",
"hmac-sha256"
),
"short_authentication_string" to listOf(
"decimal",
"emoji"
),
"transaction_id" to "4wNOpkHGwGZPXjkZToooCDWfb8hsf7vW"
)
@Test
fun `tracing id should be added to to_device contents`() {
val fakeCryptoAPi = FakeCryptoApi()
val sendToDeviceTask = DefaultSendToDeviceTask(
cryptoApi = fakeCryptoAPi,
globalErrorReceiver = mockk(relaxed = true)
)
val contentMap = MXUsersDevicesMap<Any>()
users.forEach { pairOfUserDevices ->
val userId = pairOfUserDevices.first
pairOfUserDevices.second.forEach {
contentMap.setObject(userId, it, fakeEncryptedContent)
}
}
val params = SendToDeviceTask.Params(
eventType = EventType.ENCRYPTED,
contentMap = contentMap
)
runBlocking {
sendToDeviceTask.execute(params)
}
val generatedIds = mutableListOf<String>()
users.forEach { pairOfUserDevices ->
val userId = pairOfUserDevices.first
pairOfUserDevices.second.forEach {
val modifiedContent = fakeCryptoAPi.body!!.messages!![userId]!![it] as Map<*, *>
Assert.assertNotNull("Tracing id should have been added", modifiedContent["org.matrix.msgid"])
generatedIds.add(modifiedContent["org.matrix.msgid"] as String)
assertEquals(
"The rest of the content should be the same",
fakeEncryptedContent.keys,
modifiedContent.toMutableMap().apply { remove("org.matrix.msgid") }.keys
)
}
}
assertEquals("Id should be unique per content", generatedIds.size, generatedIds.toSet().size)
println("modified content ${fakeCryptoAPi.body}")
}
@Test
fun `tracing id should not be added to verification start to_device contents`() {
val fakeCryptoAPi = FakeCryptoApi()
val sendToDeviceTask = DefaultSendToDeviceTask(
cryptoApi = fakeCryptoAPi,
globalErrorReceiver = mockk(relaxed = true)
)
val contentMap = MXUsersDevicesMap<Any>()
contentMap.setObject("@alice:example.com", "MNQHVEISFQ", fakeStartVerificationContent)
val params = SendToDeviceTask.Params(
eventType = EventType.KEY_VERIFICATION_START,
contentMap = contentMap
)
runBlocking {
sendToDeviceTask.execute(params)
}
val modifiedContent = fakeCryptoAPi.body!!.messages!!["@alice:example.com"]!!["MNQHVEISFQ"] as Map<*, *>
Assert.assertNull("Tracing id should not have been added", modifiedContent["org.matrix.msgid"])
// try to force
runBlocking {
sendToDeviceTask.execute(
SendToDeviceTask.Params(
eventType = EventType.KEY_VERIFICATION_START,
contentMap = contentMap,
addTracingIds = true
)
)
}
val modifiedContentForced = fakeCryptoAPi.body!!.messages!!["@alice:example.com"]!!["MNQHVEISFQ"] as Map<*, *>
Assert.assertNotNull("Tracing id should have been added", modifiedContentForced["org.matrix.msgid"])
}
@Test
fun `tracing id should not be added to all verification to_device contents`() {
val fakeCryptoAPi = FakeCryptoApi()
val sendToDeviceTask = DefaultSendToDeviceTask(
cryptoApi = fakeCryptoAPi,
globalErrorReceiver = mockk(relaxed = true)
)
val contentMap = MXUsersDevicesMap<Any>()
contentMap.setObject("@alice:example.com", "MNQHVEISFQ", emptyMap<String, Any>())
val verificationEvents = listOf(
MessageType.MSGTYPE_VERIFICATION_REQUEST,
EventType.KEY_VERIFICATION_START,
EventType.KEY_VERIFICATION_ACCEPT,
EventType.KEY_VERIFICATION_KEY,
EventType.KEY_VERIFICATION_MAC,
EventType.KEY_VERIFICATION_CANCEL,
EventType.KEY_VERIFICATION_DONE,
EventType.KEY_VERIFICATION_READY
)
for (type in verificationEvents) {
val params = SendToDeviceTask.Params(
eventType = type,
contentMap = contentMap
)
runBlocking {
sendToDeviceTask.execute(params)
}
val modifiedContent = fakeCryptoAPi.body!!.messages!!["@alice:example.com"]!!["MNQHVEISFQ"] as Map<*, *>
Assert.assertNull("Tracing id should not have been added", modifiedContent["org.matrix.msgid"])
}
}
internal class FakeCryptoApi : CryptoApi {
override suspend fun getDevices(): DevicesListResponse {
throw java.lang.AssertionError("Should not be called")
}
override suspend fun getDeviceInfo(deviceId: String): DeviceInfo {
throw java.lang.AssertionError("Should not be called")
}
override suspend fun uploadKeys(body: KeysUploadBody): KeysUploadResponse {
throw java.lang.AssertionError("Should not be called")
}
override suspend fun downloadKeysForUsers(params: KeysQueryBody): KeysQueryResponse {
throw java.lang.AssertionError("Should not be called")
}
override suspend fun uploadSigningKeys(params: UploadSigningKeysBody): KeysQueryResponse {
throw java.lang.AssertionError("Should not be called")
}
override suspend fun uploadSignatures(params: Map<String, Any>?): SignatureUploadResponse {
throw java.lang.AssertionError("Should not be called")
}
override suspend fun claimOneTimeKeysForUsersDevices(body: KeysClaimBody): KeysClaimResponse {
throw java.lang.AssertionError("Should not be called")
}
var body: SendToDeviceBody? = null
override suspend fun sendToDevice(eventType: String, transactionId: String, body: SendToDeviceBody) {
this.body = body
}
override suspend fun deleteDevice(deviceId: String, params: DeleteDeviceParams) {
throw java.lang.AssertionError("Should not be called")
}
override suspend fun deleteDevices(params: DeleteDevicesParams) {
throw java.lang.AssertionError("Should not be called")
}
override suspend fun updateDeviceInfo(deviceId: String, params: UpdateDeviceInfoBody) {
throw java.lang.AssertionError("Should not be called")
}
override suspend fun getKeyChanges(oldToken: String, newToken: String): KeyChangesResponse {
throw java.lang.AssertionError("Should not be called")
}
}
}

View File

@@ -47,7 +47,7 @@ import org.matrix.android.sdk.test.fakes.FakeRealm
import org.matrix.android.sdk.test.fakes.givenEqualTo
import org.matrix.android.sdk.test.fakes.givenFindFirst
class PollAggregationProcessorTest {
class DefaultPollAggregationProcessorTest {
private val pollAggregationProcessor: PollAggregationProcessor = DefaultPollAggregationProcessor()
private val realm = FakeRealm()

View File

@@ -87,7 +87,7 @@ object PollEventsTestData {
)
internal val A_POLL_START_EVENT = Event(
type = EventType.POLL_START.stable,
type = EventType.POLL_START.unstable,
eventId = AN_EVENT_ID,
originServerTs = 1652435922563,
senderId = A_USER_ID_1,
@@ -96,7 +96,7 @@ object PollEventsTestData {
)
internal val A_POLL_RESPONSE_EVENT = Event(
type = EventType.POLL_RESPONSE.stable,
type = EventType.POLL_RESPONSE.unstable,
eventId = AN_EVENT_ID,
originServerTs = 1652435922563,
senderId = A_USER_ID_1,
@@ -105,7 +105,7 @@ object PollEventsTestData {
)
internal val A_POLL_END_EVENT = Event(
type = EventType.POLL_END.stable,
type = EventType.POLL_END.unstable,
eventId = AN_EVENT_ID,
originServerTs = 1652435922563,
senderId = A_USER_ID_1,

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