Refine handleSnackbarMessage API (#676)

As per our offline convos during a PR review.
This commit is contained in:
Marco Romano 2023-06-26 16:29:50 +02:00 committed by GitHub
parent 52fd72d24b
commit ffc9d1e82e
4 changed files with 17 additions and 14 deletions

View file

@ -58,7 +58,7 @@ import io.element.android.libraries.designsystem.components.avatar.AvatarData
import io.element.android.libraries.designsystem.components.avatar.AvatarSize import io.element.android.libraries.designsystem.components.avatar.AvatarSize
import io.element.android.libraries.designsystem.utils.SnackbarDispatcher import io.element.android.libraries.designsystem.utils.SnackbarDispatcher
import io.element.android.libraries.designsystem.utils.SnackbarMessage import io.element.android.libraries.designsystem.utils.SnackbarMessage
import io.element.android.libraries.designsystem.utils.handleSnackbarMessage import io.element.android.libraries.designsystem.utils.collectSnackbarMessageAsState
import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.core.EventId
import io.element.android.libraries.matrix.api.room.MatrixRoom import io.element.android.libraries.matrix.api.room.MatrixRoom
import io.element.android.libraries.matrix.api.room.MessageEventType import io.element.android.libraries.matrix.api.room.MessageEventType
@ -110,7 +110,7 @@ class MessagesPresenter @AssistedInject constructor(
val networkConnectionStatus by networkMonitor.connectivity.collectAsState(initial = networkMonitor.currentConnectivityStatus) val networkConnectionStatus by networkMonitor.connectivity.collectAsState(initial = networkMonitor.currentConnectivityStatus)
val snackbarMessage = handleSnackbarMessage(snackbarDispatcher) val snackbarMessage by snackbarDispatcher.collectSnackbarMessageAsState()
LaunchedEffect(syncUpdateFlow) { LaunchedEffect(syncUpdateFlow) {
roomAvatar.value = roomAvatar.value =

View file

@ -35,7 +35,7 @@ import io.element.android.libraries.architecture.Async
import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.architecture.Presenter
import io.element.android.libraries.designsystem.utils.SnackbarDispatcher import io.element.android.libraries.designsystem.utils.SnackbarDispatcher
import io.element.android.libraries.designsystem.utils.SnackbarMessage import io.element.android.libraries.designsystem.utils.SnackbarMessage
import io.element.android.libraries.designsystem.utils.handleSnackbarMessage import io.element.android.libraries.designsystem.utils.collectSnackbarMessageAsState
import io.element.android.libraries.matrix.api.media.MatrixMediaLoader import io.element.android.libraries.matrix.api.media.MatrixMediaLoader
import io.element.android.libraries.matrix.api.media.MediaFile import io.element.android.libraries.matrix.api.media.MediaFile
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
@ -66,7 +66,7 @@ class MediaViewerPresenter @AssistedInject constructor(
val localMedia: MutableState<Async<LocalMedia>> = remember { val localMedia: MutableState<Async<LocalMedia>> = remember {
mutableStateOf(Async.Uninitialized) mutableStateOf(Async.Uninitialized)
} }
val snackbarMessage = handleSnackbarMessage(snackbarDispatcher) val snackbarMessage by snackbarDispatcher.collectSnackbarMessageAsState()
localMediaActions.Configure() localMediaActions.Configure()
DisposableEffect(loadMediaTrigger) { DisposableEffect(loadMediaTrigger) {
coroutineScope.downloadMedia(mediaFile, localMedia) coroutineScope.downloadMedia(mediaFile, localMedia)

View file

@ -38,7 +38,7 @@ import io.element.android.libraries.core.extensions.orEmpty
import io.element.android.libraries.dateformatter.api.LastMessageTimestampFormatter 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.AvatarData
import io.element.android.libraries.designsystem.utils.SnackbarDispatcher import io.element.android.libraries.designsystem.utils.SnackbarDispatcher
import io.element.android.libraries.designsystem.utils.handleSnackbarMessage import io.element.android.libraries.designsystem.utils.collectSnackbarMessageAsState
import io.element.android.libraries.eventformatter.api.RoomLastMessageFormatter import io.element.android.libraries.eventformatter.api.RoomLastMessageFormatter
import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.MatrixClient
import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.RoomId
@ -135,7 +135,7 @@ class RoomListPresenter @Inject constructor(
filteredRoomSummaries.value = updateFilteredRoomSummaries(mappedRoomSummaries.value, filter) filteredRoomSummaries.value = updateFilteredRoomSummaries(mappedRoomSummaries.value, filter)
} }
val snackbarMessage = handleSnackbarMessage(snackbarDispatcher) val snackbarMessage by snackbarDispatcher.collectSnackbarMessageAsState()
return RoomListState( return RoomListState(
matrixUser = matrixUser.value, matrixUser = matrixUser.value,

View file

@ -21,6 +21,7 @@ import androidx.compose.material3.SnackbarDuration
import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.SnackbarHostState
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.State
import androidx.compose.runtime.collectAsState import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.compositionLocalOf import androidx.compose.runtime.compositionLocalOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
@ -28,27 +29,31 @@ import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update import kotlinx.coroutines.flow.update
import kotlinx.coroutines.isActive import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock import kotlinx.coroutines.sync.withLock
/**
* A global dispatcher of [SnackbarMessage] to be displayed in [Snackbar] via a [SnackbarHostState].
*/
class SnackbarDispatcher { class SnackbarDispatcher {
private val mutex = Mutex() private val mutex = Mutex()
private val snackbarState = MutableStateFlow<SnackbarMessage?>(null) private val _snackbarMessage = MutableStateFlow<SnackbarMessage?>(null)
val snackbarMessage: Flow<SnackbarMessage?> = snackbarState val snackbarMessage: Flow<SnackbarMessage?> = _snackbarMessage.asStateFlow()
suspend fun post(message: SnackbarMessage) { suspend fun post(message: SnackbarMessage) {
mutex.withLock { mutex.withLock {
snackbarState.update { message } _snackbarMessage.update { message }
} }
} }
suspend fun clear() { suspend fun clear() {
mutex.withLock { mutex.withLock {
snackbarState.update { null } _snackbarMessage.update { null }
} }
} }
} }
@ -59,10 +64,8 @@ val LocalSnackbarDispatcher = compositionLocalOf<SnackbarDispatcher> {
} }
@Composable @Composable
fun handleSnackbarMessage( fun SnackbarDispatcher.collectSnackbarMessageAsState(): State<SnackbarMessage?> {
snackbarDispatcher: SnackbarDispatcher return snackbarMessage.collectAsState(initial = null)
): SnackbarMessage? {
return snackbarDispatcher.snackbarMessage.collectAsState(initial = null).value
} }
@Composable @Composable