Compare commits

...
Sign in to create a new pull request.

436 commits
wallet ... main

Author SHA1 Message Date
Jorge Martin Espinosa
87b3a5d2f0
Add better logs to track token update failures (#6859)
1. Make some logs use `info` log level instead of `debug`, so they appear in most user's bug reports.
2. Make the anonymized tokens even harder to reverse.
3. Detect when the tokens we should be saving match the current ones, as that's an error.
2026-05-26 12:19:26 +02:00
Jorge Martin Espinosa
1e67c2f77b
Move empty day separator filtering to a timeline post-processor (#6866)
* Move empty day separator filtering to a timeline post-processor

* Split `FilterPublicMembershipChangesPostProcessor` from `RoomBeginningPostProcessor`
2026-05-26 08:28:32 +00:00
Jorge Martin Espinosa
0e2213a199
Fix public read receipts being sent by mistake (#6838)
When returning to the chat screen from the room details one or a member's profile, `TimelineEvent.OnScrollFinished` will be called immediately, and this would read the default value for `isSendPublicReadReceiptsEnabled`, which is `true`.

If you had public read receipts disabled, this is a mistake, and would send a public read receipt. Instead, what we want to do is wait until the updated value is emitted and use it to decide whether we want to send a public or private read receipt.
2026-05-26 10:10:42 +02:00
Benoit Marty
1f3d848c79
Image edition before sending: crop and rotate. (#6842)
* Add crop and rotate editing before sending images (#6363)

* feat(messages): add crop and rotate before image upload

* Update screenshots

* chore: trigger CI after screenshot update

* fix: resolve detekt violations in image editor and media viewer modules

* fix: require explicit edits param, use plurals for rotation a11y, remove redundant @Inject

* fix: require explicit edits param, use plurals for rotation a11y, remove redundant @Inject

* fix: use semantically correct RotateRight icon for image rotation action

* Update screenshots

* chore: trigger CI after screenshot update

---------

Co-authored-by: ElementBot <android@element.io>
Co-authored-by: Benoit Marty <benoitm@element.io>

* Update design and UX

Update and add tests
Improve preview

* Update screenshots

* For quality issue and improve preview

* Update screenshots

* Remove default value of data class.

* Rename file.

* Fix tests.

* Allow detecting touch events outside the image by applying the drag detection to the parent node and offsetting the touch events

* Improve touch detection.

* Update screenshots

* Remove useless line.

---------

Co-authored-by: Gianluca Iavicoli <gianluca.iavicoli04@gmail.com>
Co-authored-by: ElementBot <android@element.io>
Co-authored-by: Jorge Martín <jorgem@element.io>
2026-05-26 10:07:05 +02:00
ElementBot
0aaa80cbdc
Sync Strings from Localazy (#6856)
Co-authored-by: bmarty <3940906+bmarty@users.noreply.github.com>
2026-05-26 08:05:07 +00:00
Jorge Martin Espinosa
7b93bfbba9
Use runBlocking for the token refresh logic (#6863)
* Use `runBlocking` for the token refresh logic

The `RustClientSessionDelegate` callbacks always run in a separate thread, so they don't block the main thread.

This ensures the token refresh is fully done (data saved/failed to) before the SDK continues sending the pending previously failed requests
2026-05-26 09:40:07 +02:00
Benoit Marty
6cef5cec1b Remove useless line. 2026-05-26 09:22:43 +02:00
renovate[bot]
f447560665
Update codecov/codecov-action action to v6.0.1 (#6864)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-26 07:59:33 +02:00
ElementBot
1f6824d285 Update screenshots 2026-05-25 19:34:34 +00:00
Benoit Marty
8a4ff4c456 Improve touch detection. 2026-05-25 21:16:12 +02:00
bxdxnn
3df85017af
Fix formatting inconsistencies in latest event summaries (#6855)
* Fix message type prefixes formatting inconsistencies

* Use new string for the poll summary prefix instead of the A11y text. Also add tests check for the bold spans.

---------

Co-authored-by: Jorge Martín <jorgem@element.io>
2026-05-25 11:40:25 +02:00
bxdxnn
b31dad4b26
Do not show membership/profile events in public rooms (#6360)
* Filter some membership/profile/topic events in public rooms: don't display join and leave membership events in publicly joinable rooms, and hide display name and avatar url changes in non encrypted and publicly joinable rooms.

* Add empty day post-processing to the timeline based on bxdxnn's code, tweaked.

---------

Co-authored-by: Jorge Martín <jorgem@element.io>
2026-05-25 10:31:53 +02:00
Jorge Martín
6e74446209 Allow detecting touch events outside the image by applying the drag detection to the parent node and offsetting the touch events 2026-05-22 16:57:00 +02:00
Benoit Marty
afa2a824b5 Fix tests. 2026-05-22 15:28:48 +02:00
Benoit Marty
94c3bb9c41 Rename file. 2026-05-22 13:59:21 +02:00
Benoit Marty
fe6a17e977 Remove default value of data class. 2026-05-22 13:56:50 +02:00
ElementBot
4876b7c930 Update screenshots 2026-05-22 10:29:31 +00:00
Benoit Marty
a158da1d18 For quality issue and improve preview 2026-05-22 12:13:09 +02:00
ElementBot
aa92bb61c1 Update screenshots 2026-05-22 08:45:58 +00:00
Benoit Marty
bb2779549e Update design and UX
Update and add tests
Improve preview
2026-05-22 10:29:36 +02:00
renovate[bot]
5277382e6d
Update dependencyAnalysis to v3.12.0 (#6840)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-22 07:57:00 +02:00
Gianluca Iavicoli
bcad1f9dce Add crop and rotate editing before sending images (#6363)
* feat(messages): add crop and rotate before image upload

* Update screenshots

* chore: trigger CI after screenshot update

* fix: resolve detekt violations in image editor and media viewer modules

* fix: require explicit edits param, use plurals for rotation a11y, remove redundant @Inject

* fix: require explicit edits param, use plurals for rotation a11y, remove redundant @Inject

* fix: use semantically correct RotateRight icon for image rotation action

* Update screenshots

* chore: trigger CI after screenshot update

---------

Co-authored-by: ElementBot <android@element.io>
Co-authored-by: Benoit Marty <benoitm@element.io>
2026-05-21 15:18:40 +02:00
renovate[bot]
00efd9a01c
Update peaceiris/actions-gh-pages action to v4.1.0 (#6820)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-21 15:01:35 +02:00
renovate[bot]
d6ef505260
Merge pull request #6816 from element-hq/renovate/media3
Update media3 to v1.10.1
2026-05-21 15:01:00 +02:00
renovate[bot]
7e42dd1529
Update dependency org.matrix.rustcomponents:sdk-android to v26.05.20 (#6831)
* Update dependency org.matrix.rustcomponents:sdk-android to v26.05.20

* Fix API breaks:

- Handle new `ClientBuildException.InvalidRawKey` variant.
- `RoomInfo` now has a `fullyReadEventId` .

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Jorge Martín <jorgem@element.io>
2026-05-21 12:27:29 +02:00
Benoit Marty
989201eb68
Merge pull request #6705 from bxdxnn/misc/roommembermoderation-avatar-tap
Make the avatar in the room member moderation bottom sheet clickable
2026-05-21 11:59:28 +02:00
Benoit Marty
5be14df828
Merge pull request #6822 from element-hq/renovate/kotlin
Update kotlin to v2.3.8
2026-05-21 10:56:54 +02:00
Benoit Marty
88a90aeb5a
Merge pull request #6833 from element-hq/renovate/io.element.android-element-call-embedded-0.x
Update dependency io.element.android:element-call-embedded to v0.19.4
2026-05-21 10:55:48 +02:00
Benoit Marty
4526563668
Merge pull request #6817 from element-hq/feature/bma/automaticRetry
[Link new device] Rotate QrCode instead of showing an error
2026-05-21 10:29:29 +02:00
renovate[bot]
4607681c5f
Update dependency io.element.android:element-call-embedded to v0.19.4 2026-05-21 08:15:40 +00:00
renovate[bot]
eed183be53
Update metro to v1.1.1 (#6832)
* Update metro to v1.1.1

* Fix `@ContributesBinding` usage with `@AssistedInject` in `DefaultVideoMetadataExtractor`

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Jorge Martín <jorgem@element.io>
2026-05-21 10:10:13 +02:00
Benoit Marty
b4f23d9d9e Fix wrong 'modifier' usage. 2026-05-21 09:14:18 +02:00
Benoit Marty
19397b6fa7 Fix warning 2026-05-21 09:10:43 +02:00
Benoit Marty
dea808ce8d
Merge pull request #6818 from element-hq/feature/bma/markAsUnreadInRoomDetails
Add mark as read / unread in room details
2026-05-21 09:01:52 +02:00
Benoit Marty
c3a4d64ec6
Merge pull request #6827 from element-hq/feature/bma/a11y/roomNameHeading
[a11y] Improve accessibility of screen headers.
2026-05-21 09:00:33 +02:00
Benoit Marty
0c3c9f48bb
Merge pull request #6830 from element-hq/feature/bma/a11y/videoPlayer
[a11y] Improve accessibility of video and audio player
2026-05-20 18:06:04 +02:00
Benoit Marty
44df2d2c17 [a11y] Improve accessibility of media controller 2026-05-20 17:23:30 +02:00
cizra
a33d717aa0
Don't compress images sent through the Files attachment picker (#6755)
* Don't compress images sent through the Files attachment picker

Images and videos picked through the "Attachment" picker are now
uploaded without re-encoding, regardless of the "Optimize media quality"
setting. The gallery and camera pickers keep the existing behaviour,
matching what Element Web/Desktop and most other messengers do.

Fixes #6365

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Make sure we select the right video preset for sending as file

Wait for the video size estimations to be calculated before preprocessing the video file

---------

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Jorge Martín <jorgem@element.io>
2026-05-20 17:19:08 +02:00
ganfra
933b18f6c2
Merge pull request #6813 from element-hq/renovate/dependencyanalysis
Update dependencyAnalysis to v3.11.0
2026-05-20 17:09:13 +02:00
Benoit Marty
4641ae666e [a11y] Improve accessibility of media controller 2026-05-20 17:04:24 +02:00
Benoit Marty
bd01b27517 [a11y] Ensure that video overlay with controls is never hidden when screen reader is enabled. 2026-05-20 16:21:06 +02:00
Benoit Marty
0725c16471
Merge pull request #6826 from element-hq/feature/bma/a11y/avatarEdit
Hide edit pencil from accessibility
2026-05-20 15:58:05 +02:00
Benoit Marty
df9a3fe9c2 [a11y] Improve accessibility of screen headers. 2026-05-20 15:53:08 +02:00
Benoit Marty
c2e357cbcd [a11y] Improve accessibility of screen headers. 2026-05-20 15:52:46 +02:00
Benoit Marty
5b2970f789 [a11y] Improve accessibility of screen headers. 2026-05-20 15:49:18 +02:00
Benoit Marty
620f1865e8 [a11y] Improve accessibility of screen headers. 2026-05-20 15:39:11 +02:00
Jorge Martin Espinosa
42566b4b1f
Release proximity wakelock on Element Call when call ends (#6825)
The `CoroutineScope` that launched this logic was cancelled by that point, so the wakelock was never released.
2026-05-20 15:23:03 +02:00
Benoit Marty
67c668990e Hide edit pencil from accessibility
Closes #6378
2026-05-20 14:50:26 +02:00
ElementBot
260ea4a7d2 Update screenshots 2026-05-20 12:44:42 +00:00
Benoit Marty
3d85cf4fd2 Format 2026-05-20 14:27:38 +02:00
Jorge Martin Espinosa
64d9336901
Fix 'Conversation label cannot be empty' error (#6823)
This happens when building a `ShortcutInfoCompat` in `DefaultNotificationConversationService.onSendMessage` when the provided room name is not null but it's empty.
2026-05-20 14:26:44 +02:00
Jorge Martin Espinosa
42c141109f
Fix media viewer flickering (#6800)
* Fix media viewer flickering

This was caused by the data being loaded triggering an index update that got out of sync with the displayed items, and for an instant, the pager index pointed to the wrong data until it was refreshed

* Reuse the same 'displayer' function for both forwards and backwards pagination

* Make `dataFlow` a property so we don't create a new instance every time we access it

* Remove `pageDataComparator` as it prevented new items from being loaded when a pagination returned no valid items to display but has more items to load

Make sure we modify the current index when loading new data only if it was pointing to the input event id.

* Fix `MediaViewerDataSource` overriding the provided timestamp for `Loading` items

Test emitting different loading items from the data source results in the state displaying the different items, so they will trigger a new pagination attempt

* Add regression test to check loading -> error -> loading states will still trigger 2 separate `LoadMore` events
2026-05-20 11:32:32 +02:00
renovate[bot]
94392f3ebd
Update kotlin to v2.3.8 2026-05-20 09:16:18 +00:00
Benoit Marty
dc05388cca Update tests. 2026-05-20 10:53:50 +02:00
ganfra
52f12031c8
Merge pull request #6819 from element-hq/renovate/net.zetetic-sqlcipher-android-4.x
Update dependency net.zetetic:sqlcipher-android to v4.16.0
2026-05-19 21:15:19 +02:00
Benoit Marty
5dd897dae8 Use AnimatedContent instead of reinventing the wheel. 2026-05-19 19:00:58 +02:00
ElementBot
900b888044 Update screenshots 2026-05-19 18:43:48 +02:00
Benoit Marty
1473f5e806 [Link new device] and add tests. 2026-05-19 18:43:48 +02:00
Benoit Marty
33c7c75550 Fix detekt issue 2026-05-19 18:43:47 +02:00
Benoit Marty
75feaa7ee7 [Link new device] Fix and add tests. 2026-05-19 18:43:47 +02:00
Benoit Marty
18bc6a27c4 [Link new device] Improve UI transition between QRCodes. 2026-05-19 18:43:46 +02:00
Benoit Marty
a6f7c05458 [Link new device] Automatically rotate the QR Code - limit number of rotation to 10. 2026-05-19 18:43:46 +02:00
Benoit Marty
c59b96de66 [Link new device] Automatically rotate the QR Code 2026-05-19 18:43:45 +02:00
renovate[bot]
2248cd20f3
Update dependency net.zetetic:sqlcipher-android to v4.16.0 2026-05-19 16:39:00 +00:00
Benoit Marty
53fe12bdda "Mark as unread" navigate back to the room list.
#6398
2026-05-19 18:37:32 +02:00
Benoit Marty
882d5577a7 Add "Mark as read", "Mark as unread" in room settings.
#6398
2026-05-19 18:06:11 +02:00
Benoit Marty
5af57906b5 Changelog for version 26.05.2 2026-05-19 15:23:47 +02:00
Benoit Marty
28d4985435 Merge tag 'v26.05.2' into develop
tag
2026-05-19 14:44:13 +02:00
Benoit Marty
20d0d115d4 Merge branch 'release/26.05.2' 2026-05-19 14:44:04 +02:00
Benoit Marty
d8793ca8f6 Adding fastlane file for version 26.05.2 2026-05-19 14:44:02 +02:00
Benoit Marty
f373c73e60 Setting version for the release 26.05.2 2026-05-19 14:43:49 +02:00
renovate[bot]
2f406eaf41
Update dependency org.matrix.rustcomponents:sdk-android to v26.05.18 (#6805)
* Update dependency org.matrix.rustcomponents:sdk-android to v26.05.18

* Fix breaking API changes

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Jorge Martín <jorgem@element.io>
2026-05-19 09:20:06 +02:00
renovate[bot]
c94ba068ed
Update dependencyAnalysis to v3.11.0 2026-05-19 07:18:13 +00:00
ganfra
6cc2e59436
Merge pull request #6811 from element-hq/feature/live_location_remove_feature_flag
Remove LiveLocationSharing feature flag
2026-05-19 09:16:18 +02:00
Jorge Martin Espinosa
e3d1a811d5
Disable biometric unlock when we disable pin code unlock (#6781)
* Disable biometric unlock when we disable pin code unlock
2026-05-18 22:19:22 +02:00
Jorge Martin Espinosa
4e3853a718
Attempt to fix room list item duplicates at midnight (#6793)
* Attempt to fix room list item duplicates at midnight

This seems to happen because of a race condition between `RoomListDataSource.observeDateTimeChanges` and `RoomListDataSource.replaceWith` being called at almost the same time and the first one using the newly received items from observing the timeline items but not updating the cache which will be later reused by `replaceWith`, containing incorrect indices
2026-05-18 22:18:52 +02:00
Benoit Marty
1774d1d39a
Merge pull request #6776 from element-hq/feature/bma/renovateConfig
Renovate: Keep Guava on the Android variant and ignore jre-only upgrades
2026-05-18 21:04:29 +02:00
ganfra
828337b343 Remove LiveLocationSharing feature flag 2026-05-18 20:25:36 +02:00
Jorge Martin Espinosa
174a6cad0d
Create a new room when inviting people in a DM (#6756)
* Create a new room when inviting people to a DM

* Improve screenshot tests

* Update screenshots

---------

Co-authored-by: ElementBot <android@element.io>
2026-05-18 19:01:11 +02:00
Benoit Marty
07668502fa
Merge pull request #6798 from element-hq/sync-localazy
Sync Strings
2026-05-18 18:45:27 +02:00
Benoit Marty
1111315c6a
Merge pull request #6802 from hughns/qr-other-device-not-signed-in
Show error message when using "Sign in with QR code" with a QR from a device that is also not signed in
2026-05-18 14:33:17 +02:00
Benoit Marty
653d9861dc
Remove SignInWithClassic FeatureFlag to enable the feature. (#6698)
Closes #6669
2026-05-18 13:54:54 +02:00
Hugh Nimmo-Smith
2771ce9442 Merge branch 'qr-other-device-not-signed-in' of https://github.com/hughns/element-x-android into qr-other-device-not-signed-in 2026-05-18 11:53:02 +01:00
Hugh Nimmo-Smith
fb17fc7e8a Iterate 2026-05-18 11:52:51 +01:00
Hugh Nimmo-Smith
efa61f1d24
Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-05-18 11:51:23 +01:00
Hugh Nimmo-Smith
458405b29f Iterate 2026-05-18 11:44:47 +01:00
Jorge Martin Espinosa
9b1735e0e9
Fix Maestro again after changes to the invite flow (#6796)
* Fix Maestro: tap on confirmation for inviting unknown users to a room

* Tap on back after inviting some user

* Tap on back again

* Confirm inviting someone to a DM

* Make fix conditional
2026-05-18 09:26:58 +00:00
Hugh Nimmo-Smith
668edbc679 Fix scanning code from signed out device when using "Sign in with QR code" 2026-05-18 09:50:54 +01:00
Jorge Martin Espinosa
2954174c56
Only load full media on media viewer when it's the visible item (#6794)
* Only load full media on media viewer when it's the visible item

* Allow cancelling ongoing media loading if scrolling fast
2026-05-18 10:29:14 +02:00
cizra
e6c3a8ff1d
Add MIDI playback (#6770)
* Add MIDI playback

* Implement PR suggestions
2026-05-18 10:06:47 +02:00
renovate[bot]
a89d37297f
Update dependency com.google.firebase:firebase-bom to v34.13.0 (#6789)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-18 09:22:20 +02:00
renovate[bot]
1c317d1ffd
Update dependency androidx.webkit:webkit to v1.16.0 (#6786)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-18 09:21:46 +02:00
renovate[bot]
ef7d1a10bf
Merge pull request #6783 from element-hq/renovate/camera
Update camera to v1.6.1
2026-05-18 09:17:07 +02:00
bmarty
dcc67f9fc6 Sync Strings from Localazy 2026-05-18 00:57:56 +00:00
Jenna Vassar
cbc677b80d
Fix room list duplicate-detection telemetry crashing before it can report (#6791)
* Add room dupe regression tests

* Fix telemetry path for dedupe discovery
2026-05-15 10:43:21 +02:00
renovate[bot]
432a7712c4
Update kotlin (#6790)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-15 09:03:50 +02:00
renovate[bot]
486754602d
Update dependency io.sentry:sentry-android to v8.41.0 (#6787)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-14 08:09:00 +02:00
renovate[bot]
e563fc7919
Update dependency androidx.compose:compose-bom to v2026.05.00 (#6784)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-14 08:08:21 +02:00
Jorge Martín
5e577e2360 Changelog for version 26.05.1 2026-05-13 13:59:48 +02:00
Jorge Martín
68d0cad3b7 Merge tag 'v26.05.1' into develop
v26.05.1
2026-05-13 13:12:51 +02:00
Jorge Martín
c1fcb0f6f6 Merge branch 'release/26.05.1' 2026-05-13 13:12:43 +02:00
Jorge Martín
4823267013 Adding fastlane file for version 26.05.1 2026-05-13 13:12:42 +02:00
Jorge Martín
7e6d3c60d2 Setting version for the release 26.05.1 2026-05-13 12:15:26 +02:00
Benoit Marty
d770a47904
Merge pull request #6780 from element-hq/feature/bma/pinIteration
Pin code: remove the key if there is no pin code
2026-05-13 11:58:55 +02:00
Benoit Marty
31d06391ed Pin code: remove the key if there is no pin code 2026-05-13 11:39:46 +02:00
renovate[bot]
737882d35e
Update dependency org.matrix.rustcomponents:sdk-android to v26.05.13 (#6779)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-13 10:18:59 +02:00
Timo
c959f50d53
Back button web view to esc (revive fixed version of: https://github.com/element-hq/element-x-android/pull/6724) (#6725)
* Change native back button behavior in EC view:
 - inject escape into webview instead of going back.
 - the webview will call back when no other modal is open.

* call down and up in the webview + make sure that we fall back to close
pip in case the webview did not handle the esc action.

* Tests and refactor to CallScreenBackPressPolicy

---------

Co-authored-by: Jorge Martín <jorgem@element.io>
2026-05-13 10:17:23 +02:00
Benoit Marty
960ff0fb75 Renovate: Keep Guava on the Android variant and ignore jre-only upgrades. 2026-05-12 21:39:48 +02:00
Benoit Marty
2ea23bcc3e
Merge pull request #6772 from element-hq/feature/bma/addMissingStrings
Add missing strings `theme.black`
2026-05-12 21:31:24 +02:00
Jorge Martin Espinosa
e8f1bf0085
Make Element Call screen work edge-to-edge (#6634)
* Update dependency io.element.android:element-call-embedded to v0.19.3

* Remove `Scaffold` component from CallScreenView

* Add immersive mode to calls in landscape orientation

* Add `consumeWindowInsets`, which fixes the webview not displaying any insets for the bottom nav bar

* Update screenshots

* Ignore compact height in PiP mode

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: ElementBot <android@element.io>
2026-05-12 17:33:02 +00:00
Benoit Marty
3ca06d71ef Rename keys on Localazy and add Black theme. 2026-05-12 17:57:55 +02:00
renovate[bot]
9eac27515e
Update dependency com.google.guava:guava to v33.6.0-jre (#6646)
* Update dependency com.google.guava:guava to v33.6.0-jre

* Use android version

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Benoit Marty <benoitm@element.io>
2026-05-12 15:35:51 +00:00
Benoit Marty
bad934d329
Do not close the MediaPlayer when navigating back from a thread. (#6771) 2026-05-12 17:00:48 +02:00
renovate[bot]
b4305b1749
Update plugin dependencycheck to v12.2.2 (#6760)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-12 16:56:34 +02:00
Valere Fedronic
9ca0b9e898
Merge pull request #6649 from element-hq/feature/valere/call/decline_timeline_rendering
feat: Update call started timeline item + declined support
2026-05-12 16:32:51 +02:00
Benoit Marty
3f02f527f0 Rename FF title 2026-05-12 16:17:10 +02:00
renovate[bot]
ae50f6b897
Update plugin sonarqube to v7.3.0.8198 (#6743)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-12 16:03:34 +02:00
renovate[bot]
c68e1b8845
Update tspascoal/get-user-teams-membership action to v4.0.1 (#6750)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-12 15:57:18 +02:00
Benoit Marty
2d4d4cdf25
Merge pull request #6720 from element-hq/renovate/major-metro
Update metro to v1 (major)
2026-05-12 15:56:18 +02:00
Benoit Marty
d299b722e3 Format code. 2026-05-12 15:50:47 +02:00
renovate[bot]
f04c836371
Update dependency io.element.android:element-call-embedded to v0.19.3 (#6766)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-12 15:42:06 +02:00
Benoit Marty
c30fee7f14 Do not close the MediaPlayer when navigating back from a thread. 2026-05-12 15:21:20 +02:00
Jorge Martin Espinosa
3234931d3c
Use the right analytics span as a parent in checkNetworkConnection (#6751)
`AnalyticsLongRunningTransaction.PushToWorkManager` was incorrectly used instead of `AnalyticsLongRunningTransaction.PushToNotification`, resulting in wrongly formatter analytic traces
2026-05-12 15:04:13 +02:00
Benoit Marty
b11fcec985
Merge pull request #6767 from element-hq/feature/bma/llsAndThread
Prevent user from starting LLS in thread
2026-05-12 14:24:16 +02:00
Benoit Marty
9326c30f05
Reduce FeatureFlags Knock effect on room creation and room edition form. (#6768)
Closes #6701
2026-05-12 14:18:49 +02:00
Benoit Marty
72be7ff1f9 Reduce FeatureFlags Knock effect on room creation and room edition form.
Closes #6701
2026-05-12 12:23:16 +02:00
Jorge Martin Espinosa
77b444581d
Improve FetchPushForegroundService's reliability (#6757)
* Improve `FetchPushForegroundService`'s reliability

- Don't use DI, we can just create the notification channel. This should speed up the creation of the service and reduce the number of `ForegroundServiceDidNotStartInTimeException` received. Also use `MainScope` instead of the app's coroutine scope.
- Move the wakelock releasing mechanism to `onDestroy` so it's always used. Previously, this would only happen when `stopService` was called, which would only happen when `stopSelf()` is called, but not when the OS or the service manager stops the service.

* Add fallback value for the notification channel title

* Replace the wrong string for the notification/channel title

---------

Co-authored-by: Benoit Marty <benoitm@element.io>
2026-05-12 11:40:46 +02:00
Valere
a227b830be add test to MessageSummaryFormatter 2026-05-11 18:08:28 +02:00
Jorge Martin Espinosa
11476c73cf
Adapt to new DM definition changes in the SDK (#6748)
* Set `DmRoomDefinition.TwoPeople` in `ClientBuilder`. This applies the 'direct and with at most 2 non-service members' rule to what the SDK should consider a DM.

* Map `RoomInfo.isDm` from the SDK

* Map `NotificationData.isDm` from `NotificationInfo.roomInfo.isDm`

* Remove `RoomIsDmCheck` file as its extension functions are now redundant. Move `Room.isDm` helper function to `BaseRoom`.

* Map `isDm` in `SpaceRoom` from the SDK too

* Replace `isDirect` with `isDm` where possible

* Map `RoomMember.isServiceMember` from the SDK and use it to tell apart normal members of a room from service members (i.e. `RoomMembersState.getDirectRoomMember`)
2026-05-11 17:22:16 +02:00
renovate[bot]
5e5e0bbc6e
Update dependency io.github.sergio-sastre.ComposablePreviewScanner:android to v0.9.0 (#6759)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-11 17:00:49 +02:00
Jorge Martin Espinosa
1ffc09e046
Stop removing the logs dir when clearing cache (#6765) 2026-05-11 16:55:40 +02:00
Valere
6bc8cd84e4 fixup test compilation 2026-05-11 16:54:30 +02:00
Benoit Marty
7f545079ad Prevent user from starting LLS in thread 2026-05-11 14:49:53 +02:00
renovate[bot]
90ce30d6e7
Update actions/add-to-project action to v2 (#6758)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-11 14:13:23 +02:00
ElementBot
c5a054b9e3 Update screenshots 2026-05-11 09:36:54 +00:00
Valere
a478d87fc3 Merge branch 'develop' into feature/valere/call/decline_timeline_rendering 2026-05-11 11:21:02 +02:00
Valere
f0f5e8be25 review: Refactor preview, show all variants 2026-05-11 11:20:10 +02:00
Valere
9ce8253086 review: Add unit test for notificationFormater 2026-05-11 11:16:45 +02:00
Valere
9a8046c02d review: Update signature and keep formatters grouped together 2026-05-11 10:48:50 +02:00
Valere
4437d4d9df review: Invert if for better readability 2026-05-11 10:47:46 +02:00
Valere
885d0f2cb9 review: better comment 2026-05-11 10:47:32 +02:00
Valere
f05ceb9f5d review: Use @stringRes annotation for Int 2026-05-11 10:47:17 +02:00
ganfra
e49e183178
Feature : share live location (#6741)
* First live location sharing sending implementation

* Simplify logic around canStop sharing

* Add some debug logs around LiveLocationSharingService

* Add LiveLocationException

* Expose beaconId to identify the current share

* Throttle live location instead of debouncing

* Keep sync alive when sharing live location

* Improve LiveLocation sharing

* Show LiveLocationDisclaimer

* Read minDistanceUpdate in LiveLocationSharingService

* Set minDistanceUpdate in AdvancedSettings

* Display banner in room when sharing live location

* Fix tests around LiveLocationSharing

* Ensure shares are properly restarted/stopped when app is re-launched

* Ensure LLS data is cleared when session is removed

* Update and fix LLS tests

* Handle Start LLS in ui

* Add check LLS permissions

* Remove hardcoded strings

* Fix quality and format

* Create DeviceLocationProvider so we can share location data between sources (presenter/live location service)

* Update screenshots

* Fix warning

* Do not try to stop if it was not sharing

* Revert "Create DeviceLocationProvider so we can share location data between sources (presenter/live location service)"

This reverts commit ba12bd968e82941cc231bdbb449310b24c97c5b8.

* Tweak location provider config values

* Address PR review remarks

* Fix ktlint

* Update screenshots

* Fix some tests after merging develop

* Adjust TimelineItemLocationView ui to match figma

* Update screenshots

* Documentation and cleanup

* Remove temporary resource

---------

Co-authored-by: ElementBot <android@element.io>
Co-authored-by: Benoit Marty <benoit@matrix.org>
Co-authored-by: Benoit Marty <benoitm@matrix.org>
2026-05-11 08:19:28 +00:00
ElementBot
0c657c258a
Sync Strings from Localazy (#6761)
Co-authored-by: bmarty <3940906+bmarty@users.noreply.github.com>
2026-05-11 09:37:59 +02:00
bxdxnn
071d98c66b
Render media captions formatting in the media viewer (#6729)
* Render media captions formatting in the media viewer

* Update screenshots

* Trigger actions

* Remove unused imports and reformat code

---------

Co-authored-by: ElementBot <android@element.io>
Co-authored-by: Jorge Martín <jorgem@element.io>
2026-05-08 16:30:32 +02:00
Jorge Martin Espinosa
4a4b3e07ef
Use just the other user's avatar for DM details (#6738)
* Use just the other user's avatar for DM details. Remove `DmAvatars` component and other no longer needed data.

* Improve selection indicator by clipping the avatar to a circle shape

* Update screenshots

---------

Co-authored-by: ElementBot <android@element.io>
2026-05-08 11:17:30 +02:00
ganfra
245c30c18a Changelog for version 26.05.0 2026-05-07 17:47:15 +02:00
ganfra
14096f3837 Merge tag '26.05.0' into develop 2026-05-07 17:45:54 +02:00
Benoit Marty
d50c04a420
Merge pull request #6746 from element-hq/renovate/org.matrix.rustcomponents-sdk-android-26.x
Update dependency org.matrix.rustcomponents:sdk-android to v26.05.7
2026-05-07 17:23:20 +02:00
Benoit Marty
4497d7da36
Merge pull request #6744 from element-hq/feature/bma/improvePinUX
Improve pin code ux
2026-05-07 17:04:43 +02:00
ganfra
cc65a0f114 Merge branch 'release/26.05.0' 2026-05-07 16:03:03 +02:00
ganfra
63edcd6989 Adding fastlane file for version 26.05.0 2026-05-07 16:01:40 +02:00
ganfra
0cb1a9fb14 Setting version for the release 26.05.0 2026-05-07 16:01:34 +02:00
renovate[bot]
95dac66869
Update tspascoal/get-user-teams-membership action to v4 (#6747)
* Update tspascoal/get-user-teams-membership action to v4

* Point the commit to the right tag v4.0.0

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Jorge Martín <jorgem@element.io>
2026-05-07 15:39:26 +02:00
Jorge Martín
7e3acc03b9 Fix API breaks 2026-05-07 15:13:51 +02:00
renovate[bot]
a6bee757b4
Update dependency org.matrix.rustcomponents:sdk-android to v26.05.7 2026-05-07 12:11:36 +00:00
Benoit Marty
a7c9fedc8f
Merge pull request #6740 from element-hq/feature/bma/uiSample
Introduce UI sample
2026-05-07 12:28:08 +02:00
Benoit Marty
0abb04ea62
Merge pull request #6708 from escix/patch-3
Fix 2 x Crash the app in Developer Options - Update AppDeveloperSettingsView.kt
2026-05-07 11:56:01 +02:00
Benoit Marty
022d21b097
Remove trailing spaces 2026-05-07 11:54:27 +02:00
Benoit Marty
80a46fdb3d Fix test 2026-05-07 11:52:21 +02:00
ElementBot
790c30ca1f Update screenshots 2026-05-07 09:20:09 +00:00
Jorge Martin Espinosa
866c8375b3
Make send event state UI easier to click (#6739)
* Make send event state UI easier to click

Make it so the whole timestamp view can be clicked

* Update screenshots

* Simplify `clickableModifier`

---------

Co-authored-by: ElementBot <android@element.io>
2026-05-07 11:11:07 +02:00
Benoit Marty
ae044607c7 Add missing screenshot and improve UX when user enter wrong pin then correct pin. 2026-05-07 10:59:13 +02:00
Benoit Marty
d18b529285 Ensure that remaining pin code attempts is never bigger than the value in the config. 2026-05-07 10:59:13 +02:00
Benoit Marty
d558371798 Add test. 2026-05-07 10:59:12 +02:00
Benoit Marty
5269b9787e Fix quality issue. 2026-05-07 10:59:12 +02:00
Benoit Marty
44baa4a383 PinUnlockEvents -> PinUnlockEvent 2026-05-07 10:59:12 +02:00
Benoit Marty
668b03f8bc SetupPinEvents -> SetupPinEvent 2026-05-07 10:59:11 +02:00
Benoit Marty
90918cbb9d SetupBiometricEvents -> SetupBiometricEvent 2026-05-07 10:59:11 +02:00
Benoit Marty
bc60512e10 LockScreenSettingsEvents -> LockScreenSettingsEvent 2026-05-07 10:59:11 +02:00
Benoit Marty
94d37c68d5 Use test extension. 2026-05-07 10:59:11 +02:00
Benoit Marty
8799dda471 Force sign out if PIN code store is corrupted. 2026-05-07 10:59:10 +02:00
Benoit Marty
61374bca4e Improve detection of configure PIN code. 2026-05-07 10:59:10 +02:00
Benoit Marty
2f45ca8835
Merge pull request #6682 from element-hq/feature/bma/customMasScheme
Add a way to tweak MAS url.
2026-05-07 10:51:32 +02:00
ElementBot
861de339d8 Update screenshots 2026-05-07 08:43:48 +00:00
Benoit Marty
4948497be2 More replacements 2026-05-07 10:01:30 +02:00
Benoit Marty
b19a2c5a44 Use generic id for default 2026-05-07 09:50:12 +02:00
Benoit Marty
0349162694 More replacements 2026-05-07 09:50:00 +02:00
renovate[bot]
a27278da20
Update dependencyAnalysis to v3.10.0 (#6742)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-07 08:09:15 +02:00
ElementBot
a7c4a2b404 Update screenshots 2026-05-06 20:17:22 +00:00
Benoit Marty
223dd1f6b0 Fix invalid userId. 2026-05-06 21:59:59 +02:00
Benoit Marty
a77c2c0c7e Update ref to submodule. 2026-05-06 17:54:22 +02:00
Benoit Marty
15162e4e32
Merge pull request #6726 from element-hq/feature/bma/renameVerificationMethod
Rename verification methods
2026-05-06 17:50:11 +02:00
Benoit Marty
2a694f6dfd Create PreviewData with sample of UGC used for preview.
Fix preview issue where username was used for room/avatar name.
2026-05-06 17:45:50 +02:00
Copilot
6ef9315468
Remove RoomDirectorySearch feature flag — always enable the feature (#6736)
* Remove RoomDirectorySearch feature flag, always enable the feature

Co-authored-by: stefanceriu <637564+stefanceriu@users.noreply.github.com>

* Apply ktlint formatting

Co-authored-by: jmartinesp <480955+jmartinesp@users.noreply.github.com>

* Update screenshots

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: stefanceriu <637564+stefanceriu@users.noreply.github.com>
Co-authored-by: jmartinesp <480955+jmartinesp@users.noreply.github.com>
Co-authored-by: ElementBot <android@element.io>
2026-05-06 16:05:19 +02:00
Jorge Martin Espinosa
9b91fabbd6
Use 'Report a problem' string instead of 'Report bug' (#6735)
* Use 'Report a problem' instead of 'Report bug'. This old string will be deleted soon.

* Update screenshots

---------

Co-authored-by: ElementBot <android@element.io>
2026-05-06 15:33:17 +02:00
renovate[bot]
f4cf704335
Update dependency org.matrix.rustcomponents:sdk-android to v26.05.6 (#6734)
* Update dependency org.matrix.rustcomponents:sdk-android to v26.05.6

* Fix API breaks:

- Add `RoomMember.isServiceMember`.
- Add `beacon` and `beaconInfo` power levels.

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Jorge Martín <jorgem@element.io>
2026-05-06 15:31:52 +02:00
Jorge Martin Espinosa
34f001d22c
Fix back button sometimes not working after exiting a thread (#6732)
When I reproduced the issue, it looked like the coroutine used to mark as read and then exit the room was canceled, leaving the `markingAsReadAndExiting` variable with `true` value and preventing the exit block from running again.
2026-05-06 14:35:08 +02:00
Jorge Martin Espinosa
70452842d3
Make icons in the Chat screen top bar 16dp (#6733)
* Make icons in the Chat screen top bar 16dp. This matches the designs in Figma.

* Fix the padding between the title and the icons

* Update screenshots

---------

Co-authored-by: ElementBot <android@element.io>
2026-05-06 09:16:13 +00:00
ganfra
f0b9ce567a
Merge pull request #6731 from element-hq/renovate/org.maplibre.gl-android-sdk-13.x
Update dependency org.maplibre.gl:android-sdk to v13.1.0
2026-05-06 10:49:49 +02:00
ganfra
bcc2eb3d34
Merge pull request #6727 from element-hq/renovate/net.zetetic-sqlcipher-android-4.x
Update dependency net.zetetic:sqlcipher-android to v4.15.0
2026-05-06 10:28:04 +02:00
ganfra
1fd02be0f4
Merge branch 'develop' into renovate/net.zetetic-sqlcipher-android-4.x 2026-05-06 10:10:57 +02:00
renovate[bot]
47ca5a5f2f
Update dependency org.maplibre.gl:android-sdk to v13.1.0 2026-05-06 01:36:24 +00:00
Kurban Sagitov
a7711b7d52
Fix low width image message (#6692)
* fix low width image message

* added previews for narrow images

* Update screenshots
---------

Co-authored-by: ElementBot <android@element.io>
2026-05-05 17:10:24 +02:00
Benoit Marty
65ddc4355e
Merge pull request #6700 from element-hq/feature/bma/lenientJson
Let our Json parser accept comments and trailing comma.
2026-05-05 17:08:21 +02:00
Benoit Marty
3b3b4813b6 Detekt and ktlint are confused with Kotlin context... 2026-05-05 16:50:22 +02:00
Benoit Marty
384c806131 Fix compilation warnings 2026-05-05 16:22:32 +02:00
renovate[bot]
54a6666988
Update dependency net.zetetic:sqlcipher-android to v4.15.0 2026-05-05 14:05:26 +00:00
bxdxnn
28e1062eed
Reimplement "Natural media viewer swiping order" (#6715) 2026-05-05 16:02:52 +02:00
Benoit Marty
0a9259604b Improve FakeSessionVerificationService 2026-05-05 15:29:32 +02:00
Jorge Martin Espinosa
2d203e83b9
Revert PR #6642 (#6724)
* Revert "Change native back button behavior in EC view (close settings in EC with os native back) (#6642)"

This reverts commit 6ba4679908.

* Fix API breaks from revert
2026-05-05 15:24:27 +02:00
Jorge Martin Espinosa
a12b519155
Allow cancelling room loading in Home screen (#6723)
Previously, this was disabled by mistake, since it's the default behavior.
2026-05-05 13:14:30 +02:00
Benoit Marty
51bcaca9db Rename methods around verification, to match SDK naming. 2026-05-05 12:17:51 +02:00
renovate[bot]
c40f916b4f
Merge pull request #6722 from element-hq/renovate/roborazzi
Update roborazzi to v1.60.0
2026-05-05 10:55:16 +02:00
renovate[bot]
ab85c554ff
Update metro to v1 2026-05-05 00:49:45 +00:00
Benoit Marty
d7be603bfc
Merge pull request #6654 from bxdxnn/fix/clip-room-summary
Add clipping to RoomSummaryRow
2026-05-04 22:38:51 +02:00
bxdxnn
6897cc5721 Add clipping to RoomSummaryRow 2026-05-04 18:29:37 +00:00
renovate[bot]
54525d855e
Update dependency org.matrix.rustcomponents:sdk-android to v26.05.4 (#6718)
* Update dependency org.matrix.rustcomponents:sdk-android to v26.05.4

* Fix `RoomInfo` fixture

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Jorge Martín <jorgem@element.io>
2026-05-04 10:04:20 +00:00
Benoit Marty
26fe5b6492
Merge pull request #6650 from element-hq/feature/bma/a11yFixes
[a11y] Fix a set of issues
2026-05-04 11:50:15 +02:00
Benoit Marty
61f074ddc1 Let our Json parser accept comments and trailing comma. 2026-05-04 10:05:11 +02:00
Benoit Marty
e8e5a2d454
Merge pull request #6716 from element-hq/sync-localazy
Sync Strings
2026-05-04 09:59:34 +02:00
Valere
18fbe91fc7 Merge branch 'develop' into feature/valere/call/decline_timeline_rendering 2026-05-04 09:00:00 +02:00
Valere
a0646717a3 fix test compilation 2026-05-04 08:59:46 +02:00
Hi Dude!
27869c0e04
Fix calls on Huawei devices: skip addWebMessageListener on Chromium < 119 (#6640)
* Fix calls on Huawei: skip addWebMessageListener on Chromium < 119

* Fix lint issues, log webview version

---------

Co-authored-by: manfrommedan <manfrommedan@users.noreply.github.com>
Co-authored-by: Jorge Martín <jorgem@element.io>
2026-05-04 08:30:05 +02:00
renovate[bot]
5733c3149a
Update dependency com.posthog:posthog-android to v3.43.0 (#6704)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-04 08:07:11 +02:00
renovate[bot]
e81ab35f5b
Update dependency io.nlopez.compose.rules:detekt to v0.5.8 (#6711)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-05-04 08:06:30 +02:00
bmarty
0d2f71643a Sync Strings from Localazy 2026-05-04 00:54:27 +00:00
Strac Consulting Engineers Pty Ltd
715402d178
Update AppDeveloperSettingsView.kt
Fix 2 x Crash the app
Fixes #6707
2026-05-02 09:40:23 +10:00
bxdxnn
194945c49e Add .clickable to RoomMemberModerationView avatar 2026-05-01 12:19:17 +00:00
Benoit Marty
65a9a97735
Merge pull request #6668 from element-hq/feature/bma/removeExternalCallSupport
Remove external call support
2026-04-30 17:36:40 +02:00
Benoit Marty
6c7c48da69 Fix compilation issue 2026-04-30 16:59:14 +02:00
Benoit Marty
e21276f323 Merge branch 'develop' into feature/bma/removeExternalCallSupport 2026-04-30 16:58:11 +02:00
Benoit Marty
85ef12a401
Merge pull request #6697 from element-hq/feature/bma/fixDependencyError
Fix dependency error
2026-04-30 16:57:19 +02:00
Benoit Marty
4e38846342
Merge pull request #6693 from element-hq/renovate/compose.bom
Update dependency androidx.compose:compose-bom to v2026.04.01
2026-04-30 16:54:23 +02:00
Benoit Marty
11b9efa2c9 Migrate to v2 testing APIs 2026-04-30 16:04:07 +02:00
Jorge Martin Espinosa
30fd90abb9
Mitigate a deadlock when loading room timelines (#6674)
This may be happening because we were not destroying focused event timelines used for the media viewer/gallery when necessary, and having several of those back paginating *may* have caused a deadlock in the event cache.
2026-04-30 16:01:24 +02:00
Benoit Marty
13775f4fbd Update kotlin version 2026-04-30 14:09:41 +02:00
Benoit Marty
b8995e4356 Fix quality issues 2026-04-30 14:09:07 +02:00
ElementBot
0b04dec85c Update screenshots 2026-04-30 10:44:04 +00:00
Benoit Marty
d6f8c13c3f MediaPlayerControllerView: Use IconButton instead of Box and remove the clipping. 2026-04-30 12:20:53 +02:00
Benoit Marty
b1890de26a MediaViewerView: move TopBar to Scaffold topbar 2026-04-30 12:20:53 +02:00
Benoit Marty
8188ef1463 Improve MediaViewerBottomBar usage. 2026-04-30 12:19:32 +02:00
Benoit Marty
562e36b5ea Improve how the ThumbnailView is added to the composition 2026-04-30 12:19:32 +02:00
Benoit Marty
97cada7432 Move isTalkbackActive to a11y package. 2026-04-30 12:19:31 +02:00
Benoit Marty
5e963fc743 a11y: do not use Overlay if screen reader is active, or external keyboard is connected.
Related to #6399
2026-04-30 12:19:31 +02:00
Benoit Marty
dcd0a98c0c Declare Top bar first and use zIndex. 2026-04-30 12:19:30 +02:00
Benoit Marty
4e46f12a12 Remove useless Box 2026-04-30 12:17:25 +02:00
Benoit Marty
70583fc3fc Remove unused content parameter. 2026-04-30 12:07:07 +02:00
Benoit Marty
9912d763d4 a11y: use different content description when the red dot is displayed
Closes #6395
2026-04-30 12:07:06 +02:00
Benoit Marty
0c333235f8 a11y: set role = button for "learn more" texts.
Closes #6405
2026-04-30 12:07:06 +02:00
Benoit Marty
0a99b28963 a11y: let banner title be implemented as a heading.
Closes #6384
2026-04-30 12:07:06 +02:00
Benoit Marty
b815aaabc9 a11y: let section header be implemented as a heading.
Closes #6386
2026-04-30 12:07:05 +02:00
Benoit Marty
f5737e9d2b a11y: add alternative text to the info icon.
Closes #6379
2026-04-30 12:07:05 +02:00
ganfra
e5d134cd3b
Merge pull request #6687 from element-hq/renovate/kotlin
Update kotlin
2026-04-30 12:04:57 +02:00
Benoit Marty
f4b3ddfa0b Merge branch 'develop' into feature/bma/removeExternalCallSupport 2026-04-30 11:50:35 +02:00
ganfra
efe611eb4f
Merge pull request #6660 from element-hq/renovate/org.jsoup-jsoup-1.x
Update dependency org.jsoup:jsoup to v1.22.2
2026-04-30 11:30:08 +02:00
ganfra
be22ac8de9
Merge pull request #6691 from element-hq/renovate/io.sentry-sentry-android-8.x
Update dependency io.sentry:sentry-android to v8.40.0
2026-04-30 11:26:47 +02:00
ElementBot
795299ed0c Update screenshots 2026-04-30 09:20:58 +00:00
renovate[bot]
c9bc8791e9
Update kotlin 2026-04-30 09:19:59 +00:00
Benoit Marty
fabdcee520 Remove SignInWithClassic FeatureFlag to enable the feature.
Closes #6669
2026-04-30 11:19:10 +02:00
Jorge Martin Espinosa
4a79b272ef
Fix ANRs when receiving push notifications (#6696)
In Sentry there are some reports of methods called when notifications are fetched that end up having ANRs. This looked weird because everything is asynchronous... but it's still running with a `Main` dispatcher.

Using the `Default/computation` one instead should be the right call.
2026-04-30 10:51:29 +02:00
Benoit Marty
078e942a28 Cleanup dependencies 2026-04-30 09:54:54 +02:00
Benoit Marty
4d0be69b4c In the module :libraries:matrix.api, change the dependencies to:
- libraries.sessionStorage.api
- projects.libraries.architecture
from `api` to `implementation`.

Modules who need `:libraries:matrix.api` do not necessarily need to use the session storage api.
2026-04-30 09:52:10 +02:00
Benoit Marty
b50969437d Ensure clearing the cache delete the CacheStore. 2026-04-30 09:04:19 +02:00
Benoit Marty
c8773c890f Fix SQL query 2026-04-30 08:49:56 +02:00
Benoit Marty
3dd2a60b3a Do not use generic Exception 2026-04-29 22:51:54 +02:00
Benoit Marty
35a3a0ba06 Fix compilation issue. 2026-04-29 22:43:42 +02:00
Benoit Marty
8b8eedb419
Merge pull request #6681 from hughns/hughns/link-new-device-done
Improve detection of completion for Link new device flow
2026-04-29 22:32:22 +02:00
Benoit Marty
8512279d96 Add a cache for Element .well-known file. 2026-04-29 22:29:41 +02:00
Benoit Marty
29e0a08dd9 Add a CacheStore module. 2026-04-29 22:29:41 +02:00
Benoit Marty
c1e908a8e6 Fix tests. 2026-04-29 22:29:41 +02:00
Benoit Marty
a76b55e580 Add a way to tweak MAS url. 2026-04-29 22:29:40 +02:00
renovate[bot]
da36323006
Update dependency androidx.compose:compose-bom to v2026.04.01 2026-04-29 20:27:57 +00:00
renovate[bot]
7940b8f865
Update dependency io.sentry:sentry-android to v8.40.0 2026-04-29 16:11:36 +00:00
Timo
6ba4679908
Change native back button behavior in EC view (close settings in EC with os native back) (#6642)
* Change native back button behavior in EC view:
 - inject escape into webview instead of going back.
 - the webview will call back when no other modal is open.

* call down and up in the webview + make sure that we fall back to close
pip in case the webview did not handle the esc action.

---------

Co-authored-by: Jorge Martín <jorgem@element.io>
2026-04-29 18:08:33 +02:00
Valere
66f68fdccb fixup test compilation 2026-04-29 17:27:51 +02:00
Valere
531d9b3d47 fix: consist, use sealed interface instead of class 2026-04-29 16:29:13 +02:00
Valere
6154816796 cleanup of the RTCNotificationState enum 2026-04-29 16:21:36 +02:00
Valere
a6622c6787 fix deteckt | unneeded paranthesis 2026-04-29 16:03:19 +02:00
Valere
f0dc4eeace feat: Update call started timeline item + declined support 2026-04-29 15:43:58 +02:00
Hugh Nimmo-Smith
026c448e48
Merge branch 'develop' into hughns/link-new-device-done 2026-04-29 12:06:40 +01:00
Hugh Nimmo-Smith
3b21d698ee Fix tests
Co-Authored-By: Benoit Marty <3940906+bmarty@users.noreply.github.com>
2026-04-29 12:05:16 +01:00
Jorge Martin Espinosa
d215354e64
Remove legacy mx-reply from toPlainText formatted event contents (#6683) 2026-04-29 10:54:03 +00:00
Benoit Marty
1eeabb1e64
Merge pull request #6688 from element-hq/feature/bma/errorAlreadySignedIn
[Link new device] Add missing error case "already signed in"
2026-04-29 12:42:41 +02:00
ElementBot
6de6e13f25 Update screenshots 2026-04-29 10:06:55 +00:00
Jorge Martin Espinosa
367995303d
Rename OIDC components and variables to OAuth (#6686)
* Rename `OIDC` components and variables to `OAuth`. This matches the new behavior in the SDK.
2026-04-29 11:41:47 +02:00
Benoit Marty
c750fd102f Increase title and subtitle vertical padding on FlowStepPage. 2026-04-29 11:33:45 +02:00
Benoit Marty
083fc5c5fb [Link new device] Add missing screen for the error case OtherDeviceAlreadySignedIn
Closes #6678
2026-04-29 11:33:44 +02:00
Benoit Marty
7dd81dc838
Merge pull request #6677 from hughns/hughns/qr-grant-error-mapping
Update error mappings for Link new device flow
2026-04-29 11:33:01 +02:00
Benoit Marty
1d03cbfc06
Fix quality issues and formatting 2026-04-29 10:34:50 +02:00
Benoit Marty
3fd2f0991a
Merge pull request #6670 from bxdxnn/fix/room-summary-html
Strip formatting from media captions in room summary
2026-04-29 09:40:30 +02:00
Hugh Nimmo-Smith
7d27ff3c59
Merge branch 'develop' into hughns/qr-grant-error-mapping 2026-04-28 17:04:08 +01:00
Benoit Marty
7080cf77e6
Merge pull request #6680 from element-hq/feature/bma/qrCodeFix
[Link new device] Add missing screen to render digits that the user has to type on the other device
2026-04-28 16:59:16 +02:00
Hugh Nimmo-Smith
fd69bbc57a Delint 2026-04-28 15:42:24 +01:00
Hugh Nimmo-Smith
723b7486bc Improve detection of completion for Link new device flow
The SDK emits a Done progress once complete, but our listener might have been deallocated before receiving the done.
2026-04-28 15:19:03 +01:00
renovate[bot]
997227b020
Update dependency org.matrix.rustcomponents:sdk-android to v26.04.27 (#6666)
* Update dependency org.matrix.rustcomponents:sdk-android to v26.04.27

* Fix breaking API changes:

- OIDC components are now prefixed `OAuth`.
- `Room.startLiveLocationShare` now returns the event id of the beacon state event if it succeeds.
- `RoomInfo` now contains an `activeServiceMembersCount` property.

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Jorge Martín <jorgem@element.io>
2026-04-28 14:49:37 +02:00
Jorge Martin Espinosa
90ed385745
Fix record screenshots action permissions (#6679) 2026-04-28 11:17:57 +00:00
ElementBot
cd61c6b3f0 Update screenshots 2026-04-28 11:10:56 +00:00
Hugh Nimmo-Smith
5c9d8d917c Update error mappings for Link new device 2026-04-28 11:22:25 +01:00
Benoit Marty
5508442222 [Link new device] Implement code confirmation screen. 2026-04-28 12:04:57 +02:00
renovate[bot]
5e8db74003
Update dependencyAnalysis to v3.9.0 (#6657)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-28 11:16:50 +02:00
bxdxnn
fff27ff3f1 Strip formatting from media captions in room summary 2026-04-28 08:27:28 +00:00
Benoit Marty
3878ce000c
Ensure that bottom sheet can scroll (#6661)
* RoomListDeclineInviteMenu: limit room name

Improve preview.
Closes #6659

* Ensure that all the ModalBottomSheet can scroll.

* Update screenshots

* Rename Preview.

* Preview the whole bottom sheet.

* Remove obsolete comment.

* Update screenshots

---------

Co-authored-by: ElementBot <android@element.io>
2026-04-28 09:43:41 +02:00
renovate[bot]
5bb0b92eeb
Update dependency io.element.android:element-call-embedded to v0.19.2 (#6662)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-27 17:36:41 +02:00
Benoit Marty
4bb33fc36a Use test extension on presenters. 2026-04-27 17:06:49 +02:00
Benoit Marty
944d8965f6 PictureInPictureEvents -> PictureInPictureEvent 2026-04-27 17:04:49 +02:00
Benoit Marty
2bcf10dd0b CallScreenEvents -> CallScreenEvent 2026-04-27 17:04:12 +02:00
Benoit Marty
8860647477 Element Call: remove support for SPA call links.
Closes #6578
2026-04-27 17:01:08 +02:00
ElementBot
21cae089ae Update screenshots 2026-04-27 13:39:42 +00:00
Benoit Marty
dca2dba938 Remove obsolete comment. 2026-04-27 15:16:42 +02:00
Benoit Marty
e289ec2af7 Preview the whole bottom sheet. 2026-04-27 15:15:23 +02:00
Benoit Marty
a35236b8b0 Rename Preview. 2026-04-27 15:12:23 +02:00
ElementBot
0d078a41ca Update screenshots 2026-04-27 08:40:35 +00:00
Benoit Marty
09ff3294d5 Ensure that all the ModalBottomSheet can scroll. 2026-04-27 10:23:56 +02:00
Benoit Marty
bf57223d05 RoomListDeclineInviteMenu: limit room name
Improve preview.
Closes #6659
2026-04-27 09:49:09 +02:00
renovate[bot]
14054344f4
Update dependency org.jsoup:jsoup to v1.22.2 2026-04-27 07:20:07 +00:00
ElementBot
9a2ad3928a
Merge pull request #6658 from element-hq/sync-localazy
Sync Strings
2026-04-27 09:17:54 +02:00
Benoit Marty
3c51732d35
Merge pull request #6643 from element-hq/feature/bma/updateMediaViewer
Update media viewer UI
2026-04-24 17:48:38 +02:00
ElementBot
22ef9f1a5e Update screenshots 2026-04-24 15:12:13 +00:00
Benoit Marty
fb50fce649 Ensure preview has a date 2026-04-24 16:53:53 +02:00
Benoit Marty
c283f0109b a11y: add heading to the title. 2026-04-24 16:16:15 +02:00
Benoit Marty
10c9112e03
Merge pull request #6651 from element-hq/feature/bma/mention-pill-cut-off
Mention pill cut off
2026-04-24 16:12:38 +02:00
ElementBot
5929806137 Update screenshots 2026-04-24 13:34:34 +00:00
Benoit Marty
de7b4002d8 MediaDetailsBottomSheet: update wording. 2026-04-24 15:16:26 +02:00
ElementBot
a276e67ce6 Update screenshots 2026-04-24 12:38:13 +00:00
Benoit Marty
1c229e7229 Replace " - " by " • " as it renders better. 2026-04-24 14:28:52 +02:00
renovate[bot]
112dc93fff
Update dependency io.sentry:sentry-android to v8.39.1 (#6648)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-24 14:23:26 +02:00
Kurban Sagitov
3379c61ad1
PR:Fix mention pill cut off (#6622)
* Fix mention pill cut off

* trigger CI after screenshots

* trigger CI after screenshots
2026-04-24 14:20:24 +02:00
Richard van der Hoff
289dfff50a
Promote "history sharing on invite" out of developer options (#6647)
* Enable history sharing by default, unconditionally

* Remove feature-flag dep from history viz icons in room header

* Remove feature-flag dep from warning on inviting new people

* Remove feature-flag dep from warning on starting chat with new people

* Remove `enableKeyShareOnInvite` feature flag

* Update screenshots

* Remove redundant `FakeFeatureFlagService()` invocation, per review comment

---------

Co-authored-by: ElementBot <android@element.io>
2026-04-24 10:52:21 +00:00
Jorge Martin Espinosa
92ee479e91
Set max lines for 'in reply to' view conditionally (#6612)
* Set max lines for 'in reply to' view conditionally. When there is enough screen space, use 2 lines as before. If the screen space is limited, use a single one.

* Reduce vertical padding for reply-to view in compose

* Add screenshot test with single line in reply to view

* Update screenshots

---------

Co-authored-by: ElementBot <android@element.io>
2026-04-23 15:15:52 +02:00
ElementBot
e37083669e Update screenshots 2026-04-23 09:40:14 +00:00
Benoit Marty
09e0d2d166 MediaDetailsBottomSheet: Add missing preview case. 2026-04-23 11:22:47 +02:00
Benoit Marty
bbb4a47eff MediaDetailsBottomSheet: iterate on design.
Closes #6645
2026-04-23 11:20:20 +02:00
Valere Fedronic
e036250539
Merge pull request #6636 from element-hq/feature/valere/fix_build_sdk_script_macos
devx: fix build sdk script options for macos
2026-04-23 10:12:04 +02:00
renovate[bot]
9dd61bbd37
fix(deps): update camera to v1.6.0 (#6514)
* fix(deps): update camera to v1.6.0

* Add dependency to com.google.guava:guava to fix compilation issue.

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Benoit Marty <benoit@matrix.org>
2026-04-23 09:48:15 +02:00
renovate[bot]
2c6f1888f4
Update dependency io.sentry:sentry-android to v8.38.0 (#6597)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-23 09:47:17 +02:00
renovate[bot]
d9080f5465
Update zizmorcore/zizmor-action action to v0.5.3 (#6630)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-23 09:46:37 +02:00
Jorge Martin Espinosa
b4f1627748
Remove distributed tracing of the 'timeline loading' flow (#6644)
* Remove distributed tracing of the 'timeline loading' flow. This is causing crashes in the app when a debug SDK build is used

* Discourage using the APIs related with distributed tracing, explaining the problem
2026-04-22 17:51:51 +02:00
ElementBot
92add85883 Update screenshots 2026-04-22 13:54:26 +00:00
Benoit Marty
b12a9ff2b9 Improve rendering when sender does not have a display name. 2026-04-22 14:57:18 +02:00
Benoit Marty
7bbdecc7a8 Rename sub classes of MediaBottomSheetState and improve preview of MediaDeleteConfirmationBottomSheet 2026-04-22 14:42:56 +02:00
ElementBot
c9b48d32b0 Update screenshots 2026-04-22 10:40:25 +00:00
Benoit Marty
c1678f22e6 Add more preview for MediaDetailsBottomSheetPreview 2026-04-22 12:21:20 +02:00
Benoit Marty
769341e4f2 Remove some dividers. 2026-04-22 12:16:52 +02:00
Benoit Marty
630b0c8098 Improve and add test 2026-04-22 12:07:56 +02:00
Benoit Marty
1e39736797 MediaGalleryEvents -> MediaGalleryEvent 2026-04-22 11:01:36 +02:00
Benoit Marty
83b4bfad96 Move "Open with" action to bottom sheet 2026-04-22 10:59:21 +02:00
ganfra
61a8d06a6a
Merge pull request #6594 from element-hq/renovate/io.nlopez.compose.rules-detekt-0.x
Update dependency io.nlopez.compose.rules:detekt to v0.5.7
2026-04-22 10:46:03 +02:00
renovate[bot]
3199a7dd8b
Update dependency io.nlopez.compose.rules:detekt to v0.5.7 2026-04-21 20:06:08 +00:00
Jorge Martín
24b24e511a Changelog for version 26.04.4 2026-04-21 17:37:15 +02:00
Jorge Martín
0224c7e2a5 Adding fastlane file for version 26.04.4 2026-04-21 17:37:15 +02:00
Jorge Martín
61c68f8d4a Setting version for the release 26.04.4 2026-04-21 17:37:15 +02:00
Benoit Marty
a0632b216c MediaDetailsBottomSheet: update wording and dividers. 2026-04-21 16:53:22 +02:00
Jorge Martin Espinosa
1e04a7345f
Add flag for automatic back pagination feature (#6637) 2026-04-21 14:42:44 +00:00
Jorge Martín
91d265e6bf Merge branch 'release/26.04.4' 2026-04-21 16:40:31 +02:00
Jorge Martín
d38ef5ba10 Adding fastlane file for version 26.04.4 2026-04-21 16:40:30 +02:00
Jorge Martín
5d270068d6 Setting version for the release 26.04.4 2026-04-21 16:38:53 +02:00
Benoit Marty
79afb1d9e0 MediaViewer: add Save action as a main action. 2026-04-21 16:21:01 +02:00
Benoit Marty
97ae775df5 MediaViewer: add Share action as a main action. 2026-04-21 16:14:07 +02:00
Jorge Martín
f6ed0a645a Add flag for automatic back pagination feature 2026-04-21 15:56:38 +02:00
renovate[bot]
75db550ca8
Update dependency org.matrix.rustcomponents:sdk-android to v26.04.21 (#6635)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-21 13:55:20 +00:00
Benoit Marty
54efb46294 MediaViewerEvents -> MediaViewerEvent 2026-04-21 15:50:59 +02:00
Benoit Marty
f3dd7b86d8
Merge pull request #6633 from element-hq/feature/bma/deactivateStrings
Update wording of deactivate account screen
2026-04-21 15:34:23 +02:00
Valere
283fd2970a devx: fix build sdk script options for macos 2026-04-21 15:34:01 +02:00
Jorge Martin Espinosa
2d4ed98738
Fix media viewer bottom sheets not being scrollable (#6631)
Both the info and confirm deletion bottom sheets were not scrollable, which made them useless on devices with low resolution or landscape orientation in most devices
2026-04-21 15:30:50 +02:00
Benoit Marty
a662a5a045 Use new action_delete and action_delete_account 2026-04-21 14:57:33 +02:00
Valere Fedronic
7f198155f2
Merge pull request #6627 from element-hq/feature/valere/call/fix_proximity_bug
Fix | When selecting earpiece twice in a row the proximity sensor get wrongly disabled
2026-04-21 13:52:32 +02:00
mxandreas
064c606b53
Updates to new features and some refactoring. (#6591)
* Updates to new features and some refactoring.

* Update CONTRIBUTING.md

* Typo fixes.

* Some final touches.

* Update the table of contents in `CONTRIBUTING.md`

---------

Co-authored-by: bxdxnn <267911624+bxdxnn@users.noreply.github.com>
Co-authored-by: Jorge Martín <jorgem@element.io>
2026-04-21 10:53:01 +00:00
Valere Fedronic
b080c01388
Merge pull request #6603 from element-hq/valere/call/fix_join_button_on_several_items
cleaning: Remove join button from call notify timelineItemView
2026-04-21 11:56:38 +02:00
Valere Fedronic
66ed52dee8
Merge pull request #6609 from element-hq/feature/valere/call/clean_up_call_controls
audio: Let EC decide alone what communication device to use
2026-04-21 11:53:29 +02:00
ElementBot
c343df8351 Update screenshots 2026-04-21 09:50:46 +00:00
Valere
434e592fed Merge branch 'develop' into feature/valere/call/clean_up_call_controls 2026-04-21 11:36:44 +02:00
Benoit Marty
168782e049 Update deactivate account wording. Closes #6608 2026-04-21 11:35:26 +02:00
ElementBot
3c06e0a260 Update screenshots 2026-04-21 09:26:51 +00:00
Benoit Marty
8eb5a55673 Introduce simplePluralStringResource methods, as Composable and in StringProvider. 2026-04-21 11:22:43 +02:00
Valere
af47e2b405 Merge branch 'develop' into valere/call/fix_join_button_on_several_items 2026-04-21 11:05:14 +02:00
Valere
e158be86aa review: Make call intent not optional in content 2026-04-21 11:03:48 +02:00
Valere
b0e9073efb fix test compilation 2026-04-21 10:49:08 +02:00
ganfra
e5f85592d9
Merge pull request #6611 from element-hq/feature/fga/live_location_rendering
WIP : live location rendering
2026-04-20 19:46:13 +02:00
renovate[bot]
96cbe7664b
Update dependencyAnalysis to v3.7.0 (#6616)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-20 19:20:26 +02:00
ganfra
51733ec6fe Merge branch 'develop' into feature/fga/live_location_rendering 2026-04-20 19:12:21 +02:00
ElementBot
e1b7171839
Sync Strings (#6626)
* Sync Strings from Localazy

* Use the previous plurals as plain strings

* Add extra case for 1 vs multiple users

* Update screenshots

---------

Co-authored-by: Jorge Martín <jorgem@element.io>
2026-04-20 17:09:10 +00:00
Jorge Martin Espinosa
f80a140cf9
Cleanup FetchPushForegroundService (#6577)
* Rename `PushHandlingWakeLock` to `FetchPushForegroundServiceManager`. Move the start/stop logic from `FetchPushForegroundService.Companion` to it.

* Add more tests using Robolectric.

* Remove `FeatureFlags.SyncNotificationsWithWorkManager` and associated code: this should have been removed in one of the previous refactors, since we don't have the 2 ways to sync notifications anymore, everything uses the `WorkManager`

---------

Co-authored-by: Benoit Marty <benoit@matrix.org>
2026-04-20 16:03:12 +02:00
ganfra
8853f160e2
Merge pull request #6615 from element-hq/renovate/peter-evans-create-pull-request-8.x
Update peter-evans/create-pull-request action to v8.1.1
2026-04-20 15:50:06 +02:00
ganfra
05e1048d20
Merge pull request #6606 from element-hq/renovate/actions-github-script-9.x
Update actions/github-script action to v9
2026-04-20 15:44:52 +02:00
bxdxnn
8611b9c690
Fix crash when going back to threads list (#6620)
* Fix crash when going back to threads list
2026-04-20 15:36:31 +02:00
ganfra
c35b5811d0 Restore comment on StaticMapView 2026-04-20 15:14:10 +02:00
renovate[bot]
447f4e5134
Update plugin dependencycheck to v12.2.1 (#6621)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-20 14:22:49 +02:00
renovate[bot]
f7eaedf805
Merge pull request #6614 from element-hq/renovate/actions-upload-artifact-7.x
Update actions/upload-artifact action to v7.0.1
2026-04-20 14:22:22 +02:00
Valere
18d4924171 fix: proximity sensor was wrongly disabled 2026-04-20 11:24:38 +02:00
Valere
58bde16b81 enforce selecting the EC preferred device 2026-04-20 11:19:37 +02:00
Valere
09e57e077a audio: Let EC decide alone what communication device to use 2026-04-20 11:19:37 +02:00
renovate[bot]
09720a01c9
Update peter-evans/create-pull-request action to v8.1.1 2026-04-17 18:50:20 +00:00
ganfra
41f86b492c Fix test after new property in LiveLocationShare 2026-04-17 16:58:06 +02:00
ElementBot
5fb0b3a93d Update screenshots 2026-04-17 13:45:30 +00:00
Benoit Marty
ae94e0c746
Merge pull request #6441 from timurgilfanov/feature-oled-black
Add Black theme option for battery saving on OLED displays
2026-04-17 15:41:49 +02:00
ganfra
3b813f137b Merge branch 'develop' into feature/fga/live_location_rendering 2026-04-17 15:13:13 +02:00
ganfra
8182a149d0 Live location : ensure it's not sorted randomly 2026-04-17 15:07:54 +02:00
Benoit Marty
269d367130
Merge pull request #6464 from kalix127/feat/reply-with-voice-message
Support replying to messages with voice recordings
2026-04-17 14:49:04 +02:00
Jorge Martin Espinosa
a341a1a59e
Replace rustls-platform-verifier-android.aar with single class (#6610)
* Replace the `rustls-platform-verifier-android.aar` with the actual source code

* Exclude the platform-verifier code from linters

* Add manual update instructions

* Exclude from Kover too
2026-04-17 14:48:50 +02:00
Benoit Marty
4e5542396f
Merge branch 'develop' into feature-oled-black 2026-04-17 14:47:15 +02:00
Valere
d7963ddb5a fixup: missing param 2026-04-17 12:52:25 +02:00
bxdxnn
6a4fed2baf
Natural media viewer swiping order (#6431) 2026-04-17 11:30:21 +02:00
Benoit Marty
47a430978f
Merge pull request #6602 from element-hq/feature/bma/updateSettingsUI
Settings UI update.
2026-04-17 11:30:08 +02:00
Valere
98ececf3d0 Merge branch 'develop' into valere/call/fix_join_button_on_several_items 2026-04-17 10:10:04 +02:00
Valere
6d134375f6 review: pass the RtcNotificationContent in the view to avoid casting 2026-04-17 10:07:22 +02:00
ElementBot
efe76281ad Update screenshots 2026-04-17 09:49:59 +02:00
Benoit Marty
a1c9994385 Settings UI update.
- Reorder items
- Minor UI update
- Improve the previews of the Composable
- Merge manage account and manage devices
- Add missing tests
2026-04-17 09:49:59 +02:00
renovate[bot]
f661ccf25a
Update dependency com.google.firebase:firebase-bom to v34.12.0 (#6604)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-17 09:43:32 +02:00
renovate[bot]
5b3f91ff78
Update dependency org.jetbrains.kotlinx:kotlinx-serialization-json to v1.11.0 (#6605)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-04-17 09:01:20 +02:00
renovate[bot]
555d7acbd3
Update actions/github-script action to v9 2026-04-17 00:03:24 +00:00
ElementBot
2966ccc96d Update screenshots 2026-04-16 15:25:42 +00:00
Valere
3f9b8b822e cleaning: Remove join button from call notify timelineItemView 2026-04-16 16:35:28 +02:00
ganfra
fbfeeae084 Fix formatting 2026-04-16 16:18:53 +02:00
ganfra
6b933b6506 Use "Shared live location" in formatter 2026-04-16 15:52:11 +02:00
ganfra
704ddc9132 Update live location shares when reaching timeout (before actual stop event) 2026-04-16 15:33:42 +02:00
Gianluca Iavicoli
67729f87c9
test: stabilize reply event ID test for voice message composer 2026-04-15 18:17:31 +02:00
ganfra
11866afb03 Remove hardcoded strings 2026-04-15 13:55:54 +02:00
ganfra
f5683f9c8b Improve live location bottomsheet interaction with map 2026-04-15 13:46:31 +02:00
Timur Gilfanov
f7cfa6cda8
Merge branch 'develop' into feature-oled-black 2026-04-14 10:13:46 +04:00
ganfra
e85b532d6a Merge branch 'develop' into feature/fga/live_location_rendering 2026-04-13 22:38:54 +02:00
ganfra
580e85d232 Fix live location share item description 2026-04-13 11:51:48 +02:00
ganfra
537063d899 Add focused location tracking when opening the map 2026-04-10 21:11:30 +02:00
ganfra
0e9af5f42a Refactor live location shares to use callbackFlow 2026-04-10 20:45:18 +02:00
ganfra
7c3b9523df Improve live location UI with empty state 2026-04-10 20:44:05 +02:00
ganfra
9ba8798175 Refactor LiveLocationShare to include structured LastLocation 2026-04-10 14:43:24 +02:00
ganfra
d6999b5334 Merge branch 'develop' into feature/fga/live_location_rendering 2026-04-10 09:50:44 +02:00
Timur Gilfanov
fd92a2eef2 Remove default value for allowBlackTheme in mapToTheme 2026-04-05 12:34:25 +04:00
Timur Gilfanov
43bef7f1df Add isBlackThemeAllowed as a key to theme remember block 2026-04-05 12:34:07 +04:00
Timur Gilfanov
f19295d63d
Merge branch 'develop' into feature-oled-black 2026-04-05 12:06:20 +04:00
Timur Gilfanov
5e6a6af409 Add "Allow black theme" feature flag 2026-04-05 12:03:50 +04:00
ganfra
4e0165458a Live location : start collecting live location 2026-04-03 18:21:37 +02:00
Gianluca Iavicoli
4586ee31ea
fix: re-focus text input after voice recording ends 2026-04-02 22:20:13 +02:00
Gianluca Iavicoli
9a81ec5569
refactor: remove keyboard dismissal logic during voice recording 2026-04-02 22:14:04 +02:00
Timur Gilfanov
104ae4752a Reorder imports to align with static analysis 2026-04-02 18:24:23 +04:00
Timur Gilfanov
d0dcbab750
Merge branch 'develop' into feature-oled-black 2026-03-30 11:08:53 +04:00
Gianluca Iavicoli
37da07a720
Revert unnecessary analytics refactor in voice message presenter 2026-03-27 21:18:55 +01:00
Timur Gilfanov
55d043788b Reorder theme options in AdvancedSettingsState 2026-03-26 09:11:05 +04:00
ganfra
a7e254cc84 Live location : format the endsAt timeline item content 2026-03-25 19:57:34 +01:00
Gianluca Iavicoli
d9a54fb716
fix: persist reply banner during voice recording and dismiss keyboard 2026-03-25 00:58:57 +01:00
Gianluca Iavicoli
4a5662a5e2
fix: reset composer mode after sending voice message reply 2026-03-25 00:55:57 +01:00
Gianluca Iavicoli
bf7ab31517
feat: support sending voice messages as replies 2026-03-25 00:53:57 +01:00
ganfra
b082f59f9c Start implementing LLS timeline item 2026-03-24 16:38:12 +01:00
ganfra
a22c9871e3 Map sdk timeline item for LiveLocation 2026-03-24 15:50:06 +01:00
ElementBot
cea003a929 Update screenshots 2026-03-23 12:23:50 +00:00
Timur Gilfanov
a96c146d30 Introduce "Black" theme and refactor theme handling
* Add `Theme.Black` to the `Theme` enum and update `isDark()` to include it.
* Refactor `ElementTheme` to accept a `Theme` object instead of a `darkTheme` boolean, allowing for more specific color mapping (e.g., setting `bgCanvasDefault` to `Color.Black` for the Black theme).
* Update `AdvancedSettingsPresenter` and `AdvancedSettingsState` to include "Black" as a user-selectable theme option.
* Adjust `ElementThemeApp` and `MaterialTextPreview` to handle the expanded theme selection.
* Add `ElementPreviewBlack` and update existing preview components to support the new theme.
* Update Konsist tests to ensure `@PreviewsDayNight` annotated functions don't have "BlackPreview" suffix.
2026-03-23 15:26:16 +04:00
2346 changed files with 26195 additions and 11663 deletions

View file

@ -34,6 +34,13 @@
"/^org.jetbrains.kotlinx:kotlinx-datetime/", "/^org.jetbrains.kotlinx:kotlinx-datetime/",
], ],
}, },
{
// Keep Guava on the Android variant and ignore jre-only upgrades.
"matchPackageNames": [
"com.google.guava:guava",
],
"allowedVersions": "/-android$/",
},
{ {
// Limit PostHog Android upgrade to one PR per month, the first day of the month // Limit PostHog Android upgrade to one PR per month, the first day of the month
"matchPackageNames": [ "matchPackageNames": [

View file

@ -74,7 +74,7 @@ jobs:
run: ./gradlew :app:assembleGplayDebug app:assembleFDroidDebug -PallWarningsAsErrors=true $CI_GRADLE_ARG_PROPERTIES run: ./gradlew :app:assembleGplayDebug app:assembleFDroidDebug -PallWarningsAsErrors=true $CI_GRADLE_ARG_PROPERTIES
- name: Upload debug APKs - name: Upload debug APKs
if: ${{ matrix.variant == 'debug' }} if: ${{ matrix.variant == 'debug' }}
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with: with:
name: elementx-debug name: elementx-debug
path: | path: |

View file

@ -79,7 +79,7 @@ jobs:
run: ./gradlew :app:assembleGplayDebug -PallWarningsAsErrors=true $CI_GRADLE_ARG_PROPERTIES run: ./gradlew :app:assembleGplayDebug -PallWarningsAsErrors=true $CI_GRADLE_ARG_PROPERTIES
- name: Upload debug Enterprise APKs - name: Upload debug Enterprise APKs
if: ${{ matrix.variant == 'debug' }} if: ${{ matrix.variant == 'debug' }}
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with: with:
name: elementx-enterprise-debug name: elementx-enterprise-debug
path: | path: |

View file

@ -20,7 +20,7 @@ jobs:
if: github.event.pull_request.base.repo.full_name != github.event.pull_request.head.repo.full_name if: github.event.pull_request.base.repo.full_name != github.event.pull_request.head.repo.full_name
steps: steps:
- name: Add auto-generated commit warning - name: Add auto-generated commit warning
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with: with:
script: | script: |
github.rest.issues.createComment({ github.rest.issues.createComment({

View file

@ -36,7 +36,7 @@ jobs:
mkdir -p screenshots/en mkdir -p screenshots/en
cp tests/uitests/src/test/snapshots/images/* screenshots/en cp tests/uitests/src/test/snapshots/images/* screenshots/en
- name: Deploy GitHub Pages - name: Deploy GitHub Pages
uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e # v4.0.0 uses: peaceiris/actions-gh-pages@84c30a85c19949d7eee79c4ff27748b70285e453 # v4.1.0
with: with:
github_token: ${{ secrets.GITHUB_TOKEN }} github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./screenshots publish_dir: ./screenshots

View file

@ -60,7 +60,7 @@ jobs:
ELEMENT_ANDROID_MAPTILER_LIGHT_MAP_ID: ${{ secrets.MAPTILER_LIGHT_MAP_ID }} ELEMENT_ANDROID_MAPTILER_LIGHT_MAP_ID: ${{ secrets.MAPTILER_LIGHT_MAP_ID }}
ELEMENT_ANDROID_MAPTILER_DARK_MAP_ID: ${{ secrets.MAPTILER_DARK_MAP_ID }} ELEMENT_ANDROID_MAPTILER_DARK_MAP_ID: ${{ secrets.MAPTILER_DARK_MAP_ID }}
- name: Upload APK as artifact - name: Upload APK as artifact
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with: with:
name: elementx-apk-maestro name: elementx-apk-maestro
path: | path: |
@ -119,7 +119,7 @@ jobs:
script: | script: |
.github/workflows/scripts/maestro/maestro-local-with-screen-recording.sh app-gplay-x86_64-debug.apk .github/workflows/scripts/maestro/maestro-local-with-screen-recording.sh app-gplay-x86_64-debug.apk
- name: Upload test results - name: Upload test results
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with: with:
name: test-results name: test-results
path: | path: |

View file

@ -58,7 +58,7 @@ jobs:
- name: ✅ Upload kover report - name: ✅ Upload kover report
if: always() if: always()
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with: with:
name: kover-results name: kover-results
path: | path: |
@ -92,7 +92,7 @@ jobs:
run: ./gradlew dependencyCheckAnalyze $CI_GRADLE_ARG_PROPERTIES run: ./gradlew dependencyCheckAnalyze $CI_GRADLE_ARG_PROPERTIES
- name: Upload dependency analysis - name: Upload dependency analysis
if: always() if: always()
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with: with:
name: dependency-analysis name: dependency-analysis
path: build/reports/dependency-check-report.html path: build/reports/dependency-check-report.html

View file

@ -15,7 +15,7 @@ jobs:
steps: steps:
- name: Trigger pipeline - name: Trigger pipeline
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with: with:
github-token: ${{ secrets.ENTERPRISE_ACTIONS_TOKEN }} github-token: ${{ secrets.ENTERPRISE_ACTIONS_TOKEN }}
script: | script: |

View file

@ -17,7 +17,7 @@ jobs:
pull-requests: read pull-requests: read
steps: steps:
- name: Add notice - name: Add notice
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
if: contains(github.event.pull_request.labels.*.name, 'X-Blocked') if: contains(github.event.pull_request.labels.*.name, 'X-Blocked')
with: with:
script: | script: |
@ -32,7 +32,7 @@ jobs:
steps: steps:
- name: Check membership - name: Check membership
if: github.event.pull_request.user.login != 'renovate[bot]' if: github.event.pull_request.user.login != 'renovate[bot]'
uses: tspascoal/get-user-teams-membership@57e9f42acd78f4d0f496b3be4368fc5f62696662 # v3 uses: tspascoal/get-user-teams-membership@818140d631d5f29f26b151afbe4179f87d9ceb5e # v4.0.1
id: teams id: teams
with: with:
username: ${{ github.event.pull_request.user.login }} username: ${{ github.event.pull_request.user.login }}
@ -41,7 +41,7 @@ jobs:
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN_READ_ORG }} GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN_READ_ORG }}
- name: Add label - name: Add label
if: steps.teams.outputs.isTeamMember == 'false' if: steps.teams.outputs.isTeamMember == 'false'
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with: with:
script: | script: |
github.rest.issues.addLabels({ github.rest.issues.addLabels({
@ -63,7 +63,7 @@ jobs:
github.event.pull_request.head.repo.full_name != github.repository github.event.pull_request.head.repo.full_name != github.repository
steps: steps:
- name: Close pull request - name: Close pull request
uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v8.0.0 uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
with: with:
script: | script: |
github.rest.issues.createComment({ github.rest.issues.createComment({

View file

@ -120,7 +120,7 @@ jobs:
run: ./gradlew :tests:konsist:testDebugUnitTest $CI_GRADLE_ARG_PROPERTIES --no-daemon run: ./gradlew :tests:konsist:testDebugUnitTest $CI_GRADLE_ARG_PROPERTIES --no-daemon
- name: Upload reports - name: Upload reports
if: always() if: always()
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with: with:
name: konsist-report name: konsist-report
path: | path: |
@ -199,7 +199,7 @@ jobs:
run: ./gradlew :app:lintGplayDebug :app:lintFdroidDebug lintDebug $CI_GRADLE_ARG_PROPERTIES --continue run: ./gradlew :app:lintGplayDebug :app:lintFdroidDebug lintDebug $CI_GRADLE_ARG_PROPERTIES --continue
- name: Upload reports - name: Upload reports
if: always() if: always()
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with: with:
name: linting-report name: linting-report
path: | path: |
@ -240,7 +240,7 @@ jobs:
run: ./gradlew detekt $CI_GRADLE_ARG_PROPERTIES --no-daemon run: ./gradlew detekt $CI_GRADLE_ARG_PROPERTIES --no-daemon
- name: Upload reports - name: Upload reports
if: always() if: always()
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with: with:
name: detekt-report name: detekt-report
path: | path: |
@ -281,7 +281,7 @@ jobs:
run: ./gradlew ktlintCheck $CI_GRADLE_ARG_PROPERTIES run: ./gradlew ktlintCheck $CI_GRADLE_ARG_PROPERTIES
- name: Upload reports - name: Upload reports
if: always() if: always()
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with: with:
name: ktlint-report name: ktlint-report
path: | path: |
@ -336,7 +336,7 @@ jobs:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with: with:
persist-credentials: false persist-credentials: false
- uses: zizmorcore/zizmor-action@71321a20a9ded102f6e9ce5718a2fcec2c4f70d8 # v0.5.2 - uses: zizmorcore/zizmor-action@b1d7e1fb5de872772f31590499237e7cce841e8e # v0.5.3
upload_reports: upload_reports:
name: Project Check Suite name: Project Check Suite

View file

@ -17,6 +17,7 @@ jobs:
permissions: permissions:
# Need write permissions on PRs to remove the label "Record-Screenshots" # Need write permissions on PRs to remove the label "Record-Screenshots"
pull-requests: write pull-requests: write
contents: write
name: Record screenshots on branch ${{ github.event.pull_request.head.ref || github.ref_name }} name: Record screenshots on branch ${{ github.event.pull_request.head.ref || github.ref_name }}
runs-on: ubuntu-latest runs-on: ubuntu-latest
if: github.event_name == 'workflow_dispatch' || github.event.label.name == 'Record-Screenshots' if: github.event_name == 'workflow_dispatch' || github.event.label.name == 'Record-Screenshots'

View file

@ -57,7 +57,7 @@ jobs:
ELEMENT_CALL_RAGESHAKE_URL: ${{ secrets.ELEMENT_CALL_RAGESHAKE_URL }} ELEMENT_CALL_RAGESHAKE_URL: ${{ secrets.ELEMENT_CALL_RAGESHAKE_URL }}
run: ./gradlew bundleGplayRelease $CI_GRADLE_ARG_PROPERTIES run: ./gradlew bundleGplayRelease $CI_GRADLE_ARG_PROPERTIES
- name: Upload bundle as artifact - name: Upload bundle as artifact
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with: with:
name: elementx-app-gplay-bundle-unsigned name: elementx-app-gplay-bundle-unsigned
path: | path: |
@ -95,7 +95,7 @@ jobs:
ELEMENT_ANDROID_MAPTILER_DARK_MAP_ID: ${{ secrets.MAPTILER_DARK_MAP_ID }} ELEMENT_ANDROID_MAPTILER_DARK_MAP_ID: ${{ secrets.MAPTILER_DARK_MAP_ID }}
run: ./gradlew bundleGplayRelease $CI_GRADLE_ARG_PROPERTIES run: ./gradlew bundleGplayRelease $CI_GRADLE_ARG_PROPERTIES
- name: Upload bundle as artifact - name: Upload bundle as artifact
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with: with:
name: elementx-enterprise-app-gplay-bundle-unsigned name: elementx-enterprise-app-gplay-bundle-unsigned
path: | path: |
@ -139,7 +139,7 @@ jobs:
ELEMENT_ANDROID_MAPTILER_DARK_MAP_ID: ${{ secrets.MAPTILER_DARK_MAP_ID }} ELEMENT_ANDROID_MAPTILER_DARK_MAP_ID: ${{ secrets.MAPTILER_DARK_MAP_ID }}
run: ./gradlew assembleFdroidRelease $CI_GRADLE_ARG_PROPERTIES run: ./gradlew assembleFdroidRelease $CI_GRADLE_ARG_PROPERTIES
- name: Upload apks as artifact - name: Upload apks as artifact
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with: with:
name: elementx-app-fdroid-apks-unsigned name: elementx-app-fdroid-apks-unsigned
path: | path: |

View file

@ -40,7 +40,7 @@ jobs:
./tools/localazy/importSupportedLocalesFromLocalazy.py ./tools/localazy/importSupportedLocalesFromLocalazy.py
./tools/test/generateAllScreenshots.py ./tools/test/generateAllScreenshots.py
- name: Create Pull Request for Strings - name: Create Pull Request for Strings
uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8.1.0 uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8.1.1
with: with:
token: ${{ secrets.DANGER_GITHUB_API_TOKEN }} token: ${{ secrets.DANGER_GITHUB_API_TOKEN }}
commit-message: Sync Strings from Localazy commit-message: Sync Strings from Localazy

View file

@ -27,7 +27,7 @@ jobs:
- name: Run SAS String script - name: Run SAS String script
run: ./tools/sas/import_sas_strings.py run: ./tools/sas/import_sas_strings.py
- name: Create Pull Request for SAS Strings - name: Create Pull Request for SAS Strings
uses: peter-evans/create-pull-request@c0f553fe549906ede9cf27b5156039d195d2ece0 # v8.1.0 uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8.1.1
with: with:
commit-message: Sync SAS Strings commit-message: Sync SAS Strings
title: Sync SAS Strings title: Sync SAS Strings

View file

@ -77,7 +77,7 @@ jobs:
- name: 🚫 Upload kover failed coverage reports - name: 🚫 Upload kover failed coverage reports
if: failure() if: failure()
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with: with:
name: kover-error-report name: kover-error-report
path: | path: |
@ -89,7 +89,7 @@ jobs:
- name: 🚫 Upload test results on error - name: 🚫 Upload test results on error
if: failure() if: failure()
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with: with:
name: tests-and-screenshot-tests-results name: tests-and-screenshot-tests-results
path: | path: |
@ -108,7 +108,7 @@ jobs:
# https://github.com/codecov/codecov-action # https://github.com/codecov/codecov-action
- name: ☂️ Upload coverage reports to codecov - name: ☂️ Upload coverage reports to codecov
uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6.0.0 uses: codecov/codecov-action@e79a6962e0d4c0c17b229090214935d2e33f8354 # v6.0.1
with: with:
fail_ci_if_error: true fail_ci_if_error: true
token: ${{ secrets.CODECOV_TOKEN }} token: ${{ secrets.CODECOV_TOKEN }}

View file

@ -10,7 +10,7 @@ jobs:
triage-new-issues: triage-new-issues:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/add-to-project@244f685bbc3b7adfa8466e08b698b5577571133e # v1.0.2 - uses: actions/add-to-project@5afcf98fcd03f1c2f92c3c83f58ae24323cc57fd # v2
with: with:
project-url: https://github.com/orgs/element-hq/projects/91 project-url: https://github.com/orgs/element-hq/projects/91
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }} github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}

View file

@ -14,7 +14,7 @@ jobs:
if: > if: >
github.repository == 'element-hq/element-x-android' github.repository == 'element-hq/element-x-android'
steps: steps:
- uses: actions/add-to-project@244f685bbc3b7adfa8466e08b698b5577571133e # v1.0.2 - uses: actions/add-to-project@5afcf98fcd03f1c2f92c3c83f58ae24323cc57fd # v2
with: with:
project-url: https://github.com/orgs/element-hq/projects/43 project-url: https://github.com/orgs/element-hq/projects/43
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }} github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
@ -23,7 +23,7 @@ jobs:
name: Move triaged needs info issues on board name: Move triaged needs info issues on board
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/add-to-project@244f685bbc3b7adfa8466e08b698b5577571133e # v1.0.2 - uses: actions/add-to-project@5afcf98fcd03f1c2f92c3c83f58ae24323cc57fd # v2
id: addItem id: addItem
with: with:
project-url: https://github.com/orgs/element-hq/projects/91 project-url: https://github.com/orgs/element-hq/projects/91
@ -47,7 +47,7 @@ jobs:
if: > if: >
contains(github.event.issue.labels.*.name, 'Team: Element X Feature') contains(github.event.issue.labels.*.name, 'Team: Element X Feature')
steps: steps:
- uses: actions/add-to-project@244f685bbc3b7adfa8466e08b698b5577571133e # v1.0.2 - uses: actions/add-to-project@5afcf98fcd03f1c2f92c3c83f58ae24323cc57fd # v2
with: with:
project-url: https://github.com/orgs/element-hq/projects/73 project-url: https://github.com/orgs/element-hq/projects/73
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }} github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
@ -58,7 +58,7 @@ jobs:
if: > if: >
contains(github.event.issue.labels.*.name, 'Team: Verticals Feature') contains(github.event.issue.labels.*.name, 'Team: Verticals Feature')
steps: steps:
- uses: actions/add-to-project@244f685bbc3b7adfa8466e08b698b5577571133e # v1.0.2 - uses: actions/add-to-project@5afcf98fcd03f1c2f92c3c83f58ae24323cc57fd # v2
with: with:
project-url: https://github.com/orgs/element-hq/projects/57 project-url: https://github.com/orgs/element-hq/projects/57
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }} github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
@ -70,7 +70,7 @@ jobs:
contains(github.event.issue.labels.*.name, 'Team: QA') || contains(github.event.issue.labels.*.name, 'Team: QA') ||
contains(github.event.issue.labels.*.name, 'X-Needs-Signoff') contains(github.event.issue.labels.*.name, 'X-Needs-Signoff')
steps: steps:
- uses: actions/add-to-project@244f685bbc3b7adfa8466e08b698b5577571133e # v1.0.2 - uses: actions/add-to-project@5afcf98fcd03f1c2f92c3c83f58ae24323cc57fd # v2
with: with:
project-url: https://github.com/orgs/element-hq/projects/69 project-url: https://github.com/orgs/element-hq/projects/69
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }} github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
@ -81,7 +81,7 @@ jobs:
if: > if: >
contains(github.event.issue.labels.*.name, 'X-Needs-Signoff') contains(github.event.issue.labels.*.name, 'X-Needs-Signoff')
steps: steps:
- uses: actions/add-to-project@244f685bbc3b7adfa8466e08b698b5577571133e # v1.0.2 - uses: actions/add-to-project@5afcf98fcd03f1c2f92c3c83f58ae24323cc57fd # v2
with: with:
project-url: https://github.com/orgs/element-hq/projects/89 project-url: https://github.com/orgs/element-hq/projects/89
github-token: ${{ secrets.ELEMENT_BOT_TOKEN }} github-token: ${{ secrets.ELEMENT_BOT_TOKEN }}

3
.idea/kotlinc.xml generated
View file

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="KotlinJpsPluginSettings"> <component name="KotlinJpsPluginSettings">
<option name="version" value="2.3.20" /> <option name="externalSystemId" value="Gradle" />
<option name="version" value="2.3.21" />
</component> </component>
</project> </project>

View file

@ -7,7 +7,7 @@ appId: ${MAESTRO_APP_ID}
- tapOn: - tapOn:
text: ${MAESTRO_INVITEE1_MXID} text: ${MAESTRO_INVITEE1_MXID}
index: 1 index: 1
- tapOn: "Send invite" - tapOn: "Continue"
- takeScreenshot: build/maestro/330-createAndDeleteDM - takeScreenshot: build/maestro/330-createAndDeleteDM
- tapOn: "maestroelement2" - tapOn: "maestroelement2"
- scroll - scroll

View file

@ -24,8 +24,16 @@ appId: ${MAESTRO_APP_ID}
text: ${MAESTRO_INVITEE2_MXID} text: ${MAESTRO_INVITEE2_MXID}
index: 1 index: 1
- tapOn: "Invite" - tapOn: "Invite"
- runFlow:
when:
visible: 'Invite new contact to this room?'
commands:
- tapOn:
id: "confirm_invite_unknown"
# Close the keyboard if it's still open
- tapOn: "Back"
# Go back to the room details screen
- tapOn: "Back" - tapOn: "Back"
- tapOn: "aRoomName"
- scrollUntilVisible: - scrollUntilVisible:
direction: DOWN direction: DOWN
element: element:

View file

@ -1,3 +1,213 @@
Changes in Element X v26.05.2
=============================
<!-- Release notes generated using configuration in .github/release.yml at v26.05.2 -->
## What's Changed
### ✨ Features
* Remove SignInWithClassic FeatureFlag to enable the feature. by @bmarty in https://github.com/element-hq/element-x-android/pull/6698
* Create a new room when inviting people in a DM by @jmartinesp in https://github.com/element-hq/element-x-android/pull/6756
* Remove LiveLocationSharing feature flag by @ganfra in https://github.com/element-hq/element-x-android/pull/6811
### 🙌 Improvements
* Disable biometric unlock when we disable pin code unlock by @jmartinesp in https://github.com/element-hq/element-x-android/pull/6781
### 🐛 Bugfixes
* Fix room list duplicate-detection telemetry crashing before it can report by @jennaharris7 in https://github.com/element-hq/element-x-android/pull/6791
* Only load full media on media viewer when it's the visible item by @jmartinesp in https://github.com/element-hq/element-x-android/pull/6794
* Attempt to fix room list item duplicates at midnight by @jmartinesp in https://github.com/element-hq/element-x-android/pull/6793
### 🗣 Translations
* Sync Strings by @ElementBot in https://github.com/element-hq/element-x-android/pull/6798
### 🧱 Build
* Fix Maestro again after changes to the invite flow by @jmartinesp in https://github.com/element-hq/element-x-android/pull/6796
* Renovate: Keep Guava on the Android variant and ignore jre-only upgrades by @bmarty in https://github.com/element-hq/element-x-android/pull/6776
### Dependency upgrades
* Update dependency androidx.compose:compose-bom to v2026.05.00 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6784
* Update dependency io.sentry:sentry-android to v8.41.0 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6787
* Update kotlin by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6790
* Update camera to v1.6.1 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6783
* Update dependency androidx.webkit:webkit to v1.16.0 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6786
* Update dependency com.google.firebase:firebase-bom to v34.13.0 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6789
* Update dependency org.matrix.rustcomponents:sdk-android to v26.05.18 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6805
### Others
* Add MIDI playback by @cizra in https://github.com/element-hq/element-x-android/pull/6770
* Show error message when using "Sign in with QR code" with a QR from a device that is also not signed in by @hughns in https://github.com/element-hq/element-x-android/pull/6802
## New Contributors
* @jennaharris7 made their first contribution in https://github.com/element-hq/element-x-android/pull/6791
* @cizra made their first contribution in https://github.com/element-hq/element-x-android/pull/6770
**Full Changelog**: https://github.com/element-hq/element-x-android/compare/v26.05.1...v26.05.2
Changes in Element X v26.05.1
=============================
<!-- Release notes generated using configuration in .github/release.yml at v26.05.1 -->
## What's Changed
### ✨ Features
* Make Element Call screen work edge-to-edge by @jmartinesp in https://github.com/element-hq/element-x-android/pull/6634
### 🙌 Improvements
* Stop removing the `logs` dir when clearing cache by @jmartinesp in https://github.com/element-hq/element-x-android/pull/6765
* Adapt to new DM definition changes in the SDK by @jmartinesp in https://github.com/element-hq/element-x-android/pull/6748
* feat: Update call started timeline item + declined support by @BillCarsonFr in https://github.com/element-hq/element-x-android/pull/6649
### 🐛 Bugfixes
* Improve pin code UX by @bmarty in https://github.com/element-hq/element-x-android/pull/6744
* Use just the other user's avatar for DM details by @jmartinesp in https://github.com/element-hq/element-x-android/pull/6738
* Improve `FetchPushForegroundService`'s reliability by @jmartinesp in https://github.com/element-hq/element-x-android/pull/6757
* Prevent user from starting Live Location Sharing in thread by @bmarty in https://github.com/element-hq/element-x-android/pull/6767
* Fix media playback from the timeline broken when exiting a thread by @bmarty in https://github.com/element-hq/element-x-android/pull/6771
* Pin code: remove the key if there is no pin code by @bmarty in https://github.com/element-hq/element-x-android/pull/6780
### 🗣 Translations
* Sync Strings by @ElementBot in https://github.com/element-hq/element-x-android/pull/6761
### 🚧 In development 🚧
* Feature : share live location by @ganfra in https://github.com/element-hq/element-x-android/pull/6741
### Dependency upgrades
* Update dependency org.matrix.rustcomponents:sdk-android to v26.05.7 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6746
* Update actions/add-to-project action to v2 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6758
* Update dependency io.github.sergio-sastre.ComposablePreviewScanner:android to v0.9.0 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6759
* Update dependency io.element.android:element-call-embedded to v0.19.3 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6766
* Update metro to v1 (major) by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6720
* Update tspascoal/get-user-teams-membership action to v4.0.1 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6750
* Update plugin sonarqube to v7.3.0.8198 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6743
* Update plugin dependencycheck to v12.2.2 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6760
* Update dependency com.google.guava:guava to v33.6.0-android by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6646
* Update dependency org.matrix.rustcomponents:sdk-android to v26.05.13 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6779
### Others
* Render media captions formatting in the media viewer by @bxdxnn in https://github.com/element-hq/element-x-android/pull/6729
* Reduce FeatureFlag `Knock` effect on room creation and room edition forms by @bmarty in https://github.com/element-hq/element-x-android/pull/6768
* Use the right analytics span as a parent in `checkNetworkConnection` by @jmartinesp in https://github.com/element-hq/element-x-android/pull/6751
* Add missing strings `theme.black` by @bmarty in https://github.com/element-hq/element-x-android/pull/6772
* Map back button in web view to esc (revive fixed version of: https://github.com/element-hq/element-x-android/pull/6724) by @toger5 in https://github.com/element-hq/element-x-android/pull/6725
**Full Changelog**: https://github.com/element-hq/element-x-android/compare/v26.05.0...v26.05.1
Changes in Element X v26.05.0
=============================
<!-- Release notes generated using configuration in .github/release.yml at v26.05.0 -->
## What's Changed
### ✨ Features
* Add flag for automatic back pagination feature by @jmartinesp in https://github.com/element-hq/element-x-android/pull/6637
* Promote "history sharing on invite" out of developer options by @richvdh in https://github.com/element-hq/element-x-android/pull/6647
* Remove RoomDirectorySearch feature flag — always enable the feature by @Copilot in https://github.com/element-hq/element-x-android/pull/6736
### 🙌 Improvements
* Change native back button behavior in EC view (close settings in EC with os native back) by @toger5 in https://github.com/element-hq/element-x-android/pull/6642
* Revert PR #6642 by @jmartinesp in https://github.com/element-hq/element-x-android/pull/6724
* Use 'Report a problem' string instead of 'Report bug' by @jmartinesp in https://github.com/element-hq/element-x-android/pull/6735
### 🐛 Bugfixes
* Remove distributed tracing of the 'timeline loading' flow by @jmartinesp in https://github.com/element-hq/element-x-android/pull/6644
* Set max lines for 'in reply to' view conditionally by @jmartinesp in https://github.com/element-hq/element-x-android/pull/6612
* Mention pill cut off by @bmarty in https://github.com/element-hq/element-x-android/pull/6651
* Ensure that bottom sheet can scroll by @bmarty in https://github.com/element-hq/element-x-android/pull/6661
* Remove legacy `mx-reply` from `toPlainText` formatted event contents by @jmartinesp in https://github.com/element-hq/element-x-android/pull/6683
* Fix ANRs when receiving push notifications by @jmartinesp in https://github.com/element-hq/element-x-android/pull/6696
* Mitigate a deadlock when loading room timelines by @jmartinesp in https://github.com/element-hq/element-x-android/pull/6674
* Fix calls on Huawei devices: skip addWebMessageListener on Chromium < 119 by @manfrommedan in https://github.com/element-hq/element-x-android/pull/6640
* Allow cancelling room loading in Home screen by @jmartinesp in https://github.com/element-hq/element-x-android/pull/6723
* Let our Json parser accept comments and trailing comma. by @bmarty in https://github.com/element-hq/element-x-android/pull/6700
* Fix low width image message by @krbns in https://github.com/element-hq/element-x-android/pull/6692
* Make icons in the Chat screen top bar 16dp by @jmartinesp in https://github.com/element-hq/element-x-android/pull/6733
* Fix back button sometimes not working after exiting a thread by @jmartinesp in https://github.com/element-hq/element-x-android/pull/6732
* Make send event state UI easier to click by @jmartinesp in https://github.com/element-hq/element-x-android/pull/6739
### 🗣 Translations
* Sync Strings by @ElementBot in https://github.com/element-hq/element-x-android/pull/6658
* Sync Strings by @ElementBot in https://github.com/element-hq/element-x-android/pull/6716
### 🧱 Build
* Fix record screenshots action permissions by @jmartinesp in https://github.com/element-hq/element-x-android/pull/6679
* Fix dependency error by @bmarty in https://github.com/element-hq/element-x-android/pull/6697
### 🚧 In development 🚧
* [Link new device] Add missing screen to render digits that the user has to type on the other device by @bmarty in https://github.com/element-hq/element-x-android/pull/6680
### Dependency upgrades
* Update dependency io.nlopez.compose.rules:detekt to v0.5.7 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6594
* Update zizmorcore/zizmor-action action to v0.5.3 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6630
* Update dependency io.sentry:sentry-android to v8.38.0 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6597
* fix(deps): update camera to v1.6.0 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6514
* Update dependency io.sentry:sentry-android to v8.39.1 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6648
* Update dependency io.element.android:element-call-embedded to v0.19.2 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6662
* Update dependencyAnalysis to v3.9.0 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6657
* Update dependency org.matrix.rustcomponents:sdk-android to v26.04.27 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6666
* Update dependency io.sentry:sentry-android to v8.40.0 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6691
* Update dependency org.jsoup:jsoup to v1.22.2 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6660
* Update kotlin by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6687
* Update dependency androidx.compose:compose-bom to v2026.04.01 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6693
* Update dependency io.nlopez.compose.rules:detekt to v0.5.8 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6711
* Update dependency com.posthog:posthog-android to v3.43.0 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6704
* Update dependency org.matrix.rustcomponents:sdk-android to v26.05.4 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6718
* Update roborazzi to v1.60.0 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6722
* Update dependency net.zetetic:sqlcipher-android to v4.15.0 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6727
* Update dependency org.maplibre.gl:android-sdk to v13.1.0 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6731
* Update dependency org.matrix.rustcomponents:sdk-android to v26.05.6 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6734
* Update dependencyAnalysis to v3.10.0 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6742
* Update tspascoal/get-user-teams-membership action to v4 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6747
### Others
* devx: fix build sdk script options for macos by @BillCarsonFr in https://github.com/element-hq/element-x-android/pull/6636
* PR:Fix mention pill cut off by @krbns in https://github.com/element-hq/element-x-android/pull/6622
* Update media viewer UI by @bmarty in https://github.com/element-hq/element-x-android/pull/6643
* Strip formatting from media captions in room summary by @bxdxnn in https://github.com/element-hq/element-x-android/pull/6670
* Update error mappings for Link new device flow by @hughns in https://github.com/element-hq/element-x-android/pull/6677
* Rename `OIDC` components and variables to `OAuth` by @jmartinesp in https://github.com/element-hq/element-x-android/pull/6686
* [Link new device] Add missing error case "already signed in" by @bmarty in https://github.com/element-hq/element-x-android/pull/6688
* Improve detection of completion for Link new device flow by @hughns in https://github.com/element-hq/element-x-android/pull/6681
* Remove external call support by @bmarty in https://github.com/element-hq/element-x-android/pull/6668
* [a11y] Fix a set of issues by @bmarty in https://github.com/element-hq/element-x-android/pull/6650
* Add clipping to RoomSummaryRow by @bxdxnn in https://github.com/element-hq/element-x-android/pull/6654
* Fix media viewer flickering and crashing by @bxdxnn in https://github.com/element-hq/element-x-android/pull/6715
* Rename verification methods by @bmarty in https://github.com/element-hq/element-x-android/pull/6726
* Add a way to tweak MAS url. by @bmarty in https://github.com/element-hq/element-x-android/pull/6682
* Fix 2 x Crash the app in Developer Options - Update AppDeveloperSettingsView.kt by @escix in https://github.com/element-hq/element-x-android/pull/6708
* Introduce UI sample by @bmarty in https://github.com/element-hq/element-x-android/pull/6740
## New Contributors
* @krbns made their first contribution in https://github.com/element-hq/element-x-android/pull/6622
* @toger5 made their first contribution in https://github.com/element-hq/element-x-android/pull/6642
* @manfrommedan made their first contribution in https://github.com/element-hq/element-x-android/pull/6640
* @Copilot made their first contribution in https://github.com/element-hq/element-x-android/pull/6736
**Full Changelog**: https://github.com/element-hq/element-x-android/compare/v26.04.4...v26.05.0
Changes in Element X v26.04.4
=============================
<!-- Release notes generated using configuration in .github/release.yml at v26.04.4 -->
## What's Changed
### 🙌 Improvements
* Natural media viewer swiping order by @bxdxnn in https://github.com/element-hq/element-x-android/pull/6431
* Replace `rustls-platform-verifier-android.aar` with single class by @jmartinesp in https://github.com/element-hq/element-x-android/pull/6610
* Cleanup FetchPushForegroundService by @jmartinesp in https://github.com/element-hq/element-x-android/pull/6577
* cleaning: Remove join button from call notify timelineItemView by @BillCarsonFr in https://github.com/element-hq/element-x-android/pull/6603
### 🐛 Bugfixes
* Fix crash when going back to threads list by @bxdxnn in https://github.com/element-hq/element-x-android/pull/6620
* audio: Let EC decide alone what communication device to use by @BillCarsonFr in https://github.com/element-hq/element-x-android/pull/6609
* Fix media viewer bottom sheets not being scrollable by @jmartinesp in https://github.com/element-hq/element-x-android/pull/6631
### 🗣 Translations
* Sync Strings by @ElementBot in https://github.com/element-hq/element-x-android/pull/6626
### 📄 Documentation
* Updates to new features and some refactoring. by @mxandreas in https://github.com/element-hq/element-x-android/pull/6591
### 🚧 In development 🚧
* WIP : live location rendering by @ganfra in https://github.com/element-hq/element-x-android/pull/6611
### Dependency upgrades
* Update dependency io.element.android:element-call-embedded to v0.19.1 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6593
* Update dependency androidx.annotation:annotation-jvm to v1.10.0 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6596
* Update dependency org.jetbrains.kotlinx:kotlinx-serialization-json to v1.11.0 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6605
* Update dependency com.google.firebase:firebase-bom to v34.12.0 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6604
* Update actions/upload-artifact action to v7.0.1 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6614
* Update plugin dependencycheck to v12.2.1 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6621
* Update actions/github-script action to v9 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6606
* Update peter-evans/create-pull-request action to v8.1.1 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6615
* Update dependencyAnalysis to v3.7.0 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6616
* Update dependency org.matrix.rustcomponents:sdk-android to v26.04.21 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/6635
### Others
* Settings UI update. by @bmarty in https://github.com/element-hq/element-x-android/pull/6602
* Support replying to messages with voice recordings by @kalix127 in https://github.com/element-hq/element-x-android/pull/6464
* Add Black theme option for battery saving on OLED displays by @timurgilfanov in https://github.com/element-hq/element-x-android/pull/6441
* Fix | When selecting earpiece twice in a row the proximity sensor get wrongly disabled by @BillCarsonFr in https://github.com/element-hq/element-x-android/pull/6627
* Update wording of deactivate account screen by @bmarty in https://github.com/element-hq/element-x-android/pull/6633
**Full Changelog**: https://github.com/element-hq/element-x-android/compare/v26.04.3...v26.04.4
Changes in Element X v26.04.3 Changes in Element X v26.04.3
============================= =============================

View file

@ -2,16 +2,16 @@
<!--- TOC --> <!--- TOC -->
* [Developer onboarding](#developer-onboarding) * [Contributing to Element](#contributing-to-element)
* [Contributing code to Matrix](#contributing-code-to-matrix)
* [Android Studio settings](#android-studio-settings)
* [Compilation](#compilation)
* [Strings](#strings)
* [I want to add new strings to the project](#i-want-to-add-new-strings-to-the-project)
* [I want to help translating Element](#i-want-to-help-translating-element) * [I want to help translating Element](#i-want-to-help-translating-element)
* [I want to fix a bug](#i-want-to-fix-a-bug)
* [I want to add a new feature or enhancement](#i-want-to-add-a-new-feature-or-enhancement)
* [Developer onboarding](#developer-onboarding)
* [Submitting the PRs](#submitting-the-prs)
* [Android Studio settings](#android-studio-settings)
* [Compilation](#compilation)
* [Strings](#strings)
* [Element X Android Gallery](#element-x-android-gallery) * [Element X Android Gallery](#element-x-android-gallery)
* [I want to add a new feature to Element X Android](#i-want-to-add-a-new-feature-to-element-x-android)
* [I want to submit a PR to fix an issue](#i-want-to-submit-a-pr-to-fix-an-issue)
* [Kotlin](#kotlin) * [Kotlin](#kotlin)
* [Changelog](#changelog) * [Changelog](#changelog)
* [Code quality](#code-quality) * [Code quality](#code-quality)
@ -29,69 +29,67 @@
<!--- END --> <!--- END -->
## Developer onboarding ## Contributing to Element
For a detailed overview of the project, see [Developer Onboarding](./docs/_developer_onboarding.md).
## Contributing code to Matrix
If instead of contributing to the Element X Android project, you want to contribute to Synapse, the homeserver implementation, please read the [Synapse contribution guide](https://element-hq.github.io/synapse/latest/development/contributing_guide.html).
Element X Android support can be found in this room: [![Element X Android Matrix room #element-x-android:matrix.org](https://img.shields.io/matrix/element-x-android:matrix.org.svg?label=%23element-x-android:matrix.org&logo=matrix&server_fqdn=matrix.org)](https://matrix.to/#/#element-x-android:matrix.org). Element X Android support can be found in this room: [![Element X Android Matrix room #element-x-android:matrix.org](https://img.shields.io/matrix/element-x-android:matrix.org.svg?label=%23element-x-android:matrix.org&logo=matrix&server_fqdn=matrix.org)](https://matrix.to/#/#element-x-android:matrix.org).
The rest of the document contains specific rules for Matrix Android projects. The rest of the document contains specific rules for Matrix Android projects.
## Android Studio settings
Please set the "hard wrap" setting of Android Studio to 160 chars, this is the setting we use internally to format the source code (Menu `Settings/Editor/Code Style` then `Hard wrap at`).
Please ensure that you're using the project formatting rules (which are in the project at .idea/codeStyles/), and format the file before committing them.
## Compilation
This project should compile without any special action. Just clone it and open it with Android Studio, or compile from command line using `gradlew`.
## Strings
The strings of the project are managed externally using [https://localazy.com](https://localazy.com) and shared with Element X iOS.
### I want to add new strings to the project
Only the core team can modify or add English strings to Localazy. As an external contributor, if you want to add new strings, feel free to add an Android resource file to the project (for instance a file named `temporary.xml`), with a note in the description of the PR for the reviewer to integrate the String into `Localazy`. If accepted, the reviewer will add the String(s) for you, and then you can download them on your branch (following these [instructions](./tools/localazy/README.md#download-translations)) and remove the temporary file.
Please follow the naming rules for the key. More details in [the dedicated section in this README.md](./tools/localazy/README.md#key-naming-rules)
### I want to help translating Element ### I want to help translating Element
To help translating, please go to [https://localazy.com/p/element](https://localazy.com/p/element). To help translating, please go to [https://localazy.com/p/element](https://localazy.com/p/element).
- If you want to fix an issue with an English string, please open an issue on the github project of Element X (Android or iOS). Only the core team can modify or add English strings.
- If you want to fix an issue in other languages, or add a missing translation, or even add a new language, please go to [https://localazy.com/p/element](https://localazy.com/p/element). - If you want to fix an issue in other languages, or add a missing translation, or even add a new language, please go to [https://localazy.com/p/element](https://localazy.com/p/element).
- If you want to fix an issue with an English string, please open an issue on the github project of Element X (Android or iOS). Only the core team can modify or add English strings. As an external contributor, if you want to add new strings, feel free to add an Android resource file to the project (for instance a file named `temporary.xml`), with a note in the description of the PR for the reviewer to integrate the String into `Localazy`. If accepted, the reviewer will add the String(s) for you, and then you can download them on your branch (following these [instructions](./tools/localazy/README.md#download-translations)) and remove the temporary file. Please follow the naming rules for the key. More details in [the dedicated section in this README.md](./tools/localazy/README.md#key-naming-rules) More information can be found [in this README.md](./tools/localazy/README.md).
More information can be found [in this README.md](./tools/localazy/README.md).
Once a language is sufficiently translated, it will be added to the app. The core team will decide when a language is sufficiently translated. Once a language is sufficiently translated, it will be added to the app. The core team will decide when a language is sufficiently translated.
### I want to fix a bug
Please check if a corresponding issue exists, if not please create one. In both cases, let us know in the comment that you've started working on it.
### I want to add a new feature or enhancement
To make a great product with a great user experience, all the small efforts need to go in the same direction and be aligned and consistent with each other.
Before making your contribution, please consider the following:
* One product cant do everything well. Element is focusing on private end-to-end encrypted messaging and voice - this can either be for consumers (e.g. friends and family) or for professional teams and organizations. Public forums and other types of chats without E2EE remain supported but are not the primary use case in case UX compromises need to be made.
* There are 3 platforms - Android, [iOS](https://github.com/element-hq/element-x-ios) and [Web/Desktop](https://github.com/element-hq/element-web). These platforms need to have feature parity and design consistency. For some features, supporting all platforms is a must have, in some cases exceptions can be made to have it on one platform only.
* To make sure your idea fits both from a design/solution and use case perspective, please open a new issue (or find an existing issue) in [element-meta](https://github.com/element-hq/element-meta/issues) repository describing the use case and how you plan to tackle it. Do not just describe what feature is missing, explain why the users need it with a couple of real life examples from the field.
* In case of an existing issue, please comment that you're planning to contribute. If you create a new issue, please specify that in the issue. In such a case we will try to review the issue ASAP and provide you with initial feedback so you can be confident if and at which conditions your contributions will be accepted.
Once we know that you want to contribute and have confirmed that the new feature is overall aligned with the product direction, the designers of the core team will help you with the designs and any other type of guidance when it comes to the user experience. We will try to unblock you as quickly as we can, but it may not be instant. Having a clear understanding of the use case and the impact of the feature will help us with the prioritization and faster responses.
Only once all of the above is met should you open a PR with your proposed changes.
## Developer onboarding
For a detailed overview of the project, see [Developer Onboarding](./docs/_developer_onboarding.md).
### Submitting the PRs
Please have a look in the [dedicated documentation](./docs/pull_request.md) about pull request.
### Android Studio settings
Please set the "hard wrap" setting of Android Studio to 160 chars, this is the setting we use internally to format the source code (Menu `Settings/Editor/Code Style` then `Hard wrap at`).
Please ensure that you're using the project formatting rules (which are in the project at .idea/codeStyles/), and format the file before committing them.
### Compilation
This project should compile without any special action. Just clone it and open it with Android Studio, or compile from command line using `gradlew`.
### Strings
The strings of the project are managed externally using [https://localazy.com](https://localazy.com) and shared with Element X iOS.
### Element X Android Gallery ### Element X Android Gallery
Once added to Localazy, translations can be checked screen per screen using our tool Element X Android Gallery, available at https://element-hq.github.io/element-x-android/. Once added to Localazy, translations can be checked screen per screen using our tool Element X Android Gallery, available at https://element-hq.github.io/element-x-android/.
Localazy syncs occur every Monday and the screenshots on this page are generated every Tuesday, so you'll have to wait to see your change appearing on Element X Android Gallery. Localazy syncs occur every Monday and the screenshots on this page are generated every Tuesday, so you'll have to wait to see your change appearing on Element X Android Gallery.
## I want to add a new feature to Element X Android
Thank you for contributing to the project! Please have a look in the [dedicated documentation](./docs/pull_request.md) about pull request.
Also, please keep in mind that any feature added to Element X Android needs to be added to [the iOS client](https://github.com/element-hq/element-x-ios) too, unless it's related to an Android OS only behaviour.
**IMPORTANT:** if you are adding new screens or modifying existing ones, this needs acceptance from the product and design teams before being merged. For this, it's better to start with a [feature request issue](https://github.com/element-hq/element-x-android/issues/new?template=enhancement.yml) describing the change you want to make and the motivation behind it instead of directly creating a pull request. This will allow the product and design teams to give feedback on the change before you start working on it, and avoid you doing work that might end up being rejected.
## I want to submit a PR to fix an issue
Please have a look in the [dedicated documentation](./docs/pull_request.md) about pull request.
Please check if a corresponding issue exists. If yes, please let us know in a comment that you're working on it.
If an issue does not exist yet, it may be relevant to open a new issue and let us know that you're implementing it.
### Kotlin ### Kotlin
This project is full Kotlin. Please do not write Java classes. This project is full Kotlin. Please do not write Java classes.

View file

@ -103,13 +103,13 @@ android {
logger.warnInBox("Building ${defaultConfig.applicationId} ($baseAppName) [$buildType]") logger.warnInBox("Building ${defaultConfig.applicationId} ($baseAppName) [$buildType]")
buildTypes { buildTypes {
val oidcRedirectSchemeBase = BuildTimeConfig.METADATA_HOST_REVERSED ?: "io.element.android" val oAuthRedirectSchemeBase = BuildTimeConfig.METADATA_HOST_REVERSED ?: "io.element.android"
getByName("debug") { getByName("debug") {
resValue("string", "app_name", "$baseAppName dbg") resValue("string", "app_name", "$baseAppName dbg")
resValue( resValue(
"string", "string",
"login_redirect_scheme", "login_redirect_scheme",
"$oidcRedirectSchemeBase.debug", "$oAuthRedirectSchemeBase.debug",
) )
applicationIdSuffix = ".debug" applicationIdSuffix = ".debug"
signingConfig = signingConfigs.getByName("debug") signingConfig = signingConfigs.getByName("debug")
@ -120,7 +120,7 @@ android {
resValue( resValue(
"string", "string",
"login_redirect_scheme", "login_redirect_scheme",
oidcRedirectSchemeBase, oAuthRedirectSchemeBase,
) )
signingConfig = signingConfigs.getByName("debug") signingConfig = signingConfigs.getByName("debug")
@ -157,7 +157,7 @@ android {
resValue( resValue(
"string", "string",
"login_redirect_scheme", "login_redirect_scheme",
"$oidcRedirectSchemeBase.nightly", "$oAuthRedirectSchemeBase.nightly",
) )
matchingFallbacks += listOf("release") matchingFallbacks += listOf("release")
signingConfig = signingConfigs.getByName("nightly") signingConfig = signingConfigs.getByName("nightly")

View file

@ -75,7 +75,7 @@
android:scheme="elementx" /> android:scheme="elementx" />
</intent-filter> </intent-filter>
<!-- <!--
Oidc redirection OAuth redirection
--> -->
<intent-filter> <intent-filter>
<action android:name="android.intent.action.VIEW" /> <action android:name="android.intent.action.VIEW" />

View file

@ -71,6 +71,7 @@ class MainActivity : NodeActivity() {
}.collectAsState(SemanticColorsLightDark.default) }.collectAsState(SemanticColorsLightDark.default)
ElementThemeApp( ElementThemeApp(
appPreferencesStore = appBindings.preferencesStore(), appPreferencesStore = appBindings.preferencesStore(),
featureFlagService = appBindings.featureFlagService(),
compoundLight = colors.light, compoundLight = colors.light,
compoundDark = colors.dark, compoundDark = colors.dark,
buildMeta = appBindings.buildMeta() buildMeta = appBindings.buildMeta()

View file

@ -10,14 +10,14 @@ package io.element.android.x.oidc
import dev.zacsweers.metro.AppScope import dev.zacsweers.metro.AppScope
import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.ContributesBinding
import io.element.android.libraries.matrix.api.auth.OidcRedirectUrlProvider import io.element.android.libraries.matrix.api.auth.OAuthRedirectUrlProvider
import io.element.android.services.toolbox.api.strings.StringProvider import io.element.android.services.toolbox.api.strings.StringProvider
import io.element.android.x.R import io.element.android.x.R
@ContributesBinding(AppScope::class) @ContributesBinding(AppScope::class)
class DefaultOidcRedirectUrlProvider( class DefaultOAuthRedirectUrlProvider(
private val stringProvider: StringProvider, private val stringProvider: StringProvider,
) : OidcRedirectUrlProvider { ) : OAuthRedirectUrlProvider {
override fun provide() = buildString { override fun provide() = buildString {
append(stringProvider.getString(R.string.login_redirect_scheme)) append(stringProvider.getString(R.string.login_redirect_scheme))
append(":/") append(":/")

View file

@ -2,6 +2,7 @@
<locale-config xmlns:android="http://schemas.android.com/apk/res/android"> <locale-config xmlns:android="http://schemas.android.com/apk/res/android">
<locale android:name="be"/> <locale android:name="be"/>
<locale android:name="bg"/> <locale android:name="bg"/>
<locale android:name="ca"/>
<locale android:name="cs"/> <locale android:name="cs"/>
<locale android:name="cy"/> <locale android:name="cy"/>
<locale android:name="da"/> <locale android:name="da"/>

View file

@ -13,13 +13,13 @@ import io.element.android.services.toolbox.test.strings.FakeStringProvider
import io.element.android.x.R import io.element.android.x.R
import org.junit.Test import org.junit.Test
class DefaultOidcRedirectUrlProviderTest { class DefaultOAuthRedirectUrlProviderTest {
@Test @Test
fun `test provide`() { fun `test provide`() {
val stringProvider = FakeStringProvider( val stringProvider = FakeStringProvider(
defaultResult = "str" defaultResult = "str"
) )
val sut = DefaultOidcRedirectUrlProvider( val sut = DefaultOAuthRedirectUrlProvider(
stringProvider = stringProvider, stringProvider = stringProvider,
) )
val result = sut.provide() val result = sut.provide()

View file

@ -48,6 +48,8 @@ android {
} }
dependencies { dependencies {
implementation(libs.coroutines.core)
implementation(libs.androidx.annotationjvm) implementation(libs.androidx.annotationjvm)
implementation(libs.androidx.corektx)
implementation(projects.libraries.matrix.api) implementation(projects.libraries.matrix.api)
} }

View file

@ -0,0 +1,15 @@
/*
* Copyright (c) 2026 Element Creations Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.appconfig
object ProtectionConfig {
/**
* The maximum length of a room name, to limit attack vectors in room invite.
*/
const val MAX_ROOM_NAME_LENGTH = 128
}

View file

@ -33,13 +33,14 @@ dependencies {
implementation(projects.libraries.deeplink.api) implementation(projects.libraries.deeplink.api)
implementation(projects.libraries.featureflag.api) implementation(projects.libraries.featureflag.api)
implementation(projects.libraries.matrix.api) implementation(projects.libraries.matrix.api)
implementation(projects.libraries.oidc.api) implementation(projects.libraries.oauth.api)
implementation(projects.libraries.preferences.api) implementation(projects.libraries.preferences.api)
implementation(projects.libraries.push.api) implementation(projects.libraries.push.api)
implementation(projects.libraries.pushproviders.api) implementation(projects.libraries.pushproviders.api)
implementation(projects.libraries.designsystem) implementation(projects.libraries.designsystem)
implementation(projects.libraries.matrixui) implementation(projects.libraries.matrixui)
implementation(projects.libraries.matrixmedia.api) implementation(projects.libraries.matrixmedia.api)
implementation(projects.libraries.sessionStorage.api)
implementation(projects.libraries.uiCommon) implementation(projects.libraries.uiCommon)
implementation(projects.libraries.uiStrings) implementation(projects.libraries.uiStrings)
implementation(projects.features.login.api) implementation(projects.features.login.api)
@ -59,7 +60,7 @@ dependencies {
testImplementation(projects.features.login.test) testImplementation(projects.features.login.test)
testImplementation(projects.features.share.test) testImplementation(projects.features.share.test)
testImplementation(projects.libraries.matrix.test) testImplementation(projects.libraries.matrix.test)
testImplementation(projects.libraries.oidc.test) testImplementation(projects.libraries.oauth.test)
testImplementation(projects.libraries.preferences.test) testImplementation(projects.libraries.preferences.test)
testImplementation(projects.libraries.push.test) testImplementation(projects.libraries.push.test)
testImplementation(projects.libraries.pushproviders.test) testImplementation(projects.libraries.pushproviders.test)

View file

@ -54,6 +54,7 @@ import io.element.android.features.ftue.api.state.FtueService
import io.element.android.features.ftue.api.state.FtueState import io.element.android.features.ftue.api.state.FtueState
import io.element.android.features.home.api.HomeEntryPoint import io.element.android.features.home.api.HomeEntryPoint
import io.element.android.features.linknewdevice.api.LinkNewDeviceEntryPoint import io.element.android.features.linknewdevice.api.LinkNewDeviceEntryPoint
import io.element.android.features.location.api.live.ActiveLiveLocationShareManager
import io.element.android.features.networkmonitor.api.NetworkMonitor import io.element.android.features.networkmonitor.api.NetworkMonitor
import io.element.android.features.networkmonitor.api.NetworkStatus import io.element.android.features.networkmonitor.api.NetworkStatus
import io.element.android.features.networkmonitor.api.ui.ConnectivityIndicatorContainer import io.element.android.features.networkmonitor.api.ui.ConnectivityIndicatorContainer
@ -77,6 +78,7 @@ import io.element.android.libraries.designsystem.theme.ElementThemeApp
import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher import io.element.android.libraries.designsystem.utils.snackbar.SnackbarDispatcher
import io.element.android.libraries.di.SessionScope import io.element.android.libraries.di.SessionScope
import io.element.android.libraries.di.annotations.SessionCoroutineScope import io.element.android.libraries.di.annotations.SessionCoroutineScope
import io.element.android.libraries.featureflag.api.FeatureFlagService
import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.RoomId
@ -144,11 +146,13 @@ class LoggedInFlowNode(
private val syncService: SyncService, private val syncService: SyncService,
private val enterpriseService: EnterpriseService, private val enterpriseService: EnterpriseService,
private val appPreferencesStore: AppPreferencesStore, private val appPreferencesStore: AppPreferencesStore,
private val featureFlagService: FeatureFlagService,
private val buildMeta: BuildMeta, private val buildMeta: BuildMeta,
snackbarDispatcher: SnackbarDispatcher, snackbarDispatcher: SnackbarDispatcher,
private val analyticsService: AnalyticsService, private val analyticsService: AnalyticsService,
private val analyticsRoomListStateWatcher: AnalyticsRoomListStateWatcher, private val analyticsRoomListStateWatcher: AnalyticsRoomListStateWatcher,
private val createRoomEntryPoint: CreateRoomEntryPoint, private val createRoomEntryPoint: CreateRoomEntryPoint,
private val activeLiveLocationShareManager: ActiveLiveLocationShareManager,
) : BaseFlowNode<LoggedInFlowNode.NavTarget>( ) : BaseFlowNode<LoggedInFlowNode.NavTarget>(
backstack = BackStack( backstack = BackStack(
initialElement = NavTarget.Placeholder, initialElement = NavTarget.Placeholder,
@ -209,6 +213,7 @@ class LoggedInFlowNode(
super.onBuilt() super.onBuilt()
lifecycleScope.launch { lifecycleScope.launch {
sessionEnterpriseService.init() sessionEnterpriseService.init()
activeLiveLocationShareManager.setup()
} }
lifecycle.subscribe( lifecycle.subscribe(
onCreate = { onCreate = {
@ -217,7 +222,6 @@ class LoggedInFlowNode(
loggedInFlowProcessor.observeEvents(sessionCoroutineScope) loggedInFlowProcessor.observeEvents(sessionCoroutineScope)
matrixClient.sessionVerificationService.setListener(verificationListener) matrixClient.sessionVerificationService.setListener(verificationListener)
mediaPreviewConfigMigration() mediaPreviewConfigMigration()
sessionCoroutineScope.launch { sessionCoroutineScope.launch {
// Wait for the network to be connected before pre-fetching the max file upload size // Wait for the network to be connected before pre-fetching the max file upload size
networkMonitor.connectivity.first { networkStatus -> networkStatus == NetworkStatus.Connected } networkMonitor.connectivity.first { networkStatus -> networkStatus == NetworkStatus.Connected }
@ -378,9 +382,13 @@ class LoggedInFlowNode(
} }
is NavTarget.Room -> { is NavTarget.Room -> {
val joinedRoomCallback = object : JoinedRoomLoadedFlowNode.Callback { val joinedRoomCallback = object : JoinedRoomLoadedFlowNode.Callback {
override fun navigateToRoom(roomId: RoomId, serverNames: List<String>) { override fun onDone() {
backstack.pop()
}
override fun navigateToRoom(roomId: RoomId, serverNames: List<String>, clearBackStack: Boolean) {
lifecycleScope.launch { lifecycleScope.launch {
attachRoom(roomIdOrAlias = roomId.toRoomIdOrAlias(), serverNames = serverNames, clearBackstack = false) attachRoom(roomIdOrAlias = roomId.toRoomIdOrAlias(), serverNames = serverNames, clearBackstack = clearBackStack)
} }
} }
@ -671,6 +679,7 @@ class LoggedInFlowNode(
}.collectAsState(SemanticColorsLightDark.default) }.collectAsState(SemanticColorsLightDark.default)
ElementThemeApp( ElementThemeApp(
appPreferencesStore = appPreferencesStore, appPreferencesStore = appPreferencesStore,
featureFlagService = featureFlagService,
compoundLight = colors.light, compoundLight = colors.light,
compoundDark = colors.dark, compoundDark = colors.dark,
buildMeta = buildMeta, buildMeta = buildMeta,

View file

@ -63,8 +63,8 @@ import io.element.android.libraries.matrix.api.core.ThreadId
import io.element.android.libraries.matrix.api.core.asEventId import io.element.android.libraries.matrix.api.core.asEventId
import io.element.android.libraries.matrix.api.core.toRoomIdOrAlias import io.element.android.libraries.matrix.api.core.toRoomIdOrAlias
import io.element.android.libraries.matrix.api.permalink.PermalinkData import io.element.android.libraries.matrix.api.permalink.PermalinkData
import io.element.android.libraries.oidc.api.OidcAction import io.element.android.libraries.oauth.api.OAuthAction
import io.element.android.libraries.oidc.api.OidcActionFlow import io.element.android.libraries.oauth.api.OAuthActionFlow
import io.element.android.libraries.sessionstorage.api.LoggedInState import io.element.android.libraries.sessionstorage.api.LoggedInState
import io.element.android.libraries.sessionstorage.api.SessionStore import io.element.android.libraries.sessionstorage.api.SessionStore
import io.element.android.libraries.ui.common.nodes.emptyNode import io.element.android.libraries.ui.common.nodes.emptyNode
@ -95,7 +95,7 @@ class RootFlowNode(
private val signedOutEntryPoint: SignedOutEntryPoint, private val signedOutEntryPoint: SignedOutEntryPoint,
private val accountSelectEntryPoint: AccountSelectEntryPoint, private val accountSelectEntryPoint: AccountSelectEntryPoint,
private val intentResolver: IntentResolver, private val intentResolver: IntentResolver,
private val oidcActionFlow: OidcActionFlow, private val oAuthActionFlow: OAuthActionFlow,
private val featureFlagService: FeatureFlagService, private val featureFlagService: FeatureFlagService,
private val announcementService: AnnouncementService, private val announcementService: AnnouncementService,
private val analyticsService: AnalyticsService, private val analyticsService: AnalyticsService,
@ -392,7 +392,7 @@ class RootFlowNode(
navigateTo(resolvedIntent.deeplinkData) navigateTo(resolvedIntent.deeplinkData)
} }
is ResolvedIntent.Login -> onLoginLink(resolvedIntent.params) is ResolvedIntent.Login -> onLoginLink(resolvedIntent.params)
is ResolvedIntent.Oidc -> onOidcAction(resolvedIntent.oidcAction) is ResolvedIntent.OAuth -> onOAuthAction(resolvedIntent.oAuthAction)
is ResolvedIntent.Permalink -> navigateTo(resolvedIntent.permalinkData) is ResolvedIntent.Permalink -> navigateTo(resolvedIntent.permalinkData)
is ResolvedIntent.IncomingShare -> onIncomingShare(resolvedIntent.shareIntentData) is ResolvedIntent.IncomingShare -> onIncomingShare(resolvedIntent.shareIntentData)
} }
@ -529,8 +529,8 @@ class RootFlowNode(
} }
} }
private fun onOidcAction(oidcAction: OidcAction) { private fun onOAuthAction(oAuthAction: OAuthAction) {
oidcActionFlow.post(oidcAction) oAuthActionFlow.post(oAuthAction)
} }
private suspend fun attachSession(sessionId: SessionId): LoggedInFlowNode { private suspend fun attachSession(sessionId: SessionId): LoggedInFlowNode {

View file

@ -89,16 +89,14 @@ class SyncOrchestrator(
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
internal fun observeStates() = coroutineScope.launch { internal fun observeStates() = coroutineScope.launch {
Timber.tag(tag).d("start observing the app and network state") Timber.tag(tag).d("start observing the app and network state")
val isAppActiveFlows = listOf(
val isAppActiveFlow = combine(
appForegroundStateService.isInForeground, appForegroundStateService.isInForeground,
appForegroundStateService.isInCall, appForegroundStateService.isInCall,
appForegroundStateService.isSyncingNotificationEvent, appForegroundStateService.isSyncingNotificationEvent,
appForegroundStateService.hasRingingCall, appForegroundStateService.hasRingingCall,
) { isInForeground, isInCall, isSyncingNotificationEvent, hasRingingCall -> appForegroundStateService.isSharingLiveLocation
isInForeground || isInCall || isSyncingNotificationEvent || hasRingingCall )
} val isAppActiveFlow = combine(isAppActiveFlows) { actives -> actives.any { it } }
combine( combine(
// small debounce to avoid spamming startSync when the state is changing quickly in case of error. // small debounce to avoid spamming startSync when the state is changing quickly in case of error.
syncService.syncState.debounce(100.milliseconds), syncService.syncState.debounce(100.milliseconds),

View file

@ -18,13 +18,13 @@ import io.element.android.libraries.deeplink.api.DeeplinkData
import io.element.android.libraries.deeplink.api.DeeplinkParser import io.element.android.libraries.deeplink.api.DeeplinkParser
import io.element.android.libraries.matrix.api.permalink.PermalinkData import io.element.android.libraries.matrix.api.permalink.PermalinkData
import io.element.android.libraries.matrix.api.permalink.PermalinkParser import io.element.android.libraries.matrix.api.permalink.PermalinkParser
import io.element.android.libraries.oidc.api.OidcAction import io.element.android.libraries.oauth.api.OAuthAction
import io.element.android.libraries.oidc.api.OidcIntentResolver import io.element.android.libraries.oauth.api.OAuthIntentResolver
import timber.log.Timber import timber.log.Timber
sealed interface ResolvedIntent { sealed interface ResolvedIntent {
data class Navigation(val deeplinkData: DeeplinkData) : ResolvedIntent data class Navigation(val deeplinkData: DeeplinkData) : ResolvedIntent
data class Oidc(val oidcAction: OidcAction) : ResolvedIntent data class OAuth(val oAuthAction: OAuthAction) : ResolvedIntent
data class Permalink(val permalinkData: PermalinkData) : ResolvedIntent data class Permalink(val permalinkData: PermalinkData) : ResolvedIntent
data class Login(val params: LoginParams) : ResolvedIntent data class Login(val params: LoginParams) : ResolvedIntent
data class IncomingShare(val shareIntentData: ShareIntentData) : ResolvedIntent data class IncomingShare(val shareIntentData: ShareIntentData) : ResolvedIntent
@ -34,7 +34,7 @@ sealed interface ResolvedIntent {
class IntentResolver( class IntentResolver(
private val deeplinkParser: DeeplinkParser, private val deeplinkParser: DeeplinkParser,
private val loginIntentResolver: LoginIntentResolver, private val loginIntentResolver: LoginIntentResolver,
private val oidcIntentResolver: OidcIntentResolver, private val oAuthIntentResolver: OAuthIntentResolver,
private val permalinkParser: PermalinkParser, private val permalinkParser: PermalinkParser,
private val shareIntentHandler: ShareIntentHandler, private val shareIntentHandler: ShareIntentHandler,
) { ) {
@ -45,9 +45,9 @@ class IntentResolver(
val deepLinkData = deeplinkParser.getFromIntent(intent) val deepLinkData = deeplinkParser.getFromIntent(intent)
if (deepLinkData != null) return ResolvedIntent.Navigation(deepLinkData) if (deepLinkData != null) return ResolvedIntent.Navigation(deepLinkData)
// Coming during login using Oidc? // Coming during login using OAuth?
val oidcAction = oidcIntentResolver.resolve(intent) val oAuthAction = oAuthIntentResolver.resolve(intent)
if (oidcAction != null) return ResolvedIntent.Oidc(oidcAction) if (oAuthAction != null) return ResolvedIntent.OAuth(oAuthAction)
val actionViewData = intent val actionViewData = intent
.takeIf { it.action == Intent.ACTION_VIEW } .takeIf { it.action == Intent.ACTION_VIEW }

View file

@ -31,7 +31,6 @@ import io.element.android.libraries.core.meta.BuildMeta
import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.encryption.EncryptionService import io.element.android.libraries.matrix.api.encryption.EncryptionService
import io.element.android.libraries.matrix.api.encryption.RecoveryState import io.element.android.libraries.matrix.api.encryption.RecoveryState
import io.element.android.libraries.matrix.api.oidc.AccountManagementAction
import io.element.android.libraries.matrix.api.roomlist.RoomListService import io.element.android.libraries.matrix.api.roomlist.RoomListService
import io.element.android.libraries.matrix.api.sync.SlidingSyncVersion import io.element.android.libraries.matrix.api.sync.SlidingSyncVersion
import io.element.android.libraries.matrix.api.sync.SyncService import io.element.android.libraries.matrix.api.sync.SyncService
@ -177,7 +176,6 @@ class LoggedInPresenter(
} }
private fun CoroutineScope.preloadAccountManagementUrl() = launch { private fun CoroutineScope.preloadAccountManagementUrl() = launch {
matrixClient.getAccountManagementUrl(AccountManagementAction.Profile) matrixClient.getAccountManagementUrl(null)
matrixClient.getAccountManagementUrl(AccountManagementAction.DevicesList)
} }
} }

View file

@ -82,7 +82,8 @@ class JoinedRoomLoadedFlowNode(
plugins = plugins, plugins = plugins,
), DependencyInjectionGraphOwner { ), DependencyInjectionGraphOwner {
interface Callback : Plugin { interface Callback : Plugin {
fun navigateToRoom(roomId: RoomId, serverNames: List<String>) fun onDone()
fun navigateToRoom(roomId: RoomId, serverNames: List<String>, clearBackStack: Boolean = false)
fun handlePermalinkClick(data: PermalinkData, pushToBackstack: Boolean) fun handlePermalinkClick(data: PermalinkData, pushToBackstack: Boolean)
fun navigateToGlobalNotificationSettings() fun navigateToGlobalNotificationSettings()
fun navigateToDeveloperSettings() fun navigateToDeveloperSettings()
@ -142,6 +143,10 @@ class JoinedRoomLoadedFlowNode(
private fun createRoomDetailsNode(buildContext: BuildContext, initialTarget: RoomDetailsEntryPoint.InitialTarget): Node { private fun createRoomDetailsNode(buildContext: BuildContext, initialTarget: RoomDetailsEntryPoint.InitialTarget): Node {
val callback = object : RoomDetailsEntryPoint.Callback { val callback = object : RoomDetailsEntryPoint.Callback {
override fun onDone() {
callback.onDone()
}
override fun navigateToGlobalNotificationSettings() { override fun navigateToGlobalNotificationSettings() {
callback.navigateToGlobalNotificationSettings() callback.navigateToGlobalNotificationSettings()
} }
@ -150,7 +155,7 @@ class JoinedRoomLoadedFlowNode(
callback.navigateToDeveloperSettings() callback.navigateToDeveloperSettings()
} }
override fun navigateToRoom(roomId: RoomId, serverNames: List<String>) { override fun navigateToRoom(roomId: RoomId, serverNames: List<String>, clearBackStack: Boolean) {
callback.navigateToRoom(roomId, serverNames) callback.navigateToRoom(roomId, serverNames)
} }

View file

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="banner_migrate_to_native_sliding_sync_action">"Tanca sessió i actualitza"</string>
<string name="banner_migrate_to_native_sliding_sync_app_force_logout_title">"%1$s ja no admet el protocol antic. Tanca sessió i torna a entrar per continuar utilitzant l\'aplicació."</string>
<string name="banner_migrate_to_native_sliding_sync_force_logout_title">"El servidor utilitzat ja no admet el protocol antic. Tanca sessió i torna-la a iniciar per continuar utilitzant l\'aplicació."</string>
</resources>

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="banner_migrate_to_native_sliding_sync_action">"登出并升级"</string> <string name="banner_migrate_to_native_sliding_sync_action">"注销并升级"</string>
<string name="banner_migrate_to_native_sliding_sync_app_force_logout_title">"%1$s 不再支持旧协议。请注销并重新登录以继续使用该应用程序。"</string> <string name="banner_migrate_to_native_sliding_sync_app_force_logout_title">"%1$s 不再支持旧协议。请注销并重新登录以继续使用该应用程序。"</string>
<string name="banner_migrate_to_native_sliding_sync_force_logout_title">"您的服务器不再支持旧协议。请登出并重新登录以继续使用此应用。"</string> <string name="banner_migrate_to_native_sliding_sync_force_logout_title">"你的主服务器不再支持旧协议。请注销并重新登录以继续使用此 app。"</string>
</resources> </resources>

View file

@ -26,8 +26,8 @@ import io.element.android.libraries.matrix.test.A_ROOM_ID
import io.element.android.libraries.matrix.test.A_SESSION_ID import io.element.android.libraries.matrix.test.A_SESSION_ID
import io.element.android.libraries.matrix.test.A_THREAD_ID import io.element.android.libraries.matrix.test.A_THREAD_ID
import io.element.android.libraries.matrix.test.permalink.FakePermalinkParser import io.element.android.libraries.matrix.test.permalink.FakePermalinkParser
import io.element.android.libraries.oidc.api.OidcAction import io.element.android.libraries.oauth.api.OAuthAction
import io.element.android.libraries.oidc.test.FakeOidcIntentResolver import io.element.android.libraries.oauth.test.FakeOAuthIntentResolver
import io.element.android.tests.testutils.lambda.lambdaError import io.element.android.tests.testutils.lambda.lambdaError
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
@ -170,9 +170,9 @@ class IntentResolverTest {
} }
@Test @Test
fun `test resolve oidc`() { fun `test resolve OAuth`() {
val sut = createIntentResolver( val sut = createIntentResolver(
oidcIntentResolverResult = { OidcAction.GoBack() }, oAuthIntentResolverResult = { OAuthAction.GoBack() },
) )
val intent = Intent(RuntimeEnvironment.getApplication(), Activity::class.java).apply { val intent = Intent(RuntimeEnvironment.getApplication(), Activity::class.java).apply {
action = Intent.ACTION_VIEW action = Intent.ACTION_VIEW
@ -180,8 +180,8 @@ class IntentResolverTest {
} }
val result = sut.resolve(intent) val result = sut.resolve(intent)
assertThat(result).isEqualTo( assertThat(result).isEqualTo(
ResolvedIntent.Oidc( ResolvedIntent.OAuth(
oidcAction = OidcAction.GoBack() oAuthAction = OAuthAction.GoBack()
) )
) )
} }
@ -194,7 +194,7 @@ class IntentResolverTest {
val sut = createIntentResolver( val sut = createIntentResolver(
loginIntentResolverResult = { null }, loginIntentResolverResult = { null },
permalinkParserResult = { permalinkData }, permalinkParserResult = { permalinkData },
oidcIntentResolverResult = { null }, oAuthIntentResolverResult = { null },
) )
val intent = Intent(RuntimeEnvironment.getApplication(), Activity::class.java).apply { val intent = Intent(RuntimeEnvironment.getApplication(), Activity::class.java).apply {
action = Intent.ACTION_VIEW action = Intent.ACTION_VIEW
@ -213,7 +213,7 @@ class IntentResolverTest {
val sut = createIntentResolver( val sut = createIntentResolver(
permalinkParserResult = { PermalinkData.FallbackLink(Uri.parse("https://matrix.org")) }, permalinkParserResult = { PermalinkData.FallbackLink(Uri.parse("https://matrix.org")) },
loginIntentResolverResult = { null }, loginIntentResolverResult = { null },
oidcIntentResolverResult = { null }, oAuthIntentResolverResult = { null },
) )
val intent = Intent(RuntimeEnvironment.getApplication(), Activity::class.java).apply { val intent = Intent(RuntimeEnvironment.getApplication(), Activity::class.java).apply {
action = Intent.ACTION_VIEW action = Intent.ACTION_VIEW
@ -230,7 +230,7 @@ class IntentResolverTest {
) )
val sut = createIntentResolver( val sut = createIntentResolver(
permalinkParserResult = { permalinkData }, permalinkParserResult = { permalinkData },
oidcIntentResolverResult = { null }, oAuthIntentResolverResult = { null },
) )
val intent = Intent(RuntimeEnvironment.getApplication(), Activity::class.java).apply { val intent = Intent(RuntimeEnvironment.getApplication(), Activity::class.java).apply {
action = Intent.ACTION_BATTERY_LOW action = Intent.ACTION_BATTERY_LOW
@ -244,7 +244,7 @@ class IntentResolverTest {
fun `test incoming share simple`() { fun `test incoming share simple`() {
val shareIntentData = ShareIntentData.PlainText("Hello") val shareIntentData = ShareIntentData.PlainText("Hello")
val sut = createIntentResolver( val sut = createIntentResolver(
oidcIntentResolverResult = { null }, oAuthIntentResolverResult = { null },
onIncomingShareIntent = { shareIntentData }, onIncomingShareIntent = { shareIntentData },
) )
val intent = Intent(RuntimeEnvironment.getApplication(), Activity::class.java).apply { val intent = Intent(RuntimeEnvironment.getApplication(), Activity::class.java).apply {
@ -260,7 +260,7 @@ class IntentResolverTest {
val fileUri = "content://com.example.app/file1.jpg".toUri() val fileUri = "content://com.example.app/file1.jpg".toUri()
val shareIntentData = ShareIntentData.Uris(text = "Hello", uris = listOf(UriToShare(fileUri, "image/jpg"))) val shareIntentData = ShareIntentData.Uris(text = "Hello", uris = listOf(UriToShare(fileUri, "image/jpg")))
val sut = createIntentResolver( val sut = createIntentResolver(
oidcIntentResolverResult = { null }, oAuthIntentResolverResult = { null },
onIncomingShareIntent = { shareIntentData }, onIncomingShareIntent = { shareIntentData },
) )
val intent = Intent(RuntimeEnvironment.getApplication(), Activity::class.java).apply { val intent = Intent(RuntimeEnvironment.getApplication(), Activity::class.java).apply {
@ -277,7 +277,7 @@ class IntentResolverTest {
val sut = createIntentResolver( val sut = createIntentResolver(
permalinkParserResult = { PermalinkData.FallbackLink(Uri.parse("https://matrix.org")) }, permalinkParserResult = { PermalinkData.FallbackLink(Uri.parse("https://matrix.org")) },
loginIntentResolverResult = { null }, loginIntentResolverResult = { null },
oidcIntentResolverResult = { null }, oAuthIntentResolverResult = { null },
) )
val intent = Intent(RuntimeEnvironment.getApplication(), Activity::class.java).apply { val intent = Intent(RuntimeEnvironment.getApplication(), Activity::class.java).apply {
action = Intent.ACTION_VIEW action = Intent.ACTION_VIEW
@ -292,7 +292,7 @@ class IntentResolverTest {
val aLoginParams = LoginParams("accountProvider", null) val aLoginParams = LoginParams("accountProvider", null)
val sut = createIntentResolver( val sut = createIntentResolver(
loginIntentResolverResult = { aLoginParams }, loginIntentResolverResult = { aLoginParams },
oidcIntentResolverResult = { null }, oAuthIntentResolverResult = { null },
) )
val intent = Intent(RuntimeEnvironment.getApplication(), Activity::class.java).apply { val intent = Intent(RuntimeEnvironment.getApplication(), Activity::class.java).apply {
action = Intent.ACTION_VIEW action = Intent.ACTION_VIEW
@ -306,7 +306,7 @@ class IntentResolverTest {
deeplinkParserResult: DeeplinkData? = null, deeplinkParserResult: DeeplinkData? = null,
permalinkParserResult: (String) -> PermalinkData = { lambdaError() }, permalinkParserResult: (String) -> PermalinkData = { lambdaError() },
loginIntentResolverResult: (String) -> LoginParams? = { lambdaError() }, loginIntentResolverResult: (String) -> LoginParams? = { lambdaError() },
oidcIntentResolverResult: (Intent) -> OidcAction? = { lambdaError() }, oAuthIntentResolverResult: (Intent) -> OAuthAction? = { lambdaError() },
onIncomingShareIntent: (Intent) -> ShareIntentData? = { null }, onIncomingShareIntent: (Intent) -> ShareIntentData? = { null },
): IntentResolver { ): IntentResolver {
return IntentResolver( return IntentResolver(
@ -314,8 +314,8 @@ class IntentResolverTest {
loginIntentResolver = FakeLoginIntentResolver( loginIntentResolver = FakeLoginIntentResolver(
parseResult = loginIntentResolverResult, parseResult = loginIntentResolverResult,
), ),
oidcIntentResolver = FakeOidcIntentResolver( oAuthIntentResolver = FakeOAuthIntentResolver(
resolveResult = oidcIntentResolverResult, resolveResult = oAuthIntentResolverResult,
), ),
permalinkParser = FakePermalinkParser( permalinkParser = FakePermalinkParser(
result = permalinkParserResult result = permalinkParserResult

View file

@ -21,7 +21,7 @@ import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.matrix.api.core.SessionId
import io.element.android.libraries.matrix.api.encryption.EncryptionService import io.element.android.libraries.matrix.api.encryption.EncryptionService
import io.element.android.libraries.matrix.api.encryption.RecoveryState import io.element.android.libraries.matrix.api.encryption.RecoveryState
import io.element.android.libraries.matrix.api.oidc.AccountManagementAction import io.element.android.libraries.matrix.api.oauth.AccountManagementAction
import io.element.android.libraries.matrix.api.roomlist.RoomListService import io.element.android.libraries.matrix.api.roomlist.RoomListService
import io.element.android.libraries.matrix.api.sync.SlidingSyncVersion import io.element.android.libraries.matrix.api.sync.SlidingSyncVersion
import io.element.android.libraries.matrix.api.sync.SyncState import io.element.android.libraries.matrix.api.sync.SyncState
@ -71,7 +71,7 @@ class LoggedInPresenterTest {
} }
@Test @Test
fun `present - ensure that account urls are preloaded`() = runTest { fun `present - ensure that account url is preloaded`() = runTest {
val accountManagementUrlResult = lambdaRecorder<AccountManagementAction?, Result<String?>> { Result.success("aUrl") } val accountManagementUrlResult = lambdaRecorder<AccountManagementAction?, Result<String?>> { Result.success("aUrl") }
val matrixClient = FakeMatrixClient( val matrixClient = FakeMatrixClient(
accountManagementUrlResult = accountManagementUrlResult, accountManagementUrlResult = accountManagementUrlResult,
@ -81,11 +81,8 @@ class LoggedInPresenterTest {
).test { ).test {
awaitItem() awaitItem()
advanceUntilIdle() advanceUntilIdle()
accountManagementUrlResult.assertions().isCalledExactly(2) accountManagementUrlResult.assertions().isCalledOnce()
.withSequence( .with(value(null))
listOf(value(AccountManagementAction.Profile)),
listOf(value(AccountManagementAction.DevicesList)),
)
} }
} }

View file

@ -13,7 +13,8 @@ import io.element.android.libraries.matrix.api.permalink.PermalinkData
import io.element.android.tests.testutils.lambda.lambdaError import io.element.android.tests.testutils.lambda.lambdaError
class FakeJoinedRoomLoadedFlowNodeCallback : JoinedRoomLoadedFlowNode.Callback { class FakeJoinedRoomLoadedFlowNodeCallback : JoinedRoomLoadedFlowNode.Callback {
override fun navigateToRoom(roomId: RoomId, serverNames: List<String>) = lambdaError() override fun onDone() = lambdaError()
override fun navigateToRoom(roomId: RoomId, serverNames: List<String>, clearBackStack: Boolean) = lambdaError()
override fun handlePermalinkClick(data: PermalinkData, pushToBackstack: Boolean) = lambdaError() override fun handlePermalinkClick(data: PermalinkData, pushToBackstack: Boolean) = lambdaError()
override fun navigateToGlobalNotificationSettings() = lambdaError() override fun navigateToGlobalNotificationSettings() = lambdaError()
override fun navigateToDeveloperSettings() = lambdaError() override fun navigateToDeveloperSettings() = lambdaError()

View file

@ -46,12 +46,15 @@ allprojects {
config.from(files("$rootDir/tools/detekt/detekt.yml")) config.from(files("$rootDir/tools/detekt/detekt.yml"))
} }
dependencies { dependencies {
detektPlugins("io.nlopez.compose.rules:detekt:0.5.6") detektPlugins("io.nlopez.compose.rules:detekt:0.5.8")
detektPlugins(project(":tests:detekt-rules")) detektPlugins(project(":tests:detekt-rules"))
} }
tasks.withType<io.gitlab.arturbosch.detekt.Detekt>().configureEach { tasks.withType<io.gitlab.arturbosch.detekt.Detekt>().configureEach {
exclude("io/element/android/tests/konsist/failures/**") exclude("io/element/android/tests/konsist/failures/**")
// This file comes from another project and we want to keep it as close to the original as possible
exclude("org/rustls/platformverifier/**")
} }
// KtLint // KtLint
@ -79,6 +82,9 @@ allprojects {
// This file comes from another project and we want to keep it as close to the original as possible // This file comes from another project and we want to keep it as close to the original as possible
exclude("**/SafeChildrenTransitionScope.kt") exclude("**/SafeChildrenTransitionScope.kt")
// This file comes from another project and we want to keep it as close to the original as possible
exclude("org/rustls/platformverifier/**")
} }
} }
// Dependency check // Dependency check

View file

@ -144,6 +144,11 @@ Prerequisites:
export ANDROID_HOME=$HOME/android/sdk export ANDROID_HOME=$HOME/android/sdk
``` ```
* On macos ensure gnu-getopt is installed
```
brew install gnu-getopt
```
You can then build the Rust SDK by running the script You can then build the Rust SDK by running the script
[`tools/sdk/build-rust-sdk`](../tools/sdk/build-rust-sdk). Type [`tools/sdk/build-rust-sdk`](../tools/sdk/build-rust-sdk). Type
`./tools/sdk/build-rust-sdk --help` for help. `./tools/sdk/build-rust-sdk --help` for help.

View file

@ -1,4 +1,4 @@
This file contains some rough notes about Oidc implementation, with some examples of actual data. This file contains some rough notes about OAuth implementation, with some examples of actual data.
[ios implementation](https://github.com/element-hq/element-x-ios/compare/develop...doug/oidc-temp) [ios implementation](https://github.com/element-hq/element-x-ios/compare/develop...doug/oidc-temp)
@ -25,7 +25,7 @@ tosUri = "https://element.io/user-terms-of-service",
policyUri = "https://element.io/privacy" policyUri = "https://element.io/privacy"
Example of OidcData (from presentUrl callback): Example of OAuthData (from presentUrl callback):
url: https://auth-oidc.lab.element.dev/authorize?response_type=code&client_id=01GYCAGG3PA70CJ97ZVP0WFJY3&redirect_uri=io.element%3A%2Fcallback&scope=openid+urn%3Amatrix%3Aorg.matrix.msc2967.client%3Aapi%3A*+urn%3Amatrix%3Aorg.matrix.msc2967.client%3Adevice%3AYAgcPW4mcG&state=ex6mNJVFZ5jn9wL8&nonce=NZ93DOyIGQd9exPQ&code_challenge_method=S256&code_challenge=FFRcPALNSPCh-ZgpyTRFu_h8NZJVncfvihbfT9CyX8U&prompt=consent url: https://auth-oidc.lab.element.dev/authorize?response_type=code&client_id=01GYCAGG3PA70CJ97ZVP0WFJY3&redirect_uri=io.element%3A%2Fcallback&scope=openid+urn%3Amatrix%3Aorg.matrix.msc2967.client%3Aapi%3A*+urn%3Amatrix%3Aorg.matrix.msc2967.client%3Adevice%3AYAgcPW4mcG&state=ex6mNJVFZ5jn9wL8&nonce=NZ93DOyIGQd9exPQ&code_challenge_method=S256&code_challenge=FFRcPALNSPCh-ZgpyTRFu_h8NZJVncfvihbfT9CyX8U&prompt=consent
Formatted url: Formatted url:
@ -43,8 +43,8 @@ https://auth-oidc.lab.element.dev/authorize?
state: ex6mNJVFZ5jn9wL8 state: ex6mNJVFZ5jn9wL8
Oidc client example: https://github.com/matrix-org/matrix-rust-sdk/blob/39ad8a46801fb4317a777ebf895822b3675b709c/examples/oidc_cli/src/main.rs OAuth client example: https://github.com/matrix-org/matrix-rust-sdk/blob/39ad8a46801fb4317a777ebf895822b3675b709c/examples/oidc_cli/src/main.rs
Oidc sdk doc: https://github.com/matrix-org/matrix-rust-sdk/blob/39ad8a46801fb4317a777ebf895822b3675b709c/crates/matrix-sdk/src/oidc.rs OAuth sdk doc: https://github.com/matrix-org/matrix-rust-sdk/blob/39ad8a46801fb4317a777ebf895822b3675b709c/crates/matrix-sdk/src/oidc.rs
Test server: Test server:

@ -1 +1 @@
Subproject commit cdde60c158ecd0987a3ba6fd79a4617551aff463 Subproject commit 6781da90aae61cf77dcdbc543e18d76411d578b4

View file

@ -0,0 +1,2 @@
Main changes in this version: several bug fixes.
Full changelog: https://github.com/element-hq/element-x-android/releases

View file

@ -0,0 +1,2 @@
Main changes in this version: bug fixes and improvements.
Full changelog: https://github.com/element-hq/element-x-android/releases

View file

@ -0,0 +1,2 @@
Main changes in this version: improvements in Element Call, room knocking and room directory are now available, improvements on DMs.
Full changelog: https://github.com/element-hq/element-x-android/releases

View file

@ -0,0 +1,2 @@
Main changes in this version: bug fixes and improvements.
Full changelog: https://github.com/element-hq/element-x-android/releases

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_analytics_settings_help_us_improve">"Comparteix dades d\'ús anònimes per ajudar-nos a identificar problemes."</string>
<string name="screen_analytics_settings_read_terms">"Pots llegir tots els nostres termes %1$s."</string>
<string name="screen_analytics_settings_read_terms_content_link">"aquí"</string>
<string name="screen_analytics_settings_share_data">"Comparteix dades analítiques"</string>
</resources>

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_analytics_settings_help_us_improve">"問題発見のため、匿名の使用データの共有にご協力ください。"</string> <string name="screen_analytics_settings_help_us_improve">"改善のため、匿名の使用データの共有にご協力ください。"</string>
<string name="screen_analytics_settings_read_terms">"利用規約の全文を%1$sから確認することができます。"</string> <string name="screen_analytics_settings_read_terms">"規約の全文は%1$sから確認することができます。"</string>
<string name="screen_analytics_settings_read_terms_content_link">"こちら"</string> <string name="screen_analytics_settings_read_terms_content_link">"こちら"</string>
<string name="screen_analytics_settings_share_data">"使用データを共有"</string> <string name="screen_analytics_settings_share_data">"使用データを共有"</string>
</resources> </resources>

View file

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_analytics_settings_help_us_improve">"共享匿名使用数据以帮助我们排查问题。"</string> <string name="screen_analytics_settings_help_us_improve">"共享匿名使用数据以帮助我们排查问题。"</string>
<string name="screen_analytics_settings_read_terms">"您可以阅读我们的所有条款 %1$s。"</string> <string name="screen_analytics_settings_read_terms">"你可以点击 %1$s 阅读我们的所有条款。"</string>
<string name="screen_analytics_settings_read_terms_content_link">"此处"</string> <string name="screen_analytics_settings_read_terms_content_link">"此处"</string>
<string name="screen_analytics_settings_share_data">"共享分析数据"</string> <string name="screen_analytics_settings_share_data">"共享分析数据"</string>
</resources> </resources>

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_analytics_prompt_data_usage">"No registrarem ni elaborarem perfils de cap dada personal"</string>
<string name="screen_analytics_prompt_help_us_improve">"Comparteix dades d\'ús anònimes per ajudar-nos a identificar problemes."</string>
<string name="screen_analytics_prompt_read_terms">"Pots llegir tots els nostres termes %1$s."</string>
<string name="screen_analytics_prompt_read_terms_content_link">"aquí"</string>
<string name="screen_analytics_prompt_settings">"Ho pots desactivar en qualsevol moment"</string>
<string name="screen_analytics_prompt_third_party_sharing">"No compartirem les teves dades amb tercers"</string>
<string name="screen_analytics_prompt_title">"Ajuda\'ns a millorar %1$s"</string>
</resources>

View file

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_analytics_prompt_data_usage">"いかなる個人情報も記録, 分析されることはありません"</string> <string name="screen_analytics_prompt_data_usage">"いかなる個人情報も記録, 分析されることはありません"</string>
<string name="screen_analytics_prompt_help_us_improve">"問題発見のため、匿名の使用データの共有にご協力ください。"</string> <string name="screen_analytics_prompt_help_us_improve">"改善のため、匿名の使用データの共有にご協力ください。"</string>
<string name="screen_analytics_prompt_read_terms">"利用規約の全文を%1$sから確認することができます。"</string> <string name="screen_analytics_prompt_read_terms">"規約の全文は%1$sから確認することができます。"</string>
<string name="screen_analytics_prompt_read_terms_content_link">"こちら"</string> <string name="screen_analytics_prompt_read_terms_content_link">"こちら"</string>
<string name="screen_analytics_prompt_settings">"いつでも設定は変更できます"</string> <string name="screen_analytics_prompt_settings">"いつでも設定は変更できます"</string>
<string name="screen_analytics_prompt_third_party_sharing">"情報が第三者に共有されることはありません"</string> <string name="screen_analytics_prompt_third_party_sharing">"情報が第三者に共有されることはありません"</string>

View file

@ -2,9 +2,9 @@
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_analytics_prompt_data_usage">"我们不会记录或分析任何个人数据"</string> <string name="screen_analytics_prompt_data_usage">"我们不会记录或分析任何个人数据"</string>
<string name="screen_analytics_prompt_help_us_improve">"共享匿名使用数据以帮助我们排查问题。"</string> <string name="screen_analytics_prompt_help_us_improve">"共享匿名使用数据以帮助我们排查问题。"</string>
<string name="screen_analytics_prompt_read_terms">"您可以阅读我们的所有条款 %1$s。"</string> <string name="screen_analytics_prompt_read_terms">"你可以点击 %1$s 阅读我们的所有条款。"</string>
<string name="screen_analytics_prompt_read_terms_content_link">"此处"</string> <string name="screen_analytics_prompt_read_terms_content_link">"此处"</string>
<string name="screen_analytics_prompt_settings">"可以随时关闭此功能"</string> <string name="screen_analytics_prompt_settings">"可以随时关闭此功能"</string>
<string name="screen_analytics_prompt_third_party_sharing">"我们不会与第三方共享的数据"</string> <string name="screen_analytics_prompt_third_party_sharing">"我们不会与第三方共享的数据"</string>
<string name="screen_analytics_prompt_title">"帮助改进 %1$s"</string> <string name="screen_analytics_prompt_title">"帮助改进 %1$s"</string>
</resources> </resources>

View file

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_space_announcement_item4">"Присъединете се към обществени пространства"</string>
</resources>

View file

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_space_announcement_item1">"Zobrazit prostory, které jste vytvořili nebo ke kterým jste se připojili"</string>
<string name="screen_space_announcement_item2">"Přijmout nebo odmítnout pozvánky do prostorů"</string>
<string name="screen_space_announcement_item3">"Objevte všechny místnosti, do kterých můžete vstoupit ve svých prostorech"</string>
<string name="screen_space_announcement_item4">"Připojit se k veřejným prostorům"</string>
<string name="screen_space_announcement_item5">"Opustit všechny prostory, ke kterým jste se připojili"</string>
<string name="screen_space_announcement_notice">"Filtrování, vytváření a správa prostorů bude brzy k dispozici."</string>
<string name="screen_space_announcement_subtitle">"Vítejte v beta verzi prostorů! S touto první verzí můžete:"</string>
<string name="screen_space_announcement_title">"Představujeme prostory"</string>
</resources>

View file

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_space_announcement_item1">"Se klynger, du har oprettet eller tilmeldt dig"</string>
<string name="screen_space_announcement_item2">"Acceptere eller afvise invitationer til klynger"</string>
<string name="screen_space_announcement_item3">"Finde alle rum, du kan deltage i, i dine klynger"</string>
<string name="screen_space_announcement_item4">"Deltage i offentlige klynger"</string>
<string name="screen_space_announcement_item5">"Forlade de klynger, du har tilsluttet dig"</string>
<string name="screen_space_announcement_notice">"Filtrering, oprettelse og administration af klynger kommer snart."</string>
<string name="screen_space_announcement_subtitle">"Velkommen til betaversionen af Klynger! Med denne første version kan du:"</string>
<string name="screen_space_announcement_title">"Introduktion til Klynger"</string>
</resources>

View file

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_space_announcement_item1">"Von dir erstellte oder beigetretene Spaces anzeigen"</string>
<string name="screen_space_announcement_item2">"Einladungen zu Spaces annehmen oder ablehnen"</string>
<string name="screen_space_announcement_item3">"Chats innerhalb deiner Spaces entdecken, um ihnen beizutreten"</string>
<string name="screen_space_announcement_item4">"Öffentlichen Spaces beitreten"</string>
<string name="screen_space_announcement_item5">"Spaces verlassen, bei denen du Mitglied bist"</string>
<string name="screen_space_announcement_notice">"Das Filtern, Erstellen und Verwalten von Spaces ist bald verfügbar."</string>
<string name="screen_space_announcement_subtitle">"Willkommen bei der Beta-Version von Spaces! Mit dieser ersten Version kannst du:"</string>
<string name="screen_space_announcement_title">"Einführung in Spaces"</string>
</resources>

View file

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_space_announcement_item1">"Δείτε τους χώρους που έχετε δημιουργήσει ή στους οποίους έχετε εγγραφεί"</string>
<string name="screen_space_announcement_item2">"Να αποδεχθείτε ή να απορρίψετε προσκλήσεις σε χώρους"</string>
<string name="screen_space_announcement_item3">"Να ανακαλύψτε όλες τις αίθουσες που μπορείτε να συμμετάσχετε στους χώρους σας"</string>
<string name="screen_space_announcement_item4">"Να συμμετάσχετε σε δημόσιους χώρους"</string>
<string name="screen_space_announcement_item5">"Να αποχωρήστε από χώρους στους οποίους έχετε συμμετάσχει"</string>
<string name="screen_space_announcement_notice">"Το φιλτράρισμα, η δημιουργία και η διαχείριση χώρων θα είναι σύντομα διαθέσιμα."</string>
<string name="screen_space_announcement_subtitle">"Καλώς ορίσατε στην δοκιμαστική έκδοση των Χώρων! Με αυτήν την πρώτη έκδοση μπορείτε:"</string>
<string name="screen_space_announcement_title">"Παρουσιάζοντας τους Χώρους"</string>
</resources>

View file

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_space_announcement_item1">"Vaadata kogukondi, mille oled loonud või millega oled liitunud"</string>
<string name="screen_space_announcement_item2">"Nõustuda kutsetega liitumiseks kogukonnaga või sellest keelduda"</string>
<string name="screen_space_announcement_item3">"Uurida neis kogukondades leiduvaid jututube ning nendega liituda"</string>
<string name="screen_space_announcement_item4">"Liituda avalike kogukondadega"</string>
<string name="screen_space_announcement_item5">"Lahkuda kogukonnast, millega oled liitunud"</string>
<string name="screen_space_announcement_notice">"Kogukondade filtreerimine, loomine ja haldamine lisandub peagi"</string>
<string name="screen_space_announcement_subtitle">"Tere tulemast kasutama kogukondade beetaversiooni! Selles esimeses versioonis saad sa:"</string>
<string name="screen_space_announcement_title">"Võtame kasutusele kogukonnad"</string>
</resources>

View file

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_space_announcement_item1">"دیدن فضاهایی که ساخته یا پیوسته‌اید"</string>
<string name="screen_space_announcement_item2">"پذیرش یا رد دعوت‌ها به فضاها"</string>
<string name="screen_space_announcement_item3">"کشف تمامی اتاق‌هایی که می‌توانید در فضاهایتان بپیوندید"</string>
<string name="screen_space_announcement_item4">"پیوستن به فضاهای عمومی"</string>
<string name="screen_space_announcement_item5">"ترک هر فضایی که پیوسته‌اید"</string>
<string name="screen_space_announcement_notice">"پالایش، ایجاد و مدیریت کردن فضاها به زودی."</string>
<string name="screen_space_announcement_subtitle">"به نگارش آزمایشی فضاها خوش آمدید! در این نگارش می‌توانید:"</string>
<string name="screen_space_announcement_title">"معرّفی فضاها"</string>
</resources>

View file

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_space_announcement_item1">"Nähdä luomasi tai liittymäsi tilat"</string>
<string name="screen_space_announcement_item2">"Hyväksyä tai hylätä kutsuja tiloihin"</string>
<string name="screen_space_announcement_item3">"Löytää kaikki huoneet, joihin voit liittyä tiloissasi"</string>
<string name="screen_space_announcement_item4">"Liittyä julkisiin tiloihin"</string>
<string name="screen_space_announcement_item5">"Poistua mistä tahansa tilasta, johon olet liittynyt"</string>
<string name="screen_space_announcement_notice">"Tilojen suodatus, luominen ja hallinta on tulossa pian."</string>
<string name="screen_space_announcement_subtitle">"Tervetuloa tilojen beetaversioon! Tämän ensimmäisen version avulla voit:"</string>
<string name="screen_space_announcement_title">"Esittelyssä tilat"</string>
</resources>

View file

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_space_announcement_item1">"Voir les espaces que vous avez créés ou rejoints"</string>
<string name="screen_space_announcement_item2">"Accepter ou refuser les invitations aux espaces"</string>
<string name="screen_space_announcement_item3">"Découvrir les salons que vous pouvez joindre depuis vos espaces"</string>
<string name="screen_space_announcement_item4">"Rejoindre les espaces publics"</string>
<string name="screen_space_announcement_item5">"Quitter les espaces dont vous êtes membre."</string>
<string name="screen_space_announcement_notice">"Le filtrage, la création et la gestion des espaces seront bientôt disponibles."</string>
<string name="screen_space_announcement_subtitle">"Bienvenue dans la version bêta des espaces! Avec cette première version, vous pourrez :"</string>
<string name="screen_space_announcement_title">"Ajout des espaces"</string>
</resources>

View file

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_space_announcement_item1">"Pregledajte prostore koje ste stvorili ili kojima ste se pridružili"</string>
<string name="screen_space_announcement_item2">"Prihvatite ili odbijte pozivnice za prostore"</string>
<string name="screen_space_announcement_item3">"Otkrijte sve sobe kojima se možete pridružiti u svojim prostorima"</string>
<string name="screen_space_announcement_item4">"Pridružite se javnim prostorima"</string>
<string name="screen_space_announcement_item5">"Napustite sve prostore kojima ste se pridružili"</string>
<string name="screen_space_announcement_notice">"Uskoro stiže filtriranje i stvaranje prostora te upravljanje njima."</string>
<string name="screen_space_announcement_subtitle">"Dobrodošli u beta inačicu prostora! S ovom prvom inačicom možete:"</string>
<string name="screen_space_announcement_title">"Predstavljamo prostore"</string>
</resources>

View file

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_space_announcement_item1">"Az Ön által létrehozott vagy csatlakozott térek megtekintése"</string>
<string name="screen_space_announcement_item2">"A meghívások elfogadására vagy elutasítására a terekhez"</string>
<string name="screen_space_announcement_item3">"Szobák felfedezése a terekben, amelyekhez csatlakozhat"</string>
<string name="screen_space_announcement_item4">"Csatlakozás nyilvános terekhez"</string>
<string name="screen_space_announcement_item5">"Terek elhagyása"</string>
<string name="screen_space_announcement_notice">"Terek szűrése, készítése és kezelése hamarosan érkezik."</string>
<string name="screen_space_announcement_subtitle">"Üdvözöljük a tér béta verziójában! Ezzel az első verzióval a következőket teheti:"</string>
<string name="screen_space_announcement_title">"Bemutatkoznak a terek"</string>
</resources>

View file

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_space_announcement_item1">"Visualizza gli spazi che hai creato o a cui partecipi"</string>
<string name="screen_space_announcement_item2">"Accetta o rifiuta gli inviti agli spazi"</string>
<string name="screen_space_announcement_item3">"Scopri tutte le stanze a cui puoi partecipare nei tuoi spazi"</string>
<string name="screen_space_announcement_item4">"Unisciti agli spazi pubblici"</string>
<string name="screen_space_announcement_item5">"Lascia tutti gli spazi a cui ti sei unito"</string>
<string name="screen_space_announcement_notice">"A breve saranno disponibili le funzionalità di filtraggio, creazione e gestione degli spazi."</string>
<string name="screen_space_announcement_subtitle">"Benvenuti alla versione beta degli Spazi! Con questa prima versione potrete:"</string>
<string name="screen_space_announcement_title">"Ti presentiamo gli Spazi"</string>
</resources>

View file

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_space_announcement_item1">"作成または参加したスペースを表示できます"</string>
<string name="screen_space_announcement_item2">"スペースへの招待を受諾または拒否できます"</string>
<string name="screen_space_announcement_item3">"スペース内の参加可能なルームを検索できます"</string>
<string name="screen_space_announcement_item4">"公開スペースに参加できます"</string>
<string name="screen_space_announcement_item5">"参加したスペースを退出できます"</string>
<string name="screen_space_announcement_notice">"スペースの作成や管理, フィルター検索は近日実装予定です。"</string>
<string name="screen_space_announcement_subtitle">"ベータ版のスペースにようこそ。この最新のバージョンでは:"</string>
<string name="screen_space_announcement_title">"スペースの紹介"</string>
</resources>

View file

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_space_announcement_item1">"직접 만들거나 참여 중인 스페이스 보기"</string>
<string name="screen_space_announcement_item2">"스페이스 초대 수락 또는 거절"</string>
<string name="screen_space_announcement_item3">"참여 가능한 스페이스 내 모든 방 탐색"</string>
<string name="screen_space_announcement_item4">"공개 스페이스 참여"</string>
<string name="screen_space_announcement_item5">"참여 중인 스페이스 나가기"</string>
<string name="screen_space_announcement_notice">"스페이스 필터링, 생성 및 관리 기능이 곧 추가될 예정입니다."</string>
<string name="screen_space_announcement_subtitle">"스페이스 베타 버전에 오신 것을 환영합니다! 이번 첫 번째 버전에서는 다음과 같은 기능을 이용하실 수 있습니다.:"</string>
<string name="screen_space_announcement_title">"스페이스 소개"</string>
</resources>

View file

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_space_announcement_item1">"Se områder du har opprettet eller blitt med i"</string>
<string name="screen_space_announcement_item2">"Godta eller avslå invitasjoner til områder"</string>
<string name="screen_space_announcement_item3">"Oppdag alle rom du kan bli med i i dine områder"</string>
<string name="screen_space_announcement_item4">"Bli med i offentlige områder"</string>
<string name="screen_space_announcement_item5">"Forlat områder du har blitt med i"</string>
<string name="screen_space_announcement_notice">"Oppretting, filtrering og administrasjon av områder kommer snart."</string>
<string name="screen_space_announcement_subtitle">"Velkommen til betaversjonen av Områder! Med denne første versjonen kan du:"</string>
<string name="screen_space_announcement_title">"Vi introduserer Områder"</string>
</resources>

View file

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_space_announcement_item1">"Wyświetlić przestrzenie, które stworzyłeś lub do których dołączyłeś"</string>
<string name="screen_space_announcement_item2">"Akceptować lub odrzucać zaproszenia"</string>
<string name="screen_space_announcement_item3">"Odkrywać wszystkie pokoje, do których możesz dołączyć w swoich przestrzeniach"</string>
<string name="screen_space_announcement_item4">"Dołączać do przestrzeni publicznych"</string>
<string name="screen_space_announcement_item5">"Opuszczać jakąkolwiek przestrzeń, do której dołączyłeś"</string>
<string name="screen_space_announcement_notice">"Filtrowanie, tworzenie i zarządzanie przestrzeniami pojawi się wkrótce."</string>
<string name="screen_space_announcement_subtitle">"Witamy w wersji beta przestrzeni! W tej wersji możesz:"</string>
<string name="screen_space_announcement_title">"Przedstawiamy przestrzenie"</string>
</resources>

View file

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_space_announcement_item1">"Visualizar espaços que criou ou entrou"</string>
<string name="screen_space_announcement_item2">"Aceitar ou recusar convites aos espaços"</string>
<string name="screen_space_announcement_item3">"Descobrir quaisquer salas que você pode entrar nos espaços"</string>
<string name="screen_space_announcement_item4">"Entrar espaços públicos"</string>
<string name="screen_space_announcement_item5">"Sair de quaisquer espaços que entrou"</string>
<string name="screen_space_announcement_notice">"Filtrar, criar, e gerenciar espaços virão em breve."</string>
<string name="screen_space_announcement_subtitle">"Boas-vindas à versão beta dos Espaços! Com essa primeira versão, você pode:"</string>
<string name="screen_space_announcement_title">"Apresentando Espaços"</string>
</resources>

View file

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_space_announcement_item1">"Ver espaços que criaste ou nos quais entraste"</string>
<string name="screen_space_announcement_item2">"Aceitar ou recusar convites para espaços"</string>
<string name="screen_space_announcement_item3">"Descobrir todas as salas dos seus espaços nas quais podes entrar"</string>
<string name="screen_space_announcement_item4">"Entrar em espaços públicos"</string>
<string name="screen_space_announcement_item5">"Deixar todos os espaços em que entraste"</string>
<string name="screen_space_announcement_notice">"Em breve, será possível filtrar, criar e gerir espaços."</string>
<string name="screen_space_announcement_subtitle">"Eis a versão beta dos Espaços! Nesta primeira versão, podes:"</string>
<string name="screen_space_announcement_title">"Apresentamos os Espaços"</string>
</resources>

View file

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_space_announcement_item1">"Vizualizați spațiile pe care le-ați creat sau la care v-ați alăturat"</string>
<string name="screen_space_announcement_item2">"Acceptați sau refuzați invitațiile la spații"</string>
<string name="screen_space_announcement_item3">"Descoperiți toate camerele la care vă puteți alătura în spațiile dumneavoastră."</string>
<string name="screen_space_announcement_item4">"Alăturați-vă spațiilor publice"</string>
<string name="screen_space_announcement_item5">"Părăsiți spațiile la care v-ați alăturat."</string>
<string name="screen_space_announcement_notice">"Filtrarea, crearea și gestionarea spațiilor vor fi disponibile în curând."</string>
<string name="screen_space_announcement_subtitle">"Bun venit la versiunea beta a Spațiilor! Cu această primă versiune puteți:"</string>
<string name="screen_space_announcement_title">"Vă prezentăm Spații"</string>
</resources>

View file

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_space_announcement_item1">"Просматривать пространства, которые вы создали или к которым присоединились"</string>
<string name="screen_space_announcement_item2">"Принимать или отклонять приглашения в пространства"</string>
<string name="screen_space_announcement_item3">"Находить все комнаты, к которым можно присоединиться в ваших пространствах"</string>
<string name="screen_space_announcement_item4">"Присоединяться к публичным пространствам"</string>
<string name="screen_space_announcement_item5">"Покидать все пространства, к которым вы присоединились"</string>
<string name="screen_space_announcement_notice">"Фильтровать, создавать пространства и управлять ими можно будет позже."</string>
<string name="screen_space_announcement_subtitle">"Добро пожаловать в бета-версию пространств! Сейчас вы сможете:"</string>
<string name="screen_space_announcement_title">"Представляем пространства"</string>
</resources>

View file

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_space_announcement_item1">"Zobraziť priestory, ktoré ste vytvorili alebo ku ktorým ste sa pripojili"</string>
<string name="screen_space_announcement_item2">"Prijímať alebo odmietať pozvánky do priestorov"</string>
<string name="screen_space_announcement_item3">"Objaviť všetky miestnosti, do ktorých sa môžete pripojiť vo svojich priestoroch"</string>
<string name="screen_space_announcement_item4">"Pripojiť sa k verejnému priestoru"</string>
<string name="screen_space_announcement_item5">"Opustiť akékoľvek priestory, ku ktorým ste sa pridali"</string>
<string name="screen_space_announcement_notice">"Filtrovanie, vytváranie a správa priestorov bude čoskoro k dispozícii."</string>
<string name="screen_space_announcement_subtitle">"Vitajte v beta verzii priestorov! S touto prvou verziou môžete:"</string>
<string name="screen_space_announcement_title">"Predstavujeme priestory"</string>
</resources>

View file

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_space_announcement_item1">"Oluşturduğunuz veya katıldığınız alanları görüntüleyin"</string>
<string name="screen_space_announcement_item2">"Alan davetlerini kabul edin veya reddedin"</string>
<string name="screen_space_announcement_item3">"Alanlarınızdaki katılabileceğiniz odaları keşfedin"</string>
<string name="screen_space_announcement_item4">"Herkese açık alanlara katılın"</string>
<string name="screen_space_announcement_item5">"Katıldığınız alanlardan ayrılın"</string>
<string name="screen_space_announcement_notice">"Alanları filtreleme, oluşturma ve yönetme yakında geliyor."</string>
<string name="screen_space_announcement_subtitle">"Alanların beta sürümüne hoş geldiniz! Bu ilk sürümle şunları yapabilirsiniz:"</string>
<string name="screen_space_announcement_title">"Alanlar ile tanışın"</string>
</resources>

View file

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_space_announcement_item3">"Знаходьте у своїх просторах кімнати, до яких можна приєднатися"</string>
<string name="screen_space_announcement_notice">"Фільтрування, створення та керування просторами стане доступним найближчим часом."</string>
<string name="screen_space_announcement_subtitle">"Ласкаво просимо до бета-версії Просторів! У цій першій версії ви можете:"</string>
<string name="screen_space_announcement_title">"Представляємо Простори"</string>
</resources>

View file

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_space_announcement_item1">"Siz yaratgan yoki qoshilgan maydonlarni korish"</string>
<string name="screen_space_announcement_item2">"Maydonlarga takliflarni qabul qilish yoki rad etish"</string>
<string name="screen_space_announcement_item3">"Maydonlaringizga qoshilishingiz mumkin bolgan xonalarni kashf eting"</string>
<string name="screen_space_announcement_item4">"Jamoat maydonlariga qoshilish"</string>
<string name="screen_space_announcement_item5">"Kirgan maydonlaringizni tark eting"</string>
<string name="screen_space_announcement_notice">"Maydonlarni filtrlash, yaratish va boshqarish tez orada amalga oshiriladi."</string>
<string name="screen_space_announcement_subtitle">"Maydonlar beta versiyasiga xush kelibsiz! Bu birinchi versiya bilan siz:"</string>
<string name="screen_space_announcement_title">"Maydonlar bilan tanishish"</string>
</resources>

View file

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_space_announcement_item1">"檢視您建立或加入的空間"</string>
<string name="screen_space_announcement_item2">"接受或拒絕空間邀請"</string>
<string name="screen_space_announcement_item3">"探索空間內您可以加入的任何聊天室"</string>
<string name="screen_space_announcement_item4">"加入公開空間"</string>
<string name="screen_space_announcement_item5">"離開任何您已加入的空間"</string>
<string name="screen_space_announcement_notice">"篩選、建立與管理空間功能即將推出。"</string>
<string name="screen_space_announcement_subtitle">"歡迎使用空間的測試版!此初始版本可讓您:"</string>
<string name="screen_space_announcement_title">"介紹空間"</string>
</resources>

View file

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_space_announcement_item1">"查看您创建或加入的空间"</string>
<string name="screen_space_announcement_item2">"接受或拒绝空间邀请"</string>
<string name="screen_space_announcement_item3">"发现您可以加入空间的所有房间"</string>
<string name="screen_space_announcement_item4">"加入公共空间"</string>
<string name="screen_space_announcement_item5">"离开你加入的所有空间"</string>
<string name="screen_space_announcement_notice">"筛选、创建及管理空间功能即将上线。"</string>
<string name="screen_space_announcement_subtitle">"欢迎使用空间测试版!使用首个版本,您可以:"</string>
<string name="screen_space_announcement_title">"空间简介"</string>
</resources>

View file

@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="screen_space_announcement_item1">"View spaces you\'ve created or joined"</string>
<string name="screen_space_announcement_item2">"Accept or decline invites to spaces"</string>
<string name="screen_space_announcement_item3">"Discover any rooms you can join in your spaces"</string>
<string name="screen_space_announcement_item4">"Join public spaces"</string>
<string name="screen_space_announcement_item5">"Leave any spaces youve joined"</string>
<string name="screen_space_announcement_notice">"Filtering, creating and managing spaces is coming soon."</string>
<string name="screen_space_announcement_subtitle">"Welcome to the beta version of Spaces! With this first version you can:"</string>
<string name="screen_space_announcement_title">"Introducing Spaces"</string>
</resources>

View file

@ -6,11 +6,14 @@
* Please see LICENSE files in the repository root for full details. * Please see LICENSE files in the repository root for full details.
*/ */
@file:OptIn(ExperimentalTestApi::class)
package io.element.android.features.announcement.impl.fullscreen package io.element.android.features.announcement.impl.fullscreen
import androidx.activity.ComponentActivity import androidx.activity.ComponentActivity
import androidx.compose.ui.test.junit4.AndroidComposeTestRule import androidx.compose.ui.test.AndroidComposeUiTest
import androidx.compose.ui.test.junit4.createAndroidComposeRule import androidx.compose.ui.test.ExperimentalTestApi
import androidx.compose.ui.test.v2.runAndroidComposeUiTest
import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.ext.junit.runners.AndroidJUnit4
import io.element.android.features.announcement.api.Announcement import io.element.android.features.announcement.api.Announcement
import io.element.android.features.announcement.impl.AnnouncementEvent import io.element.android.features.announcement.impl.AnnouncementEvent
@ -20,43 +23,39 @@ import io.element.android.libraries.ui.strings.CommonStrings
import io.element.android.tests.testutils.EventsRecorder import io.element.android.tests.testutils.EventsRecorder
import io.element.android.tests.testutils.clickOn import io.element.android.tests.testutils.clickOn
import io.element.android.tests.testutils.pressBackKey import io.element.android.tests.testutils.pressBackKey
import org.junit.Rule
import org.junit.Test import org.junit.Test
import org.junit.rules.TestRule
import org.junit.runner.RunWith import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class) @RunWith(AndroidJUnit4::class)
class FullscreenAnnouncementViewTest { class FullscreenAnnouncementViewTest {
@get:Rule val rule = createAndroidComposeRule<ComponentActivity>()
@Test @Test
fun `clicking on back sends a AnnouncementEvent`() { fun `clicking on back sends a AnnouncementEvent`() = runAndroidComposeUiTest {
val eventsRecorder = EventsRecorder<AnnouncementEvent>() val eventsRecorder = EventsRecorder<AnnouncementEvent>()
rule.setFullscreenAnnouncementView( setFullscreenAnnouncementView(
anAnnouncementState( anAnnouncementState(
announcement = Announcement.Fullscreen.Space, announcement = Announcement.Fullscreen.Space,
eventSink = eventsRecorder, eventSink = eventsRecorder,
), ),
) )
rule.pressBackKey() pressBackKey()
eventsRecorder.assertSingle(AnnouncementEvent.Continue(Announcement.Fullscreen.Space)) eventsRecorder.assertSingle(AnnouncementEvent.Continue(Announcement.Fullscreen.Space))
} }
@Test @Test
fun `clicking on Continue sends a AnnouncementEvent`() { fun `clicking on Continue sends a AnnouncementEvent`() = runAndroidComposeUiTest {
val eventsRecorder = EventsRecorder<AnnouncementEvent>() val eventsRecorder = EventsRecorder<AnnouncementEvent>()
rule.setFullscreenAnnouncementView( setFullscreenAnnouncementView(
anAnnouncementState( anAnnouncementState(
announcement = Announcement.Fullscreen.Space, announcement = Announcement.Fullscreen.Space,
eventSink = eventsRecorder, eventSink = eventsRecorder,
), ),
) )
rule.clickOn(CommonStrings.action_continue) clickOn(CommonStrings.action_continue)
eventsRecorder.assertSingle(AnnouncementEvent.Continue(Announcement.Fullscreen.Space)) eventsRecorder.assertSingle(AnnouncementEvent.Continue(Announcement.Fullscreen.Space))
} }
} }
private fun <R : TestRule> AndroidComposeTestRule<R, ComponentActivity>.setFullscreenAnnouncementView( private fun AndroidComposeUiTest<ComponentActivity>.setFullscreenAnnouncementView(
state: AnnouncementState, state: AnnouncementState,
) { ) {
setContent { setContent {

View file

@ -14,22 +14,9 @@ import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.matrix.api.core.SessionId
import kotlinx.parcelize.Parcelize import kotlinx.parcelize.Parcelize
sealed interface CallType : NodeInputs, Parcelable { @Parcelize
@Parcelize data class CallData(
data class ExternalUrl(val url: String) : CallType { val sessionId: SessionId,
override fun toString(): String { val roomId: RoomId,
return "ExternalUrl" val isAudioCall: Boolean
} ) : NodeInputs, Parcelable
}
@Parcelize
data class RoomCall(
val sessionId: SessionId,
val roomId: RoomId,
val isAudioCall: Boolean
) : CallType {
override fun toString(): String {
return "RoomCall(sessionId=$sessionId, roomId=$roomId, isAudioCall=$isAudioCall)"
}
}
}

View file

@ -17,13 +17,13 @@ import io.element.android.libraries.matrix.api.core.UserId
interface ElementCallEntryPoint { interface ElementCallEntryPoint {
/** /**
* Start a call of the given type. * Start a call of the given type.
* @param callType The type of call to start. * @param callData The data of call to start.
*/ */
fun startCall(callType: CallType) fun startCall(callData: CallData)
/** /**
* Handle an incoming call. * Handle an incoming call.
* @param callType The type of call. * @param callData The data of call.
* @param eventId The event id of the event that started the call. * @param eventId The event id of the event that started the call.
* @param senderId The user id of the sender of the event that started the call. * @param senderId The user id of the sender of the event that started the call.
* @param roomName The name of the room the call is in. * @param roomName The name of the room the call is in.
@ -35,7 +35,7 @@ interface ElementCallEntryPoint {
* @param textContent The text content of the notification. If null the default content from the system will be used. * @param textContent The text content of the notification. If null the default content from the system will be used.
*/ */
suspend fun handleIncomingCall( suspend fun handleIncomingCall(
callType: CallType.RoomCall, callData: CallData,
eventId: EventId, eventId: EventId,
senderId: UserId, senderId: UserId,
roomName: String?, roomName: String?,

View file

@ -30,44 +30,10 @@
<activity <activity
android:name=".ui.ElementCallActivity" android:name=".ui.ElementCallActivity"
android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation|keyboardHidden|keyboard|navigation|uiMode" android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation|keyboardHidden|keyboard|navigation|uiMode"
android:exported="true"
android:label="@string/element_call" android:label="@string/element_call"
android:launchMode="singleTask" android:launchMode="singleTask"
android:supportsPictureInPicture="true" android:supportsPictureInPicture="true"
android:taskAffinity="io.element.android.features.call"> android:taskAffinity="io.element.android.features.call" />
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" />
<!-- Matching asset file: https://call.element.io/.well-known/assetlinks.json -->
<data android:host="call.element.io" />
</intent-filter>
<!-- Custom scheme to handle urls from other domains in the format: element://call?url=https%3A%2F%2Felement.io -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="element" />
<data android:host="call" />
</intent-filter>
<!-- Custom scheme to handle urls from other domains in the format: io.element.call:/?url=https%3A%2F%2Felement.io -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="io.element.call" />
</intent-filter>
</activity>
<activity <activity
android:name=".ui.IncomingCallActivity" android:name=".ui.IncomingCallActivity"

View file

@ -11,7 +11,7 @@ package io.element.android.features.call.impl
import android.content.Context import android.content.Context
import dev.zacsweers.metro.AppScope import dev.zacsweers.metro.AppScope
import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.ContributesBinding
import io.element.android.features.call.api.CallType import io.element.android.features.call.api.CallData
import io.element.android.features.call.api.ElementCallEntryPoint import io.element.android.features.call.api.ElementCallEntryPoint
import io.element.android.features.call.impl.notifications.CallNotificationData import io.element.android.features.call.impl.notifications.CallNotificationData
import io.element.android.features.call.impl.utils.ActiveCallManager import io.element.android.features.call.impl.utils.ActiveCallManager
@ -30,12 +30,12 @@ class DefaultElementCallEntryPoint(
const val REQUEST_CODE = 2255 const val REQUEST_CODE = 2255
} }
override fun startCall(callType: CallType) { override fun startCall(callData: CallData) {
context.startActivity(IntentProvider.createIntent(context, callType)) context.startActivity(IntentProvider.createIntent(context, callData))
} }
override suspend fun handleIncomingCall( override suspend fun handleIncomingCall(
callType: CallType.RoomCall, callData: CallData,
eventId: EventId, eventId: EventId,
senderId: UserId, senderId: UserId,
roomName: String?, roomName: String?,
@ -47,8 +47,8 @@ class DefaultElementCallEntryPoint(
textContent: String?, textContent: String?,
) { ) {
val incomingCallNotificationData = CallNotificationData( val incomingCallNotificationData = CallNotificationData(
sessionId = callType.sessionId, sessionId = callData.sessionId,
roomId = callType.roomId, roomId = callData.roomId,
eventId = eventId, eventId = eventId,
senderId = senderId, senderId = senderId,
roomName = roomName, roomName = roomName,
@ -58,7 +58,7 @@ class DefaultElementCallEntryPoint(
expirationTimestamp = expirationTimestamp, expirationTimestamp = expirationTimestamp,
notificationChannelId = notificationChannelId, notificationChannelId = notificationChannelId,
textContent = textContent, textContent = textContent,
audioOnly = callType.isAudioCall audioOnly = callData.isAudioCall,
) )
activeCallManager.registerIncomingCall(notificationData = incomingCallNotificationData) activeCallManager.registerIncomingCall(notificationData = incomingCallNotificationData)
} }

View file

@ -18,7 +18,7 @@ import androidx.core.app.PendingIntentCompat
import androidx.core.app.Person import androidx.core.app.Person
import dev.zacsweers.metro.Inject import dev.zacsweers.metro.Inject
import io.element.android.appconfig.ElementCallConfig import io.element.android.appconfig.ElementCallConfig
import io.element.android.features.call.api.CallType import io.element.android.features.call.api.CallData
import io.element.android.features.call.impl.receivers.DeclineCallBroadcastReceiver import io.element.android.features.call.impl.receivers.DeclineCallBroadcastReceiver
import io.element.android.features.call.impl.ui.IncomingCallActivity import io.element.android.features.call.impl.ui.IncomingCallActivity
import io.element.android.features.call.impl.utils.IntentProvider import io.element.android.features.call.impl.utils.IntentProvider
@ -89,7 +89,14 @@ class RingingCallNotificationCreator(
.setImportant(true) .setImportant(true)
.build() .build()
val answerIntent = IntentProvider.getPendingIntent(context, CallType.RoomCall(sessionId, roomId, isAudioCall = audioOnly)) val answerIntent = IntentProvider.getPendingIntent(
context,
CallData(
sessionId = sessionId,
roomId = roomId,
isAudioCall = audioOnly,
),
)
val notificationData = CallNotificationData( val notificationData = CallNotificationData(
sessionId = sessionId, sessionId = sessionId,
roomId = roomId, roomId = roomId,

View file

@ -10,8 +10,8 @@ package io.element.android.features.call.impl.pip
import io.element.android.features.call.impl.utils.PipController import io.element.android.features.call.impl.utils.PipController
sealed interface PictureInPictureEvents { sealed interface PictureInPictureEvent {
data class SetPipController(val pipController: PipController) : PictureInPictureEvents data class SetPipController(val pipController: PipController) : PictureInPictureEvent
data object EnterPictureInPicture : PictureInPictureEvents data object EnterPictureInPicture : PictureInPictureEvent
data class OnPictureInPictureModeChanged(val isInPip: Boolean) : PictureInPictureEvents data class OnPictureInPictureModeChanged(val isInPip: Boolean) : PictureInPictureEvent
} }

View file

@ -36,17 +36,17 @@ class PictureInPicturePresenter(
var isInPictureInPicture by remember { mutableStateOf(false) } var isInPictureInPicture by remember { mutableStateOf(false) }
var pipController by remember { mutableStateOf<PipController?>(null) } var pipController by remember { mutableStateOf<PipController?>(null) }
fun handleEvent(event: PictureInPictureEvents) { fun handleEvent(event: PictureInPictureEvent) {
when (event) { when (event) {
is PictureInPictureEvents.SetPipController -> { is PictureInPictureEvent.SetPipController -> {
pipController = event.pipController pipController = event.pipController
} }
PictureInPictureEvents.EnterPictureInPicture -> { PictureInPictureEvent.EnterPictureInPicture -> {
coroutineScope.launch { coroutineScope.launch {
switchToPip(pipController) switchToPip(pipController)
} }
} }
is PictureInPictureEvents.OnPictureInPictureModeChanged -> { is PictureInPictureEvent.OnPictureInPictureModeChanged -> {
Timber.tag(loggerTag.value).d("onPictureInPictureModeChanged: ${event.isInPip}") Timber.tag(loggerTag.value).d("onPictureInPictureModeChanged: ${event.isInPip}")
isInPictureInPicture = event.isInPip isInPictureInPicture = event.isInPip
if (event.isInPip) { if (event.isInPip) {

View file

@ -11,5 +11,5 @@ package io.element.android.features.call.impl.pip
data class PictureInPictureState( data class PictureInPictureState(
val supportPip: Boolean, val supportPip: Boolean,
val isInPictureInPicture: Boolean, val isInPictureInPicture: Boolean,
val eventSink: (PictureInPictureEvents) -> Unit, val eventSink: (PictureInPictureEvent) -> Unit,
) )

View file

@ -11,7 +11,7 @@ package io.element.android.features.call.impl.pip
fun aPictureInPictureState( fun aPictureInPictureState(
supportPip: Boolean = false, supportPip: Boolean = false,
isInPictureInPicture: Boolean = false, isInPictureInPicture: Boolean = false,
eventSink: (PictureInPictureEvents) -> Unit = {}, eventSink: (PictureInPictureEvent) -> Unit = {},
): PictureInPictureState { ): PictureInPictureState {
return PictureInPictureState( return PictureInPictureState(
supportPip = supportPip, supportPip = supportPip,

View file

@ -13,7 +13,7 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import androidx.core.content.IntentCompat import androidx.core.content.IntentCompat
import dev.zacsweers.metro.Inject import dev.zacsweers.metro.Inject
import io.element.android.features.call.api.CallType import io.element.android.features.call.api.CallData
import io.element.android.features.call.impl.di.CallBindings import io.element.android.features.call.impl.di.CallBindings
import io.element.android.features.call.impl.notifications.CallNotificationData import io.element.android.features.call.impl.notifications.CallNotificationData
import io.element.android.features.call.impl.utils.ActiveCallManager import io.element.android.features.call.impl.utils.ActiveCallManager
@ -42,7 +42,7 @@ class DeclineCallBroadcastReceiver : BroadcastReceiver() {
context.bindings<CallBindings>().inject(this) context.bindings<CallBindings>().inject(this)
appCoroutineScope.launch { appCoroutineScope.launch {
activeCallManager.hangUpCall( activeCallManager.hangUpCall(
callType = CallType.RoomCall( callData = CallData(
sessionId = notificationData.sessionId, sessionId = notificationData.sessionId,
roomId = notificationData.roomId, roomId = notificationData.roomId,
isAudioCall = notificationData.audioOnly isAudioCall = notificationData.audioOnly

View file

@ -9,6 +9,8 @@ package io.element.android.features.call.impl.ui
import androidx.compose.ui.tooling.preview.PreviewParameterProvider import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import io.element.android.features.call.impl.notifications.CallNotificationData import io.element.android.features.call.impl.notifications.CallNotificationData
import io.element.android.libraries.designsystem.preview.ROOM_NAME
import io.element.android.libraries.designsystem.preview.USER_NAME_BOB
import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.RoomId
import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.matrix.api.core.SessionId
@ -34,8 +36,8 @@ internal fun aCallNotificationData(
roomId = RoomId("!1234:matrix.org"), roomId = RoomId("!1234:matrix.org"),
eventId = EventId("\$asdadadsad:matrix.org"), eventId = EventId("\$asdadadsad:matrix.org"),
senderId = UserId("@bob:matrix.org"), senderId = UserId("@bob:matrix.org"),
roomName = "A room", roomName = ROOM_NAME,
senderName = "Bob", senderName = USER_NAME_BOB,
avatarUrl = null, avatarUrl = null,
notificationChannelId = "incoming_call", notificationChannelId = "incoming_call",
timestamp = 0L, timestamp = 0L,

View file

@ -0,0 +1,26 @@
/*
* Copyright (c) 2026 Element Creations Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
* Please see LICENSE files in the repository root for full details.
*/
package io.element.android.features.call.impl.ui
internal sealed interface CallScreenBackPressAction {
data object DispatchEscapeToWebView : CallScreenBackPressAction
data object EnterPictureInPicture : CallScreenBackPressAction
}
internal object CallScreenBackPressPolicy {
fun resolve(
supportPip: Boolean,
hasWebView: Boolean,
fromNative: Boolean,
): CallScreenBackPressAction? {
return when {
hasWebView && fromNative -> CallScreenBackPressAction.DispatchEscapeToWebView
hasWebView && supportPip -> CallScreenBackPressAction.EnterPictureInPicture
else -> null
}
}
}

View file

@ -10,8 +10,8 @@ package io.element.android.features.call.impl.ui
import io.element.android.features.call.impl.utils.WidgetMessageInterceptor import io.element.android.features.call.impl.utils.WidgetMessageInterceptor
sealed interface CallScreenEvents { sealed interface CallScreenEvent {
data object Hangup : CallScreenEvents data object Hangup : CallScreenEvent
data class SetupMessageChannels(val widgetMessageInterceptor: WidgetMessageInterceptor) : CallScreenEvents data class SetupMessageChannels(val widgetMessageInterceptor: WidgetMessageInterceptor) : CallScreenEvent
data class OnWebViewError(val description: String?) : CallScreenEvents data class OnWebViewError(val description: String?) : CallScreenEvent
} }

View file

@ -23,7 +23,7 @@ import dev.zacsweers.metro.AssistedFactory
import dev.zacsweers.metro.AssistedInject import dev.zacsweers.metro.AssistedInject
import im.vector.app.features.analytics.plan.MobileScreen import im.vector.app.features.analytics.plan.MobileScreen
import io.element.android.compound.theme.ElementTheme import io.element.android.compound.theme.ElementTheme
import io.element.android.features.call.api.CallType import io.element.android.features.call.api.CallData
import io.element.android.features.call.impl.data.WidgetMessage import io.element.android.features.call.impl.data.WidgetMessage
import io.element.android.features.call.impl.utils.ActiveCallManager import io.element.android.features.call.impl.utils.ActiveCallManager
import io.element.android.features.call.impl.utils.CallWidgetProvider import io.element.android.features.call.impl.utils.CallWidgetProvider
@ -52,7 +52,7 @@ import kotlin.time.Duration.Companion.seconds
@AssistedInject @AssistedInject
class CallScreenPresenter( class CallScreenPresenter(
@Assisted private val callType: CallType, @Assisted private val callData: CallData,
@Assisted private val navigator: CallScreenNavigator, @Assisted private val navigator: CallScreenNavigator,
private val callWidgetProvider: CallWidgetProvider, private val callWidgetProvider: CallWidgetProvider,
userAgentProvider: UserAgentProvider, userAgentProvider: UserAgentProvider,
@ -69,10 +69,9 @@ class CallScreenPresenter(
) : Presenter<CallScreenState> { ) : Presenter<CallScreenState> {
@AssistedFactory @AssistedFactory
interface Factory { interface Factory {
fun create(callType: CallType, navigator: CallScreenNavigator): CallScreenPresenter fun create(callData: CallData, navigator: CallScreenNavigator): CallScreenPresenter
} }
private val isInWidgetMode = callType is CallType.RoomCall
private val userAgent = userAgentProvider.provide() private val userAgent = userAgentProvider.provide()
@Composable @Composable
@ -90,9 +89,9 @@ class CallScreenPresenter(
DisposableEffect(Unit) { DisposableEffect(Unit) {
coroutineScope.launch { coroutineScope.launch {
// Sets the call as joined // Sets the call as joined
activeCallManager.joinedCall(callType) activeCallManager.joinedCall(callData)
fetchRoomCallUrl( fetchRoomCallUrl(
inputs = callType, callData = callData,
urlState = urlState, urlState = urlState,
callWidgetDriver = callWidgetDriver, callWidgetDriver = callWidgetDriver,
languageTag = languageTag, languageTag = languageTag,
@ -100,19 +99,10 @@ class CallScreenPresenter(
) )
} }
onDispose { onDispose {
appCoroutineScope.launch { activeCallManager.hangUpCall(callType) } appCoroutineScope.launch { activeCallManager.hangUpCall(callData) }
} }
} }
screenTracker.TrackScreen(screen = MobileScreen.ScreenName.RoomCall)
when (callType) {
is CallType.ExternalUrl -> {
// No analytics yet for external calls
}
is CallType.RoomCall -> {
screenTracker.TrackScreen(screen = MobileScreen.ScreenName.RoomCall)
}
}
HandleMatrixClientSyncState() HandleMatrixClientSyncState()
callWidgetDriver.value?.let { driver -> callWidgetDriver.value?.let { driver ->
@ -149,25 +139,22 @@ class CallScreenPresenter(
.launchIn(this) .launchIn(this)
} }
if (callType is CallType.RoomCall) { LaunchedEffect(Unit) {
// Note: For external calls isWidgetLoaded will always be false // Wait for the call to be joined, if it takes too long, we display an error
LaunchedEffect(Unit) { delay(10.seconds)
// Wait for the call to be joined, if it takes too long, we display an error
delay(10.seconds)
if (!isWidgetLoaded) { if (!isWidgetLoaded) {
Timber.w("The call took too long to load. Displaying an error before exiting.") Timber.w("The call took too long to load. Displaying an error before exiting.")
// This will display a simple 'Sorry, an error occurred' dialog and force the user to exit the call // This will display a simple 'Sorry, an error occurred' dialog and force the user to exit the call
webViewError = "" webViewError = ""
}
} }
} }
} }
fun handleEvent(event: CallScreenEvents) { fun handleEvent(event: CallScreenEvent) {
when (event) { when (event) {
is CallScreenEvents.Hangup -> { is CallScreenEvent.Hangup -> {
val widgetId = callWidgetDriver.value?.id val widgetId = callWidgetDriver.value?.id
val interceptor = messageInterceptor.value val interceptor = messageInterceptor.value
if (widgetId != null && interceptor != null && isWidgetLoaded) { if (widgetId != null && interceptor != null && isWidgetLoaded) {
@ -187,10 +174,10 @@ class CallScreenPresenter(
} }
} }
} }
is CallScreenEvents.SetupMessageChannels -> { is CallScreenEvent.SetupMessageChannels -> {
messageInterceptor.value = event.widgetMessageInterceptor messageInterceptor.value = event.widgetMessageInterceptor
} }
is CallScreenEvents.OnWebViewError -> { is CallScreenEvent.OnWebViewError -> {
if (!ignoreWebViewError) { if (!ignoreWebViewError) {
webViewError = event.description.orEmpty() webViewError = event.description.orEmpty()
} }
@ -204,37 +191,29 @@ class CallScreenPresenter(
webViewError = webViewError, webViewError = webViewError,
userAgent = userAgent, userAgent = userAgent,
isCallActive = isWidgetLoaded, isCallActive = isWidgetLoaded,
isInWidgetMode = isInWidgetMode,
eventSink = ::handleEvent, eventSink = ::handleEvent,
) )
} }
private suspend fun fetchRoomCallUrl( private suspend fun fetchRoomCallUrl(
inputs: CallType, callData: CallData,
urlState: MutableState<AsyncData<String>>, urlState: MutableState<AsyncData<String>>,
callWidgetDriver: MutableState<MatrixWidgetDriver?>, callWidgetDriver: MutableState<MatrixWidgetDriver?>,
languageTag: String?, languageTag: String?,
theme: String?, theme: String?,
) { ) {
urlState.runCatchingUpdatingState { urlState.runCatchingUpdatingState {
when (inputs) { val result = callWidgetProvider.getWidget(
is CallType.ExternalUrl -> { sessionId = callData.sessionId,
inputs.url roomId = callData.roomId,
} clientId = UUID.randomUUID().toString(),
is CallType.RoomCall -> { isAudioCall = callData.isAudioCall,
val result = callWidgetProvider.getWidget( languageTag = languageTag,
sessionId = inputs.sessionId, theme = theme,
roomId = inputs.roomId, ).getOrThrow()
clientId = UUID.randomUUID().toString(), callWidgetDriver.value = result.driver
isAudioCall = inputs.isAudioCall, Timber.d("Call widget driver initialized for sessionId: ${callData.sessionId}, roomId: ${callData.roomId}")
languageTag = languageTag, result.url
theme = theme,
).getOrThrow()
callWidgetDriver.value = result.driver
Timber.d("Call widget driver initialized for sessionId: ${inputs.sessionId}, roomId: ${inputs.roomId}")
result.url
}
}
} }
} }
@ -242,12 +221,11 @@ class CallScreenPresenter(
private fun HandleMatrixClientSyncState() { private fun HandleMatrixClientSyncState() {
val coroutineScope = rememberCoroutineScope() val coroutineScope = rememberCoroutineScope()
DisposableEffect(Unit) { DisposableEffect(Unit) {
val roomCallType = callType as? CallType.RoomCall ?: return@DisposableEffect onDispose {} val client = matrixClientsProvider.getOrNull(callData.sessionId) ?: return@DisposableEffect onDispose {
val client = matrixClientsProvider.getOrNull(roomCallType.sessionId) ?: return@DisposableEffect onDispose { Timber.w("No MatrixClient found for sessionId, can't send call notification: ${callData.sessionId}")
Timber.w("No MatrixClient found for sessionId, can't send call notification: ${roomCallType.sessionId}")
} }
coroutineScope.launch { coroutineScope.launch {
Timber.d("Observing sync state in-call for sessionId: ${roomCallType.sessionId}") Timber.d("Observing sync state in-call for sessionId: ${callData.sessionId}")
client.syncService.syncState client.syncService.syncState
.collect { state -> .collect { state ->
if (state != SyncState.Running) { if (state != SyncState.Running) {
@ -256,7 +234,7 @@ class CallScreenPresenter(
} }
} }
onDispose { onDispose {
Timber.d("Stopped observing sync state in-call for sessionId: ${roomCallType.sessionId}") Timber.d("Stopped observing sync state in-call for sessionId: ${callData.sessionId}")
// Make sure we mark the call as ended in the app state // Make sure we mark the call as ended in the app state
appForegroundStateService.updateIsInCallState(false) appForegroundStateService.updateIsInCallState(false)
} }

View file

@ -15,6 +15,5 @@ data class CallScreenState(
val webViewError: String?, val webViewError: String?,
val userAgent: String, val userAgent: String,
val isCallActive: Boolean, val isCallActive: Boolean,
val isInWidgetMode: Boolean, val eventSink: (CallScreenEvent) -> Unit,
val eventSink: (CallScreenEvents) -> Unit,
) )

View file

@ -26,15 +26,13 @@ internal fun aCallScreenState(
webViewError: String? = null, webViewError: String? = null,
userAgent: String = "", userAgent: String = "",
isCallActive: Boolean = true, isCallActive: Boolean = true,
isInWidgetMode: Boolean = false, eventSink: (CallScreenEvent) -> Unit = {},
eventSink: (CallScreenEvents) -> Unit = {},
): CallScreenState { ): CallScreenState {
return CallScreenState( return CallScreenState(
urlState = urlState, urlState = urlState,
webViewError = webViewError, webViewError = webViewError,
userAgent = userAgent, userAgent = userAgent,
isCallActive = isCallActive, isCallActive = isCallActive,
isInWidgetMode = isInWidgetMode,
eventSink = eventSink, eventSink = eventSink,
) )
} }

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