Base search implementation
This commit is contained in:
5
package-lock.json
generated
5
package-lock.json
generated
@@ -4587,6 +4587,11 @@
|
||||
"integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
|
||||
"dev": true
|
||||
},
|
||||
"fuse.js": {
|
||||
"version": "6.4.0",
|
||||
"resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-6.4.0.tgz",
|
||||
"integrity": "sha512-MagWS1i3kj58BgF9xymo+n2ZiSs9MoyVfxkCcr11+mzMpNEyTDyLtbU3DyrVjHsy0Gkjf58FH1n+TaihylFcIA=="
|
||||
},
|
||||
"gensync": {
|
||||
"version": "1.0.0-beta.1",
|
||||
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz",
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
"@types/redux-logger": "^3.0.8",
|
||||
"@types/styled-components": "^5.1.0",
|
||||
"date-fns": "^2.14.0",
|
||||
"fuse.js": "^6.4.0",
|
||||
"lodash": "^4.17.15",
|
||||
"react": "16.11.0",
|
||||
"react-native": "0.62.2",
|
||||
|
||||
@@ -4,6 +4,7 @@ import { StackParams } from './types';
|
||||
import Albums from './stacks/Albums';
|
||||
import Album from './stacks/Album';
|
||||
import RecentAlbums from './stacks/RecentAlbums';
|
||||
import Search from './stacks/Search';
|
||||
|
||||
const Stack = createStackNavigator<StackParams>();
|
||||
|
||||
@@ -13,6 +14,7 @@ function MusicStack() {
|
||||
<Stack.Screen name="RecentAlbums" component={RecentAlbums} options={{ headerTitle: 'Recent Albums' }} />
|
||||
<Stack.Screen name="Albums" component={Albums} />
|
||||
<Stack.Screen name="Album" component={Album} />
|
||||
<Stack.Screen name="Search" component={Search} />
|
||||
</Stack.Navigator>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -16,10 +16,12 @@ import ListButton from 'components/ListButton';
|
||||
const NavigationHeader: React.FC = () => {
|
||||
const navigation = useNavigation();
|
||||
const handleAllAlbumsClick = useCallback(() => { navigation.navigate('Albums'); }, [navigation]);
|
||||
const handleSearchClick = useCallback(() => { navigation.navigate('Search'); }, [navigation]);
|
||||
|
||||
return (
|
||||
<ListContainer>
|
||||
<ListButton onPress={handleAllAlbumsClick}>All Albums</ListButton>
|
||||
<ListButton onPress={handleSearchClick}>Search</ListButton>
|
||||
<Header>Recent Albums</Header>
|
||||
</ListContainer>
|
||||
);
|
||||
|
||||
38
src/screens/Music/stacks/Search.tsx
Normal file
38
src/screens/Music/stacks/Search.tsx
Normal file
@@ -0,0 +1,38 @@
|
||||
import React, { useState, useEffect, useCallback } from 'react';
|
||||
import Input from 'components/Input';
|
||||
import { Text } from 'react-native';
|
||||
import styled from 'styled-components/native';
|
||||
import { useTypedSelector } from 'store';
|
||||
import Fuse from 'fuse.js';
|
||||
|
||||
const Container = styled.View`
|
||||
padding: 0 20px;
|
||||
`;
|
||||
|
||||
export default function Search() {
|
||||
const [searchTerm, setSearchTerm] = useState('');
|
||||
const albums = useTypedSelector(state => state.music.albums.entities);
|
||||
const [results, setResults] = useState([]);
|
||||
let fuse: Fuse<{}, {}>;
|
||||
|
||||
useEffect(() => {
|
||||
fuse = new Fuse(Object.values(albums), {
|
||||
keys: ['Name', 'AlbumArtist', 'AlbumArtists', 'Artists'],
|
||||
threshold: 0.1,
|
||||
includeScore: true,
|
||||
});
|
||||
}, [albums]);
|
||||
|
||||
useEffect(() => {
|
||||
setResults(fuse.search(searchTerm));
|
||||
}, [searchTerm, setResults, fuse]);
|
||||
|
||||
return (
|
||||
<Container>
|
||||
<Input value={searchTerm} onChangeText={setSearchTerm} placeholder="Search..." />
|
||||
{results.map((result) => (
|
||||
<Text key={result.refIndex}>{result.item.Name} - {result.item.AlbumArtist}</Text>
|
||||
))}
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user