Merge pull request #2609 from element-hq/feature/bma/pollTrophy
Poll trophy
This commit is contained in:
commit
347da7bcdb
16 changed files with 104 additions and 55 deletions
1
changelog.d/2608.misc
Normal file
1
changelog.d/2608.misc
Normal file
|
|
@ -0,0 +1 @@
|
|||
Make completed poll more clearly visible
|
||||
|
|
@ -25,7 +25,7 @@ import io.element.android.libraries.matrix.api.poll.PollAnswer
|
|||
* @property isSelected whether the user has selected this answer.
|
||||
* @property isEnabled whether the answer can be voted.
|
||||
* @property isWinner whether this is the winner answer in the poll.
|
||||
* @property isDisclosed whether the votes for this answer should be disclosed.
|
||||
* @property showVotes whether the votes for this answer should be displayed.
|
||||
* @property votesCount the number of votes for this answer.
|
||||
* @property percentage the percentage of votes for this answer.
|
||||
*/
|
||||
|
|
@ -34,7 +34,7 @@ data class PollAnswerItem(
|
|||
val isSelected: Boolean,
|
||||
val isEnabled: Boolean,
|
||||
val isWinner: Boolean,
|
||||
val isDisclosed: Boolean,
|
||||
val showVotes: Boolean,
|
||||
val votesCount: Int,
|
||||
val percentage: Float,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ import io.element.android.libraries.designsystem.theme.components.LinearProgress
|
|||
import io.element.android.libraries.designsystem.theme.components.Text
|
||||
import io.element.android.libraries.designsystem.theme.progressIndicatorTrackColor
|
||||
import io.element.android.libraries.designsystem.toEnabledColor
|
||||
import io.element.android.libraries.designsystem.utils.CommonDrawables
|
||||
import io.element.android.libraries.ui.strings.CommonPlurals
|
||||
|
||||
@Composable
|
||||
|
|
@ -79,17 +80,36 @@ internal fun PollAnswerView(
|
|||
text = answerItem.answer.text,
|
||||
style = if (answerItem.isWinner) ElementTheme.typography.fontBodyLgMedium else ElementTheme.typography.fontBodyLgRegular,
|
||||
)
|
||||
if (answerItem.isDisclosed) {
|
||||
Text(
|
||||
modifier = Modifier.align(Alignment.Bottom),
|
||||
text = pluralStringResource(
|
||||
id = CommonPlurals.common_poll_votes_count,
|
||||
count = answerItem.votesCount,
|
||||
answerItem.votesCount
|
||||
),
|
||||
style = if (answerItem.isWinner) ElementTheme.typography.fontBodySmMedium else ElementTheme.typography.fontBodySmRegular,
|
||||
color = if (answerItem.isWinner) ElementTheme.colors.textPrimary else ElementTheme.colors.textSecondary,
|
||||
if (answerItem.showVotes) {
|
||||
val text = pluralStringResource(
|
||||
id = CommonPlurals.common_poll_votes_count,
|
||||
count = answerItem.votesCount,
|
||||
answerItem.votesCount
|
||||
)
|
||||
Row(
|
||||
modifier = Modifier.align(Alignment.Bottom),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
if (answerItem.isWinner) {
|
||||
Icon(
|
||||
resourceId = CommonDrawables.ic_winner,
|
||||
contentDescription = null,
|
||||
tint = ElementTheme.colors.iconAccentTertiary,
|
||||
)
|
||||
Spacer(modifier = Modifier.width(2.dp))
|
||||
Text(
|
||||
text = text,
|
||||
style = ElementTheme.typography.fontBodySmMedium,
|
||||
color = ElementTheme.colors.textPrimary,
|
||||
)
|
||||
} else {
|
||||
Text(
|
||||
text = text,
|
||||
style = ElementTheme.typography.fontBodySmRegular,
|
||||
color = ElementTheme.colors.textSecondary,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Spacer(modifier = Modifier.height(10.dp))
|
||||
|
|
@ -98,7 +118,7 @@ internal fun PollAnswerView(
|
|||
color = if (answerItem.isWinner) ElementTheme.colors.textSuccessPrimary else answerItem.isEnabled.toEnabledColor(),
|
||||
progress = {
|
||||
when {
|
||||
answerItem.isDisclosed -> answerItem.percentage
|
||||
answerItem.showVotes -> answerItem.percentage
|
||||
answerItem.isSelected -> 1f
|
||||
else -> 0f
|
||||
}
|
||||
|
|
@ -114,7 +134,7 @@ internal fun PollAnswerView(
|
|||
@Composable
|
||||
internal fun PollAnswerDisclosedNotSelectedPreview() = ElementPreview {
|
||||
PollAnswerView(
|
||||
answerItem = aPollAnswerItem(isDisclosed = true, isSelected = false),
|
||||
answerItem = aPollAnswerItem(showVotes = true, isSelected = false),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -122,7 +142,7 @@ internal fun PollAnswerDisclosedNotSelectedPreview() = ElementPreview {
|
|||
@Composable
|
||||
internal fun PollAnswerDisclosedSelectedPreview() = ElementPreview {
|
||||
PollAnswerView(
|
||||
answerItem = aPollAnswerItem(isDisclosed = true, isSelected = true),
|
||||
answerItem = aPollAnswerItem(showVotes = true, isSelected = true),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -130,7 +150,7 @@ internal fun PollAnswerDisclosedSelectedPreview() = ElementPreview {
|
|||
@Composable
|
||||
internal fun PollAnswerUndisclosedNotSelectedPreview() = ElementPreview {
|
||||
PollAnswerView(
|
||||
answerItem = aPollAnswerItem(isDisclosed = false, isSelected = false),
|
||||
answerItem = aPollAnswerItem(showVotes = false, isSelected = false),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -138,7 +158,7 @@ internal fun PollAnswerUndisclosedNotSelectedPreview() = ElementPreview {
|
|||
@Composable
|
||||
internal fun PollAnswerUndisclosedSelectedPreview() = ElementPreview {
|
||||
PollAnswerView(
|
||||
answerItem = aPollAnswerItem(isDisclosed = false, isSelected = true),
|
||||
answerItem = aPollAnswerItem(showVotes = false, isSelected = true),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -146,7 +166,7 @@ internal fun PollAnswerUndisclosedSelectedPreview() = ElementPreview {
|
|||
@Composable
|
||||
internal fun PollAnswerEndedWinnerNotSelectedPreview() = ElementPreview {
|
||||
PollAnswerView(
|
||||
answerItem = aPollAnswerItem(isDisclosed = true, isSelected = false, isEnabled = false, isWinner = true),
|
||||
answerItem = aPollAnswerItem(showVotes = true, isSelected = false, isEnabled = false, isWinner = true),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -154,7 +174,7 @@ internal fun PollAnswerEndedWinnerNotSelectedPreview() = ElementPreview {
|
|||
@Composable
|
||||
internal fun PollAnswerEndedWinnerSelectedPreview() = ElementPreview {
|
||||
PollAnswerView(
|
||||
answerItem = aPollAnswerItem(isDisclosed = true, isSelected = true, isEnabled = false, isWinner = true),
|
||||
answerItem = aPollAnswerItem(showVotes = true, isSelected = true, isEnabled = false, isWinner = true),
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -162,6 +182,6 @@ internal fun PollAnswerEndedWinnerSelectedPreview() = ElementPreview {
|
|||
@Composable
|
||||
internal fun PollAnswerEndedSelectedPreview() = ElementPreview {
|
||||
PollAnswerView(
|
||||
answerItem = aPollAnswerItem(isDisclosed = true, isSelected = true, isEnabled = false, isWinner = false),
|
||||
answerItem = aPollAnswerItem(showVotes = true, isSelected = true, isEnabled = false, isWinner = false),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,11 +27,11 @@ fun aPollQuestion() = "What type of food should we have at the party?"
|
|||
fun aPollAnswerItemList(
|
||||
hasVotes: Boolean = true,
|
||||
isEnded: Boolean = false,
|
||||
isDisclosed: Boolean = true,
|
||||
showVotes: Boolean = true,
|
||||
) = persistentListOf(
|
||||
aPollAnswerItem(
|
||||
answer = PollAnswer("option_1", "Italian \uD83C\uDDEE\uD83C\uDDF9"),
|
||||
isDisclosed = isDisclosed,
|
||||
showVotes = showVotes,
|
||||
isEnabled = !isEnded,
|
||||
isWinner = isEnded,
|
||||
votesCount = if (hasVotes) 5 else 0,
|
||||
|
|
@ -39,7 +39,7 @@ fun aPollAnswerItemList(
|
|||
),
|
||||
aPollAnswerItem(
|
||||
answer = PollAnswer("option_2", "Chinese \uD83C\uDDE8\uD83C\uDDF3"),
|
||||
isDisclosed = isDisclosed,
|
||||
showVotes = showVotes,
|
||||
isEnabled = !isEnded,
|
||||
isWinner = false,
|
||||
votesCount = 0,
|
||||
|
|
@ -47,7 +47,7 @@ fun aPollAnswerItemList(
|
|||
),
|
||||
aPollAnswerItem(
|
||||
answer = PollAnswer("option_3", "Brazilian \uD83C\uDDE7\uD83C\uDDF7"),
|
||||
isDisclosed = isDisclosed,
|
||||
showVotes = showVotes,
|
||||
isEnabled = !isEnded,
|
||||
isWinner = false,
|
||||
isSelected = true,
|
||||
|
|
@ -55,7 +55,7 @@ fun aPollAnswerItemList(
|
|||
percentage = if (hasVotes) 0.1f else 0f
|
||||
),
|
||||
aPollAnswerItem(
|
||||
isDisclosed = isDisclosed,
|
||||
showVotes = showVotes,
|
||||
isEnabled = !isEnded,
|
||||
votesCount = if (hasVotes) 4 else 0,
|
||||
percentage = if (hasVotes) 0.4f else 0f,
|
||||
|
|
@ -70,7 +70,7 @@ fun aPollAnswerItem(
|
|||
isSelected: Boolean = false,
|
||||
isEnabled: Boolean = true,
|
||||
isWinner: Boolean = false,
|
||||
isDisclosed: Boolean = true,
|
||||
showVotes: Boolean = true,
|
||||
votesCount: Int = 4,
|
||||
percentage: Float = 0.4f,
|
||||
) = PollAnswerItem(
|
||||
|
|
@ -78,7 +78,7 @@ fun aPollAnswerItem(
|
|||
isSelected = isSelected,
|
||||
isEnabled = isEnabled,
|
||||
isWinner = isWinner,
|
||||
isDisclosed = isDisclosed,
|
||||
showVotes = showVotes,
|
||||
votesCount = votesCount,
|
||||
percentage = percentage
|
||||
)
|
||||
|
|
@ -87,14 +87,14 @@ fun aPollContentState(
|
|||
eventId: EventId? = null,
|
||||
isMine: Boolean = false,
|
||||
isEnded: Boolean = false,
|
||||
isDisclosed: Boolean = true,
|
||||
showVotes: Boolean = true,
|
||||
isPollEditable: Boolean = true,
|
||||
hasVotes: Boolean = true,
|
||||
question: String = aPollQuestion(),
|
||||
pollKind: PollKind = PollKind.Disclosed,
|
||||
answerItems: ImmutableList<PollAnswerItem> = aPollAnswerItemList(
|
||||
isEnded = isEnded,
|
||||
isDisclosed = isDisclosed,
|
||||
showVotes = showVotes,
|
||||
hasVotes = hasVotes
|
||||
),
|
||||
) = PollContentState(
|
||||
|
|
|
|||
|
|
@ -245,7 +245,7 @@ internal fun PollContentUndisclosedPreview() = ElementPreview {
|
|||
PollContentView(
|
||||
eventId = EventId("\$anEventId"),
|
||||
question = "What type of food should we have at the party?",
|
||||
answerItems = aPollAnswerItemList(isDisclosed = false),
|
||||
answerItems = aPollAnswerItemList(showVotes = false),
|
||||
pollKind = PollKind.Undisclosed,
|
||||
isPollEnded = false,
|
||||
isPollEditable = false,
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ class DefaultPollContentStateFactory @Inject constructor(
|
|||
isSelected = isSelected,
|
||||
isEnabled = !isPollEnded,
|
||||
isWinner = isWinner,
|
||||
isDisclosed = content.kind.isDisclosed || isPollEnded,
|
||||
showVotes = content.kind.isDisclosed || isPollEnded,
|
||||
votesCount = answerVoteCount,
|
||||
percentage = percentage,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -131,7 +131,7 @@ class PollContentStateFactoryTest {
|
|||
val state = factory.create(eventTimelineItem, aPollContent(PollKind.Undisclosed))
|
||||
val expectedState = aPollContentState(pollKind = PollKind.Undisclosed).let {
|
||||
it.copy(
|
||||
answerItems = it.answerItems.map { answerItem -> answerItem.copy(isDisclosed = false) }.toImmutableList()
|
||||
answerItems = it.answerItems.map { answerItem -> answerItem.copy(showVotes = false) }.toImmutableList()
|
||||
)
|
||||
}
|
||||
assertThat(state).isEqualTo(expectedState)
|
||||
|
|
@ -147,10 +147,10 @@ class PollContentStateFactoryTest {
|
|||
val expectedState = aPollContentState(
|
||||
pollKind = PollKind.Undisclosed,
|
||||
answerItems = listOf(
|
||||
aPollAnswerItem(answer = A_POLL_ANSWER_1, isDisclosed = false, votesCount = 3, percentage = 0.3f),
|
||||
aPollAnswerItem(answer = A_POLL_ANSWER_2, isDisclosed = false, isSelected = true, votesCount = 6, percentage = 0.6f),
|
||||
aPollAnswerItem(answer = A_POLL_ANSWER_3, isDisclosed = false),
|
||||
aPollAnswerItem(answer = A_POLL_ANSWER_4, isDisclosed = false, votesCount = 1, percentage = 0.1f),
|
||||
aPollAnswerItem(answer = A_POLL_ANSWER_1, showVotes = false, votesCount = 3, percentage = 0.3f),
|
||||
aPollAnswerItem(answer = A_POLL_ANSWER_2, showVotes = false, isSelected = true, votesCount = 6, percentage = 0.6f),
|
||||
aPollAnswerItem(answer = A_POLL_ANSWER_3, showVotes = false),
|
||||
aPollAnswerItem(answer = A_POLL_ANSWER_4, showVotes = false, votesCount = 1, percentage = 0.1f),
|
||||
),
|
||||
)
|
||||
assertThat(state).isEqualTo(expectedState)
|
||||
|
|
@ -164,7 +164,7 @@ class PollContentStateFactoryTest {
|
|||
pollKind = PollKind.Undisclosed
|
||||
).let {
|
||||
it.copy(
|
||||
answerItems = it.answerItems.map { answerItem -> answerItem.copy(isDisclosed = true, isEnabled = false) }.toImmutableList(),
|
||||
answerItems = it.answerItems.map { answerItem -> answerItem.copy(showVotes = true, isEnabled = false) }.toImmutableList(),
|
||||
)
|
||||
}
|
||||
assertThat(state).isEqualTo(expectedState)
|
||||
|
|
@ -258,7 +258,7 @@ class PollContentStateFactoryTest {
|
|||
isSelected: Boolean = false,
|
||||
isEnabled: Boolean = true,
|
||||
isWinner: Boolean = false,
|
||||
isDisclosed: Boolean = true,
|
||||
showVotes: Boolean = true,
|
||||
votesCount: Int = 0,
|
||||
percentage: Float = 0f,
|
||||
) = PollAnswerItem(
|
||||
|
|
@ -266,7 +266,7 @@ class PollContentStateFactoryTest {
|
|||
isSelected = isSelected,
|
||||
isEnabled = isEnabled,
|
||||
isWinner = isWinner,
|
||||
isDisclosed = isDisclosed,
|
||||
showVotes = showVotes,
|
||||
votesCount = votesCount,
|
||||
percentage = percentage,
|
||||
)
|
||||
|
|
|
|||
28
libraries/designsystem/src/main/res/drawable/ic_winner.xml
Normal file
28
libraries/designsystem/src/main/res/drawable/ic_winner.xml
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
<!--
|
||||
~ Copyright (c) 2024 New Vector Ltd
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="16dp"
|
||||
android:height="16dp"
|
||||
android:viewportWidth="16"
|
||||
android:viewportHeight="16">
|
||||
<group>
|
||||
<clip-path android:pathData="M0,0h16v16h-16z" />
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M12.667,3.333H11.333V2.667C11.333,2.3 11.033,2 10.667,2H5.333C4.967,2 4.667,2.3 4.667,2.667V3.333H3.333C2.6,3.333 2,3.933 2,4.667V5.333C2,7.033 3.28,8.42 4.927,8.627C5.347,9.627 6.247,10.38 7.333,10.6V12.667H5.333C4.967,12.667 4.667,12.967 4.667,13.333C4.667,13.7 4.967,14 5.333,14H10.667C11.033,14 11.333,13.7 11.333,13.333C11.333,12.967 11.033,12.667 10.667,12.667H8.667V10.6C9.753,10.38 10.653,9.627 11.073,8.627C12.72,8.42 14,7.033 14,5.333V4.667C14,3.933 13.4,3.333 12.667,3.333ZM3.333,5.333V4.667H4.667V7.213C3.893,6.933 3.333,6.2 3.333,5.333ZM12.667,5.333C12.667,6.2 12.107,6.933 11.333,7.213V4.667H12.667V5.333Z" />
|
||||
</group>
|
||||
</vector>
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:013bfb3d3bd78d8db9f0ac51b11a41c2b82daaa28f87cdfd866260d3fb40bf0d
|
||||
size 23125
|
||||
oid sha256:5855e940f101e95ff1b0f01418240fc826543528e071193ede089b740d763b4e
|
||||
size 23575
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:7c039ab6649ff160b540256dacba1037b15c5907d9994a041cbab3be0ee5cacd
|
||||
size 21283
|
||||
oid sha256:651a5479a412f527fc1cae7b5b34ec7a53aa84ec06c97f64d84e0ee6dd5a03d4
|
||||
size 21734
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:a99ff857afe6478e579c96b984e1abdbf981638e6964a7d2c94b53153aff078d
|
||||
size 23135
|
||||
oid sha256:8fc99783d3ecf3be99b2ae66d20072fcff29f04d5dc3c0ad59904421168559f2
|
||||
size 23582
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:d97ba3288f5fcdaaed917a994df9273d3e82d5a6e0c7978044dbaf03152e3269
|
||||
size 21270
|
||||
oid sha256:1b4f569efd9c37fc699b2833e69794094d2f9e0188805192a0a13cb01a96d0e7
|
||||
size 21723
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:c2730173af19765a502b68278e709f441a1ddbfae88024b416029f7c87a21537
|
||||
size 49108
|
||||
oid sha256:6b4eb2a1fa6bd966b4031df5af47c019af6500a4e36c95495619d149b90fb8c6
|
||||
size 49376
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:2d7cf73a11d38d17cd6ddbfd1819757a8f9db9db75da225ed0a9d9467644847e
|
||||
size 45981
|
||||
oid sha256:9049f20df151c4ec18be7fd58813b00d2c647118e558eaa491e9aa71a9d882f6
|
||||
size 46313
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:c2730173af19765a502b68278e709f441a1ddbfae88024b416029f7c87a21537
|
||||
size 49108
|
||||
oid sha256:6b4eb2a1fa6bd966b4031df5af47c019af6500a4e36c95495619d149b90fb8c6
|
||||
size 49376
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:2d7cf73a11d38d17cd6ddbfd1819757a8f9db9db75da225ed0a9d9467644847e
|
||||
size 45981
|
||||
oid sha256:9049f20df151c4ec18be7fd58813b00d2c647118e558eaa491e9aa71a9d882f6
|
||||
size 46313
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue