feat(Poll): add option to randomize poll choices (#2082)
* feat(Poll): add option to randomize poll choices * improve --------- Co-authored-by: Keyan <34140557+huumn@users.noreply.github.com> Co-authored-by: k00b <k00b@stacker.news>
This commit is contained in:
parent
9b77cf096d
commit
984790ed5c
@ -26,6 +26,7 @@ import performPaidAction from '../paidAction'
|
|||||||
import { GqlAuthenticationError, GqlInputError } from '@/lib/error'
|
import { GqlAuthenticationError, GqlInputError } from '@/lib/error'
|
||||||
import { verifyHmac } from './wallet'
|
import { verifyHmac } from './wallet'
|
||||||
import { parse } from 'tldts'
|
import { parse } from 'tldts'
|
||||||
|
import { shuffleArray } from '@/lib/rand'
|
||||||
|
|
||||||
function commentsOrderByClause (me, models, sort) {
|
function commentsOrderByClause (me, models, sort) {
|
||||||
const sharedSortsArray = []
|
const sharedSortsArray = []
|
||||||
@ -1150,7 +1151,8 @@ export default {
|
|||||||
poll.meVoted = false
|
poll.meVoted = false
|
||||||
}
|
}
|
||||||
|
|
||||||
poll.options = options
|
poll.randPollOptions = item?.randPollOptions
|
||||||
|
poll.options = poll.randPollOptions ? shuffleArray(options) : options
|
||||||
poll.count = options.reduce((t, o) => t + o.count, 0)
|
poll.count = options.reduce((t, o) => t + o.count, 0)
|
||||||
|
|
||||||
return poll
|
return poll
|
||||||
|
@ -57,7 +57,7 @@ export default gql`
|
|||||||
text: String!, url: String!, boost: Int, status: String, logo: Int): ItemPaidAction!
|
text: String!, url: String!, boost: Int, status: String, logo: Int): ItemPaidAction!
|
||||||
upsertPoll(
|
upsertPoll(
|
||||||
id: ID, sub: String, title: String!, text: String, options: [String!]!, boost: Int, forward: [ItemForwardInput], pollExpiresAt: Date,
|
id: ID, sub: String, title: String!, text: String, options: [String!]!, boost: Int, forward: [ItemForwardInput], pollExpiresAt: Date,
|
||||||
hash: String, hmac: String): ItemPaidAction!
|
randPollOptions: Boolean, hash: String, hmac: String): ItemPaidAction!
|
||||||
updateNoteId(id: ID!, noteId: String!): Item!
|
updateNoteId(id: ID!, noteId: String!): Item!
|
||||||
upsertComment(id: ID, text: String!, parentId: ID, boost: Int, hash: String, hmac: String): ItemPaidAction!
|
upsertComment(id: ID, text: String!, parentId: ID, boost: Int, hash: String, hmac: String): ItemPaidAction!
|
||||||
act(id: ID!, sats: Int, act: String, hasSendWallet: Boolean): ItemActPaidAction!
|
act(id: ID!, sats: Int, act: String, hasSendWallet: Boolean): ItemActPaidAction!
|
||||||
@ -81,6 +81,7 @@ export default gql`
|
|||||||
meInvoiceActionState: InvoiceActionState
|
meInvoiceActionState: InvoiceActionState
|
||||||
count: Int!
|
count: Int!
|
||||||
options: [PollOption!]!
|
options: [PollOption!]!
|
||||||
|
randPollOptions: Boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
type Items {
|
type Items {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { DateTimeInput, Form, Input, MarkdownInput, VariableInput } from '@/components/form'
|
import { Checkbox, DateTimeInput, Form, Input, MarkdownInput, VariableInput } from '@/components/form'
|
||||||
import { useApolloClient } from '@apollo/client'
|
import { useApolloClient } from '@apollo/client'
|
||||||
import Countdown from './countdown'
|
import Countdown from './countdown'
|
||||||
import AdvPostForm, { AdvPostInitial } from './adv-post-form'
|
import AdvPostForm, { AdvPostInitial } from './adv-post-form'
|
||||||
@ -30,6 +30,7 @@ export function PollForm ({ item, sub, editThreshold, children }) {
|
|||||||
text: item?.text || '',
|
text: item?.text || '',
|
||||||
options: initialOptions || ['', ''],
|
options: initialOptions || ['', ''],
|
||||||
crosspost: item ? !!item.noteId : me?.privates?.nostrCrossposting,
|
crosspost: item ? !!item.noteId : me?.privates?.nostrCrossposting,
|
||||||
|
randPollOptions: item?.poll?.randPollOptions || false,
|
||||||
pollExpiresAt: item ? item.pollExpiresAt : datePivot(new Date(), { hours: 25 }),
|
pollExpiresAt: item ? item.pollExpiresAt : datePivot(new Date(), { hours: 25 }),
|
||||||
...AdvPostInitial({ forward: normalizeForwards(item?.forwards), boost: item?.boost }),
|
...AdvPostInitial({ forward: normalizeForwards(item?.forwards), boost: item?.boost }),
|
||||||
...SubSelectInitial({ sub: item?.subName || sub?.name })
|
...SubSelectInitial({ sub: item?.subName || sub?.name })
|
||||||
@ -68,6 +69,11 @@ export function PollForm ({ item, sub, editThreshold, children }) {
|
|||||||
label='poll expiration'
|
label='poll expiration'
|
||||||
name='pollExpiresAt'
|
name='pollExpiresAt'
|
||||||
className='pr-4'
|
className='pr-4'
|
||||||
|
groupClassName='mb-0'
|
||||||
|
/>
|
||||||
|
<Checkbox
|
||||||
|
label={<div className='d-flex align-items-center'>randomize order of poll choices</div>}
|
||||||
|
name='randPollOptions'
|
||||||
/>
|
/>
|
||||||
</AdvPostForm>
|
</AdvPostForm>
|
||||||
<ItemButtonBar itemId={item?.id} />
|
<ItemButtonBar itemId={item?.id} />
|
||||||
|
@ -152,6 +152,7 @@ export const POLL_FIELDS = gql`
|
|||||||
option
|
option
|
||||||
count
|
count
|
||||||
}
|
}
|
||||||
|
randPollOptions
|
||||||
}
|
}
|
||||||
}`
|
}`
|
||||||
|
|
||||||
|
@ -192,10 +192,10 @@ export const UPSERT_POLL = gql`
|
|||||||
${PAID_ACTION}
|
${PAID_ACTION}
|
||||||
mutation upsertPoll($sub: String, $id: ID, $title: String!, $text: String,
|
mutation upsertPoll($sub: String, $id: ID, $title: String!, $text: String,
|
||||||
$options: [String!]!, $boost: Int, $forward: [ItemForwardInput], $pollExpiresAt: Date,
|
$options: [String!]!, $boost: Int, $forward: [ItemForwardInput], $pollExpiresAt: Date,
|
||||||
${HASH_HMAC_INPUT_1}) {
|
$randPollOptions: Boolean, ${HASH_HMAC_INPUT_1}) {
|
||||||
upsertPoll(sub: $sub, id: $id, title: $title, text: $text,
|
upsertPoll(sub: $sub, id: $id, title: $title, text: $text,
|
||||||
options: $options, boost: $boost, forward: $forward, pollExpiresAt: $pollExpiresAt,
|
options: $options, boost: $boost, forward: $forward, pollExpiresAt: $pollExpiresAt,
|
||||||
${HASH_HMAC_INPUT_2}) {
|
randPollOptions: $randPollOptions, ${HASH_HMAC_INPUT_2}) {
|
||||||
result {
|
result {
|
||||||
id
|
id
|
||||||
deleteScheduledAt
|
deleteScheduledAt
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
export function randInRange (min, max) {
|
export function randInRange (min, max) {
|
||||||
return Math.random() * (max - min) + min
|
return Math.random() * (max - min) + min
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function shuffleArray (array) {
|
||||||
|
return [...array].sort(() => Math.random() - 0.5)
|
||||||
|
}
|
||||||
|
@ -291,6 +291,7 @@ export function pollSchema ({ numExistingChoices = 0, ...args }) {
|
|||||||
test: arr => arr.length >= MIN_POLL_NUM_CHOICES - numExistingChoices
|
test: arr => arr.length >= MIN_POLL_NUM_CHOICES - numExistingChoices
|
||||||
}),
|
}),
|
||||||
pollExpiresAt: date().nullable().min(datePivot(new Date(), { days: 1 }), 'Expiration must be at least 1 day in the future'),
|
pollExpiresAt: date().nullable().min(datePivot(new Date(), { days: 1 }), 'Expiration must be at least 1 day in the future'),
|
||||||
|
randPollOptions: boolean(),
|
||||||
...advPostSchemaMembers(args),
|
...advPostSchemaMembers(args),
|
||||||
...subSelectSchemaMembers(args)
|
...subSelectSchemaMembers(args)
|
||||||
}).test({
|
}).test({
|
||||||
|
@ -0,0 +1,2 @@
|
|||||||
|
-- AlterTable
|
||||||
|
ALTER TABLE "Item" ADD COLUMN "randPollOptions" BOOLEAN NOT NULL DEFAULT false;
|
@ -603,6 +603,7 @@ model Item {
|
|||||||
PollBlindVote PollBlindVote[]
|
PollBlindVote PollBlindVote[]
|
||||||
ItemUserAgg ItemUserAgg[]
|
ItemUserAgg ItemUserAgg[]
|
||||||
AutoSocialPost AutoSocialPost[]
|
AutoSocialPost AutoSocialPost[]
|
||||||
|
randPollOptions Boolean @default(false)
|
||||||
|
|
||||||
@@index([uploadId])
|
@@index([uploadId])
|
||||||
@@index([lastZapAt])
|
@@index([lastZapAt])
|
||||||
|
Loading…
x
Reference in New Issue
Block a user