mirror of
https://github.com/austinried/subtracks.git
synced 2025-12-29 09:29:29 +01:00
fallback to album art for artist cover
play top songs when pressed
This commit is contained in:
parent
de342c0830
commit
62b27974a7
@ -19,6 +19,7 @@ interface ArtistArtXUpProps extends ArtistArtSizeProps {
|
|||||||
|
|
||||||
interface ArtistArtProps extends ArtistArtSizeProps {
|
interface ArtistArtProps extends ArtistArtSizeProps {
|
||||||
id: string
|
id: string
|
||||||
|
round?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const PlaceholderContainer: React.FC<ArtistArtSizeProps> = ({ height, width, children }) => {
|
const PlaceholderContainer: React.FC<ArtistArtSizeProps> = ({ height, width, children }) => {
|
||||||
@ -135,9 +136,11 @@ const NoneUp = React.memo<ArtistArtSizeProps>(({ height, width }) => (
|
|||||||
<PlaceholderContainer height={height} width={width} />
|
<PlaceholderContainer height={height} width={width} />
|
||||||
))
|
))
|
||||||
|
|
||||||
const ArtistArt = React.memo<ArtistArtProps>(({ id, height, width }) => {
|
const ArtistArt = React.memo<ArtistArtProps>(({ id, height, width, round }) => {
|
||||||
const artistArt = useAtomValue(artistArtAtomFamily(id))
|
const artistArt = useAtomValue(artistArtAtomFamily(id))
|
||||||
|
|
||||||
|
round = round === undefined ? true : round
|
||||||
|
|
||||||
const Placeholder = () => {
|
const Placeholder = () => {
|
||||||
const none = <NoneUp height={height} width={width} />
|
const none = <NoneUp height={height} width={width} />
|
||||||
|
|
||||||
@ -163,7 +166,7 @@ const ArtistArt = React.memo<ArtistArtProps>(({ id, height, width }) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={[styles.container, { borderRadius: height / 2 }]}>
|
<View style={[styles.container, round ? { borderRadius: height / 2 } : {}]}>
|
||||||
<CoverArt
|
<CoverArt
|
||||||
PlaceholderComponent={Placeholder}
|
PlaceholderComponent={Placeholder}
|
||||||
height={height}
|
height={height}
|
||||||
|
|||||||
@ -1,9 +1,11 @@
|
|||||||
|
import ArtistArt from '@app/components/ArtistArt'
|
||||||
import CoverArt from '@app/components/CoverArt'
|
import CoverArt from '@app/components/CoverArt'
|
||||||
import GradientScrollView from '@app/components/GradientScrollView'
|
import GradientScrollView from '@app/components/GradientScrollView'
|
||||||
import PressableOpacity from '@app/components/PressableOpacity'
|
import PressableOpacity from '@app/components/PressableOpacity'
|
||||||
import SongItem from '@app/components/SongItem'
|
import SongItem from '@app/components/SongItem'
|
||||||
import { Album } from '@app/models/music'
|
import { Album } from '@app/models/music'
|
||||||
import { artistInfoAtomFamily } from '@app/state/music'
|
import { artistInfoAtomFamily } from '@app/state/music'
|
||||||
|
import { useSetQueue } from '@app/state/trackplayer'
|
||||||
import colors from '@app/styles/colors'
|
import colors from '@app/styles/colors'
|
||||||
import font from '@app/styles/font'
|
import font from '@app/styles/font'
|
||||||
import { useLayout } from '@react-native-community/hooks'
|
import { useLayout } from '@react-native-community/hooks'
|
||||||
@ -33,33 +35,60 @@ const AlbumItem = React.memo<{
|
|||||||
|
|
||||||
const ArtistDetails: React.FC<{ id: string }> = ({ id }) => {
|
const ArtistDetails: React.FC<{ id: string }> = ({ id }) => {
|
||||||
const artist = useAtomValue(artistInfoAtomFamily(id))
|
const artist = useAtomValue(artistInfoAtomFamily(id))
|
||||||
const layout = useLayout()
|
const setQueue = useSetQueue()
|
||||||
|
const albumsLayout = useLayout()
|
||||||
|
const coverLayout = useLayout()
|
||||||
|
|
||||||
const size = layout.width / 2 - styles.container.paddingHorizontal / 2
|
const albumSize = albumsLayout.width / 2 - styles.container.paddingHorizontal / 2
|
||||||
|
|
||||||
if (!artist) {
|
if (!artist) {
|
||||||
return <></>
|
return <></>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const TopSongs = () => (
|
||||||
|
<>
|
||||||
|
<Text style={styles.header}>Top Songs</Text>
|
||||||
|
{artist.topSongs.map(s => (
|
||||||
|
<SongItem
|
||||||
|
key={s.id}
|
||||||
|
song={s}
|
||||||
|
showArt={true}
|
||||||
|
subtitle="album"
|
||||||
|
onPress={() => setQueue(artist.topSongs, `Top Songs: ${artist.name}`, s.id)}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
|
||||||
|
const ArtistCoverFallback = () => (
|
||||||
|
<View style={styles.artistCover}>
|
||||||
|
<ArtistArt id={artist.id} round={false} height={artistCoverHeight} width={coverLayout.width} />
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<GradientScrollView offset={artistImageHeight} style={styles.scroll} contentContainerStyle={styles.scrollContent}>
|
<GradientScrollView
|
||||||
<FastImage
|
onLayout={coverLayout.onLayout}
|
||||||
style={[styles.artistImage]}
|
offset={artistCoverHeight}
|
||||||
source={{ uri: artist.largeImageUrl }}
|
style={styles.scroll}
|
||||||
|
contentContainerStyle={styles.scrollContent}>
|
||||||
|
<CoverArt
|
||||||
|
PlaceholderComponent={ArtistCoverFallback}
|
||||||
|
coverArtUri={artist.largeImageUrl}
|
||||||
|
style={styles.artistCover}
|
||||||
|
height={artistCoverHeight}
|
||||||
|
width={coverLayout.width}
|
||||||
resizeMode={FastImage.resizeMode.cover}
|
resizeMode={FastImage.resizeMode.cover}
|
||||||
/>
|
/>
|
||||||
<View style={styles.titleContainer}>
|
<View style={styles.titleContainer}>
|
||||||
<Text style={styles.title}>{artist.name}</Text>
|
<Text style={styles.title}>{artist.name}</Text>
|
||||||
</View>
|
</View>
|
||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
<Text style={styles.header}>Top Songs</Text>
|
{artist.topSongs.length > 0 ? <TopSongs /> : <></>}
|
||||||
{artist.topSongs.map(s => (
|
|
||||||
<SongItem key={s.id} song={s} showArt={true} subtitle="album" />
|
|
||||||
))}
|
|
||||||
<Text style={styles.header}>Albums</Text>
|
<Text style={styles.header}>Albums</Text>
|
||||||
<View style={styles.albums} onLayout={layout.onLayout}>
|
<View style={styles.albums} onLayout={albumsLayout.onLayout}>
|
||||||
{artist.albums.map(a => (
|
{artist.albums.map(a => (
|
||||||
<AlbumItem key={a.id} album={a} height={size} width={size} />
|
<AlbumItem key={a.id} album={a} height={albumSize} width={albumSize} />
|
||||||
))}
|
))}
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
@ -84,7 +113,7 @@ const ArtistView: React.FC<{
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const artistImageHeight = 280
|
const artistCoverHeight = 280
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
scroll: {
|
scroll: {
|
||||||
@ -99,18 +128,19 @@ const styles = StyleSheet.create({
|
|||||||
},
|
},
|
||||||
titleContainer: {
|
titleContainer: {
|
||||||
width: '100%',
|
width: '100%',
|
||||||
height: artistImageHeight,
|
height: artistCoverHeight,
|
||||||
justifyContent: 'flex-end',
|
justifyContent: 'flex-end',
|
||||||
},
|
},
|
||||||
title: {
|
title: {
|
||||||
fontFamily: font.bold,
|
fontFamily: font.bold,
|
||||||
fontSize: 44,
|
fontSize: 44,
|
||||||
color: colors.text.primary,
|
color: colors.text.primary,
|
||||||
textAlign: 'left',
|
textAlign: 'center',
|
||||||
textShadowColor: 'black',
|
textShadowColor: 'black',
|
||||||
textShadowOffset: { width: 0, height: 0 },
|
textShadowOffset: { width: 0, height: 0 },
|
||||||
textShadowRadius: 16,
|
textShadowRadius: 16,
|
||||||
paddingHorizontal: 10,
|
paddingHorizontal: 10,
|
||||||
|
marginBottom: 10,
|
||||||
},
|
},
|
||||||
header: {
|
header: {
|
||||||
fontFamily: font.bold,
|
fontFamily: font.bold,
|
||||||
@ -119,10 +149,10 @@ const styles = StyleSheet.create({
|
|||||||
marginTop: 20,
|
marginTop: 20,
|
||||||
marginBottom: 14,
|
marginBottom: 14,
|
||||||
},
|
},
|
||||||
artistImage: {
|
artistCover: {
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
width: '100%',
|
width: '100%',
|
||||||
height: artistImageHeight,
|
height: artistCoverHeight,
|
||||||
},
|
},
|
||||||
albums: {
|
albums: {
|
||||||
width: '100%',
|
width: '100%',
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user