commit: 2a8c7e8e7d5a4525463d369b24802b71222d37ed
parent 747bad79fcacf6659b75bc46c76eb85fe58efed7
Author: tusooa <tusooa@kazv.moe>
Date:   Fri, 10 Mar 2023 20:16:03 -0500
Handle polls in drafts
Diffstat:
4 files changed, 71 insertions(+), 28 deletions(-)
diff --git 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
@@ -10,6 +10,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'
@@ -163,6 +164,7 @@ const PostStatusForm = {
         nsfw: !!sensitiveByDefault,
         files: [],
         poll: {},
+        hasPoll: false,
         mediaDescriptions: {},
         visibility: scope,
         contentType,
@@ -179,6 +181,7 @@ const PostStatusForm = {
           nsfw: this.statusIsSensitive || !!sensitiveByDefault,
           files: this.statusFiles || [],
           poll: this.statusPoll || {},
+          hasPoll: false,
           mediaDescriptions: this.statusMediaDescriptions || {},
           visibility: this.statusScope || scope,
           contentType: statusContentType
@@ -195,7 +198,6 @@ const PostStatusForm = {
       highlighted: 0,
       newStatus: statusParams,
       caret: 0,
-      pollFormVisible: false,
       showDropIcon: 'hide',
       dropStopTimeout: null,
       preview: null,
@@ -320,6 +322,9 @@ const PostStatusForm = {
     debouncedSaveDraft () {
       return debounce(this.saveDraft, 3000)
     },
+    pollFormVisible () {
+      return this.newStatus.hasPoll
+    },
     ...mapGetters(['mergedConfig']),
     ...mapState({
       mobileLayout: state => state.interface.mobileLayout
@@ -353,10 +358,10 @@ const PostStatusForm = {
         visibility: newStatus.visibility,
         contentType: newStatus.contentType,
         poll: {},
+        hasPoll: false,
         mediaDescriptions: {},
         quoting: false
       }
-      this.pollFormVisible = false
       this.$refs.mediaUpload && this.$refs.mediaUpload.clearFile()
       this.clearPollForm()
       if (this.preserveFocus) {
@@ -386,7 +391,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
@@ -666,7 +671,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
@@ -263,7 +263,7 @@
         v-if="pollsAvailable"
         ref="pollForm"
         :visible="pollFormVisible"
-        @update-poll="setPoll"
+        v-model="newStatus.poll"
       />
       <div
         ref="bottom"
diff --git a/src/services/poll/poll.service.js b/src/services/poll/poll.service.js
@@ -0,0 +1,36 @@
+import * as DateUtils from 'src/services/date_utils/date_utils.js'
+import { uniq } from 'lodash'
+
+const pollFallbackValues = {
+  pollType: 'single',
+  options: ['', ''],
+  expiryAmount: 10,
+  expiryUnit: 'minutes'
+}
+
+const pollFallback = (object, attr) => {
+  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
+}