tooot/src/screens/Compose/Root/Actions.tsx

239 lines
7.7 KiB
TypeScript
Raw Normal View History

2022-09-20 22:23:01 +02:00
import { emojis } from '@components/Emojis'
import EmojisContext from '@components/Emojis/helpers/EmojisContext'
import Icon from '@components/Icon'
2021-01-13 01:03:46 +01:00
import { useActionSheet } from '@expo/react-native-action-sheet'
2021-11-15 22:34:43 +01:00
import { getInstanceConfigurationStatusMaxAttachments } from '@utils/slices/instancesSlice'
2021-01-01 17:52:14 +01:00
import layoutAnimation from '@utils/styles/layoutAnimation'
2020-12-13 14:04:25 +01:00
import { useTheme } from '@utils/styles/ThemeManager'
import React, { useContext, useMemo } from 'react'
2021-01-19 01:13:45 +01:00
import { useTranslation } from 'react-i18next'
import { Keyboard, Pressable, StyleSheet, View } from 'react-native'
2021-11-15 22:34:43 +01:00
import { useSelector } from 'react-redux'
2021-01-19 01:13:45 +01:00
import ComposeContext from '../utils/createContext'
2022-05-02 22:31:22 +02:00
import chooseAndUploadAttachment from './Footer/addAttachment'
2020-12-03 22:03:06 +01:00
const ComposeActions: React.FC = () => {
2021-01-13 01:03:46 +01:00
const { showActionSheetWithOptions } = useActionSheet()
const { composeState, composeDispatch } = useContext(ComposeContext)
2021-03-28 23:31:10 +02:00
const { t } = useTranslation('screenCompose')
2022-02-12 14:51:01 +01:00
const { colors, mode } = useTheme()
2021-11-15 22:34:43 +01:00
const instanceConfigurationStatusMaxAttachments = useSelector(
getInstanceConfigurationStatusMaxAttachments,
() => true
)
2020-12-03 22:03:06 +01:00
2020-12-06 21:42:19 +01:00
const attachmentColor = useMemo(() => {
2022-02-12 14:51:01 +01:00
if (composeState.poll.active) return colors.disabled
2020-12-06 21:42:19 +01:00
2020-12-07 12:31:40 +01:00
if (composeState.attachments.uploads.length) {
2022-02-12 14:51:01 +01:00
return colors.primaryDefault
2020-12-06 21:42:19 +01:00
} else {
2022-02-12 14:51:01 +01:00
return colors.secondary
2020-12-06 21:42:19 +01:00
}
2020-12-30 00:56:25 +01:00
}, [composeState.poll.active, composeState.attachments.uploads])
const attachmentOnPress = () => {
2020-12-26 14:40:10 +01:00
if (composeState.poll.active) return
2020-12-06 21:42:19 +01:00
if (composeState.attachments.uploads.length < instanceConfigurationStatusMaxAttachments) {
return chooseAndUploadAttachment({
2021-01-13 01:03:46 +01:00
composeDispatch,
showActionSheetWithOptions
})
2020-12-06 21:42:19 +01:00
}
}
2020-12-06 21:42:19 +01:00
const pollColor = useMemo(() => {
2022-02-12 14:51:01 +01:00
if (composeState.attachments.uploads.length) return colors.disabled
2020-12-26 14:40:10 +01:00
2020-12-07 12:31:40 +01:00
if (composeState.poll.active) {
2022-02-12 14:51:01 +01:00
return colors.primaryDefault
2020-12-06 21:42:19 +01:00
} else {
2022-02-12 14:51:01 +01:00
return colors.secondary
2020-12-06 21:42:19 +01:00
}
2020-12-30 00:56:25 +01:00
}, [composeState.poll.active, composeState.attachments.uploads])
const pollOnPress = () => {
2020-12-30 00:56:25 +01:00
if (!composeState.attachments.uploads.length) {
layoutAnimation()
2020-12-07 12:31:40 +01:00
composeDispatch({
2020-12-06 21:42:19 +01:00
type: 'poll',
2020-12-07 12:31:40 +01:00
payload: { ...composeState.poll, active: !composeState.poll.active }
2020-12-06 21:42:19 +01:00
})
}
2020-12-07 12:31:40 +01:00
if (composeState.poll.active) {
composeState.textInputFocus.refs.text.current?.focus()
2020-12-06 21:42:19 +01:00
}
}
2020-12-06 21:42:19 +01:00
2020-12-10 19:19:56 +01:00
const visibilityIcon = useMemo(() => {
switch (composeState.visibility) {
case 'public':
return 'Globe'
2020-12-10 19:19:56 +01:00
case 'unlisted':
return 'Unlock'
2020-12-10 19:19:56 +01:00
case 'private':
return 'Lock'
2020-12-10 19:19:56 +01:00
case 'direct':
return 'Mail'
2020-12-10 19:19:56 +01:00
}
}, [composeState.visibility])
const visibilityOnPress = () => {
2020-12-26 00:40:27 +01:00
if (!composeState.visibilityLock) {
2021-01-13 01:03:46 +01:00
showActionSheetWithOptions(
2020-12-10 19:19:56 +01:00
{
2021-01-19 01:13:45 +01:00
title: t('content.root.actions.visibility.title'),
options: [
t('content.root.actions.visibility.options.public'),
t('content.root.actions.visibility.options.unlisted'),
t('content.root.actions.visibility.options.private'),
t('content.root.actions.visibility.options.direct'),
t('content.root.actions.visibility.options.cancel')
],
2022-02-12 14:51:01 +01:00
cancelButtonIndex: 4,
userInterfaceStyle: mode
2020-12-10 19:19:56 +01:00
},
buttonIndex => {
switch (buttonIndex) {
case 0:
composeDispatch({ type: 'visibility', payload: 'public' })
break
case 1:
composeDispatch({ type: 'visibility', payload: 'unlisted' })
break
case 2:
composeDispatch({ type: 'visibility', payload: 'private' })
break
case 3:
composeDispatch({ type: 'visibility', payload: 'direct' })
break
}
}
2020-12-26 00:40:27 +01:00
)
}
}
2020-12-10 19:19:56 +01:00
const spoilerOnPress = () => {
2020-12-26 00:40:27 +01:00
if (composeState.spoiler.active) {
composeState.textInputFocus.refs.text.current?.focus()
}
2020-12-30 00:56:25 +01:00
layoutAnimation()
2020-12-26 00:40:27 +01:00
composeDispatch({
type: 'spoiler',
payload: { active: !composeState.spoiler.active }
})
}
2020-12-10 19:19:56 +01:00
const { emojisState, emojisDispatch } = useContext(EmojisContext)
2020-12-06 22:32:36 +01:00
const emojiColor = useMemo(() => {
2022-09-20 22:23:01 +02:00
if (!emojis.current?.length) return colors.disabled
2020-12-26 14:40:10 +01:00
if (emojisState.targetIndex !== -1) {
2022-02-12 14:51:01 +01:00
return colors.primaryDefault
2020-12-06 22:32:36 +01:00
} else {
2022-02-12 14:51:01 +01:00
return colors.secondary
2020-12-06 22:32:36 +01:00
}
2022-09-20 22:23:01 +02:00
}, [emojis.current?.length, emojisState.targetIndex])
const emojiOnPress = () => {
if (emojisState.targetIndex === -1) {
Keyboard.dismiss()
2022-09-19 22:22:52 +02:00
const focusedPropsIndex = emojisState.inputProps?.findIndex(props => props.isFocused.current)
if (focusedPropsIndex === -1) return
emojisDispatch({ type: 'target', payload: focusedPropsIndex })
} else {
emojisDispatch({ type: 'target', payload: -1 })
return
2020-12-06 22:32:36 +01:00
}
}
2020-12-06 22:32:36 +01:00
2020-12-03 22:03:06 +01:00
return (
2020-12-10 19:19:56 +01:00
<View
2021-04-09 21:43:12 +02:00
accessibilityRole='toolbar'
2022-05-10 23:19:26 +02:00
style={{
height: 45,
borderTopWidth: StyleSheet.hairlineWidth,
flexDirection: 'row',
justifyContent: 'space-around',
alignItems: 'center',
backgroundColor: colors.backgroundDefault,
borderTopColor: colors.border
}}
2020-12-03 22:03:06 +01:00
>
<Pressable
2021-04-09 21:43:12 +02:00
accessibilityRole='button'
accessibilityLabel={t('content.root.actions.attachment.accessibilityLabel')}
accessibilityHint={t('content.root.actions.attachment.accessibilityHint')}
2021-04-09 21:43:12 +02:00
accessibilityState={{
disabled: composeState.poll.active
}}
style={styles.button}
2020-12-06 21:42:19 +01:00
onPress={attachmentOnPress}
children={<Icon name='Aperture' size={24} color={attachmentColor} />}
2020-12-03 22:03:06 +01:00
/>
<Pressable
2021-04-09 21:43:12 +02:00
accessibilityRole='button'
accessibilityLabel={t('content.root.actions.poll.accessibilityLabel')}
accessibilityHint={t('content.root.actions.poll.accessibilityHint')}
accessibilityState={{
disabled: composeState.attachments.uploads.length ? true : false,
expanded: composeState.poll.active
}}
style={styles.button}
2020-12-06 21:42:19 +01:00
onPress={pollOnPress}
children={<Icon name='BarChart2' size={24} color={pollColor} />}
2020-12-03 22:03:06 +01:00
/>
<Pressable
2021-04-09 21:43:12 +02:00
accessibilityRole='button'
accessibilityLabel={t('content.root.actions.visibility.accessibilityLabel', {
visibility: composeState.visibility
})}
2021-04-09 21:43:12 +02:00
accessibilityState={{ disabled: composeState.visibilityLock }}
style={styles.button}
2020-12-10 19:19:56 +01:00
onPress={visibilityOnPress}
children={
<Icon
name={visibilityIcon}
size={24}
color={composeState.visibilityLock ? colors.disabled : colors.secondary}
/>
}
2020-12-03 22:03:06 +01:00
/>
<Pressable
2021-04-09 21:43:12 +02:00
accessibilityRole='button'
accessibilityLabel={t('content.root.actions.spoiler.accessibilityLabel')}
2021-04-09 21:43:12 +02:00
accessibilityState={{ expanded: composeState.spoiler.active }}
style={styles.button}
2020-12-10 19:19:56 +01:00
onPress={spoilerOnPress}
children={
<Icon
name='AlertTriangle'
size={24}
color={composeState.spoiler.active ? colors.primaryDefault : colors.secondary}
/>
}
2020-12-06 23:51:13 +01:00
/>
<Pressable
2021-04-09 21:43:12 +02:00
accessibilityRole='button'
accessibilityLabel={t('content.root.actions.emoji.accessibilityLabel')}
accessibilityHint={t('content.root.actions.emoji.accessibilityHint')}
accessibilityState={{
2022-09-20 22:23:01 +02:00
disabled: emojis.current?.length ? false : true,
expanded: emojisState.targetIndex !== -1
2021-04-09 21:43:12 +02:00
}}
style={styles.button}
2020-12-06 22:32:36 +01:00
onPress={emojiOnPress}
children={<Icon name='Smile' size={24} color={emojiColor} />}
2020-12-03 22:03:06 +01:00
/>
2020-12-10 19:19:56 +01:00
</View>
2020-12-03 22:03:06 +01:00
)
}
const styles = StyleSheet.create({
2021-04-09 21:43:12 +02:00
button: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
height: '100%'
2020-12-03 22:03:06 +01:00
}
})
export default ComposeActions