Skip to content

Commit 476a2b9

Browse files
committed
Avoid using runBlocking in Node resolve function.
1 parent 037e5db commit 476a2b9

File tree

10 files changed

+159
-26
lines changed

10 files changed

+159
-26
lines changed

features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/CreateRoomFlowNode.kt

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,16 +26,13 @@ import io.element.android.libraries.architecture.BackstackView
2626
import io.element.android.libraries.architecture.BaseFlowNode
2727
import io.element.android.libraries.architecture.createNode
2828
import io.element.android.libraries.di.SessionScope
29-
import io.element.android.libraries.matrix.api.MatrixClient
3029
import io.element.android.libraries.matrix.api.core.RoomId
31-
import kotlinx.coroutines.runBlocking
3230
import kotlinx.parcelize.Parcelize
3331

3432
@ContributesNode(SessionScope::class)
3533
class CreateRoomFlowNode @AssistedInject constructor(
3634
@Assisted buildContext: BuildContext,
3735
@Assisted plugins: List<Plugin>,
38-
private val client: MatrixClient,
3936
) : BaseFlowNode<CreateRoomFlowNode.NavTarget>(
4037
backstack = BackStack(
4138
initialElement = NavTarget.ConfigureRoom,
@@ -59,8 +56,7 @@ class CreateRoomFlowNode @AssistedInject constructor(
5956
createNode<ConfigureRoomNode>(buildContext, plugins = listOf(callback))
6057
}
6158
is NavTarget.AddPeople -> {
62-
val joinedRoom = runBlocking { client.getJoinedRoom(navTarget.roomId) } ?: error("Room not found")
63-
val inputs = AddPeopleNode.Inputs(joinedRoom)
59+
val inputs = AddPeopleNode.Inputs(navTarget.roomId)
6460
val callback: AddPeopleNode.Callback = object : AddPeopleNode.Callback {
6561
override fun onFinish() {
6662
onRoomCreated(navTarget.roomId)

features/createroom/impl/src/main/kotlin/io/element/android/features/createroom/impl/addpeople/AddPeopleNode.kt

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import io.element.android.features.invitepeople.api.InvitePeopleRenderer
2121
import io.element.android.libraries.architecture.NodeInputs
2222
import io.element.android.libraries.architecture.inputs
2323
import io.element.android.libraries.di.SessionScope
24-
import io.element.android.libraries.matrix.api.room.JoinedRoom
24+
import io.element.android.libraries.matrix.api.core.RoomId
2525

2626
@ContributesNode(SessionScope::class)
2727
class AddPeopleNode @AssistedInject constructor(
@@ -31,7 +31,7 @@ class AddPeopleNode @AssistedInject constructor(
3131
private val invitePeopleRenderer: InvitePeopleRenderer,
3232
) : Node(buildContext, plugins = plugins) {
3333
data class Inputs(
34-
val joinedRoom: JoinedRoom
34+
val roomId: RoomId,
3535
) : NodeInputs
3636

3737
interface Callback : Plugin {
@@ -42,8 +42,11 @@ class AddPeopleNode @AssistedInject constructor(
4242
plugins<Callback>().forEach { it.onFinish() }
4343
}
4444

45-
private val joinedRoom = inputs<Inputs>().joinedRoom
46-
private val invitePeoplePresenter = invitePeoplePresenterFactory.create(joinedRoom)
45+
private val roomId = inputs<Inputs>().roomId
46+
private val invitePeoplePresenter = invitePeoplePresenterFactory.create(
47+
joinedRoom = null,
48+
roomId = roomId,
49+
)
4750

4851
@Composable
4952
override fun View(modifier: Modifier) {

features/invitepeople/api/src/main/kotlin/io/element/android/features/invitepeople/api/InvitePeoplePresenter.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,14 @@
88
package io.element.android.features.invitepeople.api
99

1010
import io.element.android.libraries.architecture.Presenter
11+
import io.element.android.libraries.matrix.api.core.RoomId
1112
import io.element.android.libraries.matrix.api.room.JoinedRoom
1213

1314
interface InvitePeoplePresenter : Presenter<InvitePeopleState> {
1415
interface Factory {
15-
fun create(room: JoinedRoom): InvitePeoplePresenter
16+
fun create(
17+
joinedRoom: JoinedRoom?,
18+
roomId: RoomId,
19+
): InvitePeoplePresenter
1620
}
1721
}

features/invitepeople/impl/src/main/kotlin/io/element/android/features/invitepeople/impl/DefaultInvitePeoplePresenter.kt

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import androidx.compose.runtime.LaunchedEffect
1212
import androidx.compose.runtime.MutableState
1313
import androidx.compose.runtime.getValue
1414
import androidx.compose.runtime.mutableStateOf
15+
import androidx.compose.runtime.produceState
1516
import androidx.compose.runtime.remember
1617
import androidx.compose.runtime.saveable.rememberSaveable
1718
import androidx.compose.runtime.setValue
@@ -23,11 +24,14 @@ import io.element.android.features.invitepeople.api.InvitePeopleEvents
2324
import io.element.android.features.invitepeople.api.InvitePeoplePresenter
2425
import io.element.android.features.invitepeople.api.InvitePeopleState
2526
import io.element.android.libraries.architecture.AsyncData
27+
import io.element.android.libraries.architecture.map
2628
import io.element.android.libraries.architecture.runCatchingUpdatingState
2729
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
2830
import io.element.android.libraries.designsystem.theme.components.SearchBarResultState
2931
import io.element.android.libraries.di.SessionScope
3032
import io.element.android.libraries.di.annotations.SessionCoroutineScope
33+
import io.element.android.libraries.matrix.api.MatrixClient
34+
import io.element.android.libraries.matrix.api.core.RoomId
3135
import io.element.android.libraries.matrix.api.room.JoinedRoom
3236
import io.element.android.libraries.matrix.api.room.RoomMember
3337
import io.element.android.libraries.matrix.api.room.RoomMembershipState
@@ -46,16 +50,18 @@ import kotlinx.coroutines.launch
4650
import kotlinx.coroutines.withContext
4751

4852
class DefaultInvitePeoplePresenter @AssistedInject constructor(
49-
@Assisted private val room: JoinedRoom,
53+
@Assisted private val joinedRoom: JoinedRoom?,
54+
@Assisted private val roomId: RoomId,
5055
private val userRepository: UserRepository,
5156
private val coroutineDispatchers: CoroutineDispatchers,
5257
@SessionCoroutineScope private val sessionCoroutineScope: CoroutineScope,
5358
private val appErrorStateService: AppErrorStateService,
59+
private val matrixClient: MatrixClient,
5460
) : InvitePeoplePresenter {
5561
@AssistedFactory
5662
@ContributesBinding(SessionScope::class)
5763
interface Factory : InvitePeoplePresenter.Factory {
58-
override fun create(room: JoinedRoom): DefaultInvitePeoplePresenter
64+
override fun create(joinedRoom: JoinedRoom?, roomId: RoomId): DefaultInvitePeoplePresenter
5965
}
6066

6167
@Composable
@@ -66,9 +72,21 @@ class DefaultInvitePeoplePresenter @AssistedInject constructor(
6672
var searchQuery by rememberSaveable { mutableStateOf("") }
6773
var searchActive by rememberSaveable { mutableStateOf(false) }
6874
val showSearchLoader = rememberSaveable { mutableStateOf(false) }
75+
val room by produceState(if (joinedRoom != null) AsyncData.Success(joinedRoom) else AsyncData.Loading()) {
76+
if (joinedRoom == null) {
77+
val result = matrixClient.getJoinedRoom(roomId)
78+
value = if (result == null) {
79+
AsyncData.Failure(Exception("Room not found"))
80+
} else {
81+
AsyncData.Success(result)
82+
}
83+
}
84+
}
6985

70-
LaunchedEffect(Unit) {
71-
fetchMembers(roomMembers)
86+
LaunchedEffect(room.isSuccess()) {
87+
room.dataOrNull()?.let {
88+
fetchMembers(it, roomMembers)
89+
}
7290
}
7391
LaunchedEffect(searchQuery, roomMembers) {
7492
performSearch(
@@ -96,7 +114,9 @@ class DefaultInvitePeoplePresenter @AssistedInject constructor(
96114
searchResults.toggleUser(event.user)
97115
}
98116
is InvitePeopleEvents.SendInvites -> {
99-
sessionCoroutineScope.sendInvites(selectedUsers.value)
117+
room.dataOrNull()?.let {
118+
sessionCoroutineScope.sendInvites(it, selectedUsers.value)
119+
}
100120
}
101121
is InvitePeopleEvents.CloseSearch -> {
102122
searchActive = false
@@ -106,6 +126,7 @@ class DefaultInvitePeoplePresenter @AssistedInject constructor(
106126
}
107127

108128
return DefaultInvitePeopleState(
129+
room = room.map { },
109130
canInvite = selectedUsers.value.isNotEmpty(),
110131
selectedUsers = selectedUsers.value,
111132
searchQuery = searchQuery,
@@ -116,7 +137,10 @@ class DefaultInvitePeoplePresenter @AssistedInject constructor(
116137
)
117138
}
118139

119-
private fun CoroutineScope.sendInvites(selectedUsers: List<MatrixUser>) = launch {
140+
private fun CoroutineScope.sendInvites(
141+
room: JoinedRoom,
142+
selectedUsers: List<MatrixUser>,
143+
) = launch {
120144
val anyInviteFailed = selectedUsers
121145
.map { room.inviteUserById(it.userId) }
122146
.any { it.isFailure }
@@ -186,7 +210,10 @@ class DefaultInvitePeoplePresenter @AssistedInject constructor(
186210
}.launchIn(this)
187211
}
188212

189-
private suspend fun fetchMembers(roomMembers: MutableState<AsyncData<ImmutableList<RoomMember>>>) {
213+
private suspend fun fetchMembers(
214+
room: JoinedRoom,
215+
roomMembers: MutableState<AsyncData<ImmutableList<RoomMember>>>
216+
) {
190217
suspend {
191218
room.filterMembers("", coroutineDispatchers.io).toImmutableList()
192219
}.runCatchingUpdatingState(roomMembers)

features/invitepeople/impl/src/main/kotlin/io/element/android/features/invitepeople/impl/DefaultInvitePeopleState.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,13 @@ package io.element.android.features.invitepeople.impl
99

1010
import io.element.android.features.invitepeople.api.InvitePeopleEvents
1111
import io.element.android.features.invitepeople.api.InvitePeopleState
12+
import io.element.android.libraries.architecture.AsyncData
1213
import io.element.android.libraries.designsystem.theme.components.SearchBarResultState
1314
import io.element.android.libraries.matrix.api.user.MatrixUser
1415
import kotlinx.collections.immutable.ImmutableList
1516

1617
data class DefaultInvitePeopleState(
18+
val room: AsyncData<Unit>,
1719
override val canInvite: Boolean,
1820
val searchQuery: String,
1921
val showSearchLoader: Boolean,

features/invitepeople/impl/src/main/kotlin/io/element/android/features/invitepeople/impl/DefaultInvitePeopleStateProvider.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
package io.element.android.features.invitepeople.impl
99

1010
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
11+
import io.element.android.libraries.architecture.AsyncData
1112
import io.element.android.libraries.designsystem.theme.components.SearchBarResultState
1213
import io.element.android.libraries.matrix.api.user.MatrixUser
1314
import io.element.android.libraries.matrix.ui.components.aMatrixUser
@@ -66,6 +67,7 @@ internal class DefaultInvitePeopleStateProvider : PreviewParameterProvider<Defau
6667
),
6768
showSearchLoader = true,
6869
),
70+
aDefaultInvitePeopleState(room = AsyncData.Failure(Exception("Room not found"))),
6971
)
7072
}
7173

@@ -84,6 +86,7 @@ private fun anInvitableUser(
8486
)
8587

8688
private fun aDefaultInvitePeopleState(
89+
room: AsyncData<Unit> = AsyncData.Success(Unit),
8790
canInvite: Boolean = false,
8891
searchQuery: String = "",
8992
searchResults: SearchBarResultState<ImmutableList<InvitableUser>> = SearchBarResultState.Initial(),
@@ -92,6 +95,7 @@ private fun aDefaultInvitePeopleState(
9295
showSearchLoader: Boolean = false,
9396
): DefaultInvitePeopleState {
9497
return DefaultInvitePeopleState(
98+
room = room,
9599
canInvite = canInvite,
96100
searchQuery = searchQuery,
97101
searchResults = searchResults,

features/invitepeople/impl/src/main/kotlin/io/element/android/features/invitepeople/impl/InvitePeopleView.kt

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,24 @@
88
package io.element.android.features.invitepeople.impl
99

1010
import androidx.compose.foundation.layout.Arrangement
11+
import androidx.compose.foundation.layout.Box
1112
import androidx.compose.foundation.layout.Column
1213
import androidx.compose.foundation.layout.PaddingValues
14+
import androidx.compose.foundation.layout.fillMaxSize
1315
import androidx.compose.foundation.layout.fillMaxWidth
1416
import androidx.compose.foundation.layout.padding
1517
import androidx.compose.foundation.lazy.LazyColumn
1618
import androidx.compose.foundation.lazy.itemsIndexed
1719
import androidx.compose.material3.ExperimentalMaterial3Api
1820
import androidx.compose.runtime.Composable
21+
import androidx.compose.ui.Alignment
1922
import androidx.compose.ui.Modifier
2023
import androidx.compose.ui.res.stringResource
2124
import androidx.compose.ui.tooling.preview.PreviewParameter
2225
import androidx.compose.ui.unit.dp
2326
import io.element.android.compound.theme.ElementTheme
27+
import io.element.android.libraries.architecture.AsyncData
28+
import io.element.android.libraries.designsystem.components.async.AsyncFailure
2429
import io.element.android.libraries.designsystem.components.async.AsyncLoading
2530
import io.element.android.libraries.designsystem.components.avatar.AvatarSize
2631
import io.element.android.libraries.designsystem.preview.ElementPreview
@@ -42,9 +47,39 @@ import kotlinx.collections.immutable.ImmutableList
4247
fun InvitePeopleView(
4348
state: DefaultInvitePeopleState,
4449
modifier: Modifier = Modifier,
50+
) {
51+
when (state.room) {
52+
is AsyncData.Failure -> InvitePeopleViewError(state.room.error, modifier)
53+
AsyncData.Uninitialized,
54+
is AsyncData.Loading,
55+
is AsyncData.Success -> InvitePeopleContentView(state, modifier)
56+
}
57+
}
58+
59+
@Composable
60+
private fun InvitePeopleViewError(
61+
error: Throwable,
62+
modifier: Modifier = Modifier,
63+
) {
64+
Box(
65+
modifier = modifier.fillMaxSize(),
66+
contentAlignment = Alignment.Center,
67+
) {
68+
AsyncFailure(
69+
throwable = error,
70+
onRetry = null,
71+
modifier = Modifier.padding(horizontal = 16.dp),
72+
)
73+
}
74+
}
75+
76+
@Composable
77+
private fun InvitePeopleContentView(
78+
state: DefaultInvitePeopleState,
79+
modifier: Modifier = Modifier,
4580
) {
4681
Column(
47-
modifier = modifier.fillMaxWidth(),
82+
modifier = modifier.fillMaxSize(),
4883
verticalArrangement = Arrangement.spacedBy(16.dp),
4984
) {
5085
InvitePeopleSearchBar(

0 commit comments

Comments
 (0)