diff --git a/vector/src/main/java/im/vector/app/features/home/GetSpacesNotificationBadgeStateUseCase.kt b/vector/src/main/java/im/vector/app/features/home/GetSpacesNotificationBadgeStateUseCase.kt
new file mode 100644
index 0000000000..62d1501dab
--- /dev/null
+++ b/vector/src/main/java/im/vector/app/features/home/GetSpacesNotificationBadgeStateUseCase.kt
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2023 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.home
+
+import im.vector.app.features.home.room.list.UnreadCounterBadgeView
+import im.vector.app.features.spaces.GetSpacesUseCase
+import im.vector.app.features.spaces.notification.GetNotificationCountForSpacesUseCase
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.combine
+import org.matrix.android.sdk.api.query.QueryStringValue
+import org.matrix.android.sdk.api.query.SpaceFilter
+import org.matrix.android.sdk.api.session.room.model.Membership
+import org.matrix.android.sdk.api.session.room.model.RoomSummary
+import org.matrix.android.sdk.api.session.room.spaceSummaryQueryParams
+import org.matrix.android.sdk.api.session.room.summary.RoomAggregateNotificationCount
+import javax.inject.Inject
+
+class GetSpacesNotificationBadgeStateUseCase @Inject constructor(
+        private val getNotificationCountForSpacesUseCase: GetNotificationCountForSpacesUseCase,
+        private val getSpacesUseCase: GetSpacesUseCase,
+) {
+
+    fun execute(): Flow<UnreadCounterBadgeView.State> {
+        val params = spaceSummaryQueryParams {
+            memberships = listOf(Membership.INVITE)
+            displayName = QueryStringValue.IsNotEmpty
+        }
+        return combine(
+                getNotificationCountForSpacesUseCase.execute(SpaceFilter.NoFilter),
+                getSpacesUseCase.execute(params),
+        ) { spacesNotificationCount, spaceInvites ->
+            computeSpacesNotificationCounterBadgeState(spacesNotificationCount, spaceInvites)
+        }
+    }
+
+    private fun computeSpacesNotificationCounterBadgeState(
+            spacesNotificationCount: RoomAggregateNotificationCount,
+            spaceInvites: List<RoomSummary>,
+    ): UnreadCounterBadgeView.State {
+        val hasPendingSpaceInvites = spaceInvites.isNotEmpty()
+        return if (hasPendingSpaceInvites && spacesNotificationCount.notificationCount == 0) {
+            UnreadCounterBadgeView.State.Text(
+                    text = "!",
+                    highlighted = true,
+            )
+        } else {
+            UnreadCounterBadgeView.State.Count(
+                    count = spacesNotificationCount.notificationCount,
+                    highlighted = spacesNotificationCount.isHighlight || hasPendingSpaceInvites,
+            )
+        }
+    }
+}
diff --git a/vector/src/main/java/im/vector/app/features/home/NewHomeDetailFragment.kt b/vector/src/main/java/im/vector/app/features/home/NewHomeDetailFragment.kt
index a13487afc8..ef855ff15b 100644
--- a/vector/src/main/java/im/vector/app/features/home/NewHomeDetailFragment.kt
+++ b/vector/src/main/java/im/vector/app/features/home/NewHomeDetailFragment.kt
@@ -64,7 +64,6 @@ import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.flow.onEach
 import org.matrix.android.sdk.api.session.crypto.model.DeviceInfo
 import org.matrix.android.sdk.api.session.room.model.RoomSummary
-import org.matrix.android.sdk.api.session.room.summary.RoomAggregateNotificationCount
 import javax.inject.Inject
 
 @AndroidEntryPoint
@@ -185,7 +184,7 @@ class NewHomeDetailFragment :
                 }
 
         newHomeDetailViewModel.onEach { viewState ->
-            refreshUnreadCounterBadge(viewState.spacesNotificationCount, viewState.hasPendingSpaceInvites)
+            refreshUnreadCounterBadge(viewState.spacesNotificationCounterBadgeState)
         }
     }
 
@@ -386,21 +385,7 @@ class NewHomeDetailFragment :
         }
     }
 
-    private fun refreshUnreadCounterBadge(
-            spacesNotificationCount: RoomAggregateNotificationCount,
-            hasPendingSpaceInvites: Boolean,
-    ) {
-        val badgeState = if (hasPendingSpaceInvites && spacesNotificationCount.notificationCount == 0) {
-            UnreadCounterBadgeView.State.Text(
-                    text = "!",
-                    highlighted = true,
-            )
-        } else {
-            UnreadCounterBadgeView.State.Count(
-                    count = spacesNotificationCount.notificationCount,
-                    highlighted = spacesNotificationCount.isHighlight || hasPendingSpaceInvites,
-            )
-        }
+    private fun refreshUnreadCounterBadge(badgeState: UnreadCounterBadgeView.State) {
         views.spacesUnreadCounterBadge.render(badgeState)
     }
 
diff --git a/vector/src/main/java/im/vector/app/features/home/NewHomeDetailViewModel.kt b/vector/src/main/java/im/vector/app/features/home/NewHomeDetailViewModel.kt
index b26d010137..67b4645944 100644
--- a/vector/src/main/java/im/vector/app/features/home/NewHomeDetailViewModel.kt
+++ b/vector/src/main/java/im/vector/app/features/home/NewHomeDetailViewModel.kt
@@ -25,19 +25,12 @@ import im.vector.app.core.di.hiltMavericksViewModelFactory
 import im.vector.app.core.platform.EmptyAction
 import im.vector.app.core.platform.EmptyViewEvents
 import im.vector.app.core.platform.VectorViewModel
-import im.vector.app.features.spaces.GetSpacesUseCase
-import im.vector.app.features.spaces.notification.GetNotificationCountForSpacesUseCase
 import kotlinx.coroutines.flow.launchIn
 import kotlinx.coroutines.flow.onEach
-import org.matrix.android.sdk.api.query.QueryStringValue
-import org.matrix.android.sdk.api.query.SpaceFilter
-import org.matrix.android.sdk.api.session.room.model.Membership
-import org.matrix.android.sdk.api.session.room.spaceSummaryQueryParams
 
 class NewHomeDetailViewModel @AssistedInject constructor(
         @Assisted initialState: NewHomeDetailViewState,
-        private val getNotificationCountForSpacesUseCase: GetNotificationCountForSpacesUseCase,
-        private val getSpacesUseCase: GetSpacesUseCase,
+        private val getSpacesNotificationBadgeStateUseCase: GetSpacesNotificationBadgeStateUseCase,
 ) : VectorViewModel<NewHomeDetailViewState, EmptyAction, EmptyViewEvents>(initialState) {
 
     @AssistedFactory
@@ -48,23 +41,12 @@ class NewHomeDetailViewModel @AssistedInject constructor(
     companion object : MavericksViewModelFactory<NewHomeDetailViewModel, NewHomeDetailViewState> by hiltMavericksViewModelFactory()
 
     init {
-        observeSpacesNotificationCount()
-        observeSpacesInvite()
+        observeSpacesNotificationBadgeState()
     }
 
-    private fun observeSpacesNotificationCount() {
-        getNotificationCountForSpacesUseCase.execute(SpaceFilter.NoFilter)
-                .onEach { setState { copy(spacesNotificationCount = it) } }
-                .launchIn(viewModelScope)
-    }
-
-    private fun observeSpacesInvite() {
-        val params = spaceSummaryQueryParams {
-            memberships = listOf(Membership.INVITE)
-            displayName = QueryStringValue.IsNotEmpty
-        }
-        getSpacesUseCase.execute(params)
-                .onEach { setState { copy(hasPendingSpaceInvites = it.isNotEmpty()) } }
+    private fun observeSpacesNotificationBadgeState() {
+        getSpacesNotificationBadgeStateUseCase.execute()
+                .onEach { badgeState -> setState { copy(spacesNotificationCounterBadgeState = badgeState) } }
                 .launchIn(viewModelScope)
     }
 
diff --git a/vector/src/main/java/im/vector/app/features/home/NewHomeDetailViewState.kt b/vector/src/main/java/im/vector/app/features/home/NewHomeDetailViewState.kt
index 1ff0b86511..7e368fb2d1 100644
--- a/vector/src/main/java/im/vector/app/features/home/NewHomeDetailViewState.kt
+++ b/vector/src/main/java/im/vector/app/features/home/NewHomeDetailViewState.kt
@@ -17,9 +17,8 @@
 package im.vector.app.features.home
 
 import com.airbnb.mvrx.MavericksState
-import org.matrix.android.sdk.api.session.room.summary.RoomAggregateNotificationCount
+import im.vector.app.features.home.room.list.UnreadCounterBadgeView
 
 data class NewHomeDetailViewState(
-        val spacesNotificationCount: RoomAggregateNotificationCount = RoomAggregateNotificationCount(notificationCount = 0, highlightCount = 0),
-        val hasPendingSpaceInvites: Boolean = false,
+        val spacesNotificationCounterBadgeState: UnreadCounterBadgeView.State = UnreadCounterBadgeView.State.Count(count = 0, highlighted = false),
 ) : MavericksState
diff --git a/vector/src/test/java/im/vector/app/features/home/GetSpacesNotificationBadgeStateUseCaseTest.kt b/vector/src/test/java/im/vector/app/features/home/GetSpacesNotificationBadgeStateUseCaseTest.kt
new file mode 100644
index 0000000000..4d7d0d98f4
--- /dev/null
+++ b/vector/src/test/java/im/vector/app/features/home/GetSpacesNotificationBadgeStateUseCaseTest.kt
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2023 New Vector Ltd
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package im.vector.app.features.home
+
+import im.vector.app.features.home.room.list.UnreadCounterBadgeView
+import im.vector.app.features.spaces.GetSpacesUseCase
+import im.vector.app.features.spaces.notification.GetNotificationCountForSpacesUseCase
+import im.vector.app.test.test
+import io.mockk.every
+import io.mockk.mockk
+import io.mockk.verify
+import kotlinx.coroutines.flow.flowOf
+import kotlinx.coroutines.test.advanceUntilIdle
+import kotlinx.coroutines.test.runTest
+import org.junit.Test
+import org.matrix.android.sdk.api.query.QueryStringValue
+import org.matrix.android.sdk.api.query.SpaceFilter
+import org.matrix.android.sdk.api.session.room.model.Membership
+import org.matrix.android.sdk.api.session.room.model.RoomSummary
+import org.matrix.android.sdk.api.session.room.summary.RoomAggregateNotificationCount
+
+internal class GetSpacesNotificationBadgeStateUseCaseTest {
+
+    private val fakeGetNotificationCountForSpacesUseCase = mockk<GetNotificationCountForSpacesUseCase>()
+    private val fakeGetSpacesUseCase = mockk<GetSpacesUseCase>()
+
+    private val getSpacesNotificationBadgeStateUseCase = GetSpacesNotificationBadgeStateUseCase(
+            getNotificationCountForSpacesUseCase = fakeGetNotificationCountForSpacesUseCase,
+            getSpacesUseCase = fakeGetSpacesUseCase,
+    )
+
+    @Test
+    fun `given flow of spaces invite and notification count then flow of state is correct`() = runTest {
+        // Given
+        val noSpacesInvite = emptyList<RoomSummary>()
+        val existingSpaceInvite = listOf<RoomSummary>(mockk())
+        val noNotification = RoomAggregateNotificationCount(
+                notificationCount = 0,
+                highlightCount = 0,
+        )
+        val existingNotificationNotHighlighted = RoomAggregateNotificationCount(
+                notificationCount = 1,
+                highlightCount = 0,
+        )
+        val existingNotificationHighlighted = RoomAggregateNotificationCount(
+                notificationCount = 1,
+                highlightCount = 1,
+        )
+        every { fakeGetSpacesUseCase.execute(any()) } returns
+                flowOf(noSpacesInvite, existingSpaceInvite, existingSpaceInvite, noSpacesInvite, noSpacesInvite)
+        every { fakeGetNotificationCountForSpacesUseCase.execute(any()) } returns
+                flowOf(noNotification, noNotification, existingNotificationNotHighlighted, existingNotificationNotHighlighted, existingNotificationHighlighted)
+
+        // When
+        val testObserver = getSpacesNotificationBadgeStateUseCase.execute().test(this)
+        advanceUntilIdle()
+
+        // Then
+        val expectedState1 = UnreadCounterBadgeView.State.Count(count = 0, highlighted = false)
+        val expectedState2 = UnreadCounterBadgeView.State.Text(text = "!", highlighted = true)
+        val expectedState3 = UnreadCounterBadgeView.State.Count(count = 1, highlighted = true)
+        val expectedState4 = UnreadCounterBadgeView.State.Count(count = 1, highlighted = false)
+        val expectedState5 = UnreadCounterBadgeView.State.Count(count = 1, highlighted = true)
+        testObserver
+                .assertValues(expectedState1, expectedState2, expectedState3, expectedState4, expectedState5)
+                .finish()
+        verify {
+            fakeGetSpacesUseCase.execute(match {
+                it.memberships == listOf(Membership.INVITE) && it.displayName == QueryStringValue.IsNotEmpty
+            })
+        }
+        verify { fakeGetNotificationCountForSpacesUseCase.execute(SpaceFilter.NoFilter) }
+    }
+}
diff --git a/vector/src/test/java/im/vector/app/features/home/NewHomeDetailViewModelTest.kt b/vector/src/test/java/im/vector/app/features/home/NewHomeDetailViewModelTest.kt
index 23882bf7c4..a92c4be0d7 100644
--- a/vector/src/test/java/im/vector/app/features/home/NewHomeDetailViewModelTest.kt
+++ b/vector/src/test/java/im/vector/app/features/home/NewHomeDetailViewModelTest.kt
@@ -17,8 +17,8 @@
 package im.vector.app.features.home
 
 import com.airbnb.mvrx.test.MavericksTestRule
+import im.vector.app.features.home.room.list.UnreadCounterBadgeView
 import im.vector.app.features.spaces.GetSpacesUseCase
-import im.vector.app.features.spaces.notification.GetNotificationCountForSpacesUseCase
 import im.vector.app.test.test
 import io.mockk.every
 import io.mockk.mockk
@@ -27,10 +27,6 @@ import kotlinx.coroutines.flow.flowOf
 import kotlinx.coroutines.test.UnconfinedTestDispatcher
 import org.junit.Rule
 import org.junit.Test
-import org.matrix.android.sdk.api.query.SpaceFilter
-import org.matrix.android.sdk.api.session.room.model.Membership
-import org.matrix.android.sdk.api.session.room.model.RoomSummary
-import org.matrix.android.sdk.api.session.room.summary.RoomAggregateNotificationCount
 
 internal class NewHomeDetailViewModelTest {
 
@@ -38,43 +34,34 @@ internal class NewHomeDetailViewModelTest {
     val mavericksTestRule = MavericksTestRule(testDispatcher = UnconfinedTestDispatcher())
 
     private val initialState = NewHomeDetailViewState()
-    private val fakeGetNotificationCountForSpacesUseCase = mockk<GetNotificationCountForSpacesUseCase>()
-    private val fakeGetSpacesUseCase = mockk<GetSpacesUseCase>()
+    private val fakeGetSpacesNotificationBadgeStateUseCase = mockk<GetSpacesNotificationBadgeStateUseCase>()
 
     private fun createViewModel(): NewHomeDetailViewModel {
         return NewHomeDetailViewModel(
                 initialState = initialState,
-                getNotificationCountForSpacesUseCase = fakeGetNotificationCountForSpacesUseCase,
-                getSpacesUseCase = fakeGetSpacesUseCase,
+                getSpacesNotificationBadgeStateUseCase = fakeGetSpacesNotificationBadgeStateUseCase,
         )
     }
 
     @Test
-    fun `given the viewModel is created then viewState is updated with space notifications count and pending space invites`() {
+    fun `given the viewModel is created then viewState is updated with space notifications badge state`() {
         // Given
-        val spacesNotificationCount = RoomAggregateNotificationCount(
-                notificationCount = 1,
-                highlightCount = 1,
-        )
-        every { fakeGetNotificationCountForSpacesUseCase.execute(any()) } returns flowOf(spacesNotificationCount)
-        val spaceInvites = listOf<RoomSummary>(mockk())
-        every { fakeGetSpacesUseCase.execute(any()) } returns flowOf(spaceInvites)
-        val expectedViewState = initialState.copy(
-                spacesNotificationCount = spacesNotificationCount,
-                hasPendingSpaceInvites = true,
-        )
+        val aBadgeState = UnreadCounterBadgeView.State.Count(count = 1, highlighted = false)
+        every { fakeGetSpacesNotificationBadgeStateUseCase.execute() } returns flowOf(aBadgeState)
 
         // When
         val viewModel = createViewModel()
         val viewModelTest = viewModel.test()
 
         // Then
+        val expectedViewState = initialState.copy(
+                spacesNotificationCounterBadgeState = aBadgeState,
+        )
         viewModelTest
                 .assertLatestState(expectedViewState)
                 .finish()
         verify {
-            fakeGetNotificationCountForSpacesUseCase.execute(SpaceFilter.NoFilter)
-            fakeGetSpacesUseCase.execute(match { it.memberships == listOf(Membership.INVITE) })
+            fakeGetSpacesNotificationBadgeStateUseCase.execute()
         }
     }
 }