mirror of
https://github.com/austinried/subtracks.git
synced 2026-02-10 15:02:42 +01:00
added top songs to artist view
This commit is contained in:
@@ -14,7 +14,7 @@ interface ArtistArtSizeProps {
|
||||
}
|
||||
|
||||
interface ArtistArtXUpProps extends ArtistArtSizeProps {
|
||||
coverArtUris: string[]
|
||||
albumCoverUris: string[]
|
||||
}
|
||||
|
||||
interface ArtistArtProps extends ArtistArtSizeProps {
|
||||
@@ -39,7 +39,7 @@ const PlaceholderContainer: React.FC<ArtistArtSizeProps> = ({ height, width, chi
|
||||
)
|
||||
}
|
||||
|
||||
const FourUp = React.memo<ArtistArtXUpProps>(({ height, width, coverArtUris }) => {
|
||||
const FourUp = React.memo<ArtistArtXUpProps>(({ height, width, albumCoverUris }) => {
|
||||
const halfHeight = height / 2
|
||||
const halfWidth = width / 2
|
||||
|
||||
@@ -47,24 +47,24 @@ const FourUp = React.memo<ArtistArtXUpProps>(({ height, width, coverArtUris }) =
|
||||
<PlaceholderContainer height={height} width={width}>
|
||||
<View style={[styles.artRow, { width, height: halfHeight }]}>
|
||||
<FastImage
|
||||
source={{ uri: coverArtUris[0] }}
|
||||
source={{ uri: albumCoverUris[0] }}
|
||||
style={{ height: halfHeight, width: halfWidth }}
|
||||
resizeMode={FastImage.resizeMode.cover}
|
||||
/>
|
||||
<FastImage
|
||||
source={{ uri: coverArtUris[1] }}
|
||||
source={{ uri: albumCoverUris[1] }}
|
||||
style={{ height: halfHeight, width: halfWidth }}
|
||||
resizeMode={FastImage.resizeMode.cover}
|
||||
/>
|
||||
</View>
|
||||
<View style={[styles.artRow, { width, height: halfHeight }]}>
|
||||
<FastImage
|
||||
source={{ uri: coverArtUris[2] }}
|
||||
source={{ uri: albumCoverUris[2] }}
|
||||
style={{ height: halfHeight, width: halfWidth }}
|
||||
resizeMode={FastImage.resizeMode.cover}
|
||||
/>
|
||||
<FastImage
|
||||
source={{ uri: coverArtUris[3] }}
|
||||
source={{ uri: albumCoverUris[3] }}
|
||||
style={{ height: halfHeight, width: halfWidth }}
|
||||
resizeMode={FastImage.resizeMode.cover}
|
||||
/>
|
||||
@@ -73,7 +73,7 @@ const FourUp = React.memo<ArtistArtXUpProps>(({ height, width, coverArtUris }) =
|
||||
)
|
||||
})
|
||||
|
||||
const ThreeUp = React.memo<ArtistArtXUpProps>(({ height, width, coverArtUris }) => {
|
||||
const ThreeUp = React.memo<ArtistArtXUpProps>(({ height, width, albumCoverUris }) => {
|
||||
const halfHeight = height / 2
|
||||
const halfWidth = width / 2
|
||||
|
||||
@@ -81,19 +81,19 @@ const ThreeUp = React.memo<ArtistArtXUpProps>(({ height, width, coverArtUris })
|
||||
<PlaceholderContainer height={height} width={width}>
|
||||
<View style={[styles.artRow, { width, height: halfHeight }]}>
|
||||
<FastImage
|
||||
source={{ uri: coverArtUris[0] }}
|
||||
source={{ uri: albumCoverUris[0] }}
|
||||
style={{ height: halfHeight, width }}
|
||||
resizeMode={FastImage.resizeMode.cover}
|
||||
/>
|
||||
</View>
|
||||
<View style={[styles.artRow, { width, height: halfHeight }]}>
|
||||
<FastImage
|
||||
source={{ uri: coverArtUris[1] }}
|
||||
source={{ uri: albumCoverUris[1] }}
|
||||
style={{ height: halfHeight, width: halfWidth }}
|
||||
resizeMode={FastImage.resizeMode.cover}
|
||||
/>
|
||||
<FastImage
|
||||
source={{ uri: coverArtUris[2] }}
|
||||
source={{ uri: albumCoverUris[2] }}
|
||||
style={{ height: halfHeight, width: halfWidth }}
|
||||
resizeMode={FastImage.resizeMode.cover}
|
||||
/>
|
||||
@@ -102,21 +102,21 @@ const ThreeUp = React.memo<ArtistArtXUpProps>(({ height, width, coverArtUris })
|
||||
)
|
||||
})
|
||||
|
||||
const TwoUp = React.memo<ArtistArtXUpProps>(({ height, width, coverArtUris }) => {
|
||||
const TwoUp = React.memo<ArtistArtXUpProps>(({ height, width, albumCoverUris }) => {
|
||||
const halfHeight = height / 2
|
||||
|
||||
return (
|
||||
<PlaceholderContainer height={height} width={width}>
|
||||
<View style={[styles.artRow, { width, height: halfHeight }]}>
|
||||
<FastImage
|
||||
source={{ uri: coverArtUris[0] }}
|
||||
source={{ uri: albumCoverUris[0] }}
|
||||
style={{ height: halfHeight, width }}
|
||||
resizeMode={FastImage.resizeMode.cover}
|
||||
/>
|
||||
</View>
|
||||
<View style={[styles.artRow, { width, height: halfHeight }]}>
|
||||
<FastImage
|
||||
source={{ uri: coverArtUris[1] }}
|
||||
source={{ uri: albumCoverUris[1] }}
|
||||
style={{ height: halfHeight, width }}
|
||||
resizeMode={FastImage.resizeMode.cover}
|
||||
/>
|
||||
@@ -125,9 +125,9 @@ const TwoUp = React.memo<ArtistArtXUpProps>(({ height, width, coverArtUris }) =>
|
||||
)
|
||||
})
|
||||
|
||||
const OneUp = React.memo<ArtistArtXUpProps>(({ height, width, coverArtUris }) => (
|
||||
const OneUp = React.memo<ArtistArtXUpProps>(({ height, width, albumCoverUris }) => (
|
||||
<PlaceholderContainer height={height} width={width}>
|
||||
<FastImage source={{ uri: coverArtUris[0] }} style={{ height, width }} resizeMode={FastImage.resizeMode.cover} />
|
||||
<FastImage source={{ uri: albumCoverUris[0] }} style={{ height, width }} resizeMode={FastImage.resizeMode.cover} />
|
||||
</PlaceholderContainer>
|
||||
))
|
||||
|
||||
@@ -141,22 +141,22 @@ const ArtistArt = React.memo<ArtistArtProps>(({ id, height, width }) => {
|
||||
const Placeholder = () => {
|
||||
const none = <NoneUp height={height} width={width} />
|
||||
|
||||
if (!artistArt || !artistArt.coverArtUris) {
|
||||
if (!artistArt || !artistArt.albumCoverUris) {
|
||||
return none
|
||||
}
|
||||
const { coverArtUris } = artistArt
|
||||
const { albumCoverUris } = artistArt
|
||||
|
||||
if (coverArtUris.length >= 4) {
|
||||
return <FourUp height={height} width={width} coverArtUris={coverArtUris} />
|
||||
if (albumCoverUris.length >= 4) {
|
||||
return <FourUp height={height} width={width} albumCoverUris={albumCoverUris} />
|
||||
}
|
||||
if (coverArtUris.length === 3) {
|
||||
return <ThreeUp height={height} width={width} coverArtUris={coverArtUris} />
|
||||
if (albumCoverUris.length === 3) {
|
||||
return <ThreeUp height={height} width={width} albumCoverUris={albumCoverUris} />
|
||||
}
|
||||
if (coverArtUris.length === 2) {
|
||||
return <TwoUp height={height} width={width} coverArtUris={coverArtUris} />
|
||||
if (albumCoverUris.length === 2) {
|
||||
return <TwoUp height={height} width={width} albumCoverUris={albumCoverUris} />
|
||||
}
|
||||
if (coverArtUris.length === 1) {
|
||||
return <OneUp height={height} width={width} coverArtUris={coverArtUris} />
|
||||
if (albumCoverUris.length === 1) {
|
||||
return <OneUp height={height} width={width} albumCoverUris={albumCoverUris} />
|
||||
}
|
||||
|
||||
return none
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import { ActivityIndicator, LayoutChangeEvent, StyleSheet, View } from 'react-native'
|
||||
import { ActivityIndicator, LayoutChangeEvent, StyleSheet, View, ViewStyle } from 'react-native'
|
||||
import FastImage from 'react-native-fast-image'
|
||||
import colors from '@app/styles/colors'
|
||||
import IconFA5 from 'react-native-vector-icons/FontAwesome5'
|
||||
@@ -12,7 +12,8 @@ const CoverArt: React.FC<{
|
||||
width?: string | number
|
||||
coverArtUri?: string
|
||||
resizeMode?: keyof typeof FastImage.resizeMode
|
||||
}> = ({ PlaceholderComponent, placeholderIcon, height, width, coverArtUri, resizeMode }) => {
|
||||
style?: ViewStyle
|
||||
}> = ({ PlaceholderComponent, placeholderIcon, height, width, coverArtUri, resizeMode, style }) => {
|
||||
const [placeholderVisible, setPlaceholderVisible] = useState(false)
|
||||
const [loading, setLoading] = useState(true)
|
||||
const [layout, setLayout] = useState({ x: 0, y: 0, width: 0, height: 0 })
|
||||
@@ -47,7 +48,7 @@ const CoverArt: React.FC<{
|
||||
}
|
||||
|
||||
return (
|
||||
<View style={{ ...styles.container, height, width }} onLayout={onLayout}>
|
||||
<View style={[style, { height, width }]} onLayout={onLayout}>
|
||||
{coverArtUri ? <Image /> : <></>}
|
||||
<View style={{ ...styles.placeholderContainer, opacity: placeholderVisible ? 1 : 0 }}>
|
||||
{PlaceholderComponent ? <PlaceholderComponent /> : <Placeholder />}
|
||||
|
||||
84
app/components/SongItem.tsx
Normal file
84
app/components/SongItem.tsx
Normal file
@@ -0,0 +1,84 @@
|
||||
import { Song } from '@app/models/music'
|
||||
import { currentTrackAtom } from '@app/state/trackplayer'
|
||||
import colors from '@app/styles/colors'
|
||||
import font from '@app/styles/font'
|
||||
import { useAtomValue } from 'jotai/utils'
|
||||
import React from 'react'
|
||||
import { GestureResponderEvent, StyleSheet, Text, View } from 'react-native'
|
||||
import IconFA from 'react-native-vector-icons/FontAwesome'
|
||||
import IconMat from 'react-native-vector-icons/MaterialIcons'
|
||||
import CoverArt from './CoverArt'
|
||||
import PressableOpacity from './PressableOpacity'
|
||||
|
||||
const SongItem: React.FC<{
|
||||
song: Song
|
||||
onPress?: (event: GestureResponderEvent) => void
|
||||
showArt?: boolean
|
||||
subtitle?: 'artist' | 'album'
|
||||
}> = ({ song, onPress, showArt, subtitle }) => {
|
||||
const currentTrack = useAtomValue(currentTrackAtom)
|
||||
|
||||
subtitle = subtitle || 'artist'
|
||||
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<PressableOpacity onPress={onPress} style={styles.item}>
|
||||
{showArt ? <CoverArt coverArtUri={song.coverArtThumbUri} style={styles.art} height={50} width={50} /> : <></>}
|
||||
<View style={styles.text}>
|
||||
<Text style={[styles.title, { color: currentTrack?.id === song.id ? colors.accent : colors.text.primary }]}>
|
||||
{song.title}
|
||||
</Text>
|
||||
<Text style={styles.subtitle}>{song[subtitle]}</Text>
|
||||
</View>
|
||||
</PressableOpacity>
|
||||
<View style={styles.controls}>
|
||||
<PressableOpacity onPress={undefined}>
|
||||
<IconFA name="star-o" size={26} color={colors.text.primary} />
|
||||
</PressableOpacity>
|
||||
<PressableOpacity onPress={undefined} style={styles.more}>
|
||||
<IconMat name="more-vert" size={32} color="white" />
|
||||
</PressableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
marginBottom: 14,
|
||||
minHeight: 50,
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
},
|
||||
item: {
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'flex-start',
|
||||
},
|
||||
art: {
|
||||
marginRight: 10,
|
||||
},
|
||||
text: {
|
||||
flex: 1,
|
||||
},
|
||||
title: {
|
||||
fontSize: 16,
|
||||
fontFamily: font.semiBold,
|
||||
},
|
||||
subtitle: {
|
||||
fontSize: 14,
|
||||
fontFamily: font.regular,
|
||||
color: colors.text.secondary,
|
||||
},
|
||||
controls: {
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
marginLeft: 10,
|
||||
},
|
||||
more: {
|
||||
marginLeft: 8,
|
||||
},
|
||||
})
|
||||
|
||||
export default React.memo(SongItem)
|
||||
Reference in New Issue
Block a user