artist view + moved components

This commit is contained in:
danis
2023-08-12 11:16:22 +02:00
parent f7562c18bd
commit 1255343b97
5 changed files with 146 additions and 99 deletions

View File

@@ -5,7 +5,7 @@ import { translate } from '../i18n/i18n';
import { SearchContext } from '../views/SearchView';
import { debounce } from 'lodash';
export type Filter = 'artist' | 'song' | 'genre' | 'all';
export type Filter = 'artist' | 'song' | 'genre' | 'all' | 'favorite';
type FilterButton = {
name: string;
@@ -16,7 +16,7 @@ type FilterButton = {
const SearchBar = () => {
const { filter, updateFilter } = React.useContext(SearchContext);
const { stringQuery, updateStringQuery } = React.useContext(SearchContext);
const [barText, updateBarText] = React.useState(stringQuery);
const [ barText, updateBarText ] = React.useState(stringQuery);
const debouncedUpdateStringQuery = debounce(updateStringQuery, 500);
@@ -42,6 +42,11 @@ const SearchBar = () => {
callback: () => updateFilter('all'),
id: 'all',
},
{
name: translate('favoriteFilter'),
callback: () => updateFilter('favorite'),
id: 'favorite',
},
{
name: translate('artistFilter'),
callback: () => updateFilter('artist'),

View File

@@ -29,6 +29,8 @@ import SearchHistoryCard from './HistoryCard';
import Song, { SongWithArtist } from '../models/Song';
import { useNavigation } from '../Navigation';
import Artist from '../models/Artist';
import SongRow from '../components/SongRow';
const swaToSongCardProps = (song: SongWithArtist) => ({
songId: song.id,
@@ -66,67 +68,67 @@ const RowCustom = (props: Parameters<typeof Box>[0] & { onPress?: () => void })
);
};
type SongRowProps = {
song: Song | SongWithArtist; // TODO: remove Song
onPress: () => void;
};
// type SongRowProps = {
// song: Song | SongWithArtist; // TODO: remove Song
// onPress: () => void;
// };
const SongRow = ({ song, onPress }: SongRowProps) => {
return (
<RowCustom width={'100%'}>
<HStack px={2} space={5} justifyContent={'space-between'}>
<Image
flexShrink={0}
flexGrow={0}
pl={10}
style={{ zIndex: 0, aspectRatio: 1, borderRadius: 5 }}
source={{ uri: song.cover }}
alt={song.name}
/>
<HStack
style={{
display: 'flex',
flexShrink: 1,
flexGrow: 1,
alignItems: 'center',
justifyContent: 'flex-start',
}}
space={6}
>
<Text
style={{
flexShrink: 1,
}}
isTruncated
pl={10}
maxW={'100%'}
bold
fontSize="md"
>
{song.name}
</Text>
<Text
style={{
flexShrink: 0,
}}
fontSize={'sm'}
>
{song.artistId ?? 'artist'}
</Text>
</HStack>
<TextButton
flexShrink={0}
flexGrow={0}
translate={{ translationKey: 'playBtn' }}
colorScheme="primary"
variant={'outline'}
size="sm"
onPress={onPress}
/>
</HStack>
</RowCustom>
);
};
// const SongRow = ({ song, onPress }: SongRowProps) => {
// return (
// <RowCustom width={'100%'}>
// <HStack px={2} space={5} justifyContent={'space-between'}>
// <Image
// flexShrink={0}
// flexGrow={0}
// pl={10}
// style={{ zIndex: 0, aspectRatio: 1, borderRadius: 5 }}
// source={{ uri: song.cover }}
// alt={song.name}
// />
// <HStack
// style={{
// display: 'flex',
// flexShrink: 1,
// flexGrow: 1,
// alignItems: 'center',
// justifyContent: 'flex-start',
// }}
// space={6}
// >
// <Text
// style={{
// flexShrink: 1,
// }}
// isTruncated
// pl={10}
// maxW={'100%'}
// bold
// fontSize="md"
// >
// {song.name}
// </Text>
// <Text
// style={{
// flexShrink: 0,
// }}
// fontSize={'sm'}
// >
// {song.artistId ?? 'artist'}
// </Text>
// </HStack>
// <TextButton
// flexShrink={0}
// flexGrow={0}
// translate={{ translationKey: 'playBtn' }}
// colorScheme="primary"
// variant={'outline'}
// size="sm"
// onPress={onPress}
// />
// </HStack>
// </RowCustom>
// );
// };
SongRow.defaultProps = {
onPress: () => {},
@@ -299,6 +301,35 @@ const GenreSearchComponent = (props: ItemSearchComponentProps) => {
);
};
const FavoriteSearchComponent = (props: SongsSearchComponentProps) => {
const { favoriteData } = React.useContext(SearchContext);
const navigation = useNavigation();
return (
<Box>
<Text fontSize="xl" fontWeight="bold" mt={4}>
{translate('favoriteFilter')}
</Text>
<Box>
{favoriteData?.length ? (
favoriteData.slice(0, props.maxRows).map((comp, index) => (
<SongRow
key={index}
song={comp}
onPress={() => {
API.createSearchHistoryEntry(comp.name, 'song');
navigation.navigate('Song', { songId: comp.id });
}}
/>
))
) : (
<Text>{translate('errNoResults')}</Text>
)}
</Box>
</Box>
)
}
const AllComponent = () => {
const screenSize = useBreakpointValue({ base: 'small', md: 'big' });
const isMobileView = screenSize == 'small';
@@ -344,6 +375,8 @@ const FilterSwitch = () => {
return <ArtistSearchComponent />;
case 'genre':
return <GenreSearchComponent />;
case 'favorite':
return <FavoriteSearchComponent />;
default:
return <Text>Something very bad happened: {currentFilter}</Text>;
}
@@ -351,7 +384,8 @@ const FilterSwitch = () => {
export const SearchResultComponent = () => {
const { stringQuery } = React.useContext(SearchContext);
const shouldOutput = !!stringQuery.trim();
const { filter } = React.useContext(SearchContext);
const shouldOutput = !!stringQuery.trim() || filter == "favorite";
return shouldOutput ? (
<Box p={5}>

View File

@@ -1,15 +1,21 @@
import { HStack, Image, Text } from "native-base";
import { HStack, IconButton, Image, Text } from "native-base";
import Song, { SongWithArtist } from "../models/Song";
import RowCustom from "./RowCustom";
import TextButton from "./TextButton";
import { MaterialIcons } from "@expo/vector-icons";
import API from "../API";
type SongRowProps = {
liked: boolean;
song: Song | SongWithArtist; // TODO: remove Song
onPress: () => void;
};
const SongRow = ({ song, onPress }: SongRowProps) => {
const handleLikeButton = {
}
const SongRow = ({ song, onPress, liked }: SongRowProps) => {
return (
<RowCustom width={"100%"}>
<HStack px={2} space={5} justifyContent={"space-between"}>
@@ -23,6 +29,10 @@ const SongRow = ({ song, onPress }: SongRowProps) => {
borderColor={'white'}
borderWidth={1}
/>
<IconButton size={'sm'} variant="ghost" _icon={{
as: MaterialIcons,
name: !liked ? "favorite-outline" : 'favorite',
}} />
<HStack
style={{
display: "flex",

View File

@@ -139,38 +139,28 @@ const ArtistDetailsView = ({ artistId }: any) => {
return (
<ScrollView>
<ImageBackground
style={{width : '100%', height: isMobileView ? 200 : 300}}
source={{uri : "https://picsum.photos/720"}}>
<LinearGradient
colors={['#00000000', '#000000']}
style={{height : '100%', width : '100%'}}/>
</ImageBackground>
{/* <Box>
<Image
source={{ uri: 'https://picsum.photos/720' }}
alt={artistData?.name}
size={'100%'}
height={isMobileView ? 200 : 300}
width={'100%'}
resizeMode='cover'
/> */}
<Box>
<Heading mt={-20} ml={3} fontSize={50}>{artistData?.name}</Heading>
<ScrollView mt={3}>
{songs.map((comp: Song | SongWithArtist, index: Key | null | undefined) => (
<SongRow
key={index}
song={comp}
onPress={() => {
API.createSearchHistoryEntry(comp.name, "song", Date.now());
navigation.navigate("Song", { songId: comp.id });
}}
/>
))
}
</ScrollView>
</Box>
{/* </Box> */}
style={{width : '100%', height: isMobileView ? 200 : 300}}
source={{uri : "https://picsum.photos/720"}}>
<LinearGradient
colors={['#00000000', '#000000']}
style={{height : '100%', width : '100%'}}/>
</ImageBackground>
<Box>
<Heading mt={-20} ml={3} fontSize={50}>{artistData?.name}</Heading>
<ScrollView mt={3}>
{songs.map((comp: Song | SongWithArtist, index: Key | null | undefined) => (
<SongRow
key={index}
song={comp}
onPress={() => {
API.createSearchHistoryEntry(comp.name, "song", Date.now());
navigation.navigate("Song", { songId: comp.id });
}}
/>
))
}
</ScrollView>
</Box>
</ScrollView>
);
};

View File

@@ -12,13 +12,14 @@ import { ScrollView } from 'native-base';
import { RouteProps } from '../Navigation';
interface SearchContextType {
filter: 'artist' | 'song' | 'genre' | 'all';
updateFilter: (newData: 'artist' | 'song' | 'genre' | 'all') => void;
filter: 'artist' | 'song' | 'genre' | 'all' | 'favorite';
updateFilter: (newData: 'artist' | 'song' | 'genre' | 'all' | 'favorite') => void;
stringQuery: string;
updateStringQuery: (newData: string) => void;
songData: Song[];
artistData: Artist[];
genreData: Genre[];
favoriteData: Song[];
isLoadingSong: boolean;
isLoadingArtist: boolean;
isLoadingGenre: boolean;
@@ -32,6 +33,7 @@ export const SearchContext = React.createContext<SearchContextType>({
songData: [],
artistData: [],
genreData: [],
favoriteData: [],
isLoadingSong: false,
isLoadingArtist: false,
isLoadingGenre: false,
@@ -60,6 +62,11 @@ const SearchView = (props: RouteProps<SearchViewProps>) => {
{ enabled: !!stringQuery }
);
const { isLoading: isLoadingFavorite, data: favoriteData = [] } = useQuery(
API.getFavorites(),
{ enabled: true }
)
const updateFilter = (newData: Filter) => {
// called when the filter is changed
setFilter(newData);
@@ -80,6 +87,7 @@ const SearchView = (props: RouteProps<SearchViewProps>) => {
songData,
artistData,
genreData,
favoriteData,
isLoadingSong,
isLoadingArtist,
isLoadingGenre,