Merge pull request #229 from monich/poll

Tweaked poll/quiz layout
This commit is contained in:
Sebastian Wolf 2020-12-05 23:06:49 +01:00 committed by GitHub
commit 5d1a545317
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -26,27 +26,24 @@ import "../js/twemoji.js" as Emoji
Item { Item {
id: pollMessageComponent id: pollMessageComponent
property ListItem messageListItem property ListItem messageListItem
property MessageOverlayFlickable overlayFlickable property MessageOverlayFlickable overlayFlickable
property var rawMessage: messageListItem ? messageListItem.myMessage : overlayFlickable.overlayMessage readonly property var rawMessage: messageListItem ? messageListItem.myMessage : overlayFlickable.overlayMessage
property string chatId: rawMessage.chat_id readonly property string chatId: rawMessage.chat_id
readonly property bool isOwnMessage: messageListItem ? messageListItem.isOwnMessage : overlayFlickable.isOwnMessage
property bool isOwnMessage: messageListItem ? messageListItem.isOwnMessage : overlayFlickable.isOwnMessage readonly property string messageId: rawMessage.id
readonly property bool canEdit: rawMessage.can_be_edited
property string messageId: rawMessage.id readonly property var pollData: rawMessage.content.poll
property bool canEdit: rawMessage.can_be_edited
property var pollData: rawMessage.content.poll
property var chosenPollData:({}) property var chosenPollData:({})
property var chosenIndexes: [] property var chosenIndexes: []
property bool hasAnswered: { readonly property bool hasAnswered: {
return pollData.options.filter(function(option){ return pollData.options.filter(function(option){
return option.is_chosen return option.is_chosen
}).length > 0; }).length > 0;
} }
property bool canAnswer: !hasAnswered && !pollData.is_closed readonly property bool canAnswer: !hasAnswered && !pollData.is_closed
property bool isQuiz: pollData.type['@type'] === "pollTypeQuiz" readonly property bool isQuiz: pollData.type['@type'] === "pollTypeQuiz"
property bool highlighted; property bool highlighted
width: parent.width width: parent.width
height: pollColumn.height height: pollColumn.height
opacity: 0 opacity: 0
@ -78,6 +75,7 @@ Item {
id: pollColumn id: pollColumn
width: parent.width width: parent.width
spacing: Theme.paddingSmall spacing: Theme.paddingSmall
Label { Label {
font.pixelSize: Theme.fontSizeSmall font.pixelSize: Theme.fontSizeSmall
width: parent.width width: parent.width
@ -99,7 +97,7 @@ Item {
Item { Item {
visible: !pollMessageComponent.canAnswer visible: !pollMessageComponent.canAnswer
width: parent.width width: 1
height: Theme.paddingSmall height: Theme.paddingSmall
} }
@ -117,88 +115,89 @@ Item {
} }
} }
} }
Component { Component {
id: resultDelegate id: resultDelegate
Item { Row {
id: optionDelegate id: optionDelegate
width: pollMessageComponent.width height: Math.max(Theme.itemSizeExtraSmall, implicitHeight)
height: displayOptionLabel.height + displayOptionStatistics.height
Item {
height: parent.height
width: Theme.horizontalPageMargin/2
anchors.bottom: parent.bottom
Rectangle { Rectangle {
id: displayOptionChosenMarker id: displayOptionChosenMarker
height: parent.height anchors.fill: parent
width: Theme.horizontalPageMargin/2
color: Theme.rgba(Theme.highlightBackgroundColor, Theme.highlightBackgroundOpacity) color: Theme.rgba(Theme.highlightBackgroundColor, Theme.highlightBackgroundOpacity)
visible: modelData.is_chosen visible: modelData.is_chosen
x: -width
} }
OpacityRampEffect { OpacityRampEffect {
sourceItem: displayOptionChosenMarker sourceItem: displayOptionChosenMarker
direction: OpacityRamp.LeftToRight direction: OpacityRamp.LeftToRight
} }
Column {
id: iconsColumn
width: pollMessageComponent.isQuiz ?Theme.iconSizeSmall + Theme.paddingMedium : Theme.paddingMedium
anchors {
left: parent.left
verticalCenter: parent.verticalCenter
} }
Item {
width: Theme.paddingMedium + (pollMessageComponent.isQuiz ? Theme.iconSizeSmall : 0)
height: correctAnswerIcon.height
anchors {
bottom: parent.bottom
bottomMargin: (votePercentageBar.height - height)/2
}
Icon { Icon {
id: correctAnswerIcon
anchors.bottom: parent.bottom
highlighted: pollMessageComponent.isOwnMessage || pollMessageComponent.highlighted highlighted: pollMessageComponent.isOwnMessage || pollMessageComponent.highlighted
property bool isRight: pollMessageComponent.isQuiz && pollData.type.correct_option_id === index readonly property bool isRight: pollMessageComponent.isQuiz && pollData.type.correct_option_id === index
source: "image://theme/icon-s-accept" source: "image://theme/icon-s-accept"
visible: isRight visible: isRight
} }
} }
Column {
width: list.width - x
anchors.bottom: parent.bottom
Item {
width: parent.width
height: Math.max(voteTextLabel.height, votePercentageLabel.y + votePercentageLabel.height)
Label { Label {
id: displayOptionLabel id: voteTextLabel
property int lastLineWidth
width: parent.width
text: Emoji.emojify(modelData.text, Theme.fontSizeMedium) text: Emoji.emojify(modelData.text, Theme.fontSizeMedium)
textFormat: Text.StyledText textFormat: Text.StyledText
wrapMode: Text.WrapAtWordBoundaryOrAnywhere wrapMode: Text.WrapAtWordBoundaryOrAnywhere
anchors {
left: iconsColumn.right
top: parent.top
right: parent.right
}
color: pollMessageComponent.isOwnMessage || pollMessageComponent.highlighted ? Theme.highlightColor : Theme.primaryColor color: pollMessageComponent.isOwnMessage || pollMessageComponent.highlighted ? Theme.highlightColor : Theme.primaryColor
onTextChanged: lastLineWidth = 0
onLineLaidOut: {
if (line.isLast) {
lastLineWidth = line.x + line.implicitWidth
}
} }
Item {
id: displayOptionStatistics
height: optionVoterPercentage.height + optionVoterPercentageBar.height
anchors {
top: displayOptionLabel.bottom
left: iconsColumn.right
right: parent.right
} }
Label { Label {
id: optionVoterPercentage id: votePercentageLabel
y: (voteTextLabel.lastLineWidth + Theme.paddingLarge) > x ? voteTextLabel.height : Math.max(0, voteTextLabel.height - height)
font.pixelSize: Theme.fontSizeTiny font.pixelSize: Theme.fontSizeTiny
text: qsTr("%Ln\%", "% of votes for option", modelData.vote_percentage) text: qsTr("%Ln\%", "% of votes for option", modelData.vote_percentage)
horizontalAlignment: Text.AlignRight horizontalAlignment: Text.AlignRight
anchors { anchors.right: parent.right
right: parent.right
left: parent.horizontalCenter
leftMargin: Theme.paddingSmall
}
color: pollMessageComponent.isOwnMessage || pollMessageComponent.highlighted ? Theme.secondaryHighlightColor : Theme.secondaryColor color: pollMessageComponent.isOwnMessage || pollMessageComponent.highlighted ? Theme.secondaryHighlightColor : Theme.secondaryColor
} }
Rectangle {
id: optionVoterPercentageBar
height: Theme.paddingSmall
width: parent.width
color: Theme.rgba(pollMessageComponent.isOwnMessage || pollMessageComponent.highlighted ? Theme.secondaryHighlightColor : Theme.secondaryColor, 0.3)
radius: height/2
anchors {
left: parent.left
bottom: parent.bottom
} }
Rectangle {
id: votePercentageBar
height: Theme.paddingSmall
width: parent.width
color: Theme.rgba(pollMessageComponent.isOwnMessage || pollMessageComponent.highlighted ? Theme.secondaryHighlightColor : Theme.secondaryColor, 0.3)
radius: height/2
Rectangle { Rectangle {
height: parent.height height: parent.height
color: pollMessageComponent.isOwnMessage || pollMessageComponent.highlighted ? Theme.highlightColor : Theme.primaryColor color: pollMessageComponent.isOwnMessage || pollMessageComponent.highlighted ? Theme.highlightColor : Theme.primaryColor
@ -210,32 +209,35 @@ Item {
} }
} }
Repeater { ListView {
id: list
model: pollData.options model: pollData.options
x: -Theme.horizontalPageMargin/2
width: parent.width - x
height: contentHeight
interactive: false
delegate: pollMessageComponent.canAnswer ? canAnswerDelegate : resultDelegate delegate: pollMessageComponent.canAnswer ? canAnswerDelegate : resultDelegate
} }
Row { Item {
layoutDirection: Qt.RightToLeft width: 1
width: parent.width height: Theme.paddingSmall
spacing: Theme.paddingMedium
Behavior on height { NumberAnimation {}}
Label {
id: totalVoterCount
font.pixelSize: Theme.fontSizeTiny
anchors.verticalCenter: parent.verticalCenter
text: qsTr("%Ln vote(s) total", "number of total votes", pollData.total_voter_count)
width: contentWidth
height: contentHeight
horizontalAlignment: Text.AlignRight
color: pollMessageComponent.isOwnMessage || pollMessageComponent.highlighted ? Theme.secondaryHighlightColor : Theme.secondaryColor
} }
Item {
x: -Theme.horizontalPageMargin/2
width: parent.width - x
height: Math.max(voteButtons.height, totalVoterCount.height + Theme.paddingSmall)
Row { Row {
id: voteButtons
spacing: Theme.paddingSmall spacing: Theme.paddingSmall
width: parent.width - totalVoterCount.width - parent.spacing width: parent.width - totalVoterCount.width - parent.spacing
anchors {
left: parent.left
bottom: parent.bottom
}
IconButton { IconButton {
visible: !pollData.is_closed && pollMessageComponent.chosenIndexes.length > 0 && pollData.type.allow_multiple_answers && !pollMessageComponent.hasAnswered visible: !pollData.is_closed && pollMessageComponent.chosenIndexes.length > 0 && pollData.type.allow_multiple_answers && !pollMessageComponent.hasAnswered
opacity: visible ? 1.0 : 0.0 opacity: visible ? 1.0 : 0.0
@ -246,7 +248,6 @@ Item {
} }
} }
IconButton { IconButton {
visible: !pollMessageComponent.canAnswer && !pollData.is_anonymous && pollData.total_voter_count > 0 visible: !pollMessageComponent.canAnswer && !pollData.is_anonymous && pollData.total_voter_count > 0
icon.source: "image://theme/icon-m-media-artists" icon.source: "image://theme/icon-m-media-artists"
@ -263,9 +264,25 @@ Item {
} }
} }
} }
Label {
id: totalVoterCount
font.pixelSize: Theme.fontSizeTiny
anchors {
top: parent.top
right: parent.right
left: voteButtons.right
leftMargin: Theme.paddingMedium
}
text: qsTr("%Ln vote(s) total", "number of total votes", pollData.total_voter_count)
width: contentWidth
height: contentHeight
horizontalAlignment: Text.AlignRight
color: pollMessageComponent.isOwnMessage || pollMessageComponent.highlighted ? Theme.secondaryHighlightColor : Theme.secondaryColor
}
}
} }
}
Component { Component {
id: closePollMenuItemComponent id: closePollMenuItemComponent
MenuItem { MenuItem {
@ -276,6 +293,7 @@ Item {
} }
} }
} }
Component { Component {
id: resetAnswerMenuItemComponent id: resetAnswerMenuItemComponent
MenuItem { MenuItem {