diff options
author | ThibG <thib@sitedethib.com> | 2019-09-22 14:15:18 +0200 |
---|---|---|
committer | Eugen Rochko <eugen@zeonfederated.com> | 2019-09-22 14:15:18 +0200 |
commit | b359974d9b356bb723fe046466b178328cf9bbaf (patch) | |
tree | bf8cb3887286aaced76a46ab80c7e250afbb763e | |
parent | 26b810561a5b7cfd1766699358d998b5882a5876 (diff) |
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
-rw-r--r-- | app/javascript/mastodon/actions/importer/normalizer.js | 3 | ||||
-rw-r--r-- | app/javascript/mastodon/components/poll.js | 7 | ||||
-rw-r--r-- | app/javascript/styles/mastodon/polls.scss | 10 | ||||
-rw-r--r-- | app/models/poll.rb | 4 | ||||
-rw-r--r-- | app/serializers/rest/poll_serializer.rb | 5 | ||||
-rw-r--r-- | 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 && <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> 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>< |