mirror of
				https://github.com/tooot-app/app
				synced 2025-06-05 22:19:13 +02:00 
			
		
		
		
	Emoji working for compose
This commit is contained in:
		| @@ -7,7 +7,7 @@ import { getInstanceFrequentEmojis } from '@utils/slices/instancesSlice' | ||||
| import { chunk, forEach, groupBy, sortBy } from 'lodash' | ||||
| import React, { PropsWithChildren, RefObject, useEffect, useReducer, useState } from 'react' | ||||
| import { useTranslation } from 'react-i18next' | ||||
| import { Keyboard, KeyboardAvoidingView, Platform, TextInput, View } from 'react-native' | ||||
| import { Keyboard, KeyboardAvoidingView, TextInput, View } from 'react-native' | ||||
| import FastImage from 'react-native-fast-image' | ||||
| import { Edge, SafeAreaView, useSafeAreaInsets } from 'react-native-safe-area-context' | ||||
| import { useSelector } from 'react-redux' | ||||
| @@ -74,14 +74,14 @@ const ComponentEmojis: React.FC<Props & PropsWithChildren> = ({ | ||||
|     if (data && data.length) { | ||||
|       let sortedEmojis: EmojisState['emojis'] = [] | ||||
|       forEach(groupBy(sortBy(data, ['category', 'shortcode']), 'category'), (value, key) => | ||||
|         sortedEmojis.push({ title: key, data: chunk(value, 5) }) | ||||
|         sortedEmojis.push({ title: key, data: chunk(value, 4) }) | ||||
|       ) | ||||
|       if (frequentEmojis.length) { | ||||
|         sortedEmojis.unshift({ | ||||
|           title: t('componentEmojis:frequentUsed'), | ||||
|           data: chunk( | ||||
|             frequentEmojis.map(e => e.emoji), | ||||
|             5 | ||||
|             4 | ||||
|           ), | ||||
|           type: 'frequent' | ||||
|         }) | ||||
| @@ -125,7 +125,9 @@ const ComponentEmojis: React.FC<Props & PropsWithChildren> = ({ | ||||
|             <View | ||||
|               style={[ | ||||
|                 keyboardShown ? { position: 'absolute', bottom: 0, width: '100%' } : null, | ||||
|                 { marginBottom: keyboardShown ? insets.bottom : 0 } | ||||
|                 { | ||||
|                   marginBottom: keyboardShown && emojisState.targetIndex === -1 ? insets.bottom : 0 | ||||
|                 } | ||||
|               ]} | ||||
|               children={ | ||||
|                 emojisState.targetIndex !== -1 ? ( | ||||
|   | ||||
| @@ -42,7 +42,7 @@ const EmojisList = () => { | ||||
|     } = emojisState.inputProps[emojisState.targetIndex] | ||||
|  | ||||
|     const contentFront = value.slice(0, selection.start) | ||||
|     const contentRear = value.slice(selection.end) | ||||
|     const contentRear = value.slice(selection.end || selection.start) | ||||
|  | ||||
|     const spaceFront = value.length === 0 || /\s/g.test(contentFront.slice(-1)) ? '' : ' ' | ||||
|     const spaceRear = /\s/g.test(contentRear[0]) ? '' : ' ' | ||||
|   | ||||
| @@ -157,32 +157,19 @@ const ComposeActions: React.FC = () => { | ||||
|       return colors.secondary | ||||
|     } | ||||
|   }, [emojisState.emojis.length, emojisState.targetIndex]) | ||||
|   // useEffect(() => { | ||||
|   //   const showSubscription = Keyboard.addListener('keyboardWillShow', () => { | ||||
|   //     composeDispatch({ type: 'emoji/shown', payload: false }) | ||||
|   //   }) | ||||
|  | ||||
|   //   return () => { | ||||
|   //     showSubscription.remove() | ||||
|   //   } | ||||
|   // }, []) | ||||
|   const emojiOnPress = () => { | ||||
|     analytics('compose_actions_emojis_press', { | ||||
|       current: emojisState.targetIndex !== -1 | ||||
|     }) | ||||
|     if (emojisState.targetIndex === -1) { | ||||
|       Keyboard.dismiss() | ||||
|       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 | ||||
|     } | ||||
|     const focusedPropsIndex = emojisState.inputProps?.findIndex(props => props.isFocused.current) | ||||
|     if (focusedPropsIndex === -1) return | ||||
|     emojisDispatch({ type: 'target', payload: focusedPropsIndex }) | ||||
|     // Keyboard.dismiss() | ||||
|     // analytics('compose_actions_emojis_press', { | ||||
|     //   current: composeState.emoji.active | ||||
|     // }) | ||||
|     // if (composeState.emoji.emojis) { | ||||
|     //   composeDispatch({ | ||||
|     //     type: 'emoji', | ||||
|     //     payload: { ...composeState.emoji, active: !composeState.emoji.active } | ||||
|     //   }) | ||||
|     // } | ||||
|   } | ||||
|  | ||||
|   return ( | ||||
|   | ||||
| @@ -1,161 +0,0 @@ | ||||
| import haptics from '@components/haptics' | ||||
| import CustomText from '@components/Text' | ||||
| import { useAppDispatch } from '@root/store' | ||||
| import { useAccessibility } from '@utils/accessibility/AccessibilityManager' | ||||
| import { countInstanceEmoji } from '@utils/slices/instancesSlice' | ||||
| import { getSettingsStaticEmoji } from '@utils/slices/settingsSlice' | ||||
| import { StyleConstants } from '@utils/styles/constants' | ||||
| import { useTheme } from '@utils/styles/ThemeManager' | ||||
| import React, { RefObject, useCallback, useContext, useEffect } from 'react' | ||||
| import { useTranslation } from 'react-i18next' | ||||
| import { | ||||
|   AccessibilityInfo, | ||||
|   findNodeHandle, | ||||
|   Image, | ||||
|   Pressable, | ||||
|   SectionList, | ||||
|   View | ||||
| } from 'react-native' | ||||
| import FastImage from 'react-native-fast-image' | ||||
| import { useSelector } from 'react-redux' | ||||
| import validUrl from 'valid-url' | ||||
| import updateText from '../../updateText' | ||||
| import ComposeContext from '../../utils/createContext' | ||||
|  | ||||
| export interface Props { | ||||
|   accessibleRefEmojis: RefObject<SectionList> | ||||
| } | ||||
|  | ||||
| const ComposeEmojis: React.FC<Props> = ({ accessibleRefEmojis }) => { | ||||
|   const { composeState, composeDispatch } = useContext(ComposeContext) | ||||
|   const { reduceMotionEnabled } = useAccessibility() | ||||
|   const { colors } = useTheme() | ||||
|   const { t } = useTranslation() | ||||
|   const dispatch = useAppDispatch() | ||||
|  | ||||
|   const staticEmoji = useSelector(getSettingsStaticEmoji) | ||||
|  | ||||
|   useEffect(() => { | ||||
|     const tagEmojis = findNodeHandle(accessibleRefEmojis.current) | ||||
|     if (composeState.emoji.active) { | ||||
|       tagEmojis && AccessibilityInfo.setAccessibilityFocus(tagEmojis) | ||||
|     } | ||||
|   }, [composeState.emoji.active]) | ||||
|  | ||||
|   const listItem = useCallback( | ||||
|     ({ index, item }: { item: Mastodon.Emoji[]; index: number }) => { | ||||
|       return ( | ||||
|         <View | ||||
|           key={index} | ||||
|           style={{ | ||||
|             flex: 1, | ||||
|             flexWrap: 'wrap', | ||||
|             marginTop: StyleConstants.Spacing.M, | ||||
|             marginLeft: StyleConstants.Spacing.M | ||||
|           }} | ||||
|         > | ||||
|           {item.map(emoji => { | ||||
|             const uri = reduceMotionEnabled ? emoji.static_url : emoji.url | ||||
|             if (validUrl.isHttpsUri(uri)) { | ||||
|               return ( | ||||
|                 <Pressable | ||||
|                   key={emoji.shortcode} | ||||
|                   onPress={() => { | ||||
|                     haptics('Light') | ||||
|                     updateText({ | ||||
|                       composeState, | ||||
|                       composeDispatch, | ||||
|                       newText: `:${emoji.shortcode}:`, | ||||
|                       type: 'emoji' | ||||
|                     }) | ||||
|                     dispatch(countInstanceEmoji(emoji)) | ||||
|                   }} | ||||
|                 > | ||||
|                   {staticEmoji ? ( | ||||
|                     <Image | ||||
|                       accessibilityLabel={t( | ||||
|                         'common:customEmoji.accessibilityLabel', | ||||
|                         { | ||||
|                           emoji: emoji.shortcode | ||||
|                         } | ||||
|                       )} | ||||
|                       accessibilityHint={t( | ||||
|                         'screenCompose:content.root.footer.emojis.accessibilityHint' | ||||
|                       )} | ||||
|                       source={{ uri }} | ||||
|                       style={{ | ||||
|                         width: 36, | ||||
|                         height: 36, | ||||
|                         padding: StyleConstants.Spacing.S, | ||||
|                         margin: StyleConstants.Spacing.S | ||||
|                       }} | ||||
|                     /> | ||||
|                   ) : ( | ||||
|                     <FastImage | ||||
|                       accessibilityLabel={t( | ||||
|                         'common:customEmoji.accessibilityLabel', | ||||
|                         { | ||||
|                           emoji: emoji.shortcode | ||||
|                         } | ||||
|                       )} | ||||
|                       accessibilityHint={t( | ||||
|                         'screenCompose:content.root.footer.emojis.accessibilityHint' | ||||
|                       )} | ||||
|                       source={{ uri }} | ||||
|                       style={{ | ||||
|                         width: 36, | ||||
|                         height: 36, | ||||
|                         padding: StyleConstants.Spacing.S, | ||||
|                         margin: StyleConstants.Spacing.S | ||||
|                       }} | ||||
|                     /> | ||||
|                   )} | ||||
|                 </Pressable> | ||||
|               ) | ||||
|             } else { | ||||
|               return null | ||||
|             } | ||||
|           })} | ||||
|         </View> | ||||
|       ) | ||||
|     }, | ||||
|     [composeState] | ||||
|   ) | ||||
|  | ||||
|   return ( | ||||
|     <View | ||||
|       style={{ | ||||
|         flex: 1, | ||||
|         flexDirection: 'row', | ||||
|         flexWrap: 'wrap', | ||||
|         justifyContent: 'space-around', | ||||
|         height: 280 | ||||
|       }} | ||||
|     > | ||||
|       <SectionList | ||||
|         accessible | ||||
|         ref={accessibleRefEmojis} | ||||
|         horizontal | ||||
|         keyboardShouldPersistTaps='always' | ||||
|         sections={composeState.emoji.emojis || []} | ||||
|         keyExtractor={item => item[0].shortcode} | ||||
|         renderSectionHeader={({ section: { title } }) => ( | ||||
|           <CustomText | ||||
|             fontStyle='S' | ||||
|             style={{ | ||||
|               position: 'absolute', | ||||
|               left: StyleConstants.Spacing.L, | ||||
|               color: colors.secondary | ||||
|             }} | ||||
|           > | ||||
|             {title} | ||||
|           </CustomText> | ||||
|         )} | ||||
|         renderItem={listItem} | ||||
|         windowSize={2} | ||||
|       /> | ||||
|     </View> | ||||
|   ) | ||||
| } | ||||
|  | ||||
| export default React.memo(ComposeEmojis, () => true) | ||||
		Reference in New Issue
	
	Block a user