redid cover art (again...) and impl a ListItem

This commit is contained in:
austinried
2021-07-24 17:17:55 +09:00
parent 6dd17f2797
commit fbf6060db4
24 changed files with 602 additions and 597 deletions

View File

@@ -3,8 +3,8 @@ import GradientBackground from '@app/components/GradientBackground'
import ImageGradientScrollView from '@app/components/ImageGradientScrollView'
import ListPlayerControls from '@app/components/ListPlayerControls'
import NothingHere from '@app/components/NothingHere'
import SongItem from '@app/components/SongItem'
import { albumAtomFamily } from '@app/state/music'
import ListItem from '@app/components/ListItem'
import { albumAtomFamily, useCoverArtUri } from '@app/state/music'
import { useSetQueue } from '@app/state/trackplayer'
import colors from '@app/styles/colors'
import font from '@app/styles/font'
@@ -17,6 +17,7 @@ const AlbumDetails: React.FC<{
id: string
}> = ({ id }) => {
const album = useAtomValue(albumAtomFamily(id))
const coverArtUri = useCoverArtUri()
const setQueue = useSetQueue()
if (!album) {
@@ -36,7 +37,7 @@ const AlbumDetails: React.FC<{
}
})
.map((s, i) => (
<SongItem key={i} song={s} onPress={() => setQueue(album.songs, album.name, i)} />
<ListItem key={i} item={s} subtitle={s.artist} onPress={() => setQueue(album.songs, album.name, i)} />
))}
</View>
</>
@@ -44,11 +45,11 @@ const AlbumDetails: React.FC<{
return (
<ImageGradientScrollView
imageUri={album.coverArtThumbUri}
imageUri={coverArtUri(album.coverArt)}
imageKey={`${album.name}${album.artist}`}
style={styles.container}>
<View style={styles.content}>
<CoverArt coverArtUri={album.coverArtUri} style={styles.cover} />
<CoverArt coverArt={album.coverArt} style={styles.cover} imageSize="original" />
<Text style={styles.title}>{album.name}</Text>
<Text style={styles.subtitle}>
{album.artist}

View File

@@ -1,8 +1,8 @@
import ArtistArt from '@app/components/ArtistArt'
import CoverArt from '@app/components/CoverArt'
import GradientScrollView from '@app/components/GradientScrollView'
import Header from '@app/components/Header'
import PressableOpacity from '@app/components/PressableOpacity'
import SongItem from '@app/components/SongItem'
import ListItem from '@app/components/ListItem'
import { Album } from '@app/models/music'
import { artistInfoAtomFamily } from '@app/state/music'
import { useSetQueue } from '@app/state/trackplayer'
@@ -26,7 +26,7 @@ const AlbumItem = React.memo<{
<PressableOpacity
onPress={() => navigation.navigate('AlbumView', { id: album.id, title: album.name })}
style={[styles.albumItem, { width }]}>
<CoverArt coverArtUri={album.coverArtThumbUri} style={{ height, width }} />
<CoverArt coverArt={album.coverArt} style={{ height, width }} />
<Text style={styles.albumTitle}>{album.name}</Text>
<Text style={styles.albumYear}> {album.year ? album.year : ''}</Text>
</PressableOpacity>
@@ -47,25 +47,19 @@ const ArtistDetails: React.FC<{ id: string }> = ({ id }) => {
const TopSongs = () => (
<>
<Text style={styles.header}>Top Songs</Text>
<Header>Top Songs</Header>
{artist.topSongs.map((s, i) => (
<SongItem
<ListItem
key={i}
song={s}
item={s}
showArt={true}
subtitle="album"
subtitle={s.album}
onPress={() => setQueue(artist.topSongs, `Top Songs: ${artist.name}`, i)}
/>
))}
</>
)
const ArtistCoverFallback = () => (
<View style={styles.artistCover}>
<ArtistArt id={artist.id} round={false} height={artistCoverHeight} width={coverLayout.width} />
</View>
)
return (
<GradientScrollView
onLayout={coverLayout.onLayout}
@@ -73,17 +67,18 @@ const ArtistDetails: React.FC<{ id: string }> = ({ id }) => {
style={styles.scroll}
contentContainerStyle={styles.scrollContent}>
<CoverArt
FallbackComponent={ArtistCoverFallback}
coverArtUri={artist.largeImageUrl}
artistId={artist.id}
style={styles.artistCover}
resizeMode={FastImage.resizeMode.cover}
round={false}
imageSize="original"
/>
<View style={styles.titleContainer}>
<Text style={styles.title}>{artist.name}</Text>
</View>
<View style={styles.container}>
{artist.topSongs.length > 0 ? <TopSongs /> : <></>}
<Text style={styles.header}>Albums</Text>
<Header>Albums</Header>
<View style={styles.albums} onLayout={albumsLayout.onLayout}>
{artist.albums.map(a => (
<AlbumItem key={a.id} album={a} height={albumSize} width={albumSize} />
@@ -140,13 +135,6 @@ const styles = StyleSheet.create({
paddingHorizontal: 10,
marginBottom: 10,
},
header: {
fontFamily: font.bold,
fontSize: 24,
color: colors.text.primary,
marginTop: 20,
marginBottom: 14,
},
artistCover: {
position: 'absolute',
height: artistCoverHeight,

View File

@@ -1,5 +1,6 @@
import CoverArt from '@app/components/CoverArt'
import GradientScrollView from '@app/components/GradientScrollView'
import Header from '@app/components/Header'
import NothingHere from '@app/components/NothingHere'
import PressableOpacity from '@app/components/PressableOpacity'
import { AlbumListItem } from '@app/models/music'
@@ -30,7 +31,7 @@ const AlbumItem = React.memo<{
onPress={() => navigation.navigate('AlbumView', { id: album.id, title: album.name })}
key={album.id}
style={styles.item}>
<CoverArt coverArtUri={album.coverArtThumbUri} style={{ height: styles.item.width, width: styles.item.width }} />
<CoverArt coverArt={album.coverArt} style={{ height: styles.item.width, width: styles.item.width }} />
<Text style={styles.title} numberOfLines={1}>
{album.name}
</Text>
@@ -66,7 +67,7 @@ const Category = React.memo<{
return (
<View style={styles.category}>
<Text style={styles.categoryHeader}>{name}</Text>
<Header style={styles.header}>{name}</Header>
{data.length > 0 ? <Albums /> : <Nothing />}
</View>
)
@@ -111,24 +112,19 @@ const styles = StyleSheet.create({
content: {
paddingBottom: 20,
},
category: {
marginTop: 12,
},
categoryHeader: {
fontFamily: font.bold,
fontSize: 24,
color: colors.text.primary,
header: {
paddingHorizontal: 20,
marginTop: 4,
},
category: {
// marginTop: 12,
},
nothingHereContent: {
width: '100%',
height: 200,
height: 190,
justifyContent: 'center',
alignItems: 'center',
},
artScroll: {
marginTop: 10,
height: 190,
},
artScrollContent: {

View File

@@ -17,15 +17,15 @@ const AlbumItem = React.memo<{
size: number
height: number
artist?: string
coverArtUri?: string
}>(({ id, name, artist, size, height, coverArtUri }) => {
coverArt?: string
}>(({ id, name, artist, size, height, coverArt }) => {
const navigation = useNavigation()
return (
<PressableOpacity
style={[styles.item, { maxWidth: size, height }]}
onPress={() => navigation.navigate('AlbumView', { id, title: name })}>
<CoverArt coverArtUri={coverArtUri} style={{ height: size, width: size }} />
<CoverArt coverArt={coverArt} style={{ height: size, width: size }} />
<View style={styles.itemDetails}>
<Text style={styles.title} numberOfLines={1}>
{name}
@@ -43,7 +43,7 @@ const AlbumListRenderItem: React.FC<{
}> = ({ item }) => (
<AlbumItem
id={item.album.id}
coverArtUri={item.album.coverArtThumbUri}
coverArt={item.album.coverArt}
name={item.album.name}
artist={item.album.artist}
size={item.size}

View File

@@ -1,25 +1,23 @@
import ArtistArt from '@app/components/ArtistArt'
import GradientFlatList from '@app/components/GradientFlatList'
import PressableOpacity from '@app/components/PressableOpacity'
import ListItem from '@app/components/ListItem'
import { Artist } from '@app/models/music'
import { artistsAtom, artistsUpdatingAtom, useUpdateArtists } from '@app/state/music'
import colors from '@app/styles/colors'
import font from '@app/styles/font'
import { useNavigation } from '@react-navigation/native'
import { useAtomValue } from 'jotai/utils'
import React, { useEffect } from 'react'
import { StyleSheet, Text } from 'react-native'
import { StyleSheet } from 'react-native'
const ArtistItem = React.memo<{ item: Artist }>(({ item }) => {
const navigation = useNavigation()
return (
<PressableOpacity
style={styles.item}
onPress={() => navigation.navigate('ArtistView', { id: item.id, title: item.name })}>
<ArtistArt id={item.id} width={styles.art.width} height={styles.art.height} />
<Text style={styles.title}>{item.name}</Text>
</PressableOpacity>
<ListItem
item={item}
showArt={true}
showStar={false}
listStyle="big"
onPress={() => navigation.navigate('ArtistView', { id: item.id, title: item.name })}
/>
)
})
@@ -52,23 +50,8 @@ const ArtistsList = () => {
const styles = StyleSheet.create({
listContent: {
minHeight: '100%',
},
item: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'flex-start',
marginVertical: 6,
marginLeft: 10,
},
title: {
fontFamily: font.semiBold,
fontSize: 16,
color: colors.text.primary,
marginLeft: 10,
},
art: {
height: 70,
width: 70,
paddingHorizontal: 10,
paddingTop: 6,
},
})

View File

@@ -1,36 +1,24 @@
import CoverArt from '@app/components/CoverArt'
import GradientFlatList from '@app/components/GradientFlatList'
import PressableOpacity from '@app/components/PressableOpacity'
import ListItem from '@app/components/ListItem'
import { PlaylistListItem } from '@app/models/music'
import { playlistsAtom, playlistsUpdatingAtom, useUpdatePlaylists } from '@app/state/music'
import colors from '@app/styles/colors'
import font from '@app/styles/font'
import { useNavigation } from '@react-navigation/native'
import { useAtomValue } from 'jotai/utils'
import React, { useEffect } from 'react'
import { StyleSheet, Text, View } from 'react-native'
import { StyleSheet } from 'react-native'
const PlaylistItem = React.memo<{ item: PlaylistListItem }>(({ item }) => {
const navigation = useNavigation()
return (
<PressableOpacity
style={styles.item}
onPress={() => navigation.navigate('PlaylistView', { id: item.id, title: item.name })}>
<CoverArt coverArtUri={item.coverArtThumbUri} style={styles.art} />
<View style={styles.text}>
<Text style={styles.title} numberOfLines={1}>
{item.name}
</Text>
{item.comment ? (
<Text style={styles.subtitle} numberOfLines={1}>
{item.comment}
</Text>
) : (
<></>
)}
</View>
</PressableOpacity>
<ListItem
item={item}
showArt={true}
showStar={false}
listStyle="big"
subtitle={item.comment}
onPress={() => navigation.navigate('PlaylistView', { id: item.id, title: item.name })}
/>
)
})
@@ -63,30 +51,8 @@ const PlaylistsList = () => {
const styles = StyleSheet.create({
listContent: {
minHeight: '100%',
},
item: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'flex-start',
marginVertical: 6,
marginLeft: 10,
},
text: {
marginLeft: 10,
},
title: {
fontFamily: font.semiBold,
fontSize: 16,
color: colors.text.primary,
},
subtitle: {
fontFamily: font.regular,
fontSize: 14,
color: colors.text.secondary,
},
art: {
height: 70,
width: 70,
paddingHorizontal: 10,
paddingTop: 6,
},
})

View File

@@ -75,7 +75,7 @@ const SongCoverArt = () => {
return (
<View style={coverArtStyles.container}>
<CoverArt coverArtUri={track?.artwork as string} style={coverArtStyles.image} />
<CoverArt coverArt={track?.coverArt} style={coverArtStyles.image} imageSize="original" />
</View>
)
}
@@ -318,7 +318,7 @@ const NowPlayingLayout: React.FC<NowPlayingProps> = ({ navigation }) => {
return (
<View style={styles.container}>
<ImageGradientBackground imageUri={track?.artworkThumb as string} imageKey={`${track?.album}${track?.artist}`} />
<ImageGradientBackground imageUri={track?.artwork as string} imageKey={`${track?.album}${track?.artist}`} />
<NowPlayingHeader />
<View style={styles.content}>
<SongCoverArt />

View File

@@ -3,8 +3,8 @@ import GradientBackground from '@app/components/GradientBackground'
import ImageGradientScrollView from '@app/components/ImageGradientScrollView'
import ListPlayerControls from '@app/components/ListPlayerControls'
import NothingHere from '@app/components/NothingHere'
import SongItem from '@app/components/SongItem'
import { playlistAtomFamily } from '@app/state/music'
import ListItem from '@app/components/ListItem'
import { playlistAtomFamily, useCoverArtUri } from '@app/state/music'
import { useSetQueue } from '@app/state/trackplayer'
import colors from '@app/styles/colors'
import font from '@app/styles/font'
@@ -18,6 +18,7 @@ const PlaylistDetails: React.FC<{
}> = ({ id }) => {
const playlist = useAtomValue(playlistAtomFamily(id))
const setQueue = useSetQueue()
const coverArtUri = useCoverArtUri()
if (!playlist) {
return <></>
@@ -33,7 +34,13 @@ const PlaylistDetails: React.FC<{
/>
<View style={styles.songs}>
{playlist.songs.map((s, i) => (
<SongItem key={i} song={s} showArt={true} onPress={() => setQueue(playlist.songs, playlist.name, i)} />
<ListItem
key={i}
item={s}
subtitle={s.artist}
showArt={true}
onPress={() => setQueue(playlist.songs, playlist.name, i)}
/>
))}
</View>
</>
@@ -41,11 +48,11 @@ const PlaylistDetails: React.FC<{
return (
<ImageGradientScrollView
imageUri={playlist.coverArtThumbUri}
imageUri={coverArtUri(playlist.coverArt)}
imageKey={`${playlist.id}${playlist.name}`}
style={styles.container}>
<View style={styles.content}>
<CoverArt coverArtUri={playlist.coverArtUri} style={styles.cover} />
<CoverArt coverArt={playlist.coverArt} style={styles.cover} imageSize="original" />
<Text style={styles.title}>{playlist.name}</Text>
{playlist.comment ? <Text style={styles.subtitle}>{playlist.comment}</Text> : <></>}
{playlist.songs.length > 0 ? <Songs /> : <NothingHere height={350} width={250} />}

75
app/screens/Search.tsx Normal file
View File

@@ -0,0 +1,75 @@
import GradientScrollView from '@app/components/GradientScrollView'
import Header from '@app/components/Header'
import ListItem from '@app/components/ListItem'
import { searchResultsAtom, useUpdateSearchResults } from '@app/state/music'
import colors from '@app/styles/colors'
import font from '@app/styles/font'
import { useAtomValue } from 'jotai/utils'
import React, { useState } from 'react'
import { StatusBar, StyleSheet, View, TextInput } from 'react-native'
const Search = () => {
const [text, setText] = useState('')
const updateSearch = useUpdateSearchResults()
const results = useAtomValue(searchResultsAtom)
const onSubmitEditing = () => {
console.log(text)
updateSearch(text)
}
return (
<GradientScrollView style={styles.scroll} contentContainerStyle={styles.scrollContentContainer}>
<View style={styles.content}>
<TextInput
style={styles.textInput}
placeholder="Search"
placeholderTextColor="grey"
selectionColor={colors.text.secondary}
value={text}
onChangeText={setText}
onSubmitEditing={onSubmitEditing}
/>
<Header>Artists</Header>
{results.artists.map(a => (
<ListItem key={a.id} item={a} showArt={true} showStar={false} />
))}
<Header>Albums</Header>
{results.albums.map(a => (
<ListItem key={a.id} item={a} showArt={true} showStar={false} subtitle={a.artist} />
))}
<Header>Songs</Header>
{results.songs.map(a => (
<ListItem key={a.id} item={a} showArt={true} showStar={false} subtitle={a.artist} />
))}
</View>
</GradientScrollView>
)
}
const styles = StyleSheet.create({
scroll: {
flex: 1,
},
scrollContentContainer: {
paddingTop: StatusBar.currentHeight,
},
content: {
paddingHorizontal: 20,
},
textInput: {
backgroundColor: '#515151',
fontFamily: font.regular,
fontSize: 18,
color: colors.text.primary,
marginTop: 20,
paddingHorizontal: 12,
},
itemText: {
color: colors.text.primary,
fontFamily: font.regular,
fontSize: 14,
},
})
export default Search