Code and design review fixes.

This commit is contained in:
Onuray Sahin 2021-12-13 17:07:17 +03:00
parent 9b2a3cf445
commit c7ad50a4d6
7 changed files with 85 additions and 48 deletions

View File

@ -1580,10 +1580,10 @@ class RoomDetailFragment @Inject constructor(
.show(
activity = requireActivity(),
askForReason = action.askForReason,
confirmationRes = R.string.delete_event_dialog_content,
confirmationRes = action.dialogDescriptionRes,
positiveRes = R.string.remove,
reasonHintRes = R.string.delete_event_dialog_reason_hint,
titleRes = R.string.delete_event_dialog_title
titleRes = action.dialogTitleRes
) { reason ->
roomDetailViewModel.handle(RoomDetailAction.RedactAction(action.eventId, reason))
}

View File

@ -60,7 +60,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, val askForReason: Boolean) :
data class Redact(val eventId: String, val askForReason: Boolean, val dialogTitleRes: Int, val dialogDescriptionRes: Int) :
EventSharedAction(R.string.message_action_item_redact, R.drawable.ic_delete, true)
data class Cancel(val eventId: String, val force: Boolean) :

View File

@ -333,7 +333,21 @@ class MessageActionsViewModel @AssistedInject constructor(@Assisted
}
if (canRedact(timelineEvent, actionPermissions)) {
add(EventSharedAction.Redact(eventId, askForReason = informationData.senderId != session.myUserId))
if (timelineEvent.root.getClearType() == EventType.POLL_START) {
add(EventSharedAction.Redact(
eventId,
askForReason = informationData.senderId != session.myUserId,
dialogTitleRes = R.string.delete_poll_dialog_title,
dialogDescriptionRes = R.string.delete_poll_dialog_content
))
} else {
add(EventSharedAction.Redact(
eventId,
askForReason = informationData.senderId != session.myUserId,
dialogTitleRes = R.string.delete_event_dialog_title,
dialogDescriptionRes = R.string.delete_event_dialog_content
))
}
}
if (canCopy(msgType)) {

View File

@ -54,6 +54,7 @@ import im.vector.app.features.home.room.detail.timeline.item.MessageVoiceItem
import im.vector.app.features.home.room.detail.timeline.item.MessageVoiceItem_
import im.vector.app.features.home.room.detail.timeline.item.PollItem
import im.vector.app.features.home.room.detail.timeline.item.PollItem_
import im.vector.app.features.home.room.detail.timeline.item.PollOptionViewState
import im.vector.app.features.home.room.detail.timeline.item.RedactedMessageItem
import im.vector.app.features.home.room.detail.timeline.item.RedactedMessageItem_
import im.vector.app.features.home.room.detail.timeline.item.VerificationRequestItem
@ -70,6 +71,7 @@ import im.vector.app.features.media.VideoContentRenderer
import me.gujun.android.span.span
import org.commonmark.node.Document
import org.matrix.android.sdk.api.MatrixUrls.isMxcUrl
import org.matrix.android.sdk.api.extensions.orFalse
import org.matrix.android.sdk.api.session.Session
import org.matrix.android.sdk.api.session.events.model.RelationType
import org.matrix.android.sdk.api.session.events.model.toModel
@ -170,17 +172,59 @@ class MessageItemFactory @Inject constructor(
}
}
private fun buildPollContent(messageContent: MessagePollContent,
private fun buildPollContent(pollContent: MessagePollContent,
informationData: MessageInformationData,
highlight: Boolean,
callback: TimelineEventController.Callback?,
attributes: AbsMessageItem.Attributes): PollItem? {
val optionViewStates = mutableListOf<PollOptionViewState>()
val pollResponseSummary = informationData.pollResponseAggregatedSummary
val isEnded = pollResponseSummary?.isClosed.orFalse()
val didUserVoted = pollResponseSummary?.myVote?.isNotEmpty().orFalse()
val winnerVoteCount = pollResponseSummary?.winnerVoteCount
val isPollSent = informationData.sendState.isSent()
val totalVotesText = (pollResponseSummary?.totalVotes ?: 0).let {
when {
isEnded -> stringProvider.getQuantityString(R.plurals.poll_total_vote_count_after_ended, it, it)
didUserVoted -> stringProvider.getQuantityString(R.plurals.poll_total_vote_count_before_ended_and_voted, it, it)
else -> stringProvider.getQuantityString(R.plurals.poll_total_vote_count_before_ended_and_not_voted, it, it)
}
}
pollContent.pollCreationInfo?.answers?.forEach { option ->
val voteSummary = pollResponseSummary?.votes?.get(option.id)
val isMyVote = pollResponseSummary?.myVote == option.id
val voteCount = voteSummary?.total ?: 0
val votePercentage = voteSummary?.percentage ?: 0.0
val optionName = option.answer ?: ""
optionViewStates.add(
if (!isPollSent) {
// Poll event is not send yet. Disable option.
PollOptionViewState.DisabledOptionWithInvisibleVotes(optionName)
} else if (isEnded) {
// Poll is ended. Disable option, show votes and mark the winner.
val isWinner = winnerVoteCount != 0 && voteCount == winnerVoteCount
PollOptionViewState.DisabledOptionWithVisibleVotes(optionName, voteCount, votePercentage, isWinner)
} else if (didUserVoted) {
// User voted to the poll, but poll is not ended. Enable option, show votes and mark the user's selection.
PollOptionViewState.EnabledOptionWithVisibleVotes(optionName, voteCount, votePercentage, isMyVote)
} else {
// User didn't voted yet and poll is not ended yet. Enable options, hide votes.
PollOptionViewState.EnabledOptionWithInvisibleVotes(optionName)
}
)
}
return PollItem_()
.attributes(attributes)
.eventId(informationData.eventId)
.pollResponseSummary(informationData.pollResponseAggregatedSummary)
.pollSent(informationData.sendState.isSent())
.pollContent(messageContent)
.pollResponseSummary(pollResponseSummary)
.pollSent(isPollSent)
.pollContent(pollContent)
.totalVotesText(totalVotesText)
.optionViewStates(optionViewStates)
.highlighted(highlight)
.leftGuideline(avatarSizeProvider.leftGuideline)
.callback(callback)

View File

@ -23,7 +23,6 @@ import com.airbnb.epoxy.EpoxyModelClass
import im.vector.app.R
import im.vector.app.features.home.room.detail.RoomDetailAction
import im.vector.app.features.home.room.detail.timeline.TimelineEventController
import org.matrix.android.sdk.api.extensions.orFalse
import org.matrix.android.sdk.api.session.room.model.message.MessagePollContent
@EpoxyModelClass(layout = R.layout.item_timeline_event_base)
@ -44,6 +43,12 @@ abstract class PollItem : AbsMessageItem<PollItem.Holder>() {
@EpoxyAttribute
var pollSent: Boolean = false
@EpoxyAttribute
var totalVotesText: String? = null
@EpoxyAttribute
var optionViewStates: List<PollOptionViewState>? = null
override fun bind(holder: Holder) {
super.bind(holder)
val relatedEventId = eventId ?: return
@ -51,54 +56,26 @@ abstract class PollItem : AbsMessageItem<PollItem.Holder>() {
renderSendState(holder.view, holder.questionTextView)
holder.questionTextView.text = pollContent?.pollCreationInfo?.question?.question
holder.totalVotesTextView.text = totalVotesText
holder.optionsContainer.removeAllViews()
val isEnded = pollResponseSummary?.isClosed.orFalse()
val didUserVoted = pollResponseSummary?.myVote?.isNotEmpty().orFalse()
val totalVotes = pollResponseSummary?.totalVotes ?: 0
val winnerVoteCount = pollResponseSummary?.winnerVoteCount
pollContent?.pollCreationInfo?.answers?.forEach { option ->
val voteSummary = pollResponseSummary?.votes?.get(option.id)
val isMyVote = pollResponseSummary?.myVote == option.id
val voteCount = voteSummary?.total ?: 0
val votePercentage = voteSummary?.percentage ?: 0.0
pollContent?.pollCreationInfo?.answers?.forEachIndexed { index, option ->
val optionName = option.answer ?: ""
holder.optionsContainer.addView(
PollOptionItem(holder.view.context).apply {
val callback = object : PollOptionItem.Callback {
override fun onOptionClicked() {
callback?.onTimelineItemAction(RoomDetailAction.VoteToPoll(relatedEventId, option.id ?: ""))
}
}
if (!pollSent) {
// Poll event is not send yet. Disable option.
render(PollOptionViewState.DisabledOptionWithInvisibleVotes(optionName), callback)
} else if (isEnded) {
// Poll is ended. Disable option, show votes and mark the winner.
val isWinner = winnerVoteCount != 0 && voteCount == winnerVoteCount
render(PollOptionViewState.DisabledOptionWithVisibleVotes(optionName, voteCount, votePercentage, isWinner), callback)
} else if (didUserVoted) {
// User voted to the poll, but poll is not ended. Enable option, show votes and mark the user's selection.
render(PollOptionViewState.EnabledOptionWithVisibleVotes(optionName, voteCount, votePercentage, isMyVote), callback)
} else {
// User didn't voted yet and poll is not ended yet. Enable options, hide votes.
render(PollOptionViewState.EnabledOptionWithInvisibleVotes(optionName), callback)
}
render(
state = optionViewStates?.getOrNull(index) ?: PollOptionViewState.DisabledOptionWithInvisibleVotes(optionName),
callback = object : PollOptionItem.Callback {
override fun onOptionClicked() {
callback?.onTimelineItemAction(RoomDetailAction.VoteToPoll(relatedEventId, option.id ?: ""))
}
}
)
}
)
}
holder.totalVotesTextView.apply {
text = when {
isEnded -> resources.getQuantityString(R.plurals.poll_total_vote_count_after_ended, totalVotes, totalVotes)
didUserVoted -> resources.getQuantityString(R.plurals.poll_total_vote_count_before_ended_and_voted, totalVotes, totalVotes)
else -> resources.getQuantityString(R.plurals.poll_total_vote_count_before_ended_and_not_voted, totalVotes, totalVotes)
}
}
}
class Holder : AbsMessageItem.Holder(STUB_ID) {

View File

@ -59,7 +59,7 @@
style="@style/Widget.Vector.TextView.Caption"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="12dp"
android:layout_marginEnd="8dp"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="@id/optionVoteProgress"
app:layout_constraintEnd_toEndOf="parent"

View File

@ -3678,4 +3678,6 @@
<string name="labs_enable_polls">Enable Polls</string>
<string name="poll_response_room_list_preview">Vote casted</string>
<string name="poll_end_room_list_preview">Poll ended</string>
<string name="delete_poll_dialog_title">Remove poll</string>
<string name="delete_poll_dialog_content">Are you sure you want to remove this poll? You won\'t be able to recover it once removed.</string>
</resources>