diff --git a/src/components/poll/poll.js b/src/components/poll/poll.js new file mode 100644 index 00000000..4598207b --- /dev/null +++ b/src/components/poll/poll.js @@ -0,0 +1,90 @@ +import Timeago from '../timeago/timeago.vue' + +export default { + name: 'Poll', + props: ['poll', 'statusId'], + components: { Timeago }, + data () { + return { + loading: false, + multipleChoices: [], + singleChoiceIndex: null, + refreshInterval: null + } + }, + created () { + this.refreshInterval = setTimeout(this.refreshPoll, 30 * 1000) + }, + destroyed () { + clearTimeout(this.refreshInterval) + }, + computed: { + expired () { + return Date.now() > Date.parse(this.poll.expires_at) + }, + showResults () { + return this.poll.voted || this.expired + }, + totalVotesCount () { + return this.poll.votes_count + }, + expiresAt () { + return Date.parse(this.poll.expires_at).toLocaleString() + }, + containerClass () { + return { + loading: this.loading + } + }, + choiceIndices () { + return this.multipleChoices + .map((entry, index) => index) + .filter(value => typeof value === 'number') + }, + isDisabled () { + const noChoice = this.poll.multiple + ? this.choiceIndices.length === 0 + : this.singleChoiceIndex === undefined + return this.loading || noChoice + } + }, + methods: { + refreshPoll () { + if (this.expired) return + this.fetchPoll() + this.refreshInterval = setTimeout(this.refreshPoll, 30 * 1000) + }, + percentageForOption (count) { + return this.totalVotesCount === 0 ? 0 : Math.round((count + 5) / (this.totalVotesCount + 10) * 100) + }, + resultTitle (option) { + return `${option.votes_count}/${this.totalVotesCount} ${this.$t('polls.votes')}` + }, + fetchPoll () { + this.$store.dispatch('refreshPoll', { id: this.statusId, pollId: this.poll.id }) + }, + optionId (index) { + return `poll${this.poll.id}-${index}` + }, + vote () { + this.loading = true + if (this.poll.multiple) { + if (this.choiceIndices.length === 0) return + this.$store.dispatch( + 'votePoll', + { id: this.statusId, pollId: this.poll.id, choices: this.choiceIndices } + ).then(poll => { + this.loading = false + }) + } else { + if (this.singleChoiceIndex === undefined) return + this.$store.dispatch( + 'votePoll', + { id: this.statusId, pollId: this.poll.id, choices: [this.singleChoiceIndex] } + ).then(poll => { + this.loading = false + }) + } + } + } +} \ No newline at end of file diff --git a/src/components/poll/poll.vue b/src/components/poll/poll.vue index dd65935e..ec1000c5 100644 --- a/src/components/poll/poll.vue +++ b/src/components/poll/poll.vue @@ -1,34 +1,119 @@ - - + + + + + + {{percentageForOption(option.votes_count)}}% + + {{option.title}} + + + + + + + + + {{option.title}} + + + + + - -export default { - name: 'Poll', - props: ['poll', 'statusId'], - components: { - PollResults, - PollVote - }, - computed: { - currentUserHasVoted () { - return this.poll.voted - }, - voted () { - return this.poll.voted - } - }, + diff --git a/src/components/poll/poll_form/poll_form.vue b/src/components/poll/poll_form/poll_form.vue index 523145a9..77f97501 100644 --- a/src/components/poll/poll_form/poll_form.vue +++ b/src/components/poll/poll_form/poll_form.vue @@ -66,8 +66,8 @@ export default { data: () => ({ pollType: 'single', options: ['', ''], - expiryAmount: 1, - expiryUnit: 'minutes', + expiryAmount: 2, + expiryUnit: 'hours', expiryUnits: ['minutes', 'hours', 'days'] }), computed: { diff --git a/src/components/poll/poll_vote/poll_vote.vue b/src/components/poll/poll_vote/poll_vote.vue index 0791bfe6..3950312a 100644 --- a/src/components/poll/poll_vote/poll_vote.vue +++ b/src/components/poll/poll_vote/poll_vote.vue @@ -1,31 +1,38 @@ - + - - - - {{option.title}} - + + + {{percentageForOption(option.votes_count)}}% + {{option.title}} + + + + + + + + {{option.title}} + + - +