Clarify poll choice logic a lot

This commit is contained in:
shpuld 2019-06-18 23:13:31 +03:00
parent 8a4b64f9ff
commit f11af28932
1 changed files with 22 additions and 35 deletions

View File

@ -1,5 +1,5 @@
import Timeago from '../timeago/timeago.vue' import Timeago from '../timeago/timeago.vue'
import { forEach } from 'lodash' import { forEach, map } from 'lodash'
export default { export default {
name: 'Poll', name: 'Poll',
@ -8,14 +8,14 @@ export default {
data () { data () {
return { return {
loading: false, loading: false,
multipleChoices: [], choices: [],
singleChoiceIndex: null,
refreshInterval: null refreshInterval: null
} }
}, },
created () { created () {
this.refreshInterval = setTimeout(this.refreshPoll, 30 * 1000) this.refreshInterval = setTimeout(this.refreshPoll, 30 * 1000)
this.multipleChoices = this.poll.options.map(_ => false) // Initialize choices to booleans and set its length to match options
this.choices = this.poll.options.map(_ => false)
}, },
destroyed () { destroyed () {
clearTimeout(this.refreshInterval) clearTimeout(this.refreshInterval)
@ -42,14 +42,15 @@ export default {
} }
}, },
choiceIndices () { choiceIndices () {
return this.multipleChoices // Convert array of booleans into an array of indices of the
// items that were 'true', so [true, false, false, true] becomes
// [0, 3].
return this.choices
.map((entry, index) => entry && index) .map((entry, index) => entry && index)
.filter(value => typeof value === 'number') .filter(value => typeof value === 'number')
}, },
isDisabled () { isDisabled () {
const noChoice = this.poll.multiple const noChoice = this.choiceIndices.length === 0
? this.choiceIndices.length === 0
: this.singleChoiceIndex === undefined
return this.loading || noChoice return this.loading || noChoice
} }
}, },
@ -77,44 +78,30 @@ export default {
// same poll appears multiple times on the site (notifs and // same poll appears multiple times on the site (notifs and
// timeline for example). With code we can make sure it just // timeline for example). With code we can make sure it just
// works without altering the pseudo element implementation. // works without altering the pseudo element implementation.
const allElements = this.$el.querySelectorAll('input')
const clickedElement = this.$el.querySelector(`input[value="${index}"]`) const clickedElement = this.$el.querySelector(`input[value="${index}"]`)
if (this.poll.multiple) { if (this.poll.multiple) {
// Checkboxes // Checkboxes, toggle only the clicked one
const wasChecked = this.multipleChoices[index] clickedElement.checked = !clickedElement.checked
clickedElement.checked = !wasChecked
this.$set(this.multipleChoices, index, !wasChecked)
} else { } else {
// Radio button // Radio button, uncheck everything and check the clicked one
const allElements = this.$el.querySelectorAll('input') forEach(allElements, element => { element.checked = false })
forEach(allElements, element => {
element.checked = false
})
clickedElement.checked = true clickedElement.checked = true
this.singleChoiceIndex = index
} }
this.choices = map(allElements, e => e.checked)
}, },
optionId (index) { optionId (index) {
return `poll${this.poll.id}-${index}` return `poll${this.poll.id}-${index}`
}, },
vote () { vote () {
this.loading = true
if (this.poll.multiple) {
if (this.choiceIndices.length === 0) return if (this.choiceIndices.length === 0) return
this.loading = true
this.$store.dispatch( this.$store.dispatch(
'votePoll', 'votePoll',
{ id: this.statusId, pollId: this.poll.id, choices: this.choiceIndices } { id: this.statusId, pollId: this.poll.id, choices: this.choiceIndices }
).then(poll => { ).then(poll => {
this.loading = false 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
})
}
} }
} }
} }