mirror of
https://github.com/tooot-app/app
synced 2025-03-03 02:58:05 +01:00
commit
7a3874787f
@ -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
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -149,14 +149,14 @@ const ComponentInstance: React.FC<Props> = ({
|
|||||||
style={[
|
style={[
|
||||||
styles.prefix,
|
styles.prefix,
|
||||||
{
|
{
|
||||||
|
color: theme.primaryDefault,
|
||||||
borderBottomColor: instanceQuery.isError
|
borderBottomColor: instanceQuery.isError
|
||||||
? theme.red
|
? theme.red
|
||||||
: theme.border
|
: theme.border
|
||||||
}
|
}
|
||||||
]}
|
]}
|
||||||
editable={false}
|
editable={false}
|
||||||
placeholder='https://'
|
defaultValue='https://'
|
||||||
placeholderTextColor={theme.primaryDefault}
|
|
||||||
/>
|
/>
|
||||||
<TextInput
|
<TextInput
|
||||||
style={[
|
style={[
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user