diff --git a/src/screens/Search/index.tsx b/src/screens/Search/index.tsx index f4e1ad2..f2adfe4 100644 --- a/src/screens/Search/index.tsx +++ b/src/screens/Search/index.tsx @@ -1,6 +1,6 @@ import React, { useState, useEffect, useRef, useCallback } from 'react'; import Input from 'components/Input'; -import { ActivityIndicator, SafeAreaView, View } from 'react-native'; +import { ActivityIndicator, Animated, SafeAreaView, View } from 'react-native'; import styled from 'styled-components/native'; import { useTypedSelector } from 'store'; import Fuse from 'fuse.js'; @@ -21,6 +21,7 @@ import DownloadIcon from 'components/DownloadIcon'; import ChevronRight from 'assets/icons/chevron-right.svg'; import SearchIcon from 'assets/icons/magnifying-glass.svg'; import { ShadowWrapper } from 'components/Shadow'; +import { useKeyboardHeight } from 'utility/useKeyboardHeight'; // import MicrophoneIcon from 'assets/icons/microphone.svg'; // import AlbumIcon from 'assets/icons/collection.svg'; // import TrackIcon from 'assets/icons/note.svg'; @@ -29,11 +30,11 @@ import { ShadowWrapper } from 'components/Shadow'; // import LocalIcon from 'assets/icons/internal-drive.svg'; // import SelectableFilter from './components/SelectableFilter'; -const Container = styled.View` +const Container = styled(Animated.View)` padding: 4px 32px 0 32px; margin-bottom: 0px; padding-bottom: 0px; - border-top-width: 1px; + border-top-width: 0.5px; `; const FullSizeContainer = styled.View` @@ -114,6 +115,7 @@ export default function Search() { // Prepare helpers const navigation = useNavigation(); + const keyboardHeight = useKeyboardHeight(); const getImage = useGetImage(); const dispatch = useDispatch(); @@ -218,13 +220,18 @@ export default function Search() { const HeaderComponent = React.useMemo(() => ( - + {isLoading && } diff --git a/src/utility/useKeyboardHeight.ts b/src/utility/useKeyboardHeight.ts new file mode 100644 index 0000000..0a70ab3 --- /dev/null +++ b/src/utility/useKeyboardHeight.ts @@ -0,0 +1,48 @@ +import { useBottomTabBarHeight } from '@react-navigation/bottom-tabs'; +import { useRef, useEffect } from 'react'; +import { Animated, Keyboard, KeyboardEvent } from 'react-native'; + +/** + * This returns an animated height that the keyboard is poking up from the + * bottom of the screen. This can be used to position elements to "hug" the + * keyboard. + * Adapted from https://stackoverflow.com/a/65267045/3586761 + */ +export const useKeyboardHeight = () => { + const keyboardHeight = useRef(new Animated.Value(0)).current; + const tabBarHeight = useBottomTabBarHeight(); + + useEffect(() => { + const keyboardWillShow = (e: KeyboardEvent) => { + Animated.timing(keyboardHeight, { + duration: e.duration, + toValue: tabBarHeight - e.endCoordinates.height, + useNativeDriver: true, + }).start(); + }; + + const keyboardWillHide = (e: KeyboardEvent) => { + Animated.timing(keyboardHeight, { + duration: e.duration, + toValue: 0, + useNativeDriver: true, + }).start(); + }; + + const keyboardWillShowSub = Keyboard.addListener( + 'keyboardWillShow', + keyboardWillShow + ); + const keyboardWillHideSub = Keyboard.addListener( + 'keyboardWillHide', + keyboardWillHide + ); + + return () => { + keyboardWillHideSub.remove(); + keyboardWillShowSub.remove(); + }; + }, [keyboardHeight, tabBarHeight]); + + return keyboardHeight; +}; \ No newline at end of file