Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/spreed.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJoas Schilling <213943+nickvergessen@users.noreply.github.com>2022-08-31 16:45:51 +0300
committerGitHub <noreply@github.com>2022-08-31 16:45:51 +0300
commit689dadff0e22e0cf831f2b7d4d0d79b14a727f3c (patch)
tree4fffabb5bd75200722c832d308441a04ada9f1a9 /src
parent2fb3ee82201c1c48d3388f5d3b436172fc2e3797 (diff)
parente17b23c638304a3cc2d0f2e23d74cc9bf331ee7b (diff)
Merge pull request #7820 from nextcloud/feature/7795/display-poll-voters
Show voters details in polls
Diffstat (limited to 'src')
-rw-r--r--src/components/AvatarWrapper/AvatarWrapper.vue19
-rw-r--r--src/components/MessagesList/MessagesGroup/Message/MessagePart/Poll.vue41
-rw-r--r--src/components/MessagesList/MessagesGroup/Message/MessagePart/PollVotersDetails.vue110
3 files changed, 164 insertions, 6 deletions
diff --git a/src/components/AvatarWrapper/AvatarWrapper.vue b/src/components/AvatarWrapper/AvatarWrapper.vue
index 08b2db1c3..60313b198 100644
--- a/src/components/AvatarWrapper/AvatarWrapper.vue
+++ b/src/components/AvatarWrapper/AvatarWrapper.vue
@@ -21,7 +21,10 @@
<template>
<div class="avatar-wrapper"
- :class="{'offline': offline}">
+ :class="{
+ 'offline': offline,
+ 'avatar-wrapper--condensed': condensed,
+ }">
<div v-if="iconClass"
class="icon"
:class="[`avatar-${sizeToString}px`, iconClass]" />
@@ -102,6 +105,11 @@ export default {
type: String,
default: undefined,
},
+
+ condensed: {
+ type: Boolean,
+ default: false,
+ },
},
computed: {
// Determines which icon is displayed
@@ -141,6 +149,15 @@ export default {
height: $avatar-size;
width: $avatar-size;
@include avatar-mixin($avatar-size);
+ &--condensed {
+ width: unset;
+ height: unset;
+ margin-left: -2px;
+ display: flex;
+ ::v-deep img {
+ outline: 2px solid var(--color-main-background);
+ }
+ }
}
.offline .avatar-wrapper .avatardiv {
diff --git a/src/components/MessagesList/MessagesGroup/Message/MessagePart/Poll.vue b/src/components/MessagesList/MessagesGroup/Message/MessagePart/Poll.vue
index 3b94890d0..f83c9d4cd 100644
--- a/src/components/MessagesList/MessagesGroup/Message/MessagePart/Poll.vue
+++ b/src/components/MessagesList/MessagesGroup/Message/MessagePart/Poll.vue
@@ -130,9 +130,14 @@
{{ getVotePercentage(index) + '%' }}
</p>
</div>
- <p v-if="selfHasVotedOption(index)" class="results__option-subtitle">
- {{ t('spreed','You voted') }}
- </p>
+ <div v-if="getFilteredDetails(index).length > 0 || selfHasVotedOption(index)"
+ class="results__option__details">
+ <PollVotersDetails v-if="details"
+ :details="getFilteredDetails(index)" />
+ <p v-if="selfHasVotedOption(index)" class="results__option-subtitle">
+ {{ t('spreed','You voted') }}
+ </p>
+ </div>
<NcProgressBar class="results__option-progress"
:value="getVotePercentage(index)"
size="medium" />
@@ -166,6 +171,7 @@ import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
import PollIcon from 'vue-material-design-icons/Poll.vue'
import NcProgressBar from '@nextcloud/vue/dist/Components/NcProgressBar.js'
import { PARTICIPANT } from '../../../../../constants.js'
+import PollVotersDetails from './PollVotersDetails.vue'
export default {
@@ -177,6 +183,7 @@ export default {
NcButton,
PollIcon,
NcProgressBar,
+ PollVotersDetails,
},
props: {
@@ -272,6 +279,14 @@ export default {
return this.status === 1
},
+ details() {
+ if (!this.pollLoaded || this.pollIsOpen) {
+ return undefined
+ } else {
+ return this.poll.details
+ }
+ },
+
checkboxRadioSwitchType() {
if (this.pollLoaded) {
return this.poll.maxVotes === 0 ? 'checkbox' : 'radio'
@@ -335,7 +350,7 @@ export default {
if (this.pollIsOpen) {
return this.selfHasVoted ? t('spreed', 'Poll ・ You voted') : t('spreed', 'Poll ・ Click to vote')
} else if (this.pollIsClosed) {
- return t('spreed', 'Poll ・ Closed')
+ return t('spreed', 'Poll ・ Ended')
}
return ''
},
@@ -427,6 +442,15 @@ export default {
return false
}
},
+
+ getFilteredDetails(index) {
+ if (!this.details) {
+ return []
+ }
+ return this.details.filter((item) => {
+ return item.optionId === index
+ }).slice(0, 8)
+ },
},
}
</script>
@@ -506,13 +530,19 @@ export default {
.results__options {
display: flex;
flex-direction: column;
- gap: 20px;
+ gap: 24px;
word-wrap: anywhere;
margin: 8px 0 20px 0;
}
.results__option {
display: flex;
flex-direction: column;
+
+ &__details {
+ display: flex;
+ height: 32px;
+ }
+
&-subtitle {
color: var(--color-text-maxcontrast);
}
@@ -526,6 +556,7 @@ export default {
display: flex;
justify-content: space-between;
align-items: flex-start;
+ margin-bottom: 4px;
.percentage {
white-space: nowrap;
margin-left: 16px;
diff --git a/src/components/MessagesList/MessagesGroup/Message/MessagePart/PollVotersDetails.vue b/src/components/MessagesList/MessagesGroup/Message/MessagePart/PollVotersDetails.vue
new file mode 100644
index 000000000..2cc42e4f9
--- /dev/null
+++ b/src/components/MessagesList/MessagesGroup/Message/MessagePart/PollVotersDetails.vue
@@ -0,0 +1,110 @@
+`<!--
+ - @copyright Copyright (c) 2022 Marco Ambrosini <marcoambrosini@pm.me>
+ -
+ - @author Marco Ambrosini <marcoambrosini@pm.me>
+ -
+ - @license GNU AGPL version 3 or any later version
+ -
+ - This program is free software: you can redistribute it and/or modify
+ - it under the terms of the GNU Affero General Public License as
+ - published by the Free Software Foundation, either version 3 of the
+ - License, or (at your option) any later version.
+ -
+ - This program is distributed in the hope that it will be useful,
+ - but WITHOUT ANY WARRANTY; without even the implied warranty of
+ - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ - GNU Affero General Public License for more details.
+ -
+ - You should have received a copy of the GNU Affero General Public License
+ - along with this program. If not, see <http://www.gnu.org/licenses/>.
+-->
+
+<template>
+ <NcPopover trigger="hover">
+ <button slot="trigger"
+ tabindex="0"
+ class="poll-voters-details">
+ <AvatarWrapper v-for="(item, index) in details"
+ :id="item.actorId"
+ :key="index"
+ :source="item.actorType"
+ :disable-menu="true"
+ :disable-tooltip="true"
+ :show-user-status="false"
+ :name="item.actorDisplayName"
+ :condensed="true"
+ :size="24" />
+ </button>
+ <div class="poll-voters-details__popover" tabindex="0">
+ <div v-for="(item, index) in details"
+ :key="index"
+ class="poll-voters-details__list-item">
+ <AvatarWrapper :id="item.actorId"
+ :key="index"
+ :source="item.actorType"
+ :disable-menu="true"
+ :show-user-status="false"
+ :name="item.actorDisplayName"
+ :condensed="true"
+ :size="24" />
+ <p class="poll-voters-details__display-name">
+ {{ item.actorDisplayName }}
+ </p>
+ </div>
+ </div>
+ </NcPopover>
+</template>
+
+<script>
+import AvatarWrapper from '../../../../AvatarWrapper/AvatarWrapper.vue'
+import NcPopover from '@nextcloud/vue/dist/Components/NcPopover.js'
+
+export default {
+
+ name: 'PollVotersDetails',
+
+ components: {
+ AvatarWrapper,
+ NcPopover,
+ },
+
+ props: {
+ details: {
+ type: Array,
+ required: true,
+ },
+ },
+}
+</script>
+
+<style lang="scss" scoped>
+
+.poll-voters-details {
+ display: flex;
+ background: none;
+ border: none;
+ padding: 0;
+ margin-right: 8px;
+
+ &__popover{
+ padding: 8px;
+ max-height: 400px;
+ overflow-y: scroll;
+ }
+
+ &__display-name {
+ margin-left: 4px;
+ }
+
+ &__list-item {
+ display: flex;
+ align-items: center;
+ height: 32px;
+ margin-bottom: var(--margin-small);
+ min-width: 150px;
+ justify-content: flex-start;
+ align-items: center;
+ }
+}
+
+</style>