[Message Actions] Report messages (#642)

* Add report messages feature

* Try to improve how snackbars are delivered

---------

Co-authored-by: ElementBot <benoitm+elementbot@element.io>
This commit is contained in:
Jorge Martin Espinosa 2023-06-23 10:44:47 +02:00 committed by GitHub
parent e1bb5684cd
commit 9251cbf536
36 changed files with 739 additions and 40 deletions

View file

@ -22,13 +22,14 @@ import androidx.compose.material3.SnackbarHostState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.compositionLocalOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.res.stringResource
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
@ -52,19 +53,16 @@ class SnackbarDispatcher {
}
}
/** Used to provide a [SnackbarDispatcher] to composable functions, it's needed for [rememberSnackbarHostState]. */
val LocalSnackbarDispatcher = compositionLocalOf<SnackbarDispatcher> {
error("No SnackbarDispatcher provided")
}
@Composable
fun handleSnackbarMessage(
snackbarDispatcher: SnackbarDispatcher
): SnackbarMessage? {
val snackbarMessage by snackbarDispatcher.snackbarMessage.collectAsState(initial = null)
LaunchedEffect(snackbarMessage) {
if (snackbarMessage != null) {
launch {
snackbarDispatcher.clear()
}
}
}
return snackbarMessage
return snackbarDispatcher.snackbarMessage.collectAsState(initial = null).value
}
@Composable
@ -74,6 +72,7 @@ fun rememberSnackbarHostState(snackbarMessage: SnackbarMessage?): SnackbarHostSt
val snackbarMessageText = snackbarMessage?.let {
stringResource(id = snackbarMessage.messageResId)
}
val dispatcher = LocalSnackbarDispatcher.current
LaunchedEffect(snackbarMessage) {
if (snackbarMessageText == null) return@LaunchedEffect
coroutineScope.launch {
@ -81,6 +80,9 @@ fun rememberSnackbarHostState(snackbarMessage: SnackbarMessage?): SnackbarHostSt
message = snackbarMessageText,
duration = snackbarMessage.duration,
)
if (isActive) {
dispatcher.clear()
}
}
}
return snackbarHostState

View file

@ -112,4 +112,6 @@ interface MatrixRoom : Closeable {
suspend fun setName(name: String): Result<Unit>
suspend fun setTopic(topic: String): Result<Unit>
suspend fun reportContent(eventId: EventId, reason: String, blockUserId: UserId?): Result<Unit>
}

View file

@ -329,4 +329,13 @@ class RustMatrixRoom(
innerRoom.setTopic(topic)
}
}
override suspend fun reportContent(eventId: EventId, reason: String, blockUserId: UserId?): Result<Unit> = withContext(coroutineDispatchers.io) {
runCatching {
innerRoom.reportContent(eventId = eventId.value, score = null, reason = reason)
if (blockUserId != null) {
innerRoom.ignoreUser(blockUserId.value)
}
}
}
}

View file

@ -76,6 +76,7 @@ class FakeMatrixRoom(
private var retrySendMessageResult = Result.success(Unit)
private var cancelSendResult = Result.success(Unit)
private var forwardEventResult = Result.success(Unit)
private var reportContentResult = Result.success(Unit)
var sendMediaCount = 0
private set
@ -89,6 +90,9 @@ class FakeMatrixRoom(
var cancelSendCount: Int = 0
private set
var reportedContentCount: Int = 0
private set
var isInviteAccepted: Boolean = false
private set
@ -249,6 +253,15 @@ class FakeMatrixRoom(
setTopicResult
}
override suspend fun reportContent(
eventId: EventId,
reason: String,
blockUserId: UserId?
): Result<Unit> = simulateLongTask {
reportedContentCount++
return reportContentResult
}
override fun close() = Unit
fun givenLeaveRoomError(throwable: Throwable?) {
@ -338,4 +351,8 @@ class FakeMatrixRoom(
fun givenForwardEventResult(result: Result<Unit>) {
forwardEventResult = result
}
fun givenReportContentResult(result: Result<Unit>) {
reportContentResult = result
}
}