More poll styling
This commit is contained in:
parent
98ed17723d
commit
32ebd86c5d
12 changed files with 361 additions and 344 deletions
|
|
@ -1,27 +1,60 @@
|
|||
<template>
|
||||
<message-incoming v-bind="{ ...$props, ...$attrs }" v-on="$listeners">
|
||||
<div class="bubble poll-bubble">
|
||||
{{ pollQuestion }}
|
||||
<v-container fluid>
|
||||
<div class="poll-icon">
|
||||
<svg width="17" height="19" viewBox="0 0 17 19" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M3.31462 16.4718C3.31462 16.9496 3.70026 17.3368 4.17609 17.3368L16.1385 17.3368C16.6144 17.3368 17 16.9496 17 16.4718L16.9998 13.6229C16.9998 13.1452 16.6142 12.7579 16.1383 12.7579L4.1764 12.7579C3.70056 12.7579 3.31492 13.1452 3.31492 13.6229L3.31512 16.4718L3.31462 16.4718Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
d="M3.31462 10.4557C3.31462 10.9335 3.70026 11.3208 4.17609 11.3208L11.3428 11.3208C11.8186 11.3208 12.2043 10.9335 12.2043 10.4557L12.2043 7.60711C12.2043 7.12931 11.8186 6.74208 11.3428 6.74208L4.17609 6.74208C3.70026 6.74208 3.31462 7.12932 3.31462 7.60711L3.31462 10.4557Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
d="M3.31451 1.59127L3.31451 4.44011C3.31451 4.91791 3.70016 5.30514 4.17598 5.30514L6.99509 5.30514C7.47093 5.30514 7.85657 4.91791 7.85657 4.44011L7.85637 1.59127C7.85637 1.11347 7.47073 0.726242 6.9949 0.726242L4.17599 0.726242C3.70035 0.726242 3.31452 1.11348 3.31452 1.59127L3.31451 1.59127Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
d="M-2.00529e-05 0.587841L-2.0791e-05 17.4747C-2.08052e-05 17.7995 0.262306 18.0625 0.585404 18.0625L1.38198 18.0625C1.70528 18.0625 1.96741 17.7995 1.96741 17.4747L1.96741 0.587841C1.96741 0.263208 1.70508 -1.14667e-08 1.38198 -2.55897e-08L0.585405 -6.04092e-08C0.261911 -7.45496e-08 -2.00387e-05 0.263213 -2.00529e-05 0.587841Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="poll-question">{{ pollQuestion }}</div>
|
||||
<v-container fluid ma-0 pa-0>
|
||||
<v-row
|
||||
v-for="answer in pollAnswers"
|
||||
:key="answer.id"
|
||||
@click="pollAnswer(answer.id)"
|
||||
:class="{ 'poll-answer': true, selected: answer.hasMyVote }"
|
||||
:class="{
|
||||
'poll-answer': true,
|
||||
selected: !userHasVoted && answer.id == pollTentativeAnswer,
|
||||
result: userHasVoted || pollIsClosed,
|
||||
winner: answer.winner,
|
||||
}"
|
||||
ma-0
|
||||
pa-0
|
||||
>
|
||||
<v-col cols="auto" class="ma-0 pa-0 poll-answer-title">{{ answer.text }}</v-col>
|
||||
<v-col cols="auto" class="ma-0 pa-0 poll-answer-title">{{ answer.text }} {{ answer.max }}</v-col>
|
||||
<v-col v-if="answer.id == pollTentativeAnswer" cols="auto" class="ma-0 pa-0 poll-answer-title"
|
||||
><v-img class="poll-check-icon" src="@/assets/icons/ic_check.svg"
|
||||
/></v-col>
|
||||
<v-col
|
||||
v-if="pollIsClosed || (pollIsDisclosed && userHasVoted) || pollIsAdmin"
|
||||
cols="auto"
|
||||
class="ma-0 pa-0 poll-answer-num-votes"
|
||||
>{{ answer.numVotes }}</v-col
|
||||
>{{ answer.percentage }}%</v-col
|
||||
>
|
||||
<div v-if="pollIsClosed || (pollIsDisclosed && userHasVoted) || pollIsAdmin" class="poll-percent-indicator">
|
||||
<div class="bar" :style="{ width: `${answer.percentage}%` }"></div>
|
||||
</div>
|
||||
</v-row>
|
||||
<v-row class="poll-status">
|
||||
<v-col cols="auto" class="ma-0 pa-0 poll-status-title">{{
|
||||
<v-col cols="auto" class="ma-0 pa-0 poll-status-title">
|
||||
{{ $t("poll_create.num_answered", { count: pollNumAnswers }) }}
|
||||
</v-col>
|
||||
<!-- <v-col cols="auto" class="ma-0 pa-0 poll-status-title">{{
|
||||
pollIsClosed
|
||||
? $t("poll_create.poll_status_closed")
|
||||
: pollIsDisclosed
|
||||
|
|
@ -29,7 +62,7 @@
|
|||
? $t("poll_create.poll_status_open")
|
||||
: $t("poll_create.poll_status_open_not_voted")
|
||||
: $t("poll_create.poll_status_disclosed")
|
||||
}}</v-col>
|
||||
}}</v-col> -->
|
||||
<v-col
|
||||
cols="auto"
|
||||
class="ma-0 pa-0 poll-status-close clickable"
|
||||
|
|
@ -38,6 +71,13 @@
|
|||
>{{ $t("poll_create.close_poll") }}</v-col
|
||||
>
|
||||
</v-row>
|
||||
<v-row v-if="pollTentativeAnswer" justify="center">
|
||||
<v-col cols="auto" class="ma-0 pa-0 poll-submit">
|
||||
<v-btn @click.stop="pollAnswerSubmit">
|
||||
{{ $t("poll_create.poll_submit") }}
|
||||
</v-btn>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-container>
|
||||
</div>
|
||||
</message-incoming>
|
||||
|
|
|
|||
|
|
@ -1,27 +1,61 @@
|
|||
<template>
|
||||
<message-outgoing v-bind="{ ...$props, ...$attrs }" v-on="$listeners">
|
||||
<div class="bubble poll-bubble">
|
||||
{{ pollQuestion }}
|
||||
<v-container fluid>
|
||||
<div class="poll-icon">
|
||||
<svg width="17" height="19" viewBox="0 0 17 19" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M3.31462 16.4718C3.31462 16.9496 3.70026 17.3368 4.17609 17.3368L16.1385 17.3368C16.6144 17.3368 17 16.9496 17 16.4718L16.9998 13.6229C16.9998 13.1452 16.6142 12.7579 16.1383 12.7579L4.1764 12.7579C3.70056 12.7579 3.31492 13.1452 3.31492 13.6229L3.31512 16.4718L3.31462 16.4718Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
d="M3.31462 10.4557C3.31462 10.9335 3.70026 11.3208 4.17609 11.3208L11.3428 11.3208C11.8186 11.3208 12.2043 10.9335 12.2043 10.4557L12.2043 7.60711C12.2043 7.12931 11.8186 6.74208 11.3428 6.74208L4.17609 6.74208C3.70026 6.74208 3.31462 7.12932 3.31462 7.60711L3.31462 10.4557Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
d="M3.31451 1.59127L3.31451 4.44011C3.31451 4.91791 3.70016 5.30514 4.17598 5.30514L6.99509 5.30514C7.47093 5.30514 7.85657 4.91791 7.85657 4.44011L7.85637 1.59127C7.85637 1.11347 7.47073 0.726242 6.9949 0.726242L4.17599 0.726242C3.70035 0.726242 3.31452 1.11348 3.31452 1.59127L3.31451 1.59127Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
<path
|
||||
d="M-2.00529e-05 0.587841L-2.0791e-05 17.4747C-2.08052e-05 17.7995 0.262306 18.0625 0.585404 18.0625L1.38198 18.0625C1.70528 18.0625 1.96741 17.7995 1.96741 17.4747L1.96741 0.587841C1.96741 0.263208 1.70508 -1.14667e-08 1.38198 -2.55897e-08L0.585405 -6.04092e-08C0.261911 -7.45496e-08 -2.00387e-05 0.263213 -2.00529e-05 0.587841Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<div class="poll-question">{{ pollQuestion }}</div>
|
||||
<v-container fluid ma-0 pa-0>
|
||||
<v-row
|
||||
v-for="answer in pollAnswers"
|
||||
:key="answer.id"
|
||||
@click="pollAnswer(answer.id)"
|
||||
:class="{ 'poll-answer': true, selected: answer.hasMyVote }"
|
||||
:class="{
|
||||
'poll-answer': true,
|
||||
selected: !userHasVoted && answer.id == pollTentativeAnswer,
|
||||
result: userHasVoted || pollIsClosed,
|
||||
winner: answer.winner,
|
||||
}"
|
||||
ma-0
|
||||
pa-0
|
||||
>
|
||||
<v-col cols="auto" class="ma-0 pa-0 poll-answer-title">{{ answer.text }}</v-col>
|
||||
<v-col cols="auto" class="ma-0 pa-0 poll-answer-title">{{ answer.text }} {{ answer.max }}</v-col>
|
||||
<v-col v-if="answer.id == pollTentativeAnswer" cols="auto" class="ma-0 pa-0 poll-answer-title"
|
||||
><v-img class="poll-check-icon" src="@/assets/icons/ic_check.svg"
|
||||
/></v-col>
|
||||
<v-col
|
||||
v-if="pollIsClosed || (pollIsDisclosed && userHasVoted) || pollIsAdmin"
|
||||
cols="auto"
|
||||
class="ma-0 pa-0 poll-answer-num-votes"
|
||||
>{{ answer.numVotes }}</v-col
|
||||
>{{ answer.percentage }}%</v-col
|
||||
>
|
||||
<div v-if="pollIsClosed || (pollIsDisclosed && userHasVoted) || pollIsAdmin" class="poll-percent-indicator">
|
||||
<div class="bar" :style="{ width: `${answer.percentage}%` }"></div>
|
||||
</div>
|
||||
</v-row>
|
||||
<v-row class="poll-status">
|
||||
<v-col cols="auto" class="ma-0 pa-0 poll-status-title">{{
|
||||
<v-col cols="auto" class="ma-0 pa-0 poll-status-title">
|
||||
{{ $t("poll_create.num_answered", { count: pollNumAnswers }) }}
|
||||
</v-col>
|
||||
<!-- <v-col cols="auto" class="ma-0 pa-0 poll-status-title">{{
|
||||
pollIsClosed
|
||||
? $t("poll_create.poll_status_closed")
|
||||
: pollIsDisclosed
|
||||
|
|
@ -29,7 +63,7 @@
|
|||
? $t("poll_create.poll_status_open")
|
||||
: $t("poll_create.poll_status_open_not_voted")
|
||||
: $t("poll_create.poll_status_disclosed")
|
||||
}}</v-col>
|
||||
}}</v-col> -->
|
||||
<v-col
|
||||
cols="auto"
|
||||
class="ma-0 pa-0 poll-status-close clickable"
|
||||
|
|
@ -38,6 +72,13 @@
|
|||
>{{ $t("poll_create.close_poll") }}</v-col
|
||||
>
|
||||
</v-row>
|
||||
<v-row v-if="pollTentativeAnswer" justify="center">
|
||||
<v-col cols="auto" class="ma-0 pa-0 poll-submit">
|
||||
<v-btn @click.stop="pollAnswerSubmit">
|
||||
{{ $t("poll_create.poll_submit") }}
|
||||
</v-btn>
|
||||
</v-col>
|
||||
</v-row>
|
||||
</v-container>
|
||||
</div>
|
||||
</message-outgoing>
|
||||
|
|
|
|||
|
|
@ -5,10 +5,12 @@ export default {
|
|||
return {
|
||||
pollQuestion: "",
|
||||
pollAnswers: [],
|
||||
pollTotalVotes: 0,
|
||||
pollResponseRelations: null,
|
||||
pollEndRelations: null,
|
||||
pollEndTs: null,
|
||||
pollIsDisclosed: true,
|
||||
pollTentativeAnswer: null
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
|
|
@ -93,25 +95,51 @@ export default {
|
|||
}
|
||||
}
|
||||
|
||||
// Update percentage
|
||||
answerArray.forEach(a => {
|
||||
a.percentage = parseInt(((100 * a.numVotes) / totalVotes).toFixed(0));
|
||||
// Update percentages. For algorithm, see here: https://revs.runtime-revolution.com/getting-100-with-rounded-percentages-273ffa70252b
|
||||
// (need to add up to 100%)
|
||||
let a = answerArray.map(a => {
|
||||
let votes = (100 * a.numVotes) / totalVotes;
|
||||
return {
|
||||
answer: a,
|
||||
unrounded: votes,
|
||||
floor: Math.floor(votes)
|
||||
}
|
||||
});
|
||||
a.sort((item1,item2) => {
|
||||
Math.abs(item2.floor) - Math.abs(item1.floor);
|
||||
});
|
||||
var diff = 100 - a.reduce((previousValue, currentValue) => {
|
||||
return previousValue + currentValue.floor;
|
||||
}, 0);
|
||||
const maxVotes = Math.max(...a.map(item => item.unrounded));
|
||||
a.map((answer, index) => {
|
||||
answer.answer.percentage = (index < diff) ? (answer.floor + 1) : answer.floor;
|
||||
answer.answer.winner = (answer.unrounded == maxVotes);
|
||||
});
|
||||
this.pollAnswers = answerArray;
|
||||
this.pollTotalVotes = totalVotes;
|
||||
},
|
||||
pollAnswer(id) {
|
||||
if (this.pollIsClosed) {
|
||||
if (!this.userHasVoted) {
|
||||
this.pollTentativeAnswer = id;
|
||||
}
|
||||
},
|
||||
pollAnswerSubmit() {
|
||||
if (!this.pollTentativeAnswer || this.pollIsClosed) {
|
||||
return;
|
||||
}
|
||||
util
|
||||
.sendPollAnswer(
|
||||
this.$matrix.matrixClient,
|
||||
this.room.roomId,
|
||||
[id],
|
||||
[this.pollTentativeAnswer],
|
||||
this.event
|
||||
)
|
||||
.catch((err) => {
|
||||
console.log("Failed to send:", err);
|
||||
})
|
||||
.finally(() => {
|
||||
this.pollTentativeAnswer = null;
|
||||
});
|
||||
},
|
||||
pollClose() {
|
||||
|
|
@ -148,6 +176,9 @@ export default {
|
|||
userHasVoted() {
|
||||
return this.pollAnswers.some(a => a.hasMyVote);
|
||||
},
|
||||
pollNumAnswers() {
|
||||
return this.pollTotalVotes;
|
||||
},
|
||||
pollIsAdmin() {
|
||||
// Admins can view results of not-yet-closed undisclosed polls.
|
||||
const me = this.room && this.room.getMember(this.$matrix.currentUserId);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue