Move poll state handling to its own module
This commit is contained in:
parent
eca533aab6
commit
e5e9bb27f3
6 changed files with 96 additions and 34 deletions
|
@ -3,26 +3,33 @@ import { forEach, map } from 'lodash'
|
|||
|
||||
export default {
|
||||
name: 'Poll',
|
||||
props: ['poll', 'statusId'],
|
||||
props: ['pollId'],
|
||||
components: { Timeago },
|
||||
data () {
|
||||
return {
|
||||
loading: false,
|
||||
choices: [],
|
||||
refreshInterval: null
|
||||
choices: []
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.refreshInterval = setTimeout(this.refreshPoll, 30 * 1000)
|
||||
// Initialize choices to booleans and set its length to match options
|
||||
this.choices = this.poll.options.map(_ => false)
|
||||
mounted () {
|
||||
this.$store.dispatch('trackPoll', this.pollId)
|
||||
},
|
||||
destroyed () {
|
||||
clearTimeout(this.refreshInterval)
|
||||
this.$store.dispatch('untrackPoll', this.pollId)
|
||||
},
|
||||
computed: {
|
||||
poll () {
|
||||
const storePoll = this.$store.state.polls.pollsObject[this.pollId]
|
||||
return storePoll || {}
|
||||
},
|
||||
options () {
|
||||
return (this.poll && this.poll.options) || []
|
||||
},
|
||||
expiresAt () {
|
||||
return (this.poll && this.poll.expires_at) || 0
|
||||
},
|
||||
expired () {
|
||||
return Date.now() > Date.parse(this.poll.expires_at)
|
||||
return Date.now() > Date.parse(this.expiresAt)
|
||||
},
|
||||
loggedIn () {
|
||||
return this.$store.state.users.currentUser
|
||||
|
@ -33,9 +40,6 @@ export default {
|
|||
totalVotesCount () {
|
||||
return this.poll.votes_count
|
||||
},
|
||||
expiresAt () {
|
||||
return Date.parse(this.poll.expires_at).toLocaleString()
|
||||
},
|
||||
containerClass () {
|
||||
return {
|
||||
loading: this.loading
|
||||
|
@ -55,11 +59,6 @@ export default {
|
|||
}
|
||||
},
|
||||
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 / this.totalVotesCount * 100)
|
||||
},
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<div class="poll" v-bind:class="containerClass">
|
||||
<div
|
||||
class="poll-option"
|
||||
v-for="(option, index) in poll.options"
|
||||
v-for="(option, index) in options"
|
||||
:key="index"
|
||||
>
|
||||
<div v-if="showResults" :title="resultTitle(option)" class="option-result">
|
||||
|
@ -50,7 +50,7 @@
|
|||
{{totalVotesCount}} {{ $t("polls.votes") }} ·
|
||||
</div>
|
||||
<i18n :path="expired ? 'polls.expired' : 'polls.expires_in'">
|
||||
<Timeago :time="this.poll.expires_at" :auto-update="60" :now-threshold="0" />
|
||||
<Timeago :time="this.expiresAt" :auto-update="60" :now-threshold="0" />
|
||||
</i18n>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -124,7 +124,7 @@
|
|||
</div>
|
||||
|
||||
<div v-if="status.poll && status.poll.options">
|
||||
<poll :poll="status.poll" :status-id="status.id" />
|
||||
<poll :poll-id="status.poll.id" />
|
||||
</div>
|
||||
|
||||
<div v-if="status.attachments && (!hideSubjectStatus || showingLongSubject)" class="attachments media-body">
|
||||
|
|
|
@ -14,6 +14,7 @@ import authFlowModule from './modules/auth_flow.js'
|
|||
import mediaViewerModule from './modules/media_viewer.js'
|
||||
import oauthTokensModule from './modules/oauth_tokens.js'
|
||||
import reportsModule from './modules/reports.js'
|
||||
import pollsModule from './modules/polls.js'
|
||||
|
||||
import VueI18n from 'vue-i18n'
|
||||
|
||||
|
@ -72,7 +73,8 @@ const persistedStateOptions = {
|
|||
authFlow: authFlowModule,
|
||||
mediaViewer: mediaViewerModule,
|
||||
oauthTokens: oauthTokensModule,
|
||||
reports: reportsModule
|
||||
reports: reportsModule,
|
||||
polls: pollsModule
|
||||
},
|
||||
plugins: [persistedState, pushNotifications],
|
||||
strict: false // Socket modifies itself, let's ignore this for now.
|
||||
|
|
73
src/modules/polls.js
Normal file
73
src/modules/polls.js
Normal file
|
@ -0,0 +1,73 @@
|
|||
import { each, merge } from 'lodash'
|
||||
import { set } from 'vue'
|
||||
|
||||
const polls = {
|
||||
state: {
|
||||
// Contains key = id, value = number of trackers for this poll
|
||||
trackedPolls: {},
|
||||
pollsObject: {}
|
||||
},
|
||||
mutations: {
|
||||
addNewStatuses (state, { statuses }) {
|
||||
each(statuses, status => {
|
||||
if (status.poll) {
|
||||
set(state.pollsObject, status.poll.id, status.poll)
|
||||
}
|
||||
})
|
||||
},
|
||||
mergePoll (state, poll) {
|
||||
state.pollsObject[poll.id] = merge(state.pollsObject[poll.id], poll)
|
||||
},
|
||||
trackPoll (state, pollId) {
|
||||
const currentValue = state.trackedPolls[pollId]
|
||||
if (currentValue) {
|
||||
set(state.trackedPolls, pollId, currentValue + 1)
|
||||
} else {
|
||||
set(state.trackedPolls, pollId, 1)
|
||||
}
|
||||
},
|
||||
untrackPoll (state, pollId) {
|
||||
const currentValue = state.trackedPolls[pollId]
|
||||
if (currentValue) {
|
||||
set(state.trackedPolls, pollId, currentValue - 1)
|
||||
} else {
|
||||
set(state.trackedPolls, pollId, 0)
|
||||
}
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
updatePoll ({ rootState, commit }, pollId) {
|
||||
return rootState.api.backendInteractor.fetchPoll(pollId).then(poll => {
|
||||
commit('mergePoll', poll)
|
||||
return poll
|
||||
})
|
||||
},
|
||||
updateTrackedPoll ({ rootState, dispatch, commit }, pollId) {
|
||||
rootState.api.backendInteractor.fetchPoll(pollId).then(poll => {
|
||||
setTimeout(() => {
|
||||
if (rootState.polls.trackedPolls[pollId]) {
|
||||
dispatch('updateTrackedPoll', pollId)
|
||||
}
|
||||
}, 30 * 1000)
|
||||
commit('mergePoll', poll)
|
||||
})
|
||||
},
|
||||
trackPoll ({ rootState, commit, dispatch }, pollId) {
|
||||
if (!rootState.polls.trackedPolls[pollId]) {
|
||||
setTimeout(() => dispatch('updateTrackedPoll', pollId), 30 * 1000)
|
||||
}
|
||||
commit('trackPoll', pollId)
|
||||
},
|
||||
untrackPoll ({ commit }, pollId) {
|
||||
commit('untrackPoll', pollId)
|
||||
},
|
||||
votePoll ({ rootState, commit }, { id, pollId, choices }) {
|
||||
return rootState.api.backendInteractor.vote(pollId, choices).then(poll => {
|
||||
commit('mergePoll', poll)
|
||||
return poll
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default polls
|
|
@ -582,18 +582,6 @@ const statuses = {
|
|||
]).then(([favoritedByUsers, rebloggedByUsers]) =>
|
||||
commit('addFavsAndRepeats', { id, favoritedByUsers, rebloggedByUsers })
|
||||
)
|
||||
},
|
||||
votePoll ({ rootState, commit }, { id, pollId, choices }) {
|
||||
return rootState.api.backendInteractor.vote(pollId, choices).then(poll => {
|
||||
commit('updateStatusWithPoll', { id, poll })
|
||||
return poll
|
||||
})
|
||||
},
|
||||
refreshPoll ({ rootState, commit }, { id, pollId }) {
|
||||
return rootState.api.backendInteractor.fetchPoll(pollId).then(poll => {
|
||||
commit('updateStatusWithPoll', { id, poll })
|
||||
return poll
|
||||
})
|
||||
}
|
||||
},
|
||||
mutations
|
||||
|
|
Loading…
Reference in a new issue