Merge pull request #1005 from vector-im/feature/fix_event_redaction_prompt

Do not ask for a reason if user wants to delete his own message.
This commit is contained in:
Benoit Marty 2020-02-14 14:36:01 +01:00 committed by GitHub
commit 88b8ceaeb5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 49 additions and 9 deletions

View File

@ -5,7 +5,7 @@ Features ✨:
- Polls and Bot Buttons (MSC 2192 matrix-org/matrix-doc#2192)
Improvements 🙌:
- Show confirmation dialog before deleting a message (#967)
- Show confirmation dialog before deleting a message (#967, #1003)
- Open room member profile from reactions list and read receipts list (#875)
Bugfix 🐛:

View File

@ -157,6 +157,11 @@ data class Event(
*/
fun isRedacted() = unsignedData?.redactedEvent != null
/**
* Tells if the event is redacted by the user himself.
*/
fun isRedactedBySameUser() = senderId == unsignedData?.redactedEvent?.senderId
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false

View File

@ -788,12 +788,15 @@ class RoomDetailFragment @Inject constructor(
.show()
}
private fun promptReasonToRedactEvent(eventId: String) {
private fun promptConfirmationToRedactEvent(action: EventSharedAction.Redact) {
val layout = requireActivity().layoutInflater.inflate(R.layout.dialog_delete_event, null)
val reasonCheckBox = layout.findViewById<MaterialCheckBox>(R.id.deleteEventReasonCheck)
val reasonTextInputLayout = layout.findViewById<TextInputLayout>(R.id.deleteEventReasonTextInputLayout)
val reasonInput = layout.findViewById<TextInputEditText>(R.id.deleteEventReasonInput)
reasonCheckBox.isVisible = action.askForReason
reasonTextInputLayout.isVisible = action.askForReason
reasonCheckBox.setOnCheckedChangeListener { _, isChecked -> reasonTextInputLayout.isEnabled = isChecked }
AlertDialog.Builder(requireActivity())
@ -801,9 +804,10 @@ class RoomDetailFragment @Inject constructor(
.setView(layout)
.setPositiveButton(R.string.remove) { _, _ ->
val reason = reasonInput.text.toString()
.takeIf { reasonCheckBox.isChecked }
.takeIf { action.askForReason }
?.takeIf { reasonCheckBox.isChecked }
?.takeIf { it.isNotBlank() }
roomDetailViewModel.handle(RoomDetailAction.RedactAction(eventId, reason))
roomDetailViewModel.handle(RoomDetailAction.RedactAction(action.eventId, reason))
}
.setNegativeButton(R.string.cancel, null)
.show()
@ -1121,7 +1125,7 @@ class RoomDetailFragment @Inject constructor(
showSnackWithMessage(getString(R.string.copied_to_clipboard), Snackbar.LENGTH_SHORT)
}
is EventSharedAction.Redact -> {
promptReasonToRedactEvent(action.eventId)
promptConfirmationToRedactEvent(action)
}
is EventSharedAction.Share -> {
// TODO current data communication is too limited

View File

@ -55,7 +55,7 @@ sealed class EventSharedAction(@StringRes val titleRes: Int,
data class Remove(val eventId: String) :
EventSharedAction(R.string.remove, R.drawable.ic_trash, true)
data class Redact(val eventId: String) :
data class Redact(val eventId: String, val askForReason: Boolean) :
EventSharedAction(R.string.message_action_item_redact, R.drawable.ic_delete, true)
data class Cancel(val eventId: String) :

View File

@ -168,6 +168,10 @@ class MessageActionsViewModel @AssistedInject constructor(@Assisted
}
private fun computeMessageBody(timelineEvent: TimelineEvent): CharSequence {
if (timelineEvent.root.isRedacted()) {
return getRedactionReason(timelineEvent)
}
return when (timelineEvent.root.getClearType()) {
EventType.MESSAGE,
EventType.STICKER -> {
@ -200,6 +204,31 @@ class MessageActionsViewModel @AssistedInject constructor(@Assisted
} ?: ""
}
private fun getRedactionReason(timelineEvent: TimelineEvent): String {
return (timelineEvent
.root
.unsignedData
?.redactedEvent
?.content
?.get("reason") as? String)
?.takeIf { it.isNotBlank() }
.let { reason ->
if (reason == null) {
if (timelineEvent.root.isRedactedBySameUser()) {
stringProvider.getString(R.string.event_redacted_by_user_reason)
} else {
stringProvider.getString(R.string.event_redacted_by_admin_reason)
}
} else {
if (timelineEvent.root.isRedactedBySameUser()) {
stringProvider.getString(R.string.event_redacted_by_user_reason_with_reason, reason)
} else {
stringProvider.getString(R.string.event_redacted_by_admin_reason_with_reason, reason)
}
}
}
}
private fun actionsForEvent(timelineEvent: TimelineEvent): List<EventSharedAction> {
val messageContent: MessageContent? = timelineEvent.annotations?.editSummary?.aggregatedContent.toModel()
?: timelineEvent.root.getClearContent().toModel()
@ -227,7 +256,7 @@ class MessageActionsViewModel @AssistedInject constructor(@Assisted
}
if (canRedact(timelineEvent, session.myUserId)) {
add(EventSharedAction.Redact(eventId))
add(EventSharedAction.Redact(eventId, askForReason = informationData.senderId != session.myUserId))
}
if (canCopy(msgType)) {

View File

@ -43,8 +43,7 @@
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/deleteEventReasonInput"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/event_redacted_by_user_reason" />
android:layout_height="wrap_content" />
</com.google.android.material.textfield.TextInputLayout>

View File

@ -33,6 +33,9 @@
<string name="delete_event_dialog_content">Are you sure you wish to remove (delete) this event? Note that if you delete a room name or topic change, it could undo the change.</string>
<string name="delete_event_dialog_reason_checkbox">Include a reason</string>
<string name="delete_event_dialog_reason_hint">Reason for redacting</string>
<string name="event_redacted_by_user_reason_with_reason">Event deleted by user, reason: %1$s</string>
<string name="event_redacted_by_admin_reason_with_reason">Event moderated by room admin, reason: %1$s</string>
<!-- END Strings added by Onuray -->