mirror of
				https://github.com/tooot-app/app
				synced 2025-06-05 22:19:13 +02:00 
			
		
		
		
	Refine input
This commit is contained in:
		| @@ -9,7 +9,14 @@ import React, { | |||||||
|   useRef, |   useRef, | ||||||
|   useState |   useState | ||||||
| } from 'react' | } from 'react' | ||||||
| import { Platform, StyleSheet, Text, TextInput, View } from 'react-native' | import { | ||||||
|  |   Platform, | ||||||
|  |   StyleSheet, | ||||||
|  |   Text, | ||||||
|  |   TextInput, | ||||||
|  |   TextInputProps, | ||||||
|  |   View | ||||||
|  | } from 'react-native' | ||||||
| import Animated, { useAnimatedStyle, withTiming } from 'react-native-reanimated' | import Animated, { useAnimatedStyle, withTiming } from 'react-native-reanimated' | ||||||
| import { | import { | ||||||
|   ComponentEmojis, |   ComponentEmojis, | ||||||
| @@ -23,7 +30,6 @@ export interface Props { | |||||||
|  |  | ||||||
|   title?: string |   title?: string | ||||||
|  |  | ||||||
|   maxLength?: number |  | ||||||
|   multiline?: boolean |   multiline?: boolean | ||||||
|  |  | ||||||
|   emoji?: boolean |   emoji?: boolean | ||||||
| @@ -32,16 +38,28 @@ export interface Props { | |||||||
|   setValue: |   setValue: | ||||||
|     | Dispatch<SetStateAction<string | undefined>> |     | Dispatch<SetStateAction<string | undefined>> | ||||||
|     | Dispatch<SetStateAction<string>> |     | Dispatch<SetStateAction<string>> | ||||||
|  |  | ||||||
|  |   options?: Omit< | ||||||
|  |     TextInputProps, | ||||||
|  |     | 'autoFocus' | ||||||
|  |     | 'onFocus' | ||||||
|  |     | 'onBlur' | ||||||
|  |     | 'style' | ||||||
|  |     | 'onChangeText' | ||||||
|  |     | 'onSelectionChange' | ||||||
|  |     | 'keyboardAppearance' | ||||||
|  |     | 'textAlignVertical' | ||||||
|  |   > | ||||||
| } | } | ||||||
|  |  | ||||||
| const Input: React.FC<Props> = ({ | const Input: React.FC<Props> = ({ | ||||||
|   autoFocus = true, |   autoFocus = true, | ||||||
|   title, |   title, | ||||||
|   maxLength, |  | ||||||
|   multiline = false, |   multiline = false, | ||||||
|   emoji = false, |   emoji = false, | ||||||
|   value, |   value, | ||||||
|   setValue |   setValue, | ||||||
|  |   options | ||||||
| }) => { | }) => { | ||||||
|   const { mode, theme } = useTheme() |   const { mode, theme } = useTheme() | ||||||
|  |  | ||||||
| @@ -90,7 +108,15 @@ const Input: React.FC<Props> = ({ | |||||||
|       setValue={setValue} |       setValue={setValue} | ||||||
|       selectionRange={selectionRange} |       selectionRange={selectionRange} | ||||||
|     > |     > | ||||||
|       <View style={[styles.base, { borderColor: theme.border }]}> |       <View | ||||||
|  |         style={[ | ||||||
|  |           styles.base, | ||||||
|  |           { | ||||||
|  |             borderColor: theme.border, | ||||||
|  |             flexDirection: multiline ? 'column' : 'row' | ||||||
|  |           } | ||||||
|  |         ]} | ||||||
|  |       > | ||||||
|         <EmojisContext.Consumer> |         <EmojisContext.Consumer> | ||||||
|           {({ emojisDispatch }) => ( |           {({ emojisDispatch }) => ( | ||||||
|             <TextInput |             <TextInput | ||||||
| @@ -113,11 +139,13 @@ const Input: React.FC<Props> = ({ | |||||||
|               onChangeText={setValue} |               onChangeText={setValue} | ||||||
|               onSelectionChange={onSelectionChange} |               onSelectionChange={onSelectionChange} | ||||||
|               value={value} |               value={value} | ||||||
|               maxLength={maxLength} |  | ||||||
|               {...(multiline && { |               {...(multiline && { | ||||||
|                 multiline, |                 multiline, | ||||||
|                 numberOfLines: Platform.OS === 'android' ? 5 : undefined |                 numberOfLines: Platform.OS === 'android' ? 5 : undefined | ||||||
|               })} |               })} | ||||||
|  |               keyboardAppearance={mode} | ||||||
|  |               textAlignVertical='top' | ||||||
|  |               {...options} | ||||||
|             /> |             /> | ||||||
|           )} |           )} | ||||||
|         </EmojisContext.Consumer> |         </EmojisContext.Consumer> | ||||||
| @@ -128,12 +156,14 @@ const Input: React.FC<Props> = ({ | |||||||
|             {title} |             {title} | ||||||
|           </Animated.Text> |           </Animated.Text> | ||||||
|         ) : null} |         ) : null} | ||||||
|         {maxLength && value?.length ? ( |         <View style={{ flexDirection: 'row' }}> | ||||||
|           <Text style={[styles.maxLength, { color: theme.secondary }]}> |           {options?.maxLength && value?.length ? ( | ||||||
|             {value?.length} / {maxLength} |             <Text style={[styles.maxLength, { color: theme.secondary }]}> | ||||||
|           </Text> |               {value?.length} / {options.maxLength} | ||||||
|         ) : null} |             </Text> | ||||||
|         {inputFocused ? <EmojisButton /> : null} |           ) : null} | ||||||
|  |           {inputFocused ? <EmojisButton /> : null} | ||||||
|  |         </View> | ||||||
|       </View> |       </View> | ||||||
|       <EmojisList /> |       <EmojisList /> | ||||||
|     </ComponentEmojis> |     </ComponentEmojis> | ||||||
| @@ -142,7 +172,6 @@ const Input: React.FC<Props> = ({ | |||||||
|  |  | ||||||
| const styles = StyleSheet.create({ | const styles = StyleSheet.create({ | ||||||
|   base: { |   base: { | ||||||
|     flexDirection: 'row', |  | ||||||
|     alignItems: 'flex-end', |     alignItems: 'flex-end', | ||||||
|     borderWidth: 1, |     borderWidth: 1, | ||||||
|     marginVertical: StyleConstants.Spacing.S, |     marginVertical: StyleConstants.Spacing.S, | ||||||
| @@ -156,7 +185,8 @@ const styles = StyleSheet.create({ | |||||||
|     fontSize: StyleConstants.Font.Size.M |     fontSize: StyleConstants.Font.Size.M | ||||||
|   }, |   }, | ||||||
|   maxLength: { |   maxLength: { | ||||||
|     ...StyleConstants.FontStyle.S |     ...StyleConstants.FontStyle.S, | ||||||
|  |     paddingLeft: StyleConstants.Spacing.XS | ||||||
|   } |   } | ||||||
| }) | }) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -26,10 +26,7 @@ const TabMeProfile: React.FC<StackScreenProps< | |||||||
|       behavior={Platform.OS === 'ios' ? 'padding' : 'height'} |       behavior={Platform.OS === 'ios' ? 'padding' : 'height'} | ||||||
|     > |     > | ||||||
|       <Stack.Navigator |       <Stack.Navigator | ||||||
|         screenOptions={{ |         screenOptions={{ headerHideShadow: true, headerTopInsetEnabled: false }} | ||||||
|           headerHideShadow: true, |  | ||||||
|           headerTopInsetEnabled: false |  | ||||||
|         }} |  | ||||||
|       > |       > | ||||||
|         <Stack.Screen |         <Stack.Screen | ||||||
|           name='Tab-Me-Profile-Root' |           name='Tab-Me-Profile-Root' | ||||||
|   | |||||||
| @@ -113,48 +113,51 @@ const ScreenMeProfileFields: React.FC<StackScreenProps< | |||||||
|  |  | ||||||
|   return ( |   return ( | ||||||
|     <ScrollView style={styles.base} keyboardShouldPersistTaps='handled'> |     <ScrollView style={styles.base} keyboardShouldPersistTaps='handled'> | ||||||
|       {Array.from(Array(4).keys()).map(index => ( |       <View style={{ marginBottom: StyleConstants.Spacing.L * 2 }}> | ||||||
|         <View key={index} style={styles.group}> |         {Array.from(Array(4).keys()).map(index => ( | ||||||
|           <Text style={[styles.headline, { color: theme.primaryDefault }]}> |           <View key={index} style={styles.group}> | ||||||
|             {t('me.profile.fields.group', { index: index + 1 })} |             <Text style={[styles.headline, { color: theme.primaryDefault }]}> | ||||||
|           </Text> |               {t('me.profile.fields.group', { index: index + 1 })} | ||||||
|           <Input |             </Text> | ||||||
|             title={t('me.profile.fields.label')} |             <Input | ||||||
|             autoFocus={false} |               title={t('me.profile.fields.label')} | ||||||
|             maxLength={255} |               autoFocus={false} | ||||||
|             value={newFields[index].name} |               options={{ maxLength: 255 }} | ||||||
|             setValue={(v: any) => |               value={newFields[index].name} | ||||||
|               setNewFields( |               setValue={(v: any) => | ||||||
|                 newFields.map((field, i) => |                 setNewFields( | ||||||
|                   i === index ? { ...field, name: v } : field |                   newFields.map((field, i) => | ||||||
|  |                     i === index ? { ...field, name: v } : field | ||||||
|  |                   ) | ||||||
|                 ) |                 ) | ||||||
|               ) |               } | ||||||
|             } |               emoji | ||||||
|             emoji |             /> | ||||||
|           /> |             <Input | ||||||
|           <Input |               title={t('me.profile.fields.content')} | ||||||
|             title={t('me.profile.fields.content')} |               autoFocus={false} | ||||||
|             autoFocus={false} |               options={{ maxLength: 255 }} | ||||||
|             maxLength={255} |               value={newFields[index].value} | ||||||
|             value={newFields[index].value} |               setValue={(v: any) => | ||||||
|             setValue={(v: any) => |                 setNewFields( | ||||||
|               setNewFields( |                   newFields.map((field, i) => | ||||||
|                 newFields.map((field, i) => |                     i === index ? { ...field, value: v } : field | ||||||
|                   i === index ? { ...field, value: v } : field |                   ) | ||||||
|                 ) |                 ) | ||||||
|               ) |               } | ||||||
|             } |               emoji | ||||||
|             emoji |             /> | ||||||
|           /> |           </View> | ||||||
|         </View> |         ))} | ||||||
|       ))} |       </View> | ||||||
|     </ScrollView> |     </ScrollView> | ||||||
|   ) |   ) | ||||||
| } | } | ||||||
|  |  | ||||||
| const styles = StyleSheet.create({ | const styles = StyleSheet.create({ | ||||||
|   base: { |   base: { | ||||||
|     padding: StyleConstants.Spacing.Global.PagePadding |     paddingHorizontal: StyleConstants.Spacing.Global.PagePadding, | ||||||
|  |     marginBottom: StyleConstants.Spacing.L | ||||||
|   }, |   }, | ||||||
|   group: { |   group: { | ||||||
|     marginBottom: StyleConstants.Spacing.M |     marginBottom: StyleConstants.Spacing.M | ||||||
|   | |||||||
| @@ -95,14 +95,24 @@ const ScreenMeProfileName: React.FC<StackScreenProps< | |||||||
|  |  | ||||||
|   return ( |   return ( | ||||||
|     <ScrollView style={styles.base} keyboardShouldPersistTaps='handled'> |     <ScrollView style={styles.base} keyboardShouldPersistTaps='handled'> | ||||||
|       <Input value={displayName} setValue={setDisplayName} emoji /> |       <Input | ||||||
|  |         value={displayName} | ||||||
|  |         setValue={setDisplayName} | ||||||
|  |         emoji | ||||||
|  |         options={{ | ||||||
|  |           maxLength: 30, | ||||||
|  |           autoCapitalize: 'none', | ||||||
|  |           autoCompleteType: 'username', | ||||||
|  |           autoCorrect: false | ||||||
|  |         }} | ||||||
|  |       /> | ||||||
|     </ScrollView> |     </ScrollView> | ||||||
|   ) |   ) | ||||||
| } | } | ||||||
|  |  | ||||||
| const styles = StyleSheet.create({ | const styles = StyleSheet.create({ | ||||||
|   base: { |   base: { | ||||||
|     padding: StyleConstants.Spacing.Global.PagePadding |     paddingHorizontal: StyleConstants.Spacing.Global.PagePadding | ||||||
|   } |   } | ||||||
| }) | }) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -7,7 +7,7 @@ import { StyleConstants } from '@utils/styles/constants' | |||||||
| import { useTheme } from '@utils/styles/ThemeManager' | import { useTheme } from '@utils/styles/ThemeManager' | ||||||
| import React, { RefObject, useEffect, useState } from 'react' | import React, { RefObject, useEffect, useState } from 'react' | ||||||
| import { useTranslation } from 'react-i18next' | import { useTranslation } from 'react-i18next' | ||||||
| import { Alert, StyleSheet } from 'react-native' | import { Alert, StyleSheet, View } from 'react-native' | ||||||
| import FlashMessage from 'react-native-flash-message' | import FlashMessage from 'react-native-flash-message' | ||||||
| import { ScrollView } from 'react-native-gesture-handler' | import { ScrollView } from 'react-native-gesture-handler' | ||||||
|  |  | ||||||
| @@ -95,14 +95,22 @@ const ScreenMeProfileNote: React.FC<StackScreenProps< | |||||||
|  |  | ||||||
|   return ( |   return ( | ||||||
|     <ScrollView style={styles.base} keyboardShouldPersistTaps='handled'> |     <ScrollView style={styles.base} keyboardShouldPersistTaps='handled'> | ||||||
|       <Input value={newNote} setValue={setNewNote} multiline emoji /> |       <View style={{ marginBottom: StyleConstants.Spacing.XL * 2 }}> | ||||||
|  |         <Input | ||||||
|  |           value={newNote} | ||||||
|  |           setValue={setNewNote} | ||||||
|  |           multiline | ||||||
|  |           emoji | ||||||
|  |           options={{ maxLength: 500 }} | ||||||
|  |         /> | ||||||
|  |       </View> | ||||||
|     </ScrollView> |     </ScrollView> | ||||||
|   ) |   ) | ||||||
| } | } | ||||||
|  |  | ||||||
| const styles = StyleSheet.create({ | const styles = StyleSheet.create({ | ||||||
|   base: { |   base: { | ||||||
|     padding: StyleConstants.Spacing.Global.PagePadding |     paddingHorizontal: StyleConstants.Spacing.Global.PagePadding | ||||||
|   } |   } | ||||||
| }) | }) | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user