mirror of
https://github.com/Novaloop-AG/element-x-android.git
synced 2026-11-02 03:06:14 +00:00
Add total unread notification count to home screen (#7891)
* Add total unread notification count to home screen This will be calculated on each sync heartbeat (for now, using the state updates for the room list service). * Simplify `counter` parameter logic * Read the total unread count when the home screen is first displayed --------- Co-authored-by: Benoit Marty <benoitm@element.io>
This commit is contained in:
committed by
GitHub
parent
50aa723f63
commit
9cc5cf9a01
+6
@@ -505,6 +505,12 @@ interface MatrixClient : ClientUrlContentFetcher {
|
||||
|
||||
/** Returns a provider for the capabilities the homeserver advertises, such as whether the display name can be changed. */
|
||||
fun homeserverCapabilities(): HomeserverCapabilitiesProvider
|
||||
|
||||
/**
|
||||
* Returns the total number of unread notifications across all rooms, as currently known by the client.
|
||||
* This is a snapshot and may be out of date if the sync is running.
|
||||
*/
|
||||
fun totalUnreadCount(): Result<Long>
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+7
@@ -8,6 +8,7 @@
|
||||
|
||||
package io.element.android.libraries.matrix.api.sync
|
||||
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
||||
/**
|
||||
@@ -37,4 +38,10 @@ interface SyncService {
|
||||
* This is `false` only while the state is [SyncState.Offline]; an idle or errored sync still counts as online.
|
||||
*/
|
||||
val isOnline: StateFlow<Boolean>
|
||||
|
||||
/**
|
||||
* Flow that will emit every time the sync has received a response from the server, even if it was empty.
|
||||
* Useful for triggering UI updates when the sync is running.
|
||||
*/
|
||||
val heartBeat: Flow<Unit>
|
||||
}
|
||||
|
||||
+4
@@ -1024,6 +1024,10 @@ class RustMatrixClient(
|
||||
return RustHomeserverCapabilitiesProvider(innerClient.homeserverCapabilities())
|
||||
}
|
||||
|
||||
override fun totalUnreadCount(): Result<Long> = runCatchingExceptions {
|
||||
innerClient.totalUnreadNotifications().toLong()
|
||||
}
|
||||
|
||||
private fun scheduleBackgroundSearchBackfill() {
|
||||
featureFlagService.isFeatureEnabledFlow(FeatureFlags.MessageSearch)
|
||||
.distinctUntilChanged()
|
||||
|
||||
+10
@@ -12,16 +12,20 @@ import io.element.android.libraries.core.coroutine.mapState
|
||||
import io.element.android.libraries.core.extensions.runCatchingExceptions
|
||||
import io.element.android.libraries.matrix.api.sync.SyncService
|
||||
import io.element.android.libraries.matrix.api.sync.SyncState
|
||||
import io.element.android.libraries.matrix.impl.roomlist.stateFlow
|
||||
import kotlinx.coroutines.CoroutineDispatcher
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.NonCancellable
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.filter
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.matrix.rustcomponents.sdk.RoomListServiceState
|
||||
import org.matrix.rustcomponents.sdk.SyncServiceState
|
||||
import timber.log.Timber
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
@@ -78,4 +82,10 @@ class RustSyncService(
|
||||
.stateIn(sessionCoroutineScope, SharingStarted.Eagerly, SyncState.Idle)
|
||||
|
||||
override val isOnline: StateFlow<Boolean> = syncState.mapState { it != SyncState.Offline }
|
||||
|
||||
// TODO actually use a heartbeat mechanism from the SDK, not simulate it with the room list service
|
||||
override val heartBeat: Flow<Unit> = inner.roomListService()
|
||||
.stateFlow()
|
||||
.filter { it == RoomListServiceState.RUNNING }
|
||||
.map {}
|
||||
}
|
||||
|
||||
+5
@@ -102,6 +102,7 @@ class FakeMatrixClient(
|
||||
override val mediaPreviewService: MediaPreviewService = FakeMediaPreviewService(),
|
||||
override val roomMembershipObserver: RoomMembershipObserver = RoomMembershipObserver(),
|
||||
private val homeserverCapabilitiesProvider: FakeHomeserverCapabilitiesProvider = FakeHomeserverCapabilitiesProvider(),
|
||||
private val totalUnreadCountResult: () -> Result<Long> = { Result.success(0L) },
|
||||
private val accountManagementUrlResult: (AccountManagementAction?) -> Result<String?> = { lambdaError() },
|
||||
private val resolveRoomAliasResult: suspend (RoomAlias) -> Result<Optional<ResolvedRoomAlias>> = {
|
||||
Result.success(
|
||||
@@ -468,4 +469,8 @@ class FakeMatrixClient(
|
||||
override fun homeserverCapabilities(): HomeserverCapabilitiesProvider {
|
||||
return homeserverCapabilitiesProvider
|
||||
}
|
||||
|
||||
override fun totalUnreadCount(): Result<Long> {
|
||||
return totalUnreadCountResult()
|
||||
}
|
||||
}
|
||||
|
||||
+10
@@ -11,6 +11,8 @@ package io.element.android.libraries.matrix.test.sync
|
||||
import io.element.android.libraries.core.coroutine.mapState
|
||||
import io.element.android.libraries.matrix.api.sync.SyncService
|
||||
import io.element.android.libraries.matrix.api.sync.SyncState
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
||||
@@ -33,6 +35,14 @@ class FakeSyncService(
|
||||
|
||||
override val isOnline: StateFlow<Boolean> = syncState.mapState { it != SyncState.Offline }
|
||||
|
||||
private val heartBeatFlow = MutableSharedFlow<Unit>(extraBufferCapacity = 1)
|
||||
|
||||
override val heartBeat: Flow<Unit> = heartBeatFlow
|
||||
|
||||
suspend fun emitHeartBeat() {
|
||||
heartBeatFlow.emit(Unit)
|
||||
}
|
||||
|
||||
suspend fun emitSyncState(syncState: SyncState) {
|
||||
syncStateFlow.emit(syncState)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user