Upgrade Rust SDK bindings to v25.09.15 (#5353)
* Upgrade Rust SDK bindings to `v25.09.15`: This contains important changes to the APIs used to build the EC widget. * Use the new `intent` parameter correctly, by calculating locally its behaviour based on whether the room is a DM and there is an ongoing call or not. Using just the `intent` parameter is our end goal, but sadly this is not fully supported by the current EC embedded `v0.15.0`, so we need to add a workaround using the `skipLobby` and `preload` parameters.
This commit is contained in:
parent
f4c73477c7
commit
15a99a5f0c
9 changed files with 43 additions and 27 deletions
|
|
@ -45,8 +45,14 @@ class DefaultCallWidgetProvider(
|
||||||
val customBaseUrl = appPreferencesStore.getCustomElementCallBaseUrlFlow().firstOrNull()
|
val customBaseUrl = appPreferencesStore.getCustomElementCallBaseUrlFlow().firstOrNull()
|
||||||
val baseUrl = customBaseUrl ?: EMBEDDED_CALL_WIDGET_BASE_URL
|
val baseUrl = customBaseUrl ?: EMBEDDED_CALL_WIDGET_BASE_URL
|
||||||
|
|
||||||
val isEncrypted = room.info().isEncrypted ?: room.getUpdatedIsEncrypted().getOrThrow()
|
val roomInfo = room.info()
|
||||||
val widgetSettings = callWidgetSettingsProvider.provide(baseUrl, encrypted = isEncrypted, direct = room.isDm())
|
val isEncrypted = roomInfo.isEncrypted ?: room.getUpdatedIsEncrypted().getOrThrow()
|
||||||
|
val widgetSettings = callWidgetSettingsProvider.provide(
|
||||||
|
baseUrl = baseUrl,
|
||||||
|
encrypted = isEncrypted,
|
||||||
|
direct = room.isDm(),
|
||||||
|
hasActiveCall = roomInfo.hasRoomCall,
|
||||||
|
)
|
||||||
val callUrl = room.generateWidgetWebViewUrl(
|
val callUrl = room.generateWidgetWebViewUrl(
|
||||||
widgetSettings = widgetSettings,
|
widgetSettings = widgetSettings,
|
||||||
clientId = clientId,
|
clientId = clientId,
|
||||||
|
|
|
||||||
|
|
@ -160,9 +160,9 @@ class MessagesPresenterTest {
|
||||||
@Test
|
@Test
|
||||||
fun `present - handle toggling a reaction`() = runTest {
|
fun `present - handle toggling a reaction`() = runTest {
|
||||||
val coroutineDispatchers = testCoroutineDispatchers(useUnconfinedTestDispatcher = true)
|
val coroutineDispatchers = testCoroutineDispatchers(useUnconfinedTestDispatcher = true)
|
||||||
val toggleReactionSuccess = lambdaRecorder { _: String, _: EventOrTransactionId -> Result.success(Unit) }
|
val toggleReactionSuccess = lambdaRecorder { _: String, _: EventOrTransactionId -> Result.success(true) }
|
||||||
val toggleReactionFailure =
|
val toggleReactionFailure =
|
||||||
lambdaRecorder { _: String, _: EventOrTransactionId -> Result.failure<Unit>(IllegalStateException("Failed to send reaction")) }
|
lambdaRecorder { _: String, _: EventOrTransactionId -> Result.failure<Boolean>(IllegalStateException("Failed to send reaction")) }
|
||||||
|
|
||||||
val timeline = FakeTimeline().apply {
|
val timeline = FakeTimeline().apply {
|
||||||
this.toggleReactionLambda = toggleReactionSuccess
|
this.toggleReactionLambda = toggleReactionSuccess
|
||||||
|
|
@ -200,7 +200,11 @@ class MessagesPresenterTest {
|
||||||
@Test
|
@Test
|
||||||
fun `present - handle toggling a reaction twice`() = runTest {
|
fun `present - handle toggling a reaction twice`() = runTest {
|
||||||
val coroutineDispatchers = testCoroutineDispatchers(useUnconfinedTestDispatcher = true)
|
val coroutineDispatchers = testCoroutineDispatchers(useUnconfinedTestDispatcher = true)
|
||||||
val toggleReactionSuccess = lambdaRecorder { _: String, _: EventOrTransactionId -> Result.success(Unit) }
|
var toggle = false
|
||||||
|
val toggleReactionSuccess = lambdaRecorder { _: String, _: EventOrTransactionId ->
|
||||||
|
toggle = !toggle
|
||||||
|
Result.success(toggle)
|
||||||
|
}
|
||||||
|
|
||||||
val timeline = FakeTimeline().apply {
|
val timeline = FakeTimeline().apply {
|
||||||
this.toggleReactionLambda = toggleReactionSuccess
|
this.toggleReactionLambda = toggleReactionSuccess
|
||||||
|
|
|
||||||
|
|
@ -176,7 +176,7 @@ jsoup = "org.jsoup:jsoup:1.21.2"
|
||||||
appyx_core = { module = "com.bumble.appyx:core", version.ref = "appyx" }
|
appyx_core = { module = "com.bumble.appyx:core", version.ref = "appyx" }
|
||||||
molecule-runtime = "app.cash.molecule:molecule-runtime:2.1.0"
|
molecule-runtime = "app.cash.molecule:molecule-runtime:2.1.0"
|
||||||
timber = "com.jakewharton.timber:timber:5.0.1"
|
timber = "com.jakewharton.timber:timber:5.0.1"
|
||||||
matrix_sdk = "org.matrix.rustcomponents:sdk-android:25.9.10"
|
matrix_sdk = "org.matrix.rustcomponents:sdk-android:25.9.15"
|
||||||
matrix_richtexteditor = { module = "io.element.android:wysiwyg", version.ref = "wysiwyg" }
|
matrix_richtexteditor = { module = "io.element.android:wysiwyg", version.ref = "wysiwyg" }
|
||||||
matrix_richtexteditor_compose = { module = "io.element.android:wysiwyg-compose", version.ref = "wysiwyg" }
|
matrix_richtexteditor_compose = { module = "io.element.android:wysiwyg-compose", version.ref = "wysiwyg" }
|
||||||
sqldelight-driver-android = { module = "app.cash.sqldelight:android-driver", version.ref = "sqldelight" }
|
sqldelight-driver-android = { module = "app.cash.sqldelight:android-driver", version.ref = "sqldelight" }
|
||||||
|
|
|
||||||
|
|
@ -151,7 +151,7 @@ interface Timeline : AutoCloseable {
|
||||||
|
|
||||||
suspend fun redactEvent(eventOrTransactionId: EventOrTransactionId, reason: String?): Result<Unit>
|
suspend fun redactEvent(eventOrTransactionId: EventOrTransactionId, reason: String?): Result<Unit>
|
||||||
|
|
||||||
suspend fun toggleReaction(emoji: String, eventOrTransactionId: EventOrTransactionId): Result<Unit>
|
suspend fun toggleReaction(emoji: String, eventOrTransactionId: EventOrTransactionId): Result<Boolean>
|
||||||
|
|
||||||
suspend fun forwardEvent(eventId: EventId, roomIds: List<RoomId>): Result<Unit>
|
suspend fun forwardEvent(eventId: EventId, roomIds: List<RoomId>): Result<Unit>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,5 +15,6 @@ interface CallWidgetSettingsProvider {
|
||||||
widgetId: String = UUID.randomUUID().toString(),
|
widgetId: String = UUID.randomUUID().toString(),
|
||||||
encrypted: Boolean,
|
encrypted: Boolean,
|
||||||
direct: Boolean,
|
direct: Boolean,
|
||||||
|
hasActiveCall: Boolean,
|
||||||
): MatrixWidgetSettings
|
): MatrixWidgetSettings
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -431,7 +431,7 @@ class RustTimeline(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun toggleReaction(emoji: String, eventOrTransactionId: EventOrTransactionId): Result<Unit> = withContext(dispatcher) {
|
override suspend fun toggleReaction(emoji: String, eventOrTransactionId: EventOrTransactionId): Result<Boolean> = withContext(dispatcher) {
|
||||||
runCatchingExceptions {
|
runCatchingExceptions {
|
||||||
inner.toggleReaction(
|
inner.toggleReaction(
|
||||||
key = emoji,
|
key = emoji,
|
||||||
|
|
|
||||||
|
|
@ -18,9 +18,8 @@ import io.element.android.libraries.matrix.api.widget.MatrixWidgetSettings
|
||||||
import io.element.android.services.analytics.api.AnalyticsService
|
import io.element.android.services.analytics.api.AnalyticsService
|
||||||
import kotlinx.coroutines.flow.first
|
import kotlinx.coroutines.flow.first
|
||||||
import org.matrix.rustcomponents.sdk.newVirtualElementCallWidget
|
import org.matrix.rustcomponents.sdk.newVirtualElementCallWidget
|
||||||
|
import timber.log.Timber
|
||||||
import uniffi.matrix_sdk.EncryptionSystem
|
import uniffi.matrix_sdk.EncryptionSystem
|
||||||
import uniffi.matrix_sdk.HeaderStyle
|
|
||||||
import uniffi.matrix_sdk.NotificationType
|
|
||||||
import uniffi.matrix_sdk.VirtualElementCallWidgetConfig
|
import uniffi.matrix_sdk.VirtualElementCallWidgetConfig
|
||||||
import uniffi.matrix_sdk.VirtualElementCallWidgetProperties
|
import uniffi.matrix_sdk.VirtualElementCallWidgetProperties
|
||||||
import uniffi.matrix_sdk.Intent as CallIntent
|
import uniffi.matrix_sdk.Intent as CallIntent
|
||||||
|
|
@ -32,7 +31,7 @@ class DefaultCallWidgetSettingsProvider(
|
||||||
private val callAnalyticsCredentialsProvider: CallAnalyticCredentialsProvider,
|
private val callAnalyticsCredentialsProvider: CallAnalyticCredentialsProvider,
|
||||||
private val analyticsService: AnalyticsService,
|
private val analyticsService: AnalyticsService,
|
||||||
) : CallWidgetSettingsProvider {
|
) : CallWidgetSettingsProvider {
|
||||||
override suspend fun provide(baseUrl: String, widgetId: String, encrypted: Boolean, direct: Boolean): MatrixWidgetSettings {
|
override suspend fun provide(baseUrl: String, widgetId: String, encrypted: Boolean, direct: Boolean, hasActiveCall: Boolean): MatrixWidgetSettings {
|
||||||
val isAnalyticsEnabled = analyticsService.userConsentFlow.first()
|
val isAnalyticsEnabled = analyticsService.userConsentFlow.first()
|
||||||
val properties = VirtualElementCallWidgetProperties(
|
val properties = VirtualElementCallWidgetProperties(
|
||||||
elementCallUrl = baseUrl,
|
elementCallUrl = baseUrl,
|
||||||
|
|
@ -49,18 +48,18 @@ class DefaultCallWidgetSettingsProvider(
|
||||||
parentUrl = null,
|
parentUrl = null,
|
||||||
)
|
)
|
||||||
val config = VirtualElementCallWidgetConfig(
|
val config = VirtualElementCallWidgetConfig(
|
||||||
preload = null,
|
// TODO remove this once we have the next EC version
|
||||||
appPrompt = false,
|
preload = false,
|
||||||
confineToRoom = true,
|
// TODO remove this once we have the next EC version
|
||||||
// TODO We probably want to provide different values for this field.
|
|
||||||
intent = CallIntent.START_CALL,
|
|
||||||
hideScreensharing = false,
|
|
||||||
// For backwards compatibility, it'll be ignored in recent versions of Element Call
|
|
||||||
hideHeader = true,
|
|
||||||
controlledAudioDevices = true,
|
|
||||||
header = HeaderStyle.APP_BAR,
|
|
||||||
sendNotificationType = if (direct) NotificationType.RING else NotificationType.NOTIFICATION,
|
|
||||||
skipLobby = null,
|
skipLobby = null,
|
||||||
|
intent = when {
|
||||||
|
direct && hasActiveCall -> CallIntent.JOIN_EXISTING_DM
|
||||||
|
hasActiveCall -> CallIntent.JOIN_EXISTING
|
||||||
|
direct -> CallIntent.START_CALL_DM
|
||||||
|
else -> CallIntent.START_CALL
|
||||||
|
}.also {
|
||||||
|
Timber.d("Starting/joining call with intent: $it")
|
||||||
|
}
|
||||||
)
|
)
|
||||||
val rustWidgetSettings = newVirtualElementCallWidget(
|
val rustWidgetSettings = newVirtualElementCallWidget(
|
||||||
props = properties,
|
props = properties,
|
||||||
|
|
|
||||||
|
|
@ -304,9 +304,9 @@ class FakeTimeline(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
var toggleReactionLambda: (emoji: String, eventOrTransactionId: EventOrTransactionId) -> Result<Unit> = { _, _ -> lambdaError() }
|
var toggleReactionLambda: (emoji: String, eventOrTransactionId: EventOrTransactionId) -> Result<Boolean> = { _, _ -> lambdaError() }
|
||||||
|
|
||||||
override suspend fun toggleReaction(emoji: String, eventOrTransactionId: EventOrTransactionId): Result<Unit> = simulateLongTask {
|
override suspend fun toggleReaction(emoji: String, eventOrTransactionId: EventOrTransactionId): Result<Boolean> = simulateLongTask {
|
||||||
toggleReactionLambda(
|
toggleReactionLambda(
|
||||||
emoji,
|
emoji,
|
||||||
eventOrTransactionId,
|
eventOrTransactionId,
|
||||||
|
|
|
||||||
|
|
@ -11,12 +11,18 @@ import io.element.android.libraries.matrix.api.widget.CallWidgetSettingsProvider
|
||||||
import io.element.android.libraries.matrix.api.widget.MatrixWidgetSettings
|
import io.element.android.libraries.matrix.api.widget.MatrixWidgetSettings
|
||||||
|
|
||||||
class FakeCallWidgetSettingsProvider(
|
class FakeCallWidgetSettingsProvider(
|
||||||
private val provideFn: (String, String, Boolean, Boolean) -> MatrixWidgetSettings = { _, _, _, _ -> MatrixWidgetSettings("id", true, "url") }
|
private val provideFn: (String, String, Boolean, Boolean, Boolean) -> MatrixWidgetSettings = { _, _, _, _, _ -> MatrixWidgetSettings("id", true, "url") }
|
||||||
) : CallWidgetSettingsProvider {
|
) : CallWidgetSettingsProvider {
|
||||||
val providedBaseUrls = mutableListOf<String>()
|
val providedBaseUrls = mutableListOf<String>()
|
||||||
|
|
||||||
override suspend fun provide(baseUrl: String, widgetId: String, encrypted: Boolean, direct: Boolean): MatrixWidgetSettings {
|
override suspend fun provide(
|
||||||
|
baseUrl: String,
|
||||||
|
widgetId: String,
|
||||||
|
encrypted: Boolean,
|
||||||
|
direct: Boolean,
|
||||||
|
hasActiveCall: Boolean
|
||||||
|
): MatrixWidgetSettings {
|
||||||
providedBaseUrls += baseUrl
|
providedBaseUrls += baseUrl
|
||||||
return provideFn(baseUrl, widgetId, encrypted, direct)
|
return provideFn(baseUrl, widgetId, encrypted, direct, hasActiveCall)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue