@@ -14,6 +14,7 @@ import androidx.compose.runtime.derivedStateOf
14
14
import androidx.compose.runtime.getValue
15
15
import androidx.compose.runtime.mutableIntStateOf
16
16
import androidx.compose.runtime.remember
17
+ import androidx.compose.runtime.rememberCoroutineScope
17
18
import androidx.compose.runtime.saveable.rememberSaveable
18
19
import androidx.compose.runtime.setValue
19
20
import dev.zacsweers.metro.Inject
@@ -27,8 +28,15 @@ import io.element.android.libraries.featureflag.api.FeatureFlagService
27
28
import io.element.android.libraries.featureflag.api.FeatureFlags
28
29
import io.element.android.libraries.indicator.api.IndicatorService
29
30
import io.element.android.libraries.matrix.api.MatrixClient
31
+ import io.element.android.libraries.matrix.api.core.UserId
30
32
import io.element.android.libraries.matrix.api.sync.SyncService
33
+ import io.element.android.libraries.matrix.api.user.MatrixUser
34
+ import io.element.android.libraries.sessionstorage.api.SessionData
31
35
import io.element.android.libraries.sessionstorage.api.SessionStore
36
+ import kotlinx.collections.immutable.persistentListOf
37
+ import kotlinx.collections.immutable.toPersistentList
38
+ import kotlinx.coroutines.flow.map
39
+ import kotlinx.coroutines.launch
32
40
33
41
@Inject
34
42
class HomePresenter (
@@ -44,7 +52,13 @@ class HomePresenter(
44
52
) : Presenter<HomeState> {
45
53
@Composable
46
54
override fun present (): HomeState {
55
+ val coroutineState = rememberCoroutineScope()
47
56
val matrixUser by client.userProfile.collectAsState()
57
+ val matrixUserAndNeighbors by remember {
58
+ sessionStore.sessionsFlow().map { list ->
59
+ list.takeCurrentUserWithNeighbors(matrixUser).toPersistentList()
60
+ }
61
+ }.collectAsState(initial = persistentListOf(matrixUser))
48
62
val isOnline by syncService.isOnline.collectAsState()
49
63
val canReportBug by remember { rageshakeFeatureAvailability.isAvailable() }.collectAsState(false )
50
64
val roomListState = roomListPresenter.present()
@@ -79,12 +93,15 @@ class HomePresenter(
79
93
is HomeEvents .SelectHomeNavigationBarItem -> {
80
94
currentHomeNavigationBarItemOrdinal = event.item.ordinal
81
95
}
96
+ is HomeEvents .SwitchToAccount -> coroutineState.launch {
97
+ sessionStore.setLatestSession(event.sessionId.value)
98
+ }
82
99
}
83
100
}
84
101
85
102
val snackbarMessage by snackbarDispatcher.collectSnackbarMessageAsState()
86
103
return HomeState (
87
- matrixUser = matrixUser ,
104
+ matrixUserAndNeighbors = matrixUserAndNeighbors ,
88
105
showAvatarIndicator = showAvatarIndicator,
89
106
hasNetworkConnection = isOnline,
90
107
currentHomeNavigationBarItem = currentHomeNavigationBarItem,
@@ -97,3 +114,45 @@ class HomePresenter(
97
114
)
98
115
}
99
116
}
117
+
118
+ private fun List<SessionData>.takeCurrentUserWithNeighbors (matrixUser : MatrixUser ): List <MatrixUser > {
119
+ // Sort by userId to always have the same order (not depending on last account usage)
120
+ return sortedBy { it.userId }
121
+ .map {
122
+ if (it.userId == matrixUser.userId.value) {
123
+ // Always use the freshest profile for the current user
124
+ matrixUser
125
+ } else {
126
+ // Use the data from the DB
127
+ MatrixUser (
128
+ userId = UserId (it.userId),
129
+ displayName = it.userDisplayName,
130
+ avatarUrl = it.userAvatarUrl,
131
+ )
132
+ }
133
+ }
134
+ .let { sessionList ->
135
+ // If the list has one item, there is no other session, return the list
136
+ when (sessionList.size) {
137
+ // Can happen when the user signs out (?)
138
+ 0 -> listOf (matrixUser)
139
+ 1 -> sessionList
140
+ else -> {
141
+ // Create a list with extra item at the start and end if necessary to have the current user in the middle
142
+ // If the list is [A, B, C, D] and the current user is A we want to return [D, A, B]
143
+ // If the current user is B, we want to return [A, B, C]
144
+ // If the current user is C, we want to return [B, C, D]
145
+ // If the current user is D, we want to return [C, D, A]
146
+ val currentUserIndex = sessionList.indexOfFirst { it.userId == matrixUser.userId }
147
+ when (currentUserIndex) {
148
+ // This can happen when the user signs out.
149
+ // In this case, just return a singleton list with the current user.
150
+ - 1 -> listOf (matrixUser)
151
+ 0 -> listOf (sessionList.last()) + sessionList.take(2 )
152
+ sessionList.lastIndex -> sessionList.takeLast(2 ) + sessionList.first()
153
+ else -> sessionList.slice(currentUserIndex - 1 .. currentUserIndex + 1 )
154
+ }
155
+ }
156
+ }
157
+ }
158
+ }
0 commit comments