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
This commit is contained in:
		| @@ -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), | ||||
|   })); | ||||
|  | ||||
|   | ||||
| @@ -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 && <span className={classNames('poll__input', { checkbox: poll.get('multiple'), active })} />} | ||||
|           {showResults && <span className='poll__number'>{Math.round(percent)}%</span>} | ||||
|           {showResults && <span className='poll__number'> | ||||
|             {!!voted && <Icon id='check' className='poll__vote__mark' />} | ||||
|             {Math.round(percent)}% | ||||
|           </span>} | ||||
|  | ||||
|           <span dangerouslySetInnerHTML={{ __html: titleEmojified }} /> | ||||
|         </label> | ||||
|   | ||||
| @@ -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 { | ||||
|   | ||||
| @@ -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? | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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>< | ||||
|   | ||||
		Reference in New Issue
	
	Block a user