Skip to content

Commit 3818b16

Browse files
committed
Merge branch 'release/25.06.2' into main
2 parents bad30b8 + 67fb49f commit 3818b16

File tree

26 files changed

+158
-54
lines changed

26 files changed

+158
-54
lines changed

CHANGES.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,45 @@
1+
## What's Changed
2+
### ✨ Features
3+
* Enable support for Android Auto. by @bmarty in https://github.com/element-hq/element-x-android/pull/4818
4+
* Element Call: Add audio output selector handled by Android by @jmartinesp in https://github.com/element-hq/element-x-android/pull/4663
5+
### 🙌 Improvements
6+
* Oidc: Fallback to external browser instead of using Webview by @bmarty in https://github.com/element-hq/element-x-android/pull/4808
7+
* change (room member moderation) : update icon to match figma by @ganfra in https://github.com/element-hq/element-x-android/pull/4837
8+
### 🐛 Bugfixes
9+
* Fix login flow by @bmarty in https://github.com/element-hq/element-x-android/pull/4813
10+
* fix: When sending media as files use the `octet-stream` type by @jmartinesp in https://github.com/element-hq/element-x-android/pull/4815
11+
* fix: Make `Client.findDM` return a `Result` by @jmartinesp in https://github.com/element-hq/element-x-android/pull/4816
12+
* Mark room as fully read when user goes back to the room list. by @bmarty in https://github.com/element-hq/element-x-android/pull/2687
13+
* fix (identity change) : RoomMemberIdentityStateChange in non encrypted room by @ganfra in https://github.com/element-hq/element-x-android/pull/4824
14+
* Fix room and user avatar downloaded with a `.bin` extension. by @bmarty in https://github.com/element-hq/element-x-android/pull/4830
15+
* Log the push resolving failure reason if available by @jmartinesp in https://github.com/element-hq/element-x-android/pull/4835
16+
### 🧱 Build
17+
* Update Gradle Wrapper from 8.14.1 to 8.14.2 by @ElementBot in https://github.com/element-hq/element-x-android/pull/4831
18+
### Dependency upgrades
19+
* fix(deps): update dependency androidx.compose:compose-bom to v2025.04.01 by @renovate in https://github.com/element-hq/element-x-android/pull/4631
20+
* fix(deps): update dependency androidx.compose:compose-bom to v2025.05.01 by @renovate in https://github.com/element-hq/element-x-android/pull/4814
21+
* fix(deps): update dependency io.sentry:sentry-android to v8.13.2 by @renovate in https://github.com/element-hq/element-x-android/pull/4780
22+
* fix(deps): update appyx to v1.7.1 by @renovate in https://github.com/element-hq/element-x-android/pull/4672
23+
* fix(deps): update telephoto to v0.16.0 by @renovate in https://github.com/element-hq/element-x-android/pull/4749
24+
* fix(deps): update coil to v3.2.0 by @renovate in https://github.com/element-hq/element-x-android/pull/4712
25+
* fix(deps): update dependency androidx.webkit:webkit to v1.14.0 by @renovate in https://github.com/element-hq/element-x-android/pull/4823
26+
* fix(deps): update dependency com.posthog:posthog-android to v3.17.0 by @renovate in https://github.com/element-hq/element-x-android/pull/4827
27+
* fix(deps): update dependency io.element.android:element-call-embedded to v0.12.2 by @renovate in https://github.com/element-hq/element-x-android/pull/4832
28+
* fix(deps): update dependency com.google.firebase:firebase-bom to v33.15.0 by @renovate in https://github.com/element-hq/element-x-android/pull/4833
29+
* fix(deps): update dependency org.maplibre.gl:android-sdk to v11.10.1 by @renovate in https://github.com/element-hq/element-x-android/pull/4825
30+
* fix(deps): update lifecycle to v2.9.1 by @renovate in https://github.com/element-hq/element-x-android/pull/4822
31+
* fix(deps): update dependency org.matrix.rustcomponents:sdk-android to v25.6.6 by @renovate in https://github.com/element-hq/element-x-android/pull/4834
32+
* fix(deps): update dependency io.element.android:opusencoder to v1.2.0 by @renovate in https://github.com/element-hq/element-x-android/pull/4836
33+
### Others
34+
* Add `catchingExceptions` method to replace `runCatching` by @jmartinesp in https://github.com/element-hq/element-x-android/pull/4797
35+
* Rename classes overriding classes from the FFI layer. by @bmarty in https://github.com/element-hq/element-x-android/pull/4817
36+
* Fix coroutine scope by @bmarty in https://github.com/element-hq/element-x-android/pull/4820
37+
* Add extra logs the 'send call notification' flow by @jmartinesp in https://github.com/element-hq/element-x-android/pull/4819
38+
* misc (matrix) : use innerClient.subscribeToRoomInfo sdk method by @ganfra in https://github.com/element-hq/element-x-android/pull/4838
39+
40+
41+
**Full Changelog**: https://github.com/element-hq/element-x-android/compare/v25.06.0...v25.06.1
42+
143
Changes in Element X v25.06.0
244
=============================
345

app/src/main/AndroidManifest.xml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,17 @@
122122
<data android:scheme="https" />
123123
<data android:host="matrix.to" />
124124
</intent-filter>
125+
<!--
126+
matrix: links
127+
-->
128+
<intent-filter>
129+
<action android:name="android.intent.action.VIEW" />
130+
131+
<category android:name="android.intent.category.DEFAULT" />
132+
<category android:name="android.intent.category.BROWSABLE" />
133+
134+
<data android:scheme="matrix" />
135+
</intent-filter>
125136
<!--
126137
links from matrix.to website
127138
-->
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Main changes in this version: bug fixes and improvements.
2+
Full changelog: https://github.com/element-hq/element-x-android/releases

features/call/impl/src/main/kotlin/io/element/android/features/call/impl/utils/WebViewAudioManager.kt

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,19 @@ import android.os.Build
1515
import android.os.PowerManager
1616
import android.webkit.JavascriptInterface
1717
import android.webkit.WebView
18+
import androidx.annotation.RequiresApi
1819
import androidx.core.content.getSystemService
1920
import kotlinx.coroutines.CoroutineScope
2021
import kotlinx.coroutines.Dispatchers
22+
import kotlinx.coroutines.delay
2123
import kotlinx.coroutines.launch
2224
import kotlinx.serialization.Serializable
2325
import kotlinx.serialization.Transient
2426
import kotlinx.serialization.json.Json
2527
import timber.log.Timber
2628
import java.util.concurrent.Executors
2729
import java.util.concurrent.atomic.AtomicBoolean
30+
import kotlin.time.Duration.Companion.milliseconds
2831

2932
/**
3033
* This class manages the audio devices for a WebView.
@@ -66,23 +69,26 @@ class WebViewAudioManager(
6669
/**
6770
* This listener tracks the current communication device and updates the WebView when it changes.
6871
*/
69-
private val commsDeviceChangedListener = AudioManager.OnCommunicationDeviceChangedListener { device ->
70-
if (device != null && device.id == expectedNewCommunicationDeviceId) {
71-
expectedNewCommunicationDeviceId = null
72-
Timber.d("Audio device changed, type: ${device.type}")
73-
updateSelectedAudioDeviceInWebView(device.id.toString())
74-
} else if (device != null && device.id != expectedNewCommunicationDeviceId) {
75-
// We were expecting a device change but it didn't happen, so we should retry
76-
val expectedDeviceId = expectedNewCommunicationDeviceId
77-
if (expectedDeviceId != null) {
78-
// Remove the expected id so we only retry once
72+
@get:RequiresApi(Build.VERSION_CODES.S)
73+
private val commsDeviceChangedListener by lazy {
74+
AudioManager.OnCommunicationDeviceChangedListener { device ->
75+
if (device != null && device.id == expectedNewCommunicationDeviceId) {
7976
expectedNewCommunicationDeviceId = null
80-
audioManager.selectAudioDevice(expectedDeviceId.toString())
77+
Timber.d("Audio device changed, type: ${device.type}")
78+
updateSelectedAudioDeviceInWebView(device.id.toString())
79+
} else if (device != null && device.id != expectedNewCommunicationDeviceId) {
80+
// We were expecting a device change but it didn't happen, so we should retry
81+
val expectedDeviceId = expectedNewCommunicationDeviceId
82+
if (expectedDeviceId != null) {
83+
// Remove the expected id so we only retry once
84+
expectedNewCommunicationDeviceId = null
85+
audioManager.selectAudioDevice(expectedDeviceId.toString())
86+
}
87+
} else {
88+
Timber.d("Audio device cleared")
89+
expectedNewCommunicationDeviceId = null
90+
audioManager.selectAudioDevice(null)
8191
}
82-
} else {
83-
Timber.d("Audio device cleared")
84-
expectedNewCommunicationDeviceId = null
85-
audioManager.selectAudioDevice(null)
8692
}
8793
}
8894

@@ -217,6 +223,10 @@ class WebViewAudioManager(
217223
},
218224
onAudioPlaybackStarted = {
219225
coroutineScope.launch(Dispatchers.Main) {
226+
// Even with the callback, it seems like starting the audio takes a bit on the webview side,
227+
// so we add an extra delay here to make sure it's ready
228+
delay(500.milliseconds)
229+
220230
// Calling this ahead of time makes the default audio device to not use the right audio stream
221231
setAvailableAudioDevices()
222232

features/call/impl/src/test/kotlin/io/element/android/features/call/ui/CallScreenPresenterTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ import kotlin.time.Duration.Companion.seconds
8383

8484
@Test
8585
fun `present - with CallType RoomCall sets call as active, loads URL, runs WidgetDriver and notifies the other clients a call started`() = runTest {
86-
val sendCallNotificationIfNeededLambda = lambdaRecorder<Result<Unit>> { Result.success(Unit) }
86+
val sendCallNotificationIfNeededLambda = lambdaRecorder<Result<Boolean>> { Result.success(true) }
8787
val syncService = FakeSyncService(SyncState.Running)
8888
val fakeRoom = FakeJoinedRoom(sendCallNotificationIfNeededResult = sendCallNotificationIfNeededLambda)
8989
val client = FakeMatrixClient(syncService = syncService).apply {

features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/ExpandableBottomSheetScaffold.kt

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@
1010
package io.element.android.features.messages.impl
1111

1212
import androidx.compose.foundation.layout.PaddingValues
13+
import androidx.compose.foundation.layout.WindowInsets
1314
import androidx.compose.foundation.layout.fillMaxHeight
15+
import androidx.compose.foundation.layout.ime
16+
import androidx.compose.foundation.layout.windowInsetsPadding
1417
import androidx.compose.material3.ExperimentalMaterial3Api
1518
import androidx.compose.material3.SheetValue
1619
import androidx.compose.material3.rememberBottomSheetScaffoldState
@@ -112,7 +115,7 @@ internal fun ExpandableBottomSheetScaffold(
112115
}
113116

114117
SubcomposeLayout(
115-
modifier = modifier,
118+
modifier = modifier.windowInsetsPadding(WindowInsets.ime),
116119
measurePolicy = { constraints: Constraints ->
117120
val sheetContentSub = subcompose(Slot.SheetContent(sheetContentKey)) { sheetContent(true) }.map {
118121
it.measure(Constraints(maxWidth = constraints.maxWidth))
@@ -123,7 +126,7 @@ internal fun ExpandableBottomSheetScaffold(
123126
val dragHandleHeight = dragHandleSub?.height?.toDp() ?: 0.dp
124127

125128
val maxHeight = constraints.maxHeight.toDp()
126-
val contentHeight = sheetContentSub.height.toDp() + dragHandleHeight
129+
val contentHeight = sheetContentSub.measuredHeight.toDp() + dragHandleHeight
127130

128131
contentOverflows = contentHeight > maxHeight
129132

@@ -140,7 +143,7 @@ internal fun ExpandableBottomSheetScaffold(
140143
measurePolicy = { measurables, constraints ->
141144
val constraintHeight = constraints.maxHeight
142145
val offset = tryOrNull { scaffoldState.bottomSheetState.requireOffset() } ?: 0f
143-
val height = Integer.max(0, constraintHeight - offset.roundToInt())
146+
val height = Integer.max(peekHeight.roundToPx(), constraintHeight - offset.roundToInt())
144147
val top = measurables[0].measure(
145148
constraints.copy(
146149
minHeight = height,

gradle/libs.versions.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ jsoup = "org.jsoup:jsoup:1.20.1"
172172
appyx_core = { module = "com.bumble.appyx:core", version.ref = "appyx" }
173173
molecule-runtime = "app.cash.molecule:molecule-runtime:2.1.0"
174174
timber = "com.jakewharton.timber:timber:5.0.1"
175-
matrix_sdk = "org.matrix.rustcomponents:sdk-android:25.6.6"
175+
matrix_sdk = "org.matrix.rustcomponents:sdk-android:25.6.10"
176176
matrix_richtexteditor = { module = "io.element.android:wysiwyg", version.ref = "wysiwyg" }
177177
matrix_richtexteditor_compose = { module = "io.element.android:wysiwyg-compose", version.ref = "wysiwyg" }
178178
sqldelight-driver-android = { module = "app.cash.sqldelight:android-driver", version.ref = "sqldelight" }
@@ -237,7 +237,7 @@ anvil = { id = "dev.zacsweers.anvil", version.ref = "anvil" }
237237
detekt = { id = "io.gitlab.arturbosch.detekt", version.ref = "detekt" }
238238
ktlint = "org.jlleitschuh.gradle.ktlint:12.3.0"
239239
dependencygraph = "com.savvasdalkitsis.module-dependency-graph:0.12"
240-
dependencycheck = "org.owasp.dependencycheck:12.1.1"
240+
dependencycheck = "org.owasp.dependencycheck:12.1.2"
241241
dependencyanalysis = { id = "com.autonomousapps.dependency-analysis", version.ref = "dependencyAnalysis" }
242242
paparazzi = "app.cash.paparazzi:1.3.5"
243243
sqldelight = { id = "app.cash.sqldelight", version.ref = "sqldelight" }

libraries/androidutils/src/main/kotlin/io/element/android/libraries/androidutils/ui/View.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ fun View.showKeyboard(andRequestFocus: Boolean = false) {
2727
imm?.showSoftInput(this, InputMethodManager.SHOW_IMPLICIT)
2828
}
2929

30+
fun View.isKeyboardVisible(): Boolean {
31+
val imm = context?.getSystemService<InputMethodManager>()
32+
return imm?.isAcceptingText == true
33+
}
34+
3035
suspend fun View.awaitWindowFocus() = suspendCancellableCoroutine { continuation ->
3136
if (hasWindowFocus()) {
3237
continuation.resume(Unit)

libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/permalink/PermalinkParser.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ package io.element.android.libraries.matrix.api.permalink
1212
* element-based domains (e.g. https://app.element.io/#/user/@chagai95:matrix.org) permalinks
1313
* or matrix.to permalinks (e.g. https://matrix.to/#/@chagai95:matrix.org)
1414
* or client permalinks (e.g. <clientPermalinkBaseUrl>user/@chagai95:matrix.org)
15+
* or matrix: permalinks (e.g. matrix:u/chagai95:matrix.org)
1516
*/
1617
interface PermalinkParser {
1718
/**

libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/JoinedRoom.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ interface JoinedRoom : BaseRoom {
159159
/**
160160
* Send an Element Call started notification if needed.
161161
*/
162-
suspend fun sendCallNotificationIfNeeded(): Result<Unit>
162+
suspend fun sendCallNotificationIfNeeded(): Result<Boolean>
163163

164164
suspend fun setSendQueueEnabled(enabled: Boolean)
165165

0 commit comments

Comments
 (0)