Clarify poll choice logic a lot
This commit is contained in:
parent
8a4b64f9ff
commit
f11af28932
|
@ -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
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue