diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/CurrentUserWithNeighborsBuilder.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/CurrentUserWithNeighborsBuilder.kt index f9c5fc3bc0..f4620b0f09 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/CurrentUserWithNeighborsBuilder.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/CurrentUserWithNeighborsBuilder.kt @@ -8,8 +8,8 @@ package io.element.android.features.home.impl -import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.user.MatrixUser +import io.element.android.libraries.matrix.api.user.toMatrixUser import io.element.android.libraries.sessionstorage.api.SessionData import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.toImmutableList @@ -32,12 +32,7 @@ class CurrentUserWithNeighborsBuilder { matrixUser } else { // Use the data from the DB - MatrixUser( - userId = UserId(it.userId), - displayName = it.userDisplayName, - avatarUrl = it.userAvatarUrl, - avatarThumbnail = it.userAvatarData, - ) + it.toMatrixUser() } } .let { sessionList -> diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootPresenter.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootPresenter.kt index 4bbe2eeaf8..53234c3723 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootPresenter.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/root/PreferencesRootPresenter.kt @@ -29,8 +29,7 @@ import io.element.android.libraries.di.annotations.SessionCoroutineScope import io.element.android.libraries.featureflag.api.FeatureFlagService import io.element.android.libraries.featureflag.api.FeatureFlags import io.element.android.libraries.matrix.api.MatrixClient -import io.element.android.libraries.matrix.api.core.UserId -import io.element.android.libraries.matrix.api.user.MatrixUser +import io.element.android.libraries.matrix.api.user.toMatrixUser import io.element.android.libraries.preferences.api.store.AppPreferencesStore import io.element.android.libraries.sessionstorage.api.SessionStore import io.element.android.services.analytics.api.AnalyticsService @@ -85,14 +84,7 @@ class PreferencesRootPresenter( sessionStore.sessionsFlow().map { list -> list .filter { it.userId != matrixClient.sessionId.value } - .map { - MatrixUser( - userId = UserId(it.userId), - displayName = it.userDisplayName, - avatarUrl = it.userAvatarUrl, - avatarThumbnail = it.userAvatarData, - ) - } + .map { it.toMatrixUser() } .toImmutableList() } }.collectAsState(initial = persistentListOf()) diff --git a/features/signedout/impl/src/main/kotlin/io/element/android/features/signedout/impl/SignedOutPresenter.kt b/features/signedout/impl/src/main/kotlin/io/element/android/features/signedout/impl/SignedOutPresenter.kt index 1f35da352a..3f9a3b3e4c 100644 --- a/features/signedout/impl/src/main/kotlin/io/element/android/features/signedout/impl/SignedOutPresenter.kt +++ b/features/signedout/impl/src/main/kotlin/io/element/android/features/signedout/impl/SignedOutPresenter.kt @@ -19,7 +19,7 @@ import dev.zacsweers.metro.AssistedInject import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.matrix.api.user.MatrixUser -import io.element.android.libraries.sessionstorage.api.SessionData +import io.element.android.libraries.matrix.api.user.toMatrixUser import io.element.android.libraries.sessionstorage.api.SessionStore import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.mapNotNull @@ -58,11 +58,4 @@ class SignedOutPresenter( eventSink = ::handleEvent, ) } - - private fun SessionData.toMatrixUser() = MatrixUser( - userId = sessionId, - displayName = userDisplayName, - avatarUrl = userAvatarUrl, - avatarThumbnail = userAvatarData, - ) } diff --git a/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/incoming/IncomingVerificationPresenter.kt b/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/incoming/IncomingVerificationPresenter.kt index 00daf9b5b8..98a1791774 100644 --- a/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/incoming/IncomingVerificationPresenter.kt +++ b/features/verifysession/impl/src/main/kotlin/io/element/android/features/verifysession/impl/incoming/IncomingVerificationPresenter.kt @@ -29,6 +29,7 @@ import io.element.android.libraries.dateformatter.api.DateFormatterMode import io.element.android.libraries.di.annotations.SessionCoroutineScope import io.element.android.libraries.matrix.api.core.SessionId import io.element.android.libraries.matrix.api.user.MatrixUser +import io.element.android.libraries.matrix.api.user.toMatrixUser import io.element.android.libraries.matrix.api.verification.SessionVerificationRequestDetails import io.element.android.libraries.matrix.api.verification.SessionVerificationService import io.element.android.libraries.matrix.api.verification.VerificationFlowState @@ -101,16 +102,7 @@ class IncomingVerificationPresenter( } val currentUser by remember { sessionStore.sessionsFlow().mapNotNull { sessions -> - sessions.find { it.userId == sessionId.value }?.let { sessionData -> - MatrixUser( - userId = sessionId, - displayName = sessionData.userDisplayName, - avatarUrl = sessionData.userAvatarUrl, - // Locally stored avatar, used as a fallback when the avatar cannot be loaded, - // for instance for a session which is not the current one - avatarThumbnail = sessionData.userAvatarData, - ) - } + sessions.find { it.userId == sessionId.value }?.toMatrixUser() } }.collectAsState(MatrixUser(sessionId)) val step by remember { diff --git a/libraries/accountselect/impl/src/main/kotlin/io/element/android/libraries/accountselect/impl/AccountSelectPresenter.kt b/libraries/accountselect/impl/src/main/kotlin/io/element/android/libraries/accountselect/impl/AccountSelectPresenter.kt index e1d6b2800e..8ed9a18b85 100644 --- a/libraries/accountselect/impl/src/main/kotlin/io/element/android/libraries/accountselect/impl/AccountSelectPresenter.kt +++ b/libraries/accountselect/impl/src/main/kotlin/io/element/android/libraries/accountselect/impl/AccountSelectPresenter.kt @@ -13,8 +13,8 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.produceState import dev.zacsweers.metro.Inject import io.element.android.libraries.architecture.Presenter -import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.user.MatrixUser +import io.element.android.libraries.matrix.api.user.toMatrixUser import io.element.android.libraries.sessionstorage.api.SessionStore import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf @@ -29,14 +29,7 @@ class AccountSelectPresenter( val accounts by produceState>(persistentListOf()) { // Do not use sessionStore.sessionsFlow() to not make it change when an account is selected. value = sessionStore.getAllSessions() - .map { - MatrixUser( - userId = UserId(it.userId), - displayName = it.userDisplayName, - avatarUrl = it.userAvatarUrl, - avatarThumbnail = it.userAvatarData, - ) - } + .map { it.toMatrixUser() } .toImmutableList() } diff --git a/libraries/matrix/api/build.gradle.kts b/libraries/matrix/api/build.gradle.kts index 65919e69f2..8387c1fa26 100644 --- a/libraries/matrix/api/build.gradle.kts +++ b/libraries/matrix/api/build.gradle.kts @@ -54,6 +54,7 @@ dependencies { implementation(projects.libraries.androidutils) implementation(projects.libraries.architecture) implementation(projects.services.analytics.api) + implementation(projects.libraries.sessionStorage.api) testCommonDependencies(libs) testImplementation(projects.libraries.matrix.test) diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/user/SessionDataExtensions.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/user/SessionDataExtensions.kt new file mode 100644 index 0000000000..136dbf58c3 --- /dev/null +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/user/SessionDataExtensions.kt @@ -0,0 +1,23 @@ +/* + * 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.libraries.matrix.api.user + +import io.element.android.libraries.matrix.api.core.UserId +import io.element.android.libraries.sessionstorage.api.SessionData + +/** + * Create a [MatrixUser] from the profile data stored locally for the session. + * The avatar thumbnail is used as a fallback when the avatar cannot be loaded, + * for instance for a session which is not the current one. + */ +fun SessionData.toMatrixUser() = MatrixUser( + userId = UserId(userId), + displayName = userDisplayName, + avatarUrl = userAvatarUrl, + avatarThumbnail = userAvatarData, +)