Sfoglia il codice sorgente

Improve polls: option lengths & redesign (#13257)

This commit redesign the polls and increases characters limit for the
options from 25 to 50 characters, giving pollsters more freedom.

Summarizing, the redesign is making the polls more adaptive for upcoming
changes to the options characters limit: the bar, or a "chart", is now
displayed separately from the option itself; vote check mark is moved
next to the option text, making the percentages take less space. Option
lengths are taken into account and text is wrapped to multiple lines
if necessary to avoid overflow.
Sasha Sorokin 4 anni fa
parent
commit
37b3985bfa

+ 17 - 11
app/javascript/mastodon/components/poll.js

@@ -127,15 +127,7 @@ class Poll extends ImmutablePureComponent {
 
     return (
       <li key={option.get('title')}>
-        {showResults && (
-          <Motion defaultStyle={{ width: 0 }} style={{ width: spring(percent, { stiffness: 180, damping: 12 }) }}>
-            {({ width }) =>
-              <span className={classNames('poll__chart', { leading })} style={{ width: `${width}%` }} />
-            }
-          </Motion>
-        )}
-
-        <label className={classNames('poll__text', { selectable: !showResults })}>
+        <label className={classNames('poll__option', { selectable: !showResults })}>
           <input
             name='vote-options'
             type={poll.get('multiple') ? 'checkbox' : 'radio'}
@@ -157,12 +149,26 @@ class Poll extends ImmutablePureComponent {
             />
           )}
           {showResults && <span className='poll__number'>
-            {!!voted && <Icon id='check' className='poll__vote__mark' title={intl.formatMessage(messages.voted)} />}
             {Math.round(percent)}%
           </span>}
 
-          <span dangerouslySetInnerHTML={{ __html: titleEmojified }} />
+          <span
+            className='poll__option__text'
+            dangerouslySetInnerHTML={{ __html: titleEmojified }}
+          />
+
+          {!!voted && <span className='poll__voted'>
+            <Icon id='check' className='poll__voted__mark' title={intl.formatMessage(messages.voted)} />
+          </span>}
         </label>
+
+        {showResults && (
+          <Motion defaultStyle={{ width: 0 }} style={{ width: spring(percent, { stiffness: 180, damping: 12 }) }}>
+            {({ width }) =>
+              <span className={classNames('poll__chart', { leading })} style={{ width: `${width}%` }} />
+            }
+          </Motion>
+        )}
       </li>
     );
   }

+ 2 - 2
app/javascript/mastodon/features/compose/components/poll_form.js

@@ -75,7 +75,7 @@ class Option extends React.PureComponent {
 
     return (
       <li>
-        <label className='poll__text editable'>
+        <label className='poll__option editable'>
           <span
             className={classNames('poll__input', { checkbox: isPollMultiple })}
             onClick={this.handleToggleMultiple}
@@ -88,7 +88,7 @@ class Option extends React.PureComponent {
 
           <AutosuggestInput
             placeholder={intl.formatMessage(messages.option_placeholder, { number: index + 1 })}
-            maxLength={25}
+            maxLength={50}
             value={title}
             onChange={this.handleOptionTitleChange}
             suggestions={this.props.suggestions}

+ 1 - 1
app/javascript/styles/mastodon-light/diff.scss

@@ -142,7 +142,7 @@ html {
 }
 
 .compose-form__autosuggest-wrapper,
-.poll__text input[type="text"],
+.poll__option input[type="text"],
 .compose-form .spoiler-input__input,
 .compose-form__poll-wrapper select,
 .search__input,

+ 22 - 18
app/javascript/styles/mastodon/polls.scss

@@ -8,20 +8,18 @@
   }
 
   &__chart {
-    position: absolute;
-    top: 0;
-    left: 0;
-    height: 100%;
-    display: inline-block;
     border-radius: 4px;
-    background: darken($ui-primary-color, 14%);
+    display: block;
+    background: darken($ui-primary-color, 5%);
+    height: 5px;
+    min-width: 1%;
 
     &.leading {
       background: $ui-highlight-color;
     }
   }
 
-  &__text {
+  &__option {
     position: relative;
     display: flex;
     padding: 6px 0;
@@ -29,6 +27,13 @@
     cursor: default;
     overflow: hidden;
 
+    &__text {
+      display: inline-block;
+      word-wrap: break-word;
+      overflow-wrap: break-word;
+      max-width: calc(100% - 45px - 25px);
+    }
+
     input[type=radio],
     input[type=checkbox] {
       display: none;
@@ -112,19 +117,18 @@
 
   &__number {
     display: inline-block;
-    width: 52px;
+    width: 45px;
     font-weight: 700;
-    padding: 0 10px;
-    padding-left: 8px;
-    text-align: right;
-    margin-top: auto;
-    margin-bottom: auto;
-    flex: 0 0 52px;
+    flex: 0 0 45px;
   }
 
-  &__vote__mark {
-    float: left;
-    line-height: 18px;
+  &__voted {
+    padding: 0 5px;
+    display: inline-block;
+
+    &__mark {
+      font-size: 18px;
+    }
   }
 
   &__footer {
@@ -199,7 +203,7 @@
     display: flex;
     align-items: center;
 
-    .poll__text {
+    .poll__option {
       flex: 0 0 auto;
       width: calc(100% - (23px + 6px));
       margin-right: 6px;

+ 1 - 1
app/validators/poll_validator.rb

@@ -2,7 +2,7 @@
 
 class PollValidator < ActiveModel::Validator
   MAX_OPTIONS      = 4
-  MAX_OPTION_CHARS = 25
+  MAX_OPTION_CHARS = 50
   MAX_EXPIRATION   = 1.month.freeze
   MIN_EXPIRATION   = 5.minutes.freeze
 

+ 5 - 5
app/views/statuses/_poll.html.haml

@@ -8,16 +8,16 @@
       %li
         - if show_results
           - percent = total_votes_count > 0 ? 100 * option.votes_count / total_votes_count : 0
-          %span.poll__chart{ style: "width: #{percent}%" }
-
-          %label.poll__text><
+          %label.poll__option><
             %span.poll__number><
               - if own_votes.include?(index)
-                %i.poll__vote__mark.fa.fa-check
+                %i.poll__voted__mark.fa.fa-check
               = percent.round
             = Formatter.instance.format_poll_option(status, option, autoplay: autoplay)
+
+            %span.poll__chart{ style: "width: #{percent}%" }
         - else
-          %label.poll__text><
+          %label.poll__option><
             %span.poll__input{ class: poll.multiple? ? 'checkbox' : nil}><
             = Formatter.instance.format_poll_option(status, option, autoplay: autoplay)
   .poll__footer