From 4460bdf7f963f90197311d51b005dd41e395f5ef Mon Sep 17 00:00:00 2001 From: Lei Nelissen Date: Sat, 1 Jan 2022 14:27:08 +0100 Subject: [PATCH] (1) Automatically focus on text field in search (2) Restyle no results message --- src/screens/Music/stacks/Search.tsx | 51 +++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 13 deletions(-) diff --git a/src/screens/Music/stacks/Search.tsx b/src/screens/Music/stacks/Search.tsx index dcaf07a..aaecd6f 100644 --- a/src/screens/Music/stacks/Search.tsx +++ b/src/screens/Music/stacks/Search.tsx @@ -1,6 +1,6 @@ -import React, { useState, useEffect, useRef, useCallback } from 'react'; +import React, { useState, useEffect, useRef, useCallback, Ref } from 'react'; import Input from 'components/Input'; -import { ActivityIndicator, Text, View } from 'react-native'; +import { ActivityIndicator, Text, TextInput, View } from 'react-native'; import styled from 'styled-components/native'; import { useAppDispatch, useTypedSelector } from 'store'; import Fuse from 'fuse.js'; @@ -21,6 +21,10 @@ const Container = styled.View` position: relative; `; +const FullSizeContainer = styled(Container)` + flex: 1; +`; + const Loading = styled.View` position: absolute; right: 32px; @@ -80,12 +84,14 @@ export default function Search() { // Prepare state const [fuseIsReady, setFuseReady] = useState(false); const [searchTerm, setSearchTerm] = useState(''); - const albums = useTypedSelector(state => state.music.albums.entities); + const [isLoading, setLoading] = useState(false); const [fuseResults, setFuseResults] = useState([]); const [jellyfinResults, setJellyfinResults] = useState([]); - const [isLoading, setLoading] = useState(false); + const albums = useTypedSelector(state => state.music.albums.entities); + const fuse = useRef>(); + const searchElement = useRef(null); // Prepare helpers const navigation = useNavigation(); @@ -185,6 +191,13 @@ export default function Search() { retrieveResults(); }, [searchTerm, setFuseResults, setLoading, fuse, fetchJellyfinResults]); + // Automatically focus on the text input on mount + useEffect(() => { + // Give the timeout a slight delay so the component has a chance to actually + // render the text input field. + setTimeout(() => searchElement.current?.focus(), 10); + }, []); + // Handlers const selectAlbum = useCallback((id: string) => navigation.navigate('Album', { id, album: albums[id] as Album }), [navigation, albums] @@ -192,18 +205,25 @@ export default function Search() { const HeaderComponent = React.useMemo(() => ( - + {isLoading && } ), [searchTerm, setSearchTerm, defaultStyles, isLoading]); - const FooterComponent = React.useMemo(() => ( - - {(searchTerm.length && !jellyfinResults.length && !fuseResults.length && !isLoading) - ? {t('no-results')} - : null} - - ), [searchTerm, jellyfinResults, fuseResults, isLoading]); + // const FooterComponent = React.useMemo(() => ( + // + // {(searchTerm.length && !jellyfinResults.length && !fuseResults.length && !isLoading) + // ? {t('no-results')} + // : null} + // + // ), [searchTerm, jellyfinResults, fuseResults, isLoading]); // GUARD: We cannot search for stuff unless Fuse is loaded with results. // Therefore we delay rendering to when we are certain it's there. @@ -243,9 +263,14 @@ export default function Search() { }} keyExtractor={(item) => item.id} ListHeaderComponent={HeaderComponent} - ListFooterComponent={FooterComponent} + // ListFooterComponent={FooterComponent} extraData={[searchTerm, albums]} /> + + {(searchTerm.length && !jellyfinResults.length && !fuseResults.length && !isLoading) + ? {t('no-results')} + : null} + ); } \ No newline at end of file