Skip to content

Commit

Permalink
Merge pull request #2115 from element-hq/feature/bma/reactionsPowerLevel
Browse files Browse the repository at this point in the history
Reactions power level
  • Loading branch information
bmarty authored Dec 26, 2023
2 parents 5cd511f + 0528deb commit e38799c
Show file tree
Hide file tree
Showing 22 changed files with 173 additions and 102 deletions.
1 change: 1 addition & 0 deletions changelog.d/2093.bugfix
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Disable ability to send reaction if the user does not have the permission to.
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ 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 userHasPermissionToSendReaction by room.canSendMessageAsState(type = MessageEventType.REACTION_SENT, updateKey = syncUpdateFlow.value)
val roomName: Async<String> by remember {
derivedStateOf { roomInfo?.name?.let { Async.Success(it) } ?: Async.Uninitialized }
}
Expand Down Expand Up @@ -219,6 +220,7 @@ class MessagesPresenter @AssistedInject constructor(
roomAvatar = roomAvatar,
userHasPermissionToSendMessage = userHasPermissionToSendMessage,
userHasPermissionToRedact = userHasPermissionToRedact,
userHasPermissionToSendReaction = userHasPermissionToSendReaction,
composerState = composerState,
voiceMessageComposerState = voiceMessageComposerState,
timelineState = timelineState,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ data class MessagesState(
val roomAvatar: Async<AvatarData>,
val userHasPermissionToSendMessage: Boolean,
val userHasPermissionToRedact: Boolean,
val userHasPermissionToSendReaction: Boolean,
val composerState: MessageComposerState,
val voiceMessageComposerState: VoiceMessageComposerState,
val timelineState: TimelineState,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ fun aMessagesState() = MessagesState(
roomAvatar = Async.Success(AvatarData("!id:domain", "Room name", size = AvatarSize.TimelineRoom)),
userHasPermissionToSendMessage = true,
userHasPermissionToRedact = false,
userHasPermissionToSendReaction = true,
composerState = aMessageComposerState().copy(
richTextEditorState = RichTextEditorState("Hello", initialFocus = true),
isFullScreen = false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ fun MessagesView(
event = event,
canRedact = state.userHasPermissionToRedact,
canSendMessage = state.userHasPermissionToSendMessage,
canSendReaction = state.userHasPermissionToSendReaction,
)
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,5 +24,6 @@ sealed interface ActionListEvents {
val event: TimelineItem.Event,
val canRedact: Boolean,
val canSendMessage: Boolean,
val canSendReaction: Boolean,
) : ActionListEvents
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ package io.element.android.features.messages.impl.actionlist
import androidx.compose.runtime.Composable
import androidx.compose.runtime.MutableState
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
Expand Down Expand Up @@ -53,20 +52,14 @@ class ActionListPresenter @Inject constructor(

val isDeveloperModeEnabled by preferencesStore.isDeveloperModeEnabledFlow().collectAsState(initial = false)

val displayEmojiReactions by remember {
derivedStateOf {
val event = (target.value as? ActionListState.Target.Success)?.event
event?.isRemote == true && event.content.canReact()
}
}

fun handleEvents(event: ActionListEvents) {
when (event) {
ActionListEvents.Clear -> target.value = ActionListState.Target.None
is ActionListEvents.ComputeForMessage -> localCoroutineScope.computeForMessage(
timelineItem = event.event,
userCanRedact = event.canRedact,
userCanSendMessage = event.canSendMessage,
userCanSendReaction = event.canSendReaction,
isDeveloperModeEnabled = isDeveloperModeEnabled,
target = target,
)
Expand All @@ -75,7 +68,6 @@ class ActionListPresenter @Inject constructor(

return ActionListState(
target = target.value,
displayEmojiReactions = displayEmojiReactions,
eventSink = { handleEvents(it) }
)
}
Expand All @@ -84,6 +76,7 @@ class ActionListPresenter @Inject constructor(
timelineItem: TimelineItem.Event,
userCanRedact: Boolean,
userCanSendMessage: Boolean,
userCanSendReaction: Boolean,
isDeveloperModeEnabled: Boolean,
target: MutableState<ActionListState.Target>
) = launch {
Expand Down Expand Up @@ -178,8 +171,15 @@ class ActionListPresenter @Inject constructor(
}
}
}
if (actions.isNotEmpty()) {
target.value = ActionListState.Target.Success(timelineItem, actions.toImmutableList())
val displayEmojiReactions = userCanSendReaction &&
timelineItem.isRemote &&
timelineItem.content.canReact()
if (actions.isNotEmpty() || displayEmojiReactions) {
target.value = ActionListState.Target.Success(
event = timelineItem,
displayEmojiReactions = displayEmojiReactions,
actions = actions.toImmutableList()
)
} else {
target.value = ActionListState.Target.None
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,14 @@ import kotlinx.collections.immutable.ImmutableList
@Immutable
data class ActionListState(
val target: Target,
val displayEmojiReactions: Boolean,
val eventSink: (ActionListEvents) -> Unit,
) {
sealed interface Target {
data object None : Target
data class Loading(val event: TimelineItem.Event) : Target
data class Success(
val event: TimelineItem.Event,
val displayEmojiReactions: Boolean,
val actions: ImmutableList<TimelineItemAction>,
) : Target
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ open class ActionListStateProvider : PreviewParameterProvider<ActionListState> {
event = aTimelineItemEvent().copy(
reactionsState = reactionsState
),
displayEmojiReactions = true,
actions = aTimelineItemActionList(),
)
),
Expand All @@ -50,6 +51,7 @@ open class ActionListStateProvider : PreviewParameterProvider<ActionListState> {
event = aTimelineItemEvent(content = aTimelineItemImageContent()).copy(
reactionsState = reactionsState
),
displayEmojiReactions = true,
actions = aTimelineItemActionList(),
)
),
Expand All @@ -58,6 +60,7 @@ open class ActionListStateProvider : PreviewParameterProvider<ActionListState> {
event = aTimelineItemEvent(content = aTimelineItemVideoContent()).copy(
reactionsState = reactionsState
),
displayEmojiReactions = true,
actions = aTimelineItemActionList(),
)
),
Expand All @@ -66,6 +69,7 @@ open class ActionListStateProvider : PreviewParameterProvider<ActionListState> {
event = aTimelineItemEvent(content = aTimelineItemFileContent()).copy(
reactionsState = reactionsState
),
displayEmojiReactions = true,
actions = aTimelineItemActionList(),
)
),
Expand All @@ -74,6 +78,7 @@ open class ActionListStateProvider : PreviewParameterProvider<ActionListState> {
event = aTimelineItemEvent(content = aTimelineItemAudioContent()).copy(
reactionsState = reactionsState
),
displayEmojiReactions = true,
actions = aTimelineItemActionList(),
)
),
Expand All @@ -82,6 +87,7 @@ open class ActionListStateProvider : PreviewParameterProvider<ActionListState> {
event = aTimelineItemEvent(content = aTimelineItemVoiceContent()).copy(
reactionsState = reactionsState
),
displayEmojiReactions = true,
actions = aTimelineItemActionList(),
)
),
Expand All @@ -90,6 +96,7 @@ open class ActionListStateProvider : PreviewParameterProvider<ActionListState> {
event = aTimelineItemEvent(content = aTimelineItemLocationContent()).copy(
reactionsState = reactionsState
),
displayEmojiReactions = true,
actions = aTimelineItemActionList(),
)
),
Expand All @@ -98,26 +105,25 @@ open class ActionListStateProvider : PreviewParameterProvider<ActionListState> {
event = aTimelineItemEvent(content = aTimelineItemLocationContent()).copy(
reactionsState = reactionsState
),
displayEmojiReactions = false,
actions = aTimelineItemActionList(),
),
displayEmojiReactions = false,
),
anActionListState().copy(
target = ActionListState.Target.Success(
event = aTimelineItemEvent(content = aTimelineItemPollContent()).copy(
reactionsState = reactionsState
),
displayEmojiReactions = false,
actions = aTimelineItemPollActionList(),
),
displayEmojiReactions = false,
),
)
}
}

fun anActionListState() = ActionListState(
target = ActionListState.Target.None,
displayEmojiReactions = true,
eventSink = {}
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ private fun SheetContent(
HorizontalDivider()
}
}
if (state.displayEmojiReactions) {
if (target.displayEmojiReactions) {
item {
EmojiReactionsRow(
highlightedEmojis = target.event.reactionsState.highlightedKeys,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ class TimelinePresenter @AssistedInject constructor(
val paginationState by timeline.paginationState.collectAsState()
val syncUpdateFlow = room.syncUpdateFlow.collectAsState()
val userHasPermissionToSendMessage by room.canSendMessageAsState(type = MessageEventType.ROOM_MESSAGE, updateKey = syncUpdateFlow.value)
val userHasPermissionToSendReaction by room.canSendMessageAsState(type = MessageEventType.REACTION_SENT, updateKey = syncUpdateFlow.value)

val prevMostRecentItemId = rememberSaveable { mutableStateOf<String?>(null) }
val newItemState = remember { mutableStateOf(NewEventState.None) }
Expand Down Expand Up @@ -175,12 +176,18 @@ class TimelinePresenter @AssistedInject constructor(
.launchIn(this)
}

val timelineRoomInfo by remember {
derivedStateOf {
TimelineRoomInfo(
isDirect = room.isDirect,
userHasPermissionToSendMessage = userHasPermissionToSendMessage,
userHasPermissionToSendReaction = userHasPermissionToSendReaction,
)
}
}
return TimelineState(
timelineRoomInfo = TimelineRoomInfo(
isDirect = room.isDirect
),
timelineRoomInfo = timelineRoomInfo,
highlightedEventId = highlightedEventId.value,
userHasPermissionToSendMessage = userHasPermissionToSendMessage,
paginationState = paginationState,
timelineItems = timelineItems,
showReadReceipts = readReceiptsEnabled,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ data class TimelineState(
val timelineRoomInfo: TimelineRoomInfo,
val showReadReceipts: Boolean,
val highlightedEventId: EventId?,
val userHasPermissionToSendMessage: Boolean,
val paginationState: MatrixTimeline.PaginationState,
val newEventState: NewEventState,
val sessionState: SessionState,
Expand All @@ -40,4 +39,6 @@ data class TimelineState(
@Immutable
data class TimelineRoomInfo(
val isDirect: Boolean,
val userHasPermissionToSendMessage: Boolean,
val userHasPermissionToSendReaction: Boolean,
)
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ fun aTimelineState(timelineItems: ImmutableList<TimelineItem> = persistentListOf
beginningOfRoomReached = false,
),
highlightedEventId = null,
userHasPermissionToSendMessage = true,
newEventState = NewEventState.None,
sessionState = aSessionState(
isSessionVerified = true,
Expand Down Expand Up @@ -218,4 +217,6 @@ internal fun aTimelineRoomInfo(
isDirect: Boolean = false,
) = TimelineRoomInfo(
isDirect = isDirect,
userHasPermissionToSendMessage = true,
userHasPermissionToSendReaction = true,
)
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,6 @@ fun TimelineView(
isLastOutgoingMessage = (timelineItem as? TimelineItem.Event)?.isMine == true
&& state.timelineItems.first().identifier() == timelineItem.identifier(),
highlightedItem = state.highlightedEventId?.value,
userHasPermissionToSendMessage = state.userHasPermissionToSendMessage,
onClick = onMessageClicked,
onLongClick = onMessageLongClicked,
onUserDataClick = onUserDataClicked,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ internal fun ATimelineItemEventRow(
showReadReceipts = showReadReceipts,
isLastOutgoingMessage = isLastOutgoingMessage,
isHighlighted = isHighlighted,
canReply = true,
onClick = {},
onLongClick = {},
onUserDataClick = {},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ import io.element.android.features.messages.impl.timeline.model.event.TimelineIt
import io.element.android.features.messages.impl.timeline.model.event.TimelineItemVideoContent
import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemImageContent
import io.element.android.features.messages.impl.timeline.model.event.aTimelineItemTextContent
import io.element.android.features.messages.impl.timeline.model.event.canBeRepliedTo
import io.element.android.features.messages.impl.timeline.model.metadata
import io.element.android.libraries.androidutils.system.openUrlInExternalApp
import io.element.android.libraries.designsystem.colors.AvatarColorsProvider
Expand Down Expand Up @@ -112,7 +113,6 @@ fun TimelineItemEventRow(
showReadReceipts: Boolean,
isLastOutgoingMessage: Boolean,
isHighlighted: Boolean,
canReply: Boolean,
onClick: () -> Unit,
onLongClick: () -> Unit,
onUserDataClick: (UserId) -> Unit,
Expand Down Expand Up @@ -151,6 +151,7 @@ fun TimelineItemEventRow(
} else {
Spacer(modifier = Modifier.height(2.dp))
}
val canReply = timelineRoomInfo.userHasPermissionToSendMessage && event.content.canBeRepliedTo()
if (canReply) {
val state: SwipeableActionsState = rememberSwipeableActionsState()
val offset = state.offset.floatValue
Expand Down Expand Up @@ -335,6 +336,7 @@ private fun TimelineItemEventRowContent(
if (event.reactionsState.reactions.isNotEmpty()) {
TimelineItemReactionsView(
reactionsState = event.reactionsState,
userCanSendReaction = timelineRoomInfo.userHasPermissionToSendReaction,
isOutgoing = event.isMine,
onReactionClicked = onReactionClicked,
onReactionLongClicked = onReactionLongClicked,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,6 @@ private fun TimelineItemGroupedEventsRowContent(
isLastOutgoingMessage = isLastOutgoingMessage,
highlightedItem = highlightedItem,
sessionState = sessionState,
userHasPermissionToSendMessage = false,
onClick = onClick,
onLongClick = onLongClick,
inReplyToClick = inReplyToClick,
Expand Down
Loading

0 comments on commit e38799c

Please sign in to comment.