Merge branch 'feature/adc/#224-genre-view' into feature/adc/#242-liked-songs
This commit is contained in:
@@ -1,49 +1,60 @@
|
||||
import { VStack, Image, Heading, IconButton, Icon, Container } from 'native-base';
|
||||
import { Ionicons } from '@expo/vector-icons';
|
||||
import { SafeAreaView } from 'react-native';
|
||||
import { Box, Heading, useBreakpointValue, ScrollView, useColorModeValue } from 'native-base';
|
||||
import { useQuery } from '../Queries';
|
||||
import { LoadingView } from '../components/Loading';
|
||||
import API from '../API';
|
||||
import { useNavigation } from '../Navigation';
|
||||
|
||||
const handleFavorite = () => {};
|
||||
import Song from '../models/Song';
|
||||
import SongRow from '../components/SongRow';
|
||||
import { Key } from 'react';
|
||||
import { RouteProps, useNavigation } from '../Navigation';
|
||||
import { ImageBackground } from 'react-native';
|
||||
|
||||
type ArtistDetailsViewProps = {
|
||||
artistId: number;
|
||||
};
|
||||
|
||||
const ArtistDetailsView = ({ artistId }: ArtistDetailsViewProps) => {
|
||||
const ArtistDetailsView = ({ artistId }: RouteProps<ArtistDetailsViewProps>) => {
|
||||
const artistQuery = useQuery(API.getArtist(artistId));
|
||||
const songsQuery = useQuery(API.getSongsByArtist(artistId));
|
||||
const screenSize = useBreakpointValue({ base: 'small', md: 'big' });
|
||||
const fadeColor = useColorModeValue('#ffffff', '#000000');
|
||||
const isMobileView = screenSize == 'small';
|
||||
const navigation = useNavigation();
|
||||
const { isLoading, data: artistData, isError } = useQuery(API.getArtist(artistId));
|
||||
|
||||
if (isLoading) {
|
||||
if (artistQuery.isError || songsQuery.isError) {
|
||||
navigation.navigate('Error');
|
||||
return <></>;
|
||||
}
|
||||
if (!artistQuery.data || songsQuery.data === undefined) {
|
||||
return <LoadingView />;
|
||||
}
|
||||
|
||||
if (isError) {
|
||||
navigation.navigate('Error');
|
||||
}
|
||||
|
||||
return (
|
||||
<SafeAreaView>
|
||||
<Container m={3}>
|
||||
<Image
|
||||
source={{ uri: 'https://picsum.photos/200' }}
|
||||
alt={artistData?.name}
|
||||
size={20}
|
||||
borderRadius="full"
|
||||
/>
|
||||
<VStack space={3}>
|
||||
<Heading>{artistData?.name}</Heading>
|
||||
<IconButton
|
||||
icon={<Icon as={Ionicons} name="heart" size={6} color="red.500" />}
|
||||
onPress={() => handleFavorite()}
|
||||
variant="unstyled"
|
||||
_pressed={{ opacity: 0.6 }}
|
||||
/>
|
||||
</VStack>
|
||||
</Container>
|
||||
</SafeAreaView>
|
||||
<ScrollView>
|
||||
<ImageBackground
|
||||
style={{ width: '100%', height: isMobileView ? 200 : 300 }}
|
||||
source={{ uri: API.getArtistIllustration(artistQuery.data.id) }}
|
||||
>
|
||||
</ImageBackground>
|
||||
<Box>
|
||||
<Heading mt={-20} ml={3} fontSize={50}>
|
||||
{artistQuery.data.name}
|
||||
</Heading>
|
||||
<ScrollView mt={3}>
|
||||
<Box>
|
||||
{songsQuery.data.map((comp: Song, index: Key | null | undefined) => (
|
||||
<SongRow
|
||||
key={index}
|
||||
song={comp}
|
||||
onPress={() => {
|
||||
API.createSearchHistoryEntry(comp.name, 'song');
|
||||
navigation.navigate('Song', { songId: comp.id });
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</Box>
|
||||
</ScrollView>
|
||||
</Box>
|
||||
</ScrollView>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
import { Flex, Heading, useBreakpointValue, ScrollView, useColorModeValue } from 'native-base';
|
||||
import { useQueries, useQuery } from '../Queries';
|
||||
import { LoadingView } from '../components/Loading';
|
||||
import { RouteProps, useNavigation } from '../Navigation';
|
||||
import API from '../API';
|
||||
import CardGridCustom from '../components/CardGridCustom';
|
||||
import SongCard from '../components/SongCard';
|
||||
import { ImageBackground } from 'react-native';
|
||||
|
||||
type GenreDetailsViewProps = {
|
||||
genreId: number;
|
||||
};
|
||||
|
||||
const GenreDetailsView = ({ genreId }: RouteProps<GenreDetailsViewProps>) => {
|
||||
const genreQuery = useQuery(API.getGenre(genreId));
|
||||
const songsQuery = useQuery(API.getSongsByGenre(genreId));
|
||||
const artistQueries = useQueries(
|
||||
songsQuery.data?.map((song) => song.artistId).map((artistId) => API.getArtist(artistId)) ??
|
||||
[]
|
||||
);
|
||||
// Here, .artist will always be defined
|
||||
const songWithArtist = songsQuery?.data
|
||||
?.map((song) => ({
|
||||
...song,
|
||||
artist: artistQueries.find((query) => query.data?.id == song.artistId)?.data,
|
||||
}))
|
||||
.filter((song) => song.artist !== undefined);
|
||||
|
||||
const screenSize = useBreakpointValue({ base: 'small', md: 'big' });
|
||||
const isMobileView = screenSize == 'small';
|
||||
const fadeColor = useColorModeValue('#ffffff', '#000000');
|
||||
const navigation = useNavigation();
|
||||
|
||||
if (genreQuery.isError || songsQuery.isError) {
|
||||
navigation.navigate('Error');
|
||||
return <></>;
|
||||
}
|
||||
if (!genreQuery.data || songsQuery.data === undefined || songWithArtist === undefined) {
|
||||
return <LoadingView />;
|
||||
}
|
||||
|
||||
return (
|
||||
<ScrollView>
|
||||
<ImageBackground
|
||||
style={{ width: '100%', height: isMobileView ? 200 : 300 }}
|
||||
source={{ uri: API.getGenreIllustration(genreQuery.data.id) }}
|
||||
>
|
||||
</ImageBackground>
|
||||
<Heading ml={3} fontSize={50}>
|
||||
{genreQuery.data.name}
|
||||
</Heading>
|
||||
<Flex
|
||||
flexWrap="wrap"
|
||||
direction={isMobileView ? 'column' : 'row'}
|
||||
justifyContent={['flex-start']}
|
||||
mt={4}
|
||||
>
|
||||
<CardGridCustom
|
||||
content={songWithArtist.map((songData) => ({
|
||||
name: songData.name,
|
||||
cover: songData.cover,
|
||||
artistName: songData.artist!.name,
|
||||
songId: songData.id,
|
||||
onPress: () => {
|
||||
API.createSearchHistoryEntry(songData.name, 'song');
|
||||
navigation.navigate('Song', { songId: songData.id });
|
||||
},
|
||||
}))}
|
||||
cardComponent={SongCard}
|
||||
/>
|
||||
</Flex>
|
||||
</ScrollView>
|
||||
);
|
||||
};
|
||||
|
||||
export default GenreDetailsView;
|
||||
Reference in New Issue
Block a user