[Room Details] Leave room (#296)
* Add leave room functionality to the Room Details screen * Add snackbar message throught `SnackbarDistpacher`
This commit is contained in:
parent
5fdf16772f
commit
9064481b4c
32 changed files with 564 additions and 71 deletions
|
|
@ -20,5 +20,4 @@ sealed interface RoomListEvents {
|
|||
data class UpdateFilter(val newFilter: String) : RoomListEvents
|
||||
data class UpdateVisibleRange(val range: IntRange) : RoomListEvents
|
||||
object DismissRequestVerificationPrompt : RoomListEvents
|
||||
object ClearSuccessfulVerificationMessage : RoomListEvents
|
||||
}
|
||||
|
|
|
|||
|
|
@ -34,12 +34,14 @@ import io.element.android.libraries.core.extensions.orEmpty
|
|||
import io.element.android.libraries.dateformatter.api.LastMessageTimestampFormatter
|
||||
import io.element.android.libraries.designsystem.components.avatar.AvatarData
|
||||
import io.element.android.libraries.designsystem.components.avatar.AvatarSize
|
||||
import io.element.android.libraries.designsystem.utils.SnackbarDispatcher
|
||||
import io.element.android.libraries.designsystem.utils.handleSnackbarMessage
|
||||
import io.element.android.libraries.matrix.api.MatrixClient
|
||||
import io.element.android.libraries.matrix.api.core.UserId
|
||||
import io.element.android.libraries.matrix.api.room.RoomMembershipObserver
|
||||
import io.element.android.libraries.matrix.api.room.RoomSummary
|
||||
import io.element.android.libraries.matrix.api.verification.SessionVerificationService
|
||||
import io.element.android.libraries.matrix.api.verification.SessionVerifiedStatus
|
||||
import io.element.android.libraries.matrix.api.verification.VerificationFlowState
|
||||
import io.element.android.libraries.matrix.ui.model.MatrixUser
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
|
@ -56,8 +58,11 @@ class RoomListPresenter @Inject constructor(
|
|||
private val lastMessageTimestampFormatter: LastMessageTimestampFormatter,
|
||||
private val roomLastMessageFormatter: RoomLastMessageFormatter,
|
||||
private val sessionVerificationService: SessionVerificationService,
|
||||
private val snackbarDispatcher: SnackbarDispatcher,
|
||||
) : Presenter<RoomListState> {
|
||||
|
||||
private val roomMembershipObserver: RoomMembershipObserver = client.roomMembershipObserver()
|
||||
|
||||
@Composable
|
||||
override fun present(): RoomListState {
|
||||
val matrixUser: MutableState<MatrixUser?> = remember {
|
||||
|
|
@ -86,19 +91,11 @@ class RoomListPresenter @Inject constructor(
|
|||
derivedStateOf { sessionVerifiedStatus == SessionVerifiedStatus.NotVerified && !verificationPromptDismissed }
|
||||
}
|
||||
|
||||
// Current verification flow status, if any (initial, requesting, accepted, etc.)
|
||||
val currentVerificationFlowStatus by sessionVerificationService.verificationFlowState.collectAsState()
|
||||
// We only care about the 'Finished' state to display the 'verification success' message
|
||||
val presentVerificationSuccessfulMessage = remember {
|
||||
derivedStateOf { currentVerificationFlowStatus == VerificationFlowState.Finished }
|
||||
}
|
||||
|
||||
fun handleEvents(event: RoomListEvents) {
|
||||
when (event) {
|
||||
is RoomListEvents.UpdateFilter -> filter = event.newFilter
|
||||
is RoomListEvents.UpdateVisibleRange -> updateVisibleRange(event.range)
|
||||
RoomListEvents.DismissRequestVerificationPrompt -> verificationPromptDismissed = true
|
||||
RoomListEvents.ClearSuccessfulVerificationMessage -> sessionVerificationService.reset()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -106,12 +103,14 @@ class RoomListPresenter @Inject constructor(
|
|||
filteredRoomSummaries.value = updateFilteredRoomSummaries(roomSummaries, filter)
|
||||
}
|
||||
|
||||
val snackbarMessage = handleSnackbarMessage(snackbarDispatcher)
|
||||
|
||||
return RoomListState(
|
||||
matrixUser = matrixUser.value,
|
||||
roomList = filteredRoomSummaries.value,
|
||||
filter = filter,
|
||||
presentVerificationSuccessfulMessage = presentVerificationSuccessfulMessage.value,
|
||||
displayVerificationPrompt = displayVerificationPrompt,
|
||||
snackbarMessage = snackbarMessage,
|
||||
eventSink = ::handleEvents
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package io.element.android.features.roomlist.impl
|
|||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import io.element.android.features.roomlist.impl.model.RoomListRoomSummary
|
||||
import io.element.android.libraries.designsystem.utils.SnackbarMessage
|
||||
import io.element.android.libraries.matrix.ui.model.MatrixUser
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
|
||||
|
|
@ -26,7 +27,7 @@ data class RoomListState(
|
|||
val matrixUser: MatrixUser?,
|
||||
val roomList: ImmutableList<RoomListRoomSummary>,
|
||||
val filter: String,
|
||||
val presentVerificationSuccessfulMessage: Boolean,
|
||||
val displayVerificationPrompt: Boolean,
|
||||
val snackbarMessage: SnackbarMessage?,
|
||||
val eventSink: (RoomListEvents) -> Unit
|
||||
)
|
||||
|
|
|
|||
|
|
@ -20,17 +20,19 @@ import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
|||
import io.element.android.features.roomlist.impl.model.RoomListRoomSummary
|
||||
import io.element.android.features.roomlist.impl.model.RoomListRoomSummaryPlaceholders
|
||||
import io.element.android.libraries.designsystem.components.avatar.AvatarData
|
||||
import io.element.android.libraries.designsystem.utils.SnackbarMessage
|
||||
import io.element.android.libraries.matrix.api.core.UserId
|
||||
import io.element.android.libraries.matrix.ui.model.MatrixUser
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import io.element.android.libraries.ui.strings.R as StringR
|
||||
|
||||
open class RoomListStateProvider : PreviewParameterProvider<RoomListState> {
|
||||
override val values: Sequence<RoomListState>
|
||||
get() = sequenceOf(
|
||||
aRoomListState(),
|
||||
aRoomListState().copy(displayVerificationPrompt = true),
|
||||
aRoomListState().copy(presentVerificationSuccessfulMessage = true),
|
||||
aRoomListState().copy(snackbarMessage = SnackbarMessage(StringR.string.common_verification_complete)),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -39,7 +41,7 @@ internal fun aRoomListState() = RoomListState(
|
|||
roomList = aRoomListRoomSummaryList(),
|
||||
filter = "filter",
|
||||
eventSink = {},
|
||||
presentVerificationSuccessfulMessage = false,
|
||||
snackbarMessage = null,
|
||||
displayVerificationPrompt = false,
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -40,10 +40,11 @@ import androidx.compose.material3.SnackbarHostState
|
|||
import androidx.compose.material3.TopAppBarDefaults
|
||||
import androidx.compose.material3.rememberTopAppBarState
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.SideEffect
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.input.nestedscroll.NestedScrollConnection
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
|
|
@ -67,6 +68,7 @@ import io.element.android.libraries.designsystem.theme.components.Surface
|
|||
import io.element.android.libraries.designsystem.theme.components.Text
|
||||
import io.element.android.libraries.designsystem.utils.LogCompositions
|
||||
import io.element.android.libraries.matrix.api.core.RoomId
|
||||
import kotlinx.coroutines.launch
|
||||
import io.element.android.libraries.designsystem.R as DrawableR
|
||||
import io.element.android.libraries.ui.strings.R as StringR
|
||||
|
||||
|
|
@ -130,14 +132,18 @@ fun RoomListContent(
|
|||
}
|
||||
|
||||
val snackbarHostState = remember { SnackbarHostState() }
|
||||
val verificationCompleteMessage = stringResource(StringR.string.common_verification_complete)
|
||||
LaunchedEffect(state.presentVerificationSuccessfulMessage) {
|
||||
if (state.presentVerificationSuccessfulMessage) {
|
||||
snackbarHostState.showSnackbar(
|
||||
message = verificationCompleteMessage,
|
||||
duration = SnackbarDuration.Short,
|
||||
)
|
||||
state.eventSink(RoomListEvents.ClearSuccessfulVerificationMessage)
|
||||
val snackbarMessageText = if (state.snackbarMessage != null ) {
|
||||
stringResource(state.snackbarMessage.messageResId)
|
||||
} else null
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
if (snackbarMessageText != null) {
|
||||
SideEffect {
|
||||
coroutineScope.launch {
|
||||
snackbarHostState.showSnackbar(
|
||||
message = snackbarMessageText,
|
||||
duration = SnackbarDuration.Short,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue