From 5cddf18a4efa7ac2749760e569793c6a3640b68c Mon Sep 17 00:00:00 2001 From: tusooa Date: Fri, 10 Mar 2023 20:16:03 -0500 Subject: [PATCH] Handle polls in drafts --- src/components/poll/poll_form.js | 48 ++++++++++--------- .../post_status_form/post_status_form.js | 13 +++-- .../post_status_form/post_status_form.vue | 2 +- src/services/poll/poll.service.js | 36 ++++++++++++++ 4 files changed, 71 insertions(+), 28 deletions(-) create mode 100644 src/services/poll/poll.service.js diff --git a/src/components/poll/poll_form.js b/src/components/poll/poll_form.js index a2070155..951b9454 100644 --- a/src/components/poll/poll_form.js +++ b/src/components/poll/poll_form.js @@ -1,5 +1,5 @@ import * as DateUtils from 'src/services/date_utils/date_utils.js' -import { uniq } from 'lodash' +import { pollFallback } from 'src/services/poll/poll.service.js' import { library } from '@fortawesome/fontawesome-svg-core' import Select from '../select/select.vue' import { @@ -17,14 +17,31 @@ export default { Select }, name: 'PollForm', - props: ['visible'], - data: () => ({ - pollType: 'single', - options: ['', ''], - expiryAmount: 10, - expiryUnit: 'minutes' - }), + props: { + visible: {}, + modelValue: { + type: Object, + required: true + } + }, + emits: ['update:modelValue'], computed: { + pollType: { + get () { return pollFallback(this.modelValue, 'pollType') }, + set (newVal) { this.$emit('update:modelValue', { ...this.modelValue, pollType: newVal }) } + }, + options: { + get () { return pollFallback(this.modelValue, 'options') }, + set (newVal) { this.$emit('update:modelValue', { ...this.modelValue, options: newVal }) } + }, + expiryAmount: { + get () { return pollFallback(this.modelValue, 'expiryAmount') }, + set (newVal) { this.$emit('update:modelValue', { ...this.modelValue, expiryAmount: newVal }) } + }, + expiryUnit: { + get () { return pollFallback(this.modelValue, 'expiryUnit') }, + set (newVal) { this.$emit('update:modelValue', { ...this.modelValue, expiryUnit: newVal }) } + }, pollLimits () { return this.$store.state.instance.pollLimits }, @@ -107,21 +124,6 @@ export default { this.updatePollToParent() }, updatePollToParent () { - const expiresIn = this.convertExpiryFromUnit( - this.expiryUnit, - this.expiryAmount - ) - - const options = uniq(this.options.filter(option => option !== '')) - if (options.length < 2) { - this.$emit('update-poll', { error: this.$t('polls.not_enough_options') }) - return - } - this.$emit('update-poll', { - options, - multiple: this.pollType === 'multiple', - expiresIn - }) } } } diff --git a/src/components/post_status_form/post_status_form.js b/src/components/post_status_form/post_status_form.js index 7c0289c0..b284ff8c 100644 --- a/src/components/post_status_form/post_status_form.js +++ b/src/components/post_status_form/post_status_form.js @@ -9,6 +9,7 @@ import StatusContent from '../status_content/status_content.vue' import fileTypeService from '../../services/file_type/file_type.service.js' import { findOffset } from '../../services/offset_finder/offset_finder.service.js' import { propsToNative } from '../../services/attributes_helper/attributes_helper.service.js' +import { pollFormToMasto } from 'src/services/poll/poll.service.js' import { reject, map, uniqBy, debounce } from 'lodash' import suggestor from '../emoji_input/suggestor.js' import { mapGetters, mapState } from 'vuex' @@ -159,6 +160,7 @@ const PostStatusForm = { nsfw: !!sensitiveByDefault, files: [], poll: {}, + hasPoll: false, mediaDescriptions: {}, visibility: scope, contentType @@ -174,6 +176,7 @@ const PostStatusForm = { nsfw: this.statusIsSensitive || !!sensitiveByDefault, files: this.statusFiles || [], poll: this.statusPoll || {}, + hasPoll: false, mediaDescriptions: this.statusMediaDescriptions || {}, visibility: this.statusScope || scope, contentType: statusContentType @@ -189,7 +192,6 @@ const PostStatusForm = { highlighted: 0, newStatus: statusParams, caret: 0, - pollFormVisible: false, showDropIcon: 'hide', dropStopTimeout: null, preview: null, @@ -290,6 +292,9 @@ const PostStatusForm = { debouncedSaveDraft () { return debounce(this.saveDraft, 3000) }, + pollFormVisible () { + return this.newStatus.hasPoll + }, ...mapGetters(['mergedConfig']), ...mapState({ mobileLayout: state => state.interface.mobileLayout @@ -323,9 +328,9 @@ const PostStatusForm = { visibility: newStatus.visibility, contentType: newStatus.contentType, poll: {}, + hasPoll: false, mediaDescriptions: {} } - this.pollFormVisible = false this.$refs.mediaUpload && this.$refs.mediaUpload.clearFile() this.clearPollForm() if (this.preserveFocus) { @@ -355,7 +360,7 @@ const PostStatusForm = { return } - const poll = this.pollFormVisible ? this.newStatus.poll : {} + const poll = this.newStatus.hasPoll ? pollFormToMasto(this.newStatus.poll) : {} if (this.pollContentError) { this.error = this.pollContentError return @@ -632,7 +637,7 @@ const PostStatusForm = { this.newStatus.visibility = visibility }, togglePollForm () { - this.pollFormVisible = !this.pollFormVisible + this.newStatus.hasPoll = !this.newStatus.hasPoll }, setPoll (poll) { this.newStatus.poll = poll diff --git a/src/components/post_status_form/post_status_form.vue b/src/components/post_status_form/post_status_form.vue index 86c1f907..b03e5527 100644 --- a/src/components/post_status_form/post_status_form.vue +++ b/src/components/post_status_form/post_status_form.vue @@ -233,7 +233,7 @@ v-if="pollsAvailable" ref="pollForm" :visible="pollFormVisible" - @update-poll="setPoll" + v-model="newStatus.poll" />
{ + return object[attr] !== undefined ? object[attr] : pollFallbackValues[attr] +} + +const pollFormToMasto = (poll) => { + const expiresIn = DateUtils.unitToSeconds( + pollFallback(poll, 'expiryUnit'), + pollFallback(poll, 'expiryAmount') + ) + + const options = uniq(pollFallback(poll, 'options').filter(option => option !== '')) + if (options.length < 2) { + return { errorKey: 'polls.not_enough_options' } + } + + return { + options, + multiple: pollFallback(poll, 'pollType') === 'multiple', + expiresIn + } +} + +export { + pollFallback, + pollFormToMasto +}