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=",
|
"integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
|
||||||
"dev": true
|
"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": {
|
"gensync": {
|
||||||
"version": "1.0.0-beta.1",
|
"version": "1.0.0-beta.1",
|
||||||
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz",
|
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz",
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
"@types/redux-logger": "^3.0.8",
|
"@types/redux-logger": "^3.0.8",
|
||||||
"@types/styled-components": "^5.1.0",
|
"@types/styled-components": "^5.1.0",
|
||||||
"date-fns": "^2.14.0",
|
"date-fns": "^2.14.0",
|
||||||
|
"fuse.js": "^6.4.0",
|
||||||
"lodash": "^4.17.15",
|
"lodash": "^4.17.15",
|
||||||
"react": "16.11.0",
|
"react": "16.11.0",
|
||||||
"react-native": "0.62.2",
|
"react-native": "0.62.2",
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { StackParams } from './types';
|
|||||||
import Albums from './stacks/Albums';
|
import Albums from './stacks/Albums';
|
||||||
import Album from './stacks/Album';
|
import Album from './stacks/Album';
|
||||||
import RecentAlbums from './stacks/RecentAlbums';
|
import RecentAlbums from './stacks/RecentAlbums';
|
||||||
|
import Search from './stacks/Search';
|
||||||
|
|
||||||
const Stack = createStackNavigator<StackParams>();
|
const Stack = createStackNavigator<StackParams>();
|
||||||
|
|
||||||
@@ -13,6 +14,7 @@ function MusicStack() {
|
|||||||
<Stack.Screen name="RecentAlbums" component={RecentAlbums} options={{ headerTitle: 'Recent Albums' }} />
|
<Stack.Screen name="RecentAlbums" component={RecentAlbums} options={{ headerTitle: 'Recent Albums' }} />
|
||||||
<Stack.Screen name="Albums" component={Albums} />
|
<Stack.Screen name="Albums" component={Albums} />
|
||||||
<Stack.Screen name="Album" component={Album} />
|
<Stack.Screen name="Album" component={Album} />
|
||||||
|
<Stack.Screen name="Search" component={Search} />
|
||||||
</Stack.Navigator>
|
</Stack.Navigator>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,10 +16,12 @@ import ListButton from 'components/ListButton';
|
|||||||
const NavigationHeader: React.FC = () => {
|
const NavigationHeader: React.FC = () => {
|
||||||
const navigation = useNavigation();
|
const navigation = useNavigation();
|
||||||
const handleAllAlbumsClick = useCallback(() => { navigation.navigate('Albums'); }, [navigation]);
|
const handleAllAlbumsClick = useCallback(() => { navigation.navigate('Albums'); }, [navigation]);
|
||||||
|
const handleSearchClick = useCallback(() => { navigation.navigate('Search'); }, [navigation]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ListContainer>
|
<ListContainer>
|
||||||
<ListButton onPress={handleAllAlbumsClick}>All Albums</ListButton>
|
<ListButton onPress={handleAllAlbumsClick}>All Albums</ListButton>
|
||||||
|
<ListButton onPress={handleSearchClick}>Search</ListButton>
|
||||||
<Header>Recent Albums</Header>
|
<Header>Recent Albums</Header>
|
||||||
</ListContainer>
|
</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