From 7601408d49ac7eb60f012e4656b139835240fc1c Mon Sep 17 00:00:00 2001 From: Lei Nelissen Date: Sat, 22 Apr 2023 21:58:27 +0200 Subject: [PATCH] feat: update tab bars with blurview --- src/components/Input.tsx | 35 ++++-- src/components/Typography.tsx | 3 +- .../Music/overlays/NowPlaying/index.tsx | 5 +- src/screens/Search/index.tsx | 117 +++++++++--------- src/screens/index.tsx | 7 ++ src/utility/useKeyboardHeight.ts | 5 +- 6 files changed, 101 insertions(+), 71 deletions(-) diff --git a/src/components/Input.tsx b/src/components/Input.tsx index dae4ee0..edb3aeb 100644 --- a/src/components/Input.tsx +++ b/src/components/Input.tsx @@ -2,23 +2,35 @@ import React, { useCallback, useRef } from 'react'; import { Platform, TextInput, TextInputProps } from 'react-native'; import styled, { css } from 'styled-components/native'; import useDefaultStyles from './Colors'; -import { Gap } from './Utility'; export interface InputProps extends TextInputProps { icon?: React.ReactNode; } -const Container = styled.Pressable` +const Container = styled.Pressable<{ hasIcon?: boolean }>` + position: relative; margin: 6px 0; - border-radius: 8px; + border-radius: 12px; display: flex; - flex-direction: row; - align-items: center; ${Platform.select({ ios: css`padding: 12px;`, android: css`padding: 4px 12px;`, })} + + ${({ hasIcon }) => hasIcon && css` + padding-left: 36px; + `} +`; + +const IconWrapper = styled.View` + position: absolute; + left: 0; + top: 0; + bottom: 0; + display: flex; + justify-content: center; + padding-left: 12px; `; function Input({ icon = null, style, testID, ...rest }: InputProps) { @@ -28,12 +40,17 @@ function Input({ icon = null, style, testID, ...rest }: InputProps) { const handlePress = useCallback(() => inputRef.current?.focus(), []); return ( - + {icon && ( - <> + {icon} - - + )} ) { export const Header = styled(Text)` margin: 0 0 6px 0; font-size: 28px; - font-weight: 400; + font-weight: 500; + letter-spacing: -0.3px; `; export const SubHeader = styled(Text)` diff --git a/src/screens/Music/overlays/NowPlaying/index.tsx b/src/screens/Music/overlays/NowPlaying/index.tsx index a8f97d5..9d2fe90 100644 --- a/src/screens/Music/overlays/NowPlaying/index.tsx +++ b/src/screens/Music/overlays/NowPlaying/index.tsx @@ -17,13 +17,13 @@ import { calculateProgressTranslation } from 'components/Progresstrack'; import { THEME_COLOR } from 'CONSTANTS'; import { MusicNavigationProp } from 'screens/Music/types'; import { ShadowWrapper } from 'components/Shadow'; +import { useBottomTabBarHeight } from '@react-navigation/bottom-tabs'; const NOW_PLAYING_POPOVER_MARGIN = 6; const NOW_PLAYING_POPOVER_WIDTH = Dimensions.get('screen').width - 2 * NOW_PLAYING_POPOVER_MARGIN; const PopoverPosition = css` position: absolute; - bottom: ${NOW_PLAYING_POPOVER_MARGIN}px; left: ${NOW_PLAYING_POPOVER_MARGIN}px; right: ${NOW_PLAYING_POPOVER_MARGIN}px; border-radius: 8px; @@ -111,6 +111,7 @@ function NowPlaying() { const { index, track } = useCurrentTrack(); const { buffered, position } = useProgress(); const defaultStyles = useDefaultStyles(); + const tabBarHeight = useBottomTabBarHeight(); const previousBuffered = usePrevious(buffered); const previousPosition = usePrevious(position); @@ -164,7 +165,7 @@ function NowPlaying() { } return ( - + {/** TODO: Fix shadow overflow on Android */} {Platform.OS === 'ios' ? ( diff --git a/src/screens/Search/index.tsx b/src/screens/Search/index.tsx index ddfa96d..8cf89b0 100644 --- a/src/screens/Search/index.tsx +++ b/src/screens/Search/index.tsx @@ -11,7 +11,7 @@ import { useNavigation } from '@react-navigation/native'; import { useGetImage } from 'utility/JellyfinApi'; import FastImage from 'react-native-fast-image'; import { t } from '@localisation'; -import useDefaultStyles from 'components/Colors'; +import useDefaultStyles, { ColoredBlurView } from 'components/Colors'; import { searchAndFetchAlbums } from 'store/music/actions'; import { debounce } from 'lodash'; import { Text } from 'components/Typography'; @@ -21,6 +21,7 @@ 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 { useBottomTabBarHeight } from '@react-navigation/bottom-tabs'; // import MicrophoneIcon from 'assets/icons/microphone.svg'; // import AlbumIcon from 'assets/icons/collection.svg'; // import TrackIcon from 'assets/icons/note.svg'; @@ -29,8 +30,8 @@ import { useKeyboardHeight } from 'utility/useKeyboardHeight'; // import LocalIcon from 'assets/icons/internal-drive.svg'; // import SelectableFilter from './components/SelectableFilter'; -const Container = styled(Animated.View)` - padding: 4px 32px 0 32px; +const Container = styled(View)` + padding: 4px 24px 0 24px; margin-bottom: 0px; padding-bottom: 0px; border-top-width: 0.5px; @@ -95,6 +96,7 @@ type CombinedResults = (AudioResult | AlbumResult)[]; export default function Search() { const defaultStyles = useDefaultStyles(); + const tabBarHeight = useBottomTabBarHeight(); // Prepare state for fuse and albums const [fuseIsReady, setFuseReady] = useState(false); @@ -210,60 +212,61 @@ export default function Search() { ); const HeaderComponent = React.useMemo(() => ( - - - - } - testID="search-input" - /> - {isLoading && } - - - {/* - - - - - - - - - */} - - ), [searchTerm, setSearchTerm, defaultStyles, isLoading, keyboardHeight]); + + + + + } + testID="search-input" + /> + {isLoading && } + + + {/* + + + + + + + + + */} + + + ), [searchTerm, setSearchTerm, defaultStyles, isLoading, keyboardHeight, tabBarHeight]); // GUARD: We cannot search for stuff unless Fuse is loaded with results. // Therefore we delay rendering to when we are certain it's there. diff --git a/src/screens/index.tsx b/src/screens/index.tsx index dc3dcb4..04fa446 100644 --- a/src/screens/index.tsx +++ b/src/screens/index.tsx @@ -23,6 +23,8 @@ import { t } from '@localisation'; import ErrorReportingAlert from 'utility/ErrorReportingAlert'; import ErrorReportingPopup from './modals/ErrorReportingPopup'; import Player from './modals/Player'; +import { StyleSheet } from 'react-native'; +import { ColoredBlurView } from 'components/Colors'; const Stack = createNativeStackNavigator(); const Tab = createBottomTabNavigator(); @@ -63,6 +65,11 @@ function Screens() { tabBarActiveTintColor: THEME_COLOR, tabBarInactiveTintColor: 'gray', headerShown: false, + tabBarShowLabel: false, + tabBarStyle: { position: 'absolute' }, + tabBarBackground: () => ( + + ) })} > diff --git a/src/utility/useKeyboardHeight.ts b/src/utility/useKeyboardHeight.ts index 0a70ab3..be0f7f4 100644 --- a/src/utility/useKeyboardHeight.ts +++ b/src/utility/useKeyboardHeight.ts @@ -1,6 +1,6 @@ import { useBottomTabBarHeight } from '@react-navigation/bottom-tabs'; import { useRef, useEffect } from 'react'; -import { Animated, Keyboard, KeyboardEvent } from 'react-native'; +import { Animated, Easing, Keyboard, KeyboardEvent } from 'react-native'; /** * This returns an animated height that the keyboard is poking up from the @@ -15,9 +15,10 @@ export const useKeyboardHeight = () => { useEffect(() => { const keyboardWillShow = (e: KeyboardEvent) => { Animated.timing(keyboardHeight, { - duration: e.duration, + duration: e.duration - 20, toValue: tabBarHeight - e.endCoordinates.height, useNativeDriver: true, + easing: Easing.ease, }).start(); };