From b359974d9b356bb723fe046466b178328cf9bbaf Mon Sep 17 00:00:00 2001 From: ThibG Date: Sun, 22 Sep 2019 14:15:18 +0200 Subject: Show user what options they have voted (#11195) * Add own_votes field to poll results in REST API Fixes #10679 * Display user votes in WebUI * Update styling * Add vote checkmark to public pages --- app/javascript/mastodon/actions/importer/normalizer.js | 3 ++- app/javascript/mastodon/components/poll.js | 7 ++++++- app/javascript/styles/mastodon/polls.scss | 10 ++++++++-- app/models/poll.rb | 4 ++++ app/serializers/rest/poll_serializer.rb | 5 +++++ app/views/statuses/_poll.html.haml | 8 ++++++-- 6 files changed, 31 insertions(+), 6 deletions(-) diff --git a/app/javascript/mastodon/actions/importer/normalizer.js b/app/javascript/mastodon/actions/importer/normalizer.js index 5e7e78e69..f7108fdb9 100644 --- a/app/javascript/mastodon/actions/importer/normalizer.js +++ b/app/javascript/mastodon/actions/importer/normalizer.js @@ -73,8 +73,9 @@ export function normalizePoll(poll) { const emojiMap = makeEmojiMap(normalPoll); - normalPoll.options = poll.options.map(option => ({ + normalPoll.options = poll.options.map((option, index) => ({ ...option, + voted: poll.own_votes && poll.own_votes.includes(index), title_emojified: emojify(escapeTextContentForBrowser(option.title), emojiMap), })); diff --git a/app/javascript/mastodon/components/poll.js b/app/javascript/mastodon/components/poll.js index 373f710d3..4c9b23b77 100644 --- a/app/javascript/mastodon/components/poll.js +++ b/app/javascript/mastodon/components/poll.js @@ -10,6 +10,7 @@ import spring from 'react-motion/lib/spring'; import escapeTextContentForBrowser from 'escape-html'; import emojify from 'mastodon/features/emoji/emoji'; import RelativeTimestamp from './relative_timestamp'; +import Icon from 'mastodon/components/icon'; const messages = defineMessages({ closed: { id: 'poll.closed', defaultMessage: 'Closed' }, @@ -103,6 +104,7 @@ class Poll extends ImmutablePureComponent { const percent = poll.get('votes_count') === 0 ? 0 : (option.get('votes_count') / poll.get('votes_count')) * 100; const leading = poll.get('options').filterNot(other => other.get('title') === option.get('title')).every(other => option.get('votes_count') > other.get('votes_count')); const active = !!this.state.selected[`${optionIndex}`]; + const voted = option.get('voted') || (poll.get('own_votes') && poll.get('own_votes').includes(optionIndex)); let titleEmojified = option.get('title_emojified'); if (!titleEmojified) { @@ -131,7 +133,10 @@ class Poll extends ImmutablePureComponent { /> {!showResults && } - {showResults && {Math.round(percent)}%} + {showResults && + {!!voted && } + {Math.round(percent)}% + } diff --git a/app/javascript/styles/mastodon/polls.scss b/app/javascript/styles/mastodon/polls.scss index e80220f27..85ba138b4 100644 --- a/app/javascript/styles/mastodon/polls.scss +++ b/app/javascript/styles/mastodon/polls.scss @@ -95,13 +95,19 @@ &__number { display: inline-block; - width: 36px; + width: 48px; font-weight: 700; padding: 0 10px; text-align: right; margin-top: auto; margin-bottom: auto; - flex: 0 0 36px; + flex: 0 0 48px; + } + + &__vote__mark { + float: left; + color: $valid-value-color; + line-height: 18px; } &__footer { diff --git a/app/models/poll.rb b/app/models/poll.rb index 8f72c7b11..55a8f13a6 100644 --- a/app/models/poll.rb +++ b/app/models/poll.rb @@ -54,6 +54,10 @@ class Poll < ApplicationRecord account.id == account_id || votes.where(account: account).exists? end + def own_votes(account) + votes.where(account: account).pluck(:choice) + end + delegate :local?, to: :account def remote? diff --git a/app/serializers/rest/poll_serializer.rb b/app/serializers/rest/poll_serializer.rb index 356c45b83..eb98bb2d2 100644 --- a/app/serializers/rest/poll_serializer.rb +++ b/app/serializers/rest/poll_serializer.rb @@ -8,6 +8,7 @@ class REST::PollSerializer < ActiveModel::Serializer has_many :emojis, serializer: REST::CustomEmojiSerializer attribute :voted, if: :current_user? + attribute :own_votes, if: :current_user? def id object.id.to_s @@ -21,6 +22,10 @@ class REST::PollSerializer < ActiveModel::Serializer object.voted?(current_user.account) end + def own_votes + object.own_votes(current_user.account) + end + def current_user? !current_user.nil? end diff --git a/app/views/statuses/_poll.html.haml b/app/views/statuses/_poll.html.haml index ba34890df..d6b36a5d1 100644 --- a/app/views/statuses/_poll.html.haml +++ b/app/views/statuses/_poll.html.haml @@ -1,15 +1,19 @@ - show_results = (user_signed_in? && poll.voted?(current_account)) || poll.expired? +- own_votes = user_signed_in? ? poll.own_votes(current_account) : [] .poll %ul - - poll.loaded_options.each do |option| + - poll.loaded_options.each_with_index do |option, index| %li - if show_results - percent = poll.votes_count > 0 ? 100 * option.votes_count / poll.votes_count : 0 %span.poll__chart{ style: "width: #{percent}%" } %label.poll__text>< - %span.poll__number= percent.round + %span.poll__number>< + - if own_votes.include?(index) + %i.poll__vote__mark.fa.fa-check + = percent.round = Formatter.instance.format_poll_option(status, option, autoplay: autoplay) - else %label.poll__text>< -- cgit