From 682cfbb829fe9e3a701dfd1dc3b1ab0b117f9208 Mon Sep 17 00:00:00 2001 From: Thibaut Girka Date: Sat, 31 Aug 2019 12:53:10 +0200 Subject: Fix imports importing modules from vanilla flavour instead of glitch --- app/javascript/flavours/glitch/components/poll.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'app/javascript/flavours/glitch/components/poll.js') diff --git a/app/javascript/flavours/glitch/components/poll.js b/app/javascript/flavours/glitch/components/poll.js index 690f9ae5a..36c4b236c 100644 --- a/app/javascript/flavours/glitch/components/poll.js +++ b/app/javascript/flavours/glitch/components/poll.js @@ -4,11 +4,11 @@ import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePureComponent from 'react-immutable-pure-component'; import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; import classNames from 'classnames'; -import { vote, fetchPoll } from 'mastodon/actions/polls'; -import Motion from 'mastodon/features/ui/util/optional_motion'; +import { vote, fetchPoll } from 'flavours/glitch/actions/polls'; +import Motion from 'flavours/glitch/util/optional_motion'; import spring from 'react-motion/lib/spring'; import escapeTextContentForBrowser from 'escape-html'; -import emojify from 'mastodon/features/emoji/emoji'; +import emojify from 'flavours/glitch/util/emoji'; import RelativeTimestamp from './relative_timestamp'; const messages = defineMessages({ -- cgit From 15a37a967cdf5bd1e935efc8866f6ac40d49db6b Mon Sep 17 00:00:00 2001 From: ThibG Date: Mon, 16 Sep 2019 14:32:26 +0200 Subject: [Glitch] Fix expiring polls not being displayed as such in the WebUI Port 524187b65344f6bcedb9bc188df7b6032540ac48 to glitch-soc Signed-off-by: Thibaut Girka --- app/javascript/flavours/glitch/components/poll.js | 40 ++++++++++++++++++++--- 1 file changed, 35 insertions(+), 5 deletions(-) (limited to 'app/javascript/flavours/glitch/components/poll.js') diff --git a/app/javascript/flavours/glitch/components/poll.js b/app/javascript/flavours/glitch/components/poll.js index 36c4b236c..905aa54c1 100644 --- a/app/javascript/flavours/glitch/components/poll.js +++ b/app/javascript/flavours/glitch/components/poll.js @@ -32,8 +32,38 @@ class Poll extends ImmutablePureComponent { state = { selected: {}, + expired: null, }; + static getDerivedStateFromProps (props, state) { + const { poll, intl } = props; + const expired = poll.get('expired') || (new Date(poll.get('expires_at'))).getTime() < intl.now(); + return (expired === state.expired) ? null : { expired }; + } + + componentDidMount () { + this._setupTimer(); + } + + componentDidUpdate () { + this._setupTimer(); + } + + componentWillUnmount () { + clearTimeout(this._timer); + } + + _setupTimer () { + const { poll, intl } = this.props; + clearTimeout(this._timer); + if (!this.state.expired) { + const delay = (new Date(poll.get('expires_at'))).getTime() - intl.now(); + this._timer = setTimeout(() => { + this.setState({ expired: true }); + }, delay); + } + } + handleOptionChange = e => { const { target: { value } } = e; @@ -68,12 +98,11 @@ class Poll extends ImmutablePureComponent { this.props.dispatch(fetchPoll(this.props.poll.get('id'))); }; - renderOption (option, optionIndex) { + renderOption (option, optionIndex, showResults) { const { poll, disabled } = this.props; 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 showResults = poll.get('voted') || poll.get('expired'); let titleEmojified = option.get('title_emojified'); if (!titleEmojified) { @@ -112,19 +141,20 @@ class Poll extends ImmutablePureComponent { render () { const { poll, intl } = this.props; + const { expired } = this.state; if (!poll) { return null; } - const timeRemaining = poll.get('expired') ? intl.formatMessage(messages.closed) : ; - const showResults = poll.get('voted') || poll.get('expired'); + const timeRemaining = expired ? intl.formatMessage(messages.closed) : ; + const showResults = poll.get('voted') || expired; const disabled = this.props.disabled || Object.entries(this.state.selected).every(item => !item); return (
    - {poll.get('options').map((option, i) => this.renderOption(option, i))} + {poll.get('options').map((option, i) => this.renderOption(option, i, showResults))}
-- cgit From e25b7feb72d0abc5e411fd32749c968041ade182 Mon Sep 17 00:00:00 2001 From: ThibG Date: Sun, 22 Sep 2019 14:15:18 +0200 Subject: [Glitch] Show user what options they have voted Port front-end changes from b359974d9b356bb723fe046466b178328cf9bbaf to glitch-soc Signed-off-by: Thibaut Girka --- app/javascript/flavours/glitch/actions/importer/normalizer.js | 3 ++- app/javascript/flavours/glitch/components/poll.js | 7 ++++++- app/javascript/flavours/glitch/styles/polls.scss | 10 ++++++++-- 3 files changed, 16 insertions(+), 4 deletions(-) (limited to 'app/javascript/flavours/glitch/components/poll.js') diff --git a/app/javascript/flavours/glitch/actions/importer/normalizer.js b/app/javascript/flavours/glitch/actions/importer/normalizer.js index 52d85c059..b35c4d7bd 100644 --- a/app/javascript/flavours/glitch/actions/importer/normalizer.js +++ b/app/javascript/flavours/glitch/actions/importer/normalizer.js @@ -71,8 +71,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/flavours/glitch/components/poll.js b/app/javascript/flavours/glitch/components/poll.js index 905aa54c1..e6cc809e0 100644 --- a/app/javascript/flavours/glitch/components/poll.js +++ b/app/javascript/flavours/glitch/components/poll.js @@ -10,6 +10,7 @@ import spring from 'react-motion/lib/spring'; import escapeTextContentForBrowser from 'escape-html'; import emojify from 'flavours/glitch/util/emoji'; import RelativeTimestamp from './relative_timestamp'; +import Icon from 'flavours/glitch/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/flavours/glitch/styles/polls.scss b/app/javascript/flavours/glitch/styles/polls.scss index 06f60408d..d1f69cd69 100644 --- a/app/javascript/flavours/glitch/styles/polls.scss +++ b/app/javascript/flavours/glitch/styles/polls.scss @@ -102,13 +102,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 { -- cgit From 98cc81c0e28144eda90a2d18198e7708b5e3d4b7 Mon Sep 17 00:00:00 2001 From: ThibG Date: Sat, 28 Sep 2019 19:41:36 +0200 Subject: [Glitch] Fix vote checkmark in poll results Port b0cda7a504655f6ced33802af67cabb6f3e46e19 to glitch-soc Signed-off-by: Thibaut Girka --- app/javascript/flavours/glitch/components/poll.js | 13 +++++++------ app/javascript/flavours/glitch/styles/polls.scss | 6 +++--- 2 files changed, 10 insertions(+), 9 deletions(-) (limited to 'app/javascript/flavours/glitch/components/poll.js') diff --git a/app/javascript/flavours/glitch/components/poll.js b/app/javascript/flavours/glitch/components/poll.js index e6cc809e0..2128bff61 100644 --- a/app/javascript/flavours/glitch/components/poll.js +++ b/app/javascript/flavours/glitch/components/poll.js @@ -14,6 +14,7 @@ import Icon from 'flavours/glitch/components/icon'; const messages = defineMessages({ closed: { id: 'poll.closed', defaultMessage: 'Closed' }, + voted: { id: 'poll.voted', defaultMessage: 'You voted for this answer', description: 'Tooltip of the "voted" checkmark in polls' }, }); const makeEmojiMap = record => record.get('emojis').reduce((obj, emoji) => { @@ -100,11 +101,11 @@ class Poll extends ImmutablePureComponent { }; renderOption (option, optionIndex, showResults) { - const { poll, disabled } = this.props; - 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)); + const { poll, disabled, intl } = this.props; + 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) { @@ -134,7 +135,7 @@ class Poll extends ImmutablePureComponent { {!showResults && } {showResults && - {!!voted && } + {!!voted && } {Math.round(percent)}% } diff --git a/app/javascript/flavours/glitch/styles/polls.scss b/app/javascript/flavours/glitch/styles/polls.scss index d1f69cd69..95d8e510c 100644 --- a/app/javascript/flavours/glitch/styles/polls.scss +++ b/app/javascript/flavours/glitch/styles/polls.scss @@ -102,18 +102,18 @@ &__number { display: inline-block; - width: 48px; + width: 52px; font-weight: 700; padding: 0 10px; + padding-left: 8px; text-align: right; margin-top: auto; margin-bottom: auto; - flex: 0 0 48px; + flex: 0 0 52px; } &__vote__mark { float: left; - color: $valid-value-color; line-height: 18px; } -- cgit From 332be562eab78975fdbf1e928cddbe7528d93468 Mon Sep 17 00:00:00 2001 From: ThibG Date: Sun, 29 Sep 2019 21:23:40 +0200 Subject: [Glitch] Change vote results to display ex-aequo leading options as leading Port 15b3eeb326d7e6a026235ece25c3be75250de92f to glitch-soc Signed-off-by: Thibaut Girka --- app/javascript/flavours/glitch/components/poll.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'app/javascript/flavours/glitch/components/poll.js') diff --git a/app/javascript/flavours/glitch/components/poll.js b/app/javascript/flavours/glitch/components/poll.js index 2128bff61..b431d2d8d 100644 --- a/app/javascript/flavours/glitch/components/poll.js +++ b/app/javascript/flavours/glitch/components/poll.js @@ -103,7 +103,7 @@ class Poll extends ImmutablePureComponent { renderOption (option, optionIndex, showResults) { const { poll, disabled, intl } = this.props; 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 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)); -- cgit From e5a50eda4c527040566918c717e32e9b3138bea9 Mon Sep 17 00:00:00 2001 From: ThibG Date: Sun, 29 Sep 2019 22:58:01 +0200 Subject: [Glitch] Add voters count support Port front-end changes from 3babf8464b0903b854ec16d355909444ef3ca0bc to glitch-soc Signed-off-by: Thibaut Girka --- app/javascript/flavours/glitch/components/poll.js | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'app/javascript/flavours/glitch/components/poll.js') diff --git a/app/javascript/flavours/glitch/components/poll.js b/app/javascript/flavours/glitch/components/poll.js index b431d2d8d..a7f9a97da 100644 --- a/app/javascript/flavours/glitch/components/poll.js +++ b/app/javascript/flavours/glitch/components/poll.js @@ -102,10 +102,11 @@ class Poll extends ImmutablePureComponent { renderOption (option, optionIndex, showResults) { const { poll, disabled, intl } = this.props; - 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)); + const pollVotesCount = poll.get('voters_count') || poll.get('votes_count'); + const percent = pollVotesCount === 0 ? 0 : (option.get('votes_count') / pollVotesCount) * 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) { @@ -157,6 +158,14 @@ class Poll extends ImmutablePureComponent { const showResults = poll.get('voted') || expired; const disabled = this.props.disabled || Object.entries(this.state.selected).every(item => !item); + let votesCount = null; + + if (poll.get('voters_count') !== null && poll.get('voters_count') !== undefined) { + votesCount = ; + } else { + votesCount = ; + } + return (
    @@ -166,7 +175,7 @@ class Poll extends ImmutablePureComponent {
    {!showResults && } {showResults && !this.props.disabled && · } - + {votesCount} {poll.get('expires_at') && · {timeRemaining}}
-- cgit From f2fc7246e12266b9dc4eff682b054372782e986c Mon Sep 17 00:00:00 2001 From: Takeshi Umeda Date: Sun, 27 Oct 2019 20:45:55 +0900 Subject: [Glitch] Fix an issue where polls with 'expires_at' not set expired Port 5b46467474dd88e1563561bf50643324b4f021e8 to glitch-soc Signed-off-by: Thibaut Girka --- app/javascript/flavours/glitch/components/poll.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'app/javascript/flavours/glitch/components/poll.js') diff --git a/app/javascript/flavours/glitch/components/poll.js b/app/javascript/flavours/glitch/components/poll.js index a7f9a97da..2d2a7cbe0 100644 --- a/app/javascript/flavours/glitch/components/poll.js +++ b/app/javascript/flavours/glitch/components/poll.js @@ -39,7 +39,8 @@ class Poll extends ImmutablePureComponent { static getDerivedStateFromProps (props, state) { const { poll, intl } = props; - const expired = poll.get('expired') || (new Date(poll.get('expires_at'))).getTime() < intl.now(); + const expires_at = poll.get('expires_at'); + const expired = poll.get('expired') || expires_at !== null && (new Date(expires_at)).getTime() < intl.now(); return (expired === state.expired) ? null : { expired }; } -- cgit From c6ba870f005e0393da6ba8de00246501623d52e7 Mon Sep 17 00:00:00 2001 From: ThibG Date: Tue, 3 Dec 2019 19:53:16 +0100 Subject: [Glitch] Fix poll options not being selectable via keyboard Port c05ed8a6254bc82fda3ae0fd3934dc2cdcf7c82d to glitch-soc Signed-off-by: Thibaut Girka --- app/javascript/flavours/glitch/components/poll.js | 28 +++++++++++++++++++---- app/javascript/flavours/glitch/styles/polls.scss | 17 ++++++++++++++ 2 files changed, 41 insertions(+), 4 deletions(-) (limited to 'app/javascript/flavours/glitch/components/poll.js') diff --git a/app/javascript/flavours/glitch/components/poll.js b/app/javascript/flavours/glitch/components/poll.js index 2d2a7cbe0..62965df94 100644 --- a/app/javascript/flavours/glitch/components/poll.js +++ b/app/javascript/flavours/glitch/components/poll.js @@ -67,9 +67,7 @@ class Poll extends ImmutablePureComponent { } } - handleOptionChange = e => { - const { target: { value } } = e; - + _toggleOption = value => { if (this.props.poll.get('multiple')) { const tmp = { ...this.state.selected }; if (tmp[value]) { @@ -83,8 +81,20 @@ class Poll extends ImmutablePureComponent { tmp[value] = true; this.setState({ selected: tmp }); } + } + + handleOptionChange = ({ target: { value } }) => { + this._toggleOption(value); }; + handleOptionKeyPress = (e) => { + if (e.key === 'Enter' || e.key === ' ') { + this._toggleOption(e.target.getAttribute('data-index')); + e.stopPropagation(); + e.preventDefault(); + } + } + handleVote = () => { if (this.props.disabled) { return; @@ -135,7 +145,17 @@ class Poll extends ImmutablePureComponent { disabled={disabled} /> - {!showResults && } + {!showResults && ( + + )} {showResults && {!!voted && } {Math.round(percent)}% diff --git a/app/javascript/flavours/glitch/styles/polls.scss b/app/javascript/flavours/glitch/styles/polls.scss index 95d8e510c..b43da1e28 100644 --- a/app/javascript/flavours/glitch/styles/polls.scss +++ b/app/javascript/flavours/glitch/styles/polls.scss @@ -98,6 +98,23 @@ border-color: $valid-value-color; background: $valid-value-color; } + + &:active, + &:focus, + &:hover { + border-width: 4px; + background: none; + } + + &::-moz-focus-inner { + outline: 0 !important; + border: 0; + } + + &:focus, + &:active { + outline: 0 !important; + } } &__number { -- cgit