Merge branch 'feature/adc/#224-genre-view' into feature/adc/#242-liked-songs

This commit is contained in:
danis
2023-09-13 13:23:16 +02:00
10 changed files with 313 additions and 143 deletions
+43 -32
View File
@@ -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>
);
};
+76
View File
@@ -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;