tooot/src/screens/Shared/Compose/Emojis.tsx

120 lines
2.7 KiB
TypeScript
Raw Normal View History

2020-12-10 19:19:56 +01:00
import React, { Dispatch, useCallback, useMemo } from 'react'
2020-12-03 22:03:06 +01:00
import {
Image,
Pressable,
SectionList,
StyleSheet,
Text,
TextInput,
View
} from 'react-native'
import { StyleConstants } from 'src/utils/styles/constants'
import { useTheme } from 'src/utils/styles/ThemeManager'
2020-12-07 12:31:40 +01:00
import { PostAction, ComposeState } from '../Compose'
2020-12-03 22:03:06 +01:00
import updateText from './updateText'
export interface Props {
textInputRef: React.RefObject<TextInput>
2020-12-07 12:31:40 +01:00
composeState: ComposeState
composeDispatch: Dispatch<PostAction>
2020-12-03 22:03:06 +01:00
}
2020-12-10 19:19:56 +01:00
const SingleEmoji = ({
emoji,
2020-12-03 22:03:06 +01:00
textInputRef,
2020-12-07 12:31:40 +01:00
composeState,
composeDispatch
2020-12-10 19:19:56 +01:00
}: { emoji: Mastodon.Emoji } & Props) => {
const onPress = useCallback(() => {
updateText({
origin: textInputRef.current?.isFocused() ? 'text' : 'spoiler',
composeState,
composeDispatch,
newText: `:${emoji.shortcode}:`,
type: 'emoji'
})
composeDispatch({
type: 'emoji',
payload: { ...composeState.emoji, active: false }
})
}, [])
const children = useMemo(
() => <Image source={{ uri: emoji.url }} style={styles.emoji} />,
[]
)
return (
<Pressable key={emoji.shortcode} onPress={onPress} children={children} />
)
}
const ComposeEmojis: React.FC<Props> = ({ ...props }) => {
2020-12-03 22:03:06 +01:00
const { theme } = useTheme()
2020-12-10 19:19:56 +01:00
const listHeader = useCallback(
({ section: { title } }) => (
<Text style={[styles.group, { color: theme.secondary }]}>{title}</Text>
),
[]
)
const emojiList = useCallback(
section =>
section.data.map((emoji: Mastodon.Emoji) => (
<SingleEmoji key={emoji.shortcode} emoji={emoji} {...props} />
)),
[]
)
const listItem = useCallback(
({ section, index }) =>
index === 0 ? (
<View key={section.title} style={styles.emojis}>
{emojiList(section)}
</View>
) : null,
[]
)
2020-12-03 22:03:06 +01:00
return (
<View style={styles.base}>
<SectionList
horizontal
2020-12-06 22:32:36 +01:00
keyboardShouldPersistTaps='handled'
2020-12-10 19:19:56 +01:00
sections={props.composeState.emoji.emojis!}
2020-12-03 22:03:06 +01:00
keyExtractor={item => item.shortcode}
2020-12-10 19:19:56 +01:00
renderSectionHeader={listHeader}
renderItem={listItem}
2020-12-03 22:03:06 +01:00
/>
</View>
)
}
const styles = StyleSheet.create({
base: {
flex: 1,
flexDirection: 'row',
flexWrap: 'wrap',
justifyContent: 'space-around',
height: 260
},
group: {
position: 'absolute',
left: StyleConstants.Spacing.L,
fontSize: StyleConstants.Font.Size.S
},
emojis: {
flex: 1,
flexWrap: 'wrap',
marginTop: StyleConstants.Spacing.M,
marginLeft: StyleConstants.Spacing.M
},
emoji: {
width: 32,
height: 32,
padding: StyleConstants.Spacing.S,
margin: StyleConstants.Spacing.S
}
})
export default ComposeEmojis