tooot/src/screens/Compose/Root.tsx

187 lines
5.2 KiB
TypeScript
Raw Normal View History

2021-01-16 00:00:31 +01:00
import ComponentSeparator from '@components/Separator'
2021-01-11 21:36:57 +01:00
import { useEmojisQuery } from '@utils/queryHooks/emojis'
import { useSearchQuery } from '@utils/queryHooks/search'
import { StyleConstants } from '@utils/styles/constants'
import { useTheme } from '@utils/styles/ThemeManager'
2021-05-23 23:19:37 +02:00
import { chunk, forEach, groupBy, sortBy } from 'lodash'
2021-04-09 21:43:12 +02:00
import React, {
useCallback,
useContext,
useEffect,
useMemo,
useRef
} from 'react'
import {
AccessibilityInfo,
findNodeHandle,
FlatList,
StyleSheet,
View
} from 'react-native'
2021-02-08 23:47:20 +01:00
import { Circle } from 'react-native-animated-spinkit'
2021-01-19 01:13:45 +01:00
import ComposeActions from './Root/Actions'
2021-01-14 22:53:01 +01:00
import ComposePosting from './Posting'
2021-01-01 17:52:14 +01:00
import ComposeRootFooter from './Root/Footer'
import ComposeRootHeader from './Root/Header'
2021-01-07 19:13:09 +01:00
import ComposeRootSuggestion from './Root/Suggestion'
2021-01-01 17:52:14 +01:00
import ComposeContext from './utils/createContext'
2021-02-07 00:39:11 +01:00
import ComposeDrafts from './Root/Drafts'
2021-03-27 00:02:32 +01:00
import FastImage from 'react-native-fast-image'
import { useAccessibility } from '@utils/accessibility/AccessibilityManager'
2021-05-23 23:19:37 +02:00
import { ComposeState } from './utils/types'
2021-11-15 22:34:43 +01:00
import { useSelector } from 'react-redux'
import { getInstanceConfigurationStatusCharsURL } from '@utils/slices/instancesSlice'
2020-12-04 01:17:10 +01:00
2021-02-27 16:33:54 +01:00
const prefetchEmojis = (
2021-05-23 23:19:37 +02:00
sortedEmojis: NonNullable<ComposeState['emoji']['emojis']>,
2021-03-27 00:02:32 +01:00
reduceMotionEnabled: boolean
2021-02-27 16:33:54 +01:00
) => {
2021-03-27 00:02:32 +01:00
const prefetches: { uri: string }[] = []
2021-02-27 16:33:54 +01:00
let requestedIndex = 0
2021-03-09 01:17:07 +01:00
sortedEmojis.forEach(sorted => {
2021-05-23 23:19:37 +02:00
sorted.data.forEach(emojis =>
emojis.forEach(emoji => {
if (requestedIndex > 40) {
return
}
prefetches.push({
uri: reduceMotionEnabled ? emoji.static_url : emoji.url
})
requestedIndex++
2021-03-27 00:02:32 +01:00
})
2021-05-23 23:19:37 +02:00
)
2021-02-27 16:33:54 +01:00
})
try {
FastImage.preload(prefetches)
} catch {}
2021-02-27 16:33:54 +01:00
}
2021-11-15 22:34:43 +01:00
export let instanceConfigurationStatusCharsURL = 23
2021-03-18 23:32:31 +01:00
const ComposeRoot = React.memo(
() => {
2021-03-27 00:02:32 +01:00
const { reduceMotionEnabled } = useAccessibility()
2021-03-18 23:32:31 +01:00
const { theme } = useTheme()
2021-11-15 22:34:43 +01:00
instanceConfigurationStatusCharsURL = useSelector(
getInstanceConfigurationStatusCharsURL,
() => true
)
2021-04-09 21:43:12 +02:00
const accessibleRefDrafts = useRef(null)
const accessibleRefAttachments = useRef(null)
const accessibleRefEmojis = useRef(null)
useEffect(() => {
const tagDrafts = findNodeHandle(accessibleRefDrafts.current)
tagDrafts && AccessibilityInfo.setAccessibilityFocus(tagDrafts)
}, [accessibleRefDrafts.current])
2021-03-18 23:32:31 +01:00
const { composeState, composeDispatch } = useContext(ComposeContext)
2021-03-18 23:32:31 +01:00
const { isFetching, data, refetch } = useSearchQuery({
type:
composeState.tag?.type === 'accounts' ||
composeState.tag?.type === 'hashtags'
? composeState.tag.type
: undefined,
term: composeState.tag?.text.substring(1),
options: { enabled: false }
})
2021-01-07 19:13:09 +01:00
2021-03-18 23:32:31 +01:00
useEffect(() => {
if (
(composeState.tag?.type === 'accounts' ||
composeState.tag?.type === 'hashtags') &&
composeState.tag?.text
) {
refetch()
}
}, [composeState.tag])
2020-12-04 01:17:10 +01:00
2021-03-18 23:32:31 +01:00
const { data: emojisData } = useEmojisQuery({})
useEffect(() => {
if (emojisData && emojisData.length) {
2021-05-23 23:19:37 +02:00
let sortedEmojis: { title: string; data: Mastodon.Emoji[][] }[] = []
2021-03-18 23:32:31 +01:00
forEach(
groupBy(sortBy(emojisData, ['category', 'shortcode']), 'category'),
2021-05-23 23:19:37 +02:00
(value, key) =>
sortedEmojis.push({ title: key, data: chunk(value, 5) })
2021-03-18 23:32:31 +01:00
)
composeDispatch({
type: 'emoji',
payload: { ...composeState.emoji, emojis: sortedEmojis }
})
2021-03-27 00:02:32 +01:00
prefetchEmojis(sortedEmojis, reduceMotionEnabled)
2021-03-18 23:32:31 +01:00
}
2021-03-27 00:02:32 +01:00
}, [emojisData, reduceMotionEnabled])
2020-11-15 20:29:43 +01:00
2021-03-18 23:32:31 +01:00
const listEmpty = useMemo(() => {
if (isFetching) {
return (
<View key='listEmpty' style={styles.loading}>
<Circle
size={StyleConstants.Font.Size.M * 1.25}
color={theme.secondary}
/>
</View>
)
}
}, [isFetching])
2020-12-04 01:17:10 +01:00
2021-03-18 23:32:31 +01:00
const listItem = useCallback(
({ item }) => (
<ComposeRootSuggestion
item={item}
composeState={composeState}
composeDispatch={composeDispatch}
/>
),
[composeState]
)
2020-12-30 00:56:25 +01:00
2021-04-09 21:43:12 +02:00
const ListFooter = useCallback(
() => (
<ComposeRootFooter
accessibleRefAttachments={accessibleRefAttachments}
accessibleRefEmojis={accessibleRefEmojis}
/>
),
[]
)
2021-03-18 23:32:31 +01:00
return (
<View style={styles.base}>
<FlatList
renderItem={listItem}
ListEmptyComponent={listEmpty}
keyboardShouldPersistTaps='always'
ListHeaderComponent={ComposeRootHeader}
2021-04-09 21:43:12 +02:00
ListFooterComponent={ListFooter}
2021-03-18 23:32:31 +01:00
ItemSeparatorComponent={ComponentSeparator}
// @ts-ignore
data={data ? data[composeState.tag?.type] : undefined}
keyExtractor={() => Math.random().toString()}
/>
<ComposeActions />
2021-04-09 21:43:12 +02:00
<ComposeDrafts accessibleRefDrafts={accessibleRefDrafts} />
2021-03-18 23:32:31 +01:00
<ComposePosting />
</View>
)
},
() => true
)
2020-11-15 20:29:43 +01:00
const styles = StyleSheet.create({
2020-11-20 01:41:46 +01:00
base: {
2020-11-15 20:29:43 +01:00
flex: 1
},
2020-12-03 22:03:06 +01:00
contentView: { flex: 1 },
loading: {
flex: 1,
alignItems: 'center'
2020-11-15 20:29:43 +01:00
}
})
2020-12-03 22:03:06 +01:00
export default ComposeRoot