Fix API break: use new methods canUserRedactOwn and canUserRedactOther.
This commit is contained in:
parent
ce7d77059c
commit
f844399025
13 changed files with 286 additions and 49 deletions
|
|
@ -84,7 +84,8 @@ import io.element.android.libraries.matrix.api.room.MessageEventType
|
|||
import io.element.android.libraries.matrix.api.user.CurrentSessionIdHolder
|
||||
import io.element.android.libraries.matrix.ui.components.AttachmentThumbnailInfo
|
||||
import io.element.android.libraries.matrix.ui.components.AttachmentThumbnailType
|
||||
import io.element.android.libraries.matrix.ui.room.canRedactAsState
|
||||
import io.element.android.libraries.matrix.ui.room.canRedactOtherAsState
|
||||
import io.element.android.libraries.matrix.ui.room.canRedactOwnAsState
|
||||
import io.element.android.libraries.matrix.ui.room.canSendMessageAsState
|
||||
import io.element.android.libraries.textcomposer.model.MessageComposerMode
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
|
|
@ -138,7 +139,8 @@ class MessagesPresenter @AssistedInject constructor(
|
|||
|
||||
val syncUpdateFlow = room.syncUpdateFlow.collectAsState()
|
||||
val userHasPermissionToSendMessage by room.canSendMessageAsState(type = MessageEventType.ROOM_MESSAGE, updateKey = syncUpdateFlow.value)
|
||||
val userHasPermissionToRedact by room.canRedactAsState(updateKey = syncUpdateFlow.value)
|
||||
val userHasPermissionToRedactOwn by room.canRedactOwnAsState(updateKey = syncUpdateFlow.value)
|
||||
val userHasPermissionToRedactOther by room.canRedactOtherAsState(updateKey = syncUpdateFlow.value)
|
||||
val userHasPermissionToSendReaction by room.canSendMessageAsState(type = MessageEventType.REACTION_SENT, updateKey = syncUpdateFlow.value)
|
||||
val roomName: AsyncData<String> by remember {
|
||||
derivedStateOf { roomInfo?.name?.let { AsyncData.Success(it) } ?: AsyncData.Uninitialized }
|
||||
|
|
@ -219,7 +221,8 @@ class MessagesPresenter @AssistedInject constructor(
|
|||
roomName = roomName,
|
||||
roomAvatar = roomAvatar,
|
||||
userHasPermissionToSendMessage = userHasPermissionToSendMessage,
|
||||
userHasPermissionToRedact = userHasPermissionToRedact,
|
||||
userHasPermissionToRedactOwn = userHasPermissionToRedactOwn,
|
||||
userHasPermissionToRedactOther = userHasPermissionToRedactOther,
|
||||
userHasPermissionToSendReaction = userHasPermissionToSendReaction,
|
||||
composerState = composerState,
|
||||
voiceMessageComposerState = voiceMessageComposerState,
|
||||
|
|
|
|||
|
|
@ -36,7 +36,8 @@ data class MessagesState(
|
|||
val roomName: AsyncData<String>,
|
||||
val roomAvatar: AsyncData<AvatarData>,
|
||||
val userHasPermissionToSendMessage: Boolean,
|
||||
val userHasPermissionToRedact: Boolean,
|
||||
val userHasPermissionToRedactOwn: Boolean,
|
||||
val userHasPermissionToRedactOther: Boolean,
|
||||
val userHasPermissionToSendReaction: Boolean,
|
||||
val composerState: MessageComposerState,
|
||||
val voiceMessageComposerState: VoiceMessageComposerState,
|
||||
|
|
|
|||
|
|
@ -86,7 +86,8 @@ fun aMessagesState() = MessagesState(
|
|||
roomName = AsyncData.Success("Room name"),
|
||||
roomAvatar = AsyncData.Success(AvatarData("!id:domain", "Room name", size = AvatarSize.TimelineRoom)),
|
||||
userHasPermissionToSendMessage = true,
|
||||
userHasPermissionToRedact = false,
|
||||
userHasPermissionToRedactOwn = false,
|
||||
userHasPermissionToRedactOther = false,
|
||||
userHasPermissionToSendReaction = true,
|
||||
composerState = aMessageComposerState().copy(
|
||||
richTextEditorState = RichTextEditorState("Hello", initialFocus = true),
|
||||
|
|
|
|||
|
|
@ -160,7 +160,8 @@ fun MessagesView(
|
|||
state.actionListState.eventSink(
|
||||
ActionListEvents.ComputeForMessage(
|
||||
event = event,
|
||||
canRedact = state.userHasPermissionToRedact,
|
||||
canRedactOwn = state.userHasPermissionToRedactOwn,
|
||||
canRedactOther = state.userHasPermissionToRedactOther,
|
||||
canSendMessage = state.userHasPermissionToSendMessage,
|
||||
canSendReaction = state.userHasPermissionToSendReaction,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -22,7 +22,8 @@ sealed interface ActionListEvents {
|
|||
data object Clear : ActionListEvents
|
||||
data class ComputeForMessage(
|
||||
val event: TimelineItem.Event,
|
||||
val canRedact: Boolean,
|
||||
val canRedactOwn: Boolean,
|
||||
val canRedactOther: Boolean,
|
||||
val canSendMessage: Boolean,
|
||||
val canSendReaction: Boolean,
|
||||
) : ActionListEvents
|
||||
|
|
|
|||
|
|
@ -56,7 +56,8 @@ class ActionListPresenter @Inject constructor(
|
|||
ActionListEvents.Clear -> target.value = ActionListState.Target.None
|
||||
is ActionListEvents.ComputeForMessage -> localCoroutineScope.computeForMessage(
|
||||
timelineItem = event.event,
|
||||
userCanRedact = event.canRedact,
|
||||
userCanRedactOwn = event.canRedactOwn,
|
||||
userCanRedactOther = event.canRedactOther,
|
||||
userCanSendMessage = event.canSendMessage,
|
||||
userCanSendReaction = event.canSendReaction,
|
||||
isDeveloperModeEnabled = isDeveloperModeEnabled,
|
||||
|
|
@ -73,13 +74,16 @@ class ActionListPresenter @Inject constructor(
|
|||
|
||||
private fun CoroutineScope.computeForMessage(
|
||||
timelineItem: TimelineItem.Event,
|
||||
userCanRedact: Boolean,
|
||||
userCanRedactOwn: Boolean,
|
||||
userCanRedactOther: Boolean,
|
||||
userCanSendMessage: Boolean,
|
||||
userCanSendReaction: Boolean,
|
||||
isDeveloperModeEnabled: Boolean,
|
||||
target: MutableState<ActionListState.Target>
|
||||
) = launch {
|
||||
target.value = ActionListState.Target.Loading(timelineItem)
|
||||
val canRedact = (timelineItem.isMine && userCanRedactOwn) ||
|
||||
(!timelineItem.isMine && userCanRedactOther)
|
||||
val actions =
|
||||
when (timelineItem.content) {
|
||||
is TimelineItemRedactedContent -> {
|
||||
|
|
@ -99,7 +103,6 @@ class ActionListPresenter @Inject constructor(
|
|||
}
|
||||
is TimelineItemPollContent -> {
|
||||
buildList {
|
||||
val isMineOrCanRedact = timelineItem.isMine || userCanRedact
|
||||
if (timelineItem.isRemote) {
|
||||
// Can only reply or forward messages already uploaded to the server
|
||||
add(TimelineItemAction.Reply)
|
||||
|
|
@ -107,7 +110,7 @@ class ActionListPresenter @Inject constructor(
|
|||
if (timelineItem.isRemote && timelineItem.isEditable) {
|
||||
add(TimelineItemAction.Edit)
|
||||
}
|
||||
if (timelineItem.isRemote && !timelineItem.content.isEnded && isMineOrCanRedact) {
|
||||
if (timelineItem.isRemote && !timelineItem.content.isEnded && (timelineItem.isMine || canRedact)) {
|
||||
add(TimelineItemAction.EndPoll)
|
||||
}
|
||||
if (timelineItem.content.canBeCopied()) {
|
||||
|
|
@ -119,7 +122,7 @@ class ActionListPresenter @Inject constructor(
|
|||
if (!timelineItem.isMine) {
|
||||
add(TimelineItemAction.ReportContent)
|
||||
}
|
||||
if (isMineOrCanRedact) {
|
||||
if (canRedact) {
|
||||
add(TimelineItemAction.Redact)
|
||||
}
|
||||
}
|
||||
|
|
@ -136,7 +139,7 @@ class ActionListPresenter @Inject constructor(
|
|||
if (!timelineItem.isMine) {
|
||||
add(TimelineItemAction.ReportContent)
|
||||
}
|
||||
if (timelineItem.isMine || userCanRedact) {
|
||||
if (canRedact) {
|
||||
add(TimelineItemAction.Redact)
|
||||
}
|
||||
}
|
||||
|
|
@ -169,7 +172,7 @@ class ActionListPresenter @Inject constructor(
|
|||
if (!timelineItem.isMine) {
|
||||
add(TimelineItemAction.ReportContent)
|
||||
}
|
||||
if (timelineItem.isMine || userCanRedact) {
|
||||
if (canRedact) {
|
||||
add(TimelineItemAction.Redact)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ class MessagesPresenterTest {
|
|||
assertThat(initialState.roomAvatar)
|
||||
.isEqualTo(AsyncData.Success(AvatarData(id = A_ROOM_ID.value, name = "", url = AN_AVATAR_URL, size = AvatarSize.TimelineRoom)))
|
||||
assertThat(initialState.userHasPermissionToSendMessage).isTrue()
|
||||
assertThat(initialState.userHasPermissionToRedact).isFalse()
|
||||
assertThat(initialState.userHasPermissionToRedactOwn).isFalse()
|
||||
assertThat(initialState.hasNetworkConnection).isTrue()
|
||||
assertThat(initialState.snackbarMessage).isNull()
|
||||
assertThat(initialState.inviteProgress).isEqualTo(AsyncData.Uninitialized)
|
||||
|
|
@ -601,14 +601,29 @@ class MessagesPresenterTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `present - permission to redact`() = runTest {
|
||||
val matrixRoom = FakeMatrixRoom(canRedact = true)
|
||||
fun `present - permission to redact own`() = runTest {
|
||||
val matrixRoom = FakeMatrixRoom(canRedactOwn = true)
|
||||
val presenter = createMessagesPresenter(matrixRoom = matrixRoom)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
val initialState = consumeItemsUntilPredicate { it.userHasPermissionToRedact }.last()
|
||||
assertThat(initialState.userHasPermissionToRedact).isTrue()
|
||||
val initialState = consumeItemsUntilPredicate { it.userHasPermissionToRedactOwn }.last()
|
||||
assertThat(initialState.userHasPermissionToRedactOwn).isTrue()
|
||||
assertThat(initialState.userHasPermissionToRedactOther).isFalse()
|
||||
cancelAndIgnoreRemainingEvents()
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `present - permission to redact other`() = runTest {
|
||||
val matrixRoom = FakeMatrixRoom(canRedactOther = true)
|
||||
val presenter = createMessagesPresenter(matrixRoom = matrixRoom)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
val initialState = consumeItemsUntilPredicate { it.userHasPermissionToRedactOther }.last()
|
||||
assertThat(initialState.userHasPermissionToRedactOwn).isFalse()
|
||||
assertThat(initialState.userHasPermissionToRedactOther).isTrue()
|
||||
cancelAndIgnoreRemainingEvents()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,7 +61,15 @@ class ActionListPresenterTest {
|
|||
}.test {
|
||||
val initialState = awaitItem()
|
||||
val messageEvent = aMessageEvent(isMine = true, content = TimelineItemRedactedContent)
|
||||
initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(messageEvent, canRedact = false, canSendMessage = true, canSendReaction = true))
|
||||
initialState.eventSink.invoke(
|
||||
ActionListEvents.ComputeForMessage(
|
||||
event = messageEvent,
|
||||
canRedactOwn = false,
|
||||
canRedactOther = false,
|
||||
canSendMessage = true,
|
||||
canSendReaction = true,
|
||||
)
|
||||
)
|
||||
// val loadingState = awaitItem()
|
||||
// assertThat(loadingState.target).isEqualTo(ActionListState.Target.Loading(messageEvent))
|
||||
val successState = awaitItem()
|
||||
|
|
@ -87,7 +95,15 @@ class ActionListPresenterTest {
|
|||
}.test {
|
||||
val initialState = awaitItem()
|
||||
val messageEvent = aMessageEvent(isMine = false, content = TimelineItemRedactedContent)
|
||||
initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(messageEvent, canRedact = false, canSendMessage = true, canSendReaction = true))
|
||||
initialState.eventSink.invoke(
|
||||
ActionListEvents.ComputeForMessage(
|
||||
event = messageEvent,
|
||||
canRedactOwn = false,
|
||||
canRedactOther = false,
|
||||
canSendMessage = true,
|
||||
canSendReaction = true,
|
||||
)
|
||||
)
|
||||
// val loadingState = awaitItem()
|
||||
// assertThat(loadingState.target).isEqualTo(ActionListState.Target.Loading(messageEvent))
|
||||
val successState = awaitItem()
|
||||
|
|
@ -116,7 +132,15 @@ class ActionListPresenterTest {
|
|||
isMine = false,
|
||||
content = TimelineItemTextContent(body = A_MESSAGE, htmlDocument = null, isEdited = false, formattedBody = null)
|
||||
)
|
||||
initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(messageEvent, canRedact = false, canSendMessage = true, canSendReaction = true))
|
||||
initialState.eventSink.invoke(
|
||||
ActionListEvents.ComputeForMessage(
|
||||
event = messageEvent,
|
||||
canRedactOwn = false,
|
||||
canRedactOther = false,
|
||||
canSendMessage = true,
|
||||
canSendReaction = true,
|
||||
)
|
||||
)
|
||||
// val loadingState = awaitItem()
|
||||
// assertThat(loadingState.target).isEqualTo(ActionListState.Target.Loading(messageEvent))
|
||||
val successState = awaitItem()
|
||||
|
|
@ -149,7 +173,15 @@ class ActionListPresenterTest {
|
|||
isMine = false,
|
||||
content = TimelineItemTextContent(body = A_MESSAGE, htmlDocument = null, isEdited = false, formattedBody = null)
|
||||
)
|
||||
initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(messageEvent, canRedact = false, canSendMessage = false, canSendReaction = true))
|
||||
initialState.eventSink.invoke(
|
||||
ActionListEvents.ComputeForMessage(
|
||||
event = messageEvent,
|
||||
canRedactOwn = true,
|
||||
canRedactOther = false,
|
||||
canSendMessage = false,
|
||||
canSendReaction = true
|
||||
)
|
||||
)
|
||||
// val loadingState = awaitItem()
|
||||
// assertThat(loadingState.target).isEqualTo(ActionListState.Target.Loading(messageEvent))
|
||||
val successState = awaitItem()
|
||||
|
|
@ -181,7 +213,15 @@ class ActionListPresenterTest {
|
|||
isMine = false,
|
||||
content = TimelineItemTextContent(body = A_MESSAGE, htmlDocument = null, isEdited = false, formattedBody = null)
|
||||
)
|
||||
initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(messageEvent, canRedact = true, canSendMessage = true, canSendReaction = true))
|
||||
initialState.eventSink.invoke(
|
||||
ActionListEvents.ComputeForMessage(
|
||||
event = messageEvent,
|
||||
canRedactOwn = false,
|
||||
canRedactOther = true,
|
||||
canSendMessage = true,
|
||||
canSendReaction = true,
|
||||
)
|
||||
)
|
||||
val successState = awaitItem()
|
||||
assertThat(successState.target).isEqualTo(
|
||||
ActionListState.Target.Success(
|
||||
|
|
@ -213,7 +253,15 @@ class ActionListPresenterTest {
|
|||
isMine = false,
|
||||
content = TimelineItemTextContent(body = A_MESSAGE, htmlDocument = null, isEdited = false, formattedBody = null)
|
||||
)
|
||||
initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(messageEvent, canRedact = true, canSendMessage = true, canSendReaction = false))
|
||||
initialState.eventSink.invoke(
|
||||
ActionListEvents.ComputeForMessage(
|
||||
event = messageEvent,
|
||||
canRedactOwn = false,
|
||||
canRedactOther = true,
|
||||
canSendMessage = true,
|
||||
canSendReaction = false
|
||||
)
|
||||
)
|
||||
val successState = awaitItem()
|
||||
assertThat(successState.target).isEqualTo(
|
||||
ActionListState.Target.Success(
|
||||
|
|
@ -245,7 +293,15 @@ class ActionListPresenterTest {
|
|||
isMine = true,
|
||||
content = TimelineItemTextContent(body = A_MESSAGE, htmlDocument = null, isEdited = false, formattedBody = null)
|
||||
)
|
||||
initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(messageEvent, canRedact = false, canSendMessage = true, canSendReaction = true))
|
||||
initialState.eventSink.invoke(
|
||||
ActionListEvents.ComputeForMessage(
|
||||
event = messageEvent,
|
||||
canRedactOwn = true,
|
||||
canRedactOther = false,
|
||||
canSendMessage = true,
|
||||
canSendReaction = true,
|
||||
)
|
||||
)
|
||||
// val loadingState = awaitItem()
|
||||
// assertThat(loadingState.target).isEqualTo(ActionListState.Target.Loading(messageEvent))
|
||||
val successState = awaitItem()
|
||||
|
|
@ -268,6 +324,47 @@ class ActionListPresenterTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `present - compute for my message cannot redact`() = runTest {
|
||||
val presenter = createActionListPresenter(isDeveloperModeEnabled = true)
|
||||
moleculeFlow(RecompositionMode.Immediate) {
|
||||
presenter.present()
|
||||
}.test {
|
||||
val initialState = awaitItem()
|
||||
val messageEvent = aMessageEvent(
|
||||
isMine = true,
|
||||
content = TimelineItemTextContent(body = A_MESSAGE, htmlDocument = null, isEdited = false, formattedBody = null)
|
||||
)
|
||||
initialState.eventSink.invoke(
|
||||
ActionListEvents.ComputeForMessage(
|
||||
event = messageEvent,
|
||||
canRedactOwn = false,
|
||||
canRedactOther = false,
|
||||
canSendMessage = true,
|
||||
canSendReaction = true,
|
||||
)
|
||||
)
|
||||
// val loadingState = awaitItem()
|
||||
// assertThat(loadingState.target).isEqualTo(ActionListState.Target.Loading(messageEvent))
|
||||
val successState = awaitItem()
|
||||
assertThat(successState.target).isEqualTo(
|
||||
ActionListState.Target.Success(
|
||||
event = messageEvent,
|
||||
displayEmojiReactions = true,
|
||||
actions = persistentListOf(
|
||||
TimelineItemAction.Reply,
|
||||
TimelineItemAction.Forward,
|
||||
TimelineItemAction.Edit,
|
||||
TimelineItemAction.Copy,
|
||||
TimelineItemAction.ViewSource,
|
||||
)
|
||||
)
|
||||
)
|
||||
initialState.eventSink.invoke(ActionListEvents.Clear)
|
||||
assertThat(awaitItem().target).isEqualTo(ActionListState.Target.None)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `present - compute for a media item`() = runTest {
|
||||
val presenter = createActionListPresenter(isDeveloperModeEnabled = true)
|
||||
|
|
@ -279,7 +376,15 @@ class ActionListPresenterTest {
|
|||
isMine = true,
|
||||
content = aTimelineItemImageContent(),
|
||||
)
|
||||
initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(messageEvent, canRedact = false, canSendMessage = true, canSendReaction = true))
|
||||
initialState.eventSink.invoke(
|
||||
ActionListEvents.ComputeForMessage(
|
||||
event = messageEvent,
|
||||
canRedactOwn = true,
|
||||
canRedactOther = false,
|
||||
canSendMessage = true,
|
||||
canSendReaction = true,
|
||||
)
|
||||
)
|
||||
// val loadingState = awaitItem()
|
||||
// assertThat(loadingState.target).isEqualTo(ActionListState.Target.Loading(messageEvent))
|
||||
val successState = awaitItem()
|
||||
|
|
@ -311,7 +416,15 @@ class ActionListPresenterTest {
|
|||
isMine = true,
|
||||
content = aTimelineItemStateEventContent(),
|
||||
)
|
||||
initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(stateEvent, canRedact = false, canSendMessage = true, canSendReaction = true))
|
||||
initialState.eventSink.invoke(
|
||||
ActionListEvents.ComputeForMessage(
|
||||
event = stateEvent,
|
||||
canRedactOwn = false,
|
||||
canRedactOther = false,
|
||||
canSendMessage = true,
|
||||
canSendReaction = true,
|
||||
)
|
||||
)
|
||||
// val loadingState = awaitItem()
|
||||
// assertThat(loadingState.target).isEqualTo(ActionListState.Target.Loading(messageEvent))
|
||||
val successState = awaitItem()
|
||||
|
|
@ -341,7 +454,15 @@ class ActionListPresenterTest {
|
|||
isMine = true,
|
||||
content = aTimelineItemStateEventContent(),
|
||||
)
|
||||
initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(stateEvent, canRedact = false, canSendMessage = true, canSendReaction = true))
|
||||
initialState.eventSink.invoke(
|
||||
ActionListEvents.ComputeForMessage(
|
||||
event = stateEvent,
|
||||
canRedactOwn = false,
|
||||
canRedactOther = false,
|
||||
canSendMessage = true,
|
||||
canSendReaction = true,
|
||||
)
|
||||
)
|
||||
// val loadingState = awaitItem()
|
||||
// assertThat(loadingState.target).isEqualTo(ActionListState.Target.Loading(messageEvent))
|
||||
val successState = awaitItem()
|
||||
|
|
@ -370,7 +491,15 @@ class ActionListPresenterTest {
|
|||
isMine = true,
|
||||
content = TimelineItemTextContent(body = A_MESSAGE, htmlDocument = null, isEdited = false, formattedBody = null)
|
||||
)
|
||||
initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(messageEvent, canRedact = false, canSendMessage = true, canSendReaction = true))
|
||||
initialState.eventSink.invoke(
|
||||
ActionListEvents.ComputeForMessage(
|
||||
event = messageEvent,
|
||||
canRedactOwn = true,
|
||||
canRedactOther = false,
|
||||
canSendMessage = true,
|
||||
canSendReaction = true,
|
||||
)
|
||||
)
|
||||
// val loadingState = awaitItem()
|
||||
// assertThat(loadingState.target).isEqualTo(ActionListState.Target.Loading(messageEvent))
|
||||
val successState = awaitItem()
|
||||
|
|
@ -408,10 +537,26 @@ class ActionListPresenterTest {
|
|||
content = TimelineItemRedactedContent,
|
||||
)
|
||||
|
||||
initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(messageEvent, canRedact = false, canSendMessage = true, canSendReaction = true))
|
||||
initialState.eventSink.invoke(
|
||||
ActionListEvents.ComputeForMessage(
|
||||
event = messageEvent,
|
||||
canRedactOwn = false,
|
||||
canRedactOther = false,
|
||||
canSendMessage = true,
|
||||
canSendReaction = true,
|
||||
)
|
||||
)
|
||||
assertThat(awaitItem().target).isInstanceOf(ActionListState.Target.Success::class.java)
|
||||
|
||||
initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(redactedEvent, canRedact = false, canSendMessage = true, canSendReaction = true))
|
||||
initialState.eventSink.invoke(
|
||||
ActionListEvents.ComputeForMessage(
|
||||
event = redactedEvent,
|
||||
canRedactOwn = false,
|
||||
canRedactOther = false,
|
||||
canSendMessage = true,
|
||||
canSendReaction = true,
|
||||
)
|
||||
)
|
||||
awaitItem().run {
|
||||
assertThat(target).isEqualTo(ActionListState.Target.None)
|
||||
}
|
||||
|
|
@ -432,7 +577,15 @@ class ActionListPresenterTest {
|
|||
content = TimelineItemTextContent(body = A_MESSAGE, htmlDocument = null, isEdited = false, formattedBody = null),
|
||||
)
|
||||
|
||||
initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(messageEvent, canRedact = false, canSendMessage = true, canSendReaction = true))
|
||||
initialState.eventSink.invoke(
|
||||
ActionListEvents.ComputeForMessage(
|
||||
event = messageEvent,
|
||||
canRedactOwn = true,
|
||||
canRedactOther = false,
|
||||
canSendMessage = true,
|
||||
canSendReaction = true,
|
||||
)
|
||||
)
|
||||
val successState = awaitItem()
|
||||
assertThat(successState.target).isEqualTo(
|
||||
ActionListState.Target.Success(
|
||||
|
|
@ -460,7 +613,15 @@ class ActionListPresenterTest {
|
|||
isEditable = true,
|
||||
content = aTimelineItemPollContent(answerItems = aPollAnswerItemList(hasVotes = false)),
|
||||
)
|
||||
initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(messageEvent, canRedact = false, canSendMessage = true, canSendReaction = true))
|
||||
initialState.eventSink.invoke(
|
||||
ActionListEvents.ComputeForMessage(
|
||||
event = messageEvent,
|
||||
canRedactOwn = true,
|
||||
canRedactOther = false,
|
||||
canSendMessage = true,
|
||||
canSendReaction = true,
|
||||
)
|
||||
)
|
||||
val successState = awaitItem()
|
||||
assertThat(successState.target).isEqualTo(
|
||||
ActionListState.Target.Success(
|
||||
|
|
@ -489,7 +650,15 @@ class ActionListPresenterTest {
|
|||
isEditable = false,
|
||||
content = aTimelineItemPollContent(answerItems = aPollAnswerItemList(hasVotes = true)),
|
||||
)
|
||||
initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(messageEvent, canRedact = false, canSendMessage = true, canSendReaction = true))
|
||||
initialState.eventSink.invoke(
|
||||
ActionListEvents.ComputeForMessage(
|
||||
event = messageEvent,
|
||||
canRedactOwn = true,
|
||||
canRedactOther = false,
|
||||
canSendMessage = true,
|
||||
canSendReaction = true,
|
||||
)
|
||||
)
|
||||
val successState = awaitItem()
|
||||
assertThat(successState.target).isEqualTo(
|
||||
ActionListState.Target.Success(
|
||||
|
|
@ -517,7 +686,15 @@ class ActionListPresenterTest {
|
|||
isEditable = false,
|
||||
content = aTimelineItemPollContent(isEnded = true),
|
||||
)
|
||||
initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(messageEvent, canRedact = false, canSendMessage = true, canSendReaction = true))
|
||||
initialState.eventSink.invoke(
|
||||
ActionListEvents.ComputeForMessage(
|
||||
event = messageEvent,
|
||||
canRedactOwn = true,
|
||||
canRedactOther = false,
|
||||
canSendMessage = true,
|
||||
canSendReaction = true,
|
||||
)
|
||||
)
|
||||
val successState = awaitItem()
|
||||
assertThat(successState.target).isEqualTo(
|
||||
ActionListState.Target.Success(
|
||||
|
|
@ -543,7 +720,15 @@ class ActionListPresenterTest {
|
|||
isMine = true,
|
||||
content = aTimelineItemVoiceContent(),
|
||||
)
|
||||
initialState.eventSink.invoke(ActionListEvents.ComputeForMessage(messageEvent, canRedact = false, canSendMessage = true, canSendReaction = true))
|
||||
initialState.eventSink.invoke(
|
||||
ActionListEvents.ComputeForMessage(
|
||||
event = messageEvent,
|
||||
canRedactOwn = true,
|
||||
canRedactOther = false,
|
||||
canSendMessage = true,
|
||||
canSendReaction = true,
|
||||
)
|
||||
)
|
||||
val successState = awaitItem()
|
||||
assertThat(successState.target).isEqualTo(
|
||||
ActionListState.Target.Success(
|
||||
|
|
|
|||
|
|
@ -127,7 +127,9 @@ interface MatrixRoom : Closeable {
|
|||
|
||||
suspend fun canUserInvite(userId: UserId): Result<Boolean>
|
||||
|
||||
suspend fun canUserRedact(userId: UserId): Result<Boolean>
|
||||
suspend fun canUserRedactOwn(userId: UserId): Result<Boolean>
|
||||
|
||||
suspend fun canUserRedactOther(userId: UserId): Result<Boolean>
|
||||
|
||||
suspend fun canUserSendState(userId: UserId, type: StateEventType): Result<Boolean>
|
||||
|
||||
|
|
|
|||
|
|
@ -36,6 +36,11 @@ suspend fun MatrixRoom.canSendState(type: StateEventType): Result<Boolean> = can
|
|||
suspend fun MatrixRoom.canSendMessage(type: MessageEventType): Result<Boolean> = canUserSendMessage(sessionId, type)
|
||||
|
||||
/**
|
||||
* Shortcut for calling [MatrixRoom.canUserRedact] with our own user.
|
||||
* Shortcut for calling [MatrixRoom.canUserRedactOwn] with our own user.
|
||||
*/
|
||||
suspend fun MatrixRoom.canRedact(): Result<Boolean> = canUserRedact(sessionId)
|
||||
suspend fun MatrixRoom.canRedactOwn(): Result<Boolean> = canUserRedactOwn(sessionId)
|
||||
|
||||
/**
|
||||
* Shortcut for calling [MatrixRoom.canRedactOther] with our own user.
|
||||
*/
|
||||
suspend fun MatrixRoom.canRedactOther(): Result<Boolean> = canUserRedactOther(sessionId)
|
||||
|
|
|
|||
|
|
@ -335,9 +335,15 @@ class RustMatrixRoom(
|
|||
}
|
||||
}
|
||||
|
||||
override suspend fun canUserRedact(userId: UserId): Result<Boolean> {
|
||||
override suspend fun canUserRedactOwn(userId: UserId): Result<Boolean> {
|
||||
return runCatching {
|
||||
innerRoom.canUserRedact(userId.value)
|
||||
innerRoom.canUserRedactOwn(userId.value)
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun canUserRedactOther(userId: UserId): Result<Boolean> {
|
||||
return runCatching {
|
||||
innerRoom.canUserRedactOther(userId.value)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -78,7 +78,8 @@ class FakeMatrixRoom(
|
|||
override val activeMemberCount: Long = 234L,
|
||||
val notificationSettingsService: NotificationSettingsService = FakeNotificationSettingsService(),
|
||||
private val matrixTimeline: MatrixTimeline = FakeMatrixTimeline(),
|
||||
canRedact: Boolean = false,
|
||||
canRedactOwn: Boolean = false,
|
||||
canRedactOther: Boolean = false,
|
||||
) : MatrixRoom {
|
||||
private var ignoreResult: Result<Unit> = Result.success(Unit)
|
||||
private var unignoreResult: Result<Unit> = Result.success(Unit)
|
||||
|
|
@ -88,7 +89,8 @@ class FakeMatrixRoom(
|
|||
private var joinRoomResult = Result.success(Unit)
|
||||
private var inviteUserResult = Result.success(Unit)
|
||||
private var canInviteResult = Result.success(true)
|
||||
private var canRedactResult = Result.success(canRedact)
|
||||
private var canRedactOwnResult = Result.success(canRedactOwn)
|
||||
private var canRedactOtherResult = Result.success(canRedactOther)
|
||||
private val canSendStateResults = mutableMapOf<StateEventType, Result<Boolean>>()
|
||||
private val canSendEventResults = mutableMapOf<MessageEventType, Result<Boolean>>()
|
||||
private var sendMediaResult = Result.success(FakeMediaUploadHandler())
|
||||
|
|
@ -276,8 +278,12 @@ class FakeMatrixRoom(
|
|||
return canInviteResult
|
||||
}
|
||||
|
||||
override suspend fun canUserRedact(userId: UserId): Result<Boolean> {
|
||||
return canRedactResult
|
||||
override suspend fun canUserRedactOwn(userId: UserId): Result<Boolean> {
|
||||
return canRedactOwnResult
|
||||
}
|
||||
|
||||
override suspend fun canUserRedactOther(userId: UserId): Result<Boolean> {
|
||||
return canRedactOtherResult
|
||||
}
|
||||
|
||||
override suspend fun canUserSendState(userId: UserId, type: StateEventType): Result<Boolean> {
|
||||
|
|
|
|||
|
|
@ -21,7 +21,8 @@ import androidx.compose.runtime.State
|
|||
import androidx.compose.runtime.produceState
|
||||
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.powerlevels.canRedact
|
||||
import io.element.android.libraries.matrix.api.room.powerlevels.canRedactOther
|
||||
import io.element.android.libraries.matrix.api.room.powerlevels.canRedactOwn
|
||||
import io.element.android.libraries.matrix.api.room.powerlevels.canSendMessage
|
||||
|
||||
@Composable
|
||||
|
|
@ -32,8 +33,15 @@ fun MatrixRoom.canSendMessageAsState(type: MessageEventType, updateKey: Long): S
|
|||
}
|
||||
|
||||
@Composable
|
||||
fun MatrixRoom.canRedactAsState(updateKey: Long): State<Boolean> {
|
||||
fun MatrixRoom.canRedactOwnAsState(updateKey: Long): State<Boolean> {
|
||||
return produceState(initialValue = false, key1 = updateKey) {
|
||||
value = canRedact().getOrElse { false }
|
||||
value = canRedactOwn().getOrElse { false }
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun MatrixRoom.canRedactOtherAsState(updateKey: Long): State<Boolean> {
|
||||
return produceState(initialValue = false, key1 = updateKey) {
|
||||
value = canRedactOther().getOrElse { false }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue