Skip to content

Commit

Permalink
(1) Automatically focus on text field in search
Browse files Browse the repository at this point in the history
(2) Restyle no results message
  • Loading branch information
leinelissen committed Jan 1, 2022
1 parent 9b41a0e commit 4460bdf
Showing 1 changed file with 38 additions and 13 deletions.
51 changes: 38 additions & 13 deletions src/screens/Music/stacks/Search.tsx
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -21,6 +21,10 @@ const Container = styled.View`
position: relative;
`;

const FullSizeContainer = styled(Container)`
flex: 1;
`;

const Loading = styled.View`
position: absolute;
right: 32px;
Expand Down Expand Up @@ -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<CombinedResults>([]);
const [jellyfinResults, setJellyfinResults] = useState<CombinedResults>([]);

const [isLoading, setLoading] = useState(false);
const albums = useTypedSelector(state => state.music.albums.entities);

const fuse = useRef<Fuse<Album>>();
const searchElement = useRef<TextInput>(null);

// Prepare helpers
const navigation = useNavigation<NavigationProp>();
Expand Down Expand Up @@ -185,25 +191,39 @@ 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]
);

const HeaderComponent = React.useMemo(() => (
<Container>
<Input value={searchTerm} onChangeText={setSearchTerm} style={defaultStyles.input} placeholder={t('search') + '...'} />
<Input
// @ts-expect-error Ref typing shenanigans
ref={searchElement}
value={searchTerm}
onChangeText={setSearchTerm}
style={defaultStyles.input}
placeholder={t('search') + '...'}
/>
{isLoading && <Loading><ActivityIndicator /></Loading>}
</Container>
), [searchTerm, setSearchTerm, defaultStyles, isLoading]);

const FooterComponent = React.useMemo(() => (
<Container>
{(searchTerm.length && !jellyfinResults.length && !fuseResults.length && !isLoading)
? <Text style={{ textAlign: 'center' }}>{t('no-results')}</Text>
: null}
</Container>
), [searchTerm, jellyfinResults, fuseResults, isLoading]);
// const FooterComponent = React.useMemo(() => (
// <FullSizeContainer>
// {(searchTerm.length && !jellyfinResults.length && !fuseResults.length && !isLoading)
// ? <Text style={{ textAlign: 'center', opacity: 0.5 }}>{t('no-results')}</Text>
// : null}
// </FullSizeContainer>
// ), [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.
Expand Down Expand Up @@ -243,9 +263,14 @@ export default function Search() {
}}
keyExtractor={(item) => item.id}
ListHeaderComponent={HeaderComponent}
ListFooterComponent={FooterComponent}
// ListFooterComponent={FooterComponent}
extraData={[searchTerm, albums]}
/>
<FullSizeContainer>
{(searchTerm.length && !jellyfinResults.length && !fuseResults.length && !isLoading)
? <Text style={{ textAlign: 'center', opacity: 0.5, fontSize: 18 }}>{t('no-results')}</Text>
: null}
</FullSizeContainer>
</>
);
}

0 comments on commit 4460bdf

Please sign in to comment.