mirror of https://github.com/tooot-app/app
Fixed #127
This commit is contained in:
parent
61459cd2d2
commit
f8366bb777
|
@ -12,21 +12,7 @@ import React, {
|
|||
useReducer
|
||||
} from 'react'
|
||||
import FastImage from 'react-native-fast-image'
|
||||
import EmojisContext, {
|
||||
EmojisAction,
|
||||
EmojisState
|
||||
} from './Emojis/helpers/EmojisContext'
|
||||
|
||||
const emojisReducer = (state: EmojisState, action: EmojisAction) => {
|
||||
switch (action.type) {
|
||||
case 'activate':
|
||||
return { ...state, active: action.payload }
|
||||
case 'load':
|
||||
return { ...state, emojis: action.payload }
|
||||
case 'shortcode':
|
||||
return { ...state, shortcode: action.payload }
|
||||
}
|
||||
}
|
||||
import EmojisContext, { emojisReducer } from './Emojis/helpers/EmojisContext'
|
||||
|
||||
const prefetchEmojis = (
|
||||
sortedEmojis: { title: string; data: Mastodon.Emoji[][] }[],
|
||||
|
|
|
@ -27,4 +27,15 @@ type ContextType = {
|
|||
}
|
||||
const EmojisContext = createContext<ContextType>({} as ContextType)
|
||||
|
||||
export const emojisReducer = (state: EmojisState, action: EmojisAction) => {
|
||||
switch (action.type) {
|
||||
case 'activate':
|
||||
return { ...state, active: action.payload }
|
||||
case 'load':
|
||||
return { ...state, emojis: action.payload }
|
||||
case 'shortcode':
|
||||
return { ...state, shortcode: action.payload }
|
||||
}
|
||||
}
|
||||
|
||||
export default EmojisContext
|
||||
|
|
|
@ -3,7 +3,7 @@ import { useEmojisQuery } from '@utils/queryHooks/emojis'
|
|||
import { useSearchQuery } from '@utils/queryHooks/search'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import { forEach, groupBy, sortBy } from 'lodash'
|
||||
import { chunk, forEach, groupBy, sortBy } from 'lodash'
|
||||
import React, {
|
||||
useCallback,
|
||||
useContext,
|
||||
|
@ -28,23 +28,26 @@ import ComposeContext from './utils/createContext'
|
|||
import ComposeDrafts from './Root/Drafts'
|
||||
import FastImage from 'react-native-fast-image'
|
||||
import { useAccessibility } from '@utils/accessibility/AccessibilityManager'
|
||||
import { ComposeState } from './utils/types'
|
||||
|
||||
const prefetchEmojis = (
|
||||
sortedEmojis: { title: string; data: Mastodon.Emoji[] }[],
|
||||
sortedEmojis: NonNullable<ComposeState['emoji']['emojis']>,
|
||||
reduceMotionEnabled: boolean
|
||||
) => {
|
||||
const prefetches: { uri: string }[] = []
|
||||
let requestedIndex = 0
|
||||
sortedEmojis.forEach(sorted => {
|
||||
sorted.data.forEach(emoji => {
|
||||
if (requestedIndex > 40) {
|
||||
return
|
||||
}
|
||||
prefetches.push({
|
||||
uri: reduceMotionEnabled ? emoji.static_url : emoji.url
|
||||
sorted.data.forEach(emojis =>
|
||||
emojis.forEach(emoji => {
|
||||
if (requestedIndex > 40) {
|
||||
return
|
||||
}
|
||||
prefetches.push({
|
||||
uri: reduceMotionEnabled ? emoji.static_url : emoji.url
|
||||
})
|
||||
requestedIndex++
|
||||
})
|
||||
requestedIndex++
|
||||
})
|
||||
)
|
||||
})
|
||||
try {
|
||||
FastImage.preload(prefetches)
|
||||
|
@ -90,10 +93,11 @@ const ComposeRoot = React.memo(
|
|||
const { data: emojisData } = useEmojisQuery({})
|
||||
useEffect(() => {
|
||||
if (emojisData && emojisData.length) {
|
||||
let sortedEmojis: { title: string; data: Mastodon.Emoji[] }[] = []
|
||||
let sortedEmojis: { title: string; data: Mastodon.Emoji[][] }[] = []
|
||||
forEach(
|
||||
groupBy(sortBy(emojisData, ['category', 'shortcode']), 'category'),
|
||||
(value, key) => sortedEmojis.push({ title: key, data: value })
|
||||
(value, key) =>
|
||||
sortedEmojis.push({ title: key, data: chunk(value, 5) })
|
||||
)
|
||||
composeDispatch({
|
||||
type: 'emoji',
|
||||
|
|
|
@ -1,15 +1,8 @@
|
|||
import analytics from '@components/analytics'
|
||||
import haptics from '@components/haptics'
|
||||
import { useAccessibility } from '@utils/accessibility/AccessibilityManager'
|
||||
import { StyleConstants } from '@utils/styles/constants'
|
||||
import { useTheme } from '@utils/styles/ThemeManager'
|
||||
import React, {
|
||||
RefObject,
|
||||
useCallback,
|
||||
useContext,
|
||||
useEffect,
|
||||
useMemo
|
||||
} from 'react'
|
||||
import React, { RefObject, useCallback, useContext, useEffect } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import {
|
||||
AccessibilityInfo,
|
||||
|
@ -25,52 +18,15 @@ import validUrl from 'valid-url'
|
|||
import updateText from '../../updateText'
|
||||
import ComposeContext from '../../utils/createContext'
|
||||
|
||||
const SingleEmoji = ({ emoji }: { emoji: Mastodon.Emoji }) => {
|
||||
const { t } = useTranslation()
|
||||
const { reduceMotionEnabled } = useAccessibility()
|
||||
|
||||
const { composeState, composeDispatch } = useContext(ComposeContext)
|
||||
const onPress = useCallback(() => {
|
||||
analytics('compose_emoji_add')
|
||||
updateText({
|
||||
composeState,
|
||||
composeDispatch,
|
||||
newText: `:${emoji.shortcode}:`,
|
||||
type: 'emoji'
|
||||
})
|
||||
haptics('Light')
|
||||
}, [composeState])
|
||||
const children = useMemo(() => {
|
||||
const uri = reduceMotionEnabled ? emoji.static_url : emoji.url
|
||||
if (validUrl.isHttpsUri(uri)) {
|
||||
return (
|
||||
<FastImage
|
||||
accessibilityLabel={t('common:customEmoji.accessibilityLabel', {
|
||||
emoji: emoji.shortcode
|
||||
})}
|
||||
accessibilityHint={t(
|
||||
'screenCompose:content.root.footer.emojis.accessibilityHint'
|
||||
)}
|
||||
source={{ uri: reduceMotionEnabled ? emoji.static_url : emoji.url }}
|
||||
style={styles.emoji}
|
||||
/>
|
||||
)
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
}, [])
|
||||
return (
|
||||
<Pressable key={emoji.shortcode} onPress={onPress} children={children} />
|
||||
)
|
||||
}
|
||||
|
||||
export interface Props {
|
||||
accessibleRefEmojis: RefObject<SectionList>
|
||||
}
|
||||
|
||||
const ComposeEmojis: React.FC<Props> = ({ accessibleRefEmojis }) => {
|
||||
const { composeState } = useContext(ComposeContext)
|
||||
const { composeState, composeDispatch } = useContext(ComposeContext)
|
||||
const { reduceMotionEnabled } = useAccessibility()
|
||||
const { theme } = useTheme()
|
||||
const { t } = useTranslation()
|
||||
|
||||
useEffect(() => {
|
||||
const tagEmojis = findNodeHandle(accessibleRefEmojis.current)
|
||||
|
@ -86,21 +42,49 @@ const ComposeEmojis: React.FC<Props> = ({ accessibleRefEmojis }) => {
|
|||
[]
|
||||
)
|
||||
|
||||
const emojiList = useCallback(
|
||||
section =>
|
||||
section.data.map((emoji: Mastodon.Emoji) => (
|
||||
<SingleEmoji key={emoji.shortcode} emoji={emoji} />
|
||||
)),
|
||||
[]
|
||||
)
|
||||
const listItem = useCallback(
|
||||
({ section, index }) =>
|
||||
index === 0 ? (
|
||||
<View key={section.title} style={styles.emojis}>
|
||||
{emojiList(section)}
|
||||
({ index, item }: { item: Mastodon.Emoji[]; index: number }) => {
|
||||
return (
|
||||
<View key={index} style={styles.emojis}>
|
||||
{item.map(emoji => {
|
||||
const uri = reduceMotionEnabled ? emoji.static_url : emoji.url
|
||||
if (validUrl.isHttpsUri(uri)) {
|
||||
return (
|
||||
<Pressable
|
||||
key={emoji.shortcode}
|
||||
onPress={() => {
|
||||
updateText({
|
||||
composeState,
|
||||
composeDispatch,
|
||||
newText: `:${emoji.shortcode}:`,
|
||||
type: 'emoji'
|
||||
})
|
||||
haptics('Light')
|
||||
}}
|
||||
>
|
||||
<FastImage
|
||||
accessibilityLabel={t(
|
||||
'common:customEmoji.accessibilityLabel',
|
||||
{
|
||||
emoji: emoji.shortcode
|
||||
}
|
||||
)}
|
||||
accessibilityHint={t(
|
||||
'screenCompose:content.root.footer.emojis.accessibilityHint'
|
||||
)}
|
||||
source={{ uri }}
|
||||
style={styles.emoji}
|
||||
/>
|
||||
</Pressable>
|
||||
)
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
})}
|
||||
</View>
|
||||
) : null,
|
||||
[]
|
||||
)
|
||||
},
|
||||
[composeState]
|
||||
)
|
||||
|
||||
return (
|
||||
|
@ -111,7 +95,7 @@ const ComposeEmojis: React.FC<Props> = ({ accessibleRefEmojis }) => {
|
|||
horizontal
|
||||
keyboardShouldPersistTaps='always'
|
||||
sections={composeState.emoji.emojis || []}
|
||||
keyExtractor={item => item.shortcode}
|
||||
keyExtractor={item => item[0].shortcode}
|
||||
renderSectionHeader={listHeader}
|
||||
renderItem={listItem}
|
||||
windowSize={2}
|
||||
|
|
|
@ -40,7 +40,7 @@ export type ComposeState = {
|
|||
}
|
||||
emoji: {
|
||||
active: boolean
|
||||
emojis: { title: string; data: Mastodon.Emoji[] }[] | undefined
|
||||
emojis: { title: string; data: Mastodon.Emoji[][] }[] | undefined
|
||||
}
|
||||
poll: {
|
||||
active: boolean
|
||||
|
|
Loading…
Reference in New Issue