mirror of
https://github.com/element-hq/element-android
synced 2024-11-22 17:35:37 +03:00
Merge pull request #8797 from element-hq/feature/bma/reportUser
Report user
This commit is contained in:
commit
9aaf29d4cf
11 changed files with 80 additions and 5 deletions
1
changelog.d/8796.misc
Normal file
1
changelog.d/8796.misc
Normal file
|
@ -0,0 +1 @@
|
|||
Add a report user action in the message bottom sheet and on the user profile page.
|
|
@ -1953,8 +1953,11 @@
|
|||
<string name="content_reported_as_spam_content">"This content was reported as spam.\n\nIf you don't want to see any more content from this user, you can ignore them to hide their messages."</string>
|
||||
<string name="content_reported_as_inappropriate_title">"Reported as inappropriate"</string>
|
||||
<string name="content_reported_as_inappropriate_content">"This content was reported as inappropriate.\n\nIf you don't want to see any more content from this user, you can ignore them to hide their messages."</string>
|
||||
<string name="user_reported_as_inappropriate_title">"Reported user"</string>
|
||||
<string name="user_reported_as_inappropriate_content">"The user has been reported.\n\nIf you don't want to see any more content from this user, you can ignore them to hide their messages."</string>
|
||||
|
||||
<string name="message_ignore_user">Ignore user</string>
|
||||
<string name="message_report_user">Report user</string>
|
||||
|
||||
<string name="room_list_quick_actions_notifications_all_noisy">"All messages (noisy)"</string>
|
||||
<string name="room_list_quick_actions_notifications_all">"All messages"</string>
|
||||
|
|
|
@ -61,7 +61,8 @@ sealed class RoomDetailAction : VectorViewModelAction {
|
|||
val senderId: String?,
|
||||
val reason: String,
|
||||
val spam: Boolean = false,
|
||||
val inappropriate: Boolean = false
|
||||
val inappropriate: Boolean = false,
|
||||
val user: Boolean = false,
|
||||
) : RoomDetailAction()
|
||||
|
||||
data class IgnoreUser(val userId: String?) : RoomDetailAction()
|
||||
|
|
|
@ -1345,6 +1345,16 @@ class TimelineFragment :
|
|||
}
|
||||
.show()
|
||||
}
|
||||
data.user -> {
|
||||
MaterialAlertDialogBuilder(requireActivity(), R.style.ThemeOverlay_Vector_MaterialAlertDialog_NegativeDestructive)
|
||||
.setTitle(R.string.user_reported_as_inappropriate_title)
|
||||
.setMessage(R.string.user_reported_as_inappropriate_content)
|
||||
.setPositiveButton(R.string.ok, null)
|
||||
.setNegativeButton(R.string.block_user) { _, _ ->
|
||||
timelineViewModel.handle(RoomDetailAction.IgnoreUser(data.senderId))
|
||||
}
|
||||
.show()
|
||||
}
|
||||
else -> {
|
||||
MaterialAlertDialogBuilder(requireActivity(), R.style.ThemeOverlay_Vector_MaterialAlertDialog_NegativeDestructive)
|
||||
.setTitle(R.string.content_reported_title)
|
||||
|
@ -1857,6 +1867,13 @@ class TimelineFragment :
|
|||
is EventSharedAction.IgnoreUser -> {
|
||||
action.senderId?.let { askConfirmationToIgnoreUser(it) }
|
||||
}
|
||||
is EventSharedAction.ReportUser -> {
|
||||
timelineViewModel.handle(
|
||||
RoomDetailAction.ReportContent(
|
||||
action.eventId, action.senderId, "Reporting user ${action.senderId}", user = true
|
||||
)
|
||||
)
|
||||
}
|
||||
is EventSharedAction.OnUrlClicked -> {
|
||||
onUrlClicked(action.url, action.title)
|
||||
}
|
||||
|
|
|
@ -98,6 +98,9 @@ sealed class EventSharedAction(
|
|||
data class IgnoreUser(val senderId: String?) :
|
||||
EventSharedAction(R.string.message_ignore_user, R.drawable.ic_alert_triangle, true)
|
||||
|
||||
data class ReportUser(val eventId: String, val senderId: String?) :
|
||||
EventSharedAction(R.string.message_report_user, R.drawable.ic_flag, true)
|
||||
|
||||
data class QuickReact(val eventId: String, val clickedOn: String, val add: Boolean) :
|
||||
EventSharedAction(0, 0)
|
||||
|
||||
|
|
|
@ -430,6 +430,12 @@ class MessageActionsViewModel @AssistedInject constructor(
|
|||
|
||||
add(EventSharedAction.Separator)
|
||||
add(EventSharedAction.IgnoreUser(timelineEvent.root.senderId))
|
||||
add(
|
||||
EventSharedAction.ReportUser(
|
||||
eventId = eventId,
|
||||
senderId = timelineEvent.root.senderId,
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ import im.vector.app.core.platform.VectorViewModelAction
|
|||
sealed class RoomMemberProfileAction : VectorViewModelAction {
|
||||
object RetryFetchingInfo : RoomMemberProfileAction()
|
||||
object IgnoreUser : RoomMemberProfileAction()
|
||||
object ReportUser : RoomMemberProfileAction()
|
||||
data class BanOrUnbanUser(val reason: String?) : RoomMemberProfileAction()
|
||||
data class KickUser(val reason: String?) : RoomMemberProfileAction()
|
||||
object InviteUser : RoomMemberProfileAction()
|
||||
|
|
|
@ -39,6 +39,7 @@ class RoomMemberProfileController @Inject constructor(
|
|||
|
||||
interface Callback {
|
||||
fun onIgnoreClicked()
|
||||
fun onReportClicked()
|
||||
fun onTapVerify()
|
||||
fun onShowDeviceList()
|
||||
fun onShowDeviceListNoCrossSigning()
|
||||
|
@ -225,7 +226,7 @@ class RoomMemberProfileController @Inject constructor(
|
|||
title = stringProvider.getString(R.string.room_participants_action_invite),
|
||||
destructive = false,
|
||||
editable = false,
|
||||
divider = ignoreActionTitle != null,
|
||||
divider = true,
|
||||
action = { callback?.onInviteClicked() }
|
||||
)
|
||||
}
|
||||
|
@ -235,10 +236,18 @@ class RoomMemberProfileController @Inject constructor(
|
|||
title = ignoreActionTitle,
|
||||
destructive = true,
|
||||
editable = false,
|
||||
divider = false,
|
||||
divider = true,
|
||||
action = { callback?.onIgnoreClicked() }
|
||||
)
|
||||
}
|
||||
buildProfileAction(
|
||||
id = "report",
|
||||
title = stringProvider.getString(R.string.message_report_user),
|
||||
destructive = true,
|
||||
editable = false,
|
||||
divider = false,
|
||||
action = { callback?.onReportClicked() }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -314,9 +323,9 @@ class RoomMemberProfileController @Inject constructor(
|
|||
private fun RoomMemberProfileViewState.buildIgnoreActionTitle(): String? {
|
||||
val isIgnored = isIgnored() ?: return null
|
||||
return if (isIgnored) {
|
||||
stringProvider.getString(R.string.unignore)
|
||||
stringProvider.getString(R.string.room_participants_action_unignore_title)
|
||||
} else {
|
||||
stringProvider.getString(R.string.action_ignore)
|
||||
stringProvider.getString(R.string.room_participants_action_ignore_title)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -140,11 +140,20 @@ class RoomMemberProfileFragment :
|
|||
is RoomMemberProfileViewEvents.OnIgnoreActionSuccess -> Unit
|
||||
is RoomMemberProfileViewEvents.OnInviteActionSuccess -> Unit
|
||||
RoomMemberProfileViewEvents.GoBack -> handleGoBack()
|
||||
RoomMemberProfileViewEvents.OnReportActionSuccess -> handleReportSuccess()
|
||||
}
|
||||
}
|
||||
setupLongClicks()
|
||||
}
|
||||
|
||||
private fun handleReportSuccess() {
|
||||
MaterialAlertDialogBuilder(requireContext())
|
||||
.setTitle(R.string.user_reported_as_inappropriate_title)
|
||||
.setMessage(R.string.user_reported_as_inappropriate_content)
|
||||
.setPositiveButton(R.string.ok, null)
|
||||
.show()
|
||||
}
|
||||
|
||||
private fun setupLongClicks() {
|
||||
headerViews.memberProfileNameView.copyOnLongClick()
|
||||
headerViews.memberProfileIdView.copyOnLongClick()
|
||||
|
@ -301,6 +310,10 @@ class RoomMemberProfileFragment :
|
|||
}
|
||||
}
|
||||
|
||||
override fun onReportClicked() {
|
||||
viewModel.handle(RoomMemberProfileAction.ReportUser)
|
||||
}
|
||||
|
||||
override fun onTapVerify() {
|
||||
viewModel.handle(RoomMemberProfileAction.VerifyUser)
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ sealed class RoomMemberProfileViewEvents : VectorViewEvents {
|
|||
data class Failure(val throwable: Throwable) : RoomMemberProfileViewEvents()
|
||||
|
||||
object OnIgnoreActionSuccess : RoomMemberProfileViewEvents()
|
||||
object OnReportActionSuccess : RoomMemberProfileViewEvents()
|
||||
object OnSetPowerLevelSuccess : RoomMemberProfileViewEvents()
|
||||
object OnInviteActionSuccess : RoomMemberProfileViewEvents()
|
||||
object OnKickActionSuccess : RoomMemberProfileViewEvents()
|
||||
|
|
|
@ -161,6 +161,7 @@ class RoomMemberProfileViewModel @AssistedInject constructor(
|
|||
when (action) {
|
||||
is RoomMemberProfileAction.RetryFetchingInfo -> handleRetryFetchProfileInfo()
|
||||
is RoomMemberProfileAction.IgnoreUser -> handleIgnoreAction()
|
||||
is RoomMemberProfileAction.ReportUser -> handleReportAction()
|
||||
is RoomMemberProfileAction.VerifyUser -> prepareVerification()
|
||||
is RoomMemberProfileAction.ShareRoomMemberProfile -> handleShareRoomMemberProfile()
|
||||
is RoomMemberProfileAction.SetPowerLevel -> handleSetPowerLevel(action)
|
||||
|
@ -172,6 +173,25 @@ class RoomMemberProfileViewModel @AssistedInject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun handleReportAction() {
|
||||
viewModelScope.launch {
|
||||
val event = try {
|
||||
// The API need an Event, use the latest Event.
|
||||
val latestEventId = room?.roomSummary()?.latestPreviewableEvent?.eventId ?: return@launch
|
||||
room.reportingService()
|
||||
.reportContent(
|
||||
eventId = latestEventId,
|
||||
score = -100,
|
||||
reason = "Reporting user ${initialState.userId} (eventId is not relevant)"
|
||||
)
|
||||
RoomMemberProfileViewEvents.OnReportActionSuccess
|
||||
} catch (failure: Throwable) {
|
||||
RoomMemberProfileViewEvents.Failure(failure)
|
||||
}
|
||||
_viewEvents.post(event)
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleOpenOrCreateDm(action: RoomMemberProfileAction.OpenOrCreateDm) {
|
||||
viewModelScope.launch {
|
||||
_viewEvents.post(RoomMemberProfileViewEvents.Loading())
|
||||
|
|
Loading…
Reference in a new issue