Skip to content

Commit

Permalink
Merge pull request #13518 from nextcloud/feat/13439/drafts-for-polls-…
Browse files Browse the repository at this point in the history
…frontend-2
  • Loading branch information
Antreesy authored Oct 18, 2024
2 parents 302e5a5 + 72b5efb commit 1ae5bfd
Show file tree
Hide file tree
Showing 7 changed files with 368 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,33 @@

<template>
<!-- Poll card -->
<a v-if="!showAsButton"
<div v-if="draft" class="poll-card" @click="openDraft">
<span class="poll-card__header">
<IconPoll :size="20" />
<span>{{ name }}</span>
</span>
<span class="poll-card__footer">
{{ pollFooterText }}
</span>

<NcButton class="poll-card__delete-draft"
type="tertiary"
:title="t('spreed', 'Delete poll draft')"
:aria-label="t('spreed', 'Delete poll draft')"
@click.stop="deleteDraft">
<template #icon>
<IconDelete :size="20" />
</template>
</NcButton>
</div>
<a v-else-if="!showAsButton"
v-intersection-observer="getPollData"
:aria-label="t('spreed', 'Poll')"
class="poll-card"
role="button"
@click="openPoll">
<span class="poll-card__header">
<PollIcon :size="20" />
<IconPoll :size="20" />
<span>{{ name }}</span>
</span>
<span class="poll-card__footer">
Expand All @@ -32,9 +51,10 @@
<script>
import { vIntersectionObserver as IntersectionObserver } from '@vueuse/components'

import PollIcon from 'vue-material-design-icons/Poll.vue'
import IconDelete from 'vue-material-design-icons/Delete.vue'
import IconPoll from 'vue-material-design-icons/Poll.vue'

import { t } from '@nextcloud/l10n'
import { t, n } from '@nextcloud/l10n'

import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'

Expand All @@ -46,7 +66,8 @@ export default {

components: {
NcButton,
PollIcon,
IconDelete,
IconPoll,
},

directives: {
Expand All @@ -73,8 +94,15 @@ export default {
type: Boolean,
default: false,
},

draft: {
type: Boolean,
default: false,
},
},

emits: ['click'],

setup() {
return {
pollsStore: usePollsStore(),
Expand All @@ -83,14 +111,18 @@ export default {

computed: {
poll() {
return this.pollsStore.getPoll(this.token, this.id)
return !this.draft
? this.pollsStore.getPoll(this.token, this.id)
: this.pollsStore.drafts[this.token][this.id]
},

pollFooterText() {
if (this.poll?.status === POLL.STATUS.OPEN) {
return this.poll?.votedSelf.length > 0
? t('spreed', 'Open poll • You voted already')
: t('spreed', 'Open poll • Click to vote')
} else if (this.draft) {
return n('spreed', 'Poll draft • %n option', 'Poll draft • %n options', this.poll?.options?.length)
} else {
return this.poll?.status === POLL.STATUS.CLOSED
? t('spreed', 'Poll • Ended')
Expand All @@ -101,6 +133,7 @@ export default {

methods: {
t,
n,
getPollData() {
if (!this.poll) {
this.pollsStore.getPollData({
Expand All @@ -110,6 +143,17 @@ export default {
}
},

openDraft() {
this.$emit('click', this.id)
},

deleteDraft() {
this.pollsStore.deletePollDraft({
token: this.token,
pollId: this.id,
})
},

openPoll() {
this.pollsStore.setActivePoll({
token: this.token,
Expand All @@ -123,9 +167,10 @@ export default {

<style lang="scss" scoped>
.poll-card {
position: relative;
display: block;
max-width: 300px;
padding: 16px;
padding: calc(3 * var(--default-grid-baseline)) calc(2 * var(--default-grid-baseline));
border: 2px solid var(--color-border);
border-radius: var(--border-radius-large);
background: var(--color-main-background);
Expand All @@ -146,6 +191,7 @@ export default {
font-weight: bold;
white-space: normal;
word-wrap: anywhere;
margin-right: var(--default-clickable-area);

:deep(.material-design-icon) {
margin-bottom: auto;
Expand All @@ -156,6 +202,12 @@ export default {
color: var(--color-text-maxcontrast);
white-space: normal;
}

& &__delete-draft {
position: absolute;
top: var(--default-grid-baseline);
right: var(--default-grid-baseline);
}
}

.poll-closed {
Expand Down
31 changes: 31 additions & 0 deletions src/components/NewMessage/NewMessage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,15 @@

<!-- Poll creation dialog -->
<NewMessagePollEditor v-if="showPollEditor"
ref="pollEditor"
:token="token"
@close="togglePollEditor" />

<PollDraftHandler v-if="canCreatePollDrafts && showPollDraftHandler"
:token="token"
:show-create-button="!showPollEditor"
@close="togglePollDraftHandler" />

<!-- New file creation dialog -->
<NewMessageNewFileDialog v-if="showNewFileDialog !== -1"
:token="token"
Expand Down Expand Up @@ -194,6 +200,7 @@ import NewMessageAudioRecorder from './NewMessageAudioRecorder.vue'
import NewMessageNewFileDialog from './NewMessageNewFileDialog.vue'
import NewMessagePollEditor from './NewMessagePollEditor.vue'
import NewMessageTypingIndicator from './NewMessageTypingIndicator.vue'
import PollDraftHandler from '../PollViewer/PollDraftHandler.vue'
import Quote from '../Quote.vue'

import { useIsDarkTheme } from '../../composables/useIsDarkTheme.ts'
Expand Down Expand Up @@ -226,6 +233,7 @@ export default {
NewMessageAudioRecorder,
NewMessageNewFileDialog,
NewMessagePollEditor,
PollDraftHandler,
NewMessageTypingIndicator,
Quote,
// Icons
Expand Down Expand Up @@ -301,6 +309,7 @@ export default {
// True when the audio recorder component is recording
isRecordingAudio: false,
showPollEditor: false,
showPollDraftHandler: false,
showNewFileDialog: -1,
showFilePicker: false,
// Check empty template by default
Expand Down Expand Up @@ -386,6 +395,10 @@ export default {
&& this.conversation.type !== CONVERSATION.TYPE.NOTE_TO_SELF
},

canCreatePollDrafts() {
return hasTalkFeature(this.token, 'talk-polls-drafts') && this.$store.getters.isModerator
},

currentConversationIsJoined() {
return this.$store.getters.currentConversationIsJoined
},
Expand Down Expand Up @@ -538,6 +551,8 @@ export default {
EventBus.on('upload-discard', this.handleUploadSideEffects)
EventBus.on('retry-message', this.handleRetryMessage)
EventBus.on('smart-picker-open', this.handleOpenTributeMenu)
EventBus.on('poll-editor-open', this.fillPollEditorFromDraft)
EventBus.on('poll-drafts-open', this.togglePollDraftHandler)

if (!this.$store.getters.areFileTemplatesInitialised) {
this.$store.dispatch('getFileTemplates')
Expand All @@ -550,6 +565,8 @@ export default {
EventBus.off('upload-discard', this.handleUploadSideEffects)
EventBus.off('retry-message', this.handleRetryMessage)
EventBus.off('smart-picker-open', this.handleOpenTributeMenu)
EventBus.off('poll-editor-open', this.fillPollEditorFromDraft)
EventBus.off('poll-drafts-open', this.togglePollDraftHandler)
},

methods: {
Expand Down Expand Up @@ -892,6 +909,20 @@ export default {
this.showPollEditor = !this.showPollEditor
},

fillPollEditorFromDraft(id) {
const isPollEditorOpened = this.showPollEditor
this.showPollEditor = true
this.$nextTick(() => {
this.$refs.pollEditor?.fillPollEditorFromDraft(id, isPollEditorOpened)
// Wait for editor to be mounted and filled before unmounting drafts dialog
this.togglePollDraftHandler()
})
},

togglePollDraftHandler() {
this.showPollDraftHandler = !this.showPollDraftHandler
},

async autoComplete(search, callback) {
const response = await searchPossibleMentions(this.token, search)
if (!response) {
Expand Down
Loading

0 comments on commit 1ae5bfd

Please sign in to comment.