Skip to content

Commit 86ec2f5

Browse files
committed
Merge branch 'release/25.07.0' into main
2 parents 426e5de + 622be77 commit 86ec2f5

File tree

1,075 files changed

+9410
-3980
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

1,075 files changed

+9410
-3980
lines changed

.github/workflows/quality.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,6 @@ jobs:
270270
- name: Run shellcheck
271271
uses: ludeeus/[email protected]
272272
with:
273-
scandir: ./tools
274273
severity: warning
275274

276275
upload_reports:

.github/workflows/scripts/maestro/local-recording.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ mkdir -p /data/local/tmp/recordings;
1212
FILENAME=/data/local/tmp/recordings/testRecording$COUNT.mp4
1313
while true
1414
do
15-
((COUNT++))
15+
COUNT=$((COUNT+1))
1616
FILENAME=/data/local/tmp/recordings/testRecording$COUNT.mp4
17-
echo "\nRecording video file #$COUNT"
17+
printf "\nRecording video file #%d\n" $COUNT
1818
screenrecord --bugreport --bit-rate=16m --size 720x1280 $FILENAME
1919
done

.idea/kotlinc.xml

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

CHANGES.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,45 @@
1+
Changes in Element X v25.06.3
2+
=============================
3+
4+
## What's Changed
5+
### ✨ Features
6+
* Feature : room version upgrade by @ganfra in https://github.com/element-hq/element-x-android/pull/4862
7+
* Add a developer option for history sharing on invite by @richvdh in https://github.com/element-hq/element-x-android/pull/4821
8+
### 🙌 Improvements
9+
* Change : add tombstoned room decoration by @ganfra in https://github.com/element-hq/element-x-android/pull/4891
10+
* Show generic notification when Event cannot be resolved by @bmarty in https://github.com/element-hq/element-x-android/pull/4889
11+
### 🐛 Bugfixes
12+
* [a11y] Improve screen reader on polls by @bmarty in https://github.com/element-hq/element-x-android/pull/4875
13+
* fix (event action): allow to edit only if permission to send message by @ganfra in https://github.com/element-hq/element-x-android/pull/4895
14+
* fix (room upgrade) : room predecessor banner on DM room by @ganfra in https://github.com/element-hq/element-x-android/pull/4896
15+
* fix (join room) : do not navigate up when join is successful by @ganfra in https://github.com/element-hq/element-x-android/pull/4899
16+
### 🗣 Translations
17+
* Sync Strings by @ElementBot in https://github.com/element-hq/element-x-android/pull/4842
18+
* Sync Strings by @ElementBot in https://github.com/element-hq/element-x-android/pull/4881
19+
### Dependency upgrades
20+
* chore(deps): update plugin dependencycheck to v12.1.3 by @renovate in https://github.com/element-hq/element-x-android/pull/4856
21+
* fix(deps): update dependency org.maplibre.gl:android-sdk to v11.10.2 by @renovate in https://github.com/element-hq/element-x-android/pull/4858
22+
* fix(deps): update kotlin to v2.1.21-2.0.2 by @renovate in https://github.com/element-hq/element-x-android/pull/4850
23+
* fix(deps): update dependency app.cash.turbine:turbine to v1.2.1 by @renovate in https://github.com/element-hq/element-x-android/pull/4865
24+
* Update dependency com.posthog:posthog-android to v3.18.0 by @renovate in https://github.com/element-hq/element-x-android/pull/4873
25+
* Update dependency org.maplibre.gl:android-sdk to v11.10.3 by @renovate in https://github.com/element-hq/element-x-android/pull/4879
26+
* fix(deps): update dependency com.posthog:posthog-android to v3.19.0 by @renovate in https://github.com/element-hq/element-x-android/pull/4882
27+
* fix(deps): update dependency io.sentry:sentry-android to v8.13.3 by @renovate in https://github.com/element-hq/element-x-android/pull/4870
28+
* fix(deps): update showkase to v1.0.4 by @renovate in https://github.com/element-hq/element-x-android/pull/4878
29+
* fix(deps): update dependency org.matrix.rustcomponents:sdk-android to v25.6.18 by @renovate in https://github.com/element-hq/element-x-android/pull/4894
30+
### Others
31+
* Annotate Composable functions with `@ReadOnlyComposable` where it's possible by @bmarty in https://github.com/element-hq/element-x-android/pull/4859
32+
* Add documentation on WebViewPipController by @bmarty in https://github.com/element-hq/element-x-android/pull/4861
33+
* Small cleanup around log tag. by @bmarty in https://github.com/element-hq/element-x-android/pull/4860
34+
* Another cleanup by @bmarty in https://github.com/element-hq/element-x-android/pull/4869
35+
* Disable BT audio devices for Element Call on Android < 12 by @jmartinesp in https://github.com/element-hq/element-x-android/pull/4876
36+
* Add a banner to ask the user to disable battery optimization when Event cannot be resolved from Push by @bmarty in https://github.com/element-hq/element-x-android/pull/4845
37+
* a11y: improve accessibility on rich text editor options. by @bmarty in https://github.com/element-hq/element-x-android/pull/4886
38+
* A11Y: improve accessibility on event reactions. by @bmarty in https://github.com/element-hq/element-x-android/pull/4877
39+
40+
41+
**Full Changelog**: https://github.com/element-hq/element-x-android/compare/v25.06.2...v25.06.3
42+
143
Changes in Element X v25.06.2
244
=============================
345

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ Learn more about why we are building Element X in our blog post: [https://elemen
2424
* [Translations](#translations)
2525
* [Rust SDK](#rust-sdk)
2626
* [Status](#status)
27+
* [Minimum SDK version](#minimum-sdk-version)
2728
* [Contributing](#contributing)
2829
* [Build instructions](#build-instructions)
2930
* [Support](#support)
@@ -73,6 +74,12 @@ We're doing this as a way to share code between platforms and while we've seen p
7374

7475
This project is in an early rollout and migration phase.
7576

77+
## Minimum SDK version
78+
79+
Element X Android requires a minimum SDK version of 24 (Android 7.0, Nougat). We aim to support devices running Android 7.0 and above, which covers a wide range of devices still in use today.
80+
81+
Element Android Enterprise requires a minimum SDK version of 33 (Android 13, Tiramisu). For Element Enterprise, we support only devices that still receive security updates, which means devices running Android 13 and above. Android does not have a documented support policy, but some information can be found at [https://endoflife.date/android](https://endoflife.date/android).
82+
7683
## Contributing
7784

7885
Want to get actively involved in the project? You're more than welcome! A good way to start is to check the issues that are labelled with the [good first issue](https://github.com/element-hq/element-x-android/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22) label. Let us know by commenting the issue that you're starting working on it.

app/src/main/res/xml/locales_config.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
<locale android:name="bg"/>
55
<locale android:name="cs"/>
66
<locale android:name="cy"/>
7+
<locale android:name="da"/>
78
<locale android:name="de"/>
89
<locale android:name="el"/>
910
<locale android:name="en"/>

appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import dagger.assisted.AssistedInject
4141
import im.vector.app.features.analytics.plan.JoinedRoom
4242
import io.element.android.anvilannotations.ContributesNode
4343
import io.element.android.appnav.loggedin.LoggedInNode
44+
import io.element.android.appnav.loggedin.MediaPreviewConfigMigration
4445
import io.element.android.appnav.loggedin.SendQueues
4546
import io.element.android.appnav.room.RoomFlowNode
4647
import io.element.android.appnav.room.RoomNavigationTarget
@@ -49,11 +50,11 @@ import io.element.android.features.createroom.api.CreateRoomEntryPoint
4950
import io.element.android.features.ftue.api.FtueEntryPoint
5051
import io.element.android.features.ftue.api.state.FtueService
5152
import io.element.android.features.ftue.api.state.FtueState
53+
import io.element.android.features.home.api.HomeEntryPoint
5254
import io.element.android.features.logout.api.LogoutEntryPoint
5355
import io.element.android.features.preferences.api.PreferencesEntryPoint
5456
import io.element.android.features.roomdirectory.api.RoomDescription
5557
import io.element.android.features.roomdirectory.api.RoomDirectoryEntryPoint
56-
import io.element.android.features.roomlist.api.RoomListEntryPoint
5758
import io.element.android.features.securebackup.api.SecureBackupEntryPoint
5859
import io.element.android.features.share.api.ShareEntryPoint
5960
import io.element.android.features.userprofile.api.UserProfileEntryPoint
@@ -90,6 +91,15 @@ import java.time.Duration
9091
import java.time.Instant
9192
import java.util.Optional
9293
import java.util.UUID
94+
import kotlin.collections.List
95+
import kotlin.collections.any
96+
import kotlin.collections.emptyList
97+
import kotlin.collections.first
98+
import kotlin.collections.forEach
99+
import kotlin.collections.listOf
100+
import kotlin.collections.mapNotNull
101+
import kotlin.collections.plus
102+
import kotlin.collections.setOf
93103
import kotlin.time.Duration.Companion.minutes
94104
import kotlin.time.Duration.Companion.seconds
95105
import kotlin.time.toKotlinDuration
@@ -98,7 +108,7 @@ import kotlin.time.toKotlinDuration
98108
class LoggedInFlowNode @AssistedInject constructor(
99109
@Assisted buildContext: BuildContext,
100110
@Assisted plugins: List<Plugin>,
101-
private val roomListEntryPoint: RoomListEntryPoint,
111+
private val homeEntryPoint: HomeEntryPoint,
102112
private val preferencesEntryPoint: PreferencesEntryPoint,
103113
private val createRoomEntryPoint: CreateRoomEntryPoint,
104114
private val appNavigationStateService: AppNavigationStateService,
@@ -114,6 +124,7 @@ class LoggedInFlowNode @AssistedInject constructor(
114124
private val sendingQueue: SendQueues,
115125
private val logoutEntryPoint: LogoutEntryPoint,
116126
private val incomingVerificationEntryPoint: IncomingVerificationEntryPoint,
127+
private val mediaPreviewConfigMigration: MediaPreviewConfigMigration,
117128
snackbarDispatcher: SnackbarDispatcher,
118129
) : BaseFlowNode<LoggedInFlowNode.NavTarget>(
119130
backstack = BackStack(
@@ -160,7 +171,7 @@ class LoggedInFlowNode @AssistedInject constructor(
160171
// Otherwise, the RoomList UI may be incorrectly displayed on top
161172
withTimeout(5.seconds) {
162173
backstack.elements.first { elements ->
163-
elements.any { it.key.navTarget == NavTarget.RoomList }
174+
elements.any { it.key.navTarget == NavTarget.Home }
164175
}
165176
}
166177

@@ -179,13 +190,14 @@ class LoggedInFlowNode @AssistedInject constructor(
179190
appNavigationStateService.onNavigateToSpace(id, MAIN_SPACE)
180191
loggedInFlowProcessor.observeEvents(sessionCoroutineScope)
181192
matrixClient.sessionVerificationService().setListener(verificationListener)
193+
mediaPreviewConfigMigration()
182194

183195
ftueService.state
184196
.onEach { ftueState ->
185197
when (ftueState) {
186198
is FtueState.Unknown -> Unit // Nothing to do
187199
is FtueState.Incomplete -> backstack.safeRoot(NavTarget.Ftue)
188-
is FtueState.Complete -> backstack.safeRoot(NavTarget.RoomList)
200+
is FtueState.Complete -> backstack.safeRoot(NavTarget.Home)
189201
}
190202
}
191203
.launchIn(lifecycleScope)
@@ -212,7 +224,7 @@ class LoggedInFlowNode @AssistedInject constructor(
212224
data object LoggedInPermanent : NavTarget
213225

214226
@Parcelize
215-
data object RoomList : NavTarget
227+
data object Home : NavTarget
216228

217229
@Parcelize
218230
data class Room(
@@ -269,8 +281,8 @@ class LoggedInFlowNode @AssistedInject constructor(
269281
}
270282
createNode<LoggedInNode>(buildContext, listOf(callback))
271283
}
272-
NavTarget.RoomList -> {
273-
val callback = object : RoomListEntryPoint.Callback {
284+
NavTarget.Home -> {
285+
val callback = object : HomeEntryPoint.Callback {
274286
override fun onRoomClick(roomId: RoomId) {
275287
backstack.push(NavTarget.Room(roomId.toRoomIdOrAlias()))
276288
}
@@ -303,7 +315,7 @@ class LoggedInFlowNode @AssistedInject constructor(
303315
backstack.push(NavTarget.LogoutForNativeSlidingSyncMigrationNeeded)
304316
}
305317
}
306-
roomListEntryPoint
318+
homeEntryPoint
307319
.nodeBuilder(this, buildContext)
308320
.callback(callback)
309321
.build()
@@ -487,7 +499,7 @@ class LoggedInFlowNode @AssistedInject constructor(
487499
clearBackstack: Boolean,
488500
) {
489501
waitForNavTargetAttached { navTarget ->
490-
navTarget is NavTarget.RoomList
502+
navTarget is NavTarget.Home
491503
}
492504
attachChild<RoomFlowNode> {
493505
val roomNavTarget = NavTarget.Room(
@@ -504,7 +516,7 @@ class LoggedInFlowNode @AssistedInject constructor(
504516

505517
suspend fun attachUser(userId: UserId) {
506518
waitForNavTargetAttached { navTarget ->
507-
navTarget is NavTarget.RoomList
519+
navTarget is NavTarget.Home
508520
}
509521
attachChild<Node> {
510522
backstack.push(
@@ -517,7 +529,7 @@ class LoggedInFlowNode @AssistedInject constructor(
517529

518530
internal suspend fun attachIncomingShare(intent: Intent) {
519531
waitForNavTargetAttached { navTarget ->
520-
navTarget is NavTarget.RoomList
532+
navTarget is NavTarget.Home
521533
}
522534
attachChild<Node> {
523535
backstack.push(
@@ -555,7 +567,7 @@ private class AttachRoomOperation(
555567
return if (clearBackstack) {
556568
// Makes sure the room list target is alone in the backstack and stashed
557569
elements.mapNotNull { element ->
558-
if (element.key.navTarget == LoggedInFlowNode.NavTarget.RoomList) {
570+
if (element.key.navTarget == LoggedInFlowNode.NavTarget.Home) {
559571
element.transitionTo(STASHED, this)
560572
} else {
561573
null
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* Copyright 2025 New Vector Ltd.
3+
*
4+
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
5+
* Please see LICENSE files in the repository root for full details.
6+
*/
7+
8+
package io.element.android.appnav.loggedin
9+
10+
import io.element.android.libraries.di.annotations.SessionCoroutineScope
11+
import io.element.android.libraries.matrix.api.media.MediaPreviewService
12+
import io.element.android.libraries.preferences.api.store.AppPreferencesStore
13+
import kotlinx.coroutines.CoroutineScope
14+
import kotlinx.coroutines.flow.first
15+
import kotlinx.coroutines.launch
16+
import timber.log.Timber
17+
import javax.inject.Inject
18+
19+
/**
20+
* This migration is temporary, will be safe to remove after some time.
21+
* The goal is to set the server config if it's not set, and remove the local data.
22+
*/
23+
class MediaPreviewConfigMigration @Inject constructor(
24+
private val mediaPreviewService: MediaPreviewService,
25+
private val appPreferencesStore: AppPreferencesStore,
26+
@SessionCoroutineScope
27+
private val sessionCoroutineScope: CoroutineScope,
28+
) {
29+
@Suppress("DEPRECATION")
30+
operator fun invoke() = sessionCoroutineScope.launch {
31+
val hideInviteAvatars = appPreferencesStore.getHideInviteAvatarsFlow().first()
32+
val mediaPreviewValue = appPreferencesStore.getTimelineMediaPreviewValueFlow().first()
33+
if (hideInviteAvatars == null && mediaPreviewValue == null) {
34+
// No local data, abort.
35+
return@launch
36+
}
37+
mediaPreviewService
38+
.fetchMediaPreviewConfig()
39+
.onSuccess { config ->
40+
if (config != null) {
41+
appPreferencesStore.setHideInviteAvatars(null)
42+
appPreferencesStore.setTimelineMediaPreviewValue(null)
43+
} else {
44+
if (hideInviteAvatars != null) {
45+
mediaPreviewService.setHideInviteAvatars(hideInviteAvatars)
46+
appPreferencesStore.setHideInviteAvatars(null)
47+
}
48+
if (mediaPreviewValue != null) {
49+
mediaPreviewService.setMediaPreviewValue(mediaPreviewValue)
50+
appPreferencesStore.setTimelineMediaPreviewValue(null)
51+
}
52+
}
53+
}
54+
.onFailure {
55+
Timber.e(it, "Couldn't perform migration, failed to fetch media preview config.")
56+
}
57+
}
58+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
3+
<string name="banner_migrate_to_native_sliding_sync_action">"Log ud og opgradér"</string>
4+
<string name="banner_migrate_to_native_sliding_sync_app_force_logout_title">"%1$s understøtter ikke længere den gamle protokol. Log ud og log ind igen for at fortsætte med at bruge appen."</string>
5+
<string name="banner_migrate_to_native_sliding_sync_force_logout_title">"Din hjemmeserver understøtter ikke længere den gamle protokol. Log ud og log ind igen for at fortsætte med at bruge appen."</string>
6+
</resources>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
33
<string name="banner_migrate_to_native_sliding_sync_action">"Keluar &amp; Tingkatkan"</string>
4+
<string name="banner_migrate_to_native_sliding_sync_app_force_logout_title">"%1$s tidak lagi mendukung protokol lama. Silakan keluar dan masuk kembali untuk terus menggunakan aplikasi."</string>
45
<string name="banner_migrate_to_native_sliding_sync_force_logout_title">"Homeserver Anda tidak lagi mendukung protokol lama. Silakan keluar dan masuk kembali untuk terus menggunakan aplikasi."</string>
56
</resources>

0 commit comments

Comments
 (0)