diff options
author | Paul Frazee <pfrazee@gmail.com> | 2023-03-20 16:10:29 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-03-20 16:10:29 -0500 |
commit | 8a3601c07c693fa85800644f072ab895f3be4242 (patch) | |
tree | e702865de80960190249076b263b11ce31cd29af /src | |
parent | df6a712834326d62fdac3fe459bcd1eb23bf5010 (diff) | |
download | voidsky-8a3601c07c693fa85800644f072ab895f3be4242.tar.zst |
* Improve layout in composer to ensure the mentions autocomplete is visible (closes #326) * Dont dismiss the keyboard in the composer
Diffstat (limited to 'src')
-rw-r--r-- | src/view/com/composer/Composer.tsx | 32 | ||||
-rw-r--r-- | src/view/com/composer/text-input/TextInput.tsx | 10 | ||||
-rw-r--r-- | src/view/com/composer/text-input/mobile/Autocomplete.tsx | 75 |
3 files changed, 67 insertions, 50 deletions
diff --git a/src/view/com/composer/Composer.tsx b/src/view/com/composer/Composer.tsx index db4a3233e..e10e801e4 100644 --- a/src/view/com/composer/Composer.tsx +++ b/src/view/com/composer/Composer.tsx @@ -32,6 +32,7 @@ import {SelectedPhotos} from './photos/SelectedPhotos' import {usePalette} from 'lib/hooks/usePalette' import QuoteEmbed from '../util/PostEmbeds/QuoteEmbed' import {useExternalLinkFetch} from './useExternalLinkFetch' +import {isDesktopWeb} from 'platform/detection' const MAX_TEXT_LENGTH = 256 @@ -188,10 +189,6 @@ export const ComposePost = observer(function ComposePost({ const canPost = text.length <= MAX_TEXT_LENGTH - const selectTextInputLayout = - selectedPhotos.length !== 0 - ? styles.textInputLayoutWithPhoto - : styles.textInputLayoutWithoutPhoto const selectTextInputPlaceholder = replyTo ? 'Write your reply' : selectedPhotos.length !== 0 @@ -253,7 +250,9 @@ export const ComposePost = observer(function ComposePost({ <Text style={[s.red4, s.flex1]}>{error}</Text> </View> )} - <ScrollView style={s.flex1}> + <ScrollView + style={styles.scrollView} + keyboardShouldPersistTaps="always"> {replyTo ? ( <View style={[pal.border, styles.replyToLayout]}> <UserAvatar avatar={replyTo.author.avatar} size={50} /> @@ -268,12 +267,7 @@ export const ComposePost = observer(function ComposePost({ </View> ) : undefined} - <View - style={[ - pal.border, - styles.textInputLayout, - selectTextInputLayout, - ]}> + <View style={[pal.border, styles.textInputLayout]}> <UserAvatar avatar={store.me.avatar} size={50} /> <TextInput ref={textInput} @@ -346,14 +340,14 @@ const styles = StyleSheet.create({ outer: { flexDirection: 'column', flex: 1, - padding: 15, height: '100%', }, topbar: { flexDirection: 'row', alignItems: 'center', + paddingTop: isDesktopWeb ? 10 : undefined, paddingBottom: 10, - paddingHorizontal: 5, + paddingHorizontal: 20, height: 55, }, postBtn: { @@ -365,12 +359,14 @@ const styles = StyleSheet.create({ borderRadius: 6, paddingHorizontal: 8, paddingVertical: 6, + marginHorizontal: 15, marginBottom: 6, }, errorLine: { flexDirection: 'row', backgroundColor: colors.red1, borderRadius: 6, + marginHorizontal: 15, paddingHorizontal: 8, paddingVertical: 6, marginVertical: 6, @@ -386,13 +382,12 @@ const styles = StyleSheet.create({ justifyContent: 'center', marginRight: 5, }, - textInputLayoutWithPhoto: { - flexWrap: 'wrap', - }, - textInputLayoutWithoutPhoto: { + scrollView: { flex: 1, + paddingHorizontal: 15, }, textInputLayout: { + flex: isDesktopWeb ? undefined : 1, flexDirection: 'row', borderTopWidth: 1, paddingTop: 16, @@ -418,7 +413,8 @@ const styles = StyleSheet.create({ bottomBar: { flexDirection: 'row', paddingVertical: 10, - paddingRight: 5, + paddingLeft: 15, + paddingRight: 20, alignItems: 'center', borderTopWidth: 1, }, diff --git a/src/view/com/composer/text-input/TextInput.tsx b/src/view/com/composer/text-input/TextInput.tsx index 668b148a4..877945b96 100644 --- a/src/view/com/composer/text-input/TextInput.tsx +++ b/src/view/com/composer/text-input/TextInput.tsx @@ -3,6 +3,7 @@ import { NativeSyntheticEvent, StyleSheet, TextInputSelectionChangeEventData, + View, } from 'react-native' import PasteInput, { PastedFile, @@ -185,7 +186,7 @@ export const TextInput = React.forwardRef( }, [text, pal.link, pal.text]) return ( - <> + <View style={styles.container}> <PasteInput testID="composerTextInput" ref={textInput} @@ -202,15 +203,20 @@ export const TextInput = React.forwardRef( view={autocompleteView} onSelect={onSelectAutocompleteItem} /> - </> + </View> ) }, ) const styles = StyleSheet.create({ + container: { + width: '100%', + }, textInput: { flex: 1, + minHeight: 80, padding: 5, + paddingBottom: 20, marginLeft: 8, alignSelf: 'flex-start', }, diff --git a/src/view/com/composer/text-input/mobile/Autocomplete.tsx b/src/view/com/composer/text-input/mobile/Autocomplete.tsx index 424a8629f..293c89da5 100644 --- a/src/view/com/composer/text-input/mobile/Autocomplete.tsx +++ b/src/view/com/composer/text-input/mobile/Autocomplete.tsx @@ -1,10 +1,5 @@ import React, {useEffect} from 'react' -import { - Animated, - TouchableOpacity, - StyleSheet, - useWindowDimensions, -} from 'react-native' +import {Animated, TouchableOpacity, StyleSheet, View} from 'react-native' import {observer} from 'mobx-react-lite' import {UserAutocompleteViewModel} from 'state/models/user-autocomplete-view' import {useAnimatedValue} from 'lib/hooks/useAnimatedValue' @@ -20,52 +15,72 @@ export const Autocomplete = observer( onSelect: (item: string) => void }) => { const pal = usePalette('default') - const winDim = useWindowDimensions() const positionInterp = useAnimatedValue(0) useEffect(() => { Animated.timing(positionInterp, { toValue: view.isActive ? 1 : 0, duration: 200, - useNativeDriver: false, + useNativeDriver: true, }).start() }, [positionInterp, view.isActive]) const topAnimStyle = { - top: positionInterp.interpolate({ - inputRange: [0, 1], - outputRange: [winDim.height, winDim.height / 4], - }), + transform: [ + { + translateY: positionInterp.interpolate({ + inputRange: [0, 1], + outputRange: [200, 0], + }), + }, + ], } return ( - <Animated.View style={[styles.outer, pal.view, pal.border, topAnimStyle]}> - {view.suggestions.map(item => ( - <TouchableOpacity - testID="autocompleteButton" - key={item.handle} - style={[pal.border, styles.item]} - onPress={() => onSelect(item.handle)}> - <Text type="md-medium" style={pal.text}> - {item.displayName || item.handle} - <Text type="sm" style={pal.textLight}> - @{item.handle} + <View style={[styles.container, view.isActive && styles.visible]}> + <Animated.View + style={[ + styles.animatedContainer, + pal.view, + pal.border, + topAnimStyle, + view.isActive && styles.visible, + ]}> + {view.suggestions.slice(0, 5).map(item => ( + <TouchableOpacity + testID="autocompleteButton" + key={item.handle} + style={[pal.border, styles.item]} + onPress={() => onSelect(item.handle)}> + <Text type="md-medium" style={pal.text}> + {item.displayName || item.handle} + <Text type="sm" style={pal.textLight}> + @{item.handle} + </Text> </Text> - </Text> - </TouchableOpacity> - ))} - </Animated.View> + </TouchableOpacity> + ))} + </Animated.View> + </View> ) }, ) const styles = StyleSheet.create({ - outer: { + container: { + display: 'none', + height: 250, + }, + animatedContainer: { + display: 'none', position: 'absolute', - left: 0, + left: -64, right: 0, - bottom: 0, + top: 0, borderTopWidth: 1, }, + visible: { + display: 'flex', + }, item: { borderBottomWidth: 1, paddingVertical: 16, |