Last active
January 14, 2024 08:09
-
-
Save Karthik-B-06/512831203198bf5116c9395b4928e501 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { useCallback } from "react"; | |
import { | |
NativeSyntheticEvent, | |
Platform, | |
Pressable, | |
TextInputContentSizeChangeEventData, | |
TextInputProps, | |
} from "react-native"; | |
import Animated, { | |
Layout, | |
useAnimatedProps, | |
useAnimatedStyle, | |
useSharedValue, | |
} from "react-native-reanimated"; | |
import Svg, { Path, Rect } from "react-native-svg"; | |
import { BottomSheetTextInput } from "@gorhom/bottom-sheet"; | |
import { TEXT_INPUT_CONTAINER_HEIGHT } from "../../../constants"; | |
import { useChatWindowContext } from "../../../context"; | |
import { useSendMessage } from "../../../store"; | |
import { tailwind } from "../../../theme"; | |
import { Icon } from "../../common"; | |
const AnimatedTextInput = | |
Animated.createAnimatedComponent(BottomSheetTextInput); | |
const INIT_TEXTINPUT_HEIGHT = 36; | |
// Based on Line height of text | |
const MIN_TEXTINPUT_HEIGHT = 20; | |
// Value based on initial height + 3 new line texts | |
const MAX_TEXTINPUT_HEIGHT = 76; | |
type MessageTextInputProps = {}; | |
export const MessageTextInput = ({}: MessageTextInputProps) => { | |
const textInputHeight = useSharedValue(INIT_TEXTINPUT_HEIGHT); | |
const messageText = useSharedValue(""); | |
const { textInputRef, setIsTextInputFocused } = useChatWindowContext(); | |
const setMessageText = useSendMessage(state => state.setMessageText); | |
const onContentSizeChange = ( | |
event: NativeSyntheticEvent<TextInputContentSizeChangeEventData>, | |
) => { | |
"worklet"; | |
const contentHeight = event.nativeEvent.contentSize.height; | |
if (Platform.OS === "ios") { | |
const multiplier = contentHeight / MIN_TEXTINPUT_HEIGHT - 1; | |
textInputHeight.value = Math.min( | |
MIN_TEXTINPUT_HEIGHT * multiplier + INIT_TEXTINPUT_HEIGHT, | |
MAX_TEXTINPUT_HEIGHT, | |
); | |
} | |
if (Platform.OS === "android") { | |
const multiplier = contentHeight / TEXT_INPUT_CONTAINER_HEIGHT - 1; | |
textInputHeight.value = Math.min( | |
MIN_TEXTINPUT_HEIGHT * multiplier + INIT_TEXTINPUT_HEIGHT, | |
MAX_TEXTINPUT_HEIGHT, | |
); | |
} | |
}; | |
const animatedProps = useAnimatedProps(() => { | |
return { | |
text: messageText.value, | |
} as unknown as TextInputProps; | |
}); | |
const onChangeText = (text: string) => { | |
messageText.value = text.trimEnd(); | |
setMessageText(text); | |
if (text.length === 0) { | |
textInputHeight.value = INIT_TEXTINPUT_HEIGHT; | |
} | |
}; | |
const handleFocus = useCallback(() => { | |
setIsTextInputFocused(true); | |
// eslint-disable-next-line react-hooks/exhaustive-deps | |
}, []); | |
const handleBlur = useCallback(() => { | |
setIsTextInputFocused(false); | |
// eslint-disable-next-line react-hooks/exhaustive-deps | |
}, []); | |
const animatedTextInputHeight = useAnimatedStyle(() => { | |
return { | |
height: textInputHeight.value, | |
}; | |
}, []); | |
return ( | |
<AnimatedTextInput | |
// @ts-ignore | |
ref={textInputRef} | |
layout={Layout.springify().damping(20).stiffness(180)} | |
onChangeText={onChangeText} | |
numberOfLines={3} | |
multiline | |
enablesReturnKeyAutomatically | |
style={[ | |
tailwind.style( | |
"flex-1 text-base font-inter-normal-24 tracking-[0.24px] min-h-9 leading-[20px] py-2 pl-3 pr-[36px] rounded-2xl text-gray-950", | |
isPrivateMessage ? "bg-amber-100" : "bg-blackA-A4", | |
), | |
]} | |
placeholderTextColor={tailwind.color("bg-gray-800")} | |
placeholder="Message..." | |
onContentSizeChange={onContentSizeChange} | |
onSubmitEditing={() => (messageText.value = "")} | |
returnKeyType={"default"} | |
textAlignVertical="top" | |
underlineColorAndroid="transparent" | |
onFocus={handleFocus} | |
onBlur={handleBlur} | |
animatedProps={animatedProps} | |
/> | |
); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment