make min/max expiry dynamic
This commit is contained in:
parent
32dae8eb7a
commit
64737f32d2
|
@ -194,13 +194,12 @@ const getNodeInfo = async ({ store }) => {
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
const data = await res.json()
|
const data = await res.json()
|
||||||
const metadata = data.metadata
|
const metadata = data.metadata
|
||||||
store.dispatch('setInstanceOption', { name: 'pollLimits', value: metadata.pollLimits })
|
|
||||||
|
|
||||||
const features = metadata.features
|
const features = metadata.features
|
||||||
store.dispatch('setInstanceOption', { name: 'mediaProxyAvailable', value: features.includes('media_proxy') })
|
store.dispatch('setInstanceOption', { name: 'mediaProxyAvailable', value: features.includes('media_proxy') })
|
||||||
store.dispatch('setInstanceOption', { name: 'chatAvailable', value: features.includes('chat') })
|
store.dispatch('setInstanceOption', { name: 'chatAvailable', value: features.includes('chat') })
|
||||||
store.dispatch('setInstanceOption', { name: 'gopherAvailable', value: features.includes('gopher') })
|
store.dispatch('setInstanceOption', { name: 'gopherAvailable', value: features.includes('gopher') })
|
||||||
store.dispatch('setInstanceOption', { name: 'pollsAvailable', value: features.includes('polls') })
|
store.dispatch('setInstanceOption', { name: 'pollsAvailable', value: features.includes('polls') })
|
||||||
|
store.dispatch('setInstanceOption', { name: 'pollLimits', value: metadata.pollLimits })
|
||||||
|
|
||||||
store.dispatch('setInstanceOption', { name: 'restrictedNicknames', value: metadata.restrictedNicknames })
|
store.dispatch('setInstanceOption', { name: 'restrictedNicknames', value: metadata.restrictedNicknames })
|
||||||
store.dispatch('setInstanceOption', { name: 'postFormats', value: metadata.postFormats })
|
store.dispatch('setInstanceOption', { name: 'postFormats', value: metadata.postFormats })
|
||||||
|
|
|
@ -13,7 +13,8 @@
|
||||||
<style>
|
<style>
|
||||||
.media-upload {
|
.media-upload {
|
||||||
font-size: 26px;
|
font-size: 26px;
|
||||||
flex: 1;
|
min-width: 50px;
|
||||||
|
flex: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon-upload {
|
.icon-upload {
|
||||||
|
|
|
@ -1,12 +1,13 @@
|
||||||
|
import * as DateUtils from 'src/services/date_utils/date_utils.js'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'PollForm',
|
name: 'PollForm',
|
||||||
props: ['visible'],
|
props: ['visible'],
|
||||||
data: () => ({
|
data: () => ({
|
||||||
pollType: 'single',
|
pollType: 'single',
|
||||||
options: ['', ''],
|
options: ['', ''],
|
||||||
expiryAmount: 2,
|
expiryAmount: 10,
|
||||||
expiryUnit: 'hours',
|
expiryUnit: 'minutes'
|
||||||
expiryUnits: ['minutes', 'hours', 'days']
|
|
||||||
}),
|
}),
|
||||||
computed: {
|
computed: {
|
||||||
pollLimits () {
|
pollLimits () {
|
||||||
|
@ -17,17 +18,40 @@ export default {
|
||||||
},
|
},
|
||||||
maxLength () {
|
maxLength () {
|
||||||
return this.pollLimits.max_option_chars
|
return this.pollLimits.max_option_chars
|
||||||
|
},
|
||||||
|
expiryUnits () {
|
||||||
|
const allUnits = ['minutes', 'hours', 'days']
|
||||||
|
const expiry = this.convertExpiryFromUnit
|
||||||
|
return allUnits.filter(
|
||||||
|
unit => this.pollLimits.max_expiration >= expiry(unit, 1)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
minExpirationInCurrentUnit () {
|
||||||
|
return Math.ceil(
|
||||||
|
this.convertExpiryToUnit(
|
||||||
|
this.expiryUnit,
|
||||||
|
this.pollLimits.min_expiration
|
||||||
|
)
|
||||||
|
)
|
||||||
|
},
|
||||||
|
maxExpirationInCurrentUnit () {
|
||||||
|
return Math.floor(
|
||||||
|
this.convertExpiryToUnit(
|
||||||
|
this.expiryUnit,
|
||||||
|
this.pollLimits.max_expiration
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
clear () {
|
clear () {
|
||||||
this.pollType = 'single'
|
this.pollType = 'single'
|
||||||
this.options = ['', '']
|
this.options = ['', '']
|
||||||
this.expiryAmount = 1
|
this.expiryAmount = 10
|
||||||
this.expiryUnit = 'minutes'
|
this.expiryUnit = 'minutes'
|
||||||
},
|
},
|
||||||
nextOption (index) {
|
nextOption (index) {
|
||||||
const element = this.$el.querySelector(`#poll-${index+1}`)
|
const element = this.$el.querySelector(`#poll-${index + 1}`)
|
||||||
if (element) {
|
if (element) {
|
||||||
element.focus()
|
element.focus()
|
||||||
} else {
|
} else {
|
||||||
|
@ -52,17 +76,34 @@ export default {
|
||||||
this.options.splice(index, 1)
|
this.options.splice(index, 1)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
convertExpiryToUnit (unit, amount) {
|
||||||
|
// Note: we want seconds and not milliseconds
|
||||||
|
switch (unit) {
|
||||||
|
case 'minutes': return (1000 * amount) / DateUtils.MINUTE
|
||||||
|
case 'hours': return (1000 * amount) / DateUtils.HOUR
|
||||||
|
case 'days': return (1000 * amount) / DateUtils.DAY
|
||||||
|
}
|
||||||
|
},
|
||||||
|
convertExpiryFromUnit (unit, amount) {
|
||||||
|
// Note: we want seconds and not milliseconds
|
||||||
|
switch (unit) {
|
||||||
|
case 'minutes': return 0.001 * amount * DateUtils.MINUTE
|
||||||
|
case 'hours': return 0.001 * amount * DateUtils.HOUR
|
||||||
|
case 'days': return 0.001 * amount * DateUtils.DAY
|
||||||
|
}
|
||||||
|
},
|
||||||
expiryAmountChange () {
|
expiryAmountChange () {
|
||||||
this.expiryAmount = Math.max(1, this.expiryAmount)
|
this.expiryAmount =
|
||||||
this.expiryAmount = Math.min(120, this.expiryAmount)
|
Math.max(this.minExpirationInCurrentUnit, this.expiryAmount)
|
||||||
|
this.expiryAmount =
|
||||||
|
Math.min(this.maxExpirationInCurrentUnit, this.expiryAmount)
|
||||||
this.updatePollToParent()
|
this.updatePollToParent()
|
||||||
},
|
},
|
||||||
updatePollToParent () {
|
updatePollToParent () {
|
||||||
const unitMultiplier = this.expiryUnit === 'minutes' ? 60
|
const expiresIn = this.convertExpiryFromUnit(
|
||||||
: this.expiryUnit === 'hours' ? 60 * 60
|
this.expiryUnit,
|
||||||
: 60 * 60 * 24
|
this.expiryAmount
|
||||||
|
)
|
||||||
const expiresIn = this.expiryAmount * unitMultiplier
|
|
||||||
|
|
||||||
this.$emit('update-poll', {
|
this.$emit('update-poll', {
|
||||||
options: this.options,
|
options: this.options,
|
||||||
|
|
|
@ -39,13 +39,16 @@
|
||||||
<input
|
<input
|
||||||
type="number"
|
type="number"
|
||||||
class="expiry-amount hide-number-spinner"
|
class="expiry-amount hide-number-spinner"
|
||||||
min="1"
|
:min="minExpirationInCurrentUnit"
|
||||||
max="120"
|
:max="maxExpirationInCurrentUnit"
|
||||||
v-model="expiryAmount"
|
v-model="expiryAmount"
|
||||||
@change="expiryAmountChange"
|
@change="expiryAmountChange"
|
||||||
>
|
>
|
||||||
<label class="expiry-unit select">
|
<label class="expiry-unit select">
|
||||||
<select v-model="expiryUnit" @change="updatePollToParent">
|
<select
|
||||||
|
v-model="expiryUnit"
|
||||||
|
@change="expiryAmountChange"
|
||||||
|
>
|
||||||
<option v-for="unit in expiryUnits" :value="unit">
|
<option v-for="unit in expiryUnits" :value="unit">
|
||||||
{{ $t(`time.${unit}_short`, ['']) }}
|
{{ $t(`time.${unit}_short`, ['']) }}
|
||||||
</option>
|
</option>
|
||||||
|
@ -83,12 +86,14 @@
|
||||||
.input-container {
|
.input-container {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
input {
|
input {
|
||||||
|
// Hack: dodge the floating X icon
|
||||||
|
padding-right: 2.5em;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon-container {
|
.icon-container {
|
||||||
// Move the icon over the input box
|
// Hack: Move the icon over the input box
|
||||||
width: 2em;
|
width: 2em;
|
||||||
margin-left: -2em;
|
margin-left: -2em;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
|
|
|
@ -7,13 +7,13 @@ import fileTypeService from '../../services/file_type/file_type.service.js'
|
||||||
import Completion from '../../services/completion/completion.js'
|
import Completion from '../../services/completion/completion.js'
|
||||||
import { take, filter, reject, map, uniqBy } from 'lodash'
|
import { take, filter, reject, map, uniqBy } from 'lodash'
|
||||||
|
|
||||||
const buildMentionsString = ({user, attentions}, currentUser) => {
|
const buildMentionsString = ({ user, attentions }, currentUser) => {
|
||||||
let allAttentions = [...attentions]
|
let allAttentions = [...attentions]
|
||||||
|
|
||||||
allAttentions.unshift(user)
|
allAttentions.unshift(user)
|
||||||
|
|
||||||
allAttentions = uniqBy(allAttentions, 'id')
|
allAttentions = uniqBy(allAttentions, 'id')
|
||||||
allAttentions = reject(allAttentions, {id: currentUser.id})
|
allAttentions = reject(allAttentions, { id: currentUser.id })
|
||||||
|
|
||||||
let mentions = map(allAttentions, (attention) => {
|
let mentions = map(allAttentions, (attention) => {
|
||||||
return `@${attention.screen_name}`
|
return `@${attention.screen_name}`
|
||||||
|
@ -98,7 +98,7 @@ const PostStatusForm = {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
// eslint-disable-next-line camelcase
|
// eslint-disable-next-line camelcase
|
||||||
return map(take(matchedUsers, 5), ({screen_name, name, profile_image_url_original}, index) => ({
|
return map(take(matchedUsers, 5), ({ screen_name, name, profile_image_url_original }, index) => ({
|
||||||
// eslint-disable-next-line camelcase
|
// eslint-disable-next-line camelcase
|
||||||
screen_name: `@${screen_name}`,
|
screen_name: `@${screen_name}`,
|
||||||
name: name,
|
name: name,
|
||||||
|
@ -111,7 +111,7 @@ const PostStatusForm = {
|
||||||
if (matchedEmoji.length <= 0) {
|
if (matchedEmoji.length <= 0) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return map(take(matchedEmoji, 5), ({shortcode, image_url, utf}, index) => ({
|
return map(take(matchedEmoji, 5), ({ shortcode, image_url, utf }, index) => ({
|
||||||
screen_name: `:${shortcode}:`,
|
screen_name: `:${shortcode}:`,
|
||||||
name: '',
|
name: '',
|
||||||
utf: utf || '',
|
utf: utf || '',
|
||||||
|
@ -188,7 +188,8 @@ const PostStatusForm = {
|
||||||
return this.$store.state.instance.safeDM
|
return this.$store.state.instance.safeDM
|
||||||
},
|
},
|
||||||
pollsAvailable () {
|
pollsAvailable () {
|
||||||
return this.$store.state.instance.pollsAvailable
|
return this.$store.state.instance.pollsAvailable &&
|
||||||
|
this.$store.state.instance.pollLimits.max_options >= 2
|
||||||
},
|
},
|
||||||
hideScopeNotice () {
|
hideScopeNotice () {
|
||||||
return this.$store.state.config.hideScopeNotice
|
return this.$store.state.config.hideScopeNotice
|
||||||
|
@ -243,7 +244,7 @@ const PostStatusForm = {
|
||||||
onKeydown (e) {
|
onKeydown (e) {
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
},
|
},
|
||||||
setCaret ({target: {selectionStart}}) {
|
setCaret ({ target: { selectionStart } }) {
|
||||||
this.caret = selectionStart
|
this.caret = selectionStart
|
||||||
},
|
},
|
||||||
postStatus (newStatus) {
|
postStatus (newStatus) {
|
||||||
|
@ -330,7 +331,7 @@ const PostStatusForm = {
|
||||||
},
|
},
|
||||||
fileDrop (e) {
|
fileDrop (e) {
|
||||||
if (e.dataTransfer.files.length > 0) {
|
if (e.dataTransfer.files.length > 0) {
|
||||||
e.preventDefault() // allow dropping text like before
|
e.preventDefault() // allow dropping text like before
|
||||||
this.dropFiles = e.dataTransfer.files
|
this.dropFiles = e.dataTransfer.files
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue