mirror of
https://github.com/Novaloop-AG/element-x-android.git
synced 2026-11-03 16:10:00 +00:00
Subscribe to own profile updates and gate on server support
This commit is contained in:
+8
-2
@@ -74,8 +74,14 @@ class PreferencesRootPresenter(
|
|||||||
val showLinkNewDevice by remember {
|
val showLinkNewDevice by remember {
|
||||||
featureFlagService.isFeatureEnabledFlow(FeatureFlags.QrCodeLogin)
|
featureFlagService.isFeatureEnabledFlow(FeatureFlags.QrCodeLogin)
|
||||||
}.collectAsState(initial = false)
|
}.collectAsState(initial = false)
|
||||||
val isUserStatusEnabled by featureFlagService.isFeatureEnabledFlow(FeatureFlags.UserStatus).collectAsState(initial = false)
|
|
||||||
val userStatusState = if (isUserStatusEnabled) userStatusPresenter.present() else null
|
val isUserStatusSupported by produceState(false) {
|
||||||
|
featureFlagService.isFeatureEnabledFlow(FeatureFlags.UserStatus)
|
||||||
|
.collect { isUserStatusEnabled ->
|
||||||
|
value = isUserStatusEnabled && matrixClient.isUserStatusSupported().getOrDefault(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val userStatusState = if (isUserStatusSupported) userStatusPresenter.present() else null
|
||||||
|
|
||||||
val otherSessions by remember {
|
val otherSessions by remember {
|
||||||
sessionStore.sessionsFlow().map { list ->
|
sessionStore.sessionsFlow().map { list ->
|
||||||
|
|||||||
+31
-11
@@ -57,8 +57,6 @@ import io.element.android.libraries.matrix.impl.exception.mapClientException
|
|||||||
import io.element.android.libraries.matrix.impl.linknewdevice.RustLinkDesktopHandler
|
import io.element.android.libraries.matrix.impl.linknewdevice.RustLinkDesktopHandler
|
||||||
import io.element.android.libraries.matrix.impl.linknewdevice.RustLinkMobileHandler
|
import io.element.android.libraries.matrix.impl.linknewdevice.RustLinkMobileHandler
|
||||||
import io.element.android.libraries.matrix.impl.linknewdevice.RustQrCodeDataParser
|
import io.element.android.libraries.matrix.impl.linknewdevice.RustQrCodeDataParser
|
||||||
import io.element.android.libraries.matrix.impl.user.into
|
|
||||||
import io.element.android.libraries.matrix.impl.user.map
|
|
||||||
import io.element.android.libraries.matrix.impl.media.RustMediaLoader
|
import io.element.android.libraries.matrix.impl.media.RustMediaLoader
|
||||||
import io.element.android.libraries.matrix.impl.media.RustMediaPreviewService
|
import io.element.android.libraries.matrix.impl.media.RustMediaPreviewService
|
||||||
import io.element.android.libraries.matrix.impl.notification.RustNotificationService
|
import io.element.android.libraries.matrix.impl.notification.RustNotificationService
|
||||||
@@ -86,6 +84,8 @@ import io.element.android.libraries.matrix.impl.spaces.RustSpaceService
|
|||||||
import io.element.android.libraries.matrix.impl.sync.RustSyncService
|
import io.element.android.libraries.matrix.impl.sync.RustSyncService
|
||||||
import io.element.android.libraries.matrix.impl.sync.map
|
import io.element.android.libraries.matrix.impl.sync.map
|
||||||
import io.element.android.libraries.matrix.impl.user.UserSearchResultMapper
|
import io.element.android.libraries.matrix.impl.user.UserSearchResultMapper
|
||||||
|
import io.element.android.libraries.matrix.impl.user.into
|
||||||
|
import io.element.android.libraries.matrix.impl.user.map
|
||||||
import io.element.android.libraries.matrix.impl.util.cancelAndDestroy
|
import io.element.android.libraries.matrix.impl.util.cancelAndDestroy
|
||||||
import io.element.android.libraries.matrix.impl.util.mxCallbackFlow
|
import io.element.android.libraries.matrix.impl.util.mxCallbackFlow
|
||||||
import io.element.android.libraries.matrix.impl.verification.RustSessionVerificationService
|
import io.element.android.libraries.matrix.impl.verification.RustSessionVerificationService
|
||||||
@@ -126,9 +126,11 @@ import org.matrix.rustcomponents.sdk.IgnoredUsersListener
|
|||||||
import org.matrix.rustcomponents.sdk.Membership
|
import org.matrix.rustcomponents.sdk.Membership
|
||||||
import org.matrix.rustcomponents.sdk.NotificationProcessSetup
|
import org.matrix.rustcomponents.sdk.NotificationProcessSetup
|
||||||
import org.matrix.rustcomponents.sdk.PowerLevels
|
import org.matrix.rustcomponents.sdk.PowerLevels
|
||||||
|
import org.matrix.rustcomponents.sdk.ProfileListener
|
||||||
import org.matrix.rustcomponents.sdk.RoomInfoListener
|
import org.matrix.rustcomponents.sdk.RoomInfoListener
|
||||||
import org.matrix.rustcomponents.sdk.SendQueueRoomErrorListener
|
import org.matrix.rustcomponents.sdk.SendQueueRoomErrorListener
|
||||||
import org.matrix.rustcomponents.sdk.TaskHandle
|
import org.matrix.rustcomponents.sdk.TaskHandle
|
||||||
|
import org.matrix.rustcomponents.sdk.UserProfile
|
||||||
import org.matrix.rustcomponents.sdk.use
|
import org.matrix.rustcomponents.sdk.use
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.io.File
|
import java.io.File
|
||||||
@@ -281,6 +283,14 @@ class RustMatrixClient(
|
|||||||
|
|
||||||
override val userProfile: StateFlow<MatrixUser> = _userProfile
|
override val userProfile: StateFlow<MatrixUser> = _userProfile
|
||||||
|
|
||||||
|
private var ownProfileTaskHandle: TaskHandle? = null
|
||||||
|
|
||||||
|
private val ownProfileListener = object : ProfileListener {
|
||||||
|
override fun onUpdate(profile: UserProfile) {
|
||||||
|
_userProfile.tryEmit(profile.map())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override val ignoredUsersFlow = mxCallbackFlow<ImmutableList<UserId>> {
|
override val ignoredUsersFlow = mxCallbackFlow<ImmutableList<UserId>> {
|
||||||
// Fetch the initial value manually, the SDK won't return it automatically
|
// Fetch the initial value manually, the SDK won't return it automatically
|
||||||
channel.trySend(innerClient.ignoredUsers().map(::UserId).toImmutableList())
|
channel.trySend(innerClient.ignoredUsers().map(::UserId).toImmutableList())
|
||||||
@@ -301,8 +311,21 @@ class RustMatrixClient(
|
|||||||
sessionCoroutineScope.launch {
|
sessionCoroutineScope.launch {
|
||||||
// Start notification settings
|
// Start notification settings
|
||||||
notificationSettingsService.start()
|
notificationSettingsService.start()
|
||||||
|
// Setup user profile logic
|
||||||
|
setupUserProfile()
|
||||||
|
}
|
||||||
|
|
||||||
// Update the user profile in the session store if needed
|
// Schedule regular database vacuuming to ensure DB performance remains optimal
|
||||||
|
scheduleDatabaseVacuum()
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun setupUserProfile() {
|
||||||
|
val supported = isUserStatusSupported().getOrDefault(false)
|
||||||
|
if (supported) {
|
||||||
|
// No need to seed the data here, it's already stored by the sdk.
|
||||||
|
ownProfileTaskHandle = innerClient.subscribeToOwnProfile(ownProfileListener)
|
||||||
|
} else {
|
||||||
|
// Seed from the session store so cold-start UI has something to render before the network fetch.
|
||||||
sessionStore.getSession(sessionId.value)?.let { sessionData ->
|
sessionStore.getSession(sessionId.value)?.let { sessionData ->
|
||||||
_userProfile.emit(
|
_userProfile.emit(
|
||||||
MatrixUser(
|
MatrixUser(
|
||||||
@@ -312,12 +335,8 @@ class RustMatrixClient(
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
// Force a refresh of the profile
|
|
||||||
getUserProfile()
|
getUserProfile()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Schedule regular database vacuuming to ensure DB performance remains optimal
|
|
||||||
scheduleDatabaseVacuum()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun userIdServerName(): String {
|
override fun userIdServerName(): String {
|
||||||
@@ -491,8 +510,8 @@ class RustMatrixClient(
|
|||||||
runCatchingExceptions {
|
runCatchingExceptions {
|
||||||
innerClient.setUserStatus(status.into())
|
innerClient.setUserStatus(status.into())
|
||||||
}.onSuccess {
|
}.onSuccess {
|
||||||
// try to refresh data once it's updated
|
// The subscription pushes the update on supported servers; only refresh manually as a fallback.
|
||||||
getUserProfile()
|
if (ownProfileTaskHandle == null) getUserProfile()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -500,8 +519,8 @@ class RustMatrixClient(
|
|||||||
runCatchingExceptions {
|
runCatchingExceptions {
|
||||||
innerClient.clearUserStatus()
|
innerClient.clearUserStatus()
|
||||||
}.onSuccess {
|
}.onSuccess {
|
||||||
// try to refresh data once it's updated
|
// The subscription pushes the update on supported servers; only refresh manually as a fallback.
|
||||||
getUserProfile()
|
if (ownProfileTaskHandle == null) getUserProfile()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -616,6 +635,7 @@ class RustMatrixClient(
|
|||||||
|
|
||||||
sessionCoroutineScope.cancel()
|
sessionCoroutineScope.cancel()
|
||||||
clientDelegateTaskHandle?.cancelAndDestroy()
|
clientDelegateTaskHandle?.cancelAndDestroy()
|
||||||
|
ownProfileTaskHandle?.cancelAndDestroy()
|
||||||
sessionVerificationService.destroy()
|
sessionVerificationService.destroy()
|
||||||
|
|
||||||
sessionDelegate.clearCurrentClient()
|
sessionDelegate.clearCurrentClient()
|
||||||
|
|||||||
+1
@@ -155,6 +155,7 @@ class RustMatrixClientFactory(
|
|||||||
val syncService = client.syncService()
|
val syncService = client.syncService()
|
||||||
.withSharePos(true)
|
.withSharePos(true)
|
||||||
.withOfflineMode()
|
.withOfflineMode()
|
||||||
|
.withProfilesExtension()
|
||||||
.finish()
|
.finish()
|
||||||
|
|
||||||
return RustMatrixClient(
|
return RustMatrixClient(
|
||||||
|
|||||||
+10
@@ -26,6 +26,7 @@ import org.matrix.rustcomponents.sdk.NoHandle
|
|||||||
import org.matrix.rustcomponents.sdk.NotificationClient
|
import org.matrix.rustcomponents.sdk.NotificationClient
|
||||||
import org.matrix.rustcomponents.sdk.NotificationProcessSetup
|
import org.matrix.rustcomponents.sdk.NotificationProcessSetup
|
||||||
import org.matrix.rustcomponents.sdk.NotificationSettings
|
import org.matrix.rustcomponents.sdk.NotificationSettings
|
||||||
|
import org.matrix.rustcomponents.sdk.ProfileListener
|
||||||
import org.matrix.rustcomponents.sdk.PusherIdentifiers
|
import org.matrix.rustcomponents.sdk.PusherIdentifiers
|
||||||
import org.matrix.rustcomponents.sdk.PusherKind
|
import org.matrix.rustcomponents.sdk.PusherKind
|
||||||
import org.matrix.rustcomponents.sdk.RoomDirectorySearch
|
import org.matrix.rustcomponents.sdk.RoomDirectorySearch
|
||||||
@@ -55,6 +56,8 @@ class FakeFfiClient(
|
|||||||
private val getStoreSizesResult: () -> StoreSizes = { lambdaError() },
|
private val getStoreSizesResult: () -> StoreSizes = { lambdaError() },
|
||||||
private val createRoomResult: (CreateRoomParameters) -> String = { lambdaError() },
|
private val createRoomResult: (CreateRoomParameters) -> String = { lambdaError() },
|
||||||
private val homeserverCapabilities: HomeserverCapabilities = FakeFfiHomeserverCapabilities(),
|
private val homeserverCapabilities: HomeserverCapabilities = FakeFfiHomeserverCapabilities(),
|
||||||
|
private val isUserStatusSupportedResult: () -> Boolean = { false },
|
||||||
|
private val subscribeToOwnProfileResult: (ProfileListener) -> Unit = {},
|
||||||
private val closeResult: () -> Unit = {},
|
private val closeResult: () -> Unit = {},
|
||||||
) : Client(NoHandle) {
|
) : Client(NoHandle) {
|
||||||
override fun userId(): String = userId
|
override fun userId(): String = userId
|
||||||
@@ -92,6 +95,13 @@ class FakeFfiClient(
|
|||||||
return FakeFfiTaskHandle()
|
return FakeFfiTaskHandle()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override suspend fun isUserStatusSupported(): Boolean = isUserStatusSupportedResult()
|
||||||
|
|
||||||
|
override fun subscribeToOwnProfile(listener: ProfileListener): TaskHandle {
|
||||||
|
subscribeToOwnProfileResult(listener)
|
||||||
|
return FakeFfiTaskHandle()
|
||||||
|
}
|
||||||
|
|
||||||
override suspend fun getProfile(userId: String): UserProfile {
|
override suspend fun getProfile(userId: String): UserProfile {
|
||||||
return getProfileResult(userId)
|
return getProfileResult(userId)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user