refs #874 Show voted polls with percentage in timeline
This commit is contained in:
parent
3d862068c0
commit
369ff3097b
|
@ -1,11 +1,22 @@
|
|||
<template>
|
||||
<div class="poll">
|
||||
<ul class="poll-list" v-if="poll">
|
||||
<li v-for="(option, id) in poll.options" v-bind:key="id">
|
||||
<el-radio v-model="pollRadio" :label="option.title">{{ option.title }}</el-radio>
|
||||
</li>
|
||||
<template v-if="poll.voted">
|
||||
<li class="voted" v-for="(option, id) in poll.options" v-bind:key="id">
|
||||
<span class="progress-bar" :style="progress(option.votes_count * 100 / poll.votes_count)"></span>
|
||||
<label class="text">
|
||||
<span class="percentage">{{ option.votes_count * 100 / poll.votes_count }}%</span>
|
||||
<span>{{ option.title }}</span>
|
||||
</label>
|
||||
</li>
|
||||
</template>
|
||||
<template v-else>
|
||||
<li class="not-voted" v-for="(option, id) in poll.options" v-bind:key="id">
|
||||
<el-radio v-model="pollRadio" :label="id">{{ option.title }}</el-radio>
|
||||
</li>
|
||||
</template>
|
||||
</ul>
|
||||
<el-button type="success" @click="vote" :disabled="pollRadio === null">Vote</el-button>
|
||||
<el-button type="success" @click="vote" v-if="!poll.voted" :disabled="pollRadio === null">Vote</el-button>
|
||||
{{ poll.votes_count }} votes,
|
||||
until {{ parseDatetime(poll.expires_at, now) }}
|
||||
</div>
|
||||
|
@ -49,6 +60,9 @@ export default {
|
|||
if (this.pollRadio !== null) {
|
||||
this.$emit('vote', [this.pollRadio])
|
||||
}
|
||||
},
|
||||
progress(percent) {
|
||||
return `width: ${percent}%`
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -61,7 +75,31 @@ export default {
|
|||
padding-left: 16px;
|
||||
|
||||
li {
|
||||
position: relative;
|
||||
margin: 4px 0;
|
||||
line-height: 32px;
|
||||
}
|
||||
|
||||
.voted {
|
||||
max-width: 200px;
|
||||
|
||||
.progress-bar {
|
||||
position: absolute;
|
||||
display: inline-block;
|
||||
height: 100%;
|
||||
background-color: #409eff;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.text {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
padding-left: 8px;
|
||||
|
||||
.percentage {
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -199,7 +199,8 @@ export default {
|
|||
showContent: this.$store.state.App.ignoreCW,
|
||||
showAttachments: this.$store.state.App.ignoreNFSW,
|
||||
hideAllAttachments: this.$store.state.App.hideAllAttachments,
|
||||
now: Date.now()
|
||||
now: Date.now(),
|
||||
pollResponse: null
|
||||
}
|
||||
},
|
||||
props: {
|
||||
|
@ -279,7 +280,11 @@ export default {
|
|||
return !this.spoilered || this.showContent
|
||||
},
|
||||
poll: function() {
|
||||
return this.originalMessage.poll
|
||||
if (this.pollResponse) {
|
||||
return this.pollResponse
|
||||
} else {
|
||||
return this.originalMessage.poll
|
||||
}
|
||||
},
|
||||
sensitive: function() {
|
||||
return (this.hideAllAttachments || this.originalMessage.sensitive) && this.mediaAttachments.length > 0
|
||||
|
@ -555,8 +560,12 @@ export default {
|
|||
break
|
||||
}
|
||||
},
|
||||
vote(choices) {
|
||||
console.log(choices)
|
||||
async vote(choices) {
|
||||
const res = await this.$store.dispatch('organisms/Toot/vote', {
|
||||
id: this.poll.id,
|
||||
choices: choices
|
||||
})
|
||||
this.pollResponse = res
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
import Mastodon, { Response, Status, Account } from 'megalodon'
|
||||
import Mastodon, { Response, Status, Account, Poll } from 'megalodon'
|
||||
import { ipcRenderer } from 'electron'
|
||||
import { Module, ActionTree } from 'vuex'
|
||||
import { RootState } from '@/store'
|
||||
|
||||
type VoteParam = {
|
||||
id: string
|
||||
choices: Array<string>
|
||||
}
|
||||
|
||||
export type TootState = {}
|
||||
|
||||
const state = (): TootState => ({})
|
||||
|
@ -45,6 +50,13 @@ const actions: ActionTree<TootState, RootState> = {
|
|||
block: async ({ rootState }, account: Account) => {
|
||||
const client = new Mastodon(rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.account.baseURL + '/api/v1')
|
||||
return client.post(`/accounts/${account.id}/block`)
|
||||
},
|
||||
vote: async({ rootState }, params: VoteParam): Promise<Poll> => {
|
||||
const client = new Mastodon(rootState.TimelineSpace.account.accessToken!, rootState.TimelineSpace.account.baseURL + '/api/v1')
|
||||
const res = await client.post<Poll>(`/polls/${params.id}/votes`, {
|
||||
choices: params.choices
|
||||
})
|
||||
return res.data
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue