import Button from '@components/Button'
import haptics from '@components/haptics'
import Icon from '@components/Icon'
import { displayMessage } from '@components/Message'
import { ParseEmojis } from '@components/Parse'
import RelativeTime from '@components/RelativeTime'
import CustomText from '@components/Text'
import { useQueryClient } from '@tanstack/react-query'
import { useNavState } from '@utils/navigation/navigators'
import {
MutationVarsTimelineUpdateStatusProperty,
useTimelineMutation
} from '@utils/queryHooks/timeline'
import updateStatusProperty from '@utils/queryHooks/timeline/updateStatusProperty'
import { StyleConstants } from '@utils/styles/constants'
import { useTheme } from '@utils/styles/ThemeManager'
import { maxBy } from 'lodash'
import React, { useContext, useState } from 'react'
import { Trans, useTranslation } from 'react-i18next'
import { Pressable, View } from 'react-native'
import StatusContext from './Context'
const TimelinePoll: React.FC = () => {
const { queryKey, status, ownAccount, spoilerHidden, disableDetails, highlighted } =
useContext(StatusContext)
if (!queryKey || !status || !status.poll) return null
const poll = status.poll
const { colors, theme } = useTheme()
const { t } = useTranslation(['common', 'componentTimeline'])
const [allOptions, setAllOptions] = useState(new Array(status.poll.options.length).fill(false))
const navigationState = useNavState()
const queryClient = useQueryClient()
const mutation = useTimelineMutation({
onSuccess: ({ body }, params) => {
const theParams = params as MutationVarsTimelineUpdateStatusProperty
queryClient.cancelQueries(queryKey)
haptics('Success')
switch (theParams.payload.type) {
case 'poll':
updateStatusProperty(
{ ...theParams, poll: body as unknown as Mastodon.Poll },
navigationState
)
break
}
},
onError: (err: any, params) => {
const theParams = params as MutationVarsTimelineUpdateStatusProperty
displayMessage({
theme,
type: 'error',
message: t('common:message.error.message', {
// @ts-ignore
function: t(`componentTimeline:shared.poll.meta.button.${theParams.payload.type}` as any)
}),
...(err.status &&
typeof err.status === 'number' &&
err.data &&
err.data.error &&
typeof err.data.error === 'string' && {
description: err.data.error
})
})
queryClient.invalidateQueries(queryKey)
}
})
const pollButton = () => {
if (!poll.expired) {
if (!ownAccount && !poll.voted) {
return (
)
} else if (highlighted) {
return (
)
}
}
}
const isSelected = (index: number) =>
allOptions[index]
? poll.multiple
? 'check-square'
: 'check-circle'
: poll.multiple
? 'square'
: 'circle'
const pollBodyDisallow = () => {
const maxValue = maxBy(poll.options, option => option.votes_count)?.votes_count
return poll.options.map((option, index) => (
{poll.votes_count
? Math.round((option.votes_count / (poll.voters_count || poll.votes_count)) * 100)
: 0}
%
))
}
const pollBodyAllow = () => {
return poll.options.map((option, index) => (
{
!allOptions[index] && haptics('Light')
if (poll.multiple) {
setAllOptions(allOptions.map((o, i) => (i === index ? !o : o)))
} else {
{
const otherOptions = allOptions[index] === false ? false : undefined
setAllOptions(
allOptions.map((o, i) =>
i === index ? !o : otherOptions !== undefined ? otherOptions : o
)
)
}
}
}}
>
))
}
const pollVoteCounts = () => {
if (poll.voters_count !== null) {
return t('componentTimeline:shared.poll.meta.count.voters', { count: poll.voters_count })
} else if (poll.votes_count !== null) {
return t('componentTimeline:shared.poll.meta.count.votes', { count: poll.votes_count })
}
}
const pollExpiration = () => {
if (poll.expired) {
return t('componentTimeline:shared.poll.meta.expiration.expired')
} else {
if (poll.expires_at) {
return (
<>
{' • '}
]}
/>
>
)
}
}
}
if (spoilerHidden || disableDetails) return null
return (
{poll.expired || poll.voted ? pollBodyDisallow() : pollBodyAllow()}
{pollButton()}
{pollVoteCounts()}
{pollExpiration()}
)
}
export default TimelinePoll